Skip to content

Commit

Permalink
Expose _something_ from private modules used in tests where the test …
Browse files Browse the repository at this point in the history
…is validating that the parent can't re-bind something from the private module. If nothing is exposed, the child/private injector can otherwise be immediately GC'd (which then allows the parent to have the binding). (Note that there are other ways the child/private module could be captured: such as a Provider or its Injector being captured into a longer-lived Thread... but this is the simplest way to do it). This is happening with some regularity on the Github Actions tests, making the tests a bit flaky.

PiperOrigin-RevId: 529467328
  • Loading branch information
sameb authored and Guice Team committed May 4, 2023
1 parent 95a2fbb commit bb931fe
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
28 changes: 25 additions & 3 deletions core/test/com/google/inject/PrivateModuleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -646,19 +646,30 @@ private static class ManyPrivateModules extends AbstractModule {
@Override
protected void configure() {
// make sure duplicate sources are collapsed
install(new FailingPrivateModule());
install(new FailingPrivateModule());
install(new FailingPrivateModule("a"));
install(new FailingPrivateModule("b"));
// but additional sources are listed
install(new SecondFailingPrivateModule());
install(new SecondFailingPrivateModule("c"));
}
}

private static class FailingPrivateModule extends PrivateModule {
private final String exposeAs;

FailingPrivateModule(String exposeAs) {
this.exposeAs = exposeAs;
}

@Override
protected void configure() {
Key<List<String>> key = new Key<List<String>>() {};
bind(key).toInstance(new ArrayList<String>());

// Expose _something_ so that the child/private injector doesn't immediately get GC'd.
Key<String> exposedKey = new Key<String>(Names.named(exposeAs)) {};
bind(exposedKey).toInstance("exposed");
expose(exposedKey);

// Add the Provider<List> binding, created just-in-time,
// to make sure our linked JIT bindings have the correct source.
getProvider(key);
Expand All @@ -672,11 +683,22 @@ protected void configure() {

/** A second class, so we can see another name in the source list. */
private static class SecondFailingPrivateModule extends PrivateModule {
private final String exposeAs;

SecondFailingPrivateModule(String exposeAs) {
this.exposeAs = exposeAs;
}

@Override
protected void configure() {
Key<List<String>> key = new Key<List<String>>() {};
bind(key).toInstance(new ArrayList<String>());

// Expose _something_ so that the child/private injector doesn't immediately get GC'd.
Key<String> exposedKey = new Key<String>(Names.named(exposeAs)) {};
bind(exposedKey).toInstance("exposed");
expose(exposedKey);

// Add the Provider<List> binding, created just-in-time,
// to make sure our linked JIT bindings have the correct source.
getProvider(key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
import com.google.inject.AbstractModule;
import com.google.inject.ConfigurationException;
import com.google.inject.CreationException;
import com.google.inject.Exposed;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import com.google.inject.internal.InternalFlags;
import com.google.inject.internal.InternalFlags.IncludeStackTraceOption;
import javax.inject.Inject;
import javax.inject.Named;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -42,6 +44,14 @@ static class ChildModule extends PrivateModule {
protected void configure() {
bind(Foo.class).to(SubFoo.class);
}

// Expose _something_ so that the child/private injector doesn't immediately get GC'd.
@Provides
@Named("ChildModule")
@Exposed
String provideExposed() {
return "a";
}
}

@Test
Expand All @@ -61,6 +71,14 @@ protected void configure() {}
Foo provideFoo() {
return new Foo();
}

// Expose _something_ so that the child/private injector doesn't immediately get GC'd.
@Provides
@Named("Child2Module")
@Exposed
String provideExposed() {
return "a";
}
}

static class DependsOnFoo {
Expand Down Expand Up @@ -106,13 +124,29 @@ protected void configure() {
// Trigger a JIT binding for DependsOnFoo in this PrivateModule.
getProvider(DependsOnFoo.class);
}

// Expose _something_ so that the child/private injector doesn't immediately get GC'd.
@Provides
@Named("Child3Module")
@Exposed
String provideExposed() {
return "a";
}
}

static class ChildModule4 extends PrivateModule {
@Override
protected void configure() {
bind(DependsOnFoo.class).toInstance(new DependsOnFoo(new Foo()));
}

// Expose _something_ so that the child/private injector doesn't immediately get GC'd.
@Provides
@Named("Child4Module")
@Exposed
String provideExposed() {
return "a";
}
}

@Test
Expand Down

0 comments on commit bb931fe

Please sign in to comment.