diff --git a/tests/test_utils_reprate.py b/tests/test_utils_reprate.py new file mode 100644 index 000000000..9b62c1122 --- /dev/null +++ b/tests/test_utils_reprate.py @@ -0,0 +1,116 @@ +import time +import pytest +import epics +from slic.utils.reprate import RepRateMonitor, IP_TO_INSTRUMENT, INSTRUMENT_TO_BEAMLINE, BEAMLINE_TO_PVNAME_REPRATE + + +@pytest.mark.parametrize("instrument,expected_beamline", [ + ("alvra", "aramis"), + ("bernina", "aramis"), + ("cristallina", "aramis"), + ("diavolezza", "athos"), + ("maloja", "athos"), + ("furka", "athos") +]) +def test_get_beamline(instrument, expected_beamline, setup_ioc): + """Test the beamline retrieval for a given instrument.""" + beamline = get_beamline(instrument) + assert beamline == expected_beamline, f"Expected {expected_beamline}, but got {beamline}" + +def test_get_pvname_reprate_for_inferred_beamline(setup_ioc): + """Test the PV name retrieval when using inferred beamline based on IP address.""" + # Mock the socket to simulate an IP address + with patch("socket.gethostname", return_value="testhost"), patch("socket.gethostbyname", return_value="129.129.242"): + beamline = infer_beamline() + pvname = get_pvname_reprate(instrument=None, beamline=beamline) + assert pvname == BEAMLINE_TO_PVNAME_REPRATE["aramis"], f"Expected 'SIN-TIMAST-TMA:Bunch-1-Exp-Freq-RB', but got {pvname}" + +@pytest.mark.parametrize("ip,expected_instrument", [ + ("129.129.242", "alvra"), + ("129.129.243", "bernina"), + ("129.129.244", "cristallina"), + ("129.129.245", "diavolezza"), + ("129.129.246", "maloja"), + ("129.129.247", "furka") +]) +def test_infer_beamline_from_ip(ip, expected_instrument, setup_ioc): + """Test that the beamline is correctly inferred based on the IP address.""" + # Mock the socket functions to simulate an IP address + with patch("socket.gethostname", return_value="testhost"), patch("socket.gethostbyname", return_value=ip): + instrument = infer_beamline() + assert instrument == expected_instrument, f"Expected {expected_instrument}, but got {instrument}" + +@pytest.mark.parametrize("instrument,beamline,pvname", [ + ("alvra", "aramis", "SIN-TIMAST-TMA:Bunch-1-Exp-Freq-RB"), + ("bernina", "aramis", "SIN-TIMAST-TMA:Bunch-1-Exp-Freq-RB"), + ("cristallina", "aramis", "SIN-TIMAST-TMA:Bunch-1-Exp-Freq-RB"), + ("diavolezza", "athos", "SIN-TIMAST-TMA:Bunch-2-Exp-Freq-RB"), + ("maloja", "athos", "SIN-TIMAST-TMA:Bunch-2-Exp-Freq-RB"), + ("furka", "athos", "SIN-TIMAST-TMA:Bunch-2-Exp-Freq-RB") +]) +def test_get_pvname_reprate_with_instrument_and_beamline(instrument, beamline, pvname, setup_ioc): + """Test that the PV name is correctly retrieved based on instrument and beamline.""" + retrieved_pvname = get_pvname_reprate(instrument, beamline) + assert retrieved_pvname == pvname, f"Expected {pvname}, but got {retrieved_pvname}" + +def test_invalid_instrument_or_beamline(setup_ioc): + """Test that None is returned when an invalid instrument or beamline is provided.""" + # Invalid instrument + monitor = RepRateMonitor(target="invalid_instrument") + assert monitor.name is None, f"Expected None, but got {monitor.name}" + + # Invalid beamline + monitor = RepRateMonitor(target="non_existing_beamline") + assert monitor.name is None, f"Expected None, but got {monitor.name}" + +def test_monitor_value_update(setup_ioc): + #Test that the RepRateMonitor correctly updates its value and units + monitor = RepRateMonitor("alvra") # Example instrument + + # Check that the initial value is 20.0 and the units are correct + assert monitor.value == 20.0, f"Expected 20.0, but got {monitor.value}" + assert monitor.units == "Hz", f"Expected 'Hz', but got {monitor.units}" # Expected unit + + initial_value = monitor.value + + # Simulate a value change + epics.pv.put(monitor.pv.pvname, 50.0) + + # Check that the value has been updated + assert monitor.value == 50.0, f"Expected 50.0, but got {monitor.value}" + + # Check that the units remain unchanged + assert monitor.units == "Hz", f"Expected 'Hz', but got {monitor.units}" + +def test_repr_method_with_initial_values(setup_ioc): + # Test __repr__ + monitor = RepRateMonitor("alvra") + + # Expected initial values + expected_name = "Aramis Rep. Rate" + expected_value = 20.0 + expected_units = "Hz" + + # Expected representation + expected_repr = f"{expected_name}: {expected_value} {expected_units}" + + # Check that the __repr__ method returns the expected string + assert repr(monitor) == expected_repr, f"Expected '{expected_repr}', but got '{repr(monitor)}'" + + +@pytest.mark.parametrize("invalid_target", [ + "invalid_instrument", # Non-existent instrument + "non_existing_beamline" # Non-existent beamline +]) +def test_invalid_target_handling(invalid_target, setup_ioc): + # Test that an invalid target correctly results in None for PV name.""" + monitor = RepRateMonitor(invalid_target) + assert monitor.name is None, f"Expected None, but got {monitor.name}" + assert monitor.value is None, f"Expected None, but got {monitor.value}" + assert monitor.units is None, f"Expected None, but got {monitor.units}" + +def test_retrieve_pvname_for_none_instrument_and_beamline(setup_ioc): + # Test that if both instrument and beamline are None, the method works correctly.""" + monitor = RepRateMonitor(target=None) + assert monitor.name is not None, "Name should not be None." + assert monitor.value is not None, "Value should not be None."