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); 41 ATF_TC_HEAD(basic, conf) 42 { 43 atf_tc_set_md_var(conf, "require.user", "root"); 44 } 45 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); 97 ATF_TC_HEAD(persistence, conf) 98 { 99 atf_tc_set_md_var(conf, "require.user", "root"); 100 } 101 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); 119 ATF_TC_HEAD(loop, conf) 120 { 121 atf_tc_set_md_var(conf, "require.user", "root"); 122 } 123 124 ATF_TC_BODY(loop, dummy) 125 { 126 ng_counter_t r; 127 int i; 128 char msg[] = "LOOP Alert!"; 129 130 #if defined(__riscv) 131 if (atf_tc_get_config_var_as_bool_wd(dummy, "ci", false)) 132 atf_tc_skip("https://bugs.freebsd.org/259157"); 133 #endif 134 135 ng_errors(PASS); 136 ng_shutdown("hub1:"); 137 ng_shutdown("hub2:"); 138 ng_errors(FAIL); 139 140 ng_init(); 141 ng_mkpeer(".", "a", "hub", "a"); 142 ng_name("a", "hub1"); 143 ng_mkpeer(".", "b", "hub", "b"); 144 ng_name("b", "hub2"); 145 146 ng_register_data("a", get_data0); 147 ng_register_data("b", get_data0); 148 149 /*- 150 * Open loop 151 * 152 * /-- hub1 153 * . < | 154 * \-- hub2 155 */ 156 ng_connect("hub1:", "xc1", "hub2:", "xc1"); 157 158 ng_counter_clear(r); 159 ng_send_data("a", msg, sizeof(msg)); 160 ng_handle_events(50, r); 161 ATF_CHECK(r[0] == 1); 162 163 /*- 164 * Closed loop, DANGEROUS! 165 * 166 * /-- hub1 -\ 167 * . < | | 168 * \-- hub2 -/ 169 */ 170 ng_connect("hub1:", "xc2", "hub2:", "xc2"); 171 172 ng_counter_clear(r); 173 ng_send_data("a", msg, sizeof(msg)); 174 for (i = 0; i < 10; i++) /* don't run forever */ 175 if (!ng_handle_event(50, r)) 176 break; 177 ATF_CHECK(r[0] > 7); 178 179 ng_shutdown("hub1:"); 180 ng_shutdown("hub2:"); 181 } 182 183 ATF_TC(many_hooks); 184 ATF_TC_HEAD(many_hooks, conf) 185 { 186 atf_tc_set_md_var(conf, "require.user", "root"); 187 } 188 189 ATF_TC_BODY(many_hooks, dummy) 190 { 191 ng_counter_t r; 192 int i; 193 char msg[] = "test"; 194 const int HOOKS = 1000; 195 196 ng_errors(PASS); 197 ng_shutdown("hub:"); 198 ng_errors(FAIL); 199 200 ng_init(); 201 ng_mkpeer(".", "a", "hub", "a"); 202 ng_name("a", "hub"); 203 204 ng_register_data("a", get_data0); 205 ng_counter_clear(r); 206 for (i = 0; i < HOOKS; i++) 207 { 208 char hook[20]; 209 210 snprintf(hook, sizeof(hook), "hook%d", i); 211 ng_connect(".", hook, "hub:", hook); 212 ng_errors(PASS); 213 ng_send_data(hook, msg, sizeof(msg)); 214 ng_errors(FAIL); 215 if (errno != 0) 216 break; 217 ng_handle_events(50, r); 218 } 219 ATF_CHECK(r[0] > 100); 220 atf_tc_expect_fail("Implementation limitation (%d)", i); 221 ATF_CHECK(r[0] == HOOKS); 222 atf_tc_expect_pass(); 223 224 ng_shutdown("hub:"); 225 } 226 227 228 ATF_TP_ADD_TCS(hub) 229 { 230 ATF_TP_ADD_TC(hub, basic); 231 ATF_TP_ADD_TC(hub, loop); 232 ATF_TP_ADD_TC(hub, persistence); 233 ATF_TP_ADD_TC(hub, many_hooks); 234 235 return atf_no_error(); 236 } 237