Fix expectCallback does not fail when no callback received
This hides 3 bugs where,
1. In Android S, onNetworkRequested is no longer broadcasted
by ConnectivityService in any condition. However, the test
still passes since assertion does not fail when no callback
received. Ignore the test on S+ devices since the behavior
changed on S or later devices.
2. Test network agent is not registered, but the test still
passes.
3. Test network agent does not fulfill the request that kept
the network up, so the test fails since the test network
is not needed and be torn down.
Test: android.net.NetworkProviderTest on R/S device
Bug: 189074532
Merged-In: I627dcd0f57b6ef4197d16e6c1ec0c53e675ab055
Change-Id: I627dcd0f57b6ef4197d16e6c1ec0c53e675ab055
(cherry-picked from aosp/1731450)
This commit is contained in:
@@ -18,6 +18,7 @@ package android.net
|
|||||||
|
|
||||||
import android.app.Instrumentation
|
import android.app.Instrumentation
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
|
||||||
import android.net.NetworkCapabilities.TRANSPORT_TEST
|
import android.net.NetworkCapabilities.TRANSPORT_TEST
|
||||||
import android.net.NetworkProviderTest.TestNetworkCallback.CallbackEntry.OnUnavailable
|
import android.net.NetworkProviderTest.TestNetworkCallback.CallbackEntry.OnUnavailable
|
||||||
import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequestWithdrawn
|
import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequestWithdrawn
|
||||||
@@ -25,14 +26,18 @@ import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetwo
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.HandlerThread
|
import android.os.HandlerThread
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.util.Log
|
||||||
import androidx.test.InstrumentationRegistry
|
import androidx.test.InstrumentationRegistry
|
||||||
import com.android.net.module.util.ArrayTrackRecord
|
import com.android.net.module.util.ArrayTrackRecord
|
||||||
import com.android.testutils.CompatUtil
|
import com.android.testutils.CompatUtil
|
||||||
|
import com.android.testutils.DevSdkIgnoreRule
|
||||||
|
import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter
|
||||||
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
|
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
|
||||||
import com.android.testutils.DevSdkIgnoreRunner
|
import com.android.testutils.DevSdkIgnoreRunner
|
||||||
import com.android.testutils.isDevSdkInRange
|
import com.android.testutils.isDevSdkInRange
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mockito.doReturn
|
import org.mockito.Mockito.doReturn
|
||||||
@@ -41,6 +46,7 @@ import org.mockito.Mockito.verifyNoMoreInteractions
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
|
import kotlin.test.fail
|
||||||
|
|
||||||
private const val DEFAULT_TIMEOUT_MS = 5000L
|
private const val DEFAULT_TIMEOUT_MS = 5000L
|
||||||
private val instrumentation: Instrumentation
|
private val instrumentation: Instrumentation
|
||||||
@@ -51,6 +57,8 @@ private val PROVIDER_NAME = "NetworkProviderTest"
|
|||||||
@RunWith(DevSdkIgnoreRunner::class)
|
@RunWith(DevSdkIgnoreRunner::class)
|
||||||
@IgnoreUpTo(Build.VERSION_CODES.Q)
|
@IgnoreUpTo(Build.VERSION_CODES.Q)
|
||||||
class NetworkProviderTest {
|
class NetworkProviderTest {
|
||||||
|
@Rule @JvmField
|
||||||
|
val mIgnoreRule = DevSdkIgnoreRule()
|
||||||
private val mCm = context.getSystemService(ConnectivityManager::class.java)
|
private val mCm = context.getSystemService(ConnectivityManager::class.java)
|
||||||
private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread")
|
private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread")
|
||||||
|
|
||||||
@@ -68,6 +76,7 @@ class NetworkProviderTest {
|
|||||||
|
|
||||||
private class TestNetworkProvider(context: Context, looper: Looper) :
|
private class TestNetworkProvider(context: Context, looper: Looper) :
|
||||||
NetworkProvider(context, looper, PROVIDER_NAME) {
|
NetworkProvider(context, looper, PROVIDER_NAME) {
|
||||||
|
private val TAG = this::class.simpleName
|
||||||
private val seenEvents = ArrayTrackRecord<CallbackEntry>().newReadHead()
|
private val seenEvents = ArrayTrackRecord<CallbackEntry>().newReadHead()
|
||||||
|
|
||||||
sealed class CallbackEntry {
|
sealed class CallbackEntry {
|
||||||
@@ -80,22 +89,30 @@ class NetworkProviderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onNetworkRequested(request: NetworkRequest, score: Int, id: Int) {
|
override fun onNetworkRequested(request: NetworkRequest, score: Int, id: Int) {
|
||||||
|
Log.d(TAG, "onNetworkRequested $request, $score, $id")
|
||||||
seenEvents.add(OnNetworkRequested(request, score, id))
|
seenEvents.add(OnNetworkRequested(request, score, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNetworkRequestWithdrawn(request: NetworkRequest) {
|
override fun onNetworkRequestWithdrawn(request: NetworkRequest) {
|
||||||
|
Log.d(TAG, "onNetworkRequestWithdrawn $request")
|
||||||
seenEvents.add(OnNetworkRequestWithdrawn(request))
|
seenEvents.add(OnNetworkRequestWithdrawn(request))
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T : CallbackEntry> expectCallback(
|
inline fun <reified T : CallbackEntry> eventuallyExpectCallbackThat(
|
||||||
crossinline predicate: (T) -> Boolean
|
crossinline predicate: (T) -> Boolean
|
||||||
) = seenEvents.poll(DEFAULT_TIMEOUT_MS) { it is T && predicate(it) }
|
) = seenEvents.poll(DEFAULT_TIMEOUT_MS) { it is T && predicate(it) }
|
||||||
|
?: fail("Did not receive callback after ${DEFAULT_TIMEOUT_MS}ms")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createNetworkProvider(ctx: Context = context): TestNetworkProvider {
|
private fun createNetworkProvider(ctx: Context = context): TestNetworkProvider {
|
||||||
return TestNetworkProvider(ctx, mHandlerThread.looper)
|
return TestNetworkProvider(ctx, mHandlerThread.looper)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// might have ability to setup, and expects {@link NetworkOfferCallback#onNetworkNeeded}.
|
||||||
|
@IgnoreAfter(Build.VERSION_CODES.R)
|
||||||
@Test
|
@Test
|
||||||
fun testOnNetworkRequested() {
|
fun testOnNetworkRequested() {
|
||||||
val provider = createNetworkProvider()
|
val provider = createNetworkProvider()
|
||||||
@@ -105,13 +122,15 @@ class NetworkProviderTest {
|
|||||||
|
|
||||||
val specifier = CompatUtil.makeTestNetworkSpecifier(
|
val specifier = CompatUtil.makeTestNetworkSpecifier(
|
||||||
UUID.randomUUID().toString())
|
UUID.randomUUID().toString())
|
||||||
|
// Test network is not allowed to be trusted.
|
||||||
val nr: NetworkRequest = NetworkRequest.Builder()
|
val nr: NetworkRequest = NetworkRequest.Builder()
|
||||||
.addTransportType(TRANSPORT_TEST)
|
.addTransportType(TRANSPORT_TEST)
|
||||||
|
.removeCapability(NET_CAPABILITY_TRUSTED)
|
||||||
.setNetworkSpecifier(specifier)
|
.setNetworkSpecifier(specifier)
|
||||||
.build()
|
.build()
|
||||||
val cb = ConnectivityManager.NetworkCallback()
|
val cb = ConnectivityManager.NetworkCallback()
|
||||||
mCm.requestNetwork(nr, cb)
|
mCm.requestNetwork(nr, cb)
|
||||||
provider.expectCallback<OnNetworkRequested>() { callback ->
|
provider.eventuallyExpectCallbackThat<OnNetworkRequested>() { callback ->
|
||||||
callback.request.getNetworkSpecifier() == specifier &&
|
callback.request.getNetworkSpecifier() == specifier &&
|
||||||
callback.request.hasTransport(TRANSPORT_TEST)
|
callback.request.hasTransport(TRANSPORT_TEST)
|
||||||
}
|
}
|
||||||
@@ -131,22 +150,24 @@ class NetworkProviderTest {
|
|||||||
val config = NetworkAgentConfig.Builder().build()
|
val config = NetworkAgentConfig.Builder().build()
|
||||||
val agent = object : NetworkAgent(context, mHandlerThread.looper, "TestAgent", nc, lp,
|
val agent = object : NetworkAgent(context, mHandlerThread.looper, "TestAgent", nc, lp,
|
||||||
initialScore, config, provider) {}
|
initialScore, config, provider) {}
|
||||||
|
agent.register()
|
||||||
|
agent.markConnected()
|
||||||
|
|
||||||
provider.expectCallback<OnNetworkRequested>() { callback ->
|
provider.eventuallyExpectCallbackThat<OnNetworkRequested>() { callback ->
|
||||||
callback.request.getNetworkSpecifier() == specifier &&
|
callback.request.getNetworkSpecifier() == specifier &&
|
||||||
callback.score == initialScore &&
|
callback.score == initialScore &&
|
||||||
callback.id == agent.providerId
|
callback.id == agent.providerId
|
||||||
}
|
}
|
||||||
|
|
||||||
agent.sendNetworkScore(updatedScore)
|
agent.sendNetworkScore(updatedScore)
|
||||||
provider.expectCallback<OnNetworkRequested>() { callback ->
|
provider.eventuallyExpectCallbackThat<OnNetworkRequested>() { callback ->
|
||||||
callback.request.getNetworkSpecifier() == specifier &&
|
callback.request.getNetworkSpecifier() == specifier &&
|
||||||
callback.score == updatedScore &&
|
callback.score == updatedScore &&
|
||||||
callback.id == agent.providerId
|
callback.id == agent.providerId
|
||||||
}
|
}
|
||||||
|
|
||||||
mCm.unregisterNetworkCallback(cb)
|
mCm.unregisterNetworkCallback(cb)
|
||||||
provider.expectCallback<OnNetworkRequestWithdrawn>() { callback ->
|
provider.eventuallyExpectCallbackThat<OnNetworkRequestWithdrawn>() { callback ->
|
||||||
callback.request.getNetworkSpecifier() == specifier &&
|
callback.request.getNetworkSpecifier() == specifier &&
|
||||||
callback.request.hasTransport(TRANSPORT_TEST)
|
callback.request.hasTransport(TRANSPORT_TEST)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user