Exemple #1
0
async def test_replay_ending_cancels_timeouts(event_loop, replay_deps):
    mock_merger, mock_sender, _ = replay_deps
    conf = MockReplayConfig(15, 100)
    replay = Replay(*replay_deps, conf, 1)
    exhaust_callbacks(event_loop)
    replay.close()
    mock_merger.stop_accepting_connections.assert_called()
    mock_sender.stop_accepting_connections.assert_called()
    mock_merger.stop_accepting_connections.reset_mock()
    mock_sender.stop_accepting_connections.reset_mock()

    # Replay expects these to end after calling close
    mock_merger.wait_for_ended._lock.set()
    mock_sender.wait_for_ended._lock.set()
    await replay.wait_for_ended()

    # Did replay stop waiting until merger says there aren't more connections?
    await asyncio.sleep(1)
    mock_merger.no_connections_for._lock.set()

    # Did replay stop waiting for its own timeout?
    await asyncio.sleep(19)
    exhaust_callbacks(event_loop)
    mock_merger.stop_accepting_connections.assert_not_called()
    mock_sender.stop_accepting_connections.assert_not_called()
async def test_replay_forwarding_connections(event_loop, mock_merger,
                                             mock_sender, mock_bookkeeper,
                                             mock_conn_plus_head):
    reader = mock_conn_plus_head(ConnectionHeader.Type.READER, 1)
    writer = mock_conn_plus_head(ConnectionHeader.Type.WRITER, 1)
    invalid = mock_conn_plus_head(17, 1)
    timeout = 15
    replay = Replay(mock_merger, mock_sender, mock_bookkeeper, timeout, 1)

    await replay.handle_connection(*reader)
    mock_merger.handle_connection.assert_not_awaited()
    mock_sender.handle_connection.assert_awaited_with(reader[1])
    mock_sender.handle_connection.reset_mock()

    await replay.handle_connection(*writer)
    mock_sender.handle_connection.assert_not_awaited()
    mock_merger.handle_connection.assert_awaited_with(writer[1])
    mock_merger.handle_connection.reset_mock()

    with pytest.raises(MalformedDataError):
        await replay.handle_connection(*invalid)
    mock_sender.handle_connection.assert_not_awaited()
    mock_merger.handle_connection.assert_not_awaited()

    mock_merger._manual_end.set()
    mock_sender._manual_end.set()
    await replay.wait_for_ended()
Exemple #3
0
async def test_replay_forwarding_connections(event_loop, replay_deps,
                                             mock_conn_plus_head):
    mock_merger, mock_sender, _ = replay_deps
    reader = mock_conn_plus_head(ConnectionHeader.Type.READER, 1)
    writer = mock_conn_plus_head(ConnectionHeader.Type.WRITER, 1)
    invalid = mock_conn_plus_head(17, 1)
    conf = MockReplayConfig(15, 100)
    replay = Replay(*replay_deps, conf, 1)

    mock_sender.handle_connection._lock.set()
    mock_merger.handle_connection._lock.set()

    await replay.handle_connection(*reader)
    mock_merger.handle_connection.assert_not_awaited()
    mock_sender.handle_connection.assert_awaited_with(reader[1])
    mock_sender.handle_connection.reset_mock()

    await replay.handle_connection(*writer)
    mock_sender.handle_connection.assert_not_awaited()
    mock_merger.handle_connection.assert_awaited_with(writer[1])
    mock_merger.handle_connection.reset_mock()

    with pytest.raises(MalformedDataError):
        await replay.handle_connection(*invalid)
    mock_sender.handle_connection.assert_not_awaited()
    mock_merger.handle_connection.assert_not_awaited()

    mock_merger.wait_for_ended._lock.set()
    mock_sender.wait_for_ended._lock.set()
    await replay.wait_for_ended()
Exemple #4
0
async def test_replay_diverging_replay(event_loop, mock_bookkeeper,
                                       controlled_connections):

    r = Replay.build(1, mock_bookkeeper, replay_config(config_dict))
    conns = [controlled_connections() for _ in range(0, 6)]
    conn_work = [do_write(c, div, 4000) for c, div in zip(conns, diverging_1)]
    read_conn = controlled_connections()

    head = ConnectionHeader(ConnectionHeader.Type.WRITER, 1, "foo")
    read_head = ConnectionHeader(ConnectionHeader.Type.READER, 1, "foo")
    r_work = [r.handle_connection(head, c) for c in conns]
    w_work = [r.handle_connection(read_head, read_conn)]

    # Version 5 is the best for this replay.
    # We don't require picking a specific header, its dicts have unspecified
    # order :/
    def check_saved(_, s):
        body_offset = diverging_1[5].header_size
        assert s.data.bytes() == diverging_1[5].data[body_offset:]

    mock_bookkeeper.save_replay.side_effect = check_saved

    await asyncio.gather(*(conn_work + r_work + w_work))
    await r.wait_for_ended()
    # Our current strategy should find replay 5, ignoring header.
    read_data = read_conn._get_mock_write_data()[diverging_1[5].header_size:]
    assert read_data == diverging_1[5].main_data
Exemple #5
0
async def test_replay_timeouts_while_ending_dont_explode(
        event_loop, replay_deps):
    mock_merger, mock_sender, _ = replay_deps
    conf = MockReplayConfig(15, 100)
    replay = Replay(*replay_deps, conf, 1)
    exhaust_callbacks(event_loop)

    # Won't finish until we tell mock merger & sender to end
    f = asyncio.ensure_future(replay.wait_for_ended())

    await asyncio.sleep(1)
    mock_merger.no_connections_for._lock.set()

    await asyncio.sleep(19)
    exhaust_callbacks(event_loop)

    mock_merger.wait_for_ended._lock.set()
    mock_sender.wait_for_ended._lock.set()
    await f
Exemple #6
0
async def test_replay_closes_after_timeout(event_loop, replay_deps,
                                           mock_conn_plus_head):
    mock_merger, mock_sender, _ = replay_deps
    conf = MockReplayConfig(15, 100)
    replay = Replay(*replay_deps, conf, 1)
    mock_merger.stop_accepting_connections.assert_not_called()
    mock_sender.stop_accepting_connections.assert_not_called()

    writer = mock_conn_plus_head(ConnectionHeader.Type.WRITER, 1)
    wf = asyncio.ensure_future(replay.handle_connection(*writer))

    await asyncio.sleep(20)
    exhaust_callbacks(event_loop)
    mock_merger.stop_accepting_connections.assert_called()
    mock_sender.stop_accepting_connections.assert_called()
    writer[1].close.assert_called()

    mock_merger.handle_connection._lock.set()
    mock_merger.wait_for_ended._lock.set()
    mock_sender.wait_for_ended._lock.set()
    await wf
    await replay.wait_for_ended()
async def test_replay_close_cancels_timeout(
        event_loop, mock_merger, mock_sender, mock_bookkeeper):
    timeout = 15
    replay = Replay(mock_merger, mock_sender, mock_bookkeeper, timeout, 1)
    exhaust_callbacks(event_loop)
    replay.close()
    mock_merger.close.assert_called()
    mock_sender.close.assert_called()
    mock_merger.close.reset_mock()
    mock_sender.close.reset_mock()

    # Replay expects these to end after calling close
    mock_merger._manual_end.set()
    mock_sender._manual_end.set()

    await asyncio.sleep(20)
    exhaust_callbacks(event_loop)
    mock_merger.close.assert_not_called()
    mock_sender.close.assert_not_called()

    mock_merger._manual_end.set()
    mock_sender._manual_end.set()
    await replay.wait_for_ended()
async def test_replay_closes_after_timeout(
        event_loop, mock_merger, mock_sender, mock_bookkeeper):
    timeout = 15
    replay = Replay(mock_merger, mock_sender, mock_bookkeeper, timeout, 1)
    mock_merger.close.assert_not_called()
    mock_sender.close.assert_not_called()
    await asyncio.sleep(20)
    exhaust_callbacks(event_loop)
    mock_merger.close.assert_called()
    mock_sender.close.assert_called()

    mock_merger._manual_end.set()
    mock_sender._manual_end.set()
    await replay.wait_for_ended()
async def test_replay_keeps_proper_event_order(
        event_loop, mock_merger, mock_sender, mock_bookkeeper):

    async def bookkeeper_check(*args, **kwargs):
        # Merging has to end before bookkeeping starts
        mock_merger.wait_for_ended.assert_awaited()
        # We shall not wait for stream sending to end before bookkeeping
        mock_sender.wait_for_ended.assert_not_awaited()
        return

    mock_bookkeeper.save_replay.side_effect = bookkeeper_check

    timeout = 0.1
    replay = Replay(mock_merger, mock_sender, mock_bookkeeper, timeout, 1)
    await exhaust_callbacks(event_loop)
    mock_merger._manual_end.set()
    await exhaust_callbacks(event_loop)
    mock_sender._manual_end.set()
    await replay.wait_for_ended()
Exemple #10
0
async def test_replay_keeps_proper_event_order(event_loop, mocker,
                                               replay_deps):
    merger, sender, bookkeeper = replay_deps

    async def bookkeeper_check(game_id, stream):
        assert stream is merger.canonical_stream
        # Merging has to end before bookkeeping starts
        merger.wait_for_ended.assert_awaited()
        # We shall not wait for stream sending to end before bookkeeping
        sender.wait_for_ended.assert_not_awaited()
        return

    bookkeeper.save_replay.side_effect = bookkeeper_check

    conf = MockReplayConfig(0.1, 100)
    replay = Replay(*replay_deps, conf, 1)
    await exhaust_callbacks(event_loop)
    merger.wait_for_ended._lock.set()
    await exhaust_callbacks(event_loop)
    sender.wait_for_ended._lock.set()
    await replay.wait_for_ended()
Exemple #11
0
 def build(cls, bookkeeper, config):
     return cls(lambda game_id: Replay.build(game_id, bookkeeper, config))
Exemple #12
0
def test_replay_init(mock_bookkeeper):
    Replay.build(1, mock_bookkeeper, replay_config(config_dict))
Exemple #13
0
def test_replay_init(mock_bookkeeper):
    Replay.build(1, mock_bookkeeper, **config)
 def build(cls, bookkeeper, **kwargs):
     return cls(lambda game_id: Replay.build(game_id, bookkeeper, **kwargs))