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_events.h"
00017 #include "mbed.h"
00018 #include "rtos.h"
00019 #include "greentea-client/test_env.h"
00020 #include "unity.h"
00021 #include "utest.h"
00022 
00023 #if !DEVICE_USTICKER
00024   #error [NOT_SUPPORTED] test not supported
00025 #endif
00026 
00027 using namespace utest::v1;
00028 
00029 // Assume that tolerance is 5% of measured time.
00030 #define DELTA(ms) (ms / 20)
00031 
00032 // TEST_EQUEUE_SIZE was reduced below 1024B to fit this test to devices with small RAM (RAM <= 16kB)
00033 // additionally TEST_EQUEUE_SIZE was expressed in EVENTS_EVENT_SIZE to increase readability
00034 // (for more details about EVENTS_EVENT_SIZE see EventQueue constructor)
00035 #define TEST_EQUEUE_SIZE (18*EVENTS_EVENT_SIZE)
00036 
00037 // flag for called
00038 volatile bool touched = false;
00039 
00040 // static functions
00041 void func5(int a0, int a1, int a2, int a3, int a4) { 
00042     touched = true;
00043     TEST_ASSERT_EQUAL(a0 | a1 | a2 | a3 | a4, 0x1f);
00044 }
00045 
00046 void func4(int a0, int a1, int a2, int a3) {
00047     touched = true;
00048     TEST_ASSERT_EQUAL(a0 | a1 | a2 | a3, 0xf); 
00049 }
00050 
00051 void func3(int a0, int a1, int a2) {
00052     touched = true;
00053     TEST_ASSERT_EQUAL(a0 | a1 | a2, 0x7);
00054 }
00055 
00056 void func2(int a0, int a1) {
00057     touched = true;
00058     TEST_ASSERT_EQUAL(a0 | a1, 0x3);
00059 }
00060 
00061 void func1(int a0) {
00062     touched = true;
00063     TEST_ASSERT_EQUAL(a0, 0x1);
00064 }
00065 
00066 void func0() {
00067     touched = true;
00068 }
00069 
00070 #define SIMPLE_POSTS_TEST(i, ...)                           \
00071 void simple_posts_test##i() {                               \
00072     EventQueue queue(TEST_EQUEUE_SIZE);                     \
00073                                                             \
00074     touched = false;                                        \
00075     queue.call(func##i,##__VA_ARGS__);                      \
00076     queue.dispatch(0);                                      \
00077     TEST_ASSERT(touched);                                   \
00078                                                             \
00079     touched = false;                                        \
00080     queue.call_in(1, func##i,##__VA_ARGS__);                \
00081     queue.dispatch(2);                                      \
00082     TEST_ASSERT(touched);                                   \
00083                                                             \
00084     touched = false;                                        \
00085     queue.call_every(1, func##i,##__VA_ARGS__);             \
00086     queue.dispatch(2);                                      \
00087     TEST_ASSERT(touched);                                   \
00088 }
00089 
00090 SIMPLE_POSTS_TEST(5, 0x01, 0x02, 0x04, 0x08, 0x010)
00091 SIMPLE_POSTS_TEST(4, 0x01, 0x02, 0x04, 0x08)
00092 SIMPLE_POSTS_TEST(3, 0x01, 0x02, 0x04)
00093 SIMPLE_POSTS_TEST(2, 0x01, 0x02)
00094 SIMPLE_POSTS_TEST(1, 0x01)
00095 SIMPLE_POSTS_TEST(0)
00096 
00097 
00098 void time_func(Timer *t, int ms) {
00099     TEST_ASSERT_INT_WITHIN(DELTA(ms), ms, t->read_ms());
00100     t->reset();
00101 }
00102 
00103 template <int N>
00104 void call_in_test() {
00105     Timer tickers[N];
00106 
00107     EventQueue queue(TEST_EQUEUE_SIZE);
00108 
00109     for (int i = 0; i < N; i++) {
00110         tickers[i].start();
00111         queue.call_in((i+1)*100, time_func, &tickers[i], (i+1)*100);
00112     }
00113 
00114     queue.dispatch(N*100);
00115 }
00116 
00117 template <int N>
00118 void call_every_test() {
00119     Timer tickers[N];
00120 
00121     EventQueue queue(TEST_EQUEUE_SIZE);
00122 
00123     for (int i = 0; i < N; i++) {
00124         tickers[i].start();
00125         queue.call_every((i+1)*100, time_func, &tickers[i], (i+1)*100);
00126     }
00127 
00128     queue.dispatch(N*100);
00129 }
00130 
00131 void allocate_failure_test() {
00132     EventQueue queue(TEST_EQUEUE_SIZE);
00133     int id;
00134 
00135     for (int i = 0; i < 100; i++) {
00136         id = queue.call((void (*)())0);
00137     }
00138 
00139     TEST_ASSERT(!id);
00140 }
00141 
00142 void no() {
00143     TEST_ASSERT(false);
00144 }
00145 
00146 template <int N>
00147 void cancel_test1() {
00148     EventQueue queue(TEST_EQUEUE_SIZE);
00149 
00150     int ids[N];
00151 
00152     for (int i = 0; i < N; i++) {
00153         ids[i] = queue.call_in(1000, no);
00154     }
00155 
00156     for (int i = N-1; i >= 0; i--) {
00157         queue.cancel(ids[i]);
00158     }
00159 
00160     queue.dispatch(0);
00161 }
00162 
00163 
00164 // Testing the dynamic arguments to the event class
00165 unsigned counter = 0;
00166 
00167 void count5(unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a5) {
00168     counter += a0 + a1 + a2 + a3 + a5;
00169 }
00170 
00171 void count4(unsigned a0, unsigned a1, unsigned a2, unsigned a3) {
00172     counter += a0 + a1 + a2 + a3;
00173 }
00174 
00175 void count3(unsigned a0, unsigned a1, unsigned a2) {
00176     counter += a0 + a1 + a2;
00177 }
00178 
00179 void count2(unsigned a0, unsigned a1) {
00180     counter += a0 + a1;
00181 }
00182 
00183 void count1(unsigned a0) {
00184     counter += a0;
00185 }
00186 
00187 void count0() {
00188     counter += 0;
00189 }
00190 
00191 void event_class_test() {
00192     counter = 0;
00193     EventQueue queue(TEST_EQUEUE_SIZE);
00194 
00195     Event<void(int, int, int, int, int)> e5(&queue, count5);
00196     Event<void(int, int, int, int)> e4(&queue, count5, 1);
00197     Event<void(int, int, int)> e3(&queue, count5, 1, 1);
00198     Event<void(int, int)> e2(&queue, count5, 1, 1, 1);
00199     Event<void(int)> e1(&queue, count5, 1, 1, 1, 1);
00200     Event<void()> e0(&queue, count5, 1, 1, 1, 1, 1);
00201 
00202     e5.post(1, 1, 1, 1, 1);
00203     e4.post(1, 1, 1, 1);
00204     e3.post(1, 1, 1);
00205     e2.post(1, 1);
00206     e1.post(1);
00207     e0.post();
00208 
00209     queue.dispatch(0);
00210 
00211     TEST_ASSERT_EQUAL(counter, 30);
00212 }
00213 
00214 void event_class_helper_test() {
00215     counter = 0;
00216     EventQueue queue(TEST_EQUEUE_SIZE);
00217 
00218     Event<void()> e5 = queue.event(count5, 1, 1, 1, 1, 1);
00219     Event<void()> e4 = queue.event(count4, 1, 1, 1, 1);
00220     Event<void()> e3 = queue.event(count3, 1, 1, 1);
00221     Event<void()> e2 = queue.event(count2, 1, 1);
00222     Event<void()> e1 = queue.event(count1, 1);
00223     Event<void()> e0 = queue.event(count0);
00224 
00225     e5.post();
00226     e4.post();
00227     e3.post();
00228     e2.post();
00229     e1.post();
00230     e0.post();
00231 
00232     queue.dispatch(0);
00233 
00234     TEST_ASSERT_EQUAL(counter, 15);
00235 }
00236 
00237 void event_inference_test() {
00238     counter = 0;
00239     EventQueue queue(TEST_EQUEUE_SIZE);
00240 
00241     queue.event(count5, 1, 1, 1, 1, 1).post();
00242     queue.event(count5, 1, 1, 1, 1).post(1);
00243     queue.event(count5, 1, 1, 1).post(1, 1);
00244     queue.event(count5, 1, 1).post(1, 1, 1);
00245     queue.event(count5, 1).post(1, 1, 1, 1);
00246     queue.event(count5).post(1, 1, 1, 1, 1);
00247 
00248     queue.event(callback(count5), 1, 1, 1, 1, 1).post();
00249     queue.event(callback(count5), 1, 1, 1, 1).post(1);
00250     queue.event(callback(count5), 1, 1, 1).post(1, 1);
00251     queue.event(callback(count5), 1, 1).post(1, 1, 1);
00252     queue.event(callback(count5), 1).post(1, 1, 1, 1);
00253     queue.event(callback(count5)).post(1, 1, 1, 1, 1);
00254 
00255     queue.dispatch(0);
00256 
00257     TEST_ASSERT_EQUAL(counter, 60);
00258 }
00259 
00260 int timeleft_events[2];
00261 
00262 void check_time_left(EventQueue* queue, int index, int expected) {
00263     const int event_id = timeleft_events[index];
00264     TEST_ASSERT_INT_WITHIN(2, expected, queue->time_left(event_id));
00265     touched = true;
00266 }
00267 
00268 void time_left(EventQueue* queue, int index) {
00269     const int event_id = timeleft_events[index];
00270     TEST_ASSERT_EQUAL(0, queue->time_left(event_id));
00271 }
00272 
00273 void time_left_test() {
00274     EventQueue queue(TEST_EQUEUE_SIZE);
00275 
00276     // Enque check events
00277     TEST_ASSERT(queue.call_in(50, check_time_left, &queue, 0, 100-50));
00278     TEST_ASSERT(queue.call_in(200, check_time_left, &queue, 1, 200-200));
00279 
00280     // Enque events to be checked
00281     timeleft_events[0] = queue.call_in(100, time_left, &queue, 0);
00282     timeleft_events[1] = queue.call_in(200, time_left, &queue, 1);
00283     TEST_ASSERT(timeleft_events[0]);
00284     TEST_ASSERT(timeleft_events[1]);
00285 
00286     queue.dispatch(300);
00287 
00288     // Ensure check was called
00289     TEST_ASSERT(touched);
00290     touched = false;
00291 
00292     int id = queue.call(func0);
00293     TEST_ASSERT(id);
00294     TEST_ASSERT_EQUAL(0, queue.time_left(id));
00295     queue.dispatch(10);
00296 
00297     // Test invalid event id
00298     TEST_ASSERT_EQUAL(-1, queue.time_left(0));
00299 }
00300 
00301 // Test setup
00302 utest::v1::status_t test_setup(const size_t number_of_cases) {
00303     GREENTEA_SETUP(20, "default_auto");
00304     return verbose_test_setup_handler(number_of_cases);
00305 }
00306 
00307 const Case cases[] = {
00308     Case("Testing calls with 5 args", simple_posts_test5),
00309     Case("Testing calls with 4 args", simple_posts_test4),
00310     Case("Testing calls with 3 args", simple_posts_test3),
00311     Case("Testing calls with 2 args", simple_posts_test2),
00312     Case("Testing calls with 1 args", simple_posts_test1),
00313     Case("Testing calls with 0 args", simple_posts_test0),
00314 
00315     Case("Testing call_in",    call_in_test<20>),
00316     Case("Testing call_every", call_every_test<20>),
00317 
00318     Case("Testing allocate failure", allocate_failure_test),
00319 
00320     Case("Testing event cancel 1", cancel_test1<20>),
00321     Case("Testing the event class", event_class_test),
00322     Case("Testing the event class helpers", event_class_helper_test),
00323     Case("Testing the event inference", event_inference_test),
00324 
00325     Case("Testing time_left", time_left_test),
00326 };
00327 
00328 Specification specification(test_setup, cases);
00329 
00330 int main() {
00331     return !Harness::run(specification);
00332 }
00333