From 09b3afb59863e6a675baaa2e3d8b1a743a943859 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Fri, 10 Feb 2017 17:57:31 -0600 Subject: [PATCH 1/2] bd: Added randomness to block device test and more debug friendly output --- .../filesystem/heap_block_device/main.cpp | 141 ++++++++++++------ 1 file changed, 97 insertions(+), 44 deletions(-) diff --git a/features/TESTS/filesystem/heap_block_device/main.cpp b/features/TESTS/filesystem/heap_block_device/main.cpp index eb057fef8e0..8d337ed73e2 100644 --- a/features/TESTS/filesystem/heap_block_device/main.cpp +++ b/features/TESTS/filesystem/heap_block_device/main.cpp @@ -23,71 +23,124 @@ using namespace utest::v1; -/* It is not possible to build a KL25Z image with IAR including the file system if - * stack tracking statistics are enabled. If this is the case, build dummy - * tests. - */ -#if ! defined(__ICCARM__) && ! defined(TARGET_KL25Z) && ! defined(MBED_STACK_STATS_ENABLED) +#define TEST_BLOCK_SIZE 512 +#define TEST_BLOCK_DEVICE_SIZE 16*TEST_BLOCK_SIZE +#define TEST_BLOCK_COUNT 10 +#define TEST_ERROR_MASK 16 + +const struct { + const char *name; + bd_size_t (BlockDevice::*method)() const; +} ATTRS[] = { + {"read size", &BlockDevice::get_read_size}, + {"program size", &BlockDevice::get_program_size}, + {"erase size", &BlockDevice::get_erase_size}, + {"total size", &BlockDevice::size}, +}; -#define BLOCK_SIZE 512 -#define HEAP_BLOCK_DEVICE_TEST_01 test_read_write -uint8_t write_block[BLOCK_SIZE]; -uint8_t read_block[BLOCK_SIZE]; -// Simple test which reads and writes a block +// Simple test that read/writes random set of blocks void test_read_write() { - HeapBlockDevice bd(16*BLOCK_SIZE, BLOCK_SIZE); + HeapBlockDevice bd(TEST_BLOCK_DEVICE_SIZE, TEST_BLOCK_SIZE); int err = bd.init(); TEST_ASSERT_EQUAL(0, err); - // Fill with random sequence - srand(1); - for (int i = 0; i < BLOCK_SIZE; i++) { - write_block[i] = 0xff & rand(); + for (unsigned a = 0; a < sizeof(ATTRS)/sizeof(ATTRS[0]); a++) { + static const char *prefixes[] = {"", "k", "M", "G"}; + for (int i = 3; i >= 0; i--) { + bd_size_t size = (bd.*ATTRS[a].method)(); + if (size >= (1ULL << 10*i)) { + printf("%s: %llu%sbytes (%llubytes)\n", + ATTRS[a].name, size >> 10*i, prefixes[i], size); + break; + } + } } - // Write, sync, and read the block - err = bd.program(write_block, 0, BLOCK_SIZE); - TEST_ASSERT_EQUAL(0, err); - - err = bd.read(read_block, 0, BLOCK_SIZE); - TEST_ASSERT_EQUAL(0, err); - - // Check that the data was unmodified - srand(1); - for (int i = 0; i < BLOCK_SIZE; i++) { - TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); + bd_size_t block_size = bd.get_erase_size(); + uint8_t *write_block = new uint8_t[block_size]; + uint8_t *read_block = new uint8_t[block_size]; + uint8_t *error_mask = new uint8_t[TEST_ERROR_MASK]; + unsigned addrwidth = ceil(log(float(bd.size()-1)) / log(float(16)))+1; + + for (int b = 0; b < TEST_BLOCK_COUNT; b++) { + // Find a random block + bd_addr_t block = (rand()*block_size) % bd.size(); + + // Use next random number as temporary seed to keep + // the address progressing in the pseudorandom sequence + unsigned seed = rand(); + + // Fill with random sequence + srand(seed); + for (bd_size_t i = 0; i < block_size; i++) { + write_block[i] = 0xff & rand(); + } + + // erase, program, and read the block + printf("test %0*llx:%llu...\n", addrwidth, block, block_size); + + err = bd.erase(block, block_size); + TEST_ASSERT_EQUAL(0, err); + + err = bd.program(write_block, block, block_size); + TEST_ASSERT_EQUAL(0, err); + + printf("write %0*llx:%llu ", addrwidth, block, block_size); + for (int i = 0; i < 16; i++) { + printf("%02x", write_block[i]); + } + printf("...\n"); + + err = bd.read(read_block, block, block_size); + TEST_ASSERT_EQUAL(0, err); + + printf("read %0*llx:%llu ", addrwidth, block, block_size); + for (int i = 0; i < 16; i++) { + printf("%02x", read_block[i]); + } + printf("...\n"); + + // Find error mask for debugging + memset(error_mask, 0, TEST_ERROR_MASK); + bd_size_t error_scale = block_size / (TEST_ERROR_MASK*8); + + srand(seed); + for (bd_size_t i = 0; i < TEST_ERROR_MASK*8; i++) { + for (bd_size_t j = 0; j < error_scale; j++) { + if ((0xff & rand()) != read_block[i*error_scale + j]) { + error_mask[i/8] |= 1 << (i%8); + } + } + } + + printf("error %0*llx:%llu ", addrwidth, block, block_size); + for (int i = 0; i < 16; i++) { + printf("%02x", error_mask[i]); + } + printf("\n"); + + // Check that the data was unmodified + srand(seed); + for (bd_size_t i = 0; i < block_size; i++) { + TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); + } } - + err = bd.deinit(); TEST_ASSERT_EQUAL(0, err); } -#else /* ! defined(__ICCARM__) && ! defined(TARGET_KL25Z) && ! defined(MBED_STACK_STATS_ENABLED) */ - -#define HEAP_BLOCK_DEVICE_TEST_01 heap_block_device_test_dummy - -/** @brief heap_block_device_test_dummy Dummy test case for testing when KL25Z being built with stack statistics enabled. - * - * @return success always - */ -static control_t heap_block_device_test_dummy() -{ - printf("Null test\n"); - return CaseNext; -} - -#endif /* ! defined(__ICCARM__) && ! defined(TARGET_KL25Z) && ! defined(MBED_STACK_STATS_ENABLED) */ // Test setup utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(10, "default_auto"); + GREENTEA_SETUP(30, "default_auto"); return verbose_test_setup_handler(number_of_cases); } Case cases[] = { - Case("Testing read write of a block", HEAP_BLOCK_DEVICE_TEST_01), + Case("Testing read write random blocks", test_read_write), }; Specification specification(test_setup, cases); From 704c94d52ea0e24e3be2a6e7e2810e6ffea44471 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 7 Mar 2017 17:04:09 -0600 Subject: [PATCH 2/2] bd: Remove constraints on device for block device tests --- .../filesystem/util_block_device/main.cpp | 38 +++++-------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/features/TESTS/filesystem/util_block_device/main.cpp b/features/TESTS/filesystem/util_block_device/main.cpp index 98933c14c13..50867568ac8 100644 --- a/features/TESTS/filesystem/util_block_device/main.cpp +++ b/features/TESTS/filesystem/util_block_device/main.cpp @@ -25,23 +25,15 @@ using namespace utest::v1; -/* It is not possible to build a KL25Z image with IAR including the file system if - * stack tracking statistics are enabled. If this is the case, build dummy - * tests. - */ -#if ! defined(TOOLCHAIN_IAR) && ! defined(TARGET_KL25Z) && ! defined(MBED_STACK_STATS_ENABLED) - #define BLOCK_COUNT 16 #define BLOCK_SIZE 512 -#define UTIL_BLOCK_DEVICE_TEST_01 test_slicing -#define UTIL_BLOCK_DEVICE_TEST_02 test_chaining -uint8_t write_block[BLOCK_SIZE]; -uint8_t read_block[BLOCK_SIZE]; // Simple test which read/writes blocks on a sliced block device void test_slicing() { HeapBlockDevice bd(BLOCK_COUNT*BLOCK_SIZE, BLOCK_SIZE); + uint8_t *write_block = new uint8_t[BLOCK_SIZE]; + uint8_t *read_block = new uint8_t[BLOCK_SIZE]; // Test with first slice of block device SlicingBlockDevice slice1(&bd, 0, (BLOCK_COUNT/2)*BLOCK_SIZE); @@ -123,6 +115,8 @@ void test_slicing() { TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); } + delete[] write_block; + delete[] read_block; err = slice2.deinit(); TEST_ASSERT_EQUAL(0, err); } @@ -131,6 +125,8 @@ void test_slicing() { void test_chaining() { HeapBlockDevice bd1((BLOCK_COUNT/2)*BLOCK_SIZE, BLOCK_SIZE); HeapBlockDevice bd2((BLOCK_COUNT/2)*BLOCK_SIZE, BLOCK_SIZE); + uint8_t *write_block = new uint8_t[BLOCK_SIZE]; + uint8_t *read_block = new uint8_t[BLOCK_SIZE]; // Test with chain of block device BlockDevice *bds[] = {&bd1, &bd2}; @@ -174,26 +170,12 @@ void test_chaining() { TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); } + delete[] write_block; + delete[] read_block; err = chain.deinit(); TEST_ASSERT_EQUAL(0, err); } -#else /* ! defined(TOOLCHAIN_IAR) && ! defined(TARGET_KL25Z) && ! defined(MBED_STACK_STATS_ENABLED) */ - -#define UTIL_BLOCK_DEVICE_TEST_01 util_block_device_test_dummy -#define UTIL_BLOCK_DEVICE_TEST_02 util_block_device_test_dummy - -/** @brief util_block_device_test_dummy Dummy test case for testing when KL25Z being built with stack statistics enabled. - * - * @return success always - */ -static control_t util_block_device_test_dummy() -{ - printf("Null test\n"); - return CaseNext; -} - -#endif /* ! defined(TOOLCHAIN_IAR) && ! defined(TARGET_KL25Z) && ! defined(MBED_STACK_STATS_ENABLED) */ // Test setup utest::v1::status_t test_setup(const size_t number_of_cases) { @@ -202,8 +184,8 @@ utest::v1::status_t test_setup(const size_t number_of_cases) { } Case cases[] = { - Case("Testing slicing of a block device", UTIL_BLOCK_DEVICE_TEST_01), - Case("Testing chaining of block devices", UTIL_BLOCK_DEVICE_TEST_02), + Case("Testing slicing of a block device", test_slicing), + Case("Testing chaining of block devices", test_chaining), }; Specification specification(test_setup, cases);