1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.android.testutils
18
19 import android.net.ConnectivityManager.NetworkCallback
20 import android.net.LinkProperties
21 import android.net.LocalNetworkInfo
22 import android.net.Network
23 import android.net.NetworkCapabilities
24 import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
25 import android.util.Log
26 import com.android.net.module.util.ArrayTrackRecord
27 import com.android.testutils.RecorderCallback.CallbackEntry.Available
28 import com.android.testutils.RecorderCallback.CallbackEntry.BlockedStatus
29 import com.android.testutils.RecorderCallback.CallbackEntry.BlockedStatusInt
30 import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
31 import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
32 import com.android.testutils.RecorderCallback.CallbackEntry.LocalInfoChanged
33 import com.android.testutils.RecorderCallback.CallbackEntry.Losing
34 import com.android.testutils.RecorderCallback.CallbackEntry.Lost
35 import com.android.testutils.RecorderCallback.CallbackEntry.Resumed
36 import com.android.testutils.RecorderCallback.CallbackEntry.Suspended
37 import com.android.testutils.RecorderCallback.CallbackEntry.Unavailable
38 import kotlin.reflect.KClass
39 import kotlin.test.assertEquals
40 import kotlin.test.assertNotNull
41 import kotlin.test.fail
42
43 object NULL_NETWORK : Network(-1)
44 object ANY_NETWORK : Network(-2)
anyNetworknull45 fun anyNetwork() = ANY_NETWORK
46
47 open class RecorderCallback private constructor(
48 private val backingRecord: ArrayTrackRecord<CallbackEntry>
49 ) : NetworkCallback() {
50 public constructor() : this(ArrayTrackRecord())
51 protected constructor(src: RecorderCallback?) : this(src?.backingRecord ?: ArrayTrackRecord())
52
53 private val TAG = this::class.simpleName
54
55 sealed class CallbackEntry {
56 // To get equals(), hashcode(), componentN() etc for free, the child classes of
57 // this class are data classes. But while data classes can inherit from other classes,
58 // they may only have visible members in the constructors, so they couldn't declare
59 // a constructor with a non-val arg to pass to CallbackEntry. Instead, force all
60 // subclasses to implement a `network' property, which can be done in a data class
61 // constructor by specifying override.
62 abstract val network: Network
63
64 data class Available(override val network: Network) : CallbackEntry()
65 data class CapabilitiesChanged(
66 override val network: Network,
67 val caps: NetworkCapabilities
68 ) : CallbackEntry()
69 data class LinkPropertiesChanged(
70 override val network: Network,
71 val lp: LinkProperties
72 ) : CallbackEntry()
73 data class LocalInfoChanged(
74 override val network: Network,
75 val info: LocalNetworkInfo
76 ) : CallbackEntry()
77 data class Suspended(override val network: Network) : CallbackEntry()
78 data class Resumed(override val network: Network) : CallbackEntry()
79 data class Losing(override val network: Network, val maxMsToLive: Int) : CallbackEntry()
80 data class Lost(override val network: Network) : CallbackEntry()
81 data class Unavailable private constructor(
82 override val network: Network
83 ) : CallbackEntry() {
84 constructor() : this(NULL_NETWORK)
85 }
86 data class BlockedStatus(
87 override val network: Network,
88 val blocked: Boolean
89 ) : CallbackEntry()
90 data class BlockedStatusInt(
91 override val network: Network,
92 val reason: Int
93 ) : CallbackEntry()
94
95 // Convenience constants for expecting a type
96 companion object {
97 @JvmField
98 val AVAILABLE = Available::class
99 @JvmField
100 val NETWORK_CAPS_UPDATED = CapabilitiesChanged::class
101 @JvmField
102 val LINK_PROPERTIES_CHANGED = LinkPropertiesChanged::class
103 @JvmField
104 val LOCAL_INFO_CHANGED = LocalInfoChanged::class
105 @JvmField
106 val SUSPENDED = Suspended::class
107 @JvmField
108 val RESUMED = Resumed::class
109 @JvmField
110 val LOSING = Losing::class
111 @JvmField
112 val LOST = Lost::class
113 @JvmField
114 val UNAVAILABLE = Unavailable::class
115 @JvmField
116 val BLOCKED_STATUS = BlockedStatus::class
117 @JvmField
118 val BLOCKED_STATUS_INT = BlockedStatusInt::class
119 }
120 }
121
122 val history = backingRecord.newReadHead()
123 val mark get() = history.mark
124
125 override fun onAvailable(network: Network) {
126 Log.d(TAG, "onAvailable $network")
127 history.add(Available(network))
128 }
129
130 // PreCheck is not used in the tests today. For backward compatibility with existing tests that
131 // expect the callbacks not to record this, do not listen to PreCheck here.
132
133 override fun onCapabilitiesChanged(network: Network, caps: NetworkCapabilities) {
134 Log.d(TAG, "onCapabilitiesChanged $network $caps")
135 history.add(CapabilitiesChanged(network, caps))
136 }
137
138 override fun onLinkPropertiesChanged(network: Network, lp: LinkProperties) {
139 Log.d(TAG, "onLinkPropertiesChanged $network $lp")
140 history.add(LinkPropertiesChanged(network, lp))
141 }
142
143 override fun onLocalNetworkInfoChanged(network: Network, info: LocalNetworkInfo) {
144 Log.d(TAG, "onLocalNetworkInfoChanged $network $info")
145 history.add(LocalInfoChanged(network, info))
146 }
147
148 override fun onBlockedStatusChanged(network: Network, blocked: Boolean) {
149 Log.d(TAG, "onBlockedStatusChanged $network $blocked")
150 history.add(BlockedStatus(network, blocked))
151 }
152
153 // Cannot do:
154 // fun onBlockedStatusChanged(network: Network, blocked: Int) {
155 // because on S, that needs to be "override fun", and on R, that cannot be "override fun".
156 override fun onNetworkSuspended(network: Network) {
157 Log.d(TAG, "onNetworkSuspended $network $network")
158 history.add(Suspended(network))
159 }
160
161 override fun onNetworkResumed(network: Network) {
162 Log.d(TAG, "$network onNetworkResumed $network")
163 history.add(Resumed(network))
164 }
165
166 override fun onLosing(network: Network, maxMsToLive: Int) {
167 Log.d(TAG, "onLosing $network $maxMsToLive")
168 history.add(Losing(network, maxMsToLive))
169 }
170
171 override fun onLost(network: Network) {
172 Log.d(TAG, "onLost $network")
173 history.add(Lost(network))
174 }
175
176 override fun onUnavailable() {
177 Log.d(TAG, "onUnavailable")
178 history.add(Unavailable())
179 }
180 }
181
182 private const val DEFAULT_TIMEOUT = 30_000L // ms
183 private const val DEFAULT_NO_CALLBACK_TIMEOUT = 200L // ms
<lambda>null184 private val NOOP = Runnable {}
185
186 /**
187 * See comments on the public constructor below for a description of the arguments.
188 */
189 open class TestableNetworkCallback private constructor(
190 src: TestableNetworkCallback?,
191 val defaultTimeoutMs: Long = DEFAULT_TIMEOUT,
192 val defaultNoCallbackTimeoutMs: Long = DEFAULT_NO_CALLBACK_TIMEOUT,
193 val waiterFunc: Runnable = NOOP // "() -> Unit" would forbid calling with a void func from Java
194 ) : RecorderCallback(src) {
195 /**
196 * Construct a testable network callback.
197 * @param timeoutMs the default timeout for expecting a callback. Default 30 seconds. This
198 * should be long in most cases, because the success case doesn't incur
199 * the wait.
200 * @param noCallbackTimeoutMs the timeout for expecting that no callback is received. Default
201 * 200ms. Because the success case does incur the timeout, this
202 * should be short in most cases, but not so short as to frequently
203 * time out before an incorrect callback is received.
204 * @param waiterFunc a function to use before asserting no callback. For some specific tests,
205 * it is useful to run test-specific code before asserting no callback to
206 * increase the likelihood that a spurious callback is correctly detected.
207 * As an example, a unit test using mock loopers may want to use this to
208 * make sure the loopers are drained before asserting no callback, since
209 * one of them may cause a callback to be called. @see ConnectivityServiceTest
210 * for such an example.
211 */
212 @JvmOverloads
213 constructor(
214 timeoutMs: Long = DEFAULT_TIMEOUT,
215 noCallbackTimeoutMs: Long = DEFAULT_NO_CALLBACK_TIMEOUT,
216 waiterFunc: Runnable = NOOP
217 ) : this(null, timeoutMs, noCallbackTimeoutMs, waiterFunc)
218
createLinkedCopynull219 fun createLinkedCopy() = TestableNetworkCallback(
220 this,
221 defaultTimeoutMs,
222 defaultNoCallbackTimeoutMs,
223 waiterFunc
224 )
225
226 // The last available network, or null if any network was lost since the last call to
227 // onAvailable. TODO : fix this by fixing the tests that rely on this behavior
228 val lastAvailableNetwork: Network?
229 get() = when (val it = history.lastOrNull { it is Available || it is Lost }) {
230 is Available -> it.network
231 else -> null
232 }
233
234 /**
235 * Get the next callback or null if timeout.
236 *
237 * With no argument, this method waits out the default timeout. To wait forever, pass
238 * Long.MAX_VALUE.
239 */
240 @JvmOverloads
<lambda>null241 fun poll(timeoutMs: Long = defaultTimeoutMs, predicate: (CallbackEntry) -> Boolean = { true }) =
242 history.poll(timeoutMs, predicate)
243
244 /*****
245 * expect family of methods.
246 * These methods fetch the next callback and assert it matches the conditions : type,
247 * passed predicate. If no callback is received within the timeout, these methods fail.
248 */
249 @JvmOverloads
expectnull250 fun <T : CallbackEntry> expect(
251 type: KClass<T>,
252 network: Network = ANY_NETWORK,
253 timeoutMs: Long = defaultTimeoutMs,
254 errorMsg: String? = null,
255 test: (T) -> Boolean = { true }
<lambda>null256 ) = expect<CallbackEntry>(network, timeoutMs, errorMsg) {
257 if (type.isInstance(it)) {
258 test(it as T) // Cast can't fail since type.isInstance(it) and type: KClass<T>
259 } else {
260 fail("Expected callback ${type.simpleName}, got $it")
261 }
262 } as T
263
264 @JvmOverloads
expectnull265 fun <T : CallbackEntry> expect(
266 type: KClass<T>,
267 network: HasNetwork,
268 timeoutMs: Long = defaultTimeoutMs,
269 errorMsg: String? = null,
270 test: (T) -> Boolean = { true }
271 ) = expect(type, network.network, timeoutMs, errorMsg, test)
272
273 // Java needs an explicit overload to let it omit arguments in the middle, so define these
274 // here. Note that @JvmOverloads give us the versions without the last arguments too, so
275 // there is no need to explicitly define versions without the test predicate.
276 // Without |network|
277 @JvmOverloads
expectnull278 fun <T : CallbackEntry> expect(
279 type: KClass<T>,
280 timeoutMs: Long,
281 errorMsg: String?,
282 test: (T) -> Boolean = { true }
283 ) = expect(type, ANY_NETWORK, timeoutMs, errorMsg, test)
284
285 // Without |timeout|, in Network and HasNetwork versions
286 @JvmOverloads
expectnull287 fun <T : CallbackEntry> expect(
288 type: KClass<T>,
289 network: Network,
290 errorMsg: String?,
291 test: (T) -> Boolean = { true }
292 ) = expect(type, network, defaultTimeoutMs, errorMsg, test)
293
294 @JvmOverloads
expectnull295 fun <T : CallbackEntry> expect(
296 type: KClass<T>,
297 network: HasNetwork,
298 errorMsg: String?,
299 test: (T) -> Boolean = { true }
300 ) = expect(type, network.network, defaultTimeoutMs, errorMsg, test)
301
302 // Without |errorMsg|, in Network and HasNetwork versions
303 @JvmOverloads
expectnull304 fun <T : CallbackEntry> expect(
305 type: KClass<T>,
306 network: Network,
307 timeoutMs: Long,
308 test: (T) -> Boolean
309 ) = expect(type, network, timeoutMs, null, test)
310
311 @JvmOverloads
312 fun <T : CallbackEntry> expect(
313 type: KClass<T>,
314 network: HasNetwork,
315 timeoutMs: Long,
316 test: (T) -> Boolean
317 ) = expect(type, network.network, timeoutMs, null, test)
318
319 // Without |network| or |timeout|
320 @JvmOverloads
321 fun <T : CallbackEntry> expect(
322 type: KClass<T>,
323 errorMsg: String?,
324 test: (T) -> Boolean = { true }
325 ) = expect(type, ANY_NETWORK, defaultTimeoutMs, errorMsg, test)
326
327 // Without |network| or |errorMsg|
328 @JvmOverloads
expectnull329 fun <T : CallbackEntry> expect(
330 type: KClass<T>,
331 timeoutMs: Long,
332 test: (T) -> Boolean = { true }
333 ) = expect(type, ANY_NETWORK, timeoutMs, null, test)
334
335 // Without |timeout| or |errorMsg|, in Network and HasNetwork versions
336 @JvmOverloads
expectnull337 fun <T : CallbackEntry> expect(
338 type: KClass<T>,
339 network: Network,
340 test: (T) -> Boolean
341 ) = expect(type, network, defaultTimeoutMs, null, test)
342
343 @JvmOverloads
344 fun <T : CallbackEntry> expect(
345 type: KClass<T>,
346 network: HasNetwork,
347 test: (T) -> Boolean
348 ) = expect(type, network.network, defaultTimeoutMs, null, test)
349
350 // Without |network| or |timeout| or |errorMsg|
351 @JvmOverloads
352 fun <T : CallbackEntry> expect(
353 type: KClass<T>,
354 test: (T) -> Boolean
355 ) = expect(type, ANY_NETWORK, defaultTimeoutMs, null, test)
356
357 // Kotlin reified versions. Don't call methods above, or the predicate would need to be noinline
358 inline fun <reified T : CallbackEntry> expect(
359 network: Network = ANY_NETWORK,
360 timeoutMs: Long = defaultTimeoutMs,
361 errorMsg: String? = null,
362 test: (T) -> Boolean = { true }
363 ) = (poll(timeoutMs) ?: failWithErrorReason(errorMsg,
364 "Did not receive ${T::class.simpleName} after ${timeoutMs}ms"))
<lambda>null365 .also {
366 if (it !is T) {
367 failWithErrorReason(
368 errorMsg,
369 "Expected callback ${T::class.simpleName}, got $it"
370 )
371 }
372 if (ANY_NETWORK !== network && it.network != network) {
373 failWithErrorReason(errorMsg, "Expected network $network for callback : $it")
374 }
375 if (!test(it)) {
376 failWithErrorReason(errorMsg, "Callback doesn't match predicate : $it")
377 }
378 } as T
379
380 // "Nothing" is the return type to declare a function never returns a value.
failWithErrorReasonnull381 fun failWithErrorReason(errorMsg: String?, errorReason: String): Nothing {
382 val message = if (errorMsg != null) "$errorMsg : $errorReason" else errorReason
383 fail(message)
384 }
385
expectnull386 inline fun <reified T : CallbackEntry> expect(
387 network: HasNetwork,
388 timeoutMs: Long = defaultTimeoutMs,
389 errorMsg: String? = null,
390 test: (T) -> Boolean = { true }
391 ) = expect(network.network, timeoutMs, errorMsg, test)
392
393 /*****
394 * assertNoCallback family of methods.
395 * These methods make sure that no callback that matches the predicate was received.
396 * If no predicate is given, they make sure that no callback at all was received.
397 * These methods run the waiter func given in the constructor if any.
398 */
399 @JvmOverloads
assertNoCallbacknull400 fun assertNoCallback(
401 timeoutMs: Long = defaultNoCallbackTimeoutMs,
402 valid: (CallbackEntry) -> Boolean = { true }
403 ) {
404 waiterFunc.run()
<lambda>null405 history.poll(timeoutMs) { valid(it) }?.let { fail("Expected no callback but got $it") }
406 }
407
assertNoCallbacknull408 fun assertNoCallback(valid: (CallbackEntry) -> Boolean) =
409 assertNoCallback(defaultNoCallbackTimeoutMs, valid)
410
411 /*****
412 * eventuallyExpect family of methods.
413 * These methods make sure a callback that matches the type/predicate is received eventually.
414 * Any callback of the wrong type, or doesn't match the optional predicate, is ignored.
415 * They fail if no callback matching the predicate is received within the timeout.
416 */
417 inline fun <reified T : CallbackEntry> eventuallyExpect(
418 timeoutMs: Long = defaultTimeoutMs,
419 from: Int = mark,
420 crossinline predicate: (T) -> Boolean = { true }
<lambda>null421 ): T = history.poll(timeoutMs, from) { it is T && predicate(it) }.also {
422 assertNotNull(
423 it,
424 "Callback ${T::class} not received within ${timeoutMs}ms. " +
425 "Got ${history.backtrace()}"
426 )
427 } as T
428
429 @JvmOverloads
eventuallyExpectnull430 fun <T : CallbackEntry> eventuallyExpect(
431 type: KClass<T>,
432 timeoutMs: Long = defaultTimeoutMs,
433 predicate: (cb: T) -> Boolean = { true }
<lambda>null434 ) = history.poll(timeoutMs) { type.java.isInstance(it) && predicate(it as T) }.also {
435 assertNotNull(
436 it,
437 "Callback ${type.java} not received within ${timeoutMs}ms. " +
438 "Got ${history.backtrace()}"
439 )
440 } as T
441
eventuallyExpectnull442 fun <T : CallbackEntry> eventuallyExpect(
443 type: KClass<T>,
444 timeoutMs: Long = defaultTimeoutMs,
445 from: Int = mark,
446 predicate: (cb: T) -> Boolean = { true }
<lambda>null447 ) = history.poll(timeoutMs, from) { type.java.isInstance(it) && predicate(it as T) }.also {
448 assertNotNull(
449 it,
450 "Callback ${type.java} not received within ${timeoutMs}ms. " +
451 "Got ${history.backtrace()}"
452 )
453 } as T
454
455 // Expects onAvailable and the callbacks that follow it. These are:
456 // - onSuspended, iff the network was suspended when the callbacks fire.
457 // - onCapabilitiesChanged.
458 // - onLinkPropertiesChanged.
459 // - onBlockedStatusChanged.
460 //
461 // @param network the network to expect the callbacks on.
462 // @param suspended whether to expect a SUSPENDED callback.
463 // @param validated the expected value of the VALIDATED capability in the
464 // onCapabilitiesChanged callback.
465 // @param tmt how long to wait for the callbacks.
466 @JvmOverloads
expectAvailableCallbacksnull467 fun expectAvailableCallbacks(
468 net: Network,
469 suspended: Boolean = false,
470 validated: Boolean? = true,
471 blocked: Boolean = false,
472 upstream: Network? = null,
473 tmt: Long = defaultTimeoutMs
474 ) {
475 expectAvailableCallbacksCommon(net, suspended, validated, upstream, tmt)
476 expect<BlockedStatus>(net, tmt) { it.blocked == blocked }
477 }
478
479 // For backward compatibility, add a method that allows callers to specify a timeout but
480 // no upstream.
expectAvailableCallbacksnull481 fun expectAvailableCallbacks(
482 net: Network,
483 suspended: Boolean = false,
484 validated: Boolean? = true,
485 blocked: Boolean = false,
486 tmt: Long = defaultTimeoutMs
487 ) = expectAvailableCallbacks(net, suspended, validated, blocked, upstream = null, tmt = tmt)
488
489 fun expectAvailableCallbacks(
490 net: Network,
491 suspended: Boolean,
492 validated: Boolean,
493 blockedReason: Int,
494 upstream: Network? = null,
495 tmt: Long
496 ) {
497 expectAvailableCallbacksCommon(net, suspended, validated, upstream, tmt)
498 expect<BlockedStatusInt>(net) { it.reason == blockedReason }
499 }
500
501 // For backward compatibility, add a method that allows callers to specify a timeout but
502 // no upstream.
expectAvailableCallbacksnull503 fun expectAvailableCallbacks(
504 net: Network,
505 suspended: Boolean = false,
506 validated: Boolean = true,
507 blockedReason: Int,
508 tmt: Long = defaultTimeoutMs
509 ) = expectAvailableCallbacks(net, suspended, validated, blockedReason, upstream = null, tmt)
510
511 private fun expectAvailableCallbacksCommon(
512 net: Network,
513 suspended: Boolean,
514 validated: Boolean?,
515 upstream: Network?,
516 tmt: Long
517 ) {
518 expect<Available>(net, tmt)
519 if (suspended) {
520 expect<Suspended>(net, tmt)
521 }
522 val caps = expect<CapabilitiesChanged>(net, tmt) {
523 validated == null || validated == it.caps.hasCapability(NET_CAPABILITY_VALIDATED)
524 }.caps
525 expect<LinkPropertiesChanged>(net, tmt)
526 if (caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK)) {
527 expect<LocalInfoChanged>(net, tmt) { it.info.upstreamNetwork == upstream }
528 }
529 }
530
531 // Backward compatibility for existing Java code. Use named arguments instead and remove all
532 // these when there is no user left.
expectAvailableAndSuspendedCallbacksnull533 fun expectAvailableAndSuspendedCallbacks(
534 net: Network,
535 validated: Boolean,
536 tmt: Long = defaultTimeoutMs
537 ) = expectAvailableCallbacks(net, suspended = true, validated = validated, tmt = tmt)
538
539 // Expects the available callbacks (where the onCapabilitiesChanged must contain the
540 // VALIDATED capability), plus another onCapabilitiesChanged which is identical to the
541 // one we just sent.
542 // TODO: this is likely a bug. Fix it and remove this method.
543 fun expectAvailableDoubleValidatedCallbacks(net: Network, tmt: Long = defaultTimeoutMs) {
544 val mark = history.mark
545 expectAvailableCallbacks(net, tmt = tmt)
546 val firstCaps = history.poll(tmt, mark) { it is CapabilitiesChanged }
547 assertEquals(firstCaps, expect<CapabilitiesChanged>(net, tmt))
548 }
549
550 // Expects the available callbacks where the onCapabilitiesChanged must not have validated,
551 // then expects another onCapabilitiesChanged that has the validated bit set. This is used
552 // when a network connects and satisfies a callback, and then immediately validates.
expectAvailableThenValidatedCallbacksnull553 fun expectAvailableThenValidatedCallbacks(net: Network, tmt: Long = defaultTimeoutMs) {
554 expectAvailableCallbacks(net, validated = false, tmt = tmt)
555 expectCaps(net, tmt) { it.hasCapability(NET_CAPABILITY_VALIDATED) }
556 }
557
expectAvailableThenValidatedCallbacksnull558 fun expectAvailableThenValidatedCallbacks(
559 net: Network,
560 blockedReason: Int,
561 tmt: Long = defaultTimeoutMs
562 ) {
563 expectAvailableCallbacks(
564 net,
565 validated = false,
566 suspended = false,
567 blockedReason = blockedReason,
568 tmt = tmt
569 )
570 expectCaps(net, tmt) { it.hasCapability(NET_CAPABILITY_VALIDATED) }
571 }
572
573 // Temporary Java compat measure : have MockNetworkAgent implement this so that all existing
574 // calls with networkAgent can be routed through here without moving MockNetworkAgent.
575 // TODO: clean this up, remove this method.
576 interface HasNetwork {
577 val network: Network
578 }
579
580 @JvmOverloads
expectAvailableCallbacksnull581 fun expectAvailableCallbacks(
582 n: HasNetwork,
583 suspended: Boolean,
584 validated: Boolean,
585 blocked: Boolean,
586 upstream: Network? = null,
587 timeoutMs: Long
588 ) = expectAvailableCallbacks(n.network, suspended, validated, blocked, upstream, timeoutMs)
589
590 fun expectAvailableAndSuspendedCallbacks(n: HasNetwork, expectValidated: Boolean) {
591 expectAvailableAndSuspendedCallbacks(n.network, expectValidated)
592 }
593
expectAvailableCallbacksValidatednull594 fun expectAvailableCallbacksValidated(n: HasNetwork) {
595 expectAvailableCallbacks(n.network)
596 }
597
expectAvailableCallbacksValidatedAndBlockednull598 fun expectAvailableCallbacksValidatedAndBlocked(n: HasNetwork) {
599 expectAvailableCallbacks(n.network, blocked = true)
600 }
601
expectAvailableCallbacksUnvalidatednull602 fun expectAvailableCallbacksUnvalidated(n: HasNetwork) {
603 expectAvailableCallbacks(n.network, validated = false)
604 }
605
expectAvailableCallbacksUnvalidatedAndBlockednull606 fun expectAvailableCallbacksUnvalidatedAndBlocked(n: HasNetwork) {
607 expectAvailableCallbacks(n.network, validated = false, blocked = true)
608 }
609
expectAvailableDoubleValidatedCallbacksnull610 fun expectAvailableDoubleValidatedCallbacks(n: HasNetwork) {
611 expectAvailableDoubleValidatedCallbacks(n.network, defaultTimeoutMs)
612 }
613
expectAvailableThenValidatedCallbacksnull614 fun expectAvailableThenValidatedCallbacks(n: HasNetwork) {
615 expectAvailableThenValidatedCallbacks(n.network, defaultTimeoutMs)
616 }
617
618 @JvmOverloads
expectCapsnull619 fun expectCaps(
620 n: HasNetwork,
621 tmt: Long = defaultTimeoutMs,
622 valid: (NetworkCapabilities) -> Boolean = { true }
<lambda>null623 ) = expect<CapabilitiesChanged>(n.network, tmt) { valid(it.caps) }.caps
624
625 @JvmOverloads
expectCapsnull626 fun expectCaps(
627 n: Network,
628 tmt: Long = defaultTimeoutMs,
629 valid: (NetworkCapabilities) -> Boolean
630 ) = expect<CapabilitiesChanged>(n, tmt) { valid(it.caps) }.caps
631
expectCapsnull632 fun expectCaps(
633 n: HasNetwork,
634 valid: (NetworkCapabilities) -> Boolean
635 ) = expect<CapabilitiesChanged>(n.network) { valid(it.caps) }.caps
636
expectCapsnull637 fun expectCaps(
638 tmt: Long,
639 valid: (NetworkCapabilities) -> Boolean
640 ) = expect<CapabilitiesChanged>(ANY_NETWORK, tmt) { valid(it.caps) }.caps
641 }
642