From 8b6bb6ff50bf7eefc995c2e79a39d6835c04f3e8 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Sun, 19 Nov 2017 12:40:32 +0100 Subject: [PATCH] restconf bugs and increased restconf testing --- CHANGELOG.md | 39 +++++++++++++++----------------- apps/restconf/restconf_methods.c | 1 + example/routing_backend.c | 5 ++-- lib/src/clixon_xsl.c | 6 +++-- test/test_restconf.sh | 20 ++++++++++------ 5 files changed, 39 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44e5febc..e7fa47e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,25 @@ ### Known issues ### Major changes: +* Clixon can now be compiled and run on Apple Darwin. + +* Performance improvements + * Added xml hash lookup instead of linear search for better performance of large lists. To disable, undefine XML_CHILD_HASH in clixon_custom.h + * netconf client was limited to 8K byte messages. Now limit is 2^32 bytes + +* XML and YANG-based configuration file. + * New configuration files have .xml suffix, old have .conf. Old config files till work for backward compatibility. + * The yang model is yang/clixon-config.yang. + * A migration utility is clixon_cli -x to print new format, eg: +``` +clixon_cli -f /usr/local/etc/routing.conf -1x +``` + * Introducing backend daemon startup modes. The flags -IRCr and option CLICON_USE_STARTUP_CONFIG are replaced with command-line option -s and option CLICON_STARTUP_MODE. You need to replace the starting of clixon_backend as follows: - -I replace with "init" (as -s command line option or CLICON_STARTUP_MODE option) - -CIr replace with "running" - null replace with "none" - CLICON_USE_STARTUP_CONFIG=1 replace with "startup" + * -I replace with -s "init" (or use of CLICON_STARTUP_MODE option) + * -CIr replace with -s "running" + * (no-option) replace with -s "none" + * CLICON_USE_STARTUP_CONFIG=1 replace with -s "startup" Backward compatibility is enabled by defining BACKEND_STARTUP_BACKWARD_COMPAT in include/clixon_custom.h ### Minor changes: @@ -22,8 +36,6 @@ Backward compatibility is enabled by defining BACKEND_STARTUP_BACKWARD_COMPAT in cli_set_comment, cli_tree_add, cli_tree_active, cli_tree_active_set, cli_tree. -* Apple Darwin port - * Added a format parameter to clicon_rpc_generate_error() and changed error printouts for backend errors, such as commit and validate. Example of the new format: @@ -34,22 +46,7 @@ Sep 27 18:11:58: Commit failed. Edit and try again or discard changes: protocol invalid-value Missing mandatory variable: type ``` -* Migrated to XML configure file. -** If clixon config file has .xml ending, yang/clixon-config.yang is used as - model for an xml-based configuration file. Otherwise legacy format is used. -** As migration utility from legacy to XML configure file, clixon_cli -x can be used to print new format, eg: - -``` -clixon_cli -f /usr/local/etc/routing.conf -1x -``` - -* The clixon config file format has changed. It now uses XML and YANG. - Old configuration files work, but you can use the new by setting an .xml suffix. - The yang model is yang/clixon-config.yang. -* netconf client was limited to 8K byte messages. Now limit is 2^32. * Added event_poll function. -* Added experimental xml hash for better performance of large lists. - To enable, set XML_CHILD_HASH in clixon_custom.h * Support for non-line scrolling in CLI, eg wrap lines. Set with: CLICON_CLI_LINESCROLLING 0 diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c index 82e866c6..857fbc30 100644 --- a/apps/restconf/restconf_methods.c +++ b/apps/restconf/restconf_methods.c @@ -171,6 +171,7 @@ api_data_get_gen(clicon_handle h, yspec = clicon_dbspec_yang(h); if ((path = cbuf_new()) == NULL) goto done; + cprintf(path, "/"); if (api_path2xpath_cvv(yspec, pcvec, pi, path) < 0){ notfound(r); goto done; diff --git a/example/routing_backend.c b/example/routing_backend.c index cb6dcb74..e667b2d0 100644 --- a/example/routing_backend.c +++ b/example/routing_backend.c @@ -162,15 +162,16 @@ plugin_statedata(clicon_handle h, int retval = -1; cxobj **xvec = NULL; + fprintf(stderr, "%s xpath:%s\n", __FUNCTION__, xpath); /* Example of (static) statedata, real code would poll state */ - if (0 && (xml_parse("" + if (xml_parse("" "eth0" "eth" "up" "up" "42" "1000000000" - "", xstate)) < 0) + "", xstate) < 0) goto done; retval = 0; done: diff --git a/lib/src/clixon_xsl.c b/lib/src/clixon_xsl.c index c59f6eb1..d7731de2 100644 --- a/lib/src/clixon_xsl.c +++ b/lib/src/clixon_xsl.c @@ -988,8 +988,10 @@ xpath_each(cxobj *xcur, int i; if (xprev == NULL){ - if (vec1) // XXX - free(vec1); // XXX + if (vec1) { + free(vec1); + vec1 = NULL; + } vec1len = 0; if (xpath_choice(xcur, xpath, 0, &vec1, &vec1len) < 0) goto done; diff --git a/test/test_restconf.sh b/test/test_restconf.sh index f03e1ebf..f77fd3bf 100755 --- a/test/test_restconf.sh +++ b/test/test_restconf.sh @@ -5,6 +5,9 @@ # include err() and new() functions . ./lib.sh +# This is a fixed 'state' implemented in routing_backend. It is always there +state='{"interfaces-state": {"interface": {"name": "eth0","type": "eth","admin-status": "up","oper-status": "up","if-index": "42","speed": "1000000000"}}}' + # kill old backend (if any) new "kill old backend" sudo clixon_backend -zf $clixon_cf @@ -34,27 +37,30 @@ new "restconf head" expectfn "curl -sS -I http://localhost/restconf/data" "HTTP/1.1 200 OK" #Content-Type: application/yang-data+json" -new "restconf get empty config" -expectfn "curl -sSG http://localhost/restconf/data" "null" +new "restconf get empty config + state" +expectfn "curl -sSG http://localhost/restconf/data" $state + +new "restconf get state operation" +expectfn "curl -sS -G http://localhost/restconf/data/interfaces-state" $state new "restconf Add subtree to datastore using POST" expectfn 'curl -sS -X POST -d {"interfaces":{"interface":{"name":"eth/0/0","type":"eth","enabled":"true"}}} http://localhost/restconf/data' "" new "restconf Check interfaces eth/0/0 added" -expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}}} +expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}},"interfaces-state": {"interface": {"name": "eth0","type": "eth","admin-status": "up","oper-status": "up","if-index": "42","speed": "1000000000"}}} $' new "restconf delete interfaces" expectfn 'curl -sS -X DELETE http://localhost/restconf/data/interfaces' "" new "restconf Check empty config" -expectfn "curl -sSG http://localhost/restconf/data" "null" +expectfn "curl -sSG http://localhost/restconf/data" $state new "restconf Add interfaces subtree eth/0/0 using POST" expectfn 'curl -sS -X POST -d {"interface":{"name":"eth/0/0","type":"eth","enabled":"true"}} http://localhost/restconf/data/interfaces' "" new "restconf Check eth/0/0 added" -expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}}} +expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}},"interfaces-state": {"interface": {"name": "eth0","type": "eth","admin-status": "up","oper-status": "up","if-index": "42","speed": "1000000000"}}} $' new "restconf Re-post eth/0/0 which should generate error" @@ -71,7 +77,7 @@ new "restconf delete eth/0/0" expectfn 'curl -sS -X DELETE http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' "" new "Check deleted eth/0/0" -expectfn 'curl -sS -G http://localhost/restconf/data' "null" +expectfn 'curl -sS -G http://localhost/restconf/data' $state new "restconf Re-Delete eth/0/0 using none should generate error" expectfn 'curl -sS -X DELETE http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' "Not Found" @@ -80,7 +86,7 @@ new "restconf Add subtree eth/0/0 using PUT" expectfn 'curl -sS -X PUT -d {"interface":{"name":"eth/0/0","type":"eth","enabled":"true"}} http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' "" new "restconf get subtree" -expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}}} +expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}},"interfaces-state": {"interface": {"name": "eth0","type": "eth","admin-status": "up","oper-status": "up","if-index": "42","speed": "1000000000"}}} $' new "restconf operation rpc using POST json"