summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ådahl <jadahl@gmail.com>2012-11-03 22:26:11 +0100
committerKristian Høgsberg <krh@bitplanet.net>2012-11-05 15:48:12 -0500
commit1801cdc41ac0653e4ff0f0cc4eeaf373ae40edf4 (patch)
treebc051239656e7a31249af49e3bc0ef1d2e4009a1
parente273c7cde34c23437d34732082d46aee537f6611 (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.am4
-rw-r--r--tests/queue-test.c171
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, &registry_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);
+}
+