Rework datastore tests

Sysrepo now supports parallelized tests. Use the new environmental
variables to implement this in netconf-cli. All of the tests now get
their own clean environment:

- Fresh repository and separate shm prefix. These get cleaned before and
after tests. The only thing that gets left are some empty directories.

- Its own model to test on.

- Separate Netopeer2 daemon: only for netconf tests - that means no
`sleep 5` for sysrepo-only tests. So no useless waiting. Wow! The daemon
also runs with its argv[0] changed to something recognizable for
`pkill`. That means that if Netopeer2 crashes for some reason, pkill
will notify me.

Side note: These changes somehow changed some of the linking, so hopefully I got
those right.

Change-Id: Ib0e582ef03fc559b24203af8afb2a295a6318ca9
diff --git a/tests/cleanup_datastore.bash.in b/tests/cleanup_datastore.bash.in
new file mode 100755
index 0000000..66df88c
--- /dev/null
+++ b/tests/cleanup_datastore.bash.in
@@ -0,0 +1,25 @@
+set -eux
+
+if [[ $(dirname "$(dirname "$(realpath "$SYSREPO_REPOSITORY_PATH")")") != "@CMAKE_CURRENT_BINARY_DIR@" ]]; then
+    echo "\$SYSREPO_REPOSITORY_PATH is not inside the build dir! Aborting. ($SYSREPO_REPOSITORY_PATH)"
+    exit 1
+fi
+
+if [[ -z "$SYSREPO_SHM_PREFIX" ]]; then
+    echo '$SYSREPO_SHM_PREFIX is empty! Aborting.'
+    exit 1
+fi
+
+BACKEND="$1"
+shift
+if [[ "$BACKEND" = "netconf" ]]; then
+    # The `-f` argument is neccessary so that pkill matches the whole command
+    # line, including stuff set by `exec -a`. Otherwise it matches the name in
+    # /proc/{pid}/stat and that is usually limited to 15 characters, so
+    # netopeer2-server appears as netopeer2-serve
+    pkill -f "${SYSREPO_SHM_PREFIX}_netopeer2-server"
+    rm "$NETOPEER_SOCKET"
+fi
+
+rm -r "$SYSREPO_REPOSITORY_PATH"
+rm "/dev/shm/$SYSREPO_SHM_PREFIX"*
diff --git a/tests/data_query.cpp b/tests/data_query.cpp
index d6435a8..4aa597e 100644
--- a/tests/data_query.cpp
+++ b/tests/data_query.cpp
@@ -13,7 +13,6 @@
 #include "sysrepo_access.hpp"
 #elif defined(netconf_BACKEND)
 #include "netconf_access.hpp"
-#include "netopeer_vars.hpp"
 #elif defined(yang_BACKEND)
 #include "yang_access.hpp"
 #include "yang_access_test_vars.hpp"
@@ -40,7 +39,8 @@
 #ifdef sysrepo_BACKEND
     SysrepoAccess datastore(Datastore::Running);
 #elif defined(netconf_BACKEND)
-    NetconfAccess datastore(NETOPEER_SOCKET_PATH);
+    const auto NETOPEER_SOCKET = getenv("NETOPEER_SOCKET");
+    NetconfAccess datastore(NETOPEER_SOCKET);
 #elif defined(yang_BACKEND)
     YangAccess datastore;
     datastore.addSchemaDir(schemaDir);
diff --git a/tests/datastore_access.cpp b/tests/datastore_access.cpp
index 68eac3a..cc97aa9 100644
--- a/tests/datastore_access.cpp
+++ b/tests/datastore_access.cpp
@@ -27,7 +27,6 @@
 using OnKeyNotFound = std::runtime_error;
 using OnExec = void;
 #include "netconf_access.hpp"
-#include "netopeer_vars.hpp"
 #elif defined(yang_BACKEND)
 #include <fstream>
 #include "yang_access.hpp"
@@ -122,7 +121,8 @@
 #ifdef sysrepo_BACKEND
     SysrepoAccess datastore(Datastore::Running);
 #elif defined(netconf_BACKEND)
-    NetconfAccess datastore(NETOPEER_SOCKET_PATH);
+    const auto NETOPEER_SOCKET = getenv("NETOPEER_SOCKET");
+    NetconfAccess datastore(NETOPEER_SOCKET);
 #elif defined(yang_BACKEND)
     TestYangAccess datastore;
     datastore.addSchemaDir(schemaDir);
@@ -896,7 +896,8 @@
 #ifdef sysrepo_BACKEND
     auto datastore = std::make_shared<SysrepoAccess>(Datastore::Running);
 #elif defined(netconf_BACKEND)
-    auto datastore = std::make_shared<NetconfAccess>(NETOPEER_SOCKET_PATH);
+    const auto NETOPEER_SOCKET = getenv("NETOPEER_SOCKET");
+    auto datastore = std::make_shared<NetconfAccess>(NETOPEER_SOCKET);
 #elif defined(yang_BACKEND)
     auto datastore = std::make_shared<YangAccess>();
     datastore->addSchemaDir(schemaDir);
diff --git a/tests/enable-nacm.xml b/tests/enable-nacm.xml
deleted file mode 100644
index 4a2f36a..0000000
--- a/tests/enable-nacm.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
-  <enable-nacm>true</enable-nacm>
-</nacm>
diff --git a/tests/init_datastore.bash.in b/tests/init_datastore.bash.in
new file mode 100755
index 0000000..5aec0c0
--- /dev/null
+++ b/tests/init_datastore.bash.in
@@ -0,0 +1,43 @@
+set -eux
+export UBSAN_OPTIONS=halt_on_error=1 # UBSan doesn't stop on errors by default.
+
+if [[ $(dirname "$(dirname "$(realpath "$SYSREPO_REPOSITORY_PATH")")") != "@CMAKE_CURRENT_BINARY_DIR@" ]]; then
+    echo "\$SYSREPO_REPOSITORY_PATH is not inside the build dir! Aborting. ($SYSREPO_REPOSITORY_PATH)"
+    exit 1
+fi
+
+if [[ -z "$SYSREPO_SHM_PREFIX" ]]; then
+    echo '$SYSREPO_SHM_PREFIX is empty! Aborting.'
+    exit 1
+fi
+
+rm -rf "$SYSREPO_REPOSITORY_PATH"
+rm -rf "/dev/shm/$SYSREPO_SHM_PREFIX"*
+cp -r "@SYSREPO_SR_REPO_PATH@" "$SYSREPO_REPOSITORY_PATH"
+
+SYSREPOCTL="@SYSREPOCTL_EXECUTABLE@"
+SYSREPOCFG="@SYSREPOCFG_EXECUTABLE@"
+
+MODULE="$1"
+YANG_DIR=$(dirname "$1")
+shift
+
+# Install the module
+"$SYSREPOCTL" --search-dirs "$YANG_DIR" --install "$MODULE" -a
+
+BACKEND="$1"
+shift
+if [[ "$BACKEND" = "netconf" ]]; then
+    NETOPEER2="@NETOPEER2_EXECUTABLE@"
+    # Setup netopeer config
+    "$SYSREPOCFG" --import --datastore=running --format=xml --module=ietf-netconf-server <<< ""
+
+    # Disable nacm
+    for datastore in startup running; do
+        "$SYSREPOCFG" --import="@CMAKE_CURRENT_SOURCE_DIR@/tests/disable-nacm.xml" --datastore="$datastore" --format=xml --module=ietf-netconf-acm
+    done
+
+    # Run netopeer. Use exec -a, so that each process has a recognizable name for `pkill`.
+    (exec -a "${SYSREPO_SHM_PREFIX}_netopeer2-server" "$NETOPEER2" -v2 "-U$NETOPEER_SOCKET")
+    sleep 5
+fi
diff --git a/tests/manage_nacm.sh.in b/tests/manage_nacm.sh.in
deleted file mode 100755
index db8d611..0000000
--- a/tests/manage_nacm.sh.in
+++ /dev/null
@@ -1,7 +0,0 @@
-if [ $1 != "enable" -a $1 != "disable" ]; then
-    echo 'Argument must be "enable" or "disable."'
-    exit 1
-fi
-for datastore in startup running; do
-    @SYSREPOCFG_EXECUTABLE@ --import=@CMAKE_CURRENT_SOURCE_DIR@/tests/"$1-nacm.xml" --datastore="$datastore" --format=xml --module=ietf-netconf-acm
-done
diff --git a/tests/mock/sysrepo_subscription.cpp b/tests/mock/sysrepo_subscription.cpp
index 5527c41..03be075 100644
--- a/tests/mock/sysrepo_subscription.cpp
+++ b/tests/mock/sysrepo_subscription.cpp
@@ -23,7 +23,7 @@
 
     int operator()(
             sysrepo::S_Session sess,
-            const char *module_name,
+            [[maybe_unused]] const char *module_name,
             [[maybe_unused]] const char *xpath,
             [[maybe_unused]] sr_event_t event,
             [[maybe_unused]] uint32_t request_id)
diff --git a/tests/netopeer-test-config.xml b/tests/netopeer-test-config.xml
deleted file mode 100644
index e69de29..0000000
--- a/tests/netopeer-test-config.xml
+++ /dev/null
diff --git a/tests/netopeer_vars.hpp.in b/tests/netopeer_vars.hpp.in
deleted file mode 100644
index 6036e70..0000000
--- a/tests/netopeer_vars.hpp.in
+++ /dev/null
@@ -1 +0,0 @@
-#define NETOPEER_SOCKET_PATH "@NETOPEER_SOCKET_PATH@"
diff --git a/tests/python_netconfaccess.py b/tests/python_netconfaccess.py
index ae317ee..d686cd0 100644
--- a/tests/python_netconfaccess.py
+++ b/tests/python_netconfaccess.py
@@ -1,7 +1,8 @@
+import os
 import sysrepo_subscription_py as sr_sub
 import netconf_cli_py as nc
 
-c = nc.NetconfAccess(socketPath = "@NETOPEER_SOCKET_PATH@")
+c = nc.NetconfAccess(socketPath = os.environ['NETOPEER_SOCKET'])
 data = c.getItems("/ietf-netconf-monitoring:netconf-state/datastores")
 for (k, v) in data:
     print(f"{k}: {type(v)} {v}", flush=True)
diff --git a/tests/start_daemons.sh.in b/tests/start_daemons.sh.in
deleted file mode 100755
index 5343441..0000000
--- a/tests/start_daemons.sh.in
+++ /dev/null
@@ -1,9 +0,0 @@
-set -eux -o pipefail
-shopt -s failglob
-export ASAN_OPTIONS=verify_asan_link_order=false
-export UBSAN_OPTIONS=halt_on_error=1
-
-@CMAKE_CURRENT_SOURCE_DIR@/tests/kill_daemons.sh || true
-
-@NETOPEER2_EXECUTABLE@ -v2 -U@NETOPEER_SOCKET_PATH@
-sleep 5
diff --git a/tests/sysrepoctl-manage-module.sh b/tests/sysrepoctl-manage-module.sh
deleted file mode 100755
index b618fec..0000000
--- a/tests/sysrepoctl-manage-module.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env bash
-
-set -eux -o pipefail
-shopt -s failglob
-
-SYSREPOCTL="${1}"
-shift
-if [[ ! -x "${SYSREPOCTL}" ]]; then
-  echo "Cannot locate \$SYSREPOCTL"
-  exit 1
-fi
-
-SYSREPOCFG="${1}"
-shift
-if [[ ! -x "${SYSREPOCFG}" ]]; then
-  echo "Cannot locate \$SYSREPOCFG"
-  exit 1
-fi
-
-MODE="${1}"
-shift
-
-if [[ ! -f "${1}" ]]; then
-  echo "No YANG file specified"
-  exit 1
-fi
-
-MODULE=$(basename --suffix .yang "${1}")
-YANG_DIR=$(dirname "${1}")
-
-if [[ "${MODE}" == "install" ]]; then
-  ${SYSREPOCTL} -C
-  ${SYSREPOCTL} --uninstall "${MODULE}" -a || true
-  ${SYSREPOCTL} -C
-  ${SYSREPOCTL} --search-dirs "${YANG_DIR}" --install "${1}" -a
-  JSON_DATA="${YANG_DIR}/${MODULE}.json"
-  XML_DATA="${YANG_DIR}/${MODULE}.startup.xml"
-  if [[ -f "${JSON_DATA}" ]] ;then
-    ${SYSREPOCFG} -d startup -f json "${MODULE}" -i "${JSON_DATA}" -a
-  elif [[ -f "${XML_DATA}" ]]; then
-    ${SYSREPOCFG} -d startup -f xml "${MODULE}" -i "${XML_DATA}" -a
-  fi
-elif [[ "${MODE}" == "uninstall" ]]; then
-  ${SYSREPOCTL} --uninstall "${MODULE}" -a
-else
-  echo "Mode of operation not specified"
-  exit 1
-fi