Migrate to libyang2

Explanation of some of the changes:
1) New libyang produces different schema paths, that don't include
   choice/case nodes. This can be seen in Firewall.cpp.
2) New sysrepo does not use <map>, so it has to be included at multiple
   places.
3) getUniqueSubtree is now just one line of code. Another commit can get
   rid of it.
4) dataFromSysrepo sometimes gives less and sometimes more data. This is
   because it now uses libyang instead of sr_val_t
   - When it gives more data it's usually just lists or empty containers,
     sr_val_t didn't give those.
   - When it gives less data it's also just empty containers. This can
     be seen with "sensor-data" in hardware_ietf-hardware.cpp.

Depends-on: https://gerrit.cesnet.cz/c/CzechLight/dependencies/+/5171
Change-Id: I388536269e790b8b74ea7791c79b180adc5d80a6
Co-authored-by: Jan Kundrát <jan.kundrat@cesnet.cz>
diff --git a/tests/test_sysrepo_helpers.h b/tests/test_sysrepo_helpers.h
index 8478f17..1df3dc9 100644
--- a/tests/test_sysrepo_helpers.h
+++ b/tests/test_sysrepo_helpers.h
@@ -8,71 +8,71 @@
 #include "trompeloeil_doctest.h"
 #include <boost/algorithm/string/predicate.hpp>
 #include <map>
-#include <sysrepo-cpp/Session.hpp>
+#include <sysrepo-cpp/Connection.hpp>
 #include "test_log_setup.h"
 #include "utils/sysrepo.h"
 
 /** @short Return a subtree from sysrepo, compacting the XPath */
-auto dataFromSysrepo(const std::shared_ptr<sysrepo::Session>& session, const std::string& xpath)
+auto dataFromSysrepo(const sysrepo::Session& session, const std::string& xpath)
 {
     spdlog::get("main")->error("dataFrom {}", xpath);
     std::map<std::string, std::string> res;
-    auto vals = session->get_items((xpath + "//*").c_str());
-    REQUIRE(!!vals);
-    for (size_t i = 0; i < vals->val_cnt(); ++i) {
-        const auto& v = vals->val(i);
-        const auto briefXPath = std::string(v->xpath()).substr(boost::algorithm::ends_with(xpath, ":*") ? xpath.size() - 1 : xpath.size());
-        res.emplace(briefXPath, v->val_to_string());
-    }
-    return res;
-}
+    auto data = session.getData((xpath + "/*").c_str());
+    REQUIRE(data);
+    for (const auto& sibling : data->findXPath(xpath.c_str())) { // Use findXPath here in case the xpath is list without keys.
+        for (const auto& node : sibling.childrenDfs()) {
+            const auto briefXPath = std::string(node.path()).substr(boost::algorithm::ends_with(xpath, ":*") ? xpath.size() - 1 : xpath.size());
 
-/** @short Execute an RPC or action, return result, compacting the XPath. The rpcPath and input gets concatenated. */
-auto rpcFromSysrepo(const std::shared_ptr<sysrepo::Session>& session, const std::string& rpcPath, std::map<std::string, std::string> input)
-{
-    spdlog::get("main")->info("rpcFromSysrepo {}", rpcPath);
-    auto inputNode = std::make_shared<libyang::Data_Node>(session->get_context(), rpcPath.c_str(), nullptr, LYD_ANYDATA_CONSTSTRING, 0);
-    for (const auto& [k, v] : input) {
-        inputNode->new_path(session->get_context(), (rpcPath + "/" + k).c_str(), v.c_str(), LYD_ANYDATA_CONSTSTRING, 0);
-    }
-
-    auto output = session->rpc_send(inputNode);
-    REQUIRE(!!output);
-
-    // Sysrepo returns a top-level node. I need the node that contains the action and iterate over that instead of the
-    // top-level node.
-    auto actualOutput = output->find_path(rpcPath.c_str())->data().front();
-
-    std::map<std::string, std::string> res;
-    for (const auto& node : actualOutput->tree_dfs()) {
-        if (node->schema()->nodetype() == LYS_LEAF) {
-            auto leaf = std::make_shared<libyang::Data_Node_Leaf_List>(node);
-            auto path = node->path();
-            const auto briefXPath = path.substr(rpcPath.size());
-            res.emplace(briefXPath, leaf->value_str());
+            // We ignore the thing that's exactly the xpath we're retrieving to avoid having {"": ""} entries.
+            if (briefXPath.empty()) {
+                continue;
+            }
+            res.emplace(briefXPath, node.isTerm() ? node.asTerm().valueStr() : "");
         }
     }
     return res;
 }
 
-/** @short Return a subtree from specified sysrepo's datastore, compacting the XPath*/
-auto dataFromSysrepo(const std::shared_ptr<sysrepo::Session>& session, const std::string& xpath, sr_datastore_t datastore)
+/** @short Execute an RPC or action, return result, compacting the XPath. The rpcPath and input gets concatenated. */
+auto rpcFromSysrepo(sysrepo::Session session, const std::string& rpcPath, std::map<std::string, std::string> input)
 {
-    sr_datastore_t oldDatastore = session->session_get_ds();
-    session->session_switch_ds(datastore);
+    spdlog::get("main")->info("rpcFromSysrepo {}", rpcPath);
+    auto inputNode = session.getContext().newPath(rpcPath.c_str(), nullptr);
+    for (const auto& [k, v] : input) {
+        inputNode.newPath((rpcPath + "/" + k).c_str(), v.c_str());
+    }
 
-    auto res = dataFromSysrepo(session, xpath);
+    auto output = session.sendRPC(inputNode);
 
-    session->session_switch_ds(oldDatastore);
+    std::map<std::string, std::string> res;
+    for (const auto& node : output.childrenDfs()) {
+        const auto briefXPath = std::string{node.path()}.substr(rpcPath.size());
+
+        // We ignore the thing that's exactly the xpath we're retrieving to avoid having {"": ""} entries.
+        if (briefXPath.empty()) {
+            continue;
+        }
+        res.emplace(briefXPath, node.isTerm() ? node.asTerm().valueStr() : "");
+    }
     return res;
 }
 
-#define TEST_SYSREPO_INIT                                     \
-    auto srConn = std::make_shared<sysrepo::Connection>();    \
-    auto srSess = std::make_shared<sysrepo::Session>(srConn); \
-    auto srSubs = std::make_shared<sysrepo::Subscribe>(srSess);
+/** @short Return a subtree from specified sysrepo's datastore, compacting the XPath*/
+auto dataFromSysrepo(sysrepo::Session session, const std::string& xpath, sysrepo::Datastore datastore)
+{
+    auto oldDatastore = session.activeDatastore();
+    session.switchDatastore(datastore);
 
-#define TEST_SYSREPO_INIT_CLIENT                                  \
-    auto clientConn = std::make_shared<sysrepo::Connection>();    \
-    auto client = std::make_shared<sysrepo::Session>(clientConn); \
-    auto subscription = std::make_shared<sysrepo::Subscribe>(client);
+    auto res = dataFromSysrepo(session, xpath);
+
+    session.switchDatastore(oldDatastore);
+    return res;
+}
+
+#define TEST_SYSREPO_INIT                      \
+    auto srConn = sysrepo::Connection{};       \
+    auto srSess = srConn.sessionStart();
+
+#define TEST_SYSREPO_INIT_CLIENT                     \
+    auto clientConn = sysrepo::Connection{};         \
+    auto client = clientConn.sessionStart();