Skip to content

Commit

Permalink
Fix wireguard rotation test
Browse files Browse the repository at this point in the history
The test was flaky because if a race condition which made the key
rotation missable.
  • Loading branch information
Serock3 committed Apr 9, 2024
1 parent ba74196 commit 6d0f5e8
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 22 deletions.
4 changes: 2 additions & 2 deletions mullvad-management-interface/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ use mullvad_types::{
version::AppVersionInfo,
wireguard::{PublicKey, QuantumResistantState, RotationInterval},
};
use std::path::Path;
use std::str::FromStr;
use std::{path::Path, str::FromStr};
#[cfg(target_os = "windows")]
use talpid_types::split_tunnel::ExcludedProcess;
use tonic::{Code, Status};
Expand All @@ -29,6 +28,7 @@ pub type Result<T> = std::result::Result<T, super::Error>;
#[derive(Debug, Clone)]
pub struct MullvadProxyClient(crate::ManagementServiceClient);

#[derive(Debug)]
pub enum DaemonEvent {
TunnelState(TunnelState),
Settings(Settings),
Expand Down
58 changes: 38 additions & 20 deletions test/test-manager/src/tests/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,50 +288,68 @@ pub async fn test_automatic_wireguard_rotation(
.device
.pubkey;

// Stop daemon
log::info!("Old wireguard key: {old_key}");

log::info!("Stopping deamon");
rpc.stop_mullvad_daemon()
.await
.expect("Could not stop system service");

// Open device.json and change created field to more than 7 days ago
log::info!("Mutating device.json change created field to more than 7 days ago");
rpc.make_device_json_old()
.await
.expect("Could not change device.json to have an old created timestamp");

// Start daemon
log::info!("Starting deamon");
rpc.start_mullvad_daemon()
.await
.expect("Could not start system service");

// NOTE: Need to create a new `mullvad_client` here after the restart otherwise we can't
// communicate with the daemon
log::info!("Reconnecting to daemon");
drop(mullvad_client);
let mut mullvad_client = ctx.rpc_provider.new_client().await;

// Verify rotation has happened after a minute
const KEY_ROTATION_TIMEOUT: Duration = Duration::from_secs(100);
log::info!("Verifying that wireguard key has change");

// Check if the key rotation has already occurred when connected to the daemon, otherwise
// listen for device daemon events until we se the change. We have to register the event
// listener before polling the current key to be sure we don't miss the change.
let event_listener = mullvad_client.events_listen().await.unwrap();
let new_key = mullvad_client
.get_device()
.await
.unwrap()
.into_device()
.expect("Could not get device")
.device
.pubkey;

let new_key = tokio::time::timeout(
KEY_ROTATION_TIMEOUT,
helpers::find_daemon_event(
mullvad_client.events_listen().await.unwrap(),
|daemon_event| match daemon_event {
// Current key not yet updated
if new_key == old_key {
log::info!("Listening for device daemon event");
// Verify rotation has happened within a minute
let device_event = tokio::task::spawn(tokio::time::timeout(
Duration::from_secs(100),
helpers::find_daemon_event(event_listener, |daemon_event| match daemon_event {
DaemonEvent::Device(device_event) => Some(device_event),
_ => None,
},
),
)
.await
.map_err(|_error| Error::Daemon(String::from("Tunnel event listener timed out")))?
.map(|device_event| {
device_event
}),
))
.await
.unwrap()
.map_err(|_error| Error::Daemon(String::from("Tunnel event listener timed out")))??;

let new_key = device_event
.new_state
.into_device()
.expect("Could not get device")
.device
.pubkey
})?;
.pubkey;

assert_ne!(old_key, new_key);
}

assert_ne!(old_key, new_key);
Ok(())
}

0 comments on commit 6d0f5e8

Please sign in to comment.