diff --git a/doc/changelog.md b/doc/changelog.md index ec8b07c..d26078c 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -4,6 +4,7 @@ Changes: +- ([#38](../../../issues/38)) Allow definition of restart policy on container start - ([#36](../../../issues/36)) Change docker client dependency to non-shaded - ([#34](../../../issues/34)) Expose underlying Docker API ContainerInfo to rule clients - ([#35](../../../issues/35)) Allow defining custom container startup conditions. diff --git a/src/main/java/pl/domzal/junit/docker/rule/DockerRule.java b/src/main/java/pl/domzal/junit/docker/rule/DockerRule.java index fde3cd2..341a9b9 100644 --- a/src/main/java/pl/domzal/junit/docker/rule/DockerRule.java +++ b/src/main/java/pl/domzal/junit/docker/rule/DockerRule.java @@ -105,11 +105,15 @@ public static DockerRuleBuilder builder() { */ @Override public final void before() throws Throwable { - HostConfig hostConfig = HostConfig.builder()// + HostConfig.Builder hostConfigBuilder = HostConfig.builder() .publishAllPorts(builder.publishAllPorts())// .portBindings(builder.hostPortBindings())// .binds(builder.binds())// - .links(links())// + .links(links()); + if (builder.restartPolicy() != null) { + hostConfigBuilder.restartPolicy(builder.restartPolicy().getRestartPolicy()); + } + HostConfig hostConfig = hostConfigBuilder .extraHosts(builder.extraHosts())// .build(); ContainerConfig containerConfig = ContainerConfig.builder()// diff --git a/src/main/java/pl/domzal/junit/docker/rule/DockerRuleBuilder.java b/src/main/java/pl/domzal/junit/docker/rule/DockerRuleBuilder.java index d5eb4ac..f61c224 100644 --- a/src/main/java/pl/domzal/junit/docker/rule/DockerRuleBuilder.java +++ b/src/main/java/pl/domzal/junit/docker/rule/DockerRuleBuilder.java @@ -43,6 +43,8 @@ public class DockerRuleBuilder { private StopOption.StopOptionSet stopOptions = new StopOption.StopOptionSet(); + private RestartPolicy restartPolicy; + DockerRuleBuilder(){} public DockerRule build() { @@ -482,4 +484,16 @@ public DockerRuleBuilder addLabel(String name, String value) { Map getLabels() { return labels; } + + /** + * Set container restart policy. If not set - default restart + * policy 'no' will be used. + */ + public DockerRuleBuilder restartPolicy(RestartPolicy restartPolicy) { + this.restartPolicy = restartPolicy; + return this; + } + RestartPolicy restartPolicy() { + return restartPolicy; + } } \ No newline at end of file diff --git a/src/main/java/pl/domzal/junit/docker/rule/RestartPolicy.java b/src/main/java/pl/domzal/junit/docker/rule/RestartPolicy.java new file mode 100644 index 0000000..935da33 --- /dev/null +++ b/src/main/java/pl/domzal/junit/docker/rule/RestartPolicy.java @@ -0,0 +1,43 @@ +package pl.domzal.junit.docker.rule; + +import com.spotify.docker.client.messages.HostConfig; + +/** + * Container restart policy. Possible should be created with + * {@link #always()}, {@link #unlessStopped()} or {@link #onFailure(int)}. + */ +public final class RestartPolicy { + + private final HostConfig.RestartPolicy restartPolicy; + + public RestartPolicy(HostConfig.RestartPolicy restartPolicy) { + this.restartPolicy = restartPolicy; + } + + public HostConfig.RestartPolicy getRestartPolicy() { + return restartPolicy; + } + + /** + * 'onFailure' restart policy with specified maximum number of retries. + * + * @param maxRetryCount Number of retries. + */ + public static RestartPolicy onFailure(int maxRetryCount) { + return new RestartPolicy(HostConfig.RestartPolicy.onFailure(maxRetryCount)); + } + + /** + * 'unlessStopped' restart policy. + */ + public static RestartPolicy unlessStopped() { + return new RestartPolicy(HostConfig.RestartPolicy.unlessStopped()); + } + + /** + * 'always' restart policy. + */ + public static RestartPolicy always() { + return new RestartPolicy(HostConfig.RestartPolicy.always()); + } +} diff --git a/src/test/java/pl/domzal/junit/docker/rule/DockerRuleRestartPolicyTest.java b/src/test/java/pl/domzal/junit/docker/rule/DockerRuleRestartPolicyTest.java new file mode 100644 index 0000000..b4ed79b --- /dev/null +++ b/src/test/java/pl/domzal/junit/docker/rule/DockerRuleRestartPolicyTest.java @@ -0,0 +1,44 @@ +package pl.domzal.junit.docker.rule; + +import java.io.IOException; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.spotify.docker.client.exceptions.DockerException; + +@Category(test.category.Stable.class) +public class DockerRuleRestartPolicyTest { + + private Logger log = LoggerFactory.getLogger(DockerRuleRestartPolicyTest.class); + + @Rule + public DockerRule testee = DockerRule.builder() + .imageName("alpine") + .restartPolicy(RestartPolicy.always()) + .cmd("sh", "-c", "sleep 2") + .build(); + + @Test + public void shouldRestartAfterEnd() throws InterruptedException, IOException, DockerException { + final String initialStartedUp = testee.getDockerClient().inspectContainer(testee.getContainerId()).state().startedAt().toString(); + new WaitForUnit(TimeUnit.SECONDS, 10, new WaitForUnit.WaitForCondition() { + @Override + public boolean isConditionMet() { + try { + String currentStartedAt = testee.getDockerClient().inspectContainer(testee.getContainerId()).state().startedAt().toString(); + log.debug("(initial) '{}' != (current) '{}' ?", initialStartedUp, currentStartedAt); + return ! initialStartedUp.equals(currentStartedAt); + } catch (DockerException | InterruptedException e) { + throw new RuntimeException(e); + } + } + }); + } + +}