277 lines
8.6 KiB
C++
277 lines
8.6 KiB
C++
#include <unistd.h>
|
|
#include <stddef.h>
|
|
#include <getopt.h>
|
|
#include <arpa/inet.h>
|
|
#include <gtest/gtest.h>
|
|
#include <pcap/pcap.h>
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
#include "stellar/stellar.h"
|
|
#include "monitor/monitor_private.h"
|
|
#include "sds/sds.h"
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#define TEST_PKT_DUMP_FILE_NAME "__gtest_stm_pkt_dump.pcap"
|
|
|
|
struct async_cmd_args
|
|
{
|
|
pthread_t tid;
|
|
const char *cmd;
|
|
int cmd_array_size;
|
|
sds *cmd_result_array;
|
|
int wait_thread_create_time_ms;
|
|
};
|
|
|
|
static sds *stellar_cli_exec_cmd(const char *command_str, int *result_size)
|
|
{
|
|
int ret;
|
|
sds *cmd_result_array = NULL;
|
|
char result[4096] = {};
|
|
FILE *fp = popen(command_str, "r");
|
|
if (NULL == fp)
|
|
{
|
|
return NULL;
|
|
}
|
|
ret = fread(result, 1, sizeof(result), fp);
|
|
if (ret > 0)
|
|
{
|
|
cmd_result_array = sdssplitlen(result, strlen(result), "\r\n", 1, result_size);
|
|
}
|
|
pclose(fp);
|
|
return cmd_result_array;
|
|
}
|
|
|
|
static void *async_cmd_run_thread(void *arg)
|
|
{
|
|
struct async_cmd_args *async_arg = (struct async_cmd_args *)arg;
|
|
async_arg->cmd_result_array = stellar_cli_exec_cmd(async_arg->cmd, &async_arg->cmd_array_size);
|
|
return NULL;
|
|
}
|
|
static void async_cmd_run(struct async_cmd_args *arg)
|
|
{
|
|
pthread_create(&arg->tid, NULL, async_cmd_run_thread, arg);
|
|
usleep(arg->wait_thread_create_time_ms * 1000);
|
|
}
|
|
static void async_cmd_wait(struct async_cmd_args *async_arg)
|
|
{
|
|
pthread_join(async_arg->tid, NULL);
|
|
}
|
|
|
|
// class MonitorServerMock : public testing::Test
|
|
// {
|
|
// public:
|
|
// static struct stellar *st;
|
|
// static pthread_t tid;
|
|
// static int thread_count;
|
|
// static int cmd_result_line_num;
|
|
// static int cmd_array_size;
|
|
// static sds *cmd_result_array;
|
|
|
|
// protected:
|
|
// static void SetUpTestCase()
|
|
// {
|
|
// printf("Gtest Stm Server: Setup Test Case Env...\n");
|
|
// st = stellar_new("./conf/stellar.toml", "./plugin/spec.toml", "./conf/log.toml");
|
|
// assert(st != NULL);
|
|
// }
|
|
// static void TearDownTestCase()
|
|
// {
|
|
// printf("Gtest Stm Server: Tear Down Test Case Env...\n");
|
|
// stellar_free(st);
|
|
// }
|
|
// };
|
|
// pthread_t MonitorServerMock::tid;
|
|
// int MonitorServerMock::thread_count;
|
|
// int MonitorServerMock::cmd_result_line_num;
|
|
// struct stellar *MonitorServerMock::st;
|
|
// int MonitorServerMock::cmd_array_size;
|
|
// sds *MonitorServerMock::cmd_result_array;
|
|
|
|
static int get_local_pcap_packet_number(const char *filename)
|
|
{
|
|
char cmd_buf[256] = {};
|
|
snprintf(cmd_buf, sizeof(cmd_buf), "tcpdump -r %s -n -nn -t -q | wc -l", filename);
|
|
int cmd_res_size;
|
|
sds *cmd_res = stellar_cli_exec_cmd(cmd_buf, &cmd_res_size);
|
|
|
|
int pkt_num = 0;
|
|
for (int i = 0; i < cmd_res_size; i++)
|
|
{
|
|
if (strstr(cmd_res[i], "reading from file") != NULL)
|
|
{
|
|
continue;
|
|
}
|
|
if (strstr(cmd_res[i], "tcpdump") != NULL)
|
|
{
|
|
continue;
|
|
}
|
|
if (isdigit(cmd_res[i][0]))
|
|
{
|
|
pkt_num = atoi(cmd_res[i]);
|
|
}
|
|
}
|
|
sdsfreesplitres(cmd_res, cmd_res_size);
|
|
return pkt_num;
|
|
}
|
|
|
|
static int get_netstat_num(const char *cmd)
|
|
{
|
|
int cmd_res_size;
|
|
sds *cmd_res = stellar_cli_exec_cmd(cmd, &cmd_res_size);
|
|
|
|
int pkt_num = 0;
|
|
for (int i = 0; i < cmd_res_size; i++)
|
|
{
|
|
if (isdigit(cmd_res[i][0]))
|
|
{
|
|
pkt_num = atoi(cmd_res[i]);
|
|
}
|
|
}
|
|
sdsfreesplitres(cmd_res, cmd_res_size);
|
|
return pkt_num;
|
|
}
|
|
|
|
TEST(MONITOR_PKT_DUMP, base)
|
|
{
|
|
struct async_cmd_args async_arg = {};
|
|
async_arg.wait_thread_create_time_ms = 100;
|
|
char cmd_buf[256] = {};
|
|
remove(TEST_PKT_DUMP_FILE_NAME);
|
|
const int expect_cap_pkt_num = 11;
|
|
struct stellar *st = stellar_new("./conf/stellar.toml");
|
|
ASSERT_TRUE(st != NULL);
|
|
snprintf(cmd_buf, sizeof(cmd_buf), "./stellar-dump -n -nn -c %d -s0 -w %s", expect_cap_pkt_num, TEST_PKT_DUMP_FILE_NAME);
|
|
async_arg.cmd = cmd_buf;
|
|
async_cmd_run(&async_arg);
|
|
stellar_run(st);
|
|
async_cmd_wait(&async_arg);
|
|
sdsfreesplitres(async_arg.cmd_result_array, async_arg.cmd_array_size);
|
|
|
|
int actual_cap_num = get_local_pcap_packet_number(TEST_PKT_DUMP_FILE_NAME);
|
|
EXPECT_EQ(expect_cap_pkt_num, actual_cap_num);
|
|
stellar_free(st);
|
|
}
|
|
|
|
TEST(MONITOR_PKT_DUMP, arg_ip_port)
|
|
{
|
|
struct async_cmd_args async_arg = {};
|
|
async_arg.wait_thread_create_time_ms = 100;
|
|
char cmd_buf[256] = {};
|
|
remove(TEST_PKT_DUMP_FILE_NAME);
|
|
struct stellar *st = stellar_new("./conf/stellar.toml");
|
|
ASSERT_TRUE(st != NULL);
|
|
|
|
const int expect_cap_pkt_num = 13;
|
|
snprintf(cmd_buf, sizeof(cmd_buf), "./stellar-dump -n -nn -c %d -i 127.0.0.1 -P 80 -s0 -w %s", expect_cap_pkt_num, TEST_PKT_DUMP_FILE_NAME);
|
|
async_arg.cmd = cmd_buf;
|
|
async_cmd_run(&async_arg);
|
|
stellar_run(st);
|
|
async_cmd_wait(&async_arg);
|
|
sdsfreesplitres(async_arg.cmd_result_array, async_arg.cmd_array_size);
|
|
|
|
int actual_cap_num = get_local_pcap_packet_number(TEST_PKT_DUMP_FILE_NAME);
|
|
EXPECT_EQ(expect_cap_pkt_num, actual_cap_num);
|
|
stellar_free(st);
|
|
}
|
|
|
|
TEST(MONITOR_PKT_DUMP, arg_bpf)
|
|
{
|
|
struct async_cmd_args async_arg = {};
|
|
async_arg.wait_thread_create_time_ms = 100;
|
|
char cmd_buf[256] = {};
|
|
remove(TEST_PKT_DUMP_FILE_NAME);
|
|
struct stellar *st = stellar_new("./conf/stellar.toml");
|
|
ASSERT_TRUE(st != NULL);
|
|
|
|
const int expect_cap_pkt_num = 33;
|
|
snprintf(cmd_buf, sizeof(cmd_buf), "./stellar-dump -n -nn -c %d host 172.16.0.203 and host 172.100.15.25 and udp port 1935 and udp port 52043 -s0 -U -w %s", expect_cap_pkt_num, TEST_PKT_DUMP_FILE_NAME);
|
|
async_arg.cmd = cmd_buf;
|
|
async_cmd_run(&async_arg);
|
|
stellar_run(st);
|
|
async_cmd_wait(&async_arg);
|
|
sdsfreesplitres(async_arg.cmd_result_array, async_arg.cmd_array_size);
|
|
|
|
int actual_cap_num = get_local_pcap_packet_number(TEST_PKT_DUMP_FILE_NAME);
|
|
EXPECT_EQ(expect_cap_pkt_num, actual_cap_num);
|
|
stellar_free(st);
|
|
}
|
|
|
|
TEST(MONITOR_PKT_DUMP, all_args)
|
|
{
|
|
struct async_cmd_args async_arg = {};
|
|
async_arg.wait_thread_create_time_ms = 100;
|
|
char cmd_buf[256] = {};
|
|
remove(TEST_PKT_DUMP_FILE_NAME);
|
|
struct stellar *st = stellar_new("./conf/stellar.toml");
|
|
ASSERT_TRUE(st != NULL);
|
|
|
|
const int expect_cap_pkt_num = 33;
|
|
snprintf(cmd_buf, sizeof(cmd_buf), "./stellar-dump -n -nn -c %d -i 127.0.0.1 -P 80 -g host 172.16.0.203 and host 172.100.15.25 and udp port 1935 and udp port 52043 -s0 -U -w %s", expect_cap_pkt_num, TEST_PKT_DUMP_FILE_NAME);
|
|
async_arg.cmd = cmd_buf;
|
|
async_cmd_run(&async_arg);
|
|
stellar_run(st);
|
|
async_cmd_wait(&async_arg);
|
|
sdsfreesplitres(async_arg.cmd_result_array, async_arg.cmd_array_size);
|
|
|
|
int actual_cap_num = get_local_pcap_packet_number(TEST_PKT_DUMP_FILE_NAME);
|
|
EXPECT_EQ(expect_cap_pkt_num, actual_cap_num);
|
|
stellar_free(st);
|
|
}
|
|
|
|
TEST(MONITOR_PKT_DUMP, too_many_clients)
|
|
{
|
|
#define MAX_CLIENT_NUM 1000
|
|
struct async_cmd_args async_arg[MAX_CLIENT_NUM] = {};
|
|
char cmd_buf[256] = {};
|
|
const int expect_cap_pkt_num = 1;
|
|
remove(TEST_PKT_DUMP_FILE_NAME);
|
|
struct stellar *st = stellar_new("./conf/stellar.toml");
|
|
ASSERT_TRUE(st != NULL);
|
|
|
|
snprintf(cmd_buf, sizeof(cmd_buf), "./stellar-dump -n -nn -q -t -c 1 udp port 5005 and udp port 39627 -w /dev/null"); // the last udp packet
|
|
|
|
for (int i = 0; i < MAX_CLIENT_NUM; i++)
|
|
{
|
|
async_arg[i].wait_thread_create_time_ms = 0;
|
|
async_arg[i].cmd = cmd_buf;
|
|
async_cmd_run(&async_arg[i]);
|
|
}
|
|
struct async_cmd_args save_pcap_async_arg = {};
|
|
save_pcap_async_arg.wait_thread_create_time_ms = 100;
|
|
char save_pcap_cmd_buf[256] = {};
|
|
snprintf(save_pcap_cmd_buf, sizeof(save_pcap_cmd_buf), "./stellar-dump -n -nn -q -t -c %d udp port 5005 and udp port 39627 -s0 -U -w %s", expect_cap_pkt_num, TEST_PKT_DUMP_FILE_NAME);
|
|
save_pcap_async_arg.cmd = save_pcap_cmd_buf;
|
|
async_cmd_run(&save_pcap_async_arg);
|
|
|
|
/* todo: how do I make sure all stellar-dump are started? */
|
|
while (get_netstat_num("netstat -anup | grep stellar | wc -l") < MAX_CLIENT_NUM + 1)
|
|
{
|
|
printf("### wait for all stellar-dump starting...\n");
|
|
sleep(1);
|
|
}
|
|
stellar_run(st);
|
|
|
|
for (int i = 0; i < MAX_CLIENT_NUM; i++)
|
|
{
|
|
async_cmd_wait(&async_arg[i]);
|
|
sdsfreesplitres(async_arg[i].cmd_result_array, async_arg[i].cmd_array_size);
|
|
}
|
|
async_cmd_wait(&save_pcap_async_arg);
|
|
sdsfreesplitres(save_pcap_async_arg.cmd_result_array, save_pcap_async_arg.cmd_array_size);
|
|
|
|
int actual_cap_num = get_local_pcap_packet_number(TEST_PKT_DUMP_FILE_NAME);
|
|
EXPECT_EQ(expect_cap_pkt_num, actual_cap_num);
|
|
stellar_free(st);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
testing::InitGoogleTest(&argc, argv);
|
|
int ret = RUN_ALL_TESTS();
|
|
return ret;
|
|
}
|