CI for csaxs_bec / test (push) Successful in 2m40s
A Ctrl-C interrupting an in-flight RPC call (e.g. mid
set_live_view_signal) could leave the XRayEye widget stuck showing the
smear-preview channel afterward -- and since lamnigui_show_xeyealign()
reuses the existing xeyegui widget across calls rather than recreating
it, that stale state would silently carry into the *next* alignment
run too (including production align()/find_rotation_center(), since
on_live_view_enabled() now respects whichever channel is selected).
Fix: lamnigui_show_xeyealign() unconditionally resets both
set_live_view_signal("image") and set_smear_active(False) every time
it's called -- both are cheap no-ops if already in the default state,
and this is the single shared entry point for every alignment
procedure, so one fix covers all of them.
Also add two GUI-facing controls to XRayEye, in a new row below the
shutter/camera-running toggles:
- "Smear preview channel" -- an interactive toggle mirroring
set_live_view_signal(), so the operator has a GUI-only recovery path
independent of the ipython client (e.g. if it's hung/disconnected).
- "Smear integrating" -- a read-only status indicator (disabled
ToggleSwitch) reflecting whether _smear_sweep() is currently
accumulating a composite, driven entirely by the automation.
set_live_view_signal() keeps the interactive toggle's visual state in
sync regardless of who changed the channel (automation or operator) --
single source of truth. _smear_sweep() brackets accumulation with
set_smear_active(True)/(False), turning it off as soon as the sweep
ends (independent of the channel switch, which stays on the composite
until the operator's click is collected). Both new XRayEye methods
required regenerating csaxs_bec/bec_widgets/widgets/client.py via
bw-generate-cli --target csaxs_bec.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
55 lines
2.0 KiB
Python
55 lines
2.0 KiB
Python
"""Unit tests for LamniGuiTools.lamnigui_show_xeyealign()'s live-view reset."""
|
|
|
|
from unittest import mock
|
|
|
|
from csaxs_bec.bec_ipython_client.plugins.LamNI.gui_tools import LamniGuiTools
|
|
|
|
# pylint: disable=protected-access
|
|
|
|
GUI_TOOLS = "csaxs_bec.bec_ipython_client.plugins.LamNI.gui_tools"
|
|
|
|
|
|
def _make_gui_tools():
|
|
tools = LamniGuiTools()
|
|
client = mock.MagicMock()
|
|
tools.set_client(client)
|
|
return tools, client
|
|
|
|
|
|
def test_lamnigui_show_xeyealign_resets_live_view_on_reuse():
|
|
"""A previously-interrupted run (e.g. Ctrl-C mid set_live_view_signal)
|
|
could leave xeyegui stuck on the smear channel/indicator; since the
|
|
widget is reused (not recreated) across calls, opening the alignment
|
|
view must reset both every time, not just on first creation."""
|
|
tools, client = _make_gui_tools()
|
|
tools.xeyegui = mock.MagicMock()
|
|
tools.xeyegui._is_deleted.return_value = False
|
|
client.gui.windows = {"lamni": mock.MagicMock()}
|
|
|
|
dev_mock = mock.MagicMock()
|
|
dev_mock.cam_xeye.live_mode_enabled.get.return_value = True
|
|
|
|
with mock.patch(f"{GUI_TOOLS}.dev", dev_mock, create=True):
|
|
tools.lamnigui_show_xeyealign()
|
|
|
|
tools.xeyegui.set_live_view_signal.assert_called_once_with("image")
|
|
tools.xeyegui.set_smear_active.assert_called_once_with(False)
|
|
|
|
|
|
def test_lamnigui_show_xeyealign_resets_on_fresh_widget_too():
|
|
"""Even a freshly-created widget gets the reset call -- cheap/no-op,
|
|
and keeps the behavior uniform regardless of prior state."""
|
|
tools, client = _make_gui_tools()
|
|
client.gui.windows = {"lamni": mock.MagicMock()}
|
|
new_widget = mock.MagicMock()
|
|
client.gui.lamni.new.return_value = new_widget
|
|
|
|
dev_mock = mock.MagicMock()
|
|
dev_mock.cam_xeye.live_mode_enabled.get.return_value = True
|
|
|
|
with mock.patch(f"{GUI_TOOLS}.dev", dev_mock, create=True):
|
|
tools.lamnigui_show_xeyealign()
|
|
|
|
new_widget.set_live_view_signal.assert_called_once_with("image")
|
|
new_widget.set_smear_active.assert_called_once_with(False)
|