Test Specification for ChibiOS OS Library. ChibiOS OS Library Test Suite. Test suite for ChibiOS OS Library. The purpose of this suite is to perform unit tests on the library modules and to converge to 100% code coverage through successive improvements. oslib_ Internal Tests Mailboxes. This sequence tests the ChibiOS library functionalities related to mailboxes. CH_CFG_USE_MAILBOXES Mailbox normal API, non-blocking tests. The mailbox normal API is tested without triggering blocking conditions. Testing the mailbox size. Resetting the mailbox, conditions are checked, no errors expected. Testing the behavior of API when the mailbox is in reset state then return in active state. Filling the mailbox using chMBPostTimeout() and chMBPostAheadTimeout() once, no errors expected. Testing intermediate conditions. Data pointers must be aligned, semaphore counters are checked. Emptying the mailbox using chMBFetchTimeout(), no errors expected. Posting and then fetching one more message, no errors expected. Testing final conditions. Data pointers must be aligned to buffer start, semaphore counters are checked. Mailbox I-Class API, non-blocking tests. The mailbox I-Class API is tested without triggering blocking conditions. Testing the mailbox size. Resetting the mailbox, conditions are checked, no errors expected. The mailbox is then returned in active state. Filling the mailbox using chMBPostI() and chMBPostAheadI() once, no errors expected. Testing intermediate conditions. Data pointers must be aligned, semaphore counters are checked. Emptying the mailbox using chMBFetchI(), no errors expected. Posting and then fetching one more message, no errors expected. Testing final conditions. Data pointers must be aligned to buffer start, semaphore counters are checked. Mailbox timeouts. The mailbox API is tested for timeouts. Filling the mailbox. Testing chMBPostTimeout(), chMBPostI(), chMBPostAheadTimeout() and chMBPostAheadI() timeout. Resetting the mailbox. The mailbox is then returned in active state. Testing chMBFetchTimeout() and chMBFetchI() timeout. Internal Tests Pipes This sequence tests the ChibiOS library functionalities related to pipes. CH_CFG_USE_PIPES #define PIPE_SIZE 16 static uint8_t buffer[PIPE_SIZE]; static PIPE_DECL(pipe1, buffer, PIPE_SIZE); static const uint8_t pipe_pattern[] = "0123456789ABCDEF";]]> Pipes normal API, non-blocking tests. The pipe functionality is tested by loading and emptying it, all conditions are tested. Resetting pipe. Writing data, must fail. Reading data, must fail. Reactivating pipe. Filling whole pipe. Emptying pipe. Small write. Filling remaining space. Small Read. Reading remaining data. Small Write. Small Read. Write wrapping buffer boundary. Read wrapping buffer boundary. Pipe timeouts. The pipe API is tested for timeouts. Reading while pipe is empty. Writing a string larger than pipe buffer. Internal Tests Memory Pools. This sequence tests the ChibiOS library functionalities related to memory pools. CH_CFG_USE_MEMPOOLS Loading and emptying a memory pool. The memory pool functionality is tested by loading and emptying it, all conditions are tested. Adding the objects to the pool using chPoolLoadArray(). Emptying the pool using chPoolAlloc(). Now must be empty. Adding the objects to the pool using chPoolFree(). Emptying the pool using chPoolAlloc() again. Now must be empty again. Covering the case where a provider is unable to return more memory. Loading and emptying a guarded memory pool without waiting. The memory pool functionality is tested by loading and emptying it, all conditions are tested. CH_CFG_USE_SEMAPHORES Adding the objects to the pool using chGuardedPoolLoadArray(). Emptying the pool using chGuardedPoolAllocTimeout(). Now must be empty. Adding the objects to the pool using chGuardedPoolFree(). Emptying the pool using chGuardedPoolAllocTimeout() again. Now must be empty again. Guarded Memory Pools timeout. The timeout features for the Guarded Memory Pools is tested. CH_CFG_USE_SEMAPHORES Trying to allocate with 100mS timeout, must fail because the pool is empty. Internal Tests Memory Heaps. This sequence tests the ChibiOS library functionalities related to memory heaps. CH_CFG_USE_HEAP Allocation and fragmentation. 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. Testing initial conditions, the heap must not be fragmented and one free block present. Trying to allocate an block bigger than available space, an error is expected. Single block allocation using chHeapAlloc() then the block is freed using chHeapFree(), must not fail. Using chHeapStatus() to assess the heap state. There must be at least one free block of sufficient size. = ALLOC_SIZE, "unexpected heap state"); test_assert(total_size == largest_size, "unexpected heap state");]]> Allocating then freeing in the same order. Allocating then freeing in reverse order. Small fragments handling. Checking the behavior when allocating blocks with size not multiple of alignment unit. Skipping a fragment, the first fragment in the list is too small so the allocator must pick the second one. Allocating the whole available space. Testing final conditions. The heap geometry must be the same than the one registered at beginning. Default Heap. The default heap is pre-allocated in the system. We test base functionality. Single block allocation using chHeapAlloc() then the block is freed using chHeapFree(), must not fail. Testing allocation failure. Internal Tests Objects Factory. This sequence tests the ChibiOS library functionalities related to the object factory. (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE) Objects Registry. This test case verifies the static objects registry. CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE element.refs > 0U) { chFactoryReleaseObject(rop); } }]]> Retrieving a registered object by name, must not exist. Registering an object, it must not exists, must succeed. Registering an object with the same name, must fail. Retrieving the registered object by name, must exist, then increasing the reference counter, finally releasing both references. 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"); chFactoryReleaseObject(rop1); test_assert(rop->element.refs == 1, "references mismatch");]]> Releasing the first reference to the object, must not trigger an assertion. Retrieving the registered object by name again, must not exist. Dynamic Buffers Factory. This test case verifies the dynamic buffers factory. CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE element.refs > 0U) { chFactoryReleaseBuffer(dbp); } }]]> Retrieving a dynamic buffer by name, must not exist. Creating a dynamic buffer it must not exists, must succeed. Creating a dynamic buffer with the same name, must fail. Retrieving the dynamic buffer by name, must exist, then increasing the reference counter, finally releasing both references. 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");]]> Releasing the first reference to the dynamic buffer, must not trigger an assertion. Retrieving the dynamic buffer by name again, must not exist. Dynamic Semaphores Factory. This test case verifies the dynamic semaphores factory. CH_CFG_FACTORY_SEMAPHORES == TRUE element.refs > 0U) { chFactoryReleaseSemaphore(dsp); } }]]> Retrieving a dynamic semaphore by name, must not exist. Creating a dynamic semaphore it must not exists, must succeed. Creating a dynamic semaphore with the same name, must fail. Retrieving the dynamic semaphore by name, must exist, then increasing the reference counter, finally releasing both references. 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");]]> Releasing the first reference to the dynamic semaphore must not trigger an assertion. Retrieving the dynamic semaphore by name again, must not exist. Dynamic Mailboxes Factory. This test case verifies the dynamic mailboxes factory. CH_CFG_FACTORY_MAILBOXES == TRUE element.refs > 0U) { chFactoryReleaseMailbox(dmp); } }]]> Retrieving a dynamic mailbox by name, must not exist. Creating a dynamic mailbox it must not exists, must succeed. Creating a dynamic mailbox with the same name, must fail. Retrieving the dynamic mailbox by name, must exist, then increasing the reference counter, finally releasing both references. 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");]]> Releasing the first reference to the dynamic mailbox must not trigger an assertion. Retrieving the dynamic mailbox by name again, must not exist. Dynamic Objects FIFOs Factory. This test case verifies the dynamic objects FIFOs factory. CH_CFG_FACTORY_OBJ_FIFOS == TRUE element.refs > 0U) { chFactoryReleaseObjectsFIFO(dofp); } }]]> Retrieving a dynamic objects FIFO by name, must not exist. Creating a dynamic objects FIFO it must not exists, must succeed. Creating a dynamic objects FIFO with the same name, must fail. Retrieving the dynamic objects FIFO by name, must exist, then increasing the reference counter, finally releasing both references. 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");]]> Releasing the first reference to the dynamic objects FIFO must not trigger an assertion. Retrieving the dynamic objects FIFO by name again, must not exist. Dynamic Pipes Factory. This test case verifies the dynamic pipes factory. CH_CFG_FACTORY_PIPES == TRUE element.refs > 0U) { chFactoryReleasePipe(dpp); } }]]> Retrieving a dynamic pipe by name, must not exist. Creating a dynamic pipe it must not exists, must succeed. Creating a dynamic pipe with the same name, must fail. Retrieving the dynamic pipe by name, must exist, then increasing the reference counter, finally releasing both references. 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");]]> Releasing the first reference to the dynamic pipe must not trigger an assertion. Retrieving the dynamic pipe by name again, must not exist.