Beispiel #1
0
class KepcoTests(object):
    """
    Tests for the KEPCO.
    """

    def setUp(self):
        self._lewis, self._ioc = get_running_lewis_and_ioc("kepco", DEVICE_PREFIX)
        self.ca = ChannelAccess(default_timeout=30, device_prefix=DEVICE_PREFIX)
        self._lewis.backdoor_run_function_on_device("reset")
        self.ca.assert_that_pv_exists("VOLTAGE", timeout=30)
        reset_calibration_file(self.ca, "default_calib.dat")

    def _write_voltage(self, expected_voltage):
        self._lewis.backdoor_set_on_device("voltage", expected_voltage)
        self._ioc.set_simulated_value("SIM:VOLTAGE", expected_voltage)

    def _write_current(self, expected_current):
        self._lewis.backdoor_set_on_device("current", expected_current)
        self._ioc.set_simulated_value("SIM:CURRENT", expected_current)

    def _set_IDN(self, expected_idn_no_firmware, expected_firmware):
        self._lewis.backdoor_set_on_device("idn_no_firmware", expected_idn_no_firmware)
        self._lewis.backdoor_set_on_device("firmware", expected_firmware)
        expected_idn = "{}{}".format(expected_idn_no_firmware, str(expected_firmware))[:39]  # EPICS limited to 40 chars
        self._ioc.set_simulated_value("SIM:IDN", expected_idn)
        self._ioc.set_simulated_value("SIM:FIRMWARE", str(expected_firmware))
        # Both firmware and IDN are passive so must be updated
        self.ca.process_pv("FIRMWARE")
        self.ca.process_pv("IDN")
        return expected_idn

    def _set_output_mode(self, expected_output_mode):
        self._lewis.backdoor_set_on_device("output_mode", expected_output_mode)
        self._ioc.set_simulated_value("SIM:OUTPUTMODE", expected_output_mode)

    def _set_output_status(self, expected_output_status):
        self._lewis.backdoor_set_on_device("output_status", expected_output_status)

    def test_GIVEN_voltage_set_WHEN_read_THEN_voltage_is_as_expected(self):
        expected_voltage = 1.2
        self._write_voltage(expected_voltage)
        self.ca.assert_that_pv_is("VOLTAGE", expected_voltage)

    def test_GIVEN_current_set_WHEN_read_THEN_current_is_as_expected(self):
        expected_current = 1.5
        self._write_current(expected_current)
        self.ca.assert_that_pv_is("CURRENT", expected_current)

    def test_GIVEN_setpoint_voltage_set_WHEN_read_THEN_setpoint_voltage_is_as_expected(self):
        # Get current Voltage
        current_voltage = self.ca.get_pv_value("VOLTAGE")
        # Set new Voltage via SP
        self.ca.set_pv_value("VOLTAGE:SP", current_voltage + 5)
        # Check SP RBV matches new current
        self.ca.assert_that_pv_is("VOLTAGE:SP:RBV", current_voltage + 5)

    @parameterized.expand(parameterized_list([-5.1, 7.8]))
    def test_GIVEN_setpoint_current_set_WHEN_read_THEN_setpoint_current_is_as_expected(self, _, expected_current):
        self.ca.set_pv_value("CURRENT:SP", expected_current)
        # Check SP RBV matches new current
        self.ca.assert_that_pv_is("CURRENT:SP:RBV", expected_current)

    def test_GIVEN_output_mode_set_WHEN_read_THEN_output_mode_is_as_expected(self):
        expected_output_mode_flag = UnitFlags.CURRENT
        expected_output_mode_str = OutputMode.CURRENT
        self._set_output_mode(expected_output_mode_flag)
        # Check OUTPUT MODE matches new OUTPUT MODE
        self.ca.assert_that_pv_is("OUTPUTMODE", expected_output_mode_str)

    def test_GIVEN_output_status_set_WHEN_read_THEN_output_STATUS_is_as_expected(self):
        expected_output_status_flag = UnitFlags.ON
        expected_output_status_str = Status.ON
        self.ca.set_pv_value("OUTPUTSTATUS:SP", expected_output_status_flag)
        self.ca.assert_that_pv_is("OUTPUTSTATUS:SP:RBV", expected_output_status_str)

    @parameterized.expand(parameterized_list(IDN_LIST))
    def test_GIVEN_idn_set_WHEN_read_THEN_idn_is_as_expected(self, _, idn_no_firmware, firmware):
        expected_idn = self._set_IDN(idn_no_firmware, firmware)
        self.ca.process_pv("IDN")
        self.ca.assert_that_pv_is("IDN", expected_idn)

    @skip_if_recsim("In rec sim you can not diconnect the device")
    def test_GIVEN_diconnected_WHEN_read_THEN_alarms_on_readbacks(self):
        self._lewis.backdoor_set_on_device("connected", False)

        self.ca.assert_that_pv_alarm_is("OUTPUTMODE", self.ca.Alarms.INVALID)
        self.ca.assert_that_pv_alarm_is("CURRENT", self.ca.Alarms.INVALID)
        self.ca.assert_that_pv_alarm_is("VOLTAGE", self.ca.Alarms.INVALID)

    def _test_ramp_to_target(self, start_current, target_current, ramp_rate, step_number, wait_between_changes):
        self._write_current(start_current)
        self.ca.set_pv_value("CURRENT:SP", start_current)
        self.ca.assert_that_pv_is("CURRENT:SP:RBV", start_current)
        self.ca.set_pv_value("RAMP:RATE:SP", ramp_rate)
        self.ca.set_pv_value("RAMP:STEPS:SP", step_number)
        self.ca.set_pv_value("RAMPON:SP", "ON")
        self.ca.set_pv_value("CURRENT:SP", target_current, sleep_after_set=0.0)
        if start_current < target_current:
            self.ca.assert_that_pv_value_is_increasing("CURRENT:SP:RBV", wait=wait_between_changes)
        else:
            self.ca.assert_that_pv_value_is_decreasing("CURRENT:SP:RBV", wait=wait_between_changes)
        self.ca.assert_that_pv_is("RAMPING", "YES")
        # Device stops ramping when it gets to target
        self.ca.assert_that_pv_is("CURRENT:SP:RBV", target_current, timeout=40)
        self._write_current(target_current)
        self.ca.assert_that_pv_is("RAMPING", "NO")
        self.ca.assert_that_pv_value_is_unchanged("CURRENT:SP:RBV", wait=wait_between_changes)
        self.ca.set_pv_value("RAMPON:SP", "OFF")

    def test_GIVEN_rampon_WHEN_target_set_THEN_current_ramps_to_target(self):
        self._test_ramp_to_target(1, 2, 2, 20, 7)

    def test_GIVEN_rampon_WHEN_target_set_with_different_step_rate_THEN_current_ramps_to_target_more_finely(self):
        self._test_ramp_to_target(4, 3, 2, 60, 2)

    @parameterized.expand(parameterized_list(IDN_LIST))
    def test_GIVEN_idn_set_AND_firmware_set_THEN_firmware_pv_correct(self, _, idn_no_firmware, firmware):
        self._set_IDN(idn_no_firmware, firmware)
        self.ca.process_pv("FIRMWARE")
        self.ca.assert_that_pv_is("FIRMWARE", firmware)

    @parameterized.expand(parameterized_list([
        ("default_calib.dat", 100, 100),
        ("field_double_amps.dat", 100, 50),
    ]))
    @skip_if_recsim("Calibration lookup does not work in recsim")
    def test_GIVEN_calibration_WHEN_field_set_THEN_current_as_expected(self, _, calibration_file, field, expected_current):
        with use_calibration_file(self.ca, calibration_file, "default_calib.dat"):
            self.ca.set_pv_value("FIELD:SP", field)
            self.ca.assert_that_pv_is("FIELD:SP:RBV", field)
            self.ca.assert_that_pv_is("CURRENT:SP", expected_current)
            self.ca.assert_that_pv_is("CURRENT:SP:RBV", expected_current)

    @parameterized.expand(parameterized_list([
        ("default_calib.dat", 100, 100),
        ("field_double_amps.dat", 100, 200),
    ]))
    @skip_if_recsim("Calibration lookup does not work in recsim")
    def test_GIVEN_calibration_WHEN_current_set_THEN_field_as_expected(self, _, calibration_file, current, expected_field):
        with use_calibration_file(self.ca, calibration_file, "default_calib.dat"):
            self._write_current(current)
            self.ca.assert_that_pv_is("CURRENT", current)
            self.ca.assert_that_pv_is("FIELD", expected_field)

    @skip_if_recsim("Lewis not available in recsim")
    def test_WHEN_sending_setpoint_THEN_only_one_setpoint_sent(self):
        self._lewis.backdoor_set_and_assert_set("current_set_count", 0)
        self.ca.set_pv_value("CURRENT:SP", 100)
        self._lewis.assert_that_emulator_value_is("current_set_count", 1)

        # Wait a short time and make sure count is not being incremented again later.
        time.sleep(5)
        self._lewis.assert_that_emulator_value_is("current_set_count", 1)
Beispiel #2
0
class Knr1050Tests(unittest.TestCase):
    """
    Tests for the Knr1050 IOC.
    """
    def setUp(self):
        self._lewis, self._ioc = get_running_lewis_and_ioc(device_name, DEVICE_PREFIX)
        self.ca = ChannelAccess(device_prefix=DEVICE_PREFIX, default_wait_time=0.0)
        self._lewis.backdoor_run_function_on_device("reset")
        # Set the device in remote mode ready to receive instructions
        self.ca.set_pv_value("MODE:SP", "REMOTE")
        self.ca.set_pv_value("MODE.PROC", 1)
        # Set the flow and concentrations to a default state that enable pump switch on
        self.ca.set_pv_value("STOP:SP", 1)
        self.ca.set_pv_value("STATUS", "OFF")
        self.ca.set_pv_value("FLOWRATE:SP", 0.01)
        self.ca.set_pv_value("PRESSURE:MIN:SP", 0)
        self.ca.set_pv_value("PRESSURE:MAX:SP", 100)
        self.ca.set_pv_value("COMP:A:SP", 100)
        self.ca.set_pv_value("COMP:B:SP", 0)
        self.ca.set_pv_value("COMP:C:SP", 0)
        self.ca.set_pv_value("COMP:D:SP", 0)
        self.ca.set_pv_value("STATUS:GET.PROC", 1)
        self.ca.set_pv_value("DISABLE:CHECK.PROC", 1)

    def _set_pressure_limit_low(self, limit):
        self._lewis.backdoor_set_on_device("pressure_limit_low", limit)

    def _set_pressure_limit_high(self, limit):
        self._lewis.backdoor_set_on_device("pressure_limit_high", limit)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_an_ioc_WHEN_start_pump_sent_THEN_pump_starts(self):
        self.ca.set_pv_value("START:SP", 1)

        self.ca.assert_that_pv_is("STATUS", "IDLE")

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_an_ioc_WHEN_timed_pump_sent_THEN_pump_starts(self):
        self.ca.set_pv_value("TIMED:SP", 1)

        self.ca.assert_that_pv_is("STATUS", "IDLE")

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_an_ioc_WHEN_stop_pump_sent_via_ioc_THEN_device_state_off(self):
        expected_dev_state = "OFF"
        self.ca.set_pv_value("STOP:SP", 1)

        self.ca.assert_that_pv_is("STATUS", expected_dev_state)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_an_ioc_WHEN_pump_is_turned_on_via_ioc_THEN_pump_is_on(self):
        self.ca.set_pv_value("START:SP", 1)
        pump_status = self._lewis.backdoor_get_from_device("pump_on")

        self.assertEqual(pump_status, True)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_set_concentration_via_ioc_WHEN_ramp_command_sent_via_ioc_THEN_correct_concentration_set(self):
        expected_concentrations = [0, 50, 35, 15]
        self.ca.set_pv_value("COMP:A:SP", expected_concentrations[0])
        self.ca.set_pv_value("COMP:B:SP", expected_concentrations[1])
        self.ca.set_pv_value("COMP:C:SP", expected_concentrations[2])
        self.ca.set_pv_value("COMP:D:SP", expected_concentrations[3])
        self.ca.set_pv_value("START:SP", 1)

        sleep(1.0) # allow emulator to process above data

        concentrations = [self.ca.get_pv_value("COMP:A"),
                          self.ca.get_pv_value("COMP:B"),
                          self.ca.get_pv_value("COMP:C"),
                          self.ca.get_pv_value("COMP:D")]
        self.assertEqual(expected_concentrations, concentrations)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_an_ioc_WHEN_stop_pump_sent_THEN_lewis_pump_stops(self):
        expected_pump_status = False
        self.ca.set_pv_value("STOP:SP", 1)
        pump_status = self._lewis.backdoor_get_from_device("pump_on")

        self.assertEqual(pump_status, expected_pump_status)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_an_ioc_WHEN_stop2_command_sent_THEN_expected_stop_type(self):
        self._lewis.backdoor_set_on_device("keep_last_values", False)
        stopped_status = self._lewis.backdoor_get_from_device("keep_last_values")
        self.assertEqual(stopped_status, False)
        self.ca.set_pv_value("_STOP:KLV:SP", 1)

        stopped_status = self._lewis.backdoor_get_from_device("keep_last_values")
        self.assertEqual(stopped_status, True)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_an_ioc_WHEN_pump_switched_on_then_back_to_off_THEN_device_state_off(self):
        expected_dev_state = "OFF"
        self.ca.set_pv_value("START:SP", 1)
        self.ca.set_pv_value("STOP:SP", 1)

        sleep(1.0) # allow emulator to process above data

        state = self._lewis.backdoor_get_from_device("state")

        self.assertEqual(expected_dev_state, state)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_set_low_pressure_limit_via_backdoor_WHEN_get_low_pressure_limits_via_IOC_THEN_get_expected_pressure_limit(self):
        expected_pressure = 10
        self._set_pressure_limit_low(expected_pressure)
        self.ca.set_pv_value("PRESSURE:LIMITS.PROC", 1)

        self.ca.assert_that_pv_is("PRESSURE:MIN", expected_pressure)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_set_high_pressure_limit_via_backdoor_WHEN_get_high_pressure_limits_via_IOC_THEN_get_expected_pressure_limit(self):
        expected_pressure = 100
        self._set_pressure_limit_high(expected_pressure)
        self.ca.set_pv_value("PRESSURE:LIMITS.PROC", 1)

        self.ca.assert_that_pv_is("PRESSURE:MAX", expected_pressure)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_set_low_pressure_limit_via_ioc_WHEN_get_low_pressure_limit_THEN_get_expected_pressure_limit(self):
        expected_pressure = 10
        self.ca.set_pv_value("PRESSURE:MIN:SP", expected_pressure)
        self.ca.set_pv_value("PRESSURE:LIMITS.PROC", 1)
        self.ca.assert_that_pv_is("PRESSURE:MIN", expected_pressure)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_set_high_pressure_limit_via_ioc_WHEN_get_high_pressure_limit_via_backdoor_THEN_get_expected_pressure_limit(self):
        expected_pressure = 200
        self.ca.set_pv_value("PRESSURE:MAX:SP", expected_pressure)
        self.ca.set_pv_value("PRESSURE:LIMITS.PROC", 1)
        self.ca.assert_that_pv_is("PRESSURE:MAX", expected_pressure)

        self.assertEqual(self._lewis.backdoor_get_from_device("pressure_limit_high"), expected_pressure)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_set_low_pressure_limit_via_ioc_WHEN_get_low_pressure_limit_via_IOC_THEN_get_expected_value(self):
        expected_pressure = 45
        self.ca.set_pv_value("PRESSURE:MIN:SP", expected_pressure)
        self.ca.set_pv_value("PRESSURE:LIMITS.PROC", 1)
        self.ca.assert_that_pv_is("PRESSURE:MIN", expected_pressure)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_set_high_pressure_limit_via_ioc_WHEN_get_high_pressure_limit_via_IOC_THEN_get_expected_value(self):
        expected_pressure = 500

        self.ca.set_pv_value("PRESSURE:MAX:SP", expected_pressure)
        self.ca.set_pv_value("PRESSURE:LIMITS.PROC", 1)
        self.ca.assert_that_pv_is("PRESSURE:MAX", expected_pressure)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_set_flow_limit_min_via_ioc_WHEN_ramp_command_sent_via_IOC_THEN_correct_flow_limit_set(self):
        expected_flow = 0.01
        self.ca.set_pv_value("FLOWRATE:SP", expected_flow)
        self.ca.set_pv_value("START:SP", 1)

        self.ca.assert_that_pv_is("FLOWRATE", expected_flow)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_set_flow_limit_min_via_ioc_WHEN_get_flow_via_IOC_THEN_correct_flow_limit(self):
        expected_flow = 0.01
        self.ca.set_pv_value("FLOWRATE:SP", expected_flow)

        self.assertEqual(self.ca.get_pv_value("FLOWRATE:SP:RBV"), expected_flow)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_ioc_turned_on_WHEN_get_dev_state_via_ioc_THEN_off_state_returned(self):
        expected_dev_state = 'OFF'
        state = self.ca.get_pv_value("STATUS")

        self.assertEqual(expected_dev_state, state)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_ioc_turned_on_WHEN_set_local_mode_via_IOC_THEN_disabled_mode(self):
        expected_mode = 'Disabled'
        self.ca.set_pv_value("MODE:SP", "LOCAL")

        self.ca.assert_that_pv_is("DISABLE", expected_mode)

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_local_mode_WHEN_set_pump_on_via_IOC_THEN_pump_disabled(self):
        self.ca.set_pv_value("MODE:SP", "LOCAL")
        self.ca.set_pv_value("START:SP", 1)

        self.ca.assert_that_pv_is("STATUS", 'OFF')

    @skip_if_recsim("Recsim simulation not implemented")
    def test_GIVEN_incorrect_gradients_WHEN_set_pump_on_via_IOC_THEN_pump_disabled(self):
        self.ca.set_pv_value("COMP:A:SP", 50)  # sum of gradients =/= 100%
        self.ca.set_pv_value("START:SP", 1)

        self.ca.assert_that_pv_is("STATUS", 'OFF')

    @skip_if_recsim("Can not test disconnection in rec sim")
    def test_GIVEN_device_not_connected_WHEN_get_status_THEN_alarm(self):
        self._lewis.backdoor_set_on_device('connected', False)
        self.ca.assert_that_pv_alarm_is('PRESSURE:LIMITS', ChannelAccess.Alarms.INVALID)

    @skip_if_recsim("Can not test disconnection in rec sim")
    def test_GIVEN_timed_run_started_THEN_remaining_time_decreases(self):
        self.ca.set_pv_value("TIME:SP", 10)
        self.ca.set_pv_value("TIMED:SP", 1)

        self.ca.assert_that_pv_value_is_decreasing("TIME:REMAINING", wait=5)

    @skip_if_recsim("Can not test disconnection in rec sim")
    def test_GIVEN_timed_run_started_THEN_pump_stopped_once_finished_run(self):
        self.ca.set_pv_value("TIME:SP", 10)
        self.ca.set_pv_value("TIMED:SP", 1)

        self.ca.assert_that_pv_is("STATUS", 'OFF', timeout=15)

    @skip_if_recsim("Can not test disconnection in rec sim")
    def test_GIVEN_long_timed_run_started_THEN_if_remaining_time_checked_then_not_finished(self):
        self.ca.set_pv_value("TIME:SP", 100)
        self.ca.set_pv_value("TIMED:SP", 1)

        self.ca.assert_that_pv_is("TIME:CHECK", 0)

    @skip_if_recsim("Can not test disconnection in rec sim")
    def test_GIVEN_set_volume_run_started_THEN_remaining_volume_decreases(self):
        self.ca.set_pv_value("FLOWRATE:SP", 0.02)
        self.ca.set_pv_value("VOL:SP", 0.05)
        self.ca.set_pv_value("TIMED:SP", 1)
        self.ca.assert_that_pv_is_not("VOL:REMAINING", 0.0, timeout=5)

        self.ca.assert_that_pv_value_is_decreasing("VOL:REMAINING", wait=5)

    @skip_if_recsim("Can't use lewis backdoor in RECSIM")
    def test_GIVEN_input_error_THEN_error_string_captured(self):
        expected_error = "20,Instrument in standalone mode"
        self._lewis.backdoor_set_on_device("input_correct", False)

        self.ca.assert_that_pv_is("ERROR:STR", expected_error, timeout=5)