blob: 67602b74cb5b81233a4adbeb5fed741cbc69b37c [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>
23#include <unistd.h>
24#include <string.h>
25#include <sys/stat.h>
26#include <sys/types.h>
27#include <sys/socket.h>
28
29#include <cmocka.h>
30#include <libyang/libyang.h>
31
32#include <session_client.h>
33#include <session_server.h>
34#include <session_p.h>
35#include <messages_p.h>
36#include "config.h"
37
38struct nc_session *server_session;
39struct nc_session *client_session;
Michal Vasko8c5518b2016-03-01 12:35:13 +010040struct ly_ctx *ctx;
Michal Vasko294d4c62016-02-01 10:10:27 +010041
42struct nc_server_reply *
43my_get_rpc_clb(struct lyd_node *rpc, struct nc_session *session)
44{
45 assert_string_equal(rpc->schema->name, "get");
46 assert_ptr_equal(session, server_session);
47
48 return nc_server_reply_ok();
49}
50
51struct nc_server_reply *
52my_getconfig_rpc_clb(struct lyd_node *rpc, struct nc_session *session)
53{
54 struct lyd_node *data;
Michal Vasko294d4c62016-02-01 10:10:27 +010055
56 assert_string_equal(rpc->schema->name, "get-config");
57 assert_ptr_equal(session, server_session);
58
Michal Vaskob2583f12016-05-12 11:40:23 +020059 data = lyd_new_path(NULL, session->ctx, "/ietf-netconf:get-config/data", NULL, LYD_PATH_OPT_OUTPUT);
Michal Vasko294d4c62016-02-01 10:10:27 +010060 assert_non_null(data);
61
62 return nc_server_reply_data(data, NC_PARAMTYPE_FREE);
63}
64
65static int
66setup_sessions(void **state)
67{
68 (void)state;
Michal Vasko294d4c62016-02-01 10:10:27 +010069 int sock[2];
70
Michal Vasko294d4c62016-02-01 10:10:27 +010071 /* create communication channel */
72 socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
73
Michal Vasko294d4c62016-02-01 10:10:27 +010074 /* create server session */
75 server_session = calloc(1, sizeof *server_session);
76 server_session->status = NC_STATUS_RUNNING;
77 server_session->side = NC_SERVER;
78 server_session->id = 1;
Michal Vasko294d4c62016-02-01 10:10:27 +010079 server_session->ti_type = NC_TI_FD;
80 server_session->ti_lock = malloc(sizeof *server_session->ti_lock);
81 pthread_mutex_init(server_session->ti_lock, NULL);
82 server_session->ti.fd.in = sock[0];
83 server_session->ti.fd.out = sock[0];
84 server_session->ctx = ctx;
85 server_session->flags = NC_SESSION_SHAREDCTX;
86
87 /* create client session */
88 client_session = calloc(1, sizeof *server_session);
89 client_session->status = NC_STATUS_RUNNING;
90 client_session->side = NC_CLIENT;
91 client_session->id = 1;
Michal Vasko294d4c62016-02-01 10:10:27 +010092 client_session->ti_type = NC_TI_FD;
93 client_session->ti_lock = malloc(sizeof *client_session->ti_lock);
94 pthread_mutex_init(client_session->ti_lock, NULL);
95 client_session->ti.fd.in = sock[1];
96 client_session->ti.fd.out = sock[1];
97 client_session->ctx = ctx;
98 client_session->flags = NC_SESSION_SHAREDCTX;
99 client_session->msgid = 50;
100
101 return 0;
102}
103
104static int
105teardown_sessions(void **state)
106{
107 (void)state;
108
Michal Vasko294d4c62016-02-01 10:10:27 +0100109 close(server_session->ti.fd.in);
110 pthread_mutex_destroy(server_session->ti_lock);
111 free(server_session->ti_lock);
112 free(server_session);
113
114 close(client_session->ti.fd.in);
115 pthread_mutex_destroy(client_session->ti_lock);
116 free(client_session->ti_lock);
117 free(client_session);
118
119 return 0;
120}
121
122static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100123test_send_recv_ok(void)
Michal Vasko294d4c62016-02-01 10:10:27 +0100124{
Michal Vasko294d4c62016-02-01 10:10:27 +0100125 int ret;
126 uint64_t msgid;
127 NC_MSG_TYPE msgtype;
128 struct nc_rpc *rpc;
129 struct nc_reply *reply;
130 struct nc_pollsession *ps;
131
132 /* client RPC */
133 rpc = nc_rpc_get(NULL, 0, 0);
134 assert_non_null(rpc);
135
136 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
137 assert_int_equal(msgtype, NC_MSG_RPC);
138
139 /* server RPC, send reply */
140 ps = nc_ps_new();
141 assert_non_null(ps);
142 nc_ps_add_session(ps, server_session);
143
144 ret = nc_ps_poll(ps, 0);
145 assert_int_equal(ret, 1);
146
147 /* server finished */
148 nc_ps_free(ps);
149
150 /* client reply */
Michal Vaskoeb7080e2016-02-18 13:27:05 +0100151 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, 0, &reply);
Michal Vasko294d4c62016-02-01 10:10:27 +0100152 assert_int_equal(msgtype, NC_MSG_REPLY);
153
154 nc_rpc_free(rpc);
155 assert_int_equal(reply->type, NC_RPL_OK);
156 nc_reply_free(reply);
157}
158
159static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100160test_send_recv_ok_10(void **state)
Michal Vasko294d4c62016-02-01 10:10:27 +0100161{
162 (void)state;
Michal Vasko58d152f2016-02-01 11:44:49 +0100163
164 server_session->version = NC_VERSION_10;
165 client_session->version = NC_VERSION_10;
166
167 test_send_recv_ok();
168}
169
170static void
171test_send_recv_ok_11(void **state)
172{
173 (void)state;
174
175 server_session->version = NC_VERSION_11;
176 client_session->version = NC_VERSION_11;
177
178 test_send_recv_ok();
179}
180
181static void
182test_send_recv_error(void)
183{
Michal Vasko294d4c62016-02-01 10:10:27 +0100184 int ret;
185 uint64_t msgid;
186 NC_MSG_TYPE msgtype;
187 struct nc_rpc *rpc;
188 struct nc_reply *reply;
189 struct nc_pollsession *ps;
190
191 /* client RPC */
192 rpc = nc_rpc_kill(1);
193 assert_non_null(rpc);
194
195 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
196 assert_int_equal(msgtype, NC_MSG_RPC);
197
198 /* server RPC, send reply */
199 ps = nc_ps_new();
200 assert_non_null(ps);
201 nc_ps_add_session(ps, server_session);
202
203 ret = nc_ps_poll(ps, 0);
204 assert_int_equal(ret, 1);
205
206 /* server finished */
207 nc_ps_free(ps);
208
209 /* client reply */
Michal Vaskoeb7080e2016-02-18 13:27:05 +0100210 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, 0, &reply);
Michal Vasko294d4c62016-02-01 10:10:27 +0100211 assert_int_equal(msgtype, NC_MSG_REPLY);
212
213 nc_rpc_free(rpc);
214 assert_int_equal(reply->type, NC_RPL_ERROR);
215 assert_string_equal(((struct nc_reply_error *)reply)->err->tag, "operation-not-supported");
216 nc_reply_free(reply);
217}
218
219static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100220test_send_recv_error_10(void **state)
Michal Vasko294d4c62016-02-01 10:10:27 +0100221{
222 (void)state;
Michal Vasko58d152f2016-02-01 11:44:49 +0100223
224 server_session->version = NC_VERSION_10;
225 client_session->version = NC_VERSION_10;
226
227 test_send_recv_error();
228}
229
230static void
231test_send_recv_error_11(void **state)
232{
233 (void)state;
234
235 server_session->version = NC_VERSION_11;
236 client_session->version = NC_VERSION_11;
237
238 test_send_recv_error();
239}
240
241static void
242test_send_recv_data(void)
243{
Michal Vasko294d4c62016-02-01 10:10:27 +0100244 int ret;
245 uint64_t msgid;
246 NC_MSG_TYPE msgtype;
247 struct nc_rpc *rpc;
248 struct nc_reply *reply;
249 struct nc_pollsession *ps;
250
251 /* client RPC */
252 rpc = nc_rpc_getconfig(NC_DATASTORE_RUNNING, NULL, 0, 0);
253 assert_non_null(rpc);
254
255 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
256 assert_int_equal(msgtype, NC_MSG_RPC);
257
258 /* server RPC, send reply */
259 ps = nc_ps_new();
260 assert_non_null(ps);
261 nc_ps_add_session(ps, server_session);
262
263 ret = nc_ps_poll(ps, 0);
264 assert_int_equal(ret, 1);
265
266 /* server finished */
267 nc_ps_free(ps);
268
269 /* client reply */
Michal Vaskodc3c4e12016-03-29 15:40:35 +0200270 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, LYD_OPT_KEEPEMPTYCONT, &reply);
Michal Vasko294d4c62016-02-01 10:10:27 +0100271 assert_int_equal(msgtype, NC_MSG_REPLY);
272
273 nc_rpc_free(rpc);
274 assert_int_equal(reply->type, NC_RPL_DATA);
275 nc_reply_free(reply);
276}
277
Michal Vasko58d152f2016-02-01 11:44:49 +0100278static void
279test_send_recv_data_10(void **state)
280{
281 (void)state;
282
283 server_session->version = NC_VERSION_10;
284 client_session->version = NC_VERSION_10;
285
286 test_send_recv_data();
287}
288
289static void
290test_send_recv_data_11(void **state)
291{
292 (void)state;
293
294 server_session->version = NC_VERSION_11;
295 client_session->version = NC_VERSION_11;
296
297 test_send_recv_data();
298}
299
Michal Vasko294d4c62016-02-01 10:10:27 +0100300/* TODO
301static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100302test_send_recv_notif(void)
Michal Vasko294d4c62016-02-01 10:10:27 +0100303{
304
305}*/
306
307int
308main(void)
309{
Michal Vasko8c5518b2016-03-01 12:35:13 +0100310 int ret;
311 const struct lys_module *module;
312 const struct lys_node *node;
313
314 /* create ctx */
315 ctx = ly_ctx_new(TESTS_DIR"../schemas");
316 assert_non_null(ctx);
317
318 /* load modules */
319 module = ly_ctx_load_module(ctx, "ietf-netconf-acm", NULL);
320 assert_non_null(module);
321
322 module = ly_ctx_load_module(ctx, "ietf-netconf", NULL);
323 assert_non_null(module);
324
325 /* set RPC callbacks */
Michal Vasko303245c2016-03-24 15:20:03 +0100326 node = ly_ctx_get_node(module->ctx, NULL, "/ietf-netconf:get");
Michal Vasko8c5518b2016-03-01 12:35:13 +0100327 assert_non_null(node);
328 lys_set_private(node, my_get_rpc_clb);
329
Michal Vasko303245c2016-03-24 15:20:03 +0100330 node = ly_ctx_get_node(module->ctx, NULL, "/ietf-netconf:get-config");
Michal Vasko8c5518b2016-03-01 12:35:13 +0100331 assert_non_null(node);
332 lys_set_private(node, my_getconfig_rpc_clb);
333
334 nc_server_init(ctx);
335
Michal Vasko294d4c62016-02-01 10:10:27 +0100336 const struct CMUnitTest comm[] = {
Michal Vasko58d152f2016-02-01 11:44:49 +0100337 cmocka_unit_test_setup_teardown(test_send_recv_ok_10, setup_sessions, teardown_sessions),
338 cmocka_unit_test_setup_teardown(test_send_recv_error_10, setup_sessions, teardown_sessions),
339 cmocka_unit_test_setup_teardown(test_send_recv_data_10, setup_sessions, teardown_sessions),
340 cmocka_unit_test_setup_teardown(test_send_recv_ok_11, setup_sessions, teardown_sessions),
341 cmocka_unit_test_setup_teardown(test_send_recv_error_11, setup_sessions, teardown_sessions),
342 cmocka_unit_test_setup_teardown(test_send_recv_data_11, setup_sessions, teardown_sessions)
Michal Vasko294d4c62016-02-01 10:10:27 +0100343 };
344
Michal Vasko8c5518b2016-03-01 12:35:13 +0100345 ret = cmocka_run_group_tests(comm, NULL, NULL);
346
347 nc_server_destroy();
348 ly_ctx_destroy(ctx, NULL);
349
350 return ret;
Michal Vasko294d4c62016-02-01 10:10:27 +0100351}