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
40 ATF_TC(basic);
ATF_TC_HEAD(basic,conf)41 ATF_TC_HEAD(basic, conf)
42 {
43 atf_tc_set_md_var(conf, "require.user", "root");
44 }
45
ATF_TC_BODY(basic,dummy)46 ATF_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
96 ATF_TC(persistence);
ATF_TC_HEAD(persistence,conf)97 ATF_TC_HEAD(persistence, conf)
98 {
99 atf_tc_set_md_var(conf, "require.user", "root");
100 }
101
ATF_TC_BODY(persistence,dummy)102 ATF_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
118 ATF_TC(loop);
ATF_TC_HEAD(loop,conf)119 ATF_TC_HEAD(loop, conf)
120 {
121 atf_tc_set_md_var(conf, "require.user", "root");
122 }
123
ATF_TC_BODY(loop,dummy)124 ATF_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
178 ATF_TC(many_hooks);
ATF_TC_HEAD(many_hooks,conf)179 ATF_TC_HEAD(many_hooks, conf)
180 {
181 atf_tc_set_md_var(conf, "require.user", "root");
182 }
183
ATF_TC_BODY(many_hooks,dummy)184 ATF_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
ATF_TP_ADD_TCS(hub)223 ATF_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