3 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
6 * this software and associated documentation files (the "Software"), to deal in
7 * the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * https://www.FreeRTOS.org
23 * https://github.com/FreeRTOS
26 /*! @file queue_create_dynamic_utest.c */
28 /* C runtime includes. */
33 #include "../queue_utest_common.h"
37 #include "FreeRTOSConfig.h"
40 /* ============================ GLOBAL VARIABLES =========================== */
42 /* ========================== CALLBACK FUNCTIONS =========================== */
44 /* ============================= Unity Fixtures ============================= */
61 int suiteTearDown( int numFailures )
63 return commonSuiteTearDown( numFailures );
66 /* ========================== Helper functions =========================== */
68 static void test_long_queue( QueueHandle_t xQueue,
71 /* Veify that queue is empty */
72 TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) );
74 queue_common_add_sequential_to_queue( xQueue, maxItems );
76 /* Veify that queue is full */
77 TEST_ASSERT_EQUAL( 0, uxQueueSpacesAvailable( xQueue ) );
79 queue_common_receive_sequential_from_queue( xQueue, maxItems, maxItems, 0 );
81 /* Veify that queue is empty */
82 TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) );
86 /* ========================== Test Cases =========================== */
89 * @brief Test xQueueCreate when calls to malloc fail
90 * @coverage xQueueGenericCreate
92 void test_macro_xQueueCreate_malloc_fail( void )
94 UnityMalloc_MakeMallocFailAfterCount( 0 );
96 QueueHandle_t xQueue = INVALID_PTR;
98 xQueue = xQueueCreate( 1, 1 );
100 TEST_ASSERT_EQUAL( NULL, xQueue );
104 * @brief Test xQueueCreate with uxQueueLength=0, uxItemSize=0
105 * @details This is an invalid queue configuration and causes a failed configASSERT.
106 * @coverage xQueueGenericCreate
108 void test_macro_xQueueCreate_zeroQueueLength_zeroItemSize()
110 /* Expect that xQueueCreate will assert because a length of 0 is invalid */
111 fakeAssertExpectFail();
113 QueueHandle_t xQueue = xQueueCreate( 0, 0 );
115 /* validate returned queue handle */
116 TEST_ASSERT_EQUAL( NULL, xQueue );
118 /* verify that configASSERT was called */
119 TEST_ASSERT_EQUAL( true, fakeAssertGetFlagAndClear() );
120 TEST_ASSERT_EQUAL( 0, getNumberMallocCalls() );
124 * @brief Test xQueueCreate with uxQueueLength=0, uxItemSize=1
125 * @details This is an invalid queue configuration and causes a failed configASSERT.
126 * @coverage xQueueGenericCreate
128 void test_macro_xQueueCreate_zeroQueueLength_oneItemSize( void )
130 /* Expect that xQueueCreate will assert because a length of 0 is invalid */
131 fakeAssertExpectFail();
133 QueueHandle_t xQueue = xQueueCreate( 0, 1 );
135 /* validate returned queue handle */
136 TEST_ASSERT_EQUAL( NULL, xQueue );
138 /* verify that configASSERT was called */
139 TEST_ASSERT_EQUAL( true, fakeAssertGetFlagAndClear() );
140 TEST_ASSERT_EQUAL( 0, getNumberMallocCalls() );
144 * @brief Test xQueueCreate with uxQueueLength=1, uxItemSize=0
145 * @details This configuration is equivalent to a binary semaphore.
146 * @coverage xQueueGenericCreate
148 void test_macro_xQueueCreate_oneItem_zeroLength( void )
150 QueueHandle_t xQueue = xQueueCreate( 1, 0 );
152 /* validate returned queue handle */
153 TEST_ASSERT_NOT_EQUAL( NULL, xQueue );
155 TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
157 /* Veify that new queue is empty */
158 TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) );
160 /* Valdiate that the queue has 1 space remaining */
161 TEST_ASSERT_EQUAL( 1, uxQueueSpacesAvailable( xQueue ) );
163 vQueueDelete( xQueue );
167 * @brief Test xQueueCreate with uxQueueLength=1, uxItemSize=1
168 * @details This configuration is equivalent to a 1 byte mailbox.
169 * @coverage xQueueGenericCreate
171 void test_macro_xQueueCreate_oneItem_oneLength( void )
173 QueueHandle_t xQueue = xQueueCreate( 1, 1 );
175 /* validate returned queue handle */
176 TEST_ASSERT_NOT_EQUAL( NULL, xQueue );
178 TEST_ASSERT_EQUAL( QUEUE_T_SIZE + 1, getLastMallocSize() );
180 /* Veify that new queue is empty */
181 TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) );
183 uint8_t testval = ( uint8_t ) getNextMonotonicTestValue();
185 TEST_ASSERT_EQUAL( pdTRUE, xQueueSend( xQueue, &testval, 0 ) );
187 /* Veify that queue is full */
188 TEST_ASSERT_EQUAL( 1, uxQueueMessagesWaiting( xQueue ) );
189 TEST_ASSERT_EQUAL( 0, uxQueueSpacesAvailable( xQueue ) );
191 uint8_t testVal2 = 0xFF;
193 /* Receive from the queue */
194 TEST_ASSERT_EQUAL( pdTRUE, xQueueReceive( xQueue, &testVal2, 0 ) );
195 TEST_ASSERT_EQUAL( testval, testVal2 );
197 /* Veify that queue is empty */
198 TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) );
199 TEST_ASSERT_EQUAL( 1, uxQueueSpacesAvailable( xQueue ) );
201 vQueueDelete( xQueue );
205 * @brief Test xQueueCreate with uxQueueLength=1, uxItemSize=[2,16]
206 * @details End to end test with varied mailbox sizes from 2 to 16 bytes.
207 * @coverage xQueueGenericCreate
209 void test_macro_xQueueCreate_oneItem_multiLength( void )
211 uint8_t testVal[ MAX_MULTI_LEN ];
213 /* Generate test pattern to send to the queue (re-used for each iteration) */
214 for( int i = 0; i < MAX_MULTI_LEN; i++ )
216 testVal[ i ] = ( uint8_t ) getNextMonotonicTestValue();
219 for( uint8_t i = 2; i <= MAX_MULTI_LEN; i++ )
221 QueueHandle_t xQueue = xQueueCreate( 1, i );
223 TEST_ASSERT_EQUAL( QUEUE_T_SIZE + i, getLastMallocSize() );
225 /* Veify that queue is empty */
226 TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) );
228 /* Mask off the bytes we won't use */
229 uint8_t testValCompare[ MAX_MULTI_LEN ];
231 for( int j = 0; j < MAX_MULTI_LEN; j++ )
235 testValCompare[ j ] = testVal[ j ];
239 testValCompare[ j ] = 0xFF;
243 TEST_ASSERT_EQUAL( pdTRUE, xQueueSend( xQueue, &testVal, 0 ) );
245 /* Veify that queue is also full */
246 TEST_ASSERT_EQUAL( 0, uxQueueSpacesAvailable( xQueue ) );
248 uint8_t testValCheck[ MAX_MULTI_LEN ];
249 memset( testValCheck, 0xFF, MAX_MULTI_LEN );
251 /* Receive from the queue */
252 TEST_ASSERT_EQUAL( pdTRUE, xQueueReceive( xQueue, &testValCheck, 0 ) );
253 TEST_ASSERT_EQUAL_MEMORY( testValCompare, testValCheck, MAX_MULTI_LEN );
255 /* Veify that queue is empty */
256 TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) );
258 vQueueDelete( xQueue );
263 * @brief xQueueCreate with a large queue.
264 * @coverage xQueueCreate
266 void test_LargeQueueRunThrough( void )
268 QueueHandle_t xQueue = xQueueCreate( MAX_QUEUE_ITEMS, sizeof( uint32_t ) );
270 test_long_queue( xQueue, MAX_QUEUE_ITEMS );
272 vQueueDelete( xQueue );
276 * @brief xQueueCreate where uxQueueLength * uxItemSize results in integer overflow
277 * @details In this test case xQueueSizeInBytes > MAX(size_t), but individually
278 * uxQueueLength and uxItemSize are each less than MAX(size_t).
279 * @coverage xQueueGenericCreate
281 void test_macro_xQueueCreate_multiplication_overflow( void )
283 /* Calculate a test value = 2^( sizeof(size_t) * 8 bits / 2)
284 * For a 64 bit size_t, this is 2^(8*8/2) = 2^(32) */
285 size_t factor = 1ULL << ( sizeof( size_t ) * 4 );
287 EXPECT_ASSERT_BREAK( xQueueCreate( factor, factor ) );
291 * @brief xQueueCreate where adding xQueueSizeInBytes and sizeof(StaticQueue_t)
292 * results in integer overflow.
293 * @details This test case satisfies the following constraints given that:
294 * xQueueSizeInBytes = (uxQueueLength * uxItemSize),
295 * xQueueSizeInBytes <= MAX(size_t) and
296 * ( xQueueSizeInBytes + sizeof(StaticQueue_t) ) > MAX(size_t)
297 * @coverage xQueueGenericCreate
299 void test_macro_xQueueCreate_addiiton_overflow( void )
301 /* Based on the formula:
302 * ( 2^x - 1 ) == ( 2^( x/2 ) + 1 ) * ( 2^( x/2 ) - 1 ) */
303 size_t powTwo = 1ULL << ( sizeof( size_t ) * 4 );
304 size_t factorA = powTwo - 1;
305 size_t factorB = powTwo + 1;
307 EXPECT_ASSERT_BREAK( xQueueCreate( factorA, factorB ) );