Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tests.c Source File

tests.c

00001 /*
00002  * Testing framework for the events library
00003  *
00004  * Copyright (c) 2016 ARM Limited
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *     http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 #include "events/equeue.h"
00019 #include <unistd.h>
00020 #include <stdio.h>
00021 #include <setjmp.h>
00022 #include <stdint.h>
00023 #include <stdlib.h>
00024 #include <pthread.h>
00025 
00026 
00027 // Testing setup
00028 static jmp_buf test_buf;
00029 static int test_line;
00030 static int test_failure;
00031 
00032 #define test_assert(test) ({                                                \
00033     if (!(test)) {                                                          \
00034         test_line = __LINE__;                                               \
00035         longjmp(test_buf, 1);                                               \
00036     }                                                                       \
00037 })
00038 
00039 #define test_run(func, ...) ({                                              \
00040     printf("%s: ...", #func);                                               \
00041     fflush(stdout);                                                         \
00042                                                                             \
00043     if (!setjmp(test_buf)) {                                                \
00044         func(__VA_ARGS__);                                                  \
00045         printf("\r%s: \e[32mpassed\e[0m\n", #func);                         \
00046     } else {                                                                \
00047         printf("\r%s: \e[31mfailed\e[0m at line %d\n", #func, test_line);   \
00048         test_failure = true;                                                \
00049     }                                                                       \
00050 })
00051 
00052 
00053 // Test functions
00054 void pass_func(void *eh)
00055 {
00056 }
00057 
00058 void simple_func(void *p)
00059 {
00060     (*(int *)p)++;
00061 }
00062 
00063 void sloth_func(void *p)
00064 {
00065     usleep(10000);
00066     (*(int *)p)++;
00067 }
00068 
00069 struct indirect {
00070     int *touched;
00071     uint8_t buffer[7];
00072 };
00073 
00074 void indirect_func(void *p)
00075 {
00076     struct indirect *i = (struct indirect *)p;
00077     (*i->touched)++;
00078 }
00079 
00080 struct timing {
00081     unsigned tick;
00082     unsigned delay;
00083 };
00084 
00085 void timing_func(void *p)
00086 {
00087     struct timing *timing = (struct timing *)p;
00088     unsigned tick = equeue_tick();
00089 
00090     unsigned t1 = timing->delay;
00091     unsigned t2 = tick - timing->tick;
00092     test_assert(t1 > t2 - 10 && t1 < t2 + 10);
00093 
00094     timing->tick = tick;
00095 }
00096 
00097 struct fragment {
00098     equeue_t *q;
00099     size_t size;
00100     struct timing timing;
00101 };
00102 
00103 void fragment_func(void *p)
00104 {
00105     struct fragment *fragment = (struct fragment *)p;
00106     timing_func(&fragment->timing);
00107 
00108     struct fragment *nfragment = equeue_alloc(fragment->q, fragment->size);
00109     test_assert(nfragment);
00110 
00111     *nfragment = *fragment;
00112     equeue_event_delay(nfragment, fragment->timing.delay);
00113 
00114     int id = equeue_post(nfragment->q, fragment_func, nfragment);
00115     test_assert(id);
00116 }
00117 
00118 struct cancel {
00119     equeue_t *q;
00120     int id;
00121 };
00122 
00123 void cancel_func(void *p)
00124 {
00125     struct cancel *cancel = (struct cancel *)p;
00126     equeue_cancel(cancel->q, cancel->id);
00127 }
00128 
00129 struct nest {
00130     equeue_t *q;
00131     void (*cb)(void *);
00132     void *data;
00133 };
00134 
00135 void nest_func(void *p)
00136 {
00137     struct nest *nest = (struct nest *)p;
00138     equeue_call(nest->q, nest->cb, nest->data);
00139 
00140     usleep(10000);
00141 }
00142 
00143 
00144 // Simple call tests
00145 void simple_call_test(void)
00146 {
00147     equeue_t q;
00148     int err = equeue_create(&q, 2048);
00149     test_assert(!err);
00150 
00151     bool touched = false;
00152     equeue_call(&q, simple_func, &touched);
00153     equeue_dispatch(&q, 0);
00154     test_assert(touched);
00155 
00156     equeue_destroy(&q);
00157 }
00158 
00159 void simple_call_in_test(void)
00160 {
00161     equeue_t q;
00162     int err = equeue_create(&q, 2048);
00163     test_assert(!err);
00164 
00165     bool touched = false;
00166     int id = equeue_call_in(&q, 10, simple_func, &touched);
00167     test_assert(id);
00168 
00169     equeue_dispatch(&q, 15);
00170     test_assert(touched);
00171 
00172     equeue_destroy(&q);
00173 }
00174 
00175 void simple_call_every_test(void)
00176 {
00177     equeue_t q;
00178     int err = equeue_create(&q, 2048);
00179     test_assert(!err);
00180 
00181     bool touched = false;
00182     int id = equeue_call_every(&q, 10, simple_func, &touched);
00183     test_assert(id);
00184 
00185     equeue_dispatch(&q, 15);
00186     test_assert(touched);
00187 
00188     equeue_destroy(&q);
00189 }
00190 
00191 void simple_post_test(void)
00192 {
00193     equeue_t q;
00194     int err = equeue_create(&q, 2048);
00195     test_assert(!err);
00196 
00197     int touched = false;
00198     struct indirect *i = equeue_alloc(&q, sizeof(struct indirect));
00199     test_assert(i);
00200 
00201     i->touched = &touched;
00202     int id = equeue_post(&q, indirect_func, i);
00203     test_assert(id);
00204 
00205     equeue_dispatch(&q, 0);
00206     test_assert(*i->touched);
00207 
00208     equeue_destroy(&q);
00209 }
00210 
00211 // Misc tests
00212 void destructor_test(void)
00213 {
00214     equeue_t q;
00215     int err = equeue_create(&q, 2048);
00216     test_assert(!err);
00217 
00218     int touched;
00219     struct indirect *e;
00220     int ids[3];
00221 
00222     touched = 0;
00223     for (int i = 0; i < 3; i++) {
00224         e = equeue_alloc(&q, sizeof(struct indirect));
00225         test_assert(e);
00226 
00227         e->touched = &touched;
00228         equeue_event_dtor(e, indirect_func);
00229         int id = equeue_post(&q, pass_func, e);
00230         test_assert(id);
00231     }
00232 
00233     equeue_dispatch(&q, 0);
00234     test_assert(touched == 3);
00235 
00236     touched = 0;
00237     for (int i = 0; i < 3; i++) {
00238         e = equeue_alloc(&q, sizeof(struct indirect));
00239         test_assert(e);
00240 
00241         e->touched = &touched;
00242         equeue_event_dtor(e, indirect_func);
00243         ids[i] = equeue_post(&q, pass_func, e);
00244         test_assert(ids[i]);
00245     }
00246 
00247     for (int i = 0; i < 3; i++) {
00248         equeue_cancel(&q, ids[i]);
00249     }
00250 
00251     equeue_dispatch(&q, 0);
00252     test_assert(touched == 3);
00253 
00254     touched = 0;
00255     for (int i = 0; i < 3; i++) {
00256         e = equeue_alloc(&q, sizeof(struct indirect));
00257         test_assert(e);
00258 
00259         e->touched = &touched;
00260         equeue_event_dtor(e, indirect_func);
00261         int id = equeue_post(&q, pass_func, e);
00262         test_assert(id);
00263     }
00264 
00265     equeue_destroy(&q);
00266     test_assert(touched == 3);
00267 }
00268 
00269 void allocation_failure_test(void)
00270 {
00271     equeue_t q;
00272     int err = equeue_create(&q, 2048);
00273     test_assert(!err);
00274 
00275     void *p = equeue_alloc(&q, 4096);
00276     test_assert(!p);
00277 
00278     for (int i = 0; i < 100; i++) {
00279         p = equeue_alloc(&q, 0);
00280     }
00281     test_assert(!p);
00282 
00283     equeue_destroy(&q);
00284 }
00285 
00286 void cancel_test(int N)
00287 {
00288     equeue_t q;
00289     int err = equeue_create(&q, 2048);
00290     test_assert(!err);
00291 
00292     bool touched = false;
00293     int *ids = malloc(N * sizeof(int));
00294 
00295     for (int i = 0; i < N; i++) {
00296         ids[i] = equeue_call(&q, simple_func, &touched);
00297     }
00298 
00299     for (int i = N - 1; i >= 0; i--) {
00300         test_assert(equeue_cancel(&q, ids[i]));
00301     }
00302 
00303     free(ids);
00304 
00305     equeue_dispatch(&q, 0);
00306     test_assert(!touched);
00307 
00308     equeue_destroy(&q);
00309 }
00310 
00311 void cancel_inflight_test(void)
00312 {
00313     equeue_t q;
00314     int err = equeue_create(&q, 2048);
00315     test_assert(!err);
00316 
00317     bool touched = false;
00318 
00319     int id = equeue_call(&q, simple_func, &touched);
00320     test_assert(equeue_cancel(&q, id));
00321 
00322     equeue_dispatch(&q, 0);
00323     test_assert(!touched);
00324 
00325     id = equeue_call(&q, simple_func, &touched);
00326     test_assert(equeue_cancel(&q, id));
00327 
00328     equeue_dispatch(&q, 0);
00329     test_assert(!touched);
00330 
00331     struct cancel *cancel = equeue_alloc(&q, sizeof(struct cancel));
00332     test_assert(cancel);
00333     cancel->q = &q;
00334     cancel->id = 0;
00335 
00336     id = equeue_post(&q, cancel_func, cancel);
00337     test_assert(id);
00338 
00339     cancel->id = equeue_call(&q, simple_func, &touched);
00340 
00341     equeue_dispatch(&q, 0);
00342     test_assert(!touched);
00343 
00344     equeue_destroy(&q);
00345 }
00346 
00347 void cancel_unnecessarily_test(void)
00348 {
00349     equeue_t q;
00350     int err = equeue_create(&q, 2048);
00351     test_assert(!err);
00352 
00353     int id = equeue_call(&q, pass_func, 0);
00354     for (int i = 0; i < 5; i++) {
00355         test_assert(equeue_cancel(&q, id) == (i == 0));
00356     }
00357 
00358     id = equeue_call(&q, pass_func, 0);
00359     equeue_dispatch(&q, 0);
00360     for (int i = 0; i < 5; i++) {
00361         test_assert(!equeue_cancel(&q, id));
00362     }
00363 
00364     bool touched = false;
00365     equeue_call(&q, simple_func, &touched);
00366     for (int i = 0; i < 5; i++) {
00367         test_assert(!equeue_cancel(&q, id));
00368     }
00369 
00370     equeue_dispatch(&q, 0);
00371     test_assert(touched);
00372 
00373     equeue_destroy(&q);
00374 }
00375 
00376 void loop_protect_test(void)
00377 {
00378     equeue_t q;
00379     int err = equeue_create(&q, 2048);
00380     test_assert(!err);
00381 
00382     bool touched = false;
00383     equeue_call_every(&q, 0, simple_func, &touched);
00384 
00385     equeue_dispatch(&q, 0);
00386     test_assert(touched);
00387 
00388     touched = false;
00389     equeue_call_every(&q, 1, simple_func, &touched);
00390 
00391     equeue_dispatch(&q, 0);
00392     test_assert(touched);
00393 
00394     equeue_destroy(&q);
00395 }
00396 
00397 void break_test(void)
00398 {
00399     equeue_t q;
00400     int err = equeue_create(&q, 2048);
00401     test_assert(!err);
00402 
00403     bool touched = false;
00404     equeue_call_every(&q, 0, simple_func, &touched);
00405 
00406     equeue_break(&q);
00407     equeue_dispatch(&q, -1);
00408     test_assert(touched);
00409 
00410     equeue_destroy(&q);
00411 }
00412 
00413 void break_no_windup_test(void)
00414 {
00415     equeue_t q;
00416     int err = equeue_create(&q, 2048);
00417     test_assert(!err);
00418 
00419     int count = 0;
00420     equeue_call_every(&q, 0, simple_func, &count);
00421 
00422     equeue_break(&q);
00423     equeue_break(&q);
00424     equeue_dispatch(&q, -1);
00425     test_assert(count == 1);
00426 
00427     count = 0;
00428     equeue_dispatch(&q, 55);
00429     test_assert(count > 1);
00430 
00431     equeue_destroy(&q);
00432 }
00433 
00434 void period_test(void)
00435 {
00436     equeue_t q;
00437     int err = equeue_create(&q, 2048);
00438     test_assert(!err);
00439 
00440     int count = 0;
00441     equeue_call_every(&q, 10, simple_func, &count);
00442 
00443     equeue_dispatch(&q, 55);
00444     test_assert(count == 5);
00445 
00446     equeue_destroy(&q);
00447 }
00448 
00449 void nested_test(void)
00450 {
00451     equeue_t q;
00452     int err = equeue_create(&q, 2048);
00453     test_assert(!err);
00454 
00455     int touched = 0;
00456     struct nest *nest = equeue_alloc(&q, sizeof(struct nest));
00457     test_assert(nest);
00458     nest->q = &q;
00459     nest->cb = simple_func;
00460     nest->data = &touched;
00461 
00462     int id = equeue_post(&q, nest_func, nest);
00463     test_assert(id);
00464 
00465     equeue_dispatch(&q, 5);
00466     test_assert(touched == 0);
00467 
00468     equeue_dispatch(&q, 5);
00469     test_assert(touched == 1);
00470 
00471     touched = 0;
00472     nest = equeue_alloc(&q, sizeof(struct nest));
00473     test_assert(nest);
00474     nest->q = &q;
00475     nest->cb = simple_func;
00476     nest->data = &touched;
00477 
00478     id = equeue_post(&q, nest_func, nest);
00479     test_assert(id);
00480 
00481     equeue_dispatch(&q, 20);
00482     test_assert(touched == 1);
00483 
00484     equeue_destroy(&q);
00485 }
00486 
00487 void sloth_test(void)
00488 {
00489     equeue_t q;
00490     int err = equeue_create(&q, 2048);
00491     test_assert(!err);
00492 
00493     int touched = 0;
00494     int id = equeue_call(&q, sloth_func, &touched);
00495     test_assert(id);
00496 
00497     id = equeue_call_in(&q, 5, simple_func, &touched);
00498     test_assert(id);
00499 
00500     id = equeue_call_in(&q, 15, simple_func, &touched);
00501     test_assert(id);
00502 
00503     equeue_dispatch(&q, 20);
00504     test_assert(touched == 3);
00505 
00506     equeue_destroy(&q);
00507 }
00508 
00509 void *multithread_thread(void *p)
00510 {
00511     equeue_t *q = (equeue_t *)p;
00512     equeue_dispatch(q, -1);
00513     return 0;
00514 }
00515 
00516 void multithread_test(void)
00517 {
00518     equeue_t q;
00519     int err = equeue_create(&q, 2048);
00520     test_assert(!err);
00521 
00522     int touched = 0;
00523     equeue_call_every(&q, 1, simple_func, &touched);
00524 
00525     pthread_t thread;
00526     err = pthread_create(&thread, 0, multithread_thread, &q);
00527     test_assert(!err);
00528 
00529     usleep(10000);
00530     equeue_break(&q);
00531     err = pthread_join(thread, 0);
00532     test_assert(!err);
00533 
00534     test_assert(touched);
00535 
00536     equeue_destroy(&q);
00537 }
00538 
00539 void background_func(void *p, int ms)
00540 {
00541     *(unsigned *)p = ms;
00542 }
00543 
00544 void background_test(void)
00545 {
00546     equeue_t q;
00547     int err = equeue_create(&q, 2048);
00548     test_assert(!err);
00549 
00550     int id = equeue_call_in(&q, 20, pass_func, 0);
00551     test_assert(id);
00552 
00553     unsigned ms;
00554     equeue_background(&q, background_func, &ms);
00555     test_assert(ms == 20);
00556 
00557     id = equeue_call_in(&q, 10, pass_func, 0);
00558     test_assert(id);
00559     test_assert(ms == 10);
00560 
00561     id = equeue_call(&q, pass_func, 0);
00562     test_assert(id);
00563     test_assert(ms == 0);
00564 
00565     equeue_dispatch(&q, 0);
00566     test_assert(ms == 10);
00567 
00568     equeue_destroy(&q);
00569     test_assert(ms == -1);
00570 }
00571 
00572 void chain_test(void)
00573 {
00574     equeue_t q1;
00575     int err = equeue_create(&q1, 2048);
00576     test_assert(!err);
00577 
00578     equeue_t q2;
00579     err = equeue_create(&q2, 2048);
00580     test_assert(!err);
00581 
00582     equeue_chain(&q2, &q1);
00583 
00584     int touched = 0;
00585 
00586     int id1 = equeue_call_in(&q1, 20, simple_func, &touched);
00587     int id2 = equeue_call_in(&q2, 20, simple_func, &touched);
00588     test_assert(id1 && id2);
00589 
00590     id1 = equeue_call(&q1, simple_func, &touched);
00591     id2 = equeue_call(&q2, simple_func, &touched);
00592     test_assert(id1 && id2);
00593 
00594     id1 = equeue_call_in(&q1, 5, simple_func, &touched);
00595     id2 = equeue_call_in(&q2, 5, simple_func, &touched);
00596     test_assert(id1 && id2);
00597 
00598     test_assert(equeue_cancel(&q1, id1));
00599     test_assert(equeue_cancel(&q2, id2));
00600 
00601     id1 = equeue_call_in(&q1, 10, simple_func, &touched);
00602     id2 = equeue_call_in(&q2, 10, simple_func, &touched);
00603     test_assert(id1 && id2);
00604 
00605     equeue_dispatch(&q1, 30);
00606 
00607     test_assert(touched == 6);
00608 
00609     equeue_destroy(&q2);
00610     equeue_destroy(&q1);
00611 }
00612 
00613 void unchain_test(void)
00614 {
00615     equeue_t q1;
00616     int err = equeue_create(&q1, 2048);
00617     test_assert(!err);
00618 
00619     equeue_t q2;
00620     err = equeue_create(&q2, 2048);
00621     test_assert(!err);
00622 
00623     equeue_chain(&q2, &q1);
00624 
00625     int touched = 0;
00626     int id1 = equeue_call(&q1, simple_func, &touched);
00627     int id2 = equeue_call(&q2, simple_func, &touched);
00628     test_assert(id1 && id2);
00629 
00630     equeue_dispatch(&q1, 0);
00631     test_assert(touched == 2);
00632 
00633     equeue_chain(&q2, 0);
00634     equeue_chain(&q1, &q2);
00635 
00636     id1 = equeue_call(&q1, simple_func, &touched);
00637     id2 = equeue_call(&q2, simple_func, &touched);
00638     test_assert(id1 && id2);
00639 
00640     equeue_dispatch(&q2, 0);
00641     test_assert(touched == 4);
00642 
00643     equeue_destroy(&q1);
00644     equeue_destroy(&q2);
00645 }
00646 
00647 // Barrage tests
00648 void simple_barrage_test(int N)
00649 {
00650     equeue_t q;
00651     int err = equeue_create(&q, N * (EQUEUE_EVENT_SIZE + sizeof(struct timing)));
00652     test_assert(!err);
00653 
00654     for (int i = 0; i < N; i++) {
00655         struct timing *timing = equeue_alloc(&q, sizeof(struct timing));
00656         test_assert(timing);
00657 
00658         timing->tick = equeue_tick();
00659         timing->delay = (i + 1) * 100;
00660         equeue_event_delay(timing, timing->delay);
00661         equeue_event_period(timing, timing->delay);
00662 
00663         int id = equeue_post(&q, timing_func, timing);
00664         test_assert(id);
00665     }
00666 
00667     equeue_dispatch(&q, N * 100);
00668 
00669     equeue_destroy(&q);
00670 }
00671 
00672 void fragmenting_barrage_test(int N)
00673 {
00674     equeue_t q;
00675     int err = equeue_create(&q,
00676                             2 * N * (EQUEUE_EVENT_SIZE + sizeof(struct fragment) + N * sizeof(int)));
00677     test_assert(!err);
00678 
00679     for (int i = 0; i < N; i++) {
00680         size_t size = sizeof(struct fragment) + i * sizeof(int);
00681         struct fragment *fragment = equeue_alloc(&q, size);
00682         test_assert(fragment);
00683 
00684         fragment->q = &q;
00685         fragment->size = size;
00686         fragment->timing.tick = equeue_tick();
00687         fragment->timing.delay = (i + 1) * 100;
00688         equeue_event_delay(fragment, fragment->timing.delay);
00689 
00690         int id = equeue_post(&q, fragment_func, fragment);
00691         test_assert(id);
00692     }
00693 
00694     equeue_dispatch(&q, N * 100);
00695 
00696     equeue_destroy(&q);
00697 }
00698 
00699 struct ethread {
00700     pthread_t thread;
00701     equeue_t *q;
00702     int ms;
00703 };
00704 
00705 static void *ethread_dispatch(void *p)
00706 {
00707     struct ethread *t = (struct ethread *)p;
00708     equeue_dispatch(t->q, t->ms);
00709     return 0;
00710 }
00711 
00712 void multithreaded_barrage_test(int N)
00713 {
00714     equeue_t q;
00715     int err = equeue_create(&q, N * (EQUEUE_EVENT_SIZE + sizeof(struct timing)));
00716     test_assert(!err);
00717 
00718     struct ethread t;
00719     t.q = &q;
00720     t.ms = N * 100;
00721     err = pthread_create(&t.thread, 0, ethread_dispatch, &t);
00722     test_assert(!err);
00723 
00724     for (int i = 0; i < N; i++) {
00725         struct timing *timing = equeue_alloc(&q, sizeof(struct timing));
00726         test_assert(timing);
00727 
00728         timing->tick = equeue_tick();
00729         timing->delay = (i + 1) * 100;
00730         equeue_event_delay(timing, timing->delay);
00731         equeue_event_period(timing, timing->delay);
00732 
00733         int id = equeue_post(&q, timing_func, timing);
00734         test_assert(id);
00735     }
00736 
00737     err = pthread_join(t.thread, 0);
00738     test_assert(!err);
00739 
00740     equeue_destroy(&q);
00741 }
00742 
00743 struct count_and_queue {
00744     int p;
00745     equeue_t *q;
00746 };
00747 
00748 void simple_breaker(void *p)
00749 {
00750     struct count_and_queue *caq = (struct count_and_queue *)p;
00751     equeue_break(caq->q);
00752     usleep(10000);
00753     caq->p++;
00754 }
00755 
00756 void break_request_cleared_on_timeout(void)
00757 {
00758     equeue_t q;
00759     int err = equeue_create(&q, 2048);
00760     test_assert(!err);
00761 
00762     struct count_and_queue pq;
00763     pq.p = 0;
00764     pq.q = &q;
00765 
00766     int id = equeue_call_every(&q, 10, simple_breaker, &pq);
00767 
00768     equeue_dispatch(&q, 10);
00769     test_assert(pq.p == 1);
00770 
00771     test_assert(equeue_cancel(&q, id));
00772 
00773     int count = 0;
00774     equeue_call_every(&q, 10, simple_func, &count);
00775 
00776     equeue_dispatch(&q, 55);
00777     test_assert(count > 1);
00778 
00779     equeue_destroy(&q);
00780 }
00781 
00782 void sibling_test(void)
00783 {
00784     equeue_t q;
00785     int err = equeue_create(&q, 1024);
00786     test_assert(!err);
00787 
00788     int id0 = equeue_call_in(&q, 1, pass_func, 0);
00789     int id1 = equeue_call_in(&q, 1, pass_func, 0);
00790     int id2 = equeue_call_in(&q, 1, pass_func, 0);
00791 
00792     struct equeue_event *e = q.queue;
00793 
00794     for (; e; e = e->next) {
00795         for (struct equeue_event *s = e->sibling; s; s = s->sibling) {
00796             test_assert(!s->next);
00797         }
00798     }
00799     test_assert(equeue_cancel(&q, id0));
00800     test_assert(equeue_cancel(&q, id1));
00801     test_assert(equeue_cancel(&q, id2));
00802     equeue_destroy(&q);
00803 }
00804 
00805 struct user_allocated_event {
00806     struct equeue_event e;
00807     bool touched;
00808 };
00809 
00810 void user_allocated_event_test()
00811 {
00812     equeue_t q;
00813     int err = equeue_create(&q, EQUEUE_EVENT_SIZE);
00814     test_assert(!err);
00815 
00816     bool touched = false;
00817     struct user_allocated_event e1 = { { 0, 0, 0, NULL, NULL, NULL, 0, -1, NULL, NULL }, 0 };
00818     struct user_allocated_event e2 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
00819     struct user_allocated_event e3 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
00820     struct user_allocated_event e4 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
00821     struct user_allocated_event e5 = { { 0, 0, 0, NULL, NULL, NULL, 0, -1, NULL, NULL }, 0 };
00822 
00823     test_assert(0 != equeue_call(&q, simple_func, &touched));
00824     test_assert(0 == equeue_call(&q, simple_func, &touched));
00825     test_assert(0 == equeue_call(&q, simple_func, &touched));
00826 
00827     equeue_post_user_allocated(&q, simple_func, &e1.e);
00828     equeue_post_user_allocated(&q, simple_func, &e2.e);
00829     equeue_post_user_allocated(&q, simple_func, &e3.e);
00830     equeue_post_user_allocated(&q, simple_func, &e4.e);
00831     equeue_post_user_allocated(&q, simple_func, &e5.e);
00832     test_assert(equeue_cancel_user_allocated(&q, &e3.e));
00833 
00834     equeue_dispatch(&q, 1);
00835 
00836     test_assert(true == touched);
00837     test_assert(true == e1.touched);
00838     test_assert(true == e2.touched);
00839     test_assert(false == e3.touched);
00840     test_assert(true == e4.touched);
00841     test_assert(true == e5.touched);
00842 
00843     equeue_dispatch(&q, 10);
00844 
00845     test_assert(true == touched);
00846     test_assert(true == e1.touched);
00847     test_assert(true == e2.touched);
00848     test_assert(false == e3.touched);
00849     test_assert(true == e4.touched);
00850     test_assert(true == e5.touched);
00851 
00852     equeue_destroy(&q);
00853 }
00854 
00855 void id_cycle()
00856 {
00857     equeue_t q;
00858     int err = equeue_create(&q, 10000000);
00859     test_assert(!err);
00860 
00861     for (int i = 0; i < 300; i++) {
00862         int id = equeue_call(&q, pass_func, 0);
00863         test_assert(id != 0);
00864         test_assert(equeue_cancel(&q, id));
00865     }
00866 
00867     equeue_destroy(&q);
00868 }
00869 
00870 int main()
00871 {
00872     printf("beginning tests...\n");
00873 
00874     test_run(simple_call_test);
00875     test_run(simple_call_in_test);
00876     test_run(simple_call_every_test);
00877     test_run(simple_post_test);
00878     test_run(destructor_test);
00879     test_run(allocation_failure_test);
00880     test_run(cancel_test, 20);
00881     test_run(cancel_inflight_test);
00882     test_run(cancel_unnecessarily_test);
00883     test_run(loop_protect_test);
00884     test_run(break_test);
00885     test_run(break_no_windup_test);
00886     test_run(period_test);
00887     test_run(nested_test);
00888     test_run(sloth_test);
00889     test_run(background_test);
00890     test_run(chain_test);
00891     test_run(unchain_test);
00892     test_run(multithread_test);
00893     test_run(simple_barrage_test, 20);
00894     test_run(fragmenting_barrage_test, 20);
00895     test_run(multithreaded_barrage_test, 20);
00896     test_run(break_request_cleared_on_timeout);
00897     test_run(sibling_test);
00898     test_run(user_allocated_event_test);
00899     test_run(id_cycle);
00900     printf("done!\n");
00901     return test_failure;
00902 }