Exemplo n.º 1
0
def test_FIFOReadProducer__puts_sawtooth_waveform_in_data_out_queue_each_iteration_with_increasing_sample_idx(
    mocker, ):
    expected_num_cycles_1 = 30
    expected_num_cycles_2 = 17
    mocker.patch.object(
        fifo_read_producer,
        "_get_cms_since_last_data_packet",
        side_effect=[
            expected_num_cycles_1 * ROUND_ROBIN_PERIOD,
            expected_num_cycles_2 * ROUND_ROBIN_PERIOD
        ],
    )

    expected_read_1 = produce_data(expected_num_cycles_1, 0)
    expected_read_2 = produce_data(
        expected_num_cycles_2,
        (expected_num_cycles_1 * ROUND_ROBIN_PERIOD) //
        TIMESTEP_CONVERSION_FACTOR,
    )

    data_out_queue = queue.Queue()
    error_queue = queue.Queue()
    producer_thread = FIFOReadProducer(data_out_queue, error_queue,
                                       threading.Lock())

    invoke_process_run_and_check_errors(producer_thread, num_iterations=2)

    actual_1 = data_out_queue.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    assert actual_1 == expected_read_1
    actual_2 = data_out_queue.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    assert actual_2 == expected_read_2

    # clean up the queues to avoid BrokenPipe errors
    producer_thread.hard_stop()
Exemplo n.º 2
0
def test_build_file_writer_objects__logs_warning__when_first_data_frame_period_of_read_is_not_expected_value_and_logging_level_is_debug(
        test_data_frame_period, test_description, mocker):
    mocked_put = mocker.patch.object(ok_comm,
                                     "put_log_message_into_queue",
                                     autospec=True)
    expected_queue = TestingQueue()
    first_data_frame_size = DATA_FRAME_SIZE_WORDS * 4  # number of bytes in a word
    test_bytearray = produce_data(1, 0)[:first_data_frame_size]
    test_bytearray.extend(produce_data(1, test_data_frame_period))

    expected_logging_threshold = logging.DEBUG
    build_file_writer_objects(
        test_bytearray,
        "six_channels_32_bit__single_sample_index",
        expected_queue,
        expected_logging_threshold,
    )

    expected_message = f"Detected period between first two data frames of FIFO read: {test_data_frame_period * TIMESTEP_CONVERSION_FACTOR} does not matched expected value: {DATA_FRAME_PERIOD}. Actual time indices: 0x0, {hex(test_data_frame_period * TIMESTEP_CONVERSION_FACTOR)}"
    mocked_put.assert_any_call(
        logging.DEBUG,
        expected_message,
        expected_queue,
        expected_logging_threshold,
    )
Exemplo n.º 3
0
def test_build_file_writer_objects_performance():
    # 10 iterations with 625 Hz data rate
    #
    # 1. cython parse_sensor_bytes:         266523479.8
    # 2. parse_sensor_bytes (4):            253645684.3
    # 3. parse_sensor_bytes (5):            246193920.3

    num_cycles = math.ceil(CENTIMILLISECONDS_PER_SECOND / ROUND_ROBIN_PERIOD)
    test_bytearray = produce_data(num_cycles, 0)
    q = Queue()

    start = time.perf_counter_ns()
    num_iterations = 10
    for _ in range(num_iterations):
        build_file_writer_objects(
            test_bytearray,
            "six_channels_32_bit__single_sample_index",
            q,
            logging.DEBUG,
        )
    dur = time.perf_counter_ns() - start

    ns_per_iter = dur / num_iterations
    # print(f"ns per iterations: {ns_per_iter}") # pylint:disable=wrong-spelling-in-comment # Eli (4/8/21): this is commented code that is deliberately kept in the codebase since it is often toggled on/off during optimization
    assert (
        ns_per_iter < 450000000
    )  # Eli (10/20/20): bumped up from 300000000 to 450000000 because it was running a bit slow on windows in Github CI
Exemplo n.º 4
0
def test_build_file_writer_objects__raises_error__when_first_data_frame_period_of_read_is_not_expected_value_and_logging_level_is_info_or_higher(
        test_data_frame_period, test_logging_level, test_description, mocker):
    # Tanner (7/10/20) When the error is raised, the queue is closed before it finishes writing to Pipe, so mock to avoid error in test
    mocker.patch.object(ok_comm, "put_log_message_into_queue", autospec=True)
    q = TestingQueue()
    first_data_frame_size = DATA_FRAME_SIZE_WORDS * 4  # number of bytes in a word
    test_bytearray = produce_data(1, 0)[:first_data_frame_size]
    test_bytearray.extend(produce_data(1, test_data_frame_period))
    expected_error_string = f"Detected period between first two data frames of FIFO read: {test_data_frame_period * TIMESTEP_CONVERSION_FACTOR} does not matched expected value: {DATA_FRAME_PERIOD}. Actual time indices: 0x0, {hex(test_data_frame_period * TIMESTEP_CONVERSION_FACTOR)}"
    with pytest.raises(InvalidDataFramePeriodError,
                       match=expected_error_string):
        build_file_writer_objects(
            test_bytearray,
            "six_channels_32_bit__single_sample_index",
            q,
            test_logging_level,
        )
Exemplo n.º 5
0
def test_RunningFIFOSimulator__add_data_cycles__adds_correct_bytearray_to_fifo(
        test_num_cycles, test_description, fifo_simulator):
    fifo_simulator.initialize_board()
    fifo_simulator.add_data_cycles(test_num_cycles)

    expected_bytearray = produce_data(test_num_cycles, 0)

    actual = fifo_simulator.read_from_fifo()
    assert actual == expected_bytearray
Exemplo n.º 6
0
def test_OkCommunicationProcess_managed_acquisition__handles_ignoring_first_data_cycle(
    four_board_comm_process, ):
    ok_process = four_board_comm_process["ok_process"]
    board_queues = four_board_comm_process["board_queues"]

    ok_process._logging_level = logging.DEBUG  # pylint:disable=protected-access

    board_queues[0][0].put_nowait(
        get_mutable_copy_of_START_MANAGED_ACQUISITION_COMMUNICATION())
    fifo = TestingQueue()
    fifo.put_nowait(produce_data(2, 0))
    assert is_queue_eventually_of_size(
        fifo, 1, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True
    queues = {"pipe_outs": {PIPE_OUT_FIFO: fifo}}

    simulator = FrontPanelSimulator(queues)
    simulator.initialize_board()
    ok_process.set_board_connection(0, simulator)
    to_file_writer_queue = board_queues[0][2]
    invoke_process_run_and_check_errors(ok_process)

    ok_process._time_of_last_fifo_read[0] = datetime.datetime(  # pylint: disable=protected-access
        year=2000, month=12, day=2)
    ok_process._timepoint_of_last_fifo_read[0] = time.perf_counter()  # pylint: disable=protected-access
    invoke_process_run_and_check_errors(ok_process)
    assert ok_process._is_first_managed_read[0] is False  # pylint: disable=protected-access

    expected_well_idx = 0
    test_value_1 = (FIFO_READ_PRODUCER_DATA_OFFSET +
                    FIFO_READ_PRODUCER_WELL_AMPLITUDE *
                    (expected_well_idx + 1) * signal.sawtooth(
                        (ROUND_ROBIN_PERIOD // TIMESTEP_CONVERSION_FACTOR) /
                        FIFO_READ_PRODUCER_SAWTOOTH_PERIOD,
                        width=0.5,
                    ) * -1)
    expected_first_dict_sent = {
        "is_reference_sensor":
        False,
        "well_index":
        expected_well_idx,
        "data":
        np.array(
            [
                [ROUND_ROBIN_PERIOD],
                [int(test_value_1) - RAW_TO_SIGNED_CONVERSION_VALUE],
            ],
            dtype=np.int32,
        ),
    }
    actual = to_file_writer_queue.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    assert actual["is_reference_sensor"] == expected_first_dict_sent[
        "is_reference_sensor"]
    assert actual["well_index"] == expected_first_dict_sent["well_index"]
    np.testing.assert_equal(actual["data"], expected_first_dict_sent["data"])
Exemplo n.º 7
0
def test_OkCommunicationProcess_managed_acquisition__does_not_log_when_non_parsing_error_raised_with_first_round_robin(
        four_board_comm_process, mocker):
    mocker.patch(
        "builtins.print",
        autospec=True)  # don't print all the error messages to console
    ok_process = four_board_comm_process["ok_process"]
    board_queues = four_board_comm_process["board_queues"]

    ok_process._logging_level = logging.DEBUG  # pylint:disable=protected-access
    ok_process._data_frame_format = "fake_format"  # pylint:disable=protected-access

    board_queues[0][0].put_nowait(
        get_mutable_copy_of_START_MANAGED_ACQUISITION_COMMUNICATION())
    assert (is_queue_eventually_of_size(
        board_queues[0][0], 1, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is
            True)
    fifo = TestingQueue()
    fifo.put_nowait(produce_data(1, 0))
    assert is_queue_eventually_of_size(
        fifo, 1, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True
    queues = {"pipe_outs": {PIPE_OUT_FIFO: fifo}}

    simulator = FrontPanelSimulator(queues)
    simulator.initialize_board()
    ok_process.set_board_connection(0, simulator)
    comm_to_main = board_queues[0][1]

    invoke_process_run_and_check_errors(ok_process)
    comm_to_main.get(
        timeout=QUEUE_CHECK_TIMEOUT_SECONDS)  # pop out init message
    assert is_queue_eventually_empty(
        comm_to_main, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True

    ok_process._time_of_last_fifo_read[0] = datetime.datetime(  # pylint: disable=protected-access
        year=2000, month=12, day=2)
    ok_process._timepoint_of_last_fifo_read[0] = time.perf_counter()  # pylint: disable=protected-access
    with pytest.raises(UnrecognizedDataFrameFormatNameError):
        invoke_process_run_and_check_errors(ok_process)

    for _ in range(6):
        assert (is_queue_eventually_not_empty(
            comm_to_main, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True)
        comm_to_main.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS
                         )  # pop out expected log messages

    assert is_queue_eventually_empty(
        comm_to_main, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True
Exemplo n.º 8
0
def test_produce_data__returns_correct_bytearray_with_given_num_cycles_and_starting_sample_index(
        test_num_cycles, test_starting_sample_index, test_description):
    expected_data = bytearray(0)
    for cycle in range(test_num_cycles):
        for frame in range(8):
            # add header
            expected_data.extend(
                build_header_magic_number_bytes(HEADER_MAGIC_NUMBER))
            sample_index = (
                test_starting_sample_index +
                (cycle * (ROUND_ROBIN_PERIOD // TIMESTEP_CONVERSION_FACTOR)) +
                (frame * (DATA_FRAME_PERIOD // TIMESTEP_CONVERSION_FACTOR)))
            # add sample index
            expected_data.extend(struct.pack("<L", sample_index))
            # add channel data
            for adc_num in range(6):
                # add metadata byte
                adc_ch_num = frame
                metadata_byte = (adc_num << 4) + adc_ch_num
                expected_data.extend([metadata_byte])
                # add sawtooth data
                is_ref_sensor = adc_ch_num not in ADC_CH_TO_24_WELL_INDEX[
                    adc_num]
                data_value = 0
                t = sample_index
                if is_ref_sensor:
                    amplitude = FIFO_READ_PRODUCER_REF_AMPLITUDE * (adc_num +
                                                                    1)
                    data_value = (
                        FIFO_READ_PRODUCER_DATA_OFFSET + amplitude *
                        signal.sawtooth(t / FIFO_READ_PRODUCER_SAWTOOTH_PERIOD,
                                        width=0.5) * -1)
                else:
                    scaling_factor = ADC_CH_TO_24_WELL_INDEX[adc_num][
                        adc_ch_num] + 1
                    amplitude = FIFO_READ_PRODUCER_WELL_AMPLITUDE * scaling_factor
                    data_value = (
                        FIFO_READ_PRODUCER_DATA_OFFSET + amplitude *
                        signal.sawtooth(t / FIFO_READ_PRODUCER_SAWTOOTH_PERIOD,
                                        width=0.5) * -1)
                test_data_byte = struct.pack("<L", int(data_value))
                expected_data.extend(test_data_byte[:3])

    actual = produce_data(test_num_cycles, test_starting_sample_index)
    assert actual == expected_data
Exemplo n.º 9
0
def test_OkCommunicationProcess_managed_acquisition__does_not_log_percent_use_metrics_in_first_logging_cycle(
        four_board_comm_process, mocker):
    mocker.patch.object(OkCommunicationProcess,
                        "_is_ready_to_read_from_fifo",
                        return_value=True)

    ok_process = four_board_comm_process["ok_process"]
    board_queues = four_board_comm_process["board_queues"]
    ok_process._time_of_last_fifo_read[0] = datetime.datetime(  # pylint: disable=protected-access
        2020, 7, 3, 9, 25, 0, 0)
    ok_process._timepoint_of_last_fifo_read[0] = 10  # pylint: disable=protected-access
    ok_process._minimum_iteration_duration_seconds = 0  # pylint: disable=protected-access

    fifo = TestingQueue()
    for _ in range(INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES):
        fifo.put_nowait(produce_data(2, 0))
    confirm_queue_is_eventually_of_size(
        fifo, INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES)
    queues = {"pipe_outs": {PIPE_OUT_FIFO: fifo}}
    simulator = FrontPanelSimulator(queues)
    simulator.initialize_board()
    ok_process.set_board_connection(0, simulator)
    board_queues[0][0].put_nowait(
        get_mutable_copy_of_START_MANAGED_ACQUISITION_COMMUNICATION())
    confirm_queue_is_eventually_of_size(board_queues[0][0], 1)

    invoke_process_run_and_check_errors(
        ok_process,
        num_iterations=INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES,
        perform_setup_before_loop=True,
    )

    assert_queue_is_eventually_not_empty(board_queues[0][1])
    queue_items = drain_queue(board_queues[0][1])
    actual = queue_items[-1]
    assert "message" in actual
    assert "percent_use_metrics" not in actual["message"]

    # Tanner (5/29/20): Closing a queue while it is not empty (especially when very full) causes BrokePipeErrors, so flushing it before the test ends prevents this
    drain_queue(board_queues[0][2])
Exemplo n.º 10
0
def test_OkCommunicationProcess_managed_acquisition__reads_at_least_one_prepopulated_simulated_fifo_read(
        four_board_comm_process,  # mocker
):
    ok_process = four_board_comm_process["ok_process"]
    board_queues = four_board_comm_process["board_queues"]

    ok_process._logging_level = logging.DEBUG  # pylint:disable=protected-access

    board_queues[0][0].put_nowait(
        get_mutable_copy_of_START_MANAGED_ACQUISITION_COMMUNICATION())
    fifo = TestingQueue()
    fifo.put_nowait(produce_data(2, 0))
    assert is_queue_eventually_of_size(
        fifo, 1, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True
    queues = {"pipe_outs": {PIPE_OUT_FIFO: fifo}}

    simulator = FrontPanelSimulator(queues)
    simulator.initialize_board()
    ok_process.set_board_connection(0, simulator)
    to_main_queue = board_queues[0][1]
    invoke_process_run_and_check_errors(ok_process)

    to_main_queue.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS
                      )  # pop out the receipt of the command
    assert to_main_queue.empty()

    ok_process._time_of_last_fifo_read[0] = datetime.datetime(  # pylint: disable=protected-access
        year=2000, month=12, day=2)
    ok_process._timepoint_of_last_fifo_read[0] = time.perf_counter()  # pylint: disable=protected-access
    invoke_process_run_and_check_errors(ok_process)

    words_msg = to_main_queue.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    assert "words in the FIFO" in words_msg["message"]
    about_to_read_msg = to_main_queue.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    assert "About to read from FIFO" in about_to_read_msg["message"]
    after_read_msg = to_main_queue.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    assert "After reading from FIFO" in after_read_msg["message"]
    size_msg = to_main_queue.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    assert "576 bytes" in size_msg["message"]
Exemplo n.º 11
0
def test_OkCommunicationProcess_run__processes_read_from_fifo_debug_console_command(
    test_num_words_to_log,
    test_num_cycles_to_read,
    test_description,
    four_board_comm_process,
):
    ok_process = four_board_comm_process["ok_process"]
    board_queues = four_board_comm_process["board_queues"]
    input_queue = board_queues[0][0]
    response_queue = board_queues[0][1]

    test_bytearray = produce_data(test_num_cycles_to_read, 0)
    fifo = TestingQueue()
    put_object_into_queue_and_raise_error_if_eventually_still_empty(
        test_bytearray, fifo)
    queues = {"pipe_outs": {PIPE_OUT_FIFO: fifo}}
    simulator = FrontPanelSimulator(queues)
    simulator.initialize_board()
    ok_process.set_board_connection(0, simulator)
    simulator.start_acquisition()

    expected_returned_communication = {
        "communication_type": "debug_console",
        "command": "read_from_fifo",
        "num_words_to_log": test_num_words_to_log,
    }
    put_object_into_queue_and_raise_error_if_eventually_still_empty(
        copy.deepcopy(expected_returned_communication), input_queue)
    invoke_process_run_and_check_errors(ok_process)

    total_num_words = len(test_bytearray) // 4
    test_words = struct.unpack(f"<{total_num_words}L", test_bytearray)
    formatted_test_words = list()
    num_words_to_log = min(total_num_words, test_num_words_to_log)
    for i in range(num_words_to_log):
        formatted_test_words.append(hex(test_words[i]))
    expected_returned_communication["response"] = formatted_test_words
    actual = response_queue.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    assert actual == expected_returned_communication
Exemplo n.º 12
0
def test_OkCommunicationProcess_commands_for_each_run_iteration__sends_fifo_read_to_file_writer_if_ready_to_read(
):
    board_queues, error_queue = generate_board_and_error_queues(num_boards=4)
    p = OkCommunicationProcess(board_queues, error_queue)
    test_bytearray = produce_data(1, 0)
    fifo = TestingQueue()
    fifo.put_nowait(test_bytearray)
    assert is_queue_eventually_of_size(fifo, 1) is True
    queues = {"pipe_outs": {PIPE_OUT_FIFO: fifo}}
    simulator = FrontPanelSimulator(queues)
    simulator.initialize_board()
    simulator.start_acquisition()
    p.set_board_connection(0, simulator)
    p._is_managed_acquisition_running[0] = True  # pylint:disable=protected-access
    p._time_of_last_fifo_read[0] = datetime.datetime(  # pylint:disable=protected-access
        2020, 2, 13, 11, 43, 10, 123455)
    p._timepoint_of_last_fifo_read[0] = time.perf_counter()  # pylint: disable=protected-access
    invoke_process_run_and_check_errors(p)

    expected_well_idx = 0
    test_value_1 = (
        FIFO_READ_PRODUCER_DATA_OFFSET + FIFO_READ_PRODUCER_WELL_AMPLITUDE *
        (expected_well_idx + 1) * signal.sawtooth(
            0 / FIFO_READ_PRODUCER_SAWTOOTH_PERIOD, width=0.5) * -1)
    expected_first_dict_sent = {
        "is_reference_sensor":
        False,
        "well_index":
        expected_well_idx,
        "data":
        np.array([[0], [int(test_value_1) - RAW_TO_SIGNED_CONVERSION_VALUE]],
                 dtype=np.int32),
    }
    actual = board_queues[0][2].get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    assert actual["is_reference_sensor"] == expected_first_dict_sent[
        "is_reference_sensor"]
    assert actual["well_index"] == expected_first_dict_sent["well_index"]
    np.testing.assert_equal(actual["data"], expected_first_dict_sent["data"])
Exemplo n.º 13
0
def test_OkCommunicationProcess_managed_acquisition__logs_performance_metrics_after_appropriate_number_of_read_cycles(
        four_board_comm_process, mocker):
    expected_idle_time = 1
    expected_start_timepoint = 7
    expected_stop_timepoint = 11
    expected_latest_percent_use = 100 * (
        1 - expected_idle_time /
        (expected_stop_timepoint - expected_start_timepoint))
    expected_percent_use_values = [40.1, 67.8, expected_latest_percent_use]
    expected_longest_iterations = list(
        range(INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES - 1))

    test_data_parse_dur_values = [
        0 for _ in range(INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES * 2)
    ]
    test_read_dur_values = [
        0 for _ in range(INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES * 2)
    ]
    for i in range(1, INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES * 2, 2):
        test_data_parse_dur_values[i] = i
        test_read_dur_values[i] = i // 2 + 1
    test_acquisition_values = [
        20 for _ in range(INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES)
    ]
    for i in range(1, INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES):
        test_acquisition_values[i] = test_acquisition_values[i -
                                                             1] + 10 * (i + 1)

    perf_counter_vals = list()
    for i in range(0, INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES * 2, 2):
        perf_counter_vals.append(test_read_dur_values[i])
        perf_counter_vals.append(test_read_dur_values[i + 1])
        perf_counter_vals.append(test_data_parse_dur_values[i])
        perf_counter_vals.append(test_data_parse_dur_values[i + 1])
        perf_counter_vals.append(test_acquisition_values[i // 2])
    mocker.patch.object(time, "perf_counter", side_effect=perf_counter_vals)
    mocker.patch.object(time,
                        "perf_counter_ns",
                        return_value=expected_stop_timepoint)
    mocker.patch.object(OkCommunicationProcess,
                        "_is_ready_to_read_from_fifo",
                        return_value=True)
    mocker.patch.object(
        parallelism_framework,
        "calculate_iteration_time_ns",
        autospec=True,
        side_effect=expected_longest_iterations,
    )

    ok_process = four_board_comm_process["ok_process"]
    board_queues = four_board_comm_process["board_queues"]
    ok_process._time_of_last_fifo_read[0] = datetime.datetime(  # pylint: disable=protected-access
        2020, 5, 28, 12, 58, 0, 0)
    ok_process._timepoint_of_last_fifo_read[0] = 10  # pylint: disable=protected-access
    ok_process._idle_iteration_time_ns = expected_idle_time  # pylint: disable=protected-access
    ok_process._minimum_iteration_duration_seconds = 0  # pylint: disable=protected-access
    ok_process._start_timepoint_of_last_performance_measurement = (  # pylint: disable=protected-access
        expected_start_timepoint)
    ok_process._percent_use_values = expected_percent_use_values[:-1]  # pylint: disable=protected-access

    test_fifo_reads = [
        produce_data(i + 2, 0)
        for i in range(INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES)
    ]
    fifo = TestingQueue()
    for read in test_fifo_reads:
        fifo.put_nowait(read)
    confirm_queue_is_eventually_of_size(
        fifo, INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES)
    queues = {"pipe_outs": {PIPE_OUT_FIFO: fifo}}
    simulator = FrontPanelSimulator(queues)
    simulator.initialize_board()
    ok_process.set_board_connection(0, simulator)
    board_queues[0][0].put_nowait(
        get_mutable_copy_of_START_MANAGED_ACQUISITION_COMMUNICATION())
    confirm_queue_is_eventually_of_size(board_queues[0][0], 1)

    invoke_process_run_and_check_errors(
        ok_process,
        num_iterations=INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES)

    assert_queue_is_eventually_not_empty(board_queues[0][1])
    queue_items = drain_queue(board_queues[0][1])
    actual = queue_items[-1]
    assert "message" in actual
    actual = actual["message"]

    expected_num_bytes = [len(read) for read in test_fifo_reads]
    expected_parsing_dur_values = [
        i * 2 + 1 for i in range(INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES)
    ]
    expected_read_dur_values = [
        i + 1 for i in range(INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES)
    ]
    expected_acquisition_values = [
        10 * (i + 1)
        for i in range(INSTRUMENT_COMM_PERFOMANCE_LOGGING_NUM_CYCLES)
    ]
    assert actual["communication_type"] == "performance_metrics"
    assert "idle_iteration_time_ns" not in actual
    assert "start_timepoint_of_measurements" not in actual
    assert actual["fifo_read_num_bytes"] == {
        "max": max(expected_num_bytes),
        "min": min(expected_num_bytes),
        "stdev": round(stdev(expected_num_bytes), 6),
        "mean": round(sum(expected_num_bytes) / len(expected_num_bytes), 6),
    }
    assert actual["fifo_read_duration"] == {
        "max":
        max(expected_read_dur_values),
        "min":
        min(expected_read_dur_values),
        "stdev":
        round(stdev(expected_read_dur_values), 6),
        "mean":
        round(
            sum(expected_read_dur_values) / len(expected_read_dur_values), 6),
    }
    assert actual["duration_between_acquisition"] == {
        "max":
        max(expected_acquisition_values),
        "min":
        min(expected_acquisition_values),
        "stdev":
        round(stdev(expected_acquisition_values), 6),
        "mean":
        round(
            sum(expected_acquisition_values) /
            len(expected_acquisition_values), 6),
    }
    assert actual["data_parsing_duration"] == {
        "max":
        max(expected_parsing_dur_values),
        "min":
        min(expected_parsing_dur_values),
        "stdev":
        round(stdev(expected_parsing_dur_values), 6),
        "mean":
        round(
            sum(expected_parsing_dur_values) /
            len(expected_parsing_dur_values), 6),
    }
    assert actual["percent_use"] == expected_latest_percent_use
    assert actual["percent_use_metrics"] == {
        "max":
        max(expected_percent_use_values),
        "min":
        min(expected_percent_use_values),
        "stdev":
        round(stdev(expected_percent_use_values), 6),
        "mean":
        round(
            sum(expected_percent_use_values) /
            len(expected_percent_use_values), 6),
    }
    num_longest_iterations = ok_process.num_longest_iterations
    assert actual["longest_iterations"] == expected_longest_iterations[
        -num_longest_iterations:]

    # Tanner (5/29/20): Closing a queue while it is not empty (especially when very full) causes BrokePipeErrors, so flushing it before the test ends prevents this
    drain_queue(board_queues[0][2])
Exemplo n.º 14
0
def test_OkCommunicationProcess_managed_acquisition__logs_fifo_parsing_errors_and_attempts_word_conversion_of_first_round_robin(
    four_board_comm_process, ):
    test_read = bytearray([1] * DATA_FRAME_SIZE_WORDS *
                          DATA_FRAMES_PER_ROUND_ROBIN * 4)
    test_read.extend(produce_data(1, 12345))
    ok_process = four_board_comm_process["ok_process"]
    board_queues = four_board_comm_process["board_queues"]

    ok_process._logging_level = logging.DEBUG  # pylint:disable=protected-access

    board_queues[0][0].put_nowait(
        get_mutable_copy_of_START_MANAGED_ACQUISITION_COMMUNICATION())
    fifo = TestingQueue()
    fifo.put_nowait(test_read)
    assert is_queue_eventually_of_size(
        fifo, 1, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True
    queues = {"pipe_outs": {PIPE_OUT_FIFO: fifo}}

    simulator = FrontPanelSimulator(queues)
    simulator.initialize_board()
    ok_process.set_board_connection(0, simulator)
    comm_to_main = board_queues[0][1]

    invoke_process_run_and_check_errors(ok_process)

    comm_to_main.get(
        timeout=QUEUE_CHECK_TIMEOUT_SECONDS)  # pop out init message
    assert is_queue_eventually_empty(
        comm_to_main, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True

    ok_process._time_of_last_fifo_read[0] = datetime.datetime(  # pylint: disable=protected-access
        year=2000, month=12, day=2)
    ok_process._timepoint_of_last_fifo_read[0] = time.perf_counter()  # pylint: disable=protected-access
    invoke_process_run_and_check_errors(ok_process)
    assert is_queue_eventually_not_empty(
        comm_to_main, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True

    for _ in range(6):
        comm_to_main.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS
                         )  # pop out expected log messages
        assert (is_queue_eventually_not_empty(
            comm_to_main, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True)

    fifo_read_msg = comm_to_main.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    first_round_robin_len = DATA_FRAME_SIZE_WORDS * DATA_FRAMES_PER_ROUND_ROBIN * 4
    assert f"{first_round_robin_len} bytes" in fifo_read_msg["message"]
    assert r"b'\x01\x01\x01\x01" in fifo_read_msg["message"]

    assert is_queue_eventually_not_empty(
        comm_to_main, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True
    error_msg = comm_to_main.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    assert "InstrumentCommIncorrectHeaderError" in error_msg["message"]

    for _ in range(2):
        assert (is_queue_eventually_not_empty(
            comm_to_main, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True)
        comm_to_main.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS
                         )  # pop out expected log messages

    assert is_queue_eventually_empty(
        comm_to_main, timeout_seconds=QUEUE_CHECK_TIMEOUT_SECONDS) is True