]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
tevent: add a simple wrapper test
authorRalph Boehme <slow@samba.org>
Sat, 16 Jun 2018 12:12:01 +0000 (14:12 +0200)
committerRalph Boehme <slow@samba.org>
Wed, 11 Jul 2018 21:04:21 +0000 (23:04 +0200)
This checks that for all supported event types the before and after
handlers are called.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
lib/tevent/testsuite.c

index dba8f5895f76d697bfe15fbd91aef5c3e860ee38..946dea53532ba769b8fda99de19dcfdf39d67ce9 100644 (file)
@@ -696,6 +696,358 @@ static bool test_event_fd2(struct torture_context *tctx,
        return true;
 }
 
+struct test_wrapper_state {
+       struct torture_context *tctx;
+       int num_events;
+       int num_wrap_handlers;
+};
+
+static bool test_wrapper_before_use(struct tevent_context *wrap_ev,
+                                   void *private_data,
+                                   struct tevent_context *main_ev,
+                                   const char *location)
+{
+       struct test_wrapper_state *state =
+               talloc_get_type_abort(private_data,
+               struct test_wrapper_state);
+
+       torture_comment(state->tctx, "%s\n", __func__);
+       state->num_wrap_handlers++;
+       return true;
+}
+
+static void test_wrapper_after_use(struct tevent_context *wrap_ev,
+                                  void *private_data,
+                                  struct tevent_context *main_ev,
+                                  const char *location)
+{
+       struct test_wrapper_state *state =
+               talloc_get_type_abort(private_data,
+               struct test_wrapper_state);
+
+       torture_comment(state->tctx, "%s\n", __func__);
+       state->num_wrap_handlers++;
+}
+
+static void test_wrapper_before_fd_handler(struct tevent_context *wrap_ev,
+                                          void *private_data,
+                                          struct tevent_context *main_ev,
+                                          struct tevent_fd *fde,
+                                          uint16_t flags,
+                                          const char *handler_name,
+                                          const char *location)
+{
+       struct test_wrapper_state *state =
+               talloc_get_type_abort(private_data,
+               struct test_wrapper_state);
+
+       torture_comment(state->tctx, "%s\n", __func__);
+       state->num_wrap_handlers++;
+}
+
+static void test_wrapper_after_fd_handler(struct tevent_context *wrap_ev,
+                                         void *private_data,
+                                         struct tevent_context *main_ev,
+                                         struct tevent_fd *fde,
+                                         uint16_t flags,
+                                         const char *handler_name,
+                                         const char *location)
+{
+       struct test_wrapper_state *state =
+               talloc_get_type_abort(private_data,
+               struct test_wrapper_state);
+
+       torture_comment(state->tctx, "%s\n", __func__);
+       state->num_wrap_handlers++;
+}
+
+static void test_wrapper_before_timer_handler(struct tevent_context *wrap_ev,
+                                             void *private_data,
+                                             struct tevent_context *main_ev,
+                                             struct tevent_timer *te,
+                                             struct timeval requested_time,
+                                             struct timeval trigger_time,
+                                             const char *handler_name,
+                                             const char *location)
+{
+       struct test_wrapper_state *state =
+               talloc_get_type_abort(private_data,
+               struct test_wrapper_state);
+
+       torture_comment(state->tctx, "%s\n", __func__);
+       state->num_wrap_handlers++;
+}
+
+static void test_wrapper_after_timer_handler(struct tevent_context *wrap_ev,
+                                            void *private_data,
+                                            struct tevent_context *main_ev,
+                                            struct tevent_timer *te,
+                                            struct timeval requested_time,
+                                            struct timeval trigger_time,
+                                            const char *handler_name,
+                                            const char *location)
+{
+       struct test_wrapper_state *state =
+               talloc_get_type_abort(private_data,
+               struct test_wrapper_state);
+
+       torture_comment(state->tctx, "%s\n", __func__);
+       state->num_wrap_handlers++;
+}
+
+static void test_wrapper_before_immediate_handler(struct tevent_context *wrap_ev,
+                                                 void *private_data,
+                                                 struct tevent_context *main_ev,
+                                                 struct tevent_immediate *im,
+                                                 const char *handler_name,
+                                                 const char *location)
+{
+       struct test_wrapper_state *state =
+               talloc_get_type_abort(private_data,
+               struct test_wrapper_state);
+
+       torture_comment(state->tctx, "%s\n", __func__);
+       state->num_wrap_handlers++;
+}
+
+static void test_wrapper_after_immediate_handler(struct tevent_context *wrap_ev,
+                                                void *private_data,
+                                                struct tevent_context *main_ev,
+                                                struct tevent_immediate *im,
+                                                const char *handler_name,
+                                                const char *location)
+{
+       struct test_wrapper_state *state =
+               talloc_get_type_abort(private_data,
+               struct test_wrapper_state);
+
+       torture_comment(state->tctx, "%s\n", __func__);
+       state->num_wrap_handlers++;
+}
+
+static void test_wrapper_before_signal_handler(struct tevent_context *wrap_ev,
+                                              void *private_data,
+                                              struct tevent_context *main_ev,
+                                              struct tevent_signal *se,
+                                              int signum,
+                                              int count,
+                                              void *siginfo,
+                                              const char *handler_name,
+                                              const char *location)
+{
+       struct test_wrapper_state *state =
+               talloc_get_type_abort(private_data,
+               struct test_wrapper_state);
+
+       torture_comment(state->tctx, "%s\n", __func__);
+       state->num_wrap_handlers++;
+}
+
+static void test_wrapper_after_signal_handler(struct tevent_context *wrap_ev,
+                                             void *private_data,
+                                             struct tevent_context *main_ev,
+                                             struct tevent_signal *se,
+                                             int signum,
+                                             int count,
+                                             void *siginfo,
+                                             const char *handler_name,
+                                             const char *location)
+{
+       struct test_wrapper_state *state =
+               talloc_get_type_abort(private_data,
+               struct test_wrapper_state);
+
+       torture_comment(state->tctx, "%s\n", __func__);
+       state->num_wrap_handlers++;
+}
+
+static const struct tevent_wrapper_ops test_wrapper_ops = {
+       .name                           = "test_wrapper",
+       .before_use                     = test_wrapper_before_use,
+       .after_use                      = test_wrapper_after_use,
+       .before_fd_handler              = test_wrapper_before_fd_handler,
+       .after_fd_handler               = test_wrapper_after_fd_handler,
+       .before_timer_handler           = test_wrapper_before_timer_handler,
+       .after_timer_handler            = test_wrapper_after_timer_handler,
+       .before_immediate_handler       = test_wrapper_before_immediate_handler,
+       .after_immediate_handler        = test_wrapper_after_immediate_handler,
+       .before_signal_handler          = test_wrapper_before_signal_handler,
+       .after_signal_handler           = test_wrapper_after_signal_handler,
+};
+
+static void test_wrapper_timer_handler(struct tevent_context *ev,
+                                      struct tevent_timer *te,
+                                      struct timeval tv,
+                                      void *private_data)
+{
+       struct test_wrapper_state *state =
+               (struct test_wrapper_state *)private_data;
+
+
+       torture_comment(state->tctx, "timer handler\n");
+
+       state->num_events++;
+       talloc_free(te);
+       return;
+}
+
+static void test_wrapper_fd_handler(struct tevent_context *ev,
+                                   struct tevent_fd *fde,
+                                   unsigned short fd_flags,
+                                   void *private_data)
+{
+       struct test_wrapper_state *state =
+               (struct test_wrapper_state *)private_data;
+
+       torture_comment(state->tctx, "fd handler\n");
+
+       state->num_events++;
+       talloc_free(fde);
+       return;
+}
+
+static void test_wrapper_immediate_handler(struct tevent_context *ev,
+                                          struct tevent_immediate *im,
+                                          void *private_data)
+{
+       struct test_wrapper_state *state =
+               (struct test_wrapper_state *)private_data;
+
+       state->num_events++;
+       talloc_free(im);
+
+       torture_comment(state->tctx, "immediate handler\n");
+       return;
+}
+
+static void test_wrapper_signal_handler(struct tevent_context *ev,
+                                       struct tevent_signal *se,
+                                       int signum,
+                                       int count,
+                                       void *siginfo,
+                                       void *private_data)
+{
+       struct test_wrapper_state *state =
+               (struct test_wrapper_state *)private_data;
+
+       torture_comment(state->tctx, "signal handler\n");
+
+       state->num_events++;
+       talloc_free(se);
+       return;
+}
+
+static bool test_wrapper(struct torture_context *tctx,
+                        const void *test_data)
+{
+       struct test_wrapper_state *state = NULL;
+       int sock[2] = { -1, -1};
+       uint8_t c = 0;
+       const int num_events = 4;
+       const char *backend = (const char *)test_data;
+       struct tevent_context *ev = NULL;
+       struct tevent_context *wrap_ev = NULL;
+       struct tevent_fd *fde = NULL;
+       struct tevent_timer *te = NULL;
+       struct tevent_signal *se = NULL;
+       struct tevent_immediate *im = NULL;
+       int ret;
+       bool ok = false;
+       bool ret2;
+
+       ev = tevent_context_init_byname(tctx, backend);
+       if (ev == NULL) {
+               torture_skip(tctx, talloc_asprintf(tctx,
+                            "event backend '%s' not supported\n",
+                            backend));
+               return true;
+       }
+
+       tevent_set_debug_stderr(ev);
+       torture_comment(tctx, "tevent backend '%s'\n", backend);
+
+       wrap_ev = tevent_context_wrapper_create(
+               ev, ev, &test_wrapper_ops, &state, struct test_wrapper_state);
+       torture_assert_not_null_goto(tctx, wrap_ev, ok, done,
+                                    "tevent_context_wrapper_create failed\n");
+       *state = (struct test_wrapper_state) {
+               .tctx = tctx,
+       };
+
+       ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+       torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n");
+
+       te = tevent_add_timer(wrap_ev, wrap_ev,
+                             timeval_current_ofs(0, 0),
+                             test_wrapper_timer_handler, state);
+       torture_assert_not_null_goto(tctx, te, ok, done,
+                                    "tevent_add_timer failed\n");
+
+       fde = tevent_add_fd(wrap_ev, wrap_ev,
+                           sock[1],
+                           TEVENT_FD_READ,
+                           test_wrapper_fd_handler,
+                           state);
+       torture_assert_not_null_goto(tctx, fde, ok, done,
+                                    "tevent_add_fd failed\n");
+
+       im = tevent_create_immediate(wrap_ev);
+       torture_assert_not_null_goto(tctx, im, ok, done,
+                                    "tevent_create_immediate failed\n");
+
+       se = tevent_add_signal(wrap_ev, wrap_ev,
+                              SIGUSR1,
+                              0,
+                              test_wrapper_signal_handler,
+                              state);
+       torture_assert_not_null_goto(tctx, se, ok, done,
+                                    "tevent_add_signal failed\n");
+
+       do_write(sock[0], &c, 1);
+       kill(getpid(), SIGUSR1);
+       tevent_schedule_immediate(im,
+                                 wrap_ev,
+                                 test_wrapper_immediate_handler,
+                                 state);
+
+       ret2 = tevent_context_push_use(wrap_ev);
+       torture_assert_goto(tctx, ret2, ok, done, "tevent_context_push_use(wrap_ev) failed\n");
+       ret2 = tevent_context_push_use(ev);
+       torture_assert_goto(tctx, ret2, ok, pop_use, "tevent_context_push_use(ev) failed\n");
+       tevent_context_pop_use(ev);
+       tevent_context_pop_use(wrap_ev);
+
+       ret = tevent_loop_wait(ev);
+       torture_assert_int_equal_goto(tctx, ret, 0, ok, done, "tevent_loop_wait failed\n");
+
+       torture_comment(tctx, "Num events: %d\n", state->num_events);
+       torture_comment(tctx, "Num wrap handlers: %d\n",
+                       state->num_wrap_handlers);
+
+       torture_assert_int_equal_goto(tctx, state->num_events, num_events, ok, done,
+                                     "Wrong event count\n");
+       torture_assert_int_equal_goto(tctx, state->num_wrap_handlers,
+                                     num_events*2+2,
+                                     ok, done, "Wrong wrapper count\n");
+
+       ok = true;
+
+done:
+       TALLOC_FREE(wrap_ev);
+       TALLOC_FREE(ev);
+
+       if (sock[0] != -1) {
+               close(sock[0]);
+       }
+       if (sock[1] != -1) {
+               close(sock[1]);
+       }
+       return ok;
+pop_use:
+       tevent_context_pop_use(wrap_ev);
+       goto done;
+}
+
 #ifdef HAVE_PTHREAD
 
 static pthread_mutex_t threaded_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1280,6 +1632,10 @@ struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
                                               "fd2",
                                               test_event_fd2,
                                               (const void *)list[i]);
+               torture_suite_add_simple_tcase_const(backend_suite,
+                                              "wrapper",
+                                              test_wrapper,
+                                              (const void *)list[i]);
 
                torture_suite_add_suite(suite, backend_suite);
        }