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

Fix ShadowPausedLooper to not use cached looperMode in unPause method #9069

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

warnyul
Copy link

@warnyul warnyul commented May 9, 2024

Overview

The unPause is called from resetLooperToInitialState, which means the cached looper mode might already have been reset. I think in unPause the looper mode should get from the registry.

Proposed Changes

Use ConfigurationRegistry.get(LooperMode.Mode.class) instead of looperMode() in the unPause method.

@utzcoz
Copy link
Member

utzcoz commented May 9, 2024

@warnyul Do you have evidence that it doesn't work as your expectation?

@warnyul
Copy link
Author

warnyul commented May 9, 2024

@utzcoz With jUnit 4 I do not have evidence, because in that case line 63 solves this issue in SandboxManager.java. Because the key contains the LooperMode, 2 different sandboxes will be created with 2 different ClassLoaders. One for PAUSED and one for INSTRUMENTATION_TEST mode.

I am only experiencing this issue with jUnit5, because I reuse the Sandbox. in this case it is important that the shadows are reset. Because I cannot create new classloader per test method, because it is limited in jUnit 5. If I could create a new ClassLoader that would solve the issue, like with jUnit 4. Because the ShadowPausedLooper class is loaded with two different ClassLoaders when I have two test methods annotated with different looper modes.

@warnyul warnyul force-pushed the shadow-paused-looper-reset-fix branch from b09431b to c63b5f1 Compare May 9, 2024 13:59
@hoisie
Copy link
Contributor

hoisie commented May 9, 2024

cc @brettchabot

Are you trying to reuse the same sandbox for some tests that use PAUSED looper mode (the default) and some tests that use INSTRUMENTATION_TEST looper mode? I am not sure if that is supported right now. @brettchabot would know more.

There are certain key parameters in Robolectric that will result in a new sandbox will be created. Looper mode is one of these. There is an LRU caching mechanism for sandboxes that tries to reuse sandboxes if possible.

static class SandboxKey {
private final Sdk sdk;
private final InstrumentationConfiguration instrumentationConfiguration;
private final ResourcesMode resourcesMode;
private final LooperMode.Mode looperMode;
private final GraphicsMode.Mode graphicsMode;
public SandboxKey(
InstrumentationConfiguration instrumentationConfiguration,
Sdk sdk,
ResourcesMode resourcesMode,
LooperMode.Mode looperMode,
GraphicsMode.Mode graphicsMode) {
this.sdk = sdk;
this.instrumentationConfiguration = instrumentationConfiguration;
this.resourcesMode = resourcesMode;
this.looperMode = looperMode;
this.graphicsMode = graphicsMode;

 public SandboxKey(
        InstrumentationConfiguration instrumentationConfiguration,
        Sdk sdk,
        ResourcesMode resourcesMode,
        LooperMode.Mode looperMode,
        GraphicsMode.Mode graphicsMode) {
      this.sdk = sdk;
      this.instrumentationConfiguration = instrumentationConfiguration;
      this.resourcesMode = resourcesMode;
      this.looperMode = looperMode;
      this.graphicsMode = graphicsMode;
    }

So in the JUnit4 version of Robolectric, if a test runs with PAUSED looper mode, and then a subsequent test runs with INSTRUMENTATION_TEST looper mode, a new sandbox will be created.

@warnyul
Copy link
Author

warnyul commented May 9, 2024

@hoisie Yes, I am trying to reuse the same sandbox. I have some test and it seems working: RobolectricExtensionLooperModeSelfTest

In this case I just cleared the cached looper mode with reflection: https://github.com/apter-tech/junit5-robolectric-extension/pull/59/files#diff-f70ad8af7998e9e21db351e4d56ed03a59eef332f56919716375605a09e1a889R73

…method

`unPause` is called from `resetLooperToInitialState` where the cached
looper mode maybe already cleared. Use LooperMode from the registry instead.
@warnyul warnyul force-pushed the shadow-paused-looper-reset-fix branch from c63b5f1 to a406659 Compare May 15, 2024 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants