summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2025-10-20 10:21:58 +0200
committerJoakim Hulthe <joakim.hulthe@mullvad.net>2025-10-23 10:22:48 +0200
commit1145cd7fbd798921aca80c76f8877251532e2c71 (patch)
tree7e5145e97a43e7d1431c4b0832f98fcd9043d088
parent82920c6f3702bc41028519dba318e39bd44cc52a (diff)
parent846369cb9301e524b19af38e07091367c27ef6e4 (diff)
downloadmullvadvpn-1145cd7fbd798921aca80c76f8877251532e2c71.tar.xz
mullvadvpn-1145cd7fbd798921aca80c76f8877251532e2c71.zip
Merge branch 'fix-check-interruption' into prepare-2025.13
-rw-r--r--mullvad-daemon/src/version/router.rs118
1 files changed, 114 insertions, 4 deletions
diff --git a/mullvad-daemon/src/version/router.rs b/mullvad-daemon/src/version/router.rs
index 7f878a94bc..d38edcca2e 100644
--- a/mullvad-daemon/src/version/router.rs
+++ b/mullvad-daemon/src/version/router.rs
@@ -351,14 +351,66 @@ where
}
}
#[cfg(in_app_upgrade)]
- State::Downloaded { .. } | State::Downloading { .. } => {
+ State::Downloading {
+ version_cache: prev_cache,
+ ..
+ } => {
+ let prev_app_version_info =
+ to_app_version_info(prev_cache, self.beta_program, None);
let app_version_info = to_app_version_info(&version_cache, self.beta_program, None);
- log::warn!("Received new version while upgrading: {app_version_info:?}");
- AppVersionInfoEvent {
+ let event = AppVersionInfoEvent {
+ is_new: prev_app_version_info != app_version_info,
app_version_info,
- is_new: true,
+ };
+
+ if !event.is_new {
+ log::trace!("Ignoring same version in downloading state");
+ // Return here to avoid resetting the state to `HasVersion`
+ // We update the cache because ignored information (eg available beta if beta
+ // program is off) may have changed
+ *prev_cache = version_cache.clone();
+ return event;
}
+
+ log::warn!("Received new version while downloading. Aborting download");
+
+ event
+ }
+ #[cfg(in_app_upgrade)]
+ State::Downloaded {
+ version_cache: prev_cache,
+ verified_installer_path,
+ ..
+ } => {
+ let prev_app_version_info = to_app_version_info(
+ prev_cache,
+ self.beta_program,
+ Some(verified_installer_path.clone()),
+ );
+ let app_version_info = to_app_version_info(
+ &version_cache,
+ self.beta_program,
+ Some(verified_installer_path.clone()),
+ );
+
+ let event = AppVersionInfoEvent {
+ is_new: prev_app_version_info != app_version_info,
+ app_version_info,
+ };
+
+ if !event.is_new {
+ log::trace!("Ignoring same version in downloaded state");
+ // Return here to avoid resetting the state to `HasVersion`
+ // We update the cache because ignored information (eg available beta if beta
+ // program is off) may have changed
+ *prev_cache = version_cache.clone();
+ return event;
+ }
+
+ log::warn!("Received new version in downloaded state. Aborting download");
+
+ event
}
};
self.state = State::HasVersion { version_cache };
@@ -1114,6 +1166,64 @@ mod test {
}
#[tokio::test]
+ async fn test_update_in_downloaded_state() {
+ let (mut version_router, _channels) = make_version_router::<SuccessfulAppDownloader>();
+ let mut version_cache_test = get_new_stable_version_cache();
+
+ version_router.on_new_version(version_cache_test.clone());
+
+ // Start upgrading
+ version_router.update_application();
+ // Check that the state is now downloading
+ assert!(matches!(version_router.state, State::Downloading { .. }),);
+
+ // Should remain in downloading state if same version is received
+ version_router.on_new_version(version_cache_test.clone());
+ assert!(
+ matches!(version_router.state, State::Downloading { .. }),
+ "state should be Downloading, was {:?}",
+ version_router.state,
+ );
+
+ // Unless the version is different
+ version_cache_test.version_info.stable.version.incremental += 1;
+ version_router.on_new_version(version_cache_test.clone());
+ assert!(
+ matches!(version_router.state, State::HasVersion { .. }),
+ "state should be HasVersion, was {:?}",
+ version_router.state,
+ );
+
+ // Restart upgrade
+ version_router.update_application();
+
+ // Drive the download to completion
+ assert_eq!(version_router.run_step().await, ControlFlow::Continue(()));
+ assert!(
+ matches!(version_router.state, State::Downloaded { .. }),
+ "state should be Downloaded, was {:?}",
+ version_router.state,
+ );
+
+ // Should remain in downloaded state if same version is received
+ version_router.on_new_version(version_cache_test.clone());
+ assert!(
+ matches!(version_router.state, State::Downloaded { .. }),
+ "state should be Downloaded, was {:?}",
+ version_router.state,
+ );
+
+ // Unless the version is different
+ version_cache_test.version_info.stable.version.incremental += 1;
+ version_router.on_new_version(version_cache_test.clone());
+ assert!(
+ matches!(version_router.state, State::HasVersion { .. }),
+ "state should be HasVersion, was {:?}",
+ version_router.state,
+ );
+ }
+
+ #[tokio::test]
async fn test_failed_verification() {
let (mut version_router, _channels) = make_version_router::<FailingAppVerifier>();
let version_cache_test = get_new_stable_version_cache();