blob: 0f266c56ebe8878421d213a0ea61c76e8db5ae1e [file] [log] [blame]
Tomáš Pecka98ad18d2020-11-13 15:39:55 +01001/*
2 * Copyright (C) 2016-2019 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Jan Kundrát <jan.kundrat@cesnet.cz>
5 *
Tomáš Peckac164ca62024-01-24 13:38:03 +01006 */
Tomáš Pecka98ad18d2020-11-13 15:39:55 +01007
8#include "trompeloeil_doctest.h"
9#include <boost/algorithm/string/predicate.hpp>
10#include <map>
Václav Kubernát7efd6d52021-11-09 01:31:11 +010011#include <sysrepo-cpp/Connection.hpp>
Tomáš Peckac164ca62024-01-24 13:38:03 +010012#include "common.h"
Tomáš Pecka98ad18d2020-11-13 15:39:55 +010013#include "test_log_setup.h"
Tomáš Peckaba2dc312021-01-23 22:29:11 +010014#include "utils/sysrepo.h"
Tomáš Pecka98ad18d2020-11-13 15:39:55 +010015
Tomáš Pecka7eb64592024-01-24 14:10:47 +010016bool operator==(const Deleted&, const Deleted&) { return true; }
17
18std::string nodeAsString(const libyang::DataNode& node)
19{
20 switch (node.schema().nodeType()) {
21 case libyang::NodeType::Container:
22 return "(container)";
23 case libyang::NodeType::List:
24 return "(list instance)";
25 case libyang::NodeType::Leaf:
26 case libyang::NodeType::Leaflist:
27 return std::string(node.asTerm().valueStr());
28 default:
29 return "(unprintable)";
30 }
31}
32
Tomáš Pecka98ad18d2020-11-13 15:39:55 +010033/** @short Return a subtree from sysrepo, compacting the XPath */
Tomáš Peckac164ca62024-01-24 13:38:03 +010034Values dataFromSysrepo(const sysrepo::Session& session, const std::string& xpath)
Tomáš Pecka98ad18d2020-11-13 15:39:55 +010035{
36 spdlog::get("main")->error("dataFrom {}", xpath);
Tomáš Peckac164ca62024-01-24 13:38:03 +010037 Values res;
Jan Kundrátb3e99982022-03-18 17:38:20 +010038 auto data = session.getData(xpath + "/*");
Tomáš Peckacf355002023-05-17 11:40:30 +020039 REQUIRE(data.has_value());
Jan Kundrátb3e99982022-03-18 17:38:20 +010040 for (const auto& sibling : data->findXPath(xpath)) { // Use findXPath here in case the xpath is list without keys.
Václav Kubernát7efd6d52021-11-09 01:31:11 +010041 for (const auto& node : sibling.childrenDfs()) {
42 const auto briefXPath = std::string(node.path()).substr(boost::algorithm::ends_with(xpath, ":*") ? xpath.size() - 1 : xpath.size());
Tomáš Pecka98ad18d2020-11-13 15:39:55 +010043
Václav Kubernát7efd6d52021-11-09 01:31:11 +010044 // We ignore the thing that's exactly the xpath we're retrieving to avoid having {"": ""} entries.
45 if (briefXPath.empty()) {
46 continue;
47 }
48 res.emplace(briefXPath, node.isTerm() ? node.asTerm().valueStr() : "");
Václav Kubernátbabbab92021-01-27 09:25:05 +010049 }
50 }
51 return res;
52}
53
Václav Kubernát7efd6d52021-11-09 01:31:11 +010054/** @short Execute an RPC or action, return result, compacting the XPath. The rpcPath and input gets concatenated. */
Tomáš Peckac164ca62024-01-24 13:38:03 +010055Values rpcFromSysrepo(sysrepo::Session session, const std::string& rpcPath, Values input)
Tomáš Pecka9971dcf2021-01-14 09:41:20 +010056{
Václav Kubernát7efd6d52021-11-09 01:31:11 +010057 spdlog::get("main")->info("rpcFromSysrepo {}", rpcPath);
Jan Kundrátb3e99982022-03-18 17:38:20 +010058 auto inputNode = session.getContext().newPath(rpcPath, std::nullopt);
Václav Kubernát7efd6d52021-11-09 01:31:11 +010059 for (const auto& [k, v] : input) {
Jan Kundrátb3e99982022-03-18 17:38:20 +010060 inputNode.newPath(rpcPath + "/" + k, v);
Václav Kubernát7efd6d52021-11-09 01:31:11 +010061 }
Tomáš Pecka9971dcf2021-01-14 09:41:20 +010062
Václav Kubernát7efd6d52021-11-09 01:31:11 +010063 auto output = session.sendRPC(inputNode);
Tomáš Pecka9971dcf2021-01-14 09:41:20 +010064
Tomáš Peckac164ca62024-01-24 13:38:03 +010065 Values res;
Václav Kubernát7efd6d52021-11-09 01:31:11 +010066 for (const auto& node : output.childrenDfs()) {
67 const auto briefXPath = std::string{node.path()}.substr(rpcPath.size());
68
69 // We ignore the thing that's exactly the xpath we're retrieving to avoid having {"": ""} entries.
70 if (briefXPath.empty()) {
71 continue;
72 }
73 res.emplace(briefXPath, node.isTerm() ? node.asTerm().valueStr() : "");
74 }
Tomáš Pecka9971dcf2021-01-14 09:41:20 +010075 return res;
76}
77
Václav Kubernát7efd6d52021-11-09 01:31:11 +010078/** @short Return a subtree from specified sysrepo's datastore, compacting the XPath*/
Tomáš Peckac164ca62024-01-24 13:38:03 +010079Values dataFromSysrepo(sysrepo::Session session, const std::string& xpath, sysrepo::Datastore datastore)
Václav Kubernát7efd6d52021-11-09 01:31:11 +010080{
Tomáš Pecka190c7242024-01-23 15:50:51 +010081 velia::utils::ScopedDatastoreSwitch s(session, datastore);
82 return dataFromSysrepo(session, xpath);
Václav Kubernát7efd6d52021-11-09 01:31:11 +010083}
Tomáš Peckade062902024-01-24 13:41:16 +010084
85std::string moduleFromXpath(const std::string& xpath)
86{
87 auto pos = xpath.find(":");
88 if (pos == 0 || pos == std::string::npos || xpath[0] != '/') {
89 throw std::logic_error{"module_from_xpath: malformed XPath " + xpath};
90 }
91 return xpath.substr(1, pos - 1);
92}