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