1*a664ade9SLutz Donnerhacke /*- 224ea1dbfSLutz Donnerhacke * SPDX-License-Identifier: BSD-3-Clause 324ea1dbfSLutz Donnerhacke * 424ea1dbfSLutz Donnerhacke * Copyright 2021 Lutz Donnerhacke 524ea1dbfSLutz Donnerhacke * 624ea1dbfSLutz Donnerhacke * Redistribution and use in source and binary forms, with or without 724ea1dbfSLutz Donnerhacke * modification, are permitted provided that the following conditions 824ea1dbfSLutz Donnerhacke * are met: 924ea1dbfSLutz Donnerhacke * 1024ea1dbfSLutz Donnerhacke * 1. Redistributions of source code must retain the above copyright 1124ea1dbfSLutz Donnerhacke * notice, this list of conditions and the following disclaimer. 1224ea1dbfSLutz Donnerhacke * 2. Redistributions in binary form must reproduce the above 1324ea1dbfSLutz Donnerhacke * copyright notice, this list of conditions and the following 1424ea1dbfSLutz Donnerhacke * disclaimer in the documentation and/or other materials provided 1524ea1dbfSLutz Donnerhacke * with the distribution. 1624ea1dbfSLutz Donnerhacke * 3. Neither the name of the copyright holder nor the names of its 1724ea1dbfSLutz Donnerhacke * contributors may be used to endorse or promote products derived 1824ea1dbfSLutz Donnerhacke * from this software without specific prior written permission. 1924ea1dbfSLutz Donnerhacke * 2024ea1dbfSLutz Donnerhacke * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 2124ea1dbfSLutz Donnerhacke * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 2224ea1dbfSLutz Donnerhacke * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 2324ea1dbfSLutz Donnerhacke * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2424ea1dbfSLutz Donnerhacke * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 2524ea1dbfSLutz Donnerhacke * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2624ea1dbfSLutz Donnerhacke * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2724ea1dbfSLutz Donnerhacke * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2824ea1dbfSLutz Donnerhacke * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 2924ea1dbfSLutz Donnerhacke * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 3024ea1dbfSLutz Donnerhacke * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 3124ea1dbfSLutz Donnerhacke * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3224ea1dbfSLutz Donnerhacke * SUCH DAMAGE. 3324ea1dbfSLutz Donnerhacke */ 3424ea1dbfSLutz Donnerhacke #include <atf-c.h> 3524ea1dbfSLutz Donnerhacke #include <errno.h> 3624ea1dbfSLutz Donnerhacke #include <stdio.h> 3724ea1dbfSLutz Donnerhacke 3824ea1dbfSLutz Donnerhacke #include "util.h" 3924ea1dbfSLutz Donnerhacke 4024ea1dbfSLutz Donnerhacke static void get_data(void *data, size_t len, void *ctx); 4124ea1dbfSLutz Donnerhacke 4224ea1dbfSLutz Donnerhacke ATF_TC(send_recv); 4324ea1dbfSLutz Donnerhacke ATF_TC_HEAD(send_recv, conf) 4424ea1dbfSLutz Donnerhacke { 4524ea1dbfSLutz Donnerhacke atf_tc_set_md_var(conf, "require.user", "root"); 4624ea1dbfSLutz Donnerhacke } 47*a664ade9SLutz Donnerhacke 4824ea1dbfSLutz Donnerhacke ATF_TC_BODY(send_recv, dummy) 4924ea1dbfSLutz Donnerhacke { 5024ea1dbfSLutz Donnerhacke char msg[] = "test"; 5124ea1dbfSLutz Donnerhacke int received; 5224ea1dbfSLutz Donnerhacke 5324ea1dbfSLutz Donnerhacke ng_init(); 5424ea1dbfSLutz Donnerhacke ng_connect(".", "a", ".", "b"); 5524ea1dbfSLutz Donnerhacke ng_register_data("b", get_data); 5624ea1dbfSLutz Donnerhacke ng_send_data("a", msg, sizeof(msg)); 5724ea1dbfSLutz Donnerhacke 5824ea1dbfSLutz Donnerhacke received = 0; 5924ea1dbfSLutz Donnerhacke ng_handle_events(50, &received); 6024ea1dbfSLutz Donnerhacke ATF_CHECK(received == 1); 6124ea1dbfSLutz Donnerhacke } 6224ea1dbfSLutz Donnerhacke 6324ea1dbfSLutz Donnerhacke ATF_TC(node); 6424ea1dbfSLutz Donnerhacke ATF_TC_HEAD(node, conf) 6524ea1dbfSLutz Donnerhacke { 6624ea1dbfSLutz Donnerhacke atf_tc_set_md_var(conf, "require.user", "root"); 6724ea1dbfSLutz Donnerhacke } 68*a664ade9SLutz Donnerhacke 6924ea1dbfSLutz Donnerhacke ATF_TC_BODY(node, dummy) 7024ea1dbfSLutz Donnerhacke { 7124ea1dbfSLutz Donnerhacke char msg[] = "test"; 7224ea1dbfSLutz Donnerhacke int received; 7324ea1dbfSLutz Donnerhacke 7424ea1dbfSLutz Donnerhacke ng_init(); 7524ea1dbfSLutz Donnerhacke ng_mkpeer(".", "a", "hub", "a"); 7624ea1dbfSLutz Donnerhacke ng_name("a", "test hub"); 7724ea1dbfSLutz Donnerhacke 7824ea1dbfSLutz Donnerhacke 7924ea1dbfSLutz Donnerhacke ng_connect(".", "b", "test hub:", "b"); 8024ea1dbfSLutz Donnerhacke ng_connect(".", "c", "test hub:", "c"); 8124ea1dbfSLutz Donnerhacke ng_register_data("a", get_data); 8224ea1dbfSLutz Donnerhacke ng_register_data("b", get_data); 8324ea1dbfSLutz Donnerhacke ng_register_data("c", get_data); 8424ea1dbfSLutz Donnerhacke 8524ea1dbfSLutz Donnerhacke received = 0; 8624ea1dbfSLutz Donnerhacke ng_send_data("a", msg, sizeof(msg)); 8724ea1dbfSLutz Donnerhacke ng_handle_events(50, &received); 8824ea1dbfSLutz Donnerhacke ATF_CHECK(received == 2); 8924ea1dbfSLutz Donnerhacke 9024ea1dbfSLutz Donnerhacke ng_rmhook(".", "b"); 9124ea1dbfSLutz Donnerhacke received = 0; 9224ea1dbfSLutz Donnerhacke ng_send_data("a", msg, sizeof(msg)); 9324ea1dbfSLutz Donnerhacke ng_handle_events(50, &received); 9424ea1dbfSLutz Donnerhacke ATF_CHECK(received == 1); 9524ea1dbfSLutz Donnerhacke 9624ea1dbfSLutz Donnerhacke ng_shutdown("test hub:"); 9724ea1dbfSLutz Donnerhacke } 9824ea1dbfSLutz Donnerhacke 9924ea1dbfSLutz Donnerhacke ATF_TC(message); 10024ea1dbfSLutz Donnerhacke ATF_TC_HEAD(message, conf) 10124ea1dbfSLutz Donnerhacke { 10224ea1dbfSLutz Donnerhacke atf_tc_set_md_var(conf, "require.user", "root"); 10324ea1dbfSLutz Donnerhacke } 104*a664ade9SLutz Donnerhacke 10524ea1dbfSLutz Donnerhacke ATF_TC_BODY(message, dummy) 10624ea1dbfSLutz Donnerhacke { 10724ea1dbfSLutz Donnerhacke ng_init(); 10824ea1dbfSLutz Donnerhacke ng_mkpeer(".", "a", "hub", "a"); 10924ea1dbfSLutz Donnerhacke ng_name("a", "test hub"); 11024ea1dbfSLutz Donnerhacke 11124ea1dbfSLutz Donnerhacke ng_send_msg("test hub:", "setpersistent"); 11224ea1dbfSLutz Donnerhacke ng_rmhook(".", "a"); 11324ea1dbfSLutz Donnerhacke 11424ea1dbfSLutz Donnerhacke ng_shutdown("test hub:"); 11524ea1dbfSLutz Donnerhacke } 11624ea1dbfSLutz Donnerhacke 11724ea1dbfSLutz Donnerhacke ATF_TC(same_name); 11824ea1dbfSLutz Donnerhacke ATF_TC_HEAD(same_name, conf) 11924ea1dbfSLutz Donnerhacke { 12024ea1dbfSLutz Donnerhacke atf_tc_set_md_var(conf, "require.user", "root"); 12124ea1dbfSLutz Donnerhacke } 122*a664ade9SLutz Donnerhacke 12324ea1dbfSLutz Donnerhacke ATF_TC_BODY(same_name, dummy) 12424ea1dbfSLutz Donnerhacke { 12524ea1dbfSLutz Donnerhacke ng_init(); 12624ea1dbfSLutz Donnerhacke ng_mkpeer(".", "a", "hub", "a"); 12724ea1dbfSLutz Donnerhacke ng_name("a", "test"); 12824ea1dbfSLutz Donnerhacke 12924ea1dbfSLutz Donnerhacke ng_errors(PASS); 13024ea1dbfSLutz Donnerhacke ng_connect(".", "a", ".", "b"); 13124ea1dbfSLutz Donnerhacke ATF_CHECK_ERRNO(EEXIST, 1); 13224ea1dbfSLutz Donnerhacke ng_connect(".", "b", ".", "b"); 13324ea1dbfSLutz Donnerhacke ATF_CHECK_ERRNO(EEXIST, 1); 13424ea1dbfSLutz Donnerhacke ng_name(".", "test"); 13524ea1dbfSLutz Donnerhacke ATF_CHECK_ERRNO(EADDRINUSE, 1); 13624ea1dbfSLutz Donnerhacke 13724ea1dbfSLutz Donnerhacke ng_errors(FAIL); 13824ea1dbfSLutz Donnerhacke ng_shutdown("test:"); 13924ea1dbfSLutz Donnerhacke } 14024ea1dbfSLutz Donnerhacke 14124ea1dbfSLutz Donnerhacke ATF_TC(queuelimit); 14224ea1dbfSLutz Donnerhacke ATF_TC_HEAD(queuelimit, conf) 14324ea1dbfSLutz Donnerhacke { 14424ea1dbfSLutz Donnerhacke atf_tc_set_md_var(conf, "require.user", "root"); 14524ea1dbfSLutz Donnerhacke } 146*a664ade9SLutz Donnerhacke 14724ea1dbfSLutz Donnerhacke ATF_TC_BODY(queuelimit, dummy) 14824ea1dbfSLutz Donnerhacke { 14924ea1dbfSLutz Donnerhacke int received, i; 15024ea1dbfSLutz Donnerhacke char msg[] = "test"; 15124ea1dbfSLutz Donnerhacke const int MAX = 1000; 15224ea1dbfSLutz Donnerhacke 15324ea1dbfSLutz Donnerhacke ng_init(); 15424ea1dbfSLutz Donnerhacke ng_connect(".", "a", ".", "b"); 15524ea1dbfSLutz Donnerhacke ng_register_data("b", get_data); 15624ea1dbfSLutz Donnerhacke 15724ea1dbfSLutz Donnerhacke ng_errors(PASS); 158*a664ade9SLutz Donnerhacke for (i = 0; i < MAX; i++) 159*a664ade9SLutz Donnerhacke { 16024ea1dbfSLutz Donnerhacke ng_send_data("a", msg, sizeof(msg)); 16124ea1dbfSLutz Donnerhacke if (errno != 0) 16224ea1dbfSLutz Donnerhacke break; 16324ea1dbfSLutz Donnerhacke /* no ng_handle_events -> messages stall */ 16424ea1dbfSLutz Donnerhacke } 16524ea1dbfSLutz Donnerhacke ng_errors(FAIL); 16624ea1dbfSLutz Donnerhacke printf("queued %d\n", i); 16724ea1dbfSLutz Donnerhacke sleep(3); 16824ea1dbfSLutz Donnerhacke 16924ea1dbfSLutz Donnerhacke received = 0; 17024ea1dbfSLutz Donnerhacke ng_handle_events(50, &received); 17124ea1dbfSLutz Donnerhacke ATF_CHECK(received > 100); 17224ea1dbfSLutz Donnerhacke ATF_CHECK(received == i); 17324ea1dbfSLutz Donnerhacke atf_tc_expect_fail("Queue full (%d)", i); 17424ea1dbfSLutz Donnerhacke ATF_CHECK(received == MAX); 17524ea1dbfSLutz Donnerhacke atf_tc_expect_pass(); 17624ea1dbfSLutz Donnerhacke } 17724ea1dbfSLutz Donnerhacke 17824ea1dbfSLutz Donnerhacke ATF_TP_ADD_TCS(basic) 17924ea1dbfSLutz Donnerhacke { 18024ea1dbfSLutz Donnerhacke ATF_TP_ADD_TC(basic, send_recv); 18124ea1dbfSLutz Donnerhacke ATF_TP_ADD_TC(basic, node); 18224ea1dbfSLutz Donnerhacke ATF_TP_ADD_TC(basic, message); 18324ea1dbfSLutz Donnerhacke ATF_TP_ADD_TC(basic, same_name); 18424ea1dbfSLutz Donnerhacke ATF_TP_ADD_TC(basic, queuelimit); 18524ea1dbfSLutz Donnerhacke 18624ea1dbfSLutz Donnerhacke return atf_no_error(); 18724ea1dbfSLutz Donnerhacke } 18824ea1dbfSLutz Donnerhacke 18924ea1dbfSLutz Donnerhacke static void 19024ea1dbfSLutz Donnerhacke get_data(void *data, size_t len, void *ctx) 19124ea1dbfSLutz Donnerhacke { 19224ea1dbfSLutz Donnerhacke int *cnt = ctx; 19324ea1dbfSLutz Donnerhacke 19424ea1dbfSLutz Donnerhacke (void)data; 19524ea1dbfSLutz Donnerhacke printf("Got %zu bytes of data.\n", len); 19624ea1dbfSLutz Donnerhacke (*cnt)++; 19724ea1dbfSLutz Donnerhacke } 198