blob: 493971c5e3650f23f02e780aa7803e1b7f621fa6 [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;
55 const struct lys_module *module;
56
57 assert_string_equal(rpc->schema->name, "get-config");
58 assert_ptr_equal(session, server_session);
59
60 module = ly_ctx_get_module(session->ctx, "ietf-netconf-acm", NULL);
61 assert_non_null(module);
62
63 data = lyd_new(NULL, module, "nacm");
64 assert_non_null(data);
65
66 return nc_server_reply_data(data, NC_PARAMTYPE_FREE);
67}
68
69static int
70setup_sessions(void **state)
71{
72 (void)state;
Michal Vasko294d4c62016-02-01 10:10:27 +010073 int sock[2];
74
Michal Vasko294d4c62016-02-01 10:10:27 +010075 /* create communication channel */
76 socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
77
Michal Vasko294d4c62016-02-01 10:10:27 +010078 /* create server session */
79 server_session = calloc(1, sizeof *server_session);
80 server_session->status = NC_STATUS_RUNNING;
81 server_session->side = NC_SERVER;
82 server_session->id = 1;
Michal Vasko294d4c62016-02-01 10:10:27 +010083 server_session->ti_type = NC_TI_FD;
84 server_session->ti_lock = malloc(sizeof *server_session->ti_lock);
85 pthread_mutex_init(server_session->ti_lock, NULL);
86 server_session->ti.fd.in = sock[0];
87 server_session->ti.fd.out = sock[0];
88 server_session->ctx = ctx;
89 server_session->flags = NC_SESSION_SHAREDCTX;
90
91 /* create client session */
92 client_session = calloc(1, sizeof *server_session);
93 client_session->status = NC_STATUS_RUNNING;
94 client_session->side = NC_CLIENT;
95 client_session->id = 1;
Michal Vasko294d4c62016-02-01 10:10:27 +010096 client_session->ti_type = NC_TI_FD;
97 client_session->ti_lock = malloc(sizeof *client_session->ti_lock);
98 pthread_mutex_init(client_session->ti_lock, NULL);
99 client_session->ti.fd.in = sock[1];
100 client_session->ti.fd.out = sock[1];
101 client_session->ctx = ctx;
102 client_session->flags = NC_SESSION_SHAREDCTX;
103 client_session->msgid = 50;
104
105 return 0;
106}
107
108static int
109teardown_sessions(void **state)
110{
111 (void)state;
112
Michal Vasko294d4c62016-02-01 10:10:27 +0100113 close(server_session->ti.fd.in);
114 pthread_mutex_destroy(server_session->ti_lock);
115 free(server_session->ti_lock);
116 free(server_session);
117
118 close(client_session->ti.fd.in);
119 pthread_mutex_destroy(client_session->ti_lock);
120 free(client_session->ti_lock);
121 free(client_session);
122
123 return 0;
124}
125
126static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100127test_send_recv_ok(void)
Michal Vasko294d4c62016-02-01 10:10:27 +0100128{
Michal Vasko294d4c62016-02-01 10:10:27 +0100129 int ret;
130 uint64_t msgid;
131 NC_MSG_TYPE msgtype;
132 struct nc_rpc *rpc;
133 struct nc_reply *reply;
134 struct nc_pollsession *ps;
135
136 /* client RPC */
137 rpc = nc_rpc_get(NULL, 0, 0);
138 assert_non_null(rpc);
139
140 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
141 assert_int_equal(msgtype, NC_MSG_RPC);
142
143 /* server RPC, send reply */
144 ps = nc_ps_new();
145 assert_non_null(ps);
146 nc_ps_add_session(ps, server_session);
147
148 ret = nc_ps_poll(ps, 0);
149 assert_int_equal(ret, 1);
150
151 /* server finished */
152 nc_ps_free(ps);
153
154 /* client reply */
Michal Vaskoeb7080e2016-02-18 13:27:05 +0100155 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, 0, &reply);
Michal Vasko294d4c62016-02-01 10:10:27 +0100156 assert_int_equal(msgtype, NC_MSG_REPLY);
157
158 nc_rpc_free(rpc);
159 assert_int_equal(reply->type, NC_RPL_OK);
160 nc_reply_free(reply);
161}
162
163static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100164test_send_recv_ok_10(void **state)
Michal Vasko294d4c62016-02-01 10:10:27 +0100165{
166 (void)state;
Michal Vasko58d152f2016-02-01 11:44:49 +0100167
168 server_session->version = NC_VERSION_10;
169 client_session->version = NC_VERSION_10;
170
171 test_send_recv_ok();
172}
173
174static void
175test_send_recv_ok_11(void **state)
176{
177 (void)state;
178
179 server_session->version = NC_VERSION_11;
180 client_session->version = NC_VERSION_11;
181
182 test_send_recv_ok();
183}
184
185static void
186test_send_recv_error(void)
187{
Michal Vasko294d4c62016-02-01 10:10:27 +0100188 int ret;
189 uint64_t msgid;
190 NC_MSG_TYPE msgtype;
191 struct nc_rpc *rpc;
192 struct nc_reply *reply;
193 struct nc_pollsession *ps;
194
195 /* client RPC */
196 rpc = nc_rpc_kill(1);
197 assert_non_null(rpc);
198
199 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
200 assert_int_equal(msgtype, NC_MSG_RPC);
201
202 /* server RPC, send reply */
203 ps = nc_ps_new();
204 assert_non_null(ps);
205 nc_ps_add_session(ps, server_session);
206
207 ret = nc_ps_poll(ps, 0);
208 assert_int_equal(ret, 1);
209
210 /* server finished */
211 nc_ps_free(ps);
212
213 /* client reply */
Michal Vaskoeb7080e2016-02-18 13:27:05 +0100214 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, 0, &reply);
Michal Vasko294d4c62016-02-01 10:10:27 +0100215 assert_int_equal(msgtype, NC_MSG_REPLY);
216
217 nc_rpc_free(rpc);
218 assert_int_equal(reply->type, NC_RPL_ERROR);
219 assert_string_equal(((struct nc_reply_error *)reply)->err->tag, "operation-not-supported");
220 nc_reply_free(reply);
221}
222
223static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100224test_send_recv_error_10(void **state)
Michal Vasko294d4c62016-02-01 10:10:27 +0100225{
226 (void)state;
Michal Vasko58d152f2016-02-01 11:44:49 +0100227
228 server_session->version = NC_VERSION_10;
229 client_session->version = NC_VERSION_10;
230
231 test_send_recv_error();
232}
233
234static void
235test_send_recv_error_11(void **state)
236{
237 (void)state;
238
239 server_session->version = NC_VERSION_11;
240 client_session->version = NC_VERSION_11;
241
242 test_send_recv_error();
243}
244
245static void
246test_send_recv_data(void)
247{
Michal Vasko294d4c62016-02-01 10:10:27 +0100248 int ret;
249 uint64_t msgid;
250 NC_MSG_TYPE msgtype;
251 struct nc_rpc *rpc;
252 struct nc_reply *reply;
253 struct nc_pollsession *ps;
254
255 /* client RPC */
256 rpc = nc_rpc_getconfig(NC_DATASTORE_RUNNING, NULL, 0, 0);
257 assert_non_null(rpc);
258
259 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
260 assert_int_equal(msgtype, NC_MSG_RPC);
261
262 /* server RPC, send reply */
263 ps = nc_ps_new();
264 assert_non_null(ps);
265 nc_ps_add_session(ps, server_session);
266
267 ret = nc_ps_poll(ps, 0);
268 assert_int_equal(ret, 1);
269
270 /* server finished */
271 nc_ps_free(ps);
272
273 /* client reply */
Michal Vaskodc3c4e12016-03-29 15:40:35 +0200274 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, LYD_OPT_KEEPEMPTYCONT, &reply);
Michal Vasko294d4c62016-02-01 10:10:27 +0100275 assert_int_equal(msgtype, NC_MSG_REPLY);
276
277 nc_rpc_free(rpc);
278 assert_int_equal(reply->type, NC_RPL_DATA);
279 nc_reply_free(reply);
280}
281
Michal Vasko58d152f2016-02-01 11:44:49 +0100282static void
283test_send_recv_data_10(void **state)
284{
285 (void)state;
286
287 server_session->version = NC_VERSION_10;
288 client_session->version = NC_VERSION_10;
289
290 test_send_recv_data();
291}
292
293static void
294test_send_recv_data_11(void **state)
295{
296 (void)state;
297
298 server_session->version = NC_VERSION_11;
299 client_session->version = NC_VERSION_11;
300
301 test_send_recv_data();
302}
303
Michal Vasko294d4c62016-02-01 10:10:27 +0100304/* TODO
305static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100306test_send_recv_notif(void)
Michal Vasko294d4c62016-02-01 10:10:27 +0100307{
308
309}*/
310
311int
312main(void)
313{
Michal Vasko8c5518b2016-03-01 12:35:13 +0100314 int ret;
315 const struct lys_module *module;
316 const struct lys_node *node;
317
318 /* create ctx */
319 ctx = ly_ctx_new(TESTS_DIR"../schemas");
320 assert_non_null(ctx);
321
322 /* load modules */
323 module = ly_ctx_load_module(ctx, "ietf-netconf-acm", NULL);
324 assert_non_null(module);
325
326 module = ly_ctx_load_module(ctx, "ietf-netconf", NULL);
327 assert_non_null(module);
328
329 /* set RPC callbacks */
Michal Vasko303245c2016-03-24 15:20:03 +0100330 node = ly_ctx_get_node(module->ctx, NULL, "/ietf-netconf:get");
Michal Vasko8c5518b2016-03-01 12:35:13 +0100331 assert_non_null(node);
332 lys_set_private(node, my_get_rpc_clb);
333
Michal Vasko303245c2016-03-24 15:20:03 +0100334 node = ly_ctx_get_node(module->ctx, NULL, "/ietf-netconf:get-config");
Michal Vasko8c5518b2016-03-01 12:35:13 +0100335 assert_non_null(node);
336 lys_set_private(node, my_getconfig_rpc_clb);
337
338 nc_server_init(ctx);
339
Michal Vasko294d4c62016-02-01 10:10:27 +0100340 const struct CMUnitTest comm[] = {
Michal Vasko58d152f2016-02-01 11:44:49 +0100341 cmocka_unit_test_setup_teardown(test_send_recv_ok_10, setup_sessions, teardown_sessions),
342 cmocka_unit_test_setup_teardown(test_send_recv_error_10, setup_sessions, teardown_sessions),
343 cmocka_unit_test_setup_teardown(test_send_recv_data_10, setup_sessions, teardown_sessions),
344 cmocka_unit_test_setup_teardown(test_send_recv_ok_11, setup_sessions, teardown_sessions),
345 cmocka_unit_test_setup_teardown(test_send_recv_error_11, setup_sessions, teardown_sessions),
346 cmocka_unit_test_setup_teardown(test_send_recv_data_11, setup_sessions, teardown_sessions)
Michal Vasko294d4c62016-02-01 10:10:27 +0100347 };
348
Michal Vasko8c5518b2016-03-01 12:35:13 +0100349 ret = cmocka_run_group_tests(comm, NULL, NULL);
350
351 nc_server_destroy();
352 ly_ctx_destroy(ctx, NULL);
353
354 return ret;
Michal Vasko294d4c62016-02-01 10:10:27 +0100355}