blob: 535abdc93a6becb7f277e8bc4e128870da20896c [file] [log] [blame]
Václav Kubernát73109382018-09-14 19:52:03 +02001/*
2 * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
3 * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
4 *
5 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
6 *
7*/
8
Jan Kundráta33cf082019-03-28 11:55:57 +01009#include "trompeloeil_doctest.h"
Václav Kubernát73109382018-09-14 19:52:03 +020010
Václav Kubernátc31bd602019-03-07 11:44:48 +010011#ifdef sysrepo_BACKEND
Václav Kubernát73109382018-09-14 19:52:03 +020012#include "sysrepo_access.hpp"
Václav Kubernátc31bd602019-03-07 11:44:48 +010013#elif defined(netconf_BACKEND)
14#include "netconf_access.hpp"
15#include "netopeer_vars.hpp"
16#else
17#error "Unknown backend"
18#endif
Václav Kubernát73109382018-09-14 19:52:03 +020019#include "sysrepo_subscription.hpp"
Václav Kubernát8e121ff2019-10-15 15:47:45 +020020#include "utils.hpp"
Václav Kubernát73109382018-09-14 19:52:03 +020021
Václav Kubernátbf083ec2019-02-19 13:58:09 +010022class MockRecorder : public Recorder {
Václav Kubernát73109382018-09-14 19:52:03 +020023public:
24 MAKE_MOCK3(write, void(const std::string&, const std::string&, const std::string&), override);
25};
26
Václav Kubernát8e121ff2019-10-15 15:47:45 +020027namespace std {
28std::ostream& operator<<(std::ostream& s, const std::map<std::string, leaf_data_> map)
29{
30 s << std::endl
31 << "{";
32 for (const auto& it : map) {
33 s << "{\"" << it.first << "\", " << leafDataToString(it.second) << "}" << std::endl;
34 }
35 s << "}" << std::endl;
36 return s;
37}
38}
39
40TEST_CASE("setting/getting values")
Václav Kubernát73109382018-09-14 19:52:03 +020041{
Václav Kubernát73109382018-09-14 19:52:03 +020042 trompeloeil::sequence seq1;
43 MockRecorder mock;
44 SysrepoSubscription subscription(&mock);
Václav Kubernátc31bd602019-03-07 11:44:48 +010045
46#ifdef sysrepo_BACKEND
Václav Kubernát73109382018-09-14 19:52:03 +020047 SysrepoAccess datastore("netconf-cli-test");
Václav Kubernátc31bd602019-03-07 11:44:48 +010048#elif defined(netconf_BACKEND)
49 NetconfAccess datastore(NETOPEER_SOCKET_PATH);
50#else
51#error "Unknown backend"
52#endif
Václav Kubernát73109382018-09-14 19:52:03 +020053
Václav Kubernát134d78f2019-09-03 16:42:29 +020054 SECTION("set leafInt8 to -128")
Václav Kubernát73109382018-09-14 19:52:03 +020055 {
Václav Kubernát134d78f2019-09-03 16:42:29 +020056 REQUIRE_CALL(mock, write("/example-schema:leafInt8", "", "-128"));
57 datastore.setLeaf("/example-schema:leafInt8", int8_t{-128});
58 datastore.commitChanges();
59 }
60
61 SECTION("set leafInt16 to -32768")
62 {
63 REQUIRE_CALL(mock, write("/example-schema:leafInt16", "", "-32768"));
64 datastore.setLeaf("/example-schema:leafInt16", int16_t{-32768});
65 datastore.commitChanges();
66 }
67
68 SECTION("set leafInt32 to -2147483648")
69 {
70 REQUIRE_CALL(mock, write("/example-schema:leafInt32", "", "-2147483648"));
71 datastore.setLeaf("/example-schema:leafInt32", int32_t{-2147483648});
72 datastore.commitChanges();
73 }
74
75 SECTION("set leafInt64 to -50000000000")
76 {
77 REQUIRE_CALL(mock, write("/example-schema:leafInt64", "", "-50000000000"));
78 datastore.setLeaf("/example-schema:leafInt64", int64_t{-50000000000});
79 datastore.commitChanges();
80 }
81
82 SECTION("set leafUInt8 to 255")
83 {
84 REQUIRE_CALL(mock, write("/example-schema:leafUInt8", "", "255"));
85 datastore.setLeaf("/example-schema:leafUInt8", uint8_t{255});
86 datastore.commitChanges();
87 }
88
89 SECTION("set leafUInt16 to 65535")
90 {
91 REQUIRE_CALL(mock, write("/example-schema:leafUInt16", "", "65535"));
92 datastore.setLeaf("/example-schema:leafUInt16", uint16_t{65535});
93 datastore.commitChanges();
94 }
95
96 SECTION("set leafUInt32 to 4294967295")
97 {
98 REQUIRE_CALL(mock, write("/example-schema:leafUInt32", "", "4294967295"));
99 datastore.setLeaf("/example-schema:leafUInt32", uint32_t{4294967295});
100 datastore.commitChanges();
101 }
102
103 SECTION("set leafUInt64 to 50000000000")
104 {
105 REQUIRE_CALL(mock, write("/example-schema:leafUInt64", "", "50000000000"));
106 datastore.setLeaf("/example-schema:leafUInt64", uint64_t{50000000000});
Václav Kubernát73109382018-09-14 19:52:03 +0200107 datastore.commitChanges();
108 }
109
110 SECTION("set leafEnum to coze")
111 {
112 REQUIRE_CALL(mock, write("/example-schema:leafEnum", "", "coze"));
113 datastore.setLeaf("/example-schema:leafEnum", enum_{"coze"});
114 datastore.commitChanges();
115 }
116
117 SECTION("set leafDecimal to 123.544")
118 {
119 REQUIRE_CALL(mock, write("/example-schema:leafDecimal", "", "123.544"));
120 datastore.setLeaf("/example-schema:leafDecimal", 123.544);
121 datastore.commitChanges();
122 }
123
124 SECTION("create presence container")
125 {
126 REQUIRE_CALL(mock, write("/example-schema:pContainer", "", ""));
127 datastore.createPresenceContainer("/example-schema:pContainer");
128 datastore.commitChanges();
129 }
130
Václav Kubernát45f4a822019-05-29 21:10:50 +0200131 SECTION("create a list instance")
132 {
133 REQUIRE_CALL(mock, write("/example-schema:person[name='Nguyen']", "", ""));
134 REQUIRE_CALL(mock, write("/example-schema:person[name='Nguyen']/name", "", "Nguyen"));
135 datastore.createListInstance("/example-schema:person[name='Nguyen']");
136 datastore.commitChanges();
137 }
138
Václav Kubernát3efb5ca2019-10-09 20:07:40 +0200139 SECTION("leafref pointing to a key of a list")
140 {
141 {
142 REQUIRE_CALL(mock, write("/example-schema:person[name='Dan']", "", ""));
143 REQUIRE_CALL(mock, write("/example-schema:person[name='Dan']/name", "", "Dan"));
144 REQUIRE_CALL(mock, write("/example-schema:person[name='Elfi']", "", ""));
145 REQUIRE_CALL(mock, write("/example-schema:person[name='Elfi']/name", "", "Elfi"));
146 REQUIRE_CALL(mock, write("/example-schema:person[name='Kolafa']", "", ""));
147 REQUIRE_CALL(mock, write("/example-schema:person[name='Kolafa']/name", "", "Kolafa"));
148 datastore.createListInstance("/example-schema:person[name='Dan']");
149 datastore.createListInstance("/example-schema:person[name='Elfi']");
150 datastore.createListInstance("/example-schema:person[name='Kolafa']");
151 datastore.commitChanges();
152 }
153
154 // The commitChanges method has to be called in each of the
155 // SECTIONs, because the REQUIRE_CALL only works inside the given
156 // SECTION.
157 SECTION("Dan")
158 {
159 REQUIRE_CALL(mock, write("/example-schema:bossPerson", "", "Dan"));
160 datastore.setLeaf("/example-schema:bossPerson", std::string{"Dan"});
161 datastore.commitChanges();
162 }
163
164 SECTION("Elfi")
165 {
166 REQUIRE_CALL(mock, write("/example-schema:bossPerson", "", "Elfi"));
167 datastore.setLeaf("/example-schema:bossPerson", std::string{"Elfi"});
168 datastore.commitChanges();
169 }
170
171 SECTION("Kolafa")
172 {
173 REQUIRE_CALL(mock, write("/example-schema:bossPerson", "", "Kolafa"));
174 datastore.setLeaf("/example-schema:bossPerson", std::string{"Kolafa"});
175 datastore.commitChanges();
176 }
177 }
Václav Kubernát8e121ff2019-10-15 15:47:45 +0200178 SECTION("bool values get correctly represented as bools")
179 {
180 {
181 REQUIRE_CALL(mock, write("/example-schema:down", "", "true"));
182 datastore.setLeaf("/example-schema:down", bool{true});
183 datastore.commitChanges();
184 }
185
186 std::map<std::string, leaf_data_> expected{{"/example-schema:down", bool{true}}};
187 REQUIRE(datastore.getItems("/example-schema:down") == expected);
188 }
Václav Kubernát3efb5ca2019-10-09 20:07:40 +0200189
Václav Kubernát9456b5c2019-10-02 21:14:52 +0200190 SECTION("getting items from the whole module")
191 {
192 {
193 REQUIRE_CALL(mock, write("/example-schema:up", "", "true"));
194 REQUIRE_CALL(mock, write("/example-schema:down", "", "false"));
195 datastore.setLeaf("/example-schema:up", bool{true});
196 datastore.setLeaf("/example-schema:down", bool{false});
197 datastore.commitChanges();
198 }
199
200 std::map<std::string, leaf_data_> expected{{"/example-schema:down", bool{false}},
201 // Sysrepo always returns containers when getting values, but
202 // libnetconf does not. This is fine by the YANG standard:
203 // https://tools.ietf.org/html/rfc7950#section-7.5.7 Furthermore,
204 // NetconfAccess implementation actually only iterates over leafs,
205 // so even if libnetconf did include containers, they wouldn't get
206 // shown here anyway. With sysrepo2, this won't be necessary,
207 // because it'll use the same data structure as libnetconf, so the
208 // results will be consistent.
209#ifdef sysrepo_BACKEND
Václav Kubernát144729d2020-01-08 15:20:35 +0100210 {"/example-schema:lol", special_{SpecialValue::Container}},
Václav Kubernát9456b5c2019-10-02 21:14:52 +0200211#endif
212 {"/example-schema:up", bool{true}}};
213 REQUIRE(datastore.getItems("/example-schema:*") == expected);
214 }
215
Václav Kubernát152ce222019-12-19 12:23:32 +0100216 SECTION("getItems returns correct datatypes")
217 {
218 {
219 REQUIRE_CALL(mock, write("/example-schema:leafEnum", "", "lol"));
220 datastore.setLeaf("/example-schema:leafEnum", enum_{"lol"});
221 datastore.commitChanges();
222 }
223 std::map<std::string, leaf_data_> expected{{"/example-schema:leafEnum", enum_{"lol"}}};
224
225 REQUIRE(datastore.getItems("/example-schema:leafEnum") == expected);
226 }
227
Václav Kubernátd812cfb2020-01-07 17:30:20 +0100228 SECTION("getItems on a list")
229 {
230 {
231 REQUIRE_CALL(mock, write("/example-schema:person[name='Jan']", "", ""));
232 REQUIRE_CALL(mock, write("/example-schema:person[name='Jan']/name", "", "Jan"));
233 REQUIRE_CALL(mock, write("/example-schema:person[name='Michal']", "", ""));
234 REQUIRE_CALL(mock, write("/example-schema:person[name='Michal']/name", "", "Michal"));
235 REQUIRE_CALL(mock, write("/example-schema:person[name='Petr']", "", ""));
236 REQUIRE_CALL(mock, write("/example-schema:person[name='Petr']/name", "", "Petr"));
237 datastore.createListInstance("/example-schema:person[name='Jan']");
238 datastore.createListInstance("/example-schema:person[name='Michal']");
239 datastore.createListInstance("/example-schema:person[name='Petr']");
240 datastore.commitChanges();
241 }
242 std::map<std::string, leaf_data_> expected{
Václav Kubernát144729d2020-01-08 15:20:35 +0100243 {"/example-schema:person[name='Jan']", special_{SpecialValue::List}},
Václav Kubernátd812cfb2020-01-07 17:30:20 +0100244 {"/example-schema:person[name='Jan']/name", std::string{"Jan"}},
Václav Kubernát144729d2020-01-08 15:20:35 +0100245 {"/example-schema:person[name='Michal']", special_{SpecialValue::List}},
Václav Kubernátd812cfb2020-01-07 17:30:20 +0100246 {"/example-schema:person[name='Michal']/name", std::string{"Michal"}},
Václav Kubernát144729d2020-01-08 15:20:35 +0100247 {"/example-schema:person[name='Petr']", special_{SpecialValue::List}},
Václav Kubernátd812cfb2020-01-07 17:30:20 +0100248 {"/example-schema:person[name='Petr']/name", std::string{"Petr"}}
249 };
250
251 REQUIRE(datastore.getItems("/example-schema:person") == expected);
252 }
253
Václav Kubernát73109382018-09-14 19:52:03 +0200254 waitForCompletionAndBitMore(seq1);
255}