Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use low latency servers for all tests #7184

Merged
merged 5 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions mullvad-relay-selector/src/relay_selector/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ impl RelayQuery {
&self.openvpn_constraints
}

pub fn into_openvpn_constraints(self) -> OpenVpnRelayQuery {
self.openvpn_constraints
}

pub fn set_openvpn_constraints(
&mut self,
openvpn_constraints: OpenVpnRelayQuery,
Expand All @@ -165,6 +169,10 @@ impl RelayQuery {
&self.wireguard_constraints
}

pub fn into_wireguard_constraints(self) -> WireguardRelayQuery {
self.wireguard_constraints
}

pub fn set_wireguard_constraints(
&mut self,
wireguard_constraints: WireguardRelayQuery,
Expand Down Expand Up @@ -890,9 +898,8 @@ pub mod builder {

impl<Transport> RelayQueryBuilder<OpenVPN<Transport, BridgeConstraints>> {
/// Constraint the geographical location of the selected bridge.
pub fn bridge_location(mut self, location: GeographicLocationConstraint) -> Self {
self.protocol.bridge_settings.location =
Constraint::Only(LocationConstraint::from(location));
pub fn bridge_location(mut self, location: impl Into<LocationConstraint>) -> Self {
self.protocol.bridge_settings.location = Constraint::Only(location.into());
self.query.openvpn_constraints.bridge_settings =
BridgeQuery::Normal(self.protocol.bridge_settings.clone());
self
Expand Down
44 changes: 38 additions & 6 deletions test/test-manager/src/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ pub async fn constrain_to_relay(
///
/// This can be used to query the relay selector without triggering a tunnel state change in the
/// daemon.
fn get_daemon_relay_selector(
pub fn get_daemon_relay_selector(
settings: &mullvad_types::settings::Settings,
relay_list: mullvad_types::relay_list::RelayList,
) -> RelaySelector {
Expand All @@ -767,7 +767,7 @@ pub fn into_constraint(relay: &Relay) -> Constraint<LocationConstraint> {

/// Ping monitoring made easy!
///
/// Continously ping some destination while monitoring to detect diverging
/// Continuously ping some destination while monitoring to detect diverging
/// packets.
///
/// To customize [`Pinger`] before the pinging and network monitoring starts,
Expand Down Expand Up @@ -897,7 +897,7 @@ impl PingerBuilder {
}
}

/// This helper spawns a seperate process which checks if we are connected to Mullvad, and tries to
/// This helper spawns a separate process which checks if we are connected to Mullvad, and tries to
/// leak traffic outside the tunnel by sending TCP, UDP, and ICMP packets to [LEAK_DESTINATION].
pub struct ConnChecker {
rpc: ServiceClient,
Expand Down Expand Up @@ -962,7 +962,7 @@ impl ConnChecker {
self.payload = Some(payload.into())
}

/// Spawn the connecton checker process and return a handle to it.
/// Spawn the connection checker process and return a handle to it.
///
/// Dropping the handle will stop the process.
/// **NOTE**: The handle must be dropped from a tokio runtime context.
Expand Down Expand Up @@ -1101,7 +1101,7 @@ impl ConnCheckerHandle<'_> {
}

pub async fn check_connection(&mut self) -> anyhow::Result<ConnectionStatus> {
// Monitor all pakets going to LEAK_DESTINATION during the check.
// Monitor all packets going to LEAK_DESTINATION during the check.
let leak_destination = self.checker.leak_destination;
let monitor = start_packet_monitor(
move |packet| packet.destination.ip() == leak_destination.ip(),
Expand Down Expand Up @@ -1201,18 +1201,22 @@ fn parse_am_i_mullvad(result: String) -> anyhow::Result<bool> {

pub mod custom_lists {
use super::*;

use mullvad_types::custom_list::{CustomList, Id};
use std::sync::{LazyLock, Mutex};

// Expose all custom list variants as a shorthand.
pub use List::*;

/// The default custom list to use as location for all tests.
pub const DEFAULT_LIST: List = List::Nordic;

/// Mapping between [List] to daemon custom lists. Since custom list ids are assigned by the
/// daemon at the creation of the custom list settings object, we can't map a custom list
/// name to a specific list before runtime.
static IDS: LazyLock<Mutex<HashMap<List, Id>>> = LazyLock::new(|| Mutex::new(HashMap::new()));

/// Pre-defined (well-typed) custom lists which may be useuful in different test scenarios.
/// Pre-defined (well-typed) custom lists which may be useful in different test scenarios.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum List {
/// A selection of Nordic servers
Expand Down Expand Up @@ -1310,6 +1314,34 @@ pub mod custom_lists {
Ok(())
}

/// Set the default location to the custom list specified by `DEFAULT_LIST`. This also includes
/// entry location for multihop. It does not, however, affect bridge location for OpenVPN.
/// This is for simplify, as bridges default to using the server closest to the exit anyway, and
/// OpenVPN is slated for removal.
pub async fn set_default_location(
mullvad_client: &mut MullvadProxyClient,
) -> anyhow::Result<()> {
let constraints = get_custom_list_location_relay_constraints(DEFAULT_LIST);

mullvad_client
.set_relay_settings(constraints.into())
.await
.context("Failed to set relay settings")
}

fn get_custom_list_location_relay_constraints(custom_list: List) -> RelayConstraints {
let wireguard_constraints = mullvad_types::relay_constraints::WireguardConstraints {
entry_location: Constraint::Only(custom_list.into()),
..Default::default()
};

RelayConstraints {
location: Constraint::Only(custom_list.into()),
wireguard_constraints,
..Default::default()
}
}

/// Dig out a custom list from the daemon settings based on the custom list's name.
/// There should be an rpc for this.
async fn find_custom_list(
Expand Down
19 changes: 11 additions & 8 deletions test/test-manager/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,12 @@ pub fn get_tests() -> Vec<&'static TestMetadata> {
}

pub fn get_filtered_tests(specified_tests: &[String]) -> Result<Vec<&TestMetadata>, anyhow::Error> {
let mut tests = get_tests();
tests.retain(|test| test.should_run_on_os(TEST_CONFIG.os));
if !specified_tests.is_empty() {
let tests = get_tests();

let mut tests = if specified_tests.is_empty() {
// Keep all tests
tests
} else {
specified_tests
.iter()
.map(|f| {
Expand All @@ -95,11 +98,10 @@ pub fn get_filtered_tests(specified_tests: &[String]) -> Result<Vec<&TestMetadat
.cloned()
.ok_or(anyhow::anyhow!("Test '{f}' not found"))
})
.collect()
} else {
// Keep all tests
Ok(tests)
}
.collect::<Result<_, anyhow::Error>>()?
};
tests.retain(|test| test.should_run_on_os(TEST_CONFIG.os));
Ok(tests)
}

/// Make sure the daemon is installed and logged in and restore settings to the defaults.
Expand All @@ -122,6 +124,7 @@ pub async fn prepare_daemon(
.context("Failed to disconnect daemon after test")?;
helpers::ensure_logged_in(&mut mullvad_client).await?;
helpers::custom_lists::add_default_lists(&mut mullvad_client).await?;
helpers::custom_lists::set_default_location(&mut mullvad_client).await?;

Ok(())
}
Expand Down
10 changes: 5 additions & 5 deletions test/test-manager/src/tests/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub async fn test_ui_tunnel_settings(
rpc: ServiceClient,
mut mullvad_client: MullvadProxyClient,
) -> anyhow::Result<()> {
// NOTE: This test connects multiple times using various settings, some of which may cauase a
// NOTE: This test connects multiple times using various settings, some of which may cause a
// significant increase in connection time, e.g. multihop and OpenVPN. For this reason, it is
// preferable to only target low latency servers.
use helpers::custom_lists::LowLatency;
Expand Down Expand Up @@ -223,8 +223,6 @@ async fn test_custom_bridge_gui(
rpc: ServiceClient,
mut mullvad_client: MullvadProxyClient,
) -> Result<(), Error> {
use mullvad_relay_selector::{RelaySelector, SelectorConfig};

// For this test to work, we need to supply the following env-variables:
//
// * SHADOWSOCKS_SERVER_IP
Expand All @@ -238,8 +236,10 @@ async fn test_custom_bridge_gui(
// `test_manager::tests::access_methods::test_shadowsocks`.

let gui_test = "custom-bridge.spec";

let settings = mullvad_client.get_settings().await.unwrap();
let relay_list = mullvad_client.get_relay_locations().await.unwrap();
let relay_selector = RelaySelector::from_list(SelectorConfig::default(), relay_list);
let relay_selector = helpers::get_daemon_relay_selector(&settings, relay_list);
let custom_proxy = relay_selector
.get_bridge_forced()
.expect("`test_shadowsocks` needs at least one shadowsocks relay to execute. Found none in relay list.");
Expand Down Expand Up @@ -279,7 +279,7 @@ pub async fn test_import_settings_ui(_: TestContext, rpc: ServiceClient) -> Resu
Ok(())
}

/// Test obufscation settings in the GUI
/// Test obfuscation settings in the GUI
#[test_function]
pub async fn test_obfuscation_settings_ui(_: TestContext, rpc: ServiceClient) -> Result<(), Error> {
let ui_result = run_test(&rpc, &["obfuscation.spec"]).await?;
Expand Down
Loading