Loading tests/lib/src/com/android/testutils/ConcurrentUtils.kt 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.testutils import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit import kotlin.system.measureTimeMillis // For Java usage fun durationOf(fn: Runnable) = measureTimeMillis { fn.run() } fun CountDownLatch.await(timeoutMs: Long): Boolean = await(timeoutMs, TimeUnit.MILLISECONDS) tests/lib/src/com/android/testutils/HandlerUtils.kt +6 −7 Original line number Diff line number Diff line Loading @@ -20,19 +20,18 @@ import android.os.ConditionVariable import android.os.Handler import android.os.HandlerThread import java.util.concurrent.Executor import kotlin.system.measureTimeMillis import kotlin.test.fail /** * Block until the specified Handler or HandlerThread becomes idle, or until timeoutMs has passed. */ fun Handler.waitForIdle(timeoutMs: Long) = waitForIdleHandler(this, timeoutMs) fun HandlerThread.waitForIdle(timeoutMs: Long) = waitForIdleHandler(this.threadHandler, timeoutMs) fun waitForIdleHandler(handler: HandlerThread, timeoutMs: Long) { waitForIdleHandler(handler.threadHandler, timeoutMs) } fun waitForIdleHandler(handler: Handler, timeoutMs: Long) { fun HandlerThread.waitForIdle(timeoutMs: Int) = threadHandler.waitForIdle(timeoutMs.toLong()) fun HandlerThread.waitForIdle(timeoutMs: Long) = threadHandler.waitForIdle(timeoutMs) fun Handler.waitForIdle(timeoutMs: Int) = waitForIdle(timeoutMs.toLong()) fun Handler.waitForIdle(timeoutMs: Long) { val cv = ConditionVariable(false) handler.post(cv::open) post(cv::open) if (!cv.block(timeoutMs)) { fail("Handler did not become idle after ${timeoutMs}ms") } Loading tests/lib/src/com/android/testutils/MiscAsserts.kt 0 → 100644 +93 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.testutils import android.util.Log import java.lang.reflect.Modifier import kotlin.system.measureTimeMillis import kotlin.test.assertEquals import kotlin.test.assertFailsWith import kotlin.test.assertFalse import kotlin.test.assertTrue private const val TAG = "Connectivity unit test" fun <T> assertEmpty(ts: Array<T>) = ts.size.let { len -> assertEquals(0, len, "Expected empty array, but length was ${len}") } fun <T> assertLength(expected: Int, got: Array<T>) = got.size.let { len -> assertEquals(expected, len, "Expected array of length ${expected}, but was ${len} for ${got}") } // Bridge method to help write this in Java. If you're writing Kotlin, consider using native // kotlin.test.assertFailsWith instead, as that method is reified and inlined. fun <T: Exception> assertThrows(expected: Class<T>, block: Runnable): T { return assertFailsWith(expected.kotlin) { block.run() } } fun <T> assertEqualBothWays(o1: T, o2: T) { assertTrue(o1 == o2) assertTrue(o2 == o1) } fun <T> assertNotEqualEitherWay(o1: T, o2: T) { assertFalse(o1 == o2) assertFalse(o2 == o1) } fun assertStringContains(got: String, want: String) { assertTrue(got.contains(want), "${got} did not contain \"${want}\"") } fun assertContainsExactly(actual: IntArray, vararg expected: Int) { // IntArray#sorted() returns a list, so it's fine to test with equals() assertEquals(actual.sorted(), expected.sorted(), "${actual} does not contain exactly ${expected}") } fun <T> assertContainsAll(list: Collection<T>, vararg elems: T) { assertContainsAll(list, elems.asList()) } fun <T> assertContainsAll(list: Collection<T>, elems: Collection<T>) { elems.forEach { assertTrue(list.contains(it), "${it} not in list") } } fun assertRunsInAtMost(descr: String, timeLimit: Long, fn: Runnable) { assertRunsInAtMost(descr, timeLimit) { fn.run() } } fun assertRunsInAtMost(descr: String, timeLimit: Long, fn: () -> Unit) { val timeTaken = measureTimeMillis(fn) val msg = String.format("%s: took %dms, limit was %dms", descr, timeTaken, timeLimit) Log.d(TAG, msg) assertTrue(timeTaken <= timeLimit, msg) } /** * Verifies that the number of nonstatic fields in a java class equals a given count. * Note: this is essentially not useful for Kotlin code where fields are not really a thing. * * This assertion serves as a reminder to update test code around it if fields are added * after the test is written. * @param count Expected number of nonstatic fields in the class. * @param clazz Class to test. */ fun <T> assertFieldCountEquals(count: Int, clazz: Class<T>) { assertEquals(count, clazz.declaredFields.filter { !Modifier.isStatic(it.modifiers) }.size) } tests/lib/src/com/android/testutils/ParcelUtils.kt 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.testutils import android.os.Parcel import android.os.Parcelable import kotlin.test.assertEquals import kotlin.test.fail /** * Return a new instance of `T` after being parceled then unparceled. */ fun <T: Parcelable> parcelingRoundTrip(source: T): T { val creator: Parcelable.Creator<T> try { creator = source.javaClass.getField("CREATOR").get(null) as Parcelable.Creator<T> } catch (e: IllegalAccessException) { fail("Missing CREATOR field: " + e.message) } catch (e: NoSuchFieldException) { fail("Missing CREATOR field: " + e.message) } var p = Parcel.obtain() source.writeToParcel(p, /* flags */ 0) p.setDataPosition(0) val marshalled = p.marshall() p = Parcel.obtain() p.unmarshall(marshalled, 0, marshalled.size) p.setDataPosition(0) return creator.createFromParcel(p) } /** * Assert that after being parceled then unparceled, `source` is equal to the original * object. */ fun <T: Parcelable> assertParcelingIsLossless(source: T) { assertEquals(source, parcelingRoundTrip(source)) } fun <T: Parcelable> assertParcelSane(obj: T, fieldCount: Int) { assertFieldCountEquals(fieldCount, obj::class.java) assertParcelingIsLossless(obj) } tests/lib/src/com/android/testutils/ThrowingConsumer.java 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.testutils; /** * Like a consumer, but throws an exception. * @param <T> */ @FunctionalInterface public interface ThrowingConsumer<T> { void accept(T t) throws Exception; } Loading
tests/lib/src/com/android/testutils/ConcurrentUtils.kt 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.testutils import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit import kotlin.system.measureTimeMillis // For Java usage fun durationOf(fn: Runnable) = measureTimeMillis { fn.run() } fun CountDownLatch.await(timeoutMs: Long): Boolean = await(timeoutMs, TimeUnit.MILLISECONDS)
tests/lib/src/com/android/testutils/HandlerUtils.kt +6 −7 Original line number Diff line number Diff line Loading @@ -20,19 +20,18 @@ import android.os.ConditionVariable import android.os.Handler import android.os.HandlerThread import java.util.concurrent.Executor import kotlin.system.measureTimeMillis import kotlin.test.fail /** * Block until the specified Handler or HandlerThread becomes idle, or until timeoutMs has passed. */ fun Handler.waitForIdle(timeoutMs: Long) = waitForIdleHandler(this, timeoutMs) fun HandlerThread.waitForIdle(timeoutMs: Long) = waitForIdleHandler(this.threadHandler, timeoutMs) fun waitForIdleHandler(handler: HandlerThread, timeoutMs: Long) { waitForIdleHandler(handler.threadHandler, timeoutMs) } fun waitForIdleHandler(handler: Handler, timeoutMs: Long) { fun HandlerThread.waitForIdle(timeoutMs: Int) = threadHandler.waitForIdle(timeoutMs.toLong()) fun HandlerThread.waitForIdle(timeoutMs: Long) = threadHandler.waitForIdle(timeoutMs) fun Handler.waitForIdle(timeoutMs: Int) = waitForIdle(timeoutMs.toLong()) fun Handler.waitForIdle(timeoutMs: Long) { val cv = ConditionVariable(false) handler.post(cv::open) post(cv::open) if (!cv.block(timeoutMs)) { fail("Handler did not become idle after ${timeoutMs}ms") } Loading
tests/lib/src/com/android/testutils/MiscAsserts.kt 0 → 100644 +93 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.testutils import android.util.Log import java.lang.reflect.Modifier import kotlin.system.measureTimeMillis import kotlin.test.assertEquals import kotlin.test.assertFailsWith import kotlin.test.assertFalse import kotlin.test.assertTrue private const val TAG = "Connectivity unit test" fun <T> assertEmpty(ts: Array<T>) = ts.size.let { len -> assertEquals(0, len, "Expected empty array, but length was ${len}") } fun <T> assertLength(expected: Int, got: Array<T>) = got.size.let { len -> assertEquals(expected, len, "Expected array of length ${expected}, but was ${len} for ${got}") } // Bridge method to help write this in Java. If you're writing Kotlin, consider using native // kotlin.test.assertFailsWith instead, as that method is reified and inlined. fun <T: Exception> assertThrows(expected: Class<T>, block: Runnable): T { return assertFailsWith(expected.kotlin) { block.run() } } fun <T> assertEqualBothWays(o1: T, o2: T) { assertTrue(o1 == o2) assertTrue(o2 == o1) } fun <T> assertNotEqualEitherWay(o1: T, o2: T) { assertFalse(o1 == o2) assertFalse(o2 == o1) } fun assertStringContains(got: String, want: String) { assertTrue(got.contains(want), "${got} did not contain \"${want}\"") } fun assertContainsExactly(actual: IntArray, vararg expected: Int) { // IntArray#sorted() returns a list, so it's fine to test with equals() assertEquals(actual.sorted(), expected.sorted(), "${actual} does not contain exactly ${expected}") } fun <T> assertContainsAll(list: Collection<T>, vararg elems: T) { assertContainsAll(list, elems.asList()) } fun <T> assertContainsAll(list: Collection<T>, elems: Collection<T>) { elems.forEach { assertTrue(list.contains(it), "${it} not in list") } } fun assertRunsInAtMost(descr: String, timeLimit: Long, fn: Runnable) { assertRunsInAtMost(descr, timeLimit) { fn.run() } } fun assertRunsInAtMost(descr: String, timeLimit: Long, fn: () -> Unit) { val timeTaken = measureTimeMillis(fn) val msg = String.format("%s: took %dms, limit was %dms", descr, timeTaken, timeLimit) Log.d(TAG, msg) assertTrue(timeTaken <= timeLimit, msg) } /** * Verifies that the number of nonstatic fields in a java class equals a given count. * Note: this is essentially not useful for Kotlin code where fields are not really a thing. * * This assertion serves as a reminder to update test code around it if fields are added * after the test is written. * @param count Expected number of nonstatic fields in the class. * @param clazz Class to test. */ fun <T> assertFieldCountEquals(count: Int, clazz: Class<T>) { assertEquals(count, clazz.declaredFields.filter { !Modifier.isStatic(it.modifiers) }.size) }
tests/lib/src/com/android/testutils/ParcelUtils.kt 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.testutils import android.os.Parcel import android.os.Parcelable import kotlin.test.assertEquals import kotlin.test.fail /** * Return a new instance of `T` after being parceled then unparceled. */ fun <T: Parcelable> parcelingRoundTrip(source: T): T { val creator: Parcelable.Creator<T> try { creator = source.javaClass.getField("CREATOR").get(null) as Parcelable.Creator<T> } catch (e: IllegalAccessException) { fail("Missing CREATOR field: " + e.message) } catch (e: NoSuchFieldException) { fail("Missing CREATOR field: " + e.message) } var p = Parcel.obtain() source.writeToParcel(p, /* flags */ 0) p.setDataPosition(0) val marshalled = p.marshall() p = Parcel.obtain() p.unmarshall(marshalled, 0, marshalled.size) p.setDataPosition(0) return creator.createFromParcel(p) } /** * Assert that after being parceled then unparceled, `source` is equal to the original * object. */ fun <T: Parcelable> assertParcelingIsLossless(source: T) { assertEquals(source, parcelingRoundTrip(source)) } fun <T: Parcelable> assertParcelSane(obj: T, fieldCount: Int) { assertFieldCountEquals(fieldCount, obj::class.java) assertParcelingIsLossless(obj) }
tests/lib/src/com/android/testutils/ThrowingConsumer.java 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.testutils; /** * Like a consumer, but throws an exception. * @param <T> */ @FunctionalInterface public interface ThrowingConsumer<T> { void accept(T t) throws Exception; }