[PATCH weston 6/9] tests: Allow weston-tests-env to process different test types

Kristian Høgsberg hoegsberg at gmail.com
Thu Dec 6 18:55:55 PST 2012


On Tue, Dec 04, 2012 at 02:22:12PM -0800, U. Artie Eoff wrote:
> From: "U. Artie Eoff" <ullysses.a.eoff at intel.com>
> 
> The weston-tests-env script needs to be able to handle weston
> test extension style tests as well as module style tests.

This series look good, but I don't like the python dependency or the
"give weston a moment to start" workaround here.

How about we just make the weston test module launch its test client?
Something like this:

diff --git a/tests/weston-test.c b/tests/weston-test.c
index 066650d..c957643 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -23,12 +23,15 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include <signal.h>
+#include <unistd.h>
 #include "../src/compositor.h"
 #include "wayland-test-server-protocol.h"
 
 struct weston_test {
 	struct weston_compositor *compositor;
 	struct weston_layer layer;
+	struct weston_process process;
 };
 
 struct weston_test_surface {
@@ -182,10 +185,45 @@ bind_test(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 	notify_pointer_position(test, resource);
 }
 
+static void
+test_client_sigchld(struct weston_process *process, int status)
+{
+	struct weston_test *test =
+		container_of(process, struct weston_test, process);
+}
+
+static void
+idle_launch_client(void *data)
+{
+	struct weston_test *test = data;
+	pid_t pid;
+	sigset_t allsigs;
+	char *path;
+
+	path = getenv("TEST_CLIENT_PATH");
+	if (path == NULL)
+		exit(EXIT_FAILURE);
+	pid = fork();
+	if (pid == -1)
+		exit(EXIT_FAILURE);
+	if (pid == 0) {
+		sigfillset(&allsigs);
+		sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
+		execl(path, path, NULL);
+		weston_log("compositor: executing '%s' failed: %m\n", path);
+		exit(EXIT_FAILURE);
+	}
+
+	test->process.pid = pid;
+	test->process.cleanup = test_client_sigchld;
+	weston_watch_process(&test->process);
+}
+
 WL_EXPORT int
 module_init(struct weston_compositor *ec)
 {
 	struct weston_test *test;
+	struct wl_event_loop *loop;
 
 	test = malloc(sizeof *test);
 	if (test == NULL)
@@ -198,5 +236,9 @@ module_init(struct weston_compositor *ec)
 	if (wl_display_add_global(ec->wl_display, &wl_test_interface,
 				  test, bind_test) == NULL)
 		return -1;
+
+	loop = wl_display_get_event_loop(ec->wl_display);
+	wl_event_loop_add_idle(loop, idle_launch_client, test);
+
 	return 0;
 }
diff --git a/tests/weston-tests-env b/tests/weston-tests-env
index 27b40de..a5099f2 100644
--- a/tests/weston-tests-env
+++ b/tests/weston-tests-env
@@ -1,4 +1,9 @@
 #!/bin/sh
 
-../src/weston --modules=$abs_builddir/.libs/${1/.la/.so}
-
+case $1_dir in
+	*.la|*.so)
+		../src/weston --modules=$abs_builddir/.libs/${1/.la/.so}
+		;;
+	*)
+		TEST_CLIENT_PATH=$1 ../src/weston --modules=$abs_builddir/.libs/weston-test.so
+esac


> Signed-off-by: U. Artie Eoff <ullysses.a.eoff at intel.com>
> ---
>  tests/Makefile.am      |   2 +-
>  tests/weston-tests-env | 123 ++++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 122 insertions(+), 3 deletions(-)
>  mode change 100644 => 100755 tests/weston-tests-env
> 
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index ad27f7e..3cceef2 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -3,7 +3,7 @@ TESTS = surface-test.la client-test.la	\
>  	surface-global-test.la		\
>  	button-test.la keyboard-test.la
>  
> -TESTS_ENVIRONMENT = $(SHELL) $(top_srcdir)/tests/weston-tests-env
> +TESTS_ENVIRONMENT = $(PYTHON) $(top_srcdir)/tests/weston-tests-env
>  
>  export abs_builddir
>  
> diff --git a/tests/weston-tests-env b/tests/weston-tests-env
> old mode 100644
> new mode 100755
> index 27b40de..9de90ca
> --- a/tests/weston-tests-env
> +++ b/tests/weston-tests-env
> @@ -1,4 +1,123 @@
> -#!/bin/sh
> +#!/usr/bin/env python
> +#
> +#* Copyright (c) 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.
> +#
> +# Python Version 2.6 or later is required
>  
> -../src/weston --modules=$abs_builddir/.libs/${1/.la/.so}
> +import os, sys, time
> +import subprocess, signal
> +from threading import RLock, Thread
>  
> +def synchronized_write(message):
> +### Make writing to sys.stderr threadsafe
> +	synchronized_write.lock.acquire()
> +	try:
> +		sys.stderr.write(message)
> +		sys.stderr.flush()
> +	finally:
> +		synchronized_write.lock.release()
> +synchronized_write.lock = RLock()
> +
> +def endproc(proc):
> +	proc.terminate()
> +
> +	result = proc.poll()
> +	if result is None:
> +		time.sleep(1) # Give proc more time to terminate.
> +	else:
> +		return
> +
> +	result = proc.poll()
> +	if result is None:
> +		proc.kill() # Sorry proc, you're taking too long! Bye!
> +	else:
> +		return
> +
> +	result = proc.poll()
> +	if result is None:
> +		time.sleep(1) # Give system a moment to finalize kill
> +
> +def readproc(proc):
> +### Does not return until EOF is reached in proc.stdout
> +	line = proc.stdout.readline()
> +	while line:
> +		synchronized_write(line)
> +		line = proc.stdout.readline()
> +
> +def startproc(command):
> +	proc = subprocess.Popen(
> +		command,
> +		stdout	= subprocess.PIPE,
> +		stderr	= subprocess.STDOUT,
> +		bufsize	= 1,
> +		shell	= True,
> +		env	= os.environ,
> +	)
> +	return proc
> +
> +def run_module_test(basepath, name):
> +	command = "%s/../src/weston --modules=%s/.libs/%s.so" \
> +		% (basepath, basepath, name)
> +	test = startproc(command)
> +	Thread(target = lambda: readproc(test)).start()
> +	test.wait()
> +	if test.returncode != 0:
> +		r = "fail"
> +	else:
> +		r = "pass"
> +
> +	synchronized_write('test "%s":\texit status %d, %s.\n' \
> +		% (os.path.basename(name), abs(test.returncode), r))
> +
> +	return test.returncode
> +
> +def run_weston_test(basepath, name):
> +	command = "%s/../src/weston --modules=%s/.libs/weston-test.so" \
> +		% (basepath, basepath)
> +	weston = startproc(command)
> +	Thread(target = lambda: readproc(weston)).start()
> +	time.sleep(1) # give weston a moment to start
> +
> +	command = "%s/%s" % (basepath, name)
> +	test = startproc(command)
> +	Thread(target = lambda: readproc(test)).start()
> +	test.wait()
> +
> +	endproc(weston)
> +
> +	if weston.returncode not in [0, signal.SIGTERM,]:
> +		return weston.returncode or -128
> +	return test.returncode
> +
> +def main():
> +	assert len(sys.argv) == 2
> +	assert "abs_builddir" in os.environ.keys()
> +
> +	abs_builddir = os.environ["abs_builddir"]
> +	name, ext = os.path.splitext(sys.argv[1])
> +
> +	if ext in ['.la', '.so',]:
> +		return run_module_test(abs_builddir, name)
> +
> +	return run_weston_test(abs_builddir, name)
> +
> +if "__main__" == __name__:
> +	sys.exit(main())
> -- 
> 1.7.11.7
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list