init

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 
00017 #include "utest/utest.h"
00018 #include "unity/unity.h"
00019 #include "greentea-client/test_env.h"
00020 
00021 #include "mbed.h"
00022 
00023 using namespace utest::v1;
00024 
00025 /* Structure for complex type. */
00026 typedef struct
00027 {
00028     int a;
00029     char b;
00030     int c;
00031 } COMPLEX_TYPE;
00032 
00033 /* Function to check if complex type object holds specified values.*/
00034 bool comp_is_equal(COMPLEX_TYPE *object, int a, char b, int c)
00035 {
00036     if (object->a == a && object->b == b && object->c == c) {
00037         return true;
00038     }
00039 
00040     return false;
00041 }
00042 
00043 /* Function to set complex type object fields.*/
00044 void comp_set(COMPLEX_TYPE *object, int a, char b, int c)
00045 {
00046     object->a = a;
00047     object->b = b;
00048     object->c = c;
00049 }
00050 
00051 /* Test circular buffer - input does not exceed capacity.
00052  *
00053  * Given is a circular buffer with the capacity equal to N (BufferSize).
00054  * When circular buffer is filled with N elements.
00055  * Then all elements are read from the circular buffer in the FIFO order.
00056  *
00057  */
00058 template<typename T, uint32_t BufferSize, typename CounterType>
00059 void test_input_does_not_exceed_capacity_push_max_pop_max()
00060 {
00061     CircularBuffer<T, BufferSize, CounterType> cb;
00062     T data = 0;
00063 
00064     for (uint32_t i = 0; i < BufferSize; i++) {
00065         data = (0xAA + i);
00066         cb.push(data);
00067         TEST_ASSERT_EQUAL(i + 1, cb.size());
00068     }
00069 
00070     for (uint32_t i = 0; i < BufferSize; i++) {
00071         TEST_ASSERT_TRUE(cb.pop(data));
00072         TEST_ASSERT_EQUAL(0xAA + i, data);
00073         TEST_ASSERT_EQUAL(BufferSize - i - 1, cb.size());
00074     }
00075 }
00076 
00077 /* Test circular buffer - input does not exceed capacity.
00078  *
00079  * Given is a circular buffer with the capacity equal to N (BufferSize).
00080  * When circular buffer is filled as follows: (2 * N - 2) times 2 elements are pushed and 1 element is popped.
00081  * Then all elements are read from the circular buffer in the FIFO order.
00082  *
00083  */
00084 template<typename T, uint32_t BufferSize, typename CounterType>
00085 void test_input_does_not_exceed_capacity_push_2_pop_1()
00086 {
00087     CircularBuffer<T, BufferSize, CounterType> cb;
00088     static const int num_of_elem_push = (2 * BufferSize - 2);
00089     T push_buffer = 0;
00090     T pop_buffer = 0;
00091 
00092     /* Push 2 elements and pop one element in each cycle. */
00093     for (uint32_t i = 0; i < num_of_elem_push; i += 2) {
00094         push_buffer = (0xAA + i);
00095         cb.push(push_buffer);
00096         push_buffer++;
00097         cb.push(push_buffer);
00098         TEST_ASSERT_EQUAL(i / 2 + 2, cb.size());
00099 
00100         TEST_ASSERT_TRUE(cb.pop(pop_buffer));
00101         TEST_ASSERT_EQUAL(0xAA + i / 2, pop_buffer);
00102         TEST_ASSERT_EQUAL(i / 2 + 1, cb.size());
00103     }
00104 
00105     /* Pop the rest. */
00106     for (uint32_t i = 0; i < (num_of_elem_push / 2); i++) {
00107         TEST_ASSERT_TRUE(cb.pop(pop_buffer));
00108         TEST_ASSERT_EQUAL(0xAA + num_of_elem_push / 2 + i, pop_buffer);
00109         TEST_ASSERT_EQUAL(num_of_elem_push / 2 - 1 - i, cb.size());
00110 
00111     }
00112 }
00113 
00114 /* Test circular buffer - input exceeds capacity.
00115  *
00116  * Given is a circular buffer with the capacity equal to N (BufferSize).
00117  * When circular buffer is filled with N + 1 elements.
00118  * Then first pushed element is lost (overwritten by the last element) and
00119  * elements are read from the circular buffer in the FIFO order.
00120  *
00121  */
00122 template<typename T, uint32_t BufferSize, typename CounterType>
00123 void test_input_exceeds_capacity_push_max_plus_1_pop_max()
00124 {
00125     CircularBuffer<T, BufferSize, CounterType> cb;
00126     static const int num_of_elem_push = (BufferSize + 1);
00127     T data = 0;
00128 
00129     for (uint32_t i = 0; i < num_of_elem_push; i++) {
00130         data = (0xAA + i);
00131         cb.push(data);
00132         if (i < BufferSize) {
00133             TEST_ASSERT_EQUAL(i + 1, cb.size());
00134         } else {
00135             TEST_ASSERT_EQUAL(BufferSize, cb.size());
00136         }
00137 
00138     }
00139 
00140     for (uint32_t i = 0; i < (BufferSize - 1); i++) {
00141         TEST_ASSERT_TRUE(cb.pop(data));
00142         TEST_ASSERT_EQUAL(0xAA + i + 1, data);
00143         TEST_ASSERT_EQUAL(BufferSize - 1 - i, cb.size());
00144     }
00145 
00146     /* First element should be overwritten. */
00147     TEST_ASSERT_TRUE(cb.pop(data));
00148     TEST_ASSERT_EQUAL((0xAA + num_of_elem_push - 1), data);
00149     TEST_ASSERT_EQUAL(0, cb.size());
00150 }
00151 
00152 /* Test circular buffer - input exceeds capacity.
00153  *
00154  * Given is a circular buffer with the capacity equal to N (BufferSize).
00155  * When circular buffer is filled as follows: (2 * N) times 2 elements are pushed and 1 element is popped.
00156  * Then first pushed element is lost (overwritten by the last element) and
00157  * elements are read from the circular buffer in the FIFO order.
00158  *
00159  */
00160 template<typename T, uint32_t BufferSize, typename CounterType>
00161 void test_input_exceeds_capacity_push_2_pop_1()
00162 {
00163     CircularBuffer<T, BufferSize, CounterType> cb;
00164     static const int num_of_elem_push = (2 * BufferSize);
00165     T push_buffer = 0;
00166     T pop_buffer = 0;
00167 
00168     /* Push 2 elements and pop one element in each cycle. */
00169     for (uint32_t i = 0; i < num_of_elem_push; i += 2) {
00170         push_buffer = (0xAA + i);
00171         cb.push(push_buffer);
00172         push_buffer++;
00173         cb.push(push_buffer);
00174         if ((i / 2 + 1) < BufferSize) {
00175             TEST_ASSERT_EQUAL(i / 2 + 2, cb.size());
00176         } else {
00177             TEST_ASSERT_EQUAL(BufferSize, cb.size());
00178         }
00179 
00180         TEST_ASSERT_TRUE(cb.pop(pop_buffer));
00181         if ((i / 2 + 1) < BufferSize) {
00182             TEST_ASSERT_EQUAL(i / 2 + 1, cb.size());
00183         } else {
00184             TEST_ASSERT_EQUAL(BufferSize - 1, cb.size());
00185         }
00186 
00187         /* First element has been overwritten. */
00188         if (i == (num_of_elem_push - 2)) {
00189             TEST_ASSERT_EQUAL(0xAA + i / 2 + 1, pop_buffer);
00190         } else {
00191             TEST_ASSERT_EQUAL(0xAA + i / 2, pop_buffer);
00192         }
00193     }
00194 
00195     /* Pop the rest - one element has been overwritten. */
00196     for (uint32_t i = 0; i < (num_of_elem_push / 2 - 1); i++) {
00197         TEST_ASSERT_TRUE(cb.pop(pop_buffer));
00198         TEST_ASSERT_EQUAL(0xAA + num_of_elem_push / 2 + i + 1, pop_buffer);
00199     }
00200 }
00201 
00202 /* Test circular buffer - input exceeds capacity (complex type).
00203  *
00204  * Given is a circular buffer with the capacity equal to N (BufferSize).
00205  * When circular buffer is filled as follows: (2 * N) times 2 elements are pushed and 1 element is popped.
00206  * Then first pushed element is lost (overwritten by the last element) and
00207  * elements are read from the circular buffer in the FIFO order.
00208  *
00209  */
00210 template<uint32_t BufferSize, typename CounterType>
00211 void test_input_exceeds_capacity_push_2_pop_1_complex_type()
00212 {
00213     CircularBuffer<COMPLEX_TYPE, BufferSize, CounterType> cb;
00214     static const int num_of_elem_push = (2 * BufferSize);
00215     COMPLEX_TYPE push_buffer = {0};
00216     COMPLEX_TYPE pop_buffer = {0};
00217 
00218     /* Push 2 elements and pop one element in each cycle. */
00219     for (uint32_t i = 0; i < num_of_elem_push; i += 2) {
00220         comp_set(&push_buffer, 0xAA + i, 0xBB + i, 0xCC + i);
00221         cb.push(push_buffer);
00222         comp_set(&push_buffer, 0xAA + i + 1, 0xBB + i + 1, 0xCC + i + 1);
00223         cb.push(push_buffer);
00224         if ((i / 2 + 1) < BufferSize) {
00225             TEST_ASSERT_EQUAL(i / 2 + 2, cb.size());
00226         } else {
00227             TEST_ASSERT_EQUAL(BufferSize, cb.size());
00228         }
00229 
00230         TEST_ASSERT_TRUE(cb.pop(pop_buffer));
00231         if ((i / 2 + 1) < BufferSize) {
00232             TEST_ASSERT_EQUAL(i / 2 + 1, cb.size());
00233         } else {
00234             TEST_ASSERT_EQUAL(BufferSize - 1, cb.size());
00235         }
00236 
00237         /* First element has been overwritten. */
00238         if (i == (num_of_elem_push - 2)) {
00239             const bool result = comp_is_equal(&pop_buffer, 0xAA + 1 + i / 2, 0xBB + 1 + i / 2, 0xCC + 1 + i / 2);
00240             TEST_ASSERT_TRUE(result);
00241         } else {
00242             const bool result = comp_is_equal(&pop_buffer, 0xAA + i / 2, 0xBB + i / 2, 0xCC + i / 2);
00243             TEST_ASSERT_TRUE(result);
00244         }
00245     }
00246 
00247     /* Pop the rest - one element has been overwritten. */
00248     for (uint32_t i = 0; i < (num_of_elem_push / 2 - 1); i++) {
00249         TEST_ASSERT_TRUE(cb.pop(pop_buffer));
00250         const bool result = comp_is_equal(&pop_buffer, 0xAA + num_of_elem_push / 2 + i + 1,
00251                                           0xBB + num_of_elem_push / 2 + i + 1, 0xCC + num_of_elem_push / 2 + i + 1);
00252         TEST_ASSERT_TRUE(result);
00253     }
00254 }
00255 
00256 /* Test circular buffer - test pop(), empty(), full(), size() after CircularBuffer creation.
00257  *
00258  * Given is a circular buffer.
00259  * When circular buffer is created.
00260  * Then circular buffer is empty:
00261  * - empty() returns true,
00262  * - pop() function returns false,
00263  * - full() function returns false,
00264  * - size() function returns 0,
00265  *
00266  */
00267 void test_pop_empty_full_size_after_creation()
00268 {
00269     CircularBuffer<int, 1> cb;
00270     int data = 0;
00271 
00272     TEST_ASSERT_TRUE(cb.empty());
00273     TEST_ASSERT_FALSE(cb.pop(data));
00274     TEST_ASSERT_FALSE(cb.full());
00275     TEST_ASSERT_EQUAL(0, cb.size());
00276 }
00277 
00278 /* Test circular buffer - test empty() function.
00279  *
00280  * Given is a circular buffer with the capacity equal to N (BufferSize).
00281  * When operations on circular buffer are performed (push, pop).
00282  * Then empty() function returns true if buffer is empty, false otherwise.
00283  *
00284  */
00285 template<typename T, uint32_t BufferSize>
00286 void test_empty()
00287 {
00288     CircularBuffer<T, BufferSize> cb;
00289     T data = 0;
00290 
00291     /* Push max elements. */
00292     for (uint32_t i = 0; i < BufferSize; i++) {
00293         cb.push(data);
00294         TEST_ASSERT_FALSE(cb.empty());
00295     }
00296 
00297     /* Push next 2*BufferSize elements (overwrite entries). */
00298     for (uint32_t i = 0; i < (2 * BufferSize); i++) {
00299         cb.push(data);
00300         TEST_ASSERT_FALSE(cb.empty());
00301     }
00302 
00303     /* Pop (BufferSize - 1) elements (leave one). */
00304     for (uint32_t i = 0; i < (BufferSize - 1); i++) {
00305         TEST_ASSERT_TRUE(cb.pop(data));
00306         TEST_ASSERT_FALSE(cb.empty());
00307     }
00308 
00309     /* Take one which is left. */
00310     TEST_ASSERT_TRUE(cb.pop(data));
00311     TEST_ASSERT_TRUE(cb.empty());
00312 
00313     /* Add one element to the empty buffer. */
00314     cb.push(data);
00315     TEST_ASSERT_FALSE(cb.empty());
00316 }
00317 
00318 /* Test circular buffer - test full() function.
00319  *
00320  * Given is a circular buffer with the capacity equal to N (BufferSize).
00321  * When operations on circular buffer are performed (push, pop).
00322  * Then full() function returns true if buffer is full, false otherwise.
00323  *
00324  */
00325 template<typename T, uint32_t BufferSize>
00326 void test_full()
00327 {
00328     CircularBuffer<T, BufferSize> cb;
00329     T data = 0;
00330 
00331     /* Push max elements - 1. */
00332     for (uint32_t i = 0; i < (BufferSize - 1); i++) {
00333         cb.push(data);
00334         TEST_ASSERT_FALSE(cb.full());
00335     }
00336 
00337     /* Push one element - buffer should be full now. */
00338     cb.push(data);
00339     TEST_ASSERT_TRUE(cb.full());
00340 
00341     /* Push next 2*BufferSize elements (overwrite entries). */
00342     for (uint32_t i = 0; i < (2 * BufferSize); i++) {
00343         cb.push(data);
00344         TEST_ASSERT_TRUE(cb.full());
00345     }
00346 
00347     /* Pop all elements. */
00348     for (uint32_t i = 0; i < BufferSize; i++) {
00349         TEST_ASSERT_TRUE(cb.pop(data));
00350         TEST_ASSERT_FALSE(cb.full());
00351     }
00352 }
00353 
00354 /* Test circular buffer - test reset() function.
00355  *
00356  * Given is a circular buffer with the capacity equal to N (BufferSize).
00357  * When reset operation is performed on circular buffer.
00358  * Then circular buffer is cleared.
00359  *
00360  */
00361 template<typename T, uint32_t BufferSize>
00362 void test_reset()
00363 {
00364     CircularBuffer<T, BufferSize> cb;
00365     T data = 0xAA;
00366 
00367     /* Push max elements. */
00368     for (uint32_t i = 0; i < BufferSize; i++) {
00369         cb.push(data);
00370     }
00371 
00372     TEST_ASSERT_TRUE(cb.full());
00373     TEST_ASSERT_FALSE(cb.empty());
00374     TEST_ASSERT_EQUAL(BufferSize, cb.size());
00375 
00376     cb.reset();
00377 
00378     TEST_ASSERT_FALSE(cb.full());
00379     TEST_ASSERT_TRUE(cb.empty());
00380     TEST_ASSERT_FALSE(cb.pop(data));
00381     TEST_ASSERT_EQUAL(0, cb.size());
00382 
00383     /* Check if after reset push and pop operations work. */
00384     for (uint32_t i = 0; i < BufferSize; i++) {
00385         cb.push(data);
00386         data++;
00387     }
00388 
00389     for (uint32_t i = 0; i < BufferSize; i++) {
00390         cb.pop(data);
00391         TEST_ASSERT_EQUAL(0xAA + i, data);
00392     }
00393 }
00394 
00395 /* Test circular buffer - creation of circular buffer with max buffer size consistent with counter type.
00396  *
00397  * Given is a circular buffer.
00398  * When circular buffer is created with buffer size equal to 255 and counter type equal to unsigned char.
00399  * Then circular buffer is successfully created.
00400  *
00401  */
00402 void test_counter_type_buffer_size()
00403 {
00404     CircularBuffer<int, 255, unsigned char> cb;
00405     int data = 100;
00406 
00407     /* Perform some operations. */
00408     cb.push(data);
00409     data = 0;
00410     cb.pop(data);
00411     TEST_ASSERT_EQUAL(100, data);
00412 }
00413 
00414 utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
00415 {
00416     greentea_case_failure_abort_handler(source, reason);
00417     return STATUS_CONTINUE;
00418 }
00419 
00420 Case cases[] = {
00421     Case("Input does not exceed capacity(1) push max, pop max.",
00422          test_input_does_not_exceed_capacity_push_max_pop_max<uint32_t, 1, unsigned int>, greentea_failure_handler),
00423     Case("Input does not exceed capacity(3) push max, pop max.",
00424          test_input_does_not_exceed_capacity_push_max_pop_max<char, 3, unsigned int>, greentea_failure_handler),
00425 
00426     Case("Input does not exceed capacity(5) push 2, pop 1.",
00427          test_input_does_not_exceed_capacity_push_2_pop_1<uint32_t, 5, unsigned char>, greentea_failure_handler),
00428     Case("Input does not exceed capacity(10) push 2, pop 1.",
00429          test_input_does_not_exceed_capacity_push_2_pop_1<char, 10, unsigned char>, greentea_failure_handler),
00430 
00431     Case("Input exceeds capacity(1) push max+1, pop max.",
00432          test_input_exceeds_capacity_push_max_plus_1_pop_max<uint32_t, 1, unsigned int>, greentea_failure_handler),
00433     Case("Input exceeds capacity(3) push max+1, pop max.",
00434          test_input_exceeds_capacity_push_max_plus_1_pop_max<char, 3, unsigned int>, greentea_failure_handler),
00435 
00436     Case("Input exceeds capacity(5) push 2, pop 1.",
00437          test_input_exceeds_capacity_push_2_pop_1<uint32_t, 5, unsigned short>, greentea_failure_handler),
00438     Case("Input exceeds capacity(10) push 2, pop 1.",
00439          test_input_exceeds_capacity_push_2_pop_1<char, 10, unsigned short>, greentea_failure_handler),
00440 
00441     Case("empty() returns true when buffer(3 elements) is empty.", test_empty<uint32_t, 3>, greentea_failure_handler),
00442     Case("empty() returns true when buffer(5 elements) is empty.", test_empty<uint32_t, 5>, greentea_failure_handler),
00443 
00444     Case("full() returns true when buffer(3 elements) is full.", test_full<uint32_t, 3>, greentea_failure_handler),
00445     Case("full() returns true when buffer(5 elements) is full.", test_full<uint32_t, 5>, greentea_failure_handler),
00446 
00447     Case("reset() clears the buffer.", test_reset<uint32_t, 5>, greentea_failure_handler),
00448 
00449     Case("Test pop(), empty(), full(), size() after CircularBuffer creation.",
00450          test_pop_empty_full_size_after_creation, greentea_failure_handler),
00451 
00452     Case("Test CounterType/BufferSize boarder case.", test_counter_type_buffer_size, greentea_failure_handler),
00453 
00454     Case("Input exceeds capacity(5) push 2, pop 1 - complex type.",
00455          test_input_exceeds_capacity_push_2_pop_1_complex_type<5, unsigned short>, greentea_failure_handler),
00456 };
00457 
00458 utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
00459 {
00460     GREENTEA_SETUP(15, "default_auto");
00461     return greentea_test_setup_handler(number_of_cases);
00462 }
00463 
00464 Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
00465 
00466 int main()
00467 {
00468     return Harness::run(specification);
00469 }