diff --git a/src/dist/manifestation/tests.rs b/src/dist/manifestation/tests.rs index 6f5fb16a51..22b62a0a37 100644 --- a/src/dist/manifestation/tests.rs +++ b/src/dist/manifestation/tests.rs @@ -2,20 +2,20 @@ // server (mocked on the file system) #![allow(clippy::type_complexity)] -use std::collections::HashMap; -use std::env; -use std::fs; -use std::path::Path; -use std::str::FromStr; -use std::sync::Arc; -use std::{cell::Cell, future::Future}; +use std::{ + cell::Cell, + collections::HashMap, + env, fs, + path::{Path, PathBuf}, + str::FromStr, + sync::Arc, +}; use anyhow::{anyhow, Result}; -use tokio::{runtime::Handle, task}; use url::Url; use crate::{ - currentprocess::{Process, TestProcess}, + currentprocess::TestProcess, dist::{ download::DownloadCfg, manifest::{Component, Manifest}, @@ -30,24 +30,6 @@ use crate::{ const SHA256_HASH_LEN: usize = 64; -/// Temporary thunk to support asyncifying from underneath. -fn run_future(f: F) -> Result -where - F: Future>, - E: std::convert::From, -{ - match Handle::try_current() { - Ok(current) => { - // hide the asyncness for now. - task::block_in_place(|| current.block_on(f)) - } - Err(_) => { - // Make a runtime to hide the asyncness. - tokio::runtime::Runtime::new()?.block_on(f) - } - } -} - // Creates a mock dist server populated with some test data fn create_mock_dist_server( path: &Path, @@ -283,8 +265,8 @@ fn mock_dist_server_smoke_test() { // Test that a standard rename works - the component is installed with the old name, then renamed // the next day to the new name. -#[test] -fn rename_component() { +#[tokio::test] +async fn rename_component() { let dist_tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap(); let url = Url::parse(&format!("file://{}", dist_tempdir.path().to_string_lossy())).unwrap(); @@ -327,52 +309,27 @@ fn rename_component() { ], }; - setup_from_dist_server( - mock_dist_server, - &url, - GZOnly, - &|url, toolchain, prefix, download_cfg, tmp_cx| { - let adds = [Component::new( - "bonus".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), - true, - )]; - - change_channel_date(url, "nightly", "2016-02-01"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert!(utils::path_exists(prefix.path().join("bin/bonus"))); - assert!(!utils::path_exists(prefix.path().join("bin/bobo"))); - change_channel_date(url, "nightly", "2016-02-02"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert!(utils::path_exists(prefix.path().join("bin/bonus"))); - assert!(!utils::path_exists(prefix.path().join("bin/bobo"))); - }, - ); + let cx = TestContext::from_dist_server(mock_dist_server, url, GZOnly); + + let adds = [Component::new( + "bonus".to_string(), + Some(TargetTriple::new("x86_64-apple-darwin")), + true, + )]; + + change_channel_date(&cx.url, "nightly", "2016-02-01"); + cx.update_from_dist(&adds, &[], false).await.unwrap(); + assert!(utils::path_exists(cx.prefix.path().join("bin/bonus"))); + assert!(!utils::path_exists(cx.prefix.path().join("bin/bobo"))); + change_channel_date(&cx.url, "nightly", "2016-02-02"); + cx.update_from_dist(&[], &[], false).await.unwrap(); + assert!(utils::path_exists(cx.prefix.path().join("bin/bonus"))); + assert!(!utils::path_exists(cx.prefix.path().join("bin/bobo"))); } // Test that a rename is ignored if the component with the old name was never installed. -#[test] -fn rename_component_new() { +#[tokio::test] +async fn rename_component_new() { let dist_tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap(); let url = Url::parse(&format!("file://{}", dist_tempdir.path().to_string_lossy())).unwrap(); @@ -392,108 +349,28 @@ fn rename_component_new() { ], }; - setup_from_dist_server( - mock_dist_server, - &url, - GZOnly, - &|url, toolchain, prefix, download_cfg, tmp_cx| { - let adds = [Component::new( - "bobo".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), - true, - )]; - // Install the basics from day 1 - change_channel_date(url, "nightly", "2016-02-01"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - // Neither bonus nor bobo are installed at this point. - assert!(!utils::path_exists(prefix.path().join("bin/bonus"))); - assert!(!utils::path_exists(prefix.path().join("bin/bobo"))); - // Now we move to day 2, where bobo is part of the set of things we want - // to have installed - change_channel_date(url, "nightly", "2016-02-02"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - // As a result `bin/bonus` is present but not `bin/bobo` which we'd - // expect since the bonus component installs `bin/bonus` regardless of - // its name being `bobo` - assert!(!utils::path_exists(prefix.path().join("bin/bobo"))); - assert!(utils::path_exists(prefix.path().join("bin/bonus"))); - }, - ); -} - -// Installs or updates a toolchain from a dist server. If an initial -// install then it will be installed with the default components. If -// an upgrade then all the existing components will be upgraded. -// FIXME: Unify this with dist::update_from_dist -#[allow(clippy::too_many_arguments)] -async fn update_from_dist( - dist_server: &Url, - toolchain: &ToolchainDesc, - prefix: &InstallPrefix, - add: &[Component], - remove: &[Component], - download_cfg: &DownloadCfg<'_>, - tmp_cx: &temp::Context, - force: bool, -) -> Result { - // Download the dist manifest and place it into the installation prefix - let manifest_url = make_manifest_url(dist_server, toolchain)?; - let manifest_file = tmp_cx.new_file()?; - utils::download_file( - &manifest_url, - &manifest_file, - None, - &|_| {}, - download_cfg.process, - ) - .await?; - let manifest_str = utils::read_file("manifest", &manifest_file)?; - let manifest = Manifest::parse(&manifest_str)?; - - // Read the manifest to update the components - let trip = toolchain.target.clone(); - let manifestation = Manifestation::open(prefix.clone(), trip.clone())?; - - // TODO on install, need to add profile components (but I guess we shouldn't test that logic here) - let mut profile_components = manifest.get_profile_components(Profile::Default, &trip)?; - let mut add_components = add.to_owned(); - add_components.append(&mut profile_components); - - let changes = Changes { - explicit_add_components: add_components, - remove_components: remove.to_owned(), - }; - - manifestation - .update( - &manifest, - changes, - force, - download_cfg, - &toolchain.manifest_name(), - true, - ) - .await + let cx = TestContext::from_dist_server(mock_dist_server, url, GZOnly); + + let adds = [Component::new( + "bobo".to_string(), + Some(TargetTriple::new("x86_64-apple-darwin")), + true, + )]; + // Install the basics from day 1 + change_channel_date(&cx.url, "nightly", "2016-02-01"); + cx.update_from_dist(&[], &[], false).await.unwrap(); + // Neither bonus nor bobo are installed at this point. + assert!(!utils::path_exists(cx.prefix.path().join("bin/bonus"))); + assert!(!utils::path_exists(cx.prefix.path().join("bin/bobo"))); + // Now we move to day 2, where bobo is part of the set of things we want + // to have installed + change_channel_date(&cx.url, "nightly", "2016-02-02"); + cx.update_from_dist(&adds, &[], false).await.unwrap(); + // As a result `bin/bonus` is present but not `bin/bobo` which we'd + // expect since the bonus component installs `bin/bonus` regardless of + // its name being `bobo` + assert!(!utils::path_exists(cx.prefix.path().join("bin/bobo"))); + assert!(utils::path_exists(cx.prefix.path().join("bin/bonus"))); } fn make_manifest_url(dist_server: &Url, toolchain: &ToolchainDesc) -> Result { @@ -505,22 +382,6 @@ fn make_manifest_url(dist_server: &Url, toolchain: &ToolchainDesc) -> Result), - process: &Process, -) -> Result<()> { - let trip = toolchain.target.clone(); - let manifestation = Manifestation::open(prefix.clone(), trip)?; - let manifest = manifestation.load_manifest()?.unwrap(); - - manifestation.uninstall(&manifest, tmp_cx, notify_handler, process)?; - - Ok(()) -} - #[derive(Copy, Clone, Debug)] enum Compressions { GZOnly, @@ -539,195 +400,205 @@ impl Compressions { } } -fn setup( - edit: Option<&dyn Fn(&str, &mut MockChannel)>, - comps: Compressions, - f: &dyn Fn(&Url, &ToolchainDesc, &InstallPrefix, &DownloadCfg<'_>, &temp::Context), -) { - let dist_tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap(); - let mock_dist_server = create_mock_dist_server(dist_tempdir.path(), edit); - let url = Url::parse(&format!("file://{}", dist_tempdir.path().to_string_lossy())).unwrap(); - setup_from_dist_server(mock_dist_server, &url, comps, f); +struct TestContext { + url: Url, + toolchain: ToolchainDesc, + prefix: InstallPrefix, + download_dir: PathBuf, + tp: TestProcess, + tmp_cx: temp::Context, + _tempdirs: Vec, } -fn setup_from_dist_server( - server: MockDistServer, - url: &Url, - comps: Compressions, - f: &dyn Fn(&Url, &ToolchainDesc, &InstallPrefix, &DownloadCfg<'_>, &temp::Context), -) { - server.write( - &[MockManifestVersion::V2], - comps.enable_xz(), - comps.enable_zst(), - ); +impl TestContext { + fn new(edit: Option<&dyn Fn(&str, &mut MockChannel)>, comps: Compressions) -> Self { + let dist_tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap(); + let mock_dist_server = create_mock_dist_server(dist_tempdir.path(), edit); + let url = Url::parse(&format!("file://{}", dist_tempdir.path().to_string_lossy())).unwrap(); - let prefix_tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap(); + let mut cx = Self::from_dist_server(mock_dist_server, url, comps); + cx._tempdirs.push(dist_tempdir); + cx + } - let work_tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap(); - let tmp_cx = temp::Context::new( - work_tempdir.path().to_owned(), - DEFAULT_DIST_SERVER, - Box::new(|_| ()), - ); + fn from_dist_server(server: MockDistServer, url: Url, comps: Compressions) -> Self { + server.write( + &[MockManifestVersion::V2], + comps.enable_xz(), + comps.enable_zst(), + ); - let toolchain = ToolchainDesc::from_str("nightly-x86_64-apple-darwin").unwrap(); - let prefix = InstallPrefix::from(prefix_tempdir.path()); - let tp = TestProcess::new( - env::current_dir().unwrap(), - &["rustup"], - HashMap::default(), - "", - ); + let prefix_tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap(); - let download_cfg = DownloadCfg { - dist_root: "phony", - tmp_cx: &tmp_cx, - download_dir: &prefix.path().to_owned().join("downloads"), - notify_handler: &|event| { - println!("{event}"); - }, - process: &tp.process, - }; + let work_tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap(); + let tmp_cx = temp::Context::new( + work_tempdir.path().to_owned(), + DEFAULT_DIST_SERVER, + Box::new(|_| ()), + ); - f(url, &toolchain, &prefix, &download_cfg, &tmp_cx) -} + let toolchain = ToolchainDesc::from_str("nightly-x86_64-apple-darwin").unwrap(); + let prefix = InstallPrefix::from(prefix_tempdir.path()); + let tp = TestProcess::new( + env::current_dir().unwrap(), + &["rustup"], + HashMap::default(), + "", + ); -fn initial_install(comps: Compressions) { - setup(None, comps, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - run_future(update_from_dist( + Self { url, toolchain, + download_dir: prefix.path().join("downloads"), prefix, - &[], - &[], - download_cfg, + tp, tmp_cx, - false, - )) - .unwrap(); + _tempdirs: vec![prefix_tempdir, work_tempdir], + } + } - assert!(utils::path_exists(prefix.path().join("bin/rustc"))); - assert!(utils::path_exists(prefix.path().join("lib/libstd.rlib"))); - }); + fn default_dl_cfg(&self) -> DownloadCfg<'_> { + DownloadCfg { + dist_root: "phony", + tmp_cx: &self.tmp_cx, + download_dir: &self.download_dir, + notify_handler: &|event| println!("{event}"), + process: &self.tp.process, + } + } + + // Installs or updates a toolchain from a dist server. If an initial + // install then it will be installed with the default components. If + // an upgrade then all the existing components will be upgraded. + // FIXME: Unify this with dist::update_from_dist + async fn update_from_dist( + &self, + add: &[Component], + remove: &[Component], + force: bool, + ) -> Result { + self.update_from_dist_with_dl_cfg(add, remove, force, &self.default_dl_cfg()) + .await + } + + async fn update_from_dist_with_dl_cfg( + &self, + add: &[Component], + remove: &[Component], + force: bool, + dl_cfg: &DownloadCfg<'_>, + ) -> Result { + // Download the dist manifest and place it into the installation prefix + let manifest_url = make_manifest_url(&self.url, &self.toolchain)?; + let manifest_file = self.tmp_cx.new_file()?; + utils::download_file(&manifest_url, &manifest_file, None, &|_| {}, dl_cfg.process).await?; + let manifest_str = utils::read_file("manifest", &manifest_file)?; + let manifest = Manifest::parse(&manifest_str)?; + + // Read the manifest to update the components + let trip = self.toolchain.target.clone(); + let manifestation = Manifestation::open(self.prefix.clone(), trip.clone())?; + + // TODO on install, need to add profile components (but I guess we shouldn't test that logic here) + let mut profile_components = manifest.get_profile_components(Profile::Default, &trip)?; + let mut add_components = add.to_owned(); + add_components.append(&mut profile_components); + + let changes = Changes { + explicit_add_components: add_components, + remove_components: remove.to_owned(), + }; + + manifestation + .update( + &manifest, + changes, + force, + dl_cfg, + &self.toolchain.manifest_name(), + true, + ) + .await + } + + fn uninstall(&self) -> Result<()> { + let trip = self.toolchain.target.clone(); + let manifestation = Manifestation::open(self.prefix.clone(), trip)?; + let manifest = manifestation.load_manifest()?.unwrap(); + + manifestation.uninstall(&manifest, &self.tmp_cx, &|_| (), &self.tp.process)?; + + Ok(()) + } } -#[test] -fn initial_install_gziponly() { - initial_install(GZOnly); +async fn initial_install(comps: Compressions) { + let cx = TestContext::new(None, comps); + cx.update_from_dist(&[], &[], false).await.unwrap(); + + assert!(utils::path_exists(cx.prefix.path().join("bin/rustc"))); + assert!(utils::path_exists(cx.prefix.path().join("lib/libstd.rlib"))); } -#[test] -fn initial_install_xz() { - initial_install(AddXZ); +#[tokio::test] +async fn initial_install_gziponly() { + initial_install(GZOnly).await; } -#[test] -fn initial_install_zst() { - initial_install(AddZStd); +#[tokio::test] +async fn initial_install_xz() { + initial_install(AddXZ).await; } -#[test] -fn test_uninstall() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - uninstall(toolchain, prefix, tmp_cx, &|_| (), download_cfg.process).unwrap(); +#[tokio::test] +async fn initial_install_zst() { + initial_install(AddZStd).await; +} - assert!(!utils::path_exists(prefix.path().join("bin/rustc"))); - assert!(!utils::path_exists(prefix.path().join("lib/libstd.rlib"))); - }); +#[tokio::test] +async fn test_uninstall() { + let cx = TestContext::new(None, GZOnly); + cx.update_from_dist(&[], &[], false).await.unwrap(); + cx.uninstall().unwrap(); + + assert!(!utils::path_exists(cx.prefix.path().join("bin/rustc"))); + assert!(!utils::path_exists( + cx.prefix.path().join("lib/libstd.rlib") + )); } -#[test] -fn uninstall_removes_config_file() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert!(utils::path_exists( - prefix.manifest_file("multirust-config.toml") - )); - uninstall(toolchain, prefix, tmp_cx, &|_| (), download_cfg.process).unwrap(); - assert!(!utils::path_exists( - prefix.manifest_file("multirust-config.toml") - )); - }); +#[tokio::test] +async fn uninstall_removes_config_file() { + let cx = TestContext::new(None, GZOnly); + cx.update_from_dist(&[], &[], false).await.unwrap(); + assert!(utils::path_exists( + cx.prefix.manifest_file("multirust-config.toml") + )); + cx.uninstall().unwrap(); + assert!(!utils::path_exists( + cx.prefix.manifest_file("multirust-config.toml") + )); } -#[test] -fn upgrade() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - change_channel_date(url, "nightly", "2016-02-01"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert_eq!( - "2016-02-01", - fs::read_to_string(prefix.path().join("bin/rustc")).unwrap() - ); - change_channel_date(url, "nightly", "2016-02-02"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert_eq!( - "2016-02-02", - fs::read_to_string(prefix.path().join("bin/rustc")).unwrap() - ); - }); +#[tokio::test] +async fn upgrade() { + let cx = TestContext::new(None, GZOnly); + change_channel_date(&cx.url, "nightly", "2016-02-01"); + cx.update_from_dist(&[], &[], false).await.unwrap(); + assert_eq!( + "2016-02-01", + fs::read_to_string(cx.prefix.path().join("bin/rustc")).unwrap() + ); + change_channel_date(&cx.url, "nightly", "2016-02-02"); + cx.update_from_dist(&[], &[], false).await.unwrap(); + assert_eq!( + "2016-02-02", + fs::read_to_string(cx.prefix.path().join("bin/rustc")).unwrap() + ); } -#[test] -fn unavailable_component() { +#[tokio::test] +async fn unavailable_component() { // On day 2 the bonus component is no longer available let edit = &|date: &str, chan: &mut MockChannel| { // Require the bonus component every day. @@ -758,66 +629,41 @@ fn unavailable_component() { } }; - setup( - Some(edit), - GZOnly, - &|url, toolchain, prefix, download_cfg, tmp_cx| { - let adds = [Component::new( - "bonus".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), - true, - )]; - - change_channel_date(url, "nightly", "2016-02-01"); - // Update with bonus. - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert!(utils::path_exists(prefix.path().join("bin/bonus"))); - change_channel_date(url, "nightly", "2016-02-02"); - - // Update without bonus, should fail. - let err = run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap_err(); - match err.downcast::() { - Ok(RustupError::RequestedComponentsUnavailable { - components, - manifest, - toolchain, - }) => { - assert_eq!(toolchain, "nightly"); - let descriptions = components - .iter() - .map(|c| c.description(&manifest)) - .collect::>(); - assert_eq!(descriptions, ["'bonus' for target 'x86_64-apple-darwin'"]) - } - _ => panic!(), - } - }, - ); + let cx = TestContext::new(Some(edit), GZOnly); + let adds = [Component::new( + "bonus".to_string(), + Some(TargetTriple::new("x86_64-apple-darwin")), + true, + )]; + + change_channel_date(&cx.url, "nightly", "2016-02-01"); + // Update with bonus. + cx.update_from_dist(&adds, &[], false).await.unwrap(); + assert!(utils::path_exists(cx.prefix.path().join("bin/bonus"))); + change_channel_date(&cx.url, "nightly", "2016-02-02"); + + // Update without bonus, should fail. + let err = cx.update_from_dist(&[], &[], false).await.unwrap_err(); + match err.downcast::() { + Ok(RustupError::RequestedComponentsUnavailable { + components, + manifest, + toolchain, + }) => { + assert_eq!(toolchain, "nightly"); + let descriptions = components + .iter() + .map(|c| c.description(&manifest)) + .collect::>(); + assert_eq!(descriptions, ["'bonus' for target 'x86_64-apple-darwin'"]) + } + _ => panic!(), + } } // As unavailable_component, but the unavailable component is part of the profile. -#[test] -fn unavailable_component_from_profile() { +#[tokio::test] +async fn unavailable_component_from_profile() { // On day 2 the rustc component is no longer available let edit = &|date: &str, chan: &mut MockChannel| { // Mark the rustc package as unavailable in 2016-02-02 @@ -834,71 +680,36 @@ fn unavailable_component_from_profile() { } }; - setup( - Some(edit), - GZOnly, - &|url, toolchain, prefix, download_cfg, tmp_cx| { - change_channel_date(url, "nightly", "2016-02-01"); - // Update with rustc. - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert!(utils::path_exists(prefix.path().join("bin/rustc"))); - change_channel_date(url, "nightly", "2016-02-02"); - - // Update without rustc, should fail. - let err = run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap_err(); - match err.downcast::() { - Ok(RustupError::RequestedComponentsUnavailable { - components, - manifest, - toolchain, - }) => { - assert_eq!(toolchain, "nightly"); - let descriptions = components - .iter() - .map(|c| c.description(&manifest)) - .collect::>(); - assert_eq!(descriptions, ["'rustc' for target 'x86_64-apple-darwin'"]) - } - _ => panic!(), - } + let cx = TestContext::new(Some(edit), GZOnly); + change_channel_date(&cx.url, "nightly", "2016-02-01"); + // Update with rustc. + cx.update_from_dist(&[], &[], false).await.unwrap(); + assert!(utils::path_exists(cx.prefix.path().join("bin/rustc"))); + change_channel_date(&cx.url, "nightly", "2016-02-02"); + + // Update without rustc, should fail. + let err = cx.update_from_dist(&[], &[], false).await.unwrap_err(); + match err.downcast::() { + Ok(RustupError::RequestedComponentsUnavailable { + components, + manifest, + toolchain, + }) => { + assert_eq!(toolchain, "nightly"); + let descriptions = components + .iter() + .map(|c| c.description(&manifest)) + .collect::>(); + assert_eq!(descriptions, ["'rustc' for target 'x86_64-apple-darwin'"]) + } + _ => panic!(), + } - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - true, - )) - .unwrap(); - }, - ); + cx.update_from_dist(&[], &[], true).await.unwrap(); } -#[test] -fn removed_component() { +#[tokio::test] +async fn removed_component() { // On day 1 install the 'bonus' component, on day 2 it's no longer a component let edit = &|date: &str, chan: &mut MockChannel| { if date == "2016-02-01" { @@ -917,65 +728,40 @@ fn removed_component() { } }; - setup( - Some(edit), - GZOnly, - &|url, toolchain, prefix, download_cfg, tmp_cx| { - let adds = [Component::new( - "bonus".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), - true, - )]; - - // Update with bonus. - change_channel_date(url, "nightly", "2016-02-01"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert!(utils::path_exists(prefix.path().join("bin/bonus"))); - - // Update without bonus, should fail with RequestedComponentsUnavailable - change_channel_date(url, "nightly", "2016-02-02"); - let err = run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap_err(); - match err.downcast::() { - Ok(RustupError::RequestedComponentsUnavailable { - components, - manifest, - toolchain, - }) => { - assert_eq!(toolchain, "nightly"); - let descriptions = components - .iter() - .map(|c| c.description(&manifest)) - .collect::>(); - assert_eq!(descriptions, ["'bonus' for target 'x86_64-apple-darwin'"]) - } - _ => panic!(), - } - }, - ); + let cx = TestContext::new(Some(edit), GZOnly); + let adds = [Component::new( + "bonus".to_string(), + Some(TargetTriple::new("x86_64-apple-darwin")), + true, + )]; + + // Update with bonus. + change_channel_date(&cx.url, "nightly", "2016-02-01"); + cx.update_from_dist(&adds, &[], false).await.unwrap(); + assert!(utils::path_exists(cx.prefix.path().join("bin/bonus"))); + + // Update without bonus, should fail with RequestedComponentsUnavailable + change_channel_date(&cx.url, "nightly", "2016-02-02"); + let err = cx.update_from_dist(&[], &[], false).await.unwrap_err(); + match err.downcast::() { + Ok(RustupError::RequestedComponentsUnavailable { + components, + manifest, + toolchain, + }) => { + assert_eq!(toolchain, "nightly"); + let descriptions = components + .iter() + .map(|c| c.description(&manifest)) + .collect::>(); + assert_eq!(descriptions, ["'bonus' for target 'x86_64-apple-darwin'"]) + } + _ => panic!(), + } } -#[test] -fn unavailable_components_is_target() { +#[tokio::test] +async fn unavailable_components_is_target() { // On day 2 the rust-std component is no longer available let edit = &|date: &str, chan: &mut MockChannel| { // Mark the rust-std package as unavailable in 2016-02-02 @@ -992,85 +778,61 @@ fn unavailable_components_is_target() { } }; - setup( - Some(edit), - GZOnly, - &|url, toolchain, prefix, download_cfg, tmp_cx| { - let adds = [ - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - ), - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), - false, - ), - ]; - - // Update with rust-std - change_channel_date(url, "nightly", "2016-02-01"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); + let cx = TestContext::new(Some(edit), GZOnly); + let adds = [ + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + false, + ), + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, + ), + ]; - assert!(utils::path_exists( - prefix.path().join("lib/i686-apple-darwin/libstd.rlib") - )); - assert!(utils::path_exists( - prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib") - )); - - // Update without rust-std - change_channel_date(url, "nightly", "2016-02-02"); - let err = run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap_err(); - match err.downcast::() { - Ok(RustupError::RequestedComponentsUnavailable { - components, - manifest, - toolchain, - }) => { - assert_eq!(toolchain, "nightly"); - let descriptions = components - .iter() - .map(|c| c.description(&manifest)) - .collect::>(); - assert_eq!( - descriptions, - [ - "'rust-std' for target 'x86_64-apple-darwin'", - "'rust-std' for target 'i686-apple-darwin'", - "'rust-std' for target 'i686-unknown-linux-gnu'" - ] - ); - } - _ => panic!(), - } - }, - ); + // Update with rust-std + change_channel_date(&cx.url, "nightly", "2016-02-01"); + cx.update_from_dist(&adds, &[], false).await.unwrap(); + assert!(utils::path_exists( + cx.prefix.path().join("lib/i686-apple-darwin/libstd.rlib") + )); + assert!(utils::path_exists( + cx.prefix + .path() + .join("lib/i686-unknown-linux-gnu/libstd.rlib") + )); + + // Update without rust-std + change_channel_date(&cx.url, "nightly", "2016-02-02"); + let err = cx.update_from_dist(&[], &[], false).await.unwrap_err(); + match err.downcast::() { + Ok(RustupError::RequestedComponentsUnavailable { + components, + manifest, + toolchain, + }) => { + assert_eq!(toolchain, "nightly"); + let descriptions = components + .iter() + .map(|c| c.description(&manifest)) + .collect::>(); + assert_eq!( + descriptions, + [ + "'rust-std' for target 'x86_64-apple-darwin'", + "'rust-std' for target 'i686-apple-darwin'", + "'rust-std' for target 'i686-unknown-linux-gnu'" + ] + ); + } + _ => panic!(), + } } -#[test] -fn unavailable_components_with_same_target() { +#[tokio::test] +async fn unavailable_components_with_same_target() { // On day 2, the rust-std and rustc components are no longer available let edit = &|date: &str, chan: &mut MockChannel| { // Mark the rust-std package as unavailable in 2016-02-02 @@ -1100,364 +862,205 @@ fn unavailable_components_with_same_target() { } }; - setup( - Some(edit), - GZOnly, - &|url, toolchain, prefix, download_cfg, tmp_cx| { - // Update with rust-std and rustc - change_channel_date(url, "nightly", "2016-02-01"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert!(utils::path_exists(prefix.path().join("bin/rustc"))); - assert!(utils::path_exists(prefix.path().join("lib/libstd.rlib"))); - - // Update without rust-std and rustc - change_channel_date(url, "nightly", "2016-02-02"); - let err = run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap_err(); - match err.downcast::() { - Ok(RustupError::RequestedComponentsUnavailable { - components, - manifest, - toolchain, - }) => { - assert_eq!(toolchain, "nightly"); - let descriptions = components - .iter() - .map(|c| c.description(&manifest)) - .collect::>(); - assert_eq!( - descriptions, - [ - "'rustc' for target 'x86_64-apple-darwin'", - "'rust-std' for target 'x86_64-apple-darwin'" - ] - ); - } - _ => panic!(), - } - }, - ); + let cx = TestContext::new(Some(edit), GZOnly); + // Update with rust-std and rustc + change_channel_date(&cx.url, "nightly", "2016-02-01"); + cx.update_from_dist(&[], &[], false).await.unwrap(); + assert!(utils::path_exists(cx.prefix.path().join("bin/rustc"))); + assert!(utils::path_exists(cx.prefix.path().join("lib/libstd.rlib"))); + + // Update without rust-std and rustc + change_channel_date(&cx.url, "nightly", "2016-02-02"); + let err = cx.update_from_dist(&[], &[], false).await.unwrap_err(); + match err.downcast::() { + Ok(RustupError::RequestedComponentsUnavailable { + components, + manifest, + toolchain, + }) => { + assert_eq!(toolchain, "nightly"); + let descriptions = components + .iter() + .map(|c| c.description(&manifest)) + .collect::>(); + assert_eq!( + descriptions, + [ + "'rustc' for target 'x86_64-apple-darwin'", + "'rust-std' for target 'x86_64-apple-darwin'" + ] + ); + } + _ => panic!(), + } } -#[test] -fn update_preserves_extensions() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let adds = vec![ - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - ), - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), - false, - ), - ]; - - change_channel_date(url, "nightly", "2016-02-01"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, +#[tokio::test] +async fn update_preserves_extensions() { + let cx = TestContext::new(None, GZOnly); + + let adds = vec![ + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), false, - )) - .unwrap(); + ), + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, + ), + ]; - assert!(utils::path_exists( - prefix.path().join("lib/i686-apple-darwin/libstd.rlib") - )); - assert!(utils::path_exists( - prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib") - )); + change_channel_date(&cx.url, "nightly", "2016-02-01"); + cx.update_from_dist(&adds, &[], false).await.unwrap(); - change_channel_date(url, "nightly", "2016-02-02"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); + assert!(utils::path_exists( + cx.prefix.path().join("lib/i686-apple-darwin/libstd.rlib") + )); + assert!(utils::path_exists( + cx.prefix + .path() + .join("lib/i686-unknown-linux-gnu/libstd.rlib") + )); - assert!(utils::path_exists( - prefix.path().join("lib/i686-apple-darwin/libstd.rlib") - )); - assert!(utils::path_exists( - prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib") - )); - }); -} + change_channel_date(&cx.url, "nightly", "2016-02-02"); + cx.update_from_dist(&[], &[], false).await.unwrap(); -#[test] -fn update_makes_no_changes_for_identical_manifest() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let status = run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert_eq!(status, UpdateStatus::Changed); - let status = run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert_eq!(status, UpdateStatus::Unchanged); - }); + assert!(utils::path_exists( + cx.prefix.path().join("lib/i686-apple-darwin/libstd.rlib") + )); + assert!(utils::path_exists( + cx.prefix + .path() + .join("lib/i686-unknown-linux-gnu/libstd.rlib") + )); } -#[test] -fn add_extensions_for_initial_install() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let adds = vec![ - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - ), - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), - false, - ), - ]; - - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert!(utils::path_exists( - prefix.path().join("lib/i686-apple-darwin/libstd.rlib") - )); - assert!(utils::path_exists( - prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib") - )); - }); +#[tokio::test] +async fn update_makes_no_changes_for_identical_manifest() { + let cx = TestContext::new(None, GZOnly); + let status = cx.update_from_dist(&[], &[], false).await.unwrap(); + assert_eq!(status, UpdateStatus::Changed); + let status = cx.update_from_dist(&[], &[], false).await.unwrap(); + assert_eq!(status, UpdateStatus::Unchanged); } -#[test] -fn add_extensions_for_same_manifest() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, +#[tokio::test] +async fn add_extensions_for_initial_install() { + let cx = TestContext::new(None, GZOnly); + let adds = vec![ + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), false, - )) - .unwrap(); - - let adds = vec![ - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - ), - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), - false, - ), - ]; - - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, + ), + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-unknown-linux-gnu")), false, - )) - .unwrap(); + ), + ]; - assert!(utils::path_exists( - prefix.path().join("lib/i686-apple-darwin/libstd.rlib") - )); - assert!(utils::path_exists( - prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib") - )); - }); + cx.update_from_dist(&adds, &[], false).await.unwrap(); + assert!(utils::path_exists( + cx.prefix.path().join("lib/i686-apple-darwin/libstd.rlib") + )); + assert!(utils::path_exists( + cx.prefix + .path() + .join("lib/i686-unknown-linux-gnu/libstd.rlib") + )); } -#[test] -fn add_extensions_for_upgrade() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - change_channel_date(url, "nightly", "2016-02-01"); - - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); +#[tokio::test] +async fn add_extensions_for_same_manifest() { + let cx = TestContext::new(None, GZOnly); + cx.update_from_dist(&[], &[], false).await.unwrap(); - change_channel_date(url, "nightly", "2016-02-02"); - - let adds = vec![ - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - ), - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), - false, - ), - ]; - - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, + let adds = vec![ + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), false, - )) - .unwrap(); + ), + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, + ), + ]; - assert!(utils::path_exists( - prefix.path().join("lib/i686-apple-darwin/libstd.rlib") - )); - assert!(utils::path_exists( - prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib") - )); - }); + cx.update_from_dist(&adds, &[], false).await.unwrap(); + + assert!(utils::path_exists( + cx.prefix.path().join("lib/i686-apple-darwin/libstd.rlib") + )); + assert!(utils::path_exists( + cx.prefix + .path() + .join("lib/i686-unknown-linux-gnu/libstd.rlib") + )); } -#[test] -#[should_panic] -fn add_extension_not_in_manifest() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let adds = vec![Component::new( - "rust-bogus".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - true, - )]; +#[tokio::test] +async fn add_extensions_for_upgrade() { + let cx = TestContext::new(None, GZOnly); + change_channel_date(&cx.url, "nightly", "2016-02-01"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, + cx.update_from_dist(&[], &[], false).await.unwrap(); + + change_channel_date(&cx.url, "nightly", "2016-02-02"); + + let adds = vec![ + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), false, - )) - .unwrap(); - }); + ), + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, + ), + ]; + + cx.update_from_dist(&adds, &[], false).await.unwrap(); + + assert!(utils::path_exists( + cx.prefix.path().join("lib/i686-apple-darwin/libstd.rlib") + )); + assert!(utils::path_exists( + cx.prefix + .path() + .join("lib/i686-unknown-linux-gnu/libstd.rlib") + )); } -#[test] +#[tokio::test] #[should_panic] -fn add_extension_that_is_required_component() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let adds = vec![Component::new( - "rustc".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), - false, - )]; +async fn add_extension_not_in_manifest() { + let cx = TestContext::new(None, GZOnly); + let adds = vec![Component::new( + "rust-bogus".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + true, + )]; + + cx.update_from_dist(&adds, &[], false).await.unwrap(); +} - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - }); +#[tokio::test] +#[should_panic] +async fn add_extension_that_is_required_component() { + let cx = TestContext::new(None, GZOnly); + let adds = vec![Component::new( + "rustc".to_string(), + Some(TargetTriple::new("x86_64-apple-darwin")), + false, + )]; + + cx.update_from_dist(&adds, &[], false).await.unwrap(); } #[test] @@ -1468,246 +1071,136 @@ fn add_extensions_for_same_manifest_does_not_reinstall_other_components() {} #[ignore] fn add_extensions_for_same_manifest_when_extension_already_installed() {} -#[test] -fn add_extensions_does_not_remove_other_components() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - temp_cx| { - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - temp_cx, - false, - )) - .unwrap(); +#[tokio::test] +async fn add_extensions_does_not_remove_other_components() { + let cx = TestContext::new(None, GZOnly); + cx.update_from_dist(&[], &[], false).await.unwrap(); - let adds = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - )]; + let adds = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + false, + )]; - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - temp_cx, - false, - )) - .unwrap(); + cx.update_from_dist(&adds, &[], false).await.unwrap(); - assert!(utils::path_exists(prefix.path().join("bin/rustc"))); - }); + assert!(utils::path_exists(cx.prefix.path().join("bin/rustc"))); } // Asking to remove extensions on initial install is nonsense. -#[test] +#[tokio::test] #[should_panic] -fn remove_extensions_for_initial_install() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let removes = vec![Component::new( - "rustc".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), - false, - )]; - - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &removes, - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - }); +async fn remove_extensions_for_initial_install() { + let cx = TestContext::new(None, GZOnly); + let removes = vec![Component::new( + "rustc".to_string(), + Some(TargetTriple::new("x86_64-apple-darwin")), + false, + )]; + + cx.update_from_dist(&[], &removes, false).await.unwrap(); } -#[test] -fn remove_extensions_for_same_manifest() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let adds = vec![ - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - ), - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), - false, - ), - ]; - - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - - let removes = vec![Component::new( +#[tokio::test] +async fn remove_extensions_for_same_manifest() { + let cx = TestContext::new(None, GZOnly); + let adds = vec![ + Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), false, - )]; - - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &removes, - download_cfg, - tmp_cx, + ), + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-unknown-linux-gnu")), false, - )) - .unwrap(); + ), + ]; - assert!(!utils::path_exists( - prefix.path().join("lib/i686-apple-darwin/libstd.rlib") - )); - assert!(utils::path_exists( - prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib") - )); - }); -} + cx.update_from_dist(&adds, &[], false).await.unwrap(); -#[test] -fn remove_extensions_for_upgrade() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - change_channel_date(url, "nightly", "2016-02-01"); - - let adds = vec![ - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - ), - Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), - false, - ), - ]; - - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); + let removes = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + false, + )]; - change_channel_date(url, "nightly", "2016-02-02"); + cx.update_from_dist(&[], &removes, false).await.unwrap(); - let removes = vec![Component::new( + assert!(!utils::path_exists( + cx.prefix.path().join("lib/i686-apple-darwin/libstd.rlib") + )); + assert!(utils::path_exists( + cx.prefix + .path() + .join("lib/i686-unknown-linux-gnu/libstd.rlib") + )); +} + +#[tokio::test] +async fn remove_extensions_for_upgrade() { + let cx = TestContext::new(None, GZOnly); + change_channel_date(&cx.url, "nightly", "2016-02-01"); + + let adds = vec![ + Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), false, - )]; - - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &removes, - download_cfg, - tmp_cx, + ), + Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-unknown-linux-gnu")), false, - )) - .unwrap(); + ), + ]; - assert!(!utils::path_exists( - prefix.path().join("lib/i686-apple-darwin/libstd.rlib") - )); - assert!(utils::path_exists( - prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib") - )); - }); + cx.update_from_dist(&adds, &[], false).await.unwrap(); + + change_channel_date(&cx.url, "nightly", "2016-02-02"); + + let removes = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + false, + )]; + + cx.update_from_dist(&[], &removes, false).await.unwrap(); + + assert!(!utils::path_exists( + cx.prefix.path().join("lib/i686-apple-darwin/libstd.rlib") + )); + assert!(utils::path_exists( + cx.prefix + .path() + .join("lib/i686-unknown-linux-gnu/libstd.rlib") + )); } -#[test] +#[tokio::test] #[should_panic] -fn remove_extension_not_in_manifest() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - change_channel_date(url, "nightly", "2016-02-01"); - - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); +async fn remove_extension_not_in_manifest() { + let cx = TestContext::new(None, GZOnly); - change_channel_date(url, "nightly", "2016-02-02"); + change_channel_date(&cx.url, "nightly", "2016-02-01"); - let removes = vec![Component::new( - "rust-bogus".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - true, - )]; + cx.update_from_dist(&[], &[], false).await.unwrap(); - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &removes, - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - }); + change_channel_date(&cx.url, "nightly", "2016-02-02"); + + let removes = vec![Component::new( + "rust-bogus".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + true, + )]; + + cx.update_from_dist(&[], &removes, false).await.unwrap(); } // Extensions that don't exist in the manifest may still exist on disk // from a previous manifest. -#[test] -fn remove_extension_not_in_manifest_but_is_already_installed() { +#[tokio::test] +async fn remove_extension_not_in_manifest_but_is_already_installed() { let edit = &|date: &str, chan: &mut MockChannel| { if date == "2016-02-01" { let tpkg = chan.packages[0] @@ -1724,406 +1217,212 @@ fn remove_extension_not_in_manifest_but_is_already_installed() { chan.packages.retain(|p| p.name != "bonus"); } }; - setup( - Some(edit), - GZOnly, - &|url, toolchain, prefix, download_cfg, tmp_cx| { - change_channel_date(url, "nightly", "2016-02-01"); - - let adds = [Component::new( - "bonus".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), - true, - )]; - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - assert!(utils::path_exists(prefix.path().join("bin/bonus"))); - change_channel_date(url, "nightly", "2016-02-02"); + let cx = TestContext::new(Some(edit), GZOnly); - let removes = vec![Component::new( - "bonus".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), - true, - )]; - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &removes, - download_cfg, - tmp_cx, - false, - )) - .unwrap(); - }, - ); + change_channel_date(&cx.url, "nightly", "2016-02-01"); + + let adds = [Component::new( + "bonus".to_string(), + Some(TargetTriple::new("x86_64-apple-darwin")), + true, + )]; + cx.update_from_dist(&adds, &[], false).await.unwrap(); + assert!(utils::path_exists(cx.prefix.path().join("bin/bonus"))); + + change_channel_date(&cx.url, "nightly", "2016-02-02"); + + let removes = vec![Component::new( + "bonus".to_string(), + Some(TargetTriple::new("x86_64-apple-darwin")), + true, + )]; + cx.update_from_dist(&[], &removes, false).await.unwrap(); } -#[test] +#[tokio::test] #[should_panic] -fn remove_extension_that_is_required_component() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - temp_cx| { - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - temp_cx, - false, - )) - .unwrap(); +async fn remove_extension_that_is_required_component() { + let cx = TestContext::new(None, GZOnly); + cx.update_from_dist(&[], &[], false).await.unwrap(); - let removes = vec![Component::new( - "rustc".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), - false, - )]; + let removes = vec![Component::new( + "rustc".to_string(), + Some(TargetTriple::new("x86_64-apple-darwin")), + false, + )]; - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &removes, - download_cfg, - temp_cx, - false, - )) - .unwrap(); - }); + cx.update_from_dist(&[], &removes, false).await.unwrap(); } -#[test] +#[tokio::test] #[should_panic] -fn remove_extension_not_installed() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - temp_cx| { - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - temp_cx, - false, - )) - .unwrap(); +async fn remove_extension_not_installed() { + let cx = TestContext::new(None, GZOnly); + cx.update_from_dist(&[], &[], false).await.unwrap(); - let removes = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - )]; + let removes = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + false, + )]; - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &removes, - download_cfg, - temp_cx, - false, - )) - .unwrap(); - }); + cx.update_from_dist(&[], &removes, false).await.unwrap(); } #[test] #[ignore] fn remove_extensions_for_same_manifest_does_not_reinstall_other_components() {} -#[test] -fn remove_extensions_does_not_remove_other_components() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let adds = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - )]; +#[tokio::test] +async fn remove_extensions_does_not_remove_other_components() { + let cx = TestContext::new(None, GZOnly); + let adds = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + false, + )]; - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); + cx.update_from_dist(&adds, &[], false).await.unwrap(); - let removes = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - )]; + let removes = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + false, + )]; - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &removes, - download_cfg, - tmp_cx, - false, - )) - .unwrap(); + cx.update_from_dist(&[], &removes, false).await.unwrap(); - assert!(utils::path_exists(prefix.path().join("bin/rustc"))); - }); + assert!(utils::path_exists(cx.prefix.path().join("bin/rustc"))); } -#[test] -fn add_and_remove_for_upgrade() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - change_channel_date(url, "nightly", "2016-02-01"); - - let adds = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), - false, - )]; +#[tokio::test] +async fn add_and_remove_for_upgrade() { + let cx = TestContext::new(None, GZOnly); + change_channel_date(&cx.url, "nightly", "2016-02-01"); - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); + let adds = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, + )]; - change_channel_date(url, "nightly", "2016-02-02"); + cx.update_from_dist(&adds, &[], false).await.unwrap(); - let adds = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - )]; + change_channel_date(&cx.url, "nightly", "2016-02-02"); - let removes = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), - false, - )]; + let adds = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + false, + )]; - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &removes, - download_cfg, - tmp_cx, - false, - )) - .unwrap(); + let removes = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, + )]; - assert!(utils::path_exists( - prefix.path().join("lib/i686-apple-darwin/libstd.rlib") - )); - assert!(!utils::path_exists( - prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib") - )); - }); + cx.update_from_dist(&adds, &removes, false).await.unwrap(); + + assert!(utils::path_exists( + cx.prefix.path().join("lib/i686-apple-darwin/libstd.rlib") + )); + assert!(!utils::path_exists( + cx.prefix + .path() + .join("lib/i686-unknown-linux-gnu/libstd.rlib") + )); } -#[test] -fn add_and_remove() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let adds = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), - false, - )]; +#[tokio::test] +async fn add_and_remove() { + let cx = TestContext::new(None, GZOnly); - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); + let adds = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, + )]; - let adds = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - )]; + cx.update_from_dist(&adds, &[], false).await.unwrap(); - let removes = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), - false, - )]; + let adds = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + false, + )]; - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &removes, - download_cfg, - tmp_cx, - false, - )) - .unwrap(); + let removes = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, + )]; - assert!(utils::path_exists( - prefix.path().join("lib/i686-apple-darwin/libstd.rlib") - )); - assert!(!utils::path_exists( - prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib") - )); - }); + cx.update_from_dist(&adds, &removes, false).await.unwrap(); + + assert!(utils::path_exists( + cx.prefix.path().join("lib/i686-apple-darwin/libstd.rlib") + )); + assert!(!utils::path_exists( + cx.prefix + .path() + .join("lib/i686-unknown-linux-gnu/libstd.rlib") + )); } -#[test] -fn add_and_remove_same_component() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - temp_cx| { - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - temp_cx, - false, - )) - .unwrap(); +#[tokio::test] +async fn add_and_remove_same_component() { + let cx = TestContext::new(None, GZOnly); + cx.update_from_dist(&[], &[], false).await.unwrap(); - let adds = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - )]; + let adds = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + false, + )]; - let removes = vec![Component::new( - "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), - false, - )]; + let removes = vec![Component::new( + "rust-std".to_string(), + Some(TargetTriple::new("i686-apple-darwin")), + false, + )]; - run_future(update_from_dist( - url, - toolchain, - prefix, - &adds, - &removes, - download_cfg, - temp_cx, - false, - )) + cx.update_from_dist(&adds, &removes, false) + .await .expect_err("can't both add and remove components"); - }); } -#[test] -fn bad_component_hash() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let path = url.to_file_path().unwrap(); - let path = path.join("dist/2016-02-02/rustc-nightly-x86_64-apple-darwin.tar.gz"); - utils_raw::write_file(&path, "bogus").unwrap(); - - let err = run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap_err(); +#[tokio::test] +async fn bad_component_hash() { + let cx = TestContext::new(None, GZOnly); - match err.downcast::() { - Ok(RustupError::ComponentDownloadFailed(..)) => (), - _ => panic!(), - } - }); + let path = cx.url.to_file_path().unwrap(); + let path = path.join("dist/2016-02-02/rustc-nightly-x86_64-apple-darwin.tar.gz"); + utils_raw::write_file(&path, "bogus").unwrap(); + + let err = cx.update_from_dist(&[], &[], false).await.unwrap_err(); + + match err.downcast::() { + Ok(RustupError::ComponentDownloadFailed(..)) => (), + _ => panic!(), + } } -#[test] -fn unable_to_download_component() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let path = url.to_file_path().unwrap(); - let path = path.join("dist/2016-02-02/rustc-nightly-x86_64-apple-darwin.tar.gz"); - fs::remove_file(path).unwrap(); - - let err = run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap_err(); +#[tokio::test] +async fn unable_to_download_component() { + let cx = TestContext::new(None, GZOnly); - match err.downcast::() { - Ok(RustupError::ComponentDownloadFailed(..)) => (), - _ => panic!(), - } - }); + let path = cx.url.to_file_path().unwrap(); + let path = path.join("dist/2016-02-02/rustc-nightly-x86_64-apple-darwin.tar.gz"); + fs::remove_file(path).unwrap(); + + let err = cx.update_from_dist(&[], &[], false).await.unwrap_err(); + + match err.downcast::() { + Ok(RustupError::ComponentDownloadFailed(..)) => (), + _ => panic!(), + } } fn prevent_installation(prefix: &InstallPrefix) { @@ -2142,157 +1441,90 @@ fn allow_installation(prefix: &InstallPrefix) { utils::remove_file("install-blocker", &install_blocker).unwrap(); } -#[test] -fn reuse_downloaded_file() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - prevent_installation(prefix); - - let reuse_notification_fired = Arc::new(Cell::new(false)); - - let download_cfg = DownloadCfg { - dist_root: download_cfg.dist_root, - tmp_cx: download_cfg.tmp_cx, - download_dir: download_cfg.download_dir, - notify_handler: &|n| { - if let Notification::FileAlreadyDownloaded = n { - reuse_notification_fired.set(true); - } - }, - process: download_cfg.process, - }; +#[tokio::test] +async fn reuse_downloaded_file() { + let cx = TestContext::new(None, GZOnly); + prevent_installation(&cx.prefix); - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - &download_cfg, - tmp_cx, - false, - )) - .unwrap_err(); - assert!(!reuse_notification_fired.get()); + let reuse_notification_fired = Arc::new(Cell::new(false)); + let dl_cfg = DownloadCfg { + notify_handler: &|n| { + if let Notification::FileAlreadyDownloaded = n { + reuse_notification_fired.set(true); + } + }, + ..cx.default_dl_cfg() + }; - allow_installation(prefix); + cx.update_from_dist_with_dl_cfg(&[], &[], false, &dl_cfg) + .await + .unwrap_err(); + assert!(!reuse_notification_fired.get()); - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - &download_cfg, - tmp_cx, - false, - )) + allow_installation(&cx.prefix); + cx.update_from_dist_with_dl_cfg(&[], &[], false, &dl_cfg) + .await .unwrap(); - assert!(reuse_notification_fired.get()); - }) + assert!(reuse_notification_fired.get()); } -#[test] -fn checks_files_hashes_before_reuse() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - let path = url.to_file_path().unwrap(); - let target_hash = utils::read_file( - "target hash", - &path.join("dist/2016-02-02/rustc-nightly-x86_64-apple-darwin.tar.gz.sha256"), - ) - .unwrap()[..64] - .to_owned(); - let prev_download = download_cfg.download_dir.join(target_hash); - utils::ensure_dir_exists( - "download dir", - download_cfg.download_dir, - &|_: Notification<'_>| {}, - ) - .unwrap(); - utils::write_file("bad previous download", &prev_download, "bad content").unwrap(); - println!("wrote previous download to {}", prev_download.display()); - - let noticed_bad_checksum = Arc::new(Cell::new(false)); - let download_cfg = DownloadCfg { - dist_root: download_cfg.dist_root, - tmp_cx: download_cfg.tmp_cx, - download_dir: download_cfg.download_dir, - notify_handler: &|n| { - if let Notification::CachedFileChecksumFailed = n { - noticed_bad_checksum.set(true); - } - }, - process: download_cfg.process, - }; +#[tokio::test] +async fn checks_files_hashes_before_reuse() { + let cx = TestContext::new(None, GZOnly); - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - &download_cfg, - tmp_cx, - false, - )) + let path = cx.url.to_file_path().unwrap(); + let target_hash = utils::read_file( + "target hash", + &path.join("dist/2016-02-02/rustc-nightly-x86_64-apple-darwin.tar.gz.sha256"), + ) + .unwrap()[..64] + .to_owned(); + let prev_download = cx.download_dir.join(target_hash); + utils::ensure_dir_exists("download dir", &cx.download_dir, &|_: Notification<'_>| {}).unwrap(); + utils::write_file("bad previous download", &prev_download, "bad content").unwrap(); + println!("wrote previous download to {}", prev_download.display()); + + let noticed_bad_checksum = Arc::new(Cell::new(false)); + let dl_cfg = DownloadCfg { + notify_handler: &|n| { + if let Notification::CachedFileChecksumFailed = n { + noticed_bad_checksum.set(true); + } + }, + ..cx.default_dl_cfg() + }; + + cx.update_from_dist_with_dl_cfg(&[], &[], false, &dl_cfg) + .await .unwrap(); - assert!(noticed_bad_checksum.get()); - }) + assert!(noticed_bad_checksum.get()); } -#[test] -fn handle_corrupt_partial_downloads() { - setup(None, GZOnly, &|url, - toolchain, - prefix, - download_cfg, - tmp_cx| { - // write a corrupt partial out - let path = url.to_file_path().unwrap(); - let target_hash = utils::read_file( - "target hash", - &path.join("dist/2016-02-02/rustc-nightly-x86_64-apple-darwin.tar.gz.sha256"), - ) - .unwrap()[..SHA256_HASH_LEN] - .to_owned(); - - utils::ensure_dir_exists( - "download dir", - download_cfg.download_dir, - &|_: Notification<'_>| {}, - ) - .unwrap(); - let partial_path = download_cfg - .download_dir - .join(format!("{target_hash}.partial")); - utils_raw::write_file( - &partial_path, - "file will be resumed from here and not match hash", - ) - .unwrap(); +#[tokio::test] +async fn handle_corrupt_partial_downloads() { + let cx = TestContext::new(None, GZOnly); - run_future(update_from_dist( - url, - toolchain, - prefix, - &[], - &[], - download_cfg, - tmp_cx, - false, - )) - .unwrap(); + // write a corrupt partial out + let path = cx.url.to_file_path().unwrap(); + let target_hash = utils::read_file( + "target hash", + &path.join("dist/2016-02-02/rustc-nightly-x86_64-apple-darwin.tar.gz.sha256"), + ) + .unwrap()[..SHA256_HASH_LEN] + .to_owned(); + + utils::ensure_dir_exists("download dir", &cx.download_dir, &|_: Notification<'_>| {}).unwrap(); + let partial_path = cx.download_dir.join(format!("{target_hash}.partial")); + utils_raw::write_file( + &partial_path, + "file will be resumed from here and not match hash", + ) + .unwrap(); - assert!(utils::path_exists(prefix.path().join("bin/rustc"))); - assert!(utils::path_exists(prefix.path().join("lib/libstd.rlib"))); - }); + cx.update_from_dist(&[], &[], false).await.unwrap(); + + assert!(utils::path_exists(cx.prefix.path().join("bin/rustc"))); + assert!(utils::path_exists(cx.prefix.path().join("lib/libstd.rlib"))); }