This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
stellar-stellar/test/monitor/gtest_monitor_util.cpp
2024-11-07 18:30:58 +08:00

453 lines
17 KiB
C++

#include <unistd.h>
#include <stddef.h>
#include <getopt.h>
#include <arpa/inet.h>
#include <gtest/gtest.h>
#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;
}