diff options
author | Chalard Jean <jchalard@google.com> | 2019-07-03 12:31:05 +0900 |
---|---|---|
committer | Chalard Jean <jchalard@google.com> | 2019-10-07 13:00:50 +0900 |
commit | 3c9f687c97393a15d238a3272f62c595052e6b2e (patch) | |
tree | 122b498b674cb78cd3e7e8db52bbd83ca75cacb1 | |
parent | acbf27603a53f50c461a3d7eb06901c3fcb1545c (diff) |
Add tests for TestableNetworkCallback
Test: this
Change-Id: I47b8f7c7584df0735ff9f46bee7ef10ec58e68c6
5 files changed, 363 insertions, 36 deletions
diff --git a/tests/lib/src/com/android/testutils/ConcurrentIntepreter.kt b/tests/lib/src/com/android/testutils/ConcurrentIntepreter.kt index 7796dcd..25b1e0f 100644 --- a/tests/lib/src/com/android/testutils/ConcurrentIntepreter.kt +++ b/tests/lib/src/com/android/testutils/ConcurrentIntepreter.kt @@ -4,6 +4,7 @@ import android.os.SystemClock import java.util.concurrent.CyclicBarrier import kotlin.system.measureTimeMillis import kotlin.test.assertEquals +import kotlin.test.assertFails import kotlin.test.assertNull import kotlin.test.assertTrue @@ -64,7 +65,15 @@ open class ConcurrentIntepreter<T>( // Spins as many threads as needed by the test spec and interpret each program concurrently, // having all threads waiting on a CyclicBarrier after each line. - fun interpretTestSpec(spec: String, initial: T, threadTransform: (T) -> T = { it }) { + // |lineShift| says how many lines after the call the spec starts. This is used for error + // reporting. Unfortunately AFAICT there is no way to get the line of an argument rather + // than the line at which the expression starts. + fun interpretTestSpec( + spec: String, + initial: T, + lineShift: Int = 0, + threadTransform: (T) -> T = { it } + ) { // For nice stack traces val callSite = getCallingMethod() val lines = spec.trim().trim('\n').split("\n").map { it.split("|") } @@ -91,7 +100,8 @@ open class ConcurrentIntepreter<T>( // testing. Instead, catch the exception, cancel other threads, and report // nicely. Catch throwable because fail() is AssertionError, which inherits // from Error. - crash = InterpretException(threadIndex, it, callSite.lineNumber + lineNum, + crash = InterpretException(threadIndex, it, + callSite.lineNumber + lineNum + lineShift, callSite.className, callSite.methodName, callSite.fileName, e) } barrier.await() @@ -147,6 +157,9 @@ private fun <T> getDefaultInstructions() = listOf<InterpretMatcher<T>>( // Interpret sleep. Optional argument for the count, in INTERPRET_TIME_UNIT units. Regex("""sleep(\((\d+)\))?""") to { i, t, r -> SystemClock.sleep(if (r.strArg(2).isEmpty()) i.interpretTimeUnit else r.timeArg(2)) + }, + Regex("""(.*)\s*fails""") to { i, t, r -> + assertFails { i.interpret(r.strArg(1), t) } } ) diff --git a/tests/lib/src/com/android/testutils/TestableNetworkCallback.kt b/tests/lib/src/com/android/testutils/TestableNetworkCallback.kt index 1cc1168..bbb279e 100644 --- a/tests/lib/src/com/android/testutils/TestableNetworkCallback.kt +++ b/tests/lib/src/com/android/testutils/TestableNetworkCallback.kt @@ -21,11 +21,15 @@ import android.net.LinkProperties import android.net.Network import android.net.NetworkCapabilities import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED -import com.android.testutils.RecorderCallback.CallbackRecord.Available -import com.android.testutils.RecorderCallback.CallbackRecord.BlockedStatus -import com.android.testutils.RecorderCallback.CallbackRecord.CapabilitiesChanged -import com.android.testutils.RecorderCallback.CallbackRecord.LinkPropertiesChanged -import com.android.testutils.RecorderCallback.CallbackRecord.Lost +import com.android.testutils.RecorderCallback.CallbackEntry.Available +import com.android.testutils.RecorderCallback.CallbackEntry.BlockedStatus +import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged +import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged +import com.android.testutils.RecorderCallback.CallbackEntry.Losing +import com.android.testutils.RecorderCallback.CallbackEntry.Lost +import com.android.testutils.RecorderCallback.CallbackEntry.Resumed +import com.android.testutils.RecorderCallback.CallbackEntry.Suspended +import com.android.testutils.RecorderCallback.CallbackEntry.Unavailable import kotlin.reflect.KClass import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -35,38 +39,43 @@ object NULL_NETWORK : Network(-1) private val Int.capabilityName get() = NetworkCapabilities.capabilityNameOf(this) -open class RecorderCallback : NetworkCallback() { - sealed class CallbackRecord { +open class RecorderCallback private constructor( + private val backingRecord: ArrayTrackRecord<CallbackEntry> +) : NetworkCallback() { + public constructor() : this(ArrayTrackRecord()) + protected constructor(src: RecorderCallback?): this(src?.backingRecord ?: ArrayTrackRecord()) + + sealed class CallbackEntry { // To get equals(), hashcode(), componentN() etc for free, the child classes of // this class are data classes. But while data classes can inherit from other classes, // they may only have visible members in the constructors, so they couldn't declare - // a constructor with a non-val arg to pass to CallbackRecord. Instead, force all + // a constructor with a non-val arg to pass to CallbackEntry. Instead, force all // subclasses to implement a `network' property, which can be done in a data class // constructor by specifying override. abstract val network: Network - data class Available(override val network: Network) : CallbackRecord() + data class Available(override val network: Network) : CallbackEntry() data class CapabilitiesChanged( override val network: Network, val caps: NetworkCapabilities - ) : CallbackRecord() + ) : CallbackEntry() data class LinkPropertiesChanged( override val network: Network, val lp: LinkProperties - ) : CallbackRecord() - data class Suspended(override val network: Network) : CallbackRecord() - data class Resumed(override val network: Network) : CallbackRecord() - data class Losing(override val network: Network, val maxMsToLive: Int) : CallbackRecord() - data class Lost(override val network: Network) : CallbackRecord() + ) : CallbackEntry() + data class Suspended(override val network: Network) : CallbackEntry() + data class Resumed(override val network: Network) : CallbackEntry() + data class Losing(override val network: Network, val maxMsToLive: Int) : CallbackEntry() + data class Lost(override val network: Network) : CallbackEntry() data class Unavailable private constructor( override val network: Network - ) : CallbackRecord() { + ) : CallbackEntry() { constructor() : this(NULL_NETWORK) } data class BlockedStatus( override val network: Network, val blocked: Boolean - ) : CallbackRecord() + ) : CallbackEntry() // Convenience constants for expecting a type companion object { @@ -91,12 +100,15 @@ open class RecorderCallback : NetworkCallback() { } } - protected val history = ArrayTrackRecord<CallbackRecord>().newReadHead() + protected val history = backingRecord.newReadHead() override fun onAvailable(network: Network) { history.add(Available(network)) } + // PreCheck is not used in the tests today. For backward compatibility with existing tests that + // expect the callbacks not to record this, do not listen to PreCheck here. + override fun onCapabilitiesChanged(network: Network, caps: NetworkCapabilities) { history.add(CapabilitiesChanged(network, caps)) } @@ -110,39 +122,46 @@ open class RecorderCallback : NetworkCallback() { } override fun onNetworkSuspended(network: Network) { - history.add(CallbackRecord.Suspended(network)) + history.add(Suspended(network)) } override fun onNetworkResumed(network: Network) { - history.add(CallbackRecord.Resumed(network)) + history.add(Resumed(network)) } override fun onLosing(network: Network, maxMsToLive: Int) { - history.add(CallbackRecord.Losing(network, maxMsToLive)) + history.add(Losing(network, maxMsToLive)) } override fun onLost(network: Network) { - history.add(CallbackRecord.Lost(network)) + history.add(Lost(network)) } override fun onUnavailable() { - history.add(CallbackRecord.Unavailable()) + history.add(Unavailable()) } } -typealias CallbackType = KClass<out RecorderCallback.CallbackRecord> -const val DEFAULT_TIMEOUT = 200L // ms +private const val DEFAULT_TIMEOUT = 200L // ms + +open class TestableNetworkCallback private constructor( + src: TestableNetworkCallback?, + val defaultTimeoutMs: Long = DEFAULT_TIMEOUT +) : RecorderCallback(src) { + @JvmOverloads + constructor(timeoutMs: Long = DEFAULT_TIMEOUT): this(null, timeoutMs) + + fun createLinkedCopy() = TestableNetworkCallback(this, defaultTimeoutMs) -open class TestableNetworkCallback(val defaultTimeoutMs: Long = DEFAULT_TIMEOUT) - : RecorderCallback() { - // The last available network. Null if the last available network was lost since. + // The last available network, or null if any network was lost since the last call to + // onAvailable. TODO : fix this by fixing the tests that rely on this behavior val lastAvailableNetwork: Network? get() = when (val it = history.lastOrNull { it is Available || it is Lost }) { is Available -> it.network else -> null } - fun pollForNextCallback(timeoutMs: Long = defaultTimeoutMs): CallbackRecord { + fun pollForNextCallback(timeoutMs: Long = defaultTimeoutMs): CallbackEntry { return history.poll(timeoutMs) ?: fail("Did not receive callback after ${timeoutMs}ms") } @@ -153,7 +172,7 @@ open class TestableNetworkCallback(val defaultTimeoutMs: Long = DEFAULT_TIMEOUT) if (null != cb) fail("Expected no callback but got $cb") } - inline fun <reified T : CallbackRecord> expectCallback( + inline fun <reified T : CallbackEntry> expectCallback( network: Network, timeoutMs: Long = defaultTimeoutMs ): T = pollForNextCallback(timeoutMs).let { @@ -166,7 +185,7 @@ open class TestableNetworkCallback(val defaultTimeoutMs: Long = DEFAULT_TIMEOUT) fun expectCallbackThat( timeoutMs: Long = defaultTimeoutMs, - valid: (CallbackRecord) -> Boolean + valid: (CallbackEntry) -> Boolean ) = pollForNextCallback(timeoutMs).also { assertTrue(valid(it), "Unexpected callback : $it") } fun expectCapabilitiesThat( @@ -209,7 +228,7 @@ open class TestableNetworkCallback(val defaultTimeoutMs: Long = DEFAULT_TIMEOUT) ) { expectCallback<Available>(net, tmt) if (suspended) { - expectCallback<CallbackRecord.Suspended>(net, tmt) + expectCallback<CallbackEntry.Suspended>(net, tmt) } expectCapabilitiesThat(net, tmt) { validated == it.hasCapability(NET_CAPABILITY_VALIDATED) } expectCallback<LinkPropertiesChanged>(net, tmt) @@ -257,7 +276,7 @@ open class TestableNetworkCallback(val defaultTimeoutMs: Long = DEFAULT_TIMEOUT) } @JvmOverloads - open fun <T : CallbackRecord> expectCallback( + open fun <T : CallbackEntry> expectCallback( type: KClass<T>, n: HasNetwork?, timeoutMs: Long = defaultTimeoutMs diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp index 3410d0e..03bcf95 100644 --- a/tests/unit/Android.bp +++ b/tests/unit/Android.bp @@ -22,6 +22,7 @@ android_test { resource_dirs: ["res"], static_libs: [ "androidx.test.rules", + "kotlin-reflect", "mockito-target-extended-minus-junit4", "net-tests-utils", "NetworkStackApiCurrentLib", diff --git a/tests/unit/src/android/net/testutils/TestableNetworkCallbackTest.kt b/tests/unit/src/android/net/testutils/TestableNetworkCallbackTest.kt new file mode 100644 index 0000000..4e4d25a --- /dev/null +++ b/tests/unit/src/android/net/testutils/TestableNetworkCallbackTest.kt @@ -0,0 +1,293 @@ +package android.net.testutils + +import android.net.LinkAddress +import android.net.LinkProperties +import android.net.Network +import android.net.NetworkCapabilities +import com.android.testutils.ConcurrentIntepreter +import com.android.testutils.InterpretMatcher +import com.android.testutils.RecorderCallback.CallbackEntry +import com.android.testutils.RecorderCallback.CallbackEntry.Available +import com.android.testutils.RecorderCallback.CallbackEntry.BlockedStatus +import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged +import com.android.testutils.TestableNetworkCallback +import com.android.testutils.intArg +import com.android.testutils.strArg +import com.android.testutils.timeArg +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import kotlin.reflect.KClass +import kotlin.test.assertEquals +import kotlin.test.assertFails +import kotlin.test.assertNull +import kotlin.test.assertTrue +import kotlin.test.fail + +const val SHORT_TIMEOUT_MS = 20L +const val DEFAULT_LINGER_DELAY_MS = 30000 +const val NOT_METERED = NetworkCapabilities.NET_CAPABILITY_NOT_METERED +const val WIFI = NetworkCapabilities.TRANSPORT_WIFI +const val CELLULAR = NetworkCapabilities.TRANSPORT_CELLULAR +const val TEST_INTERFACE_NAME = "testInterfaceName" + +@RunWith(JUnit4::class) +class TestableNetworkCallbackTest { + private lateinit var mCallback: TestableNetworkCallback + + private fun makeHasNetwork(netId: Int) = object : TestableNetworkCallback.HasNetwork { + override val network: Network = Network(netId) + } + + @Before + fun setUp() { + mCallback = TestableNetworkCallback() + } + + @Test + fun testLastAvailableNetwork() { + // Make sure there is no last available network at first, then the last available network + // is returned after onAvailable is called. + val net2097 = Network(2097) + assertNull(mCallback.lastAvailableNetwork) + mCallback.onAvailable(net2097) + assertEquals(mCallback.lastAvailableNetwork, net2097) + + // Make sure calling onCapsChanged/onLinkPropertiesChanged don't affect the last available + // network. + mCallback.onCapabilitiesChanged(net2097, NetworkCapabilities()) + mCallback.onLinkPropertiesChanged(net2097, LinkProperties()) + assertEquals(mCallback.lastAvailableNetwork, net2097) + + // Make sure onLost clears the last available network. + mCallback.onLost(net2097) + assertNull(mCallback.lastAvailableNetwork) + + // Do the same but with a different network after onLost : make sure the last available + // network is the new one, not the original one. + val net2098 = Network(2098) + mCallback.onAvailable(net2098) + mCallback.onCapabilitiesChanged(net2098, NetworkCapabilities()) + mCallback.onLinkPropertiesChanged(net2098, LinkProperties()) + assertEquals(mCallback.lastAvailableNetwork, net2098) + + // Make sure onAvailable changes the last available network even if onLost was not called. + val net2099 = Network(2099) + mCallback.onAvailable(net2099) + assertEquals(mCallback.lastAvailableNetwork, net2099) + + // For legacy reasons, lastAvailableNetwork is null as soon as any is lost, not necessarily + // the last available one. Check that behavior. + mCallback.onLost(net2098) + assertNull(mCallback.lastAvailableNetwork) + + // Make sure that losing the really last available one still results in null. + mCallback.onLost(net2099) + assertNull(mCallback.lastAvailableNetwork) + + // Make sure multiple onAvailable in a row then onLost still results in null. + mCallback.onAvailable(net2097) + mCallback.onAvailable(net2098) + mCallback.onAvailable(net2099) + mCallback.onLost(net2097) + assertNull(mCallback.lastAvailableNetwork) + } + + @Test + fun testAssertNoCallback() { + mCallback.assertNoCallback(SHORT_TIMEOUT_MS) + mCallback.onAvailable(Network(100)) + assertFails { mCallback.assertNoCallback(SHORT_TIMEOUT_MS) } + } + + @Test + fun testCapabilitiesWithAndWithout() { + val net = Network(101) + val matcher = makeHasNetwork(101) + val meteredNc = NetworkCapabilities() + val unmeteredNc = NetworkCapabilities().addCapability(NOT_METERED) + // Check that expecting caps (with or without) fails when no callback has been received. + assertFails { mCallback.expectCapabilitiesWith(NOT_METERED, matcher, SHORT_TIMEOUT_MS) } + assertFails { mCallback.expectCapabilitiesWithout(NOT_METERED, matcher, SHORT_TIMEOUT_MS) } + + // Add NOT_METERED and check that With succeeds and Without fails. + mCallback.onCapabilitiesChanged(net, unmeteredNc) + mCallback.expectCapabilitiesWith(NOT_METERED, matcher) + mCallback.onCapabilitiesChanged(net, unmeteredNc) + assertFails { mCallback.expectCapabilitiesWithout(NOT_METERED, matcher, SHORT_TIMEOUT_MS) } + + // Don't add NOT_METERED and check that With fails and Without succeeds. + mCallback.onCapabilitiesChanged(net, meteredNc) + assertFails { mCallback.expectCapabilitiesWith(NOT_METERED, matcher, SHORT_TIMEOUT_MS) } + mCallback.onCapabilitiesChanged(net, meteredNc) + mCallback.expectCapabilitiesWithout(NOT_METERED, matcher) + } + + @Test + fun testExpectCallbackThat() { + val net = Network(193) + val netCaps = NetworkCapabilities().addTransportType(CELLULAR) + // Check that expecting callbackThat anything fails when no callback has been received. + assertFails { mCallback.expectCallbackThat(SHORT_TIMEOUT_MS) { true } } + + // Basic test for true and false + mCallback.onAvailable(net) + mCallback.expectCallbackThat { true } + mCallback.onAvailable(net) + assertFails { mCallback.expectCallbackThat(SHORT_TIMEOUT_MS) { false } } + + // Try a positive and a negative case + mCallback.onBlockedStatusChanged(net, true) + mCallback.expectCallbackThat { cb -> cb is BlockedStatus && cb.blocked } + mCallback.onCapabilitiesChanged(net, netCaps) + assertFails { mCallback.expectCallbackThat(SHORT_TIMEOUT_MS) { cb -> + cb is CapabilitiesChanged && cb.caps.hasTransport(WIFI) + } } + } + + @Test + fun testCapabilitiesThat() { + val net = Network(101) + val netCaps = NetworkCapabilities().addCapability(NOT_METERED).addTransportType(WIFI) + // Check that expecting capabilitiesThat anything fails when no callback has been received. + assertFails { mCallback.expectCapabilitiesThat(net, SHORT_TIMEOUT_MS) { true } } + + // Basic test for true and false + mCallback.onCapabilitiesChanged(net, netCaps) + mCallback.expectCapabilitiesThat(net) { true } + mCallback.onCapabilitiesChanged(net, netCaps) + assertFails { mCallback.expectCapabilitiesThat(net, SHORT_TIMEOUT_MS) { false } } + + // Try a positive and a negative case + mCallback.onCapabilitiesChanged(net, netCaps) + mCallback.expectCapabilitiesThat(net) { caps -> + caps.hasCapability(NOT_METERED) && + caps.hasTransport(WIFI) && + !caps.hasTransport(CELLULAR) + } + mCallback.onCapabilitiesChanged(net, netCaps) + assertFails { mCallback.expectCapabilitiesThat(net, SHORT_TIMEOUT_MS) { caps -> + caps.hasTransport(CELLULAR) + } } + + // Try a matching callback on the wrong network + mCallback.onCapabilitiesChanged(net, netCaps) + assertFails { mCallback.expectCapabilitiesThat(Network(100), SHORT_TIMEOUT_MS) { true } } + } + + @Test + fun testLinkPropertiesThat() { + val net = Network(112) + val linkAddress = LinkAddress("fe80::ace:d00d/64") + val mtu = 1984 + val linkProps = LinkProperties().apply { + this.mtu = mtu + interfaceName = TEST_INTERFACE_NAME + addLinkAddress(linkAddress) + } + + // Check that expecting linkPropsThat anything fails when no callback has been received. + assertFails { mCallback.expectLinkPropertiesThat(net, SHORT_TIMEOUT_MS) { true } } + + // Basic test for true and false + mCallback.onLinkPropertiesChanged(net, linkProps) + mCallback.expectLinkPropertiesThat(net) { true } + mCallback.onLinkPropertiesChanged(net, linkProps) + assertFails { mCallback.expectLinkPropertiesThat(net, SHORT_TIMEOUT_MS) { false } } + + // Try a positive and negative case + mCallback.onLinkPropertiesChanged(net, linkProps) + mCallback.expectLinkPropertiesThat(net) { lp -> + lp.interfaceName == TEST_INTERFACE_NAME && + lp.linkAddresses.contains(linkAddress) && + lp.mtu == mtu + } + mCallback.onLinkPropertiesChanged(net, linkProps) + assertFails { mCallback.expectLinkPropertiesThat(net, SHORT_TIMEOUT_MS) { lp -> + lp.interfaceName != TEST_INTERFACE_NAME + } } + + // Try a matching callback on the wrong network + mCallback.onLinkPropertiesChanged(net, linkProps) + assertFails { mCallback.expectLinkPropertiesThat(Network(114), SHORT_TIMEOUT_MS) { lp -> + lp.interfaceName == TEST_INTERFACE_NAME + } } + } + + @Test + fun testExpectCallback() { + val net = Network(103) + // Test expectCallback fails when nothing was sent. + assertFails { mCallback.expectCallback<BlockedStatus>(net, SHORT_TIMEOUT_MS) } + + // Test onAvailable is seen and can be expected + mCallback.onAvailable(net) + mCallback.expectCallback<Available>(net, SHORT_TIMEOUT_MS) + + // Test onAvailable won't return calls with a different network + mCallback.onAvailable(Network(106)) + assertFails { mCallback.expectCallback<Available>(net, SHORT_TIMEOUT_MS) } + + // Test onAvailable won't return calls with a different callback + mCallback.onAvailable(net) + assertFails { mCallback.expectCallback<BlockedStatus>(net, SHORT_TIMEOUT_MS) } + } + + @Test + fun testPollForNextCallback() { + assertFails { mCallback.pollForNextCallback(SHORT_TIMEOUT_MS) } + TNCInterpreter.interpretTestSpec(initial = mCallback, lineShift = 1, + threadTransform = { cb -> cb.createLinkedCopy() }, spec = """ + sleep; onAvailable(133) | poll(2) = Available(133) time 1..4 + | poll(1) fails + onCapabilitiesChanged(108) | poll(1) = CapabilitiesChanged(108) time 0..3 + onBlockedStatus(199) | poll(1) = BlockedStatus(199) time 0..3 + """) + } +} + +private object TNCInterpreter : ConcurrentIntepreter<TestableNetworkCallback>(interpretTable) + +val EntryList = CallbackEntry::class.sealedSubclasses.map { it.simpleName }.joinToString("|") +private fun callbackEntryFromString(name: String): KClass<out CallbackEntry> { + return CallbackEntry::class.sealedSubclasses.first { it.simpleName == name } +} + +private val interpretTable = listOf<InterpretMatcher<TestableNetworkCallback>>( + // Interpret "Available(xx)" as "call to onAvailable with netId xx", and likewise for + // all callback types. This is implemented above by enumerating the subclasses of + // CallbackEntry and reading their simpleName. + Regex("""(.*)\s+=\s+($EntryList)\((\d+)\)""") to { i, cb, t -> + val record = i.interpret(t.strArg(1), cb) + assertTrue(callbackEntryFromString(t.strArg(2)).isInstance(record)) + // Strictly speaking testing for is CallbackEntry is useless as it's been tested above + // but the compiler can't figure things out from the isInstance call. It does understand + // from the assertTrue(is CallbackEntry) that this is true, which allows to access + // the 'network' member below. + assertTrue(record is CallbackEntry) + assertEquals(record.network.netId, t.intArg(3)) + }, + // Interpret "onAvailable(xx)" as calling "onAvailable" with a netId of xx, and likewise for + // all callback types. NetworkCapabilities and LinkProperties just get an empty object + // as their argument. Losing gets the default linger timer. Blocked gets false. + Regex("""on($EntryList)\((\d+)\)""") to { i, cb, t -> + val net = Network(t.intArg(2)) + when (t.strArg(1)) { + "Available" -> cb.onAvailable(net) + // PreCheck not used in tests. Add it here if it becomes useful. + "CapabilitiesChanged" -> cb.onCapabilitiesChanged(net, NetworkCapabilities()) + "LinkPropertiesChanged" -> cb.onLinkPropertiesChanged(net, LinkProperties()) + "Suspended" -> cb.onNetworkSuspended(net) + "Resumed" -> cb.onNetworkResumed(net) + "Losing" -> cb.onLosing(net, DEFAULT_LINGER_DELAY_MS) + "Lost" -> cb.onLost(net) + "Unavailable" -> cb.onUnavailable() + "BlockedStatus" -> cb.onBlockedStatusChanged(net, false) + else -> fail("Unknown callback type") + } + }, + Regex("""poll\((\d+)\)""") to { i, cb, t -> + cb.pollForNextCallback(t.timeArg(1)) + } +) diff --git a/tests/unit/src/android/net/testutils/TrackRecordTest.kt b/tests/unit/src/android/net/testutils/TrackRecordTest.kt index 4fe8d37..995d537 100644 --- a/tests/unit/src/android/net/testutils/TrackRecordTest.kt +++ b/tests/unit/src/android/net/testutils/TrackRecordTest.kt @@ -352,7 +352,8 @@ class TrackRecordTest { private object TRTInterpreter : ConcurrentIntepreter<TrackRecord<Int>>(interpretTable) { fun interpretTestSpec(spec: String, useReadHeads: Boolean) = if (useReadHeads) { - interpretTestSpec(spec, ArrayTrackRecord(), { (it as ArrayTrackRecord).newReadHead() }) + interpretTestSpec(spec, initial = ArrayTrackRecord(), + threadTransform = { (it as ArrayTrackRecord).newReadHead() }) } else { interpretTestSpec(spec, ArrayTrackRecord()) } |