#include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #include "monitor/monitor_private.h" #include "monitor/monitor_utils.h" #include "sds/sds.h" #ifdef __cplusplus } #endif TEST(MONITOR_UTIL, key_value_test) { struct stm_key_value *kv = NULL; char key_buf[16]; char value_buf[16]; for (int i = 0; i < 10; i++) { snprintf(key_buf, sizeof(key_buf), "key%d", i); snprintf(value_buf, sizeof(value_buf), "value%d", i); stm_cmd_key_value_append(&kv, key_buf, value_buf); } ASSERT_EQ(10, kv->tuple_num); for (int i = 0; i < 10; i++) { snprintf(key_buf, sizeof(key_buf), "key%d", i); snprintf(value_buf, sizeof(value_buf), "value%d", i); ASSERT_STREQ(key_buf, kv->tuple[i].key); ASSERT_STREQ(value_buf, kv->tuple[i].value); } stm_cmd_key_value_free(kv); } TEST(MONITOR_UTIL, stm_strncasecmp_exactly) { ASSERT_EQ(0, stm_strncasecmp_exactly("abc", "abc", 3)); ASSERT_EQ(0, stm_strncasecmp_exactly("abc", "ABC", 3)); ASSERT_EQ(-1, stm_strncasecmp_exactly("abc", "ABCD", 3)); ASSERT_EQ(-1, stm_strncasecmp_exactly("abc", "ABCD", 4)); ASSERT_EQ(-1, stm_strncasecmp_exactly(NULL, "ABCD", 4)); ASSERT_EQ(-1, stm_strncasecmp_exactly("abc", NULL, 4)); ASSERT_EQ(-1, stm_strncasecmp_exactly("", NULL, 4)); ASSERT_EQ(0, stm_strncasecmp_exactly("", "", 0)); } TEST(MONITOR_UTIL, time_range) { time_t time_range[2]; ASSERT_EQ(-1, stm_time_range_pton(NULL, 0, NULL)); ASSERT_EQ(-1, stm_time_range_pton(NULL, 0, time_range)); ASSERT_EQ(-1, stm_time_range_pton("last-7-days", 0, NULL)); ASSERT_EQ(-1, stm_time_range_pton("last", 0, time_range)); ASSERT_EQ(-1, stm_time_range_pton("last-", 0, time_range)); ASSERT_EQ(-1, stm_time_range_pton("last-1", 0, time_range)); ASSERT_EQ(-1, stm_time_range_pton("last-1-", 0, time_range)); ASSERT_EQ(-1, stm_time_range_pton("last-1-d", 0, time_range)); ASSERT_EQ(-1, stm_time_range_pton("last-1-da", 0, time_range)); ASSERT_EQ(-1, stm_time_range_pton("last-1-day", 0, time_range)); ASSERT_EQ(0, stm_time_range_pton("last-1-days", 0, time_range)); time_t now = 10000000; ASSERT_EQ(0, stm_time_range_pton("last-1-seconds", now, time_range)); ASSERT_EQ(now - 1, time_range[0]); ASSERT_EQ(now, time_range[1]); ASSERT_EQ(0, stm_time_range_pton("last-1-minutes", now, time_range)); ASSERT_EQ(now - 60, time_range[0]); ASSERT_EQ(now, time_range[1]); ASSERT_EQ(0, stm_time_range_pton("last-1-hours", now, time_range)); ASSERT_EQ(now - 60 * 60, time_range[0]); ASSERT_EQ(now, time_range[1]); ASSERT_EQ(0, stm_time_range_pton("last-1-days", now, time_range)); ASSERT_EQ(now - 24 * 60 * 60, time_range[0]); ASSERT_EQ(now, time_range[1]); now = 100; ASSERT_EQ(0, stm_time_range_pton("last-999-days", now, time_range)); ASSERT_EQ(0, time_range[0]); ASSERT_EQ(now, time_range[1]); now = 10000; ASSERT_EQ(0, stm_time_range_pton("last-1-seconds", now, time_range)); ASSERT_EQ(1, stm_time_in_range(now - 1, time_range)); ASSERT_EQ(0, stm_time_in_range(now - 10, time_range)); ASSERT_EQ(0, stm_time_in_range(now + 1, time_range)); ASSERT_EQ(0, stm_time_range_pton("last-1-minutes", now, time_range)); ASSERT_EQ(1, stm_time_in_range(now - 60, time_range)); ASSERT_EQ(0, stm_time_in_range(now - 61, time_range)); ASSERT_EQ(0, stm_time_in_range(now + 1, time_range)); ASSERT_EQ(0, stm_time_range_pton("last-1-hours", now, time_range)); ASSERT_EQ(1, stm_time_in_range(now - 60 * 60, time_range)); ASSERT_EQ(0, stm_time_in_range(now - 60 * 60 - 1, time_range)); ASSERT_EQ(0, stm_time_in_range(now + 1, time_range)); } TEST(MONITOR_UTIL, inet_pton) { unsigned int ipv4; struct in6_addr ipv6; ASSERT_EQ(0, stm_inet_pton(NULL, NULL, NULL)); ASSERT_EQ(0, stm_inet_pton("", NULL, NULL)); ASSERT_EQ(0, stm_inet_pton("1.1.1.1", NULL, &ipv6)); ASSERT_EQ(0, stm_inet_pton("1234::1", &ipv4, NULL)); ASSERT_EQ(AF_INET, stm_inet_pton("1.2.3.4", &ipv4, &ipv6)); ASSERT_EQ(0x04030201, ipv4); ASSERT_EQ(AF_INET, stm_inet_pton("1.2.3.0", &ipv4, &ipv6)); ASSERT_EQ(0x00030201, ipv4); struct in6_addr ipv6_2; inet_pton(AF_INET6, "1234::1", &ipv6_2); ASSERT_EQ(AF_INET6, stm_inet_pton("1234::1", &ipv4, &ipv6)); ASSERT_EQ(0, memcmp(&ipv6_2, &ipv6, sizeof(struct in6_addr))); inet_pton(AF_INET6, "1234::0", &ipv6_2); ASSERT_EQ(AF_INET6, stm_inet_pton("1234::0", &ipv4, &ipv6)); ASSERT_EQ(0, memcmp(&ipv6_2, &ipv6, sizeof(struct in6_addr))); } TEST(MONITOR_UTIL, ip_cidr_pton) { unsigned int ipv4, maskv4; struct in6_addr ipv6, maskv6; struct in6_addr expect_maskv6; ASSERT_EQ(0, stm_ip_cidr_pton(NULL, NULL, NULL, NULL, NULL)); ASSERT_EQ(0, stm_ip_cidr_pton("abcdefg", &ipv4, &maskv4, &ipv6, &maskv6)); ASSERT_EQ(0, stm_ip_cidr_pton("1.1.1.1", &ipv4, &maskv4, &ipv6, &maskv6)); ASSERT_EQ(0, stm_ip_cidr_pton("1.1.1.1/", &ipv4, &maskv4, &ipv6, &maskv6)); ASSERT_EQ(0, stm_ip_cidr_pton("1.1.1.1/xx", &ipv4, &maskv4, &ipv6, &maskv6)); ASSERT_EQ(AF_INET, stm_ip_cidr_pton("1.1.1.1/8", &ipv4, &maskv4, &ipv6, &maskv6)); ASSERT_EQ(0xFF000000, ntohl(maskv4)); ASSERT_EQ(AF_INET, stm_ip_cidr_pton("1.1.1.1/16", &ipv4, &maskv4, &ipv6, &maskv6)); ASSERT_EQ(0xFFFF0000, ntohl(maskv4)); ASSERT_EQ(AF_INET, stm_ip_cidr_pton("1.1.1.1/24", &ipv4, &maskv4, &ipv6, &maskv6)); ASSERT_EQ(0xFFFFFF00, ntohl(maskv4)); ASSERT_EQ(AF_INET, stm_ip_cidr_pton("1.1.1.1/32", &ipv4, &maskv4, &ipv6, &maskv6)); ASSERT_EQ(0xFFFFFFFF, maskv4); ASSERT_EQ(0, stm_ip_cidr_pton("1.1.1.1/33", &ipv4, &maskv4, &ipv6, &maskv6)); /* IPV6 */ ASSERT_EQ(AF_INET6, stm_ip_cidr_pton("::1/8", &ipv4, &maskv4, &ipv6, &maskv6)); memset(&expect_maskv6, 0, sizeof(struct in6_addr)); expect_maskv6.s6_addr[0] = 0xFF; ASSERT_EQ(0, memcmp(&expect_maskv6, &maskv6, sizeof(struct in6_addr))); ASSERT_EQ(AF_INET6, stm_ip_cidr_pton("::1/32", &ipv4, &maskv4, &ipv6, &maskv6)); memset(&expect_maskv6, 0, sizeof(struct in6_addr)); expect_maskv6.s6_addr[0] = 0xFF; expect_maskv6.s6_addr[1] = 0xFF; expect_maskv6.s6_addr[2] = 0xFF; expect_maskv6.s6_addr[3] = 0xFF; ASSERT_EQ(0, memcmp(&expect_maskv6, &maskv6, sizeof(struct in6_addr))); ASSERT_EQ(AF_INET6, stm_ip_cidr_pton("::1/128", &ipv4, &maskv4, &ipv6, &maskv6)); memset(&expect_maskv6, 0xFF, sizeof(struct in6_addr)); ASSERT_EQ(0, memcmp(&expect_maskv6, &maskv6, sizeof(struct in6_addr))); ASSERT_EQ(0, stm_ip_cidr_pton("1.1.1.1/129", &ipv4, &maskv4, &ipv6, &maskv6)); } TEST(MONITOR_UTIL, stm_ipv4_cidr_to_range) { uint32_t ipaddr, ipmask; uint32_t iprange[2]; inet_pton(AF_INET, "192.168.1.1", &ipaddr); inet_pton(AF_INET, "255.0.0.0", &ipmask); stm_ipv4_cidr_to_range(ipaddr, ipmask, iprange); ASSERT_EQ(iprange[0], ntohl(0xc0000000)); ASSERT_EQ(iprange[1], ntohl(0xc0FFFFFF)); inet_pton(AF_INET, "192.168.1.1", &ipaddr); inet_pton(AF_INET, "255.255.0.0", &ipmask); stm_ipv4_cidr_to_range(ipaddr, ipmask, iprange); ASSERT_EQ(iprange[0], ntohl(0xc0A80000)); ASSERT_EQ(iprange[1], ntohl(0xc0A8FFFF)); inet_pton(AF_INET, "192.168.1.1", &ipaddr); inet_pton(AF_INET, "255.128.0.0", &ipmask); stm_ipv4_cidr_to_range(ipaddr, ipmask, iprange); ASSERT_EQ(iprange[0], ntohl(0xc0800000)); ASSERT_EQ(iprange[1], ntohl(0xc0FFFFFF)); inet_pton(AF_INET, "192.168.1.1", &ipaddr); inet_pton(AF_INET, "255.255.255.0", &ipmask); stm_ipv4_cidr_to_range(ipaddr, ipmask, iprange); ASSERT_EQ(iprange[0], ntohl(0xc0A80100)); ASSERT_EQ(iprange[1], ntohl(0xc0A801FF)); inet_pton(AF_INET, "192.168.1.1", &ipaddr); inet_pton(AF_INET, "255.255.255.255", &ipmask); stm_ipv4_cidr_to_range(ipaddr, ipmask, iprange); ASSERT_EQ(iprange[0], ntohl(0xc0A80101)); ASSERT_EQ(iprange[1], ntohl(0xc0A80101)); } TEST(MONITOR_UTIL, stm_ipv4_cidr_string_to_range) { uint32_t ipv4, maskv4; struct in6_addr ipv6, maskv6; uint32_t ipv4_range[2]; ASSERT_EQ(AF_INET, stm_ip_cidr_pton("1.1.1.0/8", &ipv4, &maskv4, &ipv6, &maskv6)); stm_ipv4_cidr_to_range(ipv4, maskv4, ipv4_range); ASSERT_EQ(ipv4_range[0], ntohl(0x01000000)); ASSERT_EQ(ipv4_range[1], ntohl(0x01FFFFFF)); ASSERT_EQ(AF_INET, stm_ip_cidr_pton("1.1.1.0/24", &ipv4, &maskv4, &ipv6, &maskv6)); stm_ipv4_cidr_to_range(ipv4, maskv4, ipv4_range); ASSERT_EQ(ipv4_range[0], ntohl(0x01010100)); ASSERT_EQ(ipv4_range[1], ntohl(0x010101FF)); ASSERT_EQ(AF_INET, stm_ip_cidr_pton("1.2.3.4/32", &ipv4, &maskv4, &ipv6, &maskv6)); stm_ipv4_cidr_to_range(ipv4, maskv4, ipv4_range); ASSERT_EQ(ipv4_range[0], ntohl(0x01020304)); ASSERT_EQ(ipv4_range[1], ntohl(0x01020304)); } TEST(MONITOR_UTIL, stm_ipv6_cidr_string_to_range) { uint32_t ipv4, maskv4; struct in6_addr ipv6, maskv6; struct in6_addr ipv6_range[2]; struct in6_addr expect_addr; ASSERT_EQ(AF_INET6, stm_ip_cidr_pton("1234::abcd/8", &ipv4, &maskv4, &ipv6, &maskv6)); stm_ipv6_cidr_to_range(&ipv6, &maskv6, ipv6_range); inet_pton(AF_INET6, "1200::0", &expect_addr); ASSERT_EQ(0, memcmp(&ipv6_range[0], &expect_addr, sizeof(struct in6_addr))); inet_pton(AF_INET6, "12ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &expect_addr); ASSERT_EQ(0, memcmp(&ipv6_range[1], &expect_addr, sizeof(struct in6_addr))); ASSERT_EQ(AF_INET6, stm_ip_cidr_pton("1234::abcd/16", &ipv4, &maskv4, &ipv6, &maskv6)); stm_ipv6_cidr_to_range(&ipv6, &maskv6, ipv6_range); inet_pton(AF_INET6, "1234::0", &expect_addr); ASSERT_EQ(0, memcmp(&ipv6_range[0], &expect_addr, sizeof(struct in6_addr))); inet_pton(AF_INET6, "1234:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &expect_addr); ASSERT_EQ(0, memcmp(&ipv6_range[1], &expect_addr, sizeof(struct in6_addr))); ASSERT_EQ(AF_INET6, stm_ip_cidr_pton("1234::abcd/128", &ipv4, &maskv4, &ipv6, &maskv6)); stm_ipv6_cidr_to_range(&ipv6, &maskv6, ipv6_range); inet_pton(AF_INET6, "1234::abcd", &expect_addr); ASSERT_EQ(0, memcmp(&ipv6_range[0], &expect_addr, sizeof(struct in6_addr))); ASSERT_EQ(0, memcmp(&ipv6_range[1], &expect_addr, sizeof(struct in6_addr))); } TEST(MONITOR_UTIL, stm_ipv6_cidr_to_range) { struct in6_addr ipaddr, ipmask; struct in6_addr iprange[2]; struct in6_addr expect_range[2]; inet_pton(AF_INET6, "1234::abcd", &ipaddr); inet_pton(AF_INET6, "ff00::", &ipmask); // 8bit mask stm_ipv6_cidr_to_range(&ipaddr, &ipmask, iprange); inet_pton(AF_INET6, "1200::", &expect_range[0]); inet_pton(AF_INET6, "12ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &expect_range[1]); ASSERT_EQ(0, memcmp(&expect_range[0], &iprange[0], sizeof(struct in6_addr))); ASSERT_EQ(0, memcmp(&expect_range[1], &iprange[1], sizeof(struct in6_addr))); inet_pton(AF_INET6, "1234::abcd", &ipaddr); inet_pton(AF_INET6, "ffff::", &ipmask); // 16bit mask stm_ipv6_cidr_to_range(&ipaddr, &ipmask, iprange); inet_pton(AF_INET6, "1234::", &expect_range[0]); inet_pton(AF_INET6, "1234:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &expect_range[1]); ASSERT_EQ(0, memcmp(&expect_range[0], &iprange[0], sizeof(struct in6_addr))); ASSERT_EQ(0, memcmp(&expect_range[1], &iprange[1], sizeof(struct in6_addr))); inet_pton(AF_INET6, "1234::abcd", &ipaddr); inet_pton(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &ipmask); // 128bit mask stm_ipv6_cidr_to_range(&ipaddr, &ipmask, iprange); inet_pton(AF_INET6, "1234::abcd", &expect_range[0]); inet_pton(AF_INET6, "1234::abcd", &expect_range[1]); ASSERT_EQ(0, memcmp(&expect_range[0], &iprange[0], sizeof(struct in6_addr))); ASSERT_EQ(0, memcmp(&expect_range[1], &iprange[1], sizeof(struct in6_addr))); } TEST(MONITOR_UTIL, mem_rand) { char buf[10000]; srand(time(NULL)); stm_mem_fill_rand(buf, sizeof(buf), 31, 61); for (size_t i = 0; i < sizeof(buf); i++) { ASSERT_GE(buf[i], 31); ASSERT_LE(buf[i], 61); } } TEST(MONITOR_UTIL, timeout) { struct timeval start, end; start.tv_sec = 10000; start.tv_usec = 0; end = start; ASSERT_EQ(0, stm_timeout(start, end, 1)); end.tv_sec += 1; ASSERT_EQ(1, stm_timeout(start, end, 1)); end = start; end.tv_usec += 999999; ASSERT_EQ(0, stm_timeout(start, end, 1)); start.tv_sec = 10000; start.tv_usec = 900 * 1000; end.tv_sec = 10001; end.tv_usec = 1; ASSERT_EQ(0, stm_timeout(start, end, 1)); end.tv_usec += 999999; ASSERT_EQ(1, stm_timeout(start, end, 1)); } TEST(MONITOR_UTIL, parse_cli_arg) { struct monitor_cli_args expect_args[] = { {"-i", "--ip", 1, 0, NULL}, {"-p", "--port", 1, 0, NULL}, {"-t", "--timeout", 1, 0, NULL}, {"-e", "--exec", 1, 1, NULL}, }; int argc = 0; const char *cli_cmd = NULL; sds *argv = NULL; /* TEST: short options */ cli_cmd = "./monitor_cli -i 1.1.1.1 -p 8080 -t 30 -e a b c d e f g "; argv = sdssplitargs((char *)cli_cmd, &argc); EXPECT_EQ(0, monitor_util_parse_cmd_args(argc, (const char **)argv, expect_args, 4)); EXPECT_STREQ("1.1.1.1", expect_args[0].value); EXPECT_STREQ("8080", expect_args[1].value); EXPECT_STREQ("30", expect_args[2].value); EXPECT_STREQ("a b c d e f g", expect_args[3].value); sdsfree(expect_args[0].value); expect_args[0].value = NULL; sdsfree(expect_args[1].value); expect_args[1].value = NULL; sdsfree(expect_args[2].value); expect_args[2].value = NULL; sdsfree(expect_args[3].value); expect_args[3].value = NULL; sdsfreesplitres(argv, argc); /* TEST: long options */ cli_cmd = "./monitor_cli --ip 111.111.111.111 --port 80808 --timeout 300 --exec a b c d e f g "; argv = sdssplitargs((char *)cli_cmd, &argc); EXPECT_EQ(0, monitor_util_parse_cmd_args(argc, (const char **)argv, expect_args, 4)); EXPECT_STREQ("111.111.111.111", expect_args[0].value); EXPECT_STREQ("80808", expect_args[1].value); EXPECT_STREQ("300", expect_args[2].value); EXPECT_STREQ("a b c d e f g", expect_args[3].value); sdsfree(expect_args[0].value); expect_args[0].value = NULL; sdsfree(expect_args[1].value); expect_args[1].value = NULL; sdsfree(expect_args[2].value); expect_args[2].value = NULL; sdsfree(expect_args[3].value); expect_args[3].value = NULL; sdsfreesplitres(argv, argc); /* TEST: short options out of order */ cli_cmd = "./monitor_cli -e a b c d e f g -t 30 -i 1.1.1.1 -p 8080 "; argv = sdssplitargs((char *)cli_cmd, &argc); EXPECT_EQ(0, monitor_util_parse_cmd_args(argc, (const char **)argv, expect_args, 4)); EXPECT_STREQ("1.1.1.1", expect_args[0].value); EXPECT_STREQ("8080", expect_args[1].value); EXPECT_STREQ("30", expect_args[2].value); EXPECT_STREQ("a b c d e f g", expect_args[3].value); sdsfree(expect_args[0].value); expect_args[0].value = NULL; sdsfree(expect_args[1].value); expect_args[1].value = NULL; sdsfree(expect_args[2].value); expect_args[2].value = NULL; sdsfree(expect_args[3].value); expect_args[3].value = NULL; sdsfreesplitres(argv, argc); /* TEST: short options with quotes */ cli_cmd = "./monitor_cli -i 1.1.1.1 -p 8080 -t 30 -e \"a b c d e f g\""; argv = sdssplitargs((char *)cli_cmd, &argc); EXPECT_EQ(0, monitor_util_parse_cmd_args(argc, (const char **)argv, expect_args, 4)); EXPECT_STREQ("1.1.1.1", expect_args[0].value); EXPECT_STREQ("8080", expect_args[1].value); EXPECT_STREQ("30", expect_args[2].value); EXPECT_STREQ("a b c d e f g", expect_args[3].value); sdsfree(expect_args[0].value); expect_args[0].value = NULL; sdsfree(expect_args[1].value); expect_args[1].value = NULL; sdsfree(expect_args[2].value); expect_args[2].value = NULL; sdsfree(expect_args[3].value); expect_args[3].value = NULL; sdsfreesplitres(argv, argc); } TEST(MONITOR_UTIL, reply) { struct monitor_reply *reply; reply = monitor_reply_nil(); sds reply_str = monitor_reply_to_string(reply); EXPECT_STREQ(reply_str, "(nil)\r\n"); sdsfree(reply_str); monitor_reply_free(reply); reply = monitor_reply_new_string("hello, %s", "world"); reply_str = monitor_reply_to_string(reply); EXPECT_STREQ(reply_str, "hello, world\r\n"); sdsfree(reply_str); monitor_reply_free(reply); reply = monitor_reply_new_integer(12345); reply_str = monitor_reply_to_string(reply); EXPECT_STREQ(reply_str, "(integer) 12345\r\n"); sdsfree(reply_str); monitor_reply_free(reply); reply = monitor_reply_new_double(123.456); reply_str = monitor_reply_to_string(reply); EXPECT_STREQ(reply_str, "(double) 123.456000\r\n"); sdsfree(reply_str); monitor_reply_free(reply); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); return ret; }