diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c
index e5653cd8..0673d651 100644
--- a/apps/backend/backend_main.c
+++ b/apps/backend/backend_main.c
@@ -918,6 +918,7 @@ main(int argc,
if (ret != 1)
if (xmldb_copy(h, "tmp", "running") < 0)
goto done;
+ xmldb_delete(h, "tmp");
if (ret2status(ret, &status) < 0)
goto done;
break;
diff --git a/apps/backend/backend_startup.c b/apps/backend/backend_startup.c
index a5695cde..6052de51 100644
--- a/apps/backend/backend_startup.c
+++ b/apps/backend/backend_startup.c
@@ -312,8 +312,9 @@ startup_extraxml(clicon_handle h,
if (ret == 1)
goto ok;
xt = NULL;
- /* Validate the tmp db and return possibly upgraded xml in xt
- */
+ /* Clear db cache so that it can be read by startup */
+ xmldb_clear(h, tmp_db);
+ /* Validate the tmp db and return possibly upgraded xml in xt */
if ((ret = startup_validate(h, tmp_db, &xt, cbret)) < 0)
goto done;
if (ret == 0)
diff --git a/example/main/example_backend.c b/example/main/example_backend.c
index 1e728857..7aa4bef7 100644
--- a/example/main/example_backend.c
+++ b/example/main/example_backend.c
@@ -1194,31 +1194,35 @@ upgrade_interfaces(clicon_handle h,
* This involves creating default configuration files for various daemons, set interface
* flags etc.
* @param[in] h Clicon handle
- * @param[in] db Name of database. Not may be other than "running"
- * In this example, a loopback interface is added
- * @note This assumes example yang with interfaces/interface
+ * @param[in] db Name of database. Not3 may be other than "running"
+ * In this example, a loopback parameter is added
*/
int
example_reset(clicon_handle h,
const char *db)
{
- int retval = -1;
- cxobj *xt = NULL;
- int ret;
- cbuf *cbret = NULL;
+ int retval = -1;
+ cxobj *xt = NULL;
+ int ret;
+ cbuf *cbret = NULL;
yang_stmt *yspec;
+ cxobj *xerr = NULL;
if (!_reset)
goto ok; /* Note not enabled by default */
yspec = clicon_dbspec_yang(h);
- if (clixon_xml_parse_string(""
- "loex:loopback"
- "", YB_MODULE, yspec, &xt, NULL) < 0)
- goto done;
- /* Replace parent w first child */
- if (xml_rootchild(xt, 0, &xt) < 0)
+ /* Parse extra XML */
+ if ((ret = clixon_xml_parse_string("
", YB_MODULE, yspec, &xt, &xerr)) < 0)
goto done;
+ if (ret == 0){
+ clicon_debug_xml(1, xerr, "Error when parsing XML");
+ goto ok;
+ }
+ /* xmldb_put requires modification tree to be: ... */
+ xml_name_set(xt, "config");
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
@@ -1236,6 +1240,8 @@ example_reset(clicon_handle h,
done:
if (cbret)
cbuf_free(cbret);
+ if (xerr)
+ xml_free(xerr);
if (xt != NULL)
xml_free(xt);
return retval;
diff --git a/test/test_plugin_reset.sh b/test/test_plugin_reset.sh
new file mode 100755
index 00000000..af6ec584
--- /dev/null
+++ b/test/test_plugin_reset.sh
@@ -0,0 +1,209 @@
+#!/usr/bin/env bash
+# Test plugin reset functionality
+# First go through all startup modes and modstate true/false and add a loopback XML
+# in reset
+# Then do the same with an outdated modstate requiring upgrade
+
+# 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/example@2020-01-01.yang
+changelog=$dir/changelog.xml # Module revision changelog
+
+# Create configuration
+cat < $cfg
+
+ /usr/local/etc/clixon.xml
+ *:*
+ ietf-netconf:startup
+ ${YANG_INSTALLDIR}
+ $dir
+ $fyang
+ hello
+ /usr/local/lib/hello/clispec
+ /usr/local/var/hello.sock
+ /usr/local/var/hello.pidfile
+ /usr/local/lib/$APPNAME/backend
+ $dir
+ false
+ false
+ $changelog
+ false
+
+EOF
+
+cat < $fyang
+module clixon-example {
+ yang-version 1.1;
+ namespace "urn:example:clixon";
+ prefix ex;
+ revision 2020-01-01 {
+ description
+ "Clixon hello world example";
+ }
+ revision 2010-01-01 {
+ description
+ "Clixon hello world example";
+ }
+ container table{
+ list parameter{
+ key name;
+ leaf name{
+ type string;
+ }
+ leaf value{
+ type string;
+ }
+ }
+ }
+}
+EOF
+
+cat < $changelog
+
+
+ urn:example:clixon
+ 2010-01-01
+ 2020-01-01
+
+ rename foo to value
+ rename
+ /ex:table/ex:parameter/ex:foo
+ "value"
+
+
+
+EOF
+
+# Start and stop backend with reset function that adds extraxml
+# Args:
+# 1: db Startup db
+# 2: mode Startup mode (init, startup, running, none)
+# 3: modstate true: Add yang-lib modstate to sytartup file
+# 4: outdated true: Outdated modstate requires upgrade
+function testrun()
+{
+ db=$1
+ mode=$2
+ modstate=$3
+ outdated=$4
+
+ if $outdated; then
+ TAG=foo
+ REV=2010-01-01
+ else
+ TAG=value
+ REV=2020-01-01
+ fi
+ if [ -n "$db" ]; then
+ sudo rm $dir/$db
+ cat < $dir/$db
+<${DATASTORE_TOP}>
+
+
+ x
+ <$TAG>42$TAG>
+
+
+EOF
+ if $modstate; then
+ cat <> $dir/$db
+
+ 42
+
+ default
+
+ clixon-example
+ $REV
+ urn:example:clixon
+
+
+
+EOF
+ fi
+ cat <> $dir/$db
+${DATASTORE_TOP}>
+EOF
+ fi
+
+ # Bring your own backend
+ if [ $BE -ne 0 ]; then
+ # kill old backend (if any)
+ new "kill old backend"
+ sudo clixon_backend -zf $cfg
+ if [ $? -ne 0 ]; then
+ err
+ fi
+ new "start backend -s $mode -f $cfg -o CLICON_XMLDB_MODSTATE=$modstate -o CLICON_XML_CHANGELOG=$outdated -- -r"
+ start_backend -s $mode -f $cfg -o CLICON_XMLDB_MODSTATE=$modstate -o CLICON_XML_CHANGELOG=$outdated -- -r
+ fi
+
+ new "wait backend"
+ wait_backend
+
+ if [ -n "$db" ]; then
+ XMLDB="x42"
+ else
+ XMLDB=""
+ fi
+ XML=""
+
+ new "get config"
+ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "" "$XML"
+
+ if [ $BE -ne 0 ]; then
+ new "Kill backend"
+ # Check if premature kill
+ pid=$(pgrep -u root -f clixon_backend)
+ if [ -z "$pid" ]; then
+ err "backend already dead"
+ fi
+ # kill backend
+ stop_backend -f $cfg
+ fi
+}
+
+new "test params: -f $cfg"
+
+new "Startup and modstate"
+testrun startup_db startup true false
+
+new "Startup and no modstate"
+testrun startup_db startup false false
+
+new "Running and modstate"
+testrun running_db running true false
+
+new "Running and no modstate"
+testrun running_db running false false
+
+new "Init and modstate"
+testrun "" init true false
+
+new "Init and no modstate"
+testrun "" init false false
+
+new "None and modstate"
+testrun "" none true false
+
+new "None and no modstate"
+testrun "" none false false
+
+new "Startup and old modstate"
+testrun startup_db startup true true
+
+new "Running and old modstate"
+testrun running_db running true true
+
+new "Init and old modstate"
+testrun "" init true true
+
+new "None and modstate"
+testrun "" none true true
+
+rm -rf $dir
+
+new "endtest"
+endtest