diff options
| author | Niklas Berglund <niklas.berglund@gmail.com> | 2024-11-20 16:31:37 +0100 |
|---|---|---|
| committer | Niklas Berglund <niklas.berglund@gmail.com> | 2024-12-03 15:15:37 +0100 |
| commit | a83948cbb4be5c02c90ebddf8068a06e0e892fb8 (patch) | |
| tree | a5ade65e3c9e2999dd3e9bfc04deda07e65ab8ff /android/test/e2e/src | |
| parent | 7b0f970d286089d6d00ede630e275624a8b84022 (diff) | |
| download | mullvadvpn-a83948cbb4be5c02c90ebddf8068a06e0e892fb8.tar.xz mullvadvpn-a83948cbb4be5c02c90ebddf8068a06e0e892fb8.zip | |
Implement UDP-over-TCP e2e test and firewall API client
Diffstat (limited to 'android/test/e2e/src')
15 files changed, 307 insertions, 23 deletions
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt index 7b98c2f8f3..81a9eabfe6 100644 --- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt @@ -1,13 +1,27 @@ package net.mullvad.mullvadvpn.test.e2e import androidx.test.uiautomator.By +import androidx.test.uiautomator.Direction +import androidx.test.uiautomator.Until +import kotlin.time.Duration.Companion.milliseconds +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking import net.mullvad.mullvadvpn.BuildConfig +import net.mullvad.mullvadvpn.compose.test.EXPAND_BUTTON_TEST_TAG +import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_BUTTON_TEST_TAG +import net.mullvad.mullvadvpn.compose.test.SWITCH_TEST_TAG +import net.mullvad.mullvadvpn.compose.test.TOP_BAR_SETTINGS_BUTTON +import net.mullvad.mullvadvpn.test.common.constant.EXTREMELY_LONG_TIMEOUT import net.mullvad.mullvadvpn.test.common.constant.VERY_LONG_TIMEOUT import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout import net.mullvad.mullvadvpn.test.common.rule.ForgetAllVpnAppsInSettingsTestRule +import net.mullvad.mullvadvpn.test.e2e.annotations.HasDependencyOnLocalAPI import net.mullvad.mullvadvpn.test.e2e.misc.AccountTestRule +import net.mullvad.mullvadvpn.test.e2e.misc.ClearFirewallRules import net.mullvad.mullvadvpn.test.e2e.misc.ConnCheckState import net.mullvad.mullvadvpn.test.e2e.misc.SimpleMullvadHttpClient +import net.mullvad.mullvadvpn.test.e2e.router.firewall.DropRule +import net.mullvad.mullvadvpn.test.e2e.router.firewall.FirewallClient import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.RegisterExtension @@ -20,6 +34,8 @@ class ConnectionTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) { @JvmField val forgetAllVpnAppsInSettingsTestRule = ForgetAllVpnAppsInSettingsTestRule() + val firewallClient = FirewallClient() + @Test fun testConnect() { // Given @@ -48,4 +64,117 @@ class ConnectionTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) { val result = SimpleMullvadHttpClient(targetContext).runConnectionCheck() assertEquals(expected, result) } + + @Test + @HasDependencyOnLocalAPI + @ClearFirewallRules + fun testWireGuardObfuscationOff() = runBlocking { + app.launchAndEnsureLoggedIn(accountTestRule.validAccountNumber) + + enableLocalNetworkSharing() + + device.findObjectWithTimeout(By.res(SELECT_LOCATION_BUTTON_TEST_TAG)).click() + clickLocationExpandButton(DEFAULT_COUNTRY) + clickLocationExpandButton(DEFAULT_CITY) + device.findObjectWithTimeout(By.text(DEFAULT_RELAY)).click() + device.findObjectWithTimeout(By.text("OK")).click() + device.findObjectWithTimeout(By.text("CONNECTED"), VERY_LONG_TIMEOUT) + val relayIpAddress = app.extractInIpv4Address() + device.findObjectWithTimeout(By.text("Disconnect")).click() + + // Disable obfuscation + device.findObjectWithTimeout(By.res(TOP_BAR_SETTINGS_BUTTON)).click() + device.findObjectWithTimeout(By.text("VPN settings")).click() + val scrollView = device.findObjectWithTimeout(By.res(SETTINGS_SCROLL_VIEW_TEST_TAG)) + scrollView.scrollUntil( + Direction.DOWN, + Until.hasObject(By.res(WIREGUARD_OBFUSCATION_OFF_CELL_TEST_TAG)), + ) + device.findObjectWithTimeout(By.res(WIREGUARD_OBFUSCATION_OFF_CELL_TEST_TAG)).click() + device.pressBack() + device.pressBack() + + // Block UDP traffic to the relay + val firewallRule = DropRule.blockUDPTrafficRule(relayIpAddress) + firewallClient.createRule(firewallRule) + + // Ensure it is not possible to connect to relay + device.findObjectWithTimeout(By.text("Connect")).click() + // Give it some time and then verify still unable to connect. This duration must be long + // enough to ensure all retry attempts have been made. + delay(UNSUCCESSFUL_CONNECTION_TIMEOUT.milliseconds) + device.findObjectWithTimeout(By.text(("CONNECTING..."))) + device.findObjectWithTimeout(By.text("Cancel")).click() + } + + @Test + @HasDependencyOnLocalAPI + @ClearFirewallRules + fun testUDPOverTCP() = + runBlocking<Unit> { + app.launchAndEnsureLoggedIn(accountTestRule.validAccountNumber) + + enableLocalNetworkSharing() + + device.findObjectWithTimeout(By.res(SELECT_LOCATION_BUTTON_TEST_TAG)).click() + clickLocationExpandButton(DEFAULT_COUNTRY) + clickLocationExpandButton(DEFAULT_CITY) + device.findObjectWithTimeout(By.text(DEFAULT_RELAY)).click() + device.findObjectWithTimeout(By.text("OK")).click() + device.findObjectWithTimeout(By.text("CONNECTED"), VERY_LONG_TIMEOUT) + val relayIpAddress = app.extractInIpv4Address() + device.findObjectWithTimeout(By.text("Disconnect")).click() + + // Block UDP traffic to the relay + val firewallRule = DropRule.blockUDPTrafficRule(relayIpAddress) + firewallClient.createRule(firewallRule) + + // Enable UDP-over-TCP + device.findObjectWithTimeout(By.res(TOP_BAR_SETTINGS_BUTTON)).click() + device.findObjectWithTimeout(By.text("VPN settings")).click() + val scrollView2 = device.findObjectWithTimeout(By.res(SETTINGS_SCROLL_VIEW_TEST_TAG)) + scrollView2.scrollUntil( + Direction.DOWN, + Until.hasObject(By.res(WIREGUARD_OBFUSCATION_UDP_OVER_TCP_CELL_TEST_TAG)), + ) + device + .findObjectWithTimeout(By.res(WIREGUARD_OBFUSCATION_UDP_OVER_TCP_CELL_TEST_TAG)) + .click() + device.pressBack() + device.pressBack() + + // Ensure it is possible to connect by using UDP-over-TCP + device.findObjectWithTimeout(By.text("Connect")).click() + device.findObjectWithTimeout(By.text("CONNECTED"), EXTREMELY_LONG_TIMEOUT) + device.findObjectWithTimeout(By.text("Disconnect")).click() + } + + private fun enableLocalNetworkSharing() { + device.findObjectWithTimeout(By.res(TOP_BAR_SETTINGS_BUTTON)).click() + device.findObjectWithTimeout(By.text("VPN settings")).click() + + val localNetworkSharingCell = + device.findObjectWithTimeout(By.text("Local network sharing")).parent + val localNetworkSharingSwitch = + localNetworkSharingCell.findObjectWithTimeout(By.res(SWITCH_TEST_TAG)) + + localNetworkSharingSwitch.click() + device.pressBack() + device.pressBack() + } + + private fun clickLocationExpandButton(locationName: String) { + val locationCell = device.findObjectWithTimeout(By.text(locationName)).parent.parent + val expandButton = locationCell.findObjectWithTimeout(By.res(EXPAND_BUTTON_TEST_TAG)) + expandButton.click() + } + + companion object { + const val SETTINGS_SCROLL_VIEW_TEST_TAG = "lazy_list_vpn_settings_test_tag" + const val WIREGUARD_OBFUSCATION_OFF_CELL_TEST_TAG = + "wireguard_obfuscation_off_cell_test_tag" + const val WIREGUARD_OBFUSCATION_UDP_OVER_TCP_CELL_TEST_TAG = + "wireguard_obfuscation_udp_over_tcp_cell_test_tag" + const val UNSUCCESSFUL_CONNECTION_TIMEOUT = 60000L + } } diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LeakTest.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LeakTest.kt index 406671d346..47f2c72068 100644 --- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LeakTest.kt +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LeakTest.kt @@ -16,9 +16,9 @@ import net.mullvad.mullvadvpn.test.e2e.annotations.HasDependencyOnLocalAPI import net.mullvad.mullvadvpn.test.e2e.misc.AccountTestRule import net.mullvad.mullvadvpn.test.e2e.misc.LeakCheck import net.mullvad.mullvadvpn.test.e2e.misc.NoTrafficToHostRule -import net.mullvad.mullvadvpn.test.e2e.misc.PacketCapture -import net.mullvad.mullvadvpn.test.e2e.misc.PacketCaptureResult import net.mullvad.mullvadvpn.test.e2e.misc.TrafficGenerator +import net.mullvad.mullvadvpn.test.e2e.router.packetCapture.PacketCapture +import net.mullvad.mullvadvpn.test.e2e.router.packetCapture.PacketCaptureResult import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.RegisterExtension diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HasDependencyOnLocalAPI.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HasDependencyOnLocalAPI.kt index c6c9a70ee9..12987df9e0 100644 --- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HasDependencyOnLocalAPI.kt +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HasDependencyOnLocalAPI.kt @@ -1,7 +1,6 @@ package net.mullvad.mullvadvpn.test.e2e.annotations import androidx.test.platform.app.InstrumentationRegistry -import net.mullvad.mullvadvpn.test.e2e.constant.ENABLE_ACCESS_TO_LOCAL_API_TESTS import net.mullvad.mullvadvpn.test.e2e.extension.getRequiredArgument import org.junit.jupiter.api.extension.ConditionEvaluationResult import org.junit.jupiter.api.extension.ExecutionCondition @@ -22,7 +21,7 @@ annotation class HasDependencyOnLocalAPI { val enable = InstrumentationRegistry.getArguments() - .getRequiredArgument(ENABLE_ACCESS_TO_LOCAL_API_TESTS) + .getRequiredArgument("enable_access_to_local_api_tests") .toBoolean() return if (enable) { diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/ClearFirewallRules.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/ClearFirewallRules.kt new file mode 100644 index 0000000000..5fe73e04c7 --- /dev/null +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/ClearFirewallRules.kt @@ -0,0 +1,24 @@ +package net.mullvad.mullvadvpn.test.e2e.misc + +import kotlinx.coroutines.runBlocking +import net.mullvad.mullvadvpn.test.e2e.router.firewall.FirewallClient +import org.junit.jupiter.api.extension.AfterTestExecutionCallback +import org.junit.jupiter.api.extension.BeforeTestExecutionCallback +import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.api.extension.ExtensionContext + +@Retention(AnnotationRetention.RUNTIME) +@ExtendWith(ClearFirewallRules.ClearFirewallRulesAfterTest::class) +annotation class ClearFirewallRules { + class ClearFirewallRulesAfterTest : BeforeTestExecutionCallback, AfterTestExecutionCallback { + val firewallClient = FirewallClient() + + override fun beforeTestExecution(context: ExtensionContext?) { + runBlocking { firewallClient.removeAllRules() } + } + + override fun afterTestExecution(context: ExtensionContext?) { + runBlocking { firewallClient.removeAllRules() } + } + } +} diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/LeakCheck.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/LeakCheck.kt index cab83f243c..6770551f65 100644 --- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/LeakCheck.kt +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/LeakCheck.kt @@ -1,6 +1,6 @@ package net.mullvad.mullvadvpn.test.e2e.misc -import net.mullvad.mullvadvpn.test.e2e.model.Stream +import net.mullvad.mullvadvpn.test.e2e.router.packetCapture.Stream import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertTrue diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/NetworkingProtocol.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/NetworkingProtocol.kt new file mode 100644 index 0000000000..7cc12a9250 --- /dev/null +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/NetworkingProtocol.kt @@ -0,0 +1,11 @@ +package net.mullvad.mullvadvpn.test.e2e.router + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +enum class NetworkingProtocol { + @SerialName("tcp") TCP, + @SerialName("udp") UDP, + @SerialName("icmp") ICMP, +} diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/firewall/DropRule.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/firewall/DropRule.kt new file mode 100644 index 0000000000..627ecdc0fe --- /dev/null +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/firewall/DropRule.kt @@ -0,0 +1,26 @@ +package net.mullvad.mullvadvpn.test.e2e.router.firewall + +import android.annotation.SuppressLint +import kotlinx.serialization.EncodeDefault +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import net.mullvad.mullvadvpn.test.e2e.misc.Networking +import net.mullvad.mullvadvpn.test.e2e.router.NetworkingProtocol + +@SuppressLint("HardwareIds") +@OptIn(ExperimentalSerializationApi::class) +@Serializable +data class DropRule( + @SerialName("src") val source: String, + @SerialName("dst") val destination: String, + val protocols: List<NetworkingProtocol>, + @EncodeDefault val label: String = "urn:uuid:${SessionIdentifier.fromDeviceIdentifier()}", +) { + companion object { + fun blockUDPTrafficRule(to: String): DropRule { + val testDeviceIpAddress = Networking.getDeviceIpv4Address() + return DropRule(testDeviceIpAddress, to, listOf(NetworkingProtocol.UDP)) + } + } +} diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/firewall/FirewallClient.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/firewall/FirewallClient.kt new file mode 100644 index 0000000000..fabfee0132 --- /dev/null +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/firewall/FirewallClient.kt @@ -0,0 +1,73 @@ +package net.mullvad.mullvadvpn.test.e2e.router.firewall + +import co.touchlab.kermit.Logger +import io.ktor.client.HttpClient +import io.ktor.client.call.body +import io.ktor.client.engine.cio.CIO +import io.ktor.client.plugins.HttpResponseValidator +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.plugins.defaultRequest +import io.ktor.client.request.delete +import io.ktor.client.request.post +import io.ktor.client.request.setBody +import io.ktor.http.ContentType +import io.ktor.http.contentType +import io.ktor.serialization.kotlinx.json.json +import kotlinx.serialization.json.Json +import kotlinx.serialization.modules.SerializersModule +import kotlinx.serialization.modules.contextual +import net.mullvad.mullvadvpn.test.e2e.BuildConfig +import net.mullvad.mullvadvpn.test.e2e.serializer.NanoSecondsTimestampSerializer +import org.junit.jupiter.api.fail + +class FirewallClient(private val httpClient: HttpClient = defaultHttpClient()) { + suspend fun createRule(rule: DropRule) { + Logger.v( + "Sending create rule request with body: ${Json.encodeToString(DropRule.serializer(), rule)}" + ) + Logger.v( + "Requesting firewall API to block ${rule.protocols} traffic from ${rule.source} to ${rule.destination}" + ) + httpClient.post("rule") { + contentType(ContentType.Application.Json) + setBody(Json.encodeToString(DropRule.serializer(), rule)) + } + } + + suspend fun removeAllRules() { + Logger.v("Sending remove all rules request") + httpClient.delete("remove-rules/${SessionIdentifier.fromDeviceIdentifier()}") + } +} + +private fun defaultHttpClient(): HttpClient = + HttpClient(CIO) { + defaultRequest { url("http://${BuildConfig.TEST_ROUTER_API_HOST}") } + + install(ContentNegotiation) { + json( + Json { + isLenient = true + prettyPrint = true + + serializersModule = SerializersModule { + contextual(NanoSecondsTimestampSerializer) + } + } + ) + } + + HttpResponseValidator { + validateResponse { response -> + val statusCode = response.status.value + if (statusCode >= 400) { + fail( + "Request failed with response status code $statusCode: ${response.body<String>()}" + ) + } + } + handleResponseExceptionWithRequest { exception, _ -> + fail("Request failed to be sent with exception: ${exception.message}") + } + } + } diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/firewall/SessionIdentifier.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/firewall/SessionIdentifier.kt new file mode 100644 index 0000000000..4838c36486 --- /dev/null +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/firewall/SessionIdentifier.kt @@ -0,0 +1,28 @@ +package net.mullvad.mullvadvpn.test.e2e.router.firewall + +import android.annotation.SuppressLint +import android.provider.Settings +import androidx.test.platform.app.InstrumentationRegistry +import java.util.UUID +import kotlinx.serialization.Serializable + +@JvmInline +@Serializable +value class SessionIdentifier(val value: String) { + override fun toString(): String = value + + companion object { + @SuppressLint("HardwareIds") + fun fromDeviceIdentifier(): SessionIdentifier { + val deviceIdentifier = + Settings.Secure.getString( + InstrumentationRegistry.getInstrumentation().targetContext.contentResolver, + Settings.Secure.ANDROID_ID, + ) + + return SessionIdentifier( + UUID.nameUUIDFromBytes(deviceIdentifier.toByteArray()).toString() + ) + } + } +} diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/model/Host.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/packetCapture/Host.kt index d59e15d017..0a7a2a5605 100644 --- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/model/Host.kt +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/packetCapture/Host.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.test.e2e.model +package net.mullvad.mullvadvpn.test.e2e.router.packetCapture data class Host(val ipAddress: String, val port: Int) { companion object { diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/model/Packet.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/packetCapture/Packet.kt index df5c5a57b9..5c788e5710 100644 --- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/model/Packet.kt +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/packetCapture/Packet.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.test.e2e.model +package net.mullvad.mullvadvpn.test.e2e.router.packetCapture import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/PacketCapture.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/packetCapture/PacketCapture.kt index aa167c55b4..7854170114 100644 --- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/PacketCapture.kt +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/packetCapture/PacketCapture.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.test.e2e.misc +package net.mullvad.mullvadvpn.test.e2e.router.packetCapture import co.touchlab.kermit.Logger import io.ktor.client.HttpClient @@ -23,7 +23,7 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.contextual import net.mullvad.mullvadvpn.test.e2e.BuildConfig -import net.mullvad.mullvadvpn.test.e2e.model.Stream +import net.mullvad.mullvadvpn.test.e2e.misc.Networking import net.mullvad.mullvadvpn.test.e2e.serializer.NanoSecondsTimestampSerializer import net.mullvad.mullvadvpn.test.e2e.serializer.PacketCaptureSessionSerializer import org.junit.jupiter.api.fail @@ -63,7 +63,7 @@ class PacketCapture { private fun defaultHttpClient(): HttpClient = HttpClient(CIO) { - defaultRequest { url("http://${BuildConfig.PACKET_CAPTURE_API_HOST}") } + defaultRequest { url("http://${BuildConfig.TEST_ROUTER_API_HOST}") } install(ContentNegotiation) { json( diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/model/Stream.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/packetCapture/Stream.kt index 38feff34d6..564d0e25cb 100644 --- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/model/Stream.kt +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/router/packetCapture/Stream.kt @@ -1,8 +1,9 @@ -package net.mullvad.mullvadvpn.test.e2e.model +package net.mullvad.mullvadvpn.test.e2e.router.packetCapture import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.Transient +import net.mullvad.mullvadvpn.test.e2e.router.NetworkingProtocol import org.joda.time.DateTime import org.joda.time.Interval @@ -11,7 +12,7 @@ data class Stream( @SerialName("peer_addr") private val sourceAddressAndPort: String, @SerialName("other_addr") private val destinationAddressAndPort: String, @SerialName("flow_id") val flowId: String?, - @SerialName("transport_protocol") val transportProtocol: NetworkTransportProtocol, + @SerialName("transport_protocol") val transportProtocol: NetworkingProtocol, val packets: List<Packet>, ) { @Transient val sourceHost = Host.fromString(sourceAddressAndPort) @@ -40,10 +41,3 @@ data class Stream( require(packets.isNotEmpty()) { "Stream must contain at least one packet" } } } - -@Serializable -enum class NetworkTransportProtocol { - @SerialName("tcp") TCP, - @SerialName("udp") UDP, - @SerialName("icmp") ICMP, -} diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/serializer/PacketCaptureSessionSerializer.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/serializer/PacketCaptureSessionSerializer.kt index 8ec1a8bed9..16824af178 100644 --- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/serializer/PacketCaptureSessionSerializer.kt +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/serializer/PacketCaptureSessionSerializer.kt @@ -6,7 +6,7 @@ import kotlinx.serialization.builtins.serializer import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import net.mullvad.mullvadvpn.test.e2e.misc.PacketCaptureSession +import net.mullvad.mullvadvpn.test.e2e.router.packetCapture.PacketCaptureSession object PacketCaptureSessionSerializer : KSerializer<PacketCaptureSession> { override val descriptor: SerialDescriptor = String.serializer().descriptor diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/serializer/PacketSerializer.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/serializer/PacketSerializer.kt index 60391218b4..b3617a6b65 100644 --- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/serializer/PacketSerializer.kt +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/serializer/PacketSerializer.kt @@ -6,9 +6,9 @@ import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.booleanOrNull import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive -import net.mullvad.mullvadvpn.test.e2e.model.Packet -import net.mullvad.mullvadvpn.test.e2e.model.RxPacket -import net.mullvad.mullvadvpn.test.e2e.model.TxPacket +import net.mullvad.mullvadvpn.test.e2e.router.packetCapture.Packet +import net.mullvad.mullvadvpn.test.e2e.router.packetCapture.RxPacket +import net.mullvad.mullvadvpn.test.e2e.router.packetCapture.TxPacket object PacketSerializer : JsonContentPolymorphicSerializer<Packet>(Packet::class) { override fun selectDeserializer(element: JsonElement): KSerializer<out Packet> { |
