Merge "Add CTS for registerNetworkOffer" am: f92979bd5b

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/1731451

Change-Id: I3fccedc04f86a24573222e76cbcf44cb313fe569
This commit is contained in:
Junyu Lai
2021-06-21 13:54:13 +00:00
committed by Automerger Merge Worker

View File

@@ -18,12 +18,14 @@ package android.net
import android.app.Instrumentation
import android.content.Context
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED
import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
import android.net.NetworkCapabilities.TRANSPORT_TEST
import android.net.NetworkProviderTest.TestNetworkCallback.CallbackEntry.OnUnavailable
import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequestWithdrawn
import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequested
import android.os.Build
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.util.Log
@@ -34,6 +36,7 @@ import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
import com.android.testutils.TestableNetworkOfferCallback
import com.android.testutils.isDevSdkInRange
import org.junit.After
import org.junit.Before
@@ -44,11 +47,14 @@ import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
import org.mockito.Mockito.verifyNoMoreInteractions
import java.util.UUID
import java.util.concurrent.Executor
import java.util.concurrent.RejectedExecutionException
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
import kotlin.test.fail
private const val DEFAULT_TIMEOUT_MS = 5000L
private const val DEFAULT_NO_CALLBACK_TIMEOUT_MS = 200L
private val instrumentation: Instrumentation
get() = InstrumentationRegistry.getInstrumentation()
private val context: Context get() = InstrumentationRegistry.getContext()
@@ -102,12 +108,24 @@ class NetworkProviderTest {
crossinline predicate: (T) -> Boolean
) = seenEvents.poll(DEFAULT_TIMEOUT_MS) { it is T && predicate(it) }
?: fail("Did not receive callback after ${DEFAULT_TIMEOUT_MS}ms")
fun assertNoCallback() {
val cb = seenEvents.poll(DEFAULT_NO_CALLBACK_TIMEOUT_MS)
if (null != cb) fail("Expected no callback but got $cb")
}
}
private fun createNetworkProvider(ctx: Context = context): TestNetworkProvider {
return TestNetworkProvider(ctx, mHandlerThread.looper)
}
private fun createAndRegisterNetworkProvider(ctx: Context = context) =
createNetworkProvider(ctx).also {
assertEquals(it.getProviderId(), NetworkProvider.ID_NONE)
mCm.registerNetworkProvider(it)
assertNotEquals(it.getProviderId(), NetworkProvider.ID_NONE)
}
// In S+ framework, do not run this test, since the provider will no longer receive
// onNetworkRequested for every request. Instead, provider needs to
// call {@code registerNetworkOffer} with the description of networks they
@@ -115,10 +133,7 @@ class NetworkProviderTest {
@IgnoreAfter(Build.VERSION_CODES.R)
@Test
fun testOnNetworkRequested() {
val provider = createNetworkProvider()
assertEquals(provider.getProviderId(), NetworkProvider.ID_NONE)
mCm.registerNetworkProvider(provider)
assertNotEquals(provider.getProviderId(), NetworkProvider.ID_NONE)
val provider = createAndRegisterNetworkProvider()
val specifier = CompatUtil.makeTestNetworkSpecifier(
UUID.randomUUID().toString())
@@ -179,6 +194,167 @@ class NetworkProviderTest {
mCm.unregisterNetworkProvider(provider)
}
// Mainline module can't use internal HandlerExecutor, so add an identical executor here.
// TODO: Refactor with the one in MultiNetworkPolicyTracker.
private class HandlerExecutor(private val handler: Handler) : Executor {
public override fun execute(command: Runnable) {
if (!handler.post(command)) {
throw RejectedExecutionException(handler.toString() + " is shutting down")
}
}
}
@IgnoreUpTo(Build.VERSION_CODES.R)
@Test
fun testRegisterNetworkOffer() {
val provider = createAndRegisterNetworkProvider()
val provider2 = createAndRegisterNetworkProvider()
// Prepare the materials which will be used to create different offers.
val specifier1 = CompatUtil.makeTestNetworkSpecifier("TEST-SPECIFIER-1")
val specifier2 = CompatUtil.makeTestNetworkSpecifier("TEST-SPECIFIER-2")
val scoreWeaker = NetworkScore.Builder().build()
val scoreStronger = NetworkScore.Builder().setTransportPrimary(true).build()
val ncFilter1 = NetworkCapabilities.Builder().addTransportType(TRANSPORT_TEST)
.setNetworkSpecifier(specifier1).build()
val ncFilter2 = NetworkCapabilities.Builder().addTransportType(TRANSPORT_TEST)
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
.setNetworkSpecifier(specifier1).build()
val ncFilter3 = NetworkCapabilities.Builder().addTransportType(TRANSPORT_TEST)
.setNetworkSpecifier(specifier2).build()
val ncFilter4 = NetworkCapabilities.Builder().addTransportType(TRANSPORT_TEST)
.setNetworkSpecifier(specifier2).build()
// Make 4 offers, where 1 doesn't have NOT_VCN, 2 has NOT_VCN, 3 is similar to 1 but with
// different specifier, and 4 is also similar to 1 but with different provider.
val offerCallback1 = TestableNetworkOfferCallback(
DEFAULT_TIMEOUT_MS, DEFAULT_NO_CALLBACK_TIMEOUT_MS)
val offerCallback2 = TestableNetworkOfferCallback(
DEFAULT_TIMEOUT_MS, DEFAULT_NO_CALLBACK_TIMEOUT_MS)
val offerCallback3 = TestableNetworkOfferCallback(
DEFAULT_TIMEOUT_MS, DEFAULT_NO_CALLBACK_TIMEOUT_MS)
val offerCallback4 = TestableNetworkOfferCallback(
DEFAULT_TIMEOUT_MS, DEFAULT_NO_CALLBACK_TIMEOUT_MS)
provider.registerNetworkOffer(scoreWeaker, ncFilter1,
HandlerExecutor(mHandlerThread.threadHandler), offerCallback1)
provider.registerNetworkOffer(scoreStronger, ncFilter2,
HandlerExecutor(mHandlerThread.threadHandler), offerCallback2)
provider.registerNetworkOffer(scoreWeaker, ncFilter3,
HandlerExecutor(mHandlerThread.threadHandler), offerCallback3)
provider2.registerNetworkOffer(scoreWeaker, ncFilter4,
HandlerExecutor(mHandlerThread.threadHandler), offerCallback4)
// Unlike Android R, Android S+ provider will only receive interested requests via offer
// callback. Verify that the callbacks do not see any existing request such as default
// requests.
offerCallback1.assertNoCallback()
offerCallback2.assertNoCallback()
offerCallback3.assertNoCallback()
offerCallback4.assertNoCallback()
// File a request with specifier but without NOT_VCN, verify network is needed for callback
// with the same specifier.
val nrNoNotVcn: NetworkRequest = NetworkRequest.Builder()
.addTransportType(TRANSPORT_TEST)
// Test network is not allowed to be trusted.
.removeCapability(NET_CAPABILITY_TRUSTED)
.setNetworkSpecifier(specifier1)
.build()
val cb1 = ConnectivityManager.NetworkCallback()
mCm.requestNetwork(nrNoNotVcn, cb1)
offerCallback1.expectOnNetworkNeeded(ncFilter1)
offerCallback2.expectOnNetworkNeeded(ncFilter2)
offerCallback3.assertNoCallback()
offerCallback4.assertNoCallback()
mCm.unregisterNetworkCallback(cb1)
offerCallback1.expectOnNetworkUnneeded(ncFilter1)
offerCallback2.expectOnNetworkUnneeded(ncFilter2)
offerCallback3.assertNoCallback()
offerCallback4.assertNoCallback()
// File a request without specifier but with NOT_VCN, verify network is needed for offer
// with NOT_VCN.
val nrNotVcn: NetworkRequest = NetworkRequest.Builder()
.addTransportType(TRANSPORT_TEST)
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
// Test network is not allowed to be trusted.
.removeCapability(NET_CAPABILITY_TRUSTED)
.build()
val cb2 = ConnectivityManager.NetworkCallback()
mCm.requestNetwork(nrNotVcn, cb2)
offerCallback1.assertNoCallback()
offerCallback2.expectOnNetworkNeeded(ncFilter2)
offerCallback3.assertNoCallback()
offerCallback4.assertNoCallback()
// Upgrade offer 3 & 4 to satisfy previous request and then verify they are also needed.
ncFilter3.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
provider.registerNetworkOffer(scoreWeaker, ncFilter3,
HandlerExecutor(mHandlerThread.threadHandler), offerCallback3)
ncFilter4.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
provider2.registerNetworkOffer(scoreWeaker, ncFilter4,
HandlerExecutor(mHandlerThread.threadHandler), offerCallback4)
offerCallback1.assertNoCallback()
offerCallback2.assertNoCallback()
offerCallback3.expectOnNetworkNeeded(ncFilter3)
offerCallback4.expectOnNetworkNeeded(ncFilter4)
// Connect an agent to fulfill the request, verify offer 4 is not needed since it is not
// from currently serving provider nor can beat the current satisfier.
val nc = NetworkCapabilities().apply {
addTransportType(NetworkCapabilities.TRANSPORT_TEST)
removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
setNetworkSpecifier(specifier1)
}
val config = NetworkAgentConfig.Builder().build()
val agent = object : NetworkAgent(context, mHandlerThread.looper, "TestAgent", nc,
LinkProperties(), scoreWeaker, config, provider) {}
agent.register()
agent.markConnected()
// TODO: The request is satisying by offer 2 instead of offer 1, thus it should not be
// considered as needed.
offerCallback1.expectOnNetworkNeeded(ncFilter2)
offerCallback2.assertNoCallback() // Still needed.
offerCallback3.assertNoCallback() // Still needed.
offerCallback4.expectOnNetworkUnneeded(ncFilter4)
// Upgrade the agent, verify no change since the framework will treat the offer as needed
// if a request is currently satisfied by the network provided by the same provider.
// TODO: Consider offers with weaker score are unneeded.
agent.sendNetworkScore(scoreStronger)
offerCallback1.assertNoCallback()
offerCallback2.assertNoCallback() // Still needed.
offerCallback3.assertNoCallback() // Still needed.
offerCallback4.assertNoCallback() // Still unneeded.
// Verify that offer callbacks cannot receive any event if offer is unregistered.
provider2.unregisterNetworkOffer(offerCallback4)
agent.unregister()
offerCallback1.assertNoCallback() // Still needed.
offerCallback2.assertNoCallback() // Still needed.
offerCallback3.assertNoCallback() // Still needed.
// Since the agent is unregistered, and the offer has chance to satisfy the request,
// this callback should receive needed if it is not unregistered.
offerCallback4.assertNoCallback()
// Verify that offer callbacks cannot receive any event if provider is unregistered.
mCm.unregisterNetworkProvider(provider)
mCm.unregisterNetworkCallback(cb2)
offerCallback1.assertNoCallback() // Should be unneeded if not unregistered.
offerCallback2.assertNoCallback() // Should be unneeded if not unregistered.
offerCallback3.assertNoCallback() // Should be unneeded if not unregistered.
offerCallback4.assertNoCallback() // Already unregistered.
// Clean up and Verify providers did not receive any callback during the entire test.
mCm.unregisterNetworkProvider(provider2)
provider.assertNoCallback()
provider2.assertNoCallback()
}
private class TestNetworkCallback : ConnectivityManager.NetworkCallback() {
private val seenEvents = ArrayTrackRecord<CallbackEntry>().newReadHead()
sealed class CallbackEntry {