blob: a3d4bdff9d105dcf5e9ec491d040ee5baea95635 [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 *
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
Radek Krejcice24ab82015-10-08 15:37:02 +020013 */
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 <stdlib.h>
22#include <string.h>
23#include <sys/stat.h>
24#include <sys/types.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020025#include <unistd.h>
Radek Krejcice24ab82015-10-08 15:37:02 +020026
27#include <cmocka.h>
28#include <libyang/libyang.h>
29
Radek Krejci93e80222016-10-03 13:34:25 +020030#include <messages_p.h>
Michal Vasko086311b2016-01-08 09:53:11 +010031#include <session_client.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020032#include <session_p.h>
Jan Kundrátcf15d6c2017-10-26 18:07:56 +020033#include "tests/config.h"
Radek Krejcice24ab82015-10-08 15:37:02 +020034
Radek Krejcia146f472015-10-19 15:00:05 +020035struct wr {
36 struct nc_session *session;
37 struct nc_rpc *rpc;
38};
39
40static int
41setup_write(void **state)
42{
43 (void) state; /* unused */
Michal Vasko5ba14e52019-06-20 10:03:06 +020044 int fd, pipes[2];
Radek Krejcia146f472015-10-19 15:00:05 +020045 struct wr *w;
46
47 w = malloc(sizeof *w);
48 w->session = calloc(1, sizeof *w->session);
Michal Vaskob83a3fa2021-05-26 09:53:42 +020049 ly_ctx_new(TESTS_DIR "/data/modules", 0, &w->session->ctx);
Radek Krejcia146f472015-10-19 15:00:05 +020050
51 /* ietf-netconf */
Michal Vaskob83a3fa2021-05-26 09:53:42 +020052 fd = open(TESTS_DIR "/data/modules/ietf-netconf.yin", O_RDONLY);
Radek Krejcia146f472015-10-19 15:00:05 +020053 if (fd == -1) {
Michal Vasko11d142a2016-01-19 15:58:24 +010054 free(w);
Radek Krejcia146f472015-10-19 15:00:05 +020055 return -1;
56 }
57
Michal Vasko77367452021-02-16 16:32:18 +010058 lys_parse_fd(w->session->ctx, fd, LYS_IN_YIN, NULL);
Radek Krejcia146f472015-10-19 15:00:05 +020059 close(fd);
60
Michal Vasko5ba14e52019-06-20 10:03:06 +020061 pipe(pipes);
62
Radek Krejci695d4fa2015-10-22 13:23:54 +020063 w->session->status = NC_STATUS_RUNNING;
Radek Krejcia146f472015-10-19 15:00:05 +020064 w->session->version = NC_VERSION_10;
Michal Vasko338f8472016-10-13 15:01:27 +020065 w->session->opts.client.msgid = 999;
Radek Krejcia146f472015-10-19 15:00:05 +020066 w->session->ti_type = NC_TI_FD;
Michal Vasko131120a2018-05-29 15:44:02 +020067 w->session->io_lock = malloc(sizeof *w->session->io_lock);
68 pthread_mutex_init(w->session->io_lock, NULL);
Michal Vasko5ba14e52019-06-20 10:03:06 +020069 w->session->ti.fd.in = pipes[0];
70 w->session->ti.fd.out = pipes[1];
Radek Krejcia146f472015-10-19 15:00:05 +020071
Radek Krejci695d4fa2015-10-22 13:23:54 +020072 /* get rpc to write */
73 w->rpc = nc_rpc_lock(NC_DATASTORE_RUNNING);
Radek Krejcia146f472015-10-19 15:00:05 +020074 assert_non_null(w->rpc);
75
Radek Krejcia146f472015-10-19 15:00:05 +020076 *state = w;
77
Radek Krejcice24ab82015-10-08 15:37:02 +020078 return 0;
79}
80
81static int
Radek Krejcia146f472015-10-19 15:00:05 +020082teardown_write(void **state)
Radek Krejcice24ab82015-10-08 15:37:02 +020083{
Radek Krejcia146f472015-10-19 15:00:05 +020084 struct wr *w = (struct wr *)*state;
Radek Krejcice24ab82015-10-08 15:37:02 +020085
Radek Krejcia53b3fe2015-10-19 17:25:04 +020086 nc_rpc_free(w->rpc);
Michal Vasko5ba14e52019-06-20 10:03:06 +020087 close(w->session->ti.fd.in);
Radek Krejci695d4fa2015-10-22 13:23:54 +020088 w->session->ti.fd.in = -1;
Michal Vasko5ba14e52019-06-20 10:03:06 +020089 close(w->session->ti.fd.out);
Radek Krejci695d4fa2015-10-22 13:23:54 +020090 w->session->ti.fd.out = -1;
Michal Vaskoe1a64ec2016-03-01 12:21:58 +010091 nc_session_free(w->session, NULL);
Radek Krejcia146f472015-10-19 15:00:05 +020092 free(w);
93 *state = NULL;
Radek Krejcice24ab82015-10-08 15:37:02 +020094
95 return 0;
96}
97
98static void
Radek Krejcife0b3472015-10-12 13:43:42 +020099test_write_rpc(void **state)
100{
Radek Krejcia146f472015-10-19 15:00:05 +0200101 struct wr *w = (struct wr *)*state;
Michal Vaskof44f2482015-12-11 14:40:30 +0100102 uint64_t msgid;
Radek Krejcife0b3472015-10-12 13:43:42 +0200103 NC_MSG_TYPE type;
104
Radek Krejci695d4fa2015-10-22 13:23:54 +0200105 w->session->side = NC_CLIENT;
Radek Krejcife0b3472015-10-12 13:43:42 +0200106
107 do {
Michal Vaskof44f2482015-12-11 14:40:30 +0100108 type = nc_send_rpc(w->session, w->rpc, 1000, &msgid);
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200109 } while (type == NC_MSG_WOULDBLOCK);
Radek Krejcife0b3472015-10-12 13:43:42 +0200110
111 assert_int_equal(type, NC_MSG_RPC);
112
Radek Krejcia146f472015-10-19 15:00:05 +0200113 write(w->session->ti.fd.out, "\n", 1);
Radek Krejcice24ab82015-10-08 15:37:02 +0200114}
115
Radek Krejcia146f472015-10-19 15:00:05 +0200116static void
117test_write_rpc_10(void **state)
118{
119 struct wr *w = (struct wr *)*state;
120
121 w->session->version = NC_VERSION_10;
122
123 return test_write_rpc(state);
124}
125
126static void
127test_write_rpc_11(void **state)
128{
129 struct wr *w = (struct wr *)*state;
130
131 w->session->version = NC_VERSION_11;
132
133 return test_write_rpc(state);
134}
135
136static void
137test_write_rpc_bad(void **state)
138{
139 struct wr *w = (struct wr *)*state;
Michal Vaskof44f2482015-12-11 14:40:30 +0100140 uint64_t msgid;
Radek Krejcia146f472015-10-19 15:00:05 +0200141 NC_MSG_TYPE type;
142
Radek Krejci695d4fa2015-10-22 13:23:54 +0200143 w->session->side = NC_SERVER;
Michal Vaskoacf98472021-02-04 15:33:57 +0100144 pthread_mutex_init(&w->session->opts.server.rpc_lock, NULL);
145 pthread_cond_init(&w->session->opts.server.rpc_cond, NULL);
146 w->session->opts.server.rpc_inuse = 0;
Radek Krejcia146f472015-10-19 15:00:05 +0200147
148 do {
Michal Vaskof44f2482015-12-11 14:40:30 +0100149 type = nc_send_rpc(w->session, w->rpc, 1000, &msgid);
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200150 } while (type == NC_MSG_WOULDBLOCK);
Radek Krejcia146f472015-10-19 15:00:05 +0200151
152 assert_int_equal(type, NC_MSG_ERROR);
Radek Krejcia146f472015-10-19 15:00:05 +0200153}
154
155static void
156test_write_rpc_10_bad(void **state)
157{
158 struct wr *w = (struct wr *)*state;
159
160 w->session->version = NC_VERSION_10;
161
162 return test_write_rpc_bad(state);
163}
164
165static void
166test_write_rpc_11_bad(void **state)
167{
168 struct wr *w = (struct wr *)*state;
169
170 w->session->version = NC_VERSION_11;
171
172 return test_write_rpc_bad(state);
173}
Michal Vasko275a3022017-02-07 10:58:12 +0100174
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200175int
176main(void)
Radek Krejcice24ab82015-10-08 15:37:02 +0200177{
Radek Krejcife0b3472015-10-12 13:43:42 +0200178 const struct CMUnitTest io[] = {
Radek Krejcia146f472015-10-19 15:00:05 +0200179 cmocka_unit_test_setup_teardown(test_write_rpc_10, setup_write, teardown_write),
180 cmocka_unit_test_setup_teardown(test_write_rpc_10_bad, setup_write, teardown_write),
181 cmocka_unit_test_setup_teardown(test_write_rpc_11, setup_write, teardown_write),
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200182 cmocka_unit_test_setup_teardown(test_write_rpc_11_bad, setup_write, teardown_write)
183 };
Radek Krejcice24ab82015-10-08 15:37:02 +0200184
185 return cmocka_run_group_tests(io, NULL, NULL);
186}