/* * (c) Copyright 2019 Palantir Technologies Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.palantir.docker.compose; import static com.google.common.base.Throwables.propagate; import static com.palantir.docker.compose.connection.waiting.HealthChecks.toHaveAllPortsOpen; import static com.palantir.docker.compose.execution.DockerComposeExecArgument.arguments; import static com.palantir.docker.compose.execution.DockerComposeExecOption.options; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; import com.google.common.collect.ImmutableList; import com.palantir.docker.compose.configuration.DockerComposeFiles; import com.palantir.docker.compose.connection.Container; import com.palantir.docker.compose.connection.State; import com.palantir.docker.compose.connection.waiting.HealthCheck; import com.palantir.docker.compose.connection.waiting.SuccessOrFailure; import com.palantir.docker.compose.execution.DockerComposeRunArgument; import com.palantir.docker.compose.execution.DockerComposeRunOption; import java.io.IOException; import java.util.List; import java.util.function.Consumer; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; public class DockerComposeRuleIntegrationTest { private static final List<String> CONTAINERS = ImmutableList.of("db", "db2", "db3", "db4"); @Rule public final DockerComposeRule docker = DockerComposeRule.builder() .files(DockerComposeFiles.from("src/test/resources/docker-compose.yaml")) .waitingForService("db", toHaveAllPortsOpen()) .waitingForService("db2", toHaveAllPortsOpen()) .waitingForServices(ImmutableList.of("db3", "db4"), toAllHaveAllPortsOpen()) .build(); private static HealthCheck<List<Container>> toAllHaveAllPortsOpen() { return containers -> { boolean healthy = containers.stream() .map(Container::areAllPortsOpen) .allMatch(SuccessOrFailure::succeeded); return SuccessOrFailure.fromBoolean(healthy, ""); }; } @Rule public TemporaryFolder logFolder = new TemporaryFolder(); @Rule public ExpectedException exception = ExpectedException.none(); private static void forEachContainer(Consumer<String> consumer) { CONTAINERS.forEach(consumer); } @Test public void should_run_docker_compose_up_using_the_specified_docker_compose_file_to_bring_postgres_up() { forEachContainer(container -> { assertThat(docker.containers().container(container).port(5432).isListeningNow(), is(true)); }); } @Test public void after_test_is_executed_the_launched_postgres_container_is_no_longer_listening() { docker.after(); forEachContainer(container -> { assertThat(docker.containers().container(container).port(5432).isListeningNow(), is(false)); }); } @Test public void can_access_external_port_for_internal_port_of_machine() { forEachContainer(container -> { assertThat(docker.containers().container(container).port(5432).isListeningNow(), is(true)); }); } @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 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 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 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 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); } }); } @Ignore // This test will not run on Circle CI because it does not currently support docker-compose exec. @Test public void exec_returns_output() throws Exception { assertThat(docker.exec(options(), CONTAINERS.get(0), arguments("echo", "hello")), is("hello")); } @Test public void run_returns_output() throws Exception { assertThat(docker.run(DockerComposeRunOption.options("--entrypoint", "echo"), CONTAINERS.get(0), DockerComposeRunArgument.arguments("hello")), is("hello")); } }