diff --git a/.unreleased/LLT-5683 b/.unreleased/LLT-5683 new file mode 100644 index 000000000..d53e83c73 --- /dev/null +++ b/.unreleased/LLT-5683 @@ -0,0 +1 @@ +Increase constrains in link state testcases \ No newline at end of file diff --git a/nat-lab/tests/telio.py b/nat-lab/tests/telio.py index 528b0e328..5a3de9a7e 100644 --- a/nat-lab/tests/telio.py +++ b/nat-lab/tests/telio.py @@ -126,6 +126,13 @@ async def notify_peer_state( return await asyncio.sleep(0.1) + async def notify_link_state(self, public_key: str, states: List[LinkState]) -> None: + while True: + peer = self.get_peer_info(public_key) + if peer and peer.link_state in states: + return + await asyncio.sleep(0.1) + async def notify_peer_event( self, public_key: str, @@ -256,6 +263,16 @@ async def wait_for_state_peer( timeout, ) + async def wait_for_link_state( + self, + public_key: str, + state: List[LinkState], + timeout: Optional[float] = None, + ) -> None: + await asyncio.wait_for( + self._runtime.notify_link_state(public_key, state), timeout + ) + async def wait_for_event_peer( self, public_key: str, @@ -522,6 +539,18 @@ async def wait_for_state_peer( timeout, ) + async def wait_for_link_state( + self, + public_key: str, + states: List[LinkState], + timeout: Optional[float] = None, + ) -> None: + await self.get_events().wait_for_link_state( + public_key, + states, + timeout, + ) + async def wait_for_event_peer( self, public_key: str, diff --git a/nat-lab/tests/test_events_link_state.py b/nat-lab/tests/test_events_link_state.py index a540ce475..99b90611f 100644 --- a/nat-lab/tests/test_events_link_state.py +++ b/nat-lab/tests/test_events_link_state.py @@ -140,14 +140,27 @@ async def test_event_link_state_peers_idle_all_time( alpha, beta = env.nodes client_alpha, client_beta = env.clients - # Expect no link event while peers are idle - await asyncio.sleep(20) - alpha_events = client_beta.get_link_state_events(alpha.public_key) - beta_events = client_alpha.get_link_state_events(beta.public_key) + await client_alpha.wait_for_link_state(beta.public_key, [LinkState.UP]) + await client_beta.wait_for_link_state(alpha.public_key, [LinkState.UP]) - # 1 down event when Connecting, 1 up event when Connected - assert alpha_events == [LinkState.DOWN, LinkState.UP] - assert beta_events == [LinkState.DOWN, LinkState.UP] + # Expect no link event while peers are idle + with pytest.raises(asyncio.TimeoutError): + await asyncio.wait( + [ + asyncio.create_task( + client_alpha.wait_for_link_state( + beta.public_key, [LinkState.DOWN] + ) + ), + asyncio.create_task( + client_beta.wait_for_link_state( + alpha.public_key, [LinkState.DOWN] + ) + ), + ], + timeout=20, + return_when=asyncio.FIRST_COMPLETED, + ) @pytest.mark.asyncio @@ -163,18 +176,15 @@ async def test_event_link_state_peers_exchanging_data_for_a_long_time( conn.connection for conn in env.connections ] + await client_alpha.wait_for_link_state(beta.public_key, [LinkState.UP]) + await client_beta.wait_for_link_state(alpha.public_key, [LinkState.UP]) + for _ in range(0, 40): await asyncio.sleep(1) await ping(connection_alpha, beta.ip_addresses[0]) await ping(connection_beta, alpha.ip_addresses[0]) - - # Expect no nolink event while peers are active - alpha_events = client_beta.get_link_state_events(alpha.public_key) - beta_events = client_alpha.get_link_state_events(beta.public_key) - - # 1 down event when Connecting, 1 up event when Connected - assert alpha_events == [LinkState.DOWN, LinkState.UP] - assert beta_events == [LinkState.DOWN, LinkState.UP] + await client_alpha.wait_for_link_state(beta.public_key, [LinkState.UP], 1) + await client_beta.wait_for_link_state(alpha.public_key, [LinkState.UP], 1) @pytest.mark.asyncio @@ -190,21 +200,56 @@ async def test_event_link_state_peers_exchanging_data_then_idling_then_resume( conn.connection for conn in env.connections ] + await client_alpha.wait_for_link_state(beta.public_key, [LinkState.UP]) + await client_beta.wait_for_link_state(alpha.public_key, [LinkState.UP]) + await ping(connection_alpha, beta.ip_addresses[0]) await ping(connection_beta, alpha.ip_addresses[0]) # Expect no link event while peers are idle - await asyncio.sleep(20) + with pytest.raises(asyncio.TimeoutError): + await asyncio.wait( + [ + asyncio.create_task( + client_alpha.wait_for_link_state( + beta.public_key, [LinkState.DOWN] + ) + ), + asyncio.create_task( + client_beta.wait_for_link_state( + alpha.public_key, [LinkState.DOWN] + ) + ), + ], + timeout=25, + return_when=asyncio.FIRST_COMPLETED, + ) await ping(connection_alpha, beta.ip_addresses[0]) await ping(connection_beta, alpha.ip_addresses[0]) - alpha_events = client_beta.get_link_state_events(alpha.public_key) - beta_events = client_alpha.get_link_state_events(beta.public_key) - - # 1 down event when Connecting, 1 up event when Connected - assert alpha_events == [LinkState.DOWN, LinkState.UP] - assert beta_events == [LinkState.DOWN, LinkState.UP] + # Wait for another 5 seconds + with pytest.raises(asyncio.TimeoutError): + await asyncio.wait( + [ + asyncio.create_task( + client_alpha.wait_for_link_state( + beta.public_key, [LinkState.DOWN] + ) + ), + asyncio.create_task( + client_beta.wait_for_link_state( + alpha.public_key, [LinkState.DOWN] + ) + ), + ], + timeout=5, + return_when=asyncio.FIRST_COMPLETED, + ) + + # Expect the links are still UP + await client_alpha.wait_for_link_state(beta.public_key, [LinkState.UP], 1) + await client_beta.wait_for_link_state(alpha.public_key, [LinkState.UP], 1) @pytest.mark.asyncio @@ -220,24 +265,28 @@ async def test_event_link_state_peer_goes_offline( conn.connection for conn in env.connections ] + await client_alpha.wait_for_link_state(beta.public_key, [LinkState.UP]) + await client_beta.wait_for_link_state(alpha.public_key, [LinkState.UP]) + await ping(connection_alpha, beta.ip_addresses[0]) await ping(connection_beta, alpha.ip_addresses[0]) await client_beta.stop_device() - await asyncio.sleep(1) - with pytest.raises(asyncio.TimeoutError): - await ping(connection_alpha, beta.ip_addresses[0], 5) + await ping(connection_alpha, beta.ip_addresses[0], 3) - await asyncio.sleep(25) - alpha_events = client_beta.get_link_state_events(alpha.public_key) - beta_events = client_alpha.get_link_state_events(beta.public_key) + with pytest.raises(asyncio.TimeoutError): + await client_alpha.wait_for_link_state( + beta.public_key, [LinkState.DOWN], 10 + ) - # 1 down event when Connecting, 1 up event when Connected - assert alpha_events == [LinkState.DOWN, LinkState.UP] - # 1 down event when Connecting, 1 up event when Connected, 1 down event when client is stopped - assert beta_events == [LinkState.DOWN, LinkState.UP, LinkState.DOWN] + # Expect the link down event + # It should arrive in 11-15 seconds after the link is cut and ping mod disabled + # And 22-25 seconds if the ping mod is enabled + await client_alpha.wait_for_link_state(beta.public_key, [LinkState.DOWN], 30) + # Although the beta device has been stopped, it should still see alpha as up + await client_beta.wait_for_link_state(alpha.public_key, [LinkState.UP], 5) @pytest.mark.asyncio @@ -315,24 +364,29 @@ async def test_event_link_state_peer_doesnt_respond( conn.connection for conn in env.connections ] + await client_alpha.wait_for_link_state(beta.public_key, [LinkState.UP]) + await client_beta.wait_for_link_state(alpha.public_key, [LinkState.UP]) + async with ICMP_control(connection_beta): with pytest.raises(asyncio.TimeoutError): - await ping(connection_alpha, beta.ip_addresses[0], 8) - - alpha_events = client_beta.get_link_state_events(alpha.public_key) - beta_events = client_alpha.get_link_state_events(beta.public_key) - - # The connection is normal and events should be: initial down, then several up events but no more down events - assert alpha_events.count(LinkState.DOWN) == 1 - assert beta_events.count(LinkState.DOWN) == 1 - - # wait enough to pass 10 second mark since our ping request, which should trigger passive-keepalive by wireguard - await asyncio.sleep(5) + await ping(connection_alpha, beta.ip_addresses[0], 5) - alpha_events = client_beta.get_link_state_events(alpha.public_key) - beta_events = client_alpha.get_link_state_events(beta.public_key) - - # there should be no additional link down event - - assert alpha_events.count(LinkState.DOWN) == 1 - assert beta_events.count(LinkState.DOWN) == 1 + # Wait enough to pass 10 second mark since our ping request, which should trigger passive-keepalive by wireguard + # + some delay for ping mode + with pytest.raises(asyncio.TimeoutError): + await asyncio.wait( + [ + asyncio.create_task( + client_alpha.wait_for_link_state( + beta.public_key, [LinkState.DOWN] + ) + ), + asyncio.create_task( + client_beta.wait_for_link_state( + alpha.public_key, [LinkState.DOWN] + ) + ), + ], + timeout=25, + return_when=asyncio.FIRST_COMPLETED, + )