diff --git a/apps/backend/backend_commit.c b/apps/backend/backend_commit.c index 1c49a778..874ec1ad 100644 --- a/apps/backend/backend_commit.c +++ b/apps/backend/backend_commit.c @@ -100,7 +100,8 @@ generic_validate(yang_spec *yspec, /* added entries */ for (i=0; itd_alen; i++){ x2 = td->td_avec[i]; - if (xml_yang_validate(x2, xml_spec(x2)) < 0) + ys = xml_spec(x2); + if (xml_yang_validate(x2, ys) < 0) goto done; if (xml_apply(x2, CX_ELMNT, (xml_applyfn_t*)xml_yang_validate, NULL) < 0) diff --git a/apps/cli/cli_common.c b/apps/cli/cli_common.c index 5ede5012..2a5c221b 100644 --- a/apps/cli/cli_common.c +++ b/apps/cli/cli_common.c @@ -309,8 +309,8 @@ cli_commit(clicon_handle h, int snapshot = arg?cv_int32_get(arg):0; if ((retval = clicon_rpc_commit(h, - "running", "candidate", + "running", snapshot, /* snapshot */ snapshot)) < 0){ /* startup */ cli_output(stderr, "Commit failed. Edit and try again or discard changes\n"); @@ -330,7 +330,7 @@ cli_validate(clicon_handle h, cvec *vars, cg_var *arg) int retval = -1; if ((retval = clicon_rpc_validate(h, "candidate")) < 0) - cli_output(stderr, "Validate failed. Edit and try again or discard changes\n"); + clicon_err(OE_CFG, 0, "Validate failed. Edit and try again or discard changes\n"); return retval; } @@ -699,7 +699,7 @@ cli_dbxml(clicon_handle h, if (clicon_rpc_change(h, "candidate", op, xk, val) < 0) goto done; if (clicon_autocommit(h)) { - if (clicon_rpc_commit(h, "running", "candidate", 0, 0) < 0) + if (clicon_rpc_commit(h, "candidate", "running", 0, 0) < 0) goto done; } retval = 0; diff --git a/apps/cli/cli_generate.c b/apps/cli/cli_generate.c index afdb1837..d532df73 100644 --- a/apps/cli/cli_generate.c +++ b/apps/cli/cli_generate.c @@ -225,7 +225,7 @@ static int yang2cli_var_sub(clicon_handle h, yang_stmt *ys, cbuf *cb0, - char *description, + char *helptext, enum cv_type cvtype, yang_stmt *ytype, /* resolved type */ int options, @@ -324,13 +324,13 @@ yang2cli_var_sub(clicon_handle h, cprintf(cb0, " regexp:\"%s\"", pattern); cprintf(cb0, ">"); - if (description) - cprintf(cb0, "(\"%s\")", description); + if (helptext) + cprintf(cb0, "(\"%s\")", helptext); if (completion){ if (cli_expand_var_generate(h, ys, cvtype, cb0) < 0) goto done; - if (description) - cprintf(cb0, "(\"%s\")", description); + if (helptext) + cprintf(cb0, "(\"%s\")", helptext); cprintf(cb0, ")"); } retval = 0; @@ -347,7 +347,7 @@ static int yang2cli_var(clicon_handle h, yang_stmt *ys, cbuf *cb0, - char *description) + char *helptext) { int retval = -1; char *type; /* orig type */ @@ -386,7 +386,7 @@ yang2cli_var(clicon_handle h, restype = yrt?yrt->ys_argument:NULL; if (clicon_type2cv(type, restype, &cvtype) < 0) goto done; - if ((retval = yang2cli_var_sub(h, ys, cb0, description, cvtype, yrt, + if ((retval = yang2cli_var_sub(h, ys, cb0, helptext, cvtype, yrt, options, mincv, maxcv, pattern, fraction_digits)) < 0) goto done; @@ -395,7 +395,7 @@ yang2cli_var(clicon_handle h, cprintf(cb0, ")"); } else - if ((retval = yang2cli_var_sub(h, ys, cb0, description, cvtype, yrestype, + if ((retval = yang2cli_var_sub(h, ys, cb0, helptext, cvtype, yrestype, options, mincv, maxcv, pattern, fraction_digits)) < 0) goto done; @@ -418,21 +418,28 @@ yang2cli_leaf(clicon_handle h, { yang_stmt *yd; /* description */ int retval = -1; - char *description = NULL; + char *helptext = NULL; + char *s; /* description */ - if ((yd = yang_find((yang_node*)ys, Y_DESCRIPTION, NULL)) != NULL) - description = yd->ys_argument; + if ((yd = yang_find((yang_node*)ys, Y_DESCRIPTION, NULL)) != NULL){ + if ((helptext = strdup(yd->ys_argument)) == NULL){ + clicon_err(OE_UNIX, errno, "strdup"); + goto done; + } + if ((s = strstr(helptext, "\n\n")) != NULL) + *s = '\0'; + } cprintf(cbuf, "%*s", level*3, ""); if (gt == GT_VARS|| gt == GT_ALL){ cprintf(cbuf, "%s", ys->ys_argument); - if (yd != NULL) - cprintf(cbuf, "(\"%s\")", yd->ys_argument); + if (helptext) + cprintf(cbuf, "(\"%s\")", helptext); cprintf(cbuf, " "); - yang2cli_var(h, ys, cbuf, description); + yang2cli_var(h, ys, cbuf, helptext); } else - yang2cli_var(h, ys, cbuf, description); + yang2cli_var(h, ys, cbuf, helptext); if (callback){ if (cli_callback_generate(h, ys, cbuf) < 0) goto done; @@ -441,6 +448,8 @@ yang2cli_leaf(clicon_handle h, retval = 0; done: + if (helptext) + free(helptext); return retval; } @@ -456,10 +465,19 @@ yang2cli_container(clicon_handle h, yang_stmt *yd; int i; int retval = -1; + char *helptext = NULL; + char *s; cprintf(cbuf, "%*s%s", level*3, "", ys->ys_argument); - if ((yd = yang_find((yang_node*)ys, Y_DESCRIPTION, NULL)) != NULL) - cprintf(cbuf, "(\"%s\")", yd->ys_argument); + if ((yd = yang_find((yang_node*)ys, Y_DESCRIPTION, NULL)) != NULL){ + if ((helptext = strdup(yd->ys_argument)) == NULL){ + clicon_err(OE_UNIX, errno, "strdup"); + goto done; + } + if ((s = strstr(helptext, "\n\n")) != NULL) + *s = '\0'; + cprintf(cbuf, "(\"%s\")", helptext); + } if (cli_callback_generate(h, ys, cbuf) < 0) goto done; cprintf(cbuf, ";{\n"); @@ -470,6 +488,8 @@ yang2cli_container(clicon_handle h, cprintf(cbuf, "%*s}\n", level*3, ""); retval = 0; done: + if (helptext) + free(helptext); return retval; } @@ -489,10 +509,19 @@ yang2cli_list(clicon_handle h, char *keyname; cvec *cvk = NULL; /* vector of index keys */ int retval = -1; + char *helptext = NULL; + char *s; cprintf(cbuf, "%*s%s", level*3, "", ys->ys_argument); - if ((yd = yang_find((yang_node*)ys, Y_DESCRIPTION, NULL)) != NULL) - cprintf(cbuf, "(\"%s\")", yd->ys_argument); + if ((yd = yang_find((yang_node*)ys, Y_DESCRIPTION, NULL)) != NULL){ + if ((helptext = strdup(yd->ys_argument)) == NULL){ + clicon_err(OE_UNIX, errno, "strdup"); + goto done; + } + if ((s = strstr(helptext, "\n\n")) != NULL) + *s = '\0'; + cprintf(cbuf, "(\"%s\")", helptext); + } /* Loop over all key variables */ if ((ykey = yang_find((yang_node*)ys, Y_KEY, NULL)) == NULL){ clicon_err(OE_XML, 0, "List statement \"%s\" has no key", ys->ys_argument); @@ -538,6 +567,8 @@ yang2cli_list(clicon_handle h, cprintf(cbuf, "%*s}\n", level*3, ""); retval = 0; done: + if (helptext) + free(helptext); if (cvk) cvec_free(cvk); return retval; diff --git a/apps/netconf/netconf_rpc.c b/apps/netconf/netconf_rpc.c index 506473f4..eaadaab8 100644 --- a/apps/netconf/netconf_rpc.c +++ b/apps/netconf/netconf_rpc.c @@ -723,7 +723,7 @@ netconf_commit(clicon_handle h, int retval = -1; if (clicon_rpc_commit(h, "candidate", "running", - 1, 1) < 0){ + 0, 0) < 0){ netconf_create_rpc_error(cb_err, xorig, "operation-failed", "protocol", "error", diff --git a/lib/clixon/clixon_proto.h b/lib/clixon/clixon_proto.h index ad260409..af7ef511 100644 --- a/lib/clixon/clixon_proto.h +++ b/lib/clixon/clixon_proto.h @@ -156,8 +156,4 @@ int send_msg_ok(int s); int send_msg_err(int s, int err, int suberr, char *format, ...); - - - - #endif /* _CLIXON_PROTO_H_ */ diff --git a/lib/clixon/clixon_proto_client.h b/lib/clixon/clixon_proto_client.h index 89f8df1f..3f9e6cce 100644 --- a/lib/clixon/clixon_proto_client.h +++ b/lib/clixon/clixon_proto_client.h @@ -27,7 +27,7 @@ #ifndef _CLIXON_PROTO_CLIENT_H_ #define _CLIXON_PROTO_CLIENT_H_ -int clicon_rpc_commit(clicon_handle h, char *running_db, char *db, +int clicon_rpc_commit(clicon_handle h, char *from, char *to, int snapshot, int startup); int clicon_rpc_validate(clicon_handle h, char *db); int clicon_rpc_change(clicon_handle h, char *db, diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c index 8a4373fd..251188e5 100644 --- a/lib/src/clixon_proto_client.c +++ b/lib/src/clixon_proto_client.c @@ -113,23 +113,23 @@ clicon_rpc_msg(clicon_handle h, /*! Commit changes send a commit request to backend daemon * @param[in] h CLICON handle - * @param[in] running_db Name of database - * @param[in] db Name of database + * @param[in] from name of 'from' database (eg "candidate") + * @param[in] db name of 'to' database (eg "running") * @param[in] snapshot Make a snapshot copy of db state * @param[in] startup Make a copy to startup. - * @retval 0 Copy current->candidate + * @retval 0 Copy current->candidate */ int clicon_rpc_commit(clicon_handle h, - char *running_db, - char *db, + char *from, + char *to, int snapshot, int startup) { int retval = -1; struct clicon_msg *msg; - if ((msg=clicon_msg_commit_encode(db, running_db, snapshot, startup, + if ((msg=clicon_msg_commit_encode(from, to, snapshot, startup, __FUNCTION__)) == NULL) goto done; if (clicon_rpc_msg(h, msg, NULL, NULL, NULL, __FUNCTION__) < 0) diff --git a/test/lib.sh b/test/lib.sh index 8948dee8..8a1a8129 100755 --- a/test/lib.sh +++ b/test/lib.sh @@ -3,7 +3,7 @@ testnr=0 testnname= clixon_cf=/usr/local/etc/routing.conf -# error and exit +# error and exit, arg is optional extra errmsg err(){ echo "Error in Test$testnr [$testname] $1" exit $testnr @@ -18,14 +18,23 @@ new(){ } # clicon_cli tester. First arg is command and second is expected outcome -clifn(){ +expectfn(){ + cmd=$1 expect=$2 ret=`$cmd` if [ $? -ne 0 ]; then err fi - if [ "$ret" != "$expect" ]; then + # Match if both are empty string + if [ -z "$ret" -a -z "$expect" ]; then + return + fi + match=`echo "$ret" | grep -Eo "$expect"` +# echo "ret:$ret" +# echo "expect:$expect" +# echo "match:$match" + if [ -z "$match" ]; then err "\nExpected:\t\"$expect\"\nGot:\t\"$ret\"" fi } diff --git a/test/test1.sh b/test/test1.sh index 67d7d66d..9143732b 100755 --- a/test/test1.sh +++ b/test/test1.sh @@ -1,4 +1,11 @@ #!/bin/sh +# Test1: backend and cli basic functionality +# Start backend server +# Add an ethernet interface and an address +# Show configuration +# Validate without a mandatory type +# Set the mandatory type +# Commit # include err() and new() functions . ./lib.sh @@ -6,27 +13,41 @@ # kill old backend (if any) new "kill old backend" sudo clixon_backend -zf $clixon_cf - if [ $? -ne 0 ]; then err fi new "start backend" # start new backend -sudo clixon_backend -If $clixon_cf -x 0 +sudo clixon_backend -If $clixon_cf -x 0 # -x 1 with xmldb proxy if [ $? -ne 0 ]; then err fi new "cli configure" -clifn "clixon_cli -1f $clixon_cf set interfaces interface eth0" "" +expectfn "clixon_cli -1f $clixon_cf set interfaces interface eth0" "" new "cli show configuration" -clifn "clixon_cli -1f $clixon_cf show conf cli" "interfaces interface name eth0 -interfaces interface enabled true" +expectfn "clixon_cli -1f $clixon_cf show conf cli" "^interfaces interface name eth0 +interfaces interface enabled true$" + +new "cli failed validate" +expectfn "clixon_cli -1f $clixon_cf -l o validate" "Validate failed" + +new "cli configure more" +expectfn "clixon_cli -1f $clixon_cf set interfaces interface eth0 ipv4 address 1.2.3.4 prefix-length 24" "" +expectfn "clixon_cli -1f $clixon_cf set interfaces interface eth0 type bgp" "" + +new "cli commit" +expectfn "clixon_cli -1f $clixon_cf -l o commit" "" new "Kill backend" +# Check if still alive +pid=`pgrep clixon_backend` +if [ -z "$pid" ]; then + err "backend already dead" +fi # kill backend sudo clixon_backend -zf $clixon_cf if [ $? -ne 0 ]; then - err + err "kill backend" fi