* Support for multiple patterns as described in RFC7950 Section 9.4.7
* Added regex cache to type resolution * Added compiled regexp parameter as part of internal yang type resolution functions * All internal `ys_populate_*()` functions (except ys_populate()) have switched parameters: `clicon_handle, yang_stmt *)`
This commit is contained in:
parent
efd1330550
commit
2fe185d683
21 changed files with 854 additions and 604 deletions
23
CHANGELOG.md
23
CHANGELOG.md
|
|
@ -3,6 +3,18 @@
|
||||||
## 3.10.0/4.0.0 (Upcoming)
|
## 3.10.0/4.0.0 (Upcoming)
|
||||||
|
|
||||||
### Major New features
|
### Major New features
|
||||||
|
* Regexp improvements: Libxml2 XSD, multiple patterns, optimization
|
||||||
|
* Support for multiple patterns as described in RFC7950 Section 9.4.7
|
||||||
|
* Libxml2 support for full XSD matching as alternative to Posix translation
|
||||||
|
* Configure with: `./configure --with-libxml2`
|
||||||
|
* Set `CLICON_YANG_REGEXP` to libxml2 (default is posix)
|
||||||
|
* Note you need to configure cligen as well with `--with-libxml2`
|
||||||
|
* Better compliance with XSD regexps in the default Posix translation regex mode
|
||||||
|
* Added `\p{L}` and `\p{N}`
|
||||||
|
* Added escaping of `$`
|
||||||
|
* Added clixon_util_regexp utility function
|
||||||
|
* Added extensive regexp test [test/test_pattern.sh] for both posix and libxml2
|
||||||
|
* Added regex cache to type resolution
|
||||||
* Yang "min-element" and "max-element" feature supported
|
* Yang "min-element" and "max-element" feature supported
|
||||||
* According to RFC 7950 7.7.4 and 7.7.5
|
* According to RFC 7950 7.7.4 and 7.7.5
|
||||||
* See (tests)[test/test_minmax.sh]
|
* See (tests)[test/test_minmax.sh]
|
||||||
|
|
@ -54,6 +66,9 @@
|
||||||
|
|
||||||
### API changes on existing features (you may need to change your code)
|
### API changes on existing features (you may need to change your code)
|
||||||
|
|
||||||
|
* Added compiled regexp parameter as part of internal yang type resolution functions
|
||||||
|
* `yang_type_resolve()`, `yang_type_get()`
|
||||||
|
* All internal `ys_populate_*()` functions (except ys_populate()) have switched parameters: `clicon_handle, yang_stmt *)`
|
||||||
* Added clicon_handle as parameter to all validate functions
|
* Added clicon_handle as parameter to all validate functions
|
||||||
* Just add `clixon_handle h` to all calls.
|
* Just add `clixon_handle h` to all calls.
|
||||||
* Clixon transaction mechanism has changed which may affect your backend plugin callbacks:
|
* Clixon transaction mechanism has changed which may affect your backend plugin callbacks:
|
||||||
|
|
@ -141,14 +156,6 @@
|
||||||
|
|
||||||
### Minor changes
|
### Minor changes
|
||||||
|
|
||||||
* Regexp improvements: Added libxml2 XSD regexp mode as alternative to posix translation
|
|
||||||
* Configure with: `./configure --with-libxml2`
|
|
||||||
* Set `CLICON_YANG_REGEXP` to libxml2 (default is posix)
|
|
||||||
* Better compliance with XSD regexps (when transforming to Posix regexps)
|
|
||||||
* Added `\p{L}` and `\p{N}`
|
|
||||||
* Added escaping of `$`
|
|
||||||
* Added clixon_util_regexp utility function
|
|
||||||
* Added regexp test [test/test_pattern.sh] for both posix and libxml2
|
|
||||||
* Yang state get improvements
|
* Yang state get improvements
|
||||||
* Integrated state and config into same tree on retrieval, not separate trees
|
* Integrated state and config into same tree on retrieval, not separate trees
|
||||||
* Added cli functions `cli_show_config_state()` and `cli_show_auto_state()` for showing combined config and state info.
|
* Added cli functions `cli_show_config_state()` and `cli_show_auto_state()` for showing combined config and state info.
|
||||||
|
|
|
||||||
|
|
@ -477,7 +477,7 @@ from_client_edit_config(clicon_handle h,
|
||||||
/* Cant do this earlier since we dont have a yang spec to
|
/* Cant do this earlier since we dont have a yang spec to
|
||||||
* the upper part of the tree, until we get the "config" tree.
|
* the upper part of the tree, until we get the "config" tree.
|
||||||
*/
|
*/
|
||||||
if (xml_apply0(xc, CX_ELMNT, xml_sort, NULL) < 0)
|
if (xml_apply0(xc, CX_ELMNT, xml_sort, h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((ret = xmldb_put(h, target, operation, xc, username, cbret)) < 0){
|
if ((ret = xmldb_put(h, target, operation, xc, username, cbret)) < 0){
|
||||||
clicon_debug(1, "%s ERROR PUT", __FUNCTION__);
|
clicon_debug(1, "%s ERROR PUT", __FUNCTION__);
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ startup_common(clicon_handle h,
|
||||||
/* After upgrading, XML tree needs to be sorted and yang spec populated */
|
/* After upgrading, XML tree needs to be sorted and yang spec populated */
|
||||||
if (xml_apply0(xt, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
if (xml_apply0(xt, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_apply0(xt, CX_ELMNT, xml_sort, NULL) < 0)
|
if (xml_apply0(xt, CX_ELMNT, xml_sort, h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Handcraft transition with with only add tree */
|
/* Handcraft transition with with only add tree */
|
||||||
td->td_target = xt;
|
td->td_target = xt;
|
||||||
|
|
|
||||||
|
|
@ -272,6 +272,42 @@ yang2cli_var_range(yang_stmt *ys,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Generate CLI code for Yang variable pattern statement
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] patterns Cvec of regexp patterns
|
||||||
|
* @param[out] cb Buffer where cligen code is written
|
||||||
|
* @see cv_validate_pattern for netconf validate code
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
yang2cli_var_pattern(clicon_handle h,
|
||||||
|
cvec *patterns,
|
||||||
|
cbuf *cb)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
char *mode;
|
||||||
|
cg_var *cvp;
|
||||||
|
char *pattern;
|
||||||
|
|
||||||
|
mode = clicon_yang_regexp(h);
|
||||||
|
cvp = NULL; /* Loop over compiled regexps */
|
||||||
|
while ((cvp = cvec_each(patterns, cvp)) != NULL){
|
||||||
|
pattern = cv_string_get(cvp);
|
||||||
|
if (strcmp(mode, "posix") == 0){
|
||||||
|
char *posix = NULL;
|
||||||
|
if (regexp_xsd2posix(pattern, &posix) < 0)
|
||||||
|
goto done;
|
||||||
|
cprintf(cb, " regexp:\"%s\"", posix);
|
||||||
|
if (posix)
|
||||||
|
free(posix);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cprintf(cb, " regexp:\"%s\"", pattern);
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/* Forward */
|
/* Forward */
|
||||||
static int yang2cli_stmt(clicon_handle h, yang_stmt *ys,
|
static int yang2cli_stmt(clicon_handle h, yang_stmt *ys,
|
||||||
enum genmodel_type gt, int level, cbuf *cb);
|
enum genmodel_type gt, int level, cbuf *cb);
|
||||||
|
|
@ -289,7 +325,7 @@ static int yang2cli_var_union(clicon_handle h, yang_stmt *ys, char *origtype,
|
||||||
* @param[in] cvtype
|
* @param[in] cvtype
|
||||||
* @param[in] options Flags field of optional values, see YANG_OPTIONS_*
|
* @param[in] options Flags field of optional values, see YANG_OPTIONS_*
|
||||||
* @param[in] cvv Cvec with array of range_min/range_max cv:s
|
* @param[in] cvv Cvec with array of range_min/range_max cv:s
|
||||||
* @param[in] pattern String of POSIX regexp pattern
|
* @param[in] patterns Cvec of regexp patterns
|
||||||
* @param[in] fraction for decimal64, how many digits after period
|
* @param[in] fraction for decimal64, how many digits after period
|
||||||
* @param[out] cb Buffer where cligen code is written
|
* @param[out] cb Buffer where cligen code is written
|
||||||
* @see yang_type_resolve for options and other arguments
|
* @see yang_type_resolve for options and other arguments
|
||||||
|
|
@ -302,7 +338,7 @@ yang2cli_var_sub(clicon_handle h,
|
||||||
enum cv_type cvtype,
|
enum cv_type cvtype,
|
||||||
int options,
|
int options,
|
||||||
cvec *cvv,
|
cvec *cvv,
|
||||||
char *pattern,
|
cvec *patterns,
|
||||||
uint8_t fraction_digits,
|
uint8_t fraction_digits,
|
||||||
cbuf *cb
|
cbuf *cb
|
||||||
)
|
)
|
||||||
|
|
@ -358,19 +394,9 @@ yang2cli_var_sub(clicon_handle h,
|
||||||
if (yang2cli_var_range(ys, options, cvv, cb) < 0)
|
if (yang2cli_var_range(ys, options, cvv, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (options & YANG_OPTIONS_PATTERN){
|
if (patterns && cvec_len(patterns)){
|
||||||
char *mode;
|
if (yang2cli_var_pattern(h, patterns, cb) < 0)
|
||||||
mode = clicon_yang_regexp(h);
|
|
||||||
if (strcmp(mode, "posix") == 0){
|
|
||||||
char *posix = NULL;
|
|
||||||
if (regexp_xsd2posix(pattern, &posix) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, " regexp:\"%s\"", posix);
|
|
||||||
if (posix)
|
|
||||||
free(posix);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cprintf(cb, " regexp:\"%s\"", pattern);
|
|
||||||
}
|
}
|
||||||
cprintf(cb, ">");
|
cprintf(cb, ">");
|
||||||
if (helptext)
|
if (helptext)
|
||||||
|
|
@ -402,16 +428,20 @@ yang2cli_var_union_one(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int options = 0;
|
int options = 0;
|
||||||
cvec *cvv = NULL;
|
cvec *cvv = NULL;
|
||||||
char *pattern = NULL;
|
cvec *patterns = NULL;
|
||||||
uint8_t fraction_digits = 0;
|
uint8_t fraction_digits = 0;
|
||||||
enum cv_type cvtype;
|
enum cv_type cvtype;
|
||||||
yang_stmt *ytype; /* resolved type */
|
yang_stmt *ytype; /* resolved type */
|
||||||
char *restype;
|
char *restype;
|
||||||
|
|
||||||
|
if ((patterns = cvec_new(0)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
/* Resolve the sub-union type to a resolved type */
|
/* Resolve the sub-union type to a resolved type */
|
||||||
if (yang_type_resolve(ys, ys, ytsub, /* in */
|
if (yang_type_resolve(ys, ys, ytsub, /* in */
|
||||||
&ytype, &options, /* resolved type */
|
&ytype, &options, /* resolved type */
|
||||||
&cvv, &pattern, &fraction_digits) < 0)
|
&cvv, patterns, NULL, &fraction_digits) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
restype = ytype?yang_argument_get(ytype):NULL;
|
restype = ytype?yang_argument_get(ytype):NULL;
|
||||||
|
|
||||||
|
|
@ -423,11 +453,13 @@ yang2cli_var_union_one(clicon_handle h,
|
||||||
if (clicon_type2cv(origtype, restype, ys, &cvtype) < 0)
|
if (clicon_type2cv(origtype, restype, ys, &cvtype) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((retval = yang2cli_var_sub(h, ys, ytype, helptext, cvtype,
|
if ((retval = yang2cli_var_sub(h, ys, ytype, helptext, cvtype,
|
||||||
options, cvv, pattern, fraction_digits, cb)) < 0)
|
options, cvv, patterns, fraction_digits, cb)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (patterns)
|
||||||
|
cvec_free(patterns);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -494,15 +526,19 @@ yang2cli_var(clicon_handle h,
|
||||||
yang_stmt *yrestype; /* resolved type */
|
yang_stmt *yrestype; /* resolved type */
|
||||||
char *restype; /* resolved type */
|
char *restype; /* resolved type */
|
||||||
cvec *cvv = NULL;
|
cvec *cvv = NULL;
|
||||||
char *pattern = NULL;
|
cvec *patterns = NULL;
|
||||||
uint8_t fraction_digits = 0;
|
uint8_t fraction_digits = 0;
|
||||||
enum cv_type cvtype;
|
enum cv_type cvtype;
|
||||||
int options = 0;
|
int options = 0;
|
||||||
int completionp;
|
int completionp;
|
||||||
char *type;
|
char *type;
|
||||||
|
|
||||||
|
if ((patterns = cvec_new(0)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (yang_type_get(ys, &origtype, &yrestype,
|
if (yang_type_get(ys, &origtype, &yrestype,
|
||||||
&options, &cvv, &pattern, &fraction_digits) < 0)
|
&options, &cvv, patterns, NULL, &fraction_digits) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
restype = yrestype?yang_argument_get(yrestype):NULL;
|
restype = yrestype?yang_argument_get(yrestype):NULL;
|
||||||
|
|
||||||
|
|
@ -539,7 +575,7 @@ yang2cli_var(clicon_handle h,
|
||||||
if (completionp)
|
if (completionp)
|
||||||
cprintf(cb, "(");
|
cprintf(cb, "(");
|
||||||
if ((retval = yang2cli_var_sub(h, ys, yrestype, helptext, cvtype,
|
if ((retval = yang2cli_var_sub(h, ys, yrestype, helptext, cvtype,
|
||||||
options, cvv, pattern, fraction_digits, cb)) < 0)
|
options, cvv, patterns, fraction_digits, cb)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (completionp){
|
if (completionp){
|
||||||
if (cli_expand_var_generate(h, ys, cvtype,
|
if (cli_expand_var_generate(h, ys, cvtype,
|
||||||
|
|
@ -552,6 +588,8 @@ yang2cli_var(clicon_handle h,
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (patterns)
|
||||||
|
cvec_free(patterns);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -153,8 +153,6 @@ char *yang_argument_get(yang_stmt *ys);
|
||||||
cg_var *yang_cv_get(yang_stmt *ys);
|
cg_var *yang_cv_get(yang_stmt *ys);
|
||||||
cvec *yang_cvec_get(yang_stmt *ys);
|
cvec *yang_cvec_get(yang_stmt *ys);
|
||||||
int yang_cvec_set(yang_stmt *ys, cvec *cvv);
|
int yang_cvec_set(yang_stmt *ys, cvec *cvv);
|
||||||
void *yang_regex_cache_get(yang_stmt *ys);
|
|
||||||
int yang_regex_cache_set(yang_stmt *ys, void *regex);
|
|
||||||
|
|
||||||
/* Other functions */
|
/* Other functions */
|
||||||
yang_stmt *yspec_new(void);
|
yang_stmt *yspec_new(void);
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,7 @@
|
||||||
*/
|
*/
|
||||||
#define YANG_OPTIONS_LENGTH 0x01
|
#define YANG_OPTIONS_LENGTH 0x01
|
||||||
#define YANG_OPTIONS_RANGE 0x02
|
#define YANG_OPTIONS_RANGE 0x02
|
||||||
#define YANG_OPTIONS_PATTERN 0x04
|
#define YANG_OPTIONS_FRACTION_DIGITS 0x04
|
||||||
#define YANG_OPTIONS_FRACTION_DIGITS 0x08
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Types
|
* Types
|
||||||
|
|
@ -57,10 +56,11 @@ typedef struct yang_type_cache yang_type_cache;
|
||||||
*/
|
*/
|
||||||
int yang_type_cache_set(yang_type_cache **ycache,
|
int yang_type_cache_set(yang_type_cache **ycache,
|
||||||
yang_stmt *resolved, int options,
|
yang_stmt *resolved, int options,
|
||||||
cvec *cvv, char *pattern, uint8_t fraction);
|
cvec *cvv, cvec *patterns, cvec *regexps,
|
||||||
|
uint8_t fraction);
|
||||||
int yang_type_cache_get(yang_type_cache *ycache, yang_stmt **resolved,
|
int yang_type_cache_get(yang_type_cache *ycache, yang_stmt **resolved,
|
||||||
int *options, cvec **cvv, char **pattern,
|
int *options, cvec **cvv, cvec *patterns,
|
||||||
uint8_t *fraction);
|
cvec *regexps, uint8_t *fraction);
|
||||||
int yang_type_cache_cp(yang_type_cache **ycnew, yang_type_cache *ycold);
|
int yang_type_cache_cp(yang_type_cache **ycnew, yang_type_cache *ycold);
|
||||||
int yang_type_cache_free(yang_type_cache *ycache);
|
int yang_type_cache_free(yang_type_cache *ycache);
|
||||||
int ys_resolve_type(yang_stmt *ys, void *arg);
|
int ys_resolve_type(yang_stmt *ys, void *arg);
|
||||||
|
|
@ -70,11 +70,14 @@ yang_stmt *yang_find_identity(yang_stmt *ys, char *identity);
|
||||||
int ys_cv_validate(clicon_handle h, cg_var *cv, yang_stmt *ys, char **reason);
|
int ys_cv_validate(clicon_handle h, cg_var *cv, yang_stmt *ys, char **reason);
|
||||||
int clicon_type2cv(char *type, char *rtype, yang_stmt *ys, enum cv_type *cvtype);
|
int clicon_type2cv(char *type, char *rtype, yang_stmt *ys, enum cv_type *cvtype);
|
||||||
int yang_type_get(yang_stmt *ys, char **otype, yang_stmt **restype,
|
int yang_type_get(yang_stmt *ys, char **otype, yang_stmt **restype,
|
||||||
int *options, cvec **cvv, char **pattern,
|
int *options, cvec **cvv,
|
||||||
|
cvec *patterns, cvec *regexps,
|
||||||
uint8_t *fraction_digits);
|
uint8_t *fraction_digits);
|
||||||
int yang_type_resolve(yang_stmt *yorig, yang_stmt *ys, yang_stmt *ytype,
|
int yang_type_resolve(yang_stmt *yorig, yang_stmt *ys,
|
||||||
|
yang_stmt *ytype,
|
||||||
yang_stmt **restype, int *options,
|
yang_stmt **restype, int *options,
|
||||||
cvec **cvv, char **pattern, uint8_t *fraction);
|
cvec **cvv, cvec *patterns, cvec *regexps,
|
||||||
|
uint8_t *fraction);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _CLIXON_YANG_TYPE_H_ */
|
#endif /* _CLIXON_YANG_TYPE_H_ */
|
||||||
|
|
|
||||||
|
|
@ -437,7 +437,7 @@ xmldb_get_nocache(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Add default values (if not set) */
|
/* Add default values (if not set) */
|
||||||
if (xml_apply(xt, CX_ELMNT, xml_default, NULL) < 0)
|
if (xml_apply(xt, CX_ELMNT, xml_default, h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
#if 0 /* debug */
|
#if 0 /* debug */
|
||||||
if (xml_apply0(xt, -1, xml_sort_verify, NULL) < 0)
|
if (xml_apply0(xt, -1, xml_sort_verify, NULL) < 0)
|
||||||
|
|
@ -542,7 +542,7 @@ xmldb_get_cache(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
/* x1t is wrong here should be <config><system>.. but is <system>.. */
|
/* x1t is wrong here should be <config><system>.. but is <system>.. */
|
||||||
/* XXX where should we apply default values once? */
|
/* XXX where should we apply default values once? */
|
||||||
if (xml_apply(x1t, CX_ELMNT, xml_default, NULL) < 0)
|
if (xml_apply(x1t, CX_ELMNT, xml_default, h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Copy the matching parts of the (relevant) XML tree.
|
/* Copy the matching parts of the (relevant) XML tree.
|
||||||
|
|
@ -622,7 +622,7 @@ xmldb_get_zerocopy(clicon_handle h,
|
||||||
xml_apply_ancestor(x0, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_CHANGE);
|
xml_apply_ancestor(x0, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_CHANGE);
|
||||||
}
|
}
|
||||||
/* Apply default values (removed in clear function) */
|
/* Apply default values (removed in clear function) */
|
||||||
if (xml_apply(x0t, CX_ELMNT, xml_default, NULL) < 0)
|
if (xml_apply(x0t, CX_ELMNT, xml_default, h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (debug>1)
|
if (debug>1)
|
||||||
clicon_xml2file(stderr, x0t, 0, 1);
|
clicon_xml2file(stderr, x0t, 0, 1);
|
||||||
|
|
|
||||||
|
|
@ -398,7 +398,7 @@ text_modify(clicon_handle h,
|
||||||
} /* else Y_CONTAINER */
|
} /* else Y_CONTAINER */
|
||||||
#ifndef USE_XML_INSERT
|
#ifndef USE_XML_INSERT
|
||||||
if (changed)
|
if (changed)
|
||||||
xml_sort(x0p, NULL);
|
xml_sort(x0p, h);
|
||||||
#endif
|
#endif
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ parse_configfile(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_apply0(xc, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
if (xml_apply0(xc, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_apply0(xc, CX_ELMNT, xml_sort, NULL) < 0)
|
if (xml_apply0(xc, CX_ELMNT, xml_sort, h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -192,7 +192,7 @@ parse_configfile(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (xml_apply0(xc, CX_ELMNT, xml_default, yspec) < 0)
|
if (xml_apply0(xc, CX_ELMNT, xml_default, h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((cbret = cbuf_new()) == NULL){
|
if ((cbret = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
|
|
|
||||||
|
|
@ -2394,51 +2394,3 @@ clicon_log_xml(int level,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Turn this on to get a xml parse and pretty print test program
|
|
||||||
* Usage: xpath
|
|
||||||
* read xml from input
|
|
||||||
* Example compile:
|
|
||||||
gcc -g -o xml -I. -I../clixon ./clixon_xml.c -lclixon -lcligen
|
|
||||||
* Example run:
|
|
||||||
echo "<a><b/></a>" | xml
|
|
||||||
*/
|
|
||||||
#if 1 /* Test program */
|
|
||||||
|
|
||||||
static int
|
|
||||||
usage(char *argv0)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "usage:%s.\n\tInput on stdin\n", argv0);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
cxobj *xt = NULL;
|
|
||||||
cxobj *xc;
|
|
||||||
cbuf *cb = cbuf_new();
|
|
||||||
|
|
||||||
if (argc != 1){
|
|
||||||
usage(argv[0]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (xml_parse_file(0, "</config>", NULL, &xt) < 0){
|
|
||||||
fprintf(stderr, "xml parse error %s\n", clicon_err_reason);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
xc = NULL;
|
|
||||||
while ((xc = xml_child_each(xt, xc, -1)) != NULL) {
|
|
||||||
xmltree2cbuf(cb, xc, 0); /* dump data structures */
|
|
||||||
//clicon_xml2cbuf(cb, xc, 0, 1); /* print xml */
|
|
||||||
}
|
|
||||||
fprintf(stdout, "%s", cbuf_get(cb));
|
|
||||||
if (xt)
|
|
||||||
xml_free(xt);
|
|
||||||
if (cb)
|
|
||||||
cbuf_free(cb);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* Test program */
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3004,7 +3004,7 @@ yang_enum_int_value(cxobj *node,
|
||||||
if ((ytype = yang_find(ys, Y_TYPE, NULL)) == NULL)
|
if ((ytype = yang_find(ys, Y_TYPE, NULL)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (yang_type_resolve(ys, ys, ytype, &yrestype,
|
if (yang_type_resolve(ys, ys, ytype, &yrestype,
|
||||||
NULL, NULL, NULL, NULL) < 0)
|
NULL, NULL, NULL, NULL, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (yrestype==NULL || strcmp(yrestype->ys_argument, "enumeration"))
|
if (yrestype==NULL || strcmp(yrestype->ys_argument, "enumeration"))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ xml_cv_cache(cxobj *x,
|
||||||
goto ok;
|
goto ok;
|
||||||
if ((y = xml_spec(x)) == NULL)
|
if ((y = xml_spec(x)) == NULL)
|
||||||
goto ok;
|
goto ok;
|
||||||
if (yang_type_get(y, NULL, &yrestype, &options, NULL, NULL, &fraction) < 0)
|
if (yang_type_get(y, NULL, &yrestype, &options, NULL, NULL, NULL, &fraction) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
yang2cv_type(yang_argument_get(yrestype), &cvtype);
|
yang2cv_type(yang_argument_get(yrestype), &cvtype);
|
||||||
if (cvtype==CGV_ERR){
|
if (cvtype==CGV_ERR){
|
||||||
|
|
|
||||||
|
|
@ -239,30 +239,6 @@ yang_cvec_set(yang_stmt *ys,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Get regular expression cache - the compiled regex
|
|
||||||
* @param[in] ys Yang statement node
|
|
||||||
* @retval re Compiled regex
|
|
||||||
* @see regcomp
|
|
||||||
*/
|
|
||||||
void*
|
|
||||||
yang_regex_cache_get(yang_stmt *ys)
|
|
||||||
{
|
|
||||||
return ys->ys_regex_cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Set regular expression cache - the compiled regex
|
|
||||||
* @param[in] ys Yang statement node
|
|
||||||
* @param[in] re Compiled regex
|
|
||||||
* @see regcomp
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
yang_regex_cache_set(yang_stmt *ys,
|
|
||||||
void *regex)
|
|
||||||
{
|
|
||||||
ys->ys_regex_cache = regex;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* End access functions */
|
/* End access functions */
|
||||||
|
|
||||||
/*! Create new yang specification
|
/*! Create new yang specification
|
||||||
|
|
@ -307,17 +283,6 @@ ys_new(enum rfc_6020 keyw)
|
||||||
return ys;
|
return ys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
yang_regex_cache_free(yang_stmt *ys)
|
|
||||||
{
|
|
||||||
if (ys->ys_regex_cache){
|
|
||||||
regfree(ys->ys_regex_cache);
|
|
||||||
free(ys->ys_regex_cache);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Free a single yang statement */
|
/*! Free a single yang statement */
|
||||||
static int
|
static int
|
||||||
ys_free1(yang_stmt *ys)
|
ys_free1(yang_stmt *ys)
|
||||||
|
|
@ -332,7 +297,6 @@ ys_free1(yang_stmt *ys)
|
||||||
cvec_free(ys->ys_cvec);
|
cvec_free(ys->ys_cvec);
|
||||||
if (ys->ys_typecache)
|
if (ys->ys_typecache)
|
||||||
yang_type_cache_free(ys->ys_typecache);
|
yang_type_cache_free(ys->ys_typecache);
|
||||||
yang_regex_cache_free(ys);
|
|
||||||
free(ys);
|
free(ys);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1344,8 +1308,8 @@ yang_print_cbuf(cbuf *cb,
|
||||||
* @retval -1 Error with clicon_err called
|
* @retval -1 Error with clicon_err called
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ys_populate_leaf(yang_stmt *ys,
|
ys_populate_leaf(clicon_handle h,
|
||||||
void *arg)
|
yang_stmt *ys)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cg_var *cv = NULL;
|
cg_var *cv = NULL;
|
||||||
|
|
@ -1363,7 +1327,7 @@ ys_populate_leaf(yang_stmt *ys,
|
||||||
|
|
||||||
yparent = ys->ys_parent; /* Find parent: list/container */
|
yparent = ys->ys_parent; /* Find parent: list/container */
|
||||||
/* 1. Find type specification and set cv type accordingly */
|
/* 1. Find type specification and set cv type accordingly */
|
||||||
if (yang_type_get(ys, &type, &yrestype, &options, NULL, NULL, &fraction_digits)
|
if (yang_type_get(ys, &type, &yrestype, &options, NULL, NULL, NULL, &fraction_digits)
|
||||||
< 0)
|
< 0)
|
||||||
goto done;
|
goto done;
|
||||||
restype = yrestype?yrestype->ys_argument:NULL;
|
restype = yrestype?yrestype->ys_argument:NULL;
|
||||||
|
|
@ -1416,8 +1380,8 @@ ys_populate_leaf(yang_stmt *ys,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ys_populate_list(yang_stmt *ys,
|
ys_populate_list(clicon_handle h,
|
||||||
void *arg)
|
yang_stmt *ys)
|
||||||
{
|
{
|
||||||
yang_stmt *ykey;
|
yang_stmt *ykey;
|
||||||
|
|
||||||
|
|
@ -1523,8 +1487,8 @@ range_parse(yang_stmt *ys,
|
||||||
* ascending order
|
* ascending order
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ys_populate_range(yang_stmt *ys,
|
ys_populate_range(clicon_handle h,
|
||||||
void *arg)
|
yang_stmt *ys)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *yparent; /* type */
|
yang_stmt *yparent; /* type */
|
||||||
|
|
@ -1541,7 +1505,7 @@ ys_populate_range(yang_stmt *ys,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (yang_type_resolve(ys, ys, (yang_stmt*)yparent, &yrestype,
|
if (yang_type_resolve(ys, ys, (yang_stmt*)yparent, &yrestype,
|
||||||
&options, NULL, NULL, &fraction_digits) < 0)
|
&options, NULL, NULL, NULL, &fraction_digits) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
restype = yrestype?yrestype->ys_argument:NULL;
|
restype = yrestype?yrestype->ys_argument:NULL;
|
||||||
origtype = yarg_id((yang_stmt*)yparent);
|
origtype = yarg_id((yang_stmt*)yparent);
|
||||||
|
|
@ -1572,8 +1536,8 @@ ys_populate_range(yang_stmt *ys,
|
||||||
* be disjoint and MUST be in ascending order.
|
* be disjoint and MUST be in ascending order.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ys_populate_length(yang_stmt *ys,
|
ys_populate_length(clicon_handle h,
|
||||||
void *arg)
|
yang_stmt *ys)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *yparent; /* type */
|
yang_stmt *yparent; /* type */
|
||||||
|
|
@ -1598,8 +1562,9 @@ ys_populate_length(yang_stmt *ys,
|
||||||
* @
|
* @
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ys_populate_type(yang_stmt *ys,
|
ys_populate_type(clicon_handle h,
|
||||||
void *arg)
|
yang_stmt *ys)
|
||||||
|
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *ybase;
|
yang_stmt *ybase;
|
||||||
|
|
@ -1636,7 +1601,8 @@ ys_populate_type(yang_stmt *ys,
|
||||||
* @see validate_identityref which in runtime validates actual values
|
* @see validate_identityref which in runtime validates actual values
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ys_populate_identity(yang_stmt *ys,
|
ys_populate_identity(clicon_handle h,
|
||||||
|
yang_stmt *ys,
|
||||||
char *idref)
|
char *idref)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -1695,7 +1661,7 @@ ys_populate_identity(yang_stmt *ys,
|
||||||
cv = NULL;
|
cv = NULL;
|
||||||
}
|
}
|
||||||
/* Transitive to the root */
|
/* Transitive to the root */
|
||||||
if (ys_populate_identity(ybaseid, idref) < 0)
|
if (ys_populate_identity(h, ybaseid, idref) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
@ -1800,7 +1766,8 @@ ys_populate_feature(clicon_handle h,
|
||||||
/*! Populate the unique statement with a cvec
|
/*! Populate the unique statement with a cvec
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ys_populate_unique(yang_stmt *ys)
|
ys_populate_unique(clicon_handle h,
|
||||||
|
yang_stmt *ys)
|
||||||
{
|
{
|
||||||
if (ys->ys_cvec)
|
if (ys->ys_cvec)
|
||||||
cvec_free(ys->ys_cvec);
|
cvec_free(ys->ys_cvec);
|
||||||
|
|
@ -1812,7 +1779,8 @@ ys_populate_unique(yang_stmt *ys)
|
||||||
/*! Populate unknown node with extension
|
/*! Populate unknown node with extension
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ys_populate_unknown(yang_stmt *ys)
|
ys_populate_unknown(clicon_handle h,
|
||||||
|
yang_stmt *ys)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int cvret;
|
int cvret;
|
||||||
|
|
@ -1865,24 +1833,24 @@ ys_populate(yang_stmt *ys,
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
// clicon_handle h = (clicon_handle)arg;
|
clicon_handle h = (clicon_handle)arg;
|
||||||
|
|
||||||
switch(ys->ys_keyword){
|
switch(ys->ys_keyword){
|
||||||
case Y_LEAF:
|
case Y_LEAF:
|
||||||
case Y_LEAF_LIST:
|
case Y_LEAF_LIST:
|
||||||
if (ys_populate_leaf(ys, NULL) < 0)
|
if (ys_populate_leaf(h, ys) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_LIST:
|
case Y_LIST:
|
||||||
if (ys_populate_list(ys, NULL) < 0)
|
if (ys_populate_list(h, ys) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_RANGE:
|
case Y_RANGE:
|
||||||
if (ys_populate_range(ys, NULL) < 0)
|
if (ys_populate_range(h, ys) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_LENGTH:
|
case Y_LENGTH:
|
||||||
if (ys_populate_length(ys, NULL) < 0)
|
if (ys_populate_length(h, ys) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_MANDATORY: /* call yang_mandatory() to check if set */
|
case Y_MANDATORY: /* call yang_mandatory() to check if set */
|
||||||
|
|
@ -1891,19 +1859,19 @@ ys_populate(yang_stmt *ys,
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_TYPE:
|
case Y_TYPE:
|
||||||
if (ys_populate_type(ys, NULL) < 0)
|
if (ys_populate_type(h, ys) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_IDENTITY:
|
case Y_IDENTITY:
|
||||||
if (ys_populate_identity(ys, NULL) < 0)
|
if (ys_populate_identity(h, ys, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_UNIQUE:
|
case Y_UNIQUE:
|
||||||
if (ys_populate_unique(ys) < 0)
|
if (ys_populate_unique(h, ys) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case Y_UNKNOWN:
|
case Y_UNKNOWN:
|
||||||
if (ys_populate_unknown(ys) < 0)
|
if (ys_populate_unknown(h, ys) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -2631,7 +2599,7 @@ yang_parse_post(clicon_handle h,
|
||||||
* Must be done using static binding.
|
* Must be done using static binding.
|
||||||
*/
|
*/
|
||||||
for (i=modnr; i<yspec->ys_len; i++)
|
for (i=modnr; i<yspec->ys_len; i++)
|
||||||
if (yang_apply(yspec->ys_stmt[i], Y_TYPE, ys_resolve_type, NULL) < 0)
|
if (yang_apply(yspec->ys_stmt[i], Y_TYPE, ys_resolve_type, h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Up to here resolving is made in the context they are defined, rather
|
/* Up to here resolving is made in the context they are defined, rather
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,8 @@ struct yang_type_cache{
|
||||||
cvec *yc_cvv; /* Range and length restriction. (if YANG_OPTION_
|
cvec *yc_cvv; /* Range and length restriction. (if YANG_OPTION_
|
||||||
LENGTH|RANGE. Can be a vector if multiple
|
LENGTH|RANGE. Can be a vector if multiple
|
||||||
ranges*/
|
ranges*/
|
||||||
char *yc_pattern; /* regex (posix) (if YANG_OPTIONS_PATTERN) */
|
cvec *yc_patterns; /* list of regexp, if cvec_len() > 0 */
|
||||||
|
cvec *yc_regexps; /* list of _compiled_ regexp, if cvec_len() > 0 */
|
||||||
uint8_t yc_fraction; /* Fraction digits for decimal64 (if
|
uint8_t yc_fraction; /* Fraction digits for decimal64 (if
|
||||||
YANG_OPTIONS_FRACTION_DIGITS */
|
YANG_OPTIONS_FRACTION_DIGITS */
|
||||||
yang_stmt *yc_resolved; /* Resolved type object, can be NULL - note direct ptr */
|
yang_stmt *yc_resolved; /* Resolved type object, can be NULL - note direct ptr */
|
||||||
|
|
@ -95,7 +96,6 @@ 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 */
|
||||||
void *ys_regex_cache; /* regex cache */
|
|
||||||
int _ys_vector_i; /* internal use: yn_each */
|
int _ys_vector_i; /* internal use: yn_each */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,7 @@ identifier [A-Za-z_][A-Za-z0-9_\-\.]*
|
||||||
<KEYWORD>key { BEGIN(STRING); return K_KEY; }
|
<KEYWORD>key { BEGIN(STRING); return K_KEY; }
|
||||||
<KEYWORD>length { BEGIN(STRING); return K_LENGTH; }
|
<KEYWORD>length { BEGIN(STRING); return K_LENGTH; }
|
||||||
<KEYWORD>max-elements { BEGIN(STRING); return K_MAX_ELEMENTS; }
|
<KEYWORD>max-elements { BEGIN(STRING); return K_MAX_ELEMENTS; }
|
||||||
|
<KEYWORD>modifier { BEGIN(STRING); return K_MODIFIER; }
|
||||||
<KEYWORD>must { BEGIN(STRING); return K_MUST; }
|
<KEYWORD>must { BEGIN(STRING); return K_MUST; }
|
||||||
<KEYWORD>namespace { BEGIN(STRING); return K_NAMESPACE; }
|
<KEYWORD>namespace { BEGIN(STRING); return K_NAMESPACE; }
|
||||||
<KEYWORD>ordered-by { BEGIN(STRING); return K_ORDERED_BY; }
|
<KEYWORD>ordered-by { BEGIN(STRING); return K_ORDERED_BY; }
|
||||||
|
|
|
||||||
|
|
@ -863,7 +863,7 @@ pattern_substmt : modifier_stmt { clicon_debug(2,"pattern-substmt -> modifier
|
||||||
;
|
;
|
||||||
|
|
||||||
modifier_stmt : K_MODIFIER string stmtend
|
modifier_stmt : K_MODIFIER string stmtend
|
||||||
{ if (ysp_add(_yy, Y_DEFAULT, $2, NULL)== NULL) _YYERROR("modifier_stmt");
|
{ if (ysp_add(_yy, Y_MODIFIER, $2, NULL)== NULL) _YYERROR("modifier_stmt");
|
||||||
clicon_debug(2,"modifier-stmt -> MODIFIER string"); }
|
clicon_debug(2,"modifier-stmt -> MODIFIER string"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,20 @@
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
* Yang type related functions
|
* Yang type related functions
|
||||||
|
* Part of this is type resolving which is pretty complex
|
||||||
|
*
|
||||||
|
* (called at parse / set cache)
|
||||||
|
* ys_resolve_type --+ ys_populate_range, yang_enum_int_value(NULL)
|
||||||
|
* \ | cml
|
||||||
|
* v v v
|
||||||
|
* yang_type_get --> yang_type_resolve --> resolve_restrictions
|
||||||
|
* (leaf(list) front) (recursive core fn) (regexps, length, ranges, ...)
|
||||||
|
* ^ ^ ^ ^
|
||||||
|
* | | | |
|
||||||
|
* | yang2cli_var | yang2cli_var_union_one
|
||||||
|
* ys_cv_validate ys_cv_validate_union_one
|
||||||
|
* |
|
||||||
|
* ys_populate_leaf, xml_cv_cache (NULL)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
|
@ -145,7 +159,8 @@ yang_type_cache_set(yang_type_cache **ycache0,
|
||||||
yang_stmt *resolved,
|
yang_stmt *resolved,
|
||||||
int options,
|
int options,
|
||||||
cvec *cvv,
|
cvec *cvv,
|
||||||
char *pattern,
|
cvec *patterns,
|
||||||
|
cvec *regexps,
|
||||||
uint8_t fraction)
|
uint8_t fraction)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -166,8 +181,12 @@ yang_type_cache_set(yang_type_cache **ycache0,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pattern && (ycache->yc_pattern = strdup(pattern)) == NULL){
|
if (patterns && (ycache->yc_patterns = cvec_dup(patterns)) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "strdup");
|
clicon_err(OE_UNIX, errno, "cvec_dup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (regexps && (ycache->yc_regexps = cvec_dup(regexps)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_dup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
ycache->yc_fraction = fraction;
|
ycache->yc_fraction = fraction;
|
||||||
|
|
@ -176,26 +195,42 @@ yang_type_cache_set(yang_type_cache **ycache0,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Get individual fields (direct/destructively) from yang type cache. */
|
/*! Get individual fields (direct/destructively) from yang type cache.
|
||||||
|
* @param[out] patterns Initialized cvec of regexp patterns strings
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
yang_type_cache_get(yang_type_cache *ycache,
|
yang_type_cache_get(yang_type_cache *ycache,
|
||||||
yang_stmt **resolved,
|
yang_stmt **resolved,
|
||||||
int *options,
|
int *options,
|
||||||
cvec **cvv,
|
cvec **cvv,
|
||||||
char **pattern,
|
cvec *patterns,
|
||||||
|
cvec *regexps,
|
||||||
uint8_t *fraction)
|
uint8_t *fraction)
|
||||||
{
|
{
|
||||||
|
int retval = -1;
|
||||||
|
cg_var *cv = NULL;
|
||||||
|
|
||||||
if (resolved)
|
if (resolved)
|
||||||
*resolved = ycache->yc_resolved;
|
*resolved = ycache->yc_resolved;
|
||||||
if (options)
|
if (options)
|
||||||
*options = ycache->yc_options;
|
*options = ycache->yc_options;
|
||||||
if (cvv)
|
if (cvv)
|
||||||
*cvv = ycache->yc_cvv;
|
*cvv = ycache->yc_cvv;
|
||||||
if (pattern)
|
if (patterns){
|
||||||
*pattern = ycache->yc_pattern;
|
cv = NULL;
|
||||||
|
while ((cv = cvec_each(ycache->yc_patterns, cv)) != NULL)
|
||||||
|
cvec_append_var(patterns, cv);
|
||||||
|
}
|
||||||
|
if (regexps){
|
||||||
|
cv = NULL;
|
||||||
|
while ((cv = cvec_each(ycache->yc_regexps, cv)) != NULL)
|
||||||
|
cvec_append_var(regexps, cv);
|
||||||
|
}
|
||||||
if (fraction)
|
if (fraction)
|
||||||
*fraction = ycache->yc_fraction;
|
*fraction = ycache->yc_fraction;
|
||||||
return 0;
|
retval = 0;
|
||||||
|
// done:
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -205,15 +240,28 @@ yang_type_cache_cp(yang_type_cache **ycnew,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int options;
|
int options;
|
||||||
cvec *cvv;
|
cvec *cvv;
|
||||||
char *pattern;
|
cvec *patterns = NULL;
|
||||||
|
cvec *regexps = NULL;
|
||||||
uint8_t fraction;
|
uint8_t fraction;
|
||||||
yang_stmt *resolved;
|
yang_stmt *resolved;
|
||||||
|
|
||||||
yang_type_cache_get(ycold, &resolved, &options, &cvv, &pattern, &fraction);
|
if ((patterns = cvec_new(0)) == NULL){
|
||||||
if (yang_type_cache_set(ycnew, resolved, options, cvv, pattern, fraction) < 0)
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((regexps = cvec_new(0)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
yang_type_cache_get(ycold, &resolved, &options, &cvv, patterns, regexps, &fraction);
|
||||||
|
if (yang_type_cache_set(ycnew, resolved, options, cvv, patterns, regexps, fraction) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (patterns)
|
||||||
|
cvec_free(patterns);
|
||||||
|
if (regexps)
|
||||||
|
cvec_free(regexps);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,12 +270,59 @@ yang_type_cache_free(yang_type_cache *ycache)
|
||||||
{
|
{
|
||||||
if (ycache->yc_cvv)
|
if (ycache->yc_cvv)
|
||||||
cvec_free(ycache->yc_cvv);
|
cvec_free(ycache->yc_cvv);
|
||||||
if (ycache->yc_pattern)
|
if (ycache->yc_patterns)
|
||||||
free(ycache->yc_pattern);
|
cvec_free(ycache->yc_patterns);
|
||||||
|
if (ycache->yc_regexps)
|
||||||
|
cvec_free(ycache->yc_regexps);
|
||||||
free(ycache);
|
free(ycache);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compile yang patterns in string form to regex compiled void* form
|
||||||
|
* and re-store into "patterns" cvec.
|
||||||
|
* This is done here instead of deep in resolve code (resolve_restrictions)
|
||||||
|
* since it id dependent on clicon_handle.
|
||||||
|
* The downside is that all accesses to "patterns" must pass via the cache.
|
||||||
|
* If calls to yang_type_resolve is made without the cache is set, will be
|
||||||
|
* wrong.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
compile_pattern2regexp(clicon_handle h,
|
||||||
|
cvec *patterns,
|
||||||
|
cvec *regexps)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
cg_var *pcv; /* pattern cv */
|
||||||
|
cg_var *rcv; /* regexp cv */
|
||||||
|
void *re;
|
||||||
|
int ret;
|
||||||
|
char *pattern;
|
||||||
|
|
||||||
|
pcv = NULL;
|
||||||
|
while ((pcv = cvec_each(patterns, pcv)) != NULL){
|
||||||
|
if (cv_type_get(pcv) == CGV_VOID)
|
||||||
|
continue; /* already compiled */
|
||||||
|
pattern = cv_string_get(pcv);
|
||||||
|
/* Compile yang pattern. handle necessary to select regex engine */
|
||||||
|
if ((ret = regex_compile(h, pattern, &re)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0){
|
||||||
|
clicon_err(OE_YANG, errno, "regexp compile fail: \"%s\"",
|
||||||
|
pattern);
|
||||||
|
goto done;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((rcv = cvec_add(regexps, CGV_VOID)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_add");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cv_void_set(rcv, re);
|
||||||
|
}
|
||||||
|
retval = 1;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Resolve types: populate type caches
|
/*! Resolve types: populate type caches
|
||||||
* @param[in] ys This is a type statement
|
* @param[in] ys This is a type statement
|
||||||
* @param[in] arg Not used
|
* @param[in] arg Not used
|
||||||
|
|
@ -238,28 +333,55 @@ int
|
||||||
ys_resolve_type(yang_stmt *ys,
|
ys_resolve_type(yang_stmt *ys,
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
|
clicon_handle h = (clicon_handle)arg;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int options = 0x0;
|
int options = 0x0;
|
||||||
cvec *cvv = NULL;
|
cvec *cvv = NULL;
|
||||||
char *pattern = NULL;
|
cvec *patterns = NULL;
|
||||||
|
cvec *regexps = NULL;
|
||||||
uint8_t fraction = 0;
|
uint8_t fraction = 0;
|
||||||
yang_stmt *resolved = NULL;
|
yang_stmt *resolved = NULL;
|
||||||
|
|
||||||
assert(ys->ys_keyword == Y_TYPE);
|
if (yang_keyword_get(ys) != Y_TYPE){
|
||||||
|
clicon_err(OE_YANG, EINVAL, "Expected Y_TYPE");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((patterns = cvec_new(0)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
/* Recursively resolve ys -> resolve with restrictions(options, etc)
|
/* Recursively resolve ys -> resolve with restrictions(options, etc)
|
||||||
* Note that the resolved type could be ys itself.
|
* Note that the resolved type could be ys itself.
|
||||||
*/
|
*/
|
||||||
if (yang_type_resolve((yang_stmt*)ys->ys_parent, (yang_stmt*)ys->ys_parent,
|
if (yang_type_resolve(ys->ys_parent, ys->ys_parent,
|
||||||
ys, &resolved,
|
ys, &resolved,
|
||||||
&options, &cvv, &pattern, &fraction) < 0)
|
&options, &cvv, patterns, NULL, &fraction) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Cache the resolve locally */
|
/* If pattern strings, then compile regexps as well */
|
||||||
|
if (cvec_len(patterns)){
|
||||||
|
if ((regexps = cvec_new(0)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Compile from pattern strings to compiled regexps */
|
||||||
|
if (compile_pattern2regexp(h, patterns, regexps) < 1)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Cache the type resolving locally. Only place where this is done.
|
||||||
|
* Why not do it in yang_type_resolve? (compile regexps needs clicon_handle)
|
||||||
|
*/
|
||||||
if (yang_type_cache_set(&ys->ys_typecache,
|
if (yang_type_cache_set(&ys->ys_typecache,
|
||||||
resolved, options, cvv, pattern, fraction) < 0)
|
resolved, options, cvv,
|
||||||
|
patterns, regexps,
|
||||||
|
fraction) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (patterns)
|
||||||
|
cvec_free(patterns);
|
||||||
|
if (regexps)
|
||||||
|
cvec_free(regexps);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -368,6 +490,48 @@ clicon_type2cv(char *origtype,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Validate CLIgen variable with pattern statements
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] regexps Vector of compiled regexps
|
||||||
|
* @param[out] reason If given, and return value is 0, contains malloced string
|
||||||
|
* @retval -1 Error (fatal), with errno set to indicate error
|
||||||
|
* @retval 0 Validation not OK, malloced reason is returned. Free reason with free()
|
||||||
|
* @retval 1 Validation OK
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
cv_validate_pattern(clicon_handle h,
|
||||||
|
cvec *regexps,
|
||||||
|
yang_stmt *yrestype,
|
||||||
|
char *str,
|
||||||
|
char **reason)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
cg_var *cvr;
|
||||||
|
void *re = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
cvr = NULL; /* Loop over compiled regexps */
|
||||||
|
while ((cvr = cvec_each(regexps, cvr)) != NULL){
|
||||||
|
re = cv_void_get(cvr);
|
||||||
|
if ((ret = regex_exec(h, re, str?str:"")) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0){
|
||||||
|
if (reason)
|
||||||
|
*reason = cligen_reason("regexp match fail: pattern does not match %s",
|
||||||
|
str);
|
||||||
|
goto fail;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retval = 1; /* match */
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
fail:
|
||||||
|
retval = 0; /* validation failed */
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* cf cligen/cligen_var.c */
|
/* cf cligen/cligen_var.c */
|
||||||
#define range_check(i, rmin, rmax, type) \
|
#define range_check(i, rmin, rmax, type) \
|
||||||
((rmin && (i) < cv_##type##_get(rmin)) || \
|
((rmin && (i) < cv_##type##_get(rmin)) || \
|
||||||
|
|
@ -375,9 +539,17 @@ clicon_type2cv(char *origtype,
|
||||||
|
|
||||||
|
|
||||||
/*! Validate CLIgen variable
|
/*! Validate CLIgen variable
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] cv A cligen variable to validate. This is a correctly parsed cv.
|
||||||
|
* @param[in] cvtype Resolved type of cv
|
||||||
|
* string describing reason why validation failed.
|
||||||
|
* @param[in] regexps Vector of compiled regexps
|
||||||
|
* @param[out] reason If given, and return value is 0, contains malloced str
|
||||||
|
|
||||||
* @retval -1 Error (fatal), with errno set to indicate error
|
* @retval -1 Error (fatal), with errno set to indicate error
|
||||||
* @retval 0 Validation not OK, malloced reason is returned. Free reason with free()
|
* @retval 0 Validation not OK, malloced reason is returned. Free reason with free()
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
|
* @note reason if given must be freed by caller
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
cv_validate1(clicon_handle h,
|
cv_validate1(clicon_handle h,
|
||||||
|
|
@ -385,7 +557,7 @@ cv_validate1(clicon_handle h,
|
||||||
enum cv_type cvtype,
|
enum cv_type cvtype,
|
||||||
int options,
|
int options,
|
||||||
cvec *cvv,
|
cvec *cvv,
|
||||||
char *pattern,
|
cvec *regexps,
|
||||||
yang_stmt *yrestype,
|
yang_stmt *yrestype,
|
||||||
char *restype,
|
char *restype,
|
||||||
char **reason)
|
char **reason)
|
||||||
|
|
@ -554,29 +726,11 @@ cv_validate1(clicon_handle h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((options & YANG_OPTIONS_PATTERN) != 0) {
|
if (regexps && cvec_len(regexps)) {
|
||||||
void *re = NULL;
|
if ((ret = cv_validate_pattern(h, regexps, yrestype, str, reason)) < 0)
|
||||||
if ((re = yang_regex_cache_get(yrestype)) == NULL){
|
|
||||||
if ((ret = regex_compile(h, pattern, &re)) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0)
|
||||||
if (reason)
|
|
||||||
*reason = cligen_reason("regexp compile fail: \"%s\"",
|
|
||||||
pattern);
|
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
|
||||||
}
|
|
||||||
yang_regex_cache_set(yrestype, re);
|
|
||||||
}
|
|
||||||
if ((ret = regex_exec(h, re, str?str:"")) < 0)
|
|
||||||
goto done;
|
|
||||||
if (ret == 0){
|
|
||||||
if (reason)
|
|
||||||
*reason = cligen_reason("regexp match fail: \"%s\" does not match %s",
|
|
||||||
str, pattern);
|
|
||||||
goto fail;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CGV_VOID:
|
case CGV_VOID:
|
||||||
|
|
@ -605,6 +759,7 @@ static int ys_cv_validate_union(clicon_handle h,yang_stmt *ys, char **reason,
|
||||||
yang_stmt *yrestype, char *type, char *val);
|
yang_stmt *yrestype, char *type, char *val);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
* @param[out] reason If given and return val is 0, contains a malloced string
|
||||||
* @retval -1 Error (fatal), with errno set to indicate error
|
* @retval -1 Error (fatal), with errno set to indicate error
|
||||||
* @retval 0 Validation not OK, malloced reason is returned. Free reason with free()
|
* @retval 0 Validation not OK, malloced reason is returned. Free reason with free()
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
|
|
@ -621,13 +776,17 @@ ys_cv_validate_union_one(clicon_handle h,
|
||||||
yang_stmt *yrt; /* union subtype */
|
yang_stmt *yrt; /* union subtype */
|
||||||
int options = 0;
|
int options = 0;
|
||||||
cvec *cvv = NULL;
|
cvec *cvv = NULL;
|
||||||
char *pattern = NULL;
|
cvec *regexps = NULL;
|
||||||
uint8_t fraction = 0;
|
uint8_t fraction = 0;
|
||||||
char *restype;
|
char *restype;
|
||||||
enum cv_type cvtype;
|
enum cv_type cvtype;
|
||||||
cg_var *cvt=NULL;
|
cg_var *cvt=NULL;
|
||||||
|
|
||||||
if (yang_type_resolve(ys, ys, yt, &yrt, &options, &cvv, &pattern,
|
if ((regexps = cvec_new(0)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (yang_type_resolve(ys, ys, yt, &yrt, &options, &cvv, NULL, regexps,
|
||||||
&fraction) < 0)
|
&fraction) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
restype = yrt?yrt->ys_argument:NULL;
|
restype = yrt?yrt->ys_argument:NULL;
|
||||||
|
|
@ -650,16 +809,19 @@ ys_cv_validate_union_one(clicon_handle h,
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((retval = cv_validate1(h, cvt, cvtype, options, cvv,
|
if ((retval = cv_validate1(h, cvt, cvtype, options, cvv,
|
||||||
pattern, yrt, restype, reason)) < 0)
|
regexps, yrt, restype, reason)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
if (regexps)
|
||||||
|
cvec_free(regexps);
|
||||||
if (cvt)
|
if (cvt)
|
||||||
cv_free(cvt);
|
cv_free(cvt);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
* @param[out] reason If given, and return value is 0, contains malloced string
|
||||||
* @retval -1 Error (fatal), with errno set to indicate error
|
* @retval -1 Error (fatal), with errno set to indicate error
|
||||||
* @retval 0 Validation not OK, malloced reason is returned. Free reason with free()
|
* @retval 0 Validation not OK, malloced reason is returned. Free reason with free()
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
|
|
@ -705,14 +867,16 @@ ys_cv_validate_union(clicon_handle h,
|
||||||
|
|
||||||
/*! Validate cligen variable cv using yang statement as spec
|
/*! Validate cligen variable cv using yang statement as spec
|
||||||
*
|
*
|
||||||
|
* @param[in] h Clicon handle
|
||||||
* @param[in] cv A cligen variable to validate. This is a correctly parsed cv.
|
* @param[in] cv A cligen variable to validate. This is a correctly parsed cv.
|
||||||
* @param[in] ys A yang statement, must be leaf or leaf-list.
|
* @param[in] ys A yang statement, must be leaf or leaf-list.
|
||||||
* @param[out] reason If given, and if return value is 0, contains a malloced string
|
* @param[out] reason If given, and if return value is 0, contains malloced
|
||||||
* describing the reason why the validation failed. Must be freed.
|
* string describing reason why validation failed.
|
||||||
* @retval -1 Error (fatal), with errno set to indicate error
|
* @retval -1 Error (fatal), with errno set to indicate error
|
||||||
* @retval 0 Validation not OK, malloced reason is returned. Free reason with free()
|
* @retval 0 Validation not OK, malloced reason is returned. Free reason with free()
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
* See also cv_validate - the code is similar.
|
* See also cv_validate - the code is similar.
|
||||||
|
* @note reason if given must be freed by caller
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ys_cv_validate(clicon_handle h,
|
ys_cv_validate(clicon_handle h,
|
||||||
|
|
@ -724,7 +888,7 @@ ys_cv_validate(clicon_handle h,
|
||||||
cg_var *ycv; /* cv of yang-statement */
|
cg_var *ycv; /* cv of yang-statement */
|
||||||
int options = 0;
|
int options = 0;
|
||||||
cvec *cvv = NULL;
|
cvec *cvv = NULL;
|
||||||
char *pattern = NULL;
|
cvec *regexps = NULL;
|
||||||
enum cv_type cvtype;
|
enum cv_type cvtype;
|
||||||
char *type; /* orig type */
|
char *type; /* orig type */
|
||||||
yang_stmt *yrestype; /* resolved type */
|
yang_stmt *yrestype; /* resolved type */
|
||||||
|
|
@ -741,8 +905,14 @@ ys_cv_validate(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
ycv = ys->ys_cv;
|
ycv = ys->ys_cv;
|
||||||
|
if ((regexps = cvec_new(0)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (yang_type_get(ys, &type, &yrestype,
|
if (yang_type_get(ys, &type, &yrestype,
|
||||||
&options, &cvv, &pattern, &fraction) < 0)
|
&options, &cvv,
|
||||||
|
NULL, regexps,
|
||||||
|
&fraction) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
restype = yrestype?yrestype->ys_argument:NULL;
|
restype = yrestype?yrestype->ys_argument:NULL;
|
||||||
if (clicon_type2cv(type, restype, ys, &cvtype) < 0)
|
if (clicon_type2cv(type, restype, ys, &cvtype) < 0)
|
||||||
|
|
@ -767,10 +937,12 @@ ys_cv_validate(clicon_handle h,
|
||||||
retval = retval2; /* invalid (0) with latest reason or valid 1 */
|
retval = retval2; /* invalid (0) with latest reason or valid 1 */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ((retval = cv_validate1(h, cv, cvtype, options, cvv, pattern,
|
if ((retval = cv_validate1(h, cv, cvtype, options, cvv,
|
||||||
yrestype, restype, reason)) < 0)
|
regexps, yrestype, restype, reason)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
done:
|
done:
|
||||||
|
if (regexps)
|
||||||
|
cvec_free(regexps);
|
||||||
if (cvt)
|
if (cvt)
|
||||||
cv_free(cvt);
|
cv_free(cvt);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
@ -876,45 +1048,63 @@ yang_find_identity(yang_stmt *ys,
|
||||||
return yid;
|
return yid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Resolve type restrictions, return contraining parameters
|
/*! Resolve type restrictions, return constraining parameters
|
||||||
* @param[in] yrange Yang type range restriction if any
|
*
|
||||||
* @param[in] ylength Yang type length restriction if any
|
* This is for types with range/length/regexp restrictions of the base type
|
||||||
* @param[in] ypattern Yang type pattern restriction if any
|
* Also fraction-digits for decimal64 is handled as that.
|
||||||
* @param[in] yfraction Yang type fraction restriction if any
|
* @param[in] ytype yang-stmt object containing currently resolving type
|
||||||
* @param[out] options Pointer to flags field of optional values. optional
|
* @param[out] options Pointer to flags field of optional values. optional
|
||||||
* @param[out] cvv Pointer to cvec with min range or length.
|
* @param[out] cvv Pointer to cvec with min range or length.
|
||||||
* If options&YANG_OPTIONS_RANGE or YANG_OPTIONS_LENGTH
|
* If options&YANG_OPTIONS_RANGE or YANG_OPTIONS_LENGTH
|
||||||
* @param[out] pattern Pointer to static string of yang string pattern. optional
|
* @param[out] regexps Pointer to cvec of compiled patterns
|
||||||
* @param[out] fraction For decimal64, how many digits after period
|
* @param[out] fraction For decimal64, how many digits after period
|
||||||
|
* @retval -1 Error
|
||||||
* @retval 0 OK.
|
* @retval 0 OK.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
resolve_restrictions(yang_stmt *yrange,
|
resolve_restrictions(yang_stmt *ytype,
|
||||||
yang_stmt *ylength,
|
|
||||||
yang_stmt *ypattern,
|
|
||||||
yang_stmt *yfraction,
|
|
||||||
int *options,
|
int *options,
|
||||||
cvec **cvv,
|
cvec **cvv,
|
||||||
char **pattern,
|
cvec *regexps,
|
||||||
uint8_t *fraction)
|
uint8_t *fraction)
|
||||||
{
|
{
|
||||||
if (options && cvv && yrange != NULL){
|
int retval = -1;
|
||||||
*cvv = yrange->ys_cvec;
|
yang_stmt *ys;
|
||||||
|
cg_var *cv;
|
||||||
|
char *pattern;
|
||||||
|
|
||||||
|
if (options && cvv &&
|
||||||
|
(ys = yang_find(ytype, Y_RANGE, NULL)) != NULL){
|
||||||
|
*cvv = ys->ys_cvec;
|
||||||
*options |= YANG_OPTIONS_RANGE;
|
*options |= YANG_OPTIONS_RANGE;
|
||||||
}
|
}
|
||||||
if (options && cvv && ylength != NULL){
|
if (options && cvv &&
|
||||||
*cvv = ylength->ys_cvec;
|
(ys = yang_find(ytype, Y_LENGTH, NULL)) != NULL){
|
||||||
|
*cvv = ys->ys_cvec;
|
||||||
*options |= YANG_OPTIONS_LENGTH;
|
*options |= YANG_OPTIONS_LENGTH;
|
||||||
}
|
}
|
||||||
if (options && pattern && ypattern != NULL){
|
/* Find all patterns */
|
||||||
*pattern = ypattern->ys_argument;
|
if (options && regexps){
|
||||||
*options |= YANG_OPTIONS_PATTERN;
|
ys = NULL;
|
||||||
|
while ((ys = yn_each(ytype, ys)) != NULL) {
|
||||||
|
if (yang_keyword_get(ys) != Y_PATTERN)
|
||||||
|
continue;
|
||||||
|
if ((cv = cvec_add(regexps, CGV_STRING)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_add");
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
if (options && fraction && yfraction != NULL){
|
pattern = ys->ys_argument; /* clear text pattern */
|
||||||
*fraction = cv_uint8_get(yfraction->ys_cv);
|
cv_string_set(cv, pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options && fraction &&
|
||||||
|
(ys = yang_find(ytype, Y_FRACTION_DIGITS, NULL)) != NULL){
|
||||||
|
*fraction = cv_uint8_get(ys->ys_cv);
|
||||||
*options |= YANG_OPTIONS_FRACTION_DIGITS;
|
*options |= YANG_OPTIONS_FRACTION_DIGITS;
|
||||||
}
|
}
|
||||||
return 0;
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Recursively resolve a yang type to built-in type with optional restrictions
|
/*! Recursively resolve a yang type to built-in type with optional restrictions
|
||||||
|
|
@ -926,8 +1116,8 @@ resolve_restrictions(yang_stmt *yrange,
|
||||||
* @param[out] cvv Cvec with min/max range or length.
|
* @param[out] cvv Cvec with min/max range or length.
|
||||||
* Present if options&YANG_OPTIONS_RANGE|_LENGTH.
|
* Present if options&YANG_OPTIONS_RANGE|_LENGTH.
|
||||||
* Can be a vector if multiple ranges
|
* Can be a vector if multiple ranges
|
||||||
* @param[out] pattern String of POSIX regexp pattern
|
* @param[out] patterns Initialized cvec of regexp patterns strings (if any)
|
||||||
* Present if options&YANG_OPTIONS_PATTERN
|
* @param[out] regexps Initialized cvec of compiled regexps (if any)
|
||||||
* @param[out] fraction for decimal64, how many digits after period
|
* @param[out] fraction for decimal64, how many digits after period
|
||||||
* Present if options&YANG_OPTIONS_FRACTION_DIGITS
|
* Present if options&YANG_OPTIONS_FRACTION_DIGITS
|
||||||
* @retval 0 OK. Note yrestype may still be NULL.
|
* @retval 0 OK. Note yrestype may still be NULL.
|
||||||
|
|
@ -935,8 +1125,8 @@ resolve_restrictions(yang_stmt *yrange,
|
||||||
* The setting of the options argument has the following semantics:
|
* The setting of the options argument has the following semantics:
|
||||||
* options&YANG_OPTIONS_RANGE or YANG_OPTIONS_LENGTH --> cvv is set containing
|
* options&YANG_OPTIONS_RANGE or YANG_OPTIONS_LENGTH --> cvv is set containing
|
||||||
* array of range_min, range_max cv:s
|
* array of range_min, range_max cv:s
|
||||||
* options&YANG_OPTIONS_PATTERN --> pattern is set
|
|
||||||
* options&YANG_OPTIONS_FRACTION_DIGITS --> fraction is set
|
* options&YANG_OPTIONS_FRACTION_DIGITS --> fraction is set
|
||||||
|
* patterns && cvec_len(patterns) --> there are patterns
|
||||||
* Note that the static output strings (type, pattern) should be copied if used asap.
|
* Note that the static output strings (type, pattern) should be copied if used asap.
|
||||||
* Note also that for all pointer arguments, if NULL is given, no value is assigned.
|
* Note also that for all pointer arguments, if NULL is given, no value is assigned.
|
||||||
*/
|
*/
|
||||||
|
|
@ -947,15 +1137,12 @@ yang_type_resolve(yang_stmt *yorig,
|
||||||
yang_stmt **yrestype,
|
yang_stmt **yrestype,
|
||||||
int *options,
|
int *options,
|
||||||
cvec **cvv,
|
cvec **cvv,
|
||||||
char **pattern,
|
cvec *patterns,
|
||||||
|
cvec *regexps,
|
||||||
uint8_t *fraction)
|
uint8_t *fraction)
|
||||||
{
|
{
|
||||||
yang_stmt *rytypedef = NULL; /* Resolved typedef of ytype */
|
yang_stmt *rytypedef = NULL; /* Resolved typedef of ytype */
|
||||||
yang_stmt *rytype; /* Resolved type of ytype */
|
yang_stmt *rytype; /* Resolved type of ytype */
|
||||||
yang_stmt *yrange;
|
|
||||||
yang_stmt *ylength;
|
|
||||||
yang_stmt *ypattern;
|
|
||||||
yang_stmt *yfraction;
|
|
||||||
char *type;
|
char *type;
|
||||||
char *prefix = NULL;
|
char *prefix = NULL;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -968,23 +1155,18 @@ yang_type_resolve(yang_stmt *yorig,
|
||||||
type = yarg_id(ytype); /* This is the type to resolve */
|
type = yarg_id(ytype); /* This is the type to resolve */
|
||||||
prefix = yarg_prefix(ytype); /* And this its prefix */
|
prefix = yarg_prefix(ytype); /* And this its prefix */
|
||||||
/* Cache does not work for eg string length 32? */
|
/* Cache does not work for eg string length 32? */
|
||||||
if (!yang_builtin(type) && ytype->ys_typecache != NULL){
|
if (/*!yang_builtin(type) &&*/ ytype->ys_typecache != NULL){
|
||||||
if (yang_type_cache_get(ytype->ys_typecache, yrestype,
|
if (yang_type_cache_get(ytype->ys_typecache, yrestype,
|
||||||
options, cvv, pattern, fraction) < 0)
|
options, cvv, patterns, regexps, fraction) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
/* Resolving type restrictions */
|
|
||||||
yrange = yang_find(ytype, Y_RANGE, NULL);
|
|
||||||
ylength = yang_find(ytype, Y_LENGTH, NULL);
|
|
||||||
ypattern = yang_find(ytype, Y_PATTERN, NULL);
|
|
||||||
yfraction = yang_find(ytype, Y_FRACTION_DIGITS, NULL);
|
|
||||||
|
|
||||||
/* Check if type is basic type. If so, return that */
|
/* Check if type is basic type. If so, return that */
|
||||||
if (prefix == NULL && yang_builtin(type)){
|
if ((prefix == NULL && yang_builtin(type))){
|
||||||
*yrestype = ytype;
|
*yrestype = ytype;
|
||||||
resolve_restrictions(yrange, ylength, ypattern, yfraction, options,
|
if (resolve_restrictions(ytype, options, cvv, patterns, fraction) < 0)
|
||||||
cvv, pattern, fraction);
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1023,11 +1205,13 @@ yang_type_resolve(yang_stmt *yorig,
|
||||||
}
|
}
|
||||||
/* recursively resolve this new type */
|
/* recursively resolve this new type */
|
||||||
if (yang_type_resolve(yorig, ys, rytype, yrestype,
|
if (yang_type_resolve(yorig, ys, rytype, yrestype,
|
||||||
options, cvv, pattern, fraction) < 0)
|
options, cvv,
|
||||||
|
patterns, regexps,
|
||||||
|
fraction) < 0)
|
||||||
|
goto done;
|
||||||
|
/* appends patterns, overwrites others if any */
|
||||||
|
if (resolve_restrictions(ytype, options, cvv, patterns, fraction) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* overwrites the resolved if any */
|
|
||||||
resolve_restrictions(yrange, ylength, ypattern, yfraction, options,
|
|
||||||
cvv, pattern, fraction);
|
|
||||||
}
|
}
|
||||||
ok:
|
ok:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
@ -1043,17 +1227,17 @@ yang_type_resolve(yang_stmt *yorig,
|
||||||
* yang_stmt *yrestype;
|
* yang_stmt *yrestype;
|
||||||
* int options;
|
* int options;
|
||||||
* cvec *cvv = NULL;
|
* cvec *cvv = NULL;
|
||||||
* char *pattern;
|
* cvec *patterns = cvec_new(0);
|
||||||
|
* cvec *regexps = cvec_new(0);
|
||||||
* uint8_t fraction;
|
* uint8_t fraction;
|
||||||
*
|
*
|
||||||
* if (yang_type_get(ys, &type, &yrestype, &options, &cvv, &pattern, &fraction) < 0)
|
* if (yang_type_get(ys, &type, &yrestype, &options, &cvv,
|
||||||
|
* patterns, regexps, &fraction) < 0)
|
||||||
* goto err;
|
* goto err;
|
||||||
* if (yrestype == NULL) # unresolved
|
* if (yrestype == NULL) # unresolved
|
||||||
* goto err;
|
* goto err;
|
||||||
* if (options & YANG_OPTIONS_LENGTH != 0)
|
* if (options & YANG_OPTIONS_LENGTH != 0)
|
||||||
* printf("%d..%d\n", min , max);
|
* printf("%d..%d\n", min , max);
|
||||||
* if (options & YANG_OPTIONS_PATTERN != 0)
|
|
||||||
* printf("regexp: %s\n", pattern);
|
|
||||||
* @endcode
|
* @endcode
|
||||||
* @param[in] ys yang-stmt, leaf or leaf-list
|
* @param[in] ys yang-stmt, leaf or leaf-list
|
||||||
* @param[out] origtype original type may be derived or built-in
|
* @param[out] origtype original type may be derived or built-in
|
||||||
|
|
@ -1062,8 +1246,8 @@ yang_type_resolve(yang_stmt *yorig,
|
||||||
* @param[out] cvv Cvec with min/max range or length.
|
* @param[out] cvv Cvec with min/max range or length.
|
||||||
* Present if options&YANG_OPTIONS_RANGE|_LENGTH.
|
* Present if options&YANG_OPTIONS_RANGE|_LENGTH.
|
||||||
* Can be a vector if multiple ranges
|
* Can be a vector if multiple ranges
|
||||||
* @param[out] pattern yang string pattern POSIX regexp patterns
|
* @param[out] pattern yang cvec pattern POSIX regexp patterns
|
||||||
* Present if options&YANG_OPTIONS_PATTERN
|
* @param[out] regexps Initialized cvec of compiled regexps (if any)
|
||||||
* @param[out] fraction for decimal64, how many digits after period
|
* @param[out] fraction for decimal64, how many digits after period
|
||||||
* Present if options&YANG_OPTIONS_FRACTION_DIGITS
|
* Present if options&YANG_OPTIONS_FRACTION_DIGITS
|
||||||
* @retval 0 OK, but note that restype==NULL means not resolved.
|
* @retval 0 OK, but note that restype==NULL means not resolved.
|
||||||
|
|
@ -1071,7 +1255,6 @@ yang_type_resolve(yang_stmt *yorig,
|
||||||
* The setting of the options argument has the following semantics:
|
* The setting of the options argument has the following semantics:
|
||||||
* options&YANG_OPTIONS_RANGE or YANG_OPTIONS_LENGTH --> cvv is set containing
|
* options&YANG_OPTIONS_RANGE or YANG_OPTIONS_LENGTH --> cvv is set containing
|
||||||
* array of range_min, range_max cv:s
|
* array of range_min, range_max cv:s
|
||||||
* options&YANG_OPTIONS_PATTERN --> pattern is set
|
|
||||||
* options&YANG_OPTIONS_FRACTION_DIGITS --> fraction is set
|
* options&YANG_OPTIONS_FRACTION_DIGITS --> fraction is set
|
||||||
* Note that the static output strings (type, pattern) should be copied if used asap.
|
* Note that the static output strings (type, pattern) should be copied if used asap.
|
||||||
* Note also that for all pointer arguments, if NULL is given, no value is assigned.
|
* Note also that for all pointer arguments, if NULL is given, no value is assigned.
|
||||||
|
|
@ -1083,7 +1266,8 @@ yang_type_get(yang_stmt *ys,
|
||||||
yang_stmt **yrestype,
|
yang_stmt **yrestype,
|
||||||
int *options,
|
int *options,
|
||||||
cvec **cvv,
|
cvec **cvv,
|
||||||
char **pattern,
|
cvec *patterns,
|
||||||
|
cvec *regexps,
|
||||||
uint8_t *fraction
|
uint8_t *fraction
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
@ -1103,7 +1287,7 @@ yang_type_get(yang_stmt *ys,
|
||||||
if (origtype)
|
if (origtype)
|
||||||
*origtype = type;
|
*origtype = type;
|
||||||
if (yang_type_resolve(ys, ys, ytype, yrestype,
|
if (yang_type_resolve(ys, ys, ytype, yrestype,
|
||||||
options, cvv, pattern, fraction) < 0)
|
options, cvv, patterns, regexps, fraction) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
clicon_debug(3, "%s: %s %s->%s", __FUNCTION__, ys->ys_argument, type,
|
clicon_debug(3, "%s: %s %s->%s", __FUNCTION__, ys->ys_argument, type,
|
||||||
*yrestype?(*yrestype)->ys_argument:"null");
|
*yrestype?(*yrestype)->ys_argument:"null");
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -151,7 +151,7 @@ new "netconf NONEXIST subscription"
|
||||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>NONEXIST</stream></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>No such stream</error-message></rpc-error></rpc-reply>]]>]]>$' $NCWAIT
|
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>NONEXIST</stream></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>No such stream</error-message></rpc-error></rpc-reply>]]>]]>$' $NCWAIT
|
||||||
|
|
||||||
new "netconf EXAMPLE subscription with wrong date"
|
new "netconf EXAMPLE subscription with wrong date"
|
||||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><startTime>kallekaka</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: "kallekaka" does not match' 0
|
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><startTime>kallekaka</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:' 0
|
||||||
|
|
||||||
#new "netconf EXAMPLE subscription with replay"
|
#new "netconf EXAMPLE subscription with replay"
|
||||||
#NOW=$(date +"%Y-%m-%dT%H:%M:%S")
|
#NOW=$(date +"%Y-%m-%dT%H:%M:%S")
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ EOF
|
||||||
# 1: dbcache true/false
|
# 1: dbcache true/false
|
||||||
testrun(){
|
testrun(){
|
||||||
dbcache=$1
|
dbcache=$1
|
||||||
new "test params: -f $cfg -y $fyang # dbcache: $dbcache"
|
new "test params: -f $cfg # dbcache: $dbcache"
|
||||||
|
|
||||||
cat <<EOF > $cfg
|
cat <<EOF > $cfg
|
||||||
<clixon-config xmlns="http://clicon.org/config">
|
<clixon-config xmlns="http://clicon.org/config">
|
||||||
|
|
@ -208,6 +208,7 @@ testrun(){
|
||||||
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
||||||
|
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
||||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_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_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||||
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||||
|
|
@ -226,379 +227,379 @@ EOF
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
fi
|
fi
|
||||||
new "start backend -s init -f $cfg -y $fyang"
|
new "start backend -s init -f $cfg"
|
||||||
start_backend -s init -f $cfg -y $fyang
|
start_backend -s init -f $cfg
|
||||||
|
|
||||||
new "waiting"
|
new "waiting"
|
||||||
sleep $RCWAIT
|
sleep $RCWAIT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "cli set transitive string. type is alpha followed by number and is defined in three levels of modules"
|
new "cli set transitive string. type is alpha followed by number and is defined in three levels of modules"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle x99" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set c talle x99" 0 '^$'
|
||||||
|
|
||||||
new "cli set transitive string error. Wrong type"
|
new "cli set transitive string error. Wrong type"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle 9xx" 255 '^CLI syntax error: "set c talle 9xx": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set c talle 9xx" 255 '^CLI syntax error: "set c talle 9xx": 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" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
|
||||||
new "netconf set transitive string error"
|
new "netconf set transitive string error"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><c xmlns="urn:example:clixon"><talle>9xx</talle></c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><c xmlns="urn:example:clixon"><talle>9xx</talle></c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>"
|
||||||
|
|
||||||
new "netconf validate should fail"
|
new "netconf validate should fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>talle</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail: "9xx" does not match \[a-z\]\[0-9\]\*</error-message></rpc-error></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 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:'
|
||||||
|
|
||||||
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" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli set transitive union int (ulle should accept 4.44|bounded|unbounded)"
|
new "cli set transitive union int (ulle should accept 4.44|bounded|unbounded)"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 33" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set c ulle 33" 0 '^$'
|
||||||
|
|
||||||
new "cli validate"
|
new "cli validate"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o -l o validate" 0 '^$'
|
||||||
|
|
||||||
new "cli set transitive union string (and space)"
|
new "cli set transitive union string (and space)"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle un\ bounded" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set c ulle un\ bounded" 0 '^$'
|
||||||
|
|
||||||
new "cli validate"
|
new "cli validate"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o -l o validate" 0 '^$'
|
||||||
|
|
||||||
new "cli set transitive union error. should fail"
|
new "cli set transitive union error. should fail"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle kalle" 255 '^CLI syntax error: "set c ulle kalle": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set c ulle kalle" 255 '^CLI syntax error: "set c ulle kalle": Unknown command$'
|
||||||
|
|
||||||
new "cli set transitive union error int"
|
new "cli set transitive union error int"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 55" 255 '^CLI syntax error: "set c ulle 55": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set c ulle 55" 255 '^CLI syntax error: "set c ulle 55": Unknown command$'
|
||||||
|
|
||||||
new "netconf set transitive union error int"
|
new "netconf set transitive union error int"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><c xmlns="urn:example:clixon"><ulle>55</ulle></c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><c xmlns="urn:example:clixon"><ulle>55</ulle></c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>"
|
||||||
|
|
||||||
new "netconf validate should fail"
|
new "netconf validate should fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>ulle</bad-element></error-info><error-severity>error</error-severity><error-message>'55' does not match enumeration</error-message></rpc-error></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>ulle</bad-element></error-info><error-severity>error</error-severity><error-message>'55' does not match enumeration</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
#-----------
|
#-----------
|
||||||
|
|
||||||
new "cli set ab"
|
new "cli set ab"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a.b.a.b" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set list a.b.a.b" 0 '^$'
|
||||||
|
|
||||||
new "cli set cd"
|
new "cli set cd"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list c.d.c.d" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set list c.d.c.d" 0 '^$'
|
||||||
|
|
||||||
new "cli set ef"
|
new "cli set ef"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list e.f.e.f" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set list e.f.e.f" 0 '^$'
|
||||||
|
|
||||||
new "cli set ab fail"
|
new "cli set ab fail"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a&b&a&b" 255 "^CLI syntax error"
|
expectfn "$clixon_cli -1f $cfg -l o set list a&b&a&b" 255 "^CLI syntax error"
|
||||||
|
|
||||||
new "cli set ad fail"
|
new "cli set ad fail"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a.b.c.d" 255 "^CLI syntax error"
|
expectfn "$clixon_cli -1f $cfg -l o set list a.b.c.d" 255 "^CLI syntax error"
|
||||||
|
|
||||||
new "cli validate"
|
new "cli validate"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o -l o validate" 0 '^$'
|
||||||
|
|
||||||
new "cli commit"
|
new "cli commit"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o commit" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o -l o commit" 0 '^$'
|
||||||
|
|
||||||
new "netconf validate ok"
|
new "netconf validate ok"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf set ab wrong"
|
new "netconf set ab wrong"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><list xmlns="urn:example:clixon"><ip>a.b& c.d</ip></list></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><list xmlns="urn:example:clixon"><ip>a.b& c.d</ip></list></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli enum value"
|
new "cli enum value"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set status down" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set status down" 0 '^$'
|
||||||
|
|
||||||
new "cli bits value"
|
new "cli bits value"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits create" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set mbits create" 0 '^$'
|
||||||
|
|
||||||
#XXX No, cli cant assign two bit values
|
#XXX No, cli cant assign two bit values
|
||||||
#new "cli bits two values"
|
#new "cli bits two values"
|
||||||
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits \"create read\"" 0 '^$'
|
#expectfn "$clixon_cli -1f $cfg -l o set mbits \"create read\"" 0 '^$'
|
||||||
|
|
||||||
new "netconf bits two values"
|
new "netconf bits two values"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><mbits xmlns="urn:example:clixon">create read</mbits></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><mbits xmlns="urn:example:clixon">create read</mbits></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli bits validate"
|
new "cli bits validate"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang validate" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o validate" 0 '^$'
|
||||||
|
|
||||||
#-------- num0 empty value
|
#-------- num0 empty value
|
||||||
|
|
||||||
new "netconf num0 no value"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num0 xmlns="urn:example:clixon"/></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate no value wrong"
|
new "netconf validate no value 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>num0</bad-element></error-info><error-severity>error</error-severity><error-message>Invalid NULL value</error-message></rpc-error></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg" 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 "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" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
#-------- num1 single range (1)
|
#-------- num1 single range (1)
|
||||||
|
|
||||||
new "cli range test num1 1 OK"
|
new "cli range test num1 1 OK"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 1" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set num1 1" 0 '^$'
|
||||||
|
|
||||||
#new "cli range test num1 -100 ok" # XXX -/minus cant be given as argv
|
#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 '^$'
|
#expectfn "$clixon_cli -1f $cfg -l o set num1 \-100" 0 '^$'
|
||||||
|
|
||||||
new "cli range test num1 2 error"
|
new "cli range test num1 2 error"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 2" 255 '^CLI syntax error: "set num1 2": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set num1 2" 255 '^CLI syntax error: "set num1 2": Unknown command$'
|
||||||
|
|
||||||
new "netconf range set num1 -1"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num1 xmlns="urn:example:clixon">-1</num1></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate num1 -1 wrong"
|
new "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>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
#-------- num2 range and blanks
|
#-------- num2 range and blanks
|
||||||
|
|
||||||
new "cli range test num2 3 error"
|
new "cli range test num2 3 error"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 3" 255 '^CLI syntax error: "set num2 3": Number out of range: 3$'
|
expectfn "$clixon_cli -1f $cfg -l o set num2 3" 255 '^CLI syntax error: "set num2 3": Number out of range: 3$'
|
||||||
|
|
||||||
new "cli range test num2 1000 ok"
|
new "cli range test num2 1000 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 1000" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set num2 1000" 0 '^$'
|
||||||
|
|
||||||
new "cli range test num2 5000 error"
|
new "cli range test num2 5000 error"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 5000" 255 '^CLI syntax error: "set num2 5000": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set num2 5000" 255 '^CLI syntax error: "set num2 5000": Unknown command$'
|
||||||
|
|
||||||
new "netconf range set num2 3 fail"
|
new "netconf range set num2 3 fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">3</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">3</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate num2 3 fail"
|
new "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>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf range set num2 5000 fail"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
#-------- num3 min max range
|
#-------- num3 min max range
|
||||||
|
|
||||||
new "cli range test num3 42 ok"
|
new "cli range test num3 42 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 42" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set num3 42" 0 '^$'
|
||||||
|
|
||||||
new "cli range test num3 260 fail"
|
new "cli range test num3 260 fail"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 260" 255 '^CLI syntax error: "set num3 260": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set num3 260" 255 '^CLI syntax error: "set num3 260": Unknown command$'
|
||||||
|
|
||||||
new "cli range test num3 -1 fail"
|
new "cli range test num3 -1 fail"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 -1" 255 "CLI syntax error:"
|
expectfn "$clixon_cli -1f $cfg -l o set num3 -1" 255 "CLI syntax error:"
|
||||||
|
|
||||||
new "netconf range set num3 260 fail"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num3 xmlns="urn:example:clixon">260</num3></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate num3 260 fail"
|
new "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>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
#-------- num4 multiple ranges 1..2 | 42..50
|
#-------- num4 multiple ranges 1..2 | 42..50
|
||||||
|
|
||||||
new "cli range test num4 multiple 0 fail"
|
new "cli range test num4 multiple 0 fail"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 0" 255 '^CLI syntax error: "set num4 0": Number out of range: 0$'
|
expectfn "$clixon_cli -1f $cfg -l o set num4 0" 255 '^CLI syntax error: "set num4 0": Number out of range: 0$'
|
||||||
|
|
||||||
new "cli range test num4 multiple 2 ok"
|
new "cli range test num4 multiple 2 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l e -y $fyang set num4 2" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l e set num4 2" 0 '^$'
|
||||||
|
|
||||||
new "cli range test num4 multiple 20 fail"
|
new "cli range test num4 multiple 20 fail"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 20" 255 '^CLI syntax error: "set num4 20": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set num4 20" 255 '^CLI syntax error: "set num4 20": Unknown command$'
|
||||||
|
|
||||||
new "cli range test num4 multiple 42 ok"
|
new "cli range test num4 multiple 42 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 42" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set num4 42" 0 '^$'
|
||||||
|
|
||||||
new "cli range test num4 multiple 99 fail"
|
new "cli range test num4 multiple 99 fail"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 99" 255 '^CLI syntax error: "set num4 99": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set num4 99" 255 '^CLI syntax error: "set num4 99": Unknown command$'
|
||||||
|
|
||||||
new "netconf range set num4 multiple 2"
|
new "netconf range set num4 multiple 2"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
new "netconf validate num4 OK"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf range set num4 multiple 20"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate num4 fail"
|
new "netconf validate num4 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" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf range set num4 multiple 42"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate num4 fail"
|
new "netconf validate num4 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" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
#-------- dec64 multiple ranges -3.5..-2.5 | 0.0 | 10.0..20.0
|
#-------- 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?
|
# XXX how to enter negative numbers in bash string and cli -1?
|
||||||
new "cli range dec64 multiple 0 ok"
|
new "cli range dec64 multiple 0 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 0" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set dec 0" 0 '^$'
|
||||||
|
|
||||||
new "cli range dec64 multiple 0.1 fail"
|
new "cli range dec64 multiple 0.1 fail"
|
||||||
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$'
|
expectfn "$clixon_cli -1f $cfg -l o set num4 0.1" 255 '^CLI syntax error: "set num4 0.1": '"'"'0.1'"'"' is not a number$'
|
||||||
|
|
||||||
new "cli range dec64 multiple 15.0 ok"
|
new "cli range dec64 multiple 15.0 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 15.0" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set dec 15.0" 0 '^$'
|
||||||
|
|
||||||
new "cli range dec64 multiple 30.0 fail"
|
new "cli range dec64 multiple 30.0 fail"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 30.0" 255 '^CLI syntax error: "set dec 30.0": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set dec 30.0" 255 '^CLI syntax error: "set dec 30.0": Unknown command$'
|
||||||
|
|
||||||
new "dec64 discard-changes"
|
new "dec64 discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# Same with netconf
|
# Same with netconf
|
||||||
new "netconf range dec64 -3.59"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 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 "netconf range dec64 -3.59 validate fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf range dec64 -2"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
|
||||||
|
|
||||||
new "netconf range dec64 -0.001"
|
new "netconf range dec64 -0.001"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf range dec64 -0.001 validate fail"
|
new "netconf range dec64 -0.001 validate fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf range dec64 +0.001"
|
new "netconf range dec64 +0.001"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">+0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">+0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf range dec64 +0.001 validate fail"
|
new "netconf range dec64 +0.001 validate fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
|
expecteof "$clixon_netconf -qf $cfg" 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---------------------
|
#----------------string ranges---------------------
|
||||||
#-------- len1 single range (2)
|
#-------- len1 single range (2)
|
||||||
new "cli length test len1 1 fail"
|
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$'
|
expectfn "$clixon_cli -1f $cfg -l o set len1 x" 255 '^CLI syntax error: "set len1 x": String length not within limits: 1$'
|
||||||
|
|
||||||
new "cli length test len1 2 OK"
|
new "cli length test len1 2 OK"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 xy" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set len1 xy" 0 '^$'
|
||||||
|
|
||||||
new "cli length test len1 3 error"
|
new "cli length test len1 3 error"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 hej" 255 '^CLI syntax error: "set len1 hej": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set len1 hej" 255 '^CLI syntax error: "set len1 hej": 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" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf length set len1 1"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 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
|
#-------- len2 range and blanks
|
||||||
|
|
||||||
new "cli length test len2 3 error"
|
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$'
|
expectfn "$clixon_cli -1f $cfg -l o set len2 ab" 255 '^CLI syntax error: "set len2 ab": String length not within limits: 2$'
|
||||||
|
|
||||||
new "cli length test len2 42 ok"
|
new "cli length test len2 42 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 '^$'
|
||||||
|
|
||||||
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" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
#-------- len3 min max range
|
#-------- len3 min max range
|
||||||
|
|
||||||
new "cli range ptest len3 42 ok"
|
new "cli range ptest len3 42 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len3 hsakjdhkjsahdkjsahdksahdksajdhsakjhd" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set len3 hsakjdhkjsahdkjsahdksahdksajdhsakjhd" 0 '^$'
|
||||||
|
|
||||||
#-------- len4 multiple ranges 2..3 | 20-29
|
#-------- len4 multiple ranges 2..3 | 20-29
|
||||||
new "cli length test len4 1 error"
|
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$'
|
expectfn "$clixon_cli -1f $cfg -l o set len4 a" 255 '^CLI syntax error: "set len4 a": String length not within limits: 1$'
|
||||||
|
|
||||||
new "cli length test len4 2 ok"
|
new "cli length test len4 2 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 ab" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set len4 ab" 0 '^$'
|
||||||
|
|
||||||
new "cli length test len4 10 error"
|
new "cli length test len4 10 error"
|
||||||
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 set len4 abcdefghij" 255 '^CLI syntax error: "set len4 abcdefghij": Unknown command$'
|
||||||
|
|
||||||
new "cli length test len4 20 ok"
|
new "cli length test len4 20 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghija" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghijabcdefghija" 0 '^$'
|
||||||
|
|
||||||
new "cli length test len4 30 error"
|
new "cli length test len4 30 error"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghijabcdefghij" 255 '^CLI syntax error: "set len4 abcdefghijabcdefghijabcdefghij": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghijabcdefghijabcdefghij" 255 '^CLI syntax error: "set len4 abcdefghijabcdefghijabcdefghij": Unknown command$'
|
||||||
|
|
||||||
# XSD schema -> POSIX ECE translation
|
# XSD schema -> POSIX ECE translation
|
||||||
new "cli yang pattern \d ok"
|
new "cli yang pattern \d ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 0123" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set digit4 0123" 0 '^$'
|
||||||
|
|
||||||
new "cli yang pattern \d error"
|
new "cli yang pattern \d error"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 01b2" 255 '^CLI syntax error: "set digit4 01b2": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set digit4 01b2" 255 '^CLI syntax error: "set digit4 01b2": Unknown command$'
|
||||||
|
|
||||||
new "cli yang pattern \w ok"
|
new "cli yang pattern \w ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 abc9" 0 '^$'
|
expectfn "$clixon_cli -1f $cfg -l o set word4 abc9" 0 '^$'
|
||||||
|
|
||||||
new "cli yang pattern \w error"
|
new "cli yang pattern \w error"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 ab%3" 255 '^CLI syntax error: "set word4 ab%3": Unknown command$'
|
expectfn "$clixon_cli -1f $cfg -l o set word4 ab%3" 255 '^CLI syntax error: "set word4 ab%3": Unknown command$'
|
||||||
|
|
||||||
new "netconf pattern \w"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf pattern \w error"
|
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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
new "netconf pattern \w invalid"
|
||||||
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" 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:'
|
||||||
|
|
||||||
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" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
|
||||||
#------ minus
|
#------ minus
|
||||||
|
|
||||||
new "type with 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>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 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"
|
new "validate minus"
|
||||||
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" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
#new "cli type with minus"
|
#new "cli type with minus"
|
||||||
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set name my-name" 0 '^$'
|
#expectfn "$clixon_cli -1f $cfg -l o set name my-name" 0 '^$'
|
||||||
|
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ main(int argc, char **argv)
|
||||||
xml_print(stderr, x0);
|
xml_print(stderr, x0);
|
||||||
}
|
}
|
||||||
if (sort)
|
if (sort)
|
||||||
xml_sort(xb, NULL);
|
xml_sort(xb, h);
|
||||||
clicon_xml2file(stdout, xb, 0, 0);
|
clicon_xml2file(stdout, xb, 0, 0);
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue