blob: fe5bcf92a551045c96e4ac22b00e6809d01d635b [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 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of the Company nor the names of its contributors
18 * may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 */
22
23#include <errno.h>
24#include <fcntl.h>
25#include <pthread.h>
26#include <setjmp.h>
27#include <stdarg.h>
28#include <stddef.h>
29#include <stdint.h>
30#include <stdlib.h>
31#include <unistd.h>
32#include <string.h>
33#include <sys/stat.h>
34#include <sys/types.h>
35#include <sys/socket.h>
36
37#include <cmocka.h>
38#include <libyang/libyang.h>
39
40#include <session_client.h>
41#include <session_server.h>
42#include <session_p.h>
43#include <messages_p.h>
44#include "config.h"
45
46struct nc_session *server_session;
47struct nc_session *client_session;
48
49struct nc_server_reply *
50my_get_rpc_clb(struct lyd_node *rpc, struct nc_session *session)
51{
52 assert_string_equal(rpc->schema->name, "get");
53 assert_ptr_equal(session, server_session);
54
55 return nc_server_reply_ok();
56}
57
58struct nc_server_reply *
59my_getconfig_rpc_clb(struct lyd_node *rpc, struct nc_session *session)
60{
61 struct lyd_node *data;
62 const struct lys_module *module;
63
64 assert_string_equal(rpc->schema->name, "get-config");
65 assert_ptr_equal(session, server_session);
66
67 module = ly_ctx_get_module(session->ctx, "ietf-netconf-acm", NULL);
68 assert_non_null(module);
69
70 data = lyd_new(NULL, module, "nacm");
71 assert_non_null(data);
72
73 return nc_server_reply_data(data, NC_PARAMTYPE_FREE);
74}
75
76static int
77setup_sessions(void **state)
78{
79 (void)state;
80 struct ly_ctx *ctx;
81 const struct lys_module *module;
82 const struct lys_node *node;
83 int sock[2];
84
85 /* create ctx */
86 ctx = ly_ctx_new(TESTS_DIR"../schemas");
87 assert_non_null(ctx);
88
89 /* load modules */
90 module = ly_ctx_load_module(ctx, "ietf-netconf-acm", NULL);
91 assert_non_null(module);
92
93 module = ly_ctx_load_module(ctx, "ietf-netconf", NULL);
94 assert_non_null(module);
95
96 /* set RPC callbacks */
97 node = lys_get_node(module, "/get");
98 assert_non_null(node);
99 lys_set_private(node, my_get_rpc_clb);
100
101 node = lys_get_node(module, "/get-config");
102 assert_non_null(node);
103 lys_set_private(node, my_getconfig_rpc_clb);
104
105 /* create communication channel */
106 socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
107
108 nc_server_init(ctx);
109
110 /* create server session */
111 server_session = calloc(1, sizeof *server_session);
112 server_session->status = NC_STATUS_RUNNING;
113 server_session->side = NC_SERVER;
114 server_session->id = 1;
Michal Vasko294d4c62016-02-01 10:10:27 +0100115 server_session->ti_type = NC_TI_FD;
116 server_session->ti_lock = malloc(sizeof *server_session->ti_lock);
117 pthread_mutex_init(server_session->ti_lock, NULL);
118 server_session->ti.fd.in = sock[0];
119 server_session->ti.fd.out = sock[0];
120 server_session->ctx = ctx;
121 server_session->flags = NC_SESSION_SHAREDCTX;
122
123 /* create client session */
124 client_session = calloc(1, sizeof *server_session);
125 client_session->status = NC_STATUS_RUNNING;
126 client_session->side = NC_CLIENT;
127 client_session->id = 1;
Michal Vasko294d4c62016-02-01 10:10:27 +0100128 client_session->ti_type = NC_TI_FD;
129 client_session->ti_lock = malloc(sizeof *client_session->ti_lock);
130 pthread_mutex_init(client_session->ti_lock, NULL);
131 client_session->ti.fd.in = sock[1];
132 client_session->ti.fd.out = sock[1];
133 client_session->ctx = ctx;
134 client_session->flags = NC_SESSION_SHAREDCTX;
135 client_session->msgid = 50;
136
137 return 0;
138}
139
140static int
141teardown_sessions(void **state)
142{
143 (void)state;
144
145 nc_server_destroy();
146
147 ly_ctx_destroy(server_session->ctx);
148
149 close(server_session->ti.fd.in);
150 pthread_mutex_destroy(server_session->ti_lock);
151 free(server_session->ti_lock);
152 free(server_session);
153
154 close(client_session->ti.fd.in);
155 pthread_mutex_destroy(client_session->ti_lock);
156 free(client_session->ti_lock);
157 free(client_session);
158
159 return 0;
160}
161
162static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100163test_send_recv_ok(void)
Michal Vasko294d4c62016-02-01 10:10:27 +0100164{
Michal Vasko294d4c62016-02-01 10:10:27 +0100165 int ret;
166 uint64_t msgid;
167 NC_MSG_TYPE msgtype;
168 struct nc_rpc *rpc;
169 struct nc_reply *reply;
170 struct nc_pollsession *ps;
171
172 /* client RPC */
173 rpc = nc_rpc_get(NULL, 0, 0);
174 assert_non_null(rpc);
175
176 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
177 assert_int_equal(msgtype, NC_MSG_RPC);
178
179 /* server RPC, send reply */
180 ps = nc_ps_new();
181 assert_non_null(ps);
182 nc_ps_add_session(ps, server_session);
183
184 ret = nc_ps_poll(ps, 0);
185 assert_int_equal(ret, 1);
186
187 /* server finished */
188 nc_ps_free(ps);
189
190 /* client reply */
191 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, &reply);
192 assert_int_equal(msgtype, NC_MSG_REPLY);
193
194 nc_rpc_free(rpc);
195 assert_int_equal(reply->type, NC_RPL_OK);
196 nc_reply_free(reply);
197}
198
199static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100200test_send_recv_ok_10(void **state)
Michal Vasko294d4c62016-02-01 10:10:27 +0100201{
202 (void)state;
Michal Vasko58d152f2016-02-01 11:44:49 +0100203
204 server_session->version = NC_VERSION_10;
205 client_session->version = NC_VERSION_10;
206
207 test_send_recv_ok();
208}
209
210static void
211test_send_recv_ok_11(void **state)
212{
213 (void)state;
214
215 server_session->version = NC_VERSION_11;
216 client_session->version = NC_VERSION_11;
217
218 test_send_recv_ok();
219}
220
221static void
222test_send_recv_error(void)
223{
Michal Vasko294d4c62016-02-01 10:10:27 +0100224 int ret;
225 uint64_t msgid;
226 NC_MSG_TYPE msgtype;
227 struct nc_rpc *rpc;
228 struct nc_reply *reply;
229 struct nc_pollsession *ps;
230
231 /* client RPC */
232 rpc = nc_rpc_kill(1);
233 assert_non_null(rpc);
234
235 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
236 assert_int_equal(msgtype, NC_MSG_RPC);
237
238 /* server RPC, send reply */
239 ps = nc_ps_new();
240 assert_non_null(ps);
241 nc_ps_add_session(ps, server_session);
242
243 ret = nc_ps_poll(ps, 0);
244 assert_int_equal(ret, 1);
245
246 /* server finished */
247 nc_ps_free(ps);
248
249 /* client reply */
250 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, &reply);
251 assert_int_equal(msgtype, NC_MSG_REPLY);
252
253 nc_rpc_free(rpc);
254 assert_int_equal(reply->type, NC_RPL_ERROR);
255 assert_string_equal(((struct nc_reply_error *)reply)->err->tag, "operation-not-supported");
256 nc_reply_free(reply);
257}
258
259static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100260test_send_recv_error_10(void **state)
Michal Vasko294d4c62016-02-01 10:10:27 +0100261{
262 (void)state;
Michal Vasko58d152f2016-02-01 11:44:49 +0100263
264 server_session->version = NC_VERSION_10;
265 client_session->version = NC_VERSION_10;
266
267 test_send_recv_error();
268}
269
270static void
271test_send_recv_error_11(void **state)
272{
273 (void)state;
274
275 server_session->version = NC_VERSION_11;
276 client_session->version = NC_VERSION_11;
277
278 test_send_recv_error();
279}
280
281static void
282test_send_recv_data(void)
283{
Michal Vasko294d4c62016-02-01 10:10:27 +0100284 int ret;
285 uint64_t msgid;
286 NC_MSG_TYPE msgtype;
287 struct nc_rpc *rpc;
288 struct nc_reply *reply;
289 struct nc_pollsession *ps;
290
291 /* client RPC */
292 rpc = nc_rpc_getconfig(NC_DATASTORE_RUNNING, NULL, 0, 0);
293 assert_non_null(rpc);
294
295 msgtype = nc_send_rpc(client_session, rpc, 0, &msgid);
296 assert_int_equal(msgtype, NC_MSG_RPC);
297
298 /* server RPC, send reply */
299 ps = nc_ps_new();
300 assert_non_null(ps);
301 nc_ps_add_session(ps, server_session);
302
303 ret = nc_ps_poll(ps, 0);
304 assert_int_equal(ret, 1);
305
306 /* server finished */
307 nc_ps_free(ps);
308
309 /* client reply */
310 msgtype = nc_recv_reply(client_session, rpc, msgid, 0, &reply);
311 assert_int_equal(msgtype, NC_MSG_REPLY);
312
313 nc_rpc_free(rpc);
314 assert_int_equal(reply->type, NC_RPL_DATA);
315 nc_reply_free(reply);
316}
317
Michal Vasko58d152f2016-02-01 11:44:49 +0100318static void
319test_send_recv_data_10(void **state)
320{
321 (void)state;
322
323 server_session->version = NC_VERSION_10;
324 client_session->version = NC_VERSION_10;
325
326 test_send_recv_data();
327}
328
329static void
330test_send_recv_data_11(void **state)
331{
332 (void)state;
333
334 server_session->version = NC_VERSION_11;
335 client_session->version = NC_VERSION_11;
336
337 test_send_recv_data();
338}
339
Michal Vasko294d4c62016-02-01 10:10:27 +0100340/* TODO
341static void
Michal Vasko58d152f2016-02-01 11:44:49 +0100342test_send_recv_notif(void)
Michal Vasko294d4c62016-02-01 10:10:27 +0100343{
344
345}*/
346
347int
348main(void)
349{
350 const struct CMUnitTest comm[] = {
Michal Vasko58d152f2016-02-01 11:44:49 +0100351 cmocka_unit_test_setup_teardown(test_send_recv_ok_10, setup_sessions, teardown_sessions),
352 cmocka_unit_test_setup_teardown(test_send_recv_error_10, setup_sessions, teardown_sessions),
353 cmocka_unit_test_setup_teardown(test_send_recv_data_10, setup_sessions, teardown_sessions),
354 cmocka_unit_test_setup_teardown(test_send_recv_ok_11, setup_sessions, teardown_sessions),
355 cmocka_unit_test_setup_teardown(test_send_recv_error_11, setup_sessions, teardown_sessions),
356 cmocka_unit_test_setup_teardown(test_send_recv_data_11, setup_sessions, teardown_sessions)
Michal Vasko294d4c62016-02-01 10:10:27 +0100357 };
358
359 return cmocka_run_group_tests(comm, NULL, NULL);
360}