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
No related branches found
No related tags found
1 merge request!65Fix flaky live view tests on CI
Checking pipeline status
...@@ -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:
advance_frames(view, 1)
except AttributeError:
# event_source has been removed, meaning the animation was stopped
to_advance.remove(view)
except RuntimeError:
# thread did not join
continue
def stop_view(*views):
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: try:
view.stop() views[0].stop()
except RuntimeError: except AttributeError:
# Thread did not join. Try to trigger event loop once. # ???
advance_frames(view, 1) views[0].stop()
view.stop()
def close_figure(fig): def close_view(*views, in_process=False):
if not is_using_mpl_gui_backend(fig): 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