/* * Copyright © 2012 Intel Corporation * * 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. */ #define _GNU_SOURCE #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; assert(client->status == 0); if (client->terminate) wl_display_terminate(client->compositor->wl_display); } static int test_client_data(int fd, uint32_t mask, void *data) { struct test_client *client = data; struct wl_event_loop *loop; int len; len = read(client->fd, client->buf, sizeof client->buf); assert(len >= 0); fprintf(stderr, "got %.*s from client\n", len - 1, client->buf); assert(client->buf[len - 1] == '\n'); client->buf[len - 1] = '\0'; loop = wl_display_get_event_loop(client->compositor->wl_display); wl_event_loop_add_idle(loop, (void *) client->handle, client); return 1; } struct test_client * test_client_launch(struct weston_compositor *compositor) { struct test_client *client; struct wl_event_loop *loop; 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]; loop = wl_display_get_event_loop(compositor->wl_display); wl_event_loop_add_fd(loop, client->fd, WL_EVENT_READABLE, test_client_data, client); 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 run_test(void *data) { struct weston_compositor *compositor = data; const struct test *t; for (t = &__start_test_section; t < &__stop_test_section; t++) t->run(compositor); } int module_init(struct weston_compositor *compositor); WL_EXPORT int module_init(struct weston_compositor *compositor) { struct wl_event_loop *loop; loop = wl_display_get_event_loop(compositor->wl_display); wl_event_loop_add_idle(loop, run_test, compositor); return 0; }