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

Eoff, Ullysses A ullysses.a.eoff at intel.com
Fri Dec 7 06:49:06 PST 2012


>-----Original Message-----
>From: Kristian Høgsberg [mailto:hoegsberg at gmail.com]
>Sent: Thursday, December 06, 2012 6:56 PM
>To: Eoff, Ullysses A
>Cc: wayland-devel at lists.freedesktop.org
>Subject: Re: [PATCH weston 6/9] tests: Allow weston-tests-env to process
>different test types
>
>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.
>

Why not Python?  Python is very mature and pretty much mainstream
these days.  Most, if not all, development environments have Python,
I'd highly suspect.  Or is it a fear of familiarity with the language for some
developers that worries you?

Further, this only adds a dependency on Python for the tests and not Weston
itself.  And one can override this script with a custom one during
"make check" via the TESTS_ENVIRONMENT variable. Or the tests can always
be executed explicitly without a test environment if necessary.  I was
also very careful in choosing only core Python modules as dependencies.

However, I do agree that the "give weston a moment to start" workaround
is kind of kludgy.  One other way to address that would be to have some other
external mechanism that detects when Weston is initialized and "ready" before
launching any clients (something that would be useful in other domains such as
system "start-up" sequences and start-up performance measuring).

>How about we just make the weston test module launch its test client?

I would be happy with this solution, too.  However, I don't see anything here
that explicitly tells Weston to exit after the client tests are finished.  That is,
wl_display_terminate(test->compositor->wl_display).  Otherwise, the
tests won't finish.

Whatever the decision, I'm geared up and ready to start writing more tests
when this patch series (or some form thereof) is merged ;)

U. Artie

>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