diff --git a/CHANGELOG.md b/CHANGELOG.md index 19bc0d41..e929fb82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,15 +33,19 @@ * CLICON_XML_CHANGELOG enables the yang changelog feature * CLICON_XML_CHANGELOG_FILE where the changelog resides - ### API changes on existing features (you may need to change your code) + +* Structural change: removed datastore plugin and directory, and merged into regular clixon lib code. + * The CLICON_XMLDB_PLUGIN config option is obsolete, you should remove it from your config file + * All references to plugin "text.so" should be removed. + * The datastore directory is removed, code is moved to lib/src/clixon_datastore*.c + * Removed clixon_backend -x command-line options * Structural C-code change: Merged yang_spec and yang_node types into yang_stmt * Change all yn_* and yp_ to ys_* * Change all references to yang_node/yang_spec to yang_stmt -* Structural change: removed datastore plugin and directory, and merged into regulat clixon lib code. - * The CLICON_XMLDB_PLUGIN config option is obsolete, you should remove it from your config file - * The datastore directory is removed, code is moved to lib/src/clixon_datastore*.c - * removed clixon_backend -x command-line options +* xmldb_get() removed unnecessary config option: + * Change all calls to dbget from: `xmldb_get(h, db, xpath, 0|1, &xret, msd)` to `xmldb_get(h, db, xpath, &xret, msd)` + * Moved out code from clixon_options.[ch] into a new file: clixon_data.[ch] where non-option data resides. * Directory change: Moved example to example/main to make room for other examples. * Removed argc/argv parameters from ca_start plugin API function: @@ -86,6 +90,7 @@ ``` ### Minor changes +* Optimized validation by making xml_diff work on raw cache tree (not copies) * Added syntactic check for yang status: current, deprecated or obsolete. * Added `xml_wrap` function that adds an XML node above a node as a wrapper * also renamed `xml_insert` to `xml_wrap_all`. diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 9658e4ac..b5fa54ba 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -314,7 +314,7 @@ from_client_get_config(clicon_handle h, if ((xfilter = xml_find(xe, "filter")) != NULL) if ((xpath = xml_find_value(xfilter, "select"))==NULL) xpath="/"; - if (xmldb_get(h, db, xpath, 1, &xret, NULL) < 0){ + if (xmldb_get(h, db, xpath, &xret, NULL) < 0){ if (netconf_operation_failed(cbret, "application", "read registry")< 0) goto done; goto ok; @@ -773,7 +773,7 @@ from_client_get(clicon_handle h, if ((xpath = xml_find_value(xfilter, "select"))==NULL) xpath="/"; /* Get config */ - if (xmldb_get(h, "running", xpath, 0, &xret, NULL) < 0){ + if (xmldb_get(h, "running", xpath, &xret, NULL) < 0){ if (netconf_operation_failed(cbret, "application", "read registry")< 0) goto done; goto ok; diff --git a/apps/backend/backend_commit.c b/apps/backend/backend_commit.c index 561b9956..8602166c 100644 --- a/apps/backend/backend_commit.c +++ b/apps/backend/backend_commit.c @@ -180,7 +180,7 @@ startup_common(clicon_handle h, if (clicon_option_bool(h, "CLICON_XMLDB_MODSTATE")) if ((msd = modstate_diff_new()) == NULL) goto done; - if (xmldb_get(h, db, "/", 1, &xt, msd) < 0) + if (xmldb_get(h, db, "/", &xt, msd) < 0) goto done; if (msd){ if ((ret = clixon_module_upgrade(h, xt, msd, cbret)) < 0) @@ -350,11 +350,9 @@ from_validate_common(clicon_handle h, clicon_err(OE_FATAL, 0, "No DB_SPEC"); goto done; } - /* This is the state we are going to */ - if (xmldb_get(h, candidate, "/", 1, &td->td_target, NULL) < 0) + if (xmldb_get1(h, candidate, "/", &td->td_target, NULL) < 0) goto done; - /* Validate the target state. It is not completely clear this should be done * here. It is being made in generic_validate below. * But xml_diff requires some basic validation, at least check that yang-specs @@ -367,9 +365,9 @@ from_validate_common(clicon_handle h, /* 2. Parse xml trees * This is the state we are going from */ - if (xmldb_get(h, "running", "/", 1, &td->td_src, NULL) < 0) + if (xmldb_get1(h, "running", "/", &td->td_src, NULL) < 0) goto done; - + /* 3. Compute differences */ if (xml_diff(yspec, td->td_src, @@ -469,7 +467,14 @@ candidate_commit(clicon_handle h, if (plugin_transaction_commit(h, td) < 0) goto done; - /* Optionally write (potentially modified) tree back to candidate */ + /* Clear cached trees from default values and marking */ + if (xmldb_get1_clear(h, candidate) < 0) + goto done; + if (xmldb_get1_clear(h, "running") < 0) + goto done; + + /* Optionally write (potentially modified) tree back to candidate + */ if (clicon_option_bool(h, "CLICON_TRANSACTION_MOD")){ if ((ret = xmldb_put(h, candidate, OP_REPLACE, td->td_target, clicon_username_get(h), cbret)) < 0) @@ -490,8 +495,14 @@ candidate_commit(clicon_handle h, /* In case of failure (or error), call plugin transaction termination callbacks */ if (retval < 1 && td) plugin_transaction_abort(h, td); - if (td) + if (td){ + if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){ + /* xmldb_get1 requires free only if not cache */ + td->td_target = NULL; + td->td_src = NULL; + } transaction_free(td); + } return retval; fail: retval = 0; @@ -662,7 +673,7 @@ from_client_validate(clicon_handle h, } clicon_debug(1, "Validate %s", db); - /* 1. Start transaction */ + /* 1. Start transaction */ if ((td = transaction_new()) == NULL) goto done; /* Common steps (with commit) */ @@ -674,6 +685,12 @@ from_client_validate(clicon_handle h, } goto ok; } + /* Clear cached trees from default values and marking */ + if (xmldb_get1_clear(h, db) < 0) + goto done; + if (xmldb_get1_clear(h, "running") < 0) + goto done; + /* Optionally write (potentially modified) tree back to candidate */ if (clicon_option_bool(h, "CLICON_TRANSACTION_MOD")){ if ((ret = xmldb_put(h, "candidate", OP_REPLACE, td->td_target, @@ -685,10 +702,16 @@ from_client_validate(clicon_handle h, ok: retval = 0; done: - if (retval < 0 && td) - plugin_transaction_abort(h, td); - if (td) - transaction_free(td); + if (retval < 0 && td) + plugin_transaction_abort(h, td); + if (td){ + if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){ + /* xmldb_get1 requires free only if not cache */ + td->td_target = NULL; + td->td_src = NULL; + } + transaction_free(td); + } return retval; } /* from_client_validate */ diff --git a/apps/backend/backend_startup.c b/apps/backend/backend_startup.c index c59f1736..9c9ab382 100644 --- a/apps/backend/backend_startup.c +++ b/apps/backend/backend_startup.c @@ -102,7 +102,7 @@ db_merge(clicon_handle h, cxobj *xt = NULL; /* Get data as xml from db1 */ - if (xmldb_get(h, (char*)db1, NULL, 1, &xt, NULL) < 0) + if (xmldb_get(h, (char*)db1, NULL, &xt, NULL) < 0) goto done; /* Merge xml into db2. Without commit */ retval = xmldb_put(h, (char*)db2, OP_MERGE, xt, clicon_username_get(h), cbret); diff --git a/doc/DEVELOP.md b/doc/DEVELOP.md index cb59647e..7e17d086 100644 --- a/doc/DEVELOP.md +++ b/doc/DEVELOP.md @@ -83,7 +83,6 @@ cat < /tmp/myconf.xml /usr/local/var/example/example.sock /usr/local/var/example/example.pidfile /usr/local/var/example - /usr/local/lib/xmldb/text.so EOF sudo clixon_backend -F -s init -f /tmp/myconf.xml -y /tmp/my.yang diff --git a/docker/system/start.sh b/docker/system/start.sh index af20ae1d..909f72fd 100755 --- a/docker/system/start.sh +++ b/docker/system/start.sh @@ -39,7 +39,6 @@ CONFIG0=$(cat <1 VARS /usr/local/var/example - /usr/local/lib/xmldb/text.so 0 init disabled diff --git a/example/main/example.xml b/example/main/example.xml index 3d3cf99b..a7c13214 100644 --- a/example/main/example.xml +++ b/example/main/example.xml @@ -14,7 +14,6 @@ 1 VARS /usr/local/var/example - /usr/local/lib/xmldb/text.so 0 init disabled diff --git a/lib/clixon/clixon_datastore.h b/lib/clixon/clixon_datastore.h index 89b7d1f1..61ec86a2 100644 --- a/lib/clixon/clixon_datastore.h +++ b/lib/clixon/clixon_datastore.h @@ -48,7 +48,9 @@ int xmldb_db2file(clicon_handle h, const char *db, char **filename); int xmldb_validate_db(const char *db); int xmldb_connect(clicon_handle h); int xmldb_disconnect(clicon_handle h); -int xmldb_get(clicon_handle h, const char *db, char *xpath, int config, cxobj **xtop, modstate_diff_t *msd); +int xmldb_get(clicon_handle h, const char *db, char *xpath, cxobj **xtop, modstate_diff_t *msd); /* in clixon_datastore_read.[ch] */ +int xmldb_get1(clicon_handle h, const char *db, char *xpath, cxobj **xtop, modstate_diff_t *msd); /* in clixon_datastore_read.[ch] */ +int xmldb_get1_clear(clicon_handle h, const char *db); int xmldb_put(clicon_handle h, const char *db, enum operation_type op, cxobj *xt, char *username, cbuf *cbret); /* in clixon_datastore_write.[ch] */ int xmldb_copy(clicon_handle h, const char *from, const char *to); int xmldb_lock(clicon_handle h, const char *db, int pid); diff --git a/lib/clixon/clixon_xml.h b/lib/clixon/clixon_xml.h index 8114133d..ef6395a7 100644 --- a/lib/clixon/clixon_xml.h +++ b/lib/clixon/clixon_xml.h @@ -85,6 +85,7 @@ typedef int (xml_applyfn_t)(cxobj *x, void *arg); #define XML_FLAG_DEL 0x04 /* Node is deleted (commits) or parent deleted rec */ #define XML_FLAG_CHANGE 0x08 /* Node is changed (commits) or child changed rec */ #define XML_FLAG_NONE 0x10 /* Node is added as NONE */ +#define XML_FLAG_DEFAULT 0x20 /* Added as default value @see xml_default*/ /* * Prototypes @@ -137,6 +138,7 @@ int xml_rootchild(cxobj *xp, int i, cxobj **xcp); int xml_rootchild_node(cxobj *xp, cxobj *xc); int xml_enumerate_children(cxobj *xp); +int xml_enumerate_reset(cxobj *xp); int xml_enumerate_get(cxobj *x); char *xml_body(cxobj *xn); diff --git a/lib/clixon/clixon_xml_map.h b/lib/clixon/clixon_xml_map.h index def72601..5fda5af5 100644 --- a/lib/clixon/clixon_xml_map.h +++ b/lib/clixon/clixon_xml_map.h @@ -51,10 +51,10 @@ int xml_yang_validate_all(cxobj *xt, cbuf *cbret); int xml_yang_validate_all_top(cxobj *xt, cbuf *cbret); int xml2cvec(cxobj *xt, yang_stmt *ys, cvec **cvv0); int cvec2xml_1(cvec *cvv, char *toptag, cxobj *xp, cxobj **xt0); -int xml_diff(yang_stmt *yspec, cxobj *xt1, cxobj *xt2, +int xml_diff(yang_stmt *yspec, cxobj *x0, cxobj *x1, cxobj ***first, size_t *firstlen, cxobj ***second, size_t *secondlen, - cxobj ***changed1, cxobj ***changed2, size_t *changedlen); + cxobj ***changed_x0, cxobj ***changed_x1, size_t *changedlen); int yang2api_path_fmt(yang_stmt *ys, int inclkey, char **api_path_fmt); int api_path_fmt2api_path(char *api_path_fmt, cvec *cvv, char **api_path); int api_path_fmt2xpath(char *api_path_fmt, cvec *cvv, char **xpath); diff --git a/lib/src/clixon_datastore.c b/lib/src/clixon_datastore.c index e85270bc..149cf49d 100644 --- a/lib/src/clixon_datastore.c +++ b/lib/src/clixon_datastore.c @@ -172,42 +172,6 @@ xmldb_disconnect(clicon_handle h) return retval; } -/*! Get content of database using xpath. return a set of matching sub-trees - * The function returns a minimal tree that includes all sub-trees that match - * xpath. - * @param[in] h Clicon handle - * @param[in] dbname Name of database to search in (filename including dir path - * @param[in] xpath String with XPATH syntax. or NULL for all - * @param[in] config If set only configuration data, else also state - * @param[out] xret Single return XML tree. Free with xml_free() - * @param[out] msd If set, return modules-state differences - * @retval 0 OK - * @retval -1 Error - * @code - * cxobj *xt; - * if (xmldb_get(xh, "running", "/interfaces/interface[name="eth"]", 1, &xt, NULL) < 0) - * err; - * xml_free(xt); - * @endcode - * @note if xvec is given, then purge tree, if not return whole tree. - * @see xpath_vec - */ -int -xmldb_get(clicon_handle h, - const char *db, - char *xpath, - int config, - cxobj **xret, - modstate_diff_t *msd) -{ - int retval = -1; - - if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")) - retval = xmldb_get_cache(h, db, xpath, config, xret, msd); - else - retval = xmldb_get_nocache(h, db, xpath, config, xret, msd); - return retval; -} /*! Copy database from db1 to db2 * @param[in] h Clicon handle @@ -264,11 +228,11 @@ xmldb_copy(clicon_handle h, clicon_db_elmnt_set(h, to, &de0); } } + /* Copy the files themselves (above only in-memory cache) */ if (xmldb_db2file(h, from, &fromfile) < 0) goto done; if (xmldb_db2file(h, to, &tofile) < 0) goto done; - /* Copy the files themselves (above only in-memory cache) */ if (clicon_file_copy(fromfile, tofile) < 0) goto done; retval = 0; diff --git a/lib/src/clixon_datastore_read.c b/lib/src/clixon_datastore_read.c index 720fecda..80a6d635 100644 --- a/lib/src/clixon_datastore_read.c +++ b/lib/src/clixon_datastore_read.c @@ -374,18 +374,16 @@ xmldb_readfile(clicon_handle h, * @param[in] h Clicon handle * @param[in] db Name of database to search in (filename including dir path * @param[in] xpath String with XPATH syntax. or NULL for all - * @param[in] config If set only configuration data, else also state * @param[out] xret Single return XML tree. Free with xml_free() * @param[out] msd If set, return modules-state differences * @retval 0 OK * @retval -1 Error * @see xmldb_get the generic API function */ -int +static int xmldb_get_nocache(clicon_handle h, const char *db, char *xpath, - int config, cxobj **xtop, modstate_diff_t *msd) { @@ -457,15 +455,6 @@ xmldb_get_nocache(clicon_handle h, if (xml_apply(xt, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)XML_FLAG_MARK) < 0) goto done; - /* filter out state (operations) data if config not set. Mark all nodes - that are not config data */ - if (config){ - if (xml_apply(xt, CX_ELMNT, xml_non_config_data, NULL) < 0) - goto done; - /* Remove (prune) nodes that are marked (that does not pass test) */ - if (xml_tree_prune_flagged(xt, XML_FLAG_MARK, 1) < 0) - goto done; - } /* Add default values (if not set) */ if (xml_apply(xt, CX_ELMNT, xml_default, NULL) < 0) goto done; @@ -497,20 +486,18 @@ xmldb_get_nocache(clicon_handle h, * @param[in] h Clicon handle * @param[in] db Name of database to search in (filename including dir path * @param[in] xpath String with XPATH syntax. or NULL for all - * @param[in] config If set only configuration data, else also state * @param[out] xret Single return XML tree. Free with xml_free() * @param[out] msd If set, return modules-state differences * @retval 0 OK * @retval -1 Error * @see xmldb_get the generic API function */ -int +static int xmldb_get_cache(clicon_handle h, - const char *db, - char *xpath, - int config, - cxobj **xtop, - modstate_diff_t *msd) + const char *db, + char *xpath, + cxobj **xtop, + modstate_diff_t *msd) { int retval = -1; yang_stmt *yspec; @@ -591,3 +578,183 @@ xmldb_get_cache(clicon_handle h, return retval; } +/*! Get the raw cache of whole tree + * Useful for some higer level usecases for optimized access + * This is a clixon datastore plugin of the the xmldb api + * @param[in] h Clicon handle + * @param[in] db Name of database to search in (filename including dir path + * @param[in] xpath String with XPATH syntax. or NULL for all + * @param[in] config If set only configuration data, else also state + * @param[out] xret Single return XML tree. Free with xml_free() + * @param[out] msd If set, return modules-state differences + * @retval 0 OK + * @retval -1 Error + */ +static int +xmldb_get1_cache(clicon_handle h, + const char *db, + char *xpath, + cxobj **xtop, + modstate_diff_t *modst) +{ + int retval = -1; + yang_spec *yspec; + cxobj *x0t = NULL; /* (cached) top of tree */ + cxobj **xvec = NULL; + size_t xlen; + int i; + cxobj *x0; + db_elmnt *de = NULL; + db_elmnt de0 = {0,}; + + if (!clicon_option_bool(h, "CLICON_XMLDB_CACHE")){ + clicon_err(OE_CFG, 0, "CLICON_XMLDB_CACHE must be set"); + goto done; + } + if ((yspec = clicon_dbspec_yang(h)) == NULL){ + clicon_err(OE_YANG, ENOENT, "No yang spec"); + goto done; + } + de = clicon_db_elmnt_get(h, db); + if (de == NULL || de->de_xml == NULL){ /* Cache miss, read XML from file */ + /* If there is no xml x0 tree (in cache), then read it from file */ + if (xmldb_readfile(h, db, yspec, &x0t, modst) < 0) + goto done; + /* XXX: should we validate file if read from disk? + * Argument against: we may want to have a semantically wrong file and wish + * to edit? + */ + de0.de_xml = x0t; + clicon_db_elmnt_set(h, db, &de0); + } /* x0t == NULL */ + else + x0t = de->de_xml; + /* Here xt looks like: ... */ + if (xpath_vec(x0t, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + goto done; + /* Iterate through the match vector + * For every node found in x0, mark the tree up to t1 + */ + for (i=0; i1) + clicon_xml2file(stderr, x0t, 0, 1); + *xtop = x0t; + retval = 0; + done: + clicon_debug(1, "%s retval:%d", __FUNCTION__, retval); + if (xvec) + free(xvec); + return retval; +} + +/*! Get content of database using xpath. return a set of matching sub-trees + * The function returns a minimal tree that includes all sub-trees that match + * xpath. + * @param[in] h Clicon handle + * @param[in] db Name of database to search in (filename including dir path + * @param[in] xpath String with XPATH syntax. or NULL for all + * @param[out] xret Single return XML tree. Free with xml_free() + * @param[out] msd If set, return modules-state differences + * @retval 0 OK + * @retval -1 Error + * @code + * cxobj *xt; + * if (xmldb_get(xh, "running", "/interfaces/interface[name="eth"]", &xt, NULL) < 0) + * err; + * xml_free(xt); + * @endcode + * @note if xvec is given, then purge tree, if not return whole tree. + * @see xpath_vec + */ +int +xmldb_get(clicon_handle h, + const char *db, + char *xpath, + cxobj **xret, + modstate_diff_t *msd) +{ + int retval = -1; + + if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")) + retval = xmldb_get_cache(h, db, xpath, xret, msd); + else + retval = xmldb_get_nocache(h, db, xpath, xret, msd); + return retval; +} + +/*! Get content of database using xpath. return a set of matching sub-trees + * The function returns a minimal tree that includes all sub-trees that match + * xpath. + * @param[in] h Clicon handle + * @param[in] db Name of database to search in (filename including dir path + * @param[in] xpath String with XPATH syntax. or NULL for all + * @param[out] xret Single return XML tree. see note + * @param[out] msd If set, return modules-state differences + * @retval 0 OK + * @retval -1 Error + * @code + * cxobj *xt; + * if (xmldb_get(xh, "running", "/interfaces/interface[name="eth"]", &xt, NULL) < 0) + * err; + * xml_free(xt); + * @endcode + * @note if xvec is given, then purge tree, if not return whole tree. + * @see xmldb_get This version uses direct cache access and needs to be + * cleanued up after use + * @see xmldb_get1_clean Must call after use + * @note If !CLICON_XMLDB_CACHE you need to free xret after use + * This should probably replace xmldb_get completely + */ +int +xmldb_get1(clicon_handle h, + const char *db, + char *xpath, + cxobj **xret, + modstate_diff_t *msd) +{ + int retval = -1; + + if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")) + retval = xmldb_get1_cache(h, db, xpath, xret, msd); + else + retval = xmldb_get_nocache(h, db, xpath, xret, msd); + return retval; +} + +/*! Clear cached tree after accessed by xmldb_get1 + * + * @param[in] h Clicon handle + * @param[in] dbname Name of database to search in (filename including dir path + * @see xmldb_get1 + */ +int +xmldb_get1_clear(clicon_handle h, + const char *db) +{ + int retval = -1; + db_elmnt *de = NULL; + + if (!clicon_option_bool(h, "CLICON_XMLDB_CACHE")) + goto ok; /* dont bother, tree is a copy */ + de = clicon_db_elmnt_get(h, db); + if (de != NULL && de->de_xml != NULL){ + /* clear XML tree of defaults */ + if (xml_tree_prune_flagged(de->de_xml, XML_FLAG_DEFAULT, 1) < 0) + goto done; + /* clear mark and change */ + xml_apply0(de->de_xml, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, + (void*)(0xff)); + } + ok: + retval = 0; + done: + return retval; + +} diff --git a/lib/src/clixon_datastore_read.h b/lib/src/clixon_datastore_read.h index 29b1c979..3cbdef21 100644 --- a/lib/src/clixon_datastore_read.h +++ b/lib/src/clixon_datastore_read.h @@ -39,8 +39,6 @@ /* * Prototypes */ -int xmldb_get_cache(clicon_handle h, const char *db, char *xpath, int config, cxobj **xret, modstate_diff_t *msd); -int xmldb_get_nocache(clicon_handle h, const char *db, char *xpath, int config, cxobj **xret, modstate_diff_t *msd); -int xmldb_readfile(clicon_handle h, const char *db, yang_stmt *yspec, cxobj **xp, modstate_diff_t *msd); +int xmldb_readfile(clicon_handle h, const char *db, yang_stmt *yspec, cxobj **xp, modstate_diff_t *msd); #endif /* _CLIXON_DATASTORE_READ_H */ diff --git a/lib/src/clixon_datastore_write.c b/lib/src/clixon_datastore_write.c index 0172cc0e..b1727945 100644 --- a/lib/src/clixon_datastore_write.c +++ b/lib/src/clixon_datastore_write.c @@ -30,15 +30,6 @@ the terms of any one of the Apache License version 2 or the GPL. ***** END LICENSE BLOCK ***** -1000 entries -valgrind --tool=callgrind datastore_client -d candidate -b /tmp/text -p ../datastore/text/text.so -y /tmp -m ietf-ip mget 300 /x/y[a=574][b=574] > /dev/null - xml_copy_marked 87% 200x - yang_key_match 81% 600K - yang_arg2cvec 52% 400K - cvecfree 23% 400K - -10000 entries -valgrind --tool=callgrind datastore_client -d candidate -b /tmp/text -p ../datastore/text/text.so -y /tmp -m ietf-ip mget 10 /x/y[a=574][b=574] > /dev/null */ @@ -136,6 +127,7 @@ text_modify(clicon_handle h, cxobj **x0vec = NULL; int i; int ret; + int changed = 0; /* Only if x0p's children have changed-> sort is necessary */ assert(x1 && xml_type(x1) == CX_ELMNT); assert(y0); @@ -167,6 +159,7 @@ text_modify(clicon_handle h, // int iamkey=0; if ((x0 = xml_new(x1name, x0p, (yang_stmt*)y0)) == NULL) goto done; + changed++; /* Copy xmlns attributes */ x1a = NULL; @@ -291,6 +284,7 @@ text_modify(clicon_handle h, } if ((x0 = xml_new(x1name, x0p, (yang_stmt*)y0)) == NULL) goto done; + changed++; /* Copy xmlns attributes */ x1a = NULL; while ((x1a = xml_child_each(x1, x1a, CX_ATTR)) != NULL) @@ -368,13 +362,15 @@ text_modify(clicon_handle h, } if (xml_purge(x0) < 0) goto done; + changed++; } break; default: break; } /* CONTAINER switch op */ } /* else Y_CONTAINER */ - xml_sort(x0p, NULL); + if (changed) + xml_sort(x0p, NULL); retval = 1; done: if (x0vec) @@ -671,7 +667,7 @@ xmldb_put(clicon_handle h, if (xml_tree_prune_flagged_sub(x0, XML_FLAG_NONE, 0, NULL) <0) goto done; if (xml_apply(x0, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, - (void*)XML_FLAG_NONE) < 0) + (void*)(XML_FLAG_NONE|XML_FLAG_MARK)) < 0) goto done; /* Mark non-presence containers that do not have children */ if (xml_apply(x0, CX_ELMNT, (xml_applyfn_t*)xml_container_presence, NULL) < 0) diff --git a/lib/src/clixon_nacm.c b/lib/src/clixon_nacm.c index 3737561a..6f6f014b 100644 --- a/lib/src/clixon_nacm.c +++ b/lib/src/clixon_nacm.c @@ -890,7 +890,7 @@ nacm_access_pre(clicon_handle h, goto done; } else if (strcmp(mode, "internal")==0){ - if (xmldb_get(h, "running", "nacm", 0, &xnacm0, NULL) < 0) + if (xmldb_get(h, "running", "nacm", &xnacm0, NULL) < 0) goto done; } } diff --git a/lib/src/clixon_xml.c b/lib/src/clixon_xml.c index 966e37f5..957a8135 100644 --- a/lib/src/clixon_xml.c +++ b/lib/src/clixon_xml.c @@ -811,6 +811,7 @@ xml_find(cxobj *x_up, * @retval 0 OK * @retval -1 Error * @see xml_wrap + * @note xc is not sorted correctly, need to call xml_sort on parent */ int xml_addsub(cxobj *xp, @@ -1094,6 +1095,18 @@ xml_enumerate_children(cxobj *xp) return 0; } +/*! Reset enumeration as done by xml_enumerate_children + */ +int +xml_enumerate_reset(cxobj *xp) +{ + cxobj *x = NULL; + + while ((x = xml_child_each(xp, x, -1)) != NULL) + x->_x_i = 0; + return 0; +} + /*! Get the enumeration of a single child set by enumeration of parent * @see xml_children_enumerate * @note that it has to be called right after xml_children_enumerate. If not, diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index f086aa62..ff85a4d2 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -1051,96 +1051,98 @@ cvec2xml_1(cvec *cvv, } /*! Recursive help function to compute differences between two xml trees - * @param[in] x1 First XML tree - * @param[in] x2 Second XML tree - * @param[out] x1vec Pointervector to XML nodes existing in only first tree - * @param[out] x1veclen Length of first vector - * @param[out] x2vec Pointervector to XML nodes existing in only second tree - * @param[out] x2veclen Length of x2vec vector - * @param[out] changed_x1 Pointervector to XML nodes changed orig value - * @param[out] changed_x2 Pointervector to XML nodes changed wanted value + * @param[in] x0 First XML tree + * @param[in] x1 Second XML tree + * @param[out] x0vec Pointervector to XML nodes existing in only first tree + * @param[out] x0veclen Length of first vector + * @param[out] x1vec Pointervector to XML nodes existing in only second tree + * @param[out] x1veclen Length of x1vec vector + * @param[out] changed_x0 Pointervector to XML nodes changed orig value + * @param[out] changed_x1 Pointervector to XML nodes changed wanted value * @param[out] changedlen Length of changed vector */ static int xml_diff1(yang_stmt *ys, - cxobj *x1, - cxobj *x2, + cxobj *x0, + cxobj *x1, + cxobj ***x0vec, + size_t *x0veclen, cxobj ***x1vec, size_t *x1veclen, - cxobj ***x2vec, - size_t *x2veclen, + cxobj ***changed_x0, cxobj ***changed_x1, - cxobj ***changed_x2, size_t *changedlen) { int retval = -1; + cxobj *x0c = NULL; /* x0 child */ cxobj *x1c = NULL; /* x1 child */ - cxobj *x2c = NULL; /* x2 child */ yang_stmt *yc; char *b1; char *b2; clicon_debug(2, "%s: %s", __FUNCTION__, ys->ys_argument?ys->ys_argument:"yspec"); - /* Check nodes present in x1 and x2 + nodes only in x1 - * Loop over x1 + /* Check nodes present in x0 and x1 + nodes only in x0 + * Loop over x0 * XXX: room for improvement. Compare with match_base_child() */ + x0c = NULL; + while ((x0c = xml_child_each(x0, x0c, CX_ELMNT)) != NULL){ + if ((yc = xml_spec(x0c)) == NULL){ + clicon_err(OE_UNIX, errno, "Unknown element: %s", xml_name(x0c)); + goto done; + } + /* Does x1 have a child matching x0c? */ + if (match_base_child(x1, x0c, yc, &x1c) < 0) + goto done; + if (x1c == NULL){ + if (cxvec_append(x0c, x0vec, x0veclen) < 0) + goto done; + } + else if (yang_choice(yc)){ + /* if x0c and x1c are choice/case, then they are changed */ + if (cxvec_append(x0c, changed_x0, changedlen) < 0) + goto done; + (*changedlen)--; /* append two vectors */ + if (cxvec_append(x1c, changed_x1, changedlen) < 0) + goto done; + } + else{ /* if x0c and x1c are leafs w bodies, then they are changed */ + if (yc->ys_keyword == Y_LEAF){ + if ((b1 = xml_body(x0c)) == NULL) /* empty type */ + break; + if ((b2 = xml_body(x1c)) == NULL) /* empty type */ + break; + if (strcmp(b1, b2)){ + if (cxvec_append(x0c, changed_x0, changedlen) < 0) + goto done; + (*changedlen)--; /* append two vectors */ + if (cxvec_append(x1c, changed_x1, changedlen) < 0) + goto done; + } + } + if (xml_diff1(yc, x0c, x1c, + x0vec, x0veclen, + x1vec, x1veclen, + changed_x0, changed_x1, changedlen)< 0) + goto done; + } + } /* while x0 */ + /* Check nodes present only in x1 + * Loop over x1 + */ x1c = NULL; while ((x1c = xml_child_each(x1, x1c, CX_ELMNT)) != NULL){ if ((yc = xml_spec(x1c)) == NULL){ clicon_err(OE_UNIX, errno, "Unknown element: %s", xml_name(x1c)); goto done; } - if (match_base_child(x2, x1c, yc, &x2c) < 0) + /* Does x0 have a child matching x1c? */ + if (match_base_child(x0, x1c, yc, &x0c) < 0) goto done; - if (x2c == NULL){ + if (x0c == NULL) if (cxvec_append(x1c, x1vec, x1veclen) < 0) goto done; - } - else if (yang_choice(yc)){ - /* if x1c and x2c are choice/case, then they are changed */ - if (cxvec_append(x1c, changed_x1, changedlen) < 0) - goto done; - (*changedlen)--; /* append two vectors */ - if (cxvec_append(x2c, changed_x2, changedlen) < 0) - goto done; - } - else{ /* if x1c and x2c are leafs w bodies, then they are changed */ - if (yc->ys_keyword == Y_LEAF){ - if ((b1 = xml_body(x1c)) == NULL) /* empty type */ - break; - if ((b2 = xml_body(x2c)) == NULL) /* empty type */ - break; - if (strcmp(b1, b2)){ - if (cxvec_append(x1c, changed_x1, changedlen) < 0) - goto done; - (*changedlen)--; /* append two vectors */ - if (cxvec_append(x2c, changed_x2, changedlen) < 0) - goto done; - } - } - if (xml_diff1(yc, x1c, x2c, - x1vec, x1veclen, - x2vec, x2veclen, - changed_x1, changed_x2, changedlen)< 0) - goto done; - } - } /* while x1 */ - /* Check nodes present only in x2 - * Loop over x2 - */ - x2c = NULL; - while ((x2c = xml_child_each(x2, x2c, CX_ELMNT)) != NULL){ - if ((yc = xml_spec(x2c)) == NULL){ - clicon_err(OE_UNIX, errno, "Unknown element: %s", xml_name(x2c)); - goto done; - } - if (match_base_child(x1, x2c, yc, &x1c) < 0) - goto done; - if (x1c == NULL) - if (cxvec_append(x2c, x2vec, x2veclen) < 0) - goto done; - } /* while x1 */ + } /* while x0 */ retval = 0; done: return retval; @@ -1148,28 +1150,28 @@ xml_diff1(yang_stmt *ys, /*! Compute differences between two xml trees * @param[in] yspec Yang specification - * @param[in] x1 First XML tree - * @param[in] x2 Second XML tree + * @param[in] x0 First XML tree + * @param[in] x1 Second XML tree * @param[out] first Pointervector to XML nodes existing in only first tree * @param[out] firstlen Length of first vector * @param[out] second Pointervector to XML nodes existing in only second tree * @param[out] secondlen Length of second vector - * @param[out] changed1 Pointervector to XML nodes changed orig value - * @param[out] changed2 Pointervector to XML nodes changed wanted value + * @param[out] changed_x0 Pointervector to XML nodes changed orig value + * @param[out] changed_x1 Pointervector to XML nodes changed wanted value * @param[out] changedlen Length of changed vector * All xml vectors should be freed after use. * Bot xml trees should be freed with xml_free() */ int xml_diff(yang_stmt *yspec, - cxobj *x1, - cxobj *x2, + cxobj *x0, + cxobj *x1, cxobj ***first, size_t *firstlen, cxobj ***second, size_t *secondlen, - cxobj ***changed1, - cxobj ***changed2, + cxobj ***changed_x0, + cxobj ***changed_x1, size_t *changedlen) { int retval = -1; @@ -1177,22 +1179,22 @@ xml_diff(yang_stmt *yspec, *firstlen = 0; *secondlen = 0; *changedlen = 0; - if (x1 == NULL && x2 == NULL) + if (x0 == NULL && x1 == NULL) return 0; - if (x2 == NULL){ - if (cxvec_append(x1, first, firstlen) < 0) - goto done; - goto ok; - } if (x1 == NULL){ - if (cxvec_append(x1, second, secondlen) < 0) + if (cxvec_append(x0, first, firstlen) < 0) goto done; goto ok; } - if (xml_diff1((yang_stmt*)yspec, x1, x2, + if (x0 == NULL){ + if (cxvec_append(x0, second, secondlen) < 0) + goto done; + goto ok; + } + if (xml_diff1((yang_stmt*)yspec, x0, x1, first, firstlen, second, secondlen, - changed1, changed2, changedlen) < 0) + changed_x0, changed_x1, changedlen) < 0) goto done; ok: retval = 0; @@ -1565,14 +1567,13 @@ xml_tree_prune_flagged_sub(cxobj *xt, return retval; } - /*! Prune everything that passes test * @param[in] xt XML tree with some node marked * @param[in] flag Which flag to test for * @param[in] test 1: test that flag is set, 0: test that flag is not set * The function removes all branches that does not pass test * @code - * xml_tree_prune_flagged(xt, XML_FLAG_MARK, 1, NULL); + * xml_tree_prune_flagged(xt, XML_FLAG_MARK, 1); * @endcode */ int @@ -1638,6 +1639,7 @@ xml_default(cxobj *xt, if (!xml_find(xt, y->ys_argument)){ if ((xc = xml_new(y->ys_argument, xt, y)) == NULL) goto done; + xml_flag_set(xc, XML_FLAG_DEFAULT); if ((xb = xml_new("body", xc, NULL)) == NULL) goto done; xml_type_set(xb, CX_BODY); @@ -1652,7 +1654,7 @@ xml_default(cxobj *xt, } } } - // xml_sort(xt, NULL); + xml_sort(xt, NULL); retval = 0; done: return retval; diff --git a/lib/src/clixon_xml_sort.c b/lib/src/clixon_xml_sort.c index 93880c53..c5cc305b 100644 --- a/lib/src/clixon_xml_sort.c +++ b/lib/src/clixon_xml_sort.c @@ -76,7 +76,6 @@ */ static int xml_cv_cache(cxobj *x, - char *body, cg_var **cvp) { int retval = -1; @@ -88,7 +87,9 @@ xml_cv_cache(cxobj *x, char *reason=NULL; int options = 0; uint8_t fraction = 0; - + char *body; + + body = xml_body(x); if ((cv = xml_cv(x)) != NULL) goto ok; if ((y = xml_spec(x)) == NULL) @@ -186,24 +187,21 @@ xml_child_spec(cxobj *x, return retval; } -/*! Help function to qsort for sorting entries in xml child vector - * @param[in] arg1 - actually cxobj** - * @param[in] arg2 - actually cxobj** +/*! Help function to qsort for sorting entries in xml child vector same parent + * @param[in] xml object 1 + * @param[in] xml object 2 * @retval 0 If equal - * @retval <0 if arg1 is less than arg2 - * @retval >0 if arg1 is greater than arg2 - * @note args are pointer ot pointers, to fit into qsort cmp function + * @retval <0 if x1 is less than x2 + * @retval >0 if x1 is greater than x2 * @see xml_cmp1 Similar, but for one object * @note empty value/NULL is smallest value * @note xml_enumerate_children must have been called prior to this call * @note some error cases return as -1 (qsort cant handle errors) */ static int -xml_cmp(const void* arg1, - const void* arg2) +xml_cmp(cxobj *x1, + cxobj *x2) { - cxobj *x1 = *(struct xml**)arg1; - cxobj *x2 = *(struct xml**)arg2; yang_stmt *y1; yang_stmt *y2; int yi1 = 0; @@ -242,7 +240,6 @@ xml_cmp(const void* arg1, equal = 1; goto done; } - e=2; if (y1 != y2){ yi1 = yang_order(y1); @@ -268,9 +265,9 @@ xml_cmp(const void* arg1, else if ((b2 = xml_body(x2)) == NULL) equal = 1; else{ - if (xml_cv_cache(x1, b1, &cv1) < 0) /* error case */ + if (xml_cv_cache(x1, &cv1) < 0) /* error case */ goto done; - if (xml_cv_cache(x2, b2, &cv2) < 0) /* error case */ + if (xml_cv_cache(x2, &cv2) < 0) /* error case */ goto done; equal = cv_cmp(cv1, cv2); } @@ -283,15 +280,15 @@ xml_cmp(const void* arg1, while ((cvi = cvec_each(cvk, cvi)) != NULL) { keyname = cv_string_get(cvi); /* operational data may have NULL keys*/ if ((x1b = xml_find(x1, keyname)) == NULL || - (b1 = xml_body(x1b)) == NULL) + xml_body(x1b) == NULL) equal = -1; else if ((x2b = xml_find(x2, keyname)) == NULL || - (b2 = xml_body(x2b)) == NULL) + xml_body(x2b) == NULL) equal = 1; else{ - if (xml_cv_cache(x1b, b1, &cv1) < 0) /* error case */ + if (xml_cv_cache(x1b, &cv1) < 0) /* error case */ goto done; - if (xml_cv_cache(x2b, b2, &cv2) < 0) /* error case */ + if (xml_cv_cache(x2b, &cv2) < 0) /* error case */ goto done; if ((equal = cv_cmp(cv1, cv2)) != 0) goto done; @@ -308,6 +305,16 @@ xml_cmp(const void* arg1, return equal; } +/*! + * @note args are pointer ot pointers, to fit into qsort cmp function + */ +static int +xml_cmp_qsort(const void* arg1, + const void* arg2) +{ + return xml_cmp(*(struct xml**)arg1, *(struct xml**)arg2); +} + /*! Compare xml object * @param[in] x XML node to compare with * @param[in] y The yang spec of x @@ -358,7 +365,7 @@ xml_cmp1(cxobj *x, match = 1; else{ if (keycvec[0]){ - if (xml_cv_cache(x, b, &cv) < 0) /* error case */ + if (xml_cv_cache(x, &cv) < 0) /* error case */ goto done; match = cv_cmp(keycvec[0], cv); } @@ -377,7 +384,7 @@ xml_cmp1(cxobj *x, break; /* error case */ if ((b = xml_body(xb)) == NULL) break; /* error case */ - if (xml_cv_cache(xb, b, &cv) < 0) /* error case */ + if (xml_cv_cache(xb, &cv) < 0) /* error case */ goto done; if (keycvec[i]){ if ((match = cv_cmp(keycvec[i], cv)) != 0) @@ -395,7 +402,7 @@ xml_cmp1(cxobj *x, return match; } -/*! Sort children of an XML node +/*! Sort children of an XML node * Assume populated by yang spec. * @param[in] x0 XML node * @param[in] arg Dummy so it can be called by xml_apply() @@ -414,7 +421,7 @@ xml_sort(cxobj *x, if ((ys = xml_spec(x)) != 0 && yang_config(ys)==0) return 1; xml_enumerate_children(x); - qsort(xml_childvec_get(x), xml_child_nr(x), sizeof(cxobj *), xml_cmp); + qsort(xml_childvec_get(x), xml_child_nr(x), sizeof(cxobj *), xml_cmp_qsort); return 0; } @@ -489,6 +496,7 @@ xml_search1(cxobj *x0, if ((y = xml_spec(xc)) == NULL) return NULL; cmp = yangi-yang_order(y); + /* Here is right yang order == same yang? */ if (cmp == 0){ cmp = xml_cmp1(xc, y, name, keyword, keynr, keyvec, keyval, keycvec, &userorder); if (userorder && cmp) /* Look inside this yangi order */ @@ -507,9 +515,9 @@ xml_search1(cxobj *x0, /*! Find XML children using binary search * @param[in] yangi yang child order - * @param[in] keynr Length of keyvec/keyval vector when applicable - * @param[in] keyvec Array of of yang key identifiers - * @param[in] keyval Array of of yang key values + * @param[in] keynr Length of keyvec/keyval vector when applicable + * @param[in] keyvec Array of of yang key identifiers + * @param[in] keyval Array of of yang key values */ static cxobj * xml_search(cxobj *x0, @@ -534,7 +542,65 @@ xml_search(cxobj *x0, low, high); } - +#ifdef NOTUSED +/*! Position where to insert xml object into a list of children nodes + * @note EXPERIMENTAL + * Insert after position returned + * @param[in] x0 XML parent node. + * @param[in] low Lower bound + * @param[in] upper Upper bound (+1) + * @retval position + * XXX: Problem with this is that evrything must be known before insertion + */ +int +xml_insert_pos(cxobj *x0, + char *name, + int yangi, + enum rfc_6020 keyword, + int keynr, + char **keyvec, + char **keyval, + int low, + int upper) +{ + int mid; + cxobj *xc; + yang_stmt *y; + int cmp; + int i; + int userorder= 0; + + if (upper < low) + return low; /* not found */ + mid = (low + upper) / 2; + if (mid >= xml_child_nr(x0)) + return xml_child_nr(x0); /* upper range */ + xc = xml_child_i(x0, mid); + y = xml_spec(xc); + cmp = yangi-yang_order(y); + if (cmp == 0){ + cmp = xml_cmp1(xc, y, name, keyword, keynr, keyvec, keyval, keycvec, &userorder); + if (userorder){ /* Look inside this yangi order */ + /* Special case: append last of equals if ordered by user */ + for (i=mid+1;i 0) + if (xml_cmp(xprev, x) > 0) goto done; } xprev = x; @@ -632,7 +698,7 @@ match_base_child(cxobj *x0, clicon_err(OE_UNIX, errno, "calloc"); goto done; } - if (xml_cv_cache(x1c, keyval[0], &keycvec[0]) < 0) /* error case */ + if (xml_cv_cache(x1c, &keycvec[0]) < 0) /* error case */ goto done; break; case Y_LIST: /* Match with key values */ @@ -665,7 +731,7 @@ match_base_child(cxobj *x0, if ((b = xml_body(xb)) == NULL) goto ok; keyval[i] = b; - if (xml_cv_cache(xb, b, &keycvec[i]) < 0) /* error case */ + if (xml_cv_cache(xb, &keycvec[i]) < 0) /* error case */ goto done; i++; } @@ -673,8 +739,7 @@ match_base_child(cxobj *x0, default: break; } - /* Get match. - */ + /* Get match. */ yorder = yang_order(yc); x0c = xml_search(x0, xml_name(x1c), yorder, yc->ys_keyword, keynr, keyvec, keyval, keycvec); ok: @@ -685,6 +750,8 @@ match_base_child(cxobj *x0, free(keyval); if (keyvec) free(keyvec); + if (keycvec) + free(keycvec); return retval; } diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index 9be09da2..a2854d3d 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -839,9 +839,9 @@ xp_union(xp_ctx *xc1, * @param[out] xrp Resulting context */ static int -xp_eval(xp_ctx *xc, +xp_eval(xp_ctx *xc, xpath_tree *xs, - xp_ctx **xrp) + xp_ctx **xrp) { int retval = -1; diff --git a/test/long.sh b/test/long.sh index 3db6b391..55191fe7 100755 --- a/test/long.sh +++ b/test/long.sh @@ -51,7 +51,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile false /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so false EOF diff --git a/test/plot_perf.sh b/test/plot_perf.sh index c5eaaa98..dc565817 100755 --- a/test/plot_perf.sh +++ b/test/plot_perf.sh @@ -42,7 +42,6 @@ cat < $cfg /usr/local/var/routing/routing.pidfile false /usr/local/var/routing - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_augment.sh b/test/test_augment.sh index 9ae6ea60..b7302270 100755 --- a/test/test_augment.sh +++ b/test/test_augment.sh @@ -29,7 +29,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so true EOF diff --git a/test/test_choice.sh b/test/test_choice.sh index f1d5192f..6e08feb9 100755 --- a/test/test_choice.sh +++ b/test/test_choice.sh @@ -29,7 +29,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_cli.sh b/test/test_cli.sh index fe894be1..9030e6ed 100755 --- a/test/test_cli.sh +++ b/test/test_cli.sh @@ -32,7 +32,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_cli_history.sh b/test/test_cli_history.sh index 22591c66..c6700496 100755 --- a/test/test_cli_history.sh +++ b/test/test_cli_history.sh @@ -29,7 +29,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_copy_config.sh b/test/test_copy_config.sh index f9e08e31..ee1d60d1 100755 --- a/test/test_copy_config.sh +++ b/test/test_copy_config.sh @@ -47,7 +47,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 $dir - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_feature.sh b/test/test_feature.sh index d3145263..5bf5997a 100755 --- a/test/test_feature.sh +++ b/test/test_feature.sh @@ -41,7 +41,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so true EOF diff --git a/test/test_identity.sh b/test/test_identity.sh index 0a60d67c..d2ae40cf 100755 --- a/test/test_identity.sh +++ b/test/test_identity.sh @@ -26,7 +26,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_leafref.sh b/test/test_leafref.sh index a596a4f7..1c8f7eae 100755 --- a/test/test_leafref.sh +++ b/test/test_leafref.sh @@ -23,7 +23,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_list.sh b/test/test_list.sh index b43b4d95..7709c074 100755 --- a/test/test_list.sh +++ b/test/test_list.sh @@ -22,7 +22,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_nacm.sh b/test/test_nacm.sh index d919d775..b7b914ae 100755 --- a/test/test_nacm.sh +++ b/test/test_nacm.sh @@ -29,7 +29,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so false internal diff --git a/test/test_nacm_ext.sh b/test/test_nacm_ext.sh index 042b6488..5048a1e3 100755 --- a/test/test_nacm_ext.sh +++ b/test/test_nacm_ext.sh @@ -32,7 +32,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so false external $nacmfile diff --git a/test/test_nacm_module_read.sh b/test/test_nacm_module_read.sh index dbb27a24..8204b6a4 100755 --- a/test/test_nacm_module_read.sh +++ b/test/test_nacm_module_read.sh @@ -44,7 +44,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so false internal @@ -125,7 +124,7 @@ RULES=$(cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so false internal diff --git a/test/test_nacm_protocol.sh b/test/test_nacm_protocol.sh index 2e38f83c..a6af2124 100755 --- a/test/test_nacm_protocol.sh +++ b/test/test_nacm_protocol.sh @@ -49,7 +49,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so false internal diff --git a/test/test_netconf.sh b/test/test_netconf.sh index 266c31a2..9738345d 100755 --- a/test/test_netconf.sh +++ b/test/test_netconf.sh @@ -29,7 +29,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_openconfig.sh b/test/test_openconfig.sh index c3b491a7..ef9def01 100755 --- a/test/test_openconfig.sh +++ b/test/test_openconfig.sh @@ -72,7 +72,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so true EOF diff --git a/test/test_order.sh b/test/test_order.sh index 05f564ae..82171613 100755 --- a/test/test_order.sh +++ b/test/test_order.sh @@ -37,7 +37,6 @@ cat < $cfg /usr/local/lib/example/backend /usr/local/var/$APPNAME/$APPNAME.pidfile $dbdir - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_perf.sh b/test/test_perf.sh index 9e703236..596d7b70 100755 --- a/test/test_perf.sh +++ b/test/test_perf.sh @@ -49,7 +49,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile false /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so false EOF diff --git a/test/test_restconf.sh b/test/test_restconf.sh index 913216ae..f916952a 100755 --- a/test/test_restconf.sh +++ b/test/test_restconf.sh @@ -28,7 +28,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so true EOF diff --git a/test/test_restconf2.sh b/test/test_restconf2.sh index 770c87f4..543a9799 100755 --- a/test/test_restconf2.sh +++ b/test/test_restconf2.sh @@ -21,7 +21,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.sock $dir/restconf.pidfile /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_rpc.sh b/test/test_rpc.sh index 989c6f9f..3c2a44ee 100755 --- a/test/test_rpc.sh +++ b/test/test_rpc.sh @@ -29,7 +29,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_startup.sh b/test/test_startup.sh index 4a7835d3..9457e4ea 100755 --- a/test/test_startup.sh +++ b/test/test_startup.sh @@ -29,7 +29,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile $dir - /usr/local/lib/xmldb/text.so 0 init false diff --git a/test/test_stream.sh b/test/test_stream.sh index 64f14d76..670199eb 100755 --- a/test/test_stream.sh +++ b/test/test_stream.sh @@ -45,7 +45,6 @@ cat < $cfg example_backend.so$ $dir/restconf.pidfile /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/cli $APPNAME diff --git a/test/test_type.sh b/test/test_type.sh index 3b5935db..132e6a59 100755 --- a/test/test_type.sh +++ b/test/test_type.sh @@ -25,8 +25,7 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so - false + true EOF @@ -235,7 +234,7 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" -new "cli set transitive union int" +new "cli set transitive union int (ulle should accept 4.44|bounded|unbounded)" expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 33" 0 "^$" new "cli validate" diff --git a/test/test_type_nocache.sh b/test/test_type_nocache.sh new file mode 100755 index 00000000..95a0e9af --- /dev/null +++ b/test/test_type_nocache.sh @@ -0,0 +1,588 @@ +#!/bin/bash +# Advanced union types and generated code +# and enum w values +# @see test_type.sh ONLY DIFFERENCE IS db-cache is OFF here + +# Magic line must be first in script (see README.md) +s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi + +APPNAME=example + +cfg=$dir/conf_yang.xml +fyang=$dir/type.yang +fyang2=$dir/example2.yang +fyang3=$dir/example3.yang + +cat < $cfg + + $cfg + $dir + /usr/local/share/clixon + $IETFRFC + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/$APPNAME/$APPNAME.sock + /usr/local/var/$APPNAME/$APPNAME.pidfile + 1 + /usr/local/var/$APPNAME + false + +EOF + +# transitive type, exists in fyang3, referenced from fyang2, but not declared in fyang +cat < $fyang3 +module example3{ + prefix ex3; + namespace "urn:example:example3"; + typedef w{ + type union{ + type int32{ + range "4..44"; + } + } + } + typedef u{ + type union { + type w; + type enumeration { + enum "bounded"; + enum "unbounded"; + } + } + } + typedef t{ + type string{ + pattern '[a-z][0-9]*'; + } + } +} +EOF +cat < $fyang2 +module example2{ + import example3 { prefix ex3; } + namespace "urn:example:example2"; + prefix ex2; + grouping gr2 { + leaf talle{ + type ex3:t; + } + leaf ulle{ + type ex3:u; + } + } +} +EOF +cat < $fyang +module example{ + yang-version 1.1; + namespace "urn:example:clixon"; + prefix ex; + import example2 { prefix ex2; } + typedef ab { + type string { + pattern + '(([a-b])\.){3}[a-b]'; + } + } + typedef cd { + type string { + pattern + '(([c-d])\.){3}[c-d]'; + } + } + typedef ef { + type string { + pattern + '(([e-f])\.){3}[e-f]'; + length "1..253"; + } + } + typedef ad { + type union { + type ab; + type cd; + } + } + typedef af { + type union { + type ad; + type ef; + } + } + list list { + key ip; + leaf ip { + type af; + } + } + leaf status { + type enumeration { + enum up { + value 1; + } + enum down; + } + } + leaf num1 { + type int32 { + range "1"; + } + } + leaf num2 { /* range and blanks */ + type int32 { + range " 4 .. 4000 "; + } + } + leaf num3 { + type uint8 { + range "min..max"; + } + } + leaf num4 { + type uint8 { + range "1..2 | 42..50"; + } + } + leaf dec { + /* For test of multiple ranges with decimal64. More than 2, single range*/ + type decimal64 { + fraction-digits 3; + range "-3.5..-2.5 | 0.0 | 10.0..20.0"; + } + } + leaf len1 { + type string { + length "2"; + } + } + leaf len2 { + type string { + length " 4 .. 4000 "; + } + } + leaf len3 { + type string { + length "min..max"; + } + } + leaf len4 { + type string { + length "2 .. 3 | 20..29"; + } + } + typedef mybits { + description "Test adding several bits"; + type bits { + bit create; + bit read; + bit write; + } + } + leaf mbits{ + type mybits; + } + container c{ + description "transitive type- exists in ex3"; + uses ex2:gr2; + } + leaf digit4{ + type string { + pattern '\d{4}'; + } + } + leaf word4{ + type string { + pattern '\w{4}'; + } + } + leaf minus{ + description "Problem with minus"; + type string{ + pattern '[a-zA-Z_][a-zA-Z0-9_\-.]*'; + } + } +} +EOF + +new "test params: -f $cfg -y $fyang" + +if [ $BE -ne 0 ]; then + new "kill old backend" + sudo clixon_backend -zf $cfg + if [ $? -ne 0 ]; then + err + fi + new "start backend -s init -f $cfg -y $fyang" + start_backend -s init -f $cfg -y $fyang + + new "waiting" + sleep $RCWAIT +fi + +new "cli set transitive string. type is alpha followed by number and is defined in three levels of modules" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle x99" 0 "^$" + +new "cli set transitive string error. Wrong type" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle 9xx" 255 "^$" + +new "netconf set transitive string error" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '9xx]]>]]>' "^]]>]]>" + +new "netconf validate should fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" 'applicationbad-elementtalleerrorregexp match fail: "9xx" does not match \[a-z\]\[0-9\]\*]]>]]>$' + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +new "cli set transitive union int (ulle should accept 4.44|bounded|unbounded)" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 33" 0 "^$" + +new "cli validate" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$" + +new "cli set transitive union string" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle unbounded" 0 "^$" + +new "cli validate" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$" + +new "cli set transitive union error. should fail" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle kalle" 255 "" + +new "cli set transitive union error int" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 55" 255 "" + +new "netconf set transitive union error int" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '55]]>]]>' "^]]>]]>" + +new "netconf validate should fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^applicationbad-elementulleerror'55' does not match enumeration]]>]]>$" + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +#----------- + +new "cli set ab" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a.b.a.b" 0 "^$" + +new "cli set cd" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list c.d.c.d" 0 "^$" + +new "cli set ef" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list e.f.e.f" 0 "^$" + +new "cli set ab fail" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a&b&a&b" 255 "^CLI syntax error" + +new "cli set ad fail" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set list a.b.c.d" 255 "^CLI syntax error" + +new "cli validate" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o validate" 0 "^$" + +new "cli commit" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o commit" 0 "^$" + +new "netconf validate ok" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +new "netconf set ab wrong" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 'a.b& c.d]]>]]>' "^]]>]]>$" + +new "netconf validate" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^" + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +new "netconf commit" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +new "cli enum value" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set status down" 0 "^$" + +new "cli bits value" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits create" 0 "^$" + +#XXX No, cli cant assign two bit values +#new "cli bits two values" +#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits \"create read\"" 0 "^$" + +new "netconf bits two values" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 'create read]]>]]>' "^]]>]]>$" + +new "cli bits validate" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang validate" 0 "^$" + +#-------- num1 single range (1) + +new "cli range test num1 1 OK" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 1" 0 "^$" + +#new "cli range test num1 -100 ok" # XXX -/minus cant be given as argv +#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 \-100" 0 "^$" + +new "cli range test num1 2 error" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 2" 255 "^$" + +new "netconf range set num1 -1" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '-1]]>]]>' "^]]>]]>$" + +new "netconf validate num1 -1 wrong" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^applicationbad-elementnum1errorNumber out of range: -1]]>]]>$' + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +#-------- num2 range and blanks + +new "cli range test num2 3 error" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 3" 255 "^$" + +new "cli range test num2 1000 ok" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 1000" 0 "^$" + +new "cli range test num2 5000 error" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 5000" 255 "^$" + +new "netconf range set num2 3 fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '3]]>]]>' "^]]>]]>$" + +new "netconf validate num2 3 fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^applicationbad-elementnum2errorNumber out of range: 3]]>]]>$' + +new "netconf range set num2 1000 ok" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '1000]]>]]>' "^]]>]]>$" + +new "netconf validate num2 1000 ok" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^]]>]]>$' + +new "netconf range set num2 5000 fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '5000]]>]]>' "^]]>]]>$" + +new "netconf validate num2 5000 fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^applicationbad-elementnum2errorNumber out of range: 5000]]>]]>$' + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +#-------- num3 min max range + +new "cli range test num3 42 ok" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 42" 0 "^$" + +new "cli range test num3 260 fail" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 260" 255 "^$" + +new "cli range test num3 -1 fail" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 -1" 255 "^$" + +new "netconf range set num3 260 fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '260]]>]]>' "^]]>]]>$" + +new "netconf validate num3 260 fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^applicationbad-elementnum3error260 is out of range(type is uint8)]]>]]>$' + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +#-------- num4 multiple ranges 1..2 | 42..50 + +new "cli range test num4 multiple 0 fail" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 0" 255 "^$" + +new "cli range test num4 multiple 2 ok" +expectfn "$clixon_cli -1f $cfg -l e -y $fyang set num4 2" 0 "^$" + +new "cli range test num4 multiple 20 fail" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 20" 255 "^$" + +new "cli range test num4 multiple 42 ok" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 42" 0 "^$" + +new "cli range test num4 multiple 99 fail" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 99" 255 "^$" + +new "netconf range set num4 multiple 2" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '42]]>]]>' "^]]>]]>$" + +new "netconf validate num4 OK" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^]]>]]>$' + +new "netconf range set num4 multiple 20" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '42]]>]]>' "^]]>]]>$" + +new "netconf validate num4 fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^]]>]]>$' + +new "netconf range set num4 multiple 42" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '42]]>]]>' "^]]>]]>$" + +new "netconf validate num4 fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^]]>]]>$' + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 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? +new "cli range dec64 multiple 0 ok" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 0" 0 "^$" + +new "cli range dec64 multiple 0.1 fail" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 0.1" 255 "^$" + +new "cli range dec64 multiple 15.0 ok" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 15.0" 0 "^$" + +new "cli range dec64 multiple 30.0 fail" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set dec 30.0" 255 "^$" + +new "dec64 discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +# Same with netconf +new "netconf range dec64 -3.59" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '-3.59]]>]]>' "^]]>]]>$" + +new "netconf range dec64 -3.59 validate fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber out of range' + +new "netconf range dec64 -3.5" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '-3.500]]>]]>' "^]]>]]>$" + +new "netconf range dec64 -3.5 validate ok" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^]]>]]>$' + +new "netconf range dec64 -2" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '-2]]>]]>' "^]]>]]>$" + +new "netconf range dec64 -2 validate fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber out of range' + +new "netconf range dec64 -0.001" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '-0.001]]>]]>' "^]]>]]>$" + +new "netconf range dec64 -0.001 validate fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber out of range' + +new "netconf range dec64 0.0" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '0.0]]>]]>' "^]]>]]>$" + +new "netconf range dec64 0.0 validate ok" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^]]>]]>$' + +new "netconf range dec64 +0.001" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '+0.001]]>]]>' "^]]>]]>$" + +new "netconf range dec64 +0.001 validate fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber out of range' + +#----------------string ranges--------------------- +#-------- len1 single range (2) +new "cli length test len1 1 fail" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 x" 255 "^$" + +new "cli length test len1 2 OK" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 xy" 0 "^$" + +new "cli length test len1 3 error" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 hej" 255 "^$" + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +new "netconf length set len1 1" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 'x]]>]]>' "^]]>]]>$" + +new "netconf validate len1 1 wrong" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^applicationbad-elementlen1errorstring length out of range: 1]]>]]>$' + +#-------- len2 range and blanks + +new "cli length test len2 3 error" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 ab" 255 "^$" + +new "cli length test len2 42 ok" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 "^$" + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +#-------- len3 min max range + +new "cli range ptest len3 42 ok" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len3 hsakjdhkjsahdkjsahdksahdksajdhsakjhd" 0 "^$" + +#-------- len4 multiple ranges 2..3 | 20-29 +new "cli length test len4 1 error" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 a" 255 "^$" + +new "cli length test len4 2 ok" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 ab" 0 "^$" + +new "cli length test len4 10 error" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghij" 255 "^$" + +new "cli length test len4 20 ok" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghija" 0 "^$" + +new "cli length test len4 30 error" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abcdefghijabcdefghijabcdefghij" 255 "^$" + +# XSD schema -> POSIX ECE translation +new "cli yang pattern \d ok" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 0123" 0 "^$" + +new "cli yang pattern \d error" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 01b2" 255 "^$" + +new "cli yang pattern \w ok" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 abc9" 0 "^$" + +new "cli yang pattern \w error" +expectfn "$clixon_cli -1f $cfg -l o -y $fyang set word4 ab%3" 255 "^$" + +new "netconf pattern \w" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 'aXG9]]>]]>' "^]]>]]>$" + +new "netconf pattern \w valid" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 ']]>]]>' "^]]>]]>$" + +new "netconf pattern \w error" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 'ab%d3]]>]]>' "^]]>]]>$" + +new "netconf pattern \w valid" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 ']]>]]>' '^applicationbad-elementword4errorregexp match fail: "ab%d3" does not match \\w{4}]]>]]>$' + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + + +#------ minus + +new "type with minus" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 'my-name]]>]]>' "^]]>]]>$" + +new "validate minus" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +#new "cli type with minus" +#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set name my-name" 0 "^$" + +if [ $BE -eq 0 ]; then + exit # BE +fi + +new "Kill backend" +# Check if premature kill +pid=`pgrep -u root -f clixon_backend` +if [ -z "$pid" ]; then + err "backend already dead" +fi +# kill backend +stop_backend -f $cfg + +rm -rf $dir diff --git a/test/test_union.sh b/test/test_union.sh index a2d2bf46..01ef82e7 100755 --- a/test/test_union.sh +++ b/test/test_union.sh @@ -25,7 +25,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_upgrade.sh b/test/test_upgrade.sh index b143dc73..d33dbaf1 100755 --- a/test/test_upgrade.sh +++ b/test/test_upgrade.sh @@ -100,7 +100,6 @@ cat < $cfg /usr/local/lib/example/backend /usr/local/var/$APPNAME/$APPNAME.pidfile $dir - /usr/local/lib/xmldb/text.so true /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/cli diff --git a/test/test_upgrade_auto.sh b/test/test_upgrade_auto.sh index 50f52849..9827848f 100755 --- a/test/test_upgrade_auto.sh +++ b/test/test_upgrade_auto.sh @@ -179,7 +179,6 @@ cat < $cfg /usr/local/lib/example/backend /usr/local/var/$APPNAME/$APPNAME.pidfile $dir - /usr/local/lib/xmldb/text.so true true $changelog diff --git a/test/test_upgrade_interfaces.sh b/test/test_upgrade_interfaces.sh index 3bb2ed7f..2ec3b230 100755 --- a/test/test_upgrade_interfaces.sh +++ b/test/test_upgrade_interfaces.sh @@ -239,7 +239,6 @@ cat < $cfg /usr/local/lib/example/backend /usr/local/var/$APPNAME/$APPNAME.pidfile $dir - /usr/local/lib/xmldb/text.so true false /usr/local/lib/$APPNAME/clispec diff --git a/test/test_upgrade_repair.sh b/test/test_upgrade_repair.sh index 27f3e072..c6cc4dda 100755 --- a/test/test_upgrade_repair.sh +++ b/test/test_upgrade_repair.sh @@ -63,7 +63,6 @@ cat < $cfg /usr/local/lib/example/backend /usr/local/var/$APPNAME/$APPNAME.pidfile $dir - /usr/local/lib/xmldb/text.so true /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/cli diff --git a/test/test_when_must.sh b/test/test_when_must.sh index 1c65bde3..d4cbc0ea 100755 --- a/test/test_when_must.sh +++ b/test/test_when_must.sh @@ -22,7 +22,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_yang.sh b/test/test_yang.sh index a4b67cf9..b61ca9a1 100755 --- a/test/test_yang.sh +++ b/test/test_yang.sh @@ -24,7 +24,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so true EOF diff --git a/test/test_yang_load.sh b/test/test_yang_load.sh index ad772be6..19c826d5 100755 --- a/test/test_yang_load.sh +++ b/test/test_yang_load.sh @@ -67,7 +67,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/cli $APPNAME @@ -122,7 +121,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/cli $APPNAME @@ -172,7 +170,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF @@ -217,7 +214,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF @@ -262,7 +258,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF @@ -309,7 +304,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF @@ -355,7 +349,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF @@ -402,7 +395,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so EOF diff --git a/test/test_yangmodels.sh b/test/test_yang_models.sh similarity index 98% rename from test/test_yangmodels.sh rename to test/test_yang_models.sh index 91bfcc0e..6277859e 100755 --- a/test/test_yangmodels.sh +++ b/test/test_yang_models.sh @@ -46,7 +46,6 @@ cat < $cfg 1 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so true EOF diff --git a/test/test_yang_namespace.sh b/test/test_yang_namespace.sh index 13877e2d..d5c925eb 100755 --- a/test/test_yang_namespace.sh +++ b/test/test_yang_namespace.sh @@ -27,7 +27,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so true EOF diff --git a/util/clixon_util_datastore.c b/util/clixon_util_datastore.c index 72f7353c..287351e8 100644 --- a/util/clixon_util_datastore.c +++ b/util/clixon_util_datastore.c @@ -184,7 +184,7 @@ main(int argc, char **argv) xpath = argv[1]; else xpath = "/"; - if (xmldb_get(h, db, xpath, 0, &xt, NULL) < 0) + if (xmldb_get(h, db, xpath, &xt, NULL) < 0) goto done; clicon_xml2file(stdout, xt, 0, 0); @@ -200,7 +200,7 @@ main(int argc, char **argv) else xpath = "/"; for (i=0;i