diff options
author | Albert Kharisov <ah@bright-box.com> | 2021-10-26 19:05:28 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-26 19:05:28 +0300 |
commit | 400d672e8118c0f97660ef7dabfc4062a9ea7f42 (patch) | |
tree | 2df8c5646bfca46d7fec5048822e29fdfe4c2494 /applications/tests | |
parent | f8542af6533e4c1d02a6f6779b88a0e52c10a6e6 (diff) |
[FL-1955] CLI RPC (#781)
- RPC: added CLI command to start session - all input bytes goes into RPC, all RPC output goes into VCP
- RPC: added command to close session (actually it only notifies transport layer)
- RPC: added recursive rmdir
- RPC: hard-coded listing for root directory (any, ext, int)
- Fixed CLI leak
- Fixed furi_record_delete leak
- Unit tests: repaired
- Unit tests: corrected output - remove excess, change dots with progress spinner
- Unit tests: added leak check
- Unit tests: SD mount check before start
Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
Diffstat (limited to 'applications/tests')
-rw-r--r-- | applications/tests/furi_record_test.c | 3 | ||||
-rw-r--r-- | applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c | 1 | ||||
-rw-r--r-- | applications/tests/minunit.h | 88 | ||||
-rw-r--r-- | applications/tests/minunit_test.c | 1 | ||||
-rw-r--r-- | applications/tests/rpc/rpc_test.c | 207 | ||||
-rw-r--r-- | applications/tests/test_index.c | 32 |
6 files changed, 242 insertions, 90 deletions
diff --git a/applications/tests/furi_record_test.c b/applications/tests/furi_record_test.c index 7f8a0507..e7eebe4b 100644 --- a/applications/tests/furi_record_test.c +++ b/applications/tests/furi_record_test.c @@ -11,7 +11,10 @@ void test_furi_create_open() { // 2. Open it void* record = furi_record_open("test/holding"); mu_assert_pointers_eq(record, &test_data); + + // 3. Close it furi_record_close("test/holding"); + // 4. Clean up furi_record_destroy("test/holding"); } diff --git a/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c b/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c index 908e196d..80f036b0 100644 --- a/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c +++ b/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c @@ -325,7 +325,6 @@ MU_TEST_SUITE(test_irda_decoder_encoder) { int run_minunit_test_irda_decoder_encoder() { MU_RUN_SUITE(test_irda_decoder_encoder); - MU_REPORT(); return MU_EXIT_CODE; } diff --git a/applications/tests/minunit.h b/applications/tests/minunit.h index 466cf9c1..b12a87ca 100644 --- a/applications/tests/minunit.h +++ b/applications/tests/minunit.h @@ -79,6 +79,9 @@ extern "C" { __attribute__((unused)) static void (*minunit_setup)(void) = NULL; __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; +void minunit_print_progress(void); +void minunit_print_fail(const char* error); + /* Definitions */ #define MU_TEST(method_name) static void method_name(void) #define MU_TEST_SUITE(suite_name) static void suite_name(void) @@ -108,8 +111,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_run++; \ if(minunit_status) { \ minunit_fail++; \ - printf("F"); \ - printf("\n%s\n", minunit_last_message); \ + minunit_print_fail(minunit_last_message); \ } fflush(stdout); \ if(minunit_teardown)(*minunit_teardown)();) @@ -142,7 +144,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; #test); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_fail(message) \ MU__SAFE_BLOCK(minunit_assert++; snprintf( \ @@ -169,7 +171,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; message); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_assert_int_eq(expected, result) \ MU__SAFE_BLOCK( \ @@ -187,7 +189,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_tmp_r); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_assert_int_not_eq(expected, result) \ MU__SAFE_BLOCK( \ @@ -204,7 +206,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_tmp_e); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_assert_int_greater_than(val, result) \ MU__SAFE_BLOCK( \ @@ -222,7 +224,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_tmp_e); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_assert_int_less_than(val, result) \ MU__SAFE_BLOCK( \ @@ -240,7 +242,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_tmp_e); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_assert_int_between(expected_lower, expected_upper, result) \ MU__SAFE_BLOCK( \ @@ -261,7 +263,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_tmp_m); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_assert_int_in(expected, array_length, result) \ MU__SAFE_BLOCK( \ @@ -288,7 +290,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_tmp_r); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_assert_double_eq(expected, result) \ MU__SAFE_BLOCK( \ @@ -309,7 +311,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_tmp_r); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_assert_double_greater_than(val, result) \ MU__SAFE_BLOCK( \ @@ -327,7 +329,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_tmp_e); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_assert_double_less_than(val, result) \ MU__SAFE_BLOCK( \ @@ -345,7 +347,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_tmp_e); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_assert_double_between(expected_lower, expected_upper, result) \ MU__SAFE_BLOCK( \ @@ -366,7 +368,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_tmp_m); \ minunit_status = 1; \ return; \ - } else { printf("."); }) + } else { minunit_print_progress(); }) #define mu_assert_string_eq(expected, result) \ MU__SAFE_BLOCK( \ @@ -386,39 +388,39 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; minunit_tmp_r); \ minunit_status = 1; \ return; \ - } else { printf("."); }) - -#define mu_assert_null(result) \ - MU__SAFE_BLOCK( \ - minunit_assert++; if(result == NULL) { printf("."); } else { \ - snprintf( \ - minunit_last_message, \ - MINUNIT_MESSAGE_LEN, \ - "%s failed:\n\t%s:%d: Expected result was not NULL", \ - __func__, \ - __FILE__, \ - __LINE__); \ - minunit_status = 1; \ - return; \ + } else { minunit_print_progress(); }) + +#define mu_assert_null(result) \ + MU__SAFE_BLOCK( \ + minunit_assert++; if(result == NULL) { minunit_print_progress(); } else { \ + snprintf( \ + minunit_last_message, \ + MINUNIT_MESSAGE_LEN, \ + "%s failed:\n\t%s:%d: Expected result was not NULL", \ + __func__, \ + __FILE__, \ + __LINE__); \ + minunit_status = 1; \ + return; \ }) -#define mu_assert_not_null(result) \ - MU__SAFE_BLOCK( \ - minunit_assert++; if(result != NULL) { printf("."); } else { \ - snprintf( \ - minunit_last_message, \ - MINUNIT_MESSAGE_LEN, \ - "%s failed:\n\t%s:%d: Expected result was not NULL", \ - __func__, \ - __FILE__, \ - __LINE__); \ - minunit_status = 1; \ - return; \ +#define mu_assert_not_null(result) \ + MU__SAFE_BLOCK( \ + minunit_assert++; if(result != NULL) { minunit_print_progress(); } else { \ + snprintf( \ + minunit_last_message, \ + MINUNIT_MESSAGE_LEN, \ + "%s failed:\n\t%s:%d: Expected result was not NULL", \ + __func__, \ + __FILE__, \ + __LINE__); \ + minunit_status = 1; \ + return; \ }) #define mu_assert_pointers_eq(pointer1, pointer2) \ MU__SAFE_BLOCK( \ - minunit_assert++; if(pointer1 == pointer2) { printf("."); } else { \ + minunit_assert++; if(pointer1 == pointer2) { minunit_print_progress(); } else { \ snprintf( \ minunit_last_message, \ MINUNIT_MESSAGE_LEN, \ @@ -432,7 +434,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; #define mu_assert_pointers_not_eq(pointer1, pointer2) \ MU__SAFE_BLOCK( \ - minunit_assert++; if(pointer1 != pointer2) { printf("."); } else { \ + minunit_assert++; if(pointer1 != pointer2) { minunit_print_progress(); } else { \ snprintf( \ minunit_last_message, \ MINUNIT_MESSAGE_LEN, \ @@ -603,4 +605,4 @@ __attribute__((unused)) static double mu_timer_cpu(void) { } #endif -#endif /* MINUNIT_MINUNIT_H */
\ No newline at end of file +#endif /* MINUNIT_MINUNIT_H */ diff --git a/applications/tests/minunit_test.c b/applications/tests/minunit_test.c index 8c94c845..1e71fd07 100644 --- a/applications/tests/minunit_test.c +++ b/applications/tests/minunit_test.c @@ -62,7 +62,6 @@ MU_TEST_SUITE(test_suite) { int run_minunit() { MU_RUN_SUITE(test_suite); - MU_REPORT(); return MU_EXIT_CODE; } diff --git a/applications/tests/rpc/rpc_test.c b/applications/tests/rpc/rpc_test.c index 18f1c7a8..3f59cebf 100644 --- a/applications/tests/rpc/rpc_test.c +++ b/applications/tests/rpc/rpc_test.c @@ -56,33 +56,26 @@ static void test_rpc_compare_messages(PB_Main* result, PB_Main* expected); static void test_rpc_decode_and_compare(MsgList_t expected_msg_list); static void test_rpc_free_msg_list(MsgList_t msg_list); -static void test_rpc_storage_setup(void) { +static void test_rpc_setup(void) { furi_assert(!rpc); furi_assert(!session); furi_assert(!output_stream); rpc = furi_record_open("rpc"); for(int i = 0; !session && (i < 10000); ++i) { - session = rpc_open_session(rpc); + session = rpc_session_open(rpc); delay(1); } furi_assert(session); - Storage* fs_api = furi_record_open("storage"); - clean_directory(fs_api, TEST_DIR_NAME); - furi_record_close("storage"); - output_stream = xStreamBufferCreate(1000, 1); mu_assert(session, "failed to start session"); - rpc_set_send_bytes_callback(session, output_bytes_callback, output_stream); + rpc_session_set_send_bytes_callback(session, output_bytes_callback); + rpc_session_set_context(session, output_stream); } -static void test_rpc_storage_teardown(void) { - Storage* fs_api = furi_record_open("storage"); - clean_directory(fs_api, TEST_DIR_NAME); - furi_record_close("storage"); - - rpc_close_session(session); +static void test_rpc_teardown(void) { + rpc_session_close(session); furi_record_close("rpc"); vStreamBufferDelete(output_stream); ++command_id; @@ -91,6 +84,22 @@ static void test_rpc_storage_teardown(void) { session = NULL; } +static void test_rpc_storage_setup(void) { + test_rpc_setup(); + + Storage* fs_api = furi_record_open("storage"); + clean_directory(fs_api, TEST_DIR_NAME); + furi_record_close("storage"); +} + +static void test_rpc_storage_teardown(void) { + Storage* fs_api = furi_record_open("storage"); + clean_directory(fs_api, TEST_DIR_NAME); + furi_record_close("storage"); + + test_rpc_teardown(); +} + static void clean_directory(Storage* fs_api, const char* clean_dir) { furi_assert(fs_api); furi_assert(clean_dir); @@ -197,10 +206,12 @@ static void test_rpc_create_simple_message( const char* str, uint32_t command_id) { furi_assert(message); - furi_assert(str); - char* str_copy = furi_alloc(strlen(str) + 1); - strcpy(str_copy, str); + char* str_copy = NULL; + if(str) { + str_copy = furi_alloc(strlen(str) + 1); + strcpy(str_copy, str); + } message->command_id = command_id; message->command_status = PB_CommandStatus_OK; message->cb_content.funcs.encode = NULL; @@ -292,7 +303,7 @@ static void test_rpc_encode_and_feed_one(PB_Main* request) { size_t bytes_left = ostream.bytes_written; uint8_t* buffer_ptr = buffer; do { - size_t bytes_sent = rpc_feed_bytes(session, buffer_ptr, bytes_left, 1000); + size_t bytes_sent = rpc_session_feed(session, buffer_ptr, bytes_left, 1000); mu_check(bytes_sent > 0); bytes_left -= bytes_sent; @@ -402,6 +413,38 @@ static bool test_rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_ return (count == bytes_received); } +static void + test_rpc_storage_list_create_expected_list_root(MsgList_t msg_list, uint32_t command_id) { + PB_Main* message = MsgList_push_new(msg_list); + message->has_next = false; + message->cb_content.funcs.encode = NULL; + message->command_id = command_id; + message->which_content = PB_Main_storage_list_response_tag; + + message->content.storage_list_response.file_count = 3; + message->content.storage_list_response.file[0].data = NULL; + message->content.storage_list_response.file[1].data = NULL; + message->content.storage_list_response.file[2].data = NULL; + + message->content.storage_list_response.file[0].size = 0; + message->content.storage_list_response.file[1].size = 0; + message->content.storage_list_response.file[2].size = 0; + + message->content.storage_list_response.file[0].type = PB_Storage_File_FileType_DIR; + message->content.storage_list_response.file[1].type = PB_Storage_File_FileType_DIR; + message->content.storage_list_response.file[2].type = PB_Storage_File_FileType_DIR; + + char* str = furi_alloc(4); + strcpy(str, "any"); + message->content.storage_list_response.file[0].name = str; + str = furi_alloc(4); + strcpy(str, "int"); + message->content.storage_list_response.file[1].name = str; + str = furi_alloc(4); + strcpy(str, "ext"); + message->content.storage_list_response.file[2].name = str; +} + static void test_rpc_storage_list_create_expected_list( MsgList_t msg_list, const char* path, @@ -505,7 +548,11 @@ static void test_rpc_storage_list_run(const char* path, uint32_t command_id) { MsgList_init(expected_msg_list); test_rpc_create_simple_message(&request, PB_Main_storage_list_request_tag, path, command_id); - test_rpc_storage_list_create_expected_list(expected_msg_list, path, command_id); + if(!strcmp(path, "/")) { + test_rpc_storage_list_create_expected_list_root(expected_msg_list, command_id); + } else { + test_rpc_storage_list_create_expected_list(expected_msg_list, path, command_id); + } test_rpc_encode_and_feed_one(&request); test_rpc_decode_and_compare(expected_msg_list); @@ -514,6 +561,7 @@ static void test_rpc_storage_list_run(const char* path, uint32_t command_id) { } MU_TEST(test_storage_list) { + test_rpc_storage_list_run("/", ++command_id); test_rpc_storage_list_run("/ext/nfc", ++command_id); test_rpc_storage_list_run("/int", ++command_id); @@ -597,12 +645,23 @@ static void test_storage_read_run(const char* path, uint32_t command_id) { test_rpc_free_msg_list(expected_msg_list); } +static bool test_is_exists(const char* path) { + Storage* fs_api = furi_record_open("storage"); + FileInfo fileinfo; + FS_Error result = storage_common_stat(fs_api, path, &fileinfo); + + furi_check((result == FSE_OK) || (result == FSE_NOT_EXIST)); + + return result == FSE_OK; +} + static void test_create_dir(const char* path) { Storage* fs_api = furi_record_open("storage"); FS_Error error = storage_common_mkdir(fs_api, path); (void)error; furi_assert((error == FSE_OK) || (error == FSE_EXIST)); furi_record_close("storage"); + furi_check(test_is_exists(path)); } static void test_create_file(const char* path, size_t size) { @@ -625,6 +684,7 @@ static void test_create_file(const char* path, size_t size) { storage_file_free(file); furi_record_close("storage"); + furi_check(test_is_exists(path)); } MU_TEST(test_storage_read) { @@ -829,12 +889,17 @@ MU_TEST(test_storage_interrupt_continuous_another_system) { test_rpc_free_msg_list(expected_msg_list); } -static void test_storage_delete_run(const char* path, size_t command_id, PB_CommandStatus status) { +static void test_storage_delete_run( + const char* path, + size_t command_id, + PB_CommandStatus status, + bool recursive) { PB_Main request; MsgList_t expected_msg_list; MsgList_init(expected_msg_list); test_rpc_create_simple_message(&request, PB_Main_storage_delete_request_tag, path, command_id); + request.content.storage_delete_request.recursive = recursive; test_rpc_add_empty_to_list(expected_msg_list, status, command_id); test_rpc_encode_and_feed_one(&request); @@ -844,16 +909,69 @@ static void test_storage_delete_run(const char* path, size_t command_id, PB_Comm test_rpc_free_msg_list(expected_msg_list); } +#define TEST_DIR_RMRF_NAME TEST_DIR "rmrf_test" +#define TEST_DIR_RMRF TEST_DIR_RMRF_NAME "/" +MU_TEST(test_storage_delete_recursive) { + test_create_dir(TEST_DIR_RMRF_NAME); + + test_create_dir(TEST_DIR_RMRF "dir1"); + test_create_file(TEST_DIR_RMRF "dir1/file1", 1); + + test_create_dir(TEST_DIR_RMRF "dir1/dir1"); + test_create_dir(TEST_DIR_RMRF "dir1/dir2"); + test_create_file(TEST_DIR_RMRF "dir1/dir2/file1", 1); + test_create_file(TEST_DIR_RMRF "dir1/dir2/file2", 1); + test_create_dir(TEST_DIR_RMRF "dir1/dir3"); + test_create_dir(TEST_DIR_RMRF "dir1/dir3/dir1"); + test_create_dir(TEST_DIR_RMRF "dir1/dir3/dir1/dir1"); + test_create_dir(TEST_DIR_RMRF "dir1/dir3/dir1/dir1/dir1"); + test_create_dir(TEST_DIR_RMRF "dir1/dir3/dir1/dir1/dir1/dir1"); + + test_create_dir(TEST_DIR_RMRF "dir2"); + test_create_dir(TEST_DIR_RMRF "dir2/dir1"); + test_create_dir(TEST_DIR_RMRF "dir2/dir2"); + test_create_file(TEST_DIR_RMRF "dir2/dir2/file1", 1); + + test_create_dir(TEST_DIR_RMRF "dir2/dir2/dir1"); + test_create_dir(TEST_DIR_RMRF "dir2/dir2/dir1/dir1"); + test_create_dir(TEST_DIR_RMRF "dir2/dir2/dir1/dir1/dir1"); + test_create_file(TEST_DIR_RMRF "dir2/dir2/dir1/dir1/dir1/file1", 1); + + test_storage_delete_run( + TEST_DIR_RMRF_NAME, ++command_id, PB_CommandStatus_ERROR_STORAGE_DIR_NOT_EMPTY, false); + mu_check(test_is_exists(TEST_DIR_RMRF_NAME)); + test_storage_delete_run(TEST_DIR_RMRF_NAME, ++command_id, PB_CommandStatus_OK, true); + mu_check(!test_is_exists(TEST_DIR_RMRF_NAME)); + test_storage_delete_run(TEST_DIR_RMRF_NAME, ++command_id, PB_CommandStatus_OK, false); + mu_check(!test_is_exists(TEST_DIR_RMRF_NAME)); + + test_create_dir(TEST_DIR_RMRF_NAME); + test_storage_delete_run(TEST_DIR_RMRF_NAME, ++command_id, PB_CommandStatus_OK, true); + mu_check(!test_is_exists(TEST_DIR_RMRF_NAME)); + + test_create_dir(TEST_DIR "file1"); + test_storage_delete_run(TEST_DIR "file1", ++command_id, PB_CommandStatus_OK, true); + mu_check(!test_is_exists(TEST_DIR "file1")); +} + MU_TEST(test_storage_delete) { + test_storage_delete_run(NULL, ++command_id, PB_CommandStatus_ERROR_INVALID_PARAMETERS, false); + + furi_check(!test_is_exists(TEST_DIR "empty.txt")); + test_storage_delete_run(TEST_DIR "empty.txt", ++command_id, PB_CommandStatus_OK, false); + mu_check(!test_is_exists(TEST_DIR "empty.txt")); + test_create_file(TEST_DIR "empty.txt", 0); - test_storage_delete_run(TEST_DIR "empty.txt", ++command_id, PB_CommandStatus_OK); - test_storage_delete_run( - TEST_DIR "empty.txt", ++command_id, PB_CommandStatus_ERROR_STORAGE_NOT_EXIST); + test_storage_delete_run(TEST_DIR "empty.txt", ++command_id, PB_CommandStatus_OK, false); + mu_check(!test_is_exists(TEST_DIR "empty.txt")); + furi_check(!test_is_exists(TEST_DIR "dir1")); test_create_dir(TEST_DIR "dir1"); - test_storage_delete_run(TEST_DIR "dir1", ++command_id, PB_CommandStatus_OK); - test_storage_delete_run( - TEST_DIR "dir1", ++command_id, PB_CommandStatus_ERROR_STORAGE_NOT_EXIST); + test_storage_delete_run(TEST_DIR "dir1", ++command_id, PB_CommandStatus_OK, false); + mu_check(!test_is_exists(TEST_DIR "dir1")); + + test_storage_delete_run(TEST_DIR "dir1", ++command_id, PB_CommandStatus_OK, false); + mu_check(!test_is_exists(TEST_DIR "dir1")); } static void test_storage_mkdir_run(const char* path, size_t command_id, PB_CommandStatus status) { @@ -872,18 +990,17 @@ static void test_storage_mkdir_run(const char* path, size_t command_id, PB_Comma } MU_TEST(test_storage_mkdir) { + furi_check(!test_is_exists(TEST_DIR "dir1")); test_storage_mkdir_run(TEST_DIR "dir1", ++command_id, PB_CommandStatus_OK); + mu_check(test_is_exists(TEST_DIR "dir1")); + test_storage_mkdir_run(TEST_DIR "dir1", ++command_id, PB_CommandStatus_ERROR_STORAGE_EXIST); + mu_check(test_is_exists(TEST_DIR "dir1")); + + furi_check(!test_is_exists(TEST_DIR "dir2")); test_create_dir(TEST_DIR "dir2"); test_storage_mkdir_run(TEST_DIR "dir2", ++command_id, PB_CommandStatus_ERROR_STORAGE_EXIST); - - Storage* fs_api = furi_record_open("storage"); - FS_Error error = storage_common_remove(fs_api, TEST_DIR "dir1"); - (void)error; - furi_assert(error == FSE_OK); - furi_record_close("storage"); - - test_storage_mkdir_run(TEST_DIR "dir1", ++command_id, PB_CommandStatus_OK); + mu_check(test_is_exists(TEST_DIR "dir2")); } static void test_storage_calculate_md5sum(const char* path, char* md5sum) { @@ -1013,7 +1130,7 @@ MU_TEST(test_ping) { // 4) test for fill buffer till end (great varint) and close connection MU_TEST_SUITE(test_rpc_status) { - MU_SUITE_CONFIGURE(&test_rpc_storage_setup, &test_rpc_storage_teardown); + MU_SUITE_CONFIGURE(&test_rpc_setup, &test_rpc_teardown); MU_RUN_TEST(test_ping); } @@ -1026,6 +1143,7 @@ MU_TEST_SUITE(test_rpc_storage) { MU_RUN_TEST(test_storage_write_read); MU_RUN_TEST(test_storage_write); MU_RUN_TEST(test_storage_delete); + MU_RUN_TEST(test_storage_delete_recursive); MU_RUN_TEST(test_storage_mkdir); MU_RUN_TEST(test_storage_md5sum); MU_RUN_TEST(test_storage_interrupt_continuous_same_system); @@ -1112,20 +1230,19 @@ MU_TEST(test_app_start_and_lock_status) { "skynet_destroy_world_app", NULL, PB_CommandStatus_ERROR_INVALID_PARAMETERS, ++command_id); test_app_get_status_lock_run(false, ++command_id); - test_app_start_run("Delay Test App", "0", PB_CommandStatus_OK, ++command_id); + test_app_start_run("Delay Test", "0", PB_CommandStatus_OK, ++command_id); delay(100); test_app_get_status_lock_run(false, ++command_id); - test_app_start_run("Delay Test App", "200", PB_CommandStatus_OK, ++command_id); + test_app_start_run("Delay Test", "200", PB_CommandStatus_OK, ++command_id); test_app_get_status_lock_run(true, ++command_id); delay(100); test_app_get_status_lock_run(true, ++command_id); - test_app_start_run( - "Delay Test App", "0", PB_CommandStatus_ERROR_APP_SYSTEM_LOCKED, ++command_id); + test_app_start_run("Delay Test", "0", PB_CommandStatus_ERROR_APP_SYSTEM_LOCKED, ++command_id); delay(200); test_app_get_status_lock_run(false, ++command_id); - test_app_start_run("Delay Test App", "500", PB_CommandStatus_OK, ++command_id); + test_app_start_run("Delay Test", "500", PB_CommandStatus_OK, ++command_id); delay(100); test_app_get_status_lock_run(true, ++command_id); test_app_start_run("Infrared", "0", PB_CommandStatus_ERROR_APP_SYSTEM_LOCKED, ++command_id); @@ -1140,16 +1257,22 @@ MU_TEST(test_app_start_and_lock_status) { } MU_TEST_SUITE(test_rpc_app) { - MU_SUITE_CONFIGURE(&test_rpc_storage_setup, &test_rpc_storage_teardown); + MU_SUITE_CONFIGURE(&test_rpc_setup, &test_rpc_teardown); MU_RUN_TEST(test_app_start_and_lock_status); } int run_minunit_test_rpc() { - MU_RUN_SUITE(test_rpc_storage); + Storage* storage = furi_record_open("storage"); + furi_record_close("storage"); + if(storage_sd_status(storage) != FSE_OK) { + FURI_LOG_E("UNIT_TESTS", "SD card not mounted - skip storage tests"); + } else { + MU_RUN_SUITE(test_rpc_storage); + } + MU_RUN_SUITE(test_rpc_status); MU_RUN_SUITE(test_rpc_app); - MU_REPORT(); return MU_EXIT_CODE; } diff --git a/applications/tests/test_index.c b/applications/tests/test_index.c index 7158b304..d55a1e45 100644 --- a/applications/tests/test_index.c +++ b/applications/tests/test_index.c @@ -7,10 +7,27 @@ #include <cli/cli.h> #include <loader/loader.h> +#define TESTS_TAG "UNIT_TESTS" + int run_minunit(); int run_minunit_test_irda_decoder_encoder(); int run_minunit_test_rpc(); +void minunit_print_progress(void) { + static char progress[] = {'\\', '|', '/', '-'}; + static uint8_t progress_counter = 0; + static TickType_t last_tick = 0; + TickType_t current_tick = xTaskGetTickCount(); + if(current_tick - last_tick > 20) { + last_tick = current_tick; + printf("[%c]\033[3D", progress[++progress_counter % COUNT_OF(progress)]); + } +} + +void minunit_print_fail(const char* str) { + printf("%s\n", str); +} + void unit_tests_cli(Cli* cli, string_t args, void* context) { uint32_t test_result = 0; minunit_run = 0; @@ -25,21 +42,30 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { furi_record_close("notification"); if(loader_is_locked(loader)) { - FURI_LOG_E("UNIT_TESTS", "RPC: stop all applications to run tests"); + FURI_LOG_E(TESTS_TAG, "RPC: stop all applications to run tests"); notification_message(notification, &sequence_blink_magenta_100); } else { notification_message_block(notification, &sequence_set_only_blue_255); + uint32_t heap_before = memmgr_get_free_heap(); + test_result |= run_minunit(); test_result |= run_minunit_test_irda_decoder_encoder(); test_result |= run_minunit_test_rpc(); if(test_result == 0) { + delay(200); /* wait for tested services and apps to deallocate */ + uint32_t heap_after = memmgr_get_free_heap(); notification_message(notification, &sequence_success); - FURI_LOG_I("UNIT_TESTS", "PASSED"); + if(heap_after != heap_before) { + FURI_LOG_E(TESTS_TAG, "Leaked: %d", heap_before - heap_after); + } else { + FURI_LOG_I(TESTS_TAG, "No leaks"); + } + FURI_LOG_I(TESTS_TAG, "PASSED"); } else { notification_message(notification, &sequence_error); - FURI_LOG_E("UNIT_TESTS", "FAILED"); + FURI_LOG_E(TESTS_TAG, "FAILED"); } } } |