From 853c428964aa6d607c65132080f8986541191bd0 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Fri, 10 Apr 2020 11:34:58 -0600 Subject: [PATCH 1/9] Fix logic inversion bug from Android 1.0. Bug: 73822755 Test: atest CtsNetTestCases:android.net.cts.UrlQuerySanitizerTest Change-Id: Ice98bb0813918341d8cffd3197cd9758d0cbf285 --- .../android/net/cts/UrlQuerySanitizerTest.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java index 2d615bbe86..82b3b14d34 100644 --- a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java @@ -16,14 +16,15 @@ package android.net.cts; -import java.util.List; -import java.util.Set; import android.net.UrlQuerySanitizer; import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; import android.net.UrlQuerySanitizer.ParameterValuePair; import android.net.UrlQuerySanitizer.ValueSanitizer; import android.test.AndroidTestCase; +import java.util.List; +import java.util.Set; + public class UrlQuerySanitizerTest extends AndroidTestCase { private static final int ALL_OK = IllegalCharacterValueSanitizer.ALL_OK; @@ -209,6 +210,17 @@ public class UrlQuerySanitizerTest extends AndroidTestCase { } + public void testScriptUrlOk_73822755() { + ValueSanitizer sanitizer = new UrlQuerySanitizer.IllegalCharacterValueSanitizer( + UrlQuerySanitizer.IllegalCharacterValueSanitizer.SCRIPT_URL_OK); + assertEquals("javascript:alert()", sanitizer.sanitize("javascript:alert()")); + } + + public void testScriptUrlBlocked_73822755() { + ValueSanitizer sanitizer = UrlQuerySanitizer.getUrlAndSpaceLegal(); + assertEquals("", sanitizer.sanitize("javascript:alert()")); + } + private static class MockValueSanitizer implements ValueSanitizer{ public String sanitize(String value) { From 6fe3606924a9b482db264bd412dedee435592f2b Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Sun, 12 Apr 2020 21:34:11 +0900 Subject: [PATCH 2/9] Increase test independence If a test fails without unregistering an agent, other tests will see their requests match the old agent. That means any test failing will fail all subsequent tests, which is not very helpful. Solve this by making sure the agents are unregistered before the test ends. Also ensure the requests are unregistered. Test: NetworkAgentTest Bug: 139268426 Change-Id: If183d78298aa2a0bcae9e2487199dee14014cdfb Merged-In: I2c167803d478d31fd85dc6e6e621f35d36c68fb4 (cherry-picked from aosp/1284556) --- .../src/android/net/cts/NetworkAgentTest.kt | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 2fdd5fb201..d0e3023db6 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -67,6 +67,9 @@ class NetworkAgentTest { private class Provider(context: Context, looper: Looper) : NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider") + private val agentsToCleanUp = mutableListOf() + private val callbacksToCleanUp = mutableListOf() + @Before fun setUp() { instrumentation.getUiAutomation().adoptShellPermissionIdentity() @@ -75,11 +78,13 @@ class NetworkAgentTest { @After fun tearDown() { + agentsToCleanUp.forEach { it.unregister() } + callbacksToCleanUp.forEach { mCM.unregisterNetworkCallback(it) } mHandlerThread.quitSafely() instrumentation.getUiAutomation().dropShellPermissionIdentity() } - internal class TestableNetworkAgent( + private class TestableNetworkAgent( looper: Looper, nc: NetworkCapabilities, lp: LinkProperties, @@ -94,12 +99,10 @@ class NetworkAgentTest { } override fun onBandwidthUpdateRequested() { - super.onBandwidthUpdateRequested() history.add(OnBandwidthUpdateRequested) } override fun onNetworkUnwanted() { - super.onNetworkUnwanted() history.add(OnNetworkUnwanted) } @@ -109,6 +112,11 @@ class NetworkAgentTest { } } + private fun requestNetwork(request: NetworkRequest, callback: TestableNetworkCallback) { + mCM.requestNetwork(request, callback) + callbacksToCleanUp.add(callback) + } + private fun createNetworkAgent(): TestableNetworkAgent { val nc = NetworkCapabilities().apply { addTransportType(NetworkCapabilities.TRANSPORT_TEST) @@ -120,7 +128,9 @@ class NetworkAgentTest { } val lp = LinkProperties() val config = NetworkAgentConfig.Builder().build() - return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config) + return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config).also { + agentsToCleanUp.add(it) + } } private fun createConnectedNetworkAgent(): Pair { @@ -129,8 +139,9 @@ class NetworkAgentTest { .addTransportType(NetworkCapabilities.TRANSPORT_TEST) .build() val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) - mCM.requestNetwork(request, callback) - val agent = createNetworkAgent().also { it.register() } + requestNetwork(request, callback) + val agent = createNetworkAgent() + agent.register() agent.markConnected() return agent to callback } From dce3e15cd347ca563f705b1d5f01c8a7cc70d509 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Fri, 13 Mar 2020 21:10:56 +0900 Subject: [PATCH 3/9] Test onStartSocketKeepalive Test: this Bug: 139268426 Change-Id: I26f68fdf9b687a2d87c971525b1cd2c48d4579bb Merged-In: I4e251fa0203a1888badef9ed90495fe8b3340a1c (cherry-picked aosp/1258137) --- .../src/android/net/cts/NetworkAgentTest.kt | 161 +++++++++++++++++- 1 file changed, 155 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index d0e3023db6..32f2bfafe2 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -18,29 +18,51 @@ package android.net.cts import android.app.Instrumentation import android.content.Context import android.net.ConnectivityManager +import android.net.KeepalivePacketData +import android.net.LinkAddress import android.net.LinkProperties +import android.net.Network import android.net.NetworkAgent +import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE +import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE import android.net.NetworkAgentConfig import android.net.NetworkCapabilities import android.net.NetworkProvider import android.net.NetworkRequest -import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested -import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted +import android.net.SocketKeepalive import android.os.Build +import android.os.Handler import android.os.HandlerThread import android.os.Looper +import android.os.Message +import android.os.Messenger +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive import androidx.test.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 +import com.android.internal.util.AsyncChannel import com.android.testutils.ArrayTrackRecord import com.android.testutils.DevSdkIgnoreRule import com.android.testutils.RecorderCallback.CallbackEntry.Lost import com.android.testutils.TestableNetworkCallback import org.junit.After +import org.junit.Assert.fail import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import java.net.InetAddress +import java.time.Duration +import kotlin.test.assertEquals import kotlin.test.assertFailsWith +import kotlin.test.assertNotNull +import kotlin.test.assertNull import kotlin.test.assertTrue // This test doesn't really have a constraint on how fast the methods should return. If it's @@ -51,18 +73,29 @@ private const val DEFAULT_TIMEOUT_MS = 5000L // requests filed by the test and should never match normal internet requests. 70 is the default // score of Ethernet networks, it's as good a value as any other. private const val TEST_NETWORK_SCORE = 70 +private const val FAKE_NET_ID = 1098 private val instrumentation: Instrumentation get() = InstrumentationRegistry.getInstrumentation() private val context: Context get() = InstrumentationRegistry.getContext() +private fun Message(what: Int, arg1: Int, arg2: Int, obj: Any?) = Message.obtain().also { + it.what = what + it.arg1 = arg1 + it.arg2 = arg2 + it.obj = obj +} @RunWith(AndroidJUnit4::class) class NetworkAgentTest { @Rule @JvmField val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q) + private val LOCAL_IPV4_ADDRESS = InetAddress.parseNumericAddress("192.0.2.1") + private val REMOTE_IPV4_ADDRESS = InetAddress.parseNumericAddress("192.0.2.2") + private val mCM = context.getSystemService(ConnectivityManager::class.java) private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread") + private val mFakeConnectivityService by lazy { FakeConnectivityService(mHandlerThread.looper) } private class Provider(context: Context, looper: Looper) : NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider") @@ -84,8 +117,37 @@ class NetworkAgentTest { instrumentation.getUiAutomation().dropShellPermissionIdentity() } - private class TestableNetworkAgent( - looper: Looper, + /** + * A fake that helps simulating ConnectivityService talking to a harnessed agent. + * This fake only supports speaking to one harnessed agent at a time because it + * only keeps track of one async channel. + */ + private class FakeConnectivityService(looper: Looper) { + private val msgHistory = ArrayTrackRecord().newReadHead() + private val asyncChannel = AsyncChannel() + private val handler = object : Handler(looper) { + override fun handleMessage(msg: Message) { + msgHistory.add(Message.obtain(msg)) // make a copy as the original will be recycled + when (msg.what) { + AsyncChannel.CMD_CHANNEL_HALF_CONNECTED -> + asyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION) + AsyncChannel.CMD_CHANNEL_DISCONNECT, AsyncChannel.CMD_CHANNEL_DISCONNECTED -> + fail("Agent unexpectedly disconnected") + } + } + } + + fun connect(agentMsngr: Messenger) = asyncChannel.connect(context, handler, agentMsngr) + + fun sendMessage(what: Int, arg1: Int = 0, arg2: Int = 0, obj: Any? = null) = + asyncChannel.sendMessage(Message(what, arg1, arg2, obj)) + + fun expectMessage(what: Int) = + assertNotNull(msgHistory.poll(DEFAULT_TIMEOUT_MS) { it.what == what }) + } + + private open class TestableNetworkAgent( + val looper: Looper, nc: NetworkCapabilities, lp: LinkProperties, conf: NetworkAgentConfig @@ -96,6 +158,17 @@ class NetworkAgentTest { sealed class CallbackEntry { object OnBandwidthUpdateRequested : CallbackEntry() object OnNetworkUnwanted : CallbackEntry() + data class OnAddKeepalivePacketFilter( + val slot: Int, + val packet: KeepalivePacketData + ) : CallbackEntry() + data class OnRemoveKeepalivePacketFilter(val slot: Int) : CallbackEntry() + data class OnStartSocketKeepalive( + val slot: Int, + val interval: Int, + val packet: KeepalivePacketData + ) : CallbackEntry() + data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry() } override fun onBandwidthUpdateRequested() { @@ -106,9 +179,35 @@ class NetworkAgentTest { history.add(OnNetworkUnwanted) } - inline fun expectCallback() { + override fun onAddKeepalivePacketFilter(slot: Int, packet: KeepalivePacketData) { + history.add(OnAddKeepalivePacketFilter(slot, packet)) + } + + override fun onRemoveKeepalivePacketFilter(slot: Int) { + history.add(OnRemoveKeepalivePacketFilter(slot)) + } + + override fun onStartSocketKeepalive( + slot: Int, + interval: Duration, + packet: KeepalivePacketData + ) { + history.add(OnStartSocketKeepalive(slot, interval.seconds.toInt(), packet)) + } + + override fun onStopSocketKeepalive(slot: Int) { + history.add(OnStopSocketKeepalive(slot)) + } + + inline fun expectCallback(): T { val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") + return foundCallback + } + + fun assertNoCallback() { + assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS), "Handler never became idle") + assertNull(history.peek()) } } @@ -126,7 +225,9 @@ class NetworkAgentTest { addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) } - val lp = LinkProperties() + val lp = LinkProperties().apply { + addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 0)) + } val config = NetworkAgentConfig.Builder().build() return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config).also { agentsToCleanUp.add(it) @@ -146,6 +247,10 @@ class NetworkAgentTest { return agent to callback } + private fun createNetworkAgentWithFakeCS() = createNetworkAgent().also { + mFakeConnectivityService.connect(it.registerForTest(Network(FAKE_NET_ID))) + } + @Test fun testConnectAndUnregister() { val (agent, callback) = createConnectedNetworkAgent() @@ -166,4 +271,48 @@ class NetworkAgentTest { agent.expectCallback() agent.unregister() } + + @Test + fun testSocketKeepalive(): Unit = createNetworkAgentWithFakeCS().let { agent -> + val packet = object : KeepalivePacketData( + LOCAL_IPV4_ADDRESS /* srcAddress */, 1234 /* srcPort */, + REMOTE_IPV4_ADDRESS /* dstAddress */, 4567 /* dstPort */, + ByteArray(100 /* size */) { it.toByte() /* init */ }) {} + val slot = 4 + val interval = 37 + + mFakeConnectivityService.sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, + arg1 = slot, obj = packet) + mFakeConnectivityService.sendMessage(CMD_START_SOCKET_KEEPALIVE, + arg1 = slot, arg2 = interval, obj = packet) + + agent.expectCallback().let { + assertEquals(it.slot, slot) + assertEquals(it.packet, packet) + } + agent.expectCallback().let { + assertEquals(it.slot, slot) + assertEquals(it.interval, interval) + assertEquals(it.packet, packet) + } + + agent.assertNoCallback() + + // Check that when the agent sends a keepalive event, ConnectivityService receives the + // expected message. + agent.sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED) + mFakeConnectivityService.expectMessage(NetworkAgent.EVENT_SOCKET_KEEPALIVE).let() { + assertEquals(slot, it.arg1) + assertEquals(SocketKeepalive.ERROR_UNSUPPORTED, it.arg2) + } + + mFakeConnectivityService.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, arg1 = slot) + mFakeConnectivityService.sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, arg1 = slot) + agent.expectCallback().let { + assertEquals(it.slot, slot) + } + agent.expectCallback().let { + assertEquals(it.slot, slot) + } + } } From d5273557349f3afe6249404876f75df2a628ddaf Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Mon, 13 Apr 2020 14:27:45 +0900 Subject: [PATCH 4/9] Test accept unvalidated Test: this Bug: 139268426 Change-Id: I9343f72e1b1f4752e9781ff9b44e2a561d166cfb Merged-In: I3326a2119d66e67566fce0268ea4861729b1c64c (cherry-picked from aosp/1284557) --- .../src/android/net/cts/NetworkAgentTest.kt | 66 ++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 32f2bfafe2..14f52e1e7c 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -24,7 +24,9 @@ import android.net.LinkProperties import android.net.Network import android.net.NetworkAgent import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE import android.net.NetworkAgentConfig @@ -39,9 +41,11 @@ import android.os.Looper import android.os.Message import android.os.Messenger import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAutomaticReconnectDisabled import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive import androidx.test.InstrumentationRegistry @@ -60,6 +64,7 @@ import org.junit.runner.RunWith import java.net.InetAddress import java.time.Duration import kotlin.test.assertEquals +import kotlin.test.assertFalse import kotlin.test.assertFailsWith import kotlin.test.assertNotNull import kotlin.test.assertNull @@ -123,27 +128,38 @@ class NetworkAgentTest { * only keeps track of one async channel. */ private class FakeConnectivityService(looper: Looper) { + private val CMD_EXPECT_DISCONNECT = 1 + private var disconnectExpected = false private val msgHistory = ArrayTrackRecord().newReadHead() private val asyncChannel = AsyncChannel() private val handler = object : Handler(looper) { override fun handleMessage(msg: Message) { msgHistory.add(Message.obtain(msg)) // make a copy as the original will be recycled when (msg.what) { + CMD_EXPECT_DISCONNECT -> disconnectExpected = true AsyncChannel.CMD_CHANNEL_HALF_CONNECTED -> asyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION) - AsyncChannel.CMD_CHANNEL_DISCONNECT, AsyncChannel.CMD_CHANNEL_DISCONNECTED -> - fail("Agent unexpectedly disconnected") + AsyncChannel.CMD_CHANNEL_DISCONNECTED -> + if (!disconnectExpected) { + fail("Agent unexpectedly disconnected") + } else { + disconnectExpected = false + } } } } fun connect(agentMsngr: Messenger) = asyncChannel.connect(context, handler, agentMsngr) + fun disconnect() = asyncChannel.disconnect() + fun sendMessage(what: Int, arg1: Int = 0, arg2: Int = 0, obj: Any? = null) = asyncChannel.sendMessage(Message(what, arg1, arg2, obj)) fun expectMessage(what: Int) = assertNotNull(msgHistory.poll(DEFAULT_TIMEOUT_MS) { it.what == what }) + + fun willExpectDisconnectOnce() = handler.sendEmptyMessage(CMD_EXPECT_DISCONNECT) } private open class TestableNetworkAgent( @@ -169,6 +185,8 @@ class NetworkAgentTest { val packet: KeepalivePacketData ) : CallbackEntry() data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry() + data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry() + object OnAutomaticReconnectDisabled : CallbackEntry() } override fun onBandwidthUpdateRequested() { @@ -199,6 +217,14 @@ class NetworkAgentTest { history.add(OnStopSocketKeepalive(slot)) } + override fun onSaveAcceptUnvalidated(accept: Boolean) { + history.add(OnSaveAcceptUnvalidated(accept)) + } + + override fun onAutomaticReconnectDisabled() { + history.add(OnAutomaticReconnectDisabled) + } + inline fun expectCallback(): T { val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") @@ -315,4 +341,40 @@ class NetworkAgentTest { assertEquals(it.slot, slot) } } + + @Test + fun testSetAcceptUnvalidated() { + createNetworkAgentWithFakeCS().let { agent -> + mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 1) + agent.expectCallback().let { + assertTrue(it.accept) + } + agent.assertNoCallback() + } + createNetworkAgentWithFakeCS().let { agent -> + mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 0) + mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) + agent.expectCallback().let { + assertFalse(it.accept) + } + agent.expectCallback() + agent.assertNoCallback() + // When automatic reconnect is turned off, the network is torn down and + // ConnectivityService sends a disconnect. This in turn causes the agent + // to send a DISCONNECTED message to CS. + mFakeConnectivityService.willExpectDisconnectOnce() + mFakeConnectivityService.disconnect() + mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED) + agent.expectCallback() + } + createNetworkAgentWithFakeCS().let { agent -> + mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) + agent.expectCallback() + agent.assertNoCallback() + mFakeConnectivityService.willExpectDisconnectOnce() + mFakeConnectivityService.disconnect() + mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED) + agent.expectCallback() + } + } } From 4f9483a9b8f8c1a8d45b879e6f109e31b137070c Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 14 Apr 2020 03:05:24 +0000 Subject: [PATCH 5/9] Test validation status Test: this Bug: 139268426 Change-Id: I04be5cda321af109cb6fd7510362d817ab23b505 Merged-In: I8499d9da8643cf60c912570e7a2ac2207d662e16 (cherry picked from commit 03af30598907add0f64d815f5487ea97e8d61f04, aosp/1284558) --- .../src/android/net/cts/NetworkAgentTest.kt | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 14f52e1e7c..97a15ef634 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -26,15 +26,20 @@ import android.net.NetworkAgent import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER import android.net.NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS import android.net.NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE +import android.net.NetworkAgent.INVALID_NETWORK +import android.net.NetworkAgent.VALID_NETWORK import android.net.NetworkAgentConfig import android.net.NetworkCapabilities import android.net.NetworkProvider import android.net.NetworkRequest import android.net.SocketKeepalive +import android.net.Uri import android.os.Build +import android.os.Bundle import android.os.Handler import android.os.HandlerThread import android.os.Looper @@ -48,6 +53,7 @@ import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRem import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnValidationStatus import androidx.test.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 import com.android.internal.util.AsyncChannel @@ -187,6 +193,7 @@ class NetworkAgentTest { data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry() data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry() object OnAutomaticReconnectDisabled : CallbackEntry() + data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry() } override fun onBandwidthUpdateRequested() { @@ -225,6 +232,23 @@ class NetworkAgentTest { history.add(OnAutomaticReconnectDisabled) } + override fun onValidationStatus(status: Int, uri: Uri?) { + history.add(OnValidationStatus(status, uri)) + } + + // Expects the initial validation event that always occurs immediately after registering + // a NetworkAgent whose network does not require validation (which test networks do + // not, since they lack the INTERNET capability). It always contains the default argument + // for the URI. + fun expectNoInternetValidationStatus() = expectCallback().let { + assertEquals(it.status, VALID_NETWORK) + // The returned Uri is parsed from the empty string, which means it's an + // instance of the (private) Uri.StringUri. There are no real good ways + // to check this, the least bad is to just convert it to a string and + // make sure it's empty. + assertEquals("", it.uri.toString()) + } + inline fun expectCallback(): T { val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") @@ -281,6 +305,7 @@ class NetworkAgentTest { fun testConnectAndUnregister() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectNoInternetValidationStatus() agent.unregister() callback.expectCallback(agent.network) agent.expectCallback() @@ -293,6 +318,7 @@ class NetworkAgentTest { fun testOnBandwidthUpdateRequested() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectNoInternetValidationStatus() mCM.requestBandwidthUpdate(agent.network) agent.expectCallback() agent.unregister() @@ -377,4 +403,25 @@ class NetworkAgentTest { agent.expectCallback() } } + + @Test + fun testValidationStatus() = createNetworkAgentWithFakeCS().let { agent -> + val uri = Uri.parse("http://www.google.com") + val bundle = Bundle().apply { + putString(NetworkAgent.REDIRECT_URL_KEY, uri.toString()) + } + mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS, + arg1 = VALID_NETWORK, obj = bundle) + agent.expectCallback().let { + assertEquals(it.status, VALID_NETWORK) + assertEquals(it.uri, uri) + } + + mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS, + arg1 = INVALID_NETWORK, obj = Bundle()) + agent.expectCallback().let { + assertEquals(it.status, INVALID_NETWORK) + assertNull(it.uri) + } + } } From e582c5d4be0bf80985abb62f6524872001f2c367 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 14 Apr 2020 03:05:40 +0000 Subject: [PATCH 6/9] Test sendCaps and sendProps Test: this Bug: 139268426 Change-Id: I6d30ac0193225826a97ff3853a98b939e571d074 Merged-In: Idefce1174b82668d23c53dd1bf95bc660cb21c28 (cherry picked from commit 7922d354307e4a41a336c29291285550a94da434, aosp/1284560) --- .../src/android/net/cts/NetworkAgentTest.kt | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 97a15ef634..4de3a086ce 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -84,6 +84,7 @@ private const val DEFAULT_TIMEOUT_MS = 5000L // requests filed by the test and should never match normal internet requests. 70 is the default // score of Ethernet networks, it's as good a value as any other. private const val TEST_NETWORK_SCORE = 70 +private const val BETTER_NETWORK_SCORE = 75 private const val FAKE_NET_ID = 1098 private val instrumentation: Instrumentation get() = InstrumentationRegistry.getInstrumentation() @@ -170,8 +171,8 @@ class NetworkAgentTest { private open class TestableNetworkAgent( val looper: Looper, - nc: NetworkCapabilities, - lp: LinkProperties, + val nc: NetworkCapabilities, + val lp: LinkProperties, conf: NetworkAgentConfig ) : NetworkAgent(context, looper, TestableNetworkAgent::class.java.simpleName /* tag */, nc, lp, TEST_NETWORK_SCORE, conf, Provider(context, looper)) { @@ -368,6 +369,25 @@ class NetworkAgentTest { } } + @Test + fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) -> + callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectNoInternetValidationStatus() + val ifaceName = "adhocIface" + val lp = LinkProperties(agent.lp) + lp.setInterfaceName(ifaceName) + agent.sendLinkProperties(lp) + callback.expectLinkPropertiesThat(agent.network) { + it.getInterfaceName() == ifaceName + } + val nc = NetworkCapabilities(agent.nc) + nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) + agent.sendNetworkCapabilities(nc) + callback.expectCapabilitiesThat(agent.network) { + it.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) + } + } + @Test fun testSetAcceptUnvalidated() { createNetworkAgentWithFakeCS().let { agent -> From 2e3c3b8d89d83b138bd06cc31be3fbd5348398a9 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 14 Apr 2020 03:05:52 +0000 Subject: [PATCH 7/9] Test sendNetworkScore Test: this Bug: 139268426 Change-Id: Ie46ff2676944e6d6603bbff271fc6dca9935e548 Merged-In: I66cea443f0c6aa9235da577817787d764fbd030b (cherry picked from commit c7091c91558d56632da237cf0a01567fcde3cba2, aosp/1284561) --- .../src/android/net/cts/NetworkAgentTest.kt | 66 ++++++++++++++++++- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 4de3a086ce..659950a0db 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -37,6 +37,7 @@ import android.net.NetworkCapabilities import android.net.NetworkProvider import android.net.NetworkRequest import android.net.SocketKeepalive +import android.net.StringNetworkSpecifier import android.net.Uri import android.os.Build import android.os.Bundle @@ -59,8 +60,10 @@ import androidx.test.runner.AndroidJUnit4 import com.android.internal.util.AsyncChannel import com.android.testutils.ArrayTrackRecord import com.android.testutils.DevSdkIgnoreRule +import com.android.testutils.RecorderCallback.CallbackEntry.Available import com.android.testutils.RecorderCallback.CallbackEntry.Lost import com.android.testutils.TestableNetworkCallback +import java.util.UUID import org.junit.After import org.junit.Assert.fail import org.junit.Before @@ -197,6 +200,8 @@ class NetworkAgentTest { data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry() } + fun getName(): String? = (nc.getNetworkSpecifier() as? StringNetworkSpecifier)?.specifier + override fun onBandwidthUpdateRequested() { history.add(OnBandwidthUpdateRequested) } @@ -267,7 +272,7 @@ class NetworkAgentTest { callbacksToCleanUp.add(callback) } - private fun createNetworkAgent(): TestableNetworkAgent { + private fun createNetworkAgent(name: String? = null): TestableNetworkAgent { val nc = NetworkCapabilities().apply { addTransportType(NetworkCapabilities.TRANSPORT_TEST) removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) @@ -275,6 +280,9 @@ class NetworkAgentTest { addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) + if (null != name) { + setNetworkSpecifier(StringNetworkSpecifier(name)) + } } val lp = LinkProperties().apply { addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 0)) @@ -285,14 +293,15 @@ class NetworkAgentTest { } } - private fun createConnectedNetworkAgent(): Pair { + private fun createConnectedNetworkAgent(name: String? = null): + Pair { val request: NetworkRequest = NetworkRequest.Builder() .clearCapabilities() .addTransportType(NetworkCapabilities.TRANSPORT_TEST) .build() val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) requestNetwork(request, callback) - val agent = createNetworkAgent() + val agent = createNetworkAgent(name) agent.register() agent.markConnected() return agent to callback @@ -388,6 +397,57 @@ class NetworkAgentTest { } } + @Test + fun testSendScore() { + // This test will create two networks and check that the one with the stronger + // score wins out for a request that matches them both. + // First create requests to make sure both networks are kept up, using the + // specifier so they are specific to each network + val name1 = UUID.randomUUID().toString() + val name2 = UUID.randomUUID().toString() + val request1 = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setNetworkSpecifier(StringNetworkSpecifier(name1)) + .build() + val request2 = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setNetworkSpecifier(StringNetworkSpecifier(name2)) + .build() + val callback1 = TestableNetworkCallback() + val callback2 = TestableNetworkCallback() + requestNetwork(request1, callback1) + requestNetwork(request2, callback2) + + // Then file the interesting request + val request = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .build() + val callback = TestableNetworkCallback() + requestNetwork(request, callback) + + // Connect the first Network + createConnectedNetworkAgent(name1).let { (agent1, _) -> + callback.expectAvailableThenValidatedCallbacks(agent1.network) + // Upgrade agent1 to a better score so that there is no ambiguity when + // agent2 connects that agent1 is still better + agent1.sendNetworkScore(BETTER_NETWORK_SCORE - 1) + // Connect the second agent + createConnectedNetworkAgent(name2).let { (agent2, _) -> + agent2.markConnected() + // The callback should not see anything yet + callback.assertNoCallback(200) + // Now update the score and expect the callback now prefers agent2 + agent2.sendNetworkScore(BETTER_NETWORK_SCORE) + callback.expectCallback(agent2.network) + } + } + + // tearDown() will unregister the requests and agents + } + @Test fun testSetAcceptUnvalidated() { createNetworkAgentWithFakeCS().let { agent -> From 6a9699652523662ef197c85d5b24fde401da9e3c Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 14 Apr 2020 03:06:04 +0000 Subject: [PATCH 8/9] Test Signal thresholds Test: this Bug: 139268426 Change-Id: I48ea9afa2a31c3edd4b00a566ed47796912c453a Merged-In: I136f246d0e3ad6744989e7d6f4f8034cc6674def (cherry picked from commit 159bce95cb8ca0aba6cf74a0b57a24dae3aadc05, aosp/1284559) --- .../src/android/net/cts/NetworkAgentTest.kt | 81 ++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 659950a0db..9d1eee9da9 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -52,6 +52,7 @@ import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBan import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSignalStrengthThresholdsUpdated import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnValidationStatus @@ -65,6 +66,7 @@ import com.android.testutils.RecorderCallback.CallbackEntry.Lost import com.android.testutils.TestableNetworkCallback import java.util.UUID import org.junit.After +import org.junit.Assert.assertArrayEquals import org.junit.Assert.fail import org.junit.Before import org.junit.Rule @@ -83,6 +85,11 @@ import kotlin.test.assertTrue // going to fail, it will simply wait forever, so setting a high timeout lowers the flake ratio // without affecting the run time of successful runs. Thus, set a very high timeout. private const val DEFAULT_TIMEOUT_MS = 5000L +// When waiting for a NetworkCallback to determine there was no timeout, waiting is the +// only possible thing (the relevant handler is the one in the real ConnectivityService, +// and then there is the Binder call), so have a short timeout for this as it will be +// exhausted every time. +private const val NO_CALLBACK_TIMEOUT = 200L // Any legal score (0~99) for the test network would do, as it is going to be kept up by the // requests filed by the test and should never match normal internet requests. 70 is the default // score of Ethernet networks, it's as good a value as any other. @@ -198,6 +205,7 @@ class NetworkAgentTest { data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry() object OnAutomaticReconnectDisabled : CallbackEntry() data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry() + data class OnSignalStrengthThresholdsUpdated(val thresholds: IntArray) : CallbackEntry() } fun getName(): String? = (nc.getNetworkSpecifier() as? StringNetworkSpecifier)?.specifier @@ -238,6 +246,17 @@ class NetworkAgentTest { history.add(OnAutomaticReconnectDisabled) } + override fun onSignalStrengthThresholdsUpdated(thresholds: IntArray) { + history.add(OnSignalStrengthThresholdsUpdated(thresholds)) + } + + fun expectEmptySignalStrengths() { + expectCallback().let { + // intArrayOf() without arguments makes an empty array + assertArrayEquals(intArrayOf(), it.thresholds) + } + } + override fun onValidationStatus(status: Int, uri: Uri?) { history.add(OnValidationStatus(status, uri)) } @@ -272,6 +291,14 @@ class NetworkAgentTest { callbacksToCleanUp.add(callback) } + private fun registerNetworkCallback( + request: NetworkRequest, + callback: TestableNetworkCallback + ) { + mCM.registerNetworkCallback(request, callback) + callbacksToCleanUp.add(callback) + } + private fun createNetworkAgent(name: String? = null): TestableNetworkAgent { val nc = NetworkCapabilities().apply { addTransportType(NetworkCapabilities.TRANSPORT_TEST) @@ -315,6 +342,7 @@ class NetworkAgentTest { fun testConnectAndUnregister() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectEmptySignalStrengths() agent.expectNoInternetValidationStatus() agent.unregister() callback.expectCallback(agent.network) @@ -328,12 +356,62 @@ class NetworkAgentTest { fun testOnBandwidthUpdateRequested() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectEmptySignalStrengths() agent.expectNoInternetValidationStatus() mCM.requestBandwidthUpdate(agent.network) agent.expectCallback() agent.unregister() } + @Test + fun testSignalStrengthThresholds() { + val thresholds = intArrayOf(30, 50, 65) + val callbacks = thresholds.map { strength -> + val request = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setSignalStrength(strength) + .build() + TestableNetworkCallback(DEFAULT_TIMEOUT_MS).also { + registerNetworkCallback(request, it) + } + } + createConnectedNetworkAgent().let { (agent, callback) -> + callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectCallback().let { + assertArrayEquals(it.thresholds, thresholds) + } + agent.expectNoInternetValidationStatus() + + // Send signal strength and check that the callbacks are called appropriately. + val nc = NetworkCapabilities(agent.nc) + nc.setSignalStrength(20) + agent.sendNetworkCapabilities(nc) + callbacks.forEach { it.assertNoCallback(NO_CALLBACK_TIMEOUT) } + + nc.setSignalStrength(40) + agent.sendNetworkCapabilities(nc) + callbacks[0].expectAvailableCallbacks(agent.network) + callbacks[1].assertNoCallback(NO_CALLBACK_TIMEOUT) + callbacks[2].assertNoCallback(NO_CALLBACK_TIMEOUT) + + nc.setSignalStrength(80) + agent.sendNetworkCapabilities(nc) + callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 80 } + callbacks[1].expectAvailableCallbacks(agent.network) + callbacks[2].expectAvailableCallbacks(agent.network) + + nc.setSignalStrength(55) + agent.sendNetworkCapabilities(nc) + callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 } + callbacks[1].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 } + callbacks[2].expectCallback(agent.network) + } + callbacks.forEach { + mCM.unregisterNetworkCallback(it) + } + } + @Test fun testSocketKeepalive(): Unit = createNetworkAgentWithFakeCS().let { agent -> val packet = object : KeepalivePacketData( @@ -381,6 +459,7 @@ class NetworkAgentTest { @Test fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) -> callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectEmptySignalStrengths() agent.expectNoInternetValidationStatus() val ifaceName = "adhocIface" val lp = LinkProperties(agent.lp) @@ -438,7 +517,7 @@ class NetworkAgentTest { createConnectedNetworkAgent(name2).let { (agent2, _) -> agent2.markConnected() // The callback should not see anything yet - callback.assertNoCallback(200) + callback.assertNoCallback(NO_CALLBACK_TIMEOUT) // Now update the score and expect the callback now prefers agent2 agent2.sendNetworkScore(BETTER_NETWORK_SCORE) callback.expectCallback(agent2.network) From 5217786c6c1fe9b2276915dfbafc4bd104500021 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 14 Apr 2020 03:06:14 +0000 Subject: [PATCH 9/9] Address comments from aosp/1284557 Test: this Bug: 139268426 Change-Id: I5d90fe2716032b7ebd2b425225fe8e96900fe63b Merged-In: I5edbff1d7eed2f939ba26f1ebd7ead49ac67b978 (cherry picked from commit 55d7923c1d75e3d91b79461e2bd3846abdd9eed2, aosp/1284569) --- tests/cts/net/src/android/net/cts/NetworkAgentTest.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 9d1eee9da9..89d3dff66c 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -281,7 +281,8 @@ class NetworkAgentTest { } fun assertNoCallback() { - assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS), "Handler never became idle") + assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS), + "Handler didn't became idle after ${DEFAULT_TIMEOUT_MS}ms") assertNull(history.peek()) } } @@ -536,6 +537,10 @@ class NetworkAgentTest { } agent.assertNoCallback() } + } + + @Test + fun testSetAcceptUnvalidatedPreventAutomaticReconnect() { createNetworkAgentWithFakeCS().let { agent -> mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 0) mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) @@ -552,6 +557,10 @@ class NetworkAgentTest { mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED) agent.expectCallback() } + } + + @Test + fun testPreventAutomaticReconnect() { createNetworkAgentWithFakeCS().let { agent -> mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) agent.expectCallback()