[PATCH 3/3] tests: test posting errors

Marek Chalupa mchqwerty at gmail.com
Mon May 26 08:04:23 PDT 2014


Test posting errors to one and more clients.
---
 tests/display-test.c | 246 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 246 insertions(+)

diff --git a/tests/display-test.c b/tests/display-test.c
index 844a649..e212942 100644
--- a/tests/display-test.c
+++ b/tests/display-test.c
@@ -34,7 +34,9 @@
 
 #include "wayland-private.h"
 #include "wayland-server.h"
+#include "wayland-client.h"
 #include "test-runner.h"
+#include "test-compositor.h"
 
 struct display_destroy_listener {
 	struct wl_listener listener;
@@ -77,3 +79,247 @@ TEST(display_destroy_listener)
 	assert(b.done);
 }
 
+static void
+registry_handle_globals(void *data, struct wl_registry *registry,
+			uint32_t id, const char *intf, uint32_t ver)
+{
+	struct wl_seat **seat = data;
+
+	if (strcmp(intf, "wl_seat") == 0) {
+		*seat = wl_registry_bind(registry, id,
+					 &wl_seat_interface, ver);
+		assert(*seat);
+	}
+}
+
+static const struct wl_registry_listener registry_listener = {
+	registry_handle_globals,
+	NULL
+};
+
+static struct wl_seat *
+client_get_seat(struct client *c)
+{
+	struct wl_seat *seat;
+	struct wl_registry *reg = wl_display_get_registry(c->wl_display);
+	assert(reg);
+
+	wl_registry_add_listener(reg, &registry_listener, &seat);
+	wl_display_roundtrip(c->wl_display);
+	assert(seat);
+
+	wl_registry_destroy(reg);
+
+	return seat;
+}
+
+static void
+check_for_error(struct client *c, struct wl_proxy *proxy)
+{
+	uint32_t ec, id;
+	int err;
+	const struct wl_interface *intf;
+
+	/* client should be disconnected */
+	assert(wl_display_roundtrip(c->wl_display) == -1);
+
+	err = wl_display_get_error(c->wl_display);
+	assert(err == EPROTO);
+
+	ec = wl_display_get_protocol_error(c->wl_display, &intf, &id);
+	assert(ec == 23);
+	assert(intf == &wl_seat_interface);
+	assert(id == wl_proxy_get_id(proxy));
+}
+
+static void
+bind_seat(struct wl_client *client, void *data,
+	  uint32_t vers, uint32_t id)
+{
+	struct display *d = data;
+	struct client_info *ci;
+	struct wl_resource *res;
+
+	/* find the right client_info struct and save the
+	 * resource as its data, so that we can use it later */
+	wl_list_for_each(ci, &d->clients, link) {
+		if (ci->wl_client == client)
+			break;
+	}
+
+	res = wl_resource_create(client, &wl_seat_interface, vers, id);
+	assert(res);
+
+	ci->data = res;
+}
+
+static void
+post_error_main(void)
+{
+	struct client *c = client_connect();
+	struct wl_seat *seat = client_get_seat(c);
+
+	/* stop display so that it can post the error.
+	 * The function should return -1, because of the posted error */
+	assert(stop_display(c, 1) == -1);
+
+	/* display should have posted error, check it! */
+	check_for_error(c, (struct wl_proxy *) seat);
+
+	/* don't call client_disconnect(c), because then the test would be
+	 * aborted due to checks for error in this function */
+	wl_proxy_destroy((struct wl_proxy *) seat);
+	wl_proxy_destroy((struct wl_proxy *) c->tc);
+	wl_display_disconnect(c->wl_display);
+}
+
+TEST(post_error_to_one_client)
+{
+	struct display *d = display_create();
+	struct client_info *cl;
+
+	wl_global_create(d->wl_display, &wl_seat_interface,
+			 1, d, bind_seat);
+
+	cl = client_create(d, post_error_main);
+	display_run(d);
+
+	/* the display was stopped by client, so it can
+	 * proceed in the code and post an error */
+	assert(cl->data);
+	wl_resource_post_error((struct wl_resource *) cl->data,
+			       23, "Dummy error");
+
+	/* this one should be ignored */
+	wl_resource_post_error((struct wl_resource *) cl->data,
+			       21, "Dummy error (ignore)");
+
+	display_resume(d);
+	display_destroy(d);
+}
+
+static void
+post_error_main2(void)
+{
+	struct client *c = client_connect();
+	struct wl_seat *seat = client_get_seat(c);
+
+	/* the error should not be posted for this client */
+	assert(stop_display(c, 2) >= 0);
+
+	wl_proxy_destroy((struct wl_proxy *) seat);
+	client_disconnect(c);
+}
+
+static void
+post_error_main3(void)
+{
+	struct client *c = client_connect();
+	struct wl_seat *seat = client_get_seat(c);
+
+	assert(stop_display(c, 2) == -1);
+	check_for_error(c, (struct wl_proxy *) seat);
+
+	/* don't call client_disconnect(c), because then the test would be
+	 * aborted due to checks for error in this function */
+	wl_proxy_destroy((struct wl_proxy *) seat);
+	wl_proxy_destroy((struct wl_proxy *) c->tc);
+	wl_display_disconnect(c->wl_display);
+}
+
+/* all the testcases could be in one TEST, but splitting it
+ * apart is better for debugging when the test fails */
+TEST(post_error_to_one_from_two_clients)
+{
+	struct display *d = display_create();
+	struct client_info *cl;
+
+	wl_global_create(d->wl_display, &wl_seat_interface,
+			 1, d, bind_seat);
+
+	client_create(d, post_error_main2);
+	cl = client_create(d, post_error_main3);
+	display_run(d);
+
+	/* post error only to the second client */
+	assert(cl->data);
+	wl_resource_post_error((struct wl_resource *) cl->data,
+			       23, "Dummy error");
+	wl_resource_post_error((struct wl_resource *) cl->data,
+			       21, "Dummy error (ignore)");
+
+	display_resume(d);
+	display_destroy(d);
+}
+
+/* all the testcases could be in one TEST, but splitting it
+ * apart is better for debugging when the test fails */
+TEST(post_error_to_two_clients)
+{
+	struct display *d = display_create();
+	struct client_info *cl, *cl2;
+
+	wl_global_create(d->wl_display, &wl_seat_interface,
+			 1, d, bind_seat);
+
+	cl = client_create(d, post_error_main3);
+	cl2 = client_create(d, post_error_main3);
+
+	display_run(d);
+
+	/* Try to send the error to both clients */
+	assert(cl->data && cl2->data);
+	wl_resource_post_error((struct wl_resource *) cl->data,
+			       23, "Dummy error");
+	wl_resource_post_error((struct wl_resource *) cl->data,
+			       21, "Dummy error (ignore)");
+
+	wl_resource_post_error((struct wl_resource *) cl2->data,
+			       23, "Dummy error");
+	wl_resource_post_error((struct wl_resource *) cl2->data,
+			       21, "Dummy error (ignore)");
+
+	display_resume(d);
+	display_destroy(d);
+}
+
+static void
+post_nomem_main(void)
+{
+	struct client *c = client_connect();
+	struct wl_seat *seat = client_get_seat(c);
+
+	assert(stop_display(c, 1) == -1);
+	assert(wl_display_get_error(c->wl_display) == ENOMEM);
+
+	wl_proxy_destroy((struct wl_proxy *) seat);
+	wl_proxy_destroy((struct wl_proxy *) c->tc);
+	wl_display_disconnect(c->wl_display);
+}
+
+TEST(post_nomem_tst)
+{
+	struct display *d = display_create();
+	struct client_info *cl;
+
+	wl_global_create(d->wl_display, &wl_seat_interface,
+			 1, d, bind_seat);
+
+	cl = client_create(d, post_nomem_main);
+	display_run(d);
+
+	assert(cl->data);
+	wl_resource_post_no_memory((struct wl_resource *) cl->data);
+	display_resume(d);
+
+	/* first client terminated. Run it again,
+	 * but post no memory to client */
+	cl = client_create(d, post_nomem_main);
+	display_run(d);
+
+	assert(cl->data);
+	wl_client_post_no_memory(cl->wl_client);
+	display_resume(d);
+
+	display_destroy(d);
+}
-- 
1.9.1



More information about the wayland-devel mailing list