Ver Fonte

[FL-3062] Fix unit tests (#2180)

* SubGHZ unit test: fail if async_tx is not started
* Memgr unit test: fix for multithreaded enviroment
* Unit tests: fix failed_tests count
* Unit tests: remove debug code
* Double update test: increase flipper detection time

Co-authored-by: あく <alleteam@gmail.com>
Sergey Gavrilov há 3 anos atrás
pai
commit
c2cb14834d

+ 20 - 81
applications/debug/unit_tests/furi/furi_memmgr_test.c

@@ -3,98 +3,37 @@
 #include <string.h>
 #include <stdbool.h>
 
-// this test is not accurate, but gives a basic understanding
-// that memory management is working fine
-
-// do not include memmgr.h here
-// we also test that we are linking against stdlib
-extern size_t memmgr_get_free_heap(void);
-extern size_t memmgr_get_minimum_free_heap(void);
-
-// current heap management realization consume:
-// X bytes after allocate and 0 bytes after allocate and free,
-// where X = sizeof(void*) + sizeof(size_t), look to BlockLink_t
-const size_t heap_overhead_max_size = sizeof(void*) + sizeof(size_t);
-
-bool heap_equal(size_t heap_size, size_t heap_size_old) {
-    // heap borders with overhead
-    const size_t heap_low = heap_size_old - heap_overhead_max_size;
-    const size_t heap_high = heap_size_old + heap_overhead_max_size;
-
-    // not exact, so we must test it against bigger numbers than "overhead size"
-    const bool result = ((heap_size >= heap_low) && (heap_size <= heap_high));
-
-    // debug allocation info
-    if(!result) {
-        printf("\n(hl: %zu) <= (p: %zu) <= (hh: %zu)\n", heap_low, heap_size, heap_high);
-    }
-
-    return result;
-}
-
 void test_furi_memmgr() {
-    size_t heap_size = 0;
-    size_t heap_size_old = 0;
-    const int alloc_size = 128;
-
-    void* ptr = NULL;
-    void* original_ptr = NULL;
-
-    // do not include furi memmgr.h case
-#ifdef FURI_MEMMGR_GUARD
-    mu_fail("do not link against furi memmgr.h");
-#endif
+    void* ptr;
 
     // allocate memory case
-    heap_size_old = memmgr_get_free_heap();
-    ptr = malloc(alloc_size);
-    heap_size = memmgr_get_free_heap();
-    mu_assert_pointers_not_eq(ptr, NULL);
-    mu_assert(heap_equal(heap_size, heap_size_old - alloc_size), "allocate failed");
-
-    // free memory case
-    heap_size_old = memmgr_get_free_heap();
+    ptr = malloc(100);
+    mu_check(ptr != NULL);
+    // test that memory is zero-initialized after allocation
+    for(int i = 0; i < 100; i++) {
+        mu_assert_int_eq(0, ((uint8_t*)ptr)[i]);
+    }
     free(ptr);
-    ptr = NULL;
-    heap_size = memmgr_get_free_heap();
-    mu_assert(heap_equal(heap_size, heap_size_old + alloc_size), "free failed");
 
     // reallocate memory case
-
-    // get filled array with some data
-    original_ptr = malloc(alloc_size);
-    mu_assert_pointers_not_eq(original_ptr, NULL);
-    for(int i = 0; i < alloc_size; i++) {
-        *(unsigned char*)(original_ptr + i) = i;
+    ptr = malloc(100);
+    memset(ptr, 66, 100);
+    ptr = realloc(ptr, 200);
+    mu_check(ptr != NULL);
+
+    // test that memory is really reallocated
+    for(int i = 0; i < 100; i++) {
+        mu_assert_int_eq(66, ((uint8_t*)ptr)[i]);
     }
 
-    // malloc array and copy data
-    ptr = malloc(alloc_size);
-    mu_assert_pointers_not_eq(ptr, NULL);
-    memcpy(ptr, original_ptr, alloc_size);
-
-    // reallocate array
-    heap_size_old = memmgr_get_free_heap();
-    ptr = realloc(ptr, alloc_size * 2);
-    heap_size = memmgr_get_free_heap();
-    mu_assert(heap_equal(heap_size, heap_size_old - alloc_size), "reallocate failed");
-    mu_assert_int_eq(memcmp(original_ptr, ptr, alloc_size), 0);
-    free(original_ptr);
+    // TODO: fix realloc to copy only old size, and write testcase that leftover of reallocated memory is zero-initialized
     free(ptr);
 
     // allocate and zero-initialize array (calloc)
-    original_ptr = malloc(alloc_size);
-    mu_assert_pointers_not_eq(original_ptr, NULL);
-
-    for(int i = 0; i < alloc_size; i++) {
-        *(unsigned char*)(original_ptr + i) = 0;
+    ptr = calloc(100, 2);
+    mu_check(ptr != NULL);
+    for(int i = 0; i < 100 * 2; i++) {
+        mu_assert_int_eq(0, ((uint8_t*)ptr)[i]);
     }
-    heap_size_old = memmgr_get_free_heap();
-    ptr = calloc(1, alloc_size);
-    heap_size = memmgr_get_free_heap();
-    mu_assert(heap_equal(heap_size, heap_size_old - alloc_size), "callocate failed");
-    mu_assert_int_eq(memcmp(original_ptr, ptr, alloc_size), 0);
-
-    free(original_ptr);
     free(ptr);
 }

+ 4 - 1
applications/debug/unit_tests/subghz/subghz_test.c

@@ -318,7 +318,10 @@ bool subghz_hal_async_tx_test_run(SubGhzHalAsyncTxTestType type) {
     furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
     furi_hal_subghz_set_frequency_and_path(433920000);
 
-    furi_hal_subghz_start_async_tx(subghz_hal_async_tx_test_yield, &test);
+    if(!furi_hal_subghz_start_async_tx(subghz_hal_async_tx_test_yield, &test)) {
+        return false;
+    }
+
     while(!furi_hal_subghz_is_async_tx_complete()) {
         furi_delay_ms(10);
     }

+ 23 - 21
applications/debug/unit_tests/test_index.c

@@ -73,7 +73,6 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
     UNUSED(cli);
     UNUSED(args);
     UNUSED(context);
-    uint32_t failed_tests = 0;
     minunit_run = 0;
     minunit_assert = 0;
     minunit_fail = 0;
@@ -99,32 +98,35 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
 
             if(furi_string_size(args)) {
                 if(furi_string_cmp_str(args, unit_tests[i].name) == 0) {
-                    failed_tests += unit_tests[i].entry();
+                    unit_tests[i].entry();
                 } else {
                     printf("Skipping %s\r\n", unit_tests[i].name);
                 }
             } else {
-                failed_tests += unit_tests[i].entry();
+                unit_tests[i].entry();
             }
         }
-        printf("\r\nFailed tests: %lu\r\n", failed_tests);
-
-        // Time report
-        cycle_counter = (furi_get_tick() - cycle_counter);
-        printf("Consumed: %lu ms\r\n", cycle_counter);
-
-        // Wait for tested services and apps to deallocate memory
-        furi_delay_ms(200);
-        uint32_t heap_after = memmgr_get_free_heap();
-        printf("Leaked: %ld\r\n", heap_before - heap_after);
-
-        // Final Report
-        if(failed_tests == 0) {
-            notification_message(notification, &sequence_success);
-            printf("Status: PASSED\r\n");
-        } else {
-            notification_message(notification, &sequence_error);
-            printf("Status: FAILED\r\n");
+
+        if(minunit_run != 0) {
+            printf("\r\nFailed tests: %u\r\n", minunit_fail);
+
+            // Time report
+            cycle_counter = (furi_get_tick() - cycle_counter);
+            printf("Consumed: %lu ms\r\n", cycle_counter);
+
+            // Wait for tested services and apps to deallocate memory
+            furi_delay_ms(200);
+            uint32_t heap_after = memmgr_get_free_heap();
+            printf("Leaked: %ld\r\n", heap_before - heap_after);
+
+            // Final Report
+            if(minunit_fail == 0) {
+                notification_message(notification, &sequence_success);
+                printf("Status: PASSED\r\n");
+            } else {
+                notification_message(notification, &sequence_error);
+                printf("Status: FAILED\r\n");
+            }
         }
     }
 

+ 1 - 1
scripts/testing/await_flipper.py

@@ -24,7 +24,7 @@ def flp_serial_by_name(flp_name):
             return ""
 
 
-UPDATE_TIMEOUT = 60
+UPDATE_TIMEOUT = 60 * 4  # 4 minutes
 
 
 def main():