| /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| * | |
| * Test console editing and history. | |
| */ | |
| #include "common.h" | |
| #include "console.h" | |
| #include "test_util.h" | |
| #include "timer.h" | |
| #include "util.h" | |
| static int cmd_1_call_cnt; | |
| static int cmd_2_call_cnt; | |
| static int command_test_1(int argc, char **argv) | |
| { | |
| cmd_1_call_cnt++; | |
| return EC_SUCCESS; | |
| } | |
| DECLARE_CONSOLE_COMMAND(test1, command_test_1, NULL, NULL, NULL); | |
| static int command_test_2(int argc, char **argv) | |
| { | |
| cmd_2_call_cnt++; | |
| return EC_SUCCESS; | |
| } | |
| DECLARE_CONSOLE_COMMAND(test2, command_test_2, NULL, NULL, NULL); | |
| /*****************************************************************************/ | |
| /* Test utilities */ | |
| enum arrow_key_t { | |
| ARROW_UP = 0, | |
| ARROW_DOWN, | |
| ARROW_RIGHT, | |
| ARROW_LEFT, | |
| }; | |
| static void arrow_key(enum arrow_key_t k, int repeat) | |
| { | |
| static char seq[4] = {0x1B, '[', 0, 0}; | |
| seq[2] = 'A' + k; | |
| while (repeat--) | |
| UART_INJECT(seq); | |
| } | |
| static void delete_key(void) | |
| { | |
| UART_INJECT("\x1b[3~"); | |
| } | |
| static void home_key(void) | |
| { | |
| UART_INJECT("\x1b[1~"); | |
| } | |
| static void end_key(void) | |
| { | |
| UART_INJECT("\x1bOF"); | |
| } | |
| static void ctrl_key(char c) | |
| { | |
| static char seq[2] = {0, 0}; | |
| seq[0] = c - '@'; | |
| UART_INJECT(seq); | |
| } | |
| /* | |
| * Helper function to compare multiline strings. When comparing, CR's are | |
| * ignored. | |
| */ | |
| static int compare_multiline_string(const char *s1, const char *s2) | |
| { | |
| do { | |
| while (*s1 == '\r') | |
| ++s1; | |
| while (*s2 == '\r') | |
| ++s2; | |
| if (*s1 != *s2) | |
| return 1; | |
| if (*s1 == 0 && *s2 == 0) | |
| break; | |
| ++s1; | |
| ++s2; | |
| } while (1); | |
| return 0; | |
| } | |
| /*****************************************************************************/ | |
| /* Tests */ | |
| static int test_backspace(void) | |
| { | |
| cmd_1_call_cnt = 0; | |
| UART_INJECT("testx\b1\n"); | |
| msleep(30); | |
| TEST_CHECK(cmd_1_call_cnt == 1); | |
| } | |
| static int test_insert_char(void) | |
| { | |
| cmd_1_call_cnt = 0; | |
| UART_INJECT("tet1"); | |
| arrow_key(ARROW_LEFT, 2); | |
| UART_INJECT("s\n"); | |
| msleep(30); | |
| TEST_CHECK(cmd_1_call_cnt == 1); | |
| } | |
| static int test_delete_char(void) | |
| { | |
| cmd_1_call_cnt = 0; | |
| UART_INJECT("testt1"); | |
| arrow_key(ARROW_LEFT, 1); | |
| UART_INJECT("\b\n"); | |
| msleep(30); | |
| TEST_CHECK(cmd_1_call_cnt == 1); | |
| } | |
| static int test_insert_delete_char(void) | |
| { | |
| cmd_1_call_cnt = 0; | |
| UART_INJECT("txet1"); | |
| arrow_key(ARROW_LEFT, 4); | |
| delete_key(); | |
| arrow_key(ARROW_RIGHT, 1); | |
| UART_INJECT("s\n"); | |
| msleep(30); | |
| TEST_CHECK(cmd_1_call_cnt == 1); | |
| } | |
| static int test_home_end_key(void) | |
| { | |
| cmd_1_call_cnt = 0; | |
| UART_INJECT("est"); | |
| home_key(); | |
| UART_INJECT("t"); | |
| end_key(); | |
| UART_INJECT("1\n"); | |
| msleep(30); | |
| TEST_CHECK(cmd_1_call_cnt == 1); | |
| } | |
| static int test_ctrl_k(void) | |
| { | |
| cmd_1_call_cnt = 0; | |
| UART_INJECT("test123"); | |
| arrow_key(ARROW_LEFT, 2); | |
| ctrl_key('K'); | |
| UART_INJECT("\n"); | |
| msleep(30); | |
| TEST_CHECK(cmd_1_call_cnt == 1); | |
| } | |
| static int test_history_up(void) | |
| { | |
| cmd_1_call_cnt = 0; | |
| UART_INJECT("test1\n"); | |
| msleep(30); | |
| arrow_key(ARROW_UP, 1); | |
| UART_INJECT("\n"); | |
| msleep(30); | |
| TEST_CHECK(cmd_1_call_cnt == 2); | |
| } | |
| static int test_history_up_up(void) | |
| { | |
| cmd_1_call_cnt = 0; | |
| cmd_2_call_cnt = 0; | |
| UART_INJECT("test1\n"); | |
| msleep(30); | |
| UART_INJECT("test2\n"); | |
| msleep(30); | |
| arrow_key(ARROW_UP, 2); | |
| UART_INJECT("\n"); | |
| msleep(30); | |
| TEST_CHECK(cmd_1_call_cnt == 2 && cmd_2_call_cnt == 1); | |
| } | |
| static int test_history_up_up_down(void) | |
| { | |
| cmd_1_call_cnt = 0; | |
| cmd_2_call_cnt = 0; | |
| UART_INJECT("test1\n"); | |
| msleep(30); | |
| UART_INJECT("test2\n"); | |
| msleep(30); | |
| arrow_key(ARROW_UP, 2); | |
| arrow_key(ARROW_DOWN, 1); | |
| UART_INJECT("\n"); | |
| msleep(30); | |
| TEST_CHECK(cmd_1_call_cnt == 1 && cmd_2_call_cnt == 2); | |
| } | |
| static int test_history_edit(void) | |
| { | |
| cmd_1_call_cnt = 0; | |
| cmd_2_call_cnt = 0; | |
| UART_INJECT("test1\n"); | |
| msleep(30); | |
| arrow_key(ARROW_UP, 1); | |
| UART_INJECT("\b2\n"); | |
| msleep(30); | |
| TEST_CHECK(cmd_1_call_cnt == 1 && cmd_2_call_cnt == 1); | |
| } | |
| static int test_history_stash(void) | |
| { | |
| cmd_1_call_cnt = 0; | |
| cmd_2_call_cnt = 0; | |
| UART_INJECT("test1\n"); | |
| msleep(30); | |
| UART_INJECT("test"); | |
| arrow_key(ARROW_UP, 1); | |
| arrow_key(ARROW_DOWN, 1); | |
| UART_INJECT("2\n"); | |
| msleep(30); | |
| TEST_CHECK(cmd_1_call_cnt == 1 && cmd_2_call_cnt == 1); | |
| } | |
| static int test_history_list(void) | |
| { | |
| const char *exp_output = "history\n" /* Input command */ | |
| "test3\n" /* Output 4 last commands */ | |
| "test4\n" | |
| "test5\n" | |
| "history\n" | |
| "> "; | |
| UART_INJECT("test1\n"); | |
| UART_INJECT("test2\n"); | |
| UART_INJECT("test3\n"); | |
| UART_INJECT("test4\n"); | |
| UART_INJECT("test5\n"); | |
| msleep(30); | |
| test_capture_console(1); | |
| UART_INJECT("history\n"); | |
| msleep(30); | |
| test_capture_console(0); | |
| TEST_ASSERT(compare_multiline_string(test_get_captured_console(), | |
| exp_output) == 0); | |
| return EC_SUCCESS; | |
| } | |
| static int test_output_channel(void) | |
| { | |
| UART_INJECT("chan save\n"); | |
| msleep(30); | |
| UART_INJECT("chan 0\n"); | |
| msleep(30); | |
| test_capture_console(1); | |
| cprintf(CC_CHARGER, "shouldn't see this\n"); | |
| cputs(CC_CHIPSET, "shouldn't see this either\n"); | |
| cflush(); | |
| test_capture_console(0); | |
| TEST_ASSERT(compare_multiline_string(test_get_captured_console(), | |
| "") == 0); | |
| UART_INJECT("chan restore\n"); | |
| msleep(30); | |
| test_capture_console(1); | |
| cprintf(CC_CHARGER, "see me\n"); | |
| cputs(CC_CHIPSET, "me as well\n"); | |
| cflush(); | |
| test_capture_console(0); | |
| TEST_ASSERT(compare_multiline_string(test_get_captured_console(), | |
| "see me\nme as well\n") == 0); | |
| return EC_SUCCESS; | |
| } | |
| void run_test(void) | |
| { | |
| test_reset(); | |
| RUN_TEST(test_backspace); | |
| RUN_TEST(test_insert_char); | |
| RUN_TEST(test_delete_char); | |
| RUN_TEST(test_insert_delete_char); | |
| RUN_TEST(test_home_end_key); | |
| RUN_TEST(test_ctrl_k); | |
| RUN_TEST(test_history_up); | |
| RUN_TEST(test_history_up_up); | |
| RUN_TEST(test_history_up_up_down); | |
| RUN_TEST(test_history_edit); | |
| RUN_TEST(test_history_stash); | |
| RUN_TEST(test_history_list); | |
| RUN_TEST(test_output_channel); | |
| test_print_result(); | |
| } |