summaryrefslogtreecommitdiff
path: root/common/testutils/hostdevice/com/android/testutils/Cleanup.kt
diff options
context:
space:
mode:
Diffstat (limited to 'common/testutils/hostdevice/com/android/testutils/Cleanup.kt')
-rw-r--r--common/testutils/hostdevice/com/android/testutils/Cleanup.kt125
1 files changed, 0 insertions, 125 deletions
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)
-}