Skip to content

Commit

Permalink
Test that previously-downloaded files are found and re-used
Browse files Browse the repository at this point in the history
The test is only that the file-reuse notification is fired. In order to
detect this in the test, I've pushed through the notification handler
that gets given to `manifestation.update`, which in practice is nearly
always a clone of the one in DownloadCfg (but notably not when called as
in the test cases).
  • Loading branch information
jelford committed Mar 20, 2017
1 parent 8ab727a commit 2ce8d72
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 12 deletions.
18 changes: 7 additions & 11 deletions src/rustup-dist/src/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,13 +504,9 @@ impl ops::Deref for File {

impl<'a> DownloadCfg<'a> {

fn notify_handler(&self, event: Notification) {
(self.notify_handler)(event);
}

pub fn download(&self, url: &Url, hash: &str) -> Result<File> {
pub fn download(&self, url: &Url, hash: &str, notify_handler: &'a Fn(Notification)) -> Result<File> {

try!(utils::ensure_dir_exists("Download Directory", &self.download_dir, &|n| self.notify_handler(n.into())));
try!(utils::ensure_dir_exists("Download Directory", &self.download_dir, &|n| notify_handler(n.into())));
let target_file = self.download_dir.join(Path::new(hash));

if target_file.exists() {
Expand All @@ -528,11 +524,11 @@ impl<'a> DownloadCfg<'a> {
}
let cached_result = hasher.result_str();
if hash == cached_result {
self.notify_handler(Notification::FileAlreadyDownloaded);
self.notify_handler(Notification::ChecksumValid(&url.to_string()));
notify_handler(Notification::FileAlreadyDownloaded);
notify_handler(Notification::ChecksumValid(&url.to_string()));
return Ok(File { path: target_file, });
} else {
self.notify_handler(Notification::CachedFileChecksumFailed);
notify_handler(Notification::CachedFileChecksumFailed);
try!(fs::remove_file(&target_file).chain_err(|| "cleaning up previous download"));
}
}
Expand All @@ -542,7 +538,7 @@ impl<'a> DownloadCfg<'a> {
try!(utils::download_file(&url,
&target_file,
Some(&mut hasher),
&|n| self.notify_handler(n.into())));
&|n| notify_handler(n.into())));

let actual_hash = hasher.result_str();

Expand All @@ -554,7 +550,7 @@ impl<'a> DownloadCfg<'a> {
calculated: actual_hash,
}.into());
} else {
self.notify_handler(Notification::ChecksumValid(&url.to_string()));
notify_handler(Notification::ChecksumValid(&url.to_string()));
return Ok(File { path: target_file, })
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/rustup-dist/src/manifestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl Manifestation {

let url_url = try!(utils::parse_url(&url));

let dowloaded_file = try!(download_cfg.download(&url_url, &hash).chain_err(|| {
let dowloaded_file = try!(download_cfg.download(&url_url, &hash, &notify_handler).chain_err(|| {
ErrorKind::ComponentDownloadFailed(component.clone())
}));
things_downloaded.push(hash);
Expand Down
58 changes: 58 additions & 0 deletions src/rustup-dist/tests/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ use rustup_dist::temp;
use rustup_dist::manifestation::{Manifestation, UpdateStatus, Changes};
use rustup_dist::manifest::{Manifest, Component};
use url::Url;
use std::cell::Cell;
use std::fs;
use std::path::Path;
use std::sync::Arc;

use tempdir::TempDir;

// Creates a mock dist server populated with some test data
Expand Down Expand Up @@ -921,3 +924,58 @@ fn unable_to_download_component() {
}
});
}

fn prevent_installation(prefix: &InstallPrefix) {
utils::ensure_dir_exists("installation path", &prefix.path().join("lib"), &|_|{}).unwrap();
let install_blocker = prefix.path().join("lib").join("rustlib");
utils::write_file("install-blocker", &install_blocker, "fail-installation").unwrap();
}

fn allow_installation(prefix: &InstallPrefix) {
let install_blocker = prefix.path().join("lib").join("rustlib");
utils::remove_file("install-blocker", &install_blocker).unwrap();
}

#[test]
fn reuse_downloaded_file() {
setup(None, &|url, toolchain, prefix, download_cfg, temp_cfg| {

prevent_installation(prefix);

update_from_dist(url, toolchain, prefix, &[], &[], download_cfg, temp_cfg, &|_| {}).unwrap_err();

allow_installation(&prefix);

let reuse_notification_fired = Arc::new(Cell::new(false));
update_from_dist(url, toolchain, prefix, &[], &[], download_cfg, temp_cfg, &|n| {
if let Notification::FileAlreadyDownloaded = n {
reuse_notification_fired.set(true);
}
}).unwrap();

assert!(reuse_notification_fired.get());
})
}

#[test]
fn checks_files_hashes_before_reuse() {
setup(None, &|url, toolchain, prefix, download_cfg, temp_cfg| {

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, &|_|{}).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));
update_from_dist(url, toolchain, prefix, &[], &[], download_cfg, temp_cfg, &|n| {
println!("{:?}", n);
if let Notification::CachedFileChecksumFailed = n {
noticed_bad_checksum.set(true);
}
}).unwrap();

assert!(noticed_bad_checksum.get());
})
}

0 comments on commit 2ce8d72

Please sign in to comment.