diff --git a/tests/client-test.c b/tests/client-test.c index 36947aa4..623163e2 100644 --- a/tests/client-test.c +++ b/tests/client-test.c @@ -21,45 +21,22 @@ */ #include +#include #include #include +#include #include "test-runner.h" + struct context { - struct weston_process proc; struct weston_compositor *compositor; - struct wl_listener client_destroy_listener; + struct test_client *client; struct wl_listener compositor_destroy_listener; int status; - int got_client_destroy; int done; }; -static void -cleanup(struct weston_process *proc, int status) -{ - struct context *context = container_of(proc, struct context, proc); - - fprintf(stderr, "child exited, status %d\n", status); - - wl_display_terminate(context->compositor->wl_display); - context->status = status; - context->done = 1; -} - -static void -client_destroy(struct wl_listener *listener, void *data) -{ - struct context *context = - container_of(listener, struct context, - client_destroy_listener); - - context->got_client_destroy = 1; - - fprintf(stderr, "notify child destroy\n"); -} - static void compositor_destroy(struct wl_listener *listener, void *data) { @@ -68,34 +45,27 @@ compositor_destroy(struct wl_listener *listener, void *data) compositor_destroy_listener); fprintf(stderr, "notify compositor destroy, status %d, done %d\n", - context->status, context->done); + context->client->status, context->client->done); - assert(context->status == 0); - assert(context->got_client_destroy); - assert(context->done); + assert(context->client->status == 0); + assert(context->client->done); } + TEST(client_test) { struct context *context; - char path[256]; - struct wl_client *client; - - snprintf(path, sizeof path, "%s/test-client", getenv("abs_builddir")); - fprintf(stderr, "launching %s\n", path); context = malloc(sizeof *context); assert(context); context->compositor = compositor; context->done = 0; - context->got_client_destroy = 0; - client = weston_client_launch(compositor, - &context->proc, path, cleanup); - context->client_destroy_listener.notify = client_destroy; - wl_client_add_destroy_listener(client, - &context->client_destroy_listener); + context->client = test_client_launch(compositor); + context->client->terminate = 1; context->compositor_destroy_listener.notify = compositor_destroy; wl_signal_add(&compositor->destroy_signal, &context->compositor_destroy_listener); + + test_client_send(context->client, "bye\n"); } diff --git a/tests/test-client.c b/tests/test-client.c index ea8885af..3425a7d7 100644 --- a/tests/test-client.c +++ b/tests/test-client.c @@ -21,6 +21,9 @@ */ #include +#include +#include +#include #include #include @@ -33,6 +36,8 @@ handle_global(struct wl_display *display, uint32_t id, int main(int argc, char *argv[]) { struct wl_display *display; + char buf[256], *p; + int ret, fd; display = wl_display_connect(NULL); assert(display); @@ -41,5 +46,27 @@ int main(int argc, char *argv[]) wl_display_iterate(display, WL_DISPLAY_READABLE); wl_display_roundtrip(display); - return 0; + fd = 0; + p = getenv("TEST_SOCKET"); + if (p) + fd = strtol(p, NULL, 0); + + while (1) { + ret = read(fd, buf, sizeof buf); + if (ret == -1) { + fprintf(stderr, "read error: fd %d, %m\n", fd); + return -1; + } + + fprintf(stderr, "test-client: got %.*s\n", ret - 1, buf, ret); + + if (strncmp(buf, "bye\n", ret) == 0) { + return 0; + } else { + fprintf(stderr, "unknown command %.*s\n", ret, buf); + return -1; + } + } + + assert(0); } diff --git a/tests/test-runner.c b/tests/test-runner.c index fd85a6ce..9d1544ab 100644 --- a/tests/test-runner.c +++ b/tests/test-runner.c @@ -25,13 +25,75 @@ #include #include #include +#include #include #include #include #include +#include #include "test-runner.h" +static void +test_client_cleanup(struct weston_process *proc, int status) +{ + struct test_client *client = + container_of(proc, struct test_client, proc); + + fprintf(stderr, "test client exited, status %d\n", status); + + client->status = status; + client->done = 1; + + if (client->terminate) + wl_display_terminate(client->compositor->wl_display); +} + +struct test_client * +test_client_launch(struct weston_compositor *compositor) +{ + struct test_client *client; + int ret, sv[2], client_fd; + char buf[256]; + + client = malloc(sizeof *client); + assert(client); + ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv); + assert(ret == 0); + + client_fd = dup(sv[0]); + assert(client_fd >= 0); + snprintf(buf, sizeof buf, "%d", client_fd); + setenv("TEST_SOCKET", buf, 1); + snprintf(buf, sizeof buf, "%s/test-client", getenv("abs_builddir")); + fprintf(stderr, "launching %s\n", buf); + + client->terminate = 0; + client->compositor = compositor; + client->client = weston_client_launch(compositor, + &client->proc, buf, + test_client_cleanup); + assert(client->client); + close(sv[0]); + client->fd = sv[1]; + + return client; +} + +void +test_client_send(struct test_client *client, const char *fmt, ...) +{ + char buf[256]; + va_list ap; + int len; + + va_start(ap, fmt); + len = vsnprintf(buf, sizeof buf, fmt, ap); + va_end(ap); + + assert(write(client->fd, buf, len) == len); +} + extern const struct test __start_test_section, __stop_test_section; static void diff --git a/tests/test-runner.h b/tests/test-runner.h index 33df58f5..97e5529e 100644 --- a/tests/test-runner.h +++ b/tests/test-runner.h @@ -22,4 +22,17 @@ struct test { \ static void name(struct weston_compositor *compositor) +struct test_client { + struct weston_compositor *compositor; + struct wl_client *client; + struct weston_process proc; + int fd; + int done; + int status; + int terminate; +}; + +struct test_client *test_client_launch(struct weston_compositor *compositor); +void test_client_send(struct test_client *client, const char *fmt, ...); + #endif