def test_set_link_enable_blocks(abc, bc): # Make sure that the set power command can block event = threading.Event() bc.write_fpga_register.side_effect = (lambda *a, **k: event.wait()) bc.read_bmp_version.side_effect = mock_read_bmp_version done_event = OnDoneEvent() requests = AtomicRequests(done_event) requests.link(10, Links.east, True) abc.add_requests(requests) # Block for a short time to ensure the background thread gets chance to # execute assert done_event.wait(0.1) is False # We should be sure the power command is blocking on the BMP call bc.write_fpga_register.assert_called_with(0, 0x5C, False, board=10, frame=0, cabinet=0) # When the BMP call completes, so should the done_event! event.set() done_event.wait()
def test_set_link_enable(abc, bc, link, fpga, addr, enable, value, side_effect, success): # Make sure that the set link command works (and failure is reported) e = OnDoneEvent() bc.write_fpga_register.side_effect = side_effect bc.read_bmp_version.side_effect = mock_read_bmp_version requests = AtomicRequests(e) requests.link(10, link, enable) abc.add_requests(requests) e.wait() assert e.success is success bc.write_fpga_register.assert_called_with(fpga, addr, value, board=10, frame=0, cabinet=0) bc.write_fpga_register.reset_mock()
def test_set_power(abc, bc, power_side_effect, success): # Make sure that the set power command works (and failure is reported) e = OnDoneEvent() bc.power_on.side_effect = power_side_effect bc.power_off.side_effect = power_side_effect requests = AtomicRequests(e) requests.power(10, False) abc.add_requests(requests) e.wait() assert e.success is success assert len(bc.power_on.mock_calls) == 0 bc.power_off.assert_called_with(boards=[10], frame=0, cabinet=0) bc.power_off.reset_mock() bc.power_on.side_effect = power_side_effect bc.power_off.side_effect = power_side_effect bc.read_fpga_register.side_effect = mock_read_fpga_register bc.read_bmp_version.side_effect = mock_read_bmp_version e = OnDoneEvent() requests = AtomicRequests(e) requests.power(11, True) abc.add_requests(requests) e.wait() assert e.success is success bc.power_on.assert_called_with(boards=[11], frame=0, cabinet=0) bc.power_on.reset_mock() assert len(bc.power_off.mock_calls) == 0
def test_atomic_order(abc, bc): # Make sure that requests are run in order power_on_event = threading.Event() power_off_event = threading.Event() link_event = threading.Event() bc.power_on.side_effect = (lambda *a, **k: power_on_event.wait(1.0)) bc.power_off.side_effect = (lambda *a, **k: power_off_event.wait(1.0)) bc.write_fpga_register.side_effect = (lambda *a, **k: link_event.wait(1.0)) bc.read_fpga_register.side_effect = mock_read_fpga_register bc.read_bmp_version.side_effect = mock_read_bmp_version event = OnDoneEvent() requests = AtomicRequests(event) with abc: requests.link(11, Links.east, True) requests.power(12, False) requests.power(10, True) abc.add_requests(requests) # Block for a short time to ensure the background thread gets chance to # execute assert event.wait(0.1) is False # Make sure just the power command has been called bc.power_on.assert_called_with(boards=[10], frame=0, cabinet=0) bc.power_on.reset_mock() assert len(bc.power_off.mock_calls) == 0 assert len(bc.write_fpga_register.mock_calls) == 0 # Let the first power command complete power_on_event.set() # Block for a short time to ensure background thread gets chance to execute assert event.wait(0.1) is False # We should be sure the power command is blocking on the BMP call assert len(bc.power_on.mock_calls) == 0 assert len(bc.power_off.mock_calls) == 0 bc.write_fpga_register.assert_called_with(0, 0x5C, False, board=11, frame=0, cabinet=0) bc.write_fpga_register.reset_mock() # Make BMP call complete and the last event finish link_event.set() # Block for a short time to ensure background thread gets chance to execute assert event.wait(0.1) is False # Make sure just the power command has been called a second time (and not # the link setting command) bc.power_off.assert_called_with(boards=[12], frame=0, cabinet=0) bc.power_off.reset_mock() assert len(bc.power_on.mock_calls) == 0 assert len(bc.write_fpga_register.mock_calls) == 0 # Let the second power command complete power_off_event.set() event.wait(2.0)
def test_set_power_blocks(abc, bc): # Make sure that the set power command can block event = threading.Event() bc.power_off.side_effect = (lambda *a, **k: event.wait()) done_event = OnDoneEvent() requests = AtomicRequests(done_event) requests.power(10, False) abc.add_requests(requests) # Block for a short time to ensure the background thread gets chance to # execute assert done_event.wait(0.1) is False # We should be sure the power command is blocking on the BMP call bc.power_off.assert_called_with(boards=[10], frame=0, cabinet=0) # When the BMP call completes, so should the done_event! event.set() done_event.wait() assert done_event.success is True
def test_set_power_dont_merge(abc, bc): # Make sure power commands are only merged with those of the same type bc.read_fpga_register.side_effect = mock_read_fpga_register bc.read_bmp_version.side_effect = mock_read_bmp_version event = OnDoneEvent() with abc: requests = AtomicRequests(event) requests.power(10, False) requests.power(11, True) requests.power(12, False) abc.add_requests(requests) event.wait() assert event.success assert bc.power_off.mock_calls == [ call(boards=[10, 12], frame=0, cabinet=0) ] assert bc.power_on.mock_calls == [ call(boards=[11], frame=0, cabinet=0), ]
def test_set_power_merge(abc, bc, power_side_effect, success): bc.power_off.side_effect = power_side_effect # Make sure we can queue up several power commands which will get merged # (and any errors duplicated). event = OnDoneEvent() with abc: requests = AtomicRequests(event) requests.power(10, False) requests.power(11, False) requests.power(13, False) abc.add_requests(requests) event.wait() assert event.success is success bc.power_off.assert_called_with(boards=[10, 11, 13], frame=0, cabinet=0)
def test_stop_drains(abc, bc): # Make sure that the queues are emptied before the stop command is # processed event = OnDoneEvent() bc.read_bmp_version.side_effect = mock_read_bmp_version with abc: requests = AtomicRequests(event) requests.power(10, False) requests.link(11, Links.east, False) abc.add_requests(requests) abc.stop() # Both of these should be carried out event.wait(0.5) assert event.success is True # And the loop should stop! abc.join()
def test_mock_abc(mock_abc, expected_success): """Meta testing: make sure the MockAsyncBMPController works.""" # Make sure callbacks are called from another thread threads = [] def cb(success): threads.append(threading.current_thread()) assert success is expected_success abc = mock_abc("foo") abc.success = expected_success assert abc.running_theads == 1 with abc: # If made atomically, should all fire at the end... requests = AtomicRequests(cb) requests.power(None, None) requests.link(None, None, None) abc.add_requests(requests) assert abc.add_requests_calls == [requests] # Make sure the background thread gets some execution time time.sleep(0.05) assert threads == [] # Make sure the background thread gets some execution time time.sleep(0.05) assert len(threads) == 1 assert threads[0] != threading.current_thread() abc.stop() abc.join() assert abc.running_theads == 0