summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2024-04-16 01:28:40 +0200
committerDavid Lönnhager <david.l@mullvad.net>2024-04-16 12:20:38 +0200
commit3efb7a7bdaf0c4e3c59d62735eb1d314bf202b15 (patch)
tree52dacef9ae36ccd6323df4ed9a418f2928904575
parent77d21ad97bedef15a0350e4cc5ee492b35ce332c (diff)
downloadmullvadvpn-3efb7a7bdaf0c4e3c59d62735eb1d314bf202b15.tar.xz
mullvadvpn-3efb7a7bdaf0c4e3c59d62735eb1d314bf202b15.zip
Add unit tests for macOS DNS monitor
-rw-r--r--talpid-core/src/dns/macos.rs196
1 files changed, 196 insertions, 0 deletions
diff --git a/talpid-core/src/dns/macos.rs b/talpid-core/src/dns/macos.rs
index ea70951b33..e0535fedf7 100644
--- a/talpid-core/src/dns/macos.rs
+++ b/talpid-core/src/dns/macos.rs
@@ -491,3 +491,199 @@ fn state_to_setup_path(state_path: &str) -> Option<String> {
None
}
}
+
+#[cfg(test)]
+mod test {
+ use super::{DnsSettings, State};
+ use std::collections::{BTreeSet, HashMap};
+
+ /// The initial backup should equal whatever the first provided state is.
+ #[test]
+ fn test_backup_new_dns_config() {
+ let prev_state = HashMap::new();
+
+ let new_state = HashMap::from([
+ ("a".to_owned(), None),
+ (
+ "b".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["1.2.3.4".to_owned()],
+ "iface_b".to_owned(),
+ )),
+ ),
+ // One of our states already equals the desired state. It should be stored regardless.
+ (
+ "c".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["10.64.0.1".to_owned()],
+ "iface_c".to_owned(),
+ )),
+ ),
+ ]);
+
+ let desired_addresses: BTreeSet<String> = ["10.64.0.1".to_owned()].into();
+
+ let merged_state = State::merge_states(&new_state, prev_state, desired_addresses);
+
+ assert_eq!(merged_state, new_state);
+ }
+
+ /// Any changes equal to the desired state should be ignored. Other changes should be recorded.
+ #[test]
+ fn test_backup_ignore_desired_state() {
+ let prev_state = HashMap::from([
+ ("a".to_owned(), None),
+ (
+ "b".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["1.2.3.4".to_owned()],
+ "iface_b".to_owned(),
+ )),
+ ),
+ (
+ "c".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["10.64.0.1".to_owned()],
+ "iface_c".to_owned(),
+ )),
+ ),
+ (
+ "d".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["1.3.3.7".to_owned()],
+ "iface_d".to_owned(),
+ )),
+ ),
+ ]);
+ let new_state = HashMap::from([
+ // This change should be ignored
+ (
+ "a".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["10.64.0.1".to_owned()],
+ "iface_a".to_owned(),
+ )),
+ ),
+ // This change should be ignored
+ (
+ "b".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["10.64.0.1".to_owned()],
+ "iface_b".to_owned(),
+ )),
+ ),
+ // This change should be ignored
+ (
+ "c".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["4.3.2.1".to_owned()],
+ "iface_c".to_owned(),
+ )),
+ ),
+ // This change should NOT be ignored
+ (
+ "d".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["4.3.2.1".to_owned()],
+ "iface_d".to_owned(),
+ )),
+ ),
+ ]);
+ let expect_state = HashMap::from([
+ ("a".to_owned(), None),
+ (
+ "b".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["1.2.3.4".to_owned()],
+ "iface_b".to_owned(),
+ )),
+ ),
+ (
+ "c".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["4.3.2.1".to_owned()],
+ "iface_c".to_owned(),
+ )),
+ ),
+ (
+ "d".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["4.3.2.1".to_owned()],
+ "iface_d".to_owned(),
+ )),
+ ),
+ ]);
+
+ let desired_addresses: BTreeSet<String> = ["10.64.0.1".to_owned()].into();
+
+ let merged_state = State::merge_states(&new_state, prev_state, desired_addresses);
+
+ assert_eq!(merged_state, expect_state);
+ }
+
+ /// Services not specified in the new state should be removed from the backed up state
+ #[test]
+ fn test_backup_remove_dns_config() {
+ let prev_state = HashMap::from([
+ (
+ "a".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["10.64.0.1".to_owned()],
+ "iface_a".to_owned(),
+ )),
+ ),
+ (
+ "b".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["1.2.3.4".to_owned()],
+ "iface_b".to_owned(),
+ )),
+ ),
+ ("c".to_owned(), None),
+ ]);
+ let new_state = HashMap::from([("c".to_owned(), None)]);
+ let expected_state = new_state.clone();
+
+ let desired_addresses: BTreeSet<String> = ["10.64.0.1".to_owned()].into();
+
+ let merged_state = State::merge_states(&new_state, prev_state, desired_addresses);
+
+ assert_eq!(merged_state, expected_state);
+ }
+
+ /// If DHCP provides an IP identical to our desired state, the tracked state will not reflect
+ /// this. This is a known limitation.
+ // TODO: This should actually succeed. If we happen to switch to a network whose IP equals
+ // the "desired IP", we should still back up the result.
+ #[test]
+ #[should_panic]
+ fn test_backup_change_equals_desired_state() {
+ let prev_state = HashMap::from([(
+ "a".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["192.168.100.1".to_owned()],
+ "iface_a".to_owned(),
+ )),
+ )]);
+ let new_state = HashMap::from([(
+ "a".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["192.168.1.1".to_owned()],
+ "iface_a".to_owned(),
+ )),
+ )]);
+ let expect_state = HashMap::from([(
+ "a".to_owned(),
+ Some(DnsSettings::from_server_addresses(
+ &["192.168.1.1".to_owned()],
+ "iface_a".to_owned(),
+ )),
+ )]);
+
+ let desired_addresses: BTreeSet<String> = ["192.168.1.1".to_owned()].into();
+
+ let merged_state = State::merge_states(&new_state, prev_state, desired_addresses);
+
+ assert_eq!(merged_state, expect_state);
+ }
+}