From 8daa83a594a2e98f39d764422bfbdbc62c9efd44 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 19:20:00 +0200 Subject: Adding upstream version 2:4.20.0+dfsg. Signed-off-by: Daniel Baumann --- ctdb/tests/src/protocol_util_test.c | 417 ++++++++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 ctdb/tests/src/protocol_util_test.c (limited to 'ctdb/tests/src/protocol_util_test.c') diff --git a/ctdb/tests/src/protocol_util_test.c b/ctdb/tests/src/protocol_util_test.c new file mode 100644 index 0000000..4ffe58c --- /dev/null +++ b/ctdb/tests/src/protocol_util_test.c @@ -0,0 +1,417 @@ +/* + protocol utilities tests + + Copyright (C) Martin Schwenke 2016 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include "replace.h" +#include "system/network.h" + +#include + +#include "protocol/protocol_basic.c" +#include "protocol/protocol_types.c" +#include "protocol/protocol_util.c" + +/* + * Test parsing of IPs, conversion to string + */ + +static void test_sock_addr_to_string(const char *ip, bool with_port) +{ + ctdb_sock_addr sa; + const char *s; + int ret; + + ret = ctdb_sock_addr_from_string(ip, &sa, with_port); + assert(ret == 0); + s = ctdb_sock_addr_to_string(NULL, &sa, with_port); + assert(strcmp(ip, s) == 0); + talloc_free(discard_const(s)); +} + +static void test_sock_addr_from_string_bad(const char *ip, bool with_port) +{ + ctdb_sock_addr sa; + int ret; + + ret = ctdb_sock_addr_from_string(ip, &sa, with_port); + assert(ret == EINVAL); +} + +static void test_sock_addr_from_string_memcmp(const char *ip1, + const char* ip2) +{ + ctdb_sock_addr sa1, sa2; + int ret; + + ret = ctdb_sock_addr_from_string(ip1, &sa1, false); + assert(ret == 0); + ret = ctdb_sock_addr_from_string(ip2, &sa2, false); + assert(ret == 0); + ret = memcmp(&sa1, &sa2, sizeof(ctdb_sock_addr)); + assert(ret == 0); +} + +static void test_sock_addr_cmp(const char *ip1, const char *ip2, + bool with_port, int res) +{ + ctdb_sock_addr sa1, sa2; + int ret; + + ret = ctdb_sock_addr_from_string(ip1, &sa1, with_port); + assert(ret == 0); + ret = ctdb_sock_addr_from_string(ip2, &sa2, with_port); + assert(ret == 0); + ret = ctdb_sock_addr_cmp(&sa1, &sa2); + if (ret < 0) { + ret = -1; + } else if (ret > 0) { + ret = 1; + } + + assert(ret == res); +} + +/* + * Test parsing of IP/mask, conversion to string + */ + +static void test_sock_addr_mask_from_string(const char *ip_mask) +{ + ctdb_sock_addr sa; + unsigned mask; + const char *s, *t; + int ret; + + ret = ctdb_sock_addr_mask_from_string(ip_mask, &sa, &mask); + assert(ret == 0); + s = ctdb_sock_addr_to_string(NULL, &sa, false); + assert(s != NULL); + t = talloc_asprintf(s, "%s/%u", s, mask); + assert(strcmp(ip_mask, t) == 0); + talloc_free(discard_const(s)); +} + +static void test_sock_addr_mask_from_string_bad(const char *ip_mask) +{ + ctdb_sock_addr sa; + unsigned mask; + int ret; + + ret = ctdb_sock_addr_mask_from_string(ip_mask, &sa, &mask); + assert(ret == EINVAL); +} + +/* + * Test parsing of connection, conversion to string + */ + +static void test_connection_to_string(const char *conn_str) +{ + TALLOC_CTX *tmp_ctx; + struct ctdb_connection conn; + const char *s, *r; + int ret; + + tmp_ctx = talloc_new(NULL); + assert(tmp_ctx != NULL); + + /* + * Test non-reversed parse and render + */ + + ret = ctdb_connection_from_string(conn_str, false, &conn); + assert(ret == 0); + + s = ctdb_connection_to_string(tmp_ctx, &conn, false); + assert(s != NULL); + ret = strcmp(conn_str, s); + assert(ret == 0); + + talloc_free(discard_const(s)); + + /* + * Reversed render + */ + r = ctdb_connection_to_string(tmp_ctx, &conn, true); + assert(r != NULL); + ret = strcmp(conn_str, r); + assert(ret != 0); + + /* + * Reversed parse with forward render + */ + ret = ctdb_connection_from_string(conn_str, true, &conn); + assert(ret == 0); + + s = ctdb_connection_to_string(tmp_ctx, &conn, false); + assert(s != NULL); + ret = strcmp(r, s); + assert(ret == 0); + + talloc_free(discard_const(s)); + + /* + * Reversed parse and render + */ + ret = ctdb_connection_from_string(conn_str, true, &conn); + assert(ret == 0); + + s = ctdb_connection_to_string(tmp_ctx, &conn, true); + assert(s != NULL); + ret = strcmp(conn_str, s); + assert(ret == 0); + + talloc_free(tmp_ctx); +} + +static void test_connection_from_string_bad(const char *conn_str) +{ + struct ctdb_connection conn; + int ret; + + ret = ctdb_connection_from_string(conn_str, false, &conn); + assert(ret == EINVAL); +} + +/* + * Test connection list utilities + */ + +static void test_connection_list_read(const char *s1, const char *s2) +{ + TALLOC_CTX *tmp_ctx; + int pipefd[2]; + pid_t pid; + struct ctdb_connection_list *conn_list = NULL; + const char *t; + int ret; + + tmp_ctx = talloc_new(NULL); + assert(tmp_ctx != NULL); + + ret = pipe(pipefd); + assert(ret == 0); + + pid = fork(); + assert(pid != -1); + + if (pid == 0) { + close(pipefd[0]); + + ret = dup2(pipefd[1], STDOUT_FILENO); + assert(ret != -1); + + close(pipefd[1]); + + printf("%s", s1); + fflush(stdout); + + exit(0); + } + + close(pipefd[1]); + + ret = ctdb_connection_list_read(tmp_ctx, pipefd[0], false, &conn_list); + assert(ret == 0); + + close(pipefd[0]); + + ret = ctdb_connection_list_sort(conn_list); + assert(ret == 0); + + t = ctdb_connection_list_to_string(tmp_ctx, conn_list, false); + assert(t != NULL); + ret = strcmp(t, s2); + assert(ret == 0); + + talloc_free(tmp_ctx); +} + +static void test_connection_list_read_bad(const char *s1) +{ + TALLOC_CTX *tmp_ctx; + int pipefd[2]; + pid_t pid; + struct ctdb_connection_list *conn_list = NULL; + int ret; + + tmp_ctx = talloc_new(NULL); + assert(tmp_ctx != NULL); + + ret = pipe(pipefd); + assert(ret == 0); + + pid = fork(); + assert(pid != -1); + + if (pid == 0) { + close(pipefd[0]); + + ret = dup2(pipefd[1], STDOUT_FILENO); + assert(ret != -1); + + close(pipefd[1]); + + printf("%s", s1); + fflush(stdout); + + exit(0); + } + + close(pipefd[1]); + + ret = ctdb_connection_list_read(tmp_ctx, pipefd[0], false, &conn_list); + assert(ret == EINVAL); + + close(pipefd[0]); + + talloc_free(tmp_ctx); +} + +/* + * Use macros for these to make them easy to concatenate + */ + +#define CONN4 \ +"\ +127.0.0.1:12345 127.0.0.2:54321\n\ +127.0.0.2:12345 127.0.0.1:54322\n\ +127.0.0.1:12346 127.0.0.2:54323\n\ +127.0.0.2:12345 127.0.0.1:54324\n\ +127.0.0.1:12345 127.0.0.2:54325\n\ +" + +#define CONN4_SORT \ +"\ +127.0.0.1:12345 127.0.0.2:54321\n\ +127.0.0.1:12345 127.0.0.2:54325\n\ +127.0.0.1:12346 127.0.0.2:54323\n\ +127.0.0.2:12345 127.0.0.1:54322\n\ +127.0.0.2:12345 127.0.0.1:54324\n\ +" + +#define CONN6 \ +"\ +[fe80::6af7:28ff:fefa:d136]:12345 [fe80::6af7:28ff:fefa:d137]:54321\n\ +[fe80::6af7:28ff:fefa:d138]:12345 [fe80::6af7:28ff:fefa:d137]:54322\n\ +[fe80::6af7:28ff:fefa:d136]:12346 [fe80::6af7:28ff:fefa:d137]:54323\n\ +[fe80::6af7:28ff:fefa:d132]:12345 [fe80::6af7:28ff:fefa:d137]:54324\n\ +[fe80::6af7:28ff:fefa:d136]:12345 [fe80::6af7:28ff:fefa:d137]:54325\n\ +" + +#define CONN6_SORT \ +"\ +[fe80::6af7:28ff:fefa:d132]:12345 [fe80::6af7:28ff:fefa:d137]:54324\n\ +[fe80::6af7:28ff:fefa:d136]:12345 [fe80::6af7:28ff:fefa:d137]:54321\n\ +[fe80::6af7:28ff:fefa:d136]:12345 [fe80::6af7:28ff:fefa:d137]:54325\n\ +[fe80::6af7:28ff:fefa:d136]:12346 [fe80::6af7:28ff:fefa:d137]:54323\n\ +[fe80::6af7:28ff:fefa:d138]:12345 [fe80::6af7:28ff:fefa:d137]:54322\n\ +" + +int main(int argc, char *argv[]) +{ + test_sock_addr_to_string("0.0.0.0", false); + test_sock_addr_to_string("127.0.0.1", false); + test_sock_addr_to_string("::1", false); + test_sock_addr_to_string("192.168.2.1", false); + test_sock_addr_to_string("fe80::6af7:28ff:fefa:d136", false); + + test_sock_addr_to_string("0.0.0.0:0", true); + test_sock_addr_to_string("127.0.0.1:123", true); + test_sock_addr_to_string("[::1]:234", true); + test_sock_addr_to_string("192.168.2.1:123", true); + test_sock_addr_to_string("[fe80::6af7:28ff:fefa:d136]:234", true); + + test_sock_addr_from_string_bad("0.0.0", false); + test_sock_addr_from_string_bad("0.0.0:0", true); + test_sock_addr_from_string_bad("fe80::6af7:28ff:fefa:d136", true); + test_sock_addr_from_string_bad("junk", false); + test_sock_addr_from_string_bad("0.0.0.0:0 trailing junk", true); + + test_sock_addr_from_string_memcmp("127.0.0.1", "127.0.0.1"); + test_sock_addr_from_string_memcmp("fe80::6af7:28ff:fefa:d136", + "fe80::6af7:28ff:fefa:d136"); + test_sock_addr_from_string_memcmp("::ffff:192.0.2.128", "192.0.2.128"); + + test_sock_addr_cmp("127.0.0.1", "127.0.0.1" , false, 0); + test_sock_addr_cmp("127.0.0.1", "127.0.0.2" , false, -1); + test_sock_addr_cmp("127.0.0.2", "127.0.0.1" , false, 1); + test_sock_addr_cmp("127.0.1.2", "127.0.2.1" , false, -1); + test_sock_addr_cmp("127.0.2.1", "127.0.1.2" , false, 1); + test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136", "127.0.1.2" , false, 1); + test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136", + "fe80::6af7:28ff:fefa:d136" , false, 0); + test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136", + "fe80::6af7:28ff:fefa:d137" , false, -1); + test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136", + "fe80:0000:0000:0000:6af7:28ff:fefa:d136" , + false, 0); + test_sock_addr_cmp("::ffff:192.0.2.128", "192.0.2.128", false, 0); + + test_sock_addr_cmp("127.0.0.1:123", "127.0.0.1:124" , true, -1); + test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136:123", + "fe80::6af7:28ff:fefa:d136:122" , true, 1); + + /* + * Confirm equivalence of IPv6 sockets with and without + * square-brackets + */ + test_sock_addr_cmp("[::1]:234", "::1:234", true, 0); + test_sock_addr_cmp("[fe80::6af7:28ff:fefa:d136]:234", + "fe80::6af7:28ff:fefa:d136:234", + true, + 0); + /* Check IPv4-mapped IPv6 addresses */ + test_sock_addr_cmp("::ffff:172.16.0.27:977", + "172.16.0.27:977", + true, + 0); + test_sock_addr_cmp("[::ffff:172.16.0.27]:977", + "172.16.0.27:977", + true, + 0); + + test_sock_addr_mask_from_string("127.0.0.1/8"); + test_sock_addr_mask_from_string("::1/128"); + test_sock_addr_mask_from_string("fe80::6af7:28ff:fefa:d136/64"); + test_sock_addr_mask_from_string_bad("127.0.0.1"); + + test_connection_to_string("127.0.0.1:12345 127.0.0.2:54321"); + test_connection_to_string("[fe80::6af7:28ff:fefa:d137]:12345 " + "[fe80::6af7:28ff:fefa:d138]:54321"); + + test_connection_from_string_bad("127.0.0.1:12345 127.0.0.2:"); + test_connection_from_string_bad("127.0.0.1:12345"); + test_connection_from_string_bad("127.0.0.1:12345 " + "[fe80::6af7:28ff:fefa:d136]:122"); + test_connection_from_string_bad("Junk!"); + test_connection_from_string_bad("More junk"); + + test_connection_list_read(CONN4, CONN4_SORT); + test_connection_list_read(CONN6, CONN6_SORT); + test_connection_list_read(CONN4 CONN6, CONN4_SORT CONN6_SORT); + test_connection_list_read(CONN4 "# Comment\n\n# Comment\n" CONN6, + CONN4_SORT CONN6_SORT); + + test_connection_list_read_bad(CONN4 "# Comment\n\nJunk!!!\n" CONN6); + test_connection_list_read_bad(CONN4 + "# Comment\n\n127.0.0.1: 127.0.0.1:124\n" + CONN6); + + return 0; +} -- cgit v1.2.3