Skip to content
Snippets Groups Projects
Verified Commit 2a67041a authored by Tobias Hangleiter's avatar Tobias Hangleiter
Browse files

Fix flaky tests on CI

parent 1de03da4
Branches
No related tags found
1 merge request!65Fix flaky live view tests on CI
Pipeline #1641377 waiting for manual action
...@@ -35,17 +35,43 @@ def advance_frames(view: LiveViewT, n_frames: int): ...@@ -35,17 +35,43 @@ def advance_frames(view: LiveViewT, n_frames: int):
view.fig.canvas.flush_events() view.fig.canvas.flush_events()
def stop_view(view): def advance_until_stopped(*views):
to_advance = list(views)
while to_advance:
for view in to_advance:
try: try:
view.stop()
except RuntimeError:
# Thread did not join. Try to trigger event loop once.
advance_frames(view, 1) advance_frames(view, 1)
view.stop() except AttributeError:
# event_source has been removed, meaning the animation was stopped
to_advance.remove(view)
except RuntimeError:
# thread did not join
continue
def close_figure(fig): def stop_view(*views):
if not is_using_mpl_gui_backend(fig): if len(views) != 1:
# need to hack a bit to get the linked views to stop
views[0].stop_event.set()
advance_until_stopped(*views)
try:
views[0].stop()
except AttributeError:
# ???
views[0].stop()
def close_view(*views, in_process=False):
if in_process:
views[0].close_event.set()
# Give the process time to process all events
time.sleep(250e-3)
return
stop_view(*views)
if not is_using_mpl_gui_backend(fig := views[0].fig):
# Need to manually trigger the close event because the event loop isn't running # Need to manually trigger the close event because the event loop isn't running
fig.canvas.callbacks.process('close_event', CloseEvent('close_event', fig.canvas)) fig.canvas.callbacks.process('close_event', CloseEvent('close_event', fig.canvas))
...@@ -89,7 +115,7 @@ def started(spectrometer, plot_timetrace, in_process, in_gitlab_ci): ...@@ -89,7 +115,7 @@ def started(spectrometer, plot_timetrace, in_process, in_gitlab_ci):
if not in_process: if not in_process:
for view in views: for view in views:
start_animation(view.fig) start_animation(view.fig)
advance_frames(view, random.randint(1, 10)) advance_frames(view, random.randint(10, 20))
with misc.timeout(30, raise_exc=True) as exceeded: with misc.timeout(30, raise_exc=True) as exceeded:
while not all(view.is_running() for view in views) and not exceeded: while not all(view.is_running() for view in views) and not exceeded:
...@@ -97,43 +123,25 @@ def started(spectrometer, plot_timetrace, in_process, in_gitlab_ci): ...@@ -97,43 +123,25 @@ def started(spectrometer, plot_timetrace, in_process, in_gitlab_ci):
yield views yield views
for view in views: stop_view(*views)
view.stop() close_view(*views, in_process=in_process)
if in_process: if in_process:
for view in views:
view.process.terminate() view.process.terminate()
else:
close_figure(view.fig)
@pytest.fixture @pytest.fixture
def stopped(started: list[LiveViewT], in_process: bool): def stopped(started: list[LiveViewT], in_process: bool):
view = random.choice(started) random.shuffle(views := started)
stop_view(view) stop_view(*views)
return views
if not in_process and len(started) > 1:
advance_frames(started[1 - started.index(view)], 1)
stopped = started
return stopped
@pytest.fixture @pytest.fixture
def closed(started: list[LiveViewT], in_process: bool): def closed(started: list[LiveViewT], in_process: bool):
view = random.choice(started) random.shuffle(views := started)
close_view(*views, in_process=in_process)
if in_process: yield views
view.close_event.set()
else:
close_figure(view.fig)
if not in_process and len(started) > 1:
advance_frames(started[1 - started.index(view)], 1)
else:
# Give the process time to process all events
time.sleep(250e-3)
closed = started
yield closed
def test_started(spectrometer, started, plot_timetrace, in_process): def test_started(spectrometer, started, plot_timetrace, in_process):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment