diff options
| author | Markus Pettersson <markus.pettersson@mullvad.net> | 2023-11-23 16:20:00 +0100 |
|---|---|---|
| committer | Markus Pettersson <markus.pettersson@mullvad.net> | 2023-12-06 14:37:18 +0100 |
| commit | de860ecc7d9334d3c2d8e95b90caf5c7ca5a2de2 (patch) | |
| tree | 6968512dec750fe8acacb9854f1c5c2332106d2b | |
| parent | 1b930b893fa3fcb06f5fee4affbfb62887d0e68a (diff) | |
| download | mullvadvpn-de860ecc7d9334d3c2d8e95b90caf5c7ca5a2de2.tar.xz mullvadvpn-de860ecc7d9334d3c2d8e95b90caf5c7ca5a2de2.zip | |
Add `test_connecting_state_when_corrupted_state_cache`
Add regression test which checks that the daemon successfully recovers
from a corrupt target state cache. If the target state cache is corrupt,
the daemon will default to the `Connecting` target state on startup.
| -rw-r--r-- | test/test-manager/src/tests/tunnel_state.rs | 50 | ||||
| -rw-r--r-- | test/test-rpc/src/client.rs | 13 | ||||
| -rw-r--r-- | test/test-rpc/src/lib.rs | 2 |
3 files changed, 53 insertions, 12 deletions
diff --git a/test/test-manager/src/tests/tunnel_state.rs b/test/test-manager/src/tests/tunnel_state.rs index 176127d7c5..90a5086863 100644 --- a/test/test-manager/src/tests/tunnel_state.rs +++ b/test/test-manager/src/tests/tunnel_state.rs @@ -353,15 +353,51 @@ pub async fn test_connecting_state_when_corrupted_state_cache( // Stopping the app should write to the state target cache. log::info!("Stopping the app"); - rpc.restart_app().await?; + rpc.stop_app().await?; + + // Intentionally corrupt the state cache. Note that we can not simply remove + // the cache, as this will put the app in the default target state which is + // 'unsecured'. + log::info!("Figuring out where state cache resides on test runner .."); + let state_cache = rpc + .find_mullvad_app_cache_dir() + .await? + .join("target-start-state.json"); + log::info!( + "Intentionally writing garbage to the state cache {file}", + file = state_cache.display() + ); + rpc.write_file(state_cache, "cookie was here".into()) + .await?; - // Intentionally corrupt the state cache - todo!("Intentionally corrupt the state cache"); - // Start a leak monitor - todo!("Start a leak monitor"); // Start the app & make sure that we start in the 'connecting state'. The // side-effect of this is that no network traffic is allowed to leak. - todo!("Start the app"); - assert_tunnel_state!(&mut mullvad_client, TunnelState::Connecting { .. }); + log::info!("Starting the app back up again"); + rpc.start_app().await?; + + let new_state = wait_for_tunnel_state(mullvad_client.clone(), |state| { + matches!( + state, + TunnelState::Connecting { .. } | TunnelState::Connected { .. } | TunnelState::Error(..) + ) + }) + .await + .map_err(|err| { + log::error!("App did not start in an expected state."); + err + })?; + + assert!( + matches!( + new_state, + TunnelState::Connecting { .. } | TunnelState::Connected { .. } + ), + "App is not in either `Connecting` or `Connected` state after starting with corrupt state cache! There is a possibility of leaks during app startup" + ); + + log::info!( + "App started successfully! It successfully recovered from a corrupt tunnel state cache." + ); + Ok(()) } diff --git a/test/test-rpc/src/client.rs b/test/test-rpc/src/client.rs index acc462dd60..6234db0262 100644 --- a/test/test-rpc/src/client.rs +++ b/test/test-rpc/src/client.rs @@ -1,5 +1,6 @@ use std::{ collections::HashMap, + path::Path, time::{Duration, SystemTime}, }; @@ -51,7 +52,7 @@ impl ServiceClient { self.client.uninstall_app(ctx, env).await? } - /// Execute a program. + /// Execute a program with additional environment-variables set. pub async fn exec_env< I: IntoIterator<Item = T>, M: IntoIterator<Item = (K, T)>, @@ -282,14 +283,18 @@ impl ServiceClient { .await? } - pub async fn write_file(&self, dest: String, bytes: Vec<u8>) -> Result<(), Error> { + pub async fn write_file(&self, dest: impl AsRef<Path>, bytes: Vec<u8>) -> Result<(), Error> { log::debug!( "Writing {bytes} bytes to \"{file}\"", bytes = bytes.len(), - file = dest + file = dest.as_ref().display() ); self.client - .write_file(tarpc::context::current(), dest, bytes) + .write_file( + tarpc::context::current(), + dest.as_ref().to_path_buf(), + bytes, + ) .await? } diff --git a/test/test-rpc/src/lib.rs b/test/test-rpc/src/lib.rs index 65ccb2fb7a..2e5007a808 100644 --- a/test/test-rpc/src/lib.rs +++ b/test/test-rpc/src/lib.rs @@ -173,7 +173,7 @@ mod service { async fn copy_file(src: String, dest: String) -> Result<(), Error>; /// Write arbitrary bytes to some file `dest` on the test runner. - async fn write_file(dest: String, bytes: Vec<u8>) -> Result<(), Error>; + async fn write_file(dest: PathBuf, bytes: Vec<u8>) -> Result<(), Error>; async fn reboot() -> Result<(), Error>; |
