Knight KE / Mbed OS Game_Master
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 #include "mbed.h"
00017 #include "greentea-client/test_env.h"
00018 #include "unity.h"
00019 #include "utest.h"
00020 #include "rtos.h"
00021 
00022 #if defined(MBED_RTOS_SINGLE_THREAD)
00023   #error [NOT_SUPPORTED] test not supported
00024 #endif
00025 
00026 #if !DEVICE_USTICKER
00027 #error [NOT_SUPPORTED] test not supported
00028 #endif
00029 
00030 using namespace utest::v1;
00031 
00032 #define THREAD_STACK_SIZE 512
00033 #define TEST_UINT_MSG 0xDEADBEEF
00034 #define TEST_UINT_MSG2 0xE1EE7
00035 #define TEST_TIMEOUT 50
00036 
00037 template <uint32_t ms>
00038 void thread_put_uint_msg(Queue<uint32_t, 1> *q)
00039 {
00040     Thread::wait(ms);
00041     osStatus stat = q->put((uint32_t*) TEST_UINT_MSG);
00042     TEST_ASSERT_EQUAL(osOK, stat);
00043 }
00044 
00045 template <uint32_t ms, uint32_t val>
00046 void thread_get_uint_msg(Queue<uint32_t, 1> *q)
00047 {
00048     Thread::wait(ms);
00049     osEvent evt = q->get();
00050     TEST_ASSERT_EQUAL(osEventMessage, evt.status);
00051     TEST_ASSERT_EQUAL(val, evt.value.v);
00052 }
00053 
00054 /** Test pass uint msg
00055 
00056     Given a queue for uint32_t messages with one slot
00057     When a uin32_t value is inserted into the queue
00058         and a message is extracted from the queue
00059     Then the extracted message is the same as previously inserted message
00060  */
00061 void test_pass_uint()
00062 {
00063     Queue<uint32_t, 1> q;
00064     osStatus stat = q.put((uint32_t*)TEST_UINT_MSG);
00065     TEST_ASSERT_EQUAL(osOK, stat);
00066 
00067     osEvent evt = q.get();
00068     TEST_ASSERT_EQUAL(osEventMessage, evt.status);
00069     TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v);
00070 }
00071 
00072 /** Test pass uint msg twice
00073 
00074     Given a queue for uint32_t messages with one slot
00075     When a uin32_t value is inserted into the queue
00076         and a message is extracted from the queue
00077         and the procedure is repeated with different message
00078     Then the extracted message is the same as previously inserted message for both iterations
00079 
00080  */
00081 void test_pass_uint_twice()
00082 {
00083     Queue<uint32_t, 1> q;
00084     osStatus stat = q.put((uint32_t*)TEST_UINT_MSG);
00085     TEST_ASSERT_EQUAL(osOK, stat);
00086 
00087     osEvent evt = q.get();
00088     TEST_ASSERT_EQUAL(osEventMessage, evt.status);
00089     TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v);
00090 
00091     stat = q.put((uint32_t*)TEST_UINT_MSG2);
00092     TEST_ASSERT_EQUAL(osOK, stat);
00093 
00094     evt = q.get();
00095     TEST_ASSERT_EQUAL(osEventMessage, evt.status);
00096     TEST_ASSERT_EQUAL(TEST_UINT_MSG2, evt.value.v);
00097 }
00098 
00099 /** Test pass ptr msg
00100 
00101     Given a queue for pointers to uint32_t messages with one slot
00102     When a pointer to an uint32_t is inserted into the queue
00103         and a message is extracted from the queue
00104     Then the extracted message is the same as previously inserted message
00105  */
00106 void test_pass_ptr()
00107 {
00108     Queue<uint32_t, 1> q;
00109     uint32_t msg = TEST_UINT_MSG;
00110 
00111     osStatus stat = q.put(&msg);
00112     TEST_ASSERT_EQUAL(osOK, stat);
00113 
00114     osEvent evt = q.get();
00115     TEST_ASSERT_EQUAL(osEventMessage, evt.status);
00116     TEST_ASSERT_EQUAL(&msg, evt.value.p);
00117 }
00118 
00119 /** Test get from empty queue
00120 
00121     Given an empty queue for uint32_t values
00122     When @a get is called on the queue with timeout of 0
00123     Then queue returns status of osOK, but no data
00124  */
00125 void test_get_empty_no_timeout()
00126 {
00127     Queue<uint32_t, 1> q;
00128 
00129     osEvent evt = q.get(0);
00130     TEST_ASSERT_EQUAL(osOK, evt.status);
00131 }
00132 
00133 /** Test get from empty queue with timeout
00134 
00135     Given an empty queue for uint32_t values
00136     When @a get is called on the queue with timeout of 50ms
00137     Then queue returns status of osEventTimeout after about 50ms wait
00138  */
00139 void test_get_empty_timeout()
00140 {
00141     Queue<uint32_t, 1> q;
00142     Timer timer;
00143     timer.start();
00144 
00145     osEvent evt = q.get(50);
00146     TEST_ASSERT_EQUAL(osEventTimeout, evt.status);
00147     TEST_ASSERT_UINT32_WITHIN(5000, 50000, timer.read_us());
00148 }
00149 
00150 /** Test get empty wait forever
00151 
00152     Given a two threads A & B and a queue for uint32_t values
00153     When thread A calls @a get on an empty queue with osWaitForever
00154     Then the thread A waits for a message to appear in the queue
00155     When thread B puts a message in the queue
00156     Then thread A wakes up and receives it
00157  */
00158 void test_get_empty_wait_forever()
00159 {
00160     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00161     Queue<uint32_t, 1> q;
00162 
00163     t.start(callback(thread_put_uint_msg<TEST_TIMEOUT>, &q));
00164 
00165     Timer timer;
00166     timer.start();
00167 
00168     osEvent evt = q.get();
00169     TEST_ASSERT_EQUAL(osEventMessage, evt.status);
00170     TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v);
00171     TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us());
00172 }
00173 
00174 /** Test put full no timeout
00175  *
00176  * Given a queue with one slot for uint32_t data
00177  * When a thread tries to insert two messages
00178  * Then first operation succeeds and second fails with @a osErrorResource
00179  */
00180 void test_put_full_no_timeout()
00181 {
00182     Queue<uint32_t, 1> q;
00183 
00184     osStatus stat = q.put((uint32_t*) TEST_UINT_MSG);
00185     TEST_ASSERT_EQUAL(osOK, stat);
00186 
00187     stat = q.put((uint32_t*) TEST_UINT_MSG);
00188     TEST_ASSERT_EQUAL(osErrorResource, stat);
00189 }
00190 
00191 /** Test put full timeout
00192  *
00193  * Given a queue with one slot for uint32_t data
00194  * When a thread tries to insert two messages with @ TEST_TIMEOUT timeout
00195  * Then first operation succeeds and second fails with @a osErrorTimeout
00196  */
00197 void test_put_full_timeout()
00198 {
00199     Queue<uint32_t, 1> q;
00200 
00201     osStatus stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT);
00202     TEST_ASSERT_EQUAL(osOK, stat);
00203 
00204     Timer timer;
00205     timer.start();
00206 
00207     stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT);
00208     TEST_ASSERT_EQUAL(osErrorTimeout, stat);
00209     TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us());
00210 }
00211 
00212 /** Test put full wait forever
00213  *
00214  * Given two threads A & B and a queue with one slot for uint32_t data
00215  * When thread A puts a message to the queue and tries to put second one with @a osWaitForever timeout
00216  * Then thread waits for a slot to become empty in the queue
00217  * When thread B takes one message out of the queue
00218  * Then thread A successfully inserts message into the queue
00219  */
00220 void test_put_full_waitforever()
00221 {
00222     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00223     Queue<uint32_t, 1> q;
00224 
00225     t.start(callback(thread_get_uint_msg<TEST_TIMEOUT, TEST_UINT_MSG>, &q));
00226 
00227     osStatus stat = q.put((uint32_t*) TEST_UINT_MSG);
00228     TEST_ASSERT_EQUAL(osOK, stat);
00229 
00230     Timer timer;
00231     timer.start();
00232     stat = q.put((uint32_t*) TEST_UINT_MSG, osWaitForever);
00233     TEST_ASSERT_EQUAL(osOK, stat);
00234     TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us());
00235 
00236     t.join();
00237 }
00238 
00239 /** Test message ordering
00240 
00241     Given a queue of uint32_t data
00242     When two messages are inserted with equal priority
00243     Then messages should be returned in the exact order they were inserted
00244  */
00245 void test_msg_order()
00246 {
00247     Queue<uint32_t, 2> q;
00248 
00249     osStatus stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT);
00250     TEST_ASSERT_EQUAL(osOK, stat);
00251 
00252     stat = q.put((uint32_t*) TEST_UINT_MSG2, TEST_TIMEOUT);
00253     TEST_ASSERT_EQUAL(osOK, stat);
00254 
00255     osEvent evt = q.get();
00256     TEST_ASSERT_EQUAL(osEventMessage, evt.status);
00257     TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v);
00258 
00259     evt = q.get();
00260     TEST_ASSERT_EQUAL(osEventMessage, evt.status);
00261     TEST_ASSERT_EQUAL(TEST_UINT_MSG2, evt.value.v);
00262 }
00263 
00264 /** Test message priority
00265 
00266     Given a queue of uint32_t data
00267     When two messages are inserted with ascending priority
00268     Then messages should be returned in descending priority order
00269  */
00270 void test_msg_prio()
00271 {
00272     Queue<uint32_t, 2> q;
00273 
00274     osStatus stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT, 0);
00275     TEST_ASSERT_EQUAL(osOK, stat);
00276 
00277     stat = q.put((uint32_t*) TEST_UINT_MSG2, TEST_TIMEOUT, 1);
00278     TEST_ASSERT_EQUAL(osOK, stat);
00279 
00280     osEvent evt = q.get();
00281     TEST_ASSERT_EQUAL(osEventMessage, evt.status);
00282     TEST_ASSERT_EQUAL(TEST_UINT_MSG2, evt.value.v);
00283 
00284     evt = q.get();
00285     TEST_ASSERT_EQUAL(osEventMessage, evt.status);
00286     TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v);
00287 }
00288 
00289 /** Test queue empty
00290 
00291     Given a queue of uint32_t data
00292     before data is inserted the queue should be empty
00293     after data is inserted the queue shouldn't be empty
00294  */
00295 void test_queue_empty()
00296 {
00297     Queue<uint32_t, 1> q;
00298 
00299     TEST_ASSERT_EQUAL(true, q.empty());
00300 
00301     q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT, 1);
00302 
00303     TEST_ASSERT_EQUAL(false, q.empty());
00304 }
00305 
00306 /** Test queue empty
00307 
00308     Given a queue of uint32_t data with size of 1
00309     before data is inserted the queue shouldn't be full
00310     after data is inserted the queue should be full
00311  */
00312 void test_queue_full()
00313 {
00314     Queue<uint32_t, 1> q;
00315 
00316     TEST_ASSERT_EQUAL(false, q.full());
00317 
00318     q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT, 1);
00319 
00320     TEST_ASSERT_EQUAL(true, q.full());
00321 }
00322 
00323 utest::v1::status_t test_setup(const size_t number_of_cases)
00324 {
00325     GREENTEA_SETUP(5, "default_auto");
00326     return verbose_test_setup_handler(number_of_cases);
00327 }
00328 
00329 Case cases[] = {
00330     Case("Test pass uint msg", test_pass_uint),
00331     Case("Test pass uint msg twice", test_pass_uint_twice),
00332     Case("Test pass ptr msg", test_pass_ptr),
00333     Case("Test get from empty queue no timeout", test_get_empty_no_timeout),
00334     Case("Test get from empty queue timeout", test_get_empty_timeout),
00335     Case("Test get empty wait forever", test_get_empty_wait_forever),
00336     Case("Test put full no timeout", test_put_full_no_timeout),
00337     Case("Test put full timeout", test_put_full_timeout),
00338     Case("Test put full wait forever", test_put_full_waitforever),
00339     Case("Test message ordering", test_msg_order),
00340     Case("Test message priority", test_msg_prio),
00341     Case("Test queue empty", test_queue_empty),
00342     Case("Test queue full", test_queue_full)
00343 };
00344 
00345 Specification specification(test_setup, cases);
00346 
00347 int main()
00348 {
00349     return !Harness::run(specification);
00350 }