Hello community, here is the log from the commit of package gtk-layer-shell for openSUSE:Factory checked in at 2020-11-02 09:44:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/gtk-layer-shell (Old) and /work/SRC/openSUSE:Factory/.gtk-layer-shell.new.3463 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gtk-layer-shell" Mon Nov 2 09:44:06 2020 rev:7 rq:845362 version:0.5.1 Changes: -------- --- /work/SRC/openSUSE:Factory/gtk-layer-shell/gtk-layer-shell.changes 2020-10-29 09:23:37.542763656 +0100 +++ /work/SRC/openSUSE:Factory/.gtk-layer-shell.new.3463/gtk-layer-shell.changes 2020-11-02 09:44:32.921849162 +0100 @@ -1,0 +2,6 @@ +Mon Nov 2 06:52:59 UTC 2020 - Michael Vetter <mvet...@suse.com> + +- Update to 0.5.1: + * Tests: fix integration test timeout on GTK v3.24.23 (#91) + +------------------------------------------------------------------- Old: ---- v0.5.0.tar.gz New: ---- v0.5.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ gtk-layer-shell.spec ++++++ --- /var/tmp/diff_new_pack.eBGRXa/_old 2020-11-02 09:44:33.557849772 +0100 +++ /var/tmp/diff_new_pack.eBGRXa/_new 2020-11-02 09:44:33.561849776 +0100 @@ -17,7 +17,7 @@ Name: gtk-layer-shell -Version: 0.5.0 +Version: 0.5.1 Release: 0 Summary: Library to create desktop components for Wayland License: MIT AND LGPL-3.0-or-later AND GPL-3.0-or-later @@ -91,7 +91,7 @@ %license LICENSE_MIT.txt LICENSE_LGPL.txt %doc README.md %{_libdir}/libgtk-layer-shell.so.0 -%{_libdir}/libgtk-layer-shell.so.0.?.0 +%{_libdir}/libgtk-layer-shell.so.0.?.? %files -n gtk-layer-shell-devel %{_libdir}/libgtk-layer-shell.so ++++++ v0.5.0.tar.gz -> v0.5.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gtk-layer-shell-0.5.0/CHANGELOG.md new/gtk-layer-shell-0.5.1/CHANGELOG.md --- old/gtk-layer-shell-0.5.0/CHANGELOG.md 2020-10-29 05:29:13.000000000 +0100 +++ new/gtk-layer-shell-0.5.1/CHANGELOG.md 2020-11-01 23:19:21.000000000 +0100 @@ -2,6 +2,9 @@ ## [Unreleased] +## [0.5.1] - 1 Nov 2020 +- Tests: fix integration test timeout on GTK v3.24.23 (fixes [#91](https://github.com/wmww/gtk-layer-shell/issues/91)) + ## [0.5.0] - 28 Oct 2020 - API: add getters for all properties (fixes [#56](https://github.com/wmww/gtk-layer-shell/issues/56)) - API: add `gtk_layer_is_supported()` (fixes [#83](https://github.com/wmww/gtk-layer-shell/issues/83)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gtk-layer-shell-0.5.0/compatibility.md new/gtk-layer-shell-0.5.1/compatibility.md --- old/gtk-layer-shell-0.5.0/compatibility.md 2020-10-29 05:29:13.000000000 +0100 +++ new/gtk-layer-shell-0.5.1/compatibility.md 2020-11-01 23:19:21.000000000 +0100 @@ -10,4 +10,5 @@ | __v0.3.0__ | v3.20.0 - v3.24.22 | v3.24.23 | - | | __v0.4.0__ | v3.20.0 - v3.24.23 | v3.24.23 | - | | __v0.5.0__ | v3.20.0 - v3.24.23 | v3.24.23 | - | +| __v0.5.1__ | v3.20.0 - v3.24.23 | v3.24.23 | - | | __master__ | v3.20.0 - v3.24.23 | v3.24.23 | - | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gtk-layer-shell-0.5.0/meson.build new/gtk-layer-shell-0.5.1/meson.build --- old/gtk-layer-shell-0.5.0/meson.build 2020-10-29 05:29:13.000000000 +0100 +++ new/gtk-layer-shell-0.5.1/meson.build 2020-11-01 23:19:21.000000000 +0100 @@ -1,6 +1,6 @@ project('gtk-layer-shell', ['c'], - version: '0.5.0', + version: '0.5.1', license: 'LGPLv3', meson_version: '>=0.45.1', default_options: ['c_std=gnu11', 'warning_level=3']) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gtk-layer-shell-0.5.0/test/check-licenses.py new/gtk-layer-shell-0.5.1/test/check-licenses.py --- old/gtk-layer-shell-0.5.0/test/check-licenses.py 2020-10-29 05:29:13.000000000 +0100 +++ new/gtk-layer-shell-0.5.1/test/check-licenses.py 2020-11-01 23:19:21.000000000 +0100 @@ -21,7 +21,7 @@ import re logger = logging.getLogger(__name__) -logging.basicConfig(level=logging.INFO) +logging.basicConfig(level=logging.WARNING) toplevel_dirs = ['demo', 'example', 'gtk-priv', 'include', 'src', 'test'] ignore_patterns_file = 'test/license-ignore.txt' @@ -145,18 +145,18 @@ mit_example = canonify_str(MIT_EXAMPLE) lgpl3_example = canonify_str(LGPL3_EXAMPLE) for p in all_files: - contents = load_file(path.join(get_project_root(), p)) - found = 0 - if mit_example in contents: - mit_files.append(p) - found += 1 - if lgpl3_example in contents: - lgpl3_files.append(p) - found += 1 - if found > 1: - multiples_files.append(p) - elif found < 1: - none_files.append(p) + contents = load_file(path.join(get_project_root(), p)) + found = 0 + if mit_example in contents: + mit_files.append(p) + found += 1 + if lgpl3_example in contents: + lgpl3_files.append(p) + found += 1 + if found > 1: + multiples_files.append(p) + elif found < 1: + none_files.append(p) print() print_list('MIT', mit_files) print_list('LGPLv3', lgpl3_files) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gtk-layer-shell-0.5.0/test/mock-server/overrides.c new/gtk-layer-shell-0.5.1/test/mock-server/overrides.c --- old/gtk-layer-shell-0.5.0/test/mock-server/overrides.c 2020-10-29 05:29:13.000000000 +0100 +++ new/gtk-layer-shell-0.5.1/test/mock-server/overrides.c 2020-11-01 23:19:21.000000000 +0100 @@ -152,6 +152,7 @@ void wl_seat_bind(struct wl_client* client, void* data, uint32_t version, uint32_t id) { + ASSERT(!seat_global); seat_global = wl_resource_create(client, &wl_seat_interface, version, id); use_default_impl(seat_global); wl_seat_send_capabilities(seat_global, WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_KEYBOARD); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gtk-layer-shell-0.5.0/test/run-integration-test.py new/gtk-layer-shell-0.5.1/test/run-integration-test.py --- old/gtk-layer-shell-0.5.0/test/run-integration-test.py 2020-10-29 05:29:13.000000000 +0100 +++ new/gtk-layer-shell-0.5.1/test/run-integration-test.py 2020-11-01 23:19:21.000000000 +0100 @@ -20,12 +20,16 @@ import shutil import time import subprocess +import threading + +cleanup_funcs = [] def get_xdg_runtime_dir(): tmp_runtime_dir = '/tmp/layer-shell-test-runtime-dir-' + str(os.getpid()) if (path.exists(tmp_runtime_dir)): wipe_xdg_runtime_dir(tmp_runtime_dir) os.mkdir(tmp_runtime_dir) + cleanup_funcs.append(lambda: wipe_xdg_runtime_dir(tmp_runtime_dir)) return tmp_runtime_dir def wipe_xdg_runtime_dir(p): @@ -49,9 +53,6 @@ time.sleep(0.01) raise RuntimeError(p + ' did not appear in ' + str(timeout) + ' seconds') -def decode_streams(streams): - return [stream.decode('utf-8') for stream in streams] - def format_stream(name, stream): l_pad = 18 - len(name) // 2 r_pad = l_pad @@ -64,69 +65,112 @@ footer = '─' * 40 + '┈' return '╭' + header + '\n│\n│' + body + '\n│\n╰' + footer -def format_process_report(name, process, streams): +def format_process_report(name, process, stdout, stderr): streams = ( - format_stream(name + ' stdout', streams[0]) + '\n\n', - format_stream(name + ' stderr', streams[1]) + '\n\n') + format_stream(name + ' stdout', stdout) + '\n\n', + format_stream(name + ' stderr', stderr) + '\n\n') if name == 'server': streams = (streams[1], streams[0]) return ''.join(streams) + name + ' exit code: ' + str(process.returncode) +class Pipe: + def __init__(self, name): + readable, writable = os.pipe() + self.fd = writable + self.data = bytes() + self.result = None + # Read the data coming out of the pipe on a background thread + # This keeps the buffer from filling up and blocking + self.reader_thread = threading.Thread(name=name, target=self.read, args=(readable,)) + self.reader_thread.start() + cleanup_funcs.append(lambda: self.close()) + + def read(self, readable): + while True: + data = os.read(readable, 1000) + if not data: + # We've reached the end of the data + break + self.data += data + os.close(readable) + + def close(self): + if self.reader_thread.is_alive(): + os.close(self.fd) + self.reader_thread.join(timeout=1) + if self.reader_thread.is_alive(): + assert False, 'Failed to join pipe reader thread' + + def collect_str(self): + if self.result is None: + self.close() + self.result = self.data.decode('utf-8') + data = None + return self.result + +class Program: + def __init__(self, name, args, env): + self.name = name + self.stdout = Pipe(name + ' stdout') + self.stderr = Pipe(name + ' stderr') + self.subprocess = subprocess.Popen(args, stdout=self.stdout.fd, stderr=self.stderr.fd, env=env) + cleanup_funcs.append(lambda: self.kill()) + + def finish(self, timeout=None): + try: + self.subprocess.wait(timeout=timeout) + except subprocess.TimeoutExpired: + self.kill() + raise RuntimeError(self.format_output() + '\n\n' + name + ' timed out') + + def kill(self): + if self.subprocess.returncode is None: + self.subprocess.kill() + self.subprocess.wait() + + def format_output(self): + if self.subprocess.returncode is None: + assert False, 'Program.format_output() called before process exited' + return format_process_report(self.name, self.subprocess, self.stdout.collect_str(), self.stderr.collect_str()) + + def check_returncode(self): + if self.subprocess.returncode is None: + assert False, repr(name) + '.check_returncode() called before process exited' + if self.subprocess.returncode != 0: + raise RuntimeError( + self.format_output() + '\n\n' + + name + ' failed (return code ' + str(self.subprocess.returncode) + ')') + + def collect_output(self): + return self.stdout.collect_str(), self.stderr.collect_str() + def run_test(name, server_bin, client_bin, xdg_runtime, wayland_display): - server = subprocess.Popen( - server_bin, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - env={ - 'XDG_RUNTIME_DIR': xdg_runtime, - 'WAYLAND_DISPLAY': wayland_display, - 'WAYLAND_DEBUG': '1', - }) + env = os.environ.copy() + env['XDG_RUNTIME_DIR'] = xdg_runtime + env['WAYLAND_DISPLAY'] = wayland_display + env['WAYLAND_DEBUG'] = '1' + + server = Program('server', server_bin, env) try: wait_until_appears(path.join(xdg_runtime, wayland_display)) except RuntimeError as e: server.kill() - server_streams = decode_streams(server.communicate()) - raise RuntimeError(format_process_report('server', server, server_streams) + '\n\n' + str(e)) - - client = subprocess.Popen( - client_bin, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - env={ - 'XDG_RUNTIME_DIR': xdg_runtime, - 'WAYLAND_DISPLAY': wayland_display, - 'WAYLAND_DEBUG': '1', - }) - - try: - client_streams = decode_streams(client.communicate(timeout=20)) - except subprocess.TimeoutExpired: - client.kill() - time.sleep(1) - server.kill() - client_streams = decode_streams(client.communicate()) - server.communicate(timeout=1) - raise RuntimeError(format_process_report(name, client, client_streams) + '\n\n' + name + ' timed out') + raise RuntimeError(server.format_output() + '\n\n' + str(e)) - try: - server_streams = decode_streams(server.communicate(timeout=1)) - except subprocess.TimeoutExpired: - server.kill() - server_streams = decode_streams(server.communicate()) - raise RuntimeError(format_process_report('server', server, server_streams) + '\n\nserver timed out') + client = Program(name, client_bin, env) + client.finish(timeout=10) + server.finish(timeout=1) - if server.returncode != 0: - raise RuntimeError(format_process_report('server', server, server_streams) + '\n\nserver failed') + server.check_returncode() + client.check_returncode() - if client.returncode != 0: - raise RuntimeError(format_process_report(name, client, client_streams) + '\n\n' + name + ' failed') + client_stdout, client_stderr = client.collect_output() - if client_streams[0].strip() != '': - raise RuntimeError(format_stream(name + ' stdout', client_streams[0]) + '\n\n' + name + ' stdout not empty') + if client_stdout.strip() != '': + raise RuntimeError(format_stream(name + ' stdout', client_stdout) + '\n\n' + name + ' stdout not empty') - return client_streams[1] + return client_stderr def line_contains(line, tokens): found = True @@ -152,27 +196,33 @@ raise RuntimeError(section + '\n\ndid not find "' + ' '.join(assertions[0]) + '"') section_start = i + 1 -if __name__ == '__main__': - assert len(sys.argv) == 3, 'Incorrect number of args. ' + usage +def main(): name = sys.argv[2] - try: - server_bin = get_bin('mock-server/mock-server') - client_bin = get_bin(name) - wayland_display = 'wayland-test' - xdg_runtime = get_xdg_runtime_dir() + server_bin = get_bin('mock-server/mock-server') + client_bin = get_bin(name) + wayland_display = 'wayland-test' + xdg_runtime = get_xdg_runtime_dir() - try: - client_stderr = run_test(name, server_bin, client_bin, xdg_runtime, wayland_display) - finally: - wipe_xdg_runtime_dir(xdg_runtime) + client_stderr = run_test(name, server_bin, client_bin, xdg_runtime, wayland_display) + client_lines = [line.strip() for line in client_stderr.strip().splitlines()] + + try: + verify_result(client_lines) + except RuntimeError as e: + raise RuntimeError(format_stream(name + ' stderr', client_stderr) + '\n\n' + str(e)) - client_lines = [line.strip() for line in client_stderr.strip().splitlines()] - try: - verify_result(client_lines) - except RuntimeError as e: - raise RuntimeError(format_stream(name + ' stderr', client_stderr) + '\n\n' + str(e)) +if __name__ == '__main__': + assert len(sys.argv) == 3, 'Incorrect number of args. ' + usage + fail = False + try: + main() print('Passed') except RuntimeError as e: + fail = True print(e) + finally: + for func in cleanup_funcs: + func() + if fail: exit(1)