tests: add test for pubsub repetition 23/258623/4
authorSeonah Moon <seonah1.moon@samsung.com>
Fri, 21 May 2021 07:27:27 +0000 (16:27 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Mon, 24 May 2021 11:08:56 +0000 (20:08 +0900)
Change-Id: I73dc4a0290facc54ee423584a5d4e998fbb8bb92

tests/vine-test/vine-pubsub-open-close-test.cpp [new file with mode: 0644]

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 (file)
index 0000000..a64a63c
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <unistd.h>
+#include <vine.h>
+#include <vine-log.h>
+
+#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;
+}