Skip to content

Commit

Permalink
test(binaryinstall): Add initial tests
Browse files Browse the repository at this point in the history
  • Loading branch information
drager committed Jan 26, 2019
1 parent c8410f2 commit e4fdfd7
Show file tree
Hide file tree
Showing 6 changed files with 381 additions and 14 deletions.
3 changes: 3 additions & 0 deletions binary-install/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ is_executable = "0.1.2"
siphasher = "0.2.3"
tar = "0.4.16"
zip = "0.5.0"

[dev-dependencies]
tempfile = "3.0.5"
97 changes: 83 additions & 14 deletions binary-install/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ use std::path::{Path, PathBuf};

/// Global cache for wasm-pack, currently containing binaries downloaded from
/// urls like wasm-bindgen and such.
#[derive(Debug)]
pub struct Cache {
destination: PathBuf,
}

/// Representation of a downloaded tarball/zip
#[derive(Debug)]
pub struct Download {
root: PathBuf,
}
Expand Down Expand Up @@ -81,22 +83,10 @@ impl Cache {
binaries: &[&str],
url: &str,
) -> Result<Option<Download>, Error> {
let mut hasher = SipHasher13::new();
url.hash(&mut hasher);
let result = hasher.finish();
let hex = hex::encode(&[
(result >> 0) as u8,
(result >> 8) as u8,
(result >> 16) as u8,
(result >> 24) as u8,
(result >> 32) as u8,
(result >> 40) as u8,
(result >> 48) as u8,
(result >> 56) as u8,
]);
let dirname = format!("{}-{}", name, hex);
let dirname = hashed_dirname(url, name);

let destination = self.destination.join(&dirname);

if destination.exists() {
return Ok(Some(Download { root: destination }));
}
Expand Down Expand Up @@ -270,3 +260,82 @@ fn curl(url: &str) -> Result<Vec<u8>, Error> {
)
}
}

fn hashed_dirname(url: &str, name: &str) -> String {
let mut hasher = SipHasher13::new();
url.hash(&mut hasher);
let result = hasher.finish();
let hex = hex::encode(&[
(result >> 0) as u8,
(result >> 8) as u8,
(result >> 16) as u8,
(result >> 24) as u8,
(result >> 32) as u8,
(result >> 40) as u8,
(result >> 48) as u8,
(result >> 56) as u8,
]);
format!("{}-{}", name, hex)
}

#[test]
fn it_returns_same_hash_for_same_name_and_url() {
let name = "wasm-pack";
let url = "http://localhost:7878/wasm-pack-v0.6.0.tar.gz";

let first = hashed_dirname(url, name);
let second = hashed_dirname(url, name);

assert!(!first.is_empty());
assert!(!second.is_empty());
assert_eq!(first, second);
}

#[test]
fn it_returns_different_hashes_for_different_urls() {
let name = "wasm-pack";
let url = "http://localhost:7878/wasm-pack-v0.5.1.tar.gz";
let second_url = "http://localhost:7878/wasm-pack-v0.6.0.tar.gz";

let first = hashed_dirname(url, name);
let second = hashed_dirname(second_url, name);

assert_ne!(first, second);
}

#[test]
fn it_returns_cache_dir() {
let name = "wasm-pack";
let cache = Cache::new(name);

let expected = dirs::cache_dir()
.unwrap()
.join(PathBuf::from(".".to_owned() + name));

assert!(cache.is_ok());
assert_eq!(cache.unwrap().destination, expected);
}

#[test]
fn it_returns_destination_if_binary_already_exists() {
use std::fs;

let binary_name = "wasm-pack";
let binaries = vec![binary_name];

let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path());
let url = &format!("{}/{}.tar.gz", "http://localhost:7878", binary_name);

let dirname = hashed_dirname(&url, &binary_name);
let full_path = dir.path().join(dirname);

// Create temporary directory and binary to simulate that
// a cached binary already exists.
fs::create_dir_all(full_path).unwrap();

let dl = cache.download(true, binary_name, &binaries, url);

assert!(dl.is_ok());
assert!(dl.unwrap().is_some())
}
141 changes: 141 additions & 0 deletions binary-install/tests/all/cache.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use binary_install::Cache;
use std::path::Path;
use utils;

#[test]
fn it_returns_none_if_install_is_not_permitted() {
let binary_name = "wasm-pack";
let binaries = vec![binary_name];

let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path());

let dl = cache.download(
false,
binary_name,
&binaries,
&format!("{}/{}.tar.gz", "", binary_name),
);

assert!(dl.is_ok());
assert!(dl.unwrap().is_none())
}

#[test]
fn it_downloads_tarball() {
let server_port = 7880;
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port);
let binary_name = "wasm-pack";
let binaries = vec![binary_name];

// Create a temporary tarball.
let tarball = utils::create_tarball(binary_name).ok();

// Spin up a local TcpListener.
utils::start_server(server_port, tarball);

let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path());

let dl = cache.download(
true,
binary_name,
&binaries,
&format!("{}/{}.tar.gz", &url, binary_name),
);

assert!(dl.is_ok());
assert!(dl.unwrap().is_some())
}

#[test]
fn it_returns_error_when_it_failed_to_download() {
let server_port = 7881;
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port);
let binary_name = "wasm-pack";
let binaries = vec![binary_name];

let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path());
let full_url = &format!("{}/{}.tar.gz", &url, binary_name);

let dl = cache.download(true, binary_name, &binaries, full_url);

assert!(dl.is_err());
assert_eq!(
&format!("failed to download from {}", full_url),
&format!("{}", dl.unwrap_err())
);
}

#[test]
fn it_returns_error_when_it_failed_to_extract_tarball() {
let server_port = 7882;
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port);
let binary_name = "wasm-pack";
let binaries = vec![binary_name];

let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path());
let full_url = &format!("{}/{}.tar.gz", &url, binary_name);

// Spin up a local TcpListener.
utils::start_server(server_port, None);

let dl = cache.download(true, binary_name, &binaries, full_url);

assert!(dl.is_err());
assert_eq!(
&format!("failed to extract tarball from {}", full_url),
&format!("{}", dl.unwrap_err())
);
}

#[test]
fn it_returns_error_when_it_failed_to_extract_zip() {
let server_port = 7883;
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port);
let binary_name = "wasm-pack";
let binaries = vec![binary_name];

let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path());
let full_url = &format!("{}/{}.zip", &url, binary_name);

// Spin up a local TcpListener.
utils::start_server(server_port, None);

let dl = cache.download(true, binary_name, &binaries, full_url);

assert!(dl.is_err());
assert_eq!(
&format!("failed to extract zip from {}", full_url),
&format!("{}", dl.unwrap_err())
);
}

#[test]
#[should_panic(expected = "don't know how to extract http://localhost:7884/wasm-pack.bin")]
fn it_panics_if_not_tarball_or_zip() {
let server_port = 7884;
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port);
let binary_name = "wasm-pack";
let binaries = vec![binary_name];

let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path());
let full_url = &format!("{}/{}.bin", &url, binary_name);

// Spin up a local TcpListener.
utils::start_server(server_port, None);

let _ = cache.download(true, binary_name, &binaries, full_url);
}

#[test]
fn it_joins_path_with_destination() {
let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path());

assert_eq!(dir.path().join("hello"), cache.join(Path::new("hello")));
}
74 changes: 74 additions & 0 deletions binary-install/tests/all/download.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use binary_install::Download;
use std::fs::OpenOptions;
use std::os::unix::fs::OpenOptionsExt;

#[test]
#[cfg(unix)]
fn it_returns_binary_name() {
let binary_name = "wasm-pack";

let dir = tempfile::TempDir::new().unwrap();
let download = Download::at(dir.path());

let full_path = dir.path().join(binary_name);

let mut options = OpenOptions::new();
options.create(true);
options.write(true);

// Make the "binary" an executable.
options.mode(0o755);

options.open(&full_path).unwrap();

let binary = download.binary(binary_name);

assert!(binary.is_ok());
assert_eq!(full_path, binary.unwrap());
}

#[test]
fn it_bails_if_not_file() {
let binary_name = "wasm-pack";

let dir = tempfile::TempDir::new().unwrap();
let download = Download::at(dir.path());

let full_path = dir.path().join(binary_name);

let mut options = OpenOptions::new();
options.create(true);
options.write(true);

let binary = download.binary(binary_name);

assert!(binary.is_err());
assert_eq!(
format!("{} binary does not exist", full_path.to_str().unwrap()),
binary.unwrap_err().to_string()
);
}

#[test]
fn it_bails_if_not_executable() {
let binary_name = "wasm-pack";

let dir = tempfile::TempDir::new().unwrap();
let download = Download::at(dir.path());

let full_path = dir.path().join(binary_name);

let mut options = OpenOptions::new();
options.create(true);
options.write(true);

options.open(&full_path).unwrap();

let binary = download.binary(binary_name);

assert!(binary.is_err());
assert_eq!(
format!("{} is not executable", full_path.to_str().unwrap()),
binary.unwrap_err().to_string()
);
}
7 changes: 7 additions & 0 deletions binary-install/tests/all/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
extern crate binary_install;
extern crate flate2;
extern crate tar;

mod cache;
mod download;
mod utils;
Loading

0 comments on commit e4fdfd7

Please sign in to comment.