You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
2.5 KiB
113 lines
2.5 KiB
#include <gtest/gtest.h> |
|
#include <pthread.h> |
|
#include <sys/eventfd.h> |
|
#include <sys/time.h> |
|
#include <unistd.h> |
|
|
|
#include "AllocationTestHarness.h" |
|
|
|
#include "osi/include/reactor.h" |
|
|
|
class ReactorTest : public AllocationTestHarness {}; |
|
|
|
static pthread_t thread; |
|
static volatile bool thread_running; |
|
|
|
static void* reactor_thread(void* ptr) { |
|
reactor_t* reactor = (reactor_t*)ptr; |
|
|
|
thread_running = true; |
|
reactor_start(reactor); |
|
thread_running = false; |
|
|
|
return NULL; |
|
} |
|
|
|
static void spawn_reactor_thread(reactor_t* reactor) { |
|
int ret = pthread_create(&thread, NULL, reactor_thread, reactor); |
|
EXPECT_EQ(ret, 0); |
|
} |
|
|
|
static void join_reactor_thread() { pthread_join(thread, NULL); } |
|
|
|
TEST_F(ReactorTest, reactor_new) { |
|
reactor_t* reactor = reactor_new(); |
|
EXPECT_TRUE(reactor != NULL); |
|
reactor_free(reactor); |
|
} |
|
|
|
TEST_F(ReactorTest, reactor_free_null) { reactor_free(NULL); } |
|
|
|
TEST_F(ReactorTest, reactor_stop_start) { |
|
reactor_t* reactor = reactor_new(); |
|
reactor_stop(reactor); |
|
reactor_start(reactor); |
|
reactor_free(reactor); |
|
} |
|
|
|
TEST_F(ReactorTest, reactor_repeated_stop_start) { |
|
reactor_t* reactor = reactor_new(); |
|
for (int i = 0; i < 10; ++i) { |
|
reactor_stop(reactor); |
|
reactor_start(reactor); |
|
} |
|
reactor_free(reactor); |
|
} |
|
|
|
TEST_F(ReactorTest, reactor_start_wait_stop) { |
|
reactor_t* reactor = reactor_new(); |
|
|
|
spawn_reactor_thread(reactor); |
|
usleep(50 * 1000); |
|
EXPECT_TRUE(thread_running); |
|
|
|
reactor_stop(reactor); |
|
join_reactor_thread(); |
|
EXPECT_FALSE(thread_running); |
|
|
|
reactor_free(reactor); |
|
} |
|
|
|
typedef struct { |
|
reactor_t* reactor; |
|
reactor_object_t* object; |
|
} unregister_arg_t; |
|
|
|
static void unregister_cb(void* context) { |
|
unregister_arg_t* arg = (unregister_arg_t*)context; |
|
reactor_unregister(arg->object); |
|
reactor_stop(arg->reactor); |
|
} |
|
|
|
TEST_F(ReactorTest, reactor_unregister_from_callback) { |
|
reactor_t* reactor = reactor_new(); |
|
|
|
int fd = eventfd(0, 0); |
|
unregister_arg_t arg; |
|
arg.reactor = reactor; |
|
arg.object = reactor_register(reactor, fd, &arg, unregister_cb, NULL); |
|
spawn_reactor_thread(reactor); |
|
eventfd_write(fd, 1); |
|
|
|
join_reactor_thread(); |
|
|
|
close(fd); |
|
reactor_free(reactor); |
|
} |
|
|
|
TEST_F(ReactorTest, reactor_unregister_from_separate_thread) { |
|
reactor_t* reactor = reactor_new(); |
|
|
|
int fd = eventfd(0, 0); |
|
|
|
reactor_object_t* object = reactor_register(reactor, fd, NULL, NULL, NULL); |
|
spawn_reactor_thread(reactor); |
|
usleep(50 * 1000); |
|
reactor_unregister(object); |
|
|
|
reactor_stop(reactor); |
|
join_reactor_thread(); |
|
|
|
close(fd); |
|
reactor_free(reactor); |
|
}
|
|
|