From 8fa2bcdad9edb41d01c9ccf1ebbbe135713bf9c0 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 30 Sep 2018 05:38:03 +0000 Subject: Fixed small errors in pipes and pipes factory. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12307 110e8d01-0319-4d1e-a829-52ad28d1bb01 --- test/oslib/configuration.xml | 139 +++- test/oslib/oslib_test.mk | 3 +- test/oslib/source/test/oslib_test_root.c | 10 +- test/oslib/source/test/oslib_test_root.h | 1 + test/oslib/source/test/oslib_test_sequence_001.c | 2 +- test/oslib/source/test/oslib_test_sequence_002.c | 234 ++----- test/oslib/source/test/oslib_test_sequence_003.c | 299 +++++---- test/oslib/source/test/oslib_test_sequence_004.c | 773 ++++------------------- 8 files changed, 490 insertions(+), 971 deletions(-) (limited to 'test') diff --git a/test/oslib/configuration.xml b/test/oslib/configuration.xml index 7b3a6b47f..723f47727 100644 --- a/test/oslib/configuration.xml +++ b/test/oslib/configuration.xml @@ -53,7 +53,7 @@ Mailboxes. - This sequence tests the ChibiOS libraryfunctionalities related to mailboxes. + This sequence tests the ChibiOS library functionalities related to mailboxes. CH_CFG_USE_MAILBOXES @@ -430,6 +430,140 @@ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");]]> + + + Internal Tests + + + Pipes + + + This sequence tests the ChibiOS library functionalities related to pipes. + + + CH_CFG_USE_PIPES + + + + + + + + Filling and emptying a pipe, non blocking. + + + The pipe functionality is tested by loading and emptying it, all conditions are tested. + + + + + + + + + + + + + + + + + + + + Filling whole pipe. + + + + + + + + + + + Emptying pipe. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Internal Tests @@ -438,7 +572,7 @@ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");]]> Memory Pools. - This sequence tests the ChibiOS library functionalities related to memory pools. + This sequence tests the ChibiOS library functionalities related to memory pools. CH_CFG_USE_MEMPOOLS @@ -1681,6 +1815,7 @@ test_assert(dpp == NULL, "found");]]> + diff --git a/test/oslib/oslib_test.mk b/test/oslib/oslib_test.mk index f342719e1..d4d863f36 100644 --- a/test/oslib/oslib_test.mk +++ b/test/oslib/oslib_test.mk @@ -3,7 +3,8 @@ TESTSRC += ${CHIBIOS}/test/oslib/source/test/oslib_test_root.c \ ${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_001.c \ ${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_002.c \ ${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_003.c \ - ${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_004.c + ${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_004.c \ + ${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_005.c # Required include directories TESTINC += ${CHIBIOS}/test/oslib/source/test diff --git a/test/oslib/source/test/oslib_test_root.c b/test/oslib/source/test/oslib_test_root.c index e222dcd06..9f65ccc68 100644 --- a/test/oslib/source/test/oslib_test_root.c +++ b/test/oslib/source/test/oslib_test_root.c @@ -25,6 +25,7 @@ * - @subpage oslib_test_sequence_002 * - @subpage oslib_test_sequence_003 * - @subpage oslib_test_sequence_004 + * - @subpage oslib_test_sequence_005 * . */ @@ -49,14 +50,17 @@ const testsequence_t * const oslib_test_suite_array[] = { #if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__) &oslib_test_sequence_001, #endif -#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__) +#if (CH_CFG_USE_PIPES) || defined(__DOXYGEN__) &oslib_test_sequence_002, #endif -#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__) +#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__) &oslib_test_sequence_003, #endif -#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__) +#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__) &oslib_test_sequence_004, +#endif +#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__) + &oslib_test_sequence_005, #endif NULL }; diff --git a/test/oslib/source/test/oslib_test_root.h b/test/oslib/source/test/oslib_test_root.h index 760ccddc8..01b6eefe9 100644 --- a/test/oslib/source/test/oslib_test_root.h +++ b/test/oslib/source/test/oslib_test_root.h @@ -28,6 +28,7 @@ #include "oslib_test_sequence_002.h" #include "oslib_test_sequence_003.h" #include "oslib_test_sequence_004.h" +#include "oslib_test_sequence_005.h" #if !defined(__DOXYGEN__) diff --git a/test/oslib/source/test/oslib_test_sequence_001.c b/test/oslib/source/test/oslib_test_sequence_001.c index 74672a242..076efa102 100644 --- a/test/oslib/source/test/oslib_test_sequence_001.c +++ b/test/oslib/source/test/oslib_test_sequence_001.c @@ -26,7 +26,7 @@ * File: @ref oslib_test_sequence_001.c * *

Description

- * This sequence tests the ChibiOS libraryfunctionalities related to + * This sequence tests the ChibiOS library functionalities related to * mailboxes. * *

Conditions

diff --git a/test/oslib/source/test/oslib_test_sequence_002.c b/test/oslib/source/test/oslib_test_sequence_002.c index bd661ce13..406b4f21d 100644 --- a/test/oslib/source/test/oslib_test_sequence_002.c +++ b/test/oslib/source/test/oslib_test_sequence_002.c @@ -21,259 +21,121 @@ * @file oslib_test_sequence_002.c * @brief Test Sequence 002 code. * - * @page oslib_test_sequence_002 [2] Memory Pools + * @page oslib_test_sequence_002 [2] Pipes * * File: @ref oslib_test_sequence_002.c * *

Description

* This sequence tests the ChibiOS library functionalities related to - * memory pools. + * pipes. * *

Conditions

* This sequence is only executed if the following preprocessor condition * evaluates to true: - * - CH_CFG_USE_MEMPOOLS + * - CH_CFG_USE_PIPES * . * *

Test Cases

* - @subpage oslib_test_002_001 - * - @subpage oslib_test_002_002 - * - @subpage oslib_test_002_003 * . */ -#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__) +#if (CH_CFG_USE_PIPES) || defined(__DOXYGEN__) /**************************************************************************** * Shared code. ****************************************************************************/ -#define MEMORY_POOL_SIZE 4 +#define PIPE_SIZE 16 -static uint32_t objects[MEMORY_POOL_SIZE]; -static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), PORT_NATURAL_ALIGN, NULL); +static uint8_t buffer[PIPE_SIZE]; +static PIPE_DECL(pipe1, buffer, PIPE_SIZE); -#if CH_CFG_USE_SEMAPHORES -static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t), PORT_NATURAL_ALIGN); -#endif - -static void *null_provider(size_t size, unsigned align) { - - (void)size; - (void)align; - - return NULL; -} +static const uint8_t pipe_pattern[] = "0123456789ABCDEF"; /**************************************************************************** * Test cases. ****************************************************************************/ /** - * @page oslib_test_002_001 [2.1] Loading and emptying a memory pool + * @page oslib_test_002_001 [2.1] Loading and emptying a pipe, non blocking * *

Description

- * The memory pool functionality is tested by loading and emptying it, - * all conditions are tested. + * The pipe functionality is tested by loading and emptying it, all + * conditions are tested. * *

Test Steps

- * - [2.1.1] Adding the objects to the pool using chPoolLoadArray(). - * - [2.1.2] Emptying the pool using chPoolAlloc(). - * - [2.1.3] Now must be empty. - * - [2.1.4] Adding the objects to the pool using chPoolFree(). - * - [2.1.5] Emptying the pool using chPoolAlloc() again. - * - [2.1.6] Now must be empty again. - * - [2.1.7] Covering the case where a provider is unable to return - * more memory. + * - [2.1.1] Filling whole pipe. + * - [2.1.2] Emptying pipe. + * - [2.1.3]. + * - [2.1.4]. + * - [2.1.5]. + * - [2.1.6]. * . */ static void oslib_test_002_001_setup(void) { - chPoolObjectInit(&mp1, sizeof (uint32_t), NULL); + chPipeObjectInit(&pipe1, buffer, PIPE_SIZE); } static void oslib_test_002_001_execute(void) { unsigned i; - /* [2.1.1] Adding the objects to the pool using chPoolLoadArray().*/ + /* [2.1.1] Filling whole pipe.*/ test_set_step(1); { - chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE); + msg_t msg; + + msg = chPipeWriteTimeout(&pipe1, pipe_pattern, PIPE_SIZE, TIME_IMMEDIATE); + test_assert(msg == PIPE_SIZE, "wrong size"); + test_assert((pipe1.rdptr == pipe1.buffer) && + (pipe1.wrptr == pipe1.buffer) && + (pipe1.cnt == PIPE_SIZE), + "invalid pipe state"); } - /* [2.1.2] Emptying the pool using chPoolAlloc().*/ + /* [2.1.2] Emptying pipe.*/ test_set_step(2); { - for (i = 0; i < MEMORY_POOL_SIZE; i++) - test_assert(chPoolAlloc(&mp1) != NULL, "list empty"); + msg_t msg; + uint8_t buf[PIPE_SIZE]; + + msg = chPipeReadTimeout(&pipe1, buf, PIPE_SIZE, TIME_IMMEDIATE); + test_assert(msg == PIPE_SIZE, "wrong size"); + test_assert((pipe1.rdptr == pipe1.buffer) && + (pipe1.wrptr == pipe1.buffer) && + (pipe1.cnt == 0), + "invalid pipe state"); } - /* [2.1.3] Now must be empty.*/ + /* [2.1.3].*/ test_set_step(3); { - test_assert(chPoolAlloc(&mp1) == NULL, "list not empty"); } - /* [2.1.4] Adding the objects to the pool using chPoolFree().*/ + /* [2.1.4].*/ test_set_step(4); { - for (i = 0; i < MEMORY_POOL_SIZE; i++) - chPoolFree(&mp1, &objects[i]); } - /* [2.1.5] Emptying the pool using chPoolAlloc() again.*/ + /* [2.1.5].*/ test_set_step(5); { - for (i = 0; i < MEMORY_POOL_SIZE; i++) - test_assert(chPoolAlloc(&mp1) != NULL, "list empty"); } - /* [2.1.6] Now must be empty again.*/ + /* [2.1.6].*/ test_set_step(6); { - test_assert(chPoolAlloc(&mp1) == NULL, "list not empty"); - } - - /* [2.1.7] Covering the case where a provider is unable to return - more memory.*/ - test_set_step(7); - { - chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider); - test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory"); } } static const testcase_t oslib_test_002_001 = { - "Loading and emptying a memory pool", + "Loading and emptying a pipe, non blocking", oslib_test_002_001_setup, NULL, oslib_test_002_001_execute }; -#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) -/** - * @page oslib_test_002_002 [2.2] Loading and emptying a guarded memory pool without waiting - * - *

Description

- * The memory pool functionality is tested by loading and emptying it, - * all conditions are tested. - * - *

Conditions

- * This test is only executed if the following preprocessor condition - * evaluates to true: - * - CH_CFG_USE_SEMAPHORES - * . - * - *

Test Steps

- * - [2.2.1] Adding the objects to the pool using - * chGuardedPoolLoadArray(). - * - [2.2.2] Emptying the pool using chGuardedPoolAllocTimeout(). - * - [2.2.3] Now must be empty. - * - [2.2.4] Adding the objects to the pool using chGuardedPoolFree(). - * - [2.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again. - * - [2.2.6] Now must be empty again. - * . - */ - -static void oslib_test_002_002_setup(void) { - chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t)); -} - -static void oslib_test_002_002_execute(void) { - unsigned i; - - /* [2.2.1] Adding the objects to the pool using - chGuardedPoolLoadArray().*/ - test_set_step(1); - { - chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE); - } - - /* [2.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/ - test_set_step(2); - { - for (i = 0; i < MEMORY_POOL_SIZE; i++) - test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty"); - } - - /* [2.2.3] Now must be empty.*/ - test_set_step(3); - { - test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty"); - } - - /* [2.2.4] Adding the objects to the pool using - chGuardedPoolFree().*/ - test_set_step(4); - { - for (i = 0; i < MEMORY_POOL_SIZE; i++) - chGuardedPoolFree(&gmp1, &objects[i]); - } - - /* [2.2.5] Emptying the pool using chGuardedPoolAllocTimeout() - again.*/ - test_set_step(5); - { - for (i = 0; i < MEMORY_POOL_SIZE; i++) - test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty"); - } - - /* [2.2.6] Now must be empty again.*/ - test_set_step(6); - { - test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty"); - } -} - -static const testcase_t oslib_test_002_002 = { - "Loading and emptying a guarded memory pool without waiting", - oslib_test_002_002_setup, - NULL, - oslib_test_002_002_execute -}; -#endif /* CH_CFG_USE_SEMAPHORES */ - -#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) -/** - * @page oslib_test_002_003 [2.3] Guarded Memory Pools timeout - * - *

Description

- * The timeout features for the Guarded Memory Pools is tested. - * - *

Conditions

- * This test is only executed if the following preprocessor condition - * evaluates to true: - * - CH_CFG_USE_SEMAPHORES - * . - * - *

Test Steps

- * - [2.3.1] Trying to allocate with 100mS timeout, must fail because - * the pool is empty. - * . - */ - -static void oslib_test_002_003_setup(void) { - chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t)); -} - -static void oslib_test_002_003_execute(void) { - - /* [2.3.1] Trying to allocate with 100mS timeout, must fail because - the pool is empty.*/ - test_set_step(1); - { - test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty"); - } -} - -static const testcase_t oslib_test_002_003 = { - "Guarded Memory Pools timeout", - oslib_test_002_003_setup, - NULL, - oslib_test_002_003_execute -}; -#endif /* CH_CFG_USE_SEMAPHORES */ - /**************************************************************************** * Exported data. ****************************************************************************/ @@ -283,21 +145,15 @@ static const testcase_t oslib_test_002_003 = { */ const testcase_t * const oslib_test_sequence_002_array[] = { &oslib_test_002_001, -#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) - &oslib_test_002_002, -#endif -#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) - &oslib_test_002_003, -#endif NULL }; /** - * @brief Memory Pools. + * @brief Pipes. */ const testsequence_t oslib_test_sequence_002 = { - "Memory Pools", + "Pipes", oslib_test_sequence_002_array }; -#endif /* CH_CFG_USE_MEMPOOLS */ +#endif /* CH_CFG_USE_PIPES */ diff --git a/test/oslib/source/test/oslib_test_sequence_003.c b/test/oslib/source/test/oslib_test_sequence_003.c index 9f623e9db..7bfd208e0 100644 --- a/test/oslib/source/test/oslib_test_sequence_003.c +++ b/test/oslib/source/test/oslib_test_sequence_003.c @@ -21,240 +21,258 @@ * @file oslib_test_sequence_003.c * @brief Test Sequence 003 code. * - * @page oslib_test_sequence_003 [3] Memory Heaps + * @page oslib_test_sequence_003 [3] Memory Pools * * File: @ref oslib_test_sequence_003.c * *

Description

* This sequence tests the ChibiOS library functionalities related to - * memory heaps. + * memory pools. * *

Conditions

* This sequence is only executed if the following preprocessor condition * evaluates to true: - * - CH_CFG_USE_HEAP + * - CH_CFG_USE_MEMPOOLS * . * *

Test Cases

* - @subpage oslib_test_003_001 * - @subpage oslib_test_003_002 + * - @subpage oslib_test_003_003 * . */ -#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__) +#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__) /**************************************************************************** * Shared code. ****************************************************************************/ -#define ALLOC_SIZE 16 -#define HEAP_SIZE (ALLOC_SIZE * 8) +#define MEMORY_POOL_SIZE 4 -static memory_heap_t test_heap; -static uint8_t test_heap_buffer[HEAP_SIZE]; +static uint32_t objects[MEMORY_POOL_SIZE]; +static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), PORT_NATURAL_ALIGN, NULL); + +#if CH_CFG_USE_SEMAPHORES +static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t), PORT_NATURAL_ALIGN); +#endif + +static void *null_provider(size_t size, unsigned align) { + + (void)size; + (void)align; + + return NULL; +} /**************************************************************************** * Test cases. ****************************************************************************/ /** - * @page oslib_test_003_001 [3.1] Allocation and fragmentation + * @page oslib_test_003_001 [3.1] Loading and emptying a memory pool * *

Description

- * Series of allocations/deallocations are performed in carefully - * designed sequences in order to stimulate all the possible code paths - * inside the allocator. The test expects to find the heap back to the - * initial status after each sequence. + * The memory pool functionality is tested by loading and emptying it, + * all conditions are tested. * *

Test Steps

- * - [3.1.1] Testing initial conditions, the heap must not be - * fragmented and one free block present. - * - [3.1.2] Trying to allocate an block bigger than available space, - * an error is expected. - * - [3.1.3] Single block allocation using chHeapAlloc() then the block - * is freed using chHeapFree(), must not fail. - * - [3.1.4] Using chHeapStatus() to assess the heap state. There must - * be at least one free block of sufficient size. - * - [3.1.5] Allocating then freeing in the same order. - * - [3.1.6] Allocating then freeing in reverse order. - * - [3.1.7] Small fragments handling. Checking the behavior when - * allocating blocks with size not multiple of alignment unit. - * - [3.1.8] Skipping a fragment, the first fragment in the list is too - * small so the allocator must pick the second one. - * - [3.1.9] Allocating the whole available space. - * - [3.1.10] Testing final conditions. The heap geometry must be the - * same than the one registered at beginning. + * - [3.1.1] Adding the objects to the pool using chPoolLoadArray(). + * - [3.1.2] Emptying the pool using chPoolAlloc(). + * - [3.1.3] Now must be empty. + * - [3.1.4] Adding the objects to the pool using chPoolFree(). + * - [3.1.5] Emptying the pool using chPoolAlloc() again. + * - [3.1.6] Now must be empty again. + * - [3.1.7] Covering the case where a provider is unable to return + * more memory. * . */ static void oslib_test_003_001_setup(void) { - chHeapObjectInit(&test_heap, test_heap_buffer, sizeof(test_heap_buffer)); + chPoolObjectInit(&mp1, sizeof (uint32_t), NULL); } static void oslib_test_003_001_execute(void) { - void *p1, *p2, *p3; - size_t n, sz; + unsigned i; - /* [3.1.1] Testing initial conditions, the heap must not be - fragmented and one free block present.*/ + /* [3.1.1] Adding the objects to the pool using chPoolLoadArray().*/ test_set_step(1); { - test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented"); + chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE); } - /* [3.1.2] Trying to allocate an block bigger than available space, - an error is expected.*/ + /* [3.1.2] Emptying the pool using chPoolAlloc().*/ test_set_step(2); { - p1 = chHeapAlloc(&test_heap, sizeof test_heap_buffer * 2); - test_assert(p1 == NULL, "allocation not failed"); + for (i = 0; i < MEMORY_POOL_SIZE; i++) + test_assert(chPoolAlloc(&mp1) != NULL, "list empty"); } - /* [3.1.3] Single block allocation using chHeapAlloc() then the block - is freed using chHeapFree(), must not fail.*/ + /* [3.1.3] Now must be empty.*/ test_set_step(3); { - p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); - test_assert(p1 != NULL, "allocation failed"); - chHeapFree(p1); + test_assert(chPoolAlloc(&mp1) == NULL, "list not empty"); } - /* [3.1.4] Using chHeapStatus() to assess the heap state. There must - be at least one free block of sufficient size.*/ + /* [3.1.4] Adding the objects to the pool using chPoolFree().*/ test_set_step(4); { - size_t total_size, largest_size; - - n = chHeapStatus(&test_heap, &total_size, &largest_size); - test_assert(n == 1, "missing free block"); - test_assert(total_size >= ALLOC_SIZE, "unexpected heap state"); - test_assert(total_size == largest_size, "unexpected heap state"); + for (i = 0; i < MEMORY_POOL_SIZE; i++) + chPoolFree(&mp1, &objects[i]); } - /* [3.1.5] Allocating then freeing in the same order.*/ + /* [3.1.5] Emptying the pool using chPoolAlloc() again.*/ test_set_step(5); { - p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); - p2 = chHeapAlloc(&test_heap, ALLOC_SIZE); - p3 = chHeapAlloc(&test_heap, ALLOC_SIZE); - chHeapFree(p1); /* Does not merge.*/ - chHeapFree(p2); /* Merges backward.*/ - chHeapFree(p3); /* Merges both sides.*/ - test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented"); + for (i = 0; i < MEMORY_POOL_SIZE; i++) + test_assert(chPoolAlloc(&mp1) != NULL, "list empty"); } - /* [3.1.6] Allocating then freeing in reverse order.*/ + /* [3.1.6] Now must be empty again.*/ test_set_step(6); { - p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); - p2 = chHeapAlloc(&test_heap, ALLOC_SIZE); - p3 = chHeapAlloc(&test_heap, ALLOC_SIZE); - chHeapFree(p3); /* Merges forward.*/ - chHeapFree(p2); /* Merges forward.*/ - chHeapFree(p1); /* Merges forward.*/ - test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented"); + test_assert(chPoolAlloc(&mp1) == NULL, "list not empty"); } - /* [3.1.7] Small fragments handling. Checking the behavior when - allocating blocks with size not multiple of alignment unit.*/ + /* [3.1.7] Covering the case where a provider is unable to return + more memory.*/ test_set_step(7); { - p1 = chHeapAlloc(&test_heap, ALLOC_SIZE + 1); - p2 = chHeapAlloc(&test_heap, ALLOC_SIZE); - chHeapFree(p1); - test_assert(chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state"); - p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); - /* Note, the first situation happens when the alignment size is smaller - than the header size, the second in the other cases.*/ - test_assert((chHeapStatus(&test_heap, &n, NULL) == 1) || - (chHeapStatus(&test_heap, &n, NULL) == 2), "heap fragmented"); - chHeapFree(p2); - chHeapFree(p1); - test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented"); - } - - /* [3.1.8] Skipping a fragment, the first fragment in the list is too - small so the allocator must pick the second one.*/ - test_set_step(8); - { - p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); - p2 = chHeapAlloc(&test_heap, ALLOC_SIZE); - chHeapFree(p1); - test_assert( chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state"); - p1 = chHeapAlloc(&test_heap, ALLOC_SIZE * 2); /* Skips first fragment.*/ - chHeapFree(p1); - chHeapFree(p2); - test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented"); - } - - /* [3.1.9] Allocating the whole available space.*/ - test_set_step(9); - { - (void)chHeapStatus(&test_heap, &n, NULL); - p1 = chHeapAlloc(&test_heap, n); - test_assert(p1 != NULL, "allocation failed"); - test_assert(chHeapStatus(&test_heap, NULL, NULL) == 0, "not empty"); - chHeapFree(p1); - } - - /* [3.1.10] Testing final conditions. The heap geometry must be the - same than the one registered at beginning.*/ - test_set_step(10); - { - test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented"); - test_assert(n == sz, "size changed"); + chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider); + test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory"); } } static const testcase_t oslib_test_003_001 = { - "Allocation and fragmentation", + "Loading and emptying a memory pool", oslib_test_003_001_setup, NULL, oslib_test_003_001_execute }; +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) /** - * @page oslib_test_003_002 [3.2] Default Heap + * @page oslib_test_003_002 [3.2] Loading and emptying a guarded memory pool without waiting * *

Description

- * The default heap is pre-allocated in the system. We test base - * functionality. + * The memory pool functionality is tested by loading and emptying it, + * all conditions are tested. + * + *

Conditions

+ * This test is only executed if the following preprocessor condition + * evaluates to true: + * - CH_CFG_USE_SEMAPHORES + * . * *

Test Steps

- * - [3.2.1] Single block allocation using chHeapAlloc() then the block - * is freed using chHeapFree(), must not fail. - * - [3.2.2] Testing allocation failure. + * - [3.2.1] Adding the objects to the pool using + * chGuardedPoolLoadArray(). + * - [3.2.2] Emptying the pool using chGuardedPoolAllocTimeout(). + * - [3.2.3] Now must be empty. + * - [3.2.4] Adding the objects to the pool using chGuardedPoolFree(). + * - [3.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again. + * - [3.2.6] Now must be empty again. * . */ +static void oslib_test_003_002_setup(void) { + chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t)); +} + static void oslib_test_003_002_execute(void) { - void *p1; - size_t total_size, largest_size; + unsigned i; - /* [3.2.1] Single block allocation using chHeapAlloc() then the block - is freed using chHeapFree(), must not fail.*/ + /* [3.2.1] Adding the objects to the pool using + chGuardedPoolLoadArray().*/ test_set_step(1); { - (void)chHeapStatus(NULL, &total_size, &largest_size); - p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); - test_assert(p1 != NULL, "allocation failed"); - chHeapFree(p1); + chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE); } - /* [3.2.2] Testing allocation failure.*/ + /* [3.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/ test_set_step(2); { - p1 = chHeapAlloc(NULL, (size_t)-256); - test_assert(p1 == NULL, "allocation not failed"); + for (i = 0; i < MEMORY_POOL_SIZE; i++) + test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty"); + } + + /* [3.2.3] Now must be empty.*/ + test_set_step(3); + { + test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty"); + } + + /* [3.2.4] Adding the objects to the pool using + chGuardedPoolFree().*/ + test_set_step(4); + { + for (i = 0; i < MEMORY_POOL_SIZE; i++) + chGuardedPoolFree(&gmp1, &objects[i]); + } + + /* [3.2.5] Emptying the pool using chGuardedPoolAllocTimeout() + again.*/ + test_set_step(5); + { + for (i = 0; i < MEMORY_POOL_SIZE; i++) + test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty"); + } + + /* [3.2.6] Now must be empty again.*/ + test_set_step(6); + { + test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty"); } } static const testcase_t oslib_test_003_002 = { - "Default Heap", - NULL, + "Loading and emptying a guarded memory pool without waiting", + oslib_test_003_002_setup, NULL, oslib_test_003_002_execute }; +#endif /* CH_CFG_USE_SEMAPHORES */ + +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) +/** + * @page oslib_test_003_003 [3.3] Guarded Memory Pools timeout + * + *

Description

+ * The timeout features for the Guarded Memory Pools is tested. + * + *

Conditions

+ * This test is only executed if the following preprocessor condition + * evaluates to true: + * - CH_CFG_USE_SEMAPHORES + * . + * + *

Test Steps

+ * - [3.3.1] Trying to allocate with 100mS timeout, must fail because + * the pool is empty. + * . + */ + +static void oslib_test_003_003_setup(void) { + chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t)); +} + +static void oslib_test_003_003_execute(void) { + + /* [3.3.1] Trying to allocate with 100mS timeout, must fail because + the pool is empty.*/ + test_set_step(1); + { + test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty"); + } +} + +static const testcase_t oslib_test_003_003 = { + "Guarded Memory Pools timeout", + oslib_test_003_003_setup, + NULL, + oslib_test_003_003_execute +}; +#endif /* CH_CFG_USE_SEMAPHORES */ /**************************************************************************** * Exported data. @@ -265,16 +283,21 @@ static const testcase_t oslib_test_003_002 = { */ const testcase_t * const oslib_test_sequence_003_array[] = { &oslib_test_003_001, +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) &oslib_test_003_002, +#endif +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) + &oslib_test_003_003, +#endif NULL }; /** - * @brief Memory Heaps. + * @brief Memory Pools. */ const testsequence_t oslib_test_sequence_003 = { - "Memory Heaps", + "Memory Pools", oslib_test_sequence_003_array }; -#endif /* CH_CFG_USE_HEAP */ +#endif /* CH_CFG_USE_MEMPOOLS */ diff --git a/test/oslib/source/test/oslib_test_sequence_004.c b/test/oslib/source/test/oslib_test_sequence_004.c index a053008d8..84b466a64 100644 --- a/test/oslib/source/test/oslib_test_sequence_004.c +++ b/test/oslib/source/test/oslib_test_sequence_004.c @@ -21,725 +21,240 @@ * @file oslib_test_sequence_004.c * @brief Test Sequence 004 code. * - * @page oslib_test_sequence_004 [4] Objects Factory + * @page oslib_test_sequence_004 [4] Memory Heaps * * File: @ref oslib_test_sequence_004.c * *

Description

* This sequence tests the ChibiOS library functionalities related to - * the object factory. + * memory heaps. * *

Conditions

* This sequence is only executed if the following preprocessor condition * evaluates to true: - * - (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE) + * - CH_CFG_USE_HEAP * . * *

Test Cases

* - @subpage oslib_test_004_001 * - @subpage oslib_test_004_002 - * - @subpage oslib_test_004_003 - * - @subpage oslib_test_004_004 - * - @subpage oslib_test_004_005 - * - @subpage oslib_test_004_006 * . */ -#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__) +#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__) /**************************************************************************** * Shared code. ****************************************************************************/ +#define ALLOC_SIZE 16 +#define HEAP_SIZE (ALLOC_SIZE * 8) + +static memory_heap_t test_heap; +static uint8_t test_heap_buffer[HEAP_SIZE]; /**************************************************************************** * Test cases. ****************************************************************************/ -#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__) /** - * @page oslib_test_004_001 [4.1] Objects Registry + * @page oslib_test_004_001 [4.1] Allocation and fragmentation * *

Description

- * This test case verifies the static objects registry. - * - *

Conditions

- * This test is only executed if the following preprocessor condition - * evaluates to true: - * - CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE - * . + * Series of allocations/deallocations are performed in carefully + * designed sequences in order to stimulate all the possible code paths + * inside the allocator. The test expects to find the heap back to the + * initial status after each sequence. * *

Test Steps

- * - [4.1.1] Retrieving a registered object by name, must not exist. - * - [4.1.2] Registering an object, it must not exists, must succeed. - * - [4.1.3] Registering an object with the same name, must fail. - * - [4.1.4] Retrieving the registered object by name, must exist, then - * increasing the reference counter, finally releasing both - * references. - * - [4.1.5] Releasing the first reference to the object, must not - * trigger an assertion. - * - [4.1.6] Retrieving the registered object by name again, must not - * exist. + * - [4.1.1] Testing initial conditions, the heap must not be + * fragmented and one free block present. + * - [4.1.2] Trying to allocate an block bigger than available space, + * an error is expected. + * - [4.1.3] Single block allocation using chHeapAlloc() then the block + * is freed using chHeapFree(), must not fail. + * - [4.1.4] Using chHeapStatus() to assess the heap state. There must + * be at least one free block of sufficient size. + * - [4.1.5] Allocating then freeing in the same order. + * - [4.1.6] Allocating then freeing in reverse order. + * - [4.1.7] Small fragments handling. Checking the behavior when + * allocating blocks with size not multiple of alignment unit. + * - [4.1.8] Skipping a fragment, the first fragment in the list is too + * small so the allocator must pick the second one. + * - [4.1.9] Allocating the whole available space. + * - [4.1.10] Testing final conditions. The heap geometry must be the + * same than the one registered at beginning. * . */ -static void oslib_test_004_001_teardown(void) { - registered_object_t *rop; - - rop = chFactoryFindObject("myobj"); - if (rop != NULL) { - while (rop->element.refs > 0U) { - chFactoryReleaseObject(rop); - } - } +static void oslib_test_004_001_setup(void) { + chHeapObjectInit(&test_heap, test_heap_buffer, sizeof(test_heap_buffer)); } static void oslib_test_004_001_execute(void) { - registered_object_t *rop; + void *p1, *p2, *p3; + size_t n, sz; - /* [4.1.1] Retrieving a registered object by name, must not exist.*/ + /* [4.1.1] Testing initial conditions, the heap must not be + fragmented and one free block present.*/ test_set_step(1); { - rop = chFactoryFindObject("myobj"); - test_assert(rop == NULL, "found"); + test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented"); } - /* [4.1.2] Registering an object, it must not exists, must succeed.*/ + /* [4.1.2] Trying to allocate an block bigger than available space, + an error is expected.*/ test_set_step(2); { - static uint32_t myobj = 0x55aa; - - rop = chFactoryRegisterObject("myobj", (void *)&myobj); - test_assert(rop != NULL, "cannot register"); + p1 = chHeapAlloc(&test_heap, sizeof test_heap_buffer * 2); + test_assert(p1 == NULL, "allocation not failed"); } - /* [4.1.3] Registering an object with the same name, must fail.*/ + /* [4.1.3] Single block allocation using chHeapAlloc() then the block + is freed using chHeapFree(), must not fail.*/ test_set_step(3); { - registered_object_t *rop1; - static uint32_t myobj = 0x55aa; - - rop1 = chFactoryRegisterObject("myobj", (void *)&myobj); - test_assert(rop1 == NULL, "can register"); + p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); + test_assert(p1 != NULL, "allocation failed"); + chHeapFree(p1); } - /* [4.1.4] Retrieving the registered object by name, must exist, then - increasing the reference counter, finally releasing both - references.*/ + /* [4.1.4] Using chHeapStatus() to assess the heap state. There must + be at least one free block of sufficient size.*/ test_set_step(4); { - registered_object_t *rop1, *rop2; - - rop1 = chFactoryFindObject("myobj"); - test_assert(rop1 != NULL, "not found"); - test_assert(*(uint32_t *)(rop1->objp) == 0x55aa, "object mismatch"); - test_assert(rop == rop1, "object reference mismatch"); - test_assert(rop1->element.refs == 2, "object reference mismatch"); - - rop2 = (registered_object_t *)chFactoryDuplicateReference(&rop1->element); - test_assert(rop1 == rop2, "object reference mismatch"); - test_assert(*(uint32_t *)(rop2->objp) == 0x55aa, "object mismatch"); - test_assert(rop2->element.refs == 3, "object reference mismatch"); - - chFactoryReleaseObject(rop2); - test_assert(rop1->element.refs == 2, "references mismatch"); + size_t total_size, largest_size; - chFactoryReleaseObject(rop1); - test_assert(rop->element.refs == 1, "references mismatch"); + n = chHeapStatus(&test_heap, &total_size, &largest_size); + test_assert(n == 1, "missing free block"); + test_assert(total_size >= ALLOC_SIZE, "unexpected heap state"); + test_assert(total_size == largest_size, "unexpected heap state"); } - /* [4.1.5] Releasing the first reference to the object, must not - trigger an assertion.*/ + /* [4.1.5] Allocating then freeing in the same order.*/ test_set_step(5); { - chFactoryReleaseObject(rop); + p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); + p2 = chHeapAlloc(&test_heap, ALLOC_SIZE); + p3 = chHeapAlloc(&test_heap, ALLOC_SIZE); + chHeapFree(p1); /* Does not merge.*/ + chHeapFree(p2); /* Merges backward.*/ + chHeapFree(p3); /* Merges both sides.*/ + test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented"); } - /* [4.1.6] Retrieving the registered object by name again, must not - exist.*/ + /* [4.1.6] Allocating then freeing in reverse order.*/ test_set_step(6); { - rop = chFactoryFindObject("myobj"); - test_assert(rop == NULL, "found"); - } -} - -static const testcase_t oslib_test_004_001 = { - "Objects Registry", - NULL, - oslib_test_004_001_teardown, - oslib_test_004_001_execute -}; -#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */ - -#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__) -/** - * @page oslib_test_004_002 [4.2] Dynamic Buffers Factory - * - *

Description

- * This test case verifies the dynamic buffers factory. - * - *

Conditions

- * This test is only executed if the following preprocessor condition - * evaluates to true: - * - CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE - * . - * - *

Test Steps

- * - [4.2.1] Retrieving a dynamic buffer by name, must not exist. - * - [4.2.2] Creating a dynamic buffer it must not exists, must - * succeed. - * - [4.2.3] Creating a dynamic buffer with the same name, must fail. - * - [4.2.4] Retrieving the dynamic buffer by name, must exist, then - * increasing the reference counter, finally releasing both - * references. - * - [4.2.5] Releasing the first reference to the dynamic buffer, must - * not trigger an assertion. - * - [4.2.6] Retrieving the dynamic buffer by name again, must not - * exist. - * . - */ - -static void oslib_test_004_002_teardown(void) { - dyn_buffer_t *dbp; - - dbp = chFactoryFindBuffer("mybuf"); - if (dbp != NULL) { - while (dbp->element.refs > 0U) { - chFactoryReleaseBuffer(dbp); - } - } -} - -static void oslib_test_004_002_execute(void) { - dyn_buffer_t *dbp; - - /* [4.2.1] Retrieving a dynamic buffer by name, must not exist.*/ - test_set_step(1); - { - dbp = chFactoryFindBuffer("mybuf"); - test_assert(dbp == NULL, "found"); - } - - /* [4.2.2] Creating a dynamic buffer it must not exists, must - succeed.*/ - test_set_step(2); - { - dbp = chFactoryCreateBuffer("mybuf", 128U); - test_assert(dbp != NULL, "cannot create"); - } - - /* [4.2.3] Creating a dynamic buffer with the same name, must fail.*/ - test_set_step(3); - { - dyn_buffer_t *dbp1; - - dbp1 = chFactoryCreateBuffer("mybuf", 128U); - test_assert(dbp1 == NULL, "can create"); - } - - /* [4.2.4] Retrieving the dynamic buffer by name, must exist, then - increasing the reference counter, finally releasing both - references.*/ - test_set_step(4); - { - dyn_buffer_t *dbp1, *dbp2; - - dbp1 = chFactoryFindBuffer("mybuf"); - test_assert(dbp1 != NULL, "not found"); - test_assert(dbp == dbp1, "object reference mismatch"); - test_assert(dbp1->element.refs == 2, "object reference mismatch"); - - dbp2 = (dyn_buffer_t *)chFactoryDuplicateReference(&dbp1->element); - test_assert(dbp1 == dbp2, "object reference mismatch"); - test_assert(dbp2->element.refs == 3, "object reference mismatch"); - - chFactoryReleaseBuffer(dbp2); - test_assert(dbp1->element.refs == 2, "references mismatch"); - - chFactoryReleaseBuffer(dbp1); - test_assert(dbp->element.refs == 1, "references mismatch"); - } - - /* [4.2.5] Releasing the first reference to the dynamic buffer, must - not trigger an assertion.*/ - test_set_step(5); - { - chFactoryReleaseBuffer(dbp); - } - - /* [4.2.6] Retrieving the dynamic buffer by name again, must not - exist.*/ - test_set_step(6); - { - dbp = chFactoryFindBuffer("mybuf"); - test_assert(dbp == NULL, "found"); - } -} - -static const testcase_t oslib_test_004_002 = { - "Dynamic Buffers Factory", - NULL, - oslib_test_004_002_teardown, - oslib_test_004_002_execute -}; -#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE */ - -#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__) -/** - * @page oslib_test_004_003 [4.3] Dynamic Semaphores Factory - * - *

Description

- * This test case verifies the dynamic semaphores factory. - * - *

Conditions

- * This test is only executed if the following preprocessor condition - * evaluates to true: - * - CH_CFG_FACTORY_SEMAPHORES == TRUE - * . - * - *

Test Steps

- * - [4.3.1] Retrieving a dynamic semaphore by name, must not exist. - * - [4.3.2] Creating a dynamic semaphore it must not exists, must - * succeed. - * - [4.3.3] Creating a dynamic semaphore with the same name, must - * fail. - * - [4.3.4] Retrieving the dynamic semaphore by name, must exist, then - * increasing the reference counter, finally releasing both - * references. - * - [4.3.5] Releasing the first reference to the dynamic semaphore - * must not trigger an assertion. - * - [4.3.6] Retrieving the dynamic semaphore by name again, must not - * exist. - * . - */ - -static void oslib_test_004_003_teardown(void) { - dyn_semaphore_t *dsp; - - dsp = chFactoryFindSemaphore("mysem"); - if (dsp != NULL) { - while (dsp->element.refs > 0U) { - chFactoryReleaseSemaphore(dsp); - } - } -} - -static void oslib_test_004_003_execute(void) { - dyn_semaphore_t *dsp; - - /* [4.3.1] Retrieving a dynamic semaphore by name, must not exist.*/ - test_set_step(1); - { - dsp = chFactoryFindSemaphore("mysem"); - test_assert(dsp == NULL, "found"); - } - - /* [4.3.2] Creating a dynamic semaphore it must not exists, must - succeed.*/ - test_set_step(2); - { - dsp = chFactoryCreateSemaphore("mysem", 0); - test_assert(dsp != NULL, "cannot create"); - } - - /* [4.3.3] Creating a dynamic semaphore with the same name, must - fail.*/ - test_set_step(3); - { - dyn_semaphore_t *dsp1; - - dsp1 = chFactoryCreateSemaphore("mysem", 0); - test_assert(dsp1 == NULL, "can create"); - } - - /* [4.3.4] Retrieving the dynamic semaphore by name, must exist, then - increasing the reference counter, finally releasing both - references.*/ - test_set_step(4); - { - dyn_semaphore_t *dsp1, *dsp2; - - dsp1 = chFactoryFindSemaphore("mysem"); - test_assert(dsp1 != NULL, "not found"); - test_assert(dsp == dsp1, "object reference mismatch"); - test_assert(dsp1->element.refs == 2, "object reference mismatch"); - - dsp2 = (dyn_semaphore_t *)chFactoryDuplicateReference(&dsp1->element); - test_assert(dsp1 == dsp2, "object reference mismatch"); - test_assert(dsp2->element.refs == 3, "object reference mismatch"); - - chFactoryReleaseSemaphore(dsp2); - test_assert(dsp1->element.refs == 2, "references mismatch"); - - chFactoryReleaseSemaphore(dsp1); - test_assert(dsp->element.refs == 1, "references mismatch"); - } - - /* [4.3.5] Releasing the first reference to the dynamic semaphore - must not trigger an assertion.*/ - test_set_step(5); - { - chFactoryReleaseSemaphore(dsp); - } - - /* [4.3.6] Retrieving the dynamic semaphore by name again, must not - exist.*/ - test_set_step(6); - { - dsp = chFactoryFindSemaphore("mysem"); - test_assert(dsp == NULL, "found"); - } -} - -static const testcase_t oslib_test_004_003 = { - "Dynamic Semaphores Factory", - NULL, - oslib_test_004_003_teardown, - oslib_test_004_003_execute -}; -#endif /* CH_CFG_FACTORY_SEMAPHORES == TRUE */ - -#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__) -/** - * @page oslib_test_004_004 [4.4] Dynamic Mailboxes Factory - * - *

Description

- * This test case verifies the dynamic mailboxes factory. - * - *

Conditions

- * This test is only executed if the following preprocessor condition - * evaluates to true: - * - CH_CFG_FACTORY_MAILBOXES == TRUE - * . - * - *

Test Steps

- * - [4.4.1] Retrieving a dynamic mailbox by name, must not exist. - * - [4.4.2] Creating a dynamic mailbox it must not exists, must - * succeed. - * - [4.4.3] Creating a dynamic mailbox with the same name, must fail. - * - [4.4.4] Retrieving the dynamic mailbox by name, must exist, then - * increasing the reference counter, finally releasing both - * references. - * - [4.4.5] Releasing the first reference to the dynamic mailbox must - * not trigger an assertion. - * - [4.4.6] Retrieving the dynamic mailbox by name again, must not - * exist. - * . - */ - -static void oslib_test_004_004_teardown(void) { - dyn_mailbox_t *dmp; - - dmp = chFactoryFindMailbox("mymbx"); - if (dmp != NULL) { - while (dmp->element.refs > 0U) { - chFactoryReleaseMailbox(dmp); - } - } -} - -static void oslib_test_004_004_execute(void) { - dyn_mailbox_t *dmp; - - /* [4.4.1] Retrieving a dynamic mailbox by name, must not exist.*/ - test_set_step(1); - { - dmp = chFactoryFindMailbox("mymbx"); - test_assert(dmp == NULL, "found"); + p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); + p2 = chHeapAlloc(&test_heap, ALLOC_SIZE); + p3 = chHeapAlloc(&test_heap, ALLOC_SIZE); + chHeapFree(p3); /* Merges forward.*/ + chHeapFree(p2); /* Merges forward.*/ + chHeapFree(p1); /* Merges forward.*/ + test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented"); } - /* [4.4.2] Creating a dynamic mailbox it must not exists, must - succeed.*/ - test_set_step(2); + /* [4.1.7] Small fragments handling. Checking the behavior when + allocating blocks with size not multiple of alignment unit.*/ + test_set_step(7); { - dmp = chFactoryCreateMailbox("mymbx", 16U); - test_assert(dmp != NULL, "cannot create"); + p1 = chHeapAlloc(&test_heap, ALLOC_SIZE + 1); + p2 = chHeapAlloc(&test_heap, ALLOC_SIZE); + chHeapFree(p1); + test_assert(chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state"); + p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); + /* Note, the first situation happens when the alignment size is smaller + than the header size, the second in the other cases.*/ + test_assert((chHeapStatus(&test_heap, &n, NULL) == 1) || + (chHeapStatus(&test_heap, &n, NULL) == 2), "heap fragmented"); + chHeapFree(p2); + chHeapFree(p1); + test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented"); } - /* [4.4.3] Creating a dynamic mailbox with the same name, must - fail.*/ - test_set_step(3); - { - dyn_mailbox_t *dmp1; - - dmp1 = chFactoryCreateMailbox("mymbx", 16U); - test_assert(dmp1 == NULL, "can create"); - } - - /* [4.4.4] Retrieving the dynamic mailbox by name, must exist, then - increasing the reference counter, finally releasing both - references.*/ - test_set_step(4); + /* [4.1.8] Skipping a fragment, the first fragment in the list is too + small so the allocator must pick the second one.*/ + test_set_step(8); { - dyn_mailbox_t *dmp1, *dmp2; - - dmp1 = chFactoryFindMailbox("mymbx"); - test_assert(dmp1 != NULL, "not found"); - test_assert(dmp == dmp1, "object reference mismatch"); - test_assert(dmp1->element.refs == 2, "object reference mismatch"); - - dmp2 = (dyn_mailbox_t *)chFactoryDuplicateReference(&dmp1->element); - test_assert(dmp1 == dmp2, "object reference mismatch"); - test_assert(dmp2->element.refs == 3, "object reference mismatch"); - - chFactoryReleaseMailbox(dmp2); - test_assert(dmp1->element.refs == 2, "references mismatch"); - - chFactoryReleaseMailbox(dmp1); - test_assert(dmp->element.refs == 1, "references mismatch"); + p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); + p2 = chHeapAlloc(&test_heap, ALLOC_SIZE); + chHeapFree(p1); + test_assert( chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state"); + p1 = chHeapAlloc(&test_heap, ALLOC_SIZE * 2); /* Skips first fragment.*/ + chHeapFree(p1); + chHeapFree(p2); + test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented"); } - /* [4.4.5] Releasing the first reference to the dynamic mailbox must - not trigger an assertion.*/ - test_set_step(5); + /* [4.1.9] Allocating the whole available space.*/ + test_set_step(9); { - chFactoryReleaseMailbox(dmp); + (void)chHeapStatus(&test_heap, &n, NULL); + p1 = chHeapAlloc(&test_heap, n); + test_assert(p1 != NULL, "allocation failed"); + test_assert(chHeapStatus(&test_heap, NULL, NULL) == 0, "not empty"); + chHeapFree(p1); } - /* [4.4.6] Retrieving the dynamic mailbox by name again, must not - exist.*/ - test_set_step(6); + /* [4.1.10] Testing final conditions. The heap geometry must be the + same than the one registered at beginning.*/ + test_set_step(10); { - dmp = chFactoryFindMailbox("mymbx"); - test_assert(dmp == NULL, "found"); + test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented"); + test_assert(n == sz, "size changed"); } } -static const testcase_t oslib_test_004_004 = { - "Dynamic Mailboxes Factory", +static const testcase_t oslib_test_004_001 = { + "Allocation and fragmentation", + oslib_test_004_001_setup, NULL, - oslib_test_004_004_teardown, - oslib_test_004_004_execute + oslib_test_004_001_execute }; -#endif /* CH_CFG_FACTORY_MAILBOXES == TRUE */ -#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__) /** - * @page oslib_test_004_005 [4.5] Dynamic Objects FIFOs Factory + * @page oslib_test_004_002 [4.2] Default Heap * *

Description

- * This test case verifies the dynamic objects FIFOs factory. - * - *

Conditions

- * This test is only executed if the following preprocessor condition - * evaluates to true: - * - CH_CFG_FACTORY_OBJ_FIFOS == TRUE - * . + * The default heap is pre-allocated in the system. We test base + * functionality. * *

Test Steps

- * - [4.5.1] Retrieving a dynamic objects FIFO by name, must not exist. - * - [4.5.2] Creating a dynamic objects FIFO it must not exists, must - * succeed. - * - [4.5.3] Creating a dynamic objects FIFO with the same name, must - * fail. - * - [4.5.4] Retrieving the dynamic objects FIFO by name, must exist, - * then increasing the reference counter, finally releasing both - * references. - * - [4.5.5] Releasing the first reference to the dynamic objects FIFO - * must not trigger an assertion. - * - [4.5.6] Retrieving the dynamic objects FIFO by name again, must - * not exist. + * - [4.2.1] Single block allocation using chHeapAlloc() then the block + * is freed using chHeapFree(), must not fail. + * - [4.2.2] Testing allocation failure. * . */ -static void oslib_test_004_005_teardown(void) { - dyn_objects_fifo_t *dofp; - - dofp = chFactoryFindObjectsFIFO("myfifo"); - if (dofp != NULL) { - while (dofp->element.refs > 0U) { - chFactoryReleaseObjectsFIFO(dofp); - } - } -} - -static void oslib_test_004_005_execute(void) { - dyn_objects_fifo_t *dofp; +static void oslib_test_004_002_execute(void) { + void *p1; + size_t total_size, largest_size; - /* [4.5.1] Retrieving a dynamic objects FIFO by name, must not - exist.*/ + /* [4.2.1] Single block allocation using chHeapAlloc() then the block + is freed using chHeapFree(), must not fail.*/ test_set_step(1); { - dofp = chFactoryFindObjectsFIFO("myfifo"); - test_assert(dofp == NULL, "found"); + (void)chHeapStatus(NULL, &total_size, &largest_size); + p1 = chHeapAlloc(&test_heap, ALLOC_SIZE); + test_assert(p1 != NULL, "allocation failed"); + chHeapFree(p1); } - /* [4.5.2] Creating a dynamic objects FIFO it must not exists, must - succeed.*/ + /* [4.2.2] Testing allocation failure.*/ test_set_step(2); { - dofp = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN); - test_assert(dofp != NULL, "cannot create"); - } - - /* [4.5.3] Creating a dynamic objects FIFO with the same name, must - fail.*/ - test_set_step(3); - { - dyn_objects_fifo_t *dofp1; - - dofp1 = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN); - test_assert(dofp1 == NULL, "can create"); - } - - /* [4.5.4] Retrieving the dynamic objects FIFO by name, must exist, - then increasing the reference counter, finally releasing both - references.*/ - test_set_step(4); - { - dyn_objects_fifo_t *dofp1, *dofp2; - - dofp1 = chFactoryFindObjectsFIFO("myfifo"); - test_assert(dofp1 != NULL, "not found"); - test_assert(dofp == dofp1, "object reference mismatch"); - test_assert(dofp1->element.refs == 2, "object reference mismatch"); - - dofp2 = (dyn_objects_fifo_t *)chFactoryDuplicateReference(&dofp1->element); - test_assert(dofp1 == dofp2, "object reference mismatch"); - test_assert(dofp2->element.refs == 3, "object reference mismatch"); - - chFactoryReleaseObjectsFIFO(dofp2); - test_assert(dofp1->element.refs == 2, "references mismatch"); - - chFactoryReleaseObjectsFIFO(dofp1); - test_assert(dofp->element.refs == 1, "references mismatch"); - } - - /* [4.5.5] Releasing the first reference to the dynamic objects FIFO - must not trigger an assertion.*/ - test_set_step(5); - { - chFactoryReleaseObjectsFIFO(dofp); - } - - /* [4.5.6] Retrieving the dynamic objects FIFO by name again, must - not exist.*/ - test_set_step(6); - { - dofp = chFactoryFindObjectsFIFO("myfifo"); - test_assert(dofp == NULL, "found"); + p1 = chHeapAlloc(NULL, (size_t)-256); + test_assert(p1 == NULL, "allocation not failed"); } } -static const testcase_t oslib_test_004_005 = { - "Dynamic Objects FIFOs Factory", +static const testcase_t oslib_test_004_002 = { + "Default Heap", NULL, - oslib_test_004_005_teardown, - oslib_test_004_005_execute -}; -#endif /* CH_CFG_FACTORY_OBJ_FIFOS == TRUE */ - -#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__) -/** - * @page oslib_test_004_006 [4.6] Dynamic Pipes Factory - * - *

Description

- * This test case verifies the dynamic pipes factory. - * - *

Conditions

- * This test is only executed if the following preprocessor condition - * evaluates to true: - * - CH_CFG_FACTORY_PIPES == TRUE - * . - * - *

Test Steps

- * - [4.6.1] Retrieving a dynamic pipe by name, must not exist. - * - [4.6.2] Creating a dynamic pipe it must not exists, must succeed. - * - [4.6.3] Creating a dynamic pipe with the same name, must fail. - * - [4.6.4] Retrieving the dynamic pipe by name, must exist, then - * increasing the reference counter, finally releasing both - * references. - * - [4.6.5] Releasing the first reference to the dynamic pipe must not - * trigger an assertion. - * - [4.6.6] Retrieving the dynamic pipe by name again, must not exist. - * . - */ - -static void oslib_test_004_006_teardown(void) { - dyn_pipe_t *dpp; - - dpp = chFactoryFindPipe("mypipe"); - if (dpp != NULL) { - while (dpp->element.refs > 0U) { - chFactoryReleasePipe(dpp); - } - } -} - -static void oslib_test_004_006_execute(void) { - dyn_pipe_t *dpp; - - /* [4.6.1] Retrieving a dynamic pipe by name, must not exist.*/ - test_set_step(1); - { - dpp = chFactoryFindPipe("mypipe"); - test_assert(dpp == NULL, "found"); - } - - /* [4.6.2] Creating a dynamic pipe it must not exists, must - succeed.*/ - test_set_step(2); - { - dpp = chFactoryCreatePipe("mypipe", 16U); - test_assert(dpp != NULL, "cannot create"); - } - - /* [4.6.3] Creating a dynamic pipe with the same name, must fail.*/ - test_set_step(3); - { - dyn_pipe_t *dpp1; - - dpp1 = chFactoryCreatePipe("mypipe", 16U); - test_assert(dpp1 == NULL, "can create"); - } - - /* [4.6.4] Retrieving the dynamic pipe by name, must exist, then - increasing the reference counter, finally releasing both - references.*/ - test_set_step(4); - { - dyn_pipe_t *dpp1, *dpp2; - - dpp1 = chFactoryFindPipe("mypipe"); - test_assert(dpp1 != NULL, "not found"); - test_assert(dpp == dpp1, "object reference mismatch"); - test_assert(dpp1->element.refs == 2, "object reference mismatch"); - - dpp2 = (dyn_pipe_t *)chFactoryDuplicateReference(&dpp1->element); - test_assert(dpp1 == dpp2, "object reference mismatch"); - test_assert(dpp2->element.refs == 3, "object reference mismatch"); - - chFactoryReleasePipe(dpp2); - test_assert(dpp1->element.refs == 2, "references mismatch"); - - chFactoryReleasePipe(dpp1); - test_assert(dpp->element.refs == 1, "references mismatch"); - } - - /* [4.6.5] Releasing the first reference to the dynamic pipe must not - trigger an assertion.*/ - test_set_step(5); - { - chFactoryReleasePipe(dpp); - } - - /* [4.6.6] Retrieving the dynamic pipe by name again, must not - exist.*/ - test_set_step(6); - { - dpp = chFactoryFindPipe("mypipe"); - test_assert(dpp == NULL, "found"); - } -} - -static const testcase_t oslib_test_004_006 = { - "Dynamic Pipes Factory", NULL, - oslib_test_004_006_teardown, - oslib_test_004_006_execute + oslib_test_004_002_execute }; -#endif /* CH_CFG_FACTORY_PIPES == TRUE */ /**************************************************************************** * Exported data. @@ -749,33 +264,17 @@ static const testcase_t oslib_test_004_006 = { * @brief Array of test cases. */ const testcase_t * const oslib_test_sequence_004_array[] = { -#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__) &oslib_test_004_001, -#endif -#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__) &oslib_test_004_002, -#endif -#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__) - &oslib_test_004_003, -#endif -#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__) - &oslib_test_004_004, -#endif -#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__) - &oslib_test_004_005, -#endif -#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__) - &oslib_test_004_006, -#endif NULL }; /** - * @brief Objects Factory. + * @brief Memory Heaps. */ const testsequence_t oslib_test_sequence_004 = { - "Objects Factory", + "Memory Heaps", oslib_test_sequence_004_array }; -#endif /* (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE) */ +#endif /* CH_CFG_USE_HEAP */ -- cgit v1.2.3