blob: c55b97f50a68d0023e7b39d52eb502ff948dae8e [file] [log] [blame]
Radek Krejcice24ab82015-10-08 15:37:02 +02001/**
2 * \file test_io.c
3 * \author Radek Krejci <rkrejci@cesnet.cz>
4 * \brief libnetconf2 tests - input/output functions
5 *
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 <stdlib.h>
30#include <string.h>
31#include <sys/stat.h>
32#include <sys/types.h>
33
34#include <cmocka.h>
35#include <libyang/libyang.h>
36
37#include <session_p.h>
38#include <messages_p.h>
39#include "config.h"
40
Radek Krejcice24ab82015-10-08 15:37:02 +020041static int
Radek Krejcia146f472015-10-19 15:00:05 +020042setup_read(void **state)
Radek Krejcice24ab82015-10-08 15:37:02 +020043{
Radek Krejcice24ab82015-10-08 15:37:02 +020044 int fd;
Radek Krejcia146f472015-10-19 15:00:05 +020045 struct nc_session *session;
Radek Krejcice24ab82015-10-08 15:37:02 +020046
Radek Krejcia146f472015-10-19 15:00:05 +020047 session = calloc(1, sizeof *session);
48 /* test IO with standard file descriptors */
49 session->ti_type = NC_TI_FD;
50 session->ti.fd.c = 0;
51
52 session->ctx = ly_ctx_new(TESTS_DIR"/models");
53 pthread_mutex_init(&session->ti_lock, NULL);
Radek Krejcice24ab82015-10-08 15:37:02 +020054
55 /* ietf-netconf */
56 fd = open(TESTS_DIR"/models/ietf-netconf.yin", O_RDONLY);
57 if (fd == -1) {
58 return -1;
59 }
60
Radek Krejcia146f472015-10-19 15:00:05 +020061 lys_read(session->ctx, fd, LYS_IN_YIN);
Radek Krejcice24ab82015-10-08 15:37:02 +020062 close(fd);
63
Radek Krejcia146f472015-10-19 15:00:05 +020064 *state = session;
65 return 0;
66}
67
68static int
69teardown_read(void **state)
70{
71 struct nc_session *session = (struct nc_session *)*state;
72
73 close(session->ti.fd.in);
74 close(session->ti.fd.out);
75
76 ly_ctx_destroy(session->ctx);
77
78 free(session);
79 *state = NULL;
80
81 return 0;
82}
83
84static void
85test_read_rpc_10(void **state)
86{
87 struct nc_session *session = (struct nc_session *)*state;
88 struct nc_rpc *rpc = NULL;
89 NC_MSG_TYPE type;
90
91 session->ti.fd.in = open(TESTS_DIR"/data/nc10/rpc-lock", O_RDONLY);
92 session->version = NC_VERSION_10;
93 session->side = NC_SIDE_SERVER;
94
95 type = nc_recv_rpc(session, 1000, &rpc);
96 assert_int_equal(type, NC_MSG_RPC);
97 assert_non_null(rpc);
98
Radek Krejcia53b3fe2015-10-19 17:25:04 +020099 nc_rpc_free(rpc);
Radek Krejcia146f472015-10-19 15:00:05 +0200100}
101
102static void
103test_read_rpc_10_bad(void **state)
104{
105 struct nc_session *session = (struct nc_session *)*state;
106 struct nc_rpc *rpc = NULL;
107 NC_MSG_TYPE type;
108
109 session->ti.fd.in = open(TESTS_DIR"/data/nc10/rpc-lock", O_RDONLY);
110 session->version = NC_VERSION_10;
111 session->side = NC_SIDE_CLIENT;
112
113 type = nc_recv_rpc(session, 1000, &rpc);
114 assert_int_equal(type, NC_MSG_ERROR);
115 assert_null(rpc);
116
Radek Krejcia53b3fe2015-10-19 17:25:04 +0200117 nc_rpc_free(rpc);
Radek Krejcia146f472015-10-19 15:00:05 +0200118}
119
120static void
121test_read_rpc_11(void **state)
122{
123 struct nc_session *session = (struct nc_session *)*state;
124 struct nc_rpc *rpc = NULL;
125 NC_MSG_TYPE type;
126
127 session->ti.fd.in = open(TESTS_DIR"/data/nc11/rpc-lock", O_RDONLY);
128 session->version = NC_VERSION_11;
129 session->side = NC_SIDE_SERVER;
130
131 type = nc_recv_rpc(session, 1000, &rpc);
132 assert_int_equal(type, NC_MSG_RPC);
133 assert_non_null(rpc);
134
Radek Krejcia53b3fe2015-10-19 17:25:04 +0200135 nc_rpc_free(rpc);
Radek Krejcia146f472015-10-19 15:00:05 +0200136}
137
138static void
139test_read_rpc_11_bad(void **state)
140{
141 struct nc_session *session = (struct nc_session *)*state;
142 struct nc_rpc *rpc = NULL;
143 NC_MSG_TYPE type;
144
145 session->ti.fd.in = open(TESTS_DIR"/data/nc11/rpc-lock", O_RDONLY);
146 session->version = NC_VERSION_11;
147 session->side = NC_SIDE_CLIENT;
148
149 type = nc_recv_rpc(session, 1000, &rpc);
150 assert_int_equal(type, NC_MSG_ERROR);
151 assert_null(rpc);
152
Radek Krejcia53b3fe2015-10-19 17:25:04 +0200153 nc_rpc_free(rpc);
Radek Krejcia146f472015-10-19 15:00:05 +0200154}
155
156
157struct wr {
158 struct nc_session *session;
159 struct nc_rpc *rpc;
160};
161
162static int
163setup_write(void **state)
164{
165 (void) state; /* unused */
166 int fd;
167 NC_MSG_TYPE type;
168 struct wr *w;
169
170 w = malloc(sizeof *w);
171 w->session = calloc(1, sizeof *w->session);
172 w->session->ctx = ly_ctx_new(TESTS_DIR"/models");
173 pthread_mutex_init(&w->session->ti_lock, NULL);
174
175 /* ietf-netconf */
176 fd = open(TESTS_DIR"/models/ietf-netconf.yin", O_RDONLY);
177 if (fd == -1) {
178 return -1;
179 }
180
181 lys_read(w->session->ctx, fd, LYS_IN_YIN);
182 close(fd);
183
184 /* get rpc to write - TODO client side way */
185 fd = open(TESTS_DIR"/data/nc10/rpc-lock", O_RDONLY);
186 w->session->version = NC_VERSION_10;
187 w->session->msgid = 999;
188 w->session->ti_type = NC_TI_FD;
189 w->session->ti.fd.c = 0;
190 w->session->ti.fd.in = fd;
191
192 type = nc_recv_rpc(w->session, 1000, &w->rpc);
193 assert_int_equal(type, NC_MSG_RPC);
194 assert_non_null(w->rpc);
195
196 close(fd);
197 w->session->ti.fd.in = -1;
198
199 *state = w;
200
Radek Krejcice24ab82015-10-08 15:37:02 +0200201 return 0;
202}
203
204static int
Radek Krejcia146f472015-10-19 15:00:05 +0200205teardown_write(void **state)
Radek Krejcice24ab82015-10-08 15:37:02 +0200206{
Radek Krejcia146f472015-10-19 15:00:05 +0200207 struct wr *w = (struct wr *)*state;
Radek Krejcice24ab82015-10-08 15:37:02 +0200208
Radek Krejcia146f472015-10-19 15:00:05 +0200209 if (w->session->ti.fd.in != -1) {
210 close(w->session->ti.fd.in);
211 }
212 if (w->session->ti.fd.out != -1) {
213 close(w->session->ti.fd.out);
Radek Krejcife0b3472015-10-12 13:43:42 +0200214 }
215
Radek Krejcia53b3fe2015-10-19 17:25:04 +0200216 nc_rpc_free(w->rpc);
Radek Krejcia146f472015-10-19 15:00:05 +0200217 ly_ctx_destroy(w->session->ctx);
218
219 free(w->session);
220 free(w);
221 *state = NULL;
Radek Krejcice24ab82015-10-08 15:37:02 +0200222
223 return 0;
224}
225
226static void
Radek Krejcife0b3472015-10-12 13:43:42 +0200227test_write_rpc(void **state)
228{
Radek Krejcia146f472015-10-19 15:00:05 +0200229 struct wr *w = (struct wr *)*state;
Radek Krejcife0b3472015-10-12 13:43:42 +0200230 NC_MSG_TYPE type;
231
Radek Krejcia146f472015-10-19 15:00:05 +0200232 w->session->side = NC_SIDE_CLIENT;
233 w->session->ti_type = NC_TI_FD;
234 w->session->ti.fd.c = 0;
235 w->session->ti.fd.out = STDOUT_FILENO;
Radek Krejcife0b3472015-10-12 13:43:42 +0200236
237 do {
Radek Krejcia146f472015-10-19 15:00:05 +0200238 type = nc_send_rpc(w->session, w->rpc->tree, NULL);
Radek Krejcife0b3472015-10-12 13:43:42 +0200239 } while(type == NC_MSG_WOULDBLOCK);
240
241 assert_int_equal(type, NC_MSG_RPC);
242
Radek Krejcia146f472015-10-19 15:00:05 +0200243 write(w->session->ti.fd.out, "\n", 1);
244
245 w->session->ti.fd.out = -1;
Radek Krejcice24ab82015-10-08 15:37:02 +0200246}
247
Radek Krejcia146f472015-10-19 15:00:05 +0200248static void
249test_write_rpc_10(void **state)
250{
251 struct wr *w = (struct wr *)*state;
252
253 w->session->version = NC_VERSION_10;
254
255 return test_write_rpc(state);
256}
257
258static void
259test_write_rpc_11(void **state)
260{
261 struct wr *w = (struct wr *)*state;
262
263 w->session->version = NC_VERSION_11;
264
265 return test_write_rpc(state);
266}
267
268static void
269test_write_rpc_bad(void **state)
270{
271 struct wr *w = (struct wr *)*state;
272 NC_MSG_TYPE type;
273
274 w->session->side = NC_SIDE_SERVER;
275 w->session->ti_type = NC_TI_FD;
276 w->session->ti.fd.c = 0;
277 w->session->ti.fd.out = STDOUT_FILENO;
278
279 do {
280 type = nc_send_rpc(w->session, w->rpc->tree, NULL);
281 } while(type == NC_MSG_WOULDBLOCK);
282
283 assert_int_equal(type, NC_MSG_ERROR);
284
285 w->session->ti.fd.out = -1;
286}
287
288static void
289test_write_rpc_10_bad(void **state)
290{
291 struct wr *w = (struct wr *)*state;
292
293 w->session->version = NC_VERSION_10;
294
295 return test_write_rpc_bad(state);
296}
297
298static void
299test_write_rpc_11_bad(void **state)
300{
301 struct wr *w = (struct wr *)*state;
302
303 w->session->version = NC_VERSION_11;
304
305 return test_write_rpc_bad(state);
306}
Radek Krejcice24ab82015-10-08 15:37:02 +0200307int main(void)
308{
Radek Krejcife0b3472015-10-12 13:43:42 +0200309 const struct CMUnitTest io[] = {
Radek Krejcia146f472015-10-19 15:00:05 +0200310 cmocka_unit_test_setup_teardown(test_read_rpc_10, setup_read, teardown_read),
311 cmocka_unit_test_setup_teardown(test_read_rpc_10_bad, setup_read, teardown_read),
312 cmocka_unit_test_setup_teardown(test_read_rpc_11, setup_read, teardown_read),
313 cmocka_unit_test_setup_teardown(test_read_rpc_11_bad, setup_read, teardown_read),
314 cmocka_unit_test_setup_teardown(test_write_rpc_10, setup_write, teardown_write),
315 cmocka_unit_test_setup_teardown(test_write_rpc_10_bad, setup_write, teardown_write),
316 cmocka_unit_test_setup_teardown(test_write_rpc_11, setup_write, teardown_write),
317 cmocka_unit_test_setup_teardown(test_write_rpc_11_bad, setup_write, teardown_write)};
Radek Krejcice24ab82015-10-08 15:37:02 +0200318
319 return cmocka_run_group_tests(io, NULL, NULL);
320}