final Container container = cluster.container(containerName); try { Preconditions.checkState(State.Up == container.state(), "container %s should be up", containerName); } catch (IOException e) { log.error("exception thrown", e);
/** * Returns a check that the native "healthcheck" status of the docker containers is not unhealthy. * * <p>Does not wait for DOWN or PAUSED containers, or containers with no healthcheck defined. */ static ClusterHealthCheck nativeHealthChecks() { return cluster -> { Set<String> unhealthyContainers = new LinkedHashSet<>(); try { for (Container container : cluster.allContainers()) { State state = container.state(); if (state == State.UNHEALTHY) { unhealthyContainers.add(container.getContainerName()); } } if (!unhealthyContainers.isEmpty()) { return SuccessOrFailure.failure( "The following containers are not healthy: " + unhealthyContainers.stream().collect(joining(", "))); } return SuccessOrFailure.success(); } catch (IOException e) { return SuccessOrFailure.fromException(e); } }; }
@Test public void can_kill_and_start_containers() { forEachContainer(containerName -> { try { Container container = docker.containers().container(containerName); container.kill(); assertThat(container.state(), is(State.DOWN)); container.start(); assertThat(container.state(), is(State.HEALTHY)); } catch (IOException | InterruptedException e) { propagate(e); } }); }
@Test public void can_stop_and_start_containers() { forEachContainer(containerName -> { try { Container container = docker.containers().container(containerName); container.stop(); assertThat(container.state(), is(State.DOWN)); container.start(); assertThat(container.state(), is(State.HEALTHY)); } catch (IOException | InterruptedException e) { propagate(e); } }); }
@Test public void test_docker_compose_rule_up_container() throws IOException, InterruptedException { Container container = dockerComposeRule.containers().container(SERVICE_NAME); container.up(); assertThat(container.state(), is(State.HEALTHY)); }
@Test public void start_can_be_run_on_running_container() { forEachContainer(containerName -> { try { Container container = docker.containers().container(containerName); container.start(); assertThat(container.state(), is(State.HEALTHY)); } catch (IOException | InterruptedException e) { propagate(e); } }); }
@Test public void stop_can_be_run_on_stopped_container() { forEachContainer(containerName -> { try { Container container = docker.containers().container(containerName); container.stop(); assertThat(container.state(), is(State.DOWN)); container.stop(); } catch (IOException | InterruptedException e) { propagate(e); } }); }
@Test public void kill_can_be_run_on_killed_container() { forEachContainer(containerName -> { try { Container container = docker.containers().container(containerName); container.kill(); assertThat(container.state(), is(State.DOWN)); container.kill(); } catch (IOException | InterruptedException e) { propagate(e); } }); }
@Test public void testStateChanges_withoutHealthCheck() throws IOException, InterruptedException { DockerCompose dockerCompose = new DefaultDockerCompose( DockerComposeFiles.from("src/test/resources/no-healthcheck.yaml"), dockerMachine, ProjectName.random()); // The noHealthcheck service has no healthcheck specified; it should be immediately healthy Container container = new Container("noHealthcheck", docker, dockerCompose); assertEquals(State.DOWN, container.state()); container.up(); assertEquals(State.HEALTHY, container.state()); container.kill(); assertEquals(State.DOWN, container.state()); }
@Test public void test_docker_compose_rule_up_container_with_healthcheck() throws IOException, InterruptedException { Container container = dockerComposeRule.containers().container(SERVICE_NAME); container.up(); // to prove that we can use healthcheck manually after starting a single container new ClusterWait(serviceHealthCheck(SERVICE_NAME, toHaveAllPortsOpen()), Duration.standardSeconds(5)) .waitUntilReady(dockerComposeRule.containers()); assertThat(container.state(), is(State.HEALTHY)); } }
/** * This test is not currently enabled in Circle as it does not provide a sufficiently recent version of docker-compose. * * @see <a href="https://github.com/palantir/docker-compose-rule/issues/156">Issue #156</a> */ @Test public void testStateChanges_withHealthCheck() throws IOException, InterruptedException { assumeThat("docker version", Docker.version(), new GreaterOrEqual<>(Version.forIntegers(1, 12, 0))); assumeThat("docker-compose version", DockerCompose.version(), new GreaterOrEqual<>(Version.forIntegers(1, 10, 0))); DockerCompose dockerCompose = new DefaultDockerCompose( DockerComposeFiles.from("src/test/resources/native-healthcheck.yaml"), dockerMachine, ProjectName.random()); // The withHealthcheck service's healthcheck checks every 100ms whether the file "healthy" exists Container container = new Container("withHealthcheck", docker, dockerCompose); assertEquals(State.DOWN, container.state()); container.up(); assertEquals(State.UNHEALTHY, container.state()); dockerCompose.exec(noOptions(), "withHealthcheck", arguments("touch", "healthy")); wait.until(container::state, equalTo(State.HEALTHY)); dockerCompose.exec(noOptions(), "withHealthcheck", arguments("rm", "healthy")); wait.until(container::state, equalTo(State.UNHEALTHY)); container.kill(); assertEquals(State.DOWN, container.state()); } }