diff options
author | Jonas Ådahl <jadahl@gmail.com> | 2012-11-03 22:26:11 +0100 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-11-05 15:48:12 -0500 |
commit | 1801cdc41ac0653e4ff0f0cc4eeaf373ae40edf4 (patch) | |
tree | bc051239656e7a31249af49e3bc0ef1d2e4009a1 | |
parent | e273c7cde34c23437d34732082d46aee537f6611 (diff) |
tests: Add queue test case
Check that after a callback removes a proxy that most likely will have
several events queued up with the same target proxy, no more callbacks
are invoked.
Signed-off-by: Jonas Ådahl <jadahl@gmail.com>
-rw-r--r-- | tests/Makefile.am | 4 | ||||
-rw-r--r-- | tests/queue-test.c | 171 |
2 files changed, 174 insertions, 1 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index bb92c4c..cf821c0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -8,7 +8,8 @@ TESTS = \ map-test \ os-wrappers-test \ sanity-test \ - socket-test + socket-test \ + queue-test check_PROGRAMS = \ $(TESTS) \ @@ -28,6 +29,7 @@ list_test_SOURCES = list-test.c $(test_runner_src) map_test_SOURCES = map-test.c $(test_runner_src) sanity_test_SOURCES = sanity-test.c $(test_runner_src) socket_test_SOURCES = socket-test.c $(test_runner_src) +queue_test_SOURCES = queue-test.c $(test_runner_src) fixed_benchmark_SOURCES = fixed-benchmark.c diff --git a/tests/queue-test.c b/tests/queue-test.c new file mode 100644 index 0000000..f66a25f --- /dev/null +++ b/tests/queue-test.c @@ -0,0 +1,171 @@ +/* + * Copyright © 2012 Jonas Ådahl + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <assert.h> + +#include "wayland-client.h" +#include "wayland-server.h" +#include "test-runner.h" + +#define SOCKET_NAME "wayland-queue-test" + +#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) + +#define client_assert(expr) \ + do { \ + if (!(expr)) { \ + fprintf(stderr, "%s:%d: " \ + "Assertion `%s' failed.\n", \ + __FILE__, __LINE__, #expr); \ + exit(EXIT_FAILURE); \ + } \ + } while (0) + +struct display { + struct wl_display *display; + int child_exit_status; +}; + +static int +sigchld_handler(int signal_number, void *data) +{ + struct display *display = data; + int status; + + waitpid(-1, &status, 0); + display->child_exit_status = WEXITSTATUS(status); + + wl_display_terminate(display->display); + + return 0; +} + +static void +registry_handle_global(void *data, struct wl_registry *registry, + uint32_t id, const char *interface, uint32_t version) +{ + int *pcounter = data; + (*pcounter)++; + client_assert(*pcounter == 1); + wl_registry_destroy(registry); +} + +static const struct wl_registry_listener registry_listener = { + registry_handle_global, + NULL +}; + +static void +client_alarm_handler(int sig) +{ + exit(EXIT_FAILURE); +} + +static void +client_continue_handler(int sig) +{ +} + +static int +client_main(void) +{ + struct wl_display *display; + struct wl_registry *registry; + int counter = 0; + + signal(SIGALRM, client_alarm_handler); + signal(SIGCONT, client_continue_handler); + alarm(20); + pause(); + + display = wl_display_connect(SOCKET_NAME); + client_assert(display); + + registry = wl_display_get_registry(display); + wl_registry_add_listener(registry, ®istry_listener, &counter); + wl_display_roundtrip(display); + + client_assert(counter == 1); + + wl_display_disconnect(display); + + return EXIT_SUCCESS; +} + +static void +dummy_bind(struct wl_client *client, + void *data, uint32_t version, uint32_t id) +{ +} + +TEST(queue_destroy_proxy) +{ + struct display display; + struct wl_event_loop *loop; + struct wl_event_source *signal_source; + const struct wl_interface *dummy_interfaces[] = { + &wl_seat_interface, + &wl_pointer_interface, + &wl_keyboard_interface, + &wl_surface_interface + }; + unsigned int i; + pid_t pid; + int ret; + + pid = fork(); + if (pid == -1) { + perror("fork"); + exit(EXIT_FAILURE); + } else if (pid == 0) { + exit(client_main()); + } + + display.child_exit_status = EXIT_FAILURE; + display.display = wl_display_create(); + assert(display.display); + + for (i = 0; i < ARRAY_LENGTH(dummy_interfaces); i++) + wl_display_add_global(display.display, dummy_interfaces[i], + NULL, dummy_bind); + + ret = wl_display_add_socket(display.display, SOCKET_NAME); + assert(ret == 0); + + loop = wl_display_get_event_loop(display.display); + signal_source = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler, + &display); + + kill(pid, SIGCONT); + wl_display_run(display.display); + + wl_event_source_remove(signal_source); + wl_display_destroy(display.display); + + assert(display.child_exit_status == EXIT_SUCCESS); +} + |