diff --git a/drivers/at/Makefile.include b/drivers/at/Makefile.include index ce6c0e101a33b..c27e28e1c73bf 100644 --- a/drivers/at/Makefile.include +++ b/drivers/at/Makefile.include @@ -3,4 +3,3 @@ PSEUDOMODULES += at_urc_isr PSEUDOMODULES += at_urc_isr_lowest PSEUDOMODULES += at_urc_isr_medium PSEUDOMODULES += at_urc_isr_highest -PSEUDOMODULES += at_unit_tests diff --git a/drivers/at/at.c b/drivers/at/at.c index 993bf26160078..2a0f714ff2738 100644 --- a/drivers/at/at.c +++ b/drivers/at/at.c @@ -25,7 +25,6 @@ #define AT_PRINT_INCOMING (0) #endif -#define AT_RECV_EOL AT_RECV_EOL_1 AT_RECV_EOL_2 #if defined(MODULE_AT_URC) static int _check_urc(clist_node_t *node, void *arg); @@ -674,629 +673,20 @@ void at_dev_poweroff(at_dev_t *dev) uart_poweroff(dev->uart); } -#ifdef MODULE_AT_UNIT_TESTS - -#define UNIT_TEST_LONG_URC "+UNITTEST_LONG_URC_VEEERY_LONG" -#define UNIT_TEST_SHORT_URC "+U" -#define LONG_COMMAND "AT+COMMAND_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"\ - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" -#define COMMAND_WITH_EOL "AT+COMMAND_"AT_RECV_EOL"BLABLA"AT_RECV_EOL"BLA" - -#ifdef MODULE_AT_URC - -void unit_test_urc_long_handler(void *arg, char const *code) -{ - assert(strncmp(UNIT_TEST_LONG_URC, code, strlen(UNIT_TEST_LONG_URC)) == 0); - unsigned *urc_count = (unsigned *)arg; - *urc_count += 1; -} -void unit_test_urc_short_handler(void *arg, char const *code) -{ - assert(strncmp(UNIT_TEST_SHORT_URC, code, strlen(UNIT_TEST_SHORT_URC)) == 0); - unsigned *urc_count = (unsigned *)arg; - *urc_count += 1; -} -#endif - -static void inject_resp_str(at_dev_t *dev, char const *str) -{ - isrpipe_write(&dev->isrpipe, (unsigned char const *)str, strlen(str)); -} - -static void test_readline_or_echo(at_dev_t *dev) -{ - int res; - char resp_buf[64]; - at_drain(dev); - - res = read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); - assert(res == -ETIMEDOUT); - - inject_resp_str(dev, - "AT+COMMAND" - CONFIG_AT_SEND_EOL); - res = read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); - assert(res == 0); - res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, 1, 1000); - assert(res -ETIMEDOUT); - - inject_resp_str(dev, - "AT+COMMAND" - CONFIG_AT_SEND_EOL - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); - assert(res == 0); - res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); - assert(res > 0); - res = strcmp("OK", resp_buf); - assert(res == 0); - - inject_resp_str(dev, - "" - CONFIG_AT_SEND_EOL); - res = read_line_or_echo(dev, "", resp_buf, sizeof(resp_buf), 1000); - assert(res == -EINVAL); - - /* here we should have a rogue CONFIG_AT_SEND_EOL left in the buffer from before */ - inject_resp_str(dev, - LONG_COMMAND - CONFIG_AT_SEND_EOL - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = read_line_or_echo(dev, LONG_COMMAND, resp_buf, sizeof(resp_buf), 1000); - assert(res == 0); - res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); - assert(res > 0); - res = strcmp("OK", resp_buf); - assert(res == 0); - - inject_resp_str(dev, - AT_RECV_EOL - "+R" - AT_RECV_EOL); - res = read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); - assert(res > 0); - res = strcmp("+R", resp_buf); - assert(res == 0); - - inject_resp_str(dev, - CONFIG_AT_SEND_EOL - AT_RECV_EOL - "+R" - AT_RECV_EOL); - res = read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); - assert(res > 0); - res = strcmp("+R", resp_buf); - assert(res == 0); - - inject_resp_str(dev, - "+R" - AT_RECV_EOL); - res = read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); - assert(res > 0); - res = strcmp("+R", resp_buf); - assert(res == 0); - - inject_resp_str(dev, - COMMAND_WITH_EOL - CONFIG_AT_SEND_EOL); - res = read_line_or_echo(dev, COMMAND_WITH_EOL, resp_buf, sizeof(resp_buf), 1000); - assert(res == 0); - res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, 1, 1000); - assert(res -ETIMEDOUT); -} - -#ifdef MODULE_AT_URC -static void test_wait_echo(at_dev_t *dev) -{ - int res; - char resp_buf[64]; - - at_drain(dev); - - res = wait_echo(dev, "AT+COMMAND", 1000); - assert(res == -ETIMEDOUT); - - inject_resp_str(dev, "AT+COMMAND" CONFIG_AT_SEND_EOL); - res = wait_echo(dev, "AT+COMMAND", 1000); - assert(res == 0); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_LONG_URC - AT_RECV_EOL - "AT+COMMAND" - CONFIG_AT_SEND_EOL); - res = wait_echo(dev, "AT+COMMAND", 1000); - assert(res == 0); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_LONG_URC - AT_RECV_EOL - "AT+COMMAND" - CONFIG_AT_SEND_EOL - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = wait_echo(dev, "AT+COMMAND", 1000); - assert(res == 0); - res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); - assert(res > 0); - res = at_parse_resp(dev, resp_buf); - assert(res == 0); - - inject_resp_str(dev, - "" - CONFIG_AT_SEND_EOL); - res = wait_echo(dev, "", 1000); - assert(res == -EINVAL); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - "AT+COMMAND" - CONFIG_AT_SEND_EOL - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = wait_echo(dev, "AT+COMMAND", 1000); - assert(res == 0); - res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); - assert(res > 0); - res = at_parse_resp(dev, resp_buf); - assert(res == 0); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_LONG_URC - AT_RECV_EOL - "AT+COMMAND" - CONFIG_AT_SEND_EOL - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = wait_echo(dev, "AT+COMMAND", 1000); - assert(res == 0); - res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); - assert(res > 0); - res = at_parse_resp(dev, resp_buf); - assert(res == 0); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_LONG_URC - AT_RECV_EOL - COMMAND_WITH_EOL - CONFIG_AT_SEND_EOL - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = wait_echo(dev, COMMAND_WITH_EOL, 1000); - assert(res == 0); - res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); - assert(res > 0); - res = at_parse_resp(dev, resp_buf); - assert(res == 0); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_LONG_URC - AT_RECV_EOL - COMMAND_WITH_EOL - CONFIG_AT_SEND_EOL - "OK" - AT_RECV_EOL); - res = wait_echo(dev, COMMAND_WITH_EOL, 1000); - assert(res == 0); - res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); - assert(res > 0); - res = at_parse_resp(dev, resp_buf); - assert(res == 0); -} -#endif - -static void test_get_resp_with_prefix(at_dev_t *dev) -{ - int res; - char resp_buf[64]; - - at_drain(dev); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - "+RESPONSE: 123" - AT_RECV_EOL); - res = get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); - assert(res > 0); - res = strcmp("123", resp_buf); - assert(res == 0); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); - assert(res == 0); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL "+CME ERROR: 1" - AT_RECV_EOL); - res = get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); - assert(res == -AT_ERR_EXTENDED); - res = strncmp("1", dev->rp_buf, 1); - assert(res == 0); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - "ERROR" - AT_RECV_EOL); - res = get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); - assert(res == -1); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL); - res = get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); - assert(res == -ETIMEDOUT); - - inject_resp_str(dev, - "trash" - AT_RECV_EOL - "+RESPONSE: 123" - AT_RECV_EOL); - res = get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); - assert(res > 0); - res = strcmp("123", resp_buf); - assert(res == 0); -} - -static void test_read_lines(at_dev_t *dev) -{ - int res; - char resp_buf[62]; - char *p; - - at_drain(dev); - - inject_resp_str(dev, - AT_RECV_EOL - "+R1" - AT_RECV_EOL - "+R2" - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = get_lines(dev, resp_buf, sizeof(resp_buf), false, 1000); - assert(res > 0); - p = resp_buf; - p = strstr(resp_buf, "+R1"); - assert(p); - p = strstr(resp_buf, "+R2"); - assert(p); - p = strstr(resp_buf, "OK"); - assert(p); - - /* inconsistent EOL */ - inject_resp_str(dev, - "+R1" - AT_RECV_EOL - "+R2" - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = get_lines(dev, resp_buf, sizeof(resp_buf), false, 1000); - assert(res > 0); - p = resp_buf; - p = strstr(resp_buf, "+R1"); - assert(p); - p = strstr(resp_buf, "+R2"); - assert(p); - p = strstr(resp_buf, "OK"); - assert(p); - - /* URCs should get handled here */ - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - "ERROR" - AT_RECV_EOL); - res = get_lines(dev, resp_buf, sizeof(resp_buf), false, 1000); - assert(res == -1); - - /* URCs shouldn't get handled here. DCE answered neither OK nor error, - * something went terribly wrong anyway, fine to just drop them. */ - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL); - res = get_lines(dev, resp_buf, sizeof(resp_buf), false, 1000); - assert(res == -ETIMEDOUT); -} - -static void test_wait_prompt(at_dev_t *dev) -{ - int res; - char resp_buf[64]; - - at_drain(dev); - - inject_resp_str(dev, - AT_RECV_EOL - ">" - "123"); - res = wait_prompt(dev, 1000); - assert(res == 0); - res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, sizeof(resp_buf), 1000); - assert(res == 3); - res = strncmp("123", resp_buf, 3); - - inject_resp_str(dev, - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - ">" - "456"); - res = wait_prompt(dev, 1000); - assert(res == 0); - res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, sizeof(resp_buf), 1000); - assert(res == 3); - res = strncmp("456", resp_buf, 3); - - inject_resp_str(dev, - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - "ERROR" - AT_RECV_EOL); - res = wait_prompt(dev, 1000); - assert(res == -1); - - inject_resp_str(dev, - ">" - "123"); - res = wait_prompt(dev, 1000); - assert(res == 0); - res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, sizeof(resp_buf), 1000); - assert(res == 3); - res = strncmp("123", resp_buf, 3); -} - -static unsigned test_wait_ok(at_dev_t *dev) -{ - int res; - unsigned urc_cnt = 5; - - at_drain(dev); - - inject_resp_str(dev, - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = at_wait_ok(dev, 1000); - assert(res == 0); - - inject_resp_str(dev, - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - "ERROR" - AT_RECV_EOL); - res = at_wait_ok(dev, 1000); - assert(res == -1); - - inject_resp_str(dev, - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - "+CME ERROR: 2" - AT_RECV_EOL); - res = at_wait_ok(dev, 1000); - assert(res == -AT_ERR_EXTENDED); - - inject_resp_str(dev, - "trash" - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = at_wait_ok(dev, 1000); - assert(res == 0); -#ifdef CONFIG_AT_SEND_SKIP_ECHO - if (strcmp(AT_RECV_EOL, CONFIG_AT_SEND_EOL) == 0) { - /* Test echo handling when none expected */ - urc_cnt += 5; - at_drain(dev); - - inject_resp_str(dev, - UNIT_TEST_SHORT_URC - AT_RECV_EOL - "AT+COMMAND" - CONFIG_AT_SEND_EOL - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = at_wait_ok(dev, 1000); - assert(res == 0); - - inject_resp_str(dev, - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - "AT+COMMAND" - CONFIG_AT_SEND_EOL - "ERROR" - AT_RECV_EOL); - res = at_wait_ok(dev, 1000); - assert(res == -1); - - inject_resp_str(dev, - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - "AT+COMMAND" - CONFIG_AT_SEND_EOL - AT_RECV_EOL - "+CME ERROR: 2" - AT_RECV_EOL); - res = at_wait_ok(dev, 1000); - assert(res == -AT_ERR_EXTENDED); - - inject_resp_str(dev, - "trash" - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - "AT+COMMAND" - CONFIG_AT_SEND_EOL - AT_RECV_EOL - "OK" - AT_RECV_EOL); - res = at_wait_ok(dev, 1000); - assert(res == 0); - } -#endif - return urc_cnt; -} - -#ifdef MODULE_AT_URC -void test_at_process_urc(at_dev_t *dev) -{ - at_drain(dev); - - at_process_urc(dev, 1000); - - inject_resp_str(dev, - "trash" - AT_RECV_EOL - UNIT_TEST_SHORT_URC - AT_RECV_EOL - AT_RECV_EOL - UNIT_TEST_LONG_URC - AT_RECV_EOL); - at_process_urc(dev, 1000); -} -#endif - -static void test_urc_handling(at_dev_t *dev) -{ - at_drain(dev); - - unsigned urc_count_expected; -#ifdef MODULE_AT_URC - unsigned urc_count = 0; - at_urc_t urc_long = { - .arg = &urc_count, - .code = UNIT_TEST_LONG_URC, - .cb = unit_test_urc_long_handler - }; - at_urc_t urc_short = { - .arg = &urc_count, - .code = UNIT_TEST_SHORT_URC, - .cb = unit_test_urc_short_handler - }; - at_add_urc(dev, &urc_long); - at_add_urc(dev, &urc_short); -#endif - -#ifdef MODULE_AT_URC - test_wait_echo(dev); - assert(urc_count == 9); - urc_count = 0; -#endif - - test_get_resp_with_prefix(dev); -#ifdef MODULE_AT_URC - assert(urc_count == 5); - urc_count = 0; -#endif - - test_read_lines(dev); -#ifdef MODULE_AT_URC - assert(urc_count == 2); - urc_count = 0; -#endif - - test_wait_prompt(dev); -#ifdef MODULE_AT_URC - assert(urc_count == 2); - urc_count = 0; -#endif - - urc_count_expected = test_wait_ok(dev); -#ifdef MODULE_AT_URC - assert(urc_count == urc_count_expected); - urc_count = 0; - - test_at_process_urc(dev); - assert(urc_count == 2); - urc_count = 0; +#ifdef MODULE_EMBUNIT +/* Exports for unit tests */ +__attribute__((alias("read_line_or_echo"))) +int _emb_read_line_or_echo(at_dev_t *dev, char const *cmd, char *resp_buf, + size_t len, uint32_t timeout); +__attribute__((alias("get_lines"))) +ssize_t _emb_get_lines(at_dev_t *dev, char *resp_buf, size_t len, bool keep_eol, + uint32_t timeout); +__attribute__((alias("get_resp_with_prefix"))) +ssize_t _emb_get_resp_with_prefix(at_dev_t *dev, const char *resp_prefix, + char *resp_buf, size_t len, uint32_t timeout); +__attribute__((alias("wait_echo"))) +int _emb_wait_echo(at_dev_t *dev, char const *command, uint32_t timeout); +__attribute__((alias("wait_prompt"))) +int _emb_wait_prompt(at_dev_t *dev, uint32_t timeout); #endif -#ifdef MODULE_AT_URC - at_remove_urc(dev, &urc_long); - at_remove_urc(dev, &urc_short); -#endif - (void)urc_count_expected; -} - -void at_unit_tests(at_dev_t *dev) -{ - at_dev_poweroff(dev); - if (!IS_ACTIVE(CONFIG_AT_SEND_SKIP_ECHO)) { - test_readline_or_echo(dev); - } - test_urc_handling(dev); -} -#endif diff --git a/drivers/include/at.h b/drivers/include/at.h index 11a9020ecc94c..cb015ab2ad8b3 100644 --- a/drivers/include/at.h +++ b/drivers/include/at.h @@ -186,6 +186,8 @@ extern "C" { #endif /** @} */ +#define AT_RECV_EOL AT_RECV_EOL_1 AT_RECV_EOL_2 + #if defined(MODULE_AT_URC) || DOXYGEN /** * @brief Unsolicited result code callback @@ -605,18 +607,6 @@ void at_postprocess_urc(at_dev_t *dev, char *buf); void at_postprocess_urc_all(at_dev_t *dev, char *buf); #endif -#ifdef MODULE_AT_UNIT_TESTS -/** - * @brief Run unit tests. - * - * This will call @ref at_dev_power_off(). You need to re-initialize this device - * if you plan to further use it. - * - * @param[in] dev device to run the tests on - */ -void at_unit_tests(at_dev_t *dev); -#endif - #ifdef __cplusplus } #endif diff --git a/tests/drivers/at/Makefile b/tests/drivers/at/Makefile index 121ce38a7354a..288aa8e654215 100644 --- a/tests/drivers/at/Makefile +++ b/tests/drivers/at/Makefile @@ -2,7 +2,6 @@ include ../Makefile.drivers_common USEMODULE += shell USEMODULE += at -USEMODULE += at_unit_tests HANDLE_URC ?= 1 ECHO_ON ?= 1 diff --git a/tests/drivers/at/main.c b/tests/drivers/at/main.c index b9fb838830ca7..903e02f57c182 100644 --- a/tests/drivers/at/main.c +++ b/tests/drivers/at/main.c @@ -72,15 +72,6 @@ static int init(int argc, char **argv) return 1; } - at_unit_tests(&at_dev); - puts("Unit tests passed!\n"); - - /* at_unit_tests() de-activated the UART device. Re-init. */ - res = at_dev_init(&at_dev, &at_init_params); - if (res < 0) { - return 1; - } - return res; } diff --git a/tests/drivers/at/tests-with-config/test_all_configs.sh b/tests/drivers/at/tests-with-config/test_all_configs.sh index dc8750eeb1812..7ea3ed865d934 100755 --- a/tests/drivers/at/tests-with-config/test_all_configs.sh +++ b/tests/drivers/at/tests-with-config/test_all_configs.sh @@ -15,18 +15,25 @@ run_test() { echo " rcv EOL 2 = $rcv_eol_2" # make -j BOARD=native "HANDLE_URC=$handle_urc" "ECHO_ON=$echo" "SEND_EOL=\"$send_eol\"" "RECV_EOL_1=\"$rcv_eol_1\"" "RECV_EOL_2=\"$rcv_eol_2\"" compile-commands - make -j BOARD=native "HANDLE_URC=$handle_urc" "ECHO_ON=$echo" "SEND_EOL=\"$send_eol\"" "RECV_EOL_1=\"$rcv_eol_1\"" "RECV_EOL_2=\"$rcv_eol_2\"" + make -j BOARD=native "HANDLE_URC=$handle_urc" "ECHO_ON=$echo" "SEND_EOL=\"$send_eol\"" "RECV_EOL_1=\"$rcv_eol_1\"" "RECV_EOL_2=\"$rcv_eol_2\"" "AUTO_EXIT=1" tests-at # take /dev/ttyS0 as serial interface. It is only required s.t. UART # initialization succeeds and it gets turned off right away. - ./bin/native/tests_at.elf -c /dev/ttyS0 <<< "init 0 115200\n" + set +e + ./bin/native/tests_unittests.elf -c /dev/ttyS0 <<< "s\n" + if [ $? -ne 0 ] + then + echo "Test failed!" + exit 1 + fi + set -e } # set -x set -e SCRIPT=$(readlink -f "$0") -BASEDIR=$(dirname "$SCRIPT")/../ +BASEDIR=$(dirname "$SCRIPT")/../../../unittests cd "$BASEDIR" @@ -56,3 +63,5 @@ for urc_i in 0 1; do done done + +echo "All tests passed!" diff --git a/tests/unittests/tests-at/Makefile b/tests/unittests/tests-at/Makefile new file mode 100644 index 0000000000000..a59970b2199af --- /dev/null +++ b/tests/unittests/tests-at/Makefile @@ -0,0 +1,24 @@ +HANDLE_URC ?= 1 +ECHO_ON ?= 1 +SEND_EOL ?= "\\xd" +RECV_EOL_1 ?= "\\xd" +RECV_EOL_2 ?= "\\xa" +AUTO_EXIT ?= 0 + +ifeq ($(HANDLE_URC), 1) + USEMODULE += at_urc +endif + +ifeq ($(ECHO_ON), 0) + CFLAGS += -DCONFIG_AT_SEND_SKIP_ECHO=1 +endif + +ifeq ($(AUTO_EXIT), 1) + CFLAGS += -DNATIVE_AUTO_EXIT +endif + +CFLAGS += -DAT_RECV_EOL_1="\"$(RECV_EOL_1)\"" +CFLAGS += -DAT_RECV_EOL_2="\"$(RECV_EOL_2)\"" +CFLAGS += -DCONFIG_AT_SEND_EOL="\"$(SEND_EOL)\"" + +include $(RIOTBASE)/Makefile.base diff --git a/tests/unittests/tests-at/Makefile.include b/tests/unittests/tests-at/Makefile.include new file mode 100644 index 0000000000000..3fe824e968ac8 --- /dev/null +++ b/tests/unittests/tests-at/Makefile.include @@ -0,0 +1 @@ +USEMODULE += at diff --git a/tests/unittests/tests-at/tests-at.c b/tests/unittests/tests-at/tests-at.c new file mode 100644 index 0000000000000..19bc9cf4d01ae --- /dev/null +++ b/tests/unittests/tests-at/tests-at.c @@ -0,0 +1,688 @@ +/* + * Copyright (C) 2024 ML!PA GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/* clib includes */ + +#include "embUnit.h" + +#include "at.h" +#include "embUnit/AssertImpl.h" +#include "isrpipe/read_timeout.h" + +#include "tests-at.h" + +/* your macros */ + +/* your global variables */ +at_dev_t at_dev; +static char buf[256]; +// static char resp[1024]; +static char rp_buf[256]; +#ifdef MODULE_AT_URC +static unsigned urc_count = 0; + +void unit_test_urc_long_handler(void *arg, char const *code) +{ + assert(strncmp(UNIT_TEST_LONG_URC, code, strlen(UNIT_TEST_LONG_URC)) == 0); + unsigned *urc_count = (unsigned *)arg; + *urc_count += 1; +} + +void unit_test_urc_short_handler(void *arg, char const *code) +{ + assert(strncmp(UNIT_TEST_SHORT_URC, code, strlen(UNIT_TEST_SHORT_URC)) == 0); + unsigned *urc_count = (unsigned *)arg; + *urc_count += 1; +} + +at_urc_t urc_long = { + .arg = &urc_count, + .code = UNIT_TEST_LONG_URC, + .cb = unit_test_urc_long_handler +}; +at_urc_t urc_short = { + .arg = &urc_count, + .code = UNIT_TEST_SHORT_URC, + .cb = unit_test_urc_short_handler +}; +#endif + +static void set_up(void) +{ + at_dev_init_t at_init_params = { + .baudrate = 115200, + .rp_buf = rp_buf, + .rp_buf_size = sizeof(rp_buf), + .rx_buf = buf, + .rx_buf_size = sizeof(buf), + .uart = UART_DEV(0), + }; + int res = at_dev_init(&at_dev, &at_init_params); + /* check the UART initialization return value and respond as needed */ + if (res == UART_NODEV) { + TEST_FAIL("Invalid UART device given!"); + } + if (res == UART_NOBAUD) { + TEST_FAIL("Baudrate is not applicable!"); + } + + /* we don't use the serial device, make sure it doesn't clobber our rx buffer */ + at_dev_poweroff(&at_dev); + at_drain(&at_dev); + +#ifdef MODULE_AT_URC + at_add_urc(&at_dev, &urc_long); + at_add_urc(&at_dev, &urc_short); +#endif +} + +static void tear_down(void) +{ +#ifdef MODULE_AT_URC + at_remove_urc(&at_dev, &urc_long); + at_remove_urc(&at_dev, &urc_short); +#endif +} + +static void assert_urc_count(unsigned expected) +{ +#ifdef MODULE_AT_URC + TEST_ASSERT_EQUAL_INT(expected, urc_count); + urc_count = 0; +#endif + (void)expected; +} + +#define UNIT_TEST_LONG_URC "+UNITTEST_LONG_URC_VEEERY_LONG" +#define UNIT_TEST_SHORT_URC "+U" +#define LONG_COMMAND "AT+COMMAND_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"\ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +#define COMMAND_WITH_EOL "AT+COMMAND_"AT_RECV_EOL"BLABLA"AT_RECV_EOL"BLA" + + +int _emb_read_line_or_echo(at_dev_t *dev, char const *cmd, char *resp_buf, + size_t len, uint32_t timeout); +ssize_t _emb_get_lines(at_dev_t *dev, char *resp_buf, size_t len, bool keep_eol, + uint32_t timeout); +ssize_t _emb_get_resp_with_prefix(at_dev_t *dev, const char *resp_prefix, + char *resp_buf, size_t len, uint32_t timeout); +int _emb_wait_echo(at_dev_t *dev, char const *command, uint32_t timeout); +int _emb_wait_prompt(at_dev_t *dev, uint32_t timeout); + +static void inject_resp_str(at_dev_t *dev, char const *str) +{ + isrpipe_write(&dev->isrpipe, (unsigned char const *)str, strlen(str)); +} + +void test_readline_or_echo(void) +{ + int res; + char resp_buf[64]; + at_dev_t *dev = &at_dev; + at_drain(dev); + + res = _emb_read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res == -ETIMEDOUT); + + inject_resp_str(dev, + "AT+COMMAND" + CONFIG_AT_SEND_EOL); + res = _emb_read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res == 0); + res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, 1, 1000); + TEST_ASSERT(res -ETIMEDOUT); + + inject_resp_str(dev, + "AT+COMMAND" + CONFIG_AT_SEND_EOL + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = _emb_read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res == 0); + res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); + TEST_ASSERT(res > 0); + res = strcmp("OK", resp_buf); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + "" + CONFIG_AT_SEND_EOL); + res = _emb_read_line_or_echo(dev, "", resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res == -EINVAL); + + /* here we should have a rogue CONFIG_AT_SEND_EOL left in the buffer from before */ + inject_resp_str(dev, + LONG_COMMAND + CONFIG_AT_SEND_EOL + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = _emb_read_line_or_echo(dev, LONG_COMMAND, resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res == 0); + res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); + TEST_ASSERT(res > 0); + res = strcmp("OK", resp_buf); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + AT_RECV_EOL + "+R" + AT_RECV_EOL); + res = _emb_read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res > 0); + res = strcmp("+R", resp_buf); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + CONFIG_AT_SEND_EOL + AT_RECV_EOL + "+R" + AT_RECV_EOL); + res = _emb_read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res > 0); + res = strcmp("+R", resp_buf); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + "+R" + AT_RECV_EOL); + res = _emb_read_line_or_echo(dev, "AT+COMMAND", resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res > 0); + res = strcmp("+R", resp_buf); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + COMMAND_WITH_EOL + CONFIG_AT_SEND_EOL); + res = _emb_read_line_or_echo(dev, COMMAND_WITH_EOL, resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res == 0); + res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, 1, 1000); + TEST_ASSERT(res -ETIMEDOUT); +} + +void test_wait_echo(void) +{ + int res; + char resp_buf[64]; + at_dev_t *dev = &at_dev; + + at_drain(dev); + + res = _emb_wait_echo(dev, "AT+COMMAND", 1000); + TEST_ASSERT(res == -ETIMEDOUT); + + inject_resp_str(dev, "AT+COMMAND" CONFIG_AT_SEND_EOL); + res = _emb_wait_echo(dev, "AT+COMMAND", 1000); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_LONG_URC + AT_RECV_EOL + "AT+COMMAND" + CONFIG_AT_SEND_EOL); + res = _emb_wait_echo(dev, "AT+COMMAND", 1000); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_LONG_URC + AT_RECV_EOL + "AT+COMMAND" + CONFIG_AT_SEND_EOL + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = _emb_wait_echo(dev, "AT+COMMAND", 1000); + TEST_ASSERT(res == 0); + res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); + TEST_ASSERT(res > 0); + res = at_parse_resp(dev, resp_buf); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + "" + CONFIG_AT_SEND_EOL); + res = _emb_wait_echo(dev, "", 1000); + TEST_ASSERT(res == -EINVAL); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + "AT+COMMAND" + CONFIG_AT_SEND_EOL + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = _emb_wait_echo(dev, "AT+COMMAND", 1000); + TEST_ASSERT(res == 0); + res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); + TEST_ASSERT(res > 0); + res = at_parse_resp(dev, resp_buf); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_LONG_URC + AT_RECV_EOL + "AT+COMMAND" + CONFIG_AT_SEND_EOL + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = _emb_wait_echo(dev, "AT+COMMAND", 1000); + TEST_ASSERT(res == 0); + res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); + TEST_ASSERT(res > 0); + res = at_parse_resp(dev, resp_buf); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_LONG_URC + AT_RECV_EOL + COMMAND_WITH_EOL + CONFIG_AT_SEND_EOL + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = _emb_wait_echo(dev, COMMAND_WITH_EOL, 1000); + TEST_ASSERT(res == 0); + res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); + TEST_ASSERT(res > 0); + res = at_parse_resp(dev, resp_buf); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_LONG_URC + AT_RECV_EOL + COMMAND_WITH_EOL + CONFIG_AT_SEND_EOL + "OK" + AT_RECV_EOL); + res = _emb_wait_echo(dev, COMMAND_WITH_EOL, 1000); + TEST_ASSERT(res == 0); + res = at_readline_skip_empty(dev, resp_buf, sizeof(resp_buf), false, 1000); + TEST_ASSERT(res > 0); + res = at_parse_resp(dev, resp_buf); + TEST_ASSERT(res == 0); + + assert_urc_count(9); +} + +void test_get_resp_with_prefix(void) +{ + int res; + char resp_buf[64]; + at_dev_t *dev = &at_dev; + + at_drain(dev); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + "+RESPONSE: 123" + AT_RECV_EOL); + res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + TEST_ASSERT(res > 0); + res = strcmp("123", resp_buf); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL "+CME ERROR: 1" + AT_RECV_EOL); + res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + TEST_ASSERT(res == -AT_ERR_EXTENDED); + res = strncmp("1", dev->rp_buf, 1); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + "ERROR" + AT_RECV_EOL); + res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + TEST_ASSERT(res == -1); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL); + res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + TEST_ASSERT(res == -ETIMEDOUT); + + inject_resp_str(dev, + "trash" + AT_RECV_EOL + "+RESPONSE: 123" + AT_RECV_EOL); + res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + TEST_ASSERT(res > 0); + res = strcmp("123", resp_buf); + TEST_ASSERT(res == 0); + + assert_urc_count(5); +} + +void test_read_lines(void) +{ + int res; + char resp_buf[62]; + char *p; + at_dev_t *dev = &at_dev; + + at_drain(dev); + + inject_resp_str(dev, + AT_RECV_EOL + "+R1" + AT_RECV_EOL + "+R2" + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = _emb_get_lines(dev, resp_buf, sizeof(resp_buf), false, 1000); + TEST_ASSERT(res > 0); + p = resp_buf; + p = strstr(resp_buf, "+R1"); + TEST_ASSERT(p); + p = strstr(resp_buf, "+R2"); + TEST_ASSERT(p); + p = strstr(resp_buf, "OK"); + TEST_ASSERT(p); + + /* inconsistent EOL */ + inject_resp_str(dev, + "+R1" + AT_RECV_EOL + "+R2" + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = _emb_get_lines(dev, resp_buf, sizeof(resp_buf), false, 1000); + TEST_ASSERT(res > 0); + p = resp_buf; + p = strstr(resp_buf, "+R1"); + TEST_ASSERT(p); + p = strstr(resp_buf, "+R2"); + TEST_ASSERT(p); + p = strstr(resp_buf, "OK"); + TEST_ASSERT(p); + + /* URCs should get handled here */ + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + "ERROR" + AT_RECV_EOL); + res = _emb_get_lines(dev, resp_buf, sizeof(resp_buf), false, 1000); + TEST_ASSERT(res == -1); + + /* URCs shouldn't get handled here. DCE answered neither OK nor error, + * something went terribly wrong anyway, fine to just drop them. */ + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL); + res = _emb_get_lines(dev, resp_buf, sizeof(resp_buf), false, 1000); + TEST_ASSERT(res == -ETIMEDOUT); + + assert_urc_count(2); +} + +void test_wait_prompt(void) +{ + int res; + char resp_buf[64]; + at_dev_t *dev = &at_dev; + + at_drain(dev); + + inject_resp_str(dev, + AT_RECV_EOL + ">" + "123"); + res = _emb_wait_prompt(dev, 1000); + TEST_ASSERT(res == 0); + res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res == 3); + res = strncmp("123", resp_buf, 3); + + inject_resp_str(dev, + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + ">" + "456"); + res = _emb_wait_prompt(dev, 1000); + TEST_ASSERT(res == 0); + res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res == 3); + res = strncmp("456", resp_buf, 3); + + inject_resp_str(dev, + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + "ERROR" + AT_RECV_EOL); + res = _emb_wait_prompt(dev, 1000); + TEST_ASSERT(res == -1); + + inject_resp_str(dev, + ">" + "123"); + res = _emb_wait_prompt(dev, 1000); + TEST_ASSERT(res == 0); + res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, sizeof(resp_buf), 1000); + TEST_ASSERT(res == 3); + res = strncmp("123", resp_buf, 3); + TEST_ASSERT(res == 0); + + assert_urc_count(2); +} + +void test_wait_ok(void) +{ + int res; + unsigned urc_cnt = 5; + at_dev_t *dev = &at_dev; + + at_drain(dev); + + inject_resp_str(dev, + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = at_wait_ok(dev, 1000); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + "ERROR" + AT_RECV_EOL); + res = at_wait_ok(dev, 1000); + TEST_ASSERT(res == -1); + + inject_resp_str(dev, + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + "+CME ERROR: 2" + AT_RECV_EOL); + res = at_wait_ok(dev, 1000); + TEST_ASSERT(res == -AT_ERR_EXTENDED); + + inject_resp_str(dev, + "trash" + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = at_wait_ok(dev, 1000); + TEST_ASSERT(res == 0); +#ifdef CONFIG_AT_SEND_SKIP_ECHO + if (strcmp(AT_RECV_EOL, CONFIG_AT_SEND_EOL) == 0) { + /* Test echo handling when none expected */ + urc_cnt += 5; + at_drain(dev); + + inject_resp_str(dev, + UNIT_TEST_SHORT_URC + AT_RECV_EOL + "AT+COMMAND" + CONFIG_AT_SEND_EOL + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = at_wait_ok(dev, 1000); + TEST_ASSERT(res == 0); + + inject_resp_str(dev, + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + "AT+COMMAND" + CONFIG_AT_SEND_EOL + "ERROR" + AT_RECV_EOL); + res = at_wait_ok(dev, 1000); + TEST_ASSERT(res == -1); + + inject_resp_str(dev, + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + "AT+COMMAND" + CONFIG_AT_SEND_EOL + AT_RECV_EOL + "+CME ERROR: 2" + AT_RECV_EOL); + res = at_wait_ok(dev, 1000); + TEST_ASSERT(res == -AT_ERR_EXTENDED); + + inject_resp_str(dev, + "trash" + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + "AT+COMMAND" + CONFIG_AT_SEND_EOL + AT_RECV_EOL + "OK" + AT_RECV_EOL); + res = at_wait_ok(dev, 1000); + TEST_ASSERT(res == 0); + } +#endif /* CONFIG_AT_SEND_SKIP_ECHO */ + assert_urc_count(urc_cnt); +} + +#ifdef MODULE_AT_URC +void test_process_urc(void) +{ + at_dev_t *dev = &dev; + at_drain(dev); + + at_process_urc(dev, 1000); + + inject_resp_str(dev, + "trash" + AT_RECV_EOL + UNIT_TEST_SHORT_URC + AT_RECV_EOL + AT_RECV_EOL + UNIT_TEST_LONG_URC + AT_RECV_EOL); + at_process_urc(dev, 1000); + + assert_urc_count(2); +} +#endif /* MODULE_AT_URC */ + +void tests_at(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_readline_or_echo), + #ifndef CONFIG_AT_SEND_SKIP_ECHO + new_TestFixture(test_wait_echo), + #endif + new_TestFixture(test_get_resp_with_prefix), + new_TestFixture(test_read_lines), + new_TestFixture(test_wait_prompt), + new_TestFixture(test_wait_ok), + #ifdef MODULE_AT_URC + new_TestFixture(test_process_urc), + #endif + }; + + EMB_UNIT_TESTCALLER(at_tests, set_up, tear_down, fixtures); + + TESTS_RUN((Test *)&at_tests); + +#ifdef NATIVE_AUTO_EXIT + extern void (*real_exit)(int); + real_exit(TestRunnerHadErrors); +#endif +} diff --git a/tests/unittests/tests-at/tests-at.h b/tests/unittests/tests-at/tests-at.h new file mode 100644 index 0000000000000..62c0c17b347a8 --- /dev/null +++ b/tests/unittests/tests-at/tests-at.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 ML!PA GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @addtogroup unittests + * @{ + * + * @file + * @brief Unittests for the at module + * + * @author Mihai Renea + */ +#ifndef TESTS_AT_H +#define TESTS_AT_H +#include "embUnit/embUnit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Tests entry point. + */ +void tests_at(void); + +#ifdef __cplusplus +} +#endif + +#endif /* TESTS_AT_H */ +/** @} */