1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright 2021 Lutz Donnerhacke
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 *    copyright notice, this list of conditions and the following
14 *    disclaimer in the documentation and/or other materials provided
15 *    with the distribution.
16 * 3. Neither the name of the copyright holder nor the names of its
17 *    contributors may be used to endorse or promote products derived
18 *    from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
21 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
22 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
31 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34#include <atf-c.h>
35#include <errno.h>
36#include <stdio.h>
37
38#include "util.h"
39
40ATF_TC(send_recv);
41ATF_TC_HEAD(send_recv, conf)
42{
43	atf_tc_set_md_var(conf, "require.user", "root");
44}
45
46ATF_TC_BODY(send_recv, dummy)
47{
48	char		msg[] = "test";
49	ng_counter_t	r;
50
51	ng_init();
52	ng_connect(".", "a", ".", "b");
53	ng_register_data("b", get_data0);
54	ng_send_data("a", msg, sizeof(msg));
55
56	ng_counter_clear(r);
57	ng_handle_events(50, &r);
58	ATF_CHECK(r[0] == 1);
59}
60
61ATF_TC(node);
62ATF_TC_HEAD(node, conf)
63{
64	atf_tc_set_md_var(conf, "require.user", "root");
65}
66
67ATF_TC_BODY(node, dummy)
68{
69	char		msg[] = "test";
70	ng_counter_t	r;
71
72	ng_init();
73	ng_mkpeer(".", "a", "hub", "a");
74	ng_name("a", "test hub");
75
76	ng_errors(PASS);
77	ng_name("a", "test hub");
78	ng_errors(FAIL);
79	if (errno == EADDRINUSE)
80		atf_tc_expect_fail("PR241954");
81	ATF_CHECK_ERRNO(0, 1);
82	atf_tc_expect_pass();
83
84	ng_connect(".", "b", "test hub:", "b");
85	ng_connect(".", "c", "test hub:", "c");
86	ng_register_data("a", get_data0);
87	ng_register_data("b", get_data1);
88	ng_register_data("c", get_data2);
89
90	ng_counter_clear(r);
91	ng_send_data("a", msg, sizeof(msg));
92	ng_handle_events(50, &r);
93	ATF_CHECK(r[0] == 0 && r[1] == 1 && r[2] == 1);
94
95	ng_rmhook(".", "b");
96	ng_counter_clear(r);
97	ng_send_data("a", msg, sizeof(msg));
98	ng_handle_events(50, &r);
99	ATF_CHECK(r[0] == 0 && r[1] == 0 && r[2] == 1);
100
101	ng_shutdown("test hub:");
102}
103
104ATF_TC(message);
105ATF_TC_HEAD(message, conf)
106{
107	atf_tc_set_md_var(conf, "require.user", "root");
108}
109
110ATF_TC_BODY(message, dummy)
111{
112	ng_init();
113	ng_mkpeer(".", "a", "hub", "a");
114	ng_name("a", "test hub");
115
116	ng_send_msg("test hub:", "setpersistent");
117	ng_rmhook(".", "a");
118
119	ng_shutdown("test hub:");
120}
121
122ATF_TC(same_name);
123ATF_TC_HEAD(same_name, conf)
124{
125	atf_tc_set_md_var(conf, "require.user", "root");
126}
127
128ATF_TC_BODY(same_name, dummy)
129{
130	ng_init();
131	ng_mkpeer(".", "a", "hub", "a");
132	ng_name("a", "test");
133
134	ng_errors(PASS);
135	ng_connect(".", "a", ".", "b");
136	ATF_CHECK_ERRNO(EEXIST, 1);
137	ng_connect(".", "b", ".", "b");
138	ATF_CHECK_ERRNO(EEXIST, 1);
139	ng_name(".", "test");
140	ATF_CHECK_ERRNO(EADDRINUSE, 1);
141
142	ng_errors(FAIL);
143	ng_shutdown("test:");
144}
145
146ATF_TC(queuelimit);
147ATF_TC_HEAD(queuelimit, conf)
148{
149	atf_tc_set_md_var(conf, "require.user", "root");
150}
151
152ATF_TC_BODY(queuelimit, dummy)
153{
154	ng_counter_t	r;
155	int		i;
156	char		msg[] = "test";
157	const int	MAX = 1000;
158
159	ng_init();
160	ng_connect(".", "a", ".", "b");
161	ng_register_data("b", get_data0);
162
163	ng_errors(PASS);
164	for (i = 0; i < MAX; i++)
165	{
166		ng_send_data("a", msg, sizeof(msg));
167		if (errno != 0)
168			break;
169		/* no ng_handle_events -> messages stall */
170	}
171	ng_errors(FAIL);
172
173	ng_counter_clear(r);
174	ng_handle_events(50, &r);
175	ATF_CHECK(r[0] > 100);
176	ATF_CHECK(r[0] == i);
177	atf_tc_expect_fail("Queue full (%d)", i);
178	ATF_CHECK(r[0] == MAX);
179	atf_tc_expect_pass();
180}
181
182ATF_TP_ADD_TCS(basic)
183{
184	ATF_TP_ADD_TC(basic, send_recv);
185	ATF_TP_ADD_TC(basic, node);
186	ATF_TP_ADD_TC(basic, message);
187	ATF_TP_ADD_TC(basic, same_name);
188	ATF_TP_ADD_TC(basic, queuelimit);
189
190	return atf_no_error();
191}
192