#include #include #include #include #include #include #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, ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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; }