xref: /freebsd/tests/sys/netgraph/basic.c (revision 4ab5c88da28780334f48eae56db52d8e77c871cf)
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 static void	get_data(void *data, size_t len, void *ctx);
41 
42 ATF_TC(send_recv);
43 ATF_TC_HEAD(send_recv, conf)
44 {
45 	atf_tc_set_md_var(conf, "require.user", "root");
46 }
47 
48 ATF_TC_BODY(send_recv, dummy)
49 {
50 	char		msg[] = "test";
51 	int		received;
52 
53 	ng_init();
54 	ng_connect(".", "a", ".", "b");
55 	ng_register_data("b", get_data);
56 	ng_send_data("a", msg, sizeof(msg));
57 
58 	received = 0;
59 	ng_handle_events(50, &received);
60 	ATF_CHECK(received == 1);
61 }
62 
63 ATF_TC(node);
64 ATF_TC_HEAD(node, conf)
65 {
66 	atf_tc_set_md_var(conf, "require.user", "root");
67 }
68 
69 ATF_TC_BODY(node, dummy)
70 {
71 	char		msg[] = "test";
72 	int		received;
73 
74 	ng_init();
75 	ng_mkpeer(".", "a", "hub", "a");
76 	ng_name("a", "test hub");
77 
78 
79 	ng_connect(".", "b", "test hub:", "b");
80 	ng_connect(".", "c", "test hub:", "c");
81 	ng_register_data("a", get_data);
82 	ng_register_data("b", get_data);
83 	ng_register_data("c", get_data);
84 
85 	received = 0;
86 	ng_send_data("a", msg, sizeof(msg));
87 	ng_handle_events(50, &received);
88 	ATF_CHECK(received == 2);
89 
90 	ng_rmhook(".", "b");
91 	received = 0;
92 	ng_send_data("a", msg, sizeof(msg));
93 	ng_handle_events(50, &received);
94 	ATF_CHECK(received == 1);
95 
96 	ng_shutdown("test hub:");
97 }
98 
99 ATF_TC(message);
100 ATF_TC_HEAD(message, conf)
101 {
102 	atf_tc_set_md_var(conf, "require.user", "root");
103 }
104 
105 ATF_TC_BODY(message, dummy)
106 {
107 	ng_init();
108 	ng_mkpeer(".", "a", "hub", "a");
109 	ng_name("a", "test hub");
110 
111 	ng_send_msg("test hub:", "setpersistent");
112 	ng_rmhook(".", "a");
113 
114 	ng_shutdown("test hub:");
115 }
116 
117 ATF_TC(same_name);
118 ATF_TC_HEAD(same_name, conf)
119 {
120 	atf_tc_set_md_var(conf, "require.user", "root");
121 }
122 
123 ATF_TC_BODY(same_name, dummy)
124 {
125 	ng_init();
126 	ng_mkpeer(".", "a", "hub", "a");
127 	ng_name("a", "test");
128 
129 	ng_errors(PASS);
130 	ng_connect(".", "a", ".", "b");
131 	ATF_CHECK_ERRNO(EEXIST, 1);
132 	ng_connect(".", "b", ".", "b");
133 	ATF_CHECK_ERRNO(EEXIST, 1);
134 	ng_name(".", "test");
135 	ATF_CHECK_ERRNO(EADDRINUSE, 1);
136 
137 	ng_errors(FAIL);
138 	ng_shutdown("test:");
139 }
140 
141 ATF_TC(queuelimit);
142 ATF_TC_HEAD(queuelimit, conf)
143 {
144 	atf_tc_set_md_var(conf, "require.user", "root");
145 }
146 
147 ATF_TC_BODY(queuelimit, dummy)
148 {
149 	int		received, i;
150 	char		msg[] = "test";
151 	const int	MAX = 1000;
152 
153 	ng_init();
154 	ng_connect(".", "a", ".", "b");
155 	ng_register_data("b", get_data);
156 
157 	ng_errors(PASS);
158 	for (i = 0; i < MAX; i++)
159 	{
160 		ng_send_data("a", msg, sizeof(msg));
161 		if (errno != 0)
162 			break;
163 		/* no ng_handle_events -> messages stall */
164 	}
165 	ng_errors(FAIL);
166 	printf("queued %d\n", i);
167 	sleep(3);
168 
169 	received = 0;
170 	ng_handle_events(50, &received);
171 	ATF_CHECK(received > 100);
172 	ATF_CHECK(received == i);
173 	atf_tc_expect_fail("Queue full (%d)", i);
174 	ATF_CHECK(received == MAX);
175 	atf_tc_expect_pass();
176 }
177 
178 ATF_TP_ADD_TCS(basic)
179 {
180 	ATF_TP_ADD_TC(basic, send_recv);
181 	ATF_TP_ADD_TC(basic, node);
182 	ATF_TP_ADD_TC(basic, message);
183 	ATF_TP_ADD_TC(basic, same_name);
184 	ATF_TP_ADD_TC(basic, queuelimit);
185 
186 	return atf_no_error();
187 }
188 
189 static void
190 get_data(void *data, size_t len, void *ctx)
191 {
192 	int	       *cnt = ctx;
193 
194 	(void)data;
195 	printf("Got %zu bytes of data.\n", len);
196 	(*cnt)++;
197 }
198