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)


Reply via email to