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

External ports are cached between tests #246

Open
csokol opened this issue Aug 9, 2018 · 1 comment
Open

External ports are cached between tests #246

csokol opened this issue Aug 9, 2018 · 1 comment

Comments

@csokol
Copy link

csokol commented Aug 9, 2018

I'm facing a similar problem reported in #200. After a bit of debugging, it seems like the rule doesn't call stop/start or the containers are cached in ContainerCache between two tests. So if the rule runs docker compose down then docker compose up, the ports might change and this doesn't get reflected in the container objects.

I noticed this problem when trying to create a base class with a shared docker compose rule config.

For example:

docker-compose.yml

version: '2.1'
services:
  redis:
    image: redis:3.2-alpine
    ports:
    - "6379"
public abstract class Base {
  @ClassRule
  public static DockerComposeRule dockerComposeRule = DockerComposeRule.builder()
      .file(new File("./docker-compose.yml")
          .getAbsolutePath())
      .waitingForService("redis", toHaveAllPortsOpen(), Duration.standardSeconds(10))
      .build();
}

public class Foo1Test extends Base {
  @Test
  public void doit() {
    Assert.assertTrue(true);
  }
}

public class Foo2Test extends Base {
  @Test
  public void doit() {
    Assert.assertTrue(true);
  }
}

Here's the output when I run both tests:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running foo.Foo1Test
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.378 sec
Running foo.Foo2Test
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 12.753 sec <<< FAILURE!
foo.Foo2Test  Time elapsed: 12.751 sec  <<< ERROR!
java.lang.IllegalStateException: The cluster failed to pass a startup check: The following ports failed to open: [6379]
	at com.palantir.docker.compose.connection.waiting.ClusterWait.waitUntilReady(ClusterWait.java:50)
	at com.palantir.docker.compose.DockerComposeRule.lambda$before$0(DockerComposeRule.java:155)
	at java.lang.Iterable.forEach(Iterable.java:75)
	at com.palantir.docker.compose.DockerComposeRule.before(DockerComposeRule.java:155)
	at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:46)
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)


Results :

Tests in error:
  foo.Foo2Test: The cluster failed to pass a startup check: The following ports failed to open: [6379]

Tests run: 2, Failures: 0, Errors: 1, Skipped: 0

Any ideas on how to fix it?

@csokol
Copy link
Author

csokol commented Aug 10, 2018

For reference, I was able to find a hacky solution by resetting the container cache through reflection:

public class CustomDockerComposeRule extends ExternalResource {
  private DockerComposeRule delegate;

  public CustomDockerComposeRule(DockerComposeRule delegate) {
    this.delegate = delegate;
  }

  @Override
  protected void before() throws Throwable {
    ContainerCache containerCache = delegate.containers().containerCache();
    FieldUtils.writeField(containerCache, "containers", new HashMap<>(), true);
    delegate.before();
  }

  @Override
  protected void after() {
    delegate.after();
  }
}

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

No branches or pull requests

1 participant