diff --git a/.astyleignore b/.astyleignore index 90f137f81f..85d2551aa2 100644 --- a/.astyleignore +++ b/.astyleignore @@ -31,3 +31,4 @@ ^TESTS/mbed_hal/trng/pithy ^TESTS/mbed_hal/trng/pithy ^tools +^UNITTESTS diff --git a/UNITTESTS/features/storage/blockdevice/HeapBlockDevice/test.cpp b/UNITTESTS/features/storage/blockdevice/HeapBlockDevice/test.cpp index 17edf27a6f..659b47b462 100644 --- a/UNITTESTS/features/storage/blockdevice/HeapBlockDevice/test.cpp +++ b/UNITTESTS/features/storage/blockdevice/HeapBlockDevice/test.cpp @@ -16,7 +16,7 @@ #include "gtest/gtest.h" #include "features/storage/blockdevice/HeapBlockDevice.h" -#include "string.h" +#include #include "mbed_assert.h" #define BLOCK_SIZE (512) @@ -67,7 +67,7 @@ TEST_F(HeapBlockDeviceTest, get_type) TEST_F(HeapBlockDeviceTest, erase_program_read) { - uint8_t *block = new uint8_t[BLOCK_SIZE]{0xaa,0xbb,0xcc}; + uint8_t *block = new uint8_t[BLOCK_SIZE] {0xaa,0xbb,0xcc}; uint8_t *buf = new uint8_t[BLOCK_SIZE]; EXPECT_EQ(bd.erase(0, BLOCK_SIZE), BD_ERROR_OK); EXPECT_EQ(bd.program(block, 0, BLOCK_SIZE), BD_ERROR_OK); @@ -77,7 +77,7 @@ TEST_F(HeapBlockDeviceTest, erase_program_read) delete[] buf; } -TEST_F(HeapBlockDeviceTest, use_uninitalized) +TEST_F(HeapBlockDeviceTest, use_uninitialized) { mbed::HeapBlockDevice one{DEVICE_SIZE}; uint8_t *buf = new uint8_t[BLOCK_SIZE]; @@ -95,7 +95,7 @@ TEST_F(HeapBlockDeviceTest, over_read) TEST_F(HeapBlockDeviceTest, over_write) { - uint8_t *buf = new uint8_t[BLOCK_SIZE]{0xaa,0xbb,0xcc}; + uint8_t *buf = new uint8_t[BLOCK_SIZE] {0xaa,0xbb,0xcc}; EXPECT_EQ(bd.program(buf, DEVICE_SIZE, BLOCK_SIZE), BD_ERROR_DEVICE_ERROR); delete[] buf; } diff --git a/UNITTESTS/moduletests/storage/blockdevice/SlicingBlockDevice/moduletest.cpp b/UNITTESTS/moduletests/storage/blockdevice/SlicingBlockDevice/moduletest.cpp new file mode 100644 index 0000000000..ff4c995761 --- /dev/null +++ b/UNITTESTS/moduletests/storage/blockdevice/SlicingBlockDevice/moduletest.cpp @@ -0,0 +1,161 @@ +/* Copyright (c) 2019 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gtest/gtest.h" +#include "features/storage/blockdevice/HeapBlockDevice.h" +#include "features/storage/blockdevice/SlicingBlockDevice.h" + +#define BLOCK_SIZE (512) +#define DEVICE_SIZE (BLOCK_SIZE*10) + +class VerifyBorders_HeapBlockDevice : public mbed::HeapBlockDevice { +public: + mutable bool borders_crossed; + mutable bd_size_t lower_limit; + mutable bd_size_t upper_limit; + + VerifyBorders_HeapBlockDevice(bd_size_t size) + : HeapBlockDevice(size) + { + borders_crossed = false; + lower_limit = 0; + upper_limit = size; + } + + virtual bool is_valid_read(bd_addr_t addr, bd_size_t size) const + { + borders_crossed |= addr < lower_limit; + borders_crossed |= addr + size > upper_limit; + return BlockDevice::is_valid_read(addr, size); + } + + virtual bool is_valid_program(bd_addr_t addr, bd_size_t size) const + { + borders_crossed |= addr < lower_limit; + borders_crossed |= addr + size > upper_limit; + return BlockDevice::is_valid_program(addr, size); + } + + virtual bool is_valid_erase(bd_addr_t addr, bd_size_t size) const + { + borders_crossed |= addr < lower_limit; + borders_crossed |= addr + size > upper_limit; + return BlockDevice::is_valid_erase(addr, size); + } +}; + +class SlicingBlockModuleTest : public testing::Test { +protected: + VerifyBorders_HeapBlockDevice bd{DEVICE_SIZE}; + uint8_t *magic; + uint8_t *buf; + virtual void SetUp() + { + bd.init(); + magic = new uint8_t[BLOCK_SIZE]; + buf = new uint8_t[BLOCK_SIZE]; + // Generate simple pattern to verify against + for (int i = 0; i < BLOCK_SIZE; i++) { + magic[i] = 0xaa + i; + } + } + + virtual void TearDown() + { + bd.deinit(); + delete[] magic; + delete[] buf; + } +}; + +TEST_F(SlicingBlockModuleTest, constructor) +{ + mbed::SlicingBlockDevice slice(&bd, 0, bd.size()); + EXPECT_EQ(slice.init(), BD_ERROR_OK); + EXPECT_EQ(slice.get_read_size(), bd.get_read_size()); + EXPECT_EQ(slice.get_program_size(), bd.get_read_size()); + EXPECT_EQ(slice.get_erase_size(), bd.get_read_size()); + EXPECT_EQ(slice.get_erase_size(0), bd.get_read_size()); + EXPECT_EQ(slice.deinit(), BD_ERROR_OK); +} + +TEST_F(SlicingBlockModuleTest, slice_in_middle) +{ + uint8_t *program = new uint8_t[BLOCK_SIZE] {0xbb,0xbb,0xbb}; + + //Write magic value to heap block before and after the space for slice + bd.program(magic, 0, BLOCK_SIZE); + bd.program(magic, BLOCK_SIZE * 3, BLOCK_SIZE); + + bd.upper_limit = BLOCK_SIZE * 3; + bd.lower_limit = BLOCK_SIZE; + bd.borders_crossed = false; + + //Skip first block, then create sclicing device, with size of 2 blocks + mbed::SlicingBlockDevice slice(&bd, BLOCK_SIZE, BLOCK_SIZE * 3); + EXPECT_EQ(slice.init(), BD_ERROR_OK); + EXPECT_EQ(BLOCK_SIZE * 2, slice.size()); + EXPECT_EQ(bd.borders_crossed, false); + + //Program a test value + EXPECT_EQ(slice.program(program, 0, BLOCK_SIZE), BD_ERROR_OK); + EXPECT_EQ(slice.program(program, BLOCK_SIZE, BLOCK_SIZE), BD_ERROR_OK); + EXPECT_EQ(bd.borders_crossed, false); + + //Verify that blocks before and after the slicing blocks are not touched + bd.read(buf, 0, BLOCK_SIZE); + EXPECT_EQ(0, memcmp(buf, magic, BLOCK_SIZE)); + bd.read(buf, BLOCK_SIZE * 3, BLOCK_SIZE); + EXPECT_EQ(0, memcmp(buf, magic, BLOCK_SIZE)); +} + +TEST_F(SlicingBlockModuleTest, slice_at_the_end) +{ + uint8_t *program = new uint8_t[BLOCK_SIZE] {0xbb,0xbb,0xbb}; + + //Write magic value to heap block before the space for slice + // our bd is 10*BLOCK_SIZE, so sector 7 + bd.program(magic, BLOCK_SIZE * 7, BLOCK_SIZE); + + //Screate sclicing device, with size of 2 blocks + // Use negative index + mbed::SlicingBlockDevice slice(&bd, -BLOCK_SIZE*2); + EXPECT_EQ(slice.init(), BD_ERROR_OK); + EXPECT_EQ(BLOCK_SIZE * 2, slice.size()); + + //Program a test value + EXPECT_EQ(slice.program(program, 0, BLOCK_SIZE), BD_ERROR_OK); + EXPECT_EQ(slice.program(program, BLOCK_SIZE, BLOCK_SIZE), BD_ERROR_OK); + + //Verify that blocks before and after the slicing blocks are not touched + bd.read(buf, BLOCK_SIZE * 7, BLOCK_SIZE); + EXPECT_EQ(0, memcmp(buf, magic, BLOCK_SIZE)); +} + +TEST_F(SlicingBlockModuleTest, over_write) +{ + uint8_t *program = new uint8_t[BLOCK_SIZE] {0xbb,0xbb,0xbb}; + + //Screate sclicing device, with size of 2 blocks + mbed::SlicingBlockDevice slice(&bd, BLOCK_SIZE, BLOCK_SIZE * 3); + EXPECT_EQ(slice.init(), BD_ERROR_OK); + + EXPECT_EQ(slice.program(program, 0, BLOCK_SIZE), BD_ERROR_OK); + EXPECT_EQ(slice.program(program, BLOCK_SIZE, BLOCK_SIZE), BD_ERROR_OK); + //Program a test value to address that is one pass the device size + EXPECT_EQ(slice.program(program, 2 * BLOCK_SIZE, BLOCK_SIZE), BD_ERROR_DEVICE_ERROR); + delete[] program; +} diff --git a/UNITTESTS/moduletests/storage/blockdevice/SlicingBlockDevice/unittest.cmake b/UNITTESTS/moduletests/storage/blockdevice/SlicingBlockDevice/unittest.cmake new file mode 100644 index 0000000000..93285d0a13 --- /dev/null +++ b/UNITTESTS/moduletests/storage/blockdevice/SlicingBlockDevice/unittest.cmake @@ -0,0 +1,20 @@ + +#################### +# UNIT TESTS +#################### + +set(unittest-includes ${unittest-includes} + . + .. +) + +set(unittest-sources + ../features/storage/blockdevice/SlicingBlockDevice.cpp + ../features/storage/blockdevice/HeapBlockDevice.cpp + stubs/mbed_atomic_stub.c + stubs/mbed_assert_stub.c +) + +set(unittest-test-sources + moduletests/storage/blockdevice/SlicingBlockDevice/moduletest.cpp +) diff --git a/UNITTESTS/stubs/mbed_atomic_stub.c b/UNITTESTS/stubs/mbed_atomic_stub.c index c5d43d033e..3767101b04 100644 --- a/UNITTESTS/stubs/mbed_atomic_stub.c +++ b/UNITTESTS/stubs/mbed_atomic_stub.c @@ -57,33 +57,33 @@ uint32_t core_util_atomic_exchange_u32(volatile uint32_t *ptr, uint32_t desiredV uint8_t core_util_atomic_incr_u8(volatile uint8_t *valuePtr, uint8_t delta) { - return *valuePtr+=delta; + return *valuePtr += delta; } uint16_t core_util_atomic_incr_u16(volatile uint16_t *valuePtr, uint16_t delta) { - return *valuePtr+=delta; + return *valuePtr += delta; } uint32_t core_util_atomic_incr_u32(volatile uint32_t *valuePtr, uint32_t delta) { - return *valuePtr+=delta; + return *valuePtr += delta; } uint8_t core_util_atomic_decr_u8(volatile uint8_t *valuePtr, uint8_t delta) { - return *valuePtr-=delta; + return *valuePtr -= delta; } uint16_t core_util_atomic_decr_u16(volatile uint16_t *valuePtr, uint16_t delta) { - return *valuePtr-=delta; + return *valuePtr -= delta; } uint32_t core_util_atomic_decr_u32(volatile uint32_t *valuePtr, uint32_t delta) { - return *valuePtr-=delta; + return *valuePtr -= delta; } diff --git a/UNITTESTS/target_h/gpio_object.h b/UNITTESTS/target_h/gpio_object.h index f25919eebe..9f31aeb9b3 100644 --- a/UNITTESTS/target_h/gpio_object.h +++ b/UNITTESTS/target_h/gpio_object.h @@ -27,7 +27,7 @@ extern "C" { #endif typedef struct { - int unused; + int unused; } gpio_t; #ifdef __cplusplus diff --git a/UNITTESTS/target_h/objects.h b/UNITTESTS/target_h/objects.h index 542b9e80f9..23a634db26 100644 --- a/UNITTESTS/target_h/objects.h +++ b/UNITTESTS/target_h/objects.h @@ -35,39 +35,39 @@ struct serial_s { }; struct dac_s { - int unused; + int unused; }; struct i2c_s { - int unused; + int unused; }; struct qspi_s { - int unused; + int unused; }; struct spi_s { - int unused; + int unused; }; struct analogin_s { - int unused; + int unused; }; struct port_s { - int unused; + int unused; }; struct pwmout_s { - int unused; + int unused; }; struct flash_s { - int unused; + int unused; }; struct can_s { - int unused; + int unused; }; #include "gpio_object.h"