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_cmd_assistant.cpp
2024-11-07 18:30:58 +08:00

252 lines
12 KiB
C++

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stddef.h>
#include <getopt.h>
#include <gtest/gtest.h>
#include "monitor/monitor_cmd_assistant.h"
#include "sds/sds.h"
#include "linenoise/linenoise.h"
static struct monitor_reply *test_cmd_cb(int argc, char *argv[], void *user_arg)
{
(void)argc;
(void)argv;
(void)user_arg;
return NULL;
}
TEST(MONITOR_CMD_ASSISTANT, sds_compare)
{
int cli_argc, register_cmd_argc;
const char *cli = "show";
const char *register_cmd = "show";
sds *cli_array = sdssplitargs(cli, &cli_argc);
sds *register_cmd_array = sdssplitargs(register_cmd, &register_cmd_argc);
EXPECT_EQ(0, stm_cmd_assistant_sds_compare(cli_array, cli_argc, register_cmd_array, register_cmd_argc));
sdsfreesplitres(cli_array, cli_argc);
sdsfreesplitres(register_cmd_array, register_cmd_argc);
cli = "s";
register_cmd = "show";
cli_array = sdssplitargs(cli, &cli_argc);
register_cmd_array = sdssplitargs(register_cmd, &register_cmd_argc);
EXPECT_EQ(-1, stm_cmd_assistant_sds_compare(cli_array, cli_argc, register_cmd_array, register_cmd_argc));
sdsfreesplitres(cli_array, cli_argc);
sdsfreesplitres(register_cmd_array, register_cmd_argc);
cli = "show";
register_cmd = "show session";
cli_array = sdssplitargs(cli, &cli_argc);
register_cmd_array = sdssplitargs(register_cmd, &register_cmd_argc);
EXPECT_EQ(-1, stm_cmd_assistant_sds_compare(cli_array, cli_argc, register_cmd_array, register_cmd_argc));
sdsfreesplitres(cli_array, cli_argc);
sdsfreesplitres(register_cmd_array, register_cmd_argc);
cli = "show s";
register_cmd = "show session";
cli_array = sdssplitargs(cli, &cli_argc);
register_cmd_array = sdssplitargs(register_cmd, &register_cmd_argc);
EXPECT_EQ(-1, stm_cmd_assistant_sds_compare(cli_array, cli_argc, register_cmd_array, register_cmd_argc));
sdsfreesplitres(cli_array, cli_argc);
sdsfreesplitres(register_cmd_array, register_cmd_argc);
cli = "show session xxx yyy zzz";
register_cmd = "show session";
cli_array = sdssplitargs(cli, &cli_argc);
register_cmd_array = sdssplitargs(register_cmd, &register_cmd_argc);
EXPECT_EQ(1, stm_cmd_assistant_sds_compare(cli_array, cli_argc, register_cmd_array, register_cmd_argc));
sdsfreesplitres(cli_array, cli_argc);
sdsfreesplitres(register_cmd_array, register_cmd_argc);
}
TEST(MONITOR_CMD_ASSISTANT, cmd_register)
{
struct stm_cmd_assistant *cmd_aide = stm_cmd_assistant_new();
stm_cmd_assistant_register_cmd(cmd_aide, "get", (void *)"test_cmd_cb", (void *)"get args", "readonly", "key", "get xxx");
EXPECT_EQ((void *)"test_cmd_cb", stm_cmd_assistant_get_cb(cmd_aide, "get"));
EXPECT_EQ((void *)"get args", stm_cmd_assistant_get_user_arg(cmd_aide, "get"));
stm_cmd_assistant_register_cmd(cmd_aide, "show session", (void *)"show_session_cb", (void *)"show session args", "readonly", "id", "show session xxx");
EXPECT_EQ((void *)"show_session_cb", stm_cmd_assistant_get_cb(cmd_aide, "show session id 1"));
EXPECT_EQ((void *)"show session args", stm_cmd_assistant_get_user_arg(cmd_aide, "show session id 3"));
stm_cmd_assistant_register_cmd(cmd_aide, "show http", (void *)"show_http_cb", (void *)"show http args", "readonly", "id", "show http xxx");
EXPECT_EQ((void *)"show_http_cb", stm_cmd_assistant_get_cb(cmd_aide, "show http url a.b.com"));
EXPECT_EQ((void *)"show http args", stm_cmd_assistant_get_user_arg(cmd_aide, "show http url a.b.com"));
stm_cmd_assistant_register_cmd(cmd_aide, "show http stat", (void *)"show_http_stat_cb", (void *)"show http stat args", "readonly", "id", "show http stat xxx");
EXPECT_EQ((void *)"show_http_stat_cb", stm_cmd_assistant_get_cb(cmd_aide, "show http stat brief"));
EXPECT_EQ((void *)"show http stat args", stm_cmd_assistant_get_user_arg(cmd_aide, "show http stat brief"));
stm_cmd_assistant_register_cmd(cmd_aide, "show http stat brief limit", (void *)"show_http_stat_limit_cb", (void *)"show http stat limit args", "readonly", "id", "show http stat limit xxx");
EXPECT_EQ((void *)"show_http_stat_limit_cb", stm_cmd_assistant_get_cb(cmd_aide, "show http stat brief limit 1"));
EXPECT_EQ((void *)"show http stat limit args", stm_cmd_assistant_get_user_arg(cmd_aide, "show http stat brief limit 1"));
stm_cmd_assistant_free(cmd_aide);
}
TEST(MONITOR_CMD_ASSISTANT, serialize_dserialize)
{
struct stm_cmd_assistant *cmd_aide = stm_cmd_assistant_new();
stm_cmd_assistant_register_cmd(cmd_aide, "get", (void *)test_cmd_cb, NULL, "readonly", "key", "get xxx");
stm_cmd_assistant_register_cmd(cmd_aide, "set", (void *)test_cmd_cb, NULL, "write", "key value [NX] [EX seconds | PX milliseconds]", "set xxx");
stm_cmd_assistant_register_cmd(cmd_aide, "show session id", (void *)test_cmd_cb, NULL, "readonly", "value", "show session id xxx");
char *free_after_used = stm_cmd_assistant_serialize(cmd_aide);
printf("serialize : \n%s\n", free_after_used);
struct stm_cmd_assistant *cmd_aide_new = stm_cmd_assistant_new();
stm_cmd_assistant_dserialize(cmd_aide_new, free_after_used);
char *free_after_used2 = stm_cmd_assistant_serialize(cmd_aide_new);
printf("serialize : \n%s\n", free_after_used2);
ASSERT_STREQ(free_after_used, free_after_used2);
free(free_after_used);
free(free_after_used2);
stm_cmd_assistant_free(cmd_aide);
stm_cmd_assistant_free(cmd_aide_new);
}
struct gtest_cmd_completion_stat
{
linenoiseCompletions *lc;
int expect_completion_num;
int match_num;
int not_match_num;
const char *expect_completion_str[128];
};
struct gtest_cmd_completion_stat g_expect_stat = {};
static void gtest_cmd_completion_cb(void *arg, const char *candidate_completion)
{
struct gtest_cmd_completion_stat *local_expect_stat = (struct gtest_cmd_completion_stat *)arg;
for (int i = 0; i < local_expect_stat->expect_completion_num; i++)
{
if (0 == strcasecmp(local_expect_stat->expect_completion_str[i], candidate_completion))
{
// printf("gtest completion cb match : %s\n", candidate_completion);
local_expect_stat->match_num++;
return;
}
}
local_expect_stat->not_match_num++;
}
void gtest_linenoise_completion_cb(const char *line, linenoiseCompletions *lc)
{
g_expect_stat.lc = lc;
stm_cmd_assistant_input_line(stm_cmd_assistant_get(), line, (void *)&g_expect_stat);
}
TEST(MONITOR_CMD_ASSISTANT, cmd_completion)
{
struct stm_cmd_assistant *cmd_aide = stm_cmd_assistant_new();
stm_cmd_assistant_register_cmd(cmd_aide, "get", (void *)test_cmd_cb, NULL, "readonly", "key", "get xxx");
stm_cmd_assistant_register_cmd(cmd_aide, "set", (void *)test_cmd_cb, NULL, "write", "key value [NX] [EX seconds | PX milliseconds]", "set xxx");
stm_cmd_assistant_register_cmd(cmd_aide, "show session", (void *)test_cmd_cb, NULL, "readonly", "value", "show session xxx");
stm_cmd_assistant_register_cmd(cmd_aide, "show session id", (void *)test_cmd_cb, NULL, "readonly", "value", "show session id xxx");
stm_cmd_assistant_register_cmd(cmd_aide, "show http", (void *)test_cmd_cb, NULL, "readonly", "status ", "show http xxx");
stm_cmd_assistant_register_cmd(cmd_aide, "show ssl", (void *)test_cmd_cb, NULL, "readonly", "status", "show ssl xxx");
g_expect_stat.expect_completion_num = 4;
g_expect_stat.expect_completion_str[0] = "show session";
g_expect_stat.expect_completion_str[1] = "show session id";
g_expect_stat.expect_completion_str[2] = "show http";
g_expect_stat.expect_completion_str[3] = "show ssl";
stm_cmd_assistant_set_completion_cb(cmd_aide, gtest_cmd_completion_cb);
#if 0 // linenoise not call completion callback if input is not stdin (freopn stdin to a local file)
linenoiseSetCompletionCallback(gtest_linenoise_completion_cb);
FILE *fake_stdin_file = fopen("./__fake_stdin_file", "w+");
fprintf(fake_stdin_file, "show");
fflush(fake_stdin_file);
fclose(fake_stdin_file);
FILE *raw_stdin_ptr = stdin;
ASSERT_TRUE(freopen("./__fake_stdin_file", "r", stdin) != NULL);
g_expect_stat.not_match_num = 0;
g_expect_stat.match_num = 0;
char *line = linenoise("cli> ");
printf("fake cli input line : %s\n", line);
free(line);
stdin = raw_stdin_ptr;
#else
(void)stm_cmd_assistant_input_line(cmd_aide, "show", &g_expect_stat);
#endif
EXPECT_EQ(0, g_expect_stat.not_match_num);
EXPECT_EQ(g_expect_stat.match_num, g_expect_stat.expect_completion_num);
g_expect_stat.not_match_num = 0;
g_expect_stat.match_num = 0;
stm_cmd_assistant_input_line(cmd_aide, "sh", &g_expect_stat);
EXPECT_EQ(0, g_expect_stat.not_match_num);
EXPECT_EQ(g_expect_stat.match_num, g_expect_stat.expect_completion_num);
g_expect_stat.not_match_num = 0;
g_expect_stat.match_num = 0;
stm_cmd_assistant_input_line(cmd_aide, "show h", &g_expect_stat);
EXPECT_EQ(0, g_expect_stat.not_match_num);
EXPECT_EQ(1, g_expect_stat.match_num);
g_expect_stat.not_match_num = 0;
g_expect_stat.match_num = 0;
stm_cmd_assistant_input_line(cmd_aide, "show s", &g_expect_stat);
EXPECT_EQ(0, g_expect_stat.not_match_num);
EXPECT_EQ(3, g_expect_stat.match_num);
g_expect_stat.not_match_num = 0;
g_expect_stat.match_num = 0;
stm_cmd_assistant_input_line(cmd_aide, "showxxx", &g_expect_stat);
EXPECT_EQ(0, g_expect_stat.match_num);
stm_cmd_assistant_free(cmd_aide);
}
char *line_noise_hints_callback(const char *line, int *color, int *bold)
{
char *hints = (char *)stm_cmd_assistant_input_line_for_hints(stm_cmd_assistant_get(), line);
// all commands hints result preappend a blank space before hints
if (NULL == hints)
{
return NULL;
}
sds tmp = sdsnew(" ");
tmp = sdscat(tmp, hints);
*color = 90;
*bold = 0;
return tmp;
}
void line_noise_free_hints_callback(void *arg)
{
sdsfree((sds)arg);
}
TEST(MONITOR_CMD_ASSISTANT, cmd_hints)
{
struct stm_cmd_assistant *cmd_aide = stm_cmd_assistant_new();
stm_cmd_assistant_register_cmd(cmd_aide, "get", (void *)test_cmd_cb, NULL, "readonly", "key", "get xxx");
stm_cmd_assistant_register_cmd(cmd_aide, "set", (void *)test_cmd_cb, NULL, "write", "key value [NX] [EX seconds | PX milliseconds]", "set xxx");
stm_cmd_assistant_register_cmd(cmd_aide, "show session", (void *)test_cmd_cb, NULL, "readonly", "value", "show session");
stm_cmd_assistant_register_cmd(cmd_aide, "show session id", (void *)test_cmd_cb, NULL, "readonly", "id", "show session id xxx");
stm_cmd_assistant_register_cmd(cmd_aide, "show http", (void *)test_cmd_cb, NULL, "readonly", "status", "show http xxx");
stm_cmd_assistant_register_cmd(cmd_aide, "show ssl", (void *)test_cmd_cb, NULL, "readonly", "status", "show ssl xxx");
EXPECT_STREQ("key", stm_cmd_assistant_input_line_for_hints(cmd_aide, "get"));
EXPECT_STREQ("key value [NX] [EX seconds | PX milliseconds]", stm_cmd_assistant_input_line_for_hints(cmd_aide, "set"));
EXPECT_STREQ(NULL, stm_cmd_assistant_input_line_for_hints(cmd_aide, "xxx"));
EXPECT_STREQ(NULL, stm_cmd_assistant_input_line_for_hints(cmd_aide, "show"));
EXPECT_STREQ("value", stm_cmd_assistant_input_line_for_hints(cmd_aide, "show session"));
EXPECT_STREQ("id", stm_cmd_assistant_input_line_for_hints(cmd_aide, "show session id"));
EXPECT_STREQ("status", stm_cmd_assistant_input_line_for_hints(cmd_aide, "show http"));
EXPECT_STREQ("status", stm_cmd_assistant_input_line_for_hints(cmd_aide, "show ssl"));
}
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
}