Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "mbed.h" 00017 #include "greentea-client/test_env.h" 00018 #include "unity.h" 00019 #include "utest.h" 00020 00021 using namespace utest::v1; 00022 00023 /* Enum used to select block allocation method. */ 00024 typedef enum 00025 { 00026 ALLOC, CALLOC 00027 } AllocType; 00028 00029 /* Structure for complex block type. */ 00030 typedef struct 00031 { 00032 int a; 00033 char b; 00034 int c; 00035 } COMPLEX_TYPE; 00036 00037 /* Function to check if complex type object is cleared.*/ 00038 bool comp_is_cleared(COMPLEX_TYPE *object) 00039 { 00040 if (object->a == 0 && object->b == 0 && object->c == 0) { 00041 return true; 00042 } 00043 00044 return false; 00045 } 00046 00047 /* Function to check if complex type object holds specified values.*/ 00048 bool comp_is_equal(COMPLEX_TYPE *object, int a, char b, int c) 00049 { 00050 if (object->a == a && object->b == b && object->c == c) { 00051 return true; 00052 } 00053 00054 return false; 00055 } 00056 00057 /* Function to set complex type object fields.*/ 00058 void comp_set(COMPLEX_TYPE *object, int a, char b, int c) 00059 { 00060 object->a = a; 00061 object->b = b; 00062 object->c = c; 00063 } 00064 00065 /* Template for functional tests for alloc(), calloc() functions 00066 * of MemoryPool object. 00067 * 00068 * Given MemoryPool object of the specified type and queue size has 00069 * been successfully created. 00070 * When max number of blocks is allocated from the pool. 00071 * Then all allocations are successful. 00072 * 00073 * */ 00074 template<typename T, const uint32_t numOfEntries> 00075 void test_mem_pool_alloc_success(AllocType atype) 00076 { 00077 MemoryPool<T, numOfEntries> mem_pool; 00078 T * p_blocks[numOfEntries]; 00079 uint32_t i; 00080 00081 /* Test alloc()/calloc() methods - try to allocate max number of 00082 blocks. All allocations should be successful. */ 00083 for (i = 0; i < numOfEntries; i++) { 00084 /* Allocate memory block. */ 00085 if (atype == ALLOC) { 00086 p_blocks[i] = mem_pool.alloc(); 00087 } else { 00088 p_blocks[i] = mem_pool.calloc(); 00089 } 00090 00091 /* Show that memory pool block has been allocated. */ 00092 TEST_ASSERT_NOT_NULL(p_blocks[i]); 00093 00094 /* Check if Calloc clears the block. */ 00095 if (atype == CALLOC) { 00096 TEST_ASSERT_EQUAL(0, *p_blocks[i]); 00097 } 00098 00099 /* Init fields. */ 00100 *p_blocks[i] = (i + 5); 00101 } 00102 00103 /* Check if blocks holds valid values. */ 00104 for (i = 0; i < numOfEntries; i++) { 00105 TEST_ASSERT_EQUAL((i + 5), *p_blocks[i]); 00106 } 00107 } 00108 00109 /* Template for functional tests for alloc(), calloc() functions 00110 * of MemoryPool object. 00111 * 00112 * Complex memory pool block type is used. 00113 * 00114 * Given MemoryPool object of the specified type and queue size has 00115 * been successfully created. 00116 * When max number of blocks is allocated from the pool. 00117 * Then all allocations are successful. 00118 * 00119 * */ 00120 template<typename T, const uint32_t numOfEntries> 00121 void test_mem_pool_alloc_success_complex(AllocType atype) 00122 { 00123 MemoryPool<T, numOfEntries> mem_pool; 00124 T * p_blocks[numOfEntries]; 00125 uint32_t i; 00126 00127 /* Test alloc()/calloc() methods - try to allocate max number of 00128 blocks. All allocations should be successful. */ 00129 for (i = 0; i < numOfEntries; i++) { 00130 /* Allocate memory block. */ 00131 if (atype == ALLOC) { 00132 p_blocks[i] = mem_pool.alloc(); 00133 } else { 00134 p_blocks[i] = mem_pool.calloc(); 00135 } 00136 00137 /* Show that memory pool block has been allocated. */ 00138 TEST_ASSERT_NOT_NULL(p_blocks[i]); 00139 00140 /* Check if Calloc clears the block. */ 00141 if (atype == CALLOC) { 00142 TEST_ASSERT_EQUAL(true, comp_is_cleared(p_blocks[i])); 00143 } 00144 00145 /* Init fields. */ 00146 comp_set(p_blocks[i], i + 1, i + 2, i + 3); 00147 } 00148 00149 /* Check if blocks holds valid values. */ 00150 for (i = 0; i < numOfEntries; i++) { 00151 TEST_ASSERT_EQUAL(true, comp_is_equal(p_blocks[i], i + 1, i + 2, i + 3)); 00152 } 00153 } 00154 00155 /* Template for functional tests for alloc(), calloc() functions 00156 * of MemoryPool object. 00157 * 00158 * Given MemoryPool has already max number of blocks allocated from the pool. 00159 * When next block is allocated. 00160 * Then allocation fails. 00161 * 00162 * */ 00163 template<typename T, const uint32_t numOfEntries> 00164 void test_mem_pool_alloc_fail(AllocType atype) 00165 { 00166 MemoryPool<T, numOfEntries> mem_pool; 00167 T * p_blocks[numOfEntries]; 00168 T * p_extra_block; 00169 uint32_t i; 00170 00171 /* Allocate all available blocks. */ 00172 for (i = 0; i < numOfEntries; i++) { 00173 if (atype == ALLOC) { 00174 p_blocks[i] = mem_pool.alloc(); 00175 } else { 00176 p_blocks[i] = mem_pool.calloc(); 00177 } 00178 00179 /* Show that memory pool block has been allocated. */ 00180 TEST_ASSERT_NOT_NULL(p_blocks[i]); 00181 } 00182 00183 /* There are no more blocks available. Try to allocate another block. */ 00184 if (atype == ALLOC) { 00185 p_extra_block = mem_pool.alloc(); 00186 } else { 00187 p_extra_block = mem_pool.calloc(); 00188 } 00189 00190 /* Show that memory pool block has NOT been allocated. */ 00191 TEST_ASSERT_NULL(p_extra_block); 00192 } 00193 00194 /* Template for functional tests for free() function 00195 * of MemoryPool object. 00196 * 00197 * Given MemoryPool has all blocks allocated. 00198 * When free operation is executed on the each allocated block. 00199 * Then each deallocation is successfully performed. 00200 * 00201 * */ 00202 template<typename T, const uint32_t numOfEntries> 00203 void test_mem_pool_free_success(AllocType atype) 00204 { 00205 MemoryPool<T, numOfEntries> mem_pool; 00206 T * p_blocks[numOfEntries]; 00207 uint32_t i; 00208 osStatus status; 00209 00210 /* Allocate all available blocks. */ 00211 for (i = 0; i < numOfEntries; i++) { 00212 if (atype == ALLOC) { 00213 p_blocks[i] = mem_pool.alloc(); 00214 } else { 00215 p_blocks[i] = mem_pool.calloc(); 00216 } 00217 00218 /* Show that memory pool block has been allocated. */ 00219 TEST_ASSERT_NOT_NULL(p_blocks[i]); 00220 } 00221 00222 /* Free all memory blocks. */ 00223 for (i = 0; i < numOfEntries; i++) { 00224 status = mem_pool.free(p_blocks[i]); 00225 00226 /* Check operation status. */ 00227 TEST_ASSERT_EQUAL(osOK, status); 00228 } 00229 } 00230 00231 /* Template for functional tests for alloc(), calloc() functions 00232 * of MemoryPool object. 00233 * 00234 * Basic memory pool block type is used. 00235 * 00236 * Given MemoryPool had all blocks allocated and one block has 00237 * been freed (last). 00238 * When next block is allocated. 00239 * Then allocation is successful. 00240 * 00241 * */ 00242 template<typename T, const uint32_t numOfEntries> 00243 void test_mem_pool_free_realloc_last(AllocType atype) 00244 { 00245 MemoryPool<T, numOfEntries> mem_pool; 00246 T * p_blocks[numOfEntries]; 00247 uint32_t i; 00248 osStatus status; 00249 00250 /* Allocate all available blocks. */ 00251 for (i = 0; i < numOfEntries; i++) { 00252 if (atype == ALLOC) { 00253 p_blocks[i] = mem_pool.alloc(); 00254 } else { 00255 p_blocks[i] = mem_pool.calloc(); 00256 } 00257 00258 /* Init block. */ 00259 *p_blocks[i] = 0xAB; 00260 00261 /* Show that memory pool block has been allocated. */ 00262 TEST_ASSERT_NOT_NULL(p_blocks[i]); 00263 } 00264 00265 /* Free the last block. */ 00266 status = mem_pool.free(p_blocks[numOfEntries - 1]); 00267 00268 /* Check status. */ 00269 TEST_ASSERT_EQUAL(osOK, status); 00270 00271 /* Try to allocate another block (one block is now available). */ 00272 if (atype == ALLOC) { 00273 p_blocks[numOfEntries - 1] = mem_pool.alloc(); 00274 } else { 00275 p_blocks[numOfEntries - 1] = mem_pool.calloc(); 00276 } 00277 00278 /* Show that memory pool block has been now allocated. */ 00279 TEST_ASSERT_NOT_NULL(p_blocks[numOfEntries - 1]); 00280 00281 /* Check if Calloc clears the block. */ 00282 if (atype == CALLOC) { 00283 TEST_ASSERT_EQUAL(0, *p_blocks[numOfEntries - 1]); 00284 } 00285 } 00286 00287 /* Template for functional tests for alloc(), calloc() functions 00288 * of MemoryPool object. 00289 * 00290 * Complex memory pool block type is used. 00291 * 00292 * Given MemoryPool had all blocks allocated and one block has 00293 * been freed (last). 00294 * When next block is allocated. 00295 * Then allocation is successful. 00296 * 00297 * */ 00298 template<typename T, const uint32_t numOfEntries> 00299 void test_mem_pool_free_realloc_last_complex(AllocType atype) 00300 { 00301 MemoryPool<T, numOfEntries> mem_pool; 00302 T * p_blocks[numOfEntries]; 00303 uint32_t i; 00304 osStatus status; 00305 00306 /* Allocate all available blocks. */ 00307 for (i = 0; i < numOfEntries; i++) { 00308 if (atype == ALLOC) { 00309 p_blocks[i] = mem_pool.alloc(); 00310 } else { 00311 p_blocks[i] = mem_pool.calloc(); 00312 } 00313 00314 /* Init block. */ 00315 comp_set(p_blocks[i], i + 1, i + 2, i + 3); 00316 00317 /* Show that memory pool block has been allocated. */ 00318 TEST_ASSERT_NOT_NULL(p_blocks[i]); 00319 } 00320 00321 /* Free the last block. */ 00322 status = mem_pool.free(p_blocks[numOfEntries - 1]); 00323 00324 /* Check status. */ 00325 TEST_ASSERT_EQUAL(osOK, status); 00326 00327 /* Try to allocate another block (one block is now available). */ 00328 if (atype == ALLOC) { 00329 p_blocks[numOfEntries - 1] = mem_pool.alloc(); 00330 } else { 00331 p_blocks[numOfEntries - 1] = mem_pool.calloc(); 00332 } 00333 00334 /* Show that memory pool block has been now allocated. */ 00335 TEST_ASSERT_NOT_NULL(p_blocks[numOfEntries - 1]); 00336 00337 /* Check if Calloc clears the block. */ 00338 if (atype == CALLOC) { 00339 TEST_ASSERT_EQUAL(true, comp_is_cleared(p_blocks[numOfEntries - 1])); 00340 } 00341 } 00342 00343 /* Template for functional tests for alloc(), calloc() functions 00344 * of MemoryPool object. 00345 * 00346 * Basic memory pool block type is used. 00347 * 00348 * Given MemoryPool had all blocks allocated and one block has 00349 * been freed (first). 00350 * When next block is allocated. 00351 * Then allocation is successful. 00352 * 00353 * */ 00354 template<typename T, const uint32_t numOfEntries> 00355 void test_mem_pool_free_realloc_first(AllocType atype) 00356 { 00357 MemoryPool<T, numOfEntries> mem_pool; 00358 T * p_blocks[numOfEntries]; 00359 uint32_t i; 00360 osStatus status; 00361 00362 /* Allocate all available blocks. */ 00363 for (i = 0; i < numOfEntries; i++) { 00364 if (atype == ALLOC) { 00365 p_blocks[i] = mem_pool.alloc(); 00366 } else { 00367 p_blocks[i] = mem_pool.calloc(); 00368 } 00369 00370 /* Init block. */ 00371 *p_blocks[i] = 0xAB; 00372 00373 /* Show that memory pool block has been allocated. */ 00374 TEST_ASSERT_NOT_NULL(p_blocks[i]); 00375 } 00376 00377 /* Free the last block. */ 00378 status = mem_pool.free(p_blocks[0]); 00379 00380 /* Check status. */ 00381 TEST_ASSERT_EQUAL(osOK, status); 00382 00383 /* Try to allocate another block (one block is now available). */ 00384 if (atype == ALLOC) { 00385 p_blocks[0] = mem_pool.alloc(); 00386 } else { 00387 p_blocks[0] = mem_pool.calloc(); 00388 } 00389 00390 /* Show that memory pool block has been now allocated. */ 00391 TEST_ASSERT_NOT_NULL(p_blocks[0]); 00392 00393 /* Check if Calloc clears the block. */ 00394 if (atype == CALLOC) { 00395 TEST_ASSERT_EQUAL(0, *p_blocks[0]); 00396 } 00397 } 00398 00399 /* Template for functional tests for alloc(), calloc() functions 00400 * of MemoryPool object. 00401 * 00402 * Complex memory pool block type is used. 00403 * 00404 * Given MemoryPool had all blocks allocated and one block has 00405 * been freed (first). 00406 * When next block is allocated. 00407 * Then allocation is successful. 00408 * 00409 * */ 00410 template<typename T, const uint32_t numOfEntries> 00411 void test_mem_pool_free_realloc_first_complex(AllocType atype) 00412 { 00413 MemoryPool<T, numOfEntries> mem_pool; 00414 T * p_blocks[numOfEntries]; 00415 uint32_t i; 00416 osStatus status; 00417 00418 /* Allocate all available blocks. */ 00419 for (i = 0; i < numOfEntries; i++) { 00420 if (atype == ALLOC) { 00421 p_blocks[i] = mem_pool.alloc(); 00422 } else { 00423 p_blocks[i] = mem_pool.calloc(); 00424 } 00425 00426 /* Init block. */ 00427 comp_set(p_blocks[i], i + 1, i + 2, i + 3); 00428 00429 /* Show that memory pool block has been allocated. */ 00430 TEST_ASSERT_NOT_NULL(p_blocks[i]); 00431 } 00432 00433 /* Free the last block. */ 00434 status = mem_pool.free(p_blocks[0]); 00435 00436 /* Check status. */ 00437 TEST_ASSERT_EQUAL(osOK, status); 00438 00439 /* Try to allocate another block (one block is now available). */ 00440 if (atype == ALLOC) { 00441 p_blocks[0] = mem_pool.alloc(); 00442 } else { 00443 p_blocks[0] = mem_pool.calloc(); 00444 } 00445 00446 /* Show that memory pool block has been now allocated. */ 00447 TEST_ASSERT_NOT_NULL(p_blocks[0]); 00448 00449 /* Check if Calloc clears the block. */ 00450 if (atype == CALLOC) { 00451 TEST_ASSERT_EQUAL(true, comp_is_cleared(p_blocks[0])); 00452 } 00453 } 00454 00455 /* Robustness checks for free() function. 00456 * 00457 * Given block from the MemoryPool has been successfully deallocated. 00458 * When free operation is executed on this block again. 00459 * Then operation fails with osErrorResource status. 00460 * 00461 * */ 00462 void test_mem_pool_free_on_freed_block() 00463 { 00464 MemoryPool<int, 1> mem_pool; 00465 int * p_block; 00466 osStatus status; 00467 00468 /* Allocate memory block. */ 00469 p_block = mem_pool.alloc(); 00470 00471 /* Show that memory pool block has been allocated. */ 00472 TEST_ASSERT_NOT_NULL(p_block); 00473 00474 /* Free memory block. */ 00475 status = mem_pool.free(p_block); 00476 00477 /* Check operation status. */ 00478 TEST_ASSERT_EQUAL(osOK, status); 00479 00480 /* Free memory block again. */ 00481 status = mem_pool.free(p_block); 00482 00483 /* Check operation status. */ 00484 TEST_ASSERT_EQUAL(osErrorResource, status); 00485 } 00486 00487 /* Robustness checks for free() function. 00488 * Function under test is called with invalid parameters. 00489 * 00490 * Given MemoryPool object has been successfully created. 00491 * When free operation is performed on NULL address. 00492 * Then deallocation fails with osErrorParameter error. 00493 * 00494 */ 00495 void free_block_invalid_parameter_null() 00496 { 00497 MemoryPool<int, 1> mem_pool; 00498 osStatus status; 00499 00500 /* Try to free block passing invalid parameter (NULL). */ 00501 status = mem_pool.free(NULL); 00502 00503 /* Check operation status. */ 00504 TEST_ASSERT_EQUAL(osErrorParameter, status); 00505 } 00506 00507 /* Robustness checks for free() function. 00508 * Function under test is called with invalid parameters. 00509 * 00510 * Given MemoryPool object has been successfully created. 00511 * When free operation is performed on invalid address. 00512 * Then deallocation fails with osErrorParameter error. 00513 * 00514 */ 00515 void free_block_invalid_parameter() 00516 { 00517 MemoryPool<int, 1> mem_pool; 00518 osStatus status; 00519 00520 /* Try to free block passing invalid parameter (variable address). */ 00521 status = mem_pool.free(reinterpret_cast<int*>(&status)); 00522 00523 /* Check operation status. */ 00524 TEST_ASSERT_EQUAL(osErrorParameter, status); 00525 } 00526 00527 /* Use wrapper functions to reduce memory usage. */ 00528 00529 template<typename T, const uint32_t numOfEntries> 00530 void test_mem_pool_alloc_success_wrapper() 00531 { 00532 test_mem_pool_alloc_success<T, numOfEntries>(ALLOC); 00533 test_mem_pool_alloc_success<T, numOfEntries>(CALLOC); 00534 } 00535 00536 template<typename T, const uint32_t numOfEntries> 00537 void test_mem_pool_alloc_success_complex_wrapper() 00538 { 00539 test_mem_pool_alloc_success_complex<T, numOfEntries>(ALLOC); 00540 test_mem_pool_alloc_success_complex<T, numOfEntries>(CALLOC); 00541 } 00542 00543 template<typename T, const uint32_t numOfEntries> 00544 void test_mem_pool_free_success_wrapper() 00545 { 00546 test_mem_pool_free_success<T, numOfEntries>(ALLOC); 00547 test_mem_pool_free_success<T, numOfEntries>(CALLOC); 00548 } 00549 00550 template<typename T, const uint32_t numOfEntries> 00551 void test_mem_pool_free_realloc_last_wrapper() 00552 { 00553 test_mem_pool_free_realloc_last<T, numOfEntries>(ALLOC); 00554 test_mem_pool_free_realloc_last<T, numOfEntries>(CALLOC); 00555 00556 } 00557 00558 template<typename T, const uint32_t numOfEntries> 00559 void test_mem_pool_free_realloc_first_wrapper() 00560 { 00561 test_mem_pool_free_realloc_first<T, numOfEntries>(ALLOC); 00562 test_mem_pool_free_realloc_first<T, numOfEntries>(CALLOC); 00563 } 00564 00565 template<typename T, const uint32_t numOfEntries> 00566 void test_mem_pool_free_realloc_first_complex_wrapper() 00567 { 00568 test_mem_pool_free_realloc_first_complex<T, numOfEntries>(ALLOC); 00569 test_mem_pool_free_realloc_first_complex<T, numOfEntries>(CALLOC); 00570 } 00571 00572 template<typename T, const uint32_t numOfEntries> 00573 void test_mem_pool_free_realloc_last_complex_wrapper() 00574 { 00575 test_mem_pool_free_realloc_last_complex<T, numOfEntries>(ALLOC); 00576 test_mem_pool_free_realloc_last_complex<T, numOfEntries>(CALLOC); 00577 } 00578 00579 template<typename T, const uint32_t numOfEntries> 00580 void test_mem_pool_alloc_fail_wrapper() 00581 { 00582 test_mem_pool_alloc_fail<T, numOfEntries>(ALLOC); 00583 test_mem_pool_alloc_fail<T, numOfEntries>(CALLOC); 00584 } 00585 00586 Case cases[] = { 00587 Case("Test: alloc()/calloc() - success, 4 bytes b_type, q_size equal to 1.", test_mem_pool_alloc_success_wrapper<int, 1>), 00588 Case("Test: alloc()/calloc() - success, 4 bytes b_type, q_size equal to 3.", test_mem_pool_alloc_success_wrapper<int, 3>), 00589 Case("Test: alloc()/calloc() - success, 1 bytes b_type, q_size equal to 1.", test_mem_pool_alloc_success_wrapper<char, 1>), 00590 Case("Test: alloc()/calloc() - success, 1 bytes b_type, q_size equal to 3.", test_mem_pool_alloc_success_wrapper<char, 3>), 00591 Case("Test: alloc()/calloc() - success, complex b_type, q_size equal to 1.", test_mem_pool_alloc_success_complex_wrapper<COMPLEX_TYPE, 1>), 00592 Case("Test: alloc()/calloc() - success, complex b_type, q_size equal to 3.", test_mem_pool_alloc_success_complex_wrapper<COMPLEX_TYPE, 3>), 00593 00594 Case("Test: free() - success, 4 bytes b_type, q_size equal to 1.", test_mem_pool_free_success_wrapper<int, 1>), 00595 Case("Test: free() - success, 4 bytes b_type, q_size equal to 3.", test_mem_pool_free_success_wrapper<int, 3>), 00596 Case("Test: free() - success, complex b_type, q_size equal to 1.", test_mem_pool_free_success_wrapper<COMPLEX_TYPE, 1>), 00597 Case("Test: free() - success, complex b_type, q_size equal to 3.", test_mem_pool_free_success_wrapper<COMPLEX_TYPE, 3>), 00598 00599 Case("Test: re-allocation of the last block, basic type.", test_mem_pool_free_realloc_last_wrapper<int, 3>), 00600 Case("Test: re-allocation of the first block, basic type.", test_mem_pool_free_realloc_first_wrapper<int, 3>), 00601 Case("Test: re-allocation of the first block, complex type.", test_mem_pool_free_realloc_first_complex_wrapper<COMPLEX_TYPE, 3>), 00602 Case("Test: re-allocation of the last block, complex type.", test_mem_pool_free_realloc_last_complex_wrapper<COMPLEX_TYPE, 3>), 00603 00604 Case("Test: fail (out of free blocks).", test_mem_pool_alloc_fail_wrapper<int, 3>), 00605 00606 Case("Test: free() - robust (free block twice).", test_mem_pool_free_on_freed_block), 00607 Case("Test: free() - robust (free called with invalid param - NULL).", free_block_invalid_parameter_null), 00608 Case("Test: free() - robust (free called with invalid param).", free_block_invalid_parameter) 00609 }; 00610 00611 utest::v1::status_t greentea_test_setup(const size_t number_of_cases) 00612 { 00613 GREENTEA_SETUP(20, "default_auto"); 00614 return greentea_test_setup_handler(number_of_cases); 00615 } 00616 00617 Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); 00618 00619 int main() 00620 { 00621 Harness::run(specification); 00622 } 00623
Generated on Thu Jul 14 2022 14:36:19 by
