Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: TestCoroutineDispatchers time out sometimes in large Espresso Tests #5379

Open
adhiamboperes opened this issue Apr 5, 2024 · 0 comments
Labels
bug End user-perceivable behaviors which are not desirable. Impact: Medium Moderate perceived user impact (non-blocking bugs and general improvements). Work: Medium The means to find the solution is clear, but it isn't at good-first-issue level yet.

Comments

@adhiamboperes
Copy link
Collaborator

adhiamboperes commented Apr 5, 2024

Describe the bug

StateFragmentTest and ExplorationActivityTest, do not run in espresso, with the failure:

java.lang.RuntimeException: java.util.concurrent.ExecutionException: androidx.test.espresso.IdlingResourceTimeoutException: Wait for [TestCoroutineDispatcherIdlingResource] to become idle timed out
at androidx.test.espresso.Espresso.onIdle(Espresso.java:342)
at androidx.test.espresso.Espresso.onIdle(Espresso.java:361)
at org.oppia.android.testing.threading.TestCoroutineDispatchersEspressoImpl.advanceUntilIdle(TestCoroutineDispatchersEspressoImpl.kt:45)
at org.oppia.android.testing.threading.TestCoroutineDispatchersEspressoImpl.runCurrent(TestCoroutineDispatchersEspressoImpl.kt:34)
at org.oppia.android.app.player.exploration.ExplorationActivityTest.testExplorationActivity_loadingAudio_progressbarIsDisplayed(ExplorationActivityTest.kt:1321)
...
androidx.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:527)
at org.oppia.android.testing.OppiaTestRule$apply$1.evaluate(OppiaTestRule.kt:47)
at org.oppia.android.testing.junit.InitializeDefaultLocaleRule$apply$1.evaluate(InitializeDefaultLocaleRule.kt:53)
...
Caused by: java.util.concurrent.ExecutionException: androidx.test.espresso.IdlingResourceTimeoutException: Wait for [TestCoroutineDispatcherIdlingResource] to become idle timed out
at java.util.concurrent.FutureTask.report(FutureTask.java:123)
at java.util.concurrent.FutureTask.get(FutureTask.java:193)
at androidx.test.espresso.Espresso.onIdle(Espresso.java:334)

Steps To Reproduce

  • Checkout develop
  • Select and run a test from the StateFragmentTest or ExplorationActivityTest in Espresso(Aside from the default verifyScreenNameInIntent test)

Expected Behavior

Test builds, runs and passes.

Screenshots/Videos

There are a variety of errors, but the most important one is:
java.lang.RuntimeException: java.util.concurrent.ExecutionException: androidx.test.espresso.IdlingResourceTimeoutException: Wait for [TestCoroutineDispatcherIdlingResource] to become idle timed out

Another common failure:
Test instrumentation process crashed. Check org.oppia.android.app.player.exploration.ExplorationActivityTest#testExplorationActivity_hasCorrectActivityLabel.txt for details

The details, which you can. read from Logcat, are as follows:

org.oppia.android E/AndroidRuntime: FATAL EXCEPTION: main
    Process: org.oppia.android, PID: 9146
    kotlin.UninitializedPropertyAccessException: lateinit property profileId has not been initialized
        at org.oppia.android.domain.exploration.ExplorationProgressController.getCurrentState(ExplorationProgressController.kt:372)
        at org.oppia.android.app.player.state.StateFragmentPresenter$ephemeralStateLiveData$2.invoke(StateFragmentPresenter.kt:103)
        at org.oppia.android.app.player.state.StateFragmentPresenter$ephemeralStateLiveData$2.invoke(StateFragmentPresenter.kt:68)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at org.oppia.android.app.player.state.StateFragmentPresenter.getEphemeralStateLiveData(Unknown Source:2)
        at org.oppia.android.app.player.state.StateFragmentPresenter.subscribeToCurrentState(StateFragmentPresenter.kt:289)
        at org.oppia.android.app.player.state.StateFragmentPresenter.handleCreateView(StateFragmentPresenter.kt:168)
        at org.oppia.android.app.player.state.StateFragment.onCreateView(StateFragment.kt:82)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2695)
        ...
        at org.oppia.android.app.player.exploration.ExplorationActivityPresenter.loadExplorationFragment(ExplorationActivityPresenter.kt:198)
        at org.oppia.android.app.player.exploration.ExplorationActivity.onDefaultFontSizeLoaded(ExplorationActivity.kt:178)
        at org.oppia.android.app.player.exploration.ExplorationManagerFragmentPresenter$handleCreate$1.onChanged(ExplorationManagerFragmentPresenter.kt:32)
        at org.oppia.android.app.player.exploration.ExplorationManagerFragmentPresenter$handleCreate$1.onChanged(ExplorationManagerFragmentPresenter.kt:19)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
        at androidx.lifecycle.Transformations$1.onChanged(Transformations.java:76)
        at androidx.lifecycle.MediatorLiveData$Source.onChanged(MediatorLiveData.java:152)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
        at org.oppia.android.util.data.DataProviders$NotifiableAsyncLiveData.setValue(DataProviders.kt:405)
2024-04-05 22:34:29.056 9146-9146/org.oppia.android E/AndroidRuntime:     at org.oppia.android.util.data.DataProviders$NotifiableAsyncLiveData.setValue(DataProviders.kt:354)
        at androidx.lifecycle.LiveData$1.run(LiveData.java:91)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2024-04-05 22:34:29.057 9146-9146/org.oppia.android E/InstrumentationResultPrinter: Failed to mark test No Tests as finished after process crash
2024-04-05 22:34:29.057 9146-9146/org.oppia.android E/MonitoringInstr: Exception encountered by: Thread[main,5,main]. Dumping thread state to outputs and pining for the fjords.

What device/emulator are you using?

Nexus 9 emulator Pixel 3A emulator

Which Android version is your device/emulator running?

Api 29,

Which version of the Oppia Android app are you using?

Developer build

Additional Context

I read this discussion on the cause of the timeout: https://stackoverflow.com/questions/53197993/why-is-androidx-espresso-check-causing-androidx-test-espresso-idlingresourcet

@Akshatkamboj14 reported this in a discussion in the CLaM groupchat: https://docs.google.com/document/d/1bDlGkkuhDXUv04KWve4OXC11srj7jTFWdIpiCgA93NI/edit#heading=h.jl2gn54iqprw, and @BenHenning suggested:

this could potentially be caused by an animation (I'm guessing the light bulb animation in this case) as it will cause the test coroutine dispatchers to never become idle. We should probably be disabling that animation for the tests, though unfortunately the PR that was introducing a platform parameter for that hasn't yet been merged (and needs to be revived)

@BenHenning in a seperate thread explained:

Whenever you encounter an Espresso flake, it's helpful to know how Espresso behaves when reasoning about what could be going wrong.

Espresso more or less will wait to execute commands passed to it until the app is idle. It defines this by the UI thread not having things to execute over a short time window (I don't recall the exact number, but I think it's less than 1 second) as well as all IdlingResources reporting an idle state. If your test registers an idling resource with TestCoroutineDispatchers in setUp(), then this will ensure Espresso will wait for all of Oppia's background tasks AND the UI response to them to complete before running its operations.

This helps with deduction: it eliminates guesswork somewhat. A flake here may indicate that the dispatcher idling resources isn't being registered, or that there's a task along the pipeline being schedule (likely on the UI thread) to run a bit longer than the normal waiting period for idleness (this can be trickier to dig into).

I use an M1 Mac, and @ShubhadeepKarmakar and @theMr17 who have reported the same issue both use Windows PC.

@adhiamboperes adhiamboperes added Impact: Medium Moderate perceived user impact (non-blocking bugs and general improvements). bug End user-perceivable behaviors which are not desirable. Work: Medium The means to find the solution is clear, but it isn't at good-first-issue level yet. labels Apr 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug End user-perceivable behaviors which are not desirable. Impact: Medium Moderate perceived user impact (non-blocking bugs and general improvements). Work: Medium The means to find the solution is clear, but it isn't at good-first-issue level yet.
Development

No branches or pull requests

1 participant