1 /*
<lambda>null2 * 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 @file:JvmName("MiscAsserts")
18
19 package com.android.testutils
20
21 import com.android.testutils.FunctionalUtils.ThrowingRunnable
22 import java.lang.reflect.Modifier
23 import java.util.concurrent.TimeUnit
24 import java.util.function.BooleanSupplier
25 import kotlin.system.measureTimeMillis
26 import kotlin.test.assertEquals
27 import kotlin.test.assertFailsWith
28 import kotlin.test.assertFalse
29 import kotlin.test.assertTrue
30 import kotlin.test.fail
31
32 private const val TAG = "Connectivity unit test"
33
34 fun <T> assertEmpty(ts: Array<T>) = ts.size.let { len ->
35 assertEquals(0, len, "Expected empty array, but length was $len")
36 }
37
lennull38 fun <T> assertEmpty(ts: Collection<T>) = ts.size.let { len ->
39 assertEquals(0, len, "Expected empty collection, but length was $len")
40 }
41
lennull42 fun <T> assertLength(expected: Int, got: Array<T>) = got.size.let { len ->
43 assertEquals(expected, len, "Expected array of length $expected, but was $len for $got")
44 }
45
lennull46 fun <T> assertLength(expected: Int, got: List<T>) = got.size.let { len ->
47 assertEquals(expected, len, "Expected list of length $expected, but was $len for $got")
48 }
49
50 // Bridge method to help write this in Java. If you're writing Kotlin, consider using
51 // kotlin.test.assertFailsWith instead, as that method is reified and inlined.
assertThrowsnull52 fun <T : Exception> assertThrows(expected: Class<T>, block: ThrowingRunnable): T {
53 return assertFailsWith(expected.kotlin) { block.run() }
54 }
55
assertThrowsnull56 fun <T : Exception> assertThrows(msg: String, expected: Class<T>, block: ThrowingRunnable): T {
57 return assertFailsWith(expected.kotlin, msg) { block.run() }
58 }
59
assertEqualBothWaysnull60 fun <T> assertEqualBothWays(o1: T, o2: T) {
61 assertTrue(o1 == o2)
62 assertTrue(o2 == o1)
63 }
64
assertNotEqualEitherWaynull65 fun <T> assertNotEqualEitherWay(o1: T, o2: T) {
66 assertFalse(o1 == o2)
67 assertFalse(o2 == o1)
68 }
69
assertStringContainsnull70 fun assertStringContains(got: String, want: String) {
71 assertTrue(got.contains(want), "$got did not contain \"${want}\"")
72 }
73
assertContainsExactlynull74 fun assertContainsExactly(actual: IntArray, vararg expected: Int) {
75 // IntArray#sorted() returns a list, so it's fine to test with equals()
76 assertEquals(actual.sorted(), expected.sorted(),
77 "$actual does not contain exactly $expected")
78 }
79
assertContainsStringsExactlynull80 fun assertContainsStringsExactly(actual: Array<String>, vararg expected: String) {
81 assertEquals(actual.sorted(), expected.sorted(),
82 "$actual does not contain exactly $expected")
83 }
84
assertContainsAllnull85 fun <T> assertContainsAll(list: Collection<T>, vararg elems: T) {
86 assertContainsAll(list, elems.asList())
87 }
88
assertContainsAllnull89 fun <T> assertContainsAll(list: Collection<T>, elems: Collection<T>) {
90 elems.forEach { assertTrue(list.contains(it), "$it not in list") }
91 }
92
assertRunsInAtMostnull93 fun assertRunsInAtMost(descr: String, timeLimit: Long, fn: Runnable) {
94 assertRunsInAtMost(descr, timeLimit) { fn.run() }
95 }
96
assertRunsInAtMostnull97 fun assertRunsInAtMost(descr: String, timeLimit: Long, fn: () -> Unit) {
98 val timeTaken = measureTimeMillis(fn)
99 val msg = String.format("%s: took %dms, limit was %dms", descr, timeTaken, timeLimit)
100 assertTrue(timeTaken <= timeLimit, msg)
101 }
102
103 /**
104 * Verifies that the number of nonstatic fields in a java class equals a given count.
105 * Note: this is essentially not useful for Kotlin code where fields are not really a thing.
106 *
107 * This assertion serves as a reminder to update test code around it if fields are added
108 * after the test is written.
109 * @param count Expected number of nonstatic fields in the class.
110 * @param clazz Class to test.
111 */
assertFieldCountEqualsnull112 fun <T> assertFieldCountEquals(count: Int, clazz: Class<T>) {
113 assertEquals(count, clazz.declaredFields.filter {
114 !Modifier.isStatic(it.modifiers) && !Modifier.isTransient(it.modifiers)
115 }.size)
116 }
117
assertSameElementsnull118 fun <T> assertSameElements(expected: List<T>, actual: List<T>) {
119 val expectedSet: HashSet<T> = HashSet(expected)
120 assertEquals(expectedSet.size, expected.size, "expected list contains duplicates")
121 val actualSet: HashSet<T> = HashSet(actual)
122 assertEquals(actualSet.size, actual.size, "actual list contains duplicates")
123 assertEquals(expectedSet, actualSet)
124 }
125
126 @JvmOverloads
assertEventuallyTruenull127 fun assertEventuallyTrue(
128 descr: String,
129 timeoutMs: Long,
130 pollIntervalMs: Long = 10L,
131 fn: BooleanSupplier
132 ) {
133 // This should use SystemClock.elapsedRealtime() since nanoTime does not include time in deep
134 // sleep, but this is a host-device library and SystemClock is Android-specific (not available
135 // on host). When waiting for a condition during tests the device would generally not go into
136 // deep sleep, and the polling sleep would go over the timeout anyway in that case, so this is
137 // fine.
138 val limit = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeoutMs)
139 while (!fn.asBoolean) {
140 if (System.nanoTime() > limit) {
141 fail(descr)
142 }
143 Thread.sleep(pollIntervalMs)
144 }
145 }