blob: e0e2875cbd74f418bdb3821d1d8c88cde0640c93 [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
48 SysrepoAccess datastore("netconf-cli-test");
49#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 {
59 dataPath_ location;
60 location.m_scope = Scope::Absolute;
61 ModuleNodePair node;
62 std::vector<std::map<std::string, leaf_data_>> expected;
63
64 SECTION("example-schema:person")
65 {
66 datastore.createListInstance("/example-schema:person[name='Vaclav']");
67 datastore.createListInstance("/example-schema:person[name='Tomas']");
68 datastore.createListInstance("/example-schema:person[name='Jan Novak']");
69 node.first = "example-schema";
70 node.second = "person";
71 expected = {
72 {{"name", std::string{"Jan Novak"}}},
73 {{"name", std::string{"Tomas"}}},
74 {{"name", std::string{"Vaclav"}}}
75 };
76 }
77
Václav Kubernát45e55462020-02-04 11:19:32 +010078 SECTION("example-schema:person - no instances")
79 {
80 node.first = "example-schema";
81 node.second = "person";
82 expected = {
83 };
84 }
85
Václav Kubernátab612e92019-11-26 19:51:31 +010086 SECTION("example-schema:selectedNumbers")
87 {
88 datastore.createListInstance("/example-schema:selectedNumbers[value='45']");
89 datastore.createListInstance("/example-schema:selectedNumbers[value='99']");
90 datastore.createListInstance("/example-schema:selectedNumbers[value='127']");
91 node.first = "example-schema";
92 node.second = "selectedNumbers";
93 expected = {
94 {{"value", int8_t{127}}},
95 {{"value", int8_t{45}}},
96 {{"value", int8_t{99}}}
97 };
98 }
99
100 SECTION("example-schema:animalWithColor")
101 {
102 datastore.createListInstance("/example-schema:animalWithColor[name='Dog'][color='brown']");
103 datastore.createListInstance("/example-schema:animalWithColor[name='Dog'][color='white']");
104 datastore.createListInstance("/example-schema:animalWithColor[name='Cat'][color='grey']");
105 node.first = "example-schema";
106 node.second = "animalWithColor";
107 expected = {
108 {{"name", std::string{"Cat"}}, {"color", std::string{"grey"}}},
109 {{"name", std::string{"Dog"}}, {"color", std::string{"brown"}}},
110 {{"name", std::string{"Dog"}}, {"color", std::string{"white"}}}
111 };
112 }
113
114 SECTION("example-schema:animalWithColor - quotes in values")
115 {
116 datastore.createListInstance("/example-schema:animalWithColor[name='D\"o\"g'][color=\"b'r'own\"]");
117 node.first = "example-schema";
118 node.second = "animalWithColor";
119 expected = {
120 {{"name", std::string{"D\"o\"g"}}, {"color", std::string{"b'r'own"}}}
121 };
122 }
123
124 SECTION("example-schema:ports")
125 {
126 datastore.createListInstance("/example-schema:ports[name='A']");
127 datastore.createListInstance("/example-schema:ports[name='B']");
128 datastore.createListInstance("/example-schema:ports[name='E']");
129 node.first = "example-schema";
130 node.second = "ports";
131 expected = {
132 {{"name", enum_{"A"}}},
133 {{"name", enum_{"B"}}},
134 {{"name", enum_{"E"}}},
135 };
136 }
137
138 SECTION("example-schema:org/example:people - nested list")
139 {
140 datastore.createListInstance("/example-schema:org[department='accounting']");
141 datastore.createListInstance("/example-schema:org[department='sales']");
142 datastore.createListInstance("/example-schema:org[department='programmers']");
143 datastore.createListInstance("/example-schema:org[department='accounting']/people[name='Alice']");
144 datastore.createListInstance("/example-schema:org[department='accounting']/people[name='Bob']");
145 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Alice']");
146 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Cyril']");
147 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Alice']/computers[type='laptop']");
148 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Alice']/computers[type='server']");
149 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Cyril']/computers[type='PC']");
150 datastore.createListInstance("/example-schema:org[department='sales']/people[name='Cyril']/computers[type='server']");
151
152 SECTION("outer list")
153 {
154 node.first = "example-schema";
155 node.second = "org";
156 expected = {
157 {{"department", std::string{"accounting"}}},
158 {{"department", std::string{"sales"}}},
159 {{"department", std::string{"programmers"}}},
160 };
161 }
162
163 SECTION("nested list")
164 {
165 listElement_ list;
166 list.m_name = "org";
167 node.second = "people";
168 SECTION("accounting department")
169 {
170 list.m_keys = {
171 {"department", std::string{"accounting"}}
172 };
173 expected = {
174 {{"name", std::string{"Alice"}}},
175 {{"name", std::string{"Bob"}}},
176 };
177 }
178 SECTION("sales department")
179 {
180 list.m_keys = {
181 {"department", std::string{"sales"}}
182 };
183 expected = {
184 {{"name", std::string{"Alice"}}},
185 {{"name", std::string{"Cyril"}}},
186 };
187 }
188 SECTION("programmers department")
189 {
190 list.m_keys = {
191 {"department", std::string{"programmers"}}
192 };
193 expected = {
194 };
195 }
196 location.m_nodes.push_back(dataNode_{{"example-schema"}, list});
197 }
198
199 SECTION("THREE MF NESTED LISTS")
200 {
201 listElement_ listOrg;
202 listOrg.m_name = "org";
203 listOrg.m_keys = {
204 {"department", std::string{"sales"}}
205 };
206
207 listElement_ listPeople;
208 node.second = "computers";
209
210 SECTION("alice computers")
211 {
212 listPeople.m_name = "people";
213 listPeople.m_keys = {
214 {"name", std::string{"Alice"}}
215 };
216 expected = {
217 {{"type", enum_{"laptop"}}},
218 {{"type", enum_{"server"}}},
219 };
220
221 }
222
223 SECTION("cyril computers")
224 {
225 listPeople.m_name = "people";
226 listPeople.m_keys = {
227 {"name", std::string{"Cyril"}}
228 };
229 expected = {
230 {{"type", enum_{"PC"}}},
231 {{"type", enum_{"server"}}},
232 };
233 }
234
235 location.m_nodes.push_back(dataNode_{{"example-schema"}, listOrg});
236 location.m_nodes.push_back(dataNode_{listPeople});
237
238 }
239 }
240
241 SECTION("/other-module:parking-lot/example-schema:cars - list coming from an augment")
242 {
243 datastore.createListInstance("/other-module:parking-lot/example-schema:cars[id='1']");
244 datastore.createListInstance("/other-module:parking-lot/example-schema:cars[id='2']");
245
246 location.m_nodes.push_back(dataNode_{{"other-module"}, container_{"parking-lot"}});
247 node.first = "example-schema";
248 node.second = "cars";
249 expected = {
250 {{"id", int32_t{1}}},
251 {{"id", int32_t{2}}},
252 };
253
254 }
255
256 datastore.commitChanges();
257 std::sort(expected.begin(), expected.end());
258 auto keys = dataquery.listKeys(location, node);
259 std::sort(keys.begin(), keys.end());
260 REQUIRE(keys == expected);
261 }
262
263 waitForCompletionAndBitMore(seq1);
264}