예제 #1
0
def test_forwarder_sends_pv_updates_single_pv_double(docker_compose):
    """
    Test the forwarder pushes new PV value when the value is updated.

    :param docker_compose: Test fixture
    :return: None
    """

    data_topic = "TEST_forwarderData_double_pv_update"
    pvs = [PVDOUBLE]

    prod = ProducerWrapper("localhost:9092", CONFIG_TOPIC, data_topic)
    prod.add_config(pvs)
    # Wait for config to be pushed
    sleep(2)

    cons = create_consumer()
    cons.subscribe([data_topic])
    # Update value
    change_pv_value(PVDOUBLE, 5)
    # Wait for PV to be updated
    sleep(5)

    first_msg = poll_for_valid_message(cons)
    check_expected_values(first_msg, Value.Double, PVDOUBLE, 0.0)

    second_msg = poll_for_valid_message(cons)
    check_expected_values(second_msg, Value.Double, PVDOUBLE, 5.0)
    cons.close()
예제 #2
0
def test_forwarder_sends_pv_updates_single_pv_string(docker_compose):
    """
    Test the forwarder pushes new PV value when the value is updated.

    :param docker_compose: Test fixture
    :return: None
    """

    data_topic = "TEST_forwarderData_string_pv_update"
    pvs = [PVSTR]

    prod = ProducerWrapper("localhost:9092", CONFIG_TOPIC, data_topic)
    prod.add_config(pvs)
    # Wait for config to be pushed
    sleep(2)

    cons = create_consumer()
    # Update value
    change_pv_value(PVSTR, "stop")

    # Wait for PV to be updated
    sleep(5)
    cons.subscribe([data_topic])

    # Poll for empty update - initial value of PVSTR is nothing
    poll_for_valid_message(cons)
    # Poll for message which should contain forwarded PV update
    data_msg = poll_for_valid_message(cons)

    check_expected_values(data_msg, Value.String, PVSTR, b'stop')
    cons.close()
예제 #3
0
def test_forwarder_sends_pv_updates_single_pv_enum(docker_compose):
    """
    Test the forwarder pushes new PV value when the value is updated.

    NOTE: Enums are converted to Ints in the forwarder.
    :param docker_compose: Test fixture
    :return: None
    """

    data_topic = "TEST_forwarderData_enum_pv_update"
    pvs = [PVENUM]

    prod = ProducerWrapper("localhost:9092", CONFIG_TOPIC, data_topic)
    prod.add_config(pvs)
    # Wait for config to be pushed
    sleep(5)

    cons = create_consumer()

    # Update value
    change_pv_value(PVENUM, "START")
    # Wait for PV to be updated
    sleep(5)
    cons.subscribe([data_topic])

    first_msg = poll_for_valid_message(cons)
    check_expected_values(first_msg, Value.Int, PVENUM, 0)

    second_msg = poll_for_valid_message(cons)
    check_expected_values(second_msg, Value.Int, PVENUM, 1)
    cons.close()
예제 #4
0
def test_forwarder_sends_pv_updates_single_pv_long(docker_compose):
    """
    Test the forwarder pushes new PV value when the value is updated.

    NOTE: longs are converted to ints in the forwarder as they will fit in a 32 bit integer
    :param docker_compose: Test fixture
    :return: None
    """

    data_topic = "TEST_forwarderData_long_pv_update"
    pvs = [PVLONG]

    prod = ProducerWrapper("localhost:9092", CONFIG_TOPIC, data_topic)
    prod.add_config(pvs)
    # Wait for config to be pushed
    sleep(2)

    cons = create_consumer()

    # Set initial PV value
    change_pv_value(PVLONG, 0)
    sleep(2)

    # Update value
    change_pv_value(PVLONG, 5)
    # Wait for PV to be updated
    sleep(2)
    cons.subscribe([data_topic])

    first_msg = poll_for_valid_message(cons)
    check_expected_values(first_msg, Value.Int, PVLONG, 0)

    second_msg = poll_for_valid_message(cons)
    check_expected_values(second_msg, Value.Int, PVLONG, 5)
    cons.close()
예제 #5
0
def test_forwarder_sends_pv_updates_single_pv_enum(docker_compose_no_command,
                                                   start_ioc):
    """
    GIVEN PV of enum type is configured to be forwarded
    WHEN PV value is updated
    THEN Forwarder publishes the update to Kafka

    NOTE: Enums are converted to Ints in the forwarder.
    """
    data_topic = "TEST_forwarderData_enum_pv_update"
    pvs = [PVENUM]

    prod = ProducerWrapper("localhost:9092", CONFIG_TOPIC, data_topic)
    prod.add_config(pvs)
    # Wait for config to be pushed
    sleep(5)

    cons = create_consumer()

    # Update value
    change_pv_value(PVENUM, "START")
    # Wait for PV to be updated
    cons.subscribe([data_topic])
    sleep(5)

    first_msg, _ = poll_for_valid_message(cons)
    check_expected_values(first_msg, Value.Int, PVENUM, 0)

    second_msg, _ = poll_for_valid_message(cons)
    check_expected_values(second_msg, Value.Int, PVENUM, 1)
    cons.close()
예제 #6
0
def test_connection_status_messages(docker_compose_no_command):
    """
      GIVEN PV is configured to be forwarded
      WHEN Connection status changes
      THEN Forwarder publishes ep00 message with connection status

      NOTE: Enums are converted to Ints in the forwarder.
      """
    data_topic = "TEST_forwarderData_connection_status"
    pvs = [PVENUM]

    prod = ProducerWrapper("localhost:9092", CONFIG_TOPIC, data_topic)
    prod.add_config(pvs)
    # Wait for config to be pushed
    sleep(5)

    cons = create_consumer()

    # Update value
    change_pv_value(PVENUM, "START")
    # Wait for PV to be updated
    sleep(5)
    cons.subscribe([data_topic])

    first_msg = poll_for_connection_status_message(cons)
    check_expected_connection_status_values(first_msg, EventType.CONNECTED)

    cons.close()
예제 #7
0
def test_long_run(docker_compose_lr, start_ioc):
    """
    Test that the channel defined in the config file is created.

    :param docker_compose: Test fixture
    :return: None
    """
    # Set up consumer now and subscribe from earliest offset on data topic
    cons = create_consumer("earliest")
    cons.subscribe(["TEST_forwarderDataLR"])
    with open(os.path.join("logs", "forwarder_lr_stats.log"),
              "w+") as stats_file:
        with open(os.path.join("logs", "forwarder_lr_missedupdates.log"),
                  "w+") as file:
            for i in range(5150):  # minimum 12 hours with 4 second sleep time
                # Change pv value now
                change_pv_value(PVDOUBLE, i)
                # Wait for the forwarder to push the update
                sleep(3)
                try:
                    msg, _ = poll_for_valid_message(cons)
                except MsgErrorException:
                    sleep(3)
                    msg, _ = poll_for_valid_message(cons)
                try:
                    check_expected_values(msg, Value.Double, PVDOUBLE,
                                          float(i))
                except AssertionError:
                    # Message is either incorrect or empty - log expected value to file
                    file.write(str(i) + "\n")
                container = False
                # Report stats every 10th iteration
                if i % 10 == 0:
                    client = docker.from_env()
                    for item in client.containers.list():
                        if "forwarder" in item.name:
                            container = item
                            break
                    if container:
                        stats_file.write("{}\t{}\n".format(
                            datetime.now(),
                            container.stats(
                                stream=False)["memory_stats"]["usage"],
                        ))
예제 #8
0
def teardown_function(function):
    """
    Stops forwarder pv listening and resets any values in EPICS
    """
    print("Resetting PVs", flush=True)
    prod = ProducerWrapper("localhost:9092", CONFIG_TOPIC, "")
    prod.stop_all_pvs()

    defaults = {
        PVDOUBLE: 0.0,
        # We have to use this as the second parameter for caput gets parsed as empty so does not change the value of
        # the PV
        PVSTR: '""',
        PVLONG: 0,
        PVENUM: "INIT",
    }

    for key, value in defaults.items():
        change_pv_value(key, value)
    change_array_pv_value(PVFLOATARRAY, "3 1.1 2.2 3.3")
    sleep(3)
예제 #9
0
def test_config_file_channel_created_correctly(docker_compose):
    """
    Test that the channel defined in the config file is created.

    :param docker_compose: Test fixture
    :return: None
    """
    cons = create_consumer()
    cons.subscribe(['TEST_forwarderData_pv_from_config'])
    sleep(5)
    # Change the PV value, so something is forwarded
    change_pv_value(PVDOUBLE, 10)
    # Wait for PV to be updated
    sleep(5)
    # Check the initial value is forwarded
    first_msg = poll_for_valid_message(cons)
    check_expected_values(first_msg, Value.Double, PVDOUBLE, 0.0)

    # Check the new value is forwarded
    second_msg = poll_for_valid_message(cons)
    check_expected_values(second_msg, Value.Double, PVDOUBLE, 10.0)
    cons.close()
예제 #10
0
def teardown_function(function):
    """
    Stops forwarder pv listening and resets any values in EPICS
    :param docker_compose: test fixture to apply to
    :return:
    """
    print("Resetting PVs", flush=True)
    prod = ProducerWrapper("localhost:9092", CONFIG_TOPIC, "")
    prod.stop_all_pvs()

    defaults = {
        PVDOUBLE: 0.0,
        # We have to use this as the second parameter for caput gets parsed as empty so does not change the value of
        # the PV
        PVSTR: "\"\"",
        PVLONG: 0,
        PVENUM: "INIT"
    }

    for key, value in defaults.items():
        change_pv_value(key, value)
    sleep(3)