Home | History | Annotate | Download | only in test
      1 #include <gtest/gtest.h>
      2 #include <pthread.h>
      3 #include <sys/eventfd.h>
      4 #include <sys/time.h>
      5 #include <unistd.h>
      6 
      7 #include "AllocationTestHarness.h"
      8 
      9 extern "C" {
     10 #include "osi/include/reactor.h"
     11 }
     12 
     13 class ReactorTest : public AllocationTestHarness {};
     14 
     15 static pthread_t thread;
     16 static volatile bool thread_running;
     17 
     18 static void *reactor_thread(void *ptr) {
     19   reactor_t *reactor = (reactor_t *)ptr;
     20 
     21   thread_running = true;
     22   reactor_start(reactor);
     23   thread_running = false;
     24 
     25   return NULL;
     26 }
     27 
     28 static void spawn_reactor_thread(reactor_t *reactor) {
     29   int ret = pthread_create(&thread, NULL, reactor_thread, reactor);
     30   EXPECT_EQ(ret, 0);
     31 }
     32 
     33 static void join_reactor_thread() {
     34   pthread_join(thread, NULL);
     35 }
     36 
     37 TEST_F(ReactorTest, reactor_new) {
     38   reactor_t *reactor = reactor_new();
     39   EXPECT_TRUE(reactor != NULL);
     40   reactor_free(reactor);
     41 }
     42 
     43 TEST_F(ReactorTest, reactor_free_null) {
     44   reactor_free(NULL);
     45 }
     46 
     47 TEST_F(ReactorTest, reactor_stop_start) {
     48   reactor_t *reactor = reactor_new();
     49   reactor_stop(reactor);
     50   reactor_start(reactor);
     51   reactor_free(reactor);
     52 }
     53 
     54 TEST_F(ReactorTest, reactor_repeated_stop_start) {
     55   reactor_t *reactor = reactor_new();
     56   for (int i = 0; i < 10; ++i) {
     57     reactor_stop(reactor);
     58     reactor_start(reactor);
     59   }
     60   reactor_free(reactor);
     61 }
     62 
     63 TEST_F(ReactorTest, reactor_start_wait_stop) {
     64   reactor_t *reactor = reactor_new();
     65 
     66   spawn_reactor_thread(reactor);
     67   usleep(50 * 1000);
     68   EXPECT_TRUE(thread_running);
     69 
     70   reactor_stop(reactor);
     71   join_reactor_thread();
     72   EXPECT_FALSE(thread_running);
     73 
     74   reactor_free(reactor);
     75 }
     76 
     77 typedef struct {
     78   reactor_t *reactor;
     79   reactor_object_t *object;
     80 } unregister_arg_t;
     81 
     82 static void unregister_cb(void *context) {
     83   unregister_arg_t *arg = (unregister_arg_t *)context;
     84   reactor_unregister(arg->object);
     85   reactor_stop(arg->reactor);
     86 }
     87 
     88 TEST_F(ReactorTest, reactor_unregister_from_callback) {
     89   reactor_t *reactor = reactor_new();
     90 
     91   int fd = eventfd(0, 0);
     92   unregister_arg_t arg;
     93   arg.reactor = reactor;
     94   arg.object = reactor_register(reactor, fd, &arg, unregister_cb, NULL);
     95   spawn_reactor_thread(reactor);
     96   eventfd_write(fd, 1);
     97 
     98   join_reactor_thread();
     99 
    100   close(fd);
    101   reactor_free(reactor);
    102 }
    103 
    104 TEST_F(ReactorTest, reactor_unregister_from_separate_thread) {
    105   reactor_t *reactor = reactor_new();
    106 
    107   int fd = eventfd(0, 0);
    108 
    109   reactor_object_t *object = reactor_register(reactor, fd, NULL, NULL, NULL);
    110   spawn_reactor_thread(reactor);
    111   usleep(50 * 1000);
    112   reactor_unregister(object);
    113 
    114   reactor_stop(reactor);
    115   join_reactor_thread();
    116 
    117   close(fd);
    118   reactor_free(reactor);
    119 }
    120