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 stream_buffer_utest.c */
28 /* C runtime includes. */
32 /* Stream Buffer includes */
34 #include "FreeRTOSConfig.h"
35 #include "stream_buffer.h"
39 #include "unity_memory.h"
40 #include "CException.h"
43 #include "mock_task.h"
44 #include "mock_fake_assert.h"
45 #include "mock_fake_port.h"
48 * @brief Sample size in bytes of the stream buffer used for test.
49 * The size is kept short enough so that the buffer can be allocated on stack.
51 #define TEST_STREAM_BUFFER_SIZE ( 64U )
54 * @brief Sample trigger level in bytes used for stream buffer tests.
55 * When a receiver task is blocked waiting for data, trigger level determines how much bytes should
56 * be available before which receiver task can be unblocked.
58 #define TEST_STREAM_BUFFER_TRIGGER_LEVEL ( 32U )
61 * @brief Maximum unsigned long value that can be passed as a stream buffer size so as to
62 * trigger an integer overflow.
64 #define TEST_STREAM_BUFFER_MAX_UINT_SIZE ( ~( size_t ) ( 0UL ) )
67 * @brief A value used to test setting and getting stream buffer number.
69 #define TEST_STREAM_BUFFER_NUMBER ( 0xFFU )
72 * @brief Wait ticks passed into from tests if the stream buffer is full while sending data or
73 * empty while receiving data.
75 #define TEST_STREAM_BUFFER_WAIT_TICKS ( 1000U )
78 * @brief CException code for when a configASSERT should be intercepted.
80 #define configASSERT_E 0xAA101
83 * @brief Expect a configASSERT from the function called.
84 * Break out of the called function when this occurs.
85 * @details Use this macro when the call passed in as a parameter is expected
86 * to cause invalid memory access.
88 #define EXPECT_ASSERT_BREAK( call ) \
91 shouldAbortOnAssertion = true; \
92 CEXCEPTION_T e = CEXCEPTION_NONE; \
100 TEST_ASSERT_EQUAL( configASSERT_E, e ); \
105 /* ============================ GLOBAL VARIABLES =========================== */
108 * @brief Global counter for the number of assertions in code.
110 static int assertionFailed = 0;
113 * @brief Global counter to keep track of how many times a sender task was woken up by a task receiving from the stream buffer.
115 static int senderTaskWoken = 0;
118 * @brief Global counter to keep track of how many times a receiver task was woken up by a task sending to the buffer.
120 static int receiverTaskWoken = 0;
123 * @brief Dummy sender task handle to which the stream buffer receive APIs will send notification.
125 static TaskHandle_t senderTask = ( TaskHandle_t ) ( 0xAABBCCDD );
128 * @brief Dummy receiver task handle to which the stream buffer send APIs will send notifications.
130 static TaskHandle_t receiverTask = ( TaskHandle_t ) ( 0xABCDEEFF );
133 * @brief Global Stream buffer handle used for tests.
135 static StreamBufferHandle_t xStreamBuffer;
138 * @brief Flag which denotes if test need to abort on assertion.
140 static BaseType_t shouldAbortOnAssertion;
143 * @brief Variable used to record the total dynamic size allocated in a test.
145 static size_t dynamicMemoryAllocated = 0;
147 /* ========================== CALLBACK FUNCTIONS =========================== */
149 void * pvPortMalloc( size_t xSize )
151 dynamicMemoryAllocated += xSize;
152 return unity_malloc( xSize );
154 void vPortFree( void * pv )
156 return unity_free( pv );
159 static void vFakeAssertStub( bool x,
162 int cmock_num_calls )
168 if( shouldAbortOnAssertion == pdTRUE )
170 Throw( configASSERT_E );
175 static BaseType_t streamBufferReceiveCallback( UBaseType_t uxIndexToWaitOn,
176 uint32_t ulBitsToClearOnEntry,
177 uint32_t ulBitsToClearOnExit,
178 uint32_t * pulNotificationValue,
179 TickType_t xTicksToWait,
180 int cmock_num_calls )
182 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
183 size_t dataReceived = 0;
185 /* Receive enough bytes (full size) from stream buffer to wake up sender task. */
186 dataReceived = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, 0 );
187 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, dataReceived );
191 static BaseType_t streamBufferReceiveFromISRCallback( UBaseType_t uxIndexToWaitOn,
192 uint32_t ulBitsToClearOnEntry,
193 uint32_t ulBitsToClearOnExit,
194 uint32_t * pulNotificationValue,
195 TickType_t xTicksToWait,
196 int cmock_num_calls )
198 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
199 size_t dataReceived = 0;
200 BaseType_t senderTaskWokenFromISR = pdFALSE;
202 /* Receive enough bytes (full size) from stream buffer to wake up sender task. */
203 dataReceived = xStreamBufferReceiveFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, &senderTaskWokenFromISR );
204 TEST_ASSERT_EQUAL( pdTRUE, senderTaskWokenFromISR );
205 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, dataReceived );
209 static BaseType_t resetWhenBlockedCallback( UBaseType_t uxIndexToWaitOn,
210 uint32_t ulBitsToClearOnEntry,
211 uint32_t ulBitsToClearOnExit,
212 uint32_t * pulNotificationValue,
213 TickType_t xTicksToWait,
214 int cmock_num_calls )
218 /* Reset when the task is blocked on stream buffer, should fail and return pdFAIL. */
219 status = xStreamBufferReset( xStreamBuffer );
220 TEST_ASSERT_EQUAL( pdFAIL, status );
224 static BaseType_t sendCompletedFromISRCallback( UBaseType_t uxIndexToWaitOn,
225 uint32_t ulBitsToClearOnEntry,
226 uint32_t ulBitsToClearOnExit,
227 uint32_t * pulNotificationValue,
228 TickType_t xTicksToWait,
229 int cmock_num_calls )
231 BaseType_t status = pdFALSE, highPriorityTaskWoken = pdFALSE;
233 /* Executing the send completed API from ISR should unblock a high priority task waiting to receive from stream buffer. */
234 status = xStreamBufferSendCompletedFromISR( xStreamBuffer, &highPriorityTaskWoken );
235 TEST_ASSERT_EQUAL( pdTRUE, status );
236 TEST_ASSERT_EQUAL( pdTRUE, highPriorityTaskWoken );
240 static BaseType_t receiveCompletedFromISRCallback( UBaseType_t uxIndexToWaitOn,
241 uint32_t ulBitsToClearOnEntry,
242 uint32_t ulBitsToClearOnExit,
243 uint32_t * pulNotificationValue,
244 TickType_t xTicksToWait,
245 int cmock_num_calls )
247 BaseType_t status = pdFALSE, highPriorityTaskWoken = pdFALSE;
249 /* Executing the receive completed API from ISR should unblock a high priority task waiting to send to stream buffer. */
250 status = xStreamBufferReceiveCompletedFromISR( xStreamBuffer, &highPriorityTaskWoken );
251 TEST_ASSERT_EQUAL( pdTRUE, status );
252 TEST_ASSERT_EQUAL( pdTRUE, highPriorityTaskWoken );
256 static BaseType_t senderTaskNotificationCallback( TaskHandle_t xTaskToNotify,
257 UBaseType_t uxIndexToNotify,
259 eNotifyAction eAction,
260 uint32_t * pulPreviousNotificationValue,
261 int cmock_num_calls )
263 TEST_ASSERT_EQUAL( senderTask, xTaskToNotify );
268 static BaseType_t senderTaskNotificationFromISRCallback( TaskHandle_t xTaskToNotify,
269 UBaseType_t uxIndexToNotify,
271 eNotifyAction eAction,
272 uint32_t * pulPreviousNotificationValue,
273 BaseType_t * pxHigherPriorityTaskWoken,
274 int cmock_num_calls )
276 TEST_ASSERT_EQUAL( senderTask, xTaskToNotify );
278 *pxHigherPriorityTaskWoken = pdTRUE;
283 static BaseType_t streamBufferSendCallback( UBaseType_t uxIndexToWaitOn,
284 uint32_t ulBitsToClearOnEntry,
285 uint32_t ulBitsToClearOnExit,
286 uint32_t * pulNotificationValue,
287 TickType_t xTicksToWait,
288 int cmock_num_calls )
290 uint8_t data[ TEST_STREAM_BUFFER_TRIGGER_LEVEL ] = { 0 };
293 /* Send enough (trigger level) bytes to stream buffer to wake up the receiver Task. */
294 dataSent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_TRIGGER_LEVEL, 0 );
295 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL, dataSent );
299 static BaseType_t streamBufferSendFromISRCallback( UBaseType_t uxIndexToWaitOn,
300 uint32_t ulBitsToClearOnEntry,
301 uint32_t ulBitsToClearOnExit,
302 uint32_t * pulNotificationValue,
303 TickType_t xTicksToWait,
304 int cmock_num_calls )
306 uint8_t data[ TEST_STREAM_BUFFER_TRIGGER_LEVEL ] = { 0 };
308 BaseType_t receiverTaskWokenFromISR = pdFALSE;
310 /* Send enough (trigger level) bytes to stream buffer to wake up the receiver Task. */
311 dataSent = xStreamBufferSendFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_TRIGGER_LEVEL, &receiverTaskWokenFromISR );
312 TEST_ASSERT_EQUAL( pdTRUE, receiverTaskWokenFromISR );
313 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL, dataSent );
317 static BaseType_t sendLessThanTriggerLevelBytesCallback( UBaseType_t uxIndexToWaitOn,
318 uint32_t ulBitsToClearOnEntry,
319 uint32_t ulBitsToClearOnExit,
320 uint32_t * pulNotificationValue,
321 TickType_t xTicksToWait,
322 int cmock_num_calls )
324 uint8_t data[ TEST_STREAM_BUFFER_TRIGGER_LEVEL ] = { 0 };
327 /* Sending less than trigger level bytes should not wake up the receiver Task. */
328 dataSent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_TRIGGER_LEVEL - 1, 0 );
329 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL - 1, dataSent );
333 static BaseType_t sendLessThanTriggerLevelBytesFromISRCallback( UBaseType_t uxIndexToWaitOn,
334 uint32_t ulBitsToClearOnEntry,
335 uint32_t ulBitsToClearOnExit,
336 uint32_t * pulNotificationValue,
337 TickType_t xTicksToWait,
338 int cmock_num_calls )
340 uint8_t data[ TEST_STREAM_BUFFER_TRIGGER_LEVEL ] = { 0 };
342 BaseType_t receiverTaskWokenFromISR = pdFALSE;
344 /* Sending less than trigger level bytes should not wake up the receiver Task. */
345 dataSent = xStreamBufferSendFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_TRIGGER_LEVEL - 1, &receiverTaskWokenFromISR );
346 TEST_ASSERT_EQUAL( pdFALSE, receiverTaskWokenFromISR );
347 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL - 1, dataSent );
351 static BaseType_t receiverTaskNotificationFromISRCallback( TaskHandle_t xTaskToNotify,
352 UBaseType_t uxIndexToNotify,
354 eNotifyAction eAction,
355 uint32_t * pulPreviousNotificationValue,
356 BaseType_t * pxHigherPriorityTaskWoken,
357 int cmock_num_calls )
359 TEST_ASSERT_EQUAL( receiverTask, xTaskToNotify );
361 *pxHigherPriorityTaskWoken = pdTRUE;
366 static BaseType_t receiverTaskNotificationCallback( TaskHandle_t xTaskToNotify,
367 UBaseType_t uxIndexToNotify,
369 eNotifyAction eAction,
370 uint32_t * pulPreviousNotificationValue,
371 int cmock_num_calls )
373 TEST_ASSERT_EQUAL( receiverTask, xTaskToNotify );
378 /*******************************************************************************
380 ******************************************************************************/
384 xStreamBuffer = NULL;
386 receiverTaskWoken = 0;
387 shouldAbortOnAssertion = pdTRUE;
388 dynamicMemoryAllocated = 0;
392 mock_fake_assert_Init();
393 mock_fake_port_Init();
395 vFakePortEnterCriticalSection_Ignore();
396 vFakePortExitCriticalSection_Ignore();
397 ulFakePortSetInterruptMaskFromISR_IgnoreAndReturn( 0U );
398 vFakePortClearInterruptMaskFromISR_Ignore();
399 vFakeAssert_StubWithCallback( vFakeAssertStub );
400 /* Track calls to malloc / free */
401 UnityMalloc_StartTest();
404 /*! called before each test case */
405 void tearDown( void )
407 TEST_ASSERT_EQUAL_MESSAGE( 0, assertionFailed, "Assertion check failed in code." );
408 UnityMalloc_EndTest();
411 mock_fake_assert_Verify();
412 mock_fake_assert_Destroy();
413 mock_fake_port_Verify();
414 mock_fake_port_Destroy();
417 /*! called at the beginning of the whole suite */
422 /*! called at the end of the whole suite */
423 int suiteTearDown( int numFailures )
428 static void validate_stream_buffer_init_state( StreamBufferHandle_t xStreamBuffer,
431 TEST_ASSERT_TRUE( xStreamBufferIsEmpty( xStreamBuffer ) );
432 TEST_ASSERT_FALSE( xStreamBufferIsFull( xStreamBuffer ) );
433 TEST_ASSERT_EQUAL( bufferSize, xStreamBufferSpacesAvailable( xStreamBuffer ) );
434 TEST_ASSERT_EQUAL( 0U, xStreamBufferBytesAvailable( xStreamBuffer ) );
435 TEST_ASSERT_EQUAL( 0U, xStreamBufferNextMessageLengthBytes( xStreamBuffer ) );
436 TEST_ASSERT_EQUAL( 0, ucStreamBufferGetStreamBufferType( xStreamBuffer ) );
439 static void validate_and_clear_assertions( void )
441 TEST_ASSERT_EQUAL( 1, assertionFailed );
445 /* ============================== Test Cases ============================== */
448 * @brief Validates that stream buffer of sample size is created successfully.
450 void test_xStreamBufferCreate_success( void )
452 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
453 TEST_ASSERT_NOT_EQUAL( NULL, xStreamBuffer );
454 validate_stream_buffer_init_state( xStreamBuffer, TEST_STREAM_BUFFER_SIZE );
456 /* Verify internal memory allocated is equal to size of the struct + buffer size + 1. */
457 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE + 1U + sizeof( StaticStreamBuffer_t ), dynamicMemoryAllocated );
459 /* Set a stream buffer number and get it. */
460 vStreamBufferSetStreamBufferNumber( xStreamBuffer, TEST_STREAM_BUFFER_NUMBER );
461 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_NUMBER, uxStreamBufferGetStreamBufferNumber( xStreamBuffer ) );
463 vStreamBufferDelete( xStreamBuffer );
467 * Returns NULL if there is an integer overflow in the buffer size.
469 void test_xStreamBufferCreate_integer_overflow( void )
471 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_MAX_UINT_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
472 TEST_ASSERT_EQUAL( NULL, xStreamBuffer );
476 * @brief Returns NULL if internal memory allocation of the stream buffer fails.
478 void test_xStreamBufferCreate_malloc_fail( void )
480 UnityMalloc_MakeMallocFailAfterCount( 0 );
482 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
483 TEST_ASSERT_EQUAL( NULL, xStreamBuffer );
487 * @brief Assertion fails if a zero buffer size is passed as the parameter.
489 void test_xStreamBufferCreate_zero_buffer_size( void )
491 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferCreate( 0, TEST_STREAM_BUFFER_TRIGGER_LEVEL ) );
492 validate_and_clear_assertions();
496 * @brief Assertion fails if trigger level is greater than the stream buffer size.
498 void test_xStreamBufferCreate_invalid_trigger_level( void )
500 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, ( TEST_STREAM_BUFFER_SIZE + 1 ) ) );
501 validate_and_clear_assertions();
505 * @brief Assertion fails while trying to delete a null stream buffer.
507 void test_xStreamBufferDelete_null_stream_buffer( void )
509 EXPECT_ASSERT_BREAK( vStreamBufferDelete( NULL ) );
510 validate_and_clear_assertions();
514 * @brief Validates stream buffer create using a static buffer is successful.
516 void test_xStreamBufferCreateStatic_success( void )
518 StaticStreamBuffer_t streamBufferStruct;
520 /* The size of stream buffer array should be one greater than the required size of stream buffer. */
521 uint8_t streamBufferArray[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
523 xStreamBuffer = xStreamBufferCreateStatic( sizeof( streamBufferArray ), TEST_STREAM_BUFFER_TRIGGER_LEVEL, streamBufferArray, &streamBufferStruct );
525 TEST_ASSERT_NOT_NULL( xStreamBuffer );
526 validate_stream_buffer_init_state( xStreamBuffer, TEST_STREAM_BUFFER_SIZE );
528 vStreamBufferDelete( xStreamBuffer );
532 * @brief Validates stream buffer static create fails if NULL array is passed.
534 void test_xStreamBufferCreateStatic_null_array( void )
536 StaticStreamBuffer_t streamBufferStruct;
538 /* The size of stream buffer array should be one greater than the required size of stream buffer. */
539 uint8_t streamBufferArray[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
541 /* Tests should abort if assertion is enabled or return NULL. */
542 shouldAbortOnAssertion = pdFALSE;
544 /* Returns NULL if a NULL pointer is passed as the stream buffer storage area. */
545 xStreamBuffer = xStreamBufferCreateStatic( sizeof( streamBufferArray ), TEST_STREAM_BUFFER_TRIGGER_LEVEL, NULL, &streamBufferStruct );
546 TEST_ASSERT_NULL( xStreamBuffer );
547 validate_and_clear_assertions();
551 * @brief Validates stream buffer static create fails if NULL struct is passed.
553 void test_xStreamBufferCreateStatic_invalid_null_struct( void )
555 /* The size of stream buffer array should be one greater than the required size of stream buffer. */
556 uint8_t streamBufferArray[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
558 /* Tests should abort if assertion is enabled or return NULL. */
559 shouldAbortOnAssertion = pdFALSE;
561 /* Returns NULL if a NULL struct is passed as a parameter. */
562 xStreamBuffer = xStreamBufferCreateStatic( sizeof( streamBufferArray ), TEST_STREAM_BUFFER_TRIGGER_LEVEL, streamBufferArray, NULL );
563 TEST_ASSERT_NULL( xStreamBuffer );
564 validate_and_clear_assertions();
568 * @brief Validates stream buffer static create fails on passing invalid trigger level
570 void test_xStreamBufferCreateStatic_invalid_trigger_level( void )
572 StaticStreamBuffer_t streamBufferStruct;
573 /* The size of stream buffer array should be one greater than the required size of stream buffer. */
574 uint8_t streamBufferArray[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
576 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferCreateStatic( sizeof( streamBufferArray ), TEST_STREAM_BUFFER_SIZE + 2, streamBufferArray, &streamBufferStruct ) );
578 validate_and_clear_assertions();
582 * @brief Validates a task is able to send upto buffer space available without blocking.
584 void test_xStreamBufferSend_success( void )
586 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
589 vTaskSetTimeOutState_Ignore();
590 vTaskSuspendAll_Ignore();
591 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
593 /* Create a stream buffer of the default test sample size. */
594 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
595 TEST_ASSERT_NOT_NULL( xStreamBuffer );
596 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
598 /* Sending bytes of size upto to available size should succeed without blocking. */
599 sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
600 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sent );
601 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
602 TEST_ASSERT_EQUAL( pdFALSE, xStreamBufferIsEmpty( xStreamBuffer ) );
604 vStreamBufferDelete( xStreamBuffer );
608 * @brief Validates that sending data more than stream buffer size will cap it to the size of stream buffer without blocking.
610 void test_xStreamBufferSend_more_than_buffer_size( void )
612 uint8_t data[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
615 vTaskSetTimeOutState_Ignore();
616 vTaskSuspendAll_Ignore();
617 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
619 /* Create a stream buffer of the default test sample size. */
620 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
621 TEST_ASSERT_NOT_NULL( xStreamBuffer );
622 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
624 /* Sending bytes more than stream buffer size caps its to the size of stream buffer. */
625 sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE + 1, TEST_STREAM_BUFFER_WAIT_TICKS );
626 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sent );
627 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
629 vStreamBufferDelete( xStreamBuffer );
633 * @brief Sending zero bytes to stream buffer should return write nothing to the
634 * buffer and return 0.
636 void test_xStreamBufferSend_zero_bytes( void )
638 uint8_t data[ TEST_STREAM_BUFFER_SIZE + 1 ] = { 0 };
640 vTaskSetTimeOutState_Ignore();
641 vTaskSuspendAll_Ignore();
642 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
644 /* Create a stream buffer of the default test sample size. */
645 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
646 TEST_ASSERT_NOT_NULL( xStreamBuffer );
647 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
649 TEST_ASSERT_EQUAL( pdFALSE, xStreamBufferSend( xStreamBuffer, data, 0U, TEST_STREAM_BUFFER_WAIT_TICKS ) );
651 vStreamBufferDelete( xStreamBuffer );
655 * @brief Validates cases where stream buffer has insufficient space to send the data and sender has to block.
657 void test_xStreamBufferSend_blocking( void )
659 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
662 vTaskSetTimeOutState_Ignore();
663 xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
664 xTaskGetCurrentTaskHandle_IgnoreAndReturn( senderTask );
665 vTaskSuspendAll_Ignore();
666 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
668 /* Create a stream buffer of test sample size. */
669 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
670 TEST_ASSERT_NOT_NULL( xStreamBuffer );
671 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
673 /* Sending upto size of stream buffer should not block. */
674 sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE - 1, TEST_STREAM_BUFFER_WAIT_TICKS );
675 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1, sent );
676 TEST_ASSERT_EQUAL( 1, xStreamBufferSpacesAvailable( xStreamBuffer ) );
679 * Sending beyond the stream buffer size should make task wait for upto TEST_STREAM_BUFFER_WAIT_TICKS. After the timeout
680 * elapses, task should return with partial bytes sent.
682 xTaskGenericNotifyWait_ExpectAndReturn( 0, 0, 0, NULL, TEST_STREAM_BUFFER_WAIT_TICKS, pdTRUE );
683 xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
684 sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
685 TEST_ASSERT_EQUAL( 1, sent );
686 TEST_ASSERT_EQUAL( pdTRUE, xStreamBufferIsFull( xStreamBuffer ) );
689 * A task trying to send to a stream buffer without any space available should block for upto TEST_STREAM_BUFFER_WAIT_TICKS.
690 * Sender task should be notified and woken up when bytes are consumed by a receiver task during the wait period.
692 xTaskGenericNotifyWait_StubWithCallback( streamBufferReceiveCallback );
693 xTaskGenericNotify_StubWithCallback( senderTaskNotificationCallback );
694 xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
695 sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
696 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sent );
697 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
698 TEST_ASSERT_EQUAL( 1, senderTaskWoken );
701 * A task trying to send to a stream buffer without any space available should block for upto TEST_STREAM_BUFFER_WAIT_TICKS.
702 * Sender task should be notified and woken up when bytes are consumed by an ISR during the wait period.
704 xTaskGenericNotifyWait_StubWithCallback( streamBufferReceiveFromISRCallback );
705 xTaskGenericNotifyFromISR_StubWithCallback( senderTaskNotificationFromISRCallback );
706 xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
707 sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
708 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sent );
709 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
710 TEST_ASSERT_EQUAL( 2, senderTaskWoken );
712 vStreamBufferDelete( xStreamBuffer );
716 * @brief Validates that stream buffer does not block if zero wait time is passed.
718 void test_xStreamBufferSend_zero_wait_ticks( void )
720 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
723 vTaskSetTimeOutState_Ignore();
724 vTaskSuspendAll_Ignore();
725 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
727 /* Create a stream buffer of sample size. */
728 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
729 TEST_ASSERT_NOT_NULL( xStreamBuffer );
730 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
732 /* Sending data of upto stream buffer size should not block. */
733 dataSent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
734 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, dataSent );
735 TEST_ASSERT_EQUAL( 0, xStreamBufferSpacesAvailable( xStreamBuffer ) );
737 /* Sending data beyond stream buffer size but with zero wait ticks should not block and return zero bytes sent. */
738 dataSent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, 0 );
739 TEST_ASSERT_EQUAL( 0, dataSent );
741 vStreamBufferDelete( xStreamBuffer );
745 * @brief Validates that a task is able to receive from a non empty stream buffer without blocking.
747 void test_xStreamBufferReceive_success( void )
749 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
750 uint8_t dataReceived[ TEST_STREAM_BUFFER_SIZE ] = { 0x00 };
751 size_t sentBytes = 0, receivedBytes = 0;
753 vTaskSetTimeOutState_Ignore();
754 vTaskSuspendAll_Ignore();
755 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
757 /* Create a stream buffer of sample size. */
758 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
759 TEST_ASSERT_NOT_NULL( xStreamBuffer );
760 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
762 /* Send TEST_STREAM_BUFFER_SIZE data to the stream buffer. */
763 sentBytes = xStreamBufferSend( xStreamBuffer, &data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
764 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sentBytes );
766 /* Receive the partial data from stream Buffer without blocking. */
767 receivedBytes = xStreamBufferReceive( xStreamBuffer, &dataReceived, TEST_STREAM_BUFFER_SIZE - 1, TEST_STREAM_BUFFER_WAIT_TICKS );
768 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1, receivedBytes );
769 TEST_ASSERT_EQUAL_HEX8_ARRAY( data, dataReceived, receivedBytes );
770 TEST_ASSERT_EQUAL( 1, xStreamBufferBytesAvailable( xStreamBuffer ) );
772 /* Request for full TEST_STREAM_BUFFER_SIZE bytes, but only receive what's available without blocking. */
773 receivedBytes = xStreamBufferReceive( xStreamBuffer, &dataReceived, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
774 TEST_ASSERT_EQUAL( 1, receivedBytes );
775 TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
777 vStreamBufferDelete( xStreamBuffer );
781 * @brief Validates receiving from an empty stream buffer will block until at least trigger level bytes are
782 * sent to the buffer.
784 void test_xStreamBufferReceive_blocking( void )
786 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
787 size_t receivedBytes = 0;
789 vTaskSetTimeOutState_Ignore();
790 xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
791 xTaskGetCurrentTaskHandle_IgnoreAndReturn( receiverTask );
792 xTaskGenericNotify_StubWithCallback( receiverTaskNotificationCallback );
794 xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
795 vTaskSuspendAll_Ignore();
796 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
798 /* Create a stream buffer of sample size. */
799 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
800 TEST_ASSERT_NOT_NULL( xStreamBuffer );
801 TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
804 * Receiving from an empty buffer causes the task to wait for TEST_STREAM_BUFFER_WAIT_TICKS period.
805 * After the timeout elapses, task returns with zero bytes received.
807 xTaskGenericNotifyWait_ExpectAndReturn( 0, 0, 0, NULL, TEST_STREAM_BUFFER_WAIT_TICKS, pdTRUE );
808 xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
809 receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
810 TEST_ASSERT_EQUAL( 0, receivedBytes );
813 * Sending at least trigger level bytes, should notify and wake up the receiver task.
815 xTaskGenericNotifyWait_StubWithCallback( streamBufferSendCallback );
816 xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
817 receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
818 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL, receivedBytes );
819 TEST_ASSERT_EQUAL( 1, receiverTaskWoken );
820 TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
823 * Sending at least trigger level bytes from ISR, should notify and wake up the receiver task.
825 xTaskGenericNotifyWait_StubWithCallback( streamBufferSendFromISRCallback );
826 xTaskGenericNotifyFromISR_StubWithCallback( receiverTaskNotificationFromISRCallback );
827 xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE );
828 receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
829 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_TRIGGER_LEVEL, receivedBytes );
830 TEST_ASSERT_EQUAL( 2, receiverTaskWoken );
831 TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
834 /* Sending less than trigger level bytes should not wake up the task. */
835 xTaskGenericNotifyWait_StubWithCallback( sendLessThanTriggerLevelBytesCallback );
836 xTaskGenericNotifyFromISR_StubWithCallback( receiverTaskNotificationFromISRCallback );
837 xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
838 receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
839 TEST_ASSERT_EQUAL( 2, receiverTaskWoken );
841 /* Sending less than trigger level bytes from ISR should not wake up the task. */
842 xTaskGenericNotifyWait_StubWithCallback( sendLessThanTriggerLevelBytesFromISRCallback );
843 xTaskGenericNotifyFromISR_StubWithCallback( receiverTaskNotificationFromISRCallback );
844 xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
845 receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
846 TEST_ASSERT_EQUAL( 2, receiverTaskWoken );
848 vStreamBufferDelete( xStreamBuffer );
852 * @brief Validates that receiver task does not block if zero wait ticks are passed.
854 void test_xStreamBufferReceive_zero_wait_ticks( void )
856 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
857 size_t receivedBytes = 0;
859 vTaskSetTimeOutState_Ignore();
860 vTaskSuspendAll_Ignore();
861 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
863 /* Create a stream buffer of sample size. */
864 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
865 TEST_ASSERT_NOT_NULL( xStreamBuffer );
866 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
868 /* Task does not block on an empty stream buffer if zero wait ticks are passed. */
869 receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, 0 );
870 TEST_ASSERT_EQUAL( 0, receivedBytes );
872 vStreamBufferDelete( xStreamBuffer );
876 * @brief Validates that an interrupt service routine is able to read data from stream
877 * buffer without blocking.
879 void test_xStreamBufferReceiveFromISR_success( void )
881 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
882 uint8_t dataReceived[ TEST_STREAM_BUFFER_SIZE ] = { 0x00 };
883 size_t receivedBytes = 0, sentBytes = 0;
884 BaseType_t xHighPriorityTaskWoken = pdFALSE;
886 vTaskSetTimeOutState_Ignore();
887 vTaskSuspendAll_Ignore();
888 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
890 /* Create a stream buffer of sample size. */
891 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
892 TEST_ASSERT_NOT_NULL( xStreamBuffer );
893 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
895 /* Send data to fill the stream buffer to maximum capacity. */
896 sentBytes = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
897 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sentBytes );
898 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
900 /* Receive partial data from stream buffer without blocking. */
901 receivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer, &dataReceived, ( TEST_STREAM_BUFFER_SIZE - 1U ), &xHighPriorityTaskWoken );
902 TEST_ASSERT_EQUAL( ( TEST_STREAM_BUFFER_SIZE - 1U ), receivedBytes );
903 TEST_ASSERT_EQUAL_HEX8_ARRAY( data, dataReceived, receivedBytes );
904 TEST_ASSERT_EQUAL( pdFALSE, xHighPriorityTaskWoken );
906 /* Try to receive full capacity from stream buffer but only remaining data is received. */
907 receivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer, &dataReceived, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken );
908 TEST_ASSERT_EQUAL( 1U, receivedBytes );
909 TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
911 vStreamBufferDelete( xStreamBuffer );
915 * @brief Assertion fails if a null stream buffer is passed.
917 void test_xStreamBufferReceiveFromISR_null_stream_buffer( void )
919 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
920 BaseType_t xHighPriorityTaskWoken = pdFALSE;
922 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferReceiveFromISR( NULL, data, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken ) );
924 validate_and_clear_assertions();
928 * @brief Assertion fails if a null message is passed.
930 void test_xStreamBufferReceiveFromISR_null_buffer( void )
932 BaseType_t xHighPriorityTaskWoken = pdFALSE;
934 /* Create a stream buffer of sample size. */
935 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
936 TEST_ASSERT_NOT_NULL( xStreamBuffer );
937 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
939 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferReceiveFromISR( xStreamBuffer, NULL, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken ) );
941 validate_and_clear_assertions();
943 vStreamBufferDelete( xStreamBuffer );
947 * @brief Validates that an interrupt service routine is able to send data upto the size of stream buffer without blocking.
949 void test_xStreamBufferSendFromISR_success( void )
951 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
952 size_t sentBytes = 0;
953 BaseType_t xHighPriorityTaskWoken = pdFALSE;
955 vTaskSetTimeOutState_Ignore();
956 vTaskSuspendAll_Ignore();
957 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
959 /* Create a stream buffer of sample size. */
960 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
961 TEST_ASSERT_NOT_NULL( xStreamBuffer );
962 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
964 /* Send data to an empty buffer should succeed without blocking. */
965 sentBytes = xStreamBufferSendFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE - 1U, &xHighPriorityTaskWoken );
966 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1U, sentBytes );
967 TEST_ASSERT_EQUAL( 1U, xStreamBufferSpacesAvailable( xStreamBuffer ) );
968 TEST_ASSERT_EQUAL( pdFALSE, xHighPriorityTaskWoken );
970 /* Send full capacity from ISR again should send partial bytes without blocking. */
971 sentBytes = xStreamBufferSendFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken );
972 TEST_ASSERT_EQUAL( 1U, sentBytes );
973 TEST_ASSERT_EQUAL( 0, xStreamBufferSpacesAvailable( xStreamBuffer ) );
974 TEST_ASSERT_EQUAL( pdFALSE, xHighPriorityTaskWoken );
976 /* Send to full stream buffer should return 0 bytes sent without blocking. */
977 sentBytes = xStreamBufferSendFromISR( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken );
978 TEST_ASSERT_EQUAL( 0U, sentBytes );
979 TEST_ASSERT_EQUAL( pdFALSE, xHighPriorityTaskWoken );
981 vStreamBufferDelete( xStreamBuffer );
985 * @brief Assertion fails if a null stream buffer is passed.
987 void test_xStreamBufferSendFromISR_null_stream_buffer( void )
989 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
990 BaseType_t xHighPriorityTaskWoken = pdFALSE;
992 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferSendFromISR( NULL, data, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken ) );
994 validate_and_clear_assertions();
998 * @brief Assertion fails if a null message is passed.
1000 void test_xStreamBufferSendFromISR_null_message( void )
1002 BaseType_t xHighPriorityTaskWoken = pdFALSE;
1004 /* Create a stream buffer of sample size. */
1005 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
1006 TEST_ASSERT_NOT_NULL( xStreamBuffer );
1007 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
1009 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferSendFromISR( xStreamBuffer, NULL, TEST_STREAM_BUFFER_SIZE, &xHighPriorityTaskWoken ) );
1011 validate_and_clear_assertions();
1013 vStreamBufferDelete( xStreamBuffer );
1017 * @brief Validates user is able to reset the stream buffer back to empty state.
1019 void test_xStreamBufferReset_success( void )
1021 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0 };
1022 size_t dataSent = 0;
1023 BaseType_t status = pdFALSE;
1025 vTaskSetTimeOutState_Ignore();
1026 vTaskSuspendAll_Ignore();
1027 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
1029 /* Create a stream buffer of the default test sample size. */
1030 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
1031 TEST_ASSERT_NOT_NULL( xStreamBuffer );
1033 /* Validate stream buffer is empty initially. */
1034 validate_stream_buffer_init_state( xStreamBuffer, TEST_STREAM_BUFFER_SIZE );
1036 /* Send full capacity to stream buffer. */
1037 dataSent = xStreamBufferSend( xStreamBuffer, data, sizeof( data ), TEST_STREAM_BUFFER_WAIT_TICKS );
1038 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, dataSent );
1040 /* Verify that all bytes are available. */
1041 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
1043 /* Reset the stream buffer back to empty state. */
1044 status = xStreamBufferReset( xStreamBuffer );
1045 TEST_ASSERT_EQUAL( pdTRUE, status );
1047 /* Validate that stream buffer is empty. */
1048 validate_stream_buffer_init_state( xStreamBuffer, TEST_STREAM_BUFFER_SIZE );
1050 vStreamBufferDelete( xStreamBuffer );
1054 * @brief Resetting a null stream buffer should fail assertion.
1056 void test_xStreamBufferReset_null_stream_buffer( void )
1058 vTaskSetTimeOutState_Ignore();
1059 vTaskSuspendAll_Ignore();
1060 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
1062 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferReset( NULL ) );
1063 validate_and_clear_assertions();
1067 * @brief Validates that stream buffer reset fails if a sender or receiver task is blocked on it.
1069 void test_xStreamBufferReset_while_blocked( void )
1071 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
1072 size_t sentBytes = 0, receivedBytes = 0;
1074 vTaskSetTimeOutState_Ignore();
1075 xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
1076 xTaskGetCurrentTaskHandle_IgnoreAndReturn( senderTask );
1077 xTaskGenericNotifyWait_StubWithCallback( resetWhenBlockedCallback );
1078 xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
1079 vTaskSuspendAll_Ignore();
1080 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
1082 /* Create a stream buffer of sample size. */
1083 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
1084 TEST_ASSERT_NOT_NULL( xStreamBuffer );
1085 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
1088 * Perform a blocking operation to receive from an empty stream buffer. Reset stream buffer within receiver task notify
1089 * wait callback should fail.
1091 receivedBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
1092 TEST_ASSERT_EQUAL( 0, receivedBytes );
1095 * Send full size data to stream buffer.
1097 sentBytes = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
1098 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sentBytes );
1099 TEST_ASSERT_EQUAL( pdTRUE, xStreamBufferIsFull( xStreamBuffer ) );
1102 * Sending data to full stream buffer causes task to be blocked. Reset stream buffer within sender task notify
1103 * wait callback should fail.
1105 sentBytes = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
1106 TEST_ASSERT_EQUAL( 0, sentBytes );
1108 vStreamBufferDelete( xStreamBuffer );
1112 * @brief Validates that a receiver task is able to receive data after lowering the stream buffer trigger level.
1114 void test_xStreamBufferSetTrigerLevel_success( void )
1116 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
1119 vTaskSetTimeOutState_Ignore();
1120 xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
1121 xTaskGetCurrentTaskHandle_IgnoreAndReturn( receiverTask );
1122 xTaskGenericNotify_StubWithCallback( receiverTaskNotificationCallback );
1123 xTaskGenericNotifyWait_StubWithCallback( streamBufferSendCallback );
1124 xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
1125 vTaskSuspendAll_Ignore();
1126 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
1128 /* Create stream buffer with trigger level equal to maximum stream buffer size. */
1129 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_SIZE );
1130 TEST_ASSERT_NOT_NULL( xStreamBuffer );
1132 /* Set the trigger level to TEST_STREAM_BUFFER_TRIGGER_LEVEL. */
1133 status = xStreamBufferSetTriggerLevel( xStreamBuffer, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
1134 TEST_ASSERT_EQUAL( pdTRUE, status );
1137 * Receive data from empty stream buffer, with trigger level bytes send from the callback. This should unblock
1140 ( void ) xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
1141 TEST_ASSERT_EQUAL( 1, receiverTaskWoken );
1143 vStreamBufferDelete( xStreamBuffer );
1147 * @brief Validate setting trigger level with invalid parameters fails.
1149 void test_xStreamBufferSetTrigerLevel_larger_than_buffer_size( void )
1153 /* Create stream buffer. */
1154 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
1155 TEST_ASSERT_NOT_NULL( xStreamBuffer );
1157 /* Set the trigger level to ( TEST_STREAM_BUFFER_SIZE + 1) should fail. */
1158 status = xStreamBufferSetTriggerLevel( xStreamBuffer, ( TEST_STREAM_BUFFER_SIZE + 1 ) );
1159 TEST_ASSERT_EQUAL( pdFALSE, status );
1161 vStreamBufferDelete( xStreamBuffer );
1165 * @brief Set the trigger level to 0 should pass but internally set trigger level to 1.
1167 void test_xStreamBufferSetTrigerLevel_zero( void )
1171 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
1172 TEST_ASSERT_NOT_NULL( xStreamBuffer );
1174 status = xStreamBufferSetTriggerLevel( xStreamBuffer, 0 );
1175 TEST_ASSERT_EQUAL( pdTRUE, status );
1177 vStreamBufferDelete( xStreamBuffer );
1181 * @brief Setting trigger level for a null stream buffer should fail assertion.
1183 void test_xStreamBufferSetTriggerLevel_null_stream_buffer( void )
1185 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferSetTriggerLevel( NULL, TEST_STREAM_BUFFER_TRIGGER_LEVEL ) );
1186 validate_and_clear_assertions();
1190 * @brief Checking bytes available for a null stream buffer should fail assertion.
1192 void test_xStreamBufferBytesAvailable_null_stream_buffer( void )
1194 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferBytesAvailable( NULL ) );
1195 validate_and_clear_assertions();
1199 * @brief Checking if stream buffer is full for a null stream buffer should fail assertion.
1201 void test_xStreamBufferIsFull_null_stream_buffer( void )
1203 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferIsFull( NULL ) );
1204 validate_and_clear_assertions();
1208 * @brief Checking if stream buffer is empty for a null stream buffer should fail assertion.
1210 void test_xStreamBufferIsEmpty_null_stream_buffer( void )
1212 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferIsEmpty( NULL ) );
1213 validate_and_clear_assertions();
1217 * @brief Checking buffer size for a null stream buffer should fail assertion.
1219 void test_xStreamBufferSpacesAvailable_null_stream_buffer( void )
1221 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferSpacesAvailable( NULL ) );
1222 validate_and_clear_assertions();
1226 * @brief Checking Next message length available for a null stream buffer fails
1229 void test_xStreamBufferNextMessageLengthBytes_null_stream_buffer( void )
1231 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferNextMessageLengthBytes( NULL ) );
1232 validate_and_clear_assertions();
1236 * @brief Validates xStreamBufferSendCompletedFromISR function unblocks a receive task.
1238 void test_xStreamBufferSendCompletedFromISR_success( void )
1240 BaseType_t status = pdFALSE;
1241 BaseType_t highPriorityTaskWoken = pdFALSE;
1242 uint8_t data[ TEST_STREAM_BUFFER_SIZE ];
1243 size_t receiveBytes = 0;
1245 /* Create a stream buffer of the default test sample size. */
1246 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
1247 TEST_ASSERT_NOT_NULL( xStreamBuffer );
1249 /* Send completed from ISR without receiver task waiting. */
1250 status = xStreamBufferSendCompletedFromISR( xStreamBuffer, &highPriorityTaskWoken );
1251 TEST_ASSERT_EQUAL( pdFALSE, status );
1252 TEST_ASSERT_EQUAL( pdFALSE, highPriorityTaskWoken );
1254 /* Send completed from ISR with receiver task waiting. */
1255 vTaskSetTimeOutState_Ignore();
1256 xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
1257 xTaskGetCurrentTaskHandle_IgnoreAndReturn( receiverTask );
1258 xTaskGenericNotifyWait_StubWithCallback( sendCompletedFromISRCallback );
1259 xTaskGenericNotifyFromISR_StubWithCallback( receiverTaskNotificationFromISRCallback );
1260 xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
1261 vTaskSuspendAll_Ignore();
1262 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
1264 receiveBytes = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
1265 TEST_ASSERT_EQUAL( 0, receiveBytes );
1266 TEST_ASSERT_EQUAL( 1, receiverTaskWoken );
1268 vStreamBufferDelete( xStreamBuffer );
1272 * @brief Validates xStreamBufferSendCompletedFromISR fails assertion if a null stream buffer is passed.
1274 void test_xStreamBufferSendCompletedFromISR_null_stream_buffer( void )
1276 BaseType_t highPriorityTaskWoken = pdFALSE;
1278 /* Send completed from ISR without receiver task waiting. */
1279 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferSendCompletedFromISR( NULL, &highPriorityTaskWoken ) );
1280 validate_and_clear_assertions();
1284 * @brief Validates xStreamBufferReceiveCompletedFromISR unblocks a sender task.
1286 void test_xStreamBufferReceiveCompletedFromISR_success( void )
1288 BaseType_t status = pdFALSE;
1289 BaseType_t highPriorityTaskWoken = pdFALSE;
1291 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
1292 size_t sentBytes = 0;
1294 vTaskSetTimeOutState_Ignore();
1295 vTaskSuspendAll_Ignore();
1296 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
1298 /* Create a stream buffer of the default test sample size. */
1299 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
1300 TEST_ASSERT_NOT_NULL( xStreamBuffer );
1302 /* Receive completed from ISR without a sender task waiting. */
1303 status = xStreamBufferReceiveCompletedFromISR( xStreamBuffer, &highPriorityTaskWoken );
1304 TEST_ASSERT_EQUAL( pdFALSE, status );
1305 TEST_ASSERT_EQUAL( pdFALSE, highPriorityTaskWoken );
1308 /* Send full capacity to a stream buffer so that sender task blocks. */
1309 sentBytes = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
1310 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sentBytes );
1311 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
1313 /* Receive completed from ISR when a sender task is waiting. */
1314 xTaskGenericNotifyStateClear_IgnoreAndReturn( pdTRUE );
1315 xTaskGetCurrentTaskHandle_IgnoreAndReturn( senderTask );
1316 xTaskGenericNotifyWait_StubWithCallback( receiveCompletedFromISRCallback );
1317 xTaskGenericNotifyFromISR_StubWithCallback( senderTaskNotificationFromISRCallback );
1318 xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE );
1319 sentBytes = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
1320 TEST_ASSERT_EQUAL( 0, sentBytes );
1321 TEST_ASSERT_EQUAL( 1, senderTaskWoken );
1323 vStreamBufferDelete( xStreamBuffer );
1327 * @brief Validates xStreamBufferReceiveCompletedFromISR fails assertion if a null stream buffer is passed.
1329 void test_xStreamBufferReceiveCompletedFromISR_null_stream_buffer( void )
1331 BaseType_t highPriorityTaskWoken = pdFALSE;
1333 /* Send completed from ISR without receiver task waiting. */
1334 EXPECT_ASSERT_BREAK( ( void ) xStreamBufferReceiveCompletedFromISR( NULL, &highPriorityTaskWoken ) );
1335 validate_and_clear_assertions();
1339 * @brief Validates scenario where stream buffer head and tail pointer wraps over.
1341 void test_xStreamBufferSend_WrapOver( void )
1343 uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA };
1344 size_t sent = 0, received = 0;
1346 vTaskSetTimeOutState_Ignore();
1347 vTaskSuspendAll_Ignore();
1348 xTaskResumeAll_IgnoreAndReturn( pdTRUE );
1350 /* Create a stream buffer of the default test sample size. */
1351 xStreamBuffer = xStreamBufferCreate( TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_TRIGGER_LEVEL );
1352 TEST_ASSERT_NOT_NULL( xStreamBuffer );
1353 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
1355 /* Sending bytes upto max stream buffer size. */
1356 sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
1357 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, sent );
1358 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
1359 TEST_ASSERT_EQUAL( 0, xStreamBufferSpacesAvailable( xStreamBuffer ) );
1361 /* Read upto max buffer size - 1 */
1362 received = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE - 1, TEST_STREAM_BUFFER_WAIT_TICKS );
1363 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1, received );
1364 TEST_ASSERT_EQUAL( 1, xStreamBufferBytesAvailable( xStreamBuffer ) );
1365 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1, xStreamBufferSpacesAvailable( xStreamBuffer ) );
1367 /* Send upto max buffer size - 1 so that head wraps over. */
1368 sent = xStreamBufferSend( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE - 1, TEST_STREAM_BUFFER_WAIT_TICKS );
1369 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE - 1, sent );
1370 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferBytesAvailable( xStreamBuffer ) );
1371 TEST_ASSERT_EQUAL( 0U, xStreamBufferSpacesAvailable( xStreamBuffer ) );
1374 /* Read all bytes and verify that tail wraps over as well. */
1375 received = xStreamBufferReceive( xStreamBuffer, data, TEST_STREAM_BUFFER_SIZE, TEST_STREAM_BUFFER_WAIT_TICKS );
1376 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, received );
1377 TEST_ASSERT_EQUAL( 0, xStreamBufferBytesAvailable( xStreamBuffer ) );
1378 TEST_ASSERT_EQUAL( TEST_STREAM_BUFFER_SIZE, xStreamBufferSpacesAvailable( xStreamBuffer ) );
1380 vStreamBufferDelete( xStreamBuffer );