]> git.proxmox.com Git - mirror_corosync-qdevice.git/commitdiff
tests: Enhance pr-poll-loop test
authorJan Friesse <jfriesse@redhat.com>
Wed, 19 Aug 2020 12:30:08 +0000 (14:30 +0200)
committerJan Friesse <jfriesse@redhat.com>
Wed, 19 Aug 2020 12:33:01 +0000 (14:33 +0200)
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
qdevices/test-pr-poll-loop.c

index ebf63579df7c5be397c7cad9cdbac05d2da12e68..87c1f83ab36269dd08997fd84307a879e252ee74 100644 (file)
@@ -69,6 +69,17 @@ static int prfd_read_cb2_called = 0;
 static int prfd_write_cb1_called = 0;
 static int prfd_err_cb1_called = 0;
 
+static int test_complex_state = 0;
+static int test_complex_set_events_pipe1_read_called = 0;
+static int test_complex_read_pipe1_read_called = 0;
+static int test_complex_set_events_pipe1_write_called = 0;
+static int test_complex_write_pipe1_write_called = 0;
+static int test_complex_set_events_pipe2_read_called = 0;
+static int test_complex_read_pipe2_read_called = 0;
+static int test_complex_set_events_pipe2_write_called = 0;
+static int test_complex_write_pipe2_write_called = 0;
+static int test_complex_read_pipe1_fd = 0;
+
 static int
 timeout_cb(void *data1, void *data2)
 {
@@ -238,6 +249,159 @@ prfd_err_cb1(PRFileDesc *prfd, short revents, void *user_data1, void *user_data2
        return (0);
 }
 
+static int
+test_complex_set_events_pipe1_read_cb(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2)
+{
+
+       test_complex_set_events_pipe1_read_called++;
+
+       assert(user_data1 == &test_complex_set_events_pipe1_read_called);
+       assert(user_data2 == test_complex_set_events_pipe1_read_cb);
+       assert(*events == 0);
+
+       if (test_complex_state == 2) {
+               *events = POLLIN;
+       }
+
+       return (0);
+}
+
+static int
+test_complex_read_pipe1_read_cb(PRFileDesc *prfd, void *user_data1, void *user_data2)
+{
+       char buf[BUF_SIZE];
+
+       assert(user_data1 == &test_complex_set_events_pipe1_read_called);
+       assert(user_data2 == test_complex_set_events_pipe1_read_cb);
+
+       test_complex_read_pipe1_read_called++;
+
+       /*
+        * prfd for this case is just a wrapper, we need to use real fd
+        */
+       assert(read(test_complex_read_pipe1_fd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
+       assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
+
+       return (0);
+}
+
+static int
+test_complex_write_pipe1_read_cb(PRFileDesc *prfd, void *user_data1, void *user_data2)
+{
+
+       assert(0);
+
+       return (-1);
+}
+
+static int
+test_complex_set_events_pipe1_write_cb(int fd, short *events, void *user_data1, void *user_data2)
+{
+
+       test_complex_set_events_pipe1_write_called++;
+
+       assert(user_data1 == &test_complex_set_events_pipe1_write_called);
+       assert(user_data2 == test_complex_set_events_pipe1_write_cb);
+       assert(*events == 0);
+
+       if (test_complex_state == 1) {
+               *events = POLLOUT;
+       }
+
+       return (0);
+}
+
+static int
+test_complex_read_pipe1_write_cb(int fd, void *user_data1, void *user_data2)
+{
+
+       assert(0);
+
+       return (-1);
+}
+
+static int
+test_complex_write_pipe1_write_cb(int fd, void *user_data1, void *user_data2)
+{
+
+       assert(user_data1 == &test_complex_set_events_pipe1_write_called);
+       assert(user_data2 == test_complex_set_events_pipe1_write_cb);
+       test_complex_write_pipe1_write_called++;
+
+       return (0);
+}
+
+static int
+test_complex_set_events_pipe2_read_cb(int fd, short *events, void *user_data1, void *user_data2)
+{
+
+       test_complex_set_events_pipe2_read_called++;
+
+       assert(user_data1 == &test_complex_set_events_pipe2_read_called);
+       assert(user_data2 == test_complex_set_events_pipe2_read_cb);
+       assert(*events == POLLIN);
+
+       return (0);
+}
+
+static int
+test_complex_read_pipe2_read_cb(int fd, void *user_data1, void *user_data2)
+{
+       char buf[BUF_SIZE];
+
+       assert(user_data1 == &test_complex_set_events_pipe2_read_called);
+       assert(user_data2 == test_complex_set_events_pipe2_read_cb);
+
+       test_complex_read_pipe2_read_called++;
+
+       assert(read(fd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
+       assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
+
+       return (0);
+}
+
+static int
+test_complex_write_pipe2_read_cb(int fd, void *user_data1, void *user_data2)
+{
+
+       assert(0);
+
+       return (-1);
+}
+
+static int
+test_complex_set_events_pipe2_write_cb(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2)
+{
+
+       test_complex_set_events_pipe2_write_called++;
+
+       assert(user_data1 == &test_complex_set_events_pipe2_write_called);
+       assert(user_data2 == test_complex_set_events_pipe2_write_cb);
+       assert(*events == POLLOUT);
+
+       return (0);
+}
+
+static int
+test_complex_read_pipe2_write_cb(PRFileDesc *prfd, void *user_data1, void *user_data2)
+{
+
+       assert(0);
+
+       return (-1);
+}
+
+static int
+test_complex_write_pipe2_write_cb(PRFileDesc *prfd, void *user_data1, void *user_data2)
+{
+
+       assert(user_data1 == &test_complex_set_events_pipe2_write_called);
+       assert(user_data2 == test_complex_set_events_pipe2_write_cb);
+       test_complex_write_pipe2_write_called++;
+
+       return (0);
+}
+
 static void
 init_global_vars(void)
 {
@@ -634,6 +798,207 @@ test_prfd_basics(struct pr_poll_loop *poll_loop)
        assert(PR_DestroySocketPollFd(read_pipe) == PR_SUCCESS);
 }
 
+static void
+test_complex(struct pr_poll_loop *poll_loop)
+{
+       int pipe_fd1[2], pipe_fd2[2];
+       PRFileDesc *read_pipe1;
+       PRFileDesc *write_pipe2;
+       struct timer_list_entry *timeout_timer;
+
+       assert(pipe(pipe_fd1) == 0);
+       assert(pipe(pipe_fd2) == 0);
+
+       test_complex_read_pipe1_fd = pipe_fd1[0];
+
+       assert((read_pipe1 = PR_CreateSocketPollFd(pipe_fd1[0])) != NULL);
+       assert((write_pipe2 = PR_CreateSocketPollFd(pipe_fd2[1])) != NULL);
+
+       assert(pr_poll_loop_add_prfd(poll_loop, read_pipe1, 0, test_complex_set_events_pipe1_read_cb,
+           test_complex_read_pipe1_read_cb, test_complex_write_pipe1_read_cb, NULL,
+           &test_complex_set_events_pipe1_read_called, test_complex_set_events_pipe1_read_cb) == 0);
+
+       assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[1], 0, test_complex_set_events_pipe1_write_cb,
+           test_complex_read_pipe1_write_cb, test_complex_write_pipe1_write_cb, NULL,
+           &test_complex_set_events_pipe1_write_called, test_complex_set_events_pipe1_write_cb) == 0);
+
+       assert(pr_poll_loop_add_fd(poll_loop, pipe_fd2[0], POLLIN, test_complex_set_events_pipe2_read_cb,
+           test_complex_read_pipe2_read_cb, test_complex_write_pipe2_read_cb, NULL,
+           &test_complex_set_events_pipe2_read_called, test_complex_set_events_pipe2_read_cb) == 0);
+
+       assert(pr_poll_loop_add_prfd(poll_loop, write_pipe2, POLLOUT, test_complex_set_events_pipe2_write_cb,
+           test_complex_read_pipe2_write_cb, test_complex_write_pipe2_write_cb, NULL,
+           &test_complex_set_events_pipe2_write_called, test_complex_set_events_pipe2_write_cb) == 0);
+
+       /*
+        * Call for first time -> all set_events should be called and pipe2_write should be called
+        */
+       assert((timeout_timer = timer_list_add(
+           pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
+       assert(pr_poll_loop_exec(poll_loop) == 0);
+
+       assert(test_complex_set_events_pipe1_read_called == 1);
+       assert(test_complex_read_pipe1_read_called == 0);
+       assert(test_complex_set_events_pipe1_write_called == 1);
+       assert(test_complex_write_pipe1_write_called == 0);
+       assert(test_complex_set_events_pipe2_read_called == 1);
+       assert(test_complex_read_pipe2_read_called == 0);
+       assert(test_complex_set_events_pipe2_write_called == 1);
+       assert(test_complex_write_pipe2_write_called == 1);
+
+       assert(timeout_cb_called == 0);
+       timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
+
+       /*
+        * Call for second time -> same as first time
+        */
+       assert((timeout_timer = timer_list_add(
+           pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
+       assert(pr_poll_loop_exec(poll_loop) == 0);
+
+       assert(test_complex_set_events_pipe1_read_called == 2);
+       assert(test_complex_read_pipe1_read_called == 0);
+       assert(test_complex_set_events_pipe1_write_called == 2);
+       assert(test_complex_write_pipe1_write_called == 0);
+       assert(test_complex_set_events_pipe2_read_called == 2);
+       assert(test_complex_read_pipe2_read_called == 0);
+       assert(test_complex_set_events_pipe2_write_called == 2);
+       assert(test_complex_write_pipe2_write_called == 2);
+
+       assert(timeout_cb_called == 0);
+       timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
+
+       /*
+        * Change state to prepare for writing
+        */
+       test_complex_state = 1;
+       assert((timeout_timer = timer_list_add(
+           pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
+       assert(pr_poll_loop_exec(poll_loop) == 0);
+
+       assert(test_complex_set_events_pipe1_read_called == 3);
+       assert(test_complex_read_pipe1_read_called == 0);
+       assert(test_complex_set_events_pipe1_write_called == 3);
+       assert(test_complex_write_pipe1_write_called == 1);
+       assert(test_complex_set_events_pipe2_read_called == 3);
+       assert(test_complex_read_pipe2_read_called == 0);
+       assert(test_complex_set_events_pipe2_write_called == 3);
+       assert(test_complex_write_pipe2_write_called == 3);
+
+       assert(timeout_cb_called == 0);
+       timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
+
+       /*
+        * Write to first pipe
+        */
+       assert(write(pipe_fd1[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
+
+       assert((timeout_timer = timer_list_add(
+           pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
+       assert(pr_poll_loop_exec(poll_loop) == 0);
+
+       assert(test_complex_set_events_pipe1_read_called == 4);
+       assert(test_complex_read_pipe1_read_called == 0);
+       assert(test_complex_set_events_pipe1_write_called == 4);
+       assert(test_complex_write_pipe1_write_called == 2);
+       assert(test_complex_set_events_pipe2_read_called == 4);
+       assert(test_complex_read_pipe2_read_called == 0);
+       assert(test_complex_set_events_pipe2_write_called == 4);
+       assert(test_complex_write_pipe2_write_called == 4);
+
+       assert(timeout_cb_called == 0);
+       timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
+
+       /*
+        * Change state so write can propagate
+        */
+       test_complex_state = 2;
+       assert((timeout_timer = timer_list_add(
+           pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
+       assert(pr_poll_loop_exec(poll_loop) == 0);
+
+       assert(test_complex_set_events_pipe1_read_called == 5);
+       assert(test_complex_read_pipe1_read_called == 1);
+       assert(test_complex_set_events_pipe1_write_called == 5);
+       assert(test_complex_write_pipe1_write_called == 2);
+       assert(test_complex_set_events_pipe2_read_called == 5);
+       assert(test_complex_read_pipe2_read_called == 0);
+       assert(test_complex_set_events_pipe2_write_called == 5);
+       assert(test_complex_write_pipe2_write_called == 5);
+
+       assert(timeout_cb_called == 0);
+       timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
+
+       /*
+        * Change state so pipe1 events are not called any longer
+        */
+       test_complex_state = 4;
+       assert((timeout_timer = timer_list_add(
+           pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
+       assert(pr_poll_loop_exec(poll_loop) == 0);
+
+       assert(test_complex_set_events_pipe1_read_called == 6);
+       assert(test_complex_read_pipe1_read_called == 1);
+       assert(test_complex_set_events_pipe1_write_called == 6);
+       assert(test_complex_write_pipe1_write_called == 2);
+       assert(test_complex_set_events_pipe2_read_called == 6);
+       assert(test_complex_read_pipe2_read_called == 0);
+       assert(test_complex_set_events_pipe2_write_called == 6);
+       assert(test_complex_write_pipe2_write_called == 6);
+
+       assert(timeout_cb_called == 0);
+       timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
+
+       /*
+        * Write to second pipe
+        */
+       assert(write(pipe_fd2[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
+
+       assert((timeout_timer = timer_list_add(
+           pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
+       assert(pr_poll_loop_exec(poll_loop) == 0);
+
+       assert(test_complex_set_events_pipe1_read_called == 7);
+       assert(test_complex_read_pipe1_read_called == 1);
+       assert(test_complex_set_events_pipe1_write_called == 7);
+       assert(test_complex_write_pipe1_write_called == 2);
+       assert(test_complex_set_events_pipe2_read_called == 7);
+       assert(test_complex_read_pipe2_read_called == 1);
+       assert(test_complex_set_events_pipe2_write_called == 7);
+       assert(test_complex_write_pipe2_write_called == 7);
+
+       assert(timeout_cb_called == 0);
+       timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
+
+       /*
+        * And call again
+        */
+       assert((timeout_timer = timer_list_add(
+           pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
+       assert(pr_poll_loop_exec(poll_loop) == 0);
+
+       assert(test_complex_set_events_pipe1_read_called == 8);
+       assert(test_complex_read_pipe1_read_called == 1);
+       assert(test_complex_set_events_pipe1_write_called == 8);
+       assert(test_complex_write_pipe1_write_called == 2);
+       assert(test_complex_set_events_pipe2_read_called == 8);
+       assert(test_complex_read_pipe2_read_called == 1);
+       assert(test_complex_set_events_pipe2_write_called == 8);
+       assert(test_complex_write_pipe2_write_called == 8);
+
+       assert(timeout_cb_called == 0);
+       timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
+
+       assert(PR_DestroySocketPollFd(read_pipe1) == PR_SUCCESS);
+       assert(PR_DestroySocketPollFd(write_pipe2) == PR_SUCCESS);
+
+       assert(close(pipe_fd1[0]) == 0);
+       assert(close(pipe_fd1[1]) == 0);
+
+       assert(close(pipe_fd2[0]) == 0);
+       assert(close(pipe_fd2[1]) == 0);
+}
+
 int
 main(void)
 {
@@ -647,6 +1012,8 @@ main(void)
 
        test_prfd_basics(&poll_loop);
 
+       test_complex(&poll_loop);
+
        pr_poll_loop_destroy(&poll_loop);
 
        assert(PR_Cleanup() == PR_SUCCESS);