This commit is contained in:
Olof hagsand 2019-04-14 14:43:20 +02:00
commit 71da2ac6cb
30 changed files with 809 additions and 1103 deletions

View file

@ -42,9 +42,17 @@
* All references to plugin "text.so" should be removed. * All references to plugin "text.so" should be removed.
* The datastore directory is removed, code is moved to lib/src/clixon_datastore*.c * The datastore directory is removed, code is moved to lib/src/clixon_datastore*.c
* Removed clixon_backend -x <plugin> command-line options * Removed clixon_backend -x <plugin> command-line options
* Structural C-code change: Merged yang_spec and yang_node types into yang_stmt * Structural C-code change of yang statements:
* Change all yn_* and yp_ to ys_* * Merged yang_spec and yang_node types into yang_stmt
* Change all references to yang_node/yang_spec to yang_stmt * Change all references to types yang_node/yang_spec to yang_stmt
* Change all yang struct field accesses yn_* and yp_* to ys_* (but see next item for access functions).
* Added yang access functions
* Change all y->ys_parent to yang_parent_get(y)
* Change all y->ys_keyword to yang_keyword_get(y)
* Change all y->ys_argument to yang_argument_get(y)
* Change all y->ys_cv to yang_cv_get(y)
* Change all y->ys_cvec to yang_cvec_get(y)
* xmldb_get() removed unnecessary config option: * xmldb_get() removed unnecessary config option:
* Change all calls to dbget from: `xmldb_get(h, db, xpath, 0|1, &xret, msd)` to `xmldb_get(h, db, xpath, &xret, msd)` * Change all calls to dbget from: `xmldb_get(h, db, xpath, 0|1, &xret, msd)` to `xmldb_get(h, db, xpath, &xret, msd)`
@ -92,10 +100,15 @@
``` ```
### Minor changes ### Minor changes
* Optimized validation of large lists * Optimized validation of large lists
* New xmldb_get1() returning actual cache - not a copy. This has lead to some householding instead of just deleting the copy * New xmldb_get1() returning actual cache - not a copy. This has lead to some householding instead of just deleting the copy
* xml_diff rewritten to work linearly instead of O(2) * xml_diff rewritten to work linearly instead of O(2)
* New xml_insert function using tree search. The new code uses this in insertion xmldb_put and defaults. (Note previous xml_insert renamed to xml_wrap_all) * New xml_insert function using tree search. The new code uses this in insertion xmldb_put and defaults. (Note previous xml_insert renamed to xml_wrap_all)
* Experimental customized error output strings, see [lib/clixon/clixon_err_string.h]
* Empty leaf values, eg <a></a> are now checked at validation.
* Empty values were skipped in validation.
* They are now checked and invalid for ints, dec64, etc, but are treated as empty string "" for string types.
* Added syntactic check for yang status: current, deprecated or obsolete. * Added syntactic check for yang status: current, deprecated or obsolete.
* Added `xml_wrap` function that adds an XML node above a node as a wrapper * Added `xml_wrap` function that adds an XML node above a node as a wrapper
* also renamed `xml_insert` to `xml_wrap_all`. * also renamed `xml_insert` to `xml_wrap_all`.
@ -118,6 +131,9 @@
* Added libgen.h for baseline() * Added libgen.h for baseline()
### Corrected Bugs ### Corrected Bugs
* Backend plugin returning NULL was still installed - is now logged and skipped.
* [Parent list key is not validated if not provided via RESTCONF #83](https://github.com/clicon/clixon/issues/83), thanks achernavin22.
* [Invalid JSON if GET /operations via RESTCONF #82](https://github.com/clicon/clixon/issues/82), thanks achernavin22
* List ordering bug - lists with ints as keys behaved wrongly and slow. * List ordering bug - lists with ints as keys behaved wrongly and slow.
* NACM read default rule did not work properly if nacm was enabled AND no groups were defined * NACM read default rule did not work properly if nacm was enabled AND no groups were defined
* Re-inserted `cli_output_reset` for what was erroneuos thought to be an obsolete function * Re-inserted `cli_output_reset` for what was erroneuos thought to be an obsolete function

View file

@ -187,7 +187,7 @@ client_get_streams(clicon_handle h,
clicon_err(OE_UNIX, 0, "clicon buffer"); clicon_err(OE_UNIX, 0, "clicon buffer");
goto done; goto done;
} }
cprintf(cb,"<%s xmlns=\"%s\">", top, yns->ys_argument); cprintf(cb,"<%s xmlns=\"%s\">", top, yang_argument_get(yns));
if (stream_get_xml(h, strcmp(top,"restconf-state")==0, cb) < 0) if (stream_get_xml(h, strcmp(top,"restconf-state")==0, cb) < 0)
goto done; goto done;
cprintf(cb,"</%s>", top); cprintf(cb,"</%s>", top);
@ -1110,7 +1110,7 @@ from_client_msg(clicon_handle h,
clicon_err(OE_XML, ENOENT, "rpc yang does not have module"); clicon_err(OE_XML, ENOENT, "rpc yang does not have module");
goto done; goto done;
} }
module = ymod->ys_argument; module = yang_argument_get(ymod);
clicon_debug(1, "%s module:%s rpc:%s", __FUNCTION__, module, rpc); clicon_debug(1, "%s module:%s rpc:%s", __FUNCTION__, module, rpc);
/* Pre-NACM access step */ /* Pre-NACM access step */
xnacm = NULL; xnacm = NULL;

View file

@ -353,6 +353,10 @@ from_validate_common(clicon_handle h,
/* This is the state we are going to */ /* This is the state we are going to */
if (xmldb_get1(h, candidate, "/", &td->td_target, NULL) < 0) if (xmldb_get1(h, candidate, "/", &td->td_target, NULL) < 0)
goto done; goto done;
/* Clear flags xpath for get */
xml_apply0(td->td_target, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,
(void*)(XML_FLAG_MARK|XML_FLAG_CHANGE));
/* Validate the target state. It is not completely clear this should be done /* Validate the target state. It is not completely clear this should be done
* here. It is being made in generic_validate below. * here. It is being made in generic_validate below.
* But xml_diff requires some basic validation, at least check that yang-specs * But xml_diff requires some basic validation, at least check that yang-specs
@ -367,7 +371,9 @@ from_validate_common(clicon_handle h,
* This is the state we are going from */ * This is the state we are going from */
if (xmldb_get1(h, "running", "/", &td->td_src, NULL) < 0) if (xmldb_get1(h, "running", "/", &td->td_src, NULL) < 0)
goto done; goto done;
/* Clear flags xpath for get */
xml_apply0(td->td_src, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,
(void*)(XML_FLAG_MARK|XML_FLAG_CHANGE));
/* 3. Compute differences */ /* 3. Compute differences */
if (xml_diff(yspec, if (xml_diff(yspec,
td->td_src, td->td_src,

View file

@ -236,14 +236,14 @@ cli_dbxml(clicon_handle h,
if ((xtop = xml_new("config", NULL, NULL)) == NULL) if ((xtop = xml_new("config", NULL, NULL)) == NULL)
goto done; goto done;
xbot = xtop; xbot = xtop;
if (api_path && api_path2xml(api_path, yspec, xtop, YC_DATANODE, &xbot, &y) < 1) if (api_path && api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &y) < 1)
goto done; goto done;
if ((xa = xml_new("operation", xbot, NULL)) == NULL) if ((xa = xml_new("operation", xbot, NULL)) == NULL)
goto done; goto done;
xml_type_set(xa, CX_ATTR); xml_type_set(xa, CX_ATTR);
if (xml_value_set(xa, xml_operation2str(op)) < 0) if (xml_value_set(xa, xml_operation2str(op)) < 0)
goto done; goto done;
if (y->ys_keyword != Y_LIST && y->ys_keyword != Y_LEAF_LIST){ if (yang_keyword_get(y) != Y_LIST && yang_keyword_get(y) != Y_LEAF_LIST){
len = cvec_len(cvv); len = cvec_len(cvv);
if (len > 1){ if (len > 1){
cval = cvec_i(cvv, len-1); cval = cvec_i(cvv, len-1);

View file

@ -123,7 +123,7 @@ cli_expand_var_generate(clicon_handle h,
if (yang2api_path_fmt(ys, 1, &api_path_fmt) < 0) if (yang2api_path_fmt(ys, 1, &api_path_fmt) < 0)
goto done; goto done;
cprintf(cb, "|<%s:%s", ys->ys_argument, cprintf(cb, "|<%s:%s", yang_argument_get(ys),
cv_type2str(cvtype)); cv_type2str(cvtype));
if (options & YANG_OPTIONS_FRACTION_DIGITS) if (options & YANG_OPTIONS_FRACTION_DIGITS)
cprintf(cb, " fraction-digits:%u", fraction_digits); cprintf(cb, " fraction-digits:%u", fraction_digits);
@ -191,11 +191,11 @@ yang2cli_var_identityref(yang_stmt *ys,
if (helptext) if (helptext)
cprintf(cb, "(\"%s\")", helptext); cprintf(cb, "(\"%s\")", helptext);
if ((ybaseref = yang_find(ytype, Y_BASE, NULL)) != NULL && if ((ybaseref = yang_find(ytype, Y_BASE, NULL)) != NULL &&
(ybaseid = yang_find_identity(ys, ybaseref->ys_argument)) != NULL){ (ybaseid = yang_find_identity(ys, yang_argument_get(ybaseref))) != NULL){
if (cvec_len(ybaseid->ys_cvec) > 0){ if (cvec_len(yang_cvec_get(ybaseid)) > 0){
cprintf(cb, "|<%s:%s choice:", ys->ys_argument, cvtypestr); cprintf(cb, "|<%s:%s choice:", yang_argument_get(ys), cvtypestr);
i = 0; i = 0;
while ((cv = cvec_each(ybaseid->ys_cvec, cv)) != NULL){ while ((cv = cvec_each(yang_cvec_get(ybaseid), cv)) != NULL){
if (i++) if (i++)
cprintf(cb, "|"); cprintf(cb, "|");
name = strdup(cv_name_get(cv)); name = strdup(cv_name_get(cv));
@ -317,12 +317,12 @@ yang2cli_var_sub(clicon_handle h,
retval = 0; retval = 0;
goto done; goto done;
} }
type = ytype?ytype->ys_argument:NULL; type = ytype?yang_argument_get(ytype):NULL;
cvtypestr = cv_type2str(cvtype); cvtypestr = cv_type2str(cvtype);
if (type && strcmp(type, "identityref") == 0) if (type && strcmp(type, "identityref") == 0)
cprintf(cb, "("); cprintf(cb, "(");
cprintf(cb, "<%s:%s", ys->ys_argument, cvtypestr); cprintf(cb, "<%s:%s", yang_argument_get(ys), cvtypestr);
/* enumeration special case completion */ /* enumeration special case completion */
if (type){ if (type){
if (strcmp(type, "enumeration") == 0 || strcmp(type, "bits") == 0){ if (strcmp(type, "enumeration") == 0 || strcmp(type, "bits") == 0){
@ -330,11 +330,11 @@ yang2cli_var_sub(clicon_handle h,
i = 0; i = 0;
yi = NULL; yi = NULL;
while ((yi = yn_each(ytype, yi)) != NULL){ while ((yi = yn_each(ytype, yi)) != NULL){
if (yi->ys_keyword != Y_ENUM && yi->ys_keyword != Y_BIT) if (yang_keyword_get(yi) != Y_ENUM && yang_keyword_get(yi) != Y_BIT)
continue; continue;
if (i) if (i)
cprintf(cb, "|"); cprintf(cb, "|");
cprintf(cb, "%s", yi->ys_argument); cprintf(cb, "%s", yang_argument_get(yi));
i++; i++;
} }
} }
@ -399,7 +399,7 @@ yang2cli_var_union_one(clicon_handle h,
&ytype, &options, /* resolved type */ &ytype, &options, /* resolved type */
&cvv, &pattern, &fraction_digits) < 0) &cvv, &pattern, &fraction_digits) < 0)
goto done; goto done;
restype = ytype?ytype->ys_argument:NULL; restype = ytype?yang_argument_get(ytype):NULL;
if (restype && strcmp(restype, "union") == 0){ /* recursive union */ if (restype && strcmp(restype, "union") == 0){ /* recursive union */
if (yang2cli_var_union(h, ys, origtype, ytype, helptext, cb) < 0) if (yang2cli_var_union(h, ys, origtype, ytype, helptext, cb) < 0)
@ -444,7 +444,7 @@ yang2cli_var_union(clicon_handle h,
* made in the union_one call. * made in the union_one call.
*/ */
while ((ytsub = yn_each(ytype, ytsub)) != NULL){ while ((ytsub = yn_each(ytype, ytsub)) != NULL){
if (ytsub->ys_keyword != Y_TYPE) if (yang_keyword_get(ytsub) != Y_TYPE)
continue; continue;
if (i++) if (i++)
cprintf(cb, "|"); cprintf(cb, "|");
@ -490,7 +490,7 @@ yang2cli_var(clicon_handle h,
if (yang_type_get(ys, &origtype, &yrestype, if (yang_type_get(ys, &origtype, &yrestype,
&options, &cvv, &pattern, &fraction_digits) < 0) &options, &cvv, &pattern, &fraction_digits) < 0)
goto done; goto done;
restype = yrestype?yrestype->ys_argument:NULL; restype = yrestype?yang_argument_get(yrestype):NULL;
if (restype && strcmp(restype, "empty") == 0){ if (restype && strcmp(restype, "empty") == 0){
retval = 0; retval = 0;
@ -514,7 +514,7 @@ yang2cli_var(clicon_handle h,
cprintf(cb, ")"); cprintf(cb, ")");
} }
else{ else{
type = yrestype?yrestype->ys_argument:NULL; type = yrestype?yang_argument_get(yrestype):NULL;
if (type) if (type)
completionp = clicon_cli_genmodel_completion(h) && completionp = clicon_cli_genmodel_completion(h) &&
strcmp(type, "enumeration") != 0 && strcmp(type, "enumeration") != 0 &&
@ -564,7 +564,7 @@ yang2cli_leaf(clicon_handle h,
/* description */ /* description */
if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){ if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){
if ((helptext = strdup(yd->ys_argument)) == NULL){ if ((helptext = strdup(yang_argument_get(yd))) == NULL){
clicon_err(OE_UNIX, errno, "strdup"); clicon_err(OE_UNIX, errno, "strdup");
goto done; goto done;
} }
@ -573,7 +573,7 @@ yang2cli_leaf(clicon_handle h,
} }
cprintf(cb, "%*s", level*3, ""); cprintf(cb, "%*s", level*3, "");
if (gt == GT_VARS|| gt == GT_ALL){ if (gt == GT_VARS|| gt == GT_ALL){
cprintf(cb, "%s", ys->ys_argument); cprintf(cb, "%s", yang_argument_get(ys));
if (helptext) if (helptext)
cprintf(cb, "(\"%s\")", helptext); cprintf(cb, "(\"%s\")", helptext);
cprintf(cb, " "); cprintf(cb, " ");
@ -612,14 +612,13 @@ yang2cli_container(clicon_handle h,
{ {
yang_stmt *yc; yang_stmt *yc;
yang_stmt *yd; yang_stmt *yd;
int i;
int retval = -1; int retval = -1;
char *helptext = NULL; char *helptext = NULL;
char *s; char *s;
cprintf(cb, "%*s%s", level*3, "", ys->ys_argument); cprintf(cb, "%*s%s", level*3, "", yang_argument_get(ys));
if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){ if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){
if ((helptext = strdup(yd->ys_argument)) == NULL){ if ((helptext = strdup(yang_argument_get(yd))) == NULL){
clicon_err(OE_UNIX, errno, "strdup"); clicon_err(OE_UNIX, errno, "strdup");
goto done; goto done;
} }
@ -630,8 +629,9 @@ yang2cli_container(clicon_handle h,
if (cli_callback_generate(h, ys, cb) < 0) if (cli_callback_generate(h, ys, cb) < 0)
goto done; goto done;
cprintf(cb, ";{\n"); cprintf(cb, ";{\n");
for (i=0; i<ys->ys_len; i++)
if ((yc = ys->ys_stmt[i]) != NULL) yc = NULL;
while ((yc = yn_each(ys, yc)) != NULL)
if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0) if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0)
goto done; goto done;
cprintf(cb, "%*s}\n", level*3, ""); cprintf(cb, "%*s}\n", level*3, "");
@ -659,7 +659,6 @@ yang2cli_list(clicon_handle h,
yang_stmt *yc; yang_stmt *yc;
yang_stmt *yd; yang_stmt *yd;
yang_stmt *yleaf; yang_stmt *yleaf;
int i;
cg_var *cvi; cg_var *cvi;
char *keyname; char *keyname;
cvec *cvk = NULL; /* vector of index keys */ cvec *cvk = NULL; /* vector of index keys */
@ -667,9 +666,9 @@ yang2cli_list(clicon_handle h,
char *helptext = NULL; char *helptext = NULL;
char *s; char *s;
cprintf(cb, "%*s%s", level*3, "", ys->ys_argument); cprintf(cb, "%*s%s", level*3, "", yang_argument_get(ys));
if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){ if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){
if ((helptext = strdup(yd->ys_argument)) == NULL){ if ((helptext = strdup(yang_argument_get(yd))) == NULL){
clicon_err(OE_UNIX, errno, "strdup"); clicon_err(OE_UNIX, errno, "strdup");
goto done; goto done;
} }
@ -678,14 +677,14 @@ yang2cli_list(clicon_handle h,
cprintf(cb, "(\"%s\")", helptext); cprintf(cb, "(\"%s\")", helptext);
} }
/* Loop over all key variables */ /* Loop over all key variables */
cvk = ys->ys_cvec; /* Use Y_LIST cache, see ys_populate_list() */ cvk = yang_cvec_get(ys); /* Use Y_LIST cache, see ys_populate_list() */
cvi = NULL; cvi = NULL;
/* Iterate over individual keys */ /* Iterate over individual keys */
while ((cvi = cvec_each(cvk, cvi)) != NULL) { while ((cvi = cvec_each(cvk, cvi)) != NULL) {
keyname = cv_string_get(cvi); keyname = cv_string_get(cvi);
if ((yleaf = yang_find(ys, Y_LEAF, keyname)) == NULL){ if ((yleaf = yang_find(ys, Y_LEAF, keyname)) == NULL){
clicon_err(OE_XML, 0, "List statement \"%s\" has no key leaf \"%s\"", clicon_err(OE_XML, 0, "List statement \"%s\" has no key leaf \"%s\"",
ys->ys_argument, keyname); yang_argument_get(ys), keyname);
goto done; goto done;
} }
/* Print key variable now, and skip it in loop below /* Print key variable now, and skip it in loop below
@ -697,15 +696,15 @@ yang2cli_list(clicon_handle h,
} }
cprintf(cb, "{\n"); cprintf(cb, "{\n");
for (i=0; i<ys->ys_len; i++) yc = NULL;
if ((yc = ys->ys_stmt[i]) != NULL){ while ((yc = yn_each(ys, yc)) != NULL) {
/* cvk is a cvec of strings containing variable names /* cvk is a cvec of strings containing variable names
yc is a leaf that may match one of the values of cvk. yc is a leaf that may match one of the values of cvk.
*/ */
cvi = NULL; cvi = NULL;
while ((cvi = cvec_each(cvk, cvi)) != NULL) { while ((cvi = cvec_each(cvk, cvi)) != NULL) {
keyname = cv_string_get(cvi); keyname = cv_string_get(cvi);
if (strcmp(keyname, yc->ys_argument) == 0) if (strcmp(keyname, yang_argument_get(yc)) == 0)
break; break;
} }
if (cvi != NULL) if (cvi != NULL)
@ -746,11 +745,10 @@ yang2cli_choice(clicon_handle h,
{ {
int retval = -1; int retval = -1;
yang_stmt *yc; yang_stmt *yc;
int i;
for (i=0; i<ys->ys_len; i++) yc = NULL;
if ((yc = ys->ys_stmt[i]) != NULL){ while ((yc = yn_each(ys, yc)) != NULL) {
switch (yc->ys_keyword){ switch (yang_keyword_get(yc)){
case Y_CASE: case Y_CASE:
if (yang2cli_stmt(h, yc, gt, level+2, cb) < 0) if (yang2cli_stmt(h, yc, gt, level+2, cb) < 0)
goto done; goto done;
@ -786,10 +784,9 @@ yang2cli_stmt(clicon_handle h,
{ {
yang_stmt *yc; yang_stmt *yc;
int retval = -1; int retval = -1;
int i;
if (yang_config(ys)){ if (yang_config(ys)){
switch (ys->ys_keyword){ switch (yang_keyword_get(ys)){
case Y_CONTAINER: case Y_CONTAINER:
if (yang2cli_container(h, ys, gt, level, cb) < 0) if (yang2cli_container(h, ys, gt, level, cb) < 0)
goto done; goto done;
@ -810,8 +807,8 @@ yang2cli_stmt(clicon_handle h,
case Y_CASE: case Y_CASE:
case Y_SUBMODULE: case Y_SUBMODULE:
case Y_MODULE: case Y_MODULE:
for (i=0; i<ys->ys_len; i++) yc = NULL;
if ((yc = ys->ys_stmt[i]) != NULL) while ((yc = yn_each(ys, yc)) != NULL)
if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0) if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0)
goto done; goto done;
break; break;
@ -841,7 +838,6 @@ yang2cli(clicon_handle h,
enum genmodel_type gt) enum genmodel_type gt)
{ {
cbuf *cb = NULL; cbuf *cb = NULL;
int i;
int retval = -1; int retval = -1;
yang_stmt *ymod = NULL; yang_stmt *ymod = NULL;
cvec *globals; /* global variables from syntax */ cvec *globals; /* global variables from syntax */
@ -851,11 +847,10 @@ yang2cli(clicon_handle h,
goto done; goto done;
} }
/* Traverse YANG, loop through all modules and generate CLI */ /* Traverse YANG, loop through all modules and generate CLI */
for (i=0; i<yspec->ys_len; i++) ymod = NULL;
if ((ymod = yspec->ys_stmt[i]) != NULL){ while ((ymod = yn_each(yspec, ymod)) != NULL)
if (yang2cli_stmt(h, ymod, gt, 0, cb) < 0) if (yang2cli_stmt(h, ymod, gt, 0, cb) < 0)
goto done; goto done;
}
clicon_debug(2, "%s: buf\n%s\n", __FUNCTION__, cbuf_get(cb)); clicon_debug(2, "%s: buf\n%s\n", __FUNCTION__, cbuf_get(cb));
/* Parse the buffer using cligen parser. XXX why this?*/ /* Parse the buffer using cligen parser. XXX why this?*/
if ((globals = cvec_new(0)) == NULL) if ((globals = cvec_new(0)) == NULL)

View file

@ -84,7 +84,6 @@
* @param[in] name Name of this function (eg "expand_dbvar") * @param[in] name Name of this function (eg "expand_dbvar")
* @param[in] cvv The command so far. Eg: cvec [0]:"a 5 b"; [1]: x=5; * @param[in] cvv The command so far. Eg: cvec [0]:"a 5 b"; [1]: x=5;
* @param[in] argv Arguments given at the callback ("<db>" "<xmlkeyfmt>") * @param[in] argv Arguments given at the callback ("<db>" "<xmlkeyfmt>")
* @param[out] len len of return commands & helptxt
* @param[out] commands vector of function pointers to callback functions * @param[out] commands vector of function pointers to callback functions
* @param[out] helptxt vector of pointers to helptexts * @param[out] helptxt vector of pointers to helptexts
* @see cli_expand_var_generate This is where arg is generated * @see cli_expand_var_generate This is where arg is generated
@ -171,7 +170,7 @@ expand_dbvar(void *h,
/* This is primarily to get "y", /* This is primarily to get "y",
* xpath2xml would have worked!! * xpath2xml would have worked!!
*/ */
if (api_path && api_path2xml(api_path, yspec, xtop, YC_DATANODE, &xbot, &y) < 1) if (api_path && api_path2xml(api_path, yspec, xtop, YC_DATANODE, 0, &xbot, &y) < 1)
goto done; goto done;
if (y==NULL) if (y==NULL)
goto ok; goto ok;
@ -184,12 +183,12 @@ expand_dbvar(void *h,
* such operations to the datastore by a generic xpath function. * such operations to the datastore by a generic xpath function.
*/ */
if ((ytype = yang_find(y, Y_TYPE, NULL)) != NULL) if ((ytype = yang_find(y, Y_TYPE, NULL)) != NULL)
if (strcmp(ytype->ys_argument, "leafref")==0){ if (strcmp(yang_argument_get(ytype), "leafref")==0){
if ((ypath = yang_find(ytype, Y_PATH, NULL)) == NULL){ if ((ypath = yang_find(ytype, Y_PATH, NULL)) == NULL){
clicon_err(OE_DB, 0, "Leafref %s requires path statement", ytype->ys_argument); clicon_err(OE_DB, 0, "Leafref %s requires path statement", yang_argument_get(ytype));
goto done; goto done;
} }
xpathcur = ypath->ys_argument; xpathcur = yang_argument_get(ypath);
if (xml_merge(xt, xtop, yspec, &reason) < 0) /* Merge xtop into xt */ if (xml_merge(xt, xtop, yspec, &reason) < 0) /* Merge xtop into xt */
goto done; goto done;
if (reason){ if (reason){

View file

@ -469,7 +469,7 @@ api_data_post(clicon_handle h,
/* Translate api_path to xtop/xbot */ /* Translate api_path to xtop/xbot */
xbot = xtop; xbot = xtop;
if (api_path){ if (api_path){
if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, &xbot, &y)) < 0) if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &y)) < 0)
goto done; goto done;
if (ret == 0){ /* validation failed */ if (ret == 0){ /* validation failed */
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0) if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
@ -642,9 +642,9 @@ match_list_keys(yang_stmt *y,
char *keya; char *keya;
char *keyd; char *keyd;
if (y->ys_keyword != Y_LIST &&y->ys_keyword != Y_LEAF_LIST) if (yang_keyword_get(y) != Y_LIST && yang_keyword_get(y) != Y_LEAF_LIST)
goto done; goto done;
cvk = y->ys_cvec; /* Use Y_LIST cache, see ys_populate_list() */ cvk = yang_cvec_get(y); /* Use Y_LIST cache, see ys_populate_list() */
cvi = NULL; cvi = NULL;
while ((cvi = cvec_each(cvk, cvi)) != NULL) { while ((cvi = cvec_each(cvk, cvi)) != NULL) {
keyname = cv_string_get(cvi); keyname = cv_string_get(cvi);
@ -738,7 +738,7 @@ api_data_put(clicon_handle h,
/* Translate api_path to xtop/xbot */ /* Translate api_path to xtop/xbot */
xbot = xtop; xbot = xtop;
if (api_path){ if (api_path){
if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, &xbot, &y)) < 0) if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &y)) < 0)
goto done; goto done;
if (ret == 0){ /* validation failed */ if (ret == 0){ /* validation failed */
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0) if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
@ -847,7 +847,7 @@ api_data_put(clicon_handle h,
goto ok; goto ok;
} }
/* If list or leaf-list, api-path keys must match data keys */ /* If list or leaf-list, api-path keys must match data keys */
if (y && (y->ys_keyword == Y_LIST ||y->ys_keyword == Y_LEAF_LIST)){ if (y && (yang_keyword_get(y) == Y_LIST || yang_keyword_get(y) == Y_LEAF_LIST)){
if (match_list_keys((yang_stmt*)y, x, xbot) < 0){ if (match_list_keys((yang_stmt*)y, x, xbot) < 0){
if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0) if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0)
goto done; goto done;
@ -1011,7 +1011,7 @@ api_data_delete(clicon_handle h,
goto done; goto done;
xbot = xtop; xbot = xtop;
if (api_path){ if (api_path){
if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, &xbot, &y)) < 0) if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &y)) < 0)
goto done; goto done;
if (ret == 0){ /* validation failed */ if (ret == 0){ /* validation failed */
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0) if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
@ -1150,21 +1150,21 @@ api_operations_get(clicon_handle h,
namespace = yang_find_mynamespace(ymod); namespace = yang_find_mynamespace(ymod);
yc = NULL; yc = NULL;
while ((yc = yn_each(ymod, yc)) != NULL) { while ((yc = yn_each(ymod, yc)) != NULL) {
if (yc->ys_keyword != Y_RPC) if (yang_keyword_get(yc) != Y_RPC)
continue; continue;
if (use_xml) if (use_xml)
cprintf(cbx, "<%s xmlns=\"%s\"/>", yc->ys_argument, namespace); cprintf(cbx, "<%s xmlns=\"%s\"/>", yang_argument_get(yc), namespace);
else{ else{
if (i++) if (i++)
cprintf(cbx, ","); cprintf(cbx, ",");
cprintf(cbx, "\"%s:%s\": null", ymod->ys_argument, yc->ys_argument); cprintf(cbx, "\"%s:%s\": null", yang_argument_get(ymod), yang_argument_get(yc));
} }
} }
} }
if (use_xml) if (use_xml)
cprintf(cbx, "</operations>"); cprintf(cbx, "</operations>");
else else
cprintf(cbx, "}"); cprintf(cbx, "}}");
FCGX_SetExitStatus(200, r->out); /* OK */ FCGX_SetExitStatus(200, r->out); /* OK */
FCGX_FPrintF(r->out, "Content-Type: application/yang-data+%s\r\n", use_xml?"xml":"json"); FCGX_FPrintF(r->out, "Content-Type: application/yang-data+%s\r\n", use_xml?"xml":"json");
FCGX_FPrintF(r->out, "\r\n"); FCGX_FPrintF(r->out, "\r\n");
@ -1598,7 +1598,7 @@ api_operations_post(clicon_handle h,
goto done; goto done;
/* Here xtop is: <rpc username="foo"/> */ /* Here xtop is: <rpc username="foo"/> */
} }
if ((ret = api_path2xml(oppath, yspec, xtop, YC_SCHEMANODE, &xbot, &y)) < 0) if ((ret = api_path2xml(oppath, yspec, xtop, YC_SCHEMANODE, 1, &xbot, &y)) < 0)
goto done; goto done;
if (ret == 0){ /* validation failed */ if (ret == 0){ /* validation failed */
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0) if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)

View file

@ -300,7 +300,7 @@ upgrade_2016(clicon_handle h,
yspec = clicon_dbspec_yang(h); yspec = clicon_dbspec_yang(h);
if ((ym = yang_find_module_by_namespace(yspec, ns)) == NULL) if ((ym = yang_find_module_by_namespace(yspec, ns)) == NULL)
goto ok; /* shouldnt happen */ goto ok; /* shouldnt happen */
clicon_debug(1, "%s module %s", __FUNCTION__, ym?ym->ys_argument:"none"); clicon_debug(1, "%s module %s", __FUNCTION__, ym?yang_argument_get(ym):"none");
/* Get all XML nodes with that namespace */ /* Get all XML nodes with that namespace */
if (xml_namespace_vec(h, xt, ns, &vec, &vlen) < 0) if (xml_namespace_vec(h, xt, ns, &vec, &vlen) < 0)
goto done; goto done;
@ -398,7 +398,7 @@ upgrade_2018(clicon_handle h,
yspec = clicon_dbspec_yang(h); yspec = clicon_dbspec_yang(h);
if ((ym = yang_find_module_by_namespace(yspec, ns)) == NULL) if ((ym = yang_find_module_by_namespace(yspec, ns)) == NULL)
goto ok; /* shouldnt happen */ goto ok; /* shouldnt happen */
clicon_debug(1, "%s module %s", __FUNCTION__, ym?ym->ys_argument:"none"); clicon_debug(1, "%s module %s", __FUNCTION__, ym?yang_argument_get(ym):"none");
/* Get all XML nodes with that namespace */ /* Get all XML nodes with that namespace */
if (xml_namespace_vec(h, xt, ns, &vec, &vlen) < 0) if (xml_namespace_vec(h, xt, ns, &vec, &vlen) < 0)
goto done; goto done;

View file

@ -0,0 +1,48 @@
/*
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
This file is part of CLIXON.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 3 or later (the "GPL"),
in which case the provisions of the GPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of the GPL, and not to allow others to
use your version of this file under the terms of Apache License version 2,
indicate your decision by deleting the provisions above and replace them with
the notice and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the Apache License version 2 or the GPL.
***** END LICENSE BLOCK *****
* First effort in customizing error output strings.
* Here just very simple constants that can be edited and recompiled by
* an integrator.
*/
#ifndef _CLIXON_ERR_STRING_H_
#define _CLIXON_ERR_STRING_H_
/* If internal netconf validation operation failed in the backend */
#define CLIXON_ERRSTR_VALIDATE_FAILED "Validate failed. Edit and try again or discard changes"
/* If internal netconf commit operation failed in the backend */
#define CLIXON_ERRSTR_COMMIT_FAILED "Commit failed. Edit and try again or discard changes"
#endif /* _CLIXON_ERR_STRING_H_ */

View file

@ -68,7 +68,7 @@ int xml_spec_populate_rpc(clicon_handle h, cxobj *x, yang_stmt *yspec);
int xml_spec_populate(cxobj *x, void *arg); int xml_spec_populate(cxobj *x, void *arg);
int api_path2xpath(yang_stmt *yspec, cvec *cvv, int offset, cbuf *xpath); int api_path2xpath(yang_stmt *yspec, cvec *cvv, int offset, cbuf *xpath);
int api_path2xml(char *api_path, yang_stmt *yspec, cxobj *xtop, int api_path2xml(char *api_path, yang_stmt *yspec, cxobj *xtop,
yang_class nodeclass, cxobj **xpathp, yang_stmt **ypathp); yang_class nodeclass, int strict, cxobj **xpathp, yang_stmt **ypathp);
int xml_merge(cxobj *x0, cxobj *x1, yang_stmt *yspec, char **reason); int xml_merge(cxobj *x0, cxobj *x1, yang_stmt *yspec, char **reason);
int yang_enum_int_value(cxobj *node, int32_t *val); int yang_enum_int_value(cxobj *node, int32_t *val);

View file

@ -169,7 +169,7 @@ typedef enum yang_class yang_class;
#define yang_schemanode(y) (yang_datanode(y) || (y)->ys_keyword == Y_RPC || (y)->ys_keyword == Y_CHOICE || (y)->ys_keyword == Y_CASE || (y)->ys_keyword == Y_INPUT || (y)->ys_keyword == Y_OUTPUT || (y)->ys_keyword == Y_NOTIFICATION) #define yang_schemanode(y) (yang_datanode(y) || (y)->ys_keyword == Y_RPC || (y)->ys_keyword == Y_CHOICE || (y)->ys_keyword == Y_CASE || (y)->ys_keyword == Y_INPUT || (y)->ys_keyword == Y_OUTPUT || (y)->ys_keyword == Y_NOTIFICATION)
typedef struct yang_stmt yang_stmt; /* forward */ typedef struct yang_stmt yang_stmt; /* Defined in clixon_yang_internal */
/*! Yang type cache. Yang type statements can cache all typedef info here /*! Yang type cache. Yang type statements can cache all typedef info here
* @note unions not cached * @note unions not cached
@ -189,6 +189,7 @@ typedef struct yang_type_cache yang_type_cache;
/*! yang statement /*! yang statement
*/ */
struct yang_stmt{ struct yang_stmt{
int ys_len; /* Number of children */ int ys_len; /* Number of children */
struct yang_stmt **ys_stmt; /* Vector of children statement pointers */ struct yang_stmt **ys_stmt; /* Vector of children statement pointers */
@ -197,7 +198,6 @@ struct yang_stmt{
char *ys_argument; /* String / argument depending on keyword */ char *ys_argument; /* String / argument depending on keyword */
int ys_flags; /* Flags according to YANG_FLAG_* above */ int ys_flags; /* Flags according to YANG_FLAG_* above */
/*--------------here common for all -------*/
yang_stmt *ys_module; /* Shortcut to "my" module. Augmented yang_stmt *ys_module; /* Shortcut to "my" module. Augmented
nodes can belong to other nodes can belong to other
modules than the ancestor module */ modules than the ancestor module */
@ -218,31 +218,22 @@ struct yang_stmt{
Y_TYPE & identity: store all derived types Y_TYPE & identity: store all derived types
*/ */
yang_type_cache *ys_typecache; /* If ys_keyword==Y_TYPE, cache all typedef data except unions */ yang_type_cache *ys_typecache; /* If ys_keyword==Y_TYPE, cache all typedef data except unions */
int _ys_vector_i; /* internal use: yn_each */
}; };
#if 0 /* Backward compatible */
typedef struct yang_stmt yang_node;
typedef struct yang_stmt yang_spec;
#define yn_len ys_len
#define yn_stmt ys_stmt
#define yn_parent ys_parent
#define yn_keyword ys_keyword
#define yn_argument ys_argument
#define yn_flags ys_flags
#define yp_len ys_len
#define yp_stmt ys_stmt
#define yp_parent ys_parent
#define yp_keyword ys_keyword
#define yp_argument ys_argument
#define yp_flags ys_flags
#endif
typedef int (yang_applyfn_t)(yang_stmt *ys, void *arg); typedef int (yang_applyfn_t)(yang_stmt *ys, void *arg);
/* /*
* Prototypes * Prototypes
*/ */
/* Access functions */
yang_stmt *yang_parent_get(yang_stmt *ys);
enum rfc_6020 yang_keyword_get(yang_stmt *ys);
char *yang_argument_get(yang_stmt *ys);
cg_var *yang_cv_get(yang_stmt *ys);
cvec *yang_cvec_get(yang_stmt *ys);
/* Other functions */
yang_stmt *yspec_new(void); yang_stmt *yspec_new(void);
yang_stmt *ys_new(enum rfc_6020 keyw); yang_stmt *ys_new(enum rfc_6020 keyw);
int ys_free(yang_stmt *ys); int ys_free(yang_stmt *ys);

View file

@ -124,9 +124,12 @@ clean:
lex.clixon_xml_parse.c : clixon_xml_parse.l clixon_xml_parse.tab.h lex.clixon_xml_parse.c : clixon_xml_parse.l clixon_xml_parse.tab.h
$(LEX) -Pclixon_xml_parse clixon_xml_parse.l # -d is debug $(LEX) -Pclixon_xml_parse clixon_xml_parse.l # -d is debug
clixon_xml_parse.tab.c clixon_xml_parse.tab.h: clixon_xml_parse.y clixon_xml_parse.tab.h: clixon_xml_parse.y
$(YACC) -l -d -b clixon_xml_parse -p clixon_xml_parse clixon_xml_parse.y # -t is debug $(YACC) -l -d -b clixon_xml_parse -p clixon_xml_parse clixon_xml_parse.y # -t is debug
# extra rule to avoid parallell yaccs
clixon_xml_parse.tab.c: clixon_xml_parse.tab.h
lex.clixon_xml_parse.o : lex.clixon_xml_parse.c clixon_xml_parse.tab.h # special rule to for make clean to work lex.clixon_xml_parse.o : lex.clixon_xml_parse.c clixon_xml_parse.tab.h # special rule to for make clean to work
$(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -Wno-error -c $< $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -Wno-error -c $<
@ -134,9 +137,12 @@ lex.clixon_xml_parse.o : lex.clixon_xml_parse.c clixon_xml_parse.tab.h # special
lex.clixon_yang_parse.c : clixon_yang_parse.l clixon_yang_parse.tab.h lex.clixon_yang_parse.c : clixon_yang_parse.l clixon_yang_parse.tab.h
$(LEX) -Pclixon_yang_parse clixon_yang_parse.l # -d is debug $(LEX) -Pclixon_yang_parse clixon_yang_parse.l # -d is debug
clixon_yang_parse.tab.c clixon_yang_parse.tab.h: clixon_yang_parse.y clixon_yang_parse.tab.h: clixon_yang_parse.y
$(YACC) -l -d -b clixon_yang_parse -p clixon_yang_parse clixon_yang_parse.y # -t is debug $(YACC) -l -d -b clixon_yang_parse -p clixon_yang_parse clixon_yang_parse.y # -t is debug
# extra rule to avoid parallell yaccs
clixon_yang_parse.tab.c: clixon_yang_parse.tab.h
lex.clixon_yang_parse.o : lex.clixon_yang_parse.c clixon_yang_parse.tab.h lex.clixon_yang_parse.o : lex.clixon_yang_parse.c clixon_yang_parse.tab.h
$(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -Wno-error -c $< $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -Wno-error -c $<
@ -144,9 +150,12 @@ lex.clixon_yang_parse.o : lex.clixon_yang_parse.c clixon_yang_parse.tab.h
lex.clixon_json_parse.c : clixon_json_parse.l clixon_json_parse.tab.h lex.clixon_json_parse.c : clixon_json_parse.l clixon_json_parse.tab.h
$(LEX) -Pclixon_json_parse clixon_json_parse.l # -d is debug $(LEX) -Pclixon_json_parse clixon_json_parse.l # -d is debug
clixon_json_parse.tab.c clixon_json_parse.tab.h: clixon_json_parse.y clixon_json_parse.tab.h: clixon_json_parse.y
$(YACC) -l -d -b clixon_json_parse -p clixon_json_parse clixon_json_parse.y # -t is debug $(YACC) -l -d -b clixon_json_parse -p clixon_json_parse clixon_json_parse.y # -t is debug
# extra rule to avoid parallell yaccs
clixon_json_parse.tab.c: clixon_json_parse.tab.h
lex.clixon_json_parse.o : lex.clixon_json_parse.c clixon_json_parse.tab.h lex.clixon_json_parse.o : lex.clixon_json_parse.c clixon_json_parse.tab.h
$(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -Wno-error -c $< $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -Wno-error -c $<
@ -154,9 +163,12 @@ lex.clixon_json_parse.o : lex.clixon_json_parse.c clixon_json_parse.tab.h
lex.clixon_xpath_parse.c : clixon_xpath_parse.l clixon_xpath_parse.tab.h lex.clixon_xpath_parse.c : clixon_xpath_parse.l clixon_xpath_parse.tab.h
$(LEX) -Pclixon_xpath_parse clixon_xpath_parse.l # -d is debug $(LEX) -Pclixon_xpath_parse clixon_xpath_parse.l # -d is debug
clixon_xpath_parse.tab.c clixon_xpath_parse.tab.h: clixon_xpath_parse.y clixon_xpath_parse.tab.h: clixon_xpath_parse.y
$(YACC) -l -d -b clixon_xpath_parse -p clixon_xpath_parse clixon_xpath_parse.y # -t is debug $(YACC) -l -d -b clixon_xpath_parse -p clixon_xpath_parse clixon_xpath_parse.y # -t is debug
# extra rule to avoid parallell yaccs
clixon_xpath_parse.tab.c: clixon_xpath_parse.tab.h
lex.clixon_xpath_parse.o : lex.clixon_xpath_parse.c clixon_xpath_parse.tab.h lex.clixon_xpath_parse.o : lex.clixon_xpath_parse.c clixon_xpath_parse.tab.h
$(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -Wno-error -c $< $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -Wno-error -c $<

View file

@ -708,9 +708,9 @@ xmldb_get(clicon_handle h,
* @note if xvec is given, then purge tree, if not return whole tree. * @note if xvec is given, then purge tree, if not return whole tree.
* @see xmldb_get This version uses direct cache access and needs to be * @see xmldb_get This version uses direct cache access and needs to be
* cleanued up after use * cleanued up after use
* @see xmldb_get1_clean Must call after use * @see xmldb_get1_clear Must call after use
* @note If !CLICON_XMLDB_CACHE you need to free xret after use * @note If !CLICON_XMLDB_CACHE you need to free xret after use
* This should probably replace xmldb_get completely * @note If CLICON_XMLDB_CACHE mark|change flags set, need to clear after call
*/ */
int int
xmldb_get1(clicon_handle h, xmldb_get1(clicon_handle h,

View file

@ -173,16 +173,20 @@ clixon_plugin_find(clicon_handle h,
* @param[in] file Which plugin to load * @param[in] file Which plugin to load
* @param[in] function Which function symbol to load and call * @param[in] function Which function symbol to load and call
* @param[in] dlflags See man(3) dlopen * @param[in] dlflags See man(3) dlopen
* @retval cp Clixon plugin structure * @param[out] cpp Clixon plugin structure (if retval is 1)
* @retval NULL Error * @retval 1 OK
* @retval 0 Failed load, log, skip and continue with other plugins
* @retval -1 Error
* @see clixon_plugins_load Load all plugins * @see clixon_plugins_load Load all plugins
*/ */
static clixon_plugin * static int
plugin_load_one(clicon_handle h, plugin_load_one(clicon_handle h,
char *file, char *file,
char *function, char *function,
int dlflags) int dlflags,
clixon_plugin **cpp)
{ {
int retval = -1;
char *error; char *error;
void *handle = NULL; void *handle = NULL;
plginit2_t *initfn; plginit2_t *initfn;
@ -201,7 +205,7 @@ plugin_load_one(clicon_handle h,
/* call plugin_init() if defined, eg CLIXON_PLUGIN_INIT or CLIXON_BACKEND_INIT */ /* call plugin_init() if defined, eg CLIXON_PLUGIN_INIT or CLIXON_BACKEND_INIT */
if ((initfn = dlsym(handle, function)) == NULL){ if ((initfn = dlsym(handle, function)) == NULL){
clicon_err(OE_PLUGIN, errno, "Failed to find %s when loading clixon plugin %s", CLIXON_PLUGIN_INIT, file); clicon_err(OE_PLUGIN, errno, "Failed to find %s when loading clixon plugin %s", CLIXON_PLUGIN_INIT, file);
goto err; goto done;
} }
if ((error = (char*)dlerror()) != NULL) { if ((error = (char*)dlerror()) != NULL) {
clicon_err(OE_UNIX, 0, "dlsym: %s: %s", file, error); clicon_err(OE_UNIX, 0, "dlsym: %s: %s", file, error);
@ -211,11 +215,12 @@ plugin_load_one(clicon_handle h,
if ((api = initfn(h)) == NULL) { if ((api = initfn(h)) == NULL) {
if (!clicon_errno){ /* if clicon_err() is not called then log and continue */ if (!clicon_errno){ /* if clicon_err() is not called then log and continue */
clicon_log(LOG_DEBUG, "Warning: failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file); clicon_log(LOG_DEBUG, "Warning: failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file);
dlclose(handle); retval = 0;
goto done;
} }
else{ else{
clicon_err(OE_PLUGIN, errno, "Failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file); clicon_err(OE_PLUGIN, errno, "Failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file);
goto err; goto done;
} }
} }
/* Note: sizeof clixon_plugin_api which is largest of clixon_plugin_api:s */ /* Note: sizeof clixon_plugin_api which is largest of clixon_plugin_api:s */
@ -235,15 +240,19 @@ plugin_load_one(clicon_handle h,
snprintf(cp->cp_name, sizeof(cp->cp_name), "%*s", snprintf(cp->cp_name, sizeof(cp->cp_name), "%*s",
(int)strlen(name), name); (int)strlen(name), name);
if (api)
cp->cp_api = *api; cp->cp_api = *api;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(1, "%s", __FUNCTION__);
if (cp){
*cpp = cp;
cp = NULL;
}
retval = 1;
done: done:
return cp; if (retval != 1 && handle)
err:
if (handle)
dlclose(handle); dlclose(handle);
return NULL; if (cp)
free(cp);
return retval;
} }
/*! Load a set of plugin objects from a directory and and call their init-function /*! Load a set of plugin objects from a directory and and call their init-function
@ -266,6 +275,7 @@ clixon_plugins_load(clicon_handle h,
int i; int i;
char filename[MAXPATHLEN]; char filename[MAXPATHLEN];
clixon_plugin *cp; clixon_plugin *cp;
int ret;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(1, "%s", __FUNCTION__);
/* Get plugin objects names from plugin directory */ /* Get plugin objects names from plugin directory */
@ -276,8 +286,10 @@ clixon_plugins_load(clicon_handle h,
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dp[i].d_name); snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dp[i].d_name);
clicon_debug(1, "DEBUG: Loading plugin '%.*s' ...", clicon_debug(1, "DEBUG: Loading plugin '%.*s' ...",
(int)strlen(filename), filename); (int)strlen(filename), filename);
if ((cp = plugin_load_one(h, filename, function, RTLD_NOW)) == NULL) if ((ret = plugin_load_one(h, filename, function, RTLD_NOW, &cp)) < 0)
goto done; goto done;
if (ret == 0)
continue;
_clixon_nplugins++; _clixon_nplugins++;
if ((_clixon_plugins = realloc(_clixon_plugins, _clixon_nplugins*sizeof(clixon_plugin))) == NULL) { if ((_clixon_plugins = realloc(_clixon_plugins, _clixon_nplugins*sizeof(clixon_plugin))) == NULL) {
clicon_err(OE_UNIX, errno, "realloc"); clicon_err(OE_UNIX, errno, "realloc");

View file

@ -70,6 +70,7 @@
#include "clixon_xpath.h" #include "clixon_xpath.h"
#include "clixon_proto.h" #include "clixon_proto.h"
#include "clixon_err.h" #include "clixon_err.h"
#include "clixon_err_string.h"
#include "clixon_proto_client.h" #include "clixon_proto_client.h"
/*! Send internal netconf rpc from client to backend /*! Send internal netconf rpc from client to backend
@ -689,7 +690,7 @@ clicon_rpc_validate(clicon_handle h,
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done; goto done;
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
clicon_rpc_generate_error("Validate failed. Edit and try again or discard changes", xerr); clicon_rpc_generate_error(CLIXON_ERRSTR_VALIDATE_FAILED, xerr);
goto done; goto done;
} }
retval = 0; retval = 0;
@ -721,7 +722,7 @@ clicon_rpc_commit(clicon_handle h)
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done; goto done;
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
clicon_rpc_generate_error("Commit failed. Edit and try again or discard changes", xerr); clicon_rpc_generate_error(CLIXON_ERRSTR_COMMIT_FAILED, xerr);
goto done; goto done;
} }
retval = 0; retval = 0;

View file

@ -626,6 +626,7 @@ xml_child_i_set(cxobj *xt,
* ... * ...
* } * }
* @endcode * @endcode
* @note makes uses _x_vector_i:can be changed if list changed between calls
*/ */
cxobj * cxobj *
xml_child_each(cxobj *xparent, xml_child_each(cxobj *xparent,
@ -817,7 +818,7 @@ xml_cv_set(cxobj *x,
* *
* @retval xmlobj if found. * @retval xmlobj if found.
* @retval NULL if no such node found. * @retval NULL if no such node found.
* @see xml_find_type wich is a more generic function * @see xml_find_type A more generic function
*/ */
cxobj * cxobj *
xml_find(cxobj *x_up, xml_find(cxobj *x_up,

View file

@ -663,6 +663,7 @@ xml_yang_validate_add(cxobj *xt,
char *body; char *body;
int ret; int ret;
cxobj *x; cxobj *x;
enum cv_type cvtype;
/* if not given by argument (overide) use default link /* if not given by argument (overide) use default link
and !Node has a config sub-statement and it is false */ and !Node has a config sub-statement and it is false */
@ -688,18 +689,29 @@ xml_yang_validate_add(cxobj *xt,
/* In the union case, value is parsed as generic REST type, /* In the union case, value is parsed as generic REST type,
* needs to be reparsed when concrete type is selected * needs to be reparsed when concrete type is selected
*/ */
if ((body = xml_body(xt)) != NULL){ if ((body = xml_body(xt)) == NULL){
/* We do not allow ints to be empty. Otherwise NULL strings
* are considered as "" */
cvtype = cv_type_get(cv);
if (cv_isint(cvtype) || cvtype == CGV_BOOL || cvtype == CGV_DEC64){
if (netconf_bad_element(cbret, "application", yt->ys_argument, "Invalid NULL value") < 0)
goto done;
goto fail;
}
}
else{
if (cv_parse1(body, cv, &reason) != 1){ if (cv_parse1(body, cv, &reason) != 1){
if (netconf_bad_element(cbret, "application", yt->ys_argument, reason) < 0) if (netconf_bad_element(cbret, "application", yt->ys_argument, reason) < 0)
goto done; goto done;
goto fail; goto fail;
} }
}
if ((ys_cv_validate(cv, yt, &reason)) != 1){ if ((ys_cv_validate(cv, yt, &reason)) != 1){
if (netconf_bad_element(cbret, "application", yt->ys_argument, reason) < 0) if (netconf_bad_element(cbret, "application", yt->ys_argument, reason) < 0)
goto done; goto done;
goto fail; goto fail;
} }
}
break; break;
default: default:
break; break;
@ -1987,6 +1999,7 @@ api_path2xml_vec(char **vec,
cxobj *x0, cxobj *x0,
yang_stmt *y0, yang_stmt *y0,
yang_class nodeclass, yang_class nodeclass,
int strict,
cxobj **xpathp, cxobj **xpathp,
yang_stmt **ypathp) yang_stmt **ypathp)
{ {
@ -2069,9 +2082,10 @@ api_path2xml_vec(char **vec,
valvec = NULL; valvec = NULL;
} }
if (restval==NULL){ if (restval==NULL){
// XXX patch to allow for lists without restval to be backward compat if (strict){
// clicon_err(OE_XML, 0, "malformed key, expected '=restval'"); clicon_err(OE_XML, 0, "malformed key, expected '=restval'");
// goto done; goto fail;
}
} }
else{ else{
if ((valvec = clicon_strsep(restval, ",", &nvalvec)) == NULL) if ((valvec = clicon_strsep(restval, ",", &nvalvec)) == NULL)
@ -2102,9 +2116,11 @@ api_path2xml_vec(char **vec,
} }
break; break;
default: /* eg Y_CONTAINER, Y_LEAF */ default: /* eg Y_CONTAINER, Y_LEAF */
if ((x = xml_find_type(x0, NULL, name, CX_ELMNT)) == NULL){ /* eg key of list */
if ((x = xml_new(name, x0, y)) == NULL) if ((x = xml_new(name, x0, y)) == NULL)
goto done; goto done;
xml_type_set(x, CX_ELMNT); xml_type_set(x, CX_ELMNT);
}
break; break;
} }
if (x && namespace){ if (x && namespace){
@ -2113,7 +2129,7 @@ api_path2xml_vec(char **vec,
} }
if ((retval = api_path2xml_vec(vec+1, nvec-1, if ((retval = api_path2xml_vec(vec+1, nvec-1,
x, y, x, y,
nodeclass, nodeclass, strict,
xpathp, ypathp)) < 1) xpathp, ypathp)) < 1)
goto done; goto done;
ok: ok:
@ -2160,6 +2176,7 @@ api_path2xml(char *api_path,
yang_stmt *yspec, yang_stmt *yspec,
cxobj *xtop, cxobj *xtop,
yang_class nodeclass, yang_class nodeclass,
int strict,
cxobj **xbotp, cxobj **xbotp,
yang_stmt **ybotp) yang_stmt **ybotp)
{ {
@ -2185,7 +2202,7 @@ api_path2xml(char *api_path,
} }
nvec--; /* NULL-terminated */ nvec--; /* NULL-terminated */
if ((retval = api_path2xml_vec(vec+1, nvec, if ((retval = api_path2xml_vec(vec+1, nvec,
xtop, yspec, nodeclass, xtop, yspec, nodeclass, strict,
xbotp, ybotp)) < 1) xbotp, ybotp)) < 1)
goto done; goto done;
xml_yang_root(*xbotp, &xroot); xml_yang_root(*xbotp, &xroot);

View file

@ -652,9 +652,14 @@ xml_insert(cxobj *xp,
/* Ensure the intermediate state that xp is parent of x but has not yet been /* Ensure the intermediate state that xp is parent of x but has not yet been
* added as a child * added as a child
*/ */
// assert(xml_parent(xi) == NULL); if (xml_parent(xi) != NULL){
// assert(y = xml_spec(xi)); clicon_err(OE_XML, 0, "XML node %s should not have parent", xml_name(xi));
goto done;
}
if ((y = xml_spec(xi)) == NULL){
clicon_err(OE_XML, 0, "No spec found %s", xml_name(xi));
goto done;
}
upper = xml_child_nr(xp); upper = xml_child_nr(xp);
/* Assume if there are any attributes, they are first in the list, mask /* Assume if there are any attributes, they are first in the list, mask
them by raising low to skip them */ them by raising low to skip them */

View file

@ -87,9 +87,9 @@
#include "clixon_plugin.h" #include "clixon_plugin.h"
#include "clixon_data.h" #include "clixon_data.h"
#include "clixon_options.h" #include "clixon_options.h"
#include "clixon_yang_type.h"
#include "clixon_yang_parse.h" #include "clixon_yang_parse.h"
#include "clixon_yang_cardinality.h" #include "clixon_yang_cardinality.h"
#include "clixon_yang_type.h"
/* Size of json read buffer when reading from file*/ /* Size of json read buffer when reading from file*/
#define BUFLEN 1024 #define BUFLEN 1024
@ -174,6 +174,56 @@ static const map_str2int ykmap[] = {
{NULL, -1} {NULL, -1}
}; };
/* Access functions
*/
/*! Get yang statement parent
* @param[in] ys Yang statement node
*/
yang_stmt *
yang_parent_get(yang_stmt *ys)
{
return ys->ys_parent;
}
/*! Get yang statement keyword
* @param[in] ys Yang statement node
*/
enum rfc_6020
yang_keyword_get(yang_stmt *ys)
{
return ys->ys_keyword;
}
/*! Get yang statement context-dependent argument
* @param[in] ys Yang statement node
*/
char*
yang_argument_get(yang_stmt *ys)
{
return ys->ys_argument;
}
/*! Get yang statement CLIgen variable
* @param[in] ys Yang statement node
*/
cg_var*
yang_cv_get(yang_stmt *ys)
{
return ys->ys_cv;
}
/*! Get yang statement CLIgen variable vector
* @param[in] ys Yang statement node
*/
cvec*
yang_cvec_get(yang_stmt *ys)
{
return ys->ys_cvec;
}
/* End access functions */
/*! Create new yang specification /*! Create new yang specification
* @retval yspec Free with yspec_free() * @retval yspec Free with yspec_free()
* @retval NULL Error * @retval NULL Error
@ -392,29 +442,38 @@ yn_insert(yang_stmt *ys_parent,
/*! Iterate through all yang statements from a yang node /*! Iterate through all yang statements from a yang node
* *
* Note that this is not optimized, one could use 'i' as index? * @param[in] yparent yang statement whose children should be iterated
* @param[in] yprev previous child, or NULL on init
* @code * @code
* yang_stmt *ys = NULL; * yang_stmt *yprev = NULL;
* while ((ys = yn_each(yn, ys)) != NULL) { * while ((yprev = yn_each(yparent, yprev)) != NULL) {
* ...ys... * ...yprev...
* } * }
* @endcode * @endcode
* @note makes uses _ys_vector_i:can be changed if list changed between calls
*/ */
yang_stmt * yang_stmt *
yn_each(yang_stmt *yn, yn_each(yang_stmt *yparent,
yang_stmt *ys) yang_stmt *yprev)
{ {
yang_stmt *yc = NULL;
int i; int i;
yang_stmt *yc = NULL;
for (i=0; i<yn->ys_len; i++){ if (yparent == NULL)
yc = yn->ys_stmt[i];
if (ys==NULL)
return yc;
if (ys==yc)
ys = NULL;
}
return NULL; return NULL;
for (i=yprev?yprev->_ys_vector_i+1:0; i<yparent->ys_len; i++){
if ((yc = yparent->ys_stmt[i]) == NULL){
assert(yc); /* XXX Check if happens */
continue;
}
/* make room for other conditionals */
break; /* this is next object after previous */
}
if (i < yparent->ys_len) /* found */
yc->_ys_vector_i = i;
else
yc = NULL;
return yc;
} }
/*! Find first child yang_stmt with matching keyword and argument /*! Find first child yang_stmt with matching keyword and argument

View file

@ -0,0 +1,91 @@
/*
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
This file is part of CLIXON.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 3 or later (the "GPL"),
in which case the provisions of the GPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of the GPL, and not to allow others to
use your version of this file under the terms of Apache License version 2,
indicate your decision by deleting the provisions above and replace them with
the notice and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the Apache License version 2 or the GPL.
***** END LICENSE BLOCK *****
* Yang functions
* @see https://tools.ietf.org/html/rfc6020 YANG 1.0
* @see https://tools.ietf.org/html/rfc7950 YANG 1.1
*/
#ifndef _CLIXON_YANG_INTERNAL_H_
#define _CLIXON_YANG_INTERNAL_H_
/*! Yang type cache. Yang type statements can cache all typedef info here
* @note unions not cached
*/
struct yang_type_cache{
int yc_options; /* See YANG_OPTIONS_* that determines pattern/
fraction fields. */
cvec *yc_cvv; /* Range and length restriction. (if YANG_OPTION_
LENGTH|RANGE. Can be a vector if multiple
ranges*/
char *yc_pattern; /* regex (posix) (if YANG_OPTIONS_PATTERN) */
uint8_t yc_fraction; /* Fraction digits for decimal64 (if
YANG_OPTIONS_FRACTION_DIGITS */
yang_stmt *yc_resolved; /* Resolved type object, can be NULL - note direct ptr */
};
typedef struct yang_type_cache yang_type_cache;
/*! yang statement
*/
struct yang_stmt{
int ys_len; /* Number of children */
struct yang_stmt **ys_stmt; /* Vector of children statement pointers */
struct yang_stmt *ys_parent; /* Backpointer to parent: yang-stmt or yang-spec */
enum rfc_6020 ys_keyword; /* See clicon_yang_parse.tab.h */
char *ys_argument; /* String / argument depending on keyword */
int ys_flags; /* Flags according to YANG_FLAG_* above */
yang_stmt *ys_module; /* Shortcut to "my" module. Augmented
nodes can belong to other
modules than the ancestor module */
char *ys_extra; /* For unknown */
cg_var *ys_cv; /* cligen variable. See ys_populate()
Following stmts have cv:s:
leaf: for default value
leaf-list,
config: boolean true or false
mandatory: boolean true or false
fraction-digits for fraction-digits
unknown-stmt (argument)
*/
cvec *ys_cvec; /* List of stmt-specific variables
Y_RANGE: range_min, range_max
Y_LIST: vector of keys
Y_TYPE & identity: store all derived types
*/
yang_type_cache *ys_typecache; /* If ys_keyword==Y_TYPE, cache all typedef data except unions */
int _ys_vector_i; /* internal use: yn_each */
};
#endif /* _CLIXON_YANG_INTERNAL_H_ */

View file

@ -364,7 +364,7 @@ cv_validate1(cg_var *cv,
cg_var *cv2; cg_var *cv2;
int retval2; int retval2;
yang_stmt *yi = NULL; yang_stmt *yi = NULL;
char *str; char *str = NULL;
int found; int found;
char **vec = NULL; char **vec = NULL;
int nvec; int nvec;
@ -435,7 +435,8 @@ cv_validate1(cg_var *cv,
case CGV_STRING: case CGV_STRING:
case CGV_REST: case CGV_REST:
if ((str = cv_string_get(cv)) == NULL) if ((str = cv_string_get(cv)) == NULL)
break; uu = 0; /* equal no string with empty string for range check */
else
uu = strlen(str); uu = strlen(str);
rets = range_check(uu, cv1, cv2, uint64); rets = range_check(uu, cv1, cv2, uint64);
break; break;
@ -470,10 +471,13 @@ cv_validate1(cg_var *cv,
case CGV_STRING: case CGV_STRING:
case CGV_REST: case CGV_REST:
str = cv_string_get(cv); str = cv_string_get(cv);
/* Note, if there is no value, eg <s/>, str is NULL.
*/
if (restype){ if (restype){
if (strcmp(restype, "enumeration") == 0){ if (strcmp(restype, "enumeration") == 0){
found = 0; found = 0;
yi = NULL; yi = NULL;
if (str != NULL)
while ((yi = yn_each(yrestype, yi)) != NULL){ while ((yi = yn_each(yrestype, yi)) != NULL){
if (yi->ys_keyword != Y_ENUM) if (yi->ys_keyword != Y_ENUM)
continue; continue;
@ -488,11 +492,13 @@ cv_validate1(cg_var *cv,
goto fail; goto fail;
} }
} }
if (strcmp(restype, "bits") == 0){ if (strcmp(restype, "bits") == 0 && str != NULL){
/* The lexical representation of the bits type is a space-separated list /* The lexical representation of the bits type is a space-separated list
* of the names of the bits that are set. A zero-length string thus * of the names of the bits that are set. A zero-length string thus
* represents a value where no bits are set. * represents a value where no bits are set.
*/ */
nvec = 0;
if ((vec = clicon_strsep(str, " \t", &nvec)) == NULL) if ((vec = clicon_strsep(str, " \t", &nvec)) == NULL)
goto done; goto done;
for (i=0; i<nvec; i++){ for (i=0; i<nvec; i++){
@ -521,7 +527,7 @@ cv_validate1(cg_var *cv,
char *posix = NULL; char *posix = NULL;
if (regexp_xsd2posix(pattern, &posix) < 0) if (regexp_xsd2posix(pattern, &posix) < 0)
goto done; goto done;
if ((retval2 = match_regexp(str, posix)) < 0){ if ((retval2 = match_regexp(str?str:"", posix)) < 0){
clicon_err(OE_DB, 0, "match_regexp: %s", pattern); clicon_err(OE_DB, 0, "match_regexp: %s", pattern);
return -1; return -1;
} }
@ -536,8 +542,9 @@ cv_validate1(cg_var *cv,
} }
} }
break; break;
case CGV_ERR:
case CGV_VOID: case CGV_VOID:
break; /* empty type OK */
case CGV_ERR:
retval = 0; retval = 0;
if (reason) if (reason)
*reason = cligen_reason("Invalid cv"); *reason = cligen_reason("Invalid cv");

View file

@ -215,21 +215,22 @@ expectfn(){
r=$? r=$?
# echo "cmd:\"$cmd\"" # echo "cmd:\"$cmd\""
# echo "retval:\"$retval\"" # echo "retval:\"$retval\""
# echo "expect:\"$expect\""
# echo "ret:\"$ret\"" # echo "ret:\"$ret\""
# echo "r:\"$r\"" # echo "r:\"$r\""
if [ $r != $retval ]; then if [ $r != $retval ]; then
echo -e "\e[31m\nError ($r != $retval) in Test$testnr [$testname]:" echo -e "\e[31m\nError ($r != $retval) in Test$testnr [$testname]:"
echo -e "\e[0m:" echo -e "\e[0m:"
exit -1
fi
if [ $r != 0 ]; then
return return
fi fi
# if [ $ret -ne $retval ]; then # if [ $r != 0 ]; then
# echo -e "\e[31m\nError in Test$testnr [$testname]:" # return
# echo -e "\e[0m:"
# exit -1
# fi # fi
# if [ $ret -ne $retval ]; then
# echo -e "\e[31m\nError in Test$testnr [$testname]:"
# echo -e "\e[0m:"
# exit -1
# fi
# Match if both are empty string # Match if both are empty string
if [ -z "$ret" -a -z "$expect" ]; then if [ -z "$ret" -a -z "$expect" ]; then
return return

View file

@ -74,7 +74,7 @@ new "cli configure using encoded chars name <&"
expectfn "$clixon_cli -1 -f $cfg set interfaces interface fddi&< type ianaift:ethernetCsmacd" 0 "" expectfn "$clixon_cli -1 -f $cfg set interfaces interface fddi&< type ianaift:ethernetCsmacd" 0 ""
new "cli failed validate" new "cli failed validate"
expectfn "$clixon_cli -1 -f $cfg -l o validate" 255 "Missing mandatory variable" expectfn "$clixon_cli -1 -f $cfg -l o validate" 255 "Validate failed. Edit and try again or discard changes: application missing-element Mandatory variable <bad-element>type</bad-element>"
new "cli configure more" new "cli configure more"
expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0 ipv4 address 1.2.3.4 prefix-length 24" 0 "^$" expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0 ipv4 address 1.2.3.4 prefix-length 24" 0 "^$"

View file

@ -98,7 +98,7 @@ new "cli enabled feature in other module"
expectfn "$clixon_cli -1f $cfg -y $fyang set routing router-id 1.2.3.4" 0 "" expectfn "$clixon_cli -1f $cfg -y $fyang set routing router-id 1.2.3.4" 0 ""
new "cli disabled feature in other module" new "cli disabled feature in other module"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set routing ribs rib default-rib false" 255 "CLI syntax error: \"set routing ribs rib default-rib\": Unknown command" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set routing ribs rib default-rib false" 255 "CLI syntax error: \"set routing ribs rib default-rib false\": Unknown command"
new "netconf discard-changes" new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"

View file

@ -194,16 +194,16 @@ new "cli show conf as limited"
expectfn "$clixon_cli -1 -U wilma -l o -f $cfg show conf" 0 "^x 1;$" expectfn "$clixon_cli -1 -U wilma -l o -f $cfg show conf" 0 "^x 1;$"
new "cli show conf as guest" new "cli show conf as guest"
expectfn "$clixon_cli -1 -U guest -l o -f $cfg show conf" 255 "protocol access-denied" expectfn "$clixon_cli -1 -U guest -l o -f $cfg show conf" 255 "application access-denied"
new "cli rpc as admin" new "cli rpc as admin"
expectfn "$clixon_cli -1 -U andy -l o -f $cfg rpc ipv4" 0 '<x xmlns="urn:example:clixon">ipv4</x><y xmlns="urn:example:clixon">42</y>' expectfn "$clixon_cli -1 -U andy -l o -f $cfg rpc ipv4" 0 '<x xmlns="urn:example:clixon">ipv4</x><y xmlns="urn:example:clixon">42</y>'
new "cli rpc as limited" new "cli rpc as limited"
expectfn "$clixon_cli -1 -U wilma -l o -f $cfg rpc ipv4" 255 "protocol access-denied default deny" expectfn "$clixon_cli -1 -U wilma -l o -f $cfg rpc ipv4" 255 "access-denied default deny"
new "cli rpc as guest" new "cli rpc as guest"
expectfn "$clixon_cli -1 -U guest -l o -f $cfg rpc ipv4" 255 "protocol access-denied access denied" expectfn "$clixon_cli -1 -U guest -l o -f $cfg rpc ipv4" 255 "access-denied access denied"
new "Kill restconf daemon" new "Kill restconf daemon"
stop_restconf stop_restconf

View file

@ -73,7 +73,7 @@ expecteq "$(curl -s -H 'Accept: application/yang-data+xml' -G http://localhost/r
# Should be alphabetically ordered # Should be alphabetically ordered
new "restconf get restconf/operations. RFC8040 3.3.2 (json)" new "restconf get restconf/operations. RFC8040 3.3.2 (json)"
expecteq "$(curl -sG http://localhost/restconf/operations)" 0 '{"operations": {"clixon-example:client-rpc": null,"clixon-example:empty": null,"clixon-example:optional": null,"clixon-example:example": null,"clixon-lib:debug": null} expecteq "$(curl -sG http://localhost/restconf/operations)" 0 '{"operations": {"clixon-example:client-rpc": null,"clixon-example:empty": null,"clixon-example:optional": null,"clixon-example:example": null,"clixon-lib:debug": null}}
' '
new "restconf get restconf/operations. RFC8040 3.3.2 (xml)" new "restconf get restconf/operations. RFC8040 3.3.2 (xml)"
@ -263,6 +263,12 @@ if [ -z "$match" ]; then
err "$expect" "$ret" err "$expect" "$ret"
fi fi
new "restconf Add subtree without key (expected error)"
expecteq "$(curl -s -X PUT -d '{"ietf-interfaces:interface":{"name":"eth/0/0","type":"ex:eth","enabled":true}}' http://localhost/restconf/data/ietf-interfaces:interfaces/interface)" 0 '{"ietf-restconf:errors" : {"error": {"error-type": "rpc","error-tag": "malformed-message","error-severity": "error","error-message": "malformed key, expected '"'"'=restval'"'"'"}}} '
new "restconf Add subtree with too many keys (expected error)"
expecteq "$(curl -s -X PUT -d '{"ietf-interfaces:interface":{"name":"eth/0/0","type":"ex:eth","enabled":true}}' http://localhost/restconf/data/ietf-interfaces:interfaces/interface=a,b)" 0 '{"ietf-restconf:errors" : {"error": {"error-type": "rpc","error-tag": "malformed-message","error-severity": "error","error-message": "List key interface length mismatch"}}} '
new "Kill restconf daemon" new "Kill restconf daemon"
stop_restconf stop_restconf

View file

@ -138,7 +138,7 @@ new "netconf EXAMPLE subscription"
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream></create-subscription></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' $NCWAIT expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream></create-subscription></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' $NCWAIT
new "netconf subscription with empty startTime" new "netconf subscription with empty startTime"
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><startTime/></create-subscription></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' $NCWAIT expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><startTime/></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>startTime</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail:'
new "netconf EXAMPLE subscription with simple filter" new "netconf EXAMPLE subscription with simple filter"
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><filter type="xpath" select="event"/></create-subscription></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' $NCWAIT expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><filter type="xpath" select="event"/></create-subscription></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' $NCWAIT

View file

@ -1,6 +1,8 @@
#!/bin/bash #!/bin/bash
# Advanced union types and generated code # Advanced union types and generated code
# and enum w values # and enum w values
# The test is run twice, first with dbcache turned on, then turned off.
# It is the only test with dbcache off.
# Magic line must be first in script (see README.md) # Magic line must be first in script (see README.md)
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
@ -12,22 +14,6 @@ fyang=$dir/type.yang
fyang2=$dir/example2.yang fyang2=$dir/example2.yang
fyang3=$dir/example3.yang fyang3=$dir/example3.yang
cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config">
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
<CLICON_CLI_GENMODEL_COMPLETION>1</CLICON_CLI_GENMODEL_COMPLETION>
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
<CLICON_XMLDB_CACHE>true</CLICON_XMLDB_CACHE>
</clixon-config>
EOF
# transitive type, exists in fyang3, referenced from fyang2, but not declared in fyang # transitive type, exists in fyang3, referenced from fyang2, but not declared in fyang
cat <<EOF > $fyang3 cat <<EOF > $fyang3
@ -123,6 +109,9 @@ module example{
enum down; enum down;
} }
} }
leaf num0 {
type int32;
}
leaf num1 { leaf num1 {
type int32 { type int32 {
range "1"; range "1";
@ -204,9 +193,31 @@ module example{
} }
EOF EOF
new "test params: -f $cfg -y $fyang" # Type tests.
# Parameters:
# 1: dbcache true/false
testrun(){
dbcache=$1
new "test params: -f $cfg -y $fyang # dbcache: $dbcache"
if [ $BE -ne 0 ]; then cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config">
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
<CLICON_CLI_GENMODEL_COMPLETION>1</CLICON_CLI_GENMODEL_COMPLETION>
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
<CLICON_XMLDB_CACHE>$dbcache</CLICON_XMLDB_CACHE>
</clixon-config>
EOF
if [ $BE -ne 0 ]; then
new "kill old backend" new "kill old backend"
sudo clixon_backend -zf $cfg sudo clixon_backend -zf $cfg
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
@ -217,371 +228,387 @@ if [ $BE -ne 0 ]; then
new "waiting" new "waiting"
sleep $RCWAIT sleep $RCWAIT
fi fi
new "cli set transitive string. type is alpha followed by number and is defined in three levels of modules" new "cli set transitive string. type is alpha followed by number and is defined in three levels of modules"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle x99" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle x99" 0 '^$'
new "cli set transitive string error. Wrong type" new "cli set transitive string error. Wrong type"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle 9xx" 255 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle 9xx" 255 '^CLI syntax error: "set c talle 9xx": Unknown command$'
new "netconf set transitive string error" new "netconf set transitive string error"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><c xmlns="urn:example:clixon"><talle>9xx</talle></c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><c xmlns="urn:example:clixon"><talle>9xx</talle></c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>"
new "netconf validate should fail" new "netconf validate should fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>talle</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail: "9xx" does not match \[a-z\]\[0-9\]\*</error-message></rpc-error></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>talle</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail: "9xx" does not match \[a-z\]\[0-9\]\*</error-message></rpc-error></rpc-reply>]]>]]>$'
new "netconf discard-changes" new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli set transitive union int (ulle should accept 4.44|bounded|unbounded)" new "cli set transitive union int (ulle should accept 4.44|bounded|unbounded)"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 33" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 33" 0 '^$'
new "cli validate" new "cli validate"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 '^$'
new "cli set transitive union string" new "cli set transitive union string"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle unbounded" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle unbounded" 0 '^$'
new "cli validate" new "cli validate"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 '^$'
new "cli set transitive union error. should fail" new "cli set transitive union error. should fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle kalle" 255 "" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle kalle" 255 '^CLI syntax error: "set c ulle kalle": Unknown command$'
new "cli set transitive union error int" new "cli set transitive union error int"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 55" 255 "" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 55" 255 '^CLI syntax error: "set c ulle 55": Unknown command$'
new "netconf set transitive union error int" new "netconf set transitive union error int"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><c xmlns="urn:example:clixon"><ulle>55</ulle></c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><c xmlns="urn:example:clixon"><ulle>55</ulle></c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>"
new "netconf validate should fail" new "netconf validate should fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>ulle</bad-element></error-info><error-severity>error</error-severity><error-message>'55' does not match enumeration</error-message></rpc-error></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>ulle</bad-element></error-info><error-severity>error</error-severity><error-message>'55' does not match enumeration</error-message></rpc-error></rpc-reply>]]>]]>$"
new "netconf discard-changes" new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#----------- #-----------
new "cli set ab" new "cli set ab"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a.b.a.b" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a.b.a.b" 0 '^$'
new "cli set cd" new "cli set cd"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list c.d.c.d" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list c.d.c.d" 0 '^$'
new "cli set ef" new "cli set ef"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list e.f.e.f" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list e.f.e.f" 0 '^$'
new "cli set ab fail" new "cli set ab fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a&b&a&b" 255 "^CLI syntax error" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a&b&a&b" 255 "^CLI syntax error"
new "cli set ad fail" new "cli set ad fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a.b.c.d" 255 "^CLI syntax error" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a.b.c.d" 255 "^CLI syntax error"
new "cli validate" new "cli validate"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 '^$'
new "cli commit" new "cli commit"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o commit" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o commit" 0 '^$'
new "netconf validate ok" new "netconf validate ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf set ab wrong" new "netconf set ab wrong"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><list xmlns="urn:example:clixon"><ip>a.b&amp; c.d</ip></list></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><list xmlns="urn:example:clixon"><ip>a.b&amp; c.d</ip></list></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate" new "netconf validate"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
new "netconf discard-changes" new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf commit" new "netconf commit"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli enum value" new "cli enum value"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set status down" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set status down" 0 '^$'
new "cli bits value" new "cli bits value"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits create" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits create" 0 '^$'
#XXX No, cli cant assign two bit values #XXX No, cli cant assign two bit values
#new "cli bits two values" #new "cli bits two values"
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits \"create read\"" 0 "^$" #expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits \"create read\"" 0 '^$'
new "netconf bits two values" new "netconf bits two values"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><mbits xmlns="urn:example:clixon">create read</mbits></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><mbits xmlns="urn:example:clixon">create read</mbits></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli bits validate" new "cli bits validate"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang validate" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang validate" 0 '^$'
#-------- num1 single range (1) #-------- num0 empty value
new "cli range test num1 1 OK" new "netconf num0 no value"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 1" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num0 xmlns="urn:example:clixon"/></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#new "cli range test num1 -100 ok" # XXX -/minus cant be given as argv new "netconf validate no value wrong"
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 \-100" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num0</bad-element></error-info><error-severity>error</error-severity><error-message>Invalid NULL value</error-message></rpc-error></rpc-reply>]]>]]>'
new "cli range test num1 2 error" new "netconf discard-changes"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 2" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range set num1 -1" #-------- num1 single range (1)
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num1 xmlns="urn:example:clixon">-1</num1></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num1 -1 wrong" new "cli range test num1 1 OK"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num1</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: -1</error-message></rpc-error></rpc-reply>]]>]]>$' expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 1" 0 '^$'
new "netconf discard-changes" #new "cli range test num1 -100 ok" # XXX -/minus cant be given as argv
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" #expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 \-100" 0 '^$'
#-------- num2 range and blanks new "cli range test num1 2 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 2" 255 '^CLI syntax error: "set num1 2": Unknown command$'
new "cli range test num2 3 error" new "netconf range set num1 -1"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 3" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num1 xmlns="urn:example:clixon">-1</num1></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli range test num2 1000 ok" new "netconf validate num1 -1 wrong"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 1000" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num1</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: -1</error-message></rpc-error></rpc-reply>]]>]]>$'
new "cli range test num2 5000 error" new "netconf discard-changes"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 5000" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range set num2 3 fail" #-------- num2 range and blanks
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">3</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num2 3 fail" new "cli range test num2 3 error"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: 3</error-message></rpc-error></rpc-reply>]]>]]>$' expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 3" 255 '^CLI syntax error: "set num2 3": Number out of range: 3$'
new "netconf range set num2 1000 ok" new "cli range test num2 1000 ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">1000</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 1000" 0 '^$'
new "netconf validate num2 1000 ok" new "cli range test num2 5000 error"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$' expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 5000" 255 '^CLI syntax error: "set num2 5000": Unknown command$'
new "netconf range set num2 5000 fail" new "netconf range set num2 3 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">5000</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">3</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num2 5000 fail" new "netconf validate num2 3 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: 5000</error-message></rpc-error></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: 3</error-message></rpc-error></rpc-reply>]]>]]>$'
new "netconf discard-changes" new "netconf range set num2 1000 ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">1000</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#-------- num3 min max range new "netconf validate num2 1000 ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "cli range test num3 42 ok" new "netconf range set num2 5000 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 42" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">5000</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli range test num3 260 fail" new "netconf validate num2 5000 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 260" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: 5000</error-message></rpc-error></rpc-reply>]]>]]>$'
new "cli range test num3 -1 fail" new "netconf discard-changes"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 -1" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range set num3 260 fail" #-------- num3 min max range
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num3 xmlns="urn:example:clixon">260</num3></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num3 260 fail" new "cli range test num3 42 ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num3</bad-element></error-info><error-severity>error</error-severity><error-message>260 is out of range(type is uint8)</error-message></rpc-error></rpc-reply>]]>]]>$' expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 42" 0 '^$'
new "netconf discard-changes" new "cli range test num3 260 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 260" 255 '^CLI syntax error: "set num3 260": Unknown command$'
#-------- num4 multiple ranges 1..2 | 42..50 new "cli range test num3 -1 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 -1" 255 "CLI syntax error:"
new "cli range test num4 multiple 0 fail" new "netconf range set num3 260 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 0" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num3 xmlns="urn:example:clixon">260</num3></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli range test num4 multiple 2 ok" new "netconf validate num3 260 fail"
expectfn "$clixon_cli -1f $cfg -l e -y $fyang set num4 2" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num3</bad-element></error-info><error-severity>error</error-severity><error-message>260 is out of range(type is uint8)</error-message></rpc-error></rpc-reply>]]>]]>$'
new "cli range test num4 multiple 20 fail" new "netconf discard-changes"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 20" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli range test num4 multiple 42 ok" #-------- num4 multiple ranges 1..2 | 42..50
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 42" 0 "^$"
new "cli range test num4 multiple 99 fail" new "cli range test num4 multiple 0 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 99" 255 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 0" 255 '^CLI syntax error: "set num4 0": Number out of range: 0$'
new "netconf range set num4 multiple 2" new "cli range test num4 multiple 2 ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l e -y $fyang set num4 2" 0 '^$'
new "netconf validate num4 OK" new "cli range test num4 multiple 20 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$' expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 20" 255 '^CLI syntax error: "set num4 20": Unknown command$'
new "netconf range set num4 multiple 20" new "cli range test num4 multiple 42 ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 42" 0 '^$'
new "netconf validate num4 fail" new "cli range test num4 multiple 99 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$' expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 99" 255 '^CLI syntax error: "set num4 99": Unknown command$'
new "netconf range set num4 multiple 42" new "netconf range set num4 multiple 2"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num4 fail" new "netconf validate num4 OK"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "netconf discard-changes" new "netconf range set num4 multiple 20"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#-------- dec64 multiple ranges -3.5..-2.5 | 0.0 | 10.0..20.0 new "netconf validate num4 fail"
# XXX how to enter negative numbers in bash string and cli -1? expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "cli range dec64 multiple 0 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 0" 0 "^$"
new "cli range dec64 multiple 0.1 fail" new "netconf range set num4 multiple 42"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 0.1" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli range dec64 multiple 15.0 ok" new "netconf validate num4 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 15.0" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "cli range dec64 multiple 30.0 fail" new "netconf discard-changes"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 30.0" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "dec64 discard-changes" #-------- dec64 multiple ranges -3.5..-2.5 | 0.0 | 10.0..20.0
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" # XXX how to enter negative numbers in bash string and cli -1?
new "cli range dec64 multiple 0 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 0" 0 '^$'
# Same with netconf new "cli range dec64 multiple 0.1 fail"
new "netconf range dec64 -3.59" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 0.1" 255 '^CLI syntax error: "set num4 0.1": '"'"'0.1'"'"' is not a number$'
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-3.59</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 -3.59 validate fail" new "cli range dec64 multiple 15.0 ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range' expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 15.0" 0 '^$'
new "netconf range dec64 -3.5" new "cli range dec64 multiple 30.0 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-3.500</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 30.0" 255 '^CLI syntax error: "set dec 30.0": Unknown command$'
new "netconf range dec64 -3.5 validate ok" new "dec64 discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 -2" # Same with netconf
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-2</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" new "netconf range dec64 -3.59"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-3.59</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 -2 validate fail" new "netconf range dec64 -3.59 validate fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range' expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
new "netconf range dec64 -0.001" new "netconf range dec64 -3.5"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-3.500</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 -0.001 validate fail" new "netconf range dec64 -3.5 validate ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range' expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "netconf range dec64 0.0" new "netconf range dec64 -2"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">0.0</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-2</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 0.0 validate ok" new "netconf range dec64 -2 validate fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
new "netconf range dec64 +0.001" new "netconf range dec64 -0.001"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">+0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 +0.001 validate fail" new "netconf range dec64 -0.001 validate fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range' expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
#----------------string ranges--------------------- new "netconf range dec64 0.0"
#-------- len1 single range (2) expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">0.0</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli length test len1 1 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 x" 255 "^$"
new "cli length test len1 2 OK" new "netconf range dec64 0.0 validate ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 xy" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "cli length test len1 3 error" new "netconf range dec64 +0.001"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 hej" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">+0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf discard-changes" new "netconf range dec64 +0.001 validate fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
new "netconf length set len1 1" #----------------string ranges---------------------
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><len1 xmlns="urn:example:clixon">x</len1></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" #-------- len1 single range (2)
new "cli length test len1 1 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 x" 255 '^CLI syntax error: "set len1 x": String length not within limits: 1$'
new "netconf validate len1 1 wrong" new "cli length test len1 2 OK"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>len1</bad-element></error-info><error-severity>error</error-severity><error-message>string length out of range: 1</error-message></rpc-error></rpc-reply>]]>]]>$' expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 xy" 0 '^$'
#-------- len2 range and blanks new "cli length test len1 3 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 hej" 255 '^CLI syntax error: "set len1 hej": Unknown command$'
new "cli length test len2 3 error" new "netconf discard-changes"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 ab" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli length test len2 42 ok" new "netconf length set len1 1"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><len1 xmlns="urn:example:clixon">x</len1></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf discard-changes" new "netconf validate len1 1 wrong"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>len1</bad-element></error-info><error-severity>error</error-severity><error-message>string length out of range: 1</error-message></rpc-error></rpc-reply>]]>]]>$'
#-------- len3 min max range #-------- len2 range and blanks
new "cli range ptest len3 42 ok" new "cli length test len2 3 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len3 hsakjdhkjsahdkjsahdksahdksajdhsakjhd" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 ab" 255 '^CLI syntax error: "set len2 ab": String length not within limits: 2$'
#-------- len4 multiple ranges 2..3 | 20-29 new "cli length test len2 42 ok"
new "cli length test len4 1 error" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 '^$'
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 a" 255 "^$"
new "cli length test len4 2 ok" new "netconf discard-changes"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 ab" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli length test len4 10 error" #-------- len3 min max range
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghij" 255 "^$"
new "cli length test len4 20 ok" new "cli range ptest len3 42 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghija" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len3 hsakjdhkjsahdkjsahdksahdksajdhsakjhd" 0 '^$'
new "cli length test len4 30 error" #-------- len4 multiple ranges 2..3 | 20-29
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghijabcdefghij" 255 "^$" new "cli length test len4 1 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 a" 255 '^CLI syntax error: "set len4 a": String length not within limits: 1$'
# XSD schema -> POSIX ECE translation new "cli length test len4 2 ok"
new "cli yang pattern \d ok" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 ab" 0 '^$'
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 0123" 0 "^$"
new "cli yang pattern \d error" new "cli length test len4 10 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 01b2" 255 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghij" 255 '^CLI syntax error: "set len4 abcdefghij": Unknown command$'
new "cli yang pattern \w ok" new "cli length test len4 20 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 abc9" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghija" 0 '^$'
new "cli yang pattern \w error" new "cli length test len4 30 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 ab%3" 255 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghijabcdefghij" 255 '^CLI syntax error: "set len4 abcdefghijabcdefghijabcdefghij": Unknown command$'
new "netconf pattern \w" # XSD schema -> POSIX ECE translation
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><word4 xmlns="urn:example:clixon">aXG9</word4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" new "cli yang pattern \d ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 0123" 0 '^$'
new "netconf pattern \w valid" new "cli yang pattern \d error"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 01b2" 255 '^CLI syntax error: "set digit4 01b2": Unknown command$'
new "netconf pattern \w error" new "cli yang pattern \w ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><word4 xmlns="urn:example:clixon">ab%d3</word4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 abc9" 0 '^$'
new "netconf pattern \w valid" new "cli yang pattern \w error"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>word4</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail: "ab%d3" does not match \\w{4}</error-message></rpc-error></rpc-reply>]]>]]>$' expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 ab%3" 255 '^CLI syntax error: "set word4 ab%3": Unknown command$'
new "netconf discard-changes" new "netconf pattern \w"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><word4 xmlns="urn:example:clixon">aXG9</word4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf pattern \w valid"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#------ minus new "netconf pattern \w error"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><word4 xmlns="urn:example:clixon">ab%d3</word4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "type with minus" new "netconf pattern \w valid"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><minus xmlns="urn:example:clixon">my-name</minus></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>word4</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail: "ab%d3" does not match \\w{4}</error-message></rpc-error></rpc-reply>]]>]]>$'
new "validate minus" new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#new "cli type with minus"
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set name my-name" 0 "^$"
if [ $BE -eq 0 ]; then #------ minus
exit # BE
fi
new "Kill backend" new "type with minus"
# Check if premature kill expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><minus xmlns="urn:example:clixon">my-name</minus></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
pid=`pgrep -u root -f clixon_backend`
if [ -z "$pid" ]; then new "validate minus"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#new "cli type with minus"
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set name my-name" 0 '^$'
if [ $BE -ne 0 ]; then
new "Kill backend"
# Check if premature kill
pid=`pgrep -u root -f clixon_backend`
if [ -z "$pid" ]; then
err "backend already dead" err "backend already dead"
fi fi
# kill backend # kill backend
stop_backend -f $cfg stop_backend -f $cfg
fi
}
# Run with db cache
testrun true
# Run without db cache
testrun false
rm -rf $dir rm -rf $dir

View file

@ -1,588 +0,0 @@
#!/bin/bash
# Advanced union types and generated code
# and enum w values
# @see test_type.sh ONLY DIFFERENCE IS db-cache is OFF here
# Magic line must be first in script (see README.md)
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
APPNAME=example
cfg=$dir/conf_yang.xml
fyang=$dir/type.yang
fyang2=$dir/example2.yang
fyang3=$dir/example3.yang
cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config">
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
<CLICON_CLI_GENMODEL_COMPLETION>1</CLICON_CLI_GENMODEL_COMPLETION>
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
<CLICON_XMLDB_CACHE>false</CLICON_XMLDB_CACHE>
</clixon-config>
EOF
# transitive type, exists in fyang3, referenced from fyang2, but not declared in fyang
cat <<EOF > $fyang3
module example3{
prefix ex3;
namespace "urn:example:example3";
typedef w{
type union{
type int32{
range "4..44";
}
}
}
typedef u{
type union {
type w;
type enumeration {
enum "bounded";
enum "unbounded";
}
}
}
typedef t{
type string{
pattern '[a-z][0-9]*';
}
}
}
EOF
cat <<EOF > $fyang2
module example2{
import example3 { prefix ex3; }
namespace "urn:example:example2";
prefix ex2;
grouping gr2 {
leaf talle{
type ex3:t;
}
leaf ulle{
type ex3:u;
}
}
}
EOF
cat <<EOF > $fyang
module example{
yang-version 1.1;
namespace "urn:example:clixon";
prefix ex;
import example2 { prefix ex2; }
typedef ab {
type string {
pattern
'(([a-b])\.){3}[a-b]';
}
}
typedef cd {
type string {
pattern
'(([c-d])\.){3}[c-d]';
}
}
typedef ef {
type string {
pattern
'(([e-f])\.){3}[e-f]';
length "1..253";
}
}
typedef ad {
type union {
type ab;
type cd;
}
}
typedef af {
type union {
type ad;
type ef;
}
}
list list {
key ip;
leaf ip {
type af;
}
}
leaf status {
type enumeration {
enum up {
value 1;
}
enum down;
}
}
leaf num1 {
type int32 {
range "1";
}
}
leaf num2 { /* range and blanks */
type int32 {
range " 4 .. 4000 ";
}
}
leaf num3 {
type uint8 {
range "min..max";
}
}
leaf num4 {
type uint8 {
range "1..2 | 42..50";
}
}
leaf dec {
/* For test of multiple ranges with decimal64. More than 2, single range*/
type decimal64 {
fraction-digits 3;
range "-3.5..-2.5 | 0.0 | 10.0..20.0";
}
}
leaf len1 {
type string {
length "2";
}
}
leaf len2 {
type string {
length " 4 .. 4000 ";
}
}
leaf len3 {
type string {
length "min..max";
}
}
leaf len4 {
type string {
length "2 .. 3 | 20..29";
}
}
typedef mybits {
description "Test adding several bits";
type bits {
bit create;
bit read;
bit write;
}
}
leaf mbits{
type mybits;
}
container c{
description "transitive type- exists in ex3";
uses ex2:gr2;
}
leaf digit4{
type string {
pattern '\d{4}';
}
}
leaf word4{
type string {
pattern '\w{4}';
}
}
leaf minus{
description "Problem with minus";
type string{
pattern '[a-zA-Z_][a-zA-Z0-9_\-.]*';
}
}
}
EOF
new "test params: -f $cfg -y $fyang"
if [ $BE -ne 0 ]; then
new "kill old backend"
sudo clixon_backend -zf $cfg
if [ $? -ne 0 ]; then
err
fi
new "start backend -s init -f $cfg -y $fyang"
start_backend -s init -f $cfg -y $fyang
new "waiting"
sleep $RCWAIT
fi
new "cli set transitive string. type is alpha followed by number and is defined in three levels of modules"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle x99" 0 "^$"
new "cli set transitive string error. Wrong type"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle 9xx" 255 "^$"
new "netconf set transitive string error"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><c xmlns="urn:example:clixon"><talle>9xx</talle></c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>"
new "netconf validate should fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>talle</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail: "9xx" does not match \[a-z\]\[0-9\]\*</error-message></rpc-error></rpc-reply>]]>]]>$'
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli set transitive union int (ulle should accept 4.44|bounded|unbounded)"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 33" 0 "^$"
new "cli validate"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$"
new "cli set transitive union string"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle unbounded" 0 "^$"
new "cli validate"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$"
new "cli set transitive union error. should fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle kalle" 255 ""
new "cli set transitive union error int"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 55" 255 ""
new "netconf set transitive union error int"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><c xmlns="urn:example:clixon"><ulle>55</ulle></c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>"
new "netconf validate should fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>ulle</bad-element></error-info><error-severity>error</error-severity><error-message>'55' does not match enumeration</error-message></rpc-error></rpc-reply>]]>]]>$"
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#-----------
new "cli set ab"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a.b.a.b" 0 "^$"
new "cli set cd"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list c.d.c.d" 0 "^$"
new "cli set ef"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list e.f.e.f" 0 "^$"
new "cli set ab fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a&b&a&b" 255 "^CLI syntax error"
new "cli set ad fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a.b.c.d" 255 "^CLI syntax error"
new "cli validate"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$"
new "cli commit"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o commit" 0 "^$"
new "netconf validate ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf set ab wrong"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><list xmlns="urn:example:clixon"><ip>a.b&amp; c.d</ip></list></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf commit"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli enum value"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set status down" 0 "^$"
new "cli bits value"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits create" 0 "^$"
#XXX No, cli cant assign two bit values
#new "cli bits two values"
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits \"create read\"" 0 "^$"
new "netconf bits two values"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><mbits xmlns="urn:example:clixon">create read</mbits></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli bits validate"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang validate" 0 "^$"
#-------- num1 single range (1)
new "cli range test num1 1 OK"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 1" 0 "^$"
#new "cli range test num1 -100 ok" # XXX -/minus cant be given as argv
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 \-100" 0 "^$"
new "cli range test num1 2 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 2" 255 "^$"
new "netconf range set num1 -1"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num1 xmlns="urn:example:clixon">-1</num1></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num1 -1 wrong"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num1</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: -1</error-message></rpc-error></rpc-reply>]]>]]>$'
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#-------- num2 range and blanks
new "cli range test num2 3 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 3" 255 "^$"
new "cli range test num2 1000 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 1000" 0 "^$"
new "cli range test num2 5000 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 5000" 255 "^$"
new "netconf range set num2 3 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">3</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num2 3 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: 3</error-message></rpc-error></rpc-reply>]]>]]>$'
new "netconf range set num2 1000 ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">1000</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num2 1000 ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "netconf range set num2 5000 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">5000</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num2 5000 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: 5000</error-message></rpc-error></rpc-reply>]]>]]>$'
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#-------- num3 min max range
new "cli range test num3 42 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 42" 0 "^$"
new "cli range test num3 260 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 260" 255 "^$"
new "cli range test num3 -1 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 -1" 255 "^$"
new "netconf range set num3 260 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num3 xmlns="urn:example:clixon">260</num3></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num3 260 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num3</bad-element></error-info><error-severity>error</error-severity><error-message>260 is out of range(type is uint8)</error-message></rpc-error></rpc-reply>]]>]]>$'
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#-------- num4 multiple ranges 1..2 | 42..50
new "cli range test num4 multiple 0 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 0" 255 "^$"
new "cli range test num4 multiple 2 ok"
expectfn "$clixon_cli -1f $cfg -l e -y $fyang set num4 2" 0 "^$"
new "cli range test num4 multiple 20 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 20" 255 "^$"
new "cli range test num4 multiple 42 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 42" 0 "^$"
new "cli range test num4 multiple 99 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 99" 255 "^$"
new "netconf range set num4 multiple 2"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num4 OK"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "netconf range set num4 multiple 20"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num4 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "netconf range set num4 multiple 42"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate num4 fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#-------- dec64 multiple ranges -3.5..-2.5 | 0.0 | 10.0..20.0
# XXX how to enter negative numbers in bash string and cli -1?
new "cli range dec64 multiple 0 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 0" 0 "^$"
new "cli range dec64 multiple 0.1 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 0.1" 255 "^$"
new "cli range dec64 multiple 15.0 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 15.0" 0 "^$"
new "cli range dec64 multiple 30.0 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 30.0" 255 "^$"
new "dec64 discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
# Same with netconf
new "netconf range dec64 -3.59"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-3.59</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 -3.59 validate fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
new "netconf range dec64 -3.5"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-3.500</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 -3.5 validate ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "netconf range dec64 -2"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-2</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 -2 validate fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
new "netconf range dec64 -0.001"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 -0.001 validate fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
new "netconf range dec64 0.0"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">0.0</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 0.0 validate ok"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "netconf range dec64 +0.001"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">+0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 +0.001 validate fail"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
#----------------string ranges---------------------
#-------- len1 single range (2)
new "cli length test len1 1 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 x" 255 "^$"
new "cli length test len1 2 OK"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 xy" 0 "^$"
new "cli length test len1 3 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 hej" 255 "^$"
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf length set len1 1"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><len1 xmlns="urn:example:clixon">x</len1></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate len1 1 wrong"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>len1</bad-element></error-info><error-severity>error</error-severity><error-message>string length out of range: 1</error-message></rpc-error></rpc-reply>]]>]]>$'
#-------- len2 range and blanks
new "cli length test len2 3 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 ab" 255 "^$"
new "cli length test len2 42 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 "^$"
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#-------- len3 min max range
new "cli range ptest len3 42 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len3 hsakjdhkjsahdkjsahdksahdksajdhsakjhd" 0 "^$"
#-------- len4 multiple ranges 2..3 | 20-29
new "cli length test len4 1 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 a" 255 "^$"
new "cli length test len4 2 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 ab" 0 "^$"
new "cli length test len4 10 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghij" 255 "^$"
new "cli length test len4 20 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghija" 0 "^$"
new "cli length test len4 30 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghijabcdefghij" 255 "^$"
# XSD schema -> POSIX ECE translation
new "cli yang pattern \d ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 0123" 0 "^$"
new "cli yang pattern \d error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 01b2" 255 "^$"
new "cli yang pattern \w ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 abc9" 0 "^$"
new "cli yang pattern \w error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 ab%3" 255 "^$"
new "netconf pattern \w"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><word4 xmlns="urn:example:clixon">aXG9</word4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf pattern \w valid"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf pattern \w error"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><word4 xmlns="urn:example:clixon">ab%d3</word4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf pattern \w valid"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>word4</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail: "ab%d3" does not match \\w{4}</error-message></rpc-error></rpc-reply>]]>]]>$'
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#------ minus
new "type with minus"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><minus xmlns="urn:example:clixon">my-name</minus></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "validate minus"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#new "cli type with minus"
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set name my-name" 0 "^$"
if [ $BE -eq 0 ]; then
exit # BE
fi
new "Kill backend"
# Check if premature kill
pid=`pgrep -u root -f clixon_backend`
if [ -z "$pid" ]; then
err "backend already dead"
fi
# kill backend
stop_backend -f $cfg
rm -rf $dir

View file

@ -98,7 +98,7 @@ new "cli set transitive union"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 33" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 33" 0 "^$"
new "cli set transitive union error" new "cli set transitive union error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle kalle" 255 "" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle kalle" 255 '^CLI syntax error: "set c ulle kalle": Unknown command$'
if [ $BE -eq 0 ]; then if [ $BE -eq 0 ]; then
exit # BE exit # BE