From 44a278479c7632bf00d258f1f6c36cd4f9e190c7 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Fri, 21 May 2021 16:27:27 +0900 Subject: [PATCH] tests: add test for pubsub repetition Change-Id: I73dc4a0290facc54ee423584a5d4e998fbb8bb92 --- tests/vine-test/vine-pubsub-open-close-test.cpp | 250 ++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 tests/vine-test/vine-pubsub-open-close-test.cpp diff --git a/tests/vine-test/vine-pubsub-open-close-test.cpp b/tests/vine-test/vine-pubsub-open-close-test.cpp new file mode 100644 index 0000000..a64a63c --- /dev/null +++ b/tests/vine-test/vine-pubsub-open-close-test.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Test: vine-pubsub-open-close-test + * Description: + * a PubSub DP opens and closes repeatedly in one session. + * The interval is 100ms. (DP_LIFETIME) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vine-test-utils.h" + +#define MAX_EVENTS 50 +#define DEFAULT_REPETITION_TIME 100 +#define DP_LIFETIME 100000000 // nanoseconds +#define TOPIC "pubsub-test" + +static int epollfd = 0; +static vine_session_h session = NULL; +static int count = DEFAULT_REPETITION_TIME; + +enum { + EPOLL_EVENT_TYPE_SESSION = 0, + EPOLL_EVENT_TYPE_TIMEOUT +}; + +typedef struct { + int type; + int timerfd; + void *ptr; +} epoll_data_s; + +static void open_dp(vine_session_h session); + +void _logger(int log_level, const char *log) +{ + switch (log_level) { + case VINE_LOG_DEBUG: + printf("D/"); + break; + case VINE_LOG_INFO: + printf("I/"); + break; + case VINE_LOG_ERROR: + printf(COLOR_RED "E/"); + break; + } + printf("%s" COLOR_RESET "\n", log); +} + +static void add_event_fd(int fd, void *user_data) +{ + struct epoll_event ev; + ev.events = EPOLLIN; + ev.data.fd = fd; + ev.data.ptr = user_data; + if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { + print_error("Fail to add an epoll event for fd %d: %d", fd, errno); + exit(1); + } +} + +static void del_event_fd(int fd) +{ + epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL); +} + +static void _start_timer(vine_dp_h dp, int nsec) +{ + if (nsec <= 0) + return; + + int timerfd = timerfd_create(CLOCK_MONOTONIC, 0); + if (timerfd == -1) + return; + + struct itimerspec value; + value.it_interval.tv_sec = 0; + value.it_interval.tv_nsec = 0; + value.it_value.tv_sec = 0; + value.it_value.tv_nsec = nsec; + if (timerfd_settime(timerfd, 0, &value, NULL) != 0) { + close(timerfd); + return; + } + + epoll_data_s *data = (epoll_data_s *)calloc(1, sizeof(epoll_data_s)); + data->type = EPOLL_EVENT_TYPE_TIMEOUT; + data->timerfd = timerfd; + data->ptr = (void *)dp; + + add_event_fd(timerfd, (void *)data); +} + +static void _stop_timer(int fd) +{ + del_event_fd(fd); + close(fd); + --count; +} + +static void _handle_timer_event(epoll_data_s *data) +{ + int fd = data->timerfd; + vine_dp_h dp = (vine_dp_h)data->ptr; + + PRINT_LOG("Close dp[%p]", dp); + _stop_timer(fd); + vine_dp_close(dp); + vine_dp_destroy(dp); + + open_dp(session); +} + +static void _event_handler(void *user_data) +{ + epoll_data_s *data = (epoll_data_s *)user_data; + + if (!data || !data->ptr) + return; + + if (data->type == EPOLL_EVENT_TYPE_SESSION) { + PRINT_IF_ERROR(vine_session_process_event(data->ptr), "vine_process_event"); + } else if (data->type == EPOLL_EVENT_TYPE_TIMEOUT) { + _handle_timer_event(data); + free(data); + } +} + +static void run_event_loop(vine_session_h session) +{ + struct epoll_event events[MAX_EVENTS]; + + epollfd = epoll_create1(0); + if (epollfd == -1) { + print_error("Fail to create epoll fd %d", errno); + return; + } + + int fd = 0; + PRINT_IF_ERROR(vine_session_get_event_fd(session, &fd), "vine_session_get_event_fd"); + if (fd <= 0) + return; + + epoll_data_s *data = (epoll_data_s *)calloc(1, sizeof(epoll_data_s)); + data->type = EPOLL_EVENT_TYPE_SESSION; + data->ptr = session; + add_event_fd(fd, (void *)data); + + while (count) { + int n = epoll_wait(epollfd, events, MAX_EVENTS, 0); + if (n == -1) { + print_error("epoll_wait %d", errno); + break; + } + + for (int i = 0; i < n; ++i) { + if (events[i].data.ptr) + _event_handler(events[i].data.ptr); + } + } + free(data); + close(epollfd); +} + +static void open_dp(vine_session_h session) +{ + vine_dp_h dp = NULL; + + PRINT_IF_ERROR(vine_dp_create(session, VINE_DP_TYPE_PUBSUB, &dp), "vine_dp_create"); + PRINT_IF_ERROR(vine_dp_set_topic(dp, TOPIC), "vine_dp_set_topic"); + PRINT_IF_ERROR(vine_dp_set_terminated_cb(dp, + [](vine_dp_h dp, void *user_data) { + PRINT_LOG("dp[%p] is closed."); + }, NULL), "vine_dp_set_terminated_cb"); + PRINT_IF_ERROR(vine_dp_set_peer_joined_cb(dp, + [](vine_dp_h dp, const char *ip, int port, void *user_data) { + PRINT_LOG("dp[%p]'s peer[%s:%d] is joined.", dp, ip, port); + }, NULL), "vine_dp_set_peer_joined_cb"); + PRINT_IF_ERROR(vine_dp_set_peer_left_cb(dp, + [](vine_dp_h dp, const char *ip, int port, void *user_data) { + PRINT_LOG("dp[%p]'s peer[%s:%d] is left.", dp, ip, port); + }, NULL), "vine_dp_set_peer_left_cb"); + PRINT_IF_ERROR(vine_dp_open(dp, + [](vine_dp_h dp, vine_error_e result, void *user_data) { + if (result != VINE_ERROR_NONE) + return; + PRINT_LOG("dp[%p] is opened.", dp); + _start_timer(dp, DP_LIFETIME); + }, NULL), "vine_dp_open"); +} + +static void _parse_options(int argc, char **argv) +{ + int opt = 0; + + while ((opt = getopt(argc, argv, "dhn:")) != -1) { + switch(opt) { + case 'd': + vine_set_logger(_logger); + vine_set_log_level(VINE_LOG_DEBUG | VINE_LOG_INFO | VINE_LOG_ERROR); + break; + case 'n': + count = atoi(optarg); + break; + case 'h': + default: + printf(COLOR_CYN "[HELP] -n: number of times, -d: debug, -h: help\n" COLOR_RESET); + exit(1); + } + } +} + +int main(int argc, char **argv) +{ + _parse_options(argc, argv); + + PRINT_IF_ERROR(vine_initialize(), "vine_initialize()"); + PRINT_IF_ERROR(vine_session_create(&session), "vine_session_create"); + + open_dp(session); + run_event_loop(session); + + PRINT_IF_ERROR(vine_session_destroy(session), "vine_session_destroy"); + PRINT_IF_ERROR(vine_deinitialize(), "vine_deinitialize()"); + + return 0; +} -- 2.7.4