Wayland logo

Wayland Unit Test Suite

The Wayland unit test suite is part of the Wayland source tree found under the tests directory. It leverages automake's Serial Test Harness to specify, compile, and execute the tests thru make check.

It is recommended that all Wayland developers create unit tests for their code. All unit tests should pass before submitting patches upstream. The Wayland maintainer(s) have the right to refuse any patches that are not accompanied by a unit test or if the patches break existing unit tests.

Compiling and Running

$ make check

NO_ASSERT_LEAK_CHECK=1 disables the test runner's simple memory checks.

Writing Tests

The test runner (tests/test-runner.h,c) predefines the main function, does simple memory leak checking for each test, and defines various convenience macros to simplify writing unit tests. When running a unit test group, the test runner executes each test case in a separate forked subprocess.

The TEST(<test name>) macro defines a test case that "passes" on a normal exit status of the test (i.e. exitcode 0). An abnormal exit status causes the test to "fail". Tests defined with this macro are auto-registered with the test runner.

The FAIL_TEST(<test name>) macro defines a test case that "passes" on a abnormal exit status of the test. A normal exit status causes the test to "fail". Tests defined with this macro are auto-registered with the test runner.

Weston Unit Test Suite

The Weston unit test suite is part of the Weston source tree found under the tests directory. It leverages automake's Parallel Test Harness to specify, compile, and execute the tests thru make check.

It is recommended that all Weston developers make unit tests for the code that they write. All unit tests should pass before submitting patches upstream. The Weston maintainer(s) have the right to refuse any patches that are not accompanied by a unit test or if the patches break existing unit tests.

Compiling and Running

To run with the default headless backend:

$ make check

To run with a different backend, e.g. the X11 backend:

$ make check BACKEND=x11-backend.so

Running Individual Tests

The check target essentially executes all tests registered in the TESTS variable in Makefile.am. Files with a .test extension are run directly, e.g.:

$ ./vertex-clip.test
test "float_difference_same":exit status 0, pass.
...
16 tests, 16 pass, 0 skip, 0 fail

Tests suffixed with .la and .weston are run using the tests/weston-tests-env shell script, which you can use to run individual tests, thusly:

$ abs_builddir=$PWD tests/weston-tests-env pointer.weston

Test Results

The *.test tests output their results to stdout. The other tests write into a logs/ subdirectory and generate one log for the server and another for the test itself.

Example output:

$ tail logs/pointer-log.txt
test-client: got keyboard modifiers 0 0 0 0
test-client: got pointer enter 0 0, surface 0x55c836a14500
test-client: got pointer frame
test-client: got pointer motion 0 0
test-client: got global pointer 46 76
test-client: got pointer leave, surface 0x55c836a14500
test-client: got pointer frame
test-client: got global pointer 45 75
test "test_pointer_top_left":   exit status 0, pass.
14 tests, 14 pass, 0 skip, 0 fail

Writing Tests

Compositor Tests

These tests are written by leveraging Weston's module feature. See the "surface-test" for an example of how this is done.

In general, you define a module_init(...) function which registers an idle callback to your test function. The test function is responsible for ensuring the compositor exits at the end of your test. For example:

static void
test_foo(void *data)
{
	struct weston_compositor *compositor = data;

	/* Test stuff...
	assert(...);
	assert(...);
	...
	*/

	wl_display_terminate(compositor->wl_display);
}

WL_EXPORT int
module_init(struct weston_compositor *compositor,
            int *argc, char *argv[], const char *config_file)
{
	struct wl_event_loop *loop;

	loop = wl_display_get_event_loop(compositor->wl_display);

	wl_event_loop_add_idle(loop, test_foo, compositor);

	return 0;
}

Client Tests

Similar to the Wayland unit test suite, the test runner (tests/weston-test-runner.h,c) predefines the main function and various convenience macros to simplify writing unit tests. When running a unit test group, the test runner executes each test case in a separate forked subprocess. Unlike the Wayland unit test suite, this runner does not have a simple memory leak checker.

The TEST(<test name>) macro defines a test case that "passes" on a normal exit status of the test (i.e. exitcode 0). An abnormal exit status causes the test to "fail". Tests defined with this macro are auto-registered with the test runner.

The FAIL_TEST(<test name>) macro defines a test case that "passes" on a abnormal exit status of the test. A normal exit status causes the test to "fail". Tests defined with this macro are auto-registered with the test runner.

Client tests have access to the wl_test interface which defines a small API for interacting with the compositor (e.g. emit input events, query surface data, etc.) There is also a client helper API (tests/weston-test-client-helper.h,c), that simplifies client setup and wl_test interface usage. Probably the most effective way to learn how to leverage these API's is to study some of the existing tests (e.g. tests/pointer-test.c).