summaryrefslogtreecommitdiff
path: root/tests/helpers/run_surfaces.py
blob: c266b3ce404a0da515278cb291a0f7fabff47858 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/env python3
"""Run the public surface/GPU contract tests on private Weston and Xwayland."""
import os
from pathlib import Path
import subprocess
import sys
import tempfile
import time

def wait_for(process, ready):
    deadline = time.monotonic() + 12
    while time.monotonic() < deadline:
        if process.poll() is not None:
            raise RuntimeError('Display server stopped before readiness')
        if ready():
            return
        time.sleep(0.02)
    raise TimeoutError('Display server readiness')

def main():
    # Optional trailing binaries run only in the X11 phase.
    weston, xwayland, contract, hello, tablet, gl, vulkan, notepad, *x11_only = sys.argv[1:]
    servers = []
    with tempfile.TemporaryDirectory(prefix='yasl-surfaces-') as directory:
        root = Path(directory)
        env = os.environ.copy()
        env.pop('WAYLAND_SOCKET', None)
        env.update(XDG_RUNTIME_DIR=directory, WAYLAND_DISPLAY='yasl-test',
                   XDG_SESSION_TYPE='wayland', LIBGL_ALWAYS_SOFTWARE='1')
        lavapipe = next(Path('/usr/share/vulkan/icd.d').glob('*lvp*.json'), None)
        if lavapipe:
            env['VK_DRIVER_FILES'] = str(lavapipe)
        with (root/'weston.log').open('w+') as wl_log, (root/'xwayland.log').open('w+') as x_log:
            try:
                wl = subprocess.Popen([weston, '--backend=headless', '--renderer=gl',
                    '--socket=yasl-test', '--idle-time=0', '--no-config',
                    '--width=1024', '--height=768'], env=env, stdout=wl_log, stderr=wl_log)
                servers.append(wl)
                wait_for(wl, lambda: (root/'yasl-test').is_socket())
                display_file = root/'display'
                with display_file.open('w') as fd:
                    x = subprocess.Popen([xwayland, '-displayfd', str(fd.fileno()),
                        '-shm', '-noreset', '-nolisten', 'tcp'], env=env,
                        pass_fds=(fd.fileno(),), stdout=x_log, stderr=x_log)
                servers.append(x)
                wait_for(x, lambda: bool(display_file.read_text().strip()))
                env['DISPLAY'] = ':' + display_file.read_text().strip()
                for backend in ('wayland', 'x11'):
                    case = env.copy()
                    if backend == 'x11':
                        case.pop('WAYLAND_DISPLAY', None)
                        case['XDG_SESSION_TYPE'] = 'x11'
                    cases = [(contract,[backend]), (gl,[backend]),
                            (vulkan,[backend]), (tablet,['--backend',backend,'--smoke-test']),
                            (notepad,['--smoke-test'])]
                    if backend == 'x11':
                        cases += [(binary, []) for binary in x11_only]
                    for binary, args in cases:
                        if binary == '-':
                            continue
                        print('Testing', Path(binary).name, backend, flush=True)
                        subprocess.run([binary, *args], env=case, check=True, timeout=15)
                    # hello runs until closed: it must survive its first frames.
                    if hello == '-':
                        continue
                    print('Testing', Path(hello).name, backend, flush=True)
                    process = subprocess.Popen([hello], env=case)
                    try:
                        process.wait(timeout=1)
                        raise RuntimeError(f'{Path(hello).name} exited with {process.returncode}')
                    except subprocess.TimeoutExpired:
                        process.terminate()
                        process.wait()
            except BaseException:
                for log in (wl_log,x_log):
                    log.flush();log.seek(0);print(log.read(), file=sys.stderr)
                raise
            finally:
                for server in reversed(servers):
                    server.terminate()
                    try:
                        server.wait(timeout=5)
                    except subprocess.TimeoutExpired:
                        server.kill();server.wait()
if __name__ == '__main__':
    main()