blob: 79a1fb8f7a51aa64b5b428d62c6e05c5d0737131 [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
11 *
12 * 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;
40
41struct nc_server_reply *
42my_get_rpc_clb(struct lyd_node *rpc, struct nc_session *session)
43{
44 assert_string_equal(rpc->schema->name, "get");
45 assert_ptr_equal(session, server_session);
46
47 return nc_server_reply_ok();
48}
49
50struct nc_server_reply *
51my_getconfig_rpc_clb(struct lyd_node *rpc, struct nc_session *session)
52{
53 struct lyd_node *data;
54 const struct lys_module *module;
55
56 assert_string_equal(rpc->schema->name, "get-config");
57 assert_ptr_equal(session, server_session);
58
59 module = ly_ctx_get_module(session->ctx, "ietf-netconf-acm", NULL);
60 assert_non_null(module);
61
62 data = lyd_new(NULL, module, "nacm");
63 assert_non_null(data);
64
65 return nc_server_reply_data(data, NC_PARAMTYPE_FREE);
66}
67
68static int
69setup_sessions(void **state)
70{
71 (void)state;
72 struct ly_ctx *ctx;
73 const struct lys_module *module;
74 const struct lys_node *node;
75 int sock[2];
76
77 /* create ctx */
78 ctx = ly_ctx_new(TESTS_DIR"../schemas");
79 assert_non_null(ctx);
80
81 /* load modules */
82 module = ly_ctx_load_module(ctx, "ietf-netconf-acm", NULL);
83 assert_non_null(module);
84
85 module = ly_ctx_load_module(ctx, "ietf-netconf", NULL);
86 assert_non_null(module);
87
88 /* set RPC callbacks */
Michal Vaskofea54dc2016-02-17 13:12:16 +010089 node = ly_ctx_get_node(module->ctx, "/ietf-netconf:get");
Michal Vasko294d4c62016-02-01 10:10:27 +010090 assert_non_null(node);
91 lys_set_private(node, my_get_rpc_clb);
92
Michal Vaskofea54dc2016-02-17 13:12:16 +010093 node = ly_ctx_get_node(module->ctx, "/ietf-netconf:get-config");
Michal Vasko294d4c62016-02-01 10:10:27 +010094 assert_non_null(node);
95 lys_set_private(node, my_getconfig_rpc_clb);
96
97 /* create communication channel */
98 socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
99
100 nc_server_init(ctx);
101
102 /* create server session */
103 server_session = calloc(1, sizeof *server_session);
104 server_session->status = NC_STATUS_RUNNING;
105 server_session->side = NC_SERVER;
106 server_session->id = 1;
Michal Vasko294d4c62016-02-01 10:10:27 +0100107 server_session->ti_type = NC_TI_FD;
108 server_session->ti_lock = malloc(sizeof *server_session->ti_lock);
109 pthread_mutex_init(server_session->ti_lock, NULL);
110 server_session->ti.fd.in = sock[0];
111 server_session->ti.fd.out = sock[0];
112 server_session->ctx = ctx;
113 server_session->flags = NC_SESSION_SHAREDCTX;
114
115 /* create client session */
116 client_session = calloc(1, sizeof *server_session);
117 client_session->status = NC_STATUS_RUNNING;
118 client_session->side = NC_CLIENT;
119 client_session->id = 1;
Michal Vasko294d4c62016-02-01 10:10:27 +0100120 client_session->ti_type = NC_TI_FD;
121 client_session->ti_lock = malloc(sizeof *client_session->ti_lock);
122 pthread_mutex_init(client_session->ti_lock, NULL);
123 client_session->ti.fd.in = sock[1];
124 client_session->ti.fd.out = sock[1];
125 client_session->ctx = ctx;
126 client_session->flags = NC_SESSION_SHAREDCTX;
127 client_session->msgid = 50;
128
129 return 0;
130}
131
132static int
133teardown_sessions(void **state)
134{
135 (void)state;
136
137 nc_server_destroy();
138
Radek Krejci4ba285b2016-02-04 17:34:06 +0100139 ly_ctx_destroy(server_session->ctx, NULL);
Michal Vasko294d4c62016-02-01 10:10:27 +0100140
141 close(server_session->ti.fd.in);
142 pthread_mutex_destroy(server_session->ti_lock);
143 free(server_session->ti_lock);
144 free(server_session);
145
146 close(client_session->ti.fd.in);
147 pthread_mutex_destroy(client_session->ti_lock);
148 free(client_session->ti_lock);
149 free(client_session);
150
151 return 0;
152}
153
154static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100155test_send_recv_ok(void)
Michal Vasko294d4c62016-02-01 10:10:27 +0100156{
Michal Vasko294d4c62016-02-01 10:10:27 +0100157 int ret;
158 uint64_t msgid;
159 NC_MSG_TYPE msgtype;
160 struct nc_rpc *rpc;
161 struct nc_reply *reply;
162 struct nc_pollsession *ps;
163
164 /* client RPC */
165 rpc = nc_rpc_get(NULL, 0, 0);
166 assert_non_null(rpc);
167
168 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
169 assert_int_equal(msgtype, NC_MSG_RPC);
170
171 /* server RPC, send reply */
172 ps = nc_ps_new();
173 assert_non_null(ps);
174 nc_ps_add_session(ps, server_session);
175
176 ret = nc_ps_poll(ps, 0);
177 assert_int_equal(ret, 1);
178
179 /* server finished */
180 nc_ps_free(ps);
181
182 /* client reply */
Michal Vaskoeb7080e2016-02-18 13:27:05 +0100183 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, 0, &reply);
Michal Vasko294d4c62016-02-01 10:10:27 +0100184 assert_int_equal(msgtype, NC_MSG_REPLY);
185
186 nc_rpc_free(rpc);
187 assert_int_equal(reply->type, NC_RPL_OK);
188 nc_reply_free(reply);
189}
190
191static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100192test_send_recv_ok_10(void **state)
Michal Vasko294d4c62016-02-01 10:10:27 +0100193{
194 (void)state;
Michal Vasko58d152f2016-02-01 11:44:49 +0100195
196 server_session->version = NC_VERSION_10;
197 client_session->version = NC_VERSION_10;
198
199 test_send_recv_ok();
200}
201
202static void
203test_send_recv_ok_11(void **state)
204{
205 (void)state;
206
207 server_session->version = NC_VERSION_11;
208 client_session->version = NC_VERSION_11;
209
210 test_send_recv_ok();
211}
212
213static void
214test_send_recv_error(void)
215{
Michal Vasko294d4c62016-02-01 10:10:27 +0100216 int ret;
217 uint64_t msgid;
218 NC_MSG_TYPE msgtype;
219 struct nc_rpc *rpc;
220 struct nc_reply *reply;
221 struct nc_pollsession *ps;
222
223 /* client RPC */
224 rpc = nc_rpc_kill(1);
225 assert_non_null(rpc);
226
227 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
228 assert_int_equal(msgtype, NC_MSG_RPC);
229
230 /* server RPC, send reply */
231 ps = nc_ps_new();
232 assert_non_null(ps);
233 nc_ps_add_session(ps, server_session);
234
235 ret = nc_ps_poll(ps, 0);
236 assert_int_equal(ret, 1);
237
238 /* server finished */
239 nc_ps_free(ps);
240
241 /* client reply */
Michal Vaskoeb7080e2016-02-18 13:27:05 +0100242 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, 0, &reply);
Michal Vasko294d4c62016-02-01 10:10:27 +0100243 assert_int_equal(msgtype, NC_MSG_REPLY);
244
245 nc_rpc_free(rpc);
246 assert_int_equal(reply->type, NC_RPL_ERROR);
247 assert_string_equal(((struct nc_reply_error *)reply)->err->tag, "operation-not-supported");
248 nc_reply_free(reply);
249}
250
251static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100252test_send_recv_error_10(void **state)
Michal Vasko294d4c62016-02-01 10:10:27 +0100253{
254 (void)state;
Michal Vasko58d152f2016-02-01 11:44:49 +0100255
256 server_session->version = NC_VERSION_10;
257 client_session->version = NC_VERSION_10;
258
259 test_send_recv_error();
260}
261
262static void
263test_send_recv_error_11(void **state)
264{
265 (void)state;
266
267 server_session->version = NC_VERSION_11;
268 client_session->version = NC_VERSION_11;
269
270 test_send_recv_error();
271}
272
273static void
274test_send_recv_data(void)
275{
Michal Vasko294d4c62016-02-01 10:10:27 +0100276 int ret;
277 uint64_t msgid;
278 NC_MSG_TYPE msgtype;
279 struct nc_rpc *rpc;
280 struct nc_reply *reply;
281 struct nc_pollsession *ps;
282
283 /* client RPC */
284 rpc = nc_rpc_getconfig(NC_DATASTORE_RUNNING, NULL, 0, 0);
285 assert_non_null(rpc);
286
287 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
288 assert_int_equal(msgtype, NC_MSG_RPC);
289
290 /* server RPC, send reply */
291 ps = nc_ps_new();
292 assert_non_null(ps);
293 nc_ps_add_session(ps, server_session);
294
295 ret = nc_ps_poll(ps, 0);
296 assert_int_equal(ret, 1);
297
298 /* server finished */
299 nc_ps_free(ps);
300
301 /* client reply */
Michal Vaskoeb7080e2016-02-18 13:27:05 +0100302 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, 0, &reply);
Michal Vasko294d4c62016-02-01 10:10:27 +0100303 assert_int_equal(msgtype, NC_MSG_REPLY);
304
305 nc_rpc_free(rpc);
306 assert_int_equal(reply->type, NC_RPL_DATA);
307 nc_reply_free(reply);
308}
309
Michal Vasko58d152f2016-02-01 11:44:49 +0100310static void
311test_send_recv_data_10(void **state)
312{
313 (void)state;
314
315 server_session->version = NC_VERSION_10;
316 client_session->version = NC_VERSION_10;
317
318 test_send_recv_data();
319}
320
321static void
322test_send_recv_data_11(void **state)
323{
324 (void)state;
325
326 server_session->version = NC_VERSION_11;
327 client_session->version = NC_VERSION_11;
328
329 test_send_recv_data();
330}
331
Michal Vasko294d4c62016-02-01 10:10:27 +0100332/* TODO
333static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100334test_send_recv_notif(void)
Michal Vasko294d4c62016-02-01 10:10:27 +0100335{
336
337}*/
338
339int
340main(void)
341{
342 const struct CMUnitTest comm[] = {
Michal Vasko58d152f2016-02-01 11:44:49 +0100343 cmocka_unit_test_setup_teardown(test_send_recv_ok_10, setup_sessions, teardown_sessions),
344 cmocka_unit_test_setup_teardown(test_send_recv_error_10, setup_sessions, teardown_sessions),
345 cmocka_unit_test_setup_teardown(test_send_recv_data_10, setup_sessions, teardown_sessions),
346 cmocka_unit_test_setup_teardown(test_send_recv_ok_11, setup_sessions, teardown_sessions),
347 cmocka_unit_test_setup_teardown(test_send_recv_error_11, setup_sessions, teardown_sessions),
348 cmocka_unit_test_setup_teardown(test_send_recv_data_11, setup_sessions, teardown_sessions)
Michal Vasko294d4c62016-02-01 10:10:27 +0100349 };
350
351 return cmocka_run_group_tests(comm, NULL, NULL);
352}