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()
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, )
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
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, )
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
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"])
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
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
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])
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"]
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
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"])
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])
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