No-op refactoring of NetworkAgentTest

This is a no-op refactoring of NetworkAgentTest, which makes
the create*NetworkAgent helper functions easier to use, this
includes:
  1. Rename "name" field to specifier, since it is the only
     purpose of that field.
  2. Make the callback generated with agent dedicated to the
     agent by adding specifier to support multiple agent cases.
  3. Refactor some code flow to for readability and less
     duplicated code.

Test: atest CtsNetTestCases:android.net.cts.NetworkAgentTest \
      --rerun-until-failure 100
Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkAgentTest
      on R device
Bug: 188657173
Merged-In: Id7948d218b78ae0abf253ca8925e787362ac463f
Change-Id: Id7948d218b78ae0abf253ca8925e787362ac463f
  (cherry-picked from aosp/1727823)
This commit is contained in:
Junyu Lai
2021-05-20 13:48:35 +00:00
parent 42096be0c6
commit e5bdc06735

View File

@@ -269,10 +269,9 @@ class NetworkAgentTest {
history.add(OnSignalStrengthThresholdsUpdated(thresholds)) history.add(OnSignalStrengthThresholdsUpdated(thresholds))
} }
fun expectEmptySignalStrengths() { fun expectSignalStrengths(thresholds: IntArray? = intArrayOf()) {
expectCallback<OnSignalStrengthThresholdsUpdated>().let { expectCallback<OnSignalStrengthThresholdsUpdated>().let {
// intArrayOf() without arguments makes an empty array assertArrayEquals(thresholds, it.thresholds)
assertArrayEquals(intArrayOf(), it.thresholds)
} }
} }
@@ -292,7 +291,7 @@ class NetworkAgentTest {
// a NetworkAgent whose network does not require validation (which test networks do // 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 // not, since they lack the INTERNET capability). It always contains the default argument
// for the URI. // for the URI.
fun expectNoInternetValidationStatus() = expectCallback<OnValidationStatus>().let { fun expectValidationBypassedStatus() = expectCallback<OnValidationStatus>().let {
assertEquals(it.status, VALID_NETWORK) assertEquals(it.status, VALID_NETWORK)
// The returned Uri is parsed from the empty string, which means it's an // 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 // instance of the (private) Uri.StringUri. There are no real good ways
@@ -332,9 +331,21 @@ class NetworkAgentTest {
callbacksToCleanUp.add(callback) callbacksToCleanUp.add(callback)
} }
private fun makeTestNetworkRequest(specifier: String? = null): NetworkRequest {
return NetworkRequest.Builder()
.clearCapabilities()
.addTransportType(TRANSPORT_TEST)
.also {
if (specifier != null) {
it.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(specifier))
}
}
.build()
}
private fun createNetworkAgent( private fun createNetworkAgent(
context: Context = realContext, context: Context = realContext,
name: String? = null, specifier: String? = null,
initialNc: NetworkCapabilities? = null, initialNc: NetworkCapabilities? = null,
initialLp: LinkProperties? = null, initialLp: LinkProperties? = null,
initialConfig: NetworkAgentConfig? = null initialConfig: NetworkAgentConfig? = null
@@ -349,8 +360,8 @@ class NetworkAgentTest {
if (SdkLevel.isAtLeastS()) { if (SdkLevel.isAtLeastS()) {
addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
} }
if (null != name) { if (null != specifier) {
setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name)) setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(specifier))
} }
} }
val lp = initialLp ?: LinkProperties().apply { val lp = initialLp ?: LinkProperties().apply {
@@ -365,21 +376,22 @@ class NetworkAgentTest {
private fun createConnectedNetworkAgent( private fun createConnectedNetworkAgent(
context: Context = realContext, context: Context = realContext,
name: String? = null, specifier: String? = UUID.randomUUID().toString(),
initialConfig: NetworkAgentConfig? = null initialConfig: NetworkAgentConfig? = null,
expectedInitSignalStrengthThresholds: IntArray? = intArrayOf()
): Pair<TestableNetworkAgent, TestableNetworkCallback> { ): Pair<TestableNetworkAgent, TestableNetworkCallback> {
val request: NetworkRequest = NetworkRequest.Builder()
.clearCapabilities()
.addTransportType(TRANSPORT_TEST)
.build()
val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
requestNetwork(request, callback) // Ensure this NetworkAgent is never unneeded by filing a request with its specifier.
val config = initialConfig ?: NetworkAgentConfig.Builder().build() requestNetwork(makeTestNetworkRequest(specifier = specifier), callback)
val agent = createNetworkAgent(context, name, initialConfig = config) val agent = createNetworkAgent(context, specifier, initialConfig = initialConfig)
agent.setTeardownDelayMillis(0) agent.setTeardownDelayMillis(0)
// Connect the agent and verify initial status callbacks.
agent.register() agent.register()
agent.markConnected() agent.markConnected()
agent.expectCallback<OnNetworkCreated>() agent.expectCallback<OnNetworkCreated>()
agent.expectSignalStrengths(expectedInitSignalStrengthThresholds)
agent.expectValidationBypassedStatus()
callback.expectAvailableThenValidatedCallbacks(agent.network!!)
return agent to callback return agent to callback
} }
@@ -413,7 +425,6 @@ class NetworkAgentTest {
.setLegacySubType(subtypeLTE) .setLegacySubType(subtypeLTE)
.setLegacySubTypeName(subtypeNameLTE).build() .setLegacySubTypeName(subtypeNameLTE).build()
val (agent, callback) = createConnectedNetworkAgent(initialConfig = config) val (agent, callback) = createConnectedNetworkAgent(initialConfig = config)
callback.expectAvailableThenValidatedCallbacks(agent.network)
agent.setLegacySubtype(subtypeUMTS, subtypeNameUMTS) agent.setLegacySubtype(subtypeUMTS, subtypeNameUMTS)
// There is no callback when networkInfo changes, // There is no callback when networkInfo changes,
@@ -433,12 +444,8 @@ class NetworkAgentTest {
@Test @Test
fun testConnectAndUnregister() { fun testConnectAndUnregister() {
val (agent, callback) = createConnectedNetworkAgent() val (agent, callback) = createConnectedNetworkAgent()
callback.expectAvailableThenValidatedCallbacks(agent.network)
agent.expectEmptySignalStrengths()
agent.expectNoInternetValidationStatus()
unregister(agent) unregister(agent)
callback.expectCallback<Lost>(agent.network) callback.expectCallback<Lost>(agent.network!!)
assertFailsWith<IllegalStateException>("Must not be able to register an agent twice") { assertFailsWith<IllegalStateException>("Must not be able to register an agent twice") {
agent.register() agent.register()
} }
@@ -446,11 +453,8 @@ class NetworkAgentTest {
@Test @Test
fun testOnBandwidthUpdateRequested() { fun testOnBandwidthUpdateRequested() {
val (agent, callback) = createConnectedNetworkAgent() val (agent, _) = createConnectedNetworkAgent()
callback.expectAvailableThenValidatedCallbacks(agent.network) mCM.requestBandwidthUpdate(agent.network!!)
agent.expectEmptySignalStrengths()
agent.expectNoInternetValidationStatus()
mCM.requestBandwidthUpdate(agent.network)
agent.expectCallback<OnBandwidthUpdateRequested>() agent.expectCallback<OnBandwidthUpdateRequested>()
unregister(agent) unregister(agent)
} }
@@ -468,13 +472,8 @@ class NetworkAgentTest {
registerNetworkCallback(request, it) registerNetworkCallback(request, it)
} }
} }
createConnectedNetworkAgent().let { (agent, callback) -> createConnectedNetworkAgent(expectedInitSignalStrengthThresholds = thresholds).let {
callback.expectAvailableThenValidatedCallbacks(agent.network) (agent, callback) ->
agent.expectCallback<OnSignalStrengthThresholdsUpdated>().let {
assertArrayEquals(it.thresholds, thresholds)
}
agent.expectNoInternetValidationStatus()
// Send signal strength and check that the callbacks are called appropriately. // Send signal strength and check that the callbacks are called appropriately.
val nc = NetworkCapabilities(agent.nc) val nc = NetworkCapabilities(agent.nc)
nc.setSignalStrength(20) nc.setSignalStrength(20)
@@ -483,21 +482,21 @@ class NetworkAgentTest {
nc.setSignalStrength(40) nc.setSignalStrength(40)
agent.sendNetworkCapabilities(nc) agent.sendNetworkCapabilities(nc)
callbacks[0].expectAvailableCallbacks(agent.network) callbacks[0].expectAvailableCallbacks(agent.network!!)
callbacks[1].assertNoCallback(NO_CALLBACK_TIMEOUT) callbacks[1].assertNoCallback(NO_CALLBACK_TIMEOUT)
callbacks[2].assertNoCallback(NO_CALLBACK_TIMEOUT) callbacks[2].assertNoCallback(NO_CALLBACK_TIMEOUT)
nc.setSignalStrength(80) nc.setSignalStrength(80)
agent.sendNetworkCapabilities(nc) agent.sendNetworkCapabilities(nc)
callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 80 } callbacks[0].expectCapabilitiesThat(agent.network!!) { it.signalStrength == 80 }
callbacks[1].expectAvailableCallbacks(agent.network) callbacks[1].expectAvailableCallbacks(agent.network!!)
callbacks[2].expectAvailableCallbacks(agent.network) callbacks[2].expectAvailableCallbacks(agent.network!!)
nc.setSignalStrength(55) nc.setSignalStrength(55)
agent.sendNetworkCapabilities(nc) agent.sendNetworkCapabilities(nc)
callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 } callbacks[0].expectCapabilitiesThat(agent.network!!) { it.signalStrength == 55 }
callbacks[1].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 } callbacks[1].expectCapabilitiesThat(agent.network!!) { it.signalStrength == 55 }
callbacks[2].expectCallback<Lost>(agent.network) callbacks[2].expectCallback<Lost>(agent.network!!)
} }
callbacks.forEach { callbacks.forEach {
mCM.unregisterNetworkCallback(it) mCM.unregisterNetworkCallback(it)
@@ -546,20 +545,17 @@ class NetworkAgentTest {
@Test @Test
fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) -> fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) ->
callback.expectAvailableThenValidatedCallbacks(agent.network)
agent.expectEmptySignalStrengths()
agent.expectNoInternetValidationStatus()
val ifaceName = "adhocIface" val ifaceName = "adhocIface"
val lp = LinkProperties(agent.lp) val lp = LinkProperties(agent.lp)
lp.setInterfaceName(ifaceName) lp.setInterfaceName(ifaceName)
agent.sendLinkProperties(lp) agent.sendLinkProperties(lp)
callback.expectLinkPropertiesThat(agent.network) { callback.expectLinkPropertiesThat(agent.network!!) {
it.getInterfaceName() == ifaceName it.getInterfaceName() == ifaceName
} }
val nc = NetworkCapabilities(agent.nc) val nc = NetworkCapabilities(agent.nc)
nc.addCapability(NET_CAPABILITY_NOT_METERED) nc.addCapability(NET_CAPABILITY_NOT_METERED)
agent.sendNetworkCapabilities(nc) agent.sendNetworkCapabilities(nc)
callback.expectCapabilitiesThat(agent.network) { callback.expectCapabilitiesThat(agent.network!!) {
it.hasCapability(NET_CAPABILITY_NOT_METERED) it.hasCapability(NET_CAPABILITY_NOT_METERED)
} }
} }
@@ -568,56 +564,32 @@ class NetworkAgentTest {
fun testSendScore() { fun testSendScore() {
// This test will create two networks and check that the one with the stronger // This test will create two networks and check that the one with the stronger
// score wins out for a request that matches them both. // 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(TRANSPORT_TEST)
.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name1))
.build()
val request2 = NetworkRequest.Builder()
.clearCapabilities()
.addTransportType(TRANSPORT_TEST)
.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name2))
.build()
val callback1 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
val callback2 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
requestNetwork(request1, callback1)
requestNetwork(request2, callback2)
// Then file the interesting request // File the interesting request
val request = NetworkRequest.Builder()
.clearCapabilities()
.addTransportType(TRANSPORT_TEST)
.build()
val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
requestNetwork(request, callback) requestNetwork(makeTestNetworkRequest(), callback)
// Connect the first Network // Connect the first Network, with an unused callback that kept the network up.
createConnectedNetworkAgent(name = name1).let { (agent1, _) -> val (agent1, _) = createConnectedNetworkAgent()
callback.expectAvailableThenValidatedCallbacks(agent1.network) callback.expectAvailableThenValidatedCallbacks(agent1.network!!)
// If using the int ranking, agent1 must be upgraded to a better score so that there is // If using the int ranking, agent1 must be upgraded to a better score so that there is
// no ambiguity when agent2 connects that agent1 is still better. If using policy // no ambiguity when agent2 connects that agent1 is still better. If using policy
// ranking, this is not necessary. // ranking, this is not necessary.
agent1.sendNetworkScore(NetworkScore.Builder().setLegacyInt(BETTER_NETWORK_SCORE) agent1.sendNetworkScore(NetworkScore.Builder().setLegacyInt(BETTER_NETWORK_SCORE)
.build()) .build())
// Connect the second agent
createConnectedNetworkAgent(name = name2).let { (agent2, _) -> // Connect the second agent.
agent2.markConnected() val (agent2, _) = createConnectedNetworkAgent()
// The callback should not see anything yet. With int ranking, agent1 was upgraded // The callback should not see anything yet. With int ranking, agent1 was upgraded
// to a stronger score beforehand. With policy ranking, agent1 is preferred by // to a stronger score beforehand. With policy ranking, agent1 is preferred by
// virtue of already satisfying the request. // virtue of already satisfying the request.
callback.assertNoCallback(NO_CALLBACK_TIMEOUT) callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
// Now downgrade the score and expect the callback now prefers agent2 // Now downgrade the score and expect the callback now prefers agent2
agent1.sendNetworkScore(NetworkScore.Builder() agent1.sendNetworkScore(NetworkScore.Builder()
.setLegacyInt(WORSE_NETWORK_SCORE) .setLegacyInt(WORSE_NETWORK_SCORE)
.setExiting(true) .setExiting(true)
.build()) .build())
callback.expectCallback<Available>(agent2.network) callback.expectCallback<Available>(agent2.network!!)
}
}
// tearDown() will unregister the requests and agents // tearDown() will unregister the requests and agents
} }
@@ -658,7 +630,7 @@ class NetworkAgentTest {
callback.expectAvailableThenValidatedCallbacks(agent.network!!) callback.expectAvailableThenValidatedCallbacks(agent.network!!)
// Check that the default network's transport is propagated to the VPN. // Check that the default network's transport is propagated to the VPN.
var vpnNc = mCM.getNetworkCapabilities(agent.network) var vpnNc = mCM.getNetworkCapabilities(agent.network!!)
assertNotNull(vpnNc) assertNotNull(vpnNc)
assertEquals(VpnManager.TYPE_VPN_SERVICE, assertEquals(VpnManager.TYPE_VPN_SERVICE,
(vpnNc.transportInfo as VpnTransportInfo).type) (vpnNc.transportInfo as VpnTransportInfo).type)
@@ -690,7 +662,7 @@ class NetworkAgentTest {
// This is not very accurate because the test does not control the capabilities of the // This is not very accurate because the test does not control the capabilities of the
// underlying networks, and because not congested, not roaming, and not suspended are the // underlying networks, and because not congested, not roaming, and not suspended are the
// default anyway. It's still useful as an extra check though. // default anyway. It's still useful as an extra check though.
vpnNc = mCM.getNetworkCapabilities(agent.network) vpnNc = mCM.getNetworkCapabilities(agent.network!!)
for (cap in listOf(NET_CAPABILITY_NOT_CONGESTED, for (cap in listOf(NET_CAPABILITY_NOT_CONGESTED,
NET_CAPABILITY_NOT_ROAMING, NET_CAPABILITY_NOT_ROAMING,
NET_CAPABILITY_NOT_SUSPENDED)) { NET_CAPABILITY_NOT_SUSPENDED)) {
@@ -701,7 +673,7 @@ class NetworkAgentTest {
} }
unregister(agent) unregister(agent)
callback.expectCallback<Lost>(agent.network) callback.expectCallback<Lost>(agent.network!!)
} }
private fun unregister(agent: TestableNetworkAgent) { private fun unregister(agent: TestableNetworkAgent) {
@@ -789,43 +761,24 @@ class NetworkAgentTest {
fun testTemporarilyUnmeteredCapability() { fun testTemporarilyUnmeteredCapability() {
// This test will create a networks with/without NET_CAPABILITY_TEMPORARILY_NOT_METERED // This test will create a networks with/without NET_CAPABILITY_TEMPORARILY_NOT_METERED
// and check that the callback reflects the capability changes. // and check that the callback reflects the capability changes.
// First create a request to make sure the network is kept up
val request1 = NetworkRequest.Builder()
.clearCapabilities()
.addTransportType(TRANSPORT_TEST)
.build()
val callback1 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS).also {
registerNetworkCallback(request1, it)
}
requestNetwork(request1, callback1)
// Then file the interesting request
val request = NetworkRequest.Builder()
.clearCapabilities()
.addTransportType(TRANSPORT_TEST)
.build()
val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
requestNetwork(request, callback)
// Connect the network // Connect the network
createConnectedNetworkAgent().let { (agent, _) -> val (agent, callback) = createConnectedNetworkAgent()
callback.expectAvailableThenValidatedCallbacks(agent.network)
// Send TEMP_NOT_METERED and check that the callback is called appropriately. // Send TEMP_NOT_METERED and check that the callback is called appropriately.
val nc1 = NetworkCapabilities(agent.nc) val nc1 = NetworkCapabilities(agent.nc)
.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED) .addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
agent.sendNetworkCapabilities(nc1) agent.sendNetworkCapabilities(nc1)
callback.expectCapabilitiesThat(agent.network) { callback.expectCapabilitiesThat(agent.network!!) {
it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED) it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
} }
// Remove TEMP_NOT_METERED and check that the callback is called appropriately. // Remove TEMP_NOT_METERED and check that the callback is called appropriately.
val nc2 = NetworkCapabilities(agent.nc) val nc2 = NetworkCapabilities(agent.nc)
.removeCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED) .removeCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
agent.sendNetworkCapabilities(nc2) agent.sendNetworkCapabilities(nc2)
callback.expectCapabilitiesThat(agent.network) { callback.expectCapabilitiesThat(agent.network!!) {
!it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED) !it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
}
} }
// tearDown() will unregister the requests and agents // tearDown() will unregister the requests and agents
@@ -838,85 +791,78 @@ class NetworkAgentTest {
// score wins out for a request that matches them both. And the weaker agent will // score wins out for a request that matches them both. And the weaker agent will
// be disconnected after customized linger duration. // be disconnected after customized linger duration.
// Connect the first Network // Request the first Network, with a request that could moved to agentStronger in order to
val name1 = UUID.randomUUID().toString() // make agentWeaker linger later.
val name2 = UUID.randomUUID().toString() val specifierWeaker = UUID.randomUUID().toString()
val (agent1, callback) = createConnectedNetworkAgent(name = name1) val specifierStronger = UUID.randomUUID().toString()
callback.expectAvailableThenValidatedCallbacks(agent1.network!!) val commonCallback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
// Downgrade agent1 to a worse score so that there is no ambiguity when requestNetwork(makeTestNetworkRequest(), commonCallback)
// agent2 connects. val agentWeaker = createNetworkAgent(specifier = specifierWeaker)
agent1.sendNetworkScore(NetworkScore.Builder().setLegacyInt(WORSE_NETWORK_SCORE) agentWeaker.register()
agentWeaker.markConnected()
commonCallback.expectAvailableThenValidatedCallbacks(agentWeaker.network!!)
// Downgrade agentWeaker to a worse score so that there is no ambiguity when
// agentStronger connects.
agentWeaker.sendNetworkScore(NetworkScore.Builder().setLegacyInt(WORSE_NETWORK_SCORE)
.setExiting(true).build()) .setExiting(true).build())
// Verify invalid linger duration cannot be set. // Verify invalid linger duration cannot be set.
assertFailsWith<IllegalArgumentException> { assertFailsWith<IllegalArgumentException> {
agent1.setLingerDuration(Duration.ofMillis(-1)) agentWeaker.setLingerDuration(Duration.ofMillis(-1))
} }
assertFailsWith<IllegalArgumentException> { agent1.setLingerDuration(Duration.ZERO) } assertFailsWith<IllegalArgumentException> { agentWeaker.setLingerDuration(Duration.ZERO) }
assertFailsWith<IllegalArgumentException> { assertFailsWith<IllegalArgumentException> {
agent1.setLingerDuration(Duration.ofMillis(Integer.MIN_VALUE.toLong())) agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MIN_VALUE.toLong()))
} }
assertFailsWith<IllegalArgumentException> { assertFailsWith<IllegalArgumentException> {
agent1.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong() + 1)) agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong() + 1))
} }
assertFailsWith<IllegalArgumentException> { assertFailsWith<IllegalArgumentException> {
agent1.setLingerDuration(Duration.ofMillis( agentWeaker.setLingerDuration(Duration.ofMillis(
NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - 1)) NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - 1))
} }
// Verify valid linger timer can be set, but it should not take effect since the network // Verify valid linger timer can be set, but it should not take effect since the network
// is still needed. // is still needed.
agent1.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong())) agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong()))
callback.assertNoCallback(NO_CALLBACK_TIMEOUT) commonCallback.assertNoCallback(NO_CALLBACK_TIMEOUT)
// Set to the value we want to verify the functionality. // Set to the value we want to verify the functionality.
agent1.setLingerDuration(Duration.ofMillis(NetworkAgent.MIN_LINGER_TIMER_MS.toLong())) agentWeaker.setLingerDuration(Duration.ofMillis(NetworkAgent.MIN_LINGER_TIMER_MS.toLong()))
// Make a listener which can observe agent1 lost later. // Make a listener which can observe agentWeaker lost later.
val callbackWeaker = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) val callbackWeaker = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
registerNetworkCallback(NetworkRequest.Builder() registerNetworkCallback(NetworkRequest.Builder()
.clearCapabilities() .clearCapabilities()
.addTransportType(TRANSPORT_TEST) .addTransportType(TRANSPORT_TEST)
.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name1)) .setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(specifierWeaker))
.build(), callbackWeaker) .build(), callbackWeaker)
callbackWeaker.expectAvailableCallbacks(agent1.network!!) callbackWeaker.expectAvailableCallbacks(agentWeaker.network!!)
// Connect the second agent with a score better than agent1. Verify the callback for // Connect the agentStronger with a score better than agentWeaker. Verify the callback for
// agent1 sees the linger expiry while the callback for both sees the winner. // agentWeaker sees the linger expiry while the callback for both sees the winner.
// Record linger start timestamp prior to send score to prevent possible race, the actual // Record linger start timestamp prior to send score to prevent possible race, the actual
// timestamp should be slightly late than this since the service handles update // timestamp should be slightly late than this since the service handles update
// network score asynchronously. // network score asynchronously.
val lingerStart = SystemClock.elapsedRealtime() val lingerStart = SystemClock.elapsedRealtime()
val agent2 = createNetworkAgent(name = name2) val agentStronger = createNetworkAgent(specifier = specifierStronger)
agent2.register() agentStronger.register()
agent2.markConnected() agentStronger.markConnected()
callback.expectAvailableCallbacks(agent2.network!!) commonCallback.expectAvailableCallbacks(agentStronger.network!!)
callbackWeaker.expectCallback<Losing>(agent1.network!!) callbackWeaker.expectCallback<Losing>(agentWeaker.network!!)
val expectedRemainingLingerDuration = lingerStart + val expectedRemainingLingerDuration = lingerStart +
NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - SystemClock.elapsedRealtime() NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - SystemClock.elapsedRealtime()
// If the available callback is too late. The remaining duration will be reduced. // If the available callback is too late. The remaining duration will be reduced.
assertTrue(expectedRemainingLingerDuration > 0, assertTrue(expectedRemainingLingerDuration > 0,
"expected remaining linger duration is $expectedRemainingLingerDuration") "expected remaining linger duration is $expectedRemainingLingerDuration")
callbackWeaker.assertNoCallback(expectedRemainingLingerDuration) callbackWeaker.assertNoCallback(expectedRemainingLingerDuration)
callbackWeaker.expectCallback<Lost>(agent1.network!!) callbackWeaker.expectCallback<Lost>(agentWeaker.network!!)
} }
@Test @Test
@IgnoreUpTo(Build.VERSION_CODES.R) @IgnoreUpTo(Build.VERSION_CODES.R)
fun testSetSubscriberId() { fun testSetSubscriberId() {
val name = "TEST-AGENT"
val imsi = UUID.randomUUID().toString() val imsi = UUID.randomUUID().toString()
val config = NetworkAgentConfig.Builder().setSubscriberId(imsi).build() val config = NetworkAgentConfig.Builder().setSubscriberId(imsi).build()
val request: NetworkRequest = NetworkRequest.Builder() val (agent, _) = createConnectedNetworkAgent(initialConfig = config)
.clearCapabilities()
.addTransportType(TRANSPORT_TEST)
.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name))
.build()
val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
requestNetwork(request, callback)
val agent = createNetworkAgent(name = name, initialConfig = config)
agent.register()
agent.markConnected()
callback.expectAvailableThenValidatedCallbacks(agent.network!!)
val snapshots = runWithShellPermissionIdentity(ThrowingSupplier { val snapshots = runWithShellPermissionIdentity(ThrowingSupplier {
mCM!!.allNetworkStateSnapshots }, NETWORK_SETTINGS) mCM!!.allNetworkStateSnapshots }, NETWORK_SETTINGS)
val testNetworkSnapshot = snapshots.findLast { it.network == agent.network } val testNetworkSnapshot = snapshots.findLast { it.network == agent.network }