Skip to content

Commit f6c2464

Browse files
committed
test(binaryinstall): Add initial tests
1 parent c8410f2 commit f6c2464

File tree

6 files changed

+375
-14
lines changed

6 files changed

+375
-14
lines changed

binary-install/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ is_executable = "0.1.2"
1818
siphasher = "0.2.3"
1919
tar = "0.4.16"
2020
zip = "0.5.0"
21+
22+
[dev-dependencies]
23+
tempfile = "3.0.5"

binary-install/src/lib.rs

+83-14
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ use std::path::{Path, PathBuf};
2323

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

3031
/// Representation of a downloaded tarball/zip
32+
#[derive(Debug)]
3133
pub struct Download {
3234
root: PathBuf,
3335
}
@@ -81,22 +83,10 @@ impl Cache {
8183
binaries: &[&str],
8284
url: &str,
8385
) -> Result<Option<Download>, Error> {
84-
let mut hasher = SipHasher13::new();
85-
url.hash(&mut hasher);
86-
let result = hasher.finish();
87-
let hex = hex::encode(&[
88-
(result >> 0) as u8,
89-
(result >> 8) as u8,
90-
(result >> 16) as u8,
91-
(result >> 24) as u8,
92-
(result >> 32) as u8,
93-
(result >> 40) as u8,
94-
(result >> 48) as u8,
95-
(result >> 56) as u8,
96-
]);
97-
let dirname = format!("{}-{}", name, hex);
86+
let dirname = hashed_dirname(url, name);
9887

9988
let destination = self.destination.join(&dirname);
89+
10090
if destination.exists() {
10191
return Ok(Some(Download { root: destination }));
10292
}
@@ -270,3 +260,82 @@ fn curl(url: &str) -> Result<Vec<u8>, Error> {
270260
)
271261
}
272262
}
263+
264+
fn hashed_dirname(url: &str, name: &str) -> String {
265+
let mut hasher = SipHasher13::new();
266+
url.hash(&mut hasher);
267+
let result = hasher.finish();
268+
let hex = hex::encode(&[
269+
(result >> 0) as u8,
270+
(result >> 8) as u8,
271+
(result >> 16) as u8,
272+
(result >> 24) as u8,
273+
(result >> 32) as u8,
274+
(result >> 40) as u8,
275+
(result >> 48) as u8,
276+
(result >> 56) as u8,
277+
]);
278+
format!("{}-{}", name, hex)
279+
}
280+
281+
#[test]
282+
fn it_returns_same_hash_for_same_name_and_url() {
283+
let name = "wasm-pack";
284+
let url = "http://localhost:7878/wasm-pack-v0.6.0.tar.gz";
285+
286+
let first = hashed_dirname(url, name);
287+
let second = hashed_dirname(url, name);
288+
289+
assert!(!first.is_empty());
290+
assert!(!second.is_empty());
291+
assert_eq!(first, second);
292+
}
293+
294+
#[test]
295+
fn it_returns_different_hashes_for_different_urls() {
296+
let name = "wasm-pack";
297+
let url = "http://localhost:7878/wasm-pack-v0.5.1.tar.gz";
298+
let second_url = "http://localhost:7878/wasm-pack-v0.6.0.tar.gz";
299+
300+
let first = hashed_dirname(url, name);
301+
let second = hashed_dirname(second_url, name);
302+
303+
assert_ne!(first, second);
304+
}
305+
306+
#[test]
307+
fn it_returns_cache_dir() {
308+
let name = "wasm-pack";
309+
let cache = Cache::new(name);
310+
311+
let expected = dirs::cache_dir()
312+
.unwrap()
313+
.join(PathBuf::from(".".to_owned() + name));
314+
315+
assert!(cache.is_ok());
316+
assert_eq!(cache.unwrap().destination, expected);
317+
}
318+
319+
#[test]
320+
fn it_returns_destination_if_binary_already_exists() {
321+
use std::fs;
322+
323+
let binary_name = "wasm-pack";
324+
let binaries = vec![binary_name];
325+
326+
let dir = tempfile::TempDir::new().unwrap();
327+
let cache = Cache::at(dir.path());
328+
let url = &format!("{}/{}.tar.gz", "http://localhost:7878", binary_name);
329+
330+
let dirname = hashed_dirname(&url, &binary_name);
331+
let full_path = dir.path().join(dirname);
332+
333+
// Create temporary directory and binary to simulate that
334+
// a cached binary already exists.
335+
fs::create_dir_all(full_path).unwrap();
336+
337+
let dl = cache.download(true, binary_name, &binaries, url);
338+
339+
assert!(dl.is_ok());
340+
assert!(dl.unwrap().is_some())
341+
}

binary-install/tests/all/cache.rs

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
use binary_install::Cache;
2+
use std::path::Path;
3+
use utils;
4+
5+
#[test]
6+
fn it_returns_none_if_install_is_not_permitted() {
7+
let binary_name = "wasm-pack";
8+
let binaries = vec![binary_name];
9+
10+
let dir = tempfile::TempDir::new().unwrap();
11+
let cache = Cache::at(dir.path());
12+
13+
let dl = cache.download(
14+
false,
15+
binary_name,
16+
&binaries,
17+
&format!("{}/{}.tar.gz", "", binary_name),
18+
);
19+
20+
assert!(dl.is_ok());
21+
assert!(dl.unwrap().is_none())
22+
}
23+
24+
#[test]
25+
fn it_downloads_tarball() {
26+
let server_port = 7880;
27+
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port);
28+
let binary_name = "wasm-pack";
29+
let binaries = vec![binary_name];
30+
31+
// Create a temporary tarball.
32+
let tarball = utils::create_tarball(binary_name).ok();
33+
34+
// Spin up a local TcpListener.
35+
utils::start_server(server_port, tarball);
36+
37+
let dir = tempfile::TempDir::new().unwrap();
38+
let cache = Cache::at(dir.path());
39+
40+
let dl = cache.download(
41+
true,
42+
binary_name,
43+
&binaries,
44+
&format!("{}/{}.tar.gz", &url, binary_name),
45+
);
46+
47+
assert!(dl.is_ok());
48+
assert!(dl.unwrap().is_some())
49+
}
50+
51+
#[test]
52+
fn it_returns_error_when_it_failed_to_download() {
53+
let server_port = 7881;
54+
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port);
55+
let binary_name = "wasm-pack";
56+
let binaries = vec![binary_name];
57+
58+
let dir = tempfile::TempDir::new().unwrap();
59+
let cache = Cache::at(dir.path());
60+
let full_url = &format!("{}/{}.tar.gz", &url, binary_name);
61+
62+
let dl = cache.download(true, binary_name, &binaries, full_url);
63+
64+
assert!(dl.is_err());
65+
assert_eq!(
66+
&format!("failed to download from {}", full_url),
67+
&format!("{}", dl.unwrap_err())
68+
);
69+
}
70+
71+
#[test]
72+
fn it_returns_error_when_it_failed_to_extract_tarball() {
73+
let server_port = 7882;
74+
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port);
75+
let binary_name = "wasm-pack";
76+
let binaries = vec![binary_name];
77+
78+
let dir = tempfile::TempDir::new().unwrap();
79+
let cache = Cache::at(dir.path());
80+
let full_url = &format!("{}/{}.tar.gz", &url, binary_name);
81+
82+
// Spin up a local TcpListener.
83+
utils::start_server(server_port, None);
84+
85+
let dl = cache.download(true, binary_name, &binaries, full_url);
86+
87+
assert!(dl.is_err());
88+
assert_eq!(
89+
&format!("failed to extract tarball from {}", full_url),
90+
&format!("{}", dl.unwrap_err())
91+
);
92+
}
93+
94+
#[test]
95+
fn it_returns_error_when_it_failed_to_extract_zip() {
96+
let server_port = 7883;
97+
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port);
98+
let binary_name = "wasm-pack";
99+
let binaries = vec![binary_name];
100+
101+
let dir = tempfile::TempDir::new().unwrap();
102+
let cache = Cache::at(dir.path());
103+
let full_url = &format!("{}/{}.zip", &url, binary_name);
104+
105+
// Spin up a local TcpListener.
106+
utils::start_server(server_port, None);
107+
108+
let dl = cache.download(true, binary_name, &binaries, full_url);
109+
110+
assert!(dl.is_err());
111+
assert_eq!(
112+
&format!("failed to extract zip from {}", full_url),
113+
&format!("{}", dl.unwrap_err())
114+
);
115+
}
116+
117+
#[test]
118+
#[should_panic(expected = "don't know how to extract http://localhost:7884/wasm-pack.bin")]
119+
fn it_panics_if_not_tarball_or_zip() {
120+
let server_port = 7884;
121+
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port);
122+
let binary_name = "wasm-pack";
123+
let binaries = vec![binary_name];
124+
125+
let dir = tempfile::TempDir::new().unwrap();
126+
let cache = Cache::at(dir.path());
127+
let full_url = &format!("{}/{}.bin", &url, binary_name);
128+
129+
// Spin up a local TcpListener.
130+
utils::start_server(server_port, None);
131+
132+
let _ = cache.download(true, binary_name, &binaries, full_url);
133+
}
134+
135+
#[test]
136+
fn it_joins_path_with_destination() {
137+
let dir = tempfile::TempDir::new().unwrap();
138+
let cache = Cache::at(dir.path());
139+
140+
assert_eq!(dir.path().join("hello"), cache.join(Path::new("hello")));
141+
}

binary-install/tests/all/download.rs

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use binary_install::Download;
2+
use std::fs::OpenOptions;
3+
use std::os::unix::fs::OpenOptionsExt;
4+
5+
#[test]
6+
#[cfg(unix)]
7+
fn it_returns_binary_name() {
8+
let binary_name = "wasm-pack";
9+
10+
let dir = tempfile::TempDir::new().unwrap();
11+
let download = Download::at(dir.path());
12+
13+
let full_path = dir.path().join(binary_name);
14+
15+
let mut options = OpenOptions::new();
16+
options.create(true);
17+
options.write(true);
18+
19+
// Make the "binary" an executable.
20+
options.mode(0o755);
21+
22+
options.open(&full_path).unwrap();
23+
24+
let binary = download.binary(binary_name);
25+
26+
assert!(binary.is_ok());
27+
assert_eq!(full_path, binary.unwrap());
28+
}
29+
30+
#[test]
31+
fn it_bails_if_not_file() {
32+
let binary_name = "wasm-pack";
33+
34+
let dir = tempfile::TempDir::new().unwrap();
35+
let download = Download::at(dir.path());
36+
37+
let full_path = dir.path().join(binary_name);
38+
39+
let mut options = OpenOptions::new();
40+
options.create(true);
41+
options.write(true);
42+
43+
let binary = download.binary(binary_name);
44+
45+
assert!(binary.is_err());
46+
assert_eq!(
47+
format!("{} binary does not exist", full_path.to_str().unwrap()),
48+
binary.unwrap_err().to_string()
49+
);
50+
}
51+
52+
#[test]
53+
fn it_bails_if_not_executable() {
54+
let binary_name = "wasm-pack";
55+
56+
let dir = tempfile::TempDir::new().unwrap();
57+
let download = Download::at(dir.path());
58+
59+
let full_path = dir.path().join(binary_name);
60+
61+
let mut options = OpenOptions::new();
62+
options.create(true);
63+
options.write(true);
64+
65+
options.open(&full_path).unwrap();
66+
67+
let binary = download.binary(binary_name);
68+
69+
assert!(binary.is_err());
70+
assert_eq!(
71+
format!("{} is not executable", full_path.to_str().unwrap()),
72+
binary.unwrap_err().to_string()
73+
);
74+
}

binary-install/tests/all/main.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
extern crate binary_install;
2+
extern crate flate2;
3+
extern crate tar;
4+
5+
mod cache;
6+
mod download;
7+
mod utils;

0 commit comments

Comments
 (0)