diff options
| author | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2024-08-20 09:48:18 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2024-08-21 17:53:20 +0200 |
| commit | 5ff930f884c68f2b16d18fb6da1487123979b0b8 (patch) | |
| tree | 6bc2d64c11eb51dbefd0d195f45a3c46854b8914 | |
| parent | 0cc9684200426eef11b65cf8373d29eddf8aa90e (diff) | |
| download | mullvadvpn-5ff930f884c68f2b16d18fb6da1487123979b0b8.tar.xz mullvadvpn-5ff930f884c68f2b16d18fb6da1487123979b0b8.zip | |
Add unit test for feature indicator
| -rw-r--r-- | mullvad-management-interface/src/types/conversions/features.rs | 2 | ||||
| -rw-r--r-- | mullvad-types/src/features.rs | 177 |
2 files changed, 177 insertions, 2 deletions
diff --git a/mullvad-management-interface/src/types/conversions/features.rs b/mullvad-management-interface/src/types/conversions/features.rs index d21441a610..ac235d8163 100644 --- a/mullvad-management-interface/src/types/conversions/features.rs +++ b/mullvad-management-interface/src/types/conversions/features.rs @@ -57,7 +57,7 @@ impl From<mullvad_types::features::FeatureIndicators> for proto::FeatureIndicato let mut proto_features = Self::default(); features - .active_features() + .into_iter() .map(proto::FeatureIndicator::from) .for_each(|feature| proto_features.push_active_features(feature)); diff --git a/mullvad-types/src/features.rs b/mullvad-types/src/features.rs index b2205272c7..e7317ec6a7 100644 --- a/mullvad-types/src/features.rs +++ b/mullvad-types/src/features.rs @@ -11,6 +11,15 @@ use talpid_types::net::{ObfuscationType, TunnelEndpoint, TunnelType}; #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct FeatureIndicators(HashSet<FeatureIndicator>); +impl IntoIterator for FeatureIndicators { + type Item = FeatureIndicator; + type IntoIter = std::collections::hash_set::IntoIter<Self::Item>; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + impl FeatureIndicators { pub fn active_features(&self) -> impl Iterator<Item = FeatureIndicator> { self.0.clone().into_iter() @@ -86,7 +95,7 @@ pub fn compute_feature_indicators( .default_options .any_blockers_enabled(); let custom_dns = settings.tunnel_options.dns_options.state == DnsState::Custom; - let server_ip_override = !settings.relay_overrides.is_empty(); + let server_ip_override = !settings.relay_overrides.is_empty(); // TODO: Should check if actually used let generic_features = [ (split_tunneling, FeatureIndicator::SplitTunneling), @@ -146,3 +155,169 @@ pub fn compute_feature_indicators( .filter_map(|(active, feature)| active.then_some(feature)) .collect() } + +#[cfg(test)] +mod tests { + use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + + use talpid_types::net::{ + proxy::{ProxyEndpoint, ProxyType}, + Endpoint, ObfuscationEndpoint, TransportProtocol, + }; + + use super::*; + + #[test] + fn test_one_indicator_at_a_time() { + let mut settings = Settings::default(); + let mut endpoint = TunnelEndpoint { + endpoint: Endpoint { + address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080), + protocol: TransportProtocol::Udp, + }, + tunnel_type: TunnelType::Wireguard, + quantum_resistant: Default::default(), + proxy: Default::default(), + obfuscation: Default::default(), + entry_endpoint: Default::default(), + tunnel_interface: Default::default(), + daita: Default::default(), + }; + + let mut expected_indicators: FeatureIndicators = [].into_iter().collect(); + + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators, + "The default settings and TunnelEndpoint should not have any feature indicators. \ + If this is not true anymore, please update this test." + ); + + settings.block_when_disconnected = true; + expected_indicators.0.insert(FeatureIndicator::LockdownMode); + + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + + settings + .tunnel_options + .dns_options + .default_options + .block_ads = true; + + expected_indicators + .0 + .insert(FeatureIndicator::DnsContentBlockers); + + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + + settings.allow_lan = true; + + expected_indicators.0.insert(FeatureIndicator::LanSharing); + + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + + // Setting mssfix without having an openVPN endpoint should not result in an indicator + settings.tunnel_options.openvpn.mssfix = Some(1300); + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + + endpoint.tunnel_type = TunnelType::OpenVpn; + expected_indicators.0.insert(FeatureIndicator::CustomMssFix); + + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + + endpoint.proxy = Some(ProxyEndpoint { + endpoint: Endpoint { + address: SocketAddr::from(([1, 2, 3, 4], 443)), + protocol: TransportProtocol::Tcp, + }, + proxy_type: ProxyType::Shadowsocks, + }); + + expected_indicators.0.insert(FeatureIndicator::BridgeMode); + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + + endpoint.tunnel_type = TunnelType::Wireguard; + expected_indicators + .0 + .remove(&FeatureIndicator::CustomMssFix); + expected_indicators.0.remove(&FeatureIndicator::BridgeMode); + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + + endpoint.quantum_resistant = true; + expected_indicators + .0 + .insert(FeatureIndicator::QuantumResistance); + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + + endpoint.entry_endpoint = Some(Endpoint { + address: SocketAddr::from(([1, 2, 3, 4], 443)), + protocol: TransportProtocol::Tcp, + }); + expected_indicators.0.insert(FeatureIndicator::Multihop); + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + + endpoint.obfuscation = Some(ObfuscationEndpoint { + endpoint: Endpoint { + address: SocketAddr::from(([1, 2, 3, 4], 443)), + protocol: TransportProtocol::Tcp, + }, + obfuscation_type: ObfuscationType::Udp2Tcp, + }); + expected_indicators.0.insert(FeatureIndicator::Udp2Tcp); + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + endpoint.obfuscation.as_mut().unwrap().obfuscation_type = ObfuscationType::Shadowsocks; + expected_indicators.0.remove(&FeatureIndicator::Udp2Tcp); + expected_indicators.0.insert(FeatureIndicator::Shadowsocks); + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + + settings.tunnel_options.wireguard.mtu = Some(1300); + expected_indicators.0.insert(FeatureIndicator::CustomMtu); + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + + #[cfg(daita)] + { + endpoint.daita = true; + expected_indicators.0.insert(FeatureIndicator::Daita); + assert_eq!( + compute_feature_indicators(&settings, &endpoint), + expected_indicators + ); + } + } +} |
