blob: eb7253126359fd693f6481ed322d16e1fb084fac [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>
Michal Vasko3512e402016-01-28 16:22:34 +010022#include <unistd.h>
Radek Krejcice24ab82015-10-08 15:37:02 +020023#include <string.h>
24#include <sys/stat.h>
25#include <sys/types.h>
26
27#include <cmocka.h>
28#include <libyang/libyang.h>
29
Radek Krejci93e80222016-10-03 13:34:25 +020030#include <messages_p.h>
Radek Krejcice24ab82015-10-08 15:37:02 +020031#include <session_p.h>
Michal Vasko086311b2016-01-08 09:53:11 +010032#include <session_client.h>
Radek Krejcice24ab82015-10-08 15:37:02 +020033#include "config.h"
34
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 */
44 int fd;
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);
Radek Krejci695d4fa2015-10-22 13:23:54 +020049 w->session->ctx = ly_ctx_new(TESTS_DIR"../schemas");
Radek Krejcia146f472015-10-19 15:00:05 +020050
51 /* ietf-netconf */
Radek Krejci695d4fa2015-10-22 13:23:54 +020052 fd = open(TESTS_DIR"../schemas/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 Vasko608b52b2015-12-11 14:39:59 +010058 lys_parse_fd(w->session->ctx, fd, LYS_IN_YIN);
Radek Krejcia146f472015-10-19 15:00:05 +020059 close(fd);
60
Radek Krejci695d4fa2015-10-22 13:23:54 +020061 w->session->status = NC_STATUS_RUNNING;
Radek Krejcia146f472015-10-19 15:00:05 +020062 w->session->version = NC_VERSION_10;
Michal Vasko338f8472016-10-13 15:01:27 +020063 w->session->opts.client.msgid = 999;
Radek Krejcia146f472015-10-19 15:00:05 +020064 w->session->ti_type = NC_TI_FD;
Michal Vaskoade892d2017-02-22 13:40:35 +010065 w->session->ti_lock = malloc(sizeof *w->session->ti_lock);
66 pthread_mutex_init(w->session->ti_lock, NULL);
67 w->session->ti_cond = malloc(sizeof *w->session->ti_cond);
68 pthread_cond_init(w->session->ti_cond, NULL);
69 w->session->ti_inuse = malloc(sizeof *w->session->ti_inuse);
70 *w->session->ti_inuse = 0;
Radek Krejci695d4fa2015-10-22 13:23:54 +020071 w->session->ti.fd.in = STDIN_FILENO;
72 w->session->ti.fd.out = STDOUT_FILENO;
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);
Radek Krejci695d4fa2015-10-22 13:23:54 +020089 w->session->ti.fd.in = -1;
90 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);
Radek Krejcife0b3472015-10-12 13:43:42 +0200109 } while(type == NC_MSG_WOULDBLOCK);
110
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;
Radek Krejcia146f472015-10-19 15:00:05 +0200144
145 do {
Michal Vaskof44f2482015-12-11 14:40:30 +0100146 type = nc_send_rpc(w->session, w->rpc, 1000, &msgid);
Radek Krejcia146f472015-10-19 15:00:05 +0200147 } while(type == NC_MSG_WOULDBLOCK);
148
149 assert_int_equal(type, NC_MSG_ERROR);
Radek Krejcia146f472015-10-19 15:00:05 +0200150}
151
152static void
153test_write_rpc_10_bad(void **state)
154{
155 struct wr *w = (struct wr *)*state;
156
157 w->session->version = NC_VERSION_10;
158
159 return test_write_rpc_bad(state);
160}
161
162static void
163test_write_rpc_11_bad(void **state)
164{
165 struct wr *w = (struct wr *)*state;
166
167 w->session->version = NC_VERSION_11;
168
169 return test_write_rpc_bad(state);
170}
Michal Vasko275a3022017-02-07 10:58:12 +0100171
Radek Krejcice24ab82015-10-08 15:37:02 +0200172int main(void)
173{
Radek Krejcife0b3472015-10-12 13:43:42 +0200174 const struct CMUnitTest io[] = {
Radek Krejcia146f472015-10-19 15:00:05 +0200175 cmocka_unit_test_setup_teardown(test_write_rpc_10, setup_write, teardown_write),
176 cmocka_unit_test_setup_teardown(test_write_rpc_10_bad, setup_write, teardown_write),
177 cmocka_unit_test_setup_teardown(test_write_rpc_11, setup_write, teardown_write),
178 cmocka_unit_test_setup_teardown(test_write_rpc_11_bad, setup_write, teardown_write)};
Radek Krejcice24ab82015-10-08 15:37:02 +0200179
180 return cmocka_run_group_tests(io, NULL, NULL);
181}