summaryrefslogtreecommitdiff
path: root/tests/helpers/run_reconnect.py
blob: e86e994cf2d60a204cd19c3eff83fe90594ead3f (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
#!/usr/bin/env python3
"""Kill Weston under a running client, start a new one on the same socket, and
require the client to reconnect: run_reconnect.py <weston> <client>."""
import os
from pathlib import Path
import signal
import subprocess
import sys
import tempfile
import time


def start_weston(weston, root, env, log):
    process = subprocess.Popen([weston, '--backend=headless', '--renderer=gl', '--socket=yasl-test',
                                '--idle-time=0', '--no-config', '--width=1024', '--height=768'],
                               env=env, stdout=log, stderr=log)
    deadline = time.monotonic() + 12
    while not (root/'yasl-test').is_socket():
        if process.poll() is not None or time.monotonic() > deadline:
            raise RuntimeError('Weston did not start')
        time.sleep(0.02)
    return process


def expect(client, word):
    line = client.stdout.readline().strip()
    if line != word:
        raise RuntimeError(f'client printed {line!r}, expected {word!r}')


def main():
    weston, binary = sys.argv[1:]
    signal.alarm(50)
    with tempfile.TemporaryDirectory(prefix='yasl-reconnect-') as directory:
        root = Path(directory)
        env = os.environ.copy()
        env.pop('WAYLAND_SOCKET', None)
        env.update(XDG_RUNTIME_DIR=directory, WAYLAND_DISPLAY='yasl-test', 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 log:
            servers = [start_weston(weston, root, env, log)]
            client = subprocess.Popen([binary], env=env, stdout=subprocess.PIPE, text=True)
            try:
                expect(client, 'ready')
                servers[0].send_signal(signal.SIGKILL)
                servers[0].wait()
                expect(client, 'lost')
                time.sleep(0.5)
                servers.append(start_weston(weston, root, env, log))
                expect(client, 'restored')
                if client.wait(timeout=15) != 0:
                    raise RuntimeError(f'client exited with {client.returncode}')
            except BaseException:
                client.kill()
                log.flush(); log.seek(0); print(log.read(), file=sys.stderr)
                raise
            finally:
                for server in servers:
                    if server.poll() is None:
                        server.terminate()
                        server.wait(timeout=5)


if __name__ == '__main__':
    main()