Skip to content

Commit 2b6416d

Browse files
Tadeáš Vintrlíkmichalvasko
authored andcommitted
test FEATURE add few basic RPC tests
1 parent 8ef9b75 commit 2b6416d

File tree

3 files changed

+273
-30
lines changed

3 files changed

+273
-30
lines changed

tests/np_test.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,17 @@ _np_glob_setup(void **state, const char *test_name)
164164
*state = st;
165165
st->server_pid = pid;
166166

167-
/* create NETCONF session */
167+
/* create NETCONF sessions */
168168
st->nc_sess = nc_connect_unix(NP_SOCKET_PATH, NULL);
169169
if (!st->nc_sess) {
170170
return 1;
171171
}
172172

173+
st->nc_sess2 = nc_connect_unix(NP_SOCKET_PATH, NULL);
174+
if (!st->nc_sess2) {
175+
return 1;
176+
}
177+
173178
return 0;
174179
}
175180

@@ -185,6 +190,7 @@ np_glob_teardown(void **state)
185190

186191
/* stop the NETCONF session */
187192
nc_session_free(st->nc_sess, NULL);
193+
nc_session_free(st->nc_sess2, NULL);
188194

189195
/* terminate the server */
190196
if (kill(st->server_pid, SIGTERM)) {

tests/np_test.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ np_glob_setup(void **state) \
4444
struct np_test {
4545
pid_t server_pid;
4646
struct nc_session *nc_sess;
47+
struct nc_session *nc_sess2;
4748
};
4849

4950
int _np_glob_setup(void **state, const char *test_name);

tests/test_rpc.c

Lines changed: 265 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,30 +33,92 @@
3333
#include <nc_client.h>
3434

3535
#include "np_test.h"
36-
#include "np_test_config.h"
36+
#include "np_test_config.h.in"
37+
38+
#define LOCK_FAIL_TEMPLATE "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"%ld\">\n"\
39+
" <rpc-error>\n"\
40+
" <error-type>protocol</error-type>\n"\
41+
" <error-tag>lock-denied</error-tag>\n"\
42+
" <error-severity>error</error-severity>\n"\
43+
" <error-message lang=\"en\">Access to the requested lock is denied because the lock is currently held by another entity.</error-message>\n"\
44+
" <error-info>\n"\
45+
" <session-id>%d</session-id>\n"\
46+
" </error-info>\n"\
47+
" </rpc-error>\n"\
48+
"</rpc-reply>\n"
3749

3850
NP_GLOB_SETUP_FUNC
3951

52+
static void
53+
test_types(void **state)
54+
{
55+
struct nc_rpc *rpc;
56+
57+
(void)state;
58+
59+
/* Test that all constructors create the right type of rpc */
60+
rpc = nc_rpc_lock(NC_DATASTORE_RUNNING);
61+
assert_int_equal(NC_RPC_LOCK, nc_rpc_get_type(rpc));
62+
nc_rpc_free(rpc);
63+
64+
rpc = nc_rpc_unlock(NC_DATASTORE_RUNNING);
65+
assert_int_equal(NC_RPC_UNLOCK, nc_rpc_get_type(rpc));
66+
nc_rpc_free(rpc);
67+
68+
rpc = nc_rpc_get("", NC_WD_ALL, NC_PARAMTYPE_CONST);
69+
assert_int_equal(NC_RPC_GET, nc_rpc_get_type(rpc));
70+
nc_rpc_free(rpc);
71+
72+
rpc = nc_rpc_kill(NC_DATASTORE_RUNNING);
73+
assert_int_equal(NC_RPC_KILL, nc_rpc_get_type(rpc));
74+
nc_rpc_free(rpc);
75+
76+
rpc = nc_rpc_commit(NC_DATASTORE_RUNNING, 0, NULL, NULL, NC_PARAMTYPE_CONST);
77+
assert_int_equal(NC_RPC_COMMIT, nc_rpc_get_type(rpc));
78+
nc_rpc_free(rpc);
79+
80+
rpc = nc_rpc_discard();
81+
assert_int_equal(NC_RPC_DISCARD, nc_rpc_get_type(rpc));
82+
nc_rpc_free(rpc);
83+
84+
rpc = nc_rpc_cancel("", NC_PARAMTYPE_CONST);
85+
assert_int_equal(NC_RPC_CANCEL, nc_rpc_get_type(rpc));
86+
nc_rpc_free(rpc);
87+
88+
rpc = nc_rpc_validate(NC_DATASTORE_RUNNING, "", NC_PARAMTYPE_CONST);
89+
assert_int_equal(NC_RPC_VALIDATE, nc_rpc_get_type(rpc));
90+
nc_rpc_free(rpc);
91+
92+
rpc = nc_rpc_subscribe("", "", "", "", NC_PARAMTYPE_CONST);
93+
assert_int_equal(NC_RPC_SUBSCRIBE, nc_rpc_get_type(rpc));
94+
nc_rpc_free(rpc);
95+
96+
rpc = nc_rpc_getdata("", "", "", NULL, 0, 0, 0, 0, NC_WD_ALL, NC_PARAMTYPE_CONST);
97+
assert_int_equal(NC_RPC_GETDATA, nc_rpc_get_type(rpc));
98+
nc_rpc_free(rpc);
99+
100+
rpc = nc_rpc_editdata("", NC_RPC_EDIT_DFLTOP_MERGE, "", NC_PARAMTYPE_CONST);
101+
assert_int_equal(NC_RPC_EDITDATA, nc_rpc_get_type(rpc));
102+
nc_rpc_free(rpc);
103+
104+
/* TODO: NC_RPC_ESTABLISHSUB and the rest */
105+
}
106+
40107
static void
41108
test_lock(void **state)
42109
{
43110
struct np_test *st = *state;
44-
struct nc_session *nc_sess2;
45111
struct nc_rpc *rpc;
46112
NC_MSG_TYPE msgtype;
47113
uint64_t msgid;
48114
struct lyd_node *envp, *op;
49115
char *str, *str2;
50116

51-
/* create another NETCONF session */
52-
nc_sess2 = nc_connect_unix(NP_SOCKET_PATH, NULL);
53-
assert_non_null(nc_sess2);
54-
55-
/* lock RPC */
117+
/* lock from first session */
56118
rpc = nc_rpc_lock(NC_DATASTORE_RUNNING);
57119
assert_non_null(rpc);
58120

59-
/* send request on session #1 */
121+
/* send request */
60122
msgtype = nc_send_rpc(st->nc_sess, rpc, 1000, &msgid);
61123
assert_int_equal(msgtype, NC_MSG_RPC);
62124

@@ -65,63 +127,237 @@ test_lock(void **state)
65127
assert_int_equal(msgtype, NC_MSG_REPLY);
66128
assert_null(op);
67129
assert_string_equal(LYD_NAME(lyd_child(envp)), "ok");
130+
68131
lyd_free_tree(envp);
69132

70-
/* send request on session #2 */
71-
msgtype = nc_send_rpc(nc_sess2, rpc, 1000, &msgid);
133+
/* request to lock from another session should fail when lock already */
134+
msgtype = nc_send_rpc(st->nc_sess2, rpc, 1000, &msgid);
72135
assert_int_equal(msgtype, NC_MSG_RPC);
73136

74-
/* receive reply */
75-
msgtype = nc_recv_reply(nc_sess2, rpc, msgid, 2000, &envp, &op);
137+
/* recieve reply, should yield error */
138+
msgtype = nc_recv_reply(st->nc_sess2, rpc, msgid, 2000, &envp, &op);
76139
assert_int_equal(msgtype, NC_MSG_REPLY);
77140
assert_null(op);
141+
assert_string_equal(LYD_NAME(lyd_child(envp)), "rpc-error");
78142
assert_int_equal(LY_SUCCESS, lyd_print_mem(&str, envp, LYD_XML, 0));
79-
lyd_free_tree(envp);
143+
144+
assert_int_not_equal(-1, asprintf(&str2, LOCK_FAIL_TEMPLATE, msgid, nc_session_get_id(st->nc_sess)));
80145

81146
/* error expected */
82-
asprintf(&str2,
83-
"<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"%d\">\n"
84-
" <rpc-error>\n"
85-
" <error-type>protocol</error-type>\n"
86-
" <error-tag>lock-denied</error-tag>\n"
87-
" <error-severity>error</error-severity>\n"
88-
" <error-message lang=\"en\">Access to the requested lock is denied because the lock is currently held by another entity.</error-message>\n"
89-
" <error-info>\n"
90-
" <session-id>1</session-id>\n"
91-
" </error-info>\n"
92-
" </rpc-error>\n"
93-
"</rpc-reply>\n", (int)msgid);
94147
assert_string_equal(str, str2);
95148
free(str);
96149
free(str2);
97150

98151
nc_rpc_free(rpc);
152+
lyd_free_tree(envp);
99153

100154
/* unlock RPC */
101155
rpc = nc_rpc_unlock(NC_DATASTORE_RUNNING);
102-
assert_non_null(rpc);
103-
104-
/* send request */
105156
msgtype = nc_send_rpc(st->nc_sess, rpc, 1000, &msgid);
106157
assert_int_equal(msgtype, NC_MSG_RPC);
158+
msgtype = nc_recv_reply(st->nc_sess, rpc, msgid, 2000, &envp, &op);
159+
assert_int_equal(msgtype, NC_MSG_REPLY);
160+
assert_null(op);
161+
assert_string_equal(LYD_NAME(lyd_child(envp)), "ok");
162+
163+
nc_rpc_free(rpc);
164+
lyd_free_tree(envp);
165+
/* TODO: check if lock prevents changes */
166+
}
167+
168+
static void
169+
test_unlock(void **state)
170+
{
171+
struct np_test *st = *state;
172+
struct nc_rpc *rpc;
173+
NC_MSG_TYPE msgtype;
174+
uint64_t msgid;
175+
struct lyd_node *envp, *op;
176+
char *str, *str2;
177+
178+
/* Simple locking checked in previous tests */
179+
180+
/* Lock by a different session */
181+
rpc = nc_rpc_lock(NC_DATASTORE_RUNNING);
182+
msgtype = nc_send_rpc(st->nc_sess2, rpc, 1000, &msgid);
183+
assert_int_equal(msgtype, NC_MSG_RPC);
107184

108185
/* receive reply */
186+
msgtype = nc_recv_reply(st->nc_sess2, rpc, msgid, 2000, &envp, &op);
187+
assert_int_equal(msgtype, NC_MSG_REPLY);
188+
assert_null(op);
189+
assert_string_equal(LYD_NAME(lyd_child(envp)), "ok");
190+
191+
nc_rpc_free(rpc);
192+
lyd_free_tree(envp);
193+
194+
/* Try unlocking a lock by a different session */
195+
rpc = nc_rpc_unlock(NC_DATASTORE_RUNNING);
196+
msgtype = nc_send_rpc(st->nc_sess, rpc, 1000, &msgid);
197+
assert_int_equal(msgtype, NC_MSG_RPC);
198+
199+
/* recieve reply, should yield error */
200+
msgtype = nc_recv_reply(st->nc_sess, rpc, msgid, 2000, &envp, &op);
201+
assert_int_equal(msgtype, NC_MSG_REPLY);
202+
assert_null(op);
203+
assert_string_equal(LYD_NAME(lyd_child(envp)), "rpc-error");
204+
assert_int_equal(LY_SUCCESS, lyd_print_mem(&str, envp, LYD_XML, 0));
205+
206+
/* error expected */
207+
assert_int_not_equal(-1, asprintf(&str2, LOCK_FAIL_TEMPLATE, msgid, nc_session_get_id(st->nc_sess2)));
208+
assert_string_equal(str, str2);
209+
free(str);
210+
free(str2);
211+
212+
nc_rpc_free(rpc);
213+
lyd_free_tree(envp);
214+
215+
/* Try unlocking the original session, should succeed */
216+
rpc = nc_rpc_unlock(NC_DATASTORE_RUNNING);
217+
msgtype = nc_send_rpc(st->nc_sess2, rpc, 1000, &msgid);
218+
assert_int_equal(NC_MSG_RPC, msgtype);
219+
220+
/* recieve reply, should succeed */
221+
msgtype = nc_recv_reply(st->nc_sess2, rpc, msgid, 2000, &envp, &op);
222+
assert_int_equal(msgtype, NC_MSG_REPLY);
223+
assert_null(op);
224+
assert_string_equal(LYD_NAME(lyd_child(envp)), "ok");
225+
226+
nc_rpc_free(rpc);
227+
lyd_free_tree(envp);
228+
}
229+
230+
static void
231+
test_get(void **state)
232+
{
233+
struct np_test *st = *state;
234+
struct nc_rpc *rpc;
235+
NC_MSG_TYPE msgtype;
236+
uint64_t msgid;
237+
struct lyd_node *envp, *op;
238+
239+
/* Try to get all */
240+
rpc = nc_rpc_get(NULL, NC_WD_ALL, NC_PARAMTYPE_CONST);
241+
msgtype = nc_send_rpc(st->nc_sess, rpc, 1000, &msgid);
242+
assert_int_equal(NC_MSG_RPC, msgtype);
243+
244+
/* recieve reply, should succeed */
245+
msgtype = nc_recv_reply(st->nc_sess, rpc, msgid, 2000, &envp, &op);
246+
assert_int_equal(msgtype, NC_MSG_REPLY);
247+
assert_non_null(op);
248+
assert_non_null(envp);
249+
250+
nc_rpc_free(rpc);
251+
lyd_free_tree(envp);
252+
lyd_free_tree(op);
253+
254+
/* TODO: test if filter works */
255+
}
256+
257+
static void
258+
test_kill(void **state)
259+
{
260+
struct np_test *st = *state;
261+
struct nc_rpc *rpc;
262+
NC_MSG_TYPE msgtype;
263+
uint64_t msgid;
264+
struct lyd_node *envp, *op;
265+
266+
/* Try to close a session */
267+
rpc = nc_rpc_kill(nc_session_get_id(st->nc_sess2));
268+
msgtype = nc_send_rpc(st->nc_sess, rpc, 1000, &msgid);
269+
assert_int_equal(NC_MSG_RPC, msgtype);
270+
271+
/* recieve reply, should fail since wrong permissions */
272+
msgtype = nc_recv_reply(st->nc_sess, rpc, msgid, 2000, &envp, &op);
273+
assert_int_equal(msgtype, NC_MSG_REPLY);
274+
assert_null(op);
275+
assert_string_equal(LYD_NAME(lyd_child(envp)), "rpc-error");
276+
277+
nc_rpc_free(rpc);
278+
lyd_free_tree(envp);
279+
/* TODO: Check error message, would depend on current user */
280+
/* TODO: NACM tests */
281+
}
282+
283+
static void
284+
test_commit(void **state)
285+
{
286+
struct np_test *st = *state;
287+
struct nc_rpc *rpc;
288+
NC_MSG_TYPE msgtype;
289+
uint64_t msgid;
290+
struct lyd_node *envp, *op;
291+
292+
/* Try to close a session */
293+
rpc = nc_rpc_commit(0, 0, NULL, NULL, NC_PARAMTYPE_CONST);
294+
msgtype = nc_send_rpc(st->nc_sess, rpc, 1000, &msgid);
295+
assert_int_equal(NC_MSG_RPC, msgtype);
296+
297+
/* recieve reply, should fail since wrong permissions */
109298
msgtype = nc_recv_reply(st->nc_sess, rpc, msgid, 2000, &envp, &op);
110299
assert_int_equal(msgtype, NC_MSG_REPLY);
111300
assert_null(op);
112301
assert_string_equal(LYD_NAME(lyd_child(envp)), "ok");
302+
303+
nc_rpc_free(rpc);
113304
lyd_free_tree(envp);
305+
/* TODO: test funcionality */
306+
}
307+
308+
static void
309+
test_discard(void **state)
310+
{
311+
struct np_test *st = *state;
312+
struct nc_rpc *rpc;
313+
NC_MSG_TYPE msgtype;
314+
uint64_t msgid;
315+
struct lyd_node *envp, *op;
316+
317+
/* Try to close a session */
318+
rpc = nc_rpc_discard();
319+
msgtype = nc_send_rpc(st->nc_sess, rpc, 1000, &msgid);
320+
assert_int_equal(NC_MSG_RPC, msgtype);
321+
322+
/* recieve reply, should fail since wrong permissions */
323+
msgtype = nc_recv_reply(st->nc_sess, rpc, msgid, 2000, &envp, &op);
324+
assert_int_equal(msgtype, NC_MSG_REPLY);
325+
assert_null(op);
326+
assert_string_equal(LYD_NAME(lyd_child(envp)), "ok");
114327

115328
nc_rpc_free(rpc);
329+
lyd_free_tree(envp);
330+
/* TODO: test funcionality */
331+
}
116332

117-
nc_session_free(nc_sess2, NULL);
333+
static void
334+
test_unsuported(void **state)
335+
{
336+
struct np_test *st = *state;
337+
struct nc_rpc *rpc;
338+
NC_MSG_TYPE msgtype;
339+
uint64_t msgid;
340+
341+
/* Testing RPCs unsupported by netopeer, all should fail */
342+
rpc = nc_rpc_cancel(NULL, NC_PARAMTYPE_CONST);
343+
msgtype = nc_send_rpc(st->nc_sess, rpc, 1000, &msgid);
344+
assert_int_equal(NC_MSG_ERROR, msgtype);
345+
346+
nc_rpc_free(rpc);
118347
}
119348

120349
int
121350
main(void)
122351
{
123352
const struct CMUnitTest tests[] = {
353+
cmocka_unit_test(test_types),
124354
cmocka_unit_test(test_lock),
355+
cmocka_unit_test(test_unlock),
356+
cmocka_unit_test(test_get),
357+
cmocka_unit_test(test_kill),
358+
cmocka_unit_test(test_commit),
359+
cmocka_unit_test(test_discard),
360+
cmocka_unit_test(test_unsuported),
125361
};
126362

127363
nc_verbosity(NC_VERB_WARNING);

0 commit comments

Comments
 (0)