diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-06-28 09:43:53 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-06-28 09:43:53 -0300 |
| commit | 4327cc8fa8aea1a6e8f70d3ff941279e93f45fad (patch) | |
| tree | dd38d55fabe21ebd7dc70d129084078df37875c1 | |
| parent | 3a7b99dc24c3f96f4c23d77cff9c0fe0df49e170 (diff) | |
| parent | d60f943e9b3a7873654e62adc720f14dc871971a (diff) | |
| download | mullvadvpn-4327cc8fa8aea1a6e8f70d3ff941279e93f45fad.tar.xz mullvadvpn-4327cc8fa8aea1a6e8f70d3ff941279e93f45fad.zip | |
Merge branch 'connection-tests'
| -rw-r--r-- | mullvad-tests/src/bin/mock_openvpn.rs | 45 | ||||
| -rw-r--r-- | mullvad-tests/src/lib.rs | 4 | ||||
| -rw-r--r-- | mullvad-tests/tests/connection.rs | 64 |
3 files changed, 98 insertions, 15 deletions
diff --git a/mullvad-tests/src/bin/mock_openvpn.rs b/mullvad-tests/src/bin/mock_openvpn.rs index b5c1ff8be4..2786dff3f9 100644 --- a/mullvad-tests/src/bin/mock_openvpn.rs +++ b/mullvad-tests/src/bin/mock_openvpn.rs @@ -2,17 +2,23 @@ extern crate notify; use std::env; use std::fs::File; -use std::io::Write; +use std::io::{self, Read, Write}; use std::path::{Path, PathBuf}; use std::sync::mpsc; +use std::thread; use notify::{raw_watcher, RawEvent, RecursiveMode, Watcher}; fn main() { let (file, path) = create_args_file(); + let (finished_tx, finished_rx) = mpsc::channel(); write_command_line(file); - wait_for_file_to_be_deleted(path); + + wait_thread(wait_for_stdin_to_be_closed, finished_tx.clone()); + wait_thread(move || wait_for_file_to_be_deleted(path), finished_tx); + + let _ = finished_rx.recv(); } fn create_args_file() -> (File, PathBuf) { @@ -35,23 +41,32 @@ fn write_command_line(mut file: File) { } } +fn wait_thread<F>(function: F, finished_tx: mpsc::Sender<()>) +where + F: FnOnce() + Send + 'static, +{ + thread::spawn(move || { + function(); + let _ = finished_tx.send(()); + }); +} + +fn wait_for_stdin_to_be_closed() { + let _ignore_bytes = io::stdin().bytes().last(); +} + fn wait_for_file_to_be_deleted<P: AsRef<Path>>(file: P) { let file = file.as_ref(); let (tx, rx) = mpsc::channel(); - let mut watcher = raw_watcher(tx).expect(&format!( - "Failed to create file watcher for \"{}\"", - file.display() - )); - - watcher - .watch(&file, RecursiveMode::NonRecursive) - .expect(&format!("Failed to watch file: {}", file.display())); - - for event in rx { - if let RawEvent { op: Ok(op), .. } = event { - if op.contains(notify::op::REMOVE) { - break; + if let Ok(mut watcher) = raw_watcher(tx) { + if watcher.watch(&file, RecursiveMode::NonRecursive).is_ok() { + for event in rx { + if let RawEvent { op: Ok(op), .. } = event { + if op.contains(notify::op::REMOVE) { + break; + } + } } } } diff --git a/mullvad-tests/src/lib.rs b/mullvad-tests/src/lib.rs index 54aea065c8..a9af2b9c10 100644 --- a/mullvad-tests/src/lib.rs +++ b/mullvad-tests/src/lib.rs @@ -313,6 +313,10 @@ impl MockOpenVpnPluginRpcClient { self.send_event(OpenVpnPluginEvent::Up, env) } + pub fn route_predown(&mut self) -> Result<(), String> { + self.send_event(OpenVpnPluginEvent::RoutePredown, HashMap::new()) + } + fn send_event( &mut self, event: OpenVpnPluginEvent, diff --git a/mullvad-tests/tests/connection.rs b/mullvad-tests/tests/connection.rs index 84306eeb14..c0d512056f 100644 --- a/mullvad-tests/tests/connection.rs +++ b/mullvad-tests/tests/connection.rs @@ -19,6 +19,11 @@ const OPENVPN_PLUGIN_NAME: &str = "libtalpid_openvpn_plugin.so"; #[cfg(windows)] const OPENVPN_PLUGIN_NAME: &str = "talpid_openvpn_plugin.dll"; +const DISCONNECTED_STATE: DaemonState = DaemonState { + state: SecurityState::Unsecured, + target_state: TargetState::Unsecured, +}; + const CONNECTING_STATE: DaemonState = DaemonState { state: SecurityState::Unsecured, target_state: TargetState::Secured, @@ -29,6 +34,11 @@ const CONNECTED_STATE: DaemonState = DaemonState { target_state: TargetState::Secured, }; +const DISCONNECTING_STATE: DaemonState = DaemonState { + state: SecurityState::Secured, + target_state: TargetState::Unsecured, +}; + #[test] fn spawns_openvpn() { let mut daemon = DaemonRunner::spawn(); @@ -174,6 +184,60 @@ fn changes_to_connected_state() { assert_eq!(rpc_client.get_state().unwrap(), CONNECTED_STATE); } +#[test] +fn returns_to_connecting_state() { + let mut daemon = DaemonRunner::spawn(); + let mut rpc_client = daemon.rpc_client().unwrap(); + let openvpn_args_file = daemon.mock_openvpn_args_file(); + let state_events = rpc_client.new_state_subscribe().unwrap(); + + rpc_client.set_account(Some("123456".to_owned())).unwrap(); + rpc_client.connect().unwrap(); + + assert_state_event(&state_events, CONNECTING_STATE); + + let mut mock_plugin_client = create_mock_openvpn_plugin_client(openvpn_args_file); + + mock_plugin_client.authenticate().unwrap(); + mock_plugin_client.up().unwrap(); + + assert_state_event(&state_events, CONNECTED_STATE); + + mock_plugin_client.route_predown().unwrap(); + + // Wait for new OpenVPN instance + wait_for_file_write_finish(&openvpn_args_file, Duration::from_secs(5)); + + assert_state_event(&state_events, CONNECTING_STATE); + assert_eq!(rpc_client.get_state().unwrap(), CONNECTING_STATE); +} + +#[test] +fn disconnects() { + let mut daemon = DaemonRunner::spawn(); + let mut rpc_client = daemon.rpc_client().unwrap(); + let openvpn_args_file = daemon.mock_openvpn_args_file(); + let state_events = rpc_client.new_state_subscribe().unwrap(); + + rpc_client.set_account(Some("123456".to_owned())).unwrap(); + rpc_client.connect().unwrap(); + + assert_state_event(&state_events, CONNECTING_STATE); + + let mut mock_plugin_client = create_mock_openvpn_plugin_client(openvpn_args_file); + + mock_plugin_client.authenticate().unwrap(); + mock_plugin_client.up().unwrap(); + + assert_state_event(&state_events, CONNECTED_STATE); + + rpc_client.disconnect().unwrap(); + + assert_state_event(&state_events, DISCONNECTING_STATE); + assert_state_event(&state_events, DISCONNECTED_STATE); + assert_eq!(rpc_client.get_state().unwrap(), DISCONNECTED_STATE); +} + fn assert_state_event(receiver: &mpsc::Receiver<DaemonState>, expected_state: DaemonState) { let received_state = receiver .recv_timeout(Duration::from_secs(1)) |
