diff options
author | Zhiyuan Wang <zhiyuanwang@google.com> | 2023-06-28 17:13:13 -0700 |
---|---|---|
committer | Yigit Boyar <yboyar@google.com> | 2023-07-05 14:51:46 -0700 |
commit | a93a3a20314193471209a5ad5256e2a7e774dd46 (patch) | |
tree | 3a526b48f177881d48fa106e5f46415a63de6219 | |
parent | c131ab6f18ae79451bcb03f72e27e60af0500f45 (diff) | |
download | support-a93a3a20314193471209a5ad5256e2a7e774dd46.tar.gz |
Update AndroidX to coroutines 1.7.1
Update MultiProcessDataStoreMultiProcessTest/DataMigrationInitializerTest use of dispatchTimeoutMs
Updated Compose async font tests to use the new dispatchers
Updated LazyPagingItemsTest to not assume context's isActive will be false on creation. In fact, this
is true as soon as it is created before it is used.
Updated GlanceAppWidgetReceiverTest to pass again. Made some changes in the code but overall also moved
it off of the coroutines testing APIs since it does not really use them. I tried to cleanup the hosts
but there is too much I don't understand to fully move those tests to coroutines.
Bug: b/285151193
Bug: b/289542327
Test: ./gradlew :datastore:datastore-core:test; ./gradlew :datastore:datastore-core:connectedAndroidTest
Change-Id: I4716cb02c83b5fa451fcb8af1f8fe0eb14958b57
16 files changed, 92 insertions, 93 deletions
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverImplCancellationTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverImplCancellationTest.kt index cbf8603f1d5..320737cdb91 100644 --- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverImplCancellationTest.kt +++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverImplCancellationTest.kt @@ -28,7 +28,7 @@ import androidx.test.platform.app.InstrumentationRegistry import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.TestCoroutineDispatcher +import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestCoroutineScope import kotlinx.coroutines.test.runCurrent import org.junit.After @@ -54,10 +54,8 @@ class FontFamilyResolverImplCancellationTest { fun setup() { asyncTypefaceCache = AsyncTypefaceCache() typefaceRequestCache = TypefaceRequestCache() - val dispatcher = TestCoroutineDispatcher() - scope = TestCoroutineScope(dispatcher).also { - dispatcher.pauseDispatcher() - } + val dispatcher = StandardTestDispatcher() + scope = TestCoroutineScope(dispatcher) val injectedContext = scope.coroutineContext.minusKey(CoroutineExceptionHandler) subject = FontFamilyResolverImpl( fontLoader, diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverImplPreloadTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverImplPreloadTest.kt index ad5dbea3c05..4bb5b4108c4 100644 --- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverImplPreloadTest.kt +++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverImplPreloadTest.kt @@ -32,9 +32,9 @@ import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.async +import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestCoroutineDispatcher import kotlinx.coroutines.test.TestCoroutineScope -import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.test.runCurrent import org.junit.Before @@ -187,7 +187,7 @@ class FontFamilyResolverImplPreloadTest { fun preload_errorsOnTimeout() { val font = AsyncFauxFont(typefaceLoader, FontWeight.Normal, FontStyle.Normal) val fallbackFont = AsyncFauxFont(typefaceLoader, FontWeight.Normal, FontStyle.Normal) - val dispatcher = TestCoroutineDispatcher() + val dispatcher = StandardTestDispatcher() val testScope = TestCoroutineScope(dispatcher) val fontFamily = FontFamily( @@ -195,7 +195,10 @@ class FontFamilyResolverImplPreloadTest { fallbackFont ) val deferred = testScope.async { subject.preload(fontFamily) } - testScope.advanceTimeBy(Font.MaximumAsyncTimeoutMillis) + testScope.testScheduler.apply { + advanceTimeBy(Font.MaximumAsyncTimeoutMillis) + runCurrent() + } assertThat(deferred.isCompleted).isTrue() testScope.runBlockingTest { deferred.await() // actually throw here diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterPreloadTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterPreloadTest.kt index 44a252f3a60..143c90f830e 100644 --- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterPreloadTest.kt +++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterPreloadTest.kt @@ -33,7 +33,6 @@ import kotlinx.coroutines.async import kotlinx.coroutines.launch import kotlinx.coroutines.test.TestCoroutineDispatcher import kotlinx.coroutines.test.TestCoroutineScope -import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runBlockingTest import org.junit.After import org.junit.Before @@ -194,7 +193,10 @@ class FontListFontFamilyTypefaceAdapterPreloadTest { subject.preload(fontFamily, fontLoader) } assertThat(typefaceLoader.pendingRequests()).containsExactly(asyncFont) - scope.advanceTimeBy(Font.MaximumAsyncTimeoutMillis) + scope.testScheduler.apply { + advanceTimeBy(Font.MaximumAsyncTimeoutMillis) + runCurrent() + } scope.runBlockingTest { preloadJob.await() } diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterTest.kt index e5de0d1a529..990e1cc9e9a 100644 --- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterTest.kt +++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterTest.kt @@ -40,9 +40,8 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.test.TestCoroutineDispatcher +import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestCoroutineScope -import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.test.runCurrent @@ -71,10 +70,8 @@ class FontListFontFamilyTypefaceAdapterTest { @Before fun setup() { cache = AsyncTypefaceCache() - val dispatcher = TestCoroutineDispatcher() - scope = TestCoroutineScope(dispatcher).also { - dispatcher.pauseDispatcher() - } + val dispatcher = StandardTestDispatcher() + scope = TestCoroutineScope(dispatcher) val injectedContext = scope.coroutineContext.minusKey(CoroutineExceptionHandler) subject = FontListFontFamilyTypefaceAdapter(cache, injectedContext) typefaceLoader = AsyncTestTypefaceLoader() @@ -290,7 +287,10 @@ class FontListFontFamilyTypefaceAdapterTest { assertThat(it).currentAsyncTypefaceValue(Typeface.DEFAULT) }, doCompleteAsync = { - scope.advanceTimeBy(Font.MaximumAsyncTimeoutMillis) + scope.testScheduler.apply { + advanceTimeBy(Font.MaximumAsyncTimeoutMillis) + runCurrent() + } scope.runCurrent() typefaceLoader.completeOne(asyncFontFallback, expected) } @@ -492,9 +492,7 @@ class FontListFontFamilyTypefaceAdapterTest { // make another paused dispatcher // it's important that this test uses paused dispatchers to allow us control of runtime // ordering - val newDispatcher = TestCoroutineDispatcher().also { - it.pauseDispatcher() - } + val newDispatcher = StandardTestDispatcher() subject = FontListFontFamilyTypefaceAdapter(injectedContext = newDispatcher) @@ -510,7 +508,7 @@ class FontListFontFamilyTypefaceAdapterTest { ) scope.runCurrent() - newDispatcher.runCurrent() + newDispatcher.scheduler.runCurrent() assertThat(typefaceLoader.pendingRequests()).containsExactly(asyncFont) typefaceLoader.completeOne(asyncFont, Typeface.SERIF) @@ -519,7 +517,7 @@ class FontListFontFamilyTypefaceAdapterTest { assertThat(result).currentAsyncTypefaceValue(Typeface.DEFAULT) // correct scope run completes - newDispatcher.runCurrent() + newDispatcher.scheduler.runCurrent() assertThat(finalResult.isActive).isFalse() assertThat(result).currentAsyncTypefaceValue(Typeface.SERIF) scope.runBlockingTest { diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt index 6a824291861..c2b3768b831 100644 --- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt +++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt @@ -47,7 +47,6 @@ import kotlinx.coroutines.flow.toList import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.test.runTest import kotlinx.coroutines.withTimeout -import kotlinx.coroutines.yield import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue @@ -385,14 +384,9 @@ class SuspendingPointerInputFilterTest { rule.runOnIdle { runTest { - withTimeout(400) { - while (!results.isClosedForSend) { - yield() - } + val received = withTimeout(400) { + results.receiveAsFlow().toList() } - - val received = results.receiveAsFlow().toList() - assertThat(received).hasSize(twoExpectedEvents.size) twoExpectedEvents.forEachIndexed { index, expectedEvent -> diff --git a/datastore/datastore-core/src/androidTest/java/androidx/datastore/core/MultiProcessDataStoreMultiProcessTest.kt b/datastore/datastore-core/src/androidTest/java/androidx/datastore/core/MultiProcessDataStoreMultiProcessTest.kt index 27d56411dbe..2e37fcaea9a 100644 --- a/datastore/datastore-core/src/androidTest/java/androidx/datastore/core/MultiProcessDataStoreMultiProcessTest.kt +++ b/datastore/datastore-core/src/androidTest/java/androidx/datastore/core/MultiProcessDataStoreMultiProcessTest.kt @@ -31,6 +31,7 @@ import java.io.FileOutputStream import java.io.IOException import java.io.OutputStreamWriter import kotlin.coroutines.CoroutineContext +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -153,7 +154,7 @@ class MultiProcessDataStoreMultiProcessTest { fun testSimpleUpdateData_okio() = testSimpleUpdateData_runner(StorageVariant.OKIO) private fun testSimpleUpdateData_runner(variant: StorageVariant) = - runTest(dispatchTimeoutMs = 10000) { + runTest(timeout = 10000.milliseconds) { val testData: Bundle = createDataStoreBundle(testFile.absolutePath, variant) val dataStore: DataStore<FooProto> = createDataStore(testData, dataStoreScope, context = dataStoreContext) @@ -195,7 +196,7 @@ class MultiProcessDataStoreMultiProcessTest { fun testConcurrentReadUpdate_okio() = testConcurrentReadUpdate_runner(StorageVariant.OKIO) private fun testConcurrentReadUpdate_runner(variant: StorageVariant) = - runTest(dispatchTimeoutMs = 10000) { + runTest(timeout = 10000.milliseconds) { val testData: Bundle = createDataStoreBundle(testFile.absolutePath, variant) val dataStore: DataStore<FooProto> = createDataStore(testData, dataStoreScope, context = dataStoreContext) @@ -272,7 +273,7 @@ class MultiProcessDataStoreMultiProcessTest { fun testInterleavedUpdateData_okio() = testInterleavedUpdateData_runner(StorageVariant.OKIO) private fun testInterleavedUpdateData_runner(variant: StorageVariant) = - runTest(UnconfinedTestDispatcher(), dispatchTimeoutMs = 10000) { + runTest(UnconfinedTestDispatcher(), timeout = 10000.milliseconds) { val testData: Bundle = createDataStoreBundle(testFile.absolutePath, variant) val dataStore: DataStore<FooProto> = createDataStore(testData, dataStoreScope, context = dataStoreContext) @@ -334,7 +335,7 @@ class MultiProcessDataStoreMultiProcessTest { testInterleavedUpdateDataWithLocalRead_runner(StorageVariant.OKIO) private fun testInterleavedUpdateDataWithLocalRead_runner(variant: StorageVariant) = - runTest(UnconfinedTestDispatcher(), dispatchTimeoutMs = 10000) { + runTest(UnconfinedTestDispatcher(), timeout = 10000.milliseconds) { val testData: Bundle = createDataStoreBundle(testFile.absolutePath, variant) val dataStore: DataStore<FooProto> = createDataStore(testData, dataStoreScope, context = dataStoreContext) @@ -427,7 +428,7 @@ class MultiProcessDataStoreMultiProcessTest { private fun testUpdateDataExceptionUnblocksOtherProcessFromWriting_runner( variant: StorageVariant - ) = runTest(dispatchTimeoutMs = 10000) { + ) = runTest(timeout = 10000.milliseconds) { val testData: Bundle = createDataStoreBundle(testFile.absolutePath, variant) val dataStore: DataStore<FooProto> = createDataStore(testData, dataStoreScope, context = dataStoreContext) @@ -492,7 +493,7 @@ class MultiProcessDataStoreMultiProcessTest { private fun testUpdateDataCancellationUnblocksOtherProcessFromWriting_runner( variant: StorageVariant - ) = runTest(UnconfinedTestDispatcher(), dispatchTimeoutMs = 10000) { + ) = runTest(UnconfinedTestDispatcher(), timeout = 10000.milliseconds) { val localScope = TestScope(UnconfinedTestDispatcher() + Job()) val testData: Bundle = createDataStoreBundle(testFile.absolutePath, variant) val dataStore: DataStore<FooProto> = @@ -554,7 +555,7 @@ class MultiProcessDataStoreMultiProcessTest { fun testReadUpdateCorrupt_okio() = testReadUpdateCorrupt_runner(StorageVariant.OKIO) private fun testReadUpdateCorrupt_runner(variant: StorageVariant) = - runTest(dispatchTimeoutMs = 10000) { + runTest(timeout = 10000.milliseconds) { FileOutputStream(testFile).use { OutputStreamWriter(it).write("garbage") } diff --git a/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/DataMigrationInitializerTest.kt b/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/DataMigrationInitializerTest.kt index c61f85854ea..0d86c087b90 100644 --- a/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/DataMigrationInitializerTest.kt +++ b/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/DataMigrationInitializerTest.kt @@ -23,6 +23,7 @@ import androidx.kruth.assertThat import androidx.kruth.assertThrows import kotlin.test.BeforeTest import kotlin.test.Test +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.async @@ -46,7 +47,7 @@ abstract class DataMigrationInitializerTest<F : TestFile, IOE : Throwable> } fun doTest(test: suspend TestScope.() -> Unit) { - testScope.runTest(dispatchTimeoutMs = 10000) { + testScope.runTest(timeout = 10000.milliseconds) { test(testScope) } } diff --git a/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesCompatibilityTest.kt b/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesCompatibilityTest.kt index 8ec132ad4d6..a7debaec943 100644 --- a/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesCompatibilityTest.kt +++ b/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesCompatibilityTest.kt @@ -18,6 +18,7 @@ package androidx.datastore.preferences.core import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.test.runTest import okio.Buffer import okio.ByteString.Companion.decodeBase64 @@ -28,7 +29,7 @@ import okio.ByteString.Companion.decodeBase64 class PreferencesCompatibilityTest { @Test - fun testWireCompatibility() = runTest(dispatchTimeoutMs = 10000) { + fun testWireCompatibility() = runTest(timeout = 10000.milliseconds) { // base64 output of serializing "expectedProto" val protoBase64 = "ChAKB215RmxvYXQSBRXNzIw/ChUKCG15RG91YmxlEgk5mpmZmZmZ8T8KCwoFbXlJbnQSAh" + diff --git a/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerTest.kt b/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerTest.kt index b2165582a40..6861ab47656 100644 --- a/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerTest.kt +++ b/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerTest.kt @@ -22,6 +22,7 @@ import androidx.datastore.core.okio.OkioSerializer import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import okio.FileSystem @@ -45,7 +46,7 @@ class PreferencesSerializerTest { fileSystem.createDirectories(testFile.path.parent!!) } fun doTest(test: suspend TestScope.() -> Unit) { - runTest(dispatchTimeoutMs = 10000) { + runTest(timeout = 10000.milliseconds) { test(this) } } diff --git a/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerJavaTest.kt b/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerJavaTest.kt index 74fb4058eba..6a2a86b4966 100644 --- a/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerJavaTest.kt +++ b/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerJavaTest.kt @@ -25,6 +25,7 @@ import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith import kotlin.test.assertTrue +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import okio.FileSystem @@ -46,7 +47,7 @@ class PreferencesSerializerJavaTest { fileSystem.createDirectories(testFile.path.parent!!) } fun doTest(test: suspend TestScope.() -> Unit) { - runTest(dispatchTimeoutMs = 10000) { + runTest(timeout = 10000.milliseconds) { test(this) } } diff --git a/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt b/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt index f9960bede84..22f4460382d 100644 --- a/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt +++ b/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt @@ -22,6 +22,7 @@ import android.graphics.Typeface import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.GradientDrawable import android.os.Build +import android.os.FileObserver import android.text.SpannedString import android.text.style.StyleSpan import android.text.style.TextAppearanceSpan @@ -103,18 +104,19 @@ import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicReference import kotlin.test.assertIs import kotlin.test.assertNotNull -import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.Job import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.collectIndexed +import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.take +import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.test.runTest import org.junit.After -import org.junit.Assert.assertThrows import org.junit.Before import org.junit.Rule import org.junit.Test @@ -126,7 +128,6 @@ const val VERBOSE_LOG = true const val RECEIVER_TEST_TAG = "GAWRT" // shorten to avoid long tag lint -@OptIn(ExperimentalCoroutinesApi::class) @SdkSuppress(minSdkVersion = 29) @MediumTest class GlanceAppWidgetReceiverTest { @@ -147,6 +148,7 @@ class GlanceAppWidgetReceiverTest { @After fun cleanUp() { TestGlanceAppWidget.resetOnDeleteBlock() + CompoundButtonActionTest.reset() } @Test @@ -622,27 +624,28 @@ class GlanceAppWidgetReceiverTest { val fileKey = createUniqueRemoteUiName((glanceId as AppWidgetId).appWidgetId) val preferencesFile = PreferencesGlanceStateDefinition.getLocation(context, fileKey) - assertThat(preferencesFile.exists()) - - val deleteLatch = CountDownLatch(1) - TestGlanceAppWidget.setOnDeleteBlock { - deleteLatch.countDown() + assertThat(preferencesFile.exists()).isTrue() + val fileIsDeleted = CountDownLatch(1) + val fileDeletionObserver = object : FileObserver(preferencesFile, DELETE_SELF) { + override fun onEvent(event: Int, path: String?) { + if (event == DELETE_SELF) { + fileIsDeleted.countDown() + } + } } - + fileDeletionObserver.startWatching() mHostRule.removeAppWidget() - - deleteLatch.await(5, TimeUnit.SECONDS) - val interval = 200L - for (timeout in 0..2000L step interval) { - if (!preferencesFile.exists()) return - Thread.sleep(interval) + try { + assertWithMessage("View state file is deleted").that( + fileIsDeleted.await(5, TimeUnit.SECONDS) + ).isTrue() + } finally { + fileDeletionObserver.stopWatching() } - assertWithMessage("View state file exists").that(preferencesFile.exists()) - .isFalse() } @Test - fun updateAll() = runTest { + fun updateAll() = runBlocking<Unit> { TestGlanceAppWidget.uiDefinition = { Text("text") } @@ -655,7 +658,7 @@ class GlanceAppWidgetReceiverTest { } @Test - fun updateIf() = runTest { + fun updateIf() = runBlocking<Unit> { val didRun = AtomicBoolean(false) TestGlanceAppWidget.uiDefinition = { currentState<Preferences>() @@ -687,7 +690,7 @@ class GlanceAppWidgetReceiverTest { didRun.set(false) // Waiting for the update should timeout since it is never triggered. - val exception = assertThrows(IllegalArgumentException::class.java) { + val updateResult = runCatching { // AppWidgetService may send an APPWIDGET_UPDATE broadcast, which is not relevant to // this and should be ignored. mHostRule.ignoreBroadcasts { @@ -700,7 +703,10 @@ class GlanceAppWidgetReceiverTest { } } } - assertThat(exception).hasMessageThat().contains("Timeout before getting RemoteViews") + assertThat(updateResult.exceptionOrNull()).apply { + isInstanceOf(IllegalArgumentException::class.java) + hasMessageThat().contains("Timeout before getting RemoteViews") + } assertThat(didRun.get()).isFalse() } @@ -839,7 +845,7 @@ class GlanceAppWidgetReceiverTest { } @Test - fun compoundButtonAction() = runTest { + fun compoundButtonAction() = runBlocking<Unit> { val checkbox = "checkbox" val switch = "switch" val checkBoxClicked = MutableStateFlow(false) @@ -938,7 +944,7 @@ class GlanceAppWidgetReceiverTest { @Test @SdkSuppress(minSdkVersion = 31) - fun lambdaActionCallback() = runTest { + fun lambdaActionCallback() = runBlocking<Unit> { TestGlanceAppWidget.uiDefinition = { val text = remember { mutableStateOf("initial") } Button( @@ -966,7 +972,7 @@ class GlanceAppWidgetReceiverTest { @Test @SdkSuppress(minSdkVersion = 29, maxSdkVersion = 30) - fun lambdaActionCallback_backportButton() = runTest { + fun lambdaActionCallback_backportButton() = runBlocking<Unit> { TestGlanceAppWidget.uiDefinition = { val text = remember { mutableStateOf("initial") } Button( @@ -993,7 +999,7 @@ class GlanceAppWidgetReceiverTest { } @Test - fun unsetActionCallback() = runTest { + fun unsetActionCallback() = runBlocking<Unit> { var enabled by mutableStateOf(true) TestGlanceAppWidget.uiDefinition = { Text( @@ -1025,7 +1031,7 @@ class GlanceAppWidgetReceiverTest { } @Test - fun unsetCompoundButtonActionCallback() = runTest { + fun unsetCompoundButtonActionCallback() = runBlocking<Unit> { TestGlanceAppWidget.uiDefinition = { val enabled = currentState<Preferences>()[testBoolKey] ?: true CheckBox( @@ -1040,15 +1046,12 @@ class GlanceAppWidgetReceiverTest { } mHostRule.startHost() - - CompoundButtonActionTest.received.set(emptyList()) - CompoundButtonActionTest.latch = CountDownLatch(1) + CompoundButtonActionTest.reset() mHostRule.onUnboxedHostView<ViewGroup> { root -> checkNotNull(root.findChild<TextView> { it.text.toString() == "checkbox" }) .performCompoundButtonClick() } - CompoundButtonActionTest.latch.await(5, TimeUnit.SECONDS) - assertThat(CompoundButtonActionTest.received.get()).containsExactly( + assertThat(CompoundButtonActionTest.nextValue()).containsExactly( "checkbox" to true ) @@ -1059,14 +1062,13 @@ class GlanceAppWidgetReceiverTest { TestGlanceAppWidget.update(context, AppWidgetId(mHostRule.appWidgetId)) } - CompoundButtonActionTest.received.set(emptyList()) - CompoundButtonActionTest.latch = CountDownLatch(1) + CompoundButtonActionTest.reset() mHostRule.onUnboxedHostView<ViewGroup> { root -> checkNotNull(root.findChild<TextView> { it.text.toString() == "checkbox" }) .performCompoundButtonClick() } - assertThat(CompoundButtonActionTest.latch.await(5, TimeUnit.SECONDS)).isFalse() - assertThat(CompoundButtonActionTest.received.get()).isEmpty() + delay(5.seconds) + assertThat(CompoundButtonActionTest.currentValue).isNull() } @SdkSuppress(minSdkVersion = 31) @@ -1150,7 +1152,7 @@ class GlanceAppWidgetReceiverTest { } @Test - fun cancellingContentCoroutineCausesContentToLeaveComposition() = runBlocking { + fun cancellingContentCoroutineCausesContentToLeaveComposition() = runBlocking<Unit> { val currentEffectState = MutableStateFlow(EffectState.Initial) var contentJob: Job? = null TestGlanceAppWidget.onProvideGlance = { @@ -1179,7 +1181,7 @@ class GlanceAppWidgetReceiverTest { } @Test - fun rootViewIdIsNotReservedId() = runTest { + fun rootViewIdIsNotReservedId() = runBlocking<Unit> { TestGlanceAppWidget.uiDefinition = { Column {} } @@ -1285,13 +1287,17 @@ internal class CompoundButtonActionTest : ActionCallback { ) { val target = checkNotNull(parameters[key]) val value = checkNotNull(parameters[ToggleableStateKey]) - received.update { it + (target to value) } - latch.countDown() + received.update { (it ?: emptyList()) + (target to value) } } companion object { - lateinit var latch: CountDownLatch - val received = AtomicReference<List<Pair<String, Boolean>>>(emptyList()) + private val received = MutableStateFlow<List<Pair<String, Boolean>>?>(null) val key = ActionParameters.Key<String>("eventTarget") + fun reset() { + received.value = null + } + val currentValue + get() = received.value + suspend fun nextValue() = received.filterNotNull().first() } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d57b8e5cbcd..1f2bc3d7c2c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,8 +40,7 @@ kotlin = "1.8.22" kotlinBenchmark = "0.4.8" kotlinNative = "1.8.22" kotlinCompileTesting = "1.4.9" -kotlinCoroutines = "1.6.4" -kotlinCoroutines171 = "1.7.1" +kotlinCoroutines = "1.7.1" kotlinSerialization = "1.3.3" ksp = "1.8.20-1.0.11" ktfmt = "0.44" @@ -171,7 +170,6 @@ kotlinCompileTestingKsp = { module = "com.github.tschuchortdev:kotlin-compile-te kotlinCoroutinesAndroid = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinCoroutines" } kotlinCoroutinesSwing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinCoroutines" } kotlinCoroutinesCore = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinCoroutines" } -kotlinCoroutinesCore171 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinCoroutines171" } kotlinCoroutinesGuava = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-guava", version.ref = "kotlinCoroutines" } kotlinCoroutinesPlayServices = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-play-services", version.ref = "kotlinCoroutines" } kotlinCoroutinesTest = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinCoroutines" } diff --git a/paging/paging-common/src/commonTest/kotlin/androidx/paging/CachedPageEventFlowLeakTest.kt b/paging/paging-common/src/commonTest/kotlin/androidx/paging/CachedPageEventFlowLeakTest.kt index 4789277654a..8876d5c895f 100644 --- a/paging/paging-common/src/commonTest/kotlin/androidx/paging/CachedPageEventFlowLeakTest.kt +++ b/paging/paging-common/src/commonTest/kotlin/androidx/paging/CachedPageEventFlowLeakTest.kt @@ -21,7 +21,6 @@ import kotlin.test.Ignore import kotlin.test.Test import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.cancel import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.flow.Flow @@ -33,7 +32,6 @@ import kotlinx.coroutines.test.runTest /** * reproduces b/203594733 */ -@OptIn(ExperimentalCoroutinesApi::class) public class CachedPageEventFlowLeakTest { private val gcHelper = GarbageCollectionTestHelper() diff --git a/paging/paging-compose/src/androidTest/java/androidx/paging/compose/LazyPagingItemsTest.kt b/paging/paging-compose/src/androidTest/java/androidx/paging/compose/LazyPagingItemsTest.kt index f98b422e1a8..b0c4f3b95ef 100644 --- a/paging/paging-compose/src/androidTest/java/androidx/paging/compose/LazyPagingItemsTest.kt +++ b/paging/paging-compose/src/androidTest/java/androidx/paging/compose/LazyPagingItemsTest.kt @@ -52,12 +52,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.isActive import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher -import org.junit.Assert.assertFalse import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -830,7 +828,6 @@ class LazyPagingItemsTest { } rule.runOnIdle { - assertFalse(context.isActive) // collection should not have started yet assertThat(lazyPagingItems.itemSnapshotList).isEmpty() } diff --git a/privacysandbox/ads/ads-adservices-java/build.gradle b/privacysandbox/ads/ads-adservices-java/build.gradle index 57b63adf9ff..9fd75171fa6 100644 --- a/privacysandbox/ads/ads-adservices-java/build.gradle +++ b/privacysandbox/ads/ads-adservices-java/build.gradle @@ -24,7 +24,7 @@ plugins { dependencies { api(libs.kotlinStdlib) - api(libs.kotlinCoroutinesCore171) + api(libs.kotlinCoroutinesCore) implementation("androidx.core:core-ktx:1.8.0") api("androidx.annotation:annotation:1.2.0") diff --git a/privacysandbox/ads/ads-adservices/build.gradle b/privacysandbox/ads/ads-adservices/build.gradle index 3e50880679a..a954990e6a3 100644 --- a/privacysandbox/ads/ads-adservices/build.gradle +++ b/privacysandbox/ads/ads-adservices/build.gradle @@ -26,7 +26,7 @@ plugins { dependencies { api(libs.kotlinStdlib) - api(libs.kotlinCoroutinesCore171) + api(libs.kotlinCoroutinesCore) implementation("androidx.core:core-ktx:1.8.0") api("androidx.annotation:annotation:1.6.0") |