summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-06-28 09:43:53 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-06-28 09:43:53 -0300
commit4327cc8fa8aea1a6e8f70d3ff941279e93f45fad (patch)
treedd38d55fabe21ebd7dc70d129084078df37875c1
parent3a7b99dc24c3f96f4c23d77cff9c0fe0df49e170 (diff)
parentd60f943e9b3a7873654e62adc720f14dc871971a (diff)
downloadmullvadvpn-4327cc8fa8aea1a6e8f70d3ff941279e93f45fad.tar.xz
mullvadvpn-4327cc8fa8aea1a6e8f70d3ff941279e93f45fad.zip
Merge branch 'connection-tests'
-rw-r--r--mullvad-tests/src/bin/mock_openvpn.rs45
-rw-r--r--mullvad-tests/src/lib.rs4
-rw-r--r--mullvad-tests/tests/connection.rs64
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))