hub.c revision 370008
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(basic);
41ATF_TC_HEAD(basic, conf)
42{
43	atf_tc_set_md_var(conf, "require.user", "root");
44}
45
46ATF_TC_BODY(basic, dummy)
47{
48	char		msg[] = "test";
49	ng_counter_t	r;
50
51	ng_errors(PASS);
52	ng_shutdown("hub:");
53	ng_errors(FAIL);
54
55	ng_init();
56	ng_mkpeer(".", "a", "hub", "a");
57	ng_name("a", "hub");
58	ng_connect(".", "b", "hub:", "b");
59	ng_connect(".", "c", "hub:", "c");
60
61	/* do not bounce back */
62	ng_register_data("a", get_data0);
63	ng_counter_clear(r);
64	ng_send_data("a", msg, sizeof(msg));
65	ng_handle_events(50, r);
66	ATF_CHECK(r[0] == 0);
67
68	/* send to others */
69	ng_register_data("b", get_data0);
70	ng_register_data("c", get_data0);
71	ng_counter_clear(r);
72	ng_send_data("a", msg, sizeof(msg));
73	ng_handle_events(50, r);
74	ATF_CHECK(r[0] == 2);
75
76	ng_counter_clear(r);
77	ng_send_data("b", msg, sizeof(msg));
78	ng_handle_events(50, r);
79	ATF_CHECK(r[0] == 2);
80
81	ng_counter_clear(r);
82	ng_send_data("c", msg, sizeof(msg));
83	ng_handle_events(50, r);
84	ATF_CHECK(r[0] == 2);
85
86	/* remove a link */
87	ng_rmhook(".", "b");
88	ng_counter_clear(r);
89	ng_send_data("a", msg, sizeof(msg));
90	ng_handle_events(50, r);
91	ATF_CHECK(r[0] == 1);
92
93	ng_shutdown("hub:");
94}
95
96ATF_TC(persistence);
97ATF_TC_HEAD(persistence, conf)
98{
99	atf_tc_set_md_var(conf, "require.user", "root");
100}
101
102ATF_TC_BODY(persistence, dummy)
103{
104	ng_errors(PASS);
105	ng_shutdown("hub:");
106	ng_errors(FAIL);
107
108	ng_init();
109	ng_mkpeer(".", "a", "hub", "a");
110	ng_name("a", "hub");
111
112	ng_send_msg("hub:", "setpersistent");
113	ng_rmhook(".", "a");
114
115	ng_shutdown("hub:");
116}
117
118ATF_TC(loop);
119ATF_TC_HEAD(loop, conf)
120{
121	atf_tc_set_md_var(conf, "require.user", "root");
122}
123
124ATF_TC_BODY(loop, dummy)
125{
126	ng_counter_t	r;
127	int		i;
128	char		msg[] = "LOOP Alert!";
129
130	ng_errors(PASS);
131	ng_shutdown("hub1:");
132	ng_shutdown("hub2:");
133	ng_errors(FAIL);
134
135	ng_init();
136	ng_mkpeer(".", "a", "hub", "a");
137	ng_name("a", "hub1");
138	ng_mkpeer(".", "b", "hub", "b");
139	ng_name("b", "hub2");
140
141	ng_register_data("a", get_data0);
142	ng_register_data("b", get_data0);
143
144	/*-
145	 * Open loop
146	 *
147	 *    /-- hub1
148	 * . <    |
149	 *    \-- hub2
150	 */
151	ng_connect("hub1:", "xc1", "hub2:", "xc1");
152
153	ng_counter_clear(r);
154	ng_send_data("a", msg, sizeof(msg));
155	ng_handle_events(50, r);
156	ATF_CHECK(r[0] == 1);
157
158	/*-
159	 * Closed loop, DANGEROUS!
160	 *
161	 *    /-- hub1 -\
162	 * . <     |    |
163	 *    \-- hub2 -/
164	 */
165	ng_connect("hub1:", "xc2", "hub2:", "xc2");
166
167	ng_counter_clear(r);
168	ng_send_data("a", msg, sizeof(msg));
169	for (i = 0; i < 10; i++)	/* don't run forever */
170		if (!ng_handle_event(50, r))
171			break;
172	ATF_CHECK(r[0] > 7);
173
174	ng_shutdown("hub1:");
175	ng_shutdown("hub2:");
176}
177
178ATF_TC(many_hooks);
179ATF_TC_HEAD(many_hooks, conf)
180{
181	atf_tc_set_md_var(conf, "require.user", "root");
182}
183
184ATF_TC_BODY(many_hooks, dummy)
185{
186	ng_counter_t	r;
187	int		i;
188	char		msg[] = "test";
189	const int	HOOKS = 1000;
190
191	ng_errors(PASS);
192	ng_shutdown("hub:");
193	ng_errors(FAIL);
194
195	ng_init();
196	ng_mkpeer(".", "a", "hub", "a");
197	ng_name("a", "hub");
198
199	ng_register_data("a", get_data0);
200	ng_counter_clear(r);
201	for (i = 0; i < HOOKS; i++)
202	{
203		char		hook[20];
204
205		snprintf(hook, sizeof(hook), "hook%d", i);
206		ng_connect(".", hook, "hub:", hook);
207		ng_errors(PASS);
208		ng_send_data(hook, msg, sizeof(msg));
209		ng_errors(FAIL);
210		if (errno != 0)
211			break;
212		ng_handle_events(50, r);
213	}
214	ATF_CHECK(r[0] > 100);
215	atf_tc_expect_fail("Implementation limitation (%d)", i);
216	ATF_CHECK(r[0] == HOOKS);
217	atf_tc_expect_pass();
218
219	ng_shutdown("hub:");
220}
221
222
223ATF_TP_ADD_TCS(hub)
224{
225	ATF_TP_ADD_TC(hub, basic);
226	ATF_TP_ADD_TC(hub, loop);
227	ATF_TP_ADD_TC(hub, persistence);
228	ATF_TP_ADD_TC(hub, many_hooks);
229
230	return atf_no_error();
231}
232