android / nowinandroid

A fully functional Android app built entirely with Kotlin and Jetpack Compose
Apache License 2.0
16.07k stars 2.85k forks source link

[Bug]: The unit test offlineFirstTopicsRepository_toggle_followed_topics_logic_delegates_to_nia_preferences() failed #98

Open Bwaim opened 2 years ago

Bwaim commented 2 years ago

Is there an existing issue for this?

Is there a StackOverflow question about this issue?

What happened?

Windows environment Running the unit test offlineFirstTopicsRepository_toggle_followed_topics_logic_delegates_to_nia_preferences() fails. There is an exception thrown that is cached but the log of this exception causes crash because it's not mocked, the original exception is :

java.io.IOException: Unable to rename C:\xxxxx\Temp\junit2206256684596171052\user_preferences_test.pb.tmp.This likely means that there are multiple instances of DataStore for this file. Ensure that you are only creating a single instance of datastore for this file.

The stacktrace :

androidx.datastore.core.SingleProcessDataStore.writeData$datastore_core(SingleProcessDataStore.kt:433)
androidx.datastore.core.SingleProcessDataStore.transformAndWrite(SingleProcessDataStore.kt:410)
androidx.datastore.core.SingleProcessDataStore.access$transformAndWrite(SingleProcessDataStore.kt:76)
androidx.datastore.core.SingleProcessDataStore$transformAndWrite$1.invokeSuspend(SingleProcessDataStore.kt)
\b\b\b(Coroutine boundary.\b(\b)
com.google.samples.apps.nowinandroid.core.datastore.NiaPreferences.toggleFollowedTopicId(NiaPreferences.kt:46)
com.google.samples.apps.nowinandroid.core.data.repository.OfflineFirstTopicsRepositoryTest$offlineFirstTopicsRepository_toggle_followed_topics_logic_delegates_to_nia_preferences$1.invokeSuspend(OfflineFirstTopicsRepositoryTest.kt:190)

I think the problem is because the test was executed under a Windows environment and the rename failed on that platform (SingleProcessDataStore.kt : 432) :

            if (!scratchFile.renameTo(file)) {
                throw IOException(
                    "Unable to rename $scratchFile." +
                        "This likely means that there are multiple instances of DataStore " +
                        "for this file. Ensure that you are only creating a single instance of " +
                        "datastore for this file."
                )
            }

Relevant logcat output

Method e in android.util.Log not mocked. See http://g.co/androidstudio/not-mocked for details.
java.lang.RuntimeException: Method e in android.util.Log not mocked. See http://g.co/androidstudio/not-mocked for details.
    at android.util.Log.e(Log.java)
    at com.google.samples.apps.nowinandroid.core.datastore.NiaPreferences.toggleFollowedTopicId(NiaPreferences.kt:59)
    at com.google.samples.apps.nowinandroid.core.datastore.NiaPreferences$toggleFollowedTopicId$1.invokeSuspend(NiaPreferences.kt)

Code of Conduct

Rocksnake commented 2 years ago

I think the reason should be that two DataStore's writing at the same time, one of the renames seems to be failing, because the file no longer exists.

I think the place where the problem occurs should be in the TestDataStoreModule.kt file, We should instead create the DataStore once, then inject the instance where necessary or manage it as a singleton. image

alexvanyo commented 1 year ago

Hi, is this still an issue with the latest version?

SimonMarquis commented 1 year ago

FWIW, on a Windows machine, I'm unable to run the whole test suite. Many unit tests fail while SingleProcessDataStore tries to write the new data as shown above.

SimonMarquis commented 1 year ago

It seems to be a known issue on Windows:

SimonMarquis commented 4 months ago

androidx.datastore:datastore-*:1.1.0-beta02 landed:

Fixed the issue where file rename fails during updateData in non-Android JVM environments. (b/203087070) https://developer.android.com/jetpack/androidx/releases/datastore#1.1.0-beta02

Unfortunately, the issue persists...

JackEblan commented 4 months ago

Hello @SimonMarquis I am also experiencing this java.io.IOException: Unable to rename C:\Users\User\AppData\Local\Temp\junit481202955115791832\user_preferences_test.pb.tmp.This likely means that there are multiple instances of DataStore for this file. Ensure that you are only creating a single instance of datastore for this file. Is there a way to make this work on my Windows 10?

SimonMarquis commented 4 months ago

No, but you can ⭐ & +1 this issue: https://issuetracker.google.com/issues/203087070

SimonMarquis commented 1 week ago

@Bwaim a fix has been implemented in #1542, can you check if the fix works for you as well?

Bwaim commented 1 week ago

@SimonMarquis unfortunately I can't check as I don't have a Windows anymore 😞