blob: 410c7c48b24b362fb2c92194ad77b0634527fe49 [file] [log] [blame]
Václav Kubernátab612e92019-11-26 19:51:31 +01001/*
2 * Copyright (C) 2019 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
5 *
6*/
7
8#include <experimental/iterator>
Václav Kubernát26b56082020-02-03 18:28:56 +01009#include "trompeloeil_doctest.hpp"
Václav Kubernátab612e92019-11-26 19:51:31 +010010
11#ifdef sysrepo_BACKEND
12#include "sysrepo_access.hpp"
13#elif defined(netconf_BACKEND)
14#include "netconf_access.hpp"
15#include "netopeer_vars.hpp"
16#else
17#error "Unknown backend"
18#endif
19#include "data_query.hpp"
20#include "sysrepo_subscription.hpp"
21#include "utils.hpp"
22
23namespace std {
24std::ostream& operator<<(std::ostream& s, const std::vector<std::map<std::string, leaf_data_>> set)
25{
26 s << std::endl << "{" << std::endl;
27 std::transform(set.begin(), set.end(), std::experimental::make_ostream_joiner(s, ", \n"), [](const auto& map) {
28 std::ostringstream ss;
29 ss << " {" << std::endl << " ";
30 std::transform(map.begin(), map.end(), std::experimental::make_ostream_joiner(ss, ", \n "), [](const auto& keyValue){
31 return "{" + keyValue.first + "{" + boost::core::demangle(keyValue.second.type().name()) + "}" + ", " + leafDataToString(keyValue.second) + "}";
32 });
33 ss << std::endl << " }";
34 return ss.str();
35 });
36 s << std::endl << "}" << std::endl;
37 return s;
38}
39}
40
41TEST_CASE("data query")
42{
43 trompeloeil::sequence seq1;
44 SysrepoSubscription subscriptionExample("example-schema");
45 SysrepoSubscription subscriptionOther("other-module");
46
47#ifdef sysrepo_BACKEND
Václav Kubernát715c85c2020-04-14 01:46:08 +020048 SysrepoAccess datastore("netconf-cli-test", Datastore::Running);
Václav Kubernátab612e92019-11-26 19:51:31 +010049#elif defined(netconf_BACKEND)
50 NetconfAccess datastore(NETOPEER_SOCKET_PATH);
51#else
52#error "Unknown backend"
53#endif
54
55 DataQuery dataquery(datastore);
56
57 SECTION("listKeys")
58 {
Václav Kubernát2db124c2020-05-28 21:58:36 +020059 dataPath_ listPath;
60 listPath.m_scope = Scope::Absolute;
Václav Kubernátab612e92019-11-26 19:51:31 +010061 std::vector<std::map<std::string, leaf_data_>> expected;
62
63 SECTION("example-schema:person")
64 {
65 datastore.createListInstance("/example-schema:person[name='Vaclav']");
66 datastore.createListInstance("/example-schema:person[name='Tomas']");
67 datastore.createListInstance("/example-schema:person[name='Jan Novak']");
Václav Kubernát2db124c2020-05-28 21:58:36 +020068 listPath.m_nodes.push_back(dataNode_{{"example-schema"}, list_{"person"}});
Václav Kubernátab612e92019-11-26 19:51:31 +010069 expected = {
70 {{"name", std::string{"Jan Novak"}}},
71 {{"name", std::string{"Tomas"}}},
72 {{"name", std::string{"Vaclav"}}}
73 };
74 }
75
Václav Kubernát45e55462020-02-04 11:19:32 +010076 SECTION("example-schema:person - no instances")
77 {
Václav Kubernát2db124c2020-05-28 21:58:36 +020078 listPath.m_nodes.push_back(dataNode_{{"example-schema"}, list_{"person"}});
Václav Kubernát45e55462020-02-04 11:19:32 +010079 expected = {
80 };
81 }
82
Václav Kubernátab612e92019-11-26 19:51:31 +010083 SECTION("example-schema:selectedNumbers")
84 {
85 datastore.createListInstance("/example-schema:selectedNumbers[value='45']");
86 datastore.createListInstance("/example-schema:selectedNumbers[value='99']");
87 datastore.createListInstance("/example-schema:selectedNumbers[value='127']");
Václav Kubernát2db124c2020-05-28 21:58:36 +020088 listPath.m_nodes.push_back(dataNode_{{"example-schema"}, list_{"selectedNumbers"}});
Václav Kubernátab612e92019-11-26 19:51:31 +010089 expected = {
90 {{"value", int8_t{127}}},
91 {{"value", int8_t{45}}},
92 {{"value", int8_t{99}}}
93 };
94 }
95
96 SECTION("example-schema:animalWithColor")
97 {
98 datastore.createListInstance("/example-schema:animalWithColor[name='Dog'][color='brown']");
99 datastore.createListInstance("/example-schema:animalWithColor[name='Dog'][color='white']");
100 datastore.createListInstance("/example-schema:animalWithColor[name='Cat'][color='grey']");
Václav Kubernát2db124c2020-05-28 21:58:36 +0200101 listPath.m_nodes.push_back(dataNode_{{"example-schema"}, list_{"animalWithColor"}});
Václav Kubernátab612e92019-11-26 19:51:31 +0100102 expected = {
103 {{"name", std::string{"Cat"}}, {"color", std::string{"grey"}}},
104 {{"name", std::string{"Dog"}}, {"color", std::string{"brown"}}},
105 {{"name", std::string{"Dog"}}, {"color", std::string{"white"}}}
106 };
107 }
108
109 SECTION("example-schema:animalWithColor - quotes in values")
110 {
111 datastore.createListInstance("/example-schema:animalWithColor[name='D\"o\"g'][color=\"b'r'own\"]");
Václav Kubernát2db124c2020-05-28 21:58:36 +0200112 listPath.m_nodes.push_back(dataNode_{{"example-schema"}, list_{"animalWithColor"}});
Václav Kubernátab612e92019-11-26 19:51:31 +0100113 expected = {
114 {{"name", std::string{"D\"o\"g"}}, {"color", std::string{"b'r'own"}}}
115 };
116 }
117
118 SECTION("example-schema:ports")
119 {
120 datastore.createListInstance("/example-schema:ports[name='A']");
121 datastore.createListInstance("/example-schema:ports[name='B']");
122 datastore.createListInstance("/example-schema:ports[name='E']");
Václav Kubernát2db124c2020-05-28 21:58:36 +0200123 listPath.m_nodes.push_back(dataNode_{{"example-schema"}, list_{"ports"}});
Václav Kubernátab612e92019-11-26 19:51:31 +0100124 expected = {
125 {{"name", enum_{"A"}}},
126 {{"name", enum_{"B"}}},
127 {{"name", enum_{"E"}}},
128 };
129 }
130
131 SECTION("example-schema:org/example:people - nested list")
132 {
133 datastore.createListInstance("/example-schema:org[department='accounting']");
134 datastore.createListInstance("/example-schema:org[department='sales']");
135 datastore.createListInstance("/example-schema:org[department='programmers']");
136 datastore.createListInstance("/example-schema:org[department='accounting']/people[name='Alice']");
137 datastore.createListInstance("/example-schema:org[department='accounting']/people[name='Bob']");
138 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Alice']");
139 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Cyril']");
140 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Alice']/computers[type='laptop']");
141 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Alice']/computers[type='server']");
142 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Cyril']/computers[type='PC']");
143 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Cyril']/computers[type='server']");
144
145 SECTION("outer list")
146 {
Václav Kubernát2db124c2020-05-28 21:58:36 +0200147 listPath.m_nodes.push_back(dataNode_{{"example-schema"}, list_{"org"}});
Václav Kubernátab612e92019-11-26 19:51:31 +0100148 expected = {
149 {{"department", std::string{"accounting"}}},
150 {{"department", std::string{"sales"}}},
151 {{"department", std::string{"programmers"}}},
152 };
153 }
154
155 SECTION("nested list")
156 {
157 listElement_ list;
158 list.m_name = "org";
Václav Kubernátab612e92019-11-26 19:51:31 +0100159 SECTION("accounting department")
160 {
161 list.m_keys = {
162 {"department", std::string{"accounting"}}
163 };
164 expected = {
165 {{"name", std::string{"Alice"}}},
166 {{"name", std::string{"Bob"}}},
167 };
168 }
169 SECTION("sales department")
170 {
171 list.m_keys = {
172 {"department", std::string{"sales"}}
173 };
174 expected = {
175 {{"name", std::string{"Alice"}}},
176 {{"name", std::string{"Cyril"}}},
177 };
178 }
179 SECTION("programmers department")
180 {
181 list.m_keys = {
182 {"department", std::string{"programmers"}}
183 };
184 expected = {
185 };
186 }
Václav Kubernát2db124c2020-05-28 21:58:36 +0200187 listPath.m_nodes.push_back(dataNode_{{"example-schema"}, list});
188 listPath.m_nodes.push_back(dataNode_{list_{"people"}});
Václav Kubernátab612e92019-11-26 19:51:31 +0100189 }
190
191 SECTION("THREE MF NESTED LISTS")
192 {
193 listElement_ listOrg;
194 listOrg.m_name = "org";
195 listOrg.m_keys = {
196 {"department", std::string{"sales"}}
197 };
198
199 listElement_ listPeople;
Václav Kubernátab612e92019-11-26 19:51:31 +0100200
201 SECTION("alice computers")
202 {
203 listPeople.m_name = "people";
204 listPeople.m_keys = {
205 {"name", std::string{"Alice"}}
206 };
207 expected = {
208 {{"type", enum_{"laptop"}}},
209 {{"type", enum_{"server"}}},
210 };
211
212 }
213
214 SECTION("cyril computers")
215 {
216 listPeople.m_name = "people";
217 listPeople.m_keys = {
218 {"name", std::string{"Cyril"}}
219 };
220 expected = {
221 {{"type", enum_{"PC"}}},
222 {{"type", enum_{"server"}}},
223 };
224 }
225
Václav Kubernát2db124c2020-05-28 21:58:36 +0200226 listPath.m_nodes.push_back(dataNode_{{"example-schema"}, listOrg});
227 listPath.m_nodes.push_back(dataNode_{listPeople});
228 listPath.m_nodes.push_back(dataNode_{list_{"computers"}});
Václav Kubernátab612e92019-11-26 19:51:31 +0100229 }
230 }
231
232 SECTION("/other-module:parking-lot/example-schema:cars - list coming from an augment")
233 {
234 datastore.createListInstance("/other-module:parking-lot/example-schema:cars[id='1']");
235 datastore.createListInstance("/other-module:parking-lot/example-schema:cars[id='2']");
236
Václav Kubernát2db124c2020-05-28 21:58:36 +0200237 listPath.m_nodes.push_back(dataNode_{{"other-module"}, container_{"parking-lot"}});
238 listPath.m_nodes.push_back(dataNode_{{"example-schema"}, list_{"cars"}});
Václav Kubernátab612e92019-11-26 19:51:31 +0100239 expected = {
240 {{"id", int32_t{1}}},
241 {{"id", int32_t{2}}},
242 };
243
244 }
245
246 datastore.commitChanges();
247 std::sort(expected.begin(), expected.end());
Václav Kubernát2db124c2020-05-28 21:58:36 +0200248 auto keys = dataquery.listKeys(listPath);
Václav Kubernátab612e92019-11-26 19:51:31 +0100249 std::sort(keys.begin(), keys.end());
250 REQUIRE(keys == expected);
251 }
252
253 waitForCompletionAndBitMore(seq1);
254}