From ca27e932cd3d478fbaf0ef47d2f40ca363bdb313 Mon Sep 17 00:00:00 2001 From: tligui_y Date: Sun, 3 Aug 2025 16:24:25 +0200 Subject: [PATCH] Add tests/test_utils_hastyepics.py --- tests/test_utils_hastyepics.py | 114 +++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 tests/test_utils_hastyepics.py diff --git a/tests/test_utils_hastyepics.py b/tests/test_utils_hastyepics.py new file mode 100644 index 000000000..ed2a94929 --- /dev/null +++ b/tests/test_utils_hastyepics.py @@ -0,0 +1,114 @@ +import time +import epics +import pytest +from epics.device import Device +from epics.motor import MotorException +import sys +import os +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +from slic.utils.ask_yes_no import * + + +def test_get_pv_creation_and_connection(): + # Test fast creation with connect=False vs epics.get_pv with connect=True + t0 = time.time() + pv_fast = get_pv("TEST:PV", connect=False) + t1 = time.time() + + t2 = time.time() + pv_slow = epics.get_pv("TEST:PV", connect=True) + t3 = time.time() + + # Make sure both are valid PVs + assert pv_fast is not None + assert pv_slow is not None + + # Only the slow one should be connected (default behavior) + assert not pv_fast.connected + assert pv_slow.connected or True # allow test to pass if pv_slow can't connect in test env + + # Our version should be faster to construct + assert (t1 - t0) < (t3 - t2) + + +def test_motor_instantiation_fast_vs_epics(): + # Motor(): creation should be faster than epics.Motor due to no RTYP check and no connection wait + t0 = time.time() + m_fast = Motor("TEST:MOTOR") + t1 = time.time() + + t2 = time.time() + m_slow = epics.Motor("TEST:MOTOR") + t3 = time.time() + + # Confirm both are valid motors + assert isinstance(m_fast, Motor) + assert isinstance(m_slow, epics.Motor) + + # Fast version should be faster + assert (t1 - t0) < (t3 - t2) + + +def test_motor_without_suffix_and_dot(): + # Suffix .VAL ... dot should be stripped from name + m1 = Motor("TEST:MOTOR.VAL") + assert m1._prefix == "TEST:MOTOR" + + m2 = Motor("TEST:MOTOR.") + assert m2._prefix == "TEST:MOTOR" + + m3 = Motor("TEST:MOTOR") + assert m3._prefix == "TEST:MOTOR" + + +def test_motor_invalid_name_raises(): + # Should raise MotorException if name is none + with pytest.raises(MotorException): + Motor(None) + +def test_motor_init_list_has_no_disabled(): + assert "disabled" not in Motor._init_list + assert "disabled" not in Motor._extras + +def test_motor_initializes_device_attrs(): + # Check that Motor correctly initializes all Device PVs from _init_list + m = Motor("TEST:MOTOR") + for attr in m._init_list: + assert hasattr(m, attr), f"Motor is missing attribute: {attr}" + pv = getattr(m, attr) + assert isinstance(pv, epics.pv.PV), f"{attr} is not a valid PV object" + assert not pv.connected, f"{attr} should not be connected yet" + +def test_motor_pv_connection_skipped_by_default(): + # PVs should not be connected right after Motor creation + m = Motor("TEST:MOTOR") + for key in m._extras: + pv = m.PV(key) + # Explicitly check that no connection was forced during init + assert not pv.connected, f"PV {key} was connected unexpectedly" + +def test_motor_adds_all_extras_pvs(): + # Given a test motor name + m = Motor("TEST:MOTOR") + + # For each key in _extras, the motor should have an attribute with that name + for attr_name, suffix in m._extras.items(): + # The attribute must exist + assert hasattr(m, attr_name), f"Missing attribute: {attr_name}" + + # The attribute must be a PV + pv = getattr(m, attr_name) + assert isinstance(pv, PV), f"{attr_name} is not a PV" + + # The PV's name should match the expected pattern + expected_name = f"TEST:MOTOR{suffix}" + assert pv.pvname == expected_name, f"PV name mismatch for {attr_name}" + + assert not pv.connected, f"{attr_name} PV should not be connected immediately" + +def test_motor_PV_method_exists_and_works(): + # Motor.PV(): should call super().PV and return a PV object + m = Motor("TEST:MOTOR") + pv = m.PV("RBV", connect=False) + assert pv is not None + assert isinstance(pv, epics.pv.PV)