[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>
This commit is contained in:
		
							parent
							
								
									b0970953b9
								
							
						
					
					
						commit
						c2cb14834d
					
				| @ -3,98 +3,37 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <stdbool.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() { | void test_furi_memmgr() { | ||||||
|     size_t heap_size = 0; |     void* ptr; | ||||||
|     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 |  | ||||||
| 
 | 
 | ||||||
|     // allocate memory case
 |     // allocate memory case
 | ||||||
|     heap_size_old = memmgr_get_free_heap(); |     ptr = malloc(100); | ||||||
|     ptr = malloc(alloc_size); |     mu_check(ptr != NULL); | ||||||
|     heap_size = memmgr_get_free_heap(); |     // test that memory is zero-initialized after allocation
 | ||||||
|     mu_assert_pointers_not_eq(ptr, NULL); |     for(int i = 0; i < 100; i++) { | ||||||
|     mu_assert(heap_equal(heap_size, heap_size_old - alloc_size), "allocate failed"); |         mu_assert_int_eq(0, ((uint8_t*)ptr)[i]); | ||||||
| 
 |     } | ||||||
|     // free memory case
 |  | ||||||
|     heap_size_old = memmgr_get_free_heap(); |  | ||||||
|     free(ptr); |     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
 |     // reallocate memory case
 | ||||||
|  |     ptr = malloc(100); | ||||||
|  |     memset(ptr, 66, 100); | ||||||
|  |     ptr = realloc(ptr, 200); | ||||||
|  |     mu_check(ptr != NULL); | ||||||
| 
 | 
 | ||||||
|     // get filled array with some data
 |     // test that memory is really reallocated
 | ||||||
|     original_ptr = malloc(alloc_size); |     for(int i = 0; i < 100; i++) { | ||||||
|     mu_assert_pointers_not_eq(original_ptr, NULL); |         mu_assert_int_eq(66, ((uint8_t*)ptr)[i]); | ||||||
|     for(int i = 0; i < alloc_size; i++) { |  | ||||||
|         *(unsigned char*)(original_ptr + i) = i; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // malloc array and copy data
 |     // TODO: fix realloc to copy only old size, and write testcase that leftover of reallocated memory is zero-initialized
 | ||||||
|     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); |  | ||||||
|     free(ptr); |     free(ptr); | ||||||
| 
 | 
 | ||||||
|     // allocate and zero-initialize array (calloc)
 |     // allocate and zero-initialize array (calloc)
 | ||||||
|     original_ptr = malloc(alloc_size); |     ptr = calloc(100, 2); | ||||||
|     mu_assert_pointers_not_eq(original_ptr, NULL); |     mu_check(ptr != NULL); | ||||||
| 
 |     for(int i = 0; i < 100 * 2; i++) { | ||||||
|     for(int i = 0; i < alloc_size; i++) { |         mu_assert_int_eq(0, ((uint8_t*)ptr)[i]); | ||||||
|         *(unsigned char*)(original_ptr + i) = 0; |  | ||||||
|     } |     } | ||||||
|     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); |     free(ptr); | ||||||
| } | } | ||||||
|  | |||||||
| @ -318,7 +318,10 @@ bool subghz_hal_async_tx_test_run(SubGhzHalAsyncTxTestType type) { | |||||||
|     furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); |     furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); | ||||||
|     furi_hal_subghz_set_frequency_and_path(433920000); |     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()) { |     while(!furi_hal_subghz_is_async_tx_complete()) { | ||||||
|         furi_delay_ms(10); |         furi_delay_ms(10); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -73,7 +73,6 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) { | |||||||
|     UNUSED(cli); |     UNUSED(cli); | ||||||
|     UNUSED(args); |     UNUSED(args); | ||||||
|     UNUSED(context); |     UNUSED(context); | ||||||
|     uint32_t failed_tests = 0; |  | ||||||
|     minunit_run = 0; |     minunit_run = 0; | ||||||
|     minunit_assert = 0; |     minunit_assert = 0; | ||||||
|     minunit_fail = 0; |     minunit_fail = 0; | ||||||
| @ -99,15 +98,17 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) { | |||||||
| 
 | 
 | ||||||
|             if(furi_string_size(args)) { |             if(furi_string_size(args)) { | ||||||
|                 if(furi_string_cmp_str(args, unit_tests[i].name) == 0) { |                 if(furi_string_cmp_str(args, unit_tests[i].name) == 0) { | ||||||
|                     failed_tests += unit_tests[i].entry(); |                     unit_tests[i].entry(); | ||||||
|                 } else { |                 } else { | ||||||
|                     printf("Skipping %s\r\n", unit_tests[i].name); |                     printf("Skipping %s\r\n", unit_tests[i].name); | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|                 failed_tests += unit_tests[i].entry(); |                 unit_tests[i].entry(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         printf("\r\nFailed tests: %lu\r\n", failed_tests); | 
 | ||||||
|  |         if(minunit_run != 0) { | ||||||
|  |             printf("\r\nFailed tests: %u\r\n", minunit_fail); | ||||||
| 
 | 
 | ||||||
|             // Time report
 |             // Time report
 | ||||||
|             cycle_counter = (furi_get_tick() - cycle_counter); |             cycle_counter = (furi_get_tick() - cycle_counter); | ||||||
| @ -119,7 +120,7 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) { | |||||||
|             printf("Leaked: %ld\r\n", heap_before - heap_after); |             printf("Leaked: %ld\r\n", heap_before - heap_after); | ||||||
| 
 | 
 | ||||||
|             // Final Report
 |             // Final Report
 | ||||||
|         if(failed_tests == 0) { |             if(minunit_fail == 0) { | ||||||
|                 notification_message(notification, &sequence_success); |                 notification_message(notification, &sequence_success); | ||||||
|                 printf("Status: PASSED\r\n"); |                 printf("Status: PASSED\r\n"); | ||||||
|             } else { |             } else { | ||||||
| @ -127,6 +128,7 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) { | |||||||
|                 printf("Status: FAILED\r\n"); |                 printf("Status: FAILED\r\n"); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     furi_record_close(RECORD_NOTIFICATION); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
|     furi_record_close(RECORD_LOADER); |     furi_record_close(RECORD_LOADER); | ||||||
|  | |||||||
| @ -24,7 +24,7 @@ def flp_serial_by_name(flp_name): | |||||||
|             return "" |             return "" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| UPDATE_TIMEOUT = 60 | UPDATE_TIMEOUT = 60 * 4  # 4 minutes | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def main(): | def main(): | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Sergey Gavrilov
						Sergey Gavrilov