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,10 +629,11 @@ 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;
if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0) while ((yc = yn_each(ys, yc)) != NULL)
goto done; if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0)
goto done;
cprintf(cb, "%*s}\n", level*3, ""); cprintf(cb, "%*s}\n", level*3, "");
retval = 0; retval = 0;
done: done:
@ -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,22 +696,22 @@ 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)
continue;
if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0)
goto done;
} }
if (cvi != NULL)
continue;
if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0)
goto done;
}
cprintf(cb, "%*s}\n", level*3, ""); cprintf(cb, "%*s}\n", level*3, "");
retval = 0; retval = 0;
done: done:
@ -746,25 +745,24 @@ 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;
break; break;
case Y_CONTAINER: case Y_CONTAINER:
case Y_LEAF: case Y_LEAF:
case Y_LEAF_LIST: case Y_LEAF_LIST:
case Y_LIST: case Y_LIST:
default: default:
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;
}
} }
}
retval = 0; retval = 0;
done: done:
return retval; return retval;
@ -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,10 +807,10 @@ 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;
default: /* skip */ default: /* skip */
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,23 +173,27 @@ 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)
{ {
char *error; int retval = -1;
void *handle = NULL; char *error;
plginit2_t *initfn; void *handle = NULL;
plginit2_t *initfn;
clixon_plugin_api *api = NULL; clixon_plugin_api *api = NULL;
clixon_plugin *cp = NULL; clixon_plugin *cp = NULL;
char *name; char *name;
char *p; char *p;
clicon_debug(1, "%s file:%s function:%s", __FUNCTION__, file, function); clicon_debug(1, "%s file:%s function:%s", __FUNCTION__, file, function);
dlerror(); /* Clear any existing error */ dlerror(); /* Clear any existing error */
@ -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,17 +689,28 @@ 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 (netconf_bad_element(cbret, "application", yt->ys_argument, reason) < 0)
goto done; if ((ys_cv_validate(cv, yt, &reason)) != 1){
goto fail; if (netconf_bad_element(cbret, "application", yt->ys_argument, reason) < 0)
} goto done;
goto fail;
} }
break; break;
default: default:
@ -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_new(name, x0, y)) == NULL) if ((x = xml_find_type(x0, NULL, name, CX_ELMNT)) == NULL){ /* eg key of list */
goto done; if ((x = xml_new(name, x0, y)) == NULL)
xml_type_set(x, CX_ELMNT); goto done;
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)
{ {
int i;
yang_stmt *yc = NULL; yang_stmt *yc = NULL;
int i;
for (i=0; i<yn->ys_len; i++){ if (yparent == NULL)
yc = yn->ys_stmt[i]; return NULL;
if (ys==NULL) for (i=yprev?yprev->_ys_vector_i+1:0; i<yparent->ys_len; i++){
return yc; if ((yc = yparent->ys_stmt[i]) == NULL){
if (ys==yc) assert(yc); /* XXX Check if happens */
ys = NULL; continue;
}
/* make room for other conditionals */
break; /* this is next object after previous */
} }
return NULL; 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,8 +435,9 @@ 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 */
uu = strlen(str); else
uu = strlen(str);
rets = range_check(uu, cv1, cv2, uint64); rets = range_check(uu, cv1, cv2, uint64);
break; break;
default: default:
@ -470,29 +471,34 @@ 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;
while ((yi = yn_each(yrestype, yi)) != NULL){ if (str != NULL)
if (yi->ys_keyword != Y_ENUM) while ((yi = yn_each(yrestype, yi)) != NULL){
continue; if (yi->ys_keyword != Y_ENUM)
if (strcmp(yi->ys_argument, str) == 0){ continue;
found++; if (strcmp(yi->ys_argument, str) == 0){
break; found++;
break;
}
} }
}
if (!found){ if (!found){
if (reason) if (reason)
*reason = cligen_reason("'%s' does not match enumeration", str); *reason = cligen_reason("'%s' does not match enumeration", str);
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

@ -202,52 +202,53 @@ new(){
# - expected stdout outcome, # - expected stdout outcome,
# - expected2 stdout outcome, # - expected2 stdout outcome,
expectfn(){ expectfn(){
cmd=$1 cmd=$1
retval=$2 retval=$2
expect="$3" expect="$3"
if [ $# = 4 ]; then if [ $# = 4 ]; then
expect2=$4 expect2=$4
else else
expect2= expect2=
fi
ret=$($cmd)
r=$?
# echo "cmd:\"$cmd\""
# echo "retval:\"$retval\""
# echo "ret:\"$ret\""
# echo "r:\"$r\""
if [ $r != $retval ]; then
echo -e "\e[31m\nError ($r != $retval) in Test$testnr [$testname]:"
echo -e "\e[0m:"
exit -1
fi fi
if [ $r != 0 ]; then ret=$($cmd)
return r=$?
# echo "cmd:\"$cmd\""
# echo "retval:\"$retval\""
# echo "expect:\"$expect\""
# echo "ret:\"$ret\""
# echo "r:\"$r\""
if [ $r != $retval ]; then
echo -e "\e[31m\nError ($r != $retval) in Test$testnr [$testname]:"
echo -e "\e[0m:"
return
fi
# if [ $r != 0 ]; then
# return
# 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
if [ -z "$ret" -a -z "$expect" ]; then
return
fi
if [ -z "$ret" -a "$expect" = "^$" ]; then
return
fi
# grep extended grep
match=`echo $ret | grep -EZo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
if [ -n "$expect2" ]; then
match=`echo "$ret" | grep -EZo "$expect2"`
if [ -z "$match" ]; then
err $expect "$ret"
fi
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
if [ -z "$ret" -a -z "$expect" ]; then
return
fi
if [ -z "$ret" -a "$expect" = "^$" ]; then
return
fi
# grep extended grep
match=`echo $ret | grep -EZo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
if [ -n "$expect2" ]; then
match=`echo "$ret" | grep -EZo "$expect2"`
if [ -z "$match" ]; then
err $expect "$ret"
fi
fi
} }
# Evaluate and return # Evaluate and 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,384 +193,422 @@ 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
new "kill old backend" <clixon-config xmlns="http://clicon.org/config">
sudo clixon_backend -zf $cfg <CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
if [ $? -ne 0 ]; then <CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
err <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"
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 fi
new "start backend -s init -f $cfg -y $fyang"
start_backend -s init -f $cfg -y $fyang
new "waiting" new "cli set transitive string. type is alpha followed by number and is defined in three levels of modules"
sleep $RCWAIT expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle x99" 0 '^$'
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 error. Wrong type"
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 9xx" 255 '^CLI syntax error: "set c talle 9xx": Unknown command$'
new "cli set transitive string error. Wrong type" new "netconf set transitive string error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle 9xx" 255 "^$" 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 set transitive string error" new "netconf validate should fail"
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><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 validate should fail" new "netconf discard-changes"
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><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf discard-changes" new "cli set transitive union int (ulle should accept 4.44|bounded|unbounded)"
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 c ulle 33" 0 '^$'
new "cli set transitive union int (ulle should accept 4.44|bounded|unbounded)" new "cli validate"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 33" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 '^$'
new "cli validate" new "cli set transitive union string"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle unbounded" 0 '^$'
new "cli set transitive union string" new "cli validate"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle unbounded" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 '^$'
new "cli validate" new "cli set transitive union error. should fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$" 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. should fail" new "cli set transitive union error int"
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 55" 255 '^CLI syntax error: "set c ulle 55": Unknown command$'
new "cli set transitive union error int" new "netconf set transitive union error int"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 55" 255 "" 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 set transitive union error int" new "netconf validate should fail"
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><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 validate should fail" new "netconf discard-changes"
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><discard-changes/></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>]]>]]>$"
#----------- new "cli set ab"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a.b.a.b" 0 '^$'
new "cli set ab" new "cli set cd"
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 c.d.c.d" 0 '^$'
new "cli set cd" new "cli set ef"
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 e.f.e.f" 0 '^$'
new "cli set ef" new "cli set ab fail"
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 a&b&a&b" 255 "^CLI syntax error"
new "cli set ab fail" new "cli set ad 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.c.d" 255 "^CLI syntax error"
new "cli set ad fail" new "cli validate"
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 -l o validate" 0 '^$'
new "cli validate" new "cli commit"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o commit" 0 '^$'
new "cli commit" new "netconf validate ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o commit" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate ok" new "netconf set ab wrong"
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><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 set ab wrong" new "netconf validate"
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><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
new "netconf validate" new "netconf discard-changes"
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><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf discard-changes" new "netconf commit"
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><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf commit" new "cli enum value"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set status down" 0 '^$'
new "cli enum value" new "cli bits value"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set status down" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits create" 0 '^$'
new "cli bits value" #XXX No, cli cant assign two bit values
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits create" 0 "^$" #new "cli bits two values"
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits \"create read\"" 0 '^$'
#XXX No, cli cant assign two bit values new "netconf bits two values"
#new "cli 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>]]>]]>$"
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits \"create read\"" 0 "^$"
new "netconf bits two values" new "cli bits validate"
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>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang validate" 0 '^$'
new "cli bits validate" #-------- num0 empty value
expectfn "$clixon_cli -1f $cfg -l o -y $fyang validate" 0 "^$"
#-------- num1 single range (1) new "netconf num0 no value"
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 1 OK" new "netconf validate no value wrong"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 1" 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 -100 ok" # XXX -/minus cant be given as argv new "netconf discard-changes"
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 \-100" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli range test num1 2 error" #-------- num1 single range (1)
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 2" 255 "^$"
new "netconf range set num1 -1" new "cli range test num1 1 OK"
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>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 1" 0 '^$'
new "netconf validate num1 -1 wrong" #new "cli range test num1 -100 ok" # XXX -/minus cant be given as argv
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 \-100" 0 '^$'
new "netconf discard-changes" new "cli range test num1 2 error"
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 2" 255 '^CLI syntax error: "set num1 2": Unknown command$'
#-------- num2 range and blanks 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 "cli range test num2 3 error" new "netconf validate num1 -1 wrong"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 3" 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>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 1000 ok" new "netconf discard-changes"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 1000" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli range test num2 5000 error" #-------- num2 range and blanks
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 5000" 255 "^$"
new "netconf range set num2 3 fail" new "cli range test num2 3 error"
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>]]>]]>$" 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 validate num2 3 fail" new "cli range test num2 1000 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>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 1000" 0 '^$'
new "netconf range set num2 1000 ok" new "cli range test num2 5000 error"
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 5000" 255 '^CLI syntax error: "set num2 5000": Unknown command$'
new "netconf validate num2 1000 ok" new "netconf range set num2 3 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><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">3</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range set num2 5000 fail" new "netconf validate 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><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 validate num2 5000 fail" new "netconf range set num2 1000 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>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><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">1000</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf discard-changes" new "netconf validate 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><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
#-------- num3 min max range 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 "cli range test num3 42 ok" new "netconf validate 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><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 260 fail" new "netconf discard-changes"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 260" 255 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli range test num3 -1 fail" #-------- num3 min max range
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 -1" 255 "^$"
new "netconf range set num3 260 fail" new "cli range test num3 42 ok"
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>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 42" 0 '^$'
new "netconf validate num3 260 fail" new "cli range test 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>]]>]]>$' expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 260" 255 '^CLI syntax error: "set num3 260": Unknown command$'
new "netconf discard-changes" new "cli range test num3 -1 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 -1" 255 "CLI syntax error:"
#-------- num4 multiple ranges 1..2 | 42..50 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 "cli range test num4 multiple 0 fail" new "netconf validate 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><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 2 ok" new "netconf discard-changes"
expectfn "$clixon_cli -1f $cfg -l e -y $fyang set num4 2" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli range test num4 multiple 20 fail" #-------- num4 multiple ranges 1..2 | 42..50
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 20" 255 "^$"
new "cli range test num4 multiple 42 ok" new "cli range test num4 multiple 0 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 42" 0 "^$" 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 "cli range test num4 multiple 99 fail" new "cli range test num4 multiple 2 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 99" 255 "^$" expectfn "$clixon_cli -1f $cfg -l e -y $fyang set num4 2" 0 '^$'
new "netconf range set num4 multiple 2" new "cli range test num4 multiple 20 fail"
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 20" 255 '^CLI syntax error: "set num4 20": Unknown command$'
new "netconf validate num4 OK" new "cli range test num4 multiple 42 ok"
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 42" 0 '^$'
new "netconf range set num4 multiple 20" new "cli range test num4 multiple 99 fail"
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 99" 255 '^CLI syntax error: "set num4 99": Unknown command$'
new "netconf validate num4 fail" new "netconf range set num4 multiple 2"
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><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range set num4 multiple 42" new "netconf validate num4 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>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "netconf validate num4 fail" new "netconf range set num4 multiple 20"
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><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf discard-changes" new "netconf validate num4 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><ok/></rpc-reply>]]>]]>$'
#-------- dec64 multiple ranges -3.5..-2.5 | 0.0 | 10.0..20.0 new "netconf range set num4 multiple 42"
# XXX how to enter negative numbers in bash string and cli -1? 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 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 validate num4 fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 0.1" 255 "^$" 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 15.0 ok" new "netconf discard-changes"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 15.0" 0 "^$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli range dec64 multiple 30.0 fail" #-------- dec64 multiple ranges -3.5..-2.5 | 0.0 | 10.0..20.0
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 30.0" 255 "^$" # 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 "dec64 discard-changes" new "cli range dec64 multiple 0.1 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 num4 0.1" 255 '^CLI syntax error: "set num4 0.1": '"'"'0.1'"'"' is not a number$'
# Same with netconf new "cli range dec64 multiple 15.0 ok"
new "netconf range dec64 -3.59" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 15.0" 0 '^$'
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 30.0 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' 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" new "dec64 discard-changes"
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>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf range dec64 -3.5 validate ok" # Same with netconf
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></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" new "netconf range dec64 -3.59 validate fail"
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>]]>]]>$" 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 -2 validate fail" new "netconf range dec64 -3.5"
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><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" new "netconf range dec64 -3.5 validate ok"
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><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "netconf range dec64 -0.001 validate fail" new "netconf range dec64 -2"
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><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" new "netconf range dec64 -2 validate fail"
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><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 validate ok" new "netconf range dec64 -0.001"
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><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" new "netconf range dec64 -0.001 validate fail"
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><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 validate fail" new "netconf range dec64 0.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>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><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">0.0</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#----------------string ranges--------------------- new "netconf range dec64 0.0 validate ok"
#-------- len1 single range (2) 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 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.001"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 xy" 0 "^$" 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 "cli length test len1 3 error" new "netconf range dec64 +0.001 validate fail"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 hej" 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>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
new "netconf discard-changes" #----------------string ranges---------------------
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></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 length set len1 1" new "cli length test len1 2 OK"
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>]]>]]>$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 xy" 0 '^$'
new "netconf validate len1 1 wrong" new "cli length test len1 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>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 hej" 255 '^CLI syntax error: "set len1 hej": Unknown command$'
#-------- len2 range and blanks new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "cli length test len2 3 error" new "netconf length set len1 1"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 ab" 255 "^$" 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 "cli length test len2 42 ok" new "netconf validate len1 1 wrong"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 hejhophdsakjhkjsadhkjsahdkjsad" 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>len1</bad-element></error-info><error-severity>error</error-severity><error-message>string length out of range: 1</error-message></rpc-error></rpc-reply>]]>]]>$'
new "netconf discard-changes" #-------- len2 range and blanks
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#-------- len3 min max range new "cli length test len2 3 error"
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$'
new "cli range ptest len3 42 ok" new "cli length test len2 42 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len3 hsakjdhkjsahdkjsahdksahdksajdhsakjhd" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 '^$'
#-------- len4 multiple ranges 2..3 | 20-29 new "netconf discard-changes"
new "cli length test len4 1 error" 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 len4 a" 255 "^$"
new "cli length test len4 2 ok" #-------- len3 min max range
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 ab" 0 "^$"
new "cli length test len4 10 error" new "cli range ptest len3 42 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghij" 255 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len3 hsakjdhkjsahdkjsahdksahdksajdhsakjhd" 0 '^$'
new "cli length test len4 20 ok" #-------- len4 multiple ranges 2..3 | 20-29
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghija" 0 "^$" 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$'
new "cli length test len4 30 error" new "cli length test len4 2 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghijabcdefghij" 255 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 ab" 0 '^$'
# XSD schema -> POSIX ECE translation new "cli length test len4 10 error"
new "cli yang pattern \d ok" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghij" 255 '^CLI syntax error: "set len4 abcdefghij": Unknown command$'
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 0123" 0 "^$"
new "cli yang pattern \d error" new "cli length test len4 20 ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 01b2" 255 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghija" 0 '^$'
new "cli yang pattern \w ok" new "cli length test len4 30 error"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 abc9" 0 "^$" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghijabcdefghij" 255 '^CLI syntax error: "set len4 abcdefghijabcdefghijabcdefghij": Unknown command$'
new "cli yang pattern \w error" # XSD schema -> POSIX ECE translation
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 ab%3" 255 "^$" new "cli yang pattern \d ok"
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 0123" 0 '^$'
new "netconf pattern \w" new "cli yang pattern \d error"
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>]]>]]>$" 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 valid" new "cli yang pattern \w ok"
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 word4 abc9" 0 '^$'
new "netconf pattern \w error" new "cli yang 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>]]>]]>$" 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 pattern \w valid" new "netconf pattern \w"
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>]]>]]>$' 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 discard-changes" new "netconf pattern \w valid"
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><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>]]>]]>$"
#------ minus 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 "type with minus" new "netconf discard-changes"
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><discard-changes/></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" #------ minus
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set name my-name" 0 "^$"
if [ $BE -eq 0 ]; then new "type with minus"
exit # BE 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>]]>]]>$"
fi
new "Kill backend" new "validate minus"
# Check if premature kill expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
pid=`pgrep -u root -f clixon_backend`
if [ -z "$pid" ]; then #new "cli type with minus"
err "backend already dead" #expectfn "$clixon_cli -1f $cfg -l o -y $fyang set name my-name" 0 '^$'
fi
# kill backend if [ $BE -ne 0 ]; then
stop_backend -f $cfg 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
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