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

Kristian Høgsberg hoegsberg at gmail.com
Fri Dec 7 07:47:21 PST 2012


On Fri, Dec 07, 2012 at 02:49:06PM +0000, Eoff, Ullysses A wrote:
> >-----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.

It's just another dependency we don't need.  I'm not anti-python, I'd
want to avoid dart, perl, ruby, javascript, tcl etc as well.  In
particular, for a just small snippet like this, I don't want use
python.  Also this is all about forking and reading from pipes,
something shell is better at than anything else.

> 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.

Right, we need that in there too, somehow.  And an int return_code;
in struct weston_compositor, and then

  ret = ec->return_code;

after wl_display_run() in weston main(), so we can control the weston
exit code.

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

Sounds great, I'll merge the v2 series.

Kristian

> 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