diff --git a/apps/backend/backend_commit.c b/apps/backend/backend_commit.c index fdf8eeb1..deffd9fd 100644 --- a/apps/backend/backend_commit.c +++ b/apps/backend/backend_commit.c @@ -200,7 +200,7 @@ startup_common(clicon_handle h, /* Handcraft transition with with only add tree */ td->td_target = xt; x = NULL; - while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL){ + while ((x = xml_child_each(td->td_target, x, CX_ELMNT)) != NULL){ if (cxvec_append(x, &td->td_avec, &td->td_alen) < 0) goto done; } @@ -313,15 +313,6 @@ startup_commit(clicon_handle h, /* 10. Call plugin transaction end callbacks */ plugin_transaction_end(h, td); - /* 11. Copy running back to candidate in case end functions updated running - * XXX: room for improvement: candidate and running may be equal. - * Copy only diffs? - */ - if (xmldb_copy(h, "running", "candidate") < 0){ - /* ignore errors or signal major setback ? */ - clicon_log(LOG_NOTICE, "Error in rollback, trying to continue"); - goto done; - } retval = 1; done: if (td) @@ -494,15 +485,6 @@ candidate_commit(clicon_handle h, /* 9. Call plugin transaction end callbacks */ plugin_transaction_end(h, td); - /* 8. Copy running back to candidate in case end functions updated running - * XXX: room for improvement: candidate and running may be equal. - * Copy only diffs? - */ - if (xmldb_copy(h, "running", candidate) < 0){ - /* ignore errors or signal major setback ? */ - clicon_log(LOG_NOTICE, "Error in rollback, trying to continue"); - goto done; - } retval = 1; done: /* In case of failure (or error), call plugin transaction termination callbacks */ diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 09985887..8a79bdac 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -1652,7 +1652,7 @@ xml_default(cxobj *xt, } } } - xml_sort(xt, NULL); + // xml_sort(xt, NULL); retval = 0; done: return retval; diff --git a/lib/src/clixon_xpath_parse.l b/lib/src/clixon_xpath_parse.l index ca84f52a..7fd27c38 100644 --- a/lib/src/clixon_xpath_parse.l +++ b/lib/src/clixon_xpath_parse.l @@ -146,11 +146,11 @@ real ({digit}+[.]{digit}*)|({digit}*[.]{digit}+) . { fprintf(stderr,"LEXICAL ERROR\n"); return -1; } \" { BEGIN(TOKEN); return QUOTE; } -. { clixon_xpath_parselval.string = strdup(yytext); - return CHAR;} +[^"]+ { clixon_xpath_parselval.string = strdup(yytext); + return CHARS;} \' { BEGIN(TOKEN); return APOST; } -. { clixon_xpath_parselval.string = strdup(yytext); - return CHAR;} +[^']+ { clixon_xpath_parselval.string = strdup(yytext); + return CHARS;} %% diff --git a/lib/src/clixon_xpath_parse.y b/lib/src/clixon_xpath_parse.y index f2880804..f014b6a4 100644 --- a/lib/src/clixon_xpath_parse.y +++ b/lib/src/clixon_xpath_parse.y @@ -59,7 +59,7 @@ %token X_EOF %token QUOTE %token APOST -%token CHAR +%token CHARS %token NAME %token NODETYPE %token DOUBLEDOT @@ -276,14 +276,14 @@ args : args ',' expr { $$=xp_new(XP_EXP,A_NAN,0.0,NULL,NULL,$1, $3); clicon_debug(2,"args -> expr "); } ; -string : string CHAR { +string : string CHARS { int len = strlen($1); $$ = realloc($1, len+strlen($2) + 1); sprintf($$+len, "%s", $2); free($2); clicon_debug(2,"string-> string CHAR"); } - | CHAR { clicon_debug(2,"string-> "); } + | CHARS { clicon_debug(2,"string-> "); } ; diff --git a/lib/src/clixon_yang_parse.y b/lib/src/clixon_yang_parse.y index 1e49d46f..553ae319 100644 --- a/lib/src/clixon_yang_parse.y +++ b/lib/src/clixon_yang_parse.y @@ -1132,6 +1132,7 @@ leaf_list_substmt : when_stmt { clicon_debug(2,"leaf-list-substmt -> when | type_stmt { clicon_debug(2,"leaf-list-substmt -> type-stmt"); } | units_stmt { clicon_debug(2,"leaf-list-substmt -> units-stmt"); } | must_stmt { clicon_debug(2,"leaf-list-substmt -> must-stmt"); } + | default_stmt { clicon_debug(2,"leaf-list-substmt -> default-stmt"); } | config_stmt { clicon_debug(2,"leaf-list-substmt -> config-stmt"); } | min_elements_stmt { clicon_debug(2,"leaf-list-substmt -> min-elements-stmt"); } | max_elements_stmt { clicon_debug(2,"leaf-list-substmt -> max-elements-stmt"); } diff --git a/test/README.md b/test/README.md index cb41e85f..27349b26 100644 --- a/test/README.md +++ b/test/README.md @@ -52,12 +52,10 @@ Run all tests but continue after errors and only print a summary test output ide ``` ## Memory leak test -These tests use valgrind to check for memory leaks: +The `mem.sh` runs memory checks using valgrind. Start it with no arguments to test all components (backend, restconf, cli, netconf), or specify which components to run: ``` - mem.sh cli - mem.sh netconf - mem.sh backend - mem.sh restconf + mem.sh # All components + mem.sh restconf backend # Only backend and cli ``` ## Site.sh diff --git a/test/long.sh b/test/long.sh index fd8d69a2..3db6b391 100755 --- a/test/long.sh +++ b/test/long.sh @@ -41,7 +41,7 @@ module scaling{ EOF cat < $cfg - + $cfg $dir /usr/local/share/clixon @@ -53,7 +53,7 @@ cat < $cfg /usr/local/var/$APPNAME /usr/local/lib/xmldb/text.so false - + EOF new "test params: -f $cfg -y $fyang" diff --git a/test/mem.sh b/test/mem.sh index e570d96d..94ed4b51 100755 --- a/test/mem.sh +++ b/test/mem.sh @@ -1,65 +1,89 @@ #!/bin/bash # Run valgrind leak test for cli, restconf, netconf or background. # Stop on first error -# -if [ $# -ne 1 ]; then - echo "usage: $0 cli|netconf|restconf|backend" # valgrind memleak checks - exit -1 + +# Run valgrindtest once, args: +# what: cli|netconf|restconf|backend +memonce(){ + what=$1 + + valgrindfile=$(mktemp) + echo "valgrindfile:$valgrindfile" + + case "$what" in + 'cli') + valgrindtest=1 + : ${RCWAIT:=5} # valgrind backend needs some time to get up + clixon_cli="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_cli" + ;; + 'netconf') + valgrindtest=1 + : ${RCWAIT:=5} # valgrind backend needs some time to get up + clixon_netconf="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_netconf" + ;; + 'backend') + valgrindtest=2 # This means backend valgrind test + : ${RCWAIT:=10} # valgrind backend needs some time to get up + perfnr=100 # test_perf.sh restconf put more or less stops + perfreq=10 + + clixon_backend="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=yes --log-file=$valgrindfile clixon_backend" + ;; + 'restconf') + valgrindtest=3 # This means backend valgrind test + sudo chmod 660 $valgrindfile + sudo chown www-data $valgrindfile + : ${RCWAIT:=5} # valgrind backend needs some time to get up + clixon_restconf="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile /www-data/clixon_restconf" + + ;; + *) + echo "usage: $0 cli|netconf|restconf|backend" # valgrind memleak checks + rm -f $valgrindfile + exit -1 + ;; + esac + + err=0 + for test in test_*.sh; do + if [ $testnr != 0 ]; then echo; fi + testfile=$test + . ./$test + errcode=$? + if [ $errcode -ne 0 ]; then + err=1 + echo -e "\e[31mError in $test errcode=$errcode" + echo -ne "\e[0m" + exit $errcode + fi + done + if [ $valgrindtest -eq 1 ]; then + checkvalgrind + sudo rm -f $valgrindfile + fi +} + +if [ -z "$*" ]; then + cmds="backend restconf cli netconf" +else + cmds=$* fi -PROGRAM=$1 -valgrindfile=$(mktemp) -echo "valgrindfile:$valgrindfile" - -case "$PROGRAM" in - 'cli') - valgrindtest=1 - RCWAIT=1 - clixon_cli="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_cli" -;; - 'netconf') - valgrindtest=1 - RCWAIT=1 - clixon_netconf="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_netconf" -;; - 'backend') - valgrindtest=2 # This means backend valgrind test - RCWAIT=10 # valgrind backend needs some time to get up - perfnr=100 # test_perf.sh restconf put more or less stops - perfreq=10 - - clixon_backend="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=yes --log-file=$valgrindfile clixon_backend" -;; - 'restconf') - valgrindtest=3 # This means backend valgrind test - sudo chmod 660 $valgrindfile - sudo chown www-data $valgrindfile - RCWAIT=5 # valgrind restconf needs some time to get up - clixon_restconf="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile /www-data/clixon_restconf" - -;; -*) - echo "usage: $0 cli|netconf|restconf|backend" # valgrind memleak checks - rm -f $valgrindfile - exit -1 -;; -esac - -err=0 -testnr=0 -for test in test_*.sh; do - testfile=$test - . ./$test - errcode=$? - if [ $errcode -ne 0 ]; then - err=1 - echo -e "\e[31mError in $test errcode=$errcode" - echo -ne "\e[0m" - exit $errcode +# First run sanity +for c in $cmds; do + if [ $c != cli -a $c != netconf -a $c != restconf -a $c != backend ]; then + echo "c:$c" + echo "usage: $0 [cli|netconf|restconf|backend]+" + echo " with no args run all" + exit -1 fi done -if [ $valgrindtest -eq 1 ]; then - checkvalgrind - sudo rm -f $valgrindfile -fi +# Then actual run +testnr=0 +for c in $cmds; do + if [ $testnr != 0 ]; then echo; fi + echo "Mem test for $c" + echo "=================" + memonce $c +done diff --git a/test/test_yangmodels.sh b/test/test_yangmodels.sh index fde9410c..9acfc191 100755 --- a/test/test_yangmodels.sh +++ b/test/test_yangmodels.sh @@ -35,14 +35,15 @@ cat < $cfg $cfg $YANGMODELS/standard/ietf/RFC - $YANGMODELS/standard/ieee/draft - $YANGMODELS/standard/ieee/802.1/draft + $YANGMODELS/standard/ieee/draft/802.1 + $YANGMODELS/standard/ieee/draft/802 /usr/local/share/clixon /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/cli $APPNAME /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile + 1 1 /usr/local/var/$APPNAME /usr/local/lib/xmldb/text.so @@ -55,24 +56,51 @@ new "yangmodels parse: -f $cfg" new "yangmodel Experimental IEEE 802.1: $YANGMODELS/experimental/ieee/802.1" expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/experimental/ieee/802.1 -p $YANGMODELS/experimental/ieee/1588 show version" 0 "3." -# experimental 802.3 dir is empty -#new "yangmodel Experimental IEEE 802.3: $YANGMODELS/experimental/ieee/802.3" -#expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/experimental/ieee/802.3 show version" 0 "3." - new "yangmodel Experimental IEEE 1588: $YANGMODELS/experimental/ieee/1588" expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/experimental/ieee/1588 show version" 0 "3." # Standard IEEE -new "yangmodel Standard IEEE 802.1: $YANGMODELS/standard/ieee/802.1/draft" -expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/standard/ieee/802.1/draft show version" 0 "3." +new "yangmodel Standard IEEE 802.1: $YANGMODELS/standard/ieee/draft/802.1" +expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/standard/ieee/draft/802.1 show version" 0 "3." -new "yangmodel Standard IEEE 802.3: $YANGMODELS/standard/ieee/802.3/draft" -expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/standard/ieee/802.3/draft show version" 0 "3." +new "yangmodel Standard IEEE 802.3: $YANGMODELS/standard/ieee/draft/802.3" +expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/standard/ieee/draft/802.3 show version" 0 "3." # Standard IETF new "yangmodel Standard IETF: $YANGMODELS/standard/ietf/RFC" expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/standard/ietf/RFC show version" 0 "3." +# vendor/junos +#junos : M/MX, T/TX, Some EX platforms, ACX +#junos-es : SRX, Jseries, LN-* +#junos-ex : EX series +#junos-qfx : QFX series +#junos-nfx : NFX series + +# Juniper JunOS. Junos files have 4 lines copyright, then "module" on +# line 5. No sub-modules. +# NOTE: We DISABLE CLI generation, because some juniper are very large. +# and cli generation consumes memory. +# For example (100K lines): +#wc /usr/local/share/yangmodels/vendor/juniper/18.2/18.2R1/junos/conf/junos-conf-system@2018-01-01.yang +# 92853 274279 3228229 /usr/local/share/yangmodels/vendor/juniper/18.2/18.2R1/junos/conf/junos-conf-system@2018-01-01.yan +# But junos-conf-logical-systems@2018-01-01.yang takes longest time + +files=$(find $YANGMODELS/vendor/juniper/18.2/18.2R1/junos/conf -name "*.yang") +let i=0; +for f in $files; do + if [ -n "$(head -5 $f|grep '^ module')" ]; then + new "$clixon_cli -1f $cfg -o CLICON_YANG_MAIN_FILE=$f -p $YANGMODELS/vendor/juniper/18.2/18.2R1/common -p $YANGMODELS/vendor/juniper/18.2/18.2R1/junos/conf show version" + expectfn "$clixon_cli -1f $cfg -o CLICON_YANG_MAIN_FILE=$f -p $YANGMODELS/vendor/juniper/18.2/18.2R1/common -p $YANGMODELS/vendor/juniper/18.2/18.2R1/junos/conf -o CLICON_CLI_GENMODEL=0 show version" 0 "3." + let i++; + sleep 1 + fi +done + +# We skip CISCO because we have errors that vilates the RFC (I think) +# eg: Test 7(7) [yangmodel vendor cisco xr 623: /usr/local/share/yangmodels/vendor/cisco/xr/623] +# yang_abs_schema_nodeid: Absolute schema nodeid /bgp-rib/afi-safis/afi-safi/ipv4-unicast/loc-rib must have prefix + if false; then # vendor/cisco/xr new "yangmodel vendor cisco xr 623: $YANGMODELS/vendor/cisco/xr/623" @@ -88,22 +116,5 @@ new "yangmodel vendor cisco xr 651: $YANGMODELS/vendor/cisco/xr/651" expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/vendor/cisco/xr/651 show version" 0 "3." fi ### cisco -# vendor/junos -#junos : M/MX, T/TX, Some EX platforms, ACX -#junos-es : SRX, Jseries, LN-* -#junos-ex : EX series -#junos-qfx : QFX series -#junos-nfx : NFX series - -new "yangmodel vendor junos: $YANGMODELS/vendor/juniper/18.2/18.2R1/junos/conf/" -expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_FILE=$YANGMODELS/vendor/juniper/18.2/18.2R1/junos/conf/junos-conf-interfaces@2018-01-01.yang -p $YANGMODELS/vendor/juniper/18.2/18.2R1/junos/conf -p $YANGMODELS/vendor/juniper/18.2/18.2R1/common show version" 0 "3." - -# breaks memory and cpu limits,... -#new "yangmodel vendor junos: $YANGMODELS/vendor/juniper/18.2/18.2R1/junos/conf" -#expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/vendor/juniper/18.2/18.2R1/junos/conf -p $YANGMODELS/vendor/juniper/18.2/18.2R1/common show version" 0 "3." - -#new "yangmodel vendor junos: $YANGMODELS/vendor/juniper/18.2/18.2R1/junos/rpc" -#expectfn "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/vendor/juniper/18.2/18.2R1/junos/rpc -p $YANGMODELS/vendor/juniper/18.2/18.2R1/common show version" 0 "3." - rm -rf $dir