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 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); 179 ATF_TC_HEAD(many_hooks, conf) 180 { 181 atf_tc_set_md_var(conf, "require.user", "root"); 182 } 183 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 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