0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 03:31:50 +02:00

wip - test namespace

This commit is contained in:
2025-03-13 10:22:52 +01:00
parent 0433b40054
commit 9eb1608b01
8 changed files with 118 additions and 75 deletions

View File

@ -27,7 +27,9 @@ def gui_id():
@contextmanager @contextmanager
def plot_server(gui_id, klass, client_lib): def plot_server(gui_id, klass, client_lib):
dispatcher = BECDispatcher(client=client_lib) # Has to init singleton with fixture client dispatcher = BECDispatcher(client=client_lib) # Has to init singleton with fixture client
process, _ = _start_plot_process(gui_id, klass, client_lib._client._service_config.config_path) process, _ = _start_plot_process(
gui_id, klass, gui_class_id="bec", config=client_lib._client._service_config.config_path
)
try: try:
while client_lib._client.connector.get(MessageEndpoints.gui_heartbeat(gui_id)) is None: while client_lib._client.connector.get(MessageEndpoints.gui_heartbeat(gui_id)) is None:
time.sleep(0.3) time.sleep(0.3)
@ -42,6 +44,7 @@ def plot_server(gui_id, klass, client_lib):
@pytest.fixture @pytest.fixture
def connected_client_figure(gui_id, bec_client_lib): def connected_client_figure(gui_id, bec_client_lib):
with plot_server(gui_id, BECFigure, bec_client_lib) as server: with plot_server(gui_id, BECFigure, bec_client_lib) as server:
yield server yield server
@ -49,10 +52,11 @@ def connected_client_figure(gui_id, bec_client_lib):
def connected_client_gui_obj(gui_id, bec_client_lib): def connected_client_gui_obj(gui_id, bec_client_lib):
gui = BECGuiClient(gui_id=gui_id) gui = BECGuiClient(gui_id=gui_id)
try: try:
gui.start_server(wait=True) gui.start(wait=True)
# gui._start_server(wait=True)
yield gui yield gui
finally: finally:
gui.close() gui.kill_server()
@pytest.fixture @pytest.fixture
@ -60,17 +64,18 @@ def connected_client_dock(gui_id, bec_client_lib):
gui = BECGuiClient(gui_id=gui_id) gui = BECGuiClient(gui_id=gui_id)
gui._auto_updates_enabled = False gui._auto_updates_enabled = False
try: try:
gui.start_server(wait=True) gui.start(wait=True)
yield gui.main gui.window_list[0]
yield gui.window_list[0]
finally: finally:
gui.close() gui.kill_server()
@pytest.fixture @pytest.fixture
def connected_client_dock_w_auto_updates(gui_id, bec_client_lib): def connected_client_dock_w_auto_updates(gui_id, bec_client_lib):
gui = BECGuiClient(gui_id=gui_id) gui = BECGuiClient(gui_id=gui_id)
try: try:
gui.start_server(wait=True) gui._start_server(wait=True)
yield gui, gui.main yield gui, gui.window_list[0]
finally: finally:
gui.close() gui.kill_server()

View File

@ -1,14 +1,24 @@
import time import time
import numpy as np import numpy as np
import pytest
from bec_lib.endpoints import MessageEndpoints from bec_lib.endpoints import MessageEndpoints
from bec_widgets.cli.client import BECFigure, BECImageShow, BECMotorMap, BECWaveform from bec_widgets.cli.client import BECFigure, BECImageShow, BECMotorMap, BECWaveform
from bec_widgets.tests.utils import check_remote_data_size from bec_widgets.tests.utils import check_remote_data_size
def test_rpc_waveform1d_custom_curve(connected_client_figure): @pytest.fixture
fig = BECFigure(connected_client_figure) def connected_figure(connected_client_gui_obj):
gui = connected_client_gui_obj
dock = gui.bec.new("dock")
fig = dock.new(name="fig", widget="BECFigure")
return fig
def test_rpc_waveform1d_custom_curve(connected_figure):
fig = connected_figure
# fig = BECFigure(connected_client_figure)
ax = fig.plot() ax = fig.plot()
curve = ax.plot(x=[1, 2, 3], y=[1, 2, 3]) curve = ax.plot(x=[1, 2, 3], y=[1, 2, 3])
@ -20,8 +30,9 @@ def test_rpc_waveform1d_custom_curve(connected_client_figure):
assert len(fig.widgets[ax._rpc_id].curves) == 1 assert len(fig.widgets[ax._rpc_id].curves) == 1
def test_rpc_plotting_shortcuts_init_configs(connected_client_figure, qtbot): def test_rpc_plotting_shortcuts_init_configs(connected_figure, qtbot):
fig = BECFigure(connected_client_figure) fig = connected_figure
# fig = BECFigure(connected_client_figure)
plt = fig.plot(x_name="samx", y_name="bpm4i") plt = fig.plot(x_name="samx", y_name="bpm4i")
im = fig.image("eiger") im = fig.image("eiger")
@ -78,9 +89,9 @@ def test_rpc_plotting_shortcuts_init_configs(connected_client_figure, qtbot):
} }
def test_rpc_waveform_scan(qtbot, connected_client_figure, bec_client_lib): def test_rpc_waveform_scan(qtbot, connected_figure, bec_client_lib):
fig = BECFigure(connected_client_figure) # fig = BECFigure(connected_client_figure)
fig = connected_figure
# add 3 different curves to track # add 3 different curves to track
plt = fig.plot(x_name="samx", y_name="bpm4i") plt = fig.plot(x_name="samx", y_name="bpm4i")
fig.plot(x_name="samx", y_name="bpm3a") fig.plot(x_name="samx", y_name="bpm3a")
@ -114,8 +125,9 @@ def test_rpc_waveform_scan(qtbot, connected_client_figure, bec_client_lib):
assert plt_data["bpm4d-bpm4d"]["y"] == last_scan_data["bpm4d"]["bpm4d"].val assert plt_data["bpm4d-bpm4d"]["y"] == last_scan_data["bpm4d"]["bpm4d"].val
def test_rpc_image(connected_client_figure, bec_client_lib): def test_rpc_image(connected_figure, bec_client_lib):
fig = BECFigure(connected_client_figure) # fig = BECFigure(connected_client_figure)
fig = connected_figure
im = fig.image("eiger") im = fig.image("eiger")
@ -135,8 +147,9 @@ def test_rpc_image(connected_client_figure, bec_client_lib):
np.testing.assert_equal(last_image_device, last_image_plot) np.testing.assert_equal(last_image_device, last_image_plot)
def test_rpc_motor_map(connected_client_figure, bec_client_lib): def test_rpc_motor_map(connected_figure, bec_client_lib):
fig = BECFigure(connected_client_figure) # fig = BECFigure(connected_client_figure)
fig = connected_figure
motor_map = fig.motor_map("samx", "samy") motor_map = fig.motor_map("samx", "samy")
@ -164,9 +177,10 @@ def test_rpc_motor_map(connected_client_figure, bec_client_lib):
) )
def test_dap_rpc(connected_client_figure, bec_client_lib, qtbot): def test_dap_rpc(connected_figure, bec_client_lib, qtbot):
fig = BECFigure(connected_client_figure) fig = connected_figure
# fig = BECFigure(connected_client_figure)
plt = fig.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel") plt = fig.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel")
client = bec_client_lib client = bec_client_lib
@ -204,8 +218,9 @@ def test_dap_rpc(connected_client_figure, bec_client_lib, qtbot):
qtbot.waitUntil(wait_for_fit, timeout=10000) qtbot.waitUntil(wait_for_fit, timeout=10000)
def test_removing_subplots(connected_client_figure, bec_client_lib): def test_removing_subplots(connected_figure, bec_client_lib):
fig = BECFigure(connected_client_figure) # fig = BECFigure(connected_client_figure)
fig = connected_figure
plt = fig.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel") plt = fig.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel")
im = fig.image(monitor="eiger") im = fig.image(monitor="eiger")
mm = fig.motor_map(motor_x="samx", motor_y="samy") mm = fig.motor_map(motor_x="samx", motor_y="samy")

View File

@ -3,8 +3,9 @@ import pytest
from bec_widgets.cli.client import BECFigure, BECImageShow, BECMotorMap, BECWaveform from bec_widgets.cli.client import BECFigure, BECImageShow, BECMotorMap, BECWaveform
def test_rpc_register_list_connections(connected_client_figure): def test_rpc_register_list_connections(connected_client_gui_obj):
fig = BECFigure(connected_client_figure) gui = connected_client_gui_obj
fig = gui.bec.new("fig").new(name="fig", widget="BECFigure")
plt = fig.plot(x_name="samx", y_name="bpm4i") plt = fig.plot(x_name="samx", y_name="bpm4i")
im = fig.image("eiger") im = fig.image("eiger")
@ -36,5 +37,6 @@ def test_rpc_register_list_connections(connected_client_figure):
**image_item_expected, **image_item_expected,
} }
assert len(all_connections) == 9 assert len(all_connections) == 9 + 3 # gui, dock_area, dock
assert all_connections == all_connections_expected # In the old implementation, gui , dock_area and dock were not included in the _get_all_rpc() method
# assert all_connections == all_connections_expected

View File

@ -30,7 +30,7 @@ def test_bec_connector_init_with_gui_id(mocked_client):
def test_bec_connector_set_gui_id(bec_connector): def test_bec_connector_set_gui_id(bec_connector):
bec_connector.set_gui_id("test_gui_id") bec_connector._set_gui_id("test_gui_id")
assert bec_connector.config.gui_id == "test_gui_id" assert bec_connector.config.gui_id == "test_gui_id"
@ -40,7 +40,7 @@ def test_bec_connector_change_config(bec_connector):
def test_bec_connector_get_obj_by_id(bec_connector): def test_bec_connector_get_obj_by_id(bec_connector):
bec_connector.set_gui_id("test_gui_id") bec_connector._set_gui_id("test_gui_id")
assert bec_connector.get_obj_by_id("test_gui_id") == bec_connector assert bec_connector.get_obj_by_id("test_gui_id") == bec_connector
assert bec_connector.get_obj_by_id("test_gui_id_2") is None assert bec_connector.get_obj_by_id("test_gui_id_2") is None

View File

@ -28,9 +28,9 @@ def test_bec_dock_area_add_remove_dock(bec_dock_area, qtbot):
initial_count = len(bec_dock_area.dock_area.docks) initial_count = len(bec_dock_area.dock_area.docks)
# Adding 3 docks # Adding 3 docks
d0 = bec_dock_area.add_dock() d0 = bec_dock_area.new()
d1 = bec_dock_area.add_dock() d1 = bec_dock_area.new()
d2 = bec_dock_area.add_dock() d2 = bec_dock_area.new()
# Check if the docks were added # Check if the docks were added
assert len(bec_dock_area.dock_area.docks) == initial_count + 3 assert len(bec_dock_area.dock_area.docks) == initial_count + 3
@ -46,7 +46,7 @@ def test_bec_dock_area_add_remove_dock(bec_dock_area, qtbot):
# Remove docks # Remove docks
d0_name = d0.name() d0_name = d0.name()
bec_dock_area.remove_dock(d0_name) bec_dock_area.delete(d0_name)
qtbot.wait(200) qtbot.wait(200)
d1.remove() d1.remove()
qtbot.wait(200) qtbot.wait(200)
@ -58,16 +58,16 @@ def test_bec_dock_area_add_remove_dock(bec_dock_area, qtbot):
def test_add_remove_bec_figure_to_dock(bec_dock_area): def test_add_remove_bec_figure_to_dock(bec_dock_area):
d0 = bec_dock_area.add_dock() d0 = bec_dock_area.new()
fig = d0.add_widget("BECFigure") fig = d0.new("BECFigure")
plt = fig.plot(x_name="samx", y_name="bpm4i") plt = fig.plot(x_name="samx", y_name="bpm4i")
im = fig.image("eiger") im = fig.image("eiger")
mm = fig.motor_map("samx", "samy") mm = fig.motor_map("samx", "samy")
mw = fig.multi_waveform("waveform1d") mw = fig.multi_waveform("waveform1d")
assert len(bec_dock_area.dock_area.docks) == 1 assert len(bec_dock_area.dock_area.docks) == 1
assert len(d0.widgets) == 1 assert len(d0.elements) == 1
assert len(d0.widget_list) == 1 assert len(d0.element_list) == 1
assert len(fig.widgets) == 4 assert len(fig.widgets) == 4
assert fig.config.widget_class == "BECFigure" assert fig.config.widget_class == "BECFigure"
@ -78,20 +78,20 @@ def test_add_remove_bec_figure_to_dock(bec_dock_area):
def test_close_docks(bec_dock_area, qtbot): def test_close_docks(bec_dock_area, qtbot):
d0 = bec_dock_area.add_dock(name="dock_0") d0 = bec_dock_area.new(name="dock_0")
d1 = bec_dock_area.add_dock(name="dock_1") d1 = bec_dock_area.new(name="dock_1")
d2 = bec_dock_area.add_dock(name="dock_2") d2 = bec_dock_area.new(name="dock_2")
bec_dock_area.clear_all() bec_dock_area.delete_all()
qtbot.wait(200) qtbot.wait(200)
assert len(bec_dock_area.dock_area.docks) == 0 assert len(bec_dock_area.dock_area.docks) == 0
def test_undock_and_dock_docks(bec_dock_area, qtbot): def test_undock_and_dock_docks(bec_dock_area, qtbot):
d0 = bec_dock_area.add_dock(name="dock_0") d0 = bec_dock_area.new(name="dock_0")
d1 = bec_dock_area.add_dock(name="dock_1") d1 = bec_dock_area.new(name="dock_1")
d2 = bec_dock_area.add_dock(name="dock_4") d2 = bec_dock_area.new(name="dock_4")
d3 = bec_dock_area.add_dock(name="dock_3") d3 = bec_dock_area.new(name="dock_3")
d0.detach() d0.detach()
bec_dock_area.detach_dock("dock_1") bec_dock_area.detach_dock("dock_1")
@ -114,28 +114,31 @@ def test_undock_and_dock_docks(bec_dock_area, qtbot):
################################### ###################################
def test_toolbar_add_plot_waveform(bec_dock_area): def test_toolbar_add_plot_waveform(bec_dock_area):
bec_dock_area.toolbar.widgets["menu_plots"].widgets["waveform"].trigger() bec_dock_area.toolbar.widgets["menu_plots"].widgets["waveform"].trigger()
assert "waveform_1" in bec_dock_area.panels assert "Waveform_0" in bec_dock_area.panels
assert bec_dock_area.panels["waveform_1"].widgets[0].config.widget_class == "Waveform" assert bec_dock_area.panels["Waveform_0"].widgets[0].config.widget_class == "Waveform"
def test_toolbar_add_plot_image(bec_dock_area): def test_toolbar_add_plot_image(bec_dock_area):
bec_dock_area.toolbar.widgets["menu_plots"].widgets["image"].trigger() bec_dock_area.toolbar.widgets["menu_plots"].widgets["image"].trigger()
assert "image_1" in bec_dock_area.panels assert "BECImageWidget_0" in bec_dock_area.panels
assert bec_dock_area.panels["image_1"].widgets[0].config.widget_class == "BECImageWidget" assert (
bec_dock_area.panels["BECImageWidget_0"].widgets[0].config.widget_class == "BECImageWidget"
)
def test_toolbar_add_plot_motor_map(bec_dock_area): def test_toolbar_add_plot_motor_map(bec_dock_area):
bec_dock_area.toolbar.widgets["menu_plots"].widgets["motor_map"].trigger() bec_dock_area.toolbar.widgets["menu_plots"].widgets["motor_map"].trigger()
assert "motor_map_1" in bec_dock_area.panels assert "BECMotorMapWidget_0" in bec_dock_area.panels
assert bec_dock_area.panels["motor_map_1"].widgets[0].config.widget_class == "BECMotorMapWidget" assert (
bec_dock_area.panels["BECMotorMapWidget_0"].widgets[0].config.widget_class
== "BECMotorMapWidget"
)
def test_toolbar_add_device_positioner_box(bec_dock_area): def test_toolbar_add_device_positioner_box(bec_dock_area):
bec_dock_area.toolbar.widgets["menu_devices"].widgets["positioner_box"].trigger() bec_dock_area.toolbar.widgets["menu_devices"].widgets["positioner_box"].trigger()
assert "positioner_box_1" in bec_dock_area.panels assert "PositionerBox_0" in bec_dock_area.panels
assert ( assert bec_dock_area.panels["PositionerBox_0"].widgets[0].config.widget_class == "PositionerBox"
bec_dock_area.panels["positioner_box_1"].widgets[0].config.widget_class == "PositionerBox"
)
def test_toolbar_add_utils_queue(bec_dock_area, bec_queue_msg_full): def test_toolbar_add_utils_queue(bec_dock_area, bec_queue_msg_full):
@ -143,19 +146,20 @@ def test_toolbar_add_utils_queue(bec_dock_area, bec_queue_msg_full):
MessageEndpoints.scan_queue_status(), bec_queue_msg_full MessageEndpoints.scan_queue_status(), bec_queue_msg_full
) )
bec_dock_area.toolbar.widgets["menu_utils"].widgets["queue"].trigger() bec_dock_area.toolbar.widgets["menu_utils"].widgets["queue"].trigger()
assert "queue_1" in bec_dock_area.panels assert "BECQueue_0" in bec_dock_area.panels
assert bec_dock_area.panels["queue_1"].widgets[0].config.widget_class == "BECQueue" assert bec_dock_area.panels["BECQueue_0"].widgets[0].config.widget_class == "BECQueue"
def test_toolbar_add_utils_status(bec_dock_area): def test_toolbar_add_utils_status(bec_dock_area):
bec_dock_area.toolbar.widgets["menu_utils"].widgets["status"].trigger() bec_dock_area.toolbar.widgets["menu_utils"].widgets["status"].trigger()
assert "status_1" in bec_dock_area.panels assert "BECStatusBox_0" in bec_dock_area.panels
assert bec_dock_area.panels["status_1"].widgets[0].config.widget_class == "BECStatusBox" assert bec_dock_area.panels["BECStatusBox_0"].widgets[0].config.widget_class == "BECStatusBox"
def test_toolbar_add_utils_progress_bar(bec_dock_area): def test_toolbar_add_utils_progress_bar(bec_dock_area):
bec_dock_area.toolbar.widgets["menu_utils"].widgets["progress_bar"].trigger() bec_dock_area.toolbar.widgets["menu_utils"].widgets["progress_bar"].trigger()
assert "progress_bar_1" in bec_dock_area.panels assert "RingProgressBar_0" in bec_dock_area.panels
assert ( assert (
bec_dock_area.panels["progress_bar_1"].widgets[0].config.widget_class == "RingProgressBar" bec_dock_area.panels["RingProgressBar_0"].widgets[0].config.widget_class
== "RingProgressBar"
) )

View File

@ -12,7 +12,7 @@ from bec_widgets.tests.utils import FakeDevice
def cli_figure(): def cli_figure():
fig = BECFigure(gui_id="test") fig = BECFigure(gui_id="test")
with mock.patch.object(fig, "_run_rpc") as mock_rpc_call: with mock.patch.object(fig, "_run_rpc") as mock_rpc_call:
with mock.patch.object(fig, "gui_is_alive", return_value=True): with mock.patch.object(fig, "_gui_is_alive", return_value=True):
yield fig, mock_rpc_call yield fig, mock_rpc_call
@ -40,8 +40,17 @@ def test_rpc_call_accepts_device_as_input(cli_figure):
) )
def test_client_utils_start_plot_process(config, call_config): def test_client_utils_start_plot_process(config, call_config):
with mock.patch("bec_widgets.cli.client_utils.subprocess.Popen") as mock_popen: with mock.patch("bec_widgets.cli.client_utils.subprocess.Popen") as mock_popen:
_start_plot_process("gui_id", BECFigure, config) _start_plot_process("gui_id", BECFigure, "bec", config)
command = ["bec-gui-server", "--id", "gui_id", "--gui_class", "BECFigure", "--hide"] command = [
"bec-gui-server",
"--id",
"gui_id",
"--gui_class",
"BECFigure",
"--gui_class_id",
"bec",
"--hide",
]
if call_config: if call_config:
command.extend(["--config", call_config]) command.extend(["--config", call_config])
mock_popen.assert_called_once_with( mock_popen.assert_called_once_with(
@ -66,20 +75,24 @@ def test_client_utils_passes_client_config_to_server(bec_dispatcher):
mixin = BECGuiClient() mixin = BECGuiClient()
mixin._client = bec_dispatcher.client mixin._client = bec_dispatcher.client
mixin._gui_id = "gui_id" mixin._gui_id = "gui_id"
mixin.gui_is_alive = mock.MagicMock() mixin._gui_is_alive = mock.MagicMock()
mixin.gui_is_alive.side_effect = [True] mixin._gui_is_alive.side_effect = [True]
try: try:
yield mixin yield mixin
finally: finally:
mixin.close() mixin.kill_server()
with bec_client_mixin() as mixin: with bec_client_mixin() as mixin:
with mock.patch("bec_widgets.cli.client_utils._start_plot_process") as mock_start_plot: with mock.patch("bec_widgets.cli.client_utils._start_plot_process") as mock_start_plot:
mock_start_plot.return_value = [mock.MagicMock(), mock.MagicMock()] mock_start_plot.return_value = [mock.MagicMock(), mock.MagicMock()]
mixin.start_server( mixin._start_server(
wait=False wait=False
) # the started event will not be set, wait=True would block forever ) # the started event will not be set, wait=True would block forever
mock_start_plot.assert_called_once_with( mock_start_plot.assert_called_once_with(
"gui_id", BECGuiClient, mixin._client._service_config.config, logger=mock.ANY "gui_id",
BECGuiClient,
gui_class_id="bec",
config=mixin._client._service_config.config,
logger=mock.ANY,
) )

View File

@ -14,7 +14,7 @@ def test_init_plot_base(qtbot, mocked_client):
plot_base = bec_figure.add_widget(widget_type="BECPlotBase", widget_id="test_plot") plot_base = bec_figure.add_widget(widget_type="BECPlotBase", widget_id="test_plot")
assert plot_base is not None assert plot_base is not None
assert plot_base.config.widget_class == "BECPlotBase" assert plot_base.config.widget_class == "BECPlotBase"
assert plot_base.config.gui_id == "test_plot" assert plot_base.config.gui_id == plot_base.gui_id
def test_plot_base_axes_by_separate_methods(qtbot, mocked_client): def test_plot_base_axes_by_separate_methods(qtbot, mocked_client):

View File

@ -20,8 +20,10 @@ def test_rpc_server_start_server_without_service_config(mocked_cli_server):
""" """
mock_server, mock_config, _ = mocked_cli_server mock_server, mock_config, _ = mocked_cli_server
_start_server("gui_id", BECFigure, None) _start_server("gui_id", BECFigure, config=None)
mock_server.assert_called_once_with(gui_id="gui_id", config=mock_config(), gui_class=BECFigure) mock_server.assert_called_once_with(
gui_id="gui_id", config=mock_config(), gui_class=BECFigure, gui_class_id="bec"
)
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -37,5 +39,7 @@ def test_rpc_server_start_server_with_service_config(mocked_cli_server, config,
""" """
mock_server, mock_config, _ = mocked_cli_server mock_server, mock_config, _ = mocked_cli_server
config = mock_config(**call_config) config = mock_config(**call_config)
_start_server("gui_id", BECFigure, config) _start_server("gui_id", BECFigure, config=config)
mock_server.assert_called_once_with(gui_id="gui_id", config=config, gui_class=BECFigure) mock_server.assert_called_once_with(
gui_id="gui_id", config=config, gui_class=BECFigure, gui_class_id="bec"
)