blob: 1fd461c2569e75f9863354a182850b42a67e08b4 [file] [log] [blame]
/*
* Copyright (C) 2019 CESNET, https://photonics.cesnet.cz/
*
* Written by Václav Kubernát <kubervac@fit.cvut.cz>
*
*/
#include <experimental/iterator>
#include "trompeloeil_doctest.hpp"
#ifdef sysrepo_BACKEND
#include "sysrepo_access.hpp"
#elif defined(netconf_BACKEND)
#include "netconf_access.hpp"
#include "netopeer_vars.hpp"
#else
#error "Unknown backend"
#endif
#include "data_query.hpp"
#include "sysrepo_subscription.hpp"
#include "utils.hpp"
namespace std {
std::ostream& operator<<(std::ostream& s, const std::vector<std::map<std::string, leaf_data_>> set)
{
s << std::endl << "{" << std::endl;
std::transform(set.begin(), set.end(), std::experimental::make_ostream_joiner(s, ", \n"), [](const auto& map) {
std::ostringstream ss;
ss << " {" << std::endl << " ";
std::transform(map.begin(), map.end(), std::experimental::make_ostream_joiner(ss, ", \n "), [](const auto& keyValue){
return "{" + keyValue.first + "{" + boost::core::demangle(keyValue.second.type().name()) + "}" + ", " + leafDataToString(keyValue.second) + "}";
});
ss << std::endl << " }";
return ss.str();
});
s << std::endl << "}" << std::endl;
return s;
}
}
TEST_CASE("data query")
{
trompeloeil::sequence seq1;
SysrepoSubscription subscriptionExample("example-schema");
SysrepoSubscription subscriptionOther("other-module");
#ifdef sysrepo_BACKEND
SysrepoAccess datastore("netconf-cli-test");
#elif defined(netconf_BACKEND)
NetconfAccess datastore(NETOPEER_SOCKET_PATH);
#else
#error "Unknown backend"
#endif
DataQuery dataquery(datastore);
SECTION("listKeys")
{
dataPath_ location;
location.m_scope = Scope::Absolute;
ModuleNodePair node;
std::vector<std::map<std::string, leaf_data_>> expected;
SECTION("example-schema:person")
{
datastore.createListInstance("/example-schema:person[name='Vaclav']");
datastore.createListInstance("/example-schema:person[name='Tomas']");
datastore.createListInstance("/example-schema:person[name='Jan Novak']");
node.first = "example-schema";
node.second = "person";
expected = {
{{"name", std::string{"Jan Novak"}}},
{{"name", std::string{"Tomas"}}},
{{"name", std::string{"Vaclav"}}}
};
}
SECTION("example-schema:selectedNumbers")
{
datastore.createListInstance("/example-schema:selectedNumbers[value='45']");
datastore.createListInstance("/example-schema:selectedNumbers[value='99']");
datastore.createListInstance("/example-schema:selectedNumbers[value='127']");
node.first = "example-schema";
node.second = "selectedNumbers";
expected = {
{{"value", int8_t{127}}},
{{"value", int8_t{45}}},
{{"value", int8_t{99}}}
};
}
SECTION("example-schema:animalWithColor")
{
datastore.createListInstance("/example-schema:animalWithColor[name='Dog'][color='brown']");
datastore.createListInstance("/example-schema:animalWithColor[name='Dog'][color='white']");
datastore.createListInstance("/example-schema:animalWithColor[name='Cat'][color='grey']");
node.first = "example-schema";
node.second = "animalWithColor";
expected = {
{{"name", std::string{"Cat"}}, {"color", std::string{"grey"}}},
{{"name", std::string{"Dog"}}, {"color", std::string{"brown"}}},
{{"name", std::string{"Dog"}}, {"color", std::string{"white"}}}
};
}
SECTION("example-schema:animalWithColor - quotes in values")
{
datastore.createListInstance("/example-schema:animalWithColor[name='D\"o\"g'][color=\"b'r'own\"]");
node.first = "example-schema";
node.second = "animalWithColor";
expected = {
{{"name", std::string{"D\"o\"g"}}, {"color", std::string{"b'r'own"}}}
};
}
SECTION("example-schema:ports")
{
datastore.createListInstance("/example-schema:ports[name='A']");
datastore.createListInstance("/example-schema:ports[name='B']");
datastore.createListInstance("/example-schema:ports[name='E']");
node.first = "example-schema";
node.second = "ports";
expected = {
{{"name", enum_{"A"}}},
{{"name", enum_{"B"}}},
{{"name", enum_{"E"}}},
};
}
SECTION("example-schema:org/example:people - nested list")
{
datastore.createListInstance("/example-schema:org[department='accounting']");
datastore.createListInstance("/example-schema:org[department='sales']");
datastore.createListInstance("/example-schema:org[department='programmers']");
datastore.createListInstance("/example-schema:org[department='accounting']/people[name='Alice']");
datastore.createListInstance("/example-schema:org[department='accounting']/people[name='Bob']");
datastore.createListInstance("/example-schema:org[department='sales']/people[name='Alice']");
datastore.createListInstance("/example-schema:org[department='sales']/people[name='Cyril']");
datastore.createListInstance("/example-schema:org[department='sales']/people[name='Alice']/computers[type='laptop']");
datastore.createListInstance("/example-schema:org[department='sales']/people[name='Alice']/computers[type='server']");
datastore.createListInstance("/example-schema:org[department='sales']/people[name='Cyril']/computers[type='PC']");
datastore.createListInstance("/example-schema:org[department='sales']/people[name='Cyril']/computers[type='server']");
SECTION("outer list")
{
node.first = "example-schema";
node.second = "org";
expected = {
{{"department", std::string{"accounting"}}},
{{"department", std::string{"sales"}}},
{{"department", std::string{"programmers"}}},
};
}
SECTION("nested list")
{
listElement_ list;
list.m_name = "org";
node.second = "people";
SECTION("accounting department")
{
list.m_keys = {
{"department", std::string{"accounting"}}
};
expected = {
{{"name", std::string{"Alice"}}},
{{"name", std::string{"Bob"}}},
};
}
SECTION("sales department")
{
list.m_keys = {
{"department", std::string{"sales"}}
};
expected = {
{{"name", std::string{"Alice"}}},
{{"name", std::string{"Cyril"}}},
};
}
SECTION("programmers department")
{
list.m_keys = {
{"department", std::string{"programmers"}}
};
expected = {
};
}
location.m_nodes.push_back(dataNode_{{"example-schema"}, list});
}
SECTION("THREE MF NESTED LISTS")
{
listElement_ listOrg;
listOrg.m_name = "org";
listOrg.m_keys = {
{"department", std::string{"sales"}}
};
listElement_ listPeople;
node.second = "computers";
SECTION("alice computers")
{
listPeople.m_name = "people";
listPeople.m_keys = {
{"name", std::string{"Alice"}}
};
expected = {
{{"type", enum_{"laptop"}}},
{{"type", enum_{"server"}}},
};
}
SECTION("cyril computers")
{
listPeople.m_name = "people";
listPeople.m_keys = {
{"name", std::string{"Cyril"}}
};
expected = {
{{"type", enum_{"PC"}}},
{{"type", enum_{"server"}}},
};
}
location.m_nodes.push_back(dataNode_{{"example-schema"}, listOrg});
location.m_nodes.push_back(dataNode_{listPeople});
}
}
SECTION("/other-module:parking-lot/example-schema:cars - list coming from an augment")
{
datastore.createListInstance("/other-module:parking-lot/example-schema:cars[id='1']");
datastore.createListInstance("/other-module:parking-lot/example-schema:cars[id='2']");
location.m_nodes.push_back(dataNode_{{"other-module"}, container_{"parking-lot"}});
node.first = "example-schema";
node.second = "cars";
expected = {
{{"id", int32_t{1}}},
{{"id", int32_t{2}}},
};
}
datastore.commitChanges();
std::sort(expected.begin(), expected.end());
auto keys = dataquery.listKeys(location, node);
std::sort(keys.begin(), keys.end());
REQUIRE(keys == expected);
}
waitForCompletionAndBitMore(seq1);
}