Przeglądaj źródła

tests: Enhance pr-poll-loop test

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Jan Friesse 5 lat temu
rodzic
commit
e7ef364191
1 zmienionych plików z 367 dodań i 0 usunięć
  1. 367 0
      qdevices/test-pr-poll-loop.c

+ 367 - 0
qdevices/test-pr-poll-loop.c

@@ -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);