* All yang modules are stored in the clicon_dbspec_yang() option.

* Except clixon-config module due to bug reported below
* Bug: Top-level Yang symbol cannot be called "config" in any imported yang file.
  * datastore uses "config" as reserved keyword for storing any XML whoich collides with code for detecting Yang sanit
This commit is contained in:
Olof hagsand 2018-10-19 15:26:22 +02:00
parent 7de80e9fcd
commit a4e29bcdb7
14 changed files with 151 additions and 72 deletions

View file

@ -34,7 +34,7 @@
### API changes on existing features (you may need to change your code)
* Netconf hello capability updated to YANG 1.1 RFC7950 Sec 5.6.4
* Added urn:ietf:params:netconf:capability:yang-library:1.0
* Thanks SCadilhac for helping out, see https://github.com/clicon/clixon/issues/39
* Thanks @SCadilhac for helping out, see https://github.com/clicon/clixon/issues/39
* Major rewrite of event streams
* If you used old event callbacks API, you need to switch to the streams API
* See clixon_stream.[ch]
@ -53,12 +53,13 @@
* The "module-name" was a no-op before.
* This means that there was no difference between eg: GET /restconf/data/ietf-yang-library:modules-state and GET /restconf/data/XXXX:modules-state
* Generilized top-level yang parsing functions
* All yang modules are stored in the clicon_dbspec_yang() option.
* Except clixon-config module due to bug reported below
* Clarified semantics of main yang module:
* -y option to commands MUST specify filename
* CLICON_YANG_MODULE_MAIN MUST specify a module
* yang_parse() changed to take either filename or module name and revision.
* Removed clicon_dbspec_name[_set]().
* Use yang_main_module_name() instead.
* Replace code for initializing the main yang module
* Replace yang_spec_main() with yang_spec_parse_module() as follows:
```
@ -89,6 +90,8 @@
* Set dir /www-data with www-data as owner, see https://github.com/clicon/clixon/issues/37
### Known issues
* Bug: Top-level Yang symbol cannot be called "config" in any imported yang file.
* datastore uses "config" as reserved keyword for storing any XML whoich collides with code for detecting Yang sanity.
* Namespace name relabeling is not supported.
* Eg: if "des" is defined as prefix for an imported module, then a relabeling using xmlfns is not supported, such as:
```

View file

@ -262,7 +262,7 @@ nacm_load_external(clicon_handle h)
}
if ((yspec = yspec_new()) == NULL)
goto done;
if (yang_parse(h, NULL, "ietf-netconf-acm", CLIXON_DATADIR, NULL, yspec) < 0)
if (yang_parse(h, NULL, "ietf-netconf-acm", CLIXON_DATADIR, NULL, yspec, NULL) < 0)
goto done;
fd = fileno(f);
/* Read configfile */
@ -524,6 +524,7 @@ main(int argc,
char *nacm_mode;
int logdst = CLICON_LOG_SYSLOG|CLICON_LOG_STDERR;
yang_spec *yspec = NULL;
yang_spec *yspecfg = NULL; /* For config XXX clixon bug */
char *yang_filename = NULL;
/* In the startup, logs to stderr & syslog and debug flag set later */
@ -579,8 +580,12 @@ main(int argc,
clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst);
clicon_debug_init(debug, NULL);
/* Create configure yang-spec */
if ((yspecfg = yspec_new()) == NULL)
goto done;
/* Find and read configfile */
if (clicon_options_main(h) < 0){
if (clicon_options_main(h, yspecfg) < 0){
if (help)
usage(h, argv[0]);
return -1;
@ -733,19 +738,21 @@ main(int argc,
/* Connect to plugin to get a handle */
if (xmldb_connect(h) < 0)
goto done;
/* Create top-level yang spec and store as option */
if ((yspec = yspec_new()) == NULL)
goto done;
clicon_dbspec_yang_set(h, yspec);
/* Load main application yang specification: either module or specific file
*/
/* Load main application yang specification either module or specific file
* If -y <file> is given, it overrides main module */
if (yang_filename){
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec) < 0)
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec, NULL) < 0)
goto done;
}
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
clicon_yang_dir(h),
clicon_yang_module_revision(h),
yspec) < 0)
clicon_yang_dir(h),
clicon_yang_module_revision(h),
yspec, NULL) < 0)
goto done;
/* Load yang module library, RFC7895 */
@ -756,11 +763,11 @@ main(int argc,
goto done;
/* Load yang Restconf stream discovery */
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040") &&
yang_spec_parse_module(h, "ietf-restconf-monitoring", CLIXON_DATADIR, NULL, yspec)< 0)
yang_spec_parse_module(h, "ietf-restconf-monitoring", CLIXON_DATADIR, NULL, yspec, NULL)< 0)
goto done;
/* Load yang Netconf stream discovery */
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") &&
yang_spec_parse_module(h, "ietf-netconf-notification", CLIXON_DATADIR, NULL, yspec)< 0)
yang_spec_parse_module(h, "ietf-netconf-notification", CLIXON_DATADIR, NULL, yspec, NULL)< 0)
goto done;
/* Set options: database dir and yangspec (could be hidden in connect?)*/
if (xmldb_setopt(h, "dbdir", clicon_xmldb_dir(h)) < 0)

View file

@ -253,8 +253,10 @@ main(int argc, char **argv)
char *restarg = NULL; /* what remains after options */
int dump_configfile_xml = 0;
yang_spec *yspec;
yang_spec *yspecfg = NULL; /* For config XXX clixon bug */
struct passwd *pw;
char *yang_filename = NULL;
yang_stmt *ymod = NULL; /* Main module */
/* Defaults */
once = 0;
@ -327,8 +329,11 @@ main(int argc, char **argv)
goto done;
}
/* Create top-level yang spec and store as option */
if ((yspecfg = yspec_new()) == NULL)
goto done;
/* Find and read configfile */
if (clicon_options_main(h) < 0){
if (clicon_options_main(h, yspecfg) < 0){
if (help)
usage(h, argv[0]);
return -1;
@ -418,19 +423,21 @@ main(int argc, char **argv)
*/
cv_exclude_keys(clicon_cli_varonly(h));
/* Create top-level and store as option */
if ((yspec = yspec_new()) == NULL)
goto done;
clicon_dbspec_yang_set(h, yspec);
/* Parse db specification as cli.
/* Load main application yang specification either module or specific file
* If -y <file> is given, it overrides main module */
if (yang_filename){
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec) < 0)
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec, &ymod) < 0)
goto done;
}
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
clicon_yang_dir(h),
clicon_yang_module_revision(h),
yspec) < 0)
yspec, &ymod) < 0)
goto done;
/* Load yang module library, RFC7895 */
if (yang_modules_init(h) < 0)
@ -449,7 +456,8 @@ main(int argc, char **argv)
if (yang2cli(h, yspec, &pt, clicon_cli_genmodel_type(h)) < 0)
goto done;
name = yang_main_module_name(yspec);
/* name of main module */
name = ymod->ys_argument;
len = strlen("datamodel:") + strlen(name) + 1;
if ((treename = malloc(len)) == NULL){

View file

@ -336,6 +336,7 @@ main(int argc,
struct passwd *pw;
struct timeval tv = {0,}; /* timeout */
yang_spec *yspec = NULL;
yang_spec *yspecfg = NULL; /* For config XXX clixon bug */
char *yang_filename = NULL;
/* Create handle */
@ -381,8 +382,11 @@ main(int argc,
clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst);
clicon_debug_init(debug, NULL);
/* Create configure yang-spec */
if ((yspecfg = yspec_new()) == NULL)
goto done;
/* Find and read configfile */
if (clicon_options_main(h) < 0)
if (clicon_options_main(h, yspecfg) < 0)
return -1;
/* Now rest of options */
@ -432,20 +436,20 @@ main(int argc,
argc -= optind;
argv += optind;
/* Create first yang spec */
/* Create top-level yang spec and store as option */
if ((yspec = yspec_new()) == NULL)
goto done;
clicon_dbspec_yang_set(h, yspec);
/* Parse yang database spec file */
/* Load main application yang specification either module or specific file
* If -y <file> is given, it overrides main module */
if (yang_filename){
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec) < 0)
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec, NULL) < 0)
goto done;
}
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
clicon_yang_dir(h),
clicon_yang_module_revision(h),
yspec) < 0)
yspec, NULL) < 0)
goto done;
/* Load yang module library, RFC7895 */

View file

@ -527,6 +527,7 @@ main(int argc,
char *tmp;
int logdst = CLICON_LOG_SYSLOG;
yang_spec *yspec = NULL;
yang_spec *yspecfg = NULL; /* For config XXX clixon bug */
char *yang_filename = NULL;
/* In the startup, logs to stderr & debug flag set later */
@ -576,8 +577,11 @@ main(int argc,
clicon_err(OE_DEMON, errno, "Setting signal");
goto done;
}
/* Create configure yang-spec */
if ((yspecfg = yspec_new()) == NULL)
goto done;
/* Find and read configfile */
if (clicon_options_main(h) < 0)
if (clicon_options_main(h, yspecfg) < 0)
goto done;
/* Now rest of options, some overwrite option file */
@ -622,18 +626,20 @@ main(int argc,
if (clixon_plugins_load(h, CLIXON_PLUGIN_INIT, dir, NULL) < 0)
return -1;
/* Parse main yang spec */
/* Create top-level yang spec and store as option */
if ((yspec = yspec_new()) == NULL)
goto done;
clicon_dbspec_yang_set(h, yspec);
/* Load main application yang specification either module or specific file
* If -y <file> is given, it overrides main module */
if (yang_filename){
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec) < 0)
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec, NULL) < 0)
goto done;
}
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
clicon_yang_dir(h),
clicon_yang_module_revision(h),
yspec) < 0)
yspec, NULL) < 0)
goto done;
/* Load yang module library, RFC7895 */
@ -641,10 +647,10 @@ main(int argc,
goto done;
/* Add system modules */
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040") &&
yang_spec_parse_module(h, "ietf-restconf-monitoring", CLIXON_DATADIR, NULL, yspec)< 0)
yang_spec_parse_module(h, "ietf-restconf-monitoring", CLIXON_DATADIR, NULL, yspec, NULL)< 0)
goto done;
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") &&
yang_spec_parse_module(h, "ietf-netconf-notification", CLIXON_DATADIR, NULL, yspec)< 0)
yang_spec_parse_module(h, "ietf-netconf-notification", CLIXON_DATADIR, NULL, yspec, NULL)< 0)
goto done;

View file

@ -206,7 +206,7 @@ main(int argc, char **argv)
if ((yspec = yspec_new()) == NULL)
goto done;
/* Parse yang spec from given file */
if (yang_parse(h, NULL, yangmodule, yangdir, NULL, yspec) < 0)
if (yang_parse(h, NULL, yangmodule, yangdir, NULL, yspec, NULL) < 0)
goto done;
/* Set database directory option */
if (xmldb_setopt(h, "dbdir", dbdir) < 0)

View file

@ -81,7 +81,8 @@ enum startup_mode_t{
/* Print registry on file. For debugging. */
void clicon_option_dump(clicon_handle h, int dblevel);
/* Initialize options: set defaults, read config-file, etc */
int clicon_options_main(clicon_handle h);
int clicon_options_main(clicon_handle h, yang_spec *yspec);
/*! Check if a clicon option has a value */
int clicon_option_exists(clicon_handle h, const char *name);

View file

@ -245,7 +245,6 @@ yang_stmt *ys_dup(yang_stmt *old);
int yn_insert(yang_node *yn_parent, yang_stmt *ys_child);
yang_stmt *yn_each(yang_node *yn, yang_stmt *ys);
char *yang_key2str(int keyword);
char *yang_main_module_name(yang_spec *ysp);
char *yarg_prefix(yang_stmt *ys);
char *yarg_id(yang_stmt *ys);
int yang_nodeid_split(char *nodeid, char **prefix, char **id);
@ -264,7 +263,7 @@ int ys_populate(yang_stmt *ys, void *arg);
yang_stmt *yang_parse_file(int fd, const char *name, yang_spec *ysp);
int yang_parse(clicon_handle h, const char *filename,
const char *module, const char *dir,
const char *revision, yang_spec *ysp);
const char *revision, yang_spec *ysp, yang_stmt **ymodp);
int yang_apply(yang_node *yn, enum rfc_6020 key, yang_applyfn_t fn,
void *arg);
int yang_abs_schema_nodeid(yang_spec *yspec, char *schema_nodeid,
@ -275,8 +274,8 @@ cg_var *ys_parse(yang_stmt *ys, enum cv_type cvtype);
int ys_parse_sub(yang_stmt *ys, char *extra);
int yang_mandatory(yang_stmt *ys);
int yang_config(yang_stmt *ys);
int yang_spec_parse_module(clicon_handle h, char *module, char *dir, char *revision, yang_spec *yspec);
int yang_spec_parse_file(clicon_handle h, char *filename, char *dir, yang_spec *yspec);
int yang_spec_parse_module(clicon_handle h, char *module, char *dir, char *revision, yang_spec *yspec, yang_stmt **ymodp);
int yang_spec_parse_file(clicon_handle h, char *filename, char *dir, yang_spec *yspec, yang_stmt **ymodp);
cvec *yang_arg2cvec(yang_stmt *ys, char *delimi);
int yang_key_match(yang_node *yn, char *name);

View file

@ -988,7 +988,7 @@ netconf_module_load(clicon_handle h)
yspec = clicon_dbspec_yang(h);
/* Load yang spec */
if (yang_spec_parse_module(h, "ietf-netconf", CLIXON_DATADIR, NULL, yspec)< 0)
if (yang_spec_parse_module(h, "ietf-netconf", CLIXON_DATADIR, NULL, yspec, NULL)< 0)
goto done;
if ((xc = clicon_conf_xml(h)) == NULL){
clicon_err(OE_CFG, ENOENT, "Clicon configuration not loaded");

View file

@ -197,21 +197,26 @@ parse_configfile(clicon_handle h,
return retval;
}
/*! Initialize option values
/*! Parse clixon yang file. Parse XML config file. Initialize option values
*
* Set default options, Read config-file, Check that all values are set.
* Parse clixon yang file and save in yspec.
* Read clixon system config files
* @param[in] h clicon handle
* @param[in] h clicon handle
* @param[in] yspec Yang spec of clixon config file
* @note Due to Bug: Top-level Yang symbol cannot be called "config" in any
* imported yang file, the config module needs to be isolated from all
* other yang modules.
*/
int
clicon_options_main(clicon_handle h)
clicon_options_main(clicon_handle h,
yang_spec *yspec)
{
int retval = -1;
char *configfile;
clicon_hash_t *copt = clicon_options(h);
char *suffix;
char xml = 0; /* Configfile is xml, otherwise legacy */
yang_spec *yspec = NULL;
cxobj *xconfig = NULL;
/*
@ -232,9 +237,7 @@ clicon_options_main(clicon_handle h)
goto done;
}
/* Parse clixon yang spec */
if ((yspec = yspec_new()) == NULL)
goto done;
if (yang_parse(h, NULL, "clixon-config", CLIXON_DATADIR, NULL, yspec) < 0)
if (yang_parse(h, NULL, "clixon-config", CLIXON_DATADIR, NULL, yspec, NULL) < 0)
goto done;
/* Read configfile */
if (parse_configfile(h, configfile, yspec, &xconfig) < 0)
@ -249,10 +252,6 @@ clicon_options_main(clicon_handle h)
xml_child_sort = 0;
retval = 0;
done:
#if 0 /* XXX yspec should be part of top-level yang but cant since it will be main module */
if (yspec)
yspec_free(yspec);
#endif
return retval;
}

View file

@ -761,20 +761,6 @@ yang_key2str(int keyword)
return (char*)clicon_int2str(ykmap, keyword);
}
/*! Name of main module of a specification. That is, name of first module
* @param[in] ysp Yang specification
* @retval name Name of first yang module
*/
char *
yang_main_module_name(yang_spec *ysp)
{
yang_stmt *ym;
if ((ym = yang_find((yang_node*)ysp, Y_MODULE, 0)) != NULL)
return ym->ys_argument;
return NULL;
}
/*! Find top module or sub-module given a statement. Ultimate top is yang spec
* The routine recursively finds ancestors.
* @param[in] ys Any yang statement in a yang tree
@ -2109,7 +2095,8 @@ yang_features(clicon_handle h,
* @param[in] filename File name containing Yang specification. Overrides module
* @param[in] module Name of main YANG module. Or absolute file name.
* @param[in] revision Main module revision date string or NULL
* @param[out] ysp Yang specification. Should have been created by caller using yspec_new
* @param[in,out] ysp Yang specification. Should have been created by caller using yspec_new
* @param[out] ymodp Yang module of first, topmost Yang module, if given.
* @retval 0 Everything OK
* @retval -1 Error encountered
* The database symbols are inserted in alphabetical order.
@ -2130,7 +2117,8 @@ yang_parse(clicon_handle h,
const char *module,
const char *dir,
const char *revision,
yang_spec *ysp)
yang_spec *ysp,
yang_stmt **ymodp)
{
int retval = -1;
yang_stmt *ymod = NULL; /* Top-level yang (sub)module */
@ -2189,7 +2177,8 @@ yang_parse(clicon_handle h,
for (i=modnr; i<ysp->yp_len; i++)
if (yang_apply((yang_node*)ysp->yp_stmt[i], -1, ys_schemanode_check, NULL) < 0)
goto done;
if (ymodp)
*ymodp = ymod;
retval = 0;
done:
return retval;
@ -2613,6 +2602,7 @@ yang_config(yang_stmt *ys)
* @param[in] dir Directory where to look for modules and sub-modules
* @param[in] revision Revision, or NULL
* @param[in,out] yspec Modules parse are added to this yangspec
* @param[out] ymodp Yang module of first, topmost Yang module, if given.
* @retval 0 OK
* @retval -1 Error
* @see yang_spec_parse_file
@ -2622,7 +2612,8 @@ yang_spec_parse_module(clicon_handle h,
char *module,
char *dir,
char *revision,
yang_spec *yspec)
yang_spec *yspec,
yang_stmt **ymodp)
{
int retval = -1;
@ -2643,7 +2634,7 @@ yang_spec_parse_module(clicon_handle h,
clicon_err(OE_YANG, EINVAL, "yang dir not set");
goto done;
}
if (yang_parse(h, NULL, module, dir, revision, yspec) < 0)
if (yang_parse(h, NULL, module, dir, revision, yspec, ymodp) < 0)
goto done;
retval = 0;
done:
@ -2655,6 +2646,7 @@ yang_spec_parse_module(clicon_handle h,
* @param[in] filename Actual filename (including dir and revision)
* @param[in] dir Directory for sub-modules
* @param[in,out] yspec Modules parse are added to this yangspec
* @param[out] ymodp Yang module of first, topmost Yang module, if given.
* @retval 0 OK
* @retval -1 Error
* @see yang_spec_parse_module for yang dir,module,revision instead of actual filename
@ -2663,7 +2655,8 @@ int
yang_spec_parse_file(clicon_handle h,
char *filename,
char *dir,
yang_spec *yspec)
yang_spec *yspec,
yang_stmt **ymodp)
{
int retval = -1;
@ -2675,7 +2668,7 @@ yang_spec_parse_file(clicon_handle h,
clicon_err(OE_YANG, EINVAL, "yang dir not set");
goto done;
}
if (yang_parse(h, filename, NULL, dir, NULL, yspec) < 0)
if (yang_parse(h, filename, NULL, dir, NULL, yspec, ymodp) < 0)
goto done;
retval = 0;
done:

View file

@ -94,7 +94,7 @@ yang_modules_init(clicon_handle h)
goto done;
}
/* Ensure revision exists is set */
if (yang_spec_parse_module(h, "ietf-yang-library", CLIXON_DATADIR, NULL, yspec)< 0)
if (yang_spec_parse_module(h, "ietf-yang-library", CLIXON_DATADIR, NULL, yspec, NULL)< 0)
goto done;
/* Find revision */
if (yang_modules_revision(h) == NULL){

View file

@ -93,9 +93,68 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candid
new "netconf disabled feature"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><A>foo</A></config></edit-config></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-tag>operation-failed</error-tag><error-type>protocol</error-type><error-severity>error</error-severity><error-message>XML node config/A has no corresponding yang specification (Invalid XML or wrong Yang spec?'
# This is difficult test since changes to the module list are frequent
# This test has been broken up into all differetn modules instead of one large
# reply since the modules change so often
new "netconf schema resource, RFC 7895"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" select="modules-state/module" xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library"/></get></rpc>]]>]]>' '^<rpc-reply><data><modules-state><module><name>example</name><revision/><namespace/><feature>A</feature></module><module><name>ietf-inet-types</name><revision>2013-07-15</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</namespace></module><module><name>ietf-interfaces</name><revision>2014-05-08</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-interfaces</namespace></module><module><name>ietf-netconf</name><revision>2011-06-01</revision><namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace></module><module><name>ietf-routing</name><revision>2014-10-26</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-routing</namespace><feature>router-id</feature></module><module><name>ietf-yang-library</name><revision>2016-06-21</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace></module><module><name>ietf-yang-types</name><revision>2013-07-15</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namespace></module></modules-state></data></rpc-reply>]]>]]>$'
ret=$($clixon_netconf -qf $cfg -y $fyang<<EOF
<rpc><get><filter type="xpath" select="modules-state/module" xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library"/></get></rpc>]]>]]>
EOF
)
new "netconf module A"
expect="<module><name>example</name><revision/><namespace/><feature>A</feature></module>"
match=`echo "$ret" | grep -GZo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
if false ; then # clixon "config" bug
new "netconf module clixon-config"
expect="<module><name>clixon-config</name><revision>2018-09-30</revision><namespace/></module>"
match=`echo "$ret" | grep -GZo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
fi # false
new "netconf module ietf-inet-types"
expect="<module><name>ietf-inet-types</name><revision>2013-07-15</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</namespace></module>"
match=`echo "$ret" | grep -GZo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
new "netconf module ietf-interfaces"
expect="<module><name>ietf-interfaces</name><revision>2014-05-08</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-interfaces</namespace></module>"
match=`echo "$ret" | grep -GZo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
new "netconf module ietf-netconf"
expect="module><name>ietf-netconf</name><revision>2011-06-01</revision><namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace></module>"
match=`echo "$ret" | grep -GZo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
new "netconf module ietf-routing"
expect="<module><name>ietf-routing</name><revision>2014-10-26</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-routing</namespace><feature>router-id</feature></module>"
match=`echo "$ret" | grep -GZo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
expect="<module><name>ietf-yang-library</name><revision>2016-06-21</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace></module>"
match=`echo "$ret" | grep -GZo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
new "netconf module ietf-yang_types"
expect="<module><name>ietf-yang-types</name><revision>2013-07-15</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namespace></module>"
match=`echo "$ret" | grep -GZo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
new "Kill backend"
# kill backend

View file

@ -1,5 +1,5 @@
#!/bin/bash
# Test: XML parser tests
# Test: YANG parser tests
#PROG="valgrind --leak-check=full --show-leak-kinds=all ../util/clixon_util_yang"
PROG=../util/clixon_util_yang