summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-05-23 05:52:17 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-06-20 08:08:31 -0300
commitfde8ae1f62b44c9c30081d783dba8b810482ca1a (patch)
tree93f6510cc06dc4f574c6f99af80907b370fa8fe6
parent77c146075b293fa0095fc54cecaaa5da8ce27f26 (diff)
downloadmullvadvpn-fde8ae1f62b44c9c30081d783dba8b810482ca1a.tar.xz
mullvadvpn-fde8ae1f62b44c9c30081d783dba8b810482ca1a.zip
Move test `common` module to `mullvad-tests` lib.
-rw-r--r--mullvad-tests/Cargo.toml6
-rw-r--r--mullvad-tests/src/lib.rs219
-rw-r--r--mullvad-tests/tests/common/mod.rs220
-rw-r--r--mullvad-tests/tests/startup.rs8
4 files changed, 223 insertions, 230 deletions
diff --git a/mullvad-tests/Cargo.toml b/mullvad-tests/Cargo.toml
index 71dc7b8663..ae57e6cdc7 100644
--- a/mullvad-tests/Cargo.toml
+++ b/mullvad-tests/Cargo.toml
@@ -6,14 +6,12 @@ description = "Mullvad test specific modules and binaries"
license = "GPL-3.0"
[dependencies]
-notify = "4.0"
-
-[dev-dependencies]
duct = "0.10"
mullvad-ipc-client = { path = "../mullvad-ipc-client" }
mullvad-paths = { path = "../mullvad-paths" }
+notify = "4.0"
os_pipe = "0.6"
tempfile = "3.0"
-[target.'cfg(unix)'.dev-dependencies]
+[target.'cfg(unix)'.dependencies]
libc = "0.2"
diff --git a/mullvad-tests/src/lib.rs b/mullvad-tests/src/lib.rs
index 8b13789179..5489c5b23e 100644
--- a/mullvad-tests/src/lib.rs
+++ b/mullvad-tests/src/lib.rs
@@ -1 +1,220 @@
+#![allow(dead_code)]
+#[macro_use]
+extern crate duct;
+#[cfg(unix)]
+extern crate libc;
+extern crate mullvad_ipc_client;
+extern crate mullvad_paths;
+extern crate notify;
+extern crate os_pipe;
+extern crate tempfile;
+
+use std::fs;
+use std::io::{BufRead, BufReader};
+use std::path::{Path, PathBuf};
+use std::sync::{mpsc, Arc, Mutex};
+use std::thread;
+use std::time::{Duration, Instant};
+
+use self::mullvad_ipc_client::DaemonRpcClient;
+use self::notify::{op, RawEvent, RecursiveMode, Watcher};
+use self::os_pipe::{pipe, PipeReader};
+use self::tempfile::TempDir;
+
+#[cfg(unix)]
+pub static DAEMON_EXECUTABLE_PATH: &str = "../target/debug/mullvad-daemon";
+
+#[cfg(not(unix))]
+pub static DAEMON_EXECUTABLE_PATH: &str = r"..\target\debug\mullvad-daemon.exe";
+
+pub fn wait_for_file_write_finish<P: AsRef<Path>>(file_path: P, timeout: Duration) {
+ let file_path = file_path.as_ref();
+ let parent_dir = file_path.parent().expect("Missing file parent directory");
+
+ let absolute_parent_dir = parent_dir
+ .canonicalize()
+ .expect("Failed to get absolute path to watch");
+ let file_name = file_path
+ .file_name()
+ .expect("Missing file name of file path to watch");
+ let absolute_file_path = absolute_parent_dir.join(file_name);
+
+ let (tx, rx) = mpsc::channel();
+ let mut watcher = notify::raw_watcher(tx).expect("Failed to listen for file system events");
+ let start = Instant::now();
+ let mut remaining_time = Some(timeout);
+
+ watcher
+ .watch(absolute_parent_dir, RecursiveMode::NonRecursive)
+ .expect("Failed to listen for file system events on directory");
+
+ if !file_path.exists() {
+ while let Some(wait_time) = remaining_time {
+ let event = rx.recv_timeout(wait_time);
+
+ if let Ok(RawEvent {
+ path: Some(path),
+ op: Ok(op),
+ ..
+ }) = event
+ {
+ if op.contains(op::CLOSE_WRITE) && path == absolute_file_path {
+ break;
+ }
+ }
+
+ remaining_time = timeout.checked_sub(start.elapsed());
+ }
+ }
+}
+
+fn prepare_test_dirs() -> (TempDir, PathBuf) {
+ let temp_dir = TempDir::new().expect("Failed to create temporary daemon directory");
+ let resource_dir = temp_dir.path().join("resource-dir");
+
+ fs::create_dir(&resource_dir).expect("Failed to create resource directory");
+
+ prepare_relay_list(resource_dir.join("relays.json"));
+
+ (temp_dir, resource_dir)
+}
+
+fn prepare_relay_list<T: AsRef<Path>>(path: T) {
+ fs::write(
+ path,
+ r#"{
+ "countries": [{
+ "name": "Mockland",
+ "code": "fake",
+ "latitude": -91,
+ "longitude": 0,
+ "relays": [{
+ "hostname": "fake-mockland",
+ "ipv4_addr_in": "192.168.0.100",
+ "ipv4_addr_exit": "192.168.0.101",
+ "include_in_country": true,
+ "weight": 100,
+ "tunnels": {
+ "openvpn": [ { "port": 10000, "protocol": "udp" } ],
+ "wireguard": [],
+ },
+ }],
+ }]
+ }"#,
+ ).expect("Failed to create mock relay list file");
+}
+
+pub struct DaemonRunner {
+ process: Option<duct::Handle>,
+ output: Arc<Mutex<BufReader<PipeReader>>>,
+ _temp_dir: TempDir,
+}
+
+impl DaemonRunner {
+ pub fn spawn() -> Self {
+ let (temp_dir, resource_dir) = prepare_test_dirs();
+
+ let (reader, writer) = pipe().expect("Failed to open pipe to connect to daemon");
+ let process = cmd!(DAEMON_EXECUTABLE_PATH, "-v", "--disable-log-to-file")
+ .dir("..")
+ .env("MULLVAD_CACHE_DIR", "./")
+ .env("MULLVAD_RESOURCE_DIR", resource_dir)
+ .stderr_to_stdout()
+ .stdout_handle(writer)
+ .start()
+ .expect("Failed to start daemon");
+
+ DaemonRunner {
+ process: Some(process),
+ output: Arc::new(Mutex::new(BufReader::new(reader))),
+ _temp_dir: temp_dir,
+ }
+ }
+
+ pub fn assert_output(&mut self, pattern: &'static str, timeout: Duration) {
+ let (tx, rx) = mpsc::channel();
+ let stdout = self.output.clone();
+
+ thread::spawn(move || {
+ Self::wait_for_output(stdout, pattern);
+ tx.send(()).expect("Failed to report search result");
+ });
+
+ rx.recv_timeout(timeout)
+ .expect(&format!("failed to search for {:?}", pattern));
+ }
+
+ fn wait_for_output(output: Arc<Mutex<BufReader<PipeReader>>>, pattern: &str) {
+ let mut output = output
+ .lock()
+ .expect("Another thread panicked while holding a lock to the process output");
+
+ let mut line = String::new();
+
+ while !line.contains(pattern) {
+ line.clear();
+ output
+ .read_line(&mut line)
+ .expect("Failed to read line from daemon stdout");
+ }
+ }
+
+ pub fn rpc_client(&mut self) -> Result<DaemonRpcClient, String> {
+ let rpc_file = mullvad_paths::get_rpc_address_path()
+ .map_err(|error| format!("Failed to build RPC connection file path: {}", error))?;
+
+ if !rpc_file.exists() {
+ wait_for_file_write_finish(rpc_file, Duration::from_secs(10));
+ }
+
+ DaemonRpcClient::without_rpc_file_security_check()
+ .map_err(|error| format!("Failed to create RPC client: {}", error))
+ }
+
+ #[cfg(unix)]
+ fn request_clean_shutdown(&mut self, process: &mut duct::Handle) -> bool {
+ use duct::unix::HandleExt;
+
+ process.send_signal(libc::SIGTERM).is_ok()
+ }
+
+ #[cfg(not(unix))]
+ fn request_clean_shutdown(&mut self, _: &mut duct::Handle) -> bool {
+ if let Ok(mut rpc_client) = self.rpc_client() {
+ rpc_client.shutdown().is_ok()
+ } else {
+ false
+ }
+ }
+}
+
+impl Drop for DaemonRunner {
+ fn drop(&mut self) {
+ if let Some(mut process) = self.process.take() {
+ if self.request_clean_shutdown(&mut process) {
+ let process = Arc::new(process);
+ let wait_handle = process.clone();
+ let (finished_tx, finished_rx) = mpsc::channel();
+
+ thread::spawn(move || finished_tx.send(wait_handle.wait().map(|_| ())).unwrap());
+
+ let has_finished = finished_rx
+ .recv_timeout(Duration::from_secs(5))
+ .map_err(|_| ())
+ .and_then(|result| result.map_err(|_| ()))
+ .is_ok();
+
+ if !has_finished {
+ process.kill().unwrap();
+ }
+ } else {
+ process.kill().unwrap();
+ }
+ }
+
+ if let Ok(file_path) = mullvad_paths::get_rpc_address_path() {
+ let _ = fs::remove_file(file_path);
+ }
+ }
+}
diff --git a/mullvad-tests/tests/common/mod.rs b/mullvad-tests/tests/common/mod.rs
deleted file mode 100644
index a93d1b1528..0000000000
--- a/mullvad-tests/tests/common/mod.rs
+++ /dev/null
@@ -1,220 +0,0 @@
-#![allow(dead_code)]
-
-#[cfg(unix)]
-extern crate libc;
-extern crate mullvad_ipc_client;
-extern crate mullvad_paths;
-extern crate notify;
-extern crate os_pipe;
-extern crate tempfile;
-
-use std::fs;
-use std::io::{BufRead, BufReader};
-use std::path::{Path, PathBuf};
-use std::sync::{mpsc, Arc, Mutex};
-use std::thread;
-use std::time::{Duration, Instant};
-
-use duct;
-
-use self::mullvad_ipc_client::DaemonRpcClient;
-use self::notify::{op, RawEvent, RecursiveMode, Watcher};
-use self::os_pipe::{pipe, PipeReader};
-use self::tempfile::TempDir;
-
-#[cfg(unix)]
-pub static DAEMON_EXECUTABLE_PATH: &str = "../target/debug/mullvad-daemon";
-
-#[cfg(not(unix))]
-pub static DAEMON_EXECUTABLE_PATH: &str = r"..\target\debug\mullvad-daemon.exe";
-
-pub fn wait_for_file_write_finish<P: AsRef<Path>>(file_path: P, timeout: Duration) {
- let file_path = file_path.as_ref();
- let parent_dir = file_path.parent().expect("Missing file parent directory");
-
- let absolute_parent_dir = parent_dir
- .canonicalize()
- .expect("Failed to get absolute path to watch");
- let file_name = file_path
- .file_name()
- .expect("Missing file name of file path to watch");
- let absolute_file_path = absolute_parent_dir.join(file_name);
-
- let (tx, rx) = mpsc::channel();
- let mut watcher = notify::raw_watcher(tx).expect("Failed to listen for file system events");
- let start = Instant::now();
- let mut remaining_time = Some(timeout);
-
- watcher
- .watch(absolute_parent_dir, RecursiveMode::NonRecursive)
- .expect("Failed to listen for file system events on directory");
-
- if !file_path.exists() {
- while let Some(wait_time) = remaining_time {
- let event = rx.recv_timeout(wait_time);
-
- if let Ok(RawEvent {
- path: Some(path),
- op: Ok(op),
- ..
- }) = event
- {
- if op.contains(op::CLOSE_WRITE) && path == absolute_file_path {
- break;
- }
- }
-
- remaining_time = timeout.checked_sub(start.elapsed());
- }
- }
-}
-
-fn prepare_test_dirs() -> (TempDir, PathBuf) {
- let temp_dir = TempDir::new().expect("Failed to create temporary daemon directory");
- let resource_dir = temp_dir.path().join("resource-dir");
-
- fs::create_dir(&resource_dir).expect("Failed to create resource directory");
-
- prepare_relay_list(resource_dir.join("relays.json"));
-
- (temp_dir, resource_dir)
-}
-
-fn prepare_relay_list<T: AsRef<Path>>(path: T) {
- fs::write(
- path,
- r#"{
- "countries": [{
- "name": "Mockland",
- "code": "fake",
- "latitude": -91,
- "longitude": 0,
- "relays": [{
- "hostname": "fake-mockland",
- "ipv4_addr_in": "192.168.0.100",
- "ipv4_addr_exit": "192.168.0.101",
- "include_in_country": true,
- "weight": 100,
- "tunnels": {
- "openvpn": [ { "port": 10000, "protocol": "udp" } ],
- "wireguard": [],
- },
- }],
- }]
- }"#,
- ).expect("Failed to create mock relay list file");
-}
-
-pub struct DaemonRunner {
- process: Option<duct::Handle>,
- output: Arc<Mutex<BufReader<PipeReader>>>,
- _temp_dir: TempDir,
-}
-
-impl DaemonRunner {
- pub fn spawn() -> Self {
- let (temp_dir, resource_dir) = prepare_test_dirs();
-
- let (reader, writer) = pipe().expect("Failed to open pipe to connect to daemon");
- let process = cmd!(DAEMON_EXECUTABLE_PATH, "-v", "--disable-log-to-file")
- .dir("..")
- .env("MULLVAD_CACHE_DIR", "./")
- .env("MULLVAD_RESOURCE_DIR", resource_dir)
- .stderr_to_stdout()
- .stdout_handle(writer)
- .start()
- .expect("Failed to start daemon");
-
- DaemonRunner {
- process: Some(process),
- output: Arc::new(Mutex::new(BufReader::new(reader))),
- _temp_dir: temp_dir,
- }
- }
-
- pub fn assert_output(&mut self, pattern: &'static str, timeout: Duration) {
- let (tx, rx) = mpsc::channel();
- let stdout = self.output.clone();
-
- thread::spawn(move || {
- Self::wait_for_output(stdout, pattern);
- tx.send(()).expect("Failed to report search result");
- });
-
- rx.recv_timeout(timeout)
- .expect(&format!("failed to search for {:?}", pattern));
- }
-
- fn wait_for_output(output: Arc<Mutex<BufReader<PipeReader>>>, pattern: &str) {
- let mut output = output
- .lock()
- .expect("Another thread panicked while holding a lock to the process output");
-
- let mut line = String::new();
-
- while !line.contains(pattern) {
- line.clear();
- output
- .read_line(&mut line)
- .expect("Failed to read line from daemon stdout");
- }
- }
-
- pub fn rpc_client(&mut self) -> Result<DaemonRpcClient, String> {
- let rpc_file = mullvad_paths::get_rpc_address_path()
- .map_err(|error| format!("Failed to build RPC connection file path: {}", error))?;
-
- if !rpc_file.exists() {
- wait_for_file_write_finish(rpc_file, Duration::from_secs(10));
- }
-
- DaemonRpcClient::without_rpc_file_security_check()
- .map_err(|error| format!("Failed to create RPC client: {}", error))
- }
-
- #[cfg(unix)]
- fn request_clean_shutdown(&mut self, process: &mut duct::Handle) -> bool {
- use duct::unix::HandleExt;
-
- process.send_signal(libc::SIGTERM).is_ok()
- }
-
- #[cfg(not(unix))]
- fn request_clean_shutdown(&mut self, _: &mut duct::Handle) -> bool {
- if let Ok(mut rpc_client) = self.rpc_client() {
- rpc_client.shutdown().is_ok()
- } else {
- false
- }
- }
-}
-
-impl Drop for DaemonRunner {
- fn drop(&mut self) {
- if let Some(mut process) = self.process.take() {
- if self.request_clean_shutdown(&mut process) {
- let process = Arc::new(process);
- let wait_handle = process.clone();
- let (finished_tx, finished_rx) = mpsc::channel();
-
- thread::spawn(move || finished_tx.send(wait_handle.wait().map(|_| ())).unwrap());
-
- let has_finished = finished_rx
- .recv_timeout(Duration::from_secs(5))
- .map_err(|_| ())
- .and_then(|result| result.map_err(|_| ()))
- .is_ok();
-
- if !has_finished {
- process.kill().unwrap();
- }
- } else {
- process.kill().unwrap();
- }
- }
-
- if let Ok(file_path) = mullvad_paths::get_rpc_address_path() {
- let _ = fs::remove_file(file_path);
- }
- }
-}
diff --git a/mullvad-tests/tests/startup.rs b/mullvad-tests/tests/startup.rs
index f9bb5d04f6..b14b7f2070 100644
--- a/mullvad-tests/tests/startup.rs
+++ b/mullvad-tests/tests/startup.rs
@@ -1,15 +1,11 @@
-#[macro_use]
-extern crate duct;
-extern crate mullvad_ipc_client;
extern crate mullvad_paths;
-
-mod common;
+extern crate mullvad_tests;
use std::fs::{self, Metadata};
use std::io;
use std::time::Duration;
-use common::DaemonRunner;
+use mullvad_tests::DaemonRunner;
use platform_specific::*;