Move sysrepo test preparations out of the cpp file

Setting up tests using calls to system() is not good, because ctest
doesn't know which tests can be parallelized. This change moves test
preparations outside of the cpp files and makes use of fixtures for
setup and cleanup tests.

The tests/sysrepoctl-manage-module.sh script comes from cla-sysrepo,
commit d39cc7797ea371e90711ee0ed317cadc91c8368e

Change-Id: I7d6edd2988321dbc58b0b0520f088ee018742e31
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cd22deb..7ea2472 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -146,34 +146,54 @@
         message(FATAL_ERROR "Unable to find sysrepoctl, set SYSREPOCTL_EXECUTABLE manually.")
     endif()
 
-    configure_file("${PROJECT_SOURCE_DIR}/sysrepo_vars.hpp.in" "${PROJECT_BINARY_DIR}/sysrepo_vars.hpp" @ONLY)
-    configure_file("${PROJECT_SOURCE_DIR}/example-schema.yang" "${PROJECT_BINARY_DIR}/example-schema.yang" COPYONLY)
+    if (NOT SYSREPOCFG_EXECUTABLE)
+        find_program(SYSREPOCFG_EXECUTABLE sysrepocfg)
+    endif()
+    if (NOT SYSREPOCFG_EXECUTABLE)
+        message(FATAL_ERROR "Unable to find sysrepocfg, set SYSREPOCFG_EXECUTABLE manually.")
+    endif()
 
-    function(cli_test fname)
-        add_executable(test_${fname}
-            tests/${fname}.cpp
-            )
-        target_link_libraries(test_${fname} DoctestIntegration parser)
-        if(NOT CMAKE_CROSSCOMPILING)
-            add_test(test_${fname} test_${fname})
+    function(cli_test name)
+        if (${ARGC} GREATER 1) # this is how CMake does optional arguments
+            add_executable(test_${name}
+                tests/${ARGV1}
+                )
+        else()
+            add_executable(test_${name}
+                tests/${name}.cpp
+                )
         endif()
-        target_include_directories(test_${fname} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
-        target_link_libraries(test_${fname} DoctestIntegration)
+        target_link_libraries(test_${name} DoctestIntegration parser)
+        if(NOT CMAKE_CROSSCOMPILING)
+            add_test(test_${name} test_${name})
+        endif()
+        target_include_directories(test_${name} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
     endfunction()
+
+    function(datastore_test name fname model_path)
+        cli_test(${name} ${fname})
+        target_link_libraries(test_${name} sysreposubscription)
+        add_test(NAME test_${name}_init COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/sysrepoctl-manage-module.sh ${SYSREPOCTL_EXECUTABLE} ${SYSREPOCFG_EXECUTABLE} install ${model_path})
+        add_test(NAME test_${name}_cleanup COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/sysrepoctl-manage-module.sh ${SYSREPOCTL_EXECUTABLE} ${SYSREPOCFG_EXECUTABLE} uninstall ${model_path})
+        set_tests_properties(test_${name}_init PROPERTIES FIXTURES_SETUP ${name}-setup)
+        set_tests_properties(test_${name} PROPERTIES FIXTURES_REQUIRED ${name}-setup RESOURCE_LOCK sysrepo)
+        set_tests_properties(test_${name}_cleanup PROPERTIES FIXTURES_CLEANUP ${name}-setup)
+    endfunction()
+
     cli_test(cd)
     cli_test(ls)
     cli_test(presence_containers)
     cli_test(leaf_editing)
     cli_test(yang)
     target_link_libraries(test_yang yangschema)
-    cli_test(sysrepo)
-    target_link_libraries(test_sysrepo sysreposubscription sysrepoaccess yangschema parser)
-    target_include_directories(test_sysrepo PRIVATE ${PROJECT_SOURCE_DIR}/tests/mock)
     cli_test(utils)
     cli_test(path_completion)
     cli_test(command_completion)
     cli_test(enum_completion)
     cli_test(list_manipulation)
+    datastore_test(sysrepo sysrepo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/example-schema.yang)
+    target_link_libraries(test_sysrepo sysrepoaccess yangschema)
+    target_include_directories(test_sysrepo PRIVATE ${PROJECT_SOURCE_DIR}/tests/mock)
 endif()
 
 if(WITH_DOCS)
diff --git a/sysrepo_vars.hpp.in b/sysrepo_vars.hpp.in
deleted file mode 100644
index 16bc035..0000000
--- a/sysrepo_vars.hpp.in
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
- * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
- *
- * Written by Václav Kubernát <kubervac@fit.cvut.cz>
- *
-*/
-
-#define SYSREPOCTLEXECUTABLE "@SYSREPOCTL_EXECUTABLE@"
-#define EXAMPLE_SCHEMA_LOCATION "@CMAKE_CURRENT_SOURCE_DIR@/example-schema.yang"
diff --git a/tests/sysrepo.cpp b/tests/sysrepo.cpp
index ea468aa..f5476ef 100644
--- a/tests/sysrepo.cpp
+++ b/tests/sysrepo.cpp
@@ -10,7 +10,6 @@
 
 #include "sysrepo_access.hpp"
 #include "sysrepo_subscription.hpp"
-#include "sysrepo_vars.hpp"
 
 class MockRecorder : public Recorder {
 public:
@@ -19,12 +18,6 @@
 
 TEST_CASE("setting values")
 {
-    if (system(SYSREPOCTLEXECUTABLE " --uninstall --module example-schema > /dev/null") != 0) {
-        // uninstall can fail if it isn't already installed -> do nothing
-        // This crappy comment is here due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509
-    }
-    REQUIRE(system(SYSREPOCTLEXECUTABLE " --install --yang " EXAMPLE_SCHEMA_LOCATION " > /dev/null") == 0);
-
     trompeloeil::sequence seq1;
     MockRecorder mock;
     SysrepoSubscription subscription(&mock);
diff --git a/tests/sysrepoctl-manage-module.sh b/tests/sysrepoctl-manage-module.sh
new file mode 100755
index 0000000..e9693bb
--- /dev/null
+++ b/tests/sysrepoctl-manage-module.sh
@@ -0,0 +1,46 @@
+#!/bin/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} --uninstall --module "${MODULE}" || true
+  ${SYSREPOCTL} --install --yang "${1}"
+  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}"
+  elif [[ -f "${XML_DATA}" ]]; then
+    ${SYSREPOCFG} -d startup -f xml "${MODULE}" -i "${XML_DATA}"
+  fi
+elif [[ "${MODE}" == "uninstall" ]]; then
+  ${SYSREPOCTL} --uninstall --module "${MODULE}"
+else
+  echo "Mode of operation not specified"
+  exit 1
+fi