ankidroid / Anki-Android

AnkiDroid: Anki flashcards on Android. Your secret trick to achieve superhuman information retention.
GNU General Public License v3.0
8.63k stars 2.23k forks source link

flaky test: `DeckPickerWidgetConfigTest > testLoadSavedPreferences` #17010

Closed david-allison closed 1 month ago

david-allison commented 2 months ago
DeckPickerWidgetConfigTest > testLoadSavedPreferences FAILED
    java.lang.IllegalStateException: unhandled exception
        at com.ichi2.testutils.common.FailOnUnhandledExceptionRule$apply$1.evaluate(FailOnUnhandledExceptionRule.kt:64)
        at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:489)
        at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$2(SandboxTestRunner.java:291)
        at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:104)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
        at java.base/java.lang.Thread.run(Thread.java:1583)

        Caused by:
        java.lang.NullPointerException
            at com.ichi2.libanki.Collection.getDb(Collection.kt:99)
            at com.ichi2.libanki.Decks.cardCount(Decks.kt:251)
            at com.ichi2.widget.deckpicker.DeckPickerWidgetConfig.isDefaultDeckEmpty(DeckPickerWidgetConfig.kt:[289](https://github.com/ankidroid/Anki-Android/actions/runs/10640871215/job/29501280821?pr=17004#step:7:290))
            at com.ichi2.widget.deckpicker.DeckPickerWidgetConfig.access$isDefaultDeckEmpty(DeckPickerWidgetConfig.kt:60)
            at com.ichi2.widget.deckpicker.DeckPickerWidgetConfig$isDefaultDeckEmpty$1.invokeSuspend(DeckPickerWidgetConfig.kt)
            at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
            at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
            at android.os.Handler.$$robo$$android_os_Handler$handleCallback(Handler.java:958)
            at android.os.Handler.handleCallback(Handler.java)
            at android.os.Handler.$$robo$$android_os_Handler$dispatchMessage(Handler.java:99)
            at android.os.Handler.dispatchMessage(Handler.java)
            at org.robolectric.shadows.ShadowPausedLooper$IdlingRunnable.doRun(ShadowPausedLooper.java:600)
            at org.robolectric.shadows.ShadowPausedLooper$ControlRunnable.run(ShadowPausedLooper.java:563)
            at org.robolectric.shadows.ShadowPausedLooper.executeOnLooper(ShadowPausedLooper.java:685)
            at org.robolectric.shadows.ShadowPausedLooper.idle(ShadowPausedLooper.java:104)
            at org.robolectric.shadows.ShadowPausedLooper.idleFor(ShadowPausedLooper.java:113)
            at org.robolectric.shadows.ShadowLooper.idleFor(ShadowLooper.java:223)
            at org.robolectric.shadows.ShadowPausedLooper.runToEndOfTasks(ShadowPausedLooper.java:189)
            at org.robolectric.android.internal.LooperDelegatingScheduler.advanceToLastPostedRunnable(LooperDelegatingScheduler.java:93)
            at org.robolectric.Robolectric.flushForegroundThreadScheduler(Robolectric.java:374)
            at com.ichi2.anki.widget.deckpicker.DeckPickerWidgetConfigTest.testLoadSavedPreferences(DeckPickerWidgetConfigTest.kt:110)
david-allison commented 2 months ago

@xenonnn4w FYI

david-allison commented 1 month ago
DeckPickerWidgetConfigTest > testLoadSavedPreferences FAILED
    java.lang.AssertionError: 
    Expected: <1>
         but: was <0>
        at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
        at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
        at com.ichi2.anki.widget.deckpicker.DeckPickerWidgetConfigTest.testLoadSavedPreferences(DeckPickerWidgetConfigTest.kt:108)
-- executing test "testLoadSavedPreferences"
D/ChangeManager: clearing 1 subscribers
I/Themes: Setting theme to LIGHT
I/AnkiDroidApp$onCreate: DeckPickerWidgetConfig::onCreate
I/ScopedStorageService: isLegacyStorage(): false
W/VirtualDeviceManager: Failed to retrieve virtual devices; no virtual device manager service.
D/Backend: Opening rust backend with lang=[en-US]
I/Collection: (Re)opening Database: C:\Users\RUNNER~1\AppData\Local\Temp\robolectric-DeckPickerWidgetConfigTest_testLoadSavedPreferences13350412591225695864\external-files\Android\data\com.ichi2.anki.debug\AnkiDroid\collection.anki2
I/AnkiActivity: finishWithAnimation DEFAULT
I/AnkiDroidApp$onCreate: DeckPickerWidgetConfig::onStart
I/AnkiDroidApp$onCreate: DeckPickerWidgetConfig::onResume
D/UsageAnalytics: sendAnalyticsScreenView(): DeckPickerWidgetConfig
D/UsageAnalytics: getOptIn() status: false
I/RobolectricTest: closeCollection: RobolectricTest: End
I/Collection: Collection closed
-- completed test "testLoadSavedPreferences"
david-allison commented 1 month ago

Two issues:

  1. (my report, above: https://github.com/ankidroid/Anki-Android/issues/17010#issuecomment-2358781483)
    • Class is not initialized properly (it detects an empty collection and exits)
    • Updating the adapter is not properly awaited

  1. (original post)
    • updateFabVisibility launches a task under lifecycleScope, which is not cancelled on collection close
    • We do not wait for this task during a unit test