[gtk/headless-tests] Make headless tests work



commit 3e4371f0cf7081e7d520b02b1e4df2754ef3c071
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Mar 20 17:13:03 2021 -0400

    Make headless tests work
    
    Move gstreamer out of process, to avoid interference
    from its GL support having its own Wayland connection.

 tests/headless-tests.py | 72 ++++++++++++++++++++++++++-----------------------
 1 file changed, 39 insertions(+), 33 deletions(-)
---
diff --git a/tests/headless-tests.py b/tests/headless-tests.py
index a8e756cb88..15e972c451 100644
--- a/tests/headless-tests.py
+++ b/tests/headless-tests.py
@@ -1,18 +1,17 @@
 import subprocess
 import gi
 
-gi.require_version('Gst', '1.0')
 gi.require_version('Gdk', '4.0')
 gi.require_version('Gtk', '4.0')
 
-from gi.repository import GLib, Gst, Gdk
+from gi.repository import GLib, Gdk
 from pydbus import SessionBus
 
-Gst.init(None)
-
 screen_cast = None
 monitors = {}
+waiting = False
 done = False
+monitor_model = None
 
 def terminate():
     print("terminating")
@@ -21,30 +20,23 @@ def terminate():
 
 def stream_added_closure(name):
     def stream_added(node_id):
-        print(f'Stream added, node id: {node_id}')
-
         monitor = monitors[name];
 
         freq = monitor['freq'];
         width = monitor['width'];
         height = monitor['height'];
 
-        pipeline_desc = f'pipewiresrc path={node_id} ! 
video/x-raw,max-framerate={freq}/1,width={width},height={height} ! videoconvert ! glimagesink'
+        pipeline_desc = f'gst-launch-1.0 pipewiresrc path={node_id} ! 
video/x-raw,max-framerate={freq}/1,width={width},height={height} ! videoconvert ! glimagesink'
 
-        pipeline = Gst.parse_launch(pipeline_desc)
-        pipeline.set_state(Gst.State.PLAYING)
-
-        monitor['pipeline'] = pipeline
+        # print(f'launching {pipeline_desc}')
+        monitor['pipeline'] = subprocess.Popen([pipeline_desc], shell=True, stdout=subprocess.DEVNULL)
 
     return stream_added
 
-def stream_added(node_id):
-    print(f'stream added, node id: {node_id}')
-
 def add_monitor(name, width, height, freq):
     print(f'adding monitor "{name}": {width}x{height}, {freq}Hz')
     session_path = screen_cast.CreateSession({})
-    print(f'Session {session_path}')
+    # print(f'Session {session_path}')
     session = bus.get('org.gnome.Mutter.ScreenCast', session_path)
     monitors[name] = {
         "session": session,
@@ -53,7 +45,7 @@ def add_monitor(name, width, height, freq):
         "freq": freq
     }
     stream_path = session.RecordVirtual({})
-    print(f'Stream path {stream_path}')
+    # print(f'Stream path {stream_path}')
     stream = bus.get('org.gnome.Mutter.ScreenCast', stream_path)
     stream.onPipeWireStreamAdded = stream_added_closure(name)
     session.Start()
@@ -66,8 +58,7 @@ def remove_monitor(name):
     else:
         try:
             pipeline = monitor['pipeline']
-            pipeline.send_event(Gst.Event.new_eos())
-            pipeline.set_state(Gst.State.NULL)
+            pipeline.kill()
 
             session = monitor['session']
             session.Stop()
@@ -137,28 +128,24 @@ def monitors_changed(monitors, position, removed, added):
 
     expected_change = None
 
-    print(f'monitors changed: {position}, {removed}, {added}')
+    # print(f'monitors changed: {position}, {removed}, {added}')
     for i in range(position, position + added):
-        print(f'new monitor {i}:')
         monitor = monitors.get_item(i)
-        report_monitor(monitor)
-        monitor.connect('notify', monitor_changed)
+        #print(f'new monitor {i}:')
+        # report_monitor(monitor)
+        # monitor.connect('notify', monitor_changed)
 
 def launch_observer():
+    global monitor_model
+
     Gdk.set_allowed_backends('wayland')
     display = Gdk.Display.open('gtk-test')
 
-    monitors = display.get_monitors()
-    if monitors.get_n_items() > 0:
-        print('initial monitors')
-        for i in range(0, monitors.get_n_items()):
-            monitor = monitors.get_item(i)
-            report_monitor(monitor)
-            monitor.connect('notify', monitor_changed)
-    monitors.connect('items-changed', monitors_changed)
+    monitor_model = display.get_monitors()
+    assert monitor_model.get_n_items() == 0, "Unexpected initial monitors"
+    monitor_model.connect('items-changed', monitors_changed)
 
 def expect_monitors_changed(position, removed, added, timeout):
-    print("setting expected change")
     global expected_change
     expected_change = {
         'position' : position,
@@ -168,22 +155,39 @@ def expect_monitors_changed(position, removed, added, timeout):
     wait(timeout)
     assert expected_change == None, "Expected change did not happen"
 
+def expect_monitor(position, width, height, freq):
+    assert monitor_model.get_n_items() > position, f'Monitor {position} not present'
+    monitor = monitor_model.get_item(position)
+    geometry = monitor.get_geometry()
+    assert geometry.width == width, "Unexpected monitor width"
+    assert geometry.height == height, "Unexpected monitor height"
+    assert monitor.get_refresh_rate() == freq, "Unexpected monitor frequency"
+
 def run_commands():
+
     launch_observer()
     wait(500)
+
     add_monitor("0", 100, 100, 60)
     expect_monitors_changed(0, 0, 1, 500)
+    expect_monitor (0, 100, 100, 60000) # GTK reports frequency in mHz
+
     add_monitor("1", 1024, 768, 144)
     expect_monitors_changed(1, 0, 1, 500)
+    expect_monitor (1, 1024, 768, 144000)
+
     remove_monitor("0")
-    expect_monitors_changed(0, 1, 0, 11000)
+    expect_monitors_changed(0, 1, 0, 11000) # mutter takes 10 seconds to remove it
+
     remove_monitor("1")
     expect_monitors_changed(0, 1, 0, 11000)
 
 def mutter_appeared(name):
-    print("mutter entered the bus")
+    global waiting
     global screen_cast
     global done
+    if waiting:
+      print("mutter entered the bus")
 
     screen_cast = bus.get('org.gnome.Mutter.ScreenCast',
                           '/org/gnome/Mutter/ScreenCast')
@@ -191,7 +195,9 @@ def mutter_appeared(name):
     done = True
 
 def mutter_vanished():
+    global waiting
     if screen_cast == None:
+        waiting = True
         print("mutter is not on the bus. Waiting...")
     else:
         print("mutter left the bus")


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]