mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
test(connlib): ensure portal init doesn't interrupt data plane (#5899)
The connection to the portal could be interrupted at any point, most notably when it is being re-deployed. Doing so results in a new `init` message being pushed to all clients and gateways. This must not interrupt the data plane. To ensure this, we add a new `ReconnectPortal` transition to `tunnel_test` where we simulate receiving a new `init` message with the same values as we already have locally, i.e. same set of relays and resources. This resolves an existing TODO where the logic of performing non-destructive updates to resources in `set_resources` wasn't tested.
This commit is contained in:
@@ -156,6 +156,7 @@ impl ReferenceStateMachine for ReferenceState {
|
||||
question_mark_wildcard_dns_resource(sample::select(state.portal.all_sites())),
|
||||
],
|
||||
)
|
||||
.with(1, Just(Transition::ReconnectPortal))
|
||||
.with_if_not_empty(
|
||||
10,
|
||||
state.client.inner().ipv4_cidr_resource_dsts(),
|
||||
@@ -372,6 +373,9 @@ impl ReferenceStateMachine for ReferenceState {
|
||||
.client
|
||||
.exec_mut(|client| client.connected_dns_resources.clear());
|
||||
}
|
||||
Transition::ReconnectPortal => {
|
||||
// Reconnecting to the portal should have no noticeable impact on the data plane.
|
||||
}
|
||||
};
|
||||
|
||||
state
|
||||
@@ -557,6 +561,7 @@ impl ReferenceStateMachine for ReferenceState {
|
||||
|
||||
!is_assigned_ip4 && !is_assigned_ip6 && !is_previous_port
|
||||
}
|
||||
Transition::ReconnectPortal => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,6 +256,25 @@ impl StateMachineTest for TunnelTest {
|
||||
.set_resources(ref_state.client.inner().all_resources());
|
||||
});
|
||||
}
|
||||
Transition::ReconnectPortal => {
|
||||
let ipv4 = state.client.inner().sut.tunnel_ip4().unwrap();
|
||||
let ipv6 = state.client.inner().sut.tunnel_ip6().unwrap();
|
||||
let upstream_dns = ref_state.client.inner().upstream_dns_resolvers.clone();
|
||||
let relays = HashSet::from_iter(map_explode(state.relays.iter(), "client"));
|
||||
let all_resources = ref_state.client.inner().all_resources();
|
||||
|
||||
// Simulate receiving `init`.
|
||||
state.client.exec_mut(|c| {
|
||||
let _ = c.sut.update_interface_config(Interface {
|
||||
ipv4,
|
||||
ipv6,
|
||||
upstream_dns,
|
||||
});
|
||||
c.sut
|
||||
.update_relays(HashSet::default(), relays, ref_state.now);
|
||||
c.sut.set_resources(all_resources);
|
||||
});
|
||||
}
|
||||
};
|
||||
state.advance(ref_state, &mut buffered_transmits);
|
||||
assert!(buffered_transmits.is_empty()); // Sanity check to ensure we handled all packets.
|
||||
|
||||
@@ -83,6 +83,9 @@ pub(crate) enum Transition {
|
||||
ip6: Option<Ipv6Addr>,
|
||||
port: u16,
|
||||
},
|
||||
|
||||
/// Reconnect to the portal.
|
||||
ReconnectPortal,
|
||||
}
|
||||
|
||||
pub(crate) fn ping_random_ip<I>(
|
||||
|
||||
Reference in New Issue
Block a user