Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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(), peek(), 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  * - peek() function returns false,
00264  * - full() function returns false,
00265  * - size() function returns 0,
00266  *
00267  */
00268 void test_pop_empty_full_size_after_creation()
00269 {
00270     CircularBuffer<int, 1> cb;
00271     int data = 0;
00272 
00273     TEST_ASSERT_TRUE(cb.empty());
00274     TEST_ASSERT_FALSE(cb.pop(data));
00275     TEST_ASSERT_FALSE(cb.peek(data));
00276     TEST_ASSERT_FALSE(cb.full());
00277     TEST_ASSERT_EQUAL(0, cb.size());
00278 }
00279 
00280 /* Test circular buffer - test empty() function.
00281  *
00282  * Given is a circular buffer with the capacity equal to N (BufferSize).
00283  * When operations on circular buffer are performed (push, pop).
00284  * Then empty() function returns true if buffer is empty, false otherwise.
00285  *
00286  */
00287 template<typename T, uint32_t BufferSize>
00288 void test_empty()
00289 {
00290     CircularBuffer<T, BufferSize> cb;
00291     T data = 0;
00292 
00293     /* Push max elements. */
00294     for (uint32_t i = 0; i < BufferSize; i++) {
00295         cb.push(data);
00296         TEST_ASSERT_FALSE(cb.empty());
00297     }
00298 
00299     /* Push next 2*BufferSize elements (overwrite entries). */
00300     for (uint32_t i = 0; i < (2 * BufferSize); i++) {
00301         cb.push(data);
00302         TEST_ASSERT_FALSE(cb.empty());
00303     }
00304 
00305     /* Pop (BufferSize - 1) elements (leave one). */
00306     for (uint32_t i = 0; i < (BufferSize - 1); i++) {
00307         TEST_ASSERT_TRUE(cb.pop(data));
00308         TEST_ASSERT_FALSE(cb.empty());
00309     }
00310 
00311     /* Take one which is left. */
00312     TEST_ASSERT_TRUE(cb.pop(data));
00313     TEST_ASSERT_TRUE(cb.empty());
00314 
00315     /* Add one element to the empty buffer. */
00316     cb.push(data);
00317     TEST_ASSERT_FALSE(cb.empty());
00318 }
00319 
00320 /* Test circular buffer - test full() function.
00321  *
00322  * Given is a circular buffer with the capacity equal to N (BufferSize).
00323  * When operations on circular buffer are performed (push, pop).
00324  * Then full() function returns true if buffer is full, false otherwise.
00325  *
00326  */
00327 template<typename T, uint32_t BufferSize>
00328 void test_full()
00329 {
00330     CircularBuffer<T, BufferSize> cb;
00331     T data = 0;
00332 
00333     /* Push max elements - 1. */
00334     for (uint32_t i = 0; i < (BufferSize - 1); i++) {
00335         cb.push(data);
00336         TEST_ASSERT_FALSE(cb.full());
00337     }
00338 
00339     /* Push one element - buffer should be full now. */
00340     cb.push(data);
00341     TEST_ASSERT_TRUE(cb.full());
00342 
00343     /* Push next 2*BufferSize elements (overwrite entries). */
00344     for (uint32_t i = 0; i < (2 * BufferSize); i++) {
00345         cb.push(data);
00346         TEST_ASSERT_TRUE(cb.full());
00347     }
00348 
00349     /* Pop all elements. */
00350     for (uint32_t i = 0; i < BufferSize; i++) {
00351         TEST_ASSERT_TRUE(cb.pop(data));
00352         TEST_ASSERT_FALSE(cb.full());
00353     }
00354 }
00355 
00356 /* Test circular buffer - test reset() function.
00357  *
00358  * Given is a circular buffer with the capacity equal to N (BufferSize).
00359  * When reset operation is performed on circular buffer.
00360  * Then circular buffer is cleared.
00361  *
00362  */
00363 template<typename T, uint32_t BufferSize>
00364 void test_reset()
00365 {
00366     CircularBuffer<T, BufferSize> cb;
00367     T data = 0xAA;
00368 
00369     /* Push max elements. */
00370     for (uint32_t i = 0; i < BufferSize; i++) {
00371         cb.push(data);
00372     }
00373 
00374     TEST_ASSERT_TRUE(cb.full());
00375     TEST_ASSERT_FALSE(cb.empty());
00376     TEST_ASSERT_EQUAL(BufferSize, cb.size());
00377 
00378     cb.reset();
00379 
00380     TEST_ASSERT_FALSE(cb.full());
00381     TEST_ASSERT_TRUE(cb.empty());
00382     TEST_ASSERT_FALSE(cb.pop(data));
00383     TEST_ASSERT_EQUAL(0, cb.size());
00384 
00385     /* Check if after reset push and pop operations work. */
00386     for (uint32_t i = 0; i < BufferSize; i++) {
00387         cb.push(data);
00388         data++;
00389     }
00390 
00391     for (uint32_t i = 0; i < BufferSize; i++) {
00392         cb.pop(data);
00393         TEST_ASSERT_EQUAL(0xAA + i, data);
00394     }
00395 }
00396 
00397 /* Test circular buffer - creation of circular buffer with max buffer size consistent with counter type.
00398  *
00399  * Given is a circular buffer.
00400  * When circular buffer is created with buffer size equal to 255 and counter type equal to unsigned char.
00401  * Then circular buffer is successfully created.
00402  *
00403  */
00404 void test_counter_type_buffer_size()
00405 {
00406     CircularBuffer<int, 255, unsigned char> cb;
00407     int data = 100;
00408 
00409     /* Perform some operations. */
00410     cb.push(data);
00411     data = 0;
00412     cb.pop(data);
00413     TEST_ASSERT_EQUAL(100, data);
00414 }
00415 
00416 /* Test circular buffer - peek should not update buffer data.
00417  *
00418  * When circular buffer peek operation is performed along with
00419  * push and pop, it should not update the buffer data elements.
00420  * Elements read using pop/peek operation should match.
00421  *
00422  */
00423 void test_peek_no_pop()
00424 {
00425     CircularBuffer<int, 3, unsigned char> cb;
00426     int data = 0;
00427     int peek_data = 0;
00428 
00429     for (uint32_t i = 0; i < 3; i++) {
00430         data = (0xAA + i);
00431         cb.push(data);
00432         cb.peek(peek_data);
00433         TEST_ASSERT_EQUAL(i + 1, cb.size());
00434     }
00435 
00436     for (uint32_t i = 0; i < 3; i++) {
00437         TEST_ASSERT_TRUE(cb.peek(peek_data));
00438         TEST_ASSERT_EQUAL(0xAA + i, peek_data);
00439         TEST_ASSERT_TRUE(cb.pop(data));
00440         TEST_ASSERT_EQUAL(0xAA + i, data);
00441         TEST_ASSERT_EQUAL(3 - i - 1, cb.size());
00442     }
00443 }
00444 
00445 utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
00446 {
00447     greentea_case_failure_abort_handler(source, reason);
00448     return STATUS_CONTINUE;
00449 }
00450 
00451 Case cases[] = {
00452     Case("Input does not exceed capacity(1) push max, pop max.",
00453          test_input_does_not_exceed_capacity_push_max_pop_max<uint32_t, 1, unsigned int>, greentea_failure_handler),
00454     Case("Input does not exceed capacity(3) push max, pop max.",
00455          test_input_does_not_exceed_capacity_push_max_pop_max<char, 3, unsigned int>, greentea_failure_handler),
00456 
00457     Case("Input does not exceed capacity(5) push 2, pop 1.",
00458          test_input_does_not_exceed_capacity_push_2_pop_1<uint32_t, 5, unsigned char>, greentea_failure_handler),
00459     Case("Input does not exceed capacity(10) push 2, pop 1.",
00460          test_input_does_not_exceed_capacity_push_2_pop_1<char, 10, unsigned char>, greentea_failure_handler),
00461 
00462     Case("Input exceeds capacity(1) push max+1, pop max.",
00463          test_input_exceeds_capacity_push_max_plus_1_pop_max<uint32_t, 1, unsigned int>, greentea_failure_handler),
00464     Case("Input exceeds capacity(3) push max+1, pop max.",
00465          test_input_exceeds_capacity_push_max_plus_1_pop_max<char, 3, unsigned int>, greentea_failure_handler),
00466 
00467     Case("Input exceeds capacity(5) push 2, pop 1.",
00468          test_input_exceeds_capacity_push_2_pop_1<uint32_t, 5, unsigned short>, greentea_failure_handler),
00469     Case("Input exceeds capacity(10) push 2, pop 1.",
00470          test_input_exceeds_capacity_push_2_pop_1<char, 10, unsigned short>, greentea_failure_handler),
00471 
00472     Case("empty() returns true when buffer(3 elements) is empty.", test_empty<uint32_t, 3>, greentea_failure_handler),
00473     Case("empty() returns true when buffer(5 elements) is empty.", test_empty<uint32_t, 5>, greentea_failure_handler),
00474 
00475     Case("full() returns true when buffer(3 elements) is full.", test_full<uint32_t, 3>, greentea_failure_handler),
00476     Case("full() returns true when buffer(5 elements) is full.", test_full<uint32_t, 5>, greentea_failure_handler),
00477 
00478     Case("reset() clears the buffer.", test_reset<uint32_t, 5>, greentea_failure_handler),
00479 
00480     Case("Test pop(), peek(), empty(), full(), size() after CircularBuffer creation.",
00481          test_pop_empty_full_size_after_creation, greentea_failure_handler),
00482 
00483     Case("Test CounterType/BufferSize boarder case.", test_counter_type_buffer_size, greentea_failure_handler),
00484 
00485     Case("Input exceeds capacity(5) push 2, pop 1 - complex type.",
00486          test_input_exceeds_capacity_push_2_pop_1_complex_type<5, unsigned short>, greentea_failure_handler),
00487 
00488     Case("peek() return data without popping the element.", test_peek_no_pop, greentea_failure_handler),
00489 };
00490 
00491 utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
00492 {
00493     GREENTEA_SETUP(15, "default_auto");
00494     return greentea_test_setup_handler(number_of_cases);
00495 }
00496 
00497 Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
00498 
00499 int main()
00500 {
00501     return Harness::run(specification);
00502 }