From b6fdf63095f59539c48df9e21a1f369e272bbb59 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Mon, 22 Nov 2021 19:28:34 +0900 Subject: [PATCH] tryTest to return its last evaluated expression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the same thing try{} does, and allows to lift return out of tryTest. This allows syntaxes likeĀ : fun foo() = try { "Foo"; } cleanup { doSomeCleanup() } } val network = try { registerNetworkCallback callback.getNetwork() } cleanup { unregisterNetworkCallback } } Note: bypassing ktlint because of b/185077240 Test: FrameworksNetTests Change-Id: Ib8f6fde7ccfd62fdcb3c1e3b7b03909ed94d4b23 --- .../android/net/module/util/CleanupTest.kt | 9 +++- .../net/module/util/CleanupTestJava.java | 4 +- staticlibs/testutils/Android.bp | 48 +++++++++++-------- .../com/android/testutils/Cleanup.kt | 34 +++++++------ 4 files changed, 59 insertions(+), 36 deletions(-) diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt index 05faed1cb0..cc0f9bec14 100644 --- a/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt +++ b/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt @@ -34,15 +34,17 @@ class CleanupTest { @Test fun testNotThrow() { var x = 1 - tryTest { + val result = tryTest { x = 2 Log.e(TAG, "Do nothing") + 6 } cleanup { assertTrue(x == 2) x = 3 Log.e(TAG, "Do nothing") } assertTrue(x == 3) + assertTrue(result == 6) } @Test @@ -99,4 +101,9 @@ class CleanupTest { assertTrue(thrown.suppressedExceptions[0] is TestException2) assertTrue(x == 4) } + + @Test + fun testReturn() { + assertTrue(6 == tryTest { 6 } cleanup { Log.e(TAG, "tested") }) + } } diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTestJava.java b/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTestJava.java index ba4e679eb1..83abfa16d6 100644 --- a/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTestJava.java +++ b/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTestJava.java @@ -35,14 +35,16 @@ public class CleanupTestJava { @Test public void testNotThrow() { final AtomicInteger x = new AtomicInteger(1); - testAndCleanup(() -> { + final int a = testAndCleanup(() -> { x.compareAndSet(1, 2); Log.e(TAG, "Do nothing"); + return 6; }, () -> { x.compareAndSet(2, 3); Log.e(TAG, "Do nothing"); }); assertEquals(3, x.get()); + assertEquals(6, a); } @Test diff --git a/staticlibs/testutils/Android.bp b/staticlibs/testutils/Android.bp index 2f0bcc3951..29df759b04 100644 --- a/staticlibs/testutils/Android.bp +++ b/staticlibs/testutils/Android.bp @@ -42,26 +42,34 @@ java_library { } java_library { - // Consider using net-tests-utils instead if writing device code. - // That library has a lot more useful tools into it for users that - // work on Android and includes this lib. - name: "net-tests-utils-host-device-common", - srcs: [ - "hostdevice/**/*.java", - "hostdevice/**/*.kt", - ], - host_supported: true, - visibility: [ - "//frameworks/libs/net/common/tests:__subpackages__", - "//frameworks/libs/net/client-libs/tests:__subpackages__", - ], - libs: [ - "jsr305", - ], - static_libs: [ - "kotlin-test" - ], - lint: { strict_updatability_linting: true }, + // Consider using net-tests-utils instead if writing device code. + // That library has a lot more useful tools into it for users that + // work on Android and includes this lib. + name: "net-tests-utils-host-device-common", + srcs: [ + "hostdevice/**/*.java", + "hostdevice/**/*.kt", + ], + host_supported: true, + visibility: [ + "//frameworks/libs/net/common/tests:__subpackages__", + "//frameworks/libs/net/client-libs/tests:__subpackages__", + ], + // sc-mainline-prod uses an old version of Kotlin that used + // to reserve the right to make breaking changes to the + // Result type and disallowed returning an instance of it. + // Later versions allowed this and there was never a change, + // so no matter the version returning Result is always fine, + // but on sc-mainline-prod the compiler rejects it without + // the following flag. + kotlincflags: ["-Xallow-result-return-type"], + libs: [ + "jsr305", + ], + static_libs: [ + "kotlin-test" + ], + lint: { strict_updatability_linting: true }, } java_test_host { diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt b/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt index bacbbe35b8..d93c7d0893 100644 --- a/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt +++ b/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt @@ -19,6 +19,7 @@ package com.android.testutils import com.android.testutils.ExceptionUtils.ThrowingRunnable +import com.android.testutils.ExceptionUtils.ThrowingSupplier import javax.annotation.CheckReturnValue /** @@ -59,11 +60,15 @@ import javax.annotation.CheckReturnValue * cleanup code * }); */ -class ExceptionCleanupBlock(val originalException: Exception?) { - inline infix fun cleanup(block: () -> Unit) { +// sc-mainline-prod has an older kotlin that doesn't know about value classes. TODO : Change this +// to "value class" when aosp no longer merges into sc-mainline-prod. +@Suppress("INLINE_CLASS_DEPRECATED") +inline class ExceptionCleanupBlock(val result: Result) { + inline infix fun cleanup(block: () -> Unit): T { try { block() } catch (e: Exception) { + val originalException = result.exceptionOrNull() if (null == originalException) { throw e } else { @@ -71,25 +76,26 @@ class ExceptionCleanupBlock(val originalException: Exception?) { throw originalException } } - if (null != originalException) throw originalException + return result.getOrThrow() } } @CheckReturnValue -fun tryTest(block: () -> Unit): ExceptionCleanupBlock { - try { - block() - } catch (e: Exception) { - return ExceptionCleanupBlock(e) - } - return ExceptionCleanupBlock(null) -} +fun tryTest(block: () -> T) = ExceptionCleanupBlock( + try { + Result.success(block()) + } catch (e: Exception) { + Result.failure(e) + }) // Java support -fun testAndCleanup(tryBlock: ThrowingRunnable, cleanupBlock: ThrowingRunnable) { - tryTest { - tryBlock.run() +fun testAndCleanup(tryBlock: ThrowingSupplier, cleanupBlock: ThrowingRunnable): T { + return tryTest { + tryBlock.get() } cleanup { cleanupBlock.run() } } +fun testAndCleanup(tryBlock: ThrowingRunnable, cleanupBlock: ThrowingRunnable) { + return testAndCleanup(ThrowingSupplier { tryBlock.run() }, cleanupBlock) +}