From 3212fc74f9a91b8e0bebbea5f24ea2e15b1585af Mon Sep 17 00:00:00 2001 From: Markus Pettersson Date: Mon, 8 Jan 2024 15:20:24 +0100 Subject: [PATCH] Use type safe Mullvad protobuf client over generated dito Re-write some code in the test framework to prefer the type safe wrapper around the Mullvad app gRPC client instead of its auto-generated dito. `ManagementServiceClient` is automatically generated from the protobuf definitions found in `management_interface.proto`, and contains some very crude types. The `MullvadProxyClient` is a type-safe wrapper around `ManagementServiceClient` which performs conversions & validation of the data types from the gRPC server (the daemon) to their respective mappings in the `talpid-*` and `mullvad-*` crates. These types are more ergonomic to work with, and since we already have the conversions in place we should prefer those. --- test/clippy.toml | 3 + test/test-manager/README.md | 2 +- test/test-manager/src/mullvad_daemon.rs | 7 +- test/test-manager/src/run_tests.rs | 4 +- test/test-manager/src/tests/account.rs | 125 ++++++++++--------- test/test-manager/src/tests/dns.rs | 114 +++++++++--------- test/test-manager/src/tests/helpers.rs | 126 +++++++------------- test/test-manager/src/tests/install.rs | 47 +++----- test/test-manager/src/tests/mod.rs | 61 +++------- test/test-manager/src/tests/settings.rs | 8 +- test/test-manager/src/tests/software.rs | 4 +- test/test-manager/src/tests/tunnel.rs | 84 +++++++------ test/test-manager/src/tests/tunnel_state.rs | 22 ++-- test/test-manager/src/tests/ui.rs | 4 +- test/test-manager/test_macro/src/lib.rs | 20 ++-- 15 files changed, 277 insertions(+), 354 deletions(-) create mode 100644 test/clippy.toml diff --git a/test/clippy.toml b/test/clippy.toml new file mode 100644 index 000000000000..facf0ff694bd --- /dev/null +++ b/test/clippy.toml @@ -0,0 +1,3 @@ +disallowed-types = [ + { path = "mullvad_management_interface::ManagementServiceClient", reason = "use `mullvad_management_interface::MullvadProxyClient` instead" }, +] diff --git a/test/test-manager/README.md b/test/test-manager/README.md index 16a1b8ac6cd7..c35e7c5ba7d8 100644 --- a/test/test-manager/README.md +++ b/test/test-manager/README.md @@ -13,7 +13,7 @@ with the `#[test_function]` attribute #[test_function] pub async fn test( rpc: ServiceClient, - mut mullvad_client: mullvad_management_interface::ManagementServiceClient, + mut mullvad_client: mullvad_management_interface::MullvadProxyClient, ) -> Result<(), Error> { Ok(()) } diff --git a/test/test-manager/src/mullvad_daemon.rs b/test/test-manager/src/mullvad_daemon.rs index e467940d5824..e1a7680cb458 100644 --- a/test/test-manager/src/mullvad_daemon.rs +++ b/test/test-manager/src/mullvad_daemon.rs @@ -1,7 +1,8 @@ +#![allow(clippy::disallowed_types)] use std::{io, time::Duration}; use futures::{channel::mpsc, future::BoxFuture, pin_mut, FutureExt, SinkExt, StreamExt}; -use mullvad_management_interface::ManagementServiceClient; +use mullvad_management_interface::{ManagementServiceClient, MullvadProxyClient}; use test_rpc::{ mullvad_daemon::MullvadClientVersion, transport::{ConnectionHandle, GrpcForwarder}, @@ -61,7 +62,7 @@ impl RpcClientProvider { } } - pub async fn new_client(&self) -> ManagementServiceClient { + pub async fn new_client(&self) -> MullvadProxyClient { // FIXME: Ugly workaround to ensure that we don't receive stuff from a // previous RPC session. tokio::time::sleep(std::time::Duration::from_millis(500)).await; @@ -72,7 +73,7 @@ impl RpcClientProvider { .await .unwrap(); - ManagementServiceClient::new(channel) + MullvadProxyClient::from_rpc_client(ManagementServiceClient::new(channel)) } } diff --git a/test/test-manager/src/run_tests.rs b/test/test-manager/src/run_tests.rs index b316511b06f0..756d8d8b4540 100644 --- a/test/test-manager/src/run_tests.rs +++ b/test/test-manager/src/run_tests.rs @@ -8,7 +8,7 @@ use crate::{ }; use anyhow::{Context, Result}; use futures::FutureExt; -use mullvad_management_interface::ManagementServiceClient; +use mullvad_management_interface::MullvadProxyClient; use std::future::Future; use std::panic; use std::time::Duration; @@ -84,7 +84,7 @@ pub async fn run( .as_type(test.mullvad_client_version) .await; - if let Some(client) = mclient.downcast_mut::() { + if let Some(client) = mclient.downcast_mut::() { crate::tests::init_default_settings(client).await; } diff --git a/test/test-manager/src/tests/account.rs b/test/test-manager/src/tests/account.rs index d30d0330f062..3a774603acdf 100644 --- a/test/test-manager/src/tests/account.rs +++ b/test/test-manager/src/tests/account.rs @@ -1,8 +1,8 @@ use super::config::TEST_CONFIG; use super::{helpers, ui, Error, TestContext}; use mullvad_api::DevicesProxy; -use mullvad_management_interface::{types, Code, ManagementServiceClient}; -use mullvad_types::device::Device; +use mullvad_management_interface::{self, client::DaemonEvent, MullvadProxyClient}; +use mullvad_types::device::{Device, DeviceState}; use mullvad_types::states::TunnelState; use std::net::ToSocketAddrs; use std::time::Duration; @@ -17,7 +17,7 @@ const THROTTLE_RETRY_DELAY: Duration = Duration::from_secs(120); pub async fn test_login( _: TestContext, _rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { // // Instruct daemon to log in @@ -33,7 +33,7 @@ pub async fn test_login( .expect("login failed"); // Wait for the relay list to be updated - helpers::ensure_updated_relay_list(&mut mullvad_client).await; + helpers::ensure_updated_relay_list(&mut mullvad_client).await?; Ok(()) } @@ -44,12 +44,12 @@ pub async fn test_login( pub async fn test_logout( _: TestContext, _rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { log::info!("Removing device"); mullvad_client - .logout_account(()) + .logout_account() .await .expect("logout failed"); @@ -61,7 +61,7 @@ pub async fn test_logout( pub async fn test_too_many_devices( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { log::info!("Using up all devices"); @@ -97,7 +97,10 @@ pub async fn test_too_many_devices( log::info!("Log in with too many devices"); let login_result = login_with_retries(&mut mullvad_client).await; - assert!(matches!(login_result, Err(status) if status.code() == Code::ResourceExhausted)); + assert!(matches!( + login_result, + Err(mullvad_management_interface::Error::TooManyDevices) + )); // Run UI test let ui_result = ui::run_test_env( @@ -128,7 +131,7 @@ pub async fn test_too_many_devices( pub async fn test_revoked_device( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { log::info!("Logging in/generating device"); login_with_retries(&mut mullvad_client) @@ -136,14 +139,12 @@ pub async fn test_revoked_device( .expect("login failed"); let device_id = mullvad_client - .get_device(()) + .get_device() .await .expect("failed to get device data") - .into_inner() - .device + .into_device() .unwrap() .device - .unwrap() .id; helpers::connect_and_wait(&mut mullvad_client).await?; @@ -165,16 +166,16 @@ pub async fn test_revoked_device( // Begin listening to tunnel state changes first, so that we catch changes due to // `update_device`. let events = mullvad_client - .events_listen(()) + .events_listen() .await - .expect("failed to begin listening for state changes") - .into_inner(); + .expect("failed to begin listening for state changes"); let next_state = helpers::find_next_tunnel_state(events, |state| matches!(state, TunnelState::Error(..),)); log::debug!("Update device state"); - let _update_status = mullvad_client.update_device(()).await; + // Update the device status, which performs a device validation. + let _ = mullvad_client.update_device().await; // Ensure that the tunnel state transitions to "error". Fail if it transitions to some other // state. @@ -186,12 +187,11 @@ pub async fn test_revoked_device( // Verify that the device state is `Revoked`. let device_state = mullvad_client - .get_device(()) + .get_device() .await .expect("failed to get device data"); - assert_eq!( - device_state.into_inner().state, - i32::from(types::device_state::State::Revoked), + assert!( + matches!(device_state, DeviceState::Revoked), "expected device to be revoked" ); @@ -244,28 +244,26 @@ pub async fn new_device_client() -> DevicesProxy { /// Log in and retry if it fails due to throttling pub async fn login_with_retries( - mullvad_client: &mut ManagementServiceClient, -) -> Result<(), mullvad_management_interface::Status> { + mullvad_client: &mut MullvadProxyClient, +) -> Result<(), mullvad_management_interface::Error> { loop { - let result = mullvad_client + match mullvad_client .login_account(TEST_CONFIG.account_number.clone()) - .await; + .await + { + Err(mullvad_management_interface::Error::Rpc(status)) + if status.message().to_uppercase().contains("THROTTLED") => + { + // Work around throttling errors by sleeping + log::debug!( + "Login failed due to throttling. Sleeping for {} seconds", + THROTTLE_RETRY_DELAY.as_secs() + ); - if let Err(error) = result { - if !error.message().contains("THROTTLED") { - return Err(error); + tokio::time::sleep(THROTTLE_RETRY_DELAY).await; } - - // Work around throttling errors by sleeping - - log::debug!( - "Login failed due to throttling. Sleeping for {} seconds", - THROTTLE_RETRY_DELAY.as_secs() - ); - - tokio::time::sleep(THROTTLE_RETRY_DELAY).await; - } else { - break Ok(()); + Err(err) => break Err(err), + Ok(_) => break Ok(()), } } } @@ -306,18 +304,17 @@ pub async fn retry_if_throttled< pub async fn test_automatic_wireguard_rotation( ctx: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { + use futures::StreamExt; // Make note of current WG key let old_key = mullvad_client - .get_device(()) + .get_device() .await - .expect("Could not get device") - .into_inner() - .device .unwrap() + .into_device() + .expect("Could not get device") .device - .unwrap() .pubkey; // Stop daemon @@ -343,29 +340,29 @@ pub async fn test_automatic_wireguard_rotation( // Verify rotation has happened after a minute const KEY_ROTATION_TIMEOUT: Duration = Duration::from_secs(100); - let mut event_stream = mullvad_client.events_listen(()).await.unwrap().into_inner(); + let mut event_stream = mullvad_client.events_listen().await.unwrap(); let get_pub_key_event = async { loop { - let message = event_stream.message().await; - if let Ok(Some(event)) = message { - match event.event.unwrap() { - mullvad_management_interface::types::daemon_event::Event::Device( - device_event, - ) => { - let pubkey = device_event - .new_state - .unwrap() - .device - .unwrap() - .device - .unwrap() - .pubkey; - return Ok(pubkey); - } - _ => continue, + // TODO(markus): See if this can be refactored. This is exactly the same as helpers:274. + match event_stream.next().await { + Some(Ok(DaemonEvent::Device(device_event))) => { + let pubkey = device_event + .new_state + .into_device() + .expect("Could not get device") + .device + .pubkey; + return Ok(pubkey); + } + Some(Ok(_)) => continue, + Some(Err(status)) => { + break Err(Error::Daemon(format!( + "Failed to get next event: {}", + status + ))) } + None => break Err(Error::Daemon(String::from("Lost daemon event stream"))), } - return Err(message); } }; diff --git a/test/test-manager/src/tests/dns.rs b/test/test-manager/src/tests/dns.rs index 89755c3fd633..02cadf35cece 100644 --- a/test/test-manager/src/tests/dns.rs +++ b/test/test-manager/src/tests/dns.rs @@ -5,8 +5,10 @@ use std::{ }; use itertools::Itertools; -use mullvad_management_interface::{types, ManagementServiceClient}; -use mullvad_types::{relay_constraints::RelaySettings, ConnectionConfig, CustomTunnelEndpoint}; +use mullvad_management_interface::MullvadProxyClient; +use mullvad_types::{ + relay_constraints::RelaySettings, settings, ConnectionConfig, CustomTunnelEndpoint, +}; use talpid_types::net::wireguard; use test_macro::test_function; use test_rpc::ServiceClient; @@ -43,7 +45,7 @@ const MONITOR_TIMEOUT: Duration = Duration::from_secs(5); pub async fn test_dns_leak_default( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { leak_test_dns( &rpc, @@ -66,19 +68,19 @@ pub async fn test_dns_leak_default( pub async fn test_dns_leak_custom_public_ip( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { const CONFIG_IP: IpAddr = IpAddr::V4(Ipv4Addr::new(1, 3, 3, 7)); log::debug!("Setting custom DNS resolver to {CONFIG_IP}"); mullvad_client - .set_dns_options(types::DnsOptions { - default_options: Some(types::DefaultDnsOptions::default()), - custom_options: Some(types::CustomDnsOptions { - addresses: vec![CONFIG_IP.to_string()], - }), - state: i32::from(types::dns_options::DnsState::Custom), + .set_dns_options(settings::DnsOptions { + default_options: settings::DefaultDnsOptions::default(), + custom_options: settings::CustomDnsOptions { + addresses: vec![CONFIG_IP], + }, + state: settings::DnsState::Custom, }) .await .expect("failed to configure DNS server"); @@ -98,19 +100,19 @@ pub async fn test_dns_leak_custom_public_ip( pub async fn test_dns_leak_custom_private_ip( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { const CONFIG_IP: IpAddr = IpAddr::V4(Ipv4Addr::new(10, 64, 10, 1)); log::debug!("Setting custom DNS resolver to {CONFIG_IP}"); mullvad_client - .set_dns_options(types::DnsOptions { - default_options: Some(types::DefaultDnsOptions::default()), - custom_options: Some(types::CustomDnsOptions { - addresses: vec![CONFIG_IP.to_string()], - }), - state: i32::from(types::dns_options::DnsState::Custom), + .set_dns_options(settings::DnsOptions { + default_options: settings::DefaultDnsOptions::default(), + custom_options: settings::CustomDnsOptions { + addresses: vec![CONFIG_IP], + }, + state: settings::DnsState::Custom, }) .await .expect("failed to configure DNS server"); @@ -124,7 +126,7 @@ pub async fn test_dns_leak_custom_private_ip( /// * Packets to any other destination or a non-matching interface are observed. async fn leak_test_dns( rpc: &ServiceClient, - mullvad_client: &mut ManagementServiceClient, + mullvad_client: &mut MullvadProxyClient, use_tun: bool, whitelisted_dest: IpAddr, ) -> Result<(), Error> { @@ -140,7 +142,7 @@ async fn leak_test_dns( .get_default_interface() .await .expect("failed to find non-tun interface"); - let tunnel_iface = helpers::get_tunnel_interface(mullvad_client.clone()) + let tunnel_iface = helpers::get_tunnel_interface(mullvad_client) .await .expect("failed to find tunnel interface"); @@ -335,7 +337,7 @@ async fn leak_test_dns( pub async fn test_dns_config_default( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { run_dns_config_tunnel_test( &rpc, @@ -354,17 +356,17 @@ pub async fn test_dns_config_default( pub async fn test_dns_config_custom_private( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { log::debug!("Setting custom DNS resolver to {NON_TUN_GATEWAY}"); mullvad_client - .set_dns_options(types::DnsOptions { - default_options: Some(types::DefaultDnsOptions::default()), - custom_options: Some(types::CustomDnsOptions { - addresses: vec![NON_TUN_GATEWAY.to_string()], - }), - state: i32::from(types::dns_options::DnsState::Custom), + .set_dns_options(settings::DnsOptions { + default_options: settings::DefaultDnsOptions::default(), + custom_options: settings::CustomDnsOptions { + addresses: vec![IpAddr::V4(NON_TUN_GATEWAY)], + }, + state: settings::DnsState::Custom, }) .await .expect("failed to configure DNS server"); @@ -381,19 +383,19 @@ pub async fn test_dns_config_custom_private( pub async fn test_dns_config_custom_public( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { let custom_ip = IpAddr::V4(Ipv4Addr::new(1, 3, 3, 7)); log::debug!("Setting custom DNS resolver to {custom_ip}"); mullvad_client - .set_dns_options(types::DnsOptions { - default_options: Some(types::DefaultDnsOptions::default()), - custom_options: Some(types::CustomDnsOptions { - addresses: vec![custom_ip.to_string()], - }), - state: i32::from(types::dns_options::DnsState::Custom), + .set_dns_options(settings::DnsOptions { + default_options: settings::DefaultDnsOptions::default(), + custom_options: settings::CustomDnsOptions { + addresses: vec![custom_ip], + }, + state: settings::DnsState::Custom, }) .await .expect("failed to configure DNS server"); @@ -407,14 +409,14 @@ pub async fn test_dns_config_custom_public( pub async fn test_content_blockers( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { const DNS_BLOCKING_IP_BASE: Ipv4Addr = Ipv4Addr::new(100, 64, 0, 0); let content_blockers = [ ( "adblocking", 1 << 0, - types::DefaultDnsOptions { + settings::DefaultDnsOptions { block_ads: true, ..Default::default() }, @@ -422,7 +424,7 @@ pub async fn test_content_blockers( ( "tracker", 1 << 1, - types::DefaultDnsOptions { + settings::DefaultDnsOptions { block_trackers: true, ..Default::default() }, @@ -430,7 +432,7 @@ pub async fn test_content_blockers( ( "malware", 1 << 2, - types::DefaultDnsOptions { + settings::DefaultDnsOptions { block_malware: true, ..Default::default() }, @@ -438,7 +440,7 @@ pub async fn test_content_blockers( ( "adult", 1 << 3, - types::DefaultDnsOptions { + settings::DefaultDnsOptions { block_adult_content: true, ..Default::default() }, @@ -446,17 +448,17 @@ pub async fn test_content_blockers( ( "gambling", 1 << 4, - types::DefaultDnsOptions { + settings::DefaultDnsOptions { block_gambling: true, ..Default::default() }, ), ]; - let combine_cases = |v: Vec<&(&str, u8, types::DefaultDnsOptions)>| { + let combine_cases = |v: Vec<&(&str, u8, settings::DefaultDnsOptions)>| { let mut combination_name = String::new(); let mut last_byte = 0; - let mut options = types::DefaultDnsOptions::default(); + let mut options = settings::DefaultDnsOptions::default(); for case in v { if !combination_name.is_empty() { @@ -494,10 +496,10 @@ pub async fn test_content_blockers( log::debug!("Testing content blocker: {test_name}, {test_ip}"); mullvad_client - .set_dns_options(types::DnsOptions { - default_options: Some(test_opts), - custom_options: Some(types::CustomDnsOptions::default()), - state: i32::from(types::dns_options::DnsState::Default), + .set_dns_options(settings::DnsOptions { + default_options: test_opts, + custom_options: settings::CustomDnsOptions::default(), + state: settings::DnsState::Default, }) .await .expect("failed to configure DNS server"); @@ -510,7 +512,7 @@ pub async fn test_content_blockers( async fn run_dns_config_tunnel_test( rpc: &ServiceClient, - mullvad_client: &mut ManagementServiceClient, + mullvad_client: &mut MullvadProxyClient, expected_dns_resolver: IpAddr, ) -> Result<(), Error> { run_dns_config_test( @@ -534,7 +536,7 @@ async fn run_dns_config_tunnel_test( async fn run_dns_config_non_tunnel_test( rpc: &ServiceClient, - mullvad_client: &mut ManagementServiceClient, + mullvad_client: &mut MullvadProxyClient, expected_dns_resolver: IpAddr, ) -> Result<(), Error> { run_dns_config_test( @@ -561,18 +563,12 @@ async fn run_dns_config_test< >( rpc: &ServiceClient, create_monitor: impl FnOnce() -> F, - mullvad_client: &mut ManagementServiceClient, + mullvad_client: &mut MullvadProxyClient, expected_dns_resolver: IpAddr, ) -> Result<(), Error> { - match mullvad_client - .get_tunnel_state(()) - .await - .unwrap() - .into_inner() - .state - { + match mullvad_client.get_tunnel_state().await { // prevent reconnect - Some(types::tunnel_state::State::Connected(_)) => (), + Ok(mullvad_types::states::TunnelState::Connected { .. }) => (), _ => { connect_local_wg_relay(mullvad_client) .await @@ -584,7 +580,7 @@ async fn run_dns_config_test< .get_default_interface() .await .expect("failed to find non-tun interface"); - let tunnel_iface = helpers::get_tunnel_interface(mullvad_client.clone()) + let tunnel_iface = helpers::get_tunnel_interface(mullvad_client) .await .expect("failed to find tunnel interface"); @@ -633,7 +629,7 @@ async fn run_dns_config_test< /// Connect to the WireGuard relay that is set up in scripts/setup-network.sh /// See that script for details. -async fn connect_local_wg_relay(mullvad_client: &mut ManagementServiceClient) -> Result<(), Error> { +async fn connect_local_wg_relay(mullvad_client: &mut MullvadProxyClient) -> Result<(), Error> { let peer_addr: SocketAddr = SocketAddr::new( IpAddr::V4(CUSTOM_TUN_REMOTE_REAL_ADDR), CUSTOM_TUN_REMOTE_REAL_PORT, diff --git a/test/test-manager/src/tests/helpers.rs b/test/test-manager/src/tests/helpers.rs index f697900e0db4..478bb2eb46fa 100644 --- a/test/test-manager/src/tests/helpers.rs +++ b/test/test-manager/src/tests/helpers.rs @@ -3,7 +3,7 @@ use crate::network_monitor::{ self, start_packet_monitor, MonitorOptions, MonitorUnexpectedlyStopped, PacketMonitor, }; use futures::StreamExt; -use mullvad_management_interface::{types, ManagementServiceClient, MullvadProxyClient}; +use mullvad_management_interface::{client::DaemonEvent, MullvadProxyClient}; use mullvad_types::{ location::Location, relay_constraints::{ @@ -27,7 +27,7 @@ use tokio::time::timeout; #[macro_export] macro_rules! assert_tunnel_state { ($mullvad_client:expr, $pattern:pat) => {{ - let state = get_tunnel_state($mullvad_client).await; + let state = $mullvad_client.get_tunnel_state().await?; assert!(matches!(state, $pattern), "state: {:?}", state); }}; } @@ -85,8 +85,7 @@ pub async fn using_mullvad_exit(rpc: &ServiceClient) -> bool { } /// Get VPN tunnel interface name -pub async fn get_tunnel_interface(rpc: ManagementServiceClient) -> Option { - let mut client = MullvadProxyClient::from_rpc_client(rpc); +pub async fn get_tunnel_interface(client: &mut MullvadProxyClient) -> Option { match client.get_tunnel_state().await.ok()? { TunnelState::Connecting { endpoint, .. } | TunnelState::Connected { endpoint, .. } => { endpoint.tunnel_interface @@ -194,11 +193,11 @@ pub async fn ping_with_timeout( /// /// If that fails for whatever reason, the Mullvad daemon ends up in the /// [`TunnelState::Error`] state & [`Error::DaemonError`] is returned. -pub async fn connect_and_wait(mullvad_client: &mut ManagementServiceClient) -> Result<(), Error> { +pub async fn connect_and_wait(mullvad_client: &mut MullvadProxyClient) -> Result<(), Error> { log::info!("Connecting"); mullvad_client - .connect_tunnel(()) + .connect_tunnel() .await .map_err(|error| Error::Daemon(format!("failed to begin connecting: {}", error)))?; @@ -219,13 +218,11 @@ pub async fn connect_and_wait(mullvad_client: &mut ManagementServiceClient) -> R Ok(()) } -pub async fn disconnect_and_wait( - mullvad_client: &mut ManagementServiceClient, -) -> Result<(), Error> { +pub async fn disconnect_and_wait(mullvad_client: &mut MullvadProxyClient) -> Result<(), Error> { log::info!("Disconnecting"); mullvad_client - .disconnect_tunnel(()) + .disconnect_tunnel() .await .map_err(|error| Error::Daemon(format!("failed to begin disconnecting: {}", error)))?; wait_for_tunnel_state(mullvad_client.clone(), |state| { @@ -239,30 +236,29 @@ pub async fn disconnect_and_wait( } pub async fn wait_for_tunnel_state( - mut rpc: mullvad_management_interface::ManagementServiceClient, + mut rpc: MullvadProxyClient, accept_state_fn: impl Fn(&mullvad_types::states::TunnelState) -> bool, ) -> Result { let events = rpc - .events_listen(()) + .events_listen() .await .map_err(|status| Error::Daemon(format!("Failed to get event stream: {}", status)))?; - let state = mullvad_types::states::TunnelState::try_from( - rpc.get_tunnel_state(()) - .await - .map_err(|error| Error::Daemon(format!("Failed to get tunnel state: {:?}", error)))? - .into_inner(), - ) - .map_err(|error| Error::Daemon(format!("Invalid tunnel state: {:?}", error)))?; + let state = rpc + .get_tunnel_state() + .await + .map_err(|error| Error::Daemon(format!("Failed to get tunnel state: {:?}", error)))?; + if accept_state_fn(&state) { return Ok(state); } - find_next_tunnel_state(events.into_inner(), accept_state_fn).await + find_next_tunnel_state(events, accept_state_fn).await } pub async fn find_next_tunnel_state( - stream: impl futures::Stream> + Unpin, + stream: impl futures::Stream> + + Unpin, accept_state_fn: impl Fn(&mullvad_types::states::TunnelState) -> bool, ) -> Result { tokio::time::timeout( @@ -274,24 +270,16 @@ pub async fn find_next_tunnel_state( } async fn find_next_tunnel_state_inner( - mut stream: impl futures::Stream> + Unpin, + mut stream: impl futures::Stream> + + Unpin, accept_state_fn: impl Fn(&mullvad_types::states::TunnelState) -> bool, ) -> Result { loop { match stream.next().await { - Some(Ok(event)) => match event.event.unwrap() { - mullvad_management_interface::types::daemon_event::Event::TunnelState( - new_state, - ) => { - let state = mullvad_types::states::TunnelState::try_from(new_state).map_err( - |error| Error::Daemon(format!("Invalid tunnel state: {:?}", error)), - )?; - if accept_state_fn(&state) { - return Ok(state); - } - } - _ => continue, - }, + Some(Ok(DaemonEvent::TunnelState(state))) if accept_state_fn(&state) => { + return Ok(state) + } + Some(Ok(_)) => continue, Some(Err(status)) => { break Err(Error::Daemon(format!( "Failed to get next event: {}", @@ -351,9 +339,7 @@ impl Drop for AbortOnDrop { /// see [`mullvad_types::relay_constraints::WireguardConstraints`] for details. /// * OpenVPN settings are default (i.e. any port is used, no obfuscation ..) /// see [`mullvad_types::relay_constraints::OpenVpnConstraints`] for details. -pub async fn reset_relay_settings( - mullvad_client: &mut ManagementServiceClient, -) -> Result<(), Error> { +pub async fn reset_relay_settings(mullvad_client: &mut MullvadProxyClient) -> Result<(), Error> { disconnect_and_wait(mullvad_client).await?; let relay_settings = RelaySettings::Normal(RelayConstraints { @@ -372,12 +358,12 @@ pub async fn reset_relay_settings( .map_err(|error| Error::Daemon(format!("Failed to reset relay settings: {}", error)))?; mullvad_client - .set_bridge_state(types::BridgeState::from(bridge_state)) + .set_bridge_state(bridge_state) .await .map_err(|error| Error::Daemon(format!("Failed to reset bridge mode: {}", error)))?; mullvad_client - .set_obfuscation_settings(types::ObfuscationSettings::from(obfuscation_settings)) + .set_obfuscation_settings(obfuscation_settings) .await .map_err(|error| Error::Daemon(format!("Failed to reset obfuscation: {}", error)))?; @@ -385,62 +371,44 @@ pub async fn reset_relay_settings( } pub async fn set_relay_settings( - mullvad_client: &mut ManagementServiceClient, + mullvad_client: &mut MullvadProxyClient, relay_settings: RelaySettings, ) -> Result<(), Error> { - let new_settings = types::RelaySettings::from(relay_settings); - mullvad_client - .set_relay_settings(new_settings) + .set_relay_settings(relay_settings) .await - .map_err(|error| Error::Daemon(format!("Failed to set relay settings: {}", error)))?; - Ok(()) + .map_err(|error| Error::Daemon(format!("Failed to set relay settings: {}", error))) } pub async fn set_bridge_settings( - mullvad_client: &mut ManagementServiceClient, + mullvad_client: &mut MullvadProxyClient, bridge_settings: BridgeSettings, ) -> Result<(), Error> { - let new_settings = types::BridgeSettings::from(bridge_settings); - mullvad_client - .set_bridge_settings(new_settings) - .await - .map_err(|error| Error::Daemon(format!("Failed to set bridge settings: {}", error)))?; - Ok(()) -} - -pub async fn get_tunnel_state(mullvad_client: &mut ManagementServiceClient) -> TunnelState { - let state = mullvad_client - .get_tunnel_state(()) + .set_bridge_settings(bridge_settings) .await - .expect("mullvad RPC failed") - .into_inner(); - TunnelState::try_from(state).unwrap() + .map_err(|error| Error::Daemon(format!("Failed to set bridge settings: {}", error))) } /// Wait for the relay list to be updated, to make sure we have the overridden one. /// Time out after a while. -pub async fn ensure_updated_relay_list(mullvad_client: &mut ManagementServiceClient) { - let mut events = mullvad_client.events_listen(()).await.unwrap().into_inner(); - mullvad_client.update_relay_locations(()).await.unwrap(); +pub async fn ensure_updated_relay_list( + mullvad_client: &mut MullvadProxyClient, +) -> Result<(), mullvad_management_interface::Error> { + let mut events = mullvad_client.events_listen().await?; + mullvad_client.update_relay_locations().await?; - let wait_for_relay_update = async move { + let _ = tokio::time::timeout(std::time::Duration::from_secs(3), async move { while let Some(Ok(event)) = events.next().await { - if matches!( - event, - mullvad_management_interface::types::DaemonEvent { - event: Some( - mullvad_management_interface::types::daemon_event::Event::RelayList { .. } - ) - } - ) { + if matches!(event, DaemonEvent::RelayList(_)) { log::debug!("Received new relay list"); break; } } - }; - let _ = tokio::time::timeout(std::time::Duration::from_secs(3), wait_for_relay_update).await; + }) + .await; + + Ok(()) } pub fn unreachable_wireguard_tunnel() -> talpid_types::net::wireguard::ConnectionConfig { @@ -471,18 +439,16 @@ pub fn unreachable_wireguard_tunnel() -> talpid_types::net::wireguard::Connectio /// * `mullvad_client` - An interface to the Mullvad daemon. /// * `critera` - A function used to determine which relays to return. pub async fn filter_relays( - mullvad_client: &mut ManagementServiceClient, + mullvad_client: &mut MullvadProxyClient, criteria: Filter, ) -> Result, Error> where Filter: Fn(&Relay) -> bool, { let relay_list: RelayList = mullvad_client - .get_relay_locations(()) + .get_relay_locations() .await - .map_err(|error| Error::Daemon(format!("Failed to obtain relay list: {}", error)))? - .into_inner() - .try_into()?; + .map_err(|error| Error::Daemon(format!("Failed to obtain relay list: {}", error)))?; Ok(relay_list .relays() diff --git a/test/test-manager/src/tests/install.rs b/test/test-manager/src/tests/install.rs index ec1344ede0f5..c6d362825ee9 100644 --- a/test/test-manager/src/tests/install.rs +++ b/test/test-manager/src/tests/install.rs @@ -1,14 +1,15 @@ -use super::helpers::{connect_and_wait, get_package_desc}; +use super::config::TEST_CONFIG; +use super::helpers::{connect_and_wait, get_package_desc, wait_for_tunnel_state, Pinger}; use super::{Error, TestContext}; -use super::config::TEST_CONFIG; -use crate::tests::helpers::{wait_for_tunnel_state, Pinger}; -use mullvad_management_interface::{types, ManagementServiceClient}; -use std::{collections::HashMap, net::ToSocketAddrs, time::Duration}; +use mullvad_management_interface::MullvadProxyClient; +use mullvad_types::relay_constraints; use test_macro::test_function; use test_rpc::meta::Os; use test_rpc::{mullvad_daemon::ServiceStatus, ServiceClient}; +use std::{collections::HashMap, net::ToSocketAddrs, time::Duration}; + /// Install the last stable version of the app and verify that it is running. #[test_function(priority = -200)] pub async fn test_install_previous_app(_: TestContext, rpc: ServiceClient) -> Result<(), Error> { @@ -130,26 +131,19 @@ pub async fn test_upgrade_app(ctx: TestContext, rpc: ServiceClient) -> Result<() log::info!("Sanity checking settings"); let settings = mullvad_client - .get_settings(()) + .get_settings() .await - .expect("failed to obtain settings") - .into_inner(); + .expect("failed to obtain settings"); const EXPECTED_COUNTRY: &str = "xx"; let relay_location_was_preserved = match &settings.relay_settings { - Some(types::RelaySettings { - endpoint: - Some(types::relay_settings::Endpoint::Normal(types::NormalRelaySettings { - location: - Some(types::LocationConstraint { - r#type: - Some(types::location_constraint::Type::Location( - types::GeographicLocationConstraint { country, .. }, - )), - }), - .. - })), + relay_constraints::RelaySettings::Normal(relay_constraints::RelayConstraints { + location: + relay_constraints::Constraint::Only(relay_constraints::LocationConstraint::Location( + relay_constraints::GeographicLocationConstraint::Country(country), + )), + .. }) => country == EXPECTED_COUNTRY, _ => false, }; @@ -192,7 +186,7 @@ pub async fn test_upgrade_app(ctx: TestContext, rpc: ServiceClient) -> Result<() pub async fn test_uninstall_app( _: TestContext, rpc: ServiceClient, - mut mullvad_client: mullvad_management_interface::ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { if rpc.mullvad_daemon_get_status().await? != ServiceStatus::Running { return Err(Error::DaemonNotRunning); @@ -208,15 +202,12 @@ pub async fn test_uninstall_app( // save device to verify that uninstalling removes the device // we should still be logged in after upgrading let uninstalled_device = mullvad_client - .get_device(()) + .get_device() .await .expect("failed to get device data") - .into_inner(); - let uninstalled_device = uninstalled_device - .device - .expect("missing account/device") + .into_device() + .expect("failed to get device") .device - .expect("missing device id") .id; log::debug!("Uninstalling app"); @@ -291,7 +282,7 @@ pub async fn test_install_new_app(_: TestContext, rpc: ServiceClient) -> Result< pub async fn test_installation_idempotency( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { // Connect to any relay connect_and_wait(&mut mullvad_client).await?; diff --git a/test/test-manager/src/tests/mod.rs b/test/test-manager/src/tests/mod.rs index 08251eb27b08..8bebfe13dfa6 100644 --- a/test/test-manager/src/tests/mod.rs +++ b/test/test-manager/src/tests/mod.rs @@ -18,10 +18,7 @@ use test_rpc::ServiceClient; use futures::future::BoxFuture; -use mullvad_management_interface::{ - types::{self, Settings}, - ManagementServiceClient, -}; +use mullvad_management_interface::MullvadProxyClient; use once_cell::sync::OnceCell; use std::time::Duration; @@ -61,24 +58,23 @@ pub enum Error { #[error(display = "The daemon returned an error: {}", _0)] Daemon(String), - #[error(display = "Failed to parse gRPC response")] - InvalidGrpcResponse(#[error(source)] types::FromProtobufTypeError), + #[error(display = "The gRPC client ran into an error: {}", _0)] + ManagementInterface(#[source] mullvad_management_interface::Error), #[cfg(target_os = "macos")] #[error(display = "An error occurred: {}", _0)] Other(String), } -static DEFAULT_SETTINGS: OnceCell = OnceCell::new(); +static DEFAULT_SETTINGS: OnceCell = OnceCell::new(); /// Initializes `DEFAULT_SETTINGS`. This has only has an effect the first time it's called. -pub async fn init_default_settings(mullvad_client: &mut ManagementServiceClient) { +pub async fn init_default_settings(mullvad_client: &mut MullvadProxyClient) { if DEFAULT_SETTINGS.get().is_none() { - let settings: Settings = mullvad_client - .get_settings(()) + let settings = mullvad_client + .get_settings() .await - .expect("Failed to obtain settings") - .into_inner(); + .expect("Failed to obtain settings"); DEFAULT_SETTINGS.set(settings).unwrap(); } } @@ -89,9 +85,7 @@ pub async fn init_default_settings(mullvad_client: &mut ManagementServiceClient) /// /// `DEFAULT_SETTINGS` must be initialized using `init_default_settings` before any settings are /// modified, or this function panics. -pub async fn cleanup_after_test( - mullvad_client: &mut ManagementServiceClient, -) -> anyhow::Result<()> { +pub async fn cleanup_after_test(mullvad_client: &mut MullvadProxyClient) -> anyhow::Result<()> { log::debug!("Cleaning up daemon in test cleanup"); let default_settings = DEFAULT_SETTINGS @@ -113,56 +107,37 @@ pub async fn cleanup_after_test( .await .context("Could not set show beta releases in cleanup")?; mullvad_client - .set_bridge_state(default_settings.bridge_state.clone().unwrap()) + .set_bridge_state(default_settings.bridge_state) .await .context("Could not set bridge state in cleanup")?; mullvad_client - .set_bridge_settings(default_settings.bridge_settings.clone().unwrap()) + .set_bridge_settings(default_settings.bridge_settings.clone()) .await .context("Could not set bridge settings in cleanup")?; mullvad_client - .set_obfuscation_settings(default_settings.obfuscation_settings.clone().unwrap()) + .set_obfuscation_settings(default_settings.obfuscation_settings.clone()) .await .context("Could set obfuscation settings in cleanup")?; mullvad_client .set_block_when_disconnected(default_settings.block_when_disconnected) .await .context("Could not set block when disconnected setting in cleanup")?; + #[cfg(target_os = "windows")] mullvad_client - .clear_split_tunnel_apps(()) + .clear_split_tunnel_apps() .await .context("Could not clear split tunnel apps in cleanup")?; + #[cfg(target_os = "linux")] mullvad_client - .clear_split_tunnel_processes(()) + .clear_split_tunnel_processes() .await .context("Could not clear split tunnel processes in cleanup")?; mullvad_client - .set_dns_options( - default_settings - .tunnel_options - .as_ref() - .unwrap() - .dns_options - .as_ref() - .unwrap() - .clone(), - ) + .set_dns_options(default_settings.tunnel_options.dns_options.clone()) .await .context("Could not clear dns options in cleanup")?; mullvad_client - .set_quantum_resistant_tunnel( - default_settings - .tunnel_options - .as_ref() - .unwrap() - .wireguard - .as_ref() - .unwrap() - .quantum_resistant - .as_ref() - .unwrap() - .clone(), - ) + .set_quantum_resistant_tunnel(default_settings.tunnel_options.wireguard.quantum_resistant) .await .context("Could not clear PQ options in cleanup")?; diff --git a/test/test-manager/src/tests/settings.rs b/test/test-manager/src/tests/settings.rs index d2bde57fcc1e..5fdd298de15e 100644 --- a/test/test-manager/src/tests/settings.rs +++ b/test/test-manager/src/tests/settings.rs @@ -1,10 +1,10 @@ use super::helpers; -use super::helpers::{connect_and_wait, get_tunnel_state, send_guest_probes}; +use super::helpers::{connect_and_wait, send_guest_probes}; use super::{Error, TestContext}; use crate::assert_tunnel_state; use crate::vm::network::DUMMY_LAN_INTERFACE_IP; -use mullvad_management_interface::ManagementServiceClient; +use mullvad_management_interface::MullvadProxyClient; use mullvad_types::states::TunnelState; use std::net::{IpAddr, SocketAddr}; use test_macro::test_function; @@ -19,7 +19,7 @@ use test_rpc::ServiceClient; pub async fn test_lan( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { let lan_destination = SocketAddr::new(IpAddr::V4(DUMMY_LAN_INTERFACE_IP), 1234); @@ -101,7 +101,7 @@ pub async fn test_lan( pub async fn test_lockdown( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { let lan_destination: SocketAddr = SocketAddr::new(IpAddr::V4(DUMMY_LAN_INTERFACE_IP), 1337); let inet_destination: SocketAddr = "1.1.1.1:1337".parse().unwrap(); diff --git a/test/test-manager/src/tests/software.rs b/test/test-manager/src/tests/software.rs index 1c52f5032f6a..45b1c73ae100 100644 --- a/test/test-manager/src/tests/software.rs +++ b/test/test-manager/src/tests/software.rs @@ -1,7 +1,7 @@ //! Tests of interoperability with other software use super::{helpers, Error, TestContext}; -use mullvad_management_interface::ManagementServiceClient; +use mullvad_management_interface::MullvadProxyClient; use test_macro::test_function; use test_rpc::{ExecResult, ServiceClient}; @@ -10,7 +10,7 @@ use test_rpc::{ExecResult, ServiceClient}; pub async fn test_containers( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { let result = probe_container_connectivity(&rpc).await?; assert!( diff --git a/test/test-manager/src/tests/tunnel.rs b/test/test-manager/src/tests/tunnel.rs index 9544f098b21c..a66b7f7b881a 100644 --- a/test/test-manager/src/tests/tunnel.rs +++ b/test/test-manager/src/tests/tunnel.rs @@ -2,29 +2,29 @@ use super::helpers::{ self, connect_and_wait, disconnect_and_wait, set_bridge_settings, set_relay_settings, }; use super::{config::TEST_CONFIG, Error, TestContext}; - use crate::network_monitor::{start_packet_monitor, MonitorOptions}; -use mullvad_management_interface::{types, ManagementServiceClient}; + +use mullvad_management_interface::MullvadProxyClient; use mullvad_types::relay_constraints::{ - BridgeSettings, BridgeState, Constraint, ObfuscationSettings, OpenVpnConstraints, - RelayConstraints, RelaySettings, SelectedObfuscation, TransportPort, - Udp2TcpObfuscationSettings, WireguardConstraints, + self, BridgeSettings, Constraint, OpenVpnConstraints, RelayConstraints, RelaySettings, + SelectedObfuscation, TransportPort, Udp2TcpObfuscationSettings, WireguardConstraints, }; use mullvad_types::wireguard; -use pnet_packet::ip::IpNextHeaderProtocols; use talpid_types::net::{TransportProtocol, TunnelType}; use test_macro::test_function; use test_rpc::meta::Os; use test_rpc::mullvad_daemon::ServiceStatus; use test_rpc::ServiceClient; +use pnet_packet::ip::IpNextHeaderProtocols; + /// Set up an OpenVPN tunnel, UDP as well as TCP. /// This test fails if a working tunnel cannot be set up. #[test_function] pub async fn test_openvpn_tunnel( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { // TODO: observe traffic on the expected destination/port (only) @@ -79,7 +79,7 @@ pub async fn test_openvpn_tunnel( pub async fn test_wireguard_tunnel( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { // TODO: observe UDP traffic on the expected destination/port (only) // TODO: IPv6 @@ -128,15 +128,15 @@ pub async fn test_wireguard_tunnel( pub async fn test_udp2tcp_tunnel( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { mullvad_client - .set_obfuscation_settings(types::ObfuscationSettings::from(ObfuscationSettings { + .set_obfuscation_settings(relay_constraints::ObfuscationSettings { selected_obfuscation: SelectedObfuscation::Udp2Tcp, udp2tcp: Udp2TcpObfuscationSettings { port: Constraint::Any, }, - })) + }) .await .expect("failed to enable udp2tcp"); @@ -153,7 +153,7 @@ pub async fn test_udp2tcp_tunnel( connect_and_wait(&mut mullvad_client).await?; - let endpoint = match helpers::get_tunnel_state(&mut mullvad_client).await { + let endpoint = match mullvad_client.get_tunnel_state().await? { mullvad_types::states::TunnelState::Connected { endpoint, .. } => endpoint.endpoint, _ => panic!("unexpected tunnel state"), }; @@ -197,7 +197,7 @@ pub async fn test_udp2tcp_tunnel( pub async fn test_bridge( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { // // Enable bridge mode @@ -205,7 +205,7 @@ pub async fn test_bridge( log::info!("Updating bridge settings"); mullvad_client - .set_bridge_state(types::BridgeState::from(BridgeState::On)) + .set_bridge_state(relay_constraints::BridgeState::On) .await .expect("failed to enable bridge mode"); @@ -231,11 +231,13 @@ pub async fn test_bridge( connect_and_wait(&mut mullvad_client).await?; - let (entry, exit) = match helpers::get_tunnel_state(&mut mullvad_client).await { + let (entry, exit) = match mullvad_client.get_tunnel_state().await? { mullvad_types::states::TunnelState::Connected { endpoint, .. } => { (endpoint.proxy.unwrap().endpoint, endpoint.endpoint) } - _ => panic!("unexpected tunnel state"), + actual => { + panic!("unexpected tunnel state. Expected `TunnelState::Connected` but got {actual:?}") + } }; log::info!( @@ -285,7 +287,7 @@ pub async fn test_bridge( pub async fn test_multihop( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { let wireguard_constraints = WireguardConstraints { use_multihop: true, @@ -309,11 +311,13 @@ pub async fn test_multihop( connect_and_wait(&mut mullvad_client).await?; - let (entry, exit) = match helpers::get_tunnel_state(&mut mullvad_client).await { + let (entry, exit) = match mullvad_client.get_tunnel_state().await? { mullvad_types::states::TunnelState::Connected { endpoint, .. } => { (endpoint.entry_endpoint.unwrap(), endpoint.endpoint) } - _ => panic!("unexpected tunnel state"), + actual => { + panic!("unexpected tunnel state. Expected `TunnelState::Connected` but got {actual:?}") + } }; log::info!( @@ -363,7 +367,7 @@ pub async fn test_multihop( pub async fn test_wireguard_autoconnect( _: TestContext, mut rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { log::info!("Setting tunnel protocol to WireGuard"); @@ -405,7 +409,7 @@ pub async fn test_wireguard_autoconnect( pub async fn test_openvpn_autoconnect( _: TestContext, mut rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { log::info!("Setting tunnel protocol to OpenVPN"); @@ -449,12 +453,10 @@ pub async fn test_openvpn_autoconnect( pub async fn test_quantum_resistant_tunnel( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { mullvad_client - .set_quantum_resistant_tunnel(types::QuantumResistantState::from( - wireguard::QuantumResistantState::Off, - )) + .set_quantum_resistant_tunnel(wireguard::QuantumResistantState::Off) .await .expect("Failed to disable PQ tunnels"); @@ -476,9 +478,7 @@ pub async fn test_quantum_resistant_tunnel( .expect("Failed to update relay settings"); mullvad_client - .set_quantum_resistant_tunnel(types::QuantumResistantState::from( - wireguard::QuantumResistantState::On, - )) + .set_quantum_resistant_tunnel(wireguard::QuantumResistantState::On) .await .expect("Failed to enable PQ tunnels"); @@ -499,12 +499,12 @@ pub async fn test_quantum_resistant_tunnel( async fn check_tunnel_psk( rpc: &ServiceClient, - mullvad_client: &ManagementServiceClient, + mullvad_client: &MullvadProxyClient, should_have_psk: bool, ) { match TEST_CONFIG.os { Os::Linux => { - let name = helpers::get_tunnel_interface(mullvad_client.clone()) + let name = helpers::get_tunnel_interface(&mut mullvad_client.clone()) .await .expect("failed to get tun name"); let output = rpc @@ -533,36 +533,32 @@ async fn check_tunnel_psk( pub async fn test_quantum_resistant_multihop_udp2tcp_tunnel( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { mullvad_client - .set_quantum_resistant_tunnel(types::QuantumResistantState::from( - wireguard::QuantumResistantState::On, - )) + .set_quantum_resistant_tunnel(wireguard::QuantumResistantState::On) .await .expect("Failed to enable PQ tunnels"); mullvad_client - .set_obfuscation_settings(types::ObfuscationSettings::from(ObfuscationSettings { + .set_obfuscation_settings(relay_constraints::ObfuscationSettings { selected_obfuscation: SelectedObfuscation::Udp2Tcp, udp2tcp: Udp2TcpObfuscationSettings { port: Constraint::Any, }, - })) + }) .await .expect("Failed to enable obfuscation"); mullvad_client - .set_relay_settings(types::RelaySettings::from(RelaySettings::Normal( - RelayConstraints { - wireguard_constraints: WireguardConstraints { - use_multihop: true, - ..Default::default() - }, - tunnel_protocol: Constraint::Only(TunnelType::Wireguard), + .set_relay_settings(relay_constraints::RelaySettings::Normal(RelayConstraints { + wireguard_constraints: WireguardConstraints { + use_multihop: true, ..Default::default() }, - ))) + tunnel_protocol: Constraint::Only(TunnelType::Wireguard), + ..Default::default() + })) .await .expect("Failed to update relay settings"); diff --git a/test/test-manager/src/tests/tunnel_state.rs b/test/test-manager/src/tests/tunnel_state.rs index d8cce41b3a1b..565bd34552c8 100644 --- a/test/test-manager/src/tests/tunnel_state.rs +++ b/test/test-manager/src/tests/tunnel_state.rs @@ -1,12 +1,12 @@ use super::helpers::{ - self, connect_and_wait, get_tunnel_state, send_guest_probes, set_relay_settings, - unreachable_wireguard_tunnel, wait_for_tunnel_state, + self, connect_and_wait, send_guest_probes, set_relay_settings, unreachable_wireguard_tunnel, + wait_for_tunnel_state, }; use super::{ui, Error, TestContext}; use crate::assert_tunnel_state; use crate::vm::network::DUMMY_LAN_INTERFACE_IP; -use mullvad_management_interface::ManagementServiceClient; +use mullvad_management_interface::MullvadProxyClient; use mullvad_types::relay_constraints::GeographicLocationConstraint; use mullvad_types::relay_list::{Relay, RelayEndpointData}; use mullvad_types::CustomTunnelEndpoint; @@ -27,7 +27,7 @@ use test_rpc::ServiceClient; pub async fn test_disconnected_state( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { let inet_destination = "1.3.3.7:1337".parse().unwrap(); @@ -81,7 +81,7 @@ pub async fn test_disconnected_state( pub async fn test_connecting_state( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { let inet_destination = "1.1.1.1:1337".parse().unwrap(); let lan_destination: SocketAddr = SocketAddr::new(IpAddr::V4(DUMMY_LAN_INTERFACE_IP), 1337); @@ -101,7 +101,7 @@ pub async fn test_connecting_state( .expect("failed to update relay settings"); mullvad_client - .connect_tunnel(()) + .connect_tunnel() .await .expect("failed to begin connecting"); let new_state = wait_for_tunnel_state(mullvad_client.clone(), |state| { @@ -163,7 +163,7 @@ pub async fn test_connecting_state( pub async fn test_error_state( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { let inet_destination = "1.1.1.1:1337".parse().unwrap(); let lan_destination: SocketAddr = SocketAddr::new(IpAddr::V4(DUMMY_LAN_INTERFACE_IP), 1337); @@ -245,7 +245,7 @@ pub async fn test_error_state( pub async fn test_connected_state( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { let inet_destination = "1.1.1.1:1337".parse().unwrap(); @@ -279,13 +279,11 @@ pub async fn test_connected_state( connect_and_wait(&mut mullvad_client).await?; - let state = get_tunnel_state(&mut mullvad_client).await; - // // Verify that endpoint was selected // - match state { + match mullvad_client.get_tunnel_state().await? { TunnelState::Connected { endpoint: TunnelEndpoint { @@ -340,7 +338,7 @@ pub async fn test_connected_state( pub async fn test_connecting_state_when_corrupted_state_cache( _: TestContext, rpc: ServiceClient, - mullvad_client: ManagementServiceClient, + mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { // The test should start in a disconnected state. Normally this would be // preserved when restarting the app, i.e. the user would still be diff --git a/test/test-manager/src/tests/ui.rs b/test/test-manager/src/tests/ui.rs index 461d20ae108b..6ddb6b5a7f61 100644 --- a/test/test-manager/src/tests/ui.rs +++ b/test/test-manager/src/tests/ui.rs @@ -1,7 +1,7 @@ use super::config::TEST_CONFIG; use super::helpers; use super::{Error, TestContext}; -use mullvad_management_interface::ManagementServiceClient; +use mullvad_management_interface::MullvadProxyClient; use mullvad_types::relay_constraints::{RelayConstraints, RelaySettings}; use mullvad_types::relay_list::{Relay, RelayEndpointData}; use std::{ @@ -84,7 +84,7 @@ pub async fn run_test_env< pub async fn test_ui_tunnel_settings( _: TestContext, rpc: ServiceClient, - mut mullvad_client: ManagementServiceClient, + mut mullvad_client: MullvadProxyClient, ) -> Result<(), Error> { // tunnel-state.spec precondition: a single WireGuard relay should be selected log::info!("Select WireGuard relay"); diff --git a/test/test-manager/test_macro/src/lib.rs b/test/test-manager/test_macro/src/lib.rs index 07f353ad7a92..0f854e953b58 100644 --- a/test/test-manager/test_macro/src/lib.rs +++ b/test/test-manager/test_macro/src/lib.rs @@ -11,11 +11,11 @@ use syn::{AttributeArgs, Lit, Meta, NestedMeta}; /// be used to perform arbitrary network requests, inspect the local file /// system, rebooting .. /// -/// * `mullvad_client` - a -/// [`mullvad_management_interface::ManagementServiceClient`] which provides a -/// bi-directional communication channel with the `mullvad-daemon` running -/// inside of the virtual machine. All RPC-calls as defined by -/// [`mullvad_management_interface::client`] are available on `mullvad_client`. +/// * `mullvad_client` - a [`mullvad_management_interface::MullvadProxyClient`] +/// which provides a bi-directional communication channel with the +/// `mullvad-daemon` running inside of the virtual machine. All RPC-calls as +/// defined in [`mullvad_management_interface::MullvadProxyClient`] are +/// available on `mullvad_client`. /// ///# Arguments /// @@ -47,11 +47,11 @@ use syn::{AttributeArgs, Lit, Meta, NestedMeta}; /// Remember that [`test_function`] will inject `rpc` and `mullvad_client` for /// us. /// -/// ``` +/// ```ignore /// #[test_function] /// pub async fn test_function( /// rpc: ServiceClient, -/// mut mullvad_client: mullvad_management_interface::ManagementServiceClient, +/// mut mullvad_client: mullvad_management_interface::MullvadProxyClient, /// ) -> Result<(), Error> { /// Ok(()) /// } @@ -62,11 +62,11 @@ use syn::{AttributeArgs, Lit, Meta, NestedMeta}; /// This test will run early in the test loop, won't perform any cleanup, must /// succeed and will always run. /// -/// ``` +/// ```ignore /// #[test_function(priority = -1337, cleanup = false, must_succeed = true, always_run = true)] /// pub async fn test_function( /// rpc: ServiceClient, -/// mut mullvad_client: mullvad_management_interface::ManagementServiceClient, +/// mut mullvad_client: mullvad_management_interface::MullvadProxyClient, /// ) -> Result<(), Error> { /// Ok(()) /// } @@ -274,7 +274,7 @@ fn get_test_function_parameters( let mullvad_client = match &*pat_type.ty { syn::Type::Path(syn::TypePath { path, .. }) => { match path.segments[0].ident.to_string().as_str() { - "mullvad_management_interface" | "ManagementServiceClient" => { + "mullvad_management_interface" | "MullvadProxyClient" => { let mullvad_client_version = quote! { test_rpc::mullvad_daemon::MullvadClientVersion::New }; MullvadClient::New {