blob: 8e6c2d557a7b2356ea9be46a404dca8e943fdd7c [file] [log] [blame]
Michal Vasko294d4c62016-02-01 10:10:27 +01001/**
Michal Vasko7227f352016-02-01 12:11:40 +01002 * \file test_fd_comm.c
Michal Vasko294d4c62016-02-01 10:10:27 +01003 * \author Michal Vasko <mvasko@cesnet.cz>
Michal Vasko7227f352016-02-01 12:11:40 +01004 * \brief libnetconf2 tests - file descriptor basic RPC communication
Michal Vasko294d4c62016-02-01 10:10:27 +01005 *
6 * Copyright (c) 2015 CESNET, z.s.p.o.
7 *
Radek Krejci9b81f5b2016-02-24 13:14:49 +01008 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
Michal Vaskoad1cc6a2016-02-26 15:06:06 +010011 *
Radek Krejci9b81f5b2016-02-24 13:14:49 +010012 * https://opensource.org/licenses/BSD-3-Clause
Michal Vasko294d4c62016-02-01 10:10:27 +010013 */
14
15#include <errno.h>
16#include <fcntl.h>
17#include <pthread.h>
18#include <setjmp.h>
19#include <stdarg.h>
20#include <stddef.h>
21#include <stdint.h>
22#include <stdlib.h>
Michal Vasko294d4c62016-02-01 10:10:27 +010023#include <string.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020024#include <sys/socket.h>
Michal Vasko294d4c62016-02-01 10:10:27 +010025#include <sys/stat.h>
26#include <sys/types.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020027#include <unistd.h>
Michal Vasko294d4c62016-02-01 10:10:27 +010028
29#include <cmocka.h>
30#include <libyang/libyang.h>
31
Michal Vasko294d4c62016-02-01 10:10:27 +010032#include <messages_p.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020033#include <session_client.h>
34#include <session_p.h>
35#include <session_server.h>
Jan Kundrátcf15d6c2017-10-26 18:07:56 +020036#include "tests/config.h"
Michal Vasko294d4c62016-02-01 10:10:27 +010037
38struct nc_session *server_session;
39struct nc_session *client_session;
Michal Vasko8c5518b2016-03-01 12:35:13 +010040struct ly_ctx *ctx;
Michal Vaskobbaa9b22019-03-14 12:35:43 +010041pthread_mutex_t state_lock = PTHREAD_MUTEX_INITIALIZER;
tadeas-vintrlik2e803db2021-08-25 12:12:07 +020042pthread_barrier_t barrier;
Michal Vaskobbaa9b22019-03-14 12:35:43 +010043int glob_state;
Michal Vasko294d4c62016-02-01 10:10:27 +010044
45struct nc_server_reply *
46my_get_rpc_clb(struct lyd_node *rpc, struct nc_session *session)
47{
48 assert_string_equal(rpc->schema->name, "get");
49 assert_ptr_equal(session, server_session);
50
51 return nc_server_reply_ok();
52}
53
54struct nc_server_reply *
55my_getconfig_rpc_clb(struct lyd_node *rpc, struct nc_session *session)
56{
57 struct lyd_node *data;
Michal Vasko294d4c62016-02-01 10:10:27 +010058
59 assert_string_equal(rpc->schema->name, "get-config");
60 assert_ptr_equal(session, server_session);
61
Michal Vasko77367452021-02-16 16:32:18 +010062 lyd_new_path(NULL, session->ctx, "/ietf-netconf:get-config/data", NULL, LYD_NEW_PATH_OUTPUT, &data);
Michal Vasko294d4c62016-02-01 10:10:27 +010063 assert_non_null(data);
64
Radek Krejci36dfdb32016-09-01 16:56:35 +020065 return nc_server_reply_data(data, NC_WD_EXPLICIT, NC_PARAMTYPE_FREE);
Michal Vasko294d4c62016-02-01 10:10:27 +010066}
67
Michal Vasko131120a2018-05-29 15:44:02 +020068struct nc_server_reply *
69my_commit_rpc_clb(struct lyd_node *rpc, struct nc_session *session)
70{
71 assert_string_equal(rpc->schema->name, "commit");
72 assert_ptr_equal(session, server_session);
73
74 /* update state */
Michal Vaskobbaa9b22019-03-14 12:35:43 +010075 pthread_mutex_lock(&state_lock);
Michal Vasko131120a2018-05-29 15:44:02 +020076 glob_state = 1;
77
78 /* wait until the client receives the notification */
79 while (glob_state != 3) {
Michal Vaskobbaa9b22019-03-14 12:35:43 +010080 pthread_mutex_unlock(&state_lock);
Michal Vasko131120a2018-05-29 15:44:02 +020081 usleep(100000);
Michal Vaskobbaa9b22019-03-14 12:35:43 +010082 pthread_mutex_lock(&state_lock);
Michal Vasko131120a2018-05-29 15:44:02 +020083 }
Michal Vaskobbaa9b22019-03-14 12:35:43 +010084 pthread_mutex_unlock(&state_lock);
Michal Vasko131120a2018-05-29 15:44:02 +020085
86 return nc_server_reply_ok();
87}
88
89static struct nc_session *
90test_new_session(NC_SIDE side)
91{
92 struct nc_session *sess;
93
94 sess = calloc(1, sizeof *sess);
95 if (!sess) {
96 return NULL;
97 }
98
99 sess->side = side;
100
101 if (side == NC_SERVER) {
Michal Vaskoacf98472021-02-04 15:33:57 +0100102 pthread_mutex_init(&sess->opts.server.rpc_lock, NULL);
103 pthread_cond_init(&sess->opts.server.rpc_cond, NULL);
104 sess->opts.server.rpc_inuse = 0;
Michal Vasko131120a2018-05-29 15:44:02 +0200105 }
106
107 sess->io_lock = malloc(sizeof *sess->io_lock);
108 if (!sess->io_lock) {
109 goto error;
110 }
111 pthread_mutex_init(sess->io_lock, NULL);
112
113 return sess;
114
115error:
Michal Vasko131120a2018-05-29 15:44:02 +0200116 free(sess);
117 return NULL;
118}
119
Michal Vasko294d4c62016-02-01 10:10:27 +0100120static int
121setup_sessions(void **state)
122{
123 (void)state;
Michal Vasko294d4c62016-02-01 10:10:27 +0100124 int sock[2];
125
Michal Vasko294d4c62016-02-01 10:10:27 +0100126 /* create communication channel */
127 socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
128
Michal Vasko294d4c62016-02-01 10:10:27 +0100129 /* create server session */
Michal Vasko131120a2018-05-29 15:44:02 +0200130 server_session = test_new_session(NC_SERVER);
Michal Vasko294d4c62016-02-01 10:10:27 +0100131 server_session->status = NC_STATUS_RUNNING;
Michal Vasko294d4c62016-02-01 10:10:27 +0100132 server_session->id = 1;
Michal Vasko294d4c62016-02-01 10:10:27 +0100133 server_session->ti_type = NC_TI_FD;
Michal Vasko294d4c62016-02-01 10:10:27 +0100134 server_session->ti.fd.in = sock[0];
135 server_session->ti.fd.out = sock[0];
136 server_session->ctx = ctx;
137 server_session->flags = NC_SESSION_SHAREDCTX;
138
139 /* create client session */
Michal Vasko131120a2018-05-29 15:44:02 +0200140 client_session = test_new_session(NC_CLIENT);
Michal Vasko294d4c62016-02-01 10:10:27 +0100141 client_session->status = NC_STATUS_RUNNING;
Michal Vasko294d4c62016-02-01 10:10:27 +0100142 client_session->id = 1;
Michal Vasko294d4c62016-02-01 10:10:27 +0100143 client_session->ti_type = NC_TI_FD;
Michal Vasko294d4c62016-02-01 10:10:27 +0100144 client_session->ti.fd.in = sock[1];
145 client_session->ti.fd.out = sock[1];
146 client_session->ctx = ctx;
147 client_session->flags = NC_SESSION_SHAREDCTX;
Michal Vasko338f8472016-10-13 15:01:27 +0200148 client_session->opts.client.msgid = 50;
Michal Vasko294d4c62016-02-01 10:10:27 +0100149
150 return 0;
151}
152
153static int
154teardown_sessions(void **state)
155{
156 (void)state;
157
Michal Vasko294d4c62016-02-01 10:10:27 +0100158 close(server_session->ti.fd.in);
Michal Vasko77367452021-02-16 16:32:18 +0100159 server_session->ti.fd.in = -1;
Michal Vasko131120a2018-05-29 15:44:02 +0200160 nc_session_free(server_session, NULL);
Michal Vasko294d4c62016-02-01 10:10:27 +0100161
162 close(client_session->ti.fd.in);
Michal Vasko77367452021-02-16 16:32:18 +0100163 client_session->ti.fd.in = -1;
Michal Vasko131120a2018-05-29 15:44:02 +0200164 nc_session_free(client_session, NULL);
Michal Vasko294d4c62016-02-01 10:10:27 +0100165
166 return 0;
167}
168
169static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100170test_send_recv_ok(void)
Michal Vasko294d4c62016-02-01 10:10:27 +0100171{
Michal Vasko294d4c62016-02-01 10:10:27 +0100172 int ret;
173 uint64_t msgid;
174 NC_MSG_TYPE msgtype;
175 struct nc_rpc *rpc;
Michal Vasko77367452021-02-16 16:32:18 +0100176 struct lyd_node *envp, *op;
Michal Vasko294d4c62016-02-01 10:10:27 +0100177 struct nc_pollsession *ps;
178
179 /* client RPC */
180 rpc = nc_rpc_get(NULL, 0, 0);
181 assert_non_null(rpc);
182
183 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
184 assert_int_equal(msgtype, NC_MSG_RPC);
185
186 /* server RPC, send reply */
187 ps = nc_ps_new();
188 assert_non_null(ps);
189 nc_ps_add_session(ps, server_session);
190
Michal Vasko71090fc2016-05-24 16:37:28 +0200191 ret = nc_ps_poll(ps, 0, NULL);
192 assert_int_equal(ret, NC_PSPOLL_RPC);
Michal Vasko294d4c62016-02-01 10:10:27 +0100193
194 /* server finished */
195 nc_ps_free(ps);
196
197 /* client reply */
Michal Vasko77367452021-02-16 16:32:18 +0100198 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, &envp, &op);
Michal Vasko294d4c62016-02-01 10:10:27 +0100199 assert_int_equal(msgtype, NC_MSG_REPLY);
200
201 nc_rpc_free(rpc);
Michal Vasko77367452021-02-16 16:32:18 +0100202 assert_null(op);
203 assert_string_equal(LYD_NAME(lyd_child(envp)), "ok");
204 lyd_free_tree(envp);
Michal Vasko294d4c62016-02-01 10:10:27 +0100205}
206
207static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100208test_send_recv_ok_10(void **state)
Michal Vasko294d4c62016-02-01 10:10:27 +0100209{
210 (void)state;
Michal Vasko58d152f2016-02-01 11:44:49 +0100211
212 server_session->version = NC_VERSION_10;
213 client_session->version = NC_VERSION_10;
214
215 test_send_recv_ok();
216}
217
218static void
219test_send_recv_ok_11(void **state)
220{
221 (void)state;
222
223 server_session->version = NC_VERSION_11;
224 client_session->version = NC_VERSION_11;
225
226 test_send_recv_ok();
227}
228
229static void
230test_send_recv_error(void)
231{
Michal Vasko294d4c62016-02-01 10:10:27 +0100232 int ret;
233 uint64_t msgid;
234 NC_MSG_TYPE msgtype;
235 struct nc_rpc *rpc;
Michal Vasko77367452021-02-16 16:32:18 +0100236 struct lyd_node *envp, *op, *node;
Michal Vasko294d4c62016-02-01 10:10:27 +0100237 struct nc_pollsession *ps;
238
239 /* client RPC */
240 rpc = nc_rpc_kill(1);
241 assert_non_null(rpc);
242
243 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
244 assert_int_equal(msgtype, NC_MSG_RPC);
245
246 /* server RPC, send reply */
247 ps = nc_ps_new();
248 assert_non_null(ps);
249 nc_ps_add_session(ps, server_session);
250
Michal Vasko71090fc2016-05-24 16:37:28 +0200251 ret = nc_ps_poll(ps, 0, NULL);
252 assert_int_equal(ret, NC_PSPOLL_RPC | NC_PSPOLL_REPLY_ERROR);
Michal Vasko294d4c62016-02-01 10:10:27 +0100253
254 /* server finished */
255 nc_ps_free(ps);
256
257 /* client reply */
Michal Vasko77367452021-02-16 16:32:18 +0100258 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, &envp, &op);
Michal Vasko294d4c62016-02-01 10:10:27 +0100259 assert_int_equal(msgtype, NC_MSG_REPLY);
260
261 nc_rpc_free(rpc);
Michal Vasko77367452021-02-16 16:32:18 +0100262 assert_string_equal(LYD_NAME(lyd_child(envp)), "rpc-error");
263 lyd_find_sibling_opaq_next(lyd_child(lyd_child(envp)), "error-tag", &node);
264 assert_non_null(node);
265 assert_string_equal(((struct lyd_node_opaq *)node)->value, "operation-not-supported");
266 lyd_free_tree(envp);
267 assert_null(op);
Michal Vasko294d4c62016-02-01 10:10:27 +0100268}
269
270static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100271test_send_recv_error_10(void **state)
Michal Vasko294d4c62016-02-01 10:10:27 +0100272{
273 (void)state;
Michal Vasko58d152f2016-02-01 11:44:49 +0100274
275 server_session->version = NC_VERSION_10;
276 client_session->version = NC_VERSION_10;
277
278 test_send_recv_error();
279}
280
281static void
282test_send_recv_error_11(void **state)
283{
284 (void)state;
285
286 server_session->version = NC_VERSION_11;
287 client_session->version = NC_VERSION_11;
288
289 test_send_recv_error();
290}
291
292static void
293test_send_recv_data(void)
294{
Michal Vasko294d4c62016-02-01 10:10:27 +0100295 int ret;
296 uint64_t msgid;
297 NC_MSG_TYPE msgtype;
298 struct nc_rpc *rpc;
Michal Vasko77367452021-02-16 16:32:18 +0100299 struct lyd_node *envp, *op;
Michal Vasko294d4c62016-02-01 10:10:27 +0100300 struct nc_pollsession *ps;
301
302 /* client RPC */
303 rpc = nc_rpc_getconfig(NC_DATASTORE_RUNNING, NULL, 0, 0);
304 assert_non_null(rpc);
305
306 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
307 assert_int_equal(msgtype, NC_MSG_RPC);
308
309 /* server RPC, send reply */
310 ps = nc_ps_new();
311 assert_non_null(ps);
312 nc_ps_add_session(ps, server_session);
313
Michal Vasko71090fc2016-05-24 16:37:28 +0200314 ret = nc_ps_poll(ps, 0, NULL);
315 assert_int_equal(ret, NC_PSPOLL_RPC);
Michal Vasko294d4c62016-02-01 10:10:27 +0100316
317 /* server finished */
318 nc_ps_free(ps);
319
320 /* client reply */
Michal Vasko77367452021-02-16 16:32:18 +0100321 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, &envp, &op);
Michal Vasko294d4c62016-02-01 10:10:27 +0100322 assert_int_equal(msgtype, NC_MSG_REPLY);
323
324 nc_rpc_free(rpc);
Michal Vasko77367452021-02-16 16:32:18 +0100325 assert_non_null(envp);
326 lyd_free_tree(envp);
327 assert_non_null(op);
328 lyd_free_tree(op);
Michal Vasko294d4c62016-02-01 10:10:27 +0100329}
330
Michal Vasko58d152f2016-02-01 11:44:49 +0100331static void
332test_send_recv_data_10(void **state)
333{
334 (void)state;
335
336 server_session->version = NC_VERSION_10;
337 client_session->version = NC_VERSION_10;
338
339 test_send_recv_data();
340}
341
342static void
343test_send_recv_data_11(void **state)
344{
345 (void)state;
346
347 server_session->version = NC_VERSION_11;
348 client_session->version = NC_VERSION_11;
349
350 test_send_recv_data();
351}
352
Michal Vasko131120a2018-05-29 15:44:02 +0200353static void *
354server_send_notif_thread(void *arg)
355{
356 NC_MSG_TYPE msg_type;
357 struct lyd_node *notif_tree;
358 struct nc_server_notif *notif;
Michal Vasko49eb3f42021-05-19 10:20:57 +0200359 struct timespec ts;
Michal Vasko131120a2018-05-29 15:44:02 +0200360 char *buf;
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200361
Michal Vasko131120a2018-05-29 15:44:02 +0200362 (void)arg;
363
364 /* wait for the RPC callback to be called */
Michal Vaskobbaa9b22019-03-14 12:35:43 +0100365 pthread_mutex_lock(&state_lock);
Michal Vasko131120a2018-05-29 15:44:02 +0200366 while (glob_state != 1) {
Michal Vaskobbaa9b22019-03-14 12:35:43 +0100367 pthread_mutex_unlock(&state_lock);
Michal Vasko131120a2018-05-29 15:44:02 +0200368 usleep(1000);
Michal Vaskobbaa9b22019-03-14 12:35:43 +0100369 pthread_mutex_lock(&state_lock);
Michal Vasko131120a2018-05-29 15:44:02 +0200370 }
371
372 /* create notif */
Michal Vasko77367452021-02-16 16:32:18 +0100373 lyd_new_path(NULL, ctx, "/nc-notifications:notificationComplete", NULL, 0, &notif_tree);
Michal Vasko131120a2018-05-29 15:44:02 +0200374 assert_non_null(notif_tree);
Michal Vasko49eb3f42021-05-19 10:20:57 +0200375 clock_gettime(CLOCK_REALTIME, &ts);
Michal Vaskod7fb6df2021-05-19 11:27:35 +0200376 ly_time_ts2str(&ts, &buf);
377 notif = nc_server_notif_new(notif_tree, buf, NC_PARAMTYPE_FREE);
Michal Vasko131120a2018-05-29 15:44:02 +0200378 assert_non_null(notif);
379
380 /* send notif */
Michal Vasko71dbd772021-03-23 14:08:37 +0100381 nc_session_inc_notif_status(server_session);
Michal Vasko131120a2018-05-29 15:44:02 +0200382 msg_type = nc_server_notif_send(server_session, notif, 100);
383 nc_server_notif_free(notif);
384 assert_int_equal(msg_type, NC_MSG_NOTIF);
385
386 /* update state */
387 glob_state = 2;
tadeas-vintrlik2e803db2021-08-25 12:12:07 +0200388 pthread_barrier_wait(&barrier);
Michal Vaskobbaa9b22019-03-14 12:35:43 +0100389 pthread_mutex_unlock(&state_lock);
Michal Vasko131120a2018-05-29 15:44:02 +0200390
391 return NULL;
392}
393
tadeas-vintrlik2e803db2021-08-25 12:12:07 +0200394static void *
395thread_recv_notif(void *arg)
396{
397 struct nc_session *session = (struct nc_session *)arg;
398 struct lyd_node *envp;
399 struct lyd_node *op;
400 NC_MSG_TYPE msgtype;
401
402 pthread_barrier_wait(&barrier);
403 msgtype = nc_recv_notif(session, 1000, &envp, &op);
404 assert_int_equal(msgtype, NC_MSG_NOTIF);
405 assert_string_equal(op->schema->name, "notificationComplete");
406
407 lyd_free_tree(envp);
408 lyd_free_tree(op);
409
410 pthread_mutex_lock(&state_lock);
411 glob_state = 3;
412 pthread_mutex_unlock(&state_lock);
413
414 return (void *)0;
415}
416
Michal Vasko294d4c62016-02-01 10:10:27 +0100417static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100418test_send_recv_notif(void)
Michal Vasko294d4c62016-02-01 10:10:27 +0100419{
Michal Vasko131120a2018-05-29 15:44:02 +0200420 int ret;
tadeas-vintrlik2e803db2021-08-25 12:12:07 +0200421 pthread_t tid[2];
Michal Vasko131120a2018-05-29 15:44:02 +0200422 uint64_t msgid;
423 NC_MSG_TYPE msgtype;
424 struct nc_rpc *rpc;
Michal Vasko77367452021-02-16 16:32:18 +0100425 struct lyd_node *envp, *op;
Michal Vasko131120a2018-05-29 15:44:02 +0200426 struct nc_pollsession *ps;
Michal Vasko294d4c62016-02-01 10:10:27 +0100427
Michal Vasko131120a2018-05-29 15:44:02 +0200428 /* client RPC */
429 rpc = nc_rpc_commit(0, 0, NULL, NULL, 0);
430 assert_non_null(rpc);
431
432 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
433 assert_int_equal(msgtype, NC_MSG_RPC);
434
435 /* client subscription */
tadeas-vintrlik2e803db2021-08-25 12:12:07 +0200436 pthread_create(&tid[0], NULL, thread_recv_notif, client_session);
Michal Vasko131120a2018-05-29 15:44:02 +0200437
438 /* create server */
439 ps = nc_ps_new();
440 assert_non_null(ps);
441 nc_ps_add_session(ps, server_session);
442
443 /* server will send a notification */
Michal Vaskobbaa9b22019-03-14 12:35:43 +0100444 pthread_mutex_lock(&state_lock);
Michal Vasko131120a2018-05-29 15:44:02 +0200445 glob_state = 0;
Michal Vaskobbaa9b22019-03-14 12:35:43 +0100446 pthread_mutex_unlock(&state_lock);
tadeas-vintrlik2e803db2021-08-25 12:12:07 +0200447 ret = pthread_create(&tid[1], NULL, server_send_notif_thread, NULL);
Michal Vasko131120a2018-05-29 15:44:02 +0200448 assert_int_equal(ret, 0);
449
450 /* server blocked on RPC */
451 ret = nc_ps_poll(ps, 0, NULL);
452 assert_int_equal(ret, NC_PSPOLL_RPC);
453
454 /* RPC, notification finished fine */
Michal Vaskobbaa9b22019-03-14 12:35:43 +0100455 pthread_mutex_lock(&state_lock);
Michal Vasko131120a2018-05-29 15:44:02 +0200456 assert_int_equal(glob_state, 3);
Michal Vaskobbaa9b22019-03-14 12:35:43 +0100457 pthread_mutex_unlock(&state_lock);
Michal Vasko131120a2018-05-29 15:44:02 +0200458
459 /* server finished */
tadeas-vintrlik2e803db2021-08-25 12:12:07 +0200460 ret = 0;
461 ret |= pthread_join(tid[0], NULL);
462 ret |= pthread_join(tid[1], NULL);
Michal Vasko131120a2018-05-29 15:44:02 +0200463 assert_int_equal(ret, 0);
464 nc_ps_free(ps);
465
466 /* client reply */
Michal Vasko77367452021-02-16 16:32:18 +0100467 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, &envp, &op);
Michal Vasko131120a2018-05-29 15:44:02 +0200468 assert_int_equal(msgtype, NC_MSG_REPLY);
Michal Vasko131120a2018-05-29 15:44:02 +0200469 nc_rpc_free(rpc);
Michal Vasko77367452021-02-16 16:32:18 +0100470
471 assert_string_equal(LYD_NAME(lyd_child(envp)), "ok");
472 lyd_free_tree(envp);
473 assert_null(op);
Michal Vasko131120a2018-05-29 15:44:02 +0200474}
475
476static void
477test_send_recv_notif_10(void **state)
478{
479 (void)state;
480
481 server_session->version = NC_VERSION_10;
482 client_session->version = NC_VERSION_10;
483
484 test_send_recv_notif();
485}
486
487static void
488test_send_recv_notif_11(void **state)
489{
490 (void)state;
491
492 server_session->version = NC_VERSION_11;
493 client_session->version = NC_VERSION_11;
494
495 test_send_recv_notif();
496}
Michal Vasko294d4c62016-02-01 10:10:27 +0100497
Michal Vasko77e83572022-07-21 15:31:15 +0200498static void
499test_send_recv_malformed_10(void **state)
500{
501 int ret;
502 struct nc_pollsession *ps;
503 struct nc_rpc *rpc;
504 struct lyd_node *envp, *op, *node;
505 NC_MSG_TYPE msgtype;
506 const char *msg;
507
508 (void)state;
509
510 server_session->version = NC_VERSION_10;
511 client_session->version = NC_VERSION_10;
512
513 /* write malformed message */
514 msg =
515 "<nc:rpc xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
516 " <nc:commit/>"
517 "</nc:rpc>"
518 "]]>]]>";
519 assert_int_equal(write(client_session->ti.fd.out, msg, strlen(msg)), strlen(msg));
520 rpc = nc_rpc_commit(0, 0, NULL, NULL, 0);
521 assert_non_null(rpc);
522
523 /* server RPC, send reply */
524 ps = nc_ps_new();
525 assert_non_null(ps);
526 nc_ps_add_session(ps, server_session);
527
528 ret = nc_ps_poll(ps, 0, NULL);
529 assert_int_equal(ret, NC_PSPOLL_BAD_RPC);
530
531 /* server finished */
532 nc_ps_free(ps);
533
534 /* client reply */
535 msgtype = nc_recv_reply(client_session, rpc, 0, 0, &envp, &op);
536 assert_int_equal(msgtype, NC_MSG_REPLY_ERR_MSGID);
537
538 nc_rpc_free(rpc);
539 assert_string_equal(LYD_NAME(lyd_child(envp)), "rpc-error");
540 lyd_find_sibling_opaq_next(lyd_child(lyd_child(envp)), "error-tag", &node);
541 assert_non_null(node);
542 assert_string_equal(((struct lyd_node_opaq *)node)->value, "missing-attribute");
543 lyd_free_tree(envp);
544 assert_null(op);
545}
546
Michal Vasko294d4c62016-02-01 10:10:27 +0100547int
548main(void)
549{
Michal Vasko8c5518b2016-03-01 12:35:13 +0100550 int ret;
551 const struct lys_module *module;
Michal Vasko77367452021-02-16 16:32:18 +0100552 struct lysc_node *node;
553 const char *nc_features[] = {"candidate", NULL};
Michal Vasko8c5518b2016-03-01 12:35:13 +0100554
tadeas-vintrlik2e803db2021-08-25 12:12:07 +0200555 pthread_barrier_init(&barrier, NULL, 2);
556
Michal Vasko8c5518b2016-03-01 12:35:13 +0100557 /* create ctx */
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200558 ly_ctx_new(TESTS_DIR "/data/modules", 0, &ctx);
Michal Vasko8c5518b2016-03-01 12:35:13 +0100559 assert_non_null(ctx);
560
561 /* load modules */
Michal Vasko77367452021-02-16 16:32:18 +0100562 module = ly_ctx_load_module(ctx, "ietf-netconf-acm", NULL, NULL);
Michal Vasko8c5518b2016-03-01 12:35:13 +0100563 assert_non_null(module);
564
Michal Vasko77367452021-02-16 16:32:18 +0100565 module = ly_ctx_load_module(ctx, "ietf-netconf", NULL, nc_features);
Michal Vasko8c5518b2016-03-01 12:35:13 +0100566 assert_non_null(module);
Michal Vasko131120a2018-05-29 15:44:02 +0200567
Michal Vasko77367452021-02-16 16:32:18 +0100568 module = ly_ctx_load_module(ctx, "nc-notifications", NULL, NULL);
Michal Vasko131120a2018-05-29 15:44:02 +0200569 assert_non_null(module);
Michal Vasko8c5518b2016-03-01 12:35:13 +0100570
571 /* set RPC callbacks */
Michal Vasko77367452021-02-16 16:32:18 +0100572 node = (struct lysc_node *)lys_find_path(module->ctx, NULL, "/ietf-netconf:get", 0);
Michal Vasko88639e92017-08-03 14:38:10 +0200573 assert_non_null(node);
Michal Vasko77367452021-02-16 16:32:18 +0100574 node->priv = my_get_rpc_clb;
Michal Vasko88639e92017-08-03 14:38:10 +0200575
Michal Vasko77367452021-02-16 16:32:18 +0100576 node = (struct lysc_node *)lys_find_path(module->ctx, NULL, "/ietf-netconf:get-config", 0);
Michal Vasko88639e92017-08-03 14:38:10 +0200577 assert_non_null(node);
Michal Vasko77367452021-02-16 16:32:18 +0100578 node->priv = my_getconfig_rpc_clb;
Michal Vasko8c5518b2016-03-01 12:35:13 +0100579
Michal Vasko77367452021-02-16 16:32:18 +0100580 node = (struct lysc_node *)lys_find_path(module->ctx, NULL, "/ietf-netconf:commit", 0);
Michal Vasko131120a2018-05-29 15:44:02 +0200581 assert_non_null(node);
Michal Vasko77367452021-02-16 16:32:18 +0100582 node->priv = my_commit_rpc_clb;
Michal Vasko131120a2018-05-29 15:44:02 +0200583
Michal Vasko93224072021-11-09 12:14:28 +0100584 nc_server_init();
Michal Vasko8c5518b2016-03-01 12:35:13 +0100585
Michal Vasko294d4c62016-02-01 10:10:27 +0100586 const struct CMUnitTest comm[] = {
Michal Vasko58d152f2016-02-01 11:44:49 +0100587 cmocka_unit_test_setup_teardown(test_send_recv_ok_10, setup_sessions, teardown_sessions),
588 cmocka_unit_test_setup_teardown(test_send_recv_error_10, setup_sessions, teardown_sessions),
589 cmocka_unit_test_setup_teardown(test_send_recv_data_10, setup_sessions, teardown_sessions),
Michal Vasko131120a2018-05-29 15:44:02 +0200590 cmocka_unit_test_setup_teardown(test_send_recv_notif_10, setup_sessions, teardown_sessions),
Michal Vasko77e83572022-07-21 15:31:15 +0200591 cmocka_unit_test_setup_teardown(test_send_recv_malformed_10, setup_sessions, teardown_sessions),
Michal Vasko58d152f2016-02-01 11:44:49 +0100592 cmocka_unit_test_setup_teardown(test_send_recv_ok_11, setup_sessions, teardown_sessions),
593 cmocka_unit_test_setup_teardown(test_send_recv_error_11, setup_sessions, teardown_sessions),
Michal Vasko131120a2018-05-29 15:44:02 +0200594 cmocka_unit_test_setup_teardown(test_send_recv_data_11, setup_sessions, teardown_sessions),
595 cmocka_unit_test_setup_teardown(test_send_recv_notif_11, setup_sessions, teardown_sessions),
Michal Vasko294d4c62016-02-01 10:10:27 +0100596 };
597
Michal Vasko8c5518b2016-03-01 12:35:13 +0100598 ret = cmocka_run_group_tests(comm, NULL, NULL);
599
600 nc_server_destroy();
Michal Vasko1dcb7642021-04-14 15:28:23 +0200601 ly_ctx_destroy(ctx);
tadeas-vintrlik2e803db2021-08-25 12:12:07 +0200602 pthread_barrier_destroy(&barrier);
Michal Vasko8c5518b2016-03-01 12:35:13 +0100603
604 return ret;
Michal Vasko294d4c62016-02-01 10:10:27 +0100605}