blob: a8de474c5b9e26e4daa1db5b699b3235f487b121 [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
Michal Vaskoba9f3582023-02-22 10:26:32 +010015#define _GNU_SOURCE
16
Radek Krejcice24ab82015-10-08 15:37:02 +020017#include <errno.h>
18#include <fcntl.h>
19#include <pthread.h>
20#include <setjmp.h>
21#include <stdarg.h>
22#include <stddef.h>
23#include <stdlib.h>
24#include <string.h>
25#include <sys/stat.h>
26#include <sys/types.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020027#include <unistd.h>
Radek Krejcice24ab82015-10-08 15:37:02 +020028
29#include <cmocka.h>
30#include <libyang/libyang.h>
31
Radek Krejci93e80222016-10-03 13:34:25 +020032#include <messages_p.h>
Michal Vasko086311b2016-01-08 09:53:11 +010033#include <session_client.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020034#include <session_p.h>
Jan Kundrátcf15d6c2017-10-26 18:07:56 +020035#include "tests/config.h"
Radek Krejcice24ab82015-10-08 15:37:02 +020036
Radek Krejcia146f472015-10-19 15:00:05 +020037struct wr {
38 struct nc_session *session;
39 struct nc_rpc *rpc;
40};
41
42static int
43setup_write(void **state)
44{
45 (void) state; /* unused */
Michal Vasko5ba14e52019-06-20 10:03:06 +020046 int fd, pipes[2];
Radek Krejcia146f472015-10-19 15:00:05 +020047 struct wr *w;
48
49 w = malloc(sizeof *w);
50 w->session = calloc(1, sizeof *w->session);
Michal Vaskob83a3fa2021-05-26 09:53:42 +020051 ly_ctx_new(TESTS_DIR "/data/modules", 0, &w->session->ctx);
Radek Krejcia146f472015-10-19 15:00:05 +020052
53 /* ietf-netconf */
Michal Vaskob83a3fa2021-05-26 09:53:42 +020054 fd = open(TESTS_DIR "/data/modules/ietf-netconf.yin", O_RDONLY);
Radek Krejcia146f472015-10-19 15:00:05 +020055 if (fd == -1) {
Michal Vasko11d142a2016-01-19 15:58:24 +010056 free(w);
Radek Krejcia146f472015-10-19 15:00:05 +020057 return -1;
58 }
59
Michal Vasko77367452021-02-16 16:32:18 +010060 lys_parse_fd(w->session->ctx, fd, LYS_IN_YIN, NULL);
Radek Krejcia146f472015-10-19 15:00:05 +020061 close(fd);
62
Jan Kundrát5cec3c22021-10-08 19:54:39 +020063 assert_return_code(pipe(pipes), errno);
Michal Vasko5ba14e52019-06-20 10:03:06 +020064
Radek Krejci695d4fa2015-10-22 13:23:54 +020065 w->session->status = NC_STATUS_RUNNING;
Radek Krejcia146f472015-10-19 15:00:05 +020066 w->session->version = NC_VERSION_10;
Michal Vasko338f8472016-10-13 15:01:27 +020067 w->session->opts.client.msgid = 999;
Radek Krejcia146f472015-10-19 15:00:05 +020068 w->session->ti_type = NC_TI_FD;
Michal Vasko131120a2018-05-29 15:44:02 +020069 w->session->io_lock = malloc(sizeof *w->session->io_lock);
70 pthread_mutex_init(w->session->io_lock, NULL);
Michal Vasko5ba14e52019-06-20 10:03:06 +020071 w->session->ti.fd.in = pipes[0];
72 w->session->ti.fd.out = pipes[1];
Radek Krejcia146f472015-10-19 15:00:05 +020073
Radek Krejci695d4fa2015-10-22 13:23:54 +020074 /* get rpc to write */
75 w->rpc = nc_rpc_lock(NC_DATASTORE_RUNNING);
Radek Krejcia146f472015-10-19 15:00:05 +020076 assert_non_null(w->rpc);
77
Radek Krejcia146f472015-10-19 15:00:05 +020078 *state = w;
79
Radek Krejcice24ab82015-10-08 15:37:02 +020080 return 0;
81}
82
83static int
Radek Krejcia146f472015-10-19 15:00:05 +020084teardown_write(void **state)
Radek Krejcice24ab82015-10-08 15:37:02 +020085{
Radek Krejcia146f472015-10-19 15:00:05 +020086 struct wr *w = (struct wr *)*state;
Radek Krejcice24ab82015-10-08 15:37:02 +020087
Radek Krejcia53b3fe2015-10-19 17:25:04 +020088 nc_rpc_free(w->rpc);
Michal Vasko5ba14e52019-06-20 10:03:06 +020089 close(w->session->ti.fd.in);
Radek Krejci695d4fa2015-10-22 13:23:54 +020090 w->session->ti.fd.in = -1;
Michal Vasko5ba14e52019-06-20 10:03:06 +020091 close(w->session->ti.fd.out);
Radek Krejci695d4fa2015-10-22 13:23:54 +020092 w->session->ti.fd.out = -1;
Michal Vaskoe1a64ec2016-03-01 12:21:58 +010093 nc_session_free(w->session, NULL);
Radek Krejcia146f472015-10-19 15:00:05 +020094 free(w);
95 *state = NULL;
Radek Krejcice24ab82015-10-08 15:37:02 +020096
97 return 0;
98}
99
100static void
Radek Krejcife0b3472015-10-12 13:43:42 +0200101test_write_rpc(void **state)
102{
Radek Krejcia146f472015-10-19 15:00:05 +0200103 struct wr *w = (struct wr *)*state;
Michal Vaskof44f2482015-12-11 14:40:30 +0100104 uint64_t msgid;
Radek Krejcife0b3472015-10-12 13:43:42 +0200105 NC_MSG_TYPE type;
106
Radek Krejci695d4fa2015-10-22 13:23:54 +0200107 w->session->side = NC_CLIENT;
Radek Krejcife0b3472015-10-12 13:43:42 +0200108
109 do {
Michal Vaskof44f2482015-12-11 14:40:30 +0100110 type = nc_send_rpc(w->session, w->rpc, 1000, &msgid);
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200111 } while (type == NC_MSG_WOULDBLOCK);
Radek Krejcife0b3472015-10-12 13:43:42 +0200112
113 assert_int_equal(type, NC_MSG_RPC);
114
Jan Kundrát5cec3c22021-10-08 19:54:39 +0200115 assert_int_equal(write(w->session->ti.fd.out, "\n", 1), 1);
Radek Krejcice24ab82015-10-08 15:37:02 +0200116}
117
Radek Krejcia146f472015-10-19 15:00:05 +0200118static void
119test_write_rpc_10(void **state)
120{
121 struct wr *w = (struct wr *)*state;
122
123 w->session->version = NC_VERSION_10;
124
125 return test_write_rpc(state);
126}
127
128static void
129test_write_rpc_11(void **state)
130{
131 struct wr *w = (struct wr *)*state;
132
133 w->session->version = NC_VERSION_11;
134
135 return test_write_rpc(state);
136}
137
138static void
139test_write_rpc_bad(void **state)
140{
141 struct wr *w = (struct wr *)*state;
Michal Vaskof44f2482015-12-11 14:40:30 +0100142 uint64_t msgid;
Radek Krejcia146f472015-10-19 15:00:05 +0200143 NC_MSG_TYPE type;
144
Radek Krejci695d4fa2015-10-22 13:23:54 +0200145 w->session->side = NC_SERVER;
Michal Vaskoacf98472021-02-04 15:33:57 +0100146 pthread_mutex_init(&w->session->opts.server.rpc_lock, NULL);
147 pthread_cond_init(&w->session->opts.server.rpc_cond, NULL);
148 w->session->opts.server.rpc_inuse = 0;
Radek Krejcia146f472015-10-19 15:00:05 +0200149
150 do {
Michal Vaskof44f2482015-12-11 14:40:30 +0100151 type = nc_send_rpc(w->session, w->rpc, 1000, &msgid);
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200152 } while (type == NC_MSG_WOULDBLOCK);
Radek Krejcia146f472015-10-19 15:00:05 +0200153
154 assert_int_equal(type, NC_MSG_ERROR);
Radek Krejcia146f472015-10-19 15:00:05 +0200155}
156
157static void
158test_write_rpc_10_bad(void **state)
159{
160 struct wr *w = (struct wr *)*state;
161
162 w->session->version = NC_VERSION_10;
163
164 return test_write_rpc_bad(state);
165}
166
167static void
168test_write_rpc_11_bad(void **state)
169{
170 struct wr *w = (struct wr *)*state;
171
172 w->session->version = NC_VERSION_11;
173
174 return test_write_rpc_bad(state);
175}
Michal Vasko275a3022017-02-07 10:58:12 +0100176
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200177int
178main(void)
Radek Krejcice24ab82015-10-08 15:37:02 +0200179{
Radek Krejcife0b3472015-10-12 13:43:42 +0200180 const struct CMUnitTest io[] = {
Radek Krejcia146f472015-10-19 15:00:05 +0200181 cmocka_unit_test_setup_teardown(test_write_rpc_10, setup_write, teardown_write),
182 cmocka_unit_test_setup_teardown(test_write_rpc_10_bad, setup_write, teardown_write),
183 cmocka_unit_test_setup_teardown(test_write_rpc_11, setup_write, teardown_write),
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200184 cmocka_unit_test_setup_teardown(test_write_rpc_11_bad, setup_write, teardown_write)
185 };
Radek Krejcice24ab82015-10-08 15:37:02 +0200186
187 return cmocka_run_group_tests(io, NULL, NULL);
188}