]> begriffs open source - cmsis-freertos/blob - Test/CMock/queue/semaphore/recursive_mutex_utest.c
Updated pack to FreeRTOS 10.4.4
[cmsis-freertos] / Test / CMock / queue / semaphore / recursive_mutex_utest.c
1 /*
2  * FreeRTOS V202107.00
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
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:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
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.
21  *
22  * https://www.FreeRTOS.org
23  * https://github.com/FreeRTOS
24  *
25  */
26 /*! @file recursive_mutex_utest.c */
27
28 #include "../queue_utest_common.h"
29
30 /* Queue includes */
31 #include "FreeRTOS.h"
32 #include "FreeRTOSConfig.h"
33 #include "semphr.h"
34 #include "mock_fake_port.h"
35
36 /* ============================  GLOBAL VARIABLES =========================== */
37
38 /* ==========================  CALLBACK FUNCTIONS =========================== */
39
40 /* ============================= Unity Fixtures ============================= */
41
42 void setUp( void )
43 {
44     commonSetUp();
45     xTaskPriorityDisinherit_IgnoreAndReturn( pdFALSE );
46 }
47
48 void tearDown( void )
49 {
50     commonTearDown();
51 }
52
53 void suiteSetUp()
54 {
55     commonSuiteSetUp();
56 }
57
58 int suiteTearDown( int numFailures )
59 {
60     return commonSuiteTearDown( numFailures );
61 }
62
63 /* ==========================  Helper functions =========================== */
64
65 /* =============================  Test Cases ============================== */
66
67 /**
68  * @brief Test xSemaphoreCreateRecursiveMutex where the call to malloc fails
69  * @coverage xQueueCreateMutex
70  */
71 void test_macro_xSemaphoreCreateRecursiveMutex_malloc_fail( void )
72 {
73     UnityMalloc_MakeMallocFailAfterCount( 0 );
74
75     SemaphoreHandle_t xSemaphore = INVALID_PTR;
76
77     xSemaphore = xSemaphoreCreateRecursiveMutex();
78
79     /* validate returned semaphore handle */
80     TEST_ASSERT_EQUAL( NULL, xSemaphore );
81 }
82
83 /**
84  * @brief Test xSemaphoreCreateRecursiveMutex
85  * @details Create a mutex using xSemaphoreCreateRecursiveMutex
86  * @coverage xQueueCreateMutex
87  */
88 void test_macro_xSemaphoreCreateRecursiveMutex_success( void )
89 {
90     SemaphoreHandle_t xSemaphore = xSemaphoreCreateRecursiveMutex();
91
92     /* validate returned semaphore handle */
93     TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
94
95     TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
96
97     TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
98
99     vSemaphoreDelete( xSemaphore );
100 }
101
102 /**
103  * @brief Test xSemaphoreCreateRecursiveMutexStatic with a null buffer
104  * @coverage xQueueCreateMutexStatic
105  */
106 void test_macro_xSemaphoreCreateRecursiveMutexStatic_nullptr( void )
107 {
108     SemaphoreHandle_t xSemaphore = INVALID_PTR;
109
110     /* Expect that xQueueCreate will assert due to the NULL buffer */
111     fakeAssertExpectFail();
112
113     xSemaphore = xSemaphoreCreateRecursiveMutexStatic( NULL );
114
115     /* Check that configASSERT was called twice */
116     fakeAssertVerifyNumAssertsAndClear( 2 );
117
118     TEST_ASSERT_EQUAL( NULL, xSemaphore );
119     TEST_ASSERT_EQUAL( 0, getLastMallocSize() );
120 }
121
122 /**
123  * @brief Verify that calling xSemaphoreTakeRecursive with a NULL mutex handle causes a configASSERT failure.
124  * @coverage xQueueTakeMutexRecursive
125  */
126 void test_macro_xSemaphoreTakeRecursive_null_handle( void )
127 {
128     EXPECT_ASSERT_BREAK( xSemaphoreTakeRecursive( NULL, 0 ) );
129 }
130
131 /**
132  * @brief Test xSemaphoreTakeRecursive with a mutex that is not owned by any task.
133  * @coverage xQueueTakeMutexRecursive
134  */
135 void test_macro_xSemaphoreTakeRecursive_not_owned_once( void )
136 {
137     TaskHandle_t xMutexHolder = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
138
139     SemaphoreHandle_t xSemaphore = xSemaphoreCreateRecursiveMutex();
140
141     TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
142
143     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder );
144     pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder );
145
146     TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTakeRecursive( xSemaphore, 0 ) );
147
148     TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
149
150     vSemaphoreDelete( xSemaphore );
151 }
152
153 /**
154  * @brief Test xSemaphoreTakeRecursive with a mutex that is already owned by the current task
155  * @coverage xQueueTakeMutexRecursive
156  */
157 void test_macro_xSemaphoreTakeRecursive_self_owned_twice( void )
158 {
159     TaskHandle_t xMutexHolder = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
160
161     SemaphoreHandle_t xSemaphore = xSemaphoreCreateRecursiveMutex();
162
163     TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
164
165     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder );
166     pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder );
167
168     TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTakeRecursive( xSemaphore, 0 ) );
169
170     TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
171
172     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder );
173
174     TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTakeRecursive( xSemaphore, 0 ) );
175
176     TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
177
178     vSemaphoreDelete( xSemaphore );
179 }
180
181 /**
182  * @brief Test xSemaphoreTakeRecursive on a mutex that is already owned by a different task
183  * @coverage xQueueTakeMutexRecursive
184  */
185 void test_macro_xSemaphoreTakeRecursive_owned_other_task( void )
186 {
187     TaskHandle_t xMutexHolder1 = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
188     TaskHandle_t xMutexHolder2 = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
189
190     SemaphoreHandle_t xSemaphore = xSemaphoreCreateRecursiveMutex();
191
192     /* Take the recursive mutex with task handle == xMutexHolder1 */
193     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder1 );
194     pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder1 );
195     TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTakeRecursive( xSemaphore, 0 ) );
196
197     /* Attempt to take the recursive mutex with task handle == xMutexHolder2 */
198     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder2 );
199     TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreTakeRecursive( xSemaphore, 0 ) );
200
201     vSemaphoreDelete( xSemaphore );
202 }
203
204 /**
205  * @brief Verify that calling xSemaphoreGiveRecursive with a NULL mutex handle causes a configASSERT failure.
206  * @coverage xQueueGiveMutexRecursive
207  */
208 void test_macro_xSemaphoreGiveRecursive_null_handle( void )
209 {
210     EXPECT_ASSERT_BREAK( xSemaphoreGiveRecursive( NULL ) );
211 }
212
213 /**
214  * @brief Test xSemaphoreGiveRecursive with a mutex that is not already owned by any task.
215  * @coverage xQueueGiveMutexRecursive
216  */
217 void test_macro_xSemaphoreGiveRecursive_unowned( void )
218 {
219     TaskHandle_t xMutexHolder = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
220
221     SemaphoreHandle_t xSemaphore = xSemaphoreCreateRecursiveMutex();
222
223     TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
224
225     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder );
226
227     TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreGiveRecursive( xSemaphore ) );
228
229     TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
230
231     vSemaphoreDelete( xSemaphore );
232 }
233
234 /**
235  * @brief Test xSemaphoreGiveRecursive with a mutex that is not owned by any task with a NULL TaskHandle returned by calls to xTaskGetCurrentTaskHandle.
236  * @coverage xQueueGiveMutexRecursive
237  */
238 void test_macro_xSemaphoreGiveRecursive_unowned_null_taskhandle( void )
239 {
240     SemaphoreHandle_t xSemaphore = xSemaphoreCreateRecursiveMutex();
241
242     TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
243
244     xTaskGetCurrentTaskHandle_ExpectAndReturn( NULL );
245
246     TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGiveRecursive( xSemaphore ) );
247
248     TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
249
250     vSemaphoreDelete( xSemaphore );
251 }
252
253 /**
254  * @brief Test xSemaphoreGiveRecursive with a mutex that is already owned by the current task
255  * @coverage xQueueGiveMutexRecursive
256  */
257 void test_macro_xSemaphoreGiveRecursive_self_owned( void )
258 {
259     TaskHandle_t xMutexHolder = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
260
261     SemaphoreHandle_t xSemaphore = xSemaphoreCreateRecursiveMutex();
262
263     /* Take the Recursive Mutex from taskHandle == xMutexHolder */
264     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder );
265     pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder );
266
267     xSemaphoreTakeRecursive( xSemaphore, 0 );
268
269     /* Verify that the Recursive Mutex is in the taken state */
270     TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
271
272     /* call xSemaphoreGiveRecursive to release the Recursive Mutex */
273     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder );
274
275     TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGiveRecursive( xSemaphore ) );
276
277     /* Verify that the Recursive Mutex is now in the available state */
278     TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
279
280     vSemaphoreDelete( xSemaphore );
281 }
282
283 /**
284  * @brief Test xSemaphoreGiveRecursive on a mutex that is already owned by a different task
285  * @coverage xQueueGiveMutexRecursive
286  */
287 void test_macro_xSemaphoreGiveRecursive_owned_other_task( void )
288 {
289     TaskHandle_t xMutexHolder1 = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
290     TaskHandle_t xMutexHolder2 = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
291
292     SemaphoreHandle_t xSemaphore = xSemaphoreCreateRecursiveMutex();
293
294     /* Take the Recursive Mutex from taskHandle == xMutexHolder */
295     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder1 );
296     pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder1 );
297
298     xSemaphoreTakeRecursive( xSemaphore, 0 );
299
300     /* Verify that the Recursive Mutex is in the taken state */
301     TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
302
303     /* call xSemaphoreGiveRecursive to release the Recursive Mutex */
304     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder2 );
305
306     TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreGiveRecursive( xSemaphore ) );
307
308     /* Verify that the Recursive Mutex remains in the taken state */
309     TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
310
311     vSemaphoreDelete( xSemaphore );
312 }
313
314
315 /**
316  * @brief Call xSemaphoreTakeRecursive and xSemaphoreGiveRecursive each multiple times
317  * @coverage xQueueTakeMutexRecursive xQueueGiveMutexRecursive
318  */
319 void test_macro_xSemaphoreTakeRecursive_xSemaphoreGiveRecursive_recursive( void )
320 {
321     TaskHandle_t xMutexHolder = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
322
323     SemaphoreHandle_t xSemaphore = xSemaphoreCreateRecursiveMutex();
324
325     /* Take the Recursive Mutex */
326     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder );
327     pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder );
328     xSemaphoreTakeRecursive( xSemaphore, 0 );
329
330     /* Verify that the Recursive Mutex is in the taken state */
331     TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
332
333     /* Take the Recursive Mutex a second time */
334     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder );
335     xSemaphoreTakeRecursive( xSemaphore, 0 );
336
337     /* Verify that the Recursive Mutex remains in the taken state */
338     TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
339
340     /* call xSemaphoreGiveRecursive to release the Recursive Mutex (first time) */
341     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder );
342     TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGiveRecursive( xSemaphore ) );
343
344     /* Verify that the Recursive Mutex remains in the taken state */
345     TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
346
347     /* call xSemaphoreGiveRecursive to release the Recursive Mutex (second time) */
348     xTaskGetCurrentTaskHandle_ExpectAndReturn( xMutexHolder );
349     TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGiveRecursive( xSemaphore ) );
350
351     /* Verify that the Recursive Mutex is now in the available state */
352     TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
353
354     vSemaphoreDelete( xSemaphore );
355 }