summaryrefslogtreecommitdiff
path: root/common/testutils/hostdevice/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'common/testutils/hostdevice/com/android')
-rw-r--r--common/testutils/hostdevice/com/android/net/module/util/TrackRecord.kt311
-rw-r--r--common/testutils/hostdevice/com/android/testutils/Cleanup.kt125
-rw-r--r--common/testutils/hostdevice/com/android/testutils/ConcurrentUtils.kt28
-rw-r--r--common/testutils/hostdevice/com/android/testutils/ConnectivityModuleTest.kt27
-rw-r--r--common/testutils/hostdevice/com/android/testutils/DnsResolverModuleTest.kt22
-rw-r--r--common/testutils/hostdevice/com/android/testutils/FileUtils.kt27
-rw-r--r--common/testutils/hostdevice/com/android/testutils/FunctionalUtils.java99
-rw-r--r--common/testutils/hostdevice/com/android/testutils/MiscAsserts.kt121
-rw-r--r--common/testutils/hostdevice/com/android/testutils/NetworkStackModuleTest.kt22
-rw-r--r--common/testutils/hostdevice/com/android/testutils/PacketFilter.kt148
-rw-r--r--common/testutils/hostdevice/com/android/testutils/SkipMainlinePresubmit.kt25
-rw-r--r--common/testutils/hostdevice/com/android/testutils/SkipPresubmit.kt24
12 files changed, 0 insertions, 979 deletions
diff --git a/common/testutils/hostdevice/com/android/net/module/util/TrackRecord.kt b/common/testutils/hostdevice/com/android/net/module/util/TrackRecord.kt
deleted file mode 100644
index f24e4f18..00000000
--- a/common/testutils/hostdevice/com/android/net/module/util/TrackRecord.kt
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * 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.net.module.util
-
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.locks.Condition
-import java.util.concurrent.locks.ReentrantLock
-import java.util.concurrent.locks.StampedLock
-import kotlin.concurrent.withLock
-
-/**
- * A List that additionally offers the ability to append via the add() method, and to retrieve
- * an element by its index optionally waiting for it to become available.
- */
-interface TrackRecord<E> : List<E> {
- /**
- * Adds an element to this queue, waking up threads waiting for one. Returns true, as
- * per the contract for List.
- */
- fun add(e: E): Boolean
-
- /**
- * Returns the first element after {@param pos}, possibly blocking until one is available, or
- * null if no such element can be found within the timeout.
- * If a predicate is given, only elements matching the predicate are returned.
- *
- * @param timeoutMs how long, in milliseconds, to wait at most (best effort approximation).
- * @param pos the position at which to start polling.
- * @param predicate an optional predicate to filter elements to be returned.
- * @return an element matching the predicate, or null if timeout.
- */
- fun poll(timeoutMs: Long, pos: Int, predicate: (E) -> Boolean = { true }): E?
-}
-
-/**
- * A thread-safe implementation of TrackRecord that is backed by an ArrayList.
- *
- * This class also supports the creation of a read-head for easier single-thread access.
- * Refer to the documentation of {@link ArrayTrackRecord.ReadHead}.
- */
-class ArrayTrackRecord<E> : TrackRecord<E> {
- private val lock = ReentrantLock()
- private val condition = lock.newCondition()
- // Backing store. This stores the elements in this ArrayTrackRecord.
- private val elements = ArrayList<E>()
-
- // The list iterator for RecordingQueue iterates over a snapshot of the collection at the
- // time the operator is created. Because TrackRecord is only ever mutated by appending,
- // that makes this iterator thread-safe as it sees an effectively immutable List.
- class ArrayTrackRecordIterator<E>(
- private val list: ArrayList<E>,
- start: Int,
- private val end: Int
- ) : ListIterator<E> {
- var index = start
- override fun hasNext() = index < end
- override fun next() = list[index++]
- override fun hasPrevious() = index > 0
- override fun nextIndex() = index + 1
- override fun previous() = list[--index]
- override fun previousIndex() = index - 1
- }
-
- // List<E> implementation
- override val size get() = lock.withLock { elements.size }
- override fun contains(element: E) = lock.withLock { elements.contains(element) }
- override fun containsAll(elements: Collection<E>) = lock.withLock {
- this.elements.containsAll(elements)
- }
- override operator fun get(index: Int) = lock.withLock { elements[index] }
- override fun indexOf(element: E): Int = lock.withLock { elements.indexOf(element) }
- override fun lastIndexOf(element: E): Int = lock.withLock { elements.lastIndexOf(element) }
- override fun isEmpty() = lock.withLock { elements.isEmpty() }
- override fun listIterator(index: Int) = ArrayTrackRecordIterator(elements, index, size)
- override fun listIterator() = listIterator(0)
- override fun iterator() = listIterator()
- override fun subList(fromIndex: Int, toIndex: Int): List<E> = lock.withLock {
- elements.subList(fromIndex, toIndex)
- }
-
- // TrackRecord<E> implementation
- override fun add(e: E): Boolean {
- lock.withLock {
- elements.add(e)
- condition.signalAll()
- }
- return true
- }
- override fun poll(timeoutMs: Long, pos: Int, predicate: (E) -> Boolean) = lock.withLock {
- elements.getOrNull(pollForIndexReadLocked(timeoutMs, pos, predicate))
- }
-
- // For convenience
- fun getOrNull(pos: Int, predicate: (E) -> Boolean) = lock.withLock {
- if (pos < 0 || pos > size) null else elements.subList(pos, size).find(predicate)
- }
-
- // Returns the index of the next element whose position is >= pos matching the predicate, if
- // necessary waiting until such a time that such an element is available, with a timeout.
- // If no such element is found within the timeout -1 is returned.
- private fun pollForIndexReadLocked(timeoutMs: Long, pos: Int, predicate: (E) -> Boolean): Int {
- val deadline = System.currentTimeMillis() + timeoutMs
- var index = pos
- do {
- while (index < elements.size) {
- if (predicate(elements[index])) return index
- ++index
- }
- } while (condition.await(deadline - System.currentTimeMillis()))
- return -1
- }
-
- /**
- * Returns a ReadHead over this ArrayTrackRecord. The returned ReadHead is tied to the
- * current thread.
- */
- fun newReadHead() = ReadHead()
-
- /**
- * ReadHead is an object that helps users of ArrayTrackRecord keep track of how far
- * it has read this far in the ArrayTrackRecord. A ReadHead is always associated with
- * a single instance of ArrayTrackRecord. Multiple ReadHeads can be created and used
- * on the same instance of ArrayTrackRecord concurrently, and the ArrayTrackRecord
- * instance can also be used concurrently. ReadHead maintains the current index that is
- * the next to be read, and calls this the "mark".
- *
- * In a ReadHead, {@link poll(Long, (E) -> Boolean)} works similarly to a LinkedBlockingQueue.
- * It can be called repeatedly and will return the elements as they arrive.
- *
- * Intended usage looks something like this :
- * val TrackRecord<MyObject> record = ArrayTrackRecord().newReadHead()
- * Thread().start {
- * // do stuff
- * record.add(something)
- * // do stuff
- * }
- *
- * val obj1 = record.poll(timeout)
- * // do something with obj1
- * val obj2 = record.poll(timeout)
- * // do something with obj2
- *
- * The point is that the caller does not have to track the mark like it would have to if
- * it was using ArrayTrackRecord directly.
- *
- * Thread safety :
- * A ReadHead delegates all TrackRecord methods to its associated ArrayTrackRecord, and
- * inherits its thread-safe properties for all the TrackRecord methods.
- *
- * Poll() operates under its own set of rules that only allow execution on multiple threads
- * within constrained boundaries, and never concurrently or pseudo-concurrently. This is
- * because concurrent calls to poll() fundamentally do not make sense. poll() will move
- * the mark according to what events remained to be read by this read head, and therefore
- * if multiple threads were calling poll() concurrently on the same ReadHead, what
- * happens to the mark and the return values could not be useful because there is no way to
- * provide either a guarantee not to skip objects nor a guarantee about the mark position at
- * the exit of poll(). This is even more true in the presence of a predicate to filter
- * returned elements, because one thread might be filtering out the events the other is
- * interested in. For this reason, this class will fail-fast if any concurrent access is
- * detected with ConcurrentAccessException.
- * It is possible to use poll() on different threads as long as the following can be
- * guaranteed : one thread must call poll() for the last time, then execute a write barrier,
- * then the other thread must execute a read barrier before calling poll() for the first time.
- * This allows in particular to call poll in @Before and @After methods in JUnit unit tests,
- * because JUnit will enforce those barriers by creating the testing thread after executing
- * @Before and joining the thread after executing @After.
- *
- * peek() can be used by multiple threads concurrently, but only if no thread is calling
- * poll() outside of the boundaries above. For simplicity, it can be considered that peek()
- * is safe to call only when poll() is safe to call.
- *
- * Polling concurrently from the same ArrayTrackRecord is supported by creating multiple
- * ReadHeads on the same instance of ArrayTrackRecord (or of course by using ArrayTrackRecord
- * directly). Each ReadHead is then guaranteed to see all events always and
- * guarantees are made on the value of the mark upon return. {@see poll(Long, (E) -> Boolean)}
- * for details. Be careful to create each ReadHead on the thread it is meant to be used on, or
- * to have a clear synchronization point between creation and use.
- *
- * Users of a ReadHead can ask for the current position of the mark at any time, on a thread
- * where it's safe to call peek(). This mark can be used later to replay the history of events
- * either on this ReadHead, on the associated ArrayTrackRecord or on another ReadHead
- * associated with the same ArrayTrackRecord. It might look like this in the reader thread :
- *
- * val markAtStart = record.mark
- * // Start processing interesting events
- * while (val element = record.poll(timeout) { it.isInteresting() }) {
- * // Do something with element
- * }
- * // Look for stuff that happened while searching for interesting events
- * val firstElementReceived = record.getOrNull(markAtStart)
- * val firstSpecialElement = record.getOrNull(markAtStart) { it.isSpecial() }
- * // Get the first special element since markAtStart, possibly blocking until one is available
- * val specialElement = record.poll(timeout, markAtStart) { it.isSpecial() }
- */
- inner class ReadHead : TrackRecord<E> by this@ArrayTrackRecord {
- // This lock only controls access to the readHead member below. The ArrayTrackRecord
- // object has its own synchronization following different (and more usual) semantics.
- // See the comment on the ReadHead class for details.
- private val slock = StampedLock()
- private var readHead = 0
-
- // A special mark used to track the start of the last poll() operation.
- private var pollMark = 0
-
- /**
- * @return the current value of the mark.
- */
- var mark
- get() = checkThread { readHead }
- set(v: Int) = rewind(v)
- fun rewind(v: Int) {
- val stamp = slock.tryWriteLock()
- if (0L == stamp) concurrentAccessDetected()
- readHead = v
- pollMark = v
- slock.unlockWrite(stamp)
- }
-
- private fun <T> checkThread(r: (Long) -> T): T {
- // tryOptimisticRead is a read barrier, guarantees writes from other threads are visible
- // after it
- val stamp = slock.tryOptimisticRead()
- val result = r(stamp)
- // validate also performs a read barrier, guaranteeing that if validate returns true,
- // then any change either happens-before tryOptimisticRead, or happens-after validate.
- if (!slock.validate(stamp)) concurrentAccessDetected()
- return result
- }
-
- private fun concurrentAccessDetected(): Nothing {
- throw ConcurrentModificationException(
- "ReadHeads can't be used concurrently. Check your threading model.")
- }
-
- /**
- * Returns the first element after the mark, optionally blocking until one is available, or
- * null if no such element can be found within the timeout.
- * If a predicate is given, only elements matching the predicate are returned.
- *
- * Upon return the mark will be set to immediately after the returned element, or after
- * the last element in the queue if null is returned. This means this method will always
- * skip elements that do not match the predicate, even if it returns null.
- *
- * This method can only be used by the thread that created this ManagedRecordingQueue.
- * If used on another thread, this throws IllegalStateException.
- *
- * @param timeoutMs how long, in milliseconds, to wait at most (best effort approximation).
- * @param predicate an optional predicate to filter elements to be returned.
- * @return an element matching the predicate, or null if timeout.
- */
- fun poll(timeoutMs: Long, predicate: (E) -> Boolean = { true }): E? {
- val stamp = slock.tryWriteLock()
- if (0L == stamp) concurrentAccessDetected()
- pollMark = readHead
- try {
- lock.withLock {
- val index = pollForIndexReadLocked(timeoutMs, readHead, predicate)
- readHead = if (index < 0) size else index + 1
- return getOrNull(index)
- }
- } finally {
- slock.unlockWrite(stamp)
- }
- }
-
- /**
- * Returns a list of events that were observed since the last time poll() was called on this
- * ReadHead.
- *
- * @return list of events since poll() was called.
- */
- fun backtrace(): List<E> {
- val stamp = slock.tryReadLock()
- if (0L == stamp) concurrentAccessDetected()
-
- try {
- lock.withLock {
- return ArrayList(subList(pollMark, mark))
- }
- } finally {
- slock.unlockRead(stamp)
- }
- }
-
- /**
- * Returns the first element after the mark or null. This never blocks.
- *
- * This method is subject to threading restrictions. It can be used concurrently on
- * multiple threads but not if any other thread might be executing poll() at the same
- * time. See the class comment for details.
- */
- fun peek(): E? = checkThread { getOrNull(readHead) }
- }
-}
-
-// Private helper
-private fun Condition.await(timeoutMs: Long) = this.await(timeoutMs, TimeUnit.MILLISECONDS)
diff --git a/common/testutils/hostdevice/com/android/testutils/Cleanup.kt b/common/testutils/hostdevice/com/android/testutils/Cleanup.kt
deleted file mode 100644
index 9f282347..00000000
--- a/common/testutils/hostdevice/com/android/testutils/Cleanup.kt
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-@file:JvmName("Cleanup")
-
-package com.android.testutils
-
-import com.android.testutils.FunctionalUtils.ThrowingRunnable
-import com.android.testutils.FunctionalUtils.ThrowingSupplier
-import javax.annotation.CheckReturnValue
-
-/**
- * Utility to do cleanup in tests without replacing exceptions with those from a finally block.
- *
- * This utility is meant for tests that want to do cleanup after they execute their test
- * logic, whether the test fails (and throws) or not.
- *
- * The usual way of doing this is to have a try{}finally{} block and put cleanup in finally{}.
- * However, if any code in finally{} throws, the exception thrown in finally{} is thrown before
- * any thrown in try{} ; that means errors reported from tests are from finally{} even if they
- * have been caused by errors in try{}. This is unhelpful in tests, because it results in a
- * stacktrace for a symptom rather than a stacktrace for a cause.
- *
- * To alleviate this, tests are encouraged to make sure the code in finally{} can't throw, or
- * that the code in try{} can't cause it to fail. This is not always realistic ; not only does
- * it require the developer thinks about complex interactions of code, test code often relies
- * on bricks provided by other teams, not controlled by the team writing the test, which may
- * start throwing with an update (see b/198998862 for an example).
- *
- * This utility allows a different approach : it offers a new construct, tryTest{}cleanup{} similar
- * to try{}finally{}, but that will always throw the first exception that happens. In other words,
- * if only tryTest{} throws or only cleanup{} throws, that exception will be thrown, but contrary
- * to the standard try{}finally{}, if both throws, the construct throws the exception that happened
- * in tryTest{} rather than the one that happened in cleanup{}.
- *
- * Kotlin usage is as try{}finally{}, but with multiple finally{} blocks :
- * tryTest {
- * testing code
- * } cleanupStep {
- * cleanup code 1
- * } cleanupStep {
- * cleanup code 2
- * } cleanup {
- * cleanup code 3
- * }
- * Catch blocks can be added with the following syntax :
- * tryTest {
- * testing code
- * }.catch<ExceptionType> { it ->
- * do something to it
- * }
- *
- * Java doesn't allow this kind of syntax, so instead a function taking lambdas is provided.
- * testAndCleanup(() -> {
- * testing code
- * }, () -> {
- * cleanup code 1
- * }, () -> {
- * cleanup code 2
- * });
- */
-
-@CheckReturnValue
-fun <T> tryTest(block: () -> T) = TryExpr(
- try {
- Result.success(block())
- } catch (e: Throwable) {
- Result.failure(e)
- })
-
-// Some downstream branches have an older kotlin that doesn't know about value classes.
-// TODO : Change this to "value class" when aosp no longer merges into such branches.
-@Suppress("INLINE_CLASS_DEPRECATED")
-inline class TryExpr<T>(val result: Result<T>) {
- inline infix fun <reified E : Throwable> catch(block: (E) -> T): TryExpr<T> {
- val originalException = result.exceptionOrNull()
- if (originalException !is E) return this
- return TryExpr(try {
- Result.success(block(originalException))
- } catch (e: Throwable) {
- Result.failure(e)
- })
- }
-
- @CheckReturnValue
- inline infix fun cleanupStep(block: () -> Unit): TryExpr<T> {
- try {
- block()
- } catch (e: Throwable) {
- val originalException = result.exceptionOrNull()
- return TryExpr(if (null == originalException) {
- Result.failure(e)
- } else {
- originalException.addSuppressed(e)
- Result.failure(originalException)
- })
- }
- return this
- }
-
- inline infix fun cleanup(block: () -> Unit): T = cleanupStep(block).result.getOrThrow()
-}
-
-// Java support
-fun <T> testAndCleanup(tryBlock: ThrowingSupplier<T>, vararg cleanupBlock: ThrowingRunnable): T {
- return cleanupBlock.fold(tryTest { tryBlock.get() }) { previousExpr, nextCleanup ->
- previousExpr.cleanupStep { nextCleanup.run() }
- }.cleanup {}
-}
-fun testAndCleanup(tryBlock: ThrowingRunnable, vararg cleanupBlock: ThrowingRunnable) {
- return testAndCleanup(ThrowingSupplier { tryBlock.run() }, *cleanupBlock)
-}
diff --git a/common/testutils/hostdevice/com/android/testutils/ConcurrentUtils.kt b/common/testutils/hostdevice/com/android/testutils/ConcurrentUtils.kt
deleted file mode 100644
index af4f96dc..00000000
--- a/common/testutils/hostdevice/com/android/testutils/ConcurrentUtils.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-@file:JvmName("ConcurrentUtils")
-
-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)
diff --git a/common/testutils/hostdevice/com/android/testutils/ConnectivityModuleTest.kt b/common/testutils/hostdevice/com/android/testutils/ConnectivityModuleTest.kt
deleted file mode 100644
index ec485fea..00000000
--- a/common/testutils/hostdevice/com/android/testutils/ConnectivityModuleTest.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2021 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
-
-/**
- * Indicates that the test covers functionality that was rolled out in a connectivity module update.
- *
- * Annotated MTS tests will typically only be run in Connectivity/Tethering module MTS, and not when
- * only other modules (such as NetworkStack) have been updated.
- * Annotated CTS tests will always be run, as the Connectivity module should be at least newer than
- * the CTS suite.
- */
-annotation class ConnectivityModuleTest
diff --git a/common/testutils/hostdevice/com/android/testutils/DnsResolverModuleTest.kt b/common/testutils/hostdevice/com/android/testutils/DnsResolverModuleTest.kt
deleted file mode 100644
index 9e97d51e..00000000
--- a/common/testutils/hostdevice/com/android/testutils/DnsResolverModuleTest.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2023 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
-
-/**
- * Indicates that the test covers functionality that was rolled out in a resolv module update.
- */
-annotation class DnsResolverModuleTest
diff --git a/common/testutils/hostdevice/com/android/testutils/FileUtils.kt b/common/testutils/hostdevice/com/android/testutils/FileUtils.kt
deleted file mode 100644
index 678f9774..00000000
--- a/common/testutils/hostdevice/com/android/testutils/FileUtils.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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
-
-// This function is private because the 2 is hardcoded here, and is not correct if not called
-// directly from __LINE__ or __FILE__.
-private fun callerStackTrace(): StackTraceElement = try {
- throw RuntimeException()
-} catch (e: RuntimeException) {
- e.stackTrace[2] // 0 is here, 1 is get() in __FILE__ or __LINE__
-}
-val __FILE__: String get() = callerStackTrace().fileName
-val __LINE__: Int get() = callerStackTrace().lineNumber
diff --git a/common/testutils/hostdevice/com/android/testutils/FunctionalUtils.java b/common/testutils/hostdevice/com/android/testutils/FunctionalUtils.java
deleted file mode 100644
index da36e4de..00000000
--- a/common/testutils/hostdevice/com/android/testutils/FunctionalUtils.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.function.Supplier;
-
-/**
- * A class grouping some utilities to deal with exceptions.
- */
-public class FunctionalUtils {
- /**
- * Like a Consumer, but declared to throw an exception.
- * @param <T>
- */
- @FunctionalInterface
- public interface ThrowingConsumer<T> {
- /** @see java.util.function.Consumer */
- void accept(T t) throws Exception;
- }
-
- /**
- * Like a Supplier, but declared to throw an exception.
- * @param <T>
- */
- @FunctionalInterface
- public interface ThrowingSupplier<T> {
- /** @see java.util.function.Supplier */
- T get() throws Exception;
- }
-
- /**
- * Like a Runnable, but declared to throw an exception.
- */
- @FunctionalInterface
- public interface ThrowingRunnable {
- /** @see java.lang.Runnable */
- void run() throws Exception;
- }
-
- /**
- * Convert a supplier that throws into one that doesn't.
- *
- * The returned supplier returns null in cases where the source throws.
- */
- public static <T> Supplier<T> ignoreExceptions(ThrowingSupplier<T> func) {
- return () -> {
- try {
- return func.get();
- } catch (Exception e) {
- return null;
- }
- };
- }
-
- /**
- * Convert a runnable that throws into one that doesn't.
- *
- * All exceptions are ignored by the returned Runnable.
- */
- public static Runnable ignoreExceptions(ThrowingRunnable r) {
- return () -> {
- try {
- r.run();
- } catch (Exception e) {
- }
- };
- }
-
- // Java has Function<T, R> and BiFunction<T, U, V> but nothing for higher-arity functions.
- // Function3 is what Kotlin and Scala use (they also have higher-arity variants, with
- // FunctionN taking N arguments, as the JVM does not have variadic formal parameters)
- /**
- * A function with three arguments.
- * @param <TArg1> Type of the first argument
- * @param <TArg2> Type of the second argument
- * @param <TArg3> Type of the third argument
- * @param <TResult> Type of the return value
- */
- public interface Function3<TArg1, TArg2, TArg3, TResult> {
- /**
- * Apply the function to the arguments
- */
- TResult apply(TArg1 a1, TArg2 a2, TArg3 a3);
- }
-}
diff --git a/common/testutils/hostdevice/com/android/testutils/MiscAsserts.kt b/common/testutils/hostdevice/com/android/testutils/MiscAsserts.kt
deleted file mode 100644
index 1883387c..00000000
--- a/common/testutils/hostdevice/com/android/testutils/MiscAsserts.kt
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-@file:JvmName("MiscAsserts")
-
-package com.android.testutils
-
-import com.android.testutils.FunctionalUtils.ThrowingRunnable
-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> assertEmpty(ts: Collection<T>) = ts.size.let { len ->
- assertEquals(0, len, "Expected empty collection, 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")
-}
-
-fun <T> assertLength(expected: Int, got: List<T>) = got.size.let { len ->
- assertEquals(expected, len, "Expected list of length $expected, but was $len for $got")
-}
-
-// Bridge method to help write this in Java. If you're writing Kotlin, consider using
-// kotlin.test.assertFailsWith instead, as that method is reified and inlined.
-fun <T : Exception> assertThrows(expected: Class<T>, block: ThrowingRunnable): T {
- return assertFailsWith(expected.kotlin) { block.run() }
-}
-
-fun <T : Exception> assertThrows(msg: String, expected: Class<T>, block: ThrowingRunnable): T {
- return assertFailsWith(expected.kotlin, msg) { 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 assertContainsStringsExactly(actual: Array<String>, vararg expected: String) {
- 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)
- 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) && !Modifier.isTransient(it.modifiers)
- }.size)
-}
-
-fun <T> assertSameElements(expected: List<T>, actual: List<T>) {
- val expectedSet: HashSet<T> = HashSet(expected)
- assertEquals(expectedSet.size, expected.size, "expected list contains duplicates")
- val actualSet: HashSet<T> = HashSet(actual)
- assertEquals(actualSet.size, actual.size, "actual list contains duplicates")
- assertEquals(expectedSet, actualSet)
-} \ No newline at end of file
diff --git a/common/testutils/hostdevice/com/android/testutils/NetworkStackModuleTest.kt b/common/testutils/hostdevice/com/android/testutils/NetworkStackModuleTest.kt
deleted file mode 100644
index fe312a09..00000000
--- a/common/testutils/hostdevice/com/android/testutils/NetworkStackModuleTest.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2023 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
-
-/**
- * Indicates that the test covers functionality that was rolled out in a NetworkStack module update.
- */
-annotation class NetworkStackModuleTest
diff --git a/common/testutils/hostdevice/com/android/testutils/PacketFilter.kt b/common/testutils/hostdevice/com/android/testutils/PacketFilter.kt
deleted file mode 100644
index 1bb6d683..00000000
--- a/common/testutils/hostdevice/com/android/testutils/PacketFilter.kt
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2020 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.net.Inet4Address
-import java.util.function.Predicate
-
-// Some of the below constants are duplicated with NetworkStackConstants, but this is a hostdevice
-// library usable for host-side tests, so device-side utils are not usable, and there is no
-// host-side non-test library to host common constants.
-private const val ETHER_TYPE_OFFSET = 12
-private const val ETHER_HEADER_LENGTH = 14
-private const val IPV4_PROTOCOL_OFFSET = ETHER_HEADER_LENGTH + 9
-private const val IPV6_PROTOCOL_OFFSET = ETHER_HEADER_LENGTH + 6
-private const val IPV4_CHECKSUM_OFFSET = ETHER_HEADER_LENGTH + 10
-private const val IPV4_DST_OFFSET = ETHER_HEADER_LENGTH + 16
-private const val IPV4_HEADER_LENGTH = 20
-private const val IPV6_HEADER_LENGTH = 40
-private const val IPV4_PAYLOAD_OFFSET = ETHER_HEADER_LENGTH + IPV4_HEADER_LENGTH
-private const val IPV6_PAYLOAD_OFFSET = ETHER_HEADER_LENGTH + IPV6_HEADER_LENGTH
-private const val UDP_HEADER_LENGTH = 8
-private const val BOOTP_OFFSET = IPV4_PAYLOAD_OFFSET + UDP_HEADER_LENGTH
-private const val BOOTP_TID_OFFSET = BOOTP_OFFSET + 4
-private const val BOOTP_CLIENT_MAC_OFFSET = BOOTP_OFFSET + 28
-private const val DHCP_OPTIONS_OFFSET = BOOTP_OFFSET + 240
-private const val ARP_OPCODE_OFFSET = ETHER_HEADER_LENGTH + 6
-
-/**
- * A [Predicate] that matches a [ByteArray] if it contains the specified [bytes] at the specified
- * [offset].
- */
-class OffsetFilter(val offset: Int, vararg val bytes: Byte) : Predicate<ByteArray> {
- override fun test(packet: ByteArray) =
- bytes.withIndex().all { it.value == packet[offset + it.index] }
-}
-
-private class UdpPortFilter(
- private val udpOffset: Int,
- private val src: Short?,
- private val dst: Short?
-) : Predicate<ByteArray> {
- override fun test(t: ByteArray): Boolean {
- if (src != null && !OffsetFilter(udpOffset,
- src.toInt().ushr(8).toByte(), src.toByte()).test(t)) {
- return false
- }
-
- if (dst != null && !OffsetFilter(udpOffset + 2,
- dst.toInt().ushr(8).toByte(), dst.toByte()).test(t)) {
- return false
- }
- return true
- }
-}
-
-/**
- * A [Predicate] that matches ethernet-encapped packets that contain an UDP over IPv4 datagram.
- */
-class IPv4UdpFilter @JvmOverloads constructor(
- srcPort: Short? = null,
- dstPort: Short? = null
-) : Predicate<ByteArray> {
- private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x08, 0x00 /* IPv4 */).and(
- OffsetFilter(IPV4_PROTOCOL_OFFSET, 17 /* UDP */)).and(
- UdpPortFilter(IPV4_PAYLOAD_OFFSET, srcPort, dstPort))
- override fun test(t: ByteArray) = impl.test(t)
-}
-
-/**
- * A [Predicate] that matches ethernet-encapped packets that contain an UDP over IPv6 datagram.
- */
-class IPv6UdpFilter @JvmOverloads constructor(
- srcPort: Short? = null,
- dstPort: Short? = null
-) : Predicate<ByteArray> {
- private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x86.toByte(), 0xdd.toByte() /* IPv6 */).and(
- OffsetFilter(IPV6_PROTOCOL_OFFSET, 17 /* UDP */)).and(
- UdpPortFilter(IPV6_PAYLOAD_OFFSET, srcPort, dstPort))
- override fun test(t: ByteArray) = impl.test(t)
-}
-
-/**
- * A [Predicate] that matches ethernet-encapped packets sent to the specified IPv4 destination.
- */
-class IPv4DstFilter(dst: Inet4Address) : Predicate<ByteArray> {
- private val impl = OffsetFilter(IPV4_DST_OFFSET, *dst.address)
- override fun test(t: ByteArray) = impl.test(t)
-}
-
-/**
- * A [Predicate] that matches ethernet-encapped ARP requests.
- */
-class ArpRequestFilter : Predicate<ByteArray> {
- private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x08, 0x06 /* ARP */)
- .and(OffsetFilter(ARP_OPCODE_OFFSET, 0x00, 0x01 /* request */))
- override fun test(t: ByteArray) = impl.test(t)
-}
-
-/**
- * A [Predicate] that matches ethernet-encapped DHCP packets sent from a DHCP client.
- */
-class DhcpClientPacketFilter : Predicate<ByteArray> {
- private val impl = IPv4UdpFilter(srcPort = 68, dstPort = 67)
- override fun test(t: ByteArray) = impl.test(t)
-}
-
-/**
- * A [Predicate] that matches a [ByteArray] if it contains a ethernet-encapped DHCP packet that
- * contains the specified option with the specified [bytes] as value.
- */
-class DhcpOptionFilter(val option: Byte, vararg val bytes: Byte) : Predicate<ByteArray> {
- override fun test(packet: ByteArray): Boolean {
- val option = findDhcpOption(packet, option) ?: return false
- return option.contentEquals(bytes)
- }
-}
-
-/**
- * Find a DHCP option in a packet and return its value, if found.
- */
-fun findDhcpOption(packet: ByteArray, option: Byte): ByteArray? =
- findOptionOffset(packet, option, DHCP_OPTIONS_OFFSET)?.let {
- val optionLen = packet[it + 1]
- return packet.copyOfRange(it + 2 /* type, length bytes */, it + 2 + optionLen)
- }
-
-private tailrec fun findOptionOffset(packet: ByteArray, option: Byte, searchOffset: Int): Int? {
- if (packet.size <= searchOffset + 2 /* type, length bytes */) return null
-
- return if (packet[searchOffset] == option) searchOffset else {
- val optionLen = packet[searchOffset + 1]
- findOptionOffset(packet, option, searchOffset + 2 + optionLen)
- }
-}
diff --git a/common/testutils/hostdevice/com/android/testutils/SkipMainlinePresubmit.kt b/common/testutils/hostdevice/com/android/testutils/SkipMainlinePresubmit.kt
deleted file mode 100644
index 59523651..00000000
--- a/common/testutils/hostdevice/com/android/testutils/SkipMainlinePresubmit.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2023 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
-
-/**
- * Skip the test in presubmit runs for the reason specified in [reason].
- *
- * This annotation is typically used to document limitations that prevent a test from being
- * executed in presubmit on older builds.
- */
-annotation class SkipMainlinePresubmit(val reason: String)
diff --git a/common/testutils/hostdevice/com/android/testutils/SkipPresubmit.kt b/common/testutils/hostdevice/com/android/testutils/SkipPresubmit.kt
deleted file mode 100644
index 69ed048f..00000000
--- a/common/testutils/hostdevice/com/android/testutils/SkipPresubmit.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2020 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
-
-/**
- * Skip the test in presubmit runs for the reason specified in [reason].
- *
- * This annotation is typically used to document hardware or test bench limitations.
- */
-annotation class SkipPresubmit(val reason: String) \ No newline at end of file