From fa68a0d91f5c5973b9519b42d09c91d5b71c234a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20H=C3=A5kansson?= <jesper@jesperh.se> Date: Mon, 5 Nov 2018 21:54:42 +0100 Subject: [PATCH] test: Create and return tarball in tests, add more test cases --- binary-install/src/lib.rs | 5 +- binary-install/tests/path.rs | 13 ++-- binary-install/tests/test.rs | 111 ++++++++++++++++++++++++++++++++--- 3 files changed, 112 insertions(+), 17 deletions(-) diff --git a/binary-install/src/lib.rs b/binary-install/src/lib.rs index 728ee12..09f6982 100644 --- a/binary-install/src/lib.rs +++ b/binary-install/src/lib.rs @@ -47,8 +47,9 @@ where let bin = local_bin_dir(crate_path); for entry in archive.entries()? { - let mut entry = - entry.map_err(|_err| Error::archive(&format!("Invalid tarball at {}", url)))?; + let mut entry = entry.map_err(|err| { + Error::archive(&format!("Invalid tarball at {}. Inner error: {}", url, err)) + })?; let dest = match entry.path()?.file_stem() { Some(f) if binaries.contains(f) => { diff --git a/binary-install/tests/path.rs b/binary-install/tests/path.rs index a9c3b95..08139ec 100644 --- a/binary-install/tests/path.rs +++ b/binary-install/tests/path.rs @@ -9,7 +9,7 @@ use slog::Drain; use std::env; use std::fs; use std::io; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; fn logger() -> slog::Logger { let decorator = slog_term::TermDecorator::new().build(); @@ -26,11 +26,10 @@ fn get_tests_bin_path() -> PathBuf { #[test] #[cfg(not(target_os = "windows"))] fn get_local_bin_path_should_return_a_path() { - let crate_path = Path::new(""); - - let expected_path = Path::new("bin/wasm-bindgen"); + let crate_path = get_tests_bin_path(); + let expected_path = crate_path.join("bin/wasm-bindgen"); - let result = local_bin_path(crate_path, "wasm-bindgen"); + let result = local_bin_path(&crate_path, "wasm-bindgen"); assert_eq!(expected_path, result); } @@ -38,9 +37,9 @@ fn get_local_bin_path_should_return_a_path() { #[test] #[cfg(target_os = "windows")] fn get_local_bin_path_should_return_with_exe_for_windows() { - let crate_path = Path::new(""); + let crate_path = get_tests_bin_path(); - let expected_path = Path::new("bin/wasm-bindgen.exe"); + let expected_path = crate_path.join("bin/wasm-bindgen.exe"); let result = local_bin_path(crate_path, "wasm-bindgen"); diff --git a/binary-install/tests/test.rs b/binary-install/tests/test.rs index 73f4298..923688b 100644 --- a/binary-install/tests/test.rs +++ b/binary-install/tests/test.rs @@ -1,18 +1,25 @@ extern crate binary_install; extern crate curl; extern crate failure; +extern crate flate2; +extern crate tar; use binary_install::{error::Error, install_binaries_from_targz_at_url}; -use std::io::{Read, Write}; +use flate2::write::GzEncoder; +use flate2::Compression; +use std::env; +use std::fs::{File, OpenOptions}; +use std::io::{self, Read, Write}; use std::net::TcpListener; use std::path::Path; use std::thread; -const SERVER_URL: &'static str = "localhost:7878"; +const SERVER_HOST: &'static str = "localhost"; + +fn start_server(port: u32, tarball: Option<Vec<u8>>) -> thread::JoinHandle<TcpListener> { + thread::spawn(move || { + let listener = TcpListener::bind(format!("{}:{}", SERVER_HOST, port)).unwrap(); -fn start_server() -> thread::JoinHandle<TcpListener> { - thread::spawn(|| { - let listener = TcpListener::bind(SERVER_URL).unwrap(); for stream in listener.incoming() { let mut stream = stream.unwrap(); @@ -23,12 +30,49 @@ fn start_server() -> thread::JoinHandle<TcpListener> { let response = "HTTP/1.1 200 OK\r\n\r\n"; stream.write(response.as_bytes()).unwrap(); + + match tarball.to_owned() { + Some(tar) => { + stream.write(tar.as_ref()).unwrap(); + } + None => {} + } + stream.flush().unwrap(); } listener }) } +fn create_tarball(binary_name: &str) -> Result<Vec<u8>, io::Error> { + let temp_dir = env::temp_dir(); + let tar = OpenOptions::new() + .create(true) + .read(true) + .write(true) + .open(temp_dir.join("foo.tar.gz"))?; + + let mut file = OpenOptions::new() + .create(true) + .read(true) + .write(true) + .open(temp_dir.join(binary_name))?; + + let mut encoder = GzEncoder::new(tar, Compression::default()); + { + let mut archive = tar::Builder::new(&mut encoder); + archive.append_file(binary_name, &mut file)?; + } + + let mut contents = vec![]; + + encoder.finish()?; + + File::open(temp_dir.join("foo.tar.gz"))?.read_to_end(&mut contents)?; + + Ok(contents) +} + #[test] fn install_binaries_from_targz_at_url_should_return_http_error_for_bad_url() { let crate_path = Path::new(""); @@ -51,12 +95,43 @@ fn install_binaries_from_targz_at_url_should_return_http_error_for_bad_url() { #[test] fn install_binaries_from_targz_at_url_should_return_archive_error_when_tarball_is_missing() { + let server_port = 7878; + let url = format!("http://{}:{}", SERVER_HOST, server_port); let crate_path = Path::new(""); - let url = format!("http://{}", SERVER_URL); let binaries = vec![""]; // Spin up a local TcpListener. - start_server(); + start_server(server_port, None); + + let result = install_binaries_from_targz_at_url(crate_path, &url, binaries); + assert!(result.is_err()); + + let err = result.err().unwrap(); + let err = err.downcast_ref::<Error>().unwrap(); + + let expected_message = format!( + "Invalid tarball at {}. Inner error: failed to fill whole buffer", + url + ); + + match err { + Error::Archive { message } => assert_eq!(&expected_message, message), + _ => panic!("Wrong error returned"), + } +} + +#[test] +fn install_binaries_from_targz_at_url_should_return_archive_error_when_tarball_does_not_include_all_files( +) { + let server_port = 7879; + let url = format!("http://{}:{}", SERVER_HOST, server_port); + let crate_path = Path::new(""); + let binaries = vec!["wasm-pack"]; + + // Create a temporary tarball. + let tarball = create_tarball("foo.txt").ok(); + // Spin up a local TcpListener. + start_server(server_port, tarball); let result = install_binaries_from_targz_at_url(crate_path, &url, binaries); assert!(result.is_err()); @@ -64,10 +139,30 @@ fn install_binaries_from_targz_at_url_should_return_archive_error_when_tarball_i let err = result.err().unwrap(); let err = err.downcast_ref::<Error>().unwrap(); - let expected_message = format!("Invalid tarball at {}", url); + let expected_message = format!( + "the tarball at {} was missing expected executables: {}", + url, "wasm-pack" + ); match err { Error::Archive { message } => assert_eq!(&expected_message, message), _ => panic!("Wrong error returned"), } } + +#[test] +fn install_binaries_from_targz_at_url_should_return_ok_if_binary_is_found() { + let server_port = 7880; + let url = format!("http://{}:{}", SERVER_HOST, server_port); + let binary_name = "wasm-pack"; + let crate_path = Path::new(""); + let binaries = vec![binary_name]; + + // Create a temporary tarball. + let tarball = create_tarball(binary_name).ok(); + // Spin up a local TcpListener. + start_server(server_port, tarball); + + let result = install_binaries_from_targz_at_url(crate_path, &url, binaries); + assert!(result.is_ok()); +}