summaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/test-manager/src/tests/install.rs98
1 files changed, 96 insertions, 2 deletions
diff --git a/test/test-manager/src/tests/install.rs b/test/test-manager/src/tests/install.rs
index 37a89f5fc8..c809fd9ad2 100644
--- a/test/test-manager/src/tests/install.rs
+++ b/test/test-manager/src/tests/install.rs
@@ -1,9 +1,10 @@
-use super::helpers::{get_package_desc, AbortOnDrop};
+use super::helpers::{connect_and_wait, get_package_desc, AbortOnDrop};
use super::{Error, TestContext};
use super::config::TEST_CONFIG;
use crate::network_monitor::{start_packet_monitor, MonitorOptions};
-use mullvad_management_interface::types;
+use crate::tests::helpers::wait_for_tunnel_state;
+use mullvad_management_interface::{types, ManagementServiceClient};
use std::{
collections::HashMap,
net::{SocketAddr, ToSocketAddrs},
@@ -321,6 +322,99 @@ pub async fn test_install_new_app(_: TestContext, rpc: ServiceClient) -> Result<
Ok(())
}
+/// Install the multiple times starting from a connected state with auto-connect
+/// disabled, failing if the app starts in a disconnected state.
+///
+/// This test is supposed to guard against regressions to this fix included in
+/// the 2021.3-beta1 release:
+/// https://github.com/mullvad/mullvadvpn-app/blob/main/CHANGELOG.md#security-10
+#[test_function(priority = -150)]
+pub async fn test_installation_idempotency(
+ _: TestContext,
+ rpc: ServiceClient,
+ mut mullvad_client: ManagementServiceClient,
+) -> Result<(), Error> {
+ // Connect to any relay
+ connect_and_wait(&mut mullvad_client).await?;
+ // Disable auto-connect
+ mullvad_client
+ .set_auto_connect(false)
+ .await
+ .expect("failed to enable auto-connect");
+ // Start a tunnel monitor. No traffic should be observed going outside of
+ // the tunnel during either installation process.
+ let inet_destination: SocketAddr = "1.1.1.1:1337".parse().unwrap();
+ let guest_iface = rpc
+ .get_default_interface()
+ .await
+ .expect("failed to obtain default interface");
+ let guest_ip = rpc
+ .get_interface_ip(guest_iface)
+ .await
+ .expect("failed to obtain non-tun IP");
+ log::debug!("Guest IP: {guest_ip}");
+
+ log::debug!("Monitoring outgoing traffic");
+ let monitor = start_packet_monitor(
+ move |packet| {
+ // NOTE: Many packets will likely be observed for API traffic. Rather than filtering all
+ // of those specifically, simply fail if our probes are observed.
+ packet.source.ip() == guest_ip && packet.destination.ip() == inet_destination.ip()
+ },
+ MonitorOptions::default(),
+ )
+ .await;
+ // TODO: Refactor this into a nice-looking API which returns both a pinger and an associated ping-monitor. => (Pinger, PingMonitor).
+ let ping_rpc = rpc.clone();
+ let probe_sender = AbortOnDrop::new(tokio::spawn(async move {
+ // Send a ping once every second.
+ loop {
+ super::helpers::send_guest_probes_without_monitor(
+ ping_rpc.clone(),
+ None,
+ inet_destination,
+ )
+ .await;
+ tokio::time::sleep(Duration::from_secs(1)).await;
+ }
+ }));
+
+ for _ in 1..=2 {
+ // install package
+ log::debug!("Installing new app");
+ rpc.install_app(get_package_desc(&TEST_CONFIG.current_app_filename)?)
+ .await?;
+ // verify that daemon is running
+ wait_for_tunnel_state(mullvad_client.clone(), |state| state.is_connected())
+ .await
+ .map_err(|err| {
+ log::error!(
+ "App did not start in the expected `Connected` state after the installation process."
+ );
+ err
+ })?;
+
+ // Wait for an arbitrary amount of time. The point is that the pinger
+ // should be able to ping `inet_destination` while the newly installed
+ // app is running.
+ tokio::time::sleep(Duration::from_secs(3)).await;
+ }
+
+ // Make sure that no traffic leak occured during any installation process.
+ let probe_sender = probe_sender.into_inner();
+ probe_sender.abort();
+ let _ = probe_sender.await;
+
+ let monitor_result = monitor.into_result().await.unwrap();
+ assert_eq!(
+ monitor_result.packets.len(),
+ 0,
+ "observed unexpected packets from {guest_ip}"
+ );
+
+ Ok(())
+}
+
fn get_app_env() -> HashMap<String, String> {
let mut map = HashMap::new();