Add Docker Compose support
Add `spring-boot-docker-compose` module with service connection support. Closes gh-34747 Co-authored-by: Phillip Webb <pwebb@vmware.com> Co-authored-by: "Andy Wilkinson <wilkinsona@vmware.com>
This commit is contained in:
committed by
Phillip Webb
parent
4ae24e404e
commit
842e17eced
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.DefaultConnectionPorts.ContainerPort;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultConnectionPorts}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DefaultConnectionPortsTests {
|
||||
|
||||
@Test
|
||||
void createWhenBridgeNetwork() throws IOException {
|
||||
DefaultConnectionPorts ports = createForJson("docker-inspect-bridge-network.json");
|
||||
assertThat(ports.getMappings()).containsExactly(entry(new ContainerPort(6379, "tcp"), 32770));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenHostNetwork() throws Exception {
|
||||
DefaultConnectionPorts ports = createForJson("docker-inspect-host-network.json");
|
||||
assertThat(ports.getMappings()).containsExactly(entry(new ContainerPort(6379, "tcp"), 6379));
|
||||
}
|
||||
|
||||
private DefaultConnectionPorts createForJson(String path) throws IOException {
|
||||
String json = new ClassPathResource(path, getClass()).getContentAsString(StandardCharsets.UTF_8);
|
||||
DockerCliInspectResponse inspectResponse = DockerJson.deserialize(json, DockerCliInspectResponse.class);
|
||||
return new DefaultConnectionPorts(inspectResponse);
|
||||
}
|
||||
|
||||
@Nested
|
||||
class ContainerPortTests {
|
||||
|
||||
@Test
|
||||
void parse() {
|
||||
ContainerPort port = ContainerPort.parse("123/tcp");
|
||||
assertThat(port).isEqualTo(new ContainerPort(123, "tcp"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseWhenNoSlashThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> ContainerPort.parse("123"))
|
||||
.withMessage("Unable to parse container port '123'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseWhenMultipleSlashesThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> ContainerPort.parse("123/tcp/ip"))
|
||||
.withMessage("Unable to parse container port '123/tcp/ip'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseWhenNotNumberThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> ContainerPort.parse("tcp/123"))
|
||||
.withMessage("Unable to parse container port 'tcp/123'");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.Config;
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.ExposedPort;
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.HostConfig;
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.NetworkSettings;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.BDDMockito.willReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultDockerCompose}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DefaultDockerComposeTests {
|
||||
|
||||
private static final String HOST = "192.168.1.1";
|
||||
|
||||
private DockerCli cli = mock(DockerCli.class);
|
||||
|
||||
@Test
|
||||
void upRunsUpCommand() {
|
||||
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
|
||||
compose.up();
|
||||
then(this.cli).should().run(new DockerCliCommand.ComposeUp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void downRunsDownCommand() {
|
||||
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
|
||||
Duration timeout = Duration.ofSeconds(1);
|
||||
compose.down(timeout);
|
||||
then(this.cli).should().run(new DockerCliCommand.ComposeDown(timeout));
|
||||
}
|
||||
|
||||
@Test
|
||||
void startRunsStartCommand() {
|
||||
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
|
||||
compose.start();
|
||||
then(this.cli).should().run(new DockerCliCommand.ComposeStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
void stopRunsStopCommand() {
|
||||
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
|
||||
Duration timeout = Duration.ofSeconds(1);
|
||||
compose.stop(timeout);
|
||||
then(this.cli).should().run(new DockerCliCommand.ComposeStop(timeout));
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasDefinedServicesWhenComposeConfigServicesIsEmptyReturnsFalse() {
|
||||
willReturn(new DockerCliComposeConfigResponse("test", Collections.emptyMap())).given(this.cli)
|
||||
.run(new DockerCliCommand.ComposeConfig());
|
||||
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
|
||||
assertThat(compose.hasDefinedServices()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasDefinedServicesWhenComposeConfigServicesIsNotEmptyReturnsTrue() {
|
||||
willReturn(new DockerCliComposeConfigResponse("test",
|
||||
Map.of("redis", new DockerCliComposeConfigResponse.Service("redis"))))
|
||||
.given(this.cli)
|
||||
.run(new DockerCliCommand.ComposeConfig());
|
||||
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
|
||||
assertThat(compose.hasDefinedServices()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasRunningServicesWhenPsListsRunningServiceReturnsTrue() {
|
||||
willReturn(List.of(new DockerCliComposePsResponse("id", "name", "image", "exited"),
|
||||
new DockerCliComposePsResponse("id", "name", "image", "running")))
|
||||
.given(this.cli)
|
||||
.run(new DockerCliCommand.ComposePs());
|
||||
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
|
||||
assertThat(compose.hasRunningServices()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasRunningServicesWhenPsListReturnsAllExitedReturnsFalse() {
|
||||
willReturn(List.of(new DockerCliComposePsResponse("id", "name", "image", "exited"),
|
||||
new DockerCliComposePsResponse("id", "name", "image", "running")))
|
||||
.given(this.cli)
|
||||
.run(new DockerCliCommand.ComposePs());
|
||||
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
|
||||
assertThat(compose.hasRunningServices()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getRunningServicesReturnsServices() {
|
||||
String id = "123";
|
||||
DockerCliComposePsResponse psResponse = new DockerCliComposePsResponse(id, "name", "redis", "running");
|
||||
Map<String, ExposedPort> exposedPorts = Collections.emptyMap();
|
||||
Config config = new Config("redis", Map.of("spring", "boot"), exposedPorts, List.of("a=b"));
|
||||
NetworkSettings networkSettings = null;
|
||||
HostConfig hostConfig = null;
|
||||
DockerCliInspectResponse inspectResponse = new DockerCliInspectResponse(id, config, networkSettings,
|
||||
hostConfig);
|
||||
willReturn(List.of(psResponse)).given(this.cli).run(new DockerCliCommand.ComposePs());
|
||||
willReturn(List.of(inspectResponse)).given(this.cli).run(new DockerCliCommand.Inspect(List.of(id)));
|
||||
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
|
||||
List<RunningService> runningServices = compose.getRunningServices();
|
||||
assertThat(runningServices).hasSize(1);
|
||||
RunningService runningService = runningServices.get(0);
|
||||
assertThat(runningService.name()).isEqualTo("name");
|
||||
assertThat(runningService.image()).hasToString("redis");
|
||||
assertThat(runningService.host()).isEqualTo(HOST);
|
||||
assertThat(runningService.ports().getAll()).isEmpty();
|
||||
assertThat(runningService.env()).containsExactly(entry("a", "b"));
|
||||
assertThat(runningService.labels()).containsExactly(entry("spring", "boot"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getRunningServicesWhenNoHostUsesHostFromContext() {
|
||||
String id = "123";
|
||||
DockerCliComposePsResponse psResponse = new DockerCliComposePsResponse(id, "name", "redis", "running");
|
||||
Map<String, ExposedPort> exposedPorts = Collections.emptyMap();
|
||||
Config config = new Config("redis", Map.of("spring", "boot"), exposedPorts, List.of("a=b"));
|
||||
NetworkSettings networkSettings = null;
|
||||
HostConfig hostConfig = null;
|
||||
DockerCliInspectResponse inspectResponse = new DockerCliInspectResponse(id, config, networkSettings,
|
||||
hostConfig);
|
||||
willReturn(List.of(new DockerCliContextResponse("test", true, "https://192.168.1.1"))).given(this.cli)
|
||||
.run(new DockerCliCommand.Context());
|
||||
willReturn(List.of(psResponse)).given(this.cli).run(new DockerCliCommand.ComposePs());
|
||||
willReturn(List.of(inspectResponse)).given(this.cli).run(new DockerCliCommand.Inspect(List.of(id)));
|
||||
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, null);
|
||||
List<RunningService> runningServices = compose.getRunningServices();
|
||||
assertThat(runningServices).hasSize(1);
|
||||
RunningService runningService = runningServices.get(0);
|
||||
assertThat(runningService.host()).isEqualTo("192.168.1.1");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.Config;
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.ExposedPort;
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.HostConfig;
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.HostPort;
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.NetworkSettings;
|
||||
import org.springframework.boot.origin.Origin;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultRunningService}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DefaultRunningServiceTests {
|
||||
|
||||
@TempDir
|
||||
File temp;
|
||||
|
||||
private DefaultRunningService runningService;
|
||||
|
||||
private DockerComposeFile composeFile;
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
this.composeFile = createComposeFile();
|
||||
DockerHost host = DockerHost.get("192.168.1.1", () -> Collections.emptyList());
|
||||
String id = "123";
|
||||
String name = "my-service";
|
||||
String image = "redis";
|
||||
String state = "running";
|
||||
DockerCliComposePsResponse psResponse = new DockerCliComposePsResponse(id, name, image, state);
|
||||
Map<String, String> labels = Map.of("spring", "boot");
|
||||
Map<String, ExposedPort> exposedPorts = Map.of("8080/tcp", new ExposedPort());
|
||||
List<String> env = List.of("a=b");
|
||||
Config config = new Config(image, labels, exposedPorts, env);
|
||||
Map<String, List<HostPort>> ports = Map.of("8080/tcp", List.of(new HostPort(null, "9090")));
|
||||
NetworkSettings networkSettings = new NetworkSettings(ports);
|
||||
HostConfig hostConfig = new HostConfig("bridge");
|
||||
DockerCliInspectResponse inspectResponse = new DockerCliInspectResponse(id, config, networkSettings,
|
||||
hostConfig);
|
||||
this.runningService = new DefaultRunningService(host, this.composeFile, psResponse, inspectResponse);
|
||||
}
|
||||
|
||||
private DockerComposeFile createComposeFile() throws IOException {
|
||||
File file = new File(this.temp, "compose.yaml");
|
||||
FileCopyUtils.copy(new byte[0], file);
|
||||
return DockerComposeFile.of(file);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getOriginReturnsOrigin() {
|
||||
assertThat(Origin.from(this.runningService)).isEqualTo(new DockerComposeOrigin(this.composeFile, "my-service"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void nameReturnsNameFromPsResponse() {
|
||||
assertThat(this.runningService.name()).isEqualTo("my-service");
|
||||
}
|
||||
|
||||
@Test
|
||||
void imageReturnsImageFromPsResponse() {
|
||||
assertThat(this.runningService.image()).hasToString("redis");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hostReturnsHost() {
|
||||
assertThat(this.runningService.host()).isEqualTo("192.168.1.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void portsReturnsPortsFromInspectResponse() {
|
||||
ConnectionPorts ports = this.runningService.ports();
|
||||
assertThat(ports.getAll("tcp")).containsExactly(9090);
|
||||
assertThat(ports.get(8080)).isEqualTo(9090);
|
||||
}
|
||||
|
||||
@Test
|
||||
void envReturnsEnvFromInspectResponse() {
|
||||
assertThat(this.runningService.env()).containsExactly(entry("a", "b"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void labelReturnsLabelsFromInspectResponse() {
|
||||
assertThat(this.runningService.labels()).containsExactly(entry("spring", "boot"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringReturnsServiceName() {
|
||||
assertThat(this.runningService).hasToString("my-service");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerCliCommand}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerCliCommandTests {
|
||||
|
||||
@Test
|
||||
void context() {
|
||||
DockerCliCommand<?> command = new DockerCliCommand.Context();
|
||||
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER);
|
||||
assertThat(command.getCommand()).containsExactly("context", "ls", "--format={{ json . }}");
|
||||
assertThat(command.deserialize("[]")).isInstanceOf(List.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void inspect() {
|
||||
DockerCliCommand<?> command = new DockerCliCommand.Inspect(List.of("123", "345"));
|
||||
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER);
|
||||
assertThat(command.getCommand()).containsExactly("inspect", "--format={{ json . }}", "123", "345");
|
||||
assertThat(command.deserialize("[]")).isInstanceOf(List.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void composeConfig() {
|
||||
DockerCliCommand<?> command = new DockerCliCommand.ComposeConfig();
|
||||
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER_COMPOSE);
|
||||
assertThat(command.getCommand()).containsExactly("config", "--format=json");
|
||||
assertThat(command.deserialize("{}")).isInstanceOf(DockerCliComposeConfigResponse.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void composePs() {
|
||||
DockerCliCommand<?> command = new DockerCliCommand.ComposePs();
|
||||
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER_COMPOSE);
|
||||
assertThat(command.getCommand()).containsExactly("ps", "--format=json");
|
||||
assertThat(command.deserialize("[]")).isInstanceOf(List.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void composeUp() {
|
||||
DockerCliCommand<?> command = new DockerCliCommand.ComposeUp();
|
||||
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER_COMPOSE);
|
||||
assertThat(command.getCommand()).containsExactly("up", "--no-color", "--quiet-pull", "--detach", "--wait");
|
||||
assertThat(command.deserialize("[]")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void composeDown() {
|
||||
DockerCliCommand<?> command = new DockerCliCommand.ComposeDown(Duration.ofSeconds(1));
|
||||
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER_COMPOSE);
|
||||
assertThat(command.getCommand()).containsExactly("down", "--timeout", "1");
|
||||
assertThat(command.deserialize("[]")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void composeStart() {
|
||||
DockerCliCommand<?> command = new DockerCliCommand.ComposeStart();
|
||||
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER_COMPOSE);
|
||||
assertThat(command.getCommand()).containsExactly("start", "--no-color", "--quiet-pull", "--detach", "--wait");
|
||||
assertThat(command.deserialize("[]")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void composeStop() {
|
||||
DockerCliCommand<?> command = new DockerCliCommand.ComposeStop(Duration.ofSeconds(1));
|
||||
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER_COMPOSE);
|
||||
assertThat(command.getCommand()).containsExactly("stop", "--timeout", "1");
|
||||
assertThat(command.deserialize("[]")).isNull();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.DockerCliComposeConfigResponse.Service;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerCliComposeConfigResponse}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerCliComposeConfigResponseTests {
|
||||
|
||||
@Test
|
||||
void deserializeJson() throws IOException {
|
||||
String json = new ClassPathResource("docker-compose-config.json", getClass())
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
DockerCliComposeConfigResponse response = DockerJson.deserialize(json, DockerCliComposeConfigResponse.class);
|
||||
DockerCliComposeConfigResponse expected = new DockerCliComposeConfigResponse("redis-docker",
|
||||
Map.of("redis", new Service("redis:7.0")));
|
||||
assertThat(response).isEqualTo(expected);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerCliComposePsResponse}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerCliComposePsResponseTests {
|
||||
|
||||
@Test
|
||||
void deserializeJson() throws IOException {
|
||||
String json = new ClassPathResource("docker-compose-ps.json", getClass())
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
DockerCliComposePsResponse response = DockerJson.deserialize(json, DockerCliComposePsResponse.class);
|
||||
DockerCliComposePsResponse expected = new DockerCliComposePsResponse("f5af31dae7f6", "redis-docker-redis-1",
|
||||
"redis:7.0", "running");
|
||||
assertThat(response).isEqualTo(expected);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerCliComposeVersionResponse}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerCliComposeVersionResponseTests {
|
||||
|
||||
@Test
|
||||
void deserializeJson() throws IOException {
|
||||
String json = new ClassPathResource("docker-compose-version.json", getClass())
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
DockerCliComposeVersionResponse response = DockerJson.deserialize(json, DockerCliComposeVersionResponse.class);
|
||||
DockerCliComposeVersionResponse expected = new DockerCliComposeVersionResponse("123");
|
||||
assertThat(response).isEqualTo(expected);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerCliContextResponse}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerCliContextResponseTests {
|
||||
|
||||
@Test
|
||||
void deserializeJson() throws IOException {
|
||||
String json = new ClassPathResource("docker-context.json", getClass())
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
DockerCliContextResponse response = DockerJson.deserialize(json, DockerCliContextResponse.class);
|
||||
DockerCliContextResponse expected = new DockerCliContextResponse("default", true,
|
||||
"unix:///var/run/docker.sock");
|
||||
assertThat(response).isEqualTo(expected);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.Config;
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.ExposedPort;
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.HostConfig;
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.HostPort;
|
||||
import org.springframework.boot.docker.compose.core.DockerCliInspectResponse.NetworkSettings;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerCliInspectResponse}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerCliInspectResponseTests {
|
||||
|
||||
@Test
|
||||
void deserializeJson() throws IOException {
|
||||
String json = new ClassPathResource("docker-inspect.json", getClass())
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
DockerCliInspectResponse response = DockerJson.deserialize(json, DockerCliInspectResponse.class);
|
||||
LinkedHashMap<String, String> expectedLabels = linkedMapOf("com.docker.compose.config-hash",
|
||||
"cfdc8e119d85a53c7d47edb37a3b160a8c83ba48b0428ebc07713befec991dd0",
|
||||
"com.docker.compose.container-number", "1", "com.docker.compose.depends_on", "",
|
||||
"com.docker.compose.image", "sha256:e79ba23ed43baa22054741136bf45bdb041824f41c5e16c0033ea044ca164b82",
|
||||
"com.docker.compose.oneoff", "False", "com.docker.compose.project", "redis-docker",
|
||||
"com.docker.compose.project.config_files", "compose.yaml", "com.docker.compose.project.working_dir",
|
||||
"/", "com.docker.compose.service", "redis", "com.docker.compose.version", "2.16.0");
|
||||
List<String> expectedEnv = List.of("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"GOSU_VERSION=1.16", "REDIS_VERSION=7.0.8");
|
||||
Config expectedConfig = new Config("redis:7.0", expectedLabels, Map.of("6379/tcp", new ExposedPort()),
|
||||
expectedEnv);
|
||||
NetworkSettings expectedNetworkSettings = new NetworkSettings(
|
||||
Map.of("6379/tcp", List.of(new HostPort("0.0.0.0", "32770"), new HostPort("::", "32770"))));
|
||||
DockerCliInspectResponse expected = new DockerCliInspectResponse(
|
||||
"f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc", expectedConfig,
|
||||
expectedNetworkSettings, new HostConfig("redis-docker_default"));
|
||||
assertThat(response).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <K, V> LinkedHashMap<K, V> linkedMapOf(Object... values) {
|
||||
LinkedHashMap<K, V> result = new LinkedHashMap<>();
|
||||
for (int i = 0; i < values.length; i = i + 2) {
|
||||
result.put((K) values[i], (V) values[i + 1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.testsupport.process.DisabledIfProcessUnavailable;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerCli}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@DisabledIfProcessUnavailable({ "docker", "compose" })
|
||||
class DockerCliTests {
|
||||
|
||||
@Test
|
||||
void runBasicCommand() {
|
||||
DockerCli cli = new DockerCli(null, null, Collections.emptySet());
|
||||
List<DockerCliContextResponse> context = cli.run(new DockerCliCommand.Context());
|
||||
assertThat(context).isNotEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerComposeFile}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerComposeFileTests {
|
||||
|
||||
@TempDir
|
||||
File temp;
|
||||
|
||||
@Test
|
||||
void hashCodeAndEquals() throws Exception {
|
||||
File f1 = new File(this.temp, "compose.yml");
|
||||
File f2 = new File(this.temp, "docker-compose.yml");
|
||||
FileCopyUtils.copy(new byte[0], f1);
|
||||
FileCopyUtils.copy(new byte[0], f2);
|
||||
DockerComposeFile c1 = DockerComposeFile.of(f1);
|
||||
DockerComposeFile c2 = DockerComposeFile.of(f1);
|
||||
DockerComposeFile c3 = DockerComposeFile.find(f1.getParentFile());
|
||||
DockerComposeFile c4 = DockerComposeFile.of(f2);
|
||||
assertThat(c1.hashCode()).isEqualTo(c2.hashCode()).isEqualTo(c3.hashCode());
|
||||
assertThat(c1).isEqualTo(c1).isEqualTo(c2).isEqualTo(c3).isNotEqualTo(c4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringReturnsFileName() throws Exception {
|
||||
DockerComposeFile composeFile = createComposeFile("compose.yml");
|
||||
assertThat(composeFile.toString()).endsWith("/compose.yml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void findFindsSingleFile() throws Exception {
|
||||
File file = new File(this.temp, "docker-compose.yml");
|
||||
FileCopyUtils.copy(new byte[0], file);
|
||||
DockerComposeFile composeFile = DockerComposeFile.find(file.getParentFile());
|
||||
assertThat(composeFile.toString()).endsWith("/docker-compose.yml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void findWhenMultipleFilesPicksBest() throws Exception {
|
||||
File f1 = new File(this.temp, "docker-compose.yml");
|
||||
FileCopyUtils.copy(new byte[0], f1);
|
||||
File f2 = new File(this.temp, "compose.yml");
|
||||
FileCopyUtils.copy(new byte[0], f2);
|
||||
DockerComposeFile composeFile = DockerComposeFile.find(f1.getParentFile());
|
||||
assertThat(composeFile.toString()).endsWith("/compose.yml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void findWhenNoComposeFilesReturnsNull() throws Exception {
|
||||
File file = new File(this.temp, "not-a-compose.yml");
|
||||
FileCopyUtils.copy(new byte[0], file);
|
||||
DockerComposeFile composeFile = DockerComposeFile.find(file.getParentFile());
|
||||
assertThat(composeFile).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void findWhenWorkingDirectoryDoesNotExistReturnsNull() {
|
||||
File directory = new File(this.temp, "missing");
|
||||
DockerComposeFile composeFile = DockerComposeFile.find(directory);
|
||||
assertThat(composeFile).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void findWhenWorkingDirectoryIsNotDirectoryThrowsException() throws Exception {
|
||||
File file = new File(this.temp, "iamafile");
|
||||
FileCopyUtils.copy(new byte[0], file);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> DockerComposeFile.find(file))
|
||||
.withMessageEndingWith("is not a directory");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofReturnsDockerComposeFile() throws Exception {
|
||||
File file = new File(this.temp, "anyfile.yml");
|
||||
FileCopyUtils.copy(new byte[0], file);
|
||||
DockerComposeFile composeFile = DockerComposeFile.of(file);
|
||||
assertThat(composeFile).isNotNull();
|
||||
assertThat(composeFile.toString()).isEqualTo(file.getCanonicalPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenFileIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> DockerComposeFile.of(null))
|
||||
.withMessage("File must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenFileDoesNotExistThrowsException() {
|
||||
File file = new File(this.temp, "missing");
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> DockerComposeFile.of(file))
|
||||
.withMessageEndingWith("does not exist");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenFileIsNotFileThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> DockerComposeFile.of(this.temp))
|
||||
.withMessageEndingWith("is not a file");
|
||||
}
|
||||
|
||||
private DockerComposeFile createComposeFile(String name) throws IOException {
|
||||
File file = new File(this.temp, name);
|
||||
FileCopyUtils.copy(new byte[0], file);
|
||||
return DockerComposeFile.of(file);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerComposeOrigin}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerComposeOriginTests {
|
||||
|
||||
@TempDir
|
||||
File temp;
|
||||
|
||||
@Test
|
||||
void hasToString() throws Exception {
|
||||
DockerComposeFile composeFile = createTempComposeFile();
|
||||
DockerComposeOrigin origin = new DockerComposeOrigin(composeFile, "service-1");
|
||||
assertThat(origin.toString()).startsWith("Docker compose service 'service-1' defined in '")
|
||||
.endsWith("compose.yaml'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalsAndHashcode() throws Exception {
|
||||
DockerComposeFile composeFile = createTempComposeFile();
|
||||
DockerComposeOrigin origin1 = new DockerComposeOrigin(composeFile, "service-1");
|
||||
DockerComposeOrigin origin2 = new DockerComposeOrigin(composeFile, "service-1");
|
||||
DockerComposeOrigin origin3 = new DockerComposeOrigin(composeFile, "service-3");
|
||||
assertThat(origin1).isEqualTo(origin1);
|
||||
assertThat(origin1).isEqualTo(origin2);
|
||||
assertThat(origin1).hasSameHashCodeAs(origin2);
|
||||
assertThat(origin2).isEqualTo(origin1);
|
||||
assertThat(origin1).isNotEqualTo(origin3);
|
||||
assertThat(origin2).isNotEqualTo(origin3);
|
||||
assertThat(origin3).isNotEqualTo(origin1);
|
||||
assertThat(origin3).isNotEqualTo(origin2);
|
||||
}
|
||||
|
||||
private DockerComposeFile createTempComposeFile() throws IOException {
|
||||
File file = new File(this.temp, "compose.yaml");
|
||||
FileCopyUtils.copy(new byte[0], file);
|
||||
return DockerComposeFile.of(file);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerEnv}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerEnvTests {
|
||||
|
||||
@Test
|
||||
void createWhenEnvIsNullReturnsEmpty() {
|
||||
DockerEnv env = new DockerEnv(null);
|
||||
assertThat(env.asMap()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenEnvIsEmptyReturnsEmpty() {
|
||||
DockerEnv env = new DockerEnv(Collections.emptyList());
|
||||
assertThat(env.asMap()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createParsesEnv() {
|
||||
DockerEnv env = new DockerEnv(List.of("a=b", "c"));
|
||||
assertThat(env.asMap()).containsExactly(entry("a", "b"), entry("c", null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerHost}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerHostTests {
|
||||
|
||||
private static final String MAC_HOST = "unix:///var/run/docker.sock";
|
||||
|
||||
private static final String LINUX_HOST = "unix:///var/run/docker.sock";
|
||||
|
||||
private static final String WINDOWS_HOST = "npipe:////./pipe/docker_engine";
|
||||
|
||||
private static final String WSL_HOST = "unix:///var/run/docker.sock";
|
||||
|
||||
private static final String HTTP_HOST = "http://192.168.1.1";
|
||||
|
||||
private static final String HTTPS_HOST = "https://192.168.1.1";
|
||||
|
||||
private static final String TCP_HOST = "tcp://192.168.1.1";
|
||||
|
||||
private static final Function<String, String> NO_SYSTEM_ENV = (key) -> null;
|
||||
|
||||
private static final Supplier<List<DockerCliContextResponse>> NO_CONTEXT = () -> Collections.emptyList();
|
||||
|
||||
@Test
|
||||
void getWhenHasHost() {
|
||||
DockerHost host = DockerHost.get("192.168.1.1", NO_SYSTEM_ENV, NO_CONTEXT);
|
||||
assertThat(host).hasToString("192.168.1.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasServiceHostEnv() {
|
||||
Map<String, String> systemEnv = Map.of("SERVICES_HOST", "192.168.1.2");
|
||||
DockerHost host = DockerHost.get(null, systemEnv::get, NO_CONTEXT);
|
||||
assertThat(host).hasToString("192.168.1.2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasMacDockerHostEnv() {
|
||||
Map<String, String> systemEnv = Map.of("DOCKER_HOST", MAC_HOST);
|
||||
DockerHost host = DockerHost.get(null, systemEnv::get, NO_CONTEXT);
|
||||
assertThat(host).hasToString("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasLinuxDockerHostEnv() {
|
||||
Map<String, String> systemEnv = Map.of("DOCKER_HOST", LINUX_HOST);
|
||||
DockerHost host = DockerHost.get(null, systemEnv::get, NO_CONTEXT);
|
||||
assertThat(host).hasToString("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasWindowsDockerHostEnv() {
|
||||
Map<String, String> systemEnv = Map.of("DOCKER_HOST", WINDOWS_HOST);
|
||||
DockerHost host = DockerHost.get(null, systemEnv::get, NO_CONTEXT);
|
||||
assertThat(host).hasToString("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasWslDockerHostEnv() {
|
||||
Map<String, String> systemEnv = Map.of("DOCKER_HOST", WSL_HOST);
|
||||
DockerHost host = DockerHost.get(null, systemEnv::get, NO_CONTEXT);
|
||||
assertThat(host).hasToString("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasHttpDockerHostEnv() {
|
||||
Map<String, String> systemEnv = Map.of("DOCKER_HOST", HTTP_HOST);
|
||||
DockerHost host = DockerHost.get(null, systemEnv::get, NO_CONTEXT);
|
||||
assertThat(host).hasToString("192.168.1.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasHttpsDockerHostEnv() {
|
||||
Map<String, String> systemEnv = Map.of("DOCKER_HOST", HTTPS_HOST);
|
||||
DockerHost host = DockerHost.get(null, systemEnv::get, NO_CONTEXT);
|
||||
assertThat(host).hasToString("192.168.1.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasTcpDockerHostEnv() {
|
||||
Map<String, String> systemEnv = Map.of("DOCKER_HOST", TCP_HOST);
|
||||
DockerHost host = DockerHost.get(null, systemEnv::get, NO_CONTEXT);
|
||||
assertThat(host).hasToString("192.168.1.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasMacContext() {
|
||||
List<DockerCliContextResponse> context = List.of(new DockerCliContextResponse("test", true, MAC_HOST));
|
||||
DockerHost host = DockerHost.get(null, NO_SYSTEM_ENV, () -> context);
|
||||
assertThat(host).hasToString("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasLinuxContext() {
|
||||
List<DockerCliContextResponse> context = List.of(new DockerCliContextResponse("test", true, LINUX_HOST));
|
||||
DockerHost host = DockerHost.get(null, NO_SYSTEM_ENV, () -> context);
|
||||
assertThat(host).hasToString("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasWindowsContext() {
|
||||
List<DockerCliContextResponse> context = List.of(new DockerCliContextResponse("test", true, WINDOWS_HOST));
|
||||
DockerHost host = DockerHost.get(null, NO_SYSTEM_ENV, () -> context);
|
||||
assertThat(host).hasToString("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasWslContext() {
|
||||
List<DockerCliContextResponse> context = List.of(new DockerCliContextResponse("test", true, WSL_HOST));
|
||||
DockerHost host = DockerHost.get(null, NO_SYSTEM_ENV, () -> context);
|
||||
assertThat(host).hasToString("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasHttpContext() {
|
||||
List<DockerCliContextResponse> context = List.of(new DockerCliContextResponse("test", true, HTTP_HOST));
|
||||
DockerHost host = DockerHost.get(null, NO_SYSTEM_ENV, () -> context);
|
||||
assertThat(host).hasToString("192.168.1.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasHttpsContext() {
|
||||
List<DockerCliContextResponse> context = List.of(new DockerCliContextResponse("test", true, HTTPS_HOST));
|
||||
DockerHost host = DockerHost.get(null, NO_SYSTEM_ENV, () -> context);
|
||||
assertThat(host).hasToString("192.168.1.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasTcpContext() {
|
||||
List<DockerCliContextResponse> context = List.of(new DockerCliContextResponse("test", true, TCP_HOST));
|
||||
DockerHost host = DockerHost.get(null, NO_SYSTEM_ENV, () -> context);
|
||||
assertThat(host).hasToString("192.168.1.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenContextHasMultiple() {
|
||||
List<DockerCliContextResponse> context = new ArrayList<>();
|
||||
context.add(new DockerCliContextResponse("test", false, "http://192.168.1.1"));
|
||||
context.add(new DockerCliContextResponse("test", true, "http://192.168.1.2"));
|
||||
context.add(new DockerCliContextResponse("test", false, "http://192.168.1.3"));
|
||||
DockerHost host = DockerHost.get(null, NO_SYSTEM_ENV, () -> context);
|
||||
assertThat(host).hasToString("192.168.1.2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasNone() {
|
||||
DockerHost host = DockerHost.get(null, NO_SYSTEM_ENV, NO_CONTEXT);
|
||||
assertThat(host).hasToString("127.0.0.1");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerJson}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerJsonTests {
|
||||
|
||||
@Test
|
||||
void deserializeWhenSentenceCase() {
|
||||
String json = """
|
||||
{ "Value": 1 }
|
||||
""";
|
||||
TestResponse response = DockerJson.deserialize(json, TestResponse.class);
|
||||
assertThat(response).isEqualTo(new TestResponse(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void deserializeWhenLowerCase() {
|
||||
String json = """
|
||||
{ "value": 1 }
|
||||
""";
|
||||
TestResponse response = DockerJson.deserialize(json, TestResponse.class);
|
||||
assertThat(response).isEqualTo(new TestResponse(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void deserializeToListWhenArray() {
|
||||
String json = """
|
||||
[{ "value": 1 }, { "value": 2 }]
|
||||
""";
|
||||
List<TestResponse> response = DockerJson.deserializeToList(json, TestResponse.class);
|
||||
assertThat(response).containsExactly(new TestResponse(1), new TestResponse(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void deserializeToListWhenMultipleLines() {
|
||||
String json = """
|
||||
{ "Value": 1 }
|
||||
{ "Value": 2 }
|
||||
""";
|
||||
List<TestResponse> response = DockerJson.deserializeToList(json, TestResponse.class);
|
||||
assertThat(response).containsExactly(new TestResponse(1), new TestResponse(2));
|
||||
}
|
||||
|
||||
record TestResponse(int value) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ImageReference}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ImageReferenceTests {
|
||||
|
||||
@Test
|
||||
void getImageNameWhenImageOnly() {
|
||||
ImageReference imageReference = ImageReference.of("redis");
|
||||
assertThat(imageReference.getImageName()).isEqualTo("redis");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImageNameWhenImageAndTag() {
|
||||
ImageReference imageReference = ImageReference.of("redis:5");
|
||||
assertThat(imageReference.getImageName()).isEqualTo("redis");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImageNameWhenImageAndDigest() {
|
||||
ImageReference imageReference = ImageReference
|
||||
.of("redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7");
|
||||
assertThat(imageReference.getImageName()).isEqualTo("redis");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImageNameWhenProjectAndImage() {
|
||||
ImageReference imageReference = ImageReference.of("library/redis");
|
||||
assertThat(imageReference.getImageName()).isEqualTo("redis");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImageNameWhenRegistryLibraryAndImage() {
|
||||
ImageReference imageReference = ImageReference.of("docker.io/library/redis");
|
||||
assertThat(imageReference.getImageName()).isEqualTo("redis");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImageNameWhenRegistryLibraryImageAndTag() {
|
||||
ImageReference imageReference = ImageReference.of("docker.io/library/redis:5");
|
||||
assertThat(imageReference.getImageName()).isEqualTo("redis");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImageNameWhenRegistryLibraryImageAndDigest() {
|
||||
ImageReference imageReference = ImageReference
|
||||
.of("docker.io/library/redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7");
|
||||
assertThat(imageReference.getImageName()).isEqualTo("redis");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImageNameWhenRegistryWithPort() {
|
||||
ImageReference imageReference = ImageReference.of("my_private.registry:5000/redis");
|
||||
assertThat(imageReference.getImageName()).isEqualTo("redis");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImageNameWhenRegistryWithPortAndTag() {
|
||||
ImageReference imageReference = ImageReference.of("my_private.registry:5000/redis:5");
|
||||
assertThat(imageReference.getImageName()).isEqualTo("redis");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringReturnsReferenceString() {
|
||||
ImageReference imageReference = ImageReference.of("docker.io/library/redis");
|
||||
assertThat(imageReference).hasToString("docker.io/library/redis");
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalsAndHashCode() {
|
||||
ImageReference imageReference1 = ImageReference.of("docker.io/library/redis");
|
||||
ImageReference imageReference2 = ImageReference.of("docker.io/library/redis");
|
||||
ImageReference imageReference3 = ImageReference.of("docker.io/library/other");
|
||||
assertThat(imageReference1.hashCode()).isEqualTo(imageReference2.hashCode());
|
||||
assertThat(imageReference1).isEqualTo(imageReference1).isEqualTo(imageReference2).isNotEqualTo(imageReference3);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.core;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.testsupport.process.DisabledIfProcessUnavailable;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link ProcessRunner}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@DisabledIfProcessUnavailable("docker")
|
||||
class ProcessRunnerTests {
|
||||
|
||||
private ProcessRunner processRunner = new ProcessRunner();
|
||||
|
||||
@Test
|
||||
void run() {
|
||||
String out = this.processRunner.run("docker", "--version");
|
||||
assertThat(out).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void runWhenProcessDoesNotStart() {
|
||||
assertThatExceptionOfType(ProcessStartException.class)
|
||||
.isThrownBy(() -> this.processRunner.run("iverymuchdontexist", "--version"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void runWhenProcessReturnsNonZeroExitCode() {
|
||||
assertThatExceptionOfType(ProcessExitException.class)
|
||||
.isThrownBy(() -> this.processRunner.run("docker", "-thisdoesntwork"))
|
||||
.satisfies((ex) -> {
|
||||
assertThat(ex.getExitCode()).isGreaterThan(0);
|
||||
assertThat(ex.getStdOut()).isEmpty();
|
||||
assertThat(ex.getStdErr()).isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.lifecycle;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.SpringApplicationShutdownHandlers;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.docker.compose.core.DockerCompose;
|
||||
import org.springframework.boot.docker.compose.core.DockerComposeFile;
|
||||
import org.springframework.boot.docker.compose.core.RunningService;
|
||||
import org.springframework.boot.docker.compose.readiness.ServiceReadinessChecks;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerComposeLifecycleManager}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerComposeLifecycleManagerTests {
|
||||
|
||||
@TempDir
|
||||
File temp;
|
||||
|
||||
private DockerComposeFile dockerComposeFile;
|
||||
|
||||
private DockerCompose dockerCompose;
|
||||
|
||||
private Set<String> activeProfiles;
|
||||
|
||||
private GenericApplicationContext applicationContext;
|
||||
|
||||
private TestSpringApplicationShutdownHandlers shutdownHandlers;
|
||||
|
||||
private ServiceReadinessChecks serviceReadinessChecks;
|
||||
|
||||
private List<RunningService> runningServices;
|
||||
|
||||
private DockerComposeProperties properties;
|
||||
|
||||
private LinkedHashSet<ApplicationListener<?>> eventListeners;
|
||||
|
||||
private DockerComposeLifecycleManager lifecycleManager;
|
||||
|
||||
private DockerComposeSkipCheck skipCheck;
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws IOException {
|
||||
File file = new File(this.temp, "compose.yml");
|
||||
FileCopyUtils.copy(new byte[0], file);
|
||||
this.dockerComposeFile = DockerComposeFile.of(file);
|
||||
this.dockerCompose = mock(DockerCompose.class);
|
||||
File workingDirectory = new File(".");
|
||||
this.applicationContext = new GenericApplicationContext();
|
||||
this.applicationContext.refresh();
|
||||
Binder binder = Binder.get(this.applicationContext.getEnvironment());
|
||||
this.shutdownHandlers = new TestSpringApplicationShutdownHandlers();
|
||||
this.properties = DockerComposeProperties.get(binder);
|
||||
this.eventListeners = new LinkedHashSet<>();
|
||||
this.skipCheck = mock(DockerComposeSkipCheck.class);
|
||||
this.serviceReadinessChecks = mock(ServiceReadinessChecks.class);
|
||||
this.lifecycleManager = new TestDockerComposeLifecycleManager(workingDirectory, this.applicationContext, binder,
|
||||
this.shutdownHandlers, this.properties, this.eventListeners, this.skipCheck,
|
||||
this.serviceReadinessChecks);
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWhenEnabledFalseDoesNotStart() {
|
||||
this.properties.setEnabled(false);
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
setupRunningServices();
|
||||
this.lifecycleManager.startup();
|
||||
assertThat(listener.getEvent()).isNull();
|
||||
then(this.dockerCompose).should(never()).hasDefinedServices();
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWhenInTestDoesNotStart() {
|
||||
given(this.skipCheck.shouldSkip(any(), any(), any())).willReturn(true);
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
setupRunningServices();
|
||||
this.lifecycleManager.startup();
|
||||
assertThat(listener.getEvent()).isNull();
|
||||
then(this.dockerCompose).should(never()).hasDefinedServices();
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWhenHasNoDefinedServicesDoesNothing() {
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
this.lifecycleManager.startup();
|
||||
assertThat(listener.getEvent()).isNull();
|
||||
then(this.dockerCompose).should().hasDefinedServices();
|
||||
then(this.dockerCompose).should(never()).up();
|
||||
then(this.dockerCompose).should(never()).start();
|
||||
then(this.dockerCompose).should(never()).down(isA(Duration.class));
|
||||
then(this.dockerCompose).should(never()).stop(isA(Duration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWhenLifecycleStartAndStopAndHasNoRunningServicesDoesStartupAndShutdown() {
|
||||
this.properties.setLifecycleManagement(LifecycleManagement.START_AND_STOP);
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
|
||||
this.lifecycleManager.startup();
|
||||
this.shutdownHandlers.run();
|
||||
assertThat(listener.getEvent()).isNotNull();
|
||||
then(this.dockerCompose).should().up();
|
||||
then(this.dockerCompose).should(never()).start();
|
||||
then(this.dockerCompose).should().down(isA(Duration.class));
|
||||
then(this.dockerCompose).should(never()).stop(isA(Duration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWhenLifecycleStartAndStopAndHasRunningServicesDoesNoStartupOrShutdown() {
|
||||
this.properties.setLifecycleManagement(LifecycleManagement.START_AND_STOP);
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
setupRunningServices();
|
||||
this.lifecycleManager.startup();
|
||||
this.shutdownHandlers.run();
|
||||
assertThat(listener.getEvent()).isNotNull();
|
||||
then(this.dockerCompose).should(never()).up();
|
||||
then(this.dockerCompose).should(never()).start();
|
||||
then(this.dockerCompose).should(never()).down(isA(Duration.class));
|
||||
then(this.dockerCompose).should(never()).stop(isA(Duration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWhenLifecycleNoneDoesNoStartupOrShutdown() {
|
||||
this.properties.setLifecycleManagement(LifecycleManagement.NONE);
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
setupRunningServices();
|
||||
this.lifecycleManager.startup();
|
||||
this.shutdownHandlers.run();
|
||||
assertThat(listener.getEvent()).isNotNull();
|
||||
then(this.dockerCompose).should(never()).up();
|
||||
then(this.dockerCompose).should(never()).start();
|
||||
then(this.dockerCompose).should(never()).down(isA(Duration.class));
|
||||
then(this.dockerCompose).should(never()).stop(isA(Duration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWhenLifecycleStartOnlyDoesStartupAndNoShutdown() {
|
||||
this.properties.setLifecycleManagement(LifecycleManagement.START_ONLY);
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
|
||||
this.lifecycleManager.startup();
|
||||
this.shutdownHandlers.run();
|
||||
assertThat(listener.getEvent()).isNotNull();
|
||||
then(this.dockerCompose).should().up();
|
||||
then(this.dockerCompose).should(never()).start();
|
||||
then(this.dockerCompose).should(never()).down(isA(Duration.class));
|
||||
then(this.dockerCompose).should(never()).stop(isA(Duration.class));
|
||||
this.shutdownHandlers.assertNoneAdded();
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWhenStartupCommandStartDoesStartupUsingStartAndShutdown() {
|
||||
this.properties.setLifecycleManagement(LifecycleManagement.START_AND_STOP);
|
||||
this.properties.getStartup().setCommand(StartupCommand.START);
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
|
||||
this.lifecycleManager.startup();
|
||||
this.shutdownHandlers.run();
|
||||
assertThat(listener.getEvent()).isNotNull();
|
||||
then(this.dockerCompose).should(never()).up();
|
||||
then(this.dockerCompose).should().start();
|
||||
then(this.dockerCompose).should().down(isA(Duration.class));
|
||||
then(this.dockerCompose).should(never()).stop(isA(Duration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWhenShutdownCommandStopDoesStartupAndShutdownUsingStop() {
|
||||
this.properties.setLifecycleManagement(LifecycleManagement.START_AND_STOP);
|
||||
this.properties.getShutdown().setCommand(ShutdownCommand.STOP);
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
|
||||
this.lifecycleManager.startup();
|
||||
this.shutdownHandlers.run();
|
||||
assertThat(listener.getEvent()).isNotNull();
|
||||
then(this.dockerCompose).should().up();
|
||||
then(this.dockerCompose).should(never()).start();
|
||||
then(this.dockerCompose).should(never()).down(isA(Duration.class));
|
||||
then(this.dockerCompose).should().stop(isA(Duration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWhenHasShutdownTimeoutUsesDuration() {
|
||||
this.properties.setLifecycleManagement(LifecycleManagement.START_AND_STOP);
|
||||
Duration timeout = Duration.ofDays(1);
|
||||
this.properties.getShutdown().setTimeout(timeout);
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
|
||||
this.lifecycleManager.startup();
|
||||
this.shutdownHandlers.run();
|
||||
assertThat(listener.getEvent()).isNotNull();
|
||||
then(this.dockerCompose).should().down(timeout);
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWhenHasIgnoreLabelIgnoresService() {
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
setupRunningServices(Map.of("org.springframework.boot.ignore", "true"));
|
||||
this.lifecycleManager.startup();
|
||||
this.shutdownHandlers.run();
|
||||
assertThat(listener.getEvent()).isNotNull();
|
||||
assertThat(listener.getEvent().getRunningServices()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupWaitsUntilReady() {
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
setupRunningServices();
|
||||
this.lifecycleManager.startup();
|
||||
this.shutdownHandlers.run();
|
||||
then(this.serviceReadinessChecks).should().waitUntilReady(this.runningServices);
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupGetsDockerComposeWithActiveProfiles() {
|
||||
this.properties.getProfiles().setActive(Set.of("my-profile"));
|
||||
setupRunningServices();
|
||||
this.lifecycleManager.startup();
|
||||
assertThat(this.activeProfiles).containsExactly("my-profile");
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupPublishesEvent() {
|
||||
EventCapturingListener listener = new EventCapturingListener();
|
||||
this.eventListeners.add(listener);
|
||||
setupRunningServices();
|
||||
this.lifecycleManager.startup();
|
||||
DockerComposeServicesReadyEvent event = listener.getEvent();
|
||||
assertThat(event).isNotNull();
|
||||
assertThat(event.getSource()).isEqualTo(this.applicationContext);
|
||||
assertThat(event.getRunningServices()).isEqualTo(this.runningServices);
|
||||
}
|
||||
|
||||
private void setupRunningServices() {
|
||||
setupRunningServices(Collections.emptyMap());
|
||||
}
|
||||
|
||||
private void setupRunningServices(Map<String, String> labels) {
|
||||
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
|
||||
given(this.dockerCompose.hasRunningServices()).willReturn(true);
|
||||
RunningService runningService = mock(RunningService.class);
|
||||
given(runningService.labels()).willReturn(labels);
|
||||
this.runningServices = List.of(runningService);
|
||||
given(this.dockerCompose.getRunningServices()).willReturn(this.runningServices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Testable {@link SpringApplicationShutdownHandlers}.
|
||||
*/
|
||||
static class TestSpringApplicationShutdownHandlers implements SpringApplicationShutdownHandlers {
|
||||
|
||||
private final List<Runnable> actions = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void add(Runnable action) {
|
||||
this.actions.add(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Runnable action) {
|
||||
this.actions.remove(action);
|
||||
}
|
||||
|
||||
void run() {
|
||||
this.actions.forEach(Runnable::run);
|
||||
}
|
||||
|
||||
void assertNoneAdded() {
|
||||
assertThat(this.actions).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ApplicationListener} to capture the {@link DockerComposeServicesReadyEvent}.
|
||||
*/
|
||||
static class EventCapturingListener implements ApplicationListener<DockerComposeServicesReadyEvent> {
|
||||
|
||||
private DockerComposeServicesReadyEvent event;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(DockerComposeServicesReadyEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
DockerComposeServicesReadyEvent getEvent() {
|
||||
return this.event;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Testable {@link DockerComposeLifecycleManager}.
|
||||
*/
|
||||
class TestDockerComposeLifecycleManager extends DockerComposeLifecycleManager {
|
||||
|
||||
TestDockerComposeLifecycleManager(File workingDirectory, ApplicationContext applicationContext, Binder binder,
|
||||
SpringApplicationShutdownHandlers shutdownHandlers, DockerComposeProperties properties,
|
||||
Set<ApplicationListener<?>> eventListeners, DockerComposeSkipCheck skipCheck,
|
||||
ServiceReadinessChecks serviceReadinessChecks) {
|
||||
super(workingDirectory, applicationContext, binder, shutdownHandlers, properties, eventListeners, skipCheck,
|
||||
serviceReadinessChecks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DockerComposeFile getComposeFile() {
|
||||
return DockerComposeLifecycleManagerTests.this.dockerComposeFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DockerCompose getDockerCompose(DockerComposeFile composeFile, Set<String> activeProfiles) {
|
||||
DockerComposeLifecycleManagerTests.this.activeProfiles = activeProfiles;
|
||||
return DockerComposeLifecycleManagerTests.this.dockerCompose;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.lifecycle;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.SpringApplicationShutdownHandlers;
|
||||
import org.springframework.boot.context.event.ApplicationPreparedEvent;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerComposeListener}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerComposeListenerTests {
|
||||
|
||||
@Test
|
||||
void onApplicationPreparedEventCreatesAndStartsDockerComposeLifecycleManager() {
|
||||
SpringApplicationShutdownHandlers shutdownHandlers = mock(SpringApplicationShutdownHandlers.class);
|
||||
SpringApplication application = mock(SpringApplication.class);
|
||||
ConfigurableApplicationContext context = mock(ConfigurableApplicationContext.class);
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
given(context.getEnvironment()).willReturn(environment);
|
||||
TestDockerComposeListener listener = new TestDockerComposeListener(shutdownHandlers, context);
|
||||
ApplicationPreparedEvent event = new ApplicationPreparedEvent(application, new String[0], context);
|
||||
listener.onApplicationEvent(event);
|
||||
assertThat(listener.getManager()).isNotNull();
|
||||
then(listener.getManager()).should().startup();
|
||||
}
|
||||
|
||||
class TestDockerComposeListener extends DockerComposeListener {
|
||||
|
||||
private final ConfigurableApplicationContext context;
|
||||
|
||||
private DockerComposeLifecycleManager manager;
|
||||
|
||||
TestDockerComposeListener(SpringApplicationShutdownHandlers shutdownHandlers,
|
||||
ConfigurableApplicationContext context) {
|
||||
super(shutdownHandlers);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DockerComposeLifecycleManager createDockerComposeLifecycleManager(
|
||||
ConfigurableApplicationContext applicationContext, Binder binder, DockerComposeProperties properties,
|
||||
Set<ApplicationListener<?>> eventListeners) {
|
||||
this.manager = mock(DockerComposeLifecycleManager.class);
|
||||
assertThat(applicationContext).isSameAs(this.context);
|
||||
assertThat(binder).isNotNull();
|
||||
assertThat(properties).isNotNull();
|
||||
return this.manager;
|
||||
}
|
||||
|
||||
DockerComposeLifecycleManager getManager() {
|
||||
return this.manager;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.lifecycle;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.Duration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerComposeProperties}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerComposePropertiesTests {
|
||||
|
||||
@Test
|
||||
void getWhenNoPropertiesReturnsNew() {
|
||||
Binder binder = new Binder(new MapConfigurationPropertySource());
|
||||
DockerComposeProperties properties = DockerComposeProperties.get(binder);
|
||||
assertThat(properties.getFile()).isNull();
|
||||
assertThat(properties.getLifecycleManagement()).isEqualTo(LifecycleManagement.START_AND_STOP);
|
||||
assertThat(properties.getHost()).isNull();
|
||||
assertThat(properties.getStartup().getCommand()).isEqualTo(StartupCommand.UP);
|
||||
assertThat(properties.getShutdown().getCommand()).isEqualTo(ShutdownCommand.DOWN);
|
||||
assertThat(properties.getShutdown().getTimeout()).isEqualTo(Duration.ofSeconds(10));
|
||||
assertThat(properties.getProfiles().getActive()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenPropertiesReturnsBound() {
|
||||
Map<String, String> source = new LinkedHashMap<>();
|
||||
source.put("spring.docker.compose.file", "my-compose.yml");
|
||||
source.put("spring.docker.compose.lifecycle-management", "start-only");
|
||||
source.put("spring.docker.compose.host", "myhost");
|
||||
source.put("spring.docker.compose.startup.command", "start");
|
||||
source.put("spring.docker.compose.shutdown.command", "stop");
|
||||
source.put("spring.docker.compose.shutdown.timeout", "5s");
|
||||
source.put("spring.docker.compose.profiles.active", "myprofile");
|
||||
Binder binder = new Binder(new MapConfigurationPropertySource(source));
|
||||
DockerComposeProperties properties = DockerComposeProperties.get(binder);
|
||||
assertThat(properties.getFile()).isEqualTo(new File("my-compose.yml"));
|
||||
assertThat(properties.getLifecycleManagement()).isEqualTo(LifecycleManagement.START_ONLY);
|
||||
assertThat(properties.getHost()).isEqualTo("myhost");
|
||||
assertThat(properties.getStartup().getCommand()).isEqualTo(StartupCommand.START);
|
||||
assertThat(properties.getShutdown().getCommand()).isEqualTo(ShutdownCommand.STOP);
|
||||
assertThat(properties.getShutdown().getTimeout()).isEqualTo(Duration.ofSeconds(5));
|
||||
assertThat(properties.getProfiles().getActive()).containsExactly("myprofile");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.lifecycle;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.RunningService;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerComposeServicesReadyEvent}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerComposeServicesReadyEventTests {
|
||||
|
||||
private ApplicationContext applicationContext = mock(ApplicationContext.class);
|
||||
|
||||
private List<RunningService> runningServices = List.of(mock(RunningService.class));
|
||||
|
||||
private DockerComposeServicesReadyEvent event = new DockerComposeServicesReadyEvent(this.applicationContext,
|
||||
this.runningServices);
|
||||
|
||||
@Test
|
||||
void getSourceReturnsSource() {
|
||||
assertThat(this.event.getSource()).isSameAs(this.applicationContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getRunningServicesReturnsRunningServices() {
|
||||
assertThat(this.event.getRunningServices()).isSameAs(this.runningServices);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.lifecycle;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link LifecycleManagement}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class LifecycleManagementTests {
|
||||
|
||||
@Test
|
||||
void shouldStartupWhenNone() {
|
||||
assertThat(LifecycleManagement.NONE.shouldStartup()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldShutdownWhenNone() {
|
||||
assertThat(LifecycleManagement.NONE.shouldShutdown()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldStartupWhenStartOnly() {
|
||||
assertThat(LifecycleManagement.START_ONLY.shouldStartup()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldShutdownWhenStartOnly() {
|
||||
assertThat(LifecycleManagement.START_ONLY.shouldShutdown()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldStartupWhenStartAndStop() {
|
||||
assertThat(LifecycleManagement.START_AND_STOP.shouldStartup()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldShutdownWhenStartAndStop() {
|
||||
assertThat(LifecycleManagement.START_AND_STOP.shouldShutdown()).isTrue();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.lifecycle;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.DockerCompose;
|
||||
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ShutdownCommand}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ShutdownCommandTests {
|
||||
|
||||
private DockerCompose dockerCompose = mock(DockerCompose.class);
|
||||
|
||||
private Duration duration = Duration.ofSeconds(10);
|
||||
|
||||
@Test
|
||||
void applyToWhenDown() {
|
||||
ShutdownCommand.DOWN.applyTo(this.dockerCompose, this.duration);
|
||||
then(this.dockerCompose).should().down(this.duration);
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyToWhenStart() {
|
||||
ShutdownCommand.STOP.applyTo(this.dockerCompose, this.duration);
|
||||
then(this.dockerCompose).should().stop(this.duration);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.lifecycle;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.DockerCompose;
|
||||
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link StartupCommand}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class StartupCommandTests {
|
||||
|
||||
private DockerCompose dockerCompose = mock(DockerCompose.class);
|
||||
|
||||
@Test
|
||||
void applyToWhenUp() {
|
||||
StartupCommand.UP.applyTo(this.dockerCompose);
|
||||
then(this.dockerCompose).should().up();
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyToWhenStart() {
|
||||
StartupCommand.START.applyTo(this.dockerCompose);
|
||||
then(this.dockerCompose).should().start();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.readiness;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ReadinessProperties}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ReadinessPropertiesTests {
|
||||
|
||||
@Test
|
||||
void getWhenNoPropertiesReturnsNewInstance() {
|
||||
Binder binder = new Binder(new MapConfigurationPropertySource());
|
||||
ReadinessProperties properties = ReadinessProperties.get(binder);
|
||||
assertThat(properties.getTimeout()).isEqualTo(Duration.ofMinutes(2));
|
||||
assertThat(properties.getTcp().getConnectTimeout()).isEqualTo(Duration.ofMillis(200));
|
||||
assertThat(properties.getTcp().getReadTimeout()).isEqualTo(Duration.ofMillis(200));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenPropertiesReturnsBoundInstance() {
|
||||
Map<String, String> source = new LinkedHashMap<>();
|
||||
source.put("spring.docker.compose.readiness.timeout", "10s");
|
||||
source.put("spring.docker.compose.readiness.tcp.connect-timeout", "400ms");
|
||||
source.put("spring.docker.compose.readiness.tcp.read-timeout", "500ms");
|
||||
Binder binder = new Binder(new MapConfigurationPropertySource(source));
|
||||
ReadinessProperties properties = ReadinessProperties.get(binder);
|
||||
assertThat(properties.getTimeout()).isEqualTo(Duration.ofSeconds(10));
|
||||
assertThat(properties.getTcp().getConnectTimeout()).isEqualTo(Duration.ofMillis(400));
|
||||
assertThat(properties.getTcp().getReadTimeout()).isEqualTo(Duration.ofMillis(500));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.readiness;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.RunningService;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ReadinessTimeoutException}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ReadinessTimeoutExceptionTests {
|
||||
|
||||
@Test
|
||||
void createCreatesException() {
|
||||
Duration timeout = Duration.ofSeconds(10);
|
||||
RunningService s1 = mock(RunningService.class);
|
||||
given(s1.name()).willReturn("s1");
|
||||
RunningService s2 = mock(RunningService.class);
|
||||
given(s2.name()).willReturn("s2");
|
||||
ServiceNotReadyException cause1 = new ServiceNotReadyException(s1, "1 not ready");
|
||||
ServiceNotReadyException cause2 = new ServiceNotReadyException(s2, "2 not ready");
|
||||
List<ServiceNotReadyException> exceptions = List.of(cause1, cause2);
|
||||
ReadinessTimeoutException exception = new ReadinessTimeoutException(timeout, exceptions);
|
||||
assertThat(exception).hasMessage("Readiness timeout of PT10S reached while waiting for services [s1, s2]");
|
||||
assertThat(exception).hasSuppressedException(cause1).hasSuppressedException(cause2);
|
||||
assertThat(exception.getTimeout()).isEqualTo(timeout);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.readiness;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.RunningService;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ServiceNotReadyException}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ServiceNotReadyExceptionTests {
|
||||
|
||||
@Test
|
||||
void getServiceReturnsService() {
|
||||
RunningService service = mock(RunningService.class);
|
||||
ServiceNotReadyException exception = new ServiceNotReadyException(service, "fail");
|
||||
assertThat(exception.getService()).isEqualTo(service);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.readiness;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.docker.compose.core.RunningService;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader.ArgumentResolver;
|
||||
import org.springframework.core.test.io.support.MockSpringFactoriesLoader;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
/**
|
||||
* Tests for {@link ServiceReadinessChecks}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ServiceReadinessChecksTests {
|
||||
|
||||
private Clock clock;
|
||||
|
||||
Instant now = Instant.now();
|
||||
|
||||
private MockSpringFactoriesLoader loader;
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
private MockEnvironment environment;
|
||||
|
||||
private Binder binder;
|
||||
|
||||
private RunningService runningService;
|
||||
|
||||
private List<RunningService> runningServices;
|
||||
|
||||
private MockServiceReadinessCheck mockTcpCheck = new MockServiceReadinessCheck();
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.clock = mock(Clock.class);
|
||||
given(this.clock.instant()).willAnswer((args) -> this.now);
|
||||
this.loader = new MockSpringFactoriesLoader();
|
||||
this.classLoader = getClass().getClassLoader();
|
||||
this.environment = new MockEnvironment();
|
||||
this.binder = Binder.get(this.environment);
|
||||
this.runningService = mock(RunningService.class);
|
||||
this.runningServices = List.of(this.runningService);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadCanResolveArguments() {
|
||||
this.loader = spy(MockSpringFactoriesLoader.class);
|
||||
createChecks();
|
||||
ArgumentCaptor<ArgumentResolver> captor = ArgumentCaptor.forClass(ArgumentResolver.class);
|
||||
then(this.loader).should().load(eq(ServiceReadinessCheck.class), captor.capture());
|
||||
ArgumentResolver argumentResolver = captor.getValue();
|
||||
assertThat(argumentResolver.resolve(ClassLoader.class)).isEqualTo(this.classLoader);
|
||||
assertThat(argumentResolver.resolve(Environment.class)).isEqualTo(this.environment);
|
||||
assertThat(argumentResolver.resolve(Binder.class)).isEqualTo(this.binder);
|
||||
}
|
||||
|
||||
@Test
|
||||
void waitUntilReadyWhenImmediatelyReady() {
|
||||
MockServiceReadinessCheck check = new MockServiceReadinessCheck();
|
||||
this.loader.addInstance(ServiceReadinessCheck.class, check);
|
||||
createChecks().waitUntilReady(this.runningServices);
|
||||
assertThat(check.getChecked()).contains(this.runningService);
|
||||
assertThat(this.mockTcpCheck.getChecked()).contains(this.runningService);
|
||||
}
|
||||
|
||||
@Test
|
||||
void waitUntilReadyWhenTakesTimeToBeReady() {
|
||||
MockServiceReadinessCheck check = new MockServiceReadinessCheck(2);
|
||||
this.loader.addInstance(ServiceReadinessCheck.class, check);
|
||||
createChecks().waitUntilReady(this.runningServices);
|
||||
assertThat(check.getChecked()).hasSize(2).contains(this.runningService);
|
||||
assertThat(this.mockTcpCheck.getChecked()).contains(this.runningService);
|
||||
}
|
||||
|
||||
@Test
|
||||
void waitUntilReadyWhenTimeout() {
|
||||
MockServiceReadinessCheck check = new MockServiceReadinessCheck(Integer.MAX_VALUE);
|
||||
this.loader.addInstance(ServiceReadinessCheck.class, check);
|
||||
assertThatExceptionOfType(ReadinessTimeoutException.class)
|
||||
.isThrownBy(() -> createChecks().waitUntilReady(this.runningServices))
|
||||
.satisfies((ex) -> assertThat(ex.getSuppressed()).hasSize(1));
|
||||
assertThat(check.getChecked()).hasSizeGreaterThan(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
void waitForWhenServiceHasDisableLabelDoesNotCheck() {
|
||||
given(this.runningService.labels()).willReturn(Map.of("org.springframework.boot.readiness-check.disable", ""));
|
||||
MockServiceReadinessCheck check = new MockServiceReadinessCheck();
|
||||
this.loader.addInstance(ServiceReadinessCheck.class, check);
|
||||
createChecks().waitUntilReady(this.runningServices);
|
||||
assertThat(check.getChecked()).isEmpty();
|
||||
assertThat(this.mockTcpCheck.getChecked()).isEmpty();
|
||||
}
|
||||
|
||||
void sleep(Duration duration) {
|
||||
this.now = this.now.plus(duration);
|
||||
}
|
||||
|
||||
private ServiceReadinessChecks createChecks() {
|
||||
return new ServiceReadinessChecks(this.clock, this::sleep, this.loader, this.classLoader, this.environment,
|
||||
this.binder, (properties) -> this.mockTcpCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock {@link ServiceReadinessCheck}.
|
||||
*/
|
||||
static class MockServiceReadinessCheck implements ServiceReadinessCheck {
|
||||
|
||||
private final Integer failUntil;
|
||||
|
||||
private final List<RunningService> checked = new ArrayList<>();
|
||||
|
||||
MockServiceReadinessCheck() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
MockServiceReadinessCheck(Integer failUntil) {
|
||||
this.failUntil = failUntil;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(RunningService service) throws ServiceNotReadyException {
|
||||
this.checked.add(service);
|
||||
if (this.failUntil != null && this.checked.size() < this.failUntil) {
|
||||
throw new ServiceNotReadyException(service, "Waiting");
|
||||
}
|
||||
}
|
||||
|
||||
List<RunningService> getChecked() {
|
||||
return this.checked;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.readiness;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import org.assertj.core.api.ThrowingConsumer;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.ConnectionPorts;
|
||||
import org.springframework.boot.docker.compose.core.RunningService;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link TcpConnectServiceReadinessCheck}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class TcpConnectServiceReadinessCheckTests {
|
||||
|
||||
private static final int EPHEMERAL_PORT = 0;
|
||||
|
||||
private TcpConnectServiceReadinessCheck readinessCheck;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
ReadinessProperties.Tcp tcpProperties = new ReadinessProperties.Tcp();
|
||||
tcpProperties.setConnectTimeout(Duration.ofMillis(100));
|
||||
tcpProperties.setReadTimeout(Duration.ofMillis(100));
|
||||
this.readinessCheck = new TcpConnectServiceReadinessCheck(tcpProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkWhenServerWritesData() throws Exception {
|
||||
withServer((socket) -> socket.getOutputStream().write('!'), (port) -> check(port));
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkWhenNoSocketOutput() throws Exception {
|
||||
// Simulate waiting for traffic from client to server. The sleep duration must
|
||||
// be longer than the read timeout of the ready check!
|
||||
withServer((socket) -> sleep(Duration.ofSeconds(10)), (port) -> check(port));
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkWhenImmediateDisconnect() throws IOException {
|
||||
withServer(Socket::close,
|
||||
(port) -> assertThatExceptionOfType(ServiceNotReadyException.class).isThrownBy(() -> check(port))
|
||||
.withMessage("Immediate disconnect while connecting to port %d".formatted(port)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkWhenNoServerListening() {
|
||||
assertThatExceptionOfType(ServiceNotReadyException.class).isThrownBy(() -> check(12345))
|
||||
.withMessage("IOException while connecting to port 12345");
|
||||
}
|
||||
|
||||
private void withServer(ThrowingConsumer<Socket> socketAction, ThrowingConsumer<Integer> portAction)
|
||||
throws IOException {
|
||||
try (ServerSocket serverSocket = new ServerSocket()) {
|
||||
serverSocket.bind(new InetSocketAddress("127.0.0.1", EPHEMERAL_PORT));
|
||||
Thread thread = new Thread(() -> {
|
||||
try (Socket socket = serverSocket.accept()) {
|
||||
socketAction.accept(socket);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new UncheckedIOException(ex);
|
||||
}
|
||||
});
|
||||
thread.setName("Acceptor-%d".formatted(serverSocket.getLocalPort()));
|
||||
thread.setUncaughtExceptionHandler((ignored, ex) -> ex.printStackTrace());
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
portAction.accept(serverSocket.getLocalPort());
|
||||
}
|
||||
}
|
||||
|
||||
private void check(Integer port) {
|
||||
this.readinessCheck.check(mockRunningService(port));
|
||||
}
|
||||
|
||||
private RunningService mockRunningService(Integer port) {
|
||||
RunningService runningService = mock(RunningService.class);
|
||||
ConnectionPorts ports = mock(ConnectionPorts.class);
|
||||
given(ports.getAll("tcp")).willReturn(List.of(port));
|
||||
given(runningService.host()).willReturn("localhost");
|
||||
given(runningService.ports()).willReturn(ports);
|
||||
return runningService;
|
||||
}
|
||||
|
||||
private void sleep(Duration duration) {
|
||||
try {
|
||||
Thread.sleep(duration.toMillis());
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.elasticsearch;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node;
|
||||
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node.Protocol;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link ElasticsearchDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("elasticsearch-compose.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
ElasticsearchConnectionDetails connectionDetails = run(ElasticsearchConnectionDetails.class);
|
||||
assertThat(connectionDetails.getUsername()).isEqualTo("elastic");
|
||||
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
|
||||
assertThat(connectionDetails.getPathPrefix()).isNull();
|
||||
assertThat(connectionDetails.getNodes()).hasSize(1);
|
||||
Node node = connectionDetails.getNodes().get(0);
|
||||
assertThat(node.hostname()).isNotNull();
|
||||
assertThat(node.port()).isGreaterThan(0);
|
||||
assertThat(node.protocol()).isEqualTo(Protocol.HTTP);
|
||||
assertThat(node.username()).isEqualTo("elastic");
|
||||
assertThat(node.password()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.elasticsearch;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Tests for {@link ElasticsearchEnvironment}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ElasticsearchEnvironmentTests {
|
||||
|
||||
@Test
|
||||
void createWhenHasElasticPasswordFileThrowsException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new ElasticsearchEnvironment(Map.of("ELASTIC_PASSWORD_FILE", "afile")))
|
||||
.withMessage("ELASTIC_PASSWORD_FILE is not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenNoPassword() {
|
||||
ElasticsearchEnvironment environment = new ElasticsearchEnvironment(Collections.emptyMap());
|
||||
assertThat(environment.getPassword()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasPassword() {
|
||||
ElasticsearchEnvironment environment = new ElasticsearchEnvironment(Map.of("ELASTIC_PASSWORD", "secret"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.elasticsearch;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link ElasticsearchDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class XElasticsearchDockerComposeConnectionDetailsFactoryTests {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@Test
|
||||
void usernameIsElastic() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
ElasticsearchService elasticsearchService = new ElasticsearchService(service);
|
||||
assertThat(elasticsearchService.getUsername()).isEqualTo("elastic");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("ELASTIC_PASSWORD", "some-secret-password"));
|
||||
ElasticsearchService elasticsearchService = new ElasticsearchService(service);
|
||||
assertThat(elasticsearchService.getPassword()).isEqualTo("some-secret-password");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordHasFallback() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
ElasticsearchService elasticsearchService = new ElasticsearchService(service);
|
||||
assertThat(elasticsearchService.getPassword()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordDoesNotSupportFile() {
|
||||
RunningService service = createService(Map.of("ELASTIC_PASSWORD_FILE", "/password.txt"));
|
||||
ElasticsearchService elasticsearchService = new ElasticsearchService(service);
|
||||
assertThatThrownBy(elasticsearchService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("ELASTIC_PASSWORD_FILE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPort() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
ElasticsearchService elasticsearchService = new ElasticsearchService(service);
|
||||
assertThat(elasticsearchService.getPort()).isEqualTo(19200);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matches() {
|
||||
assertThat(ElasticsearchService.matches(createService(Collections.emptyMap()))).isTrue();
|
||||
assertThat(
|
||||
ElasticsearchService.matches(createService(ImageReference.parse("redis:7.1"), Collections.emptyMap())))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private RunningService createService(Map<String, String> env) {
|
||||
return createService(ImageReference.parse("elasticsearch:8.6.2"), env);
|
||||
}
|
||||
|
||||
private RunningService createService(ImageReference image, Map<String, String> env) {
|
||||
return RunningServiceBuilder.create("service-1", image).addTcpPort(9200, 19200).env(env).build();
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.jdbc;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.ConnectionPorts;
|
||||
import org.springframework.boot.docker.compose.core.RunningService;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link JdbcUrlBuilder}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class JdbcUrlBuilderTests {
|
||||
|
||||
private JdbcUrlBuilder builder = new JdbcUrlBuilder("mydb", 1234);
|
||||
|
||||
@Test
|
||||
void createWhenDriverProtocolIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new JdbcUrlBuilder(null, 123))
|
||||
.withMessage("DriverProtocol must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildBuildsUrl() {
|
||||
RunningService service = mockService(456);
|
||||
String url = this.builder.build(service, "mydb");
|
||||
assertThat(url).isEqualTo("jdbc:mydb://myhost:456/mydb");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildWhenHasParamsLabelBuildsUrl() {
|
||||
RunningService service = mockService(456, Map.of("org.springframework.boot.jdbc.parameters", "foo=bar"));
|
||||
String url = this.builder.build(service, "mydb");
|
||||
assertThat(url).isEqualTo("jdbc:mydb://myhost:456/mydb?foo=bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildWhenServiceIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.builder.build(null, "mydb"))
|
||||
.withMessage("Service must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildWhenDatabaseIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.builder.build(mockService(456), null))
|
||||
.withMessage("Database must not be null");
|
||||
}
|
||||
|
||||
private RunningService mockService(int mappedPort) {
|
||||
return mockService(mappedPort, Collections.emptyMap());
|
||||
}
|
||||
|
||||
private RunningService mockService(int mappedPort, Map<String, String> labels) {
|
||||
RunningService service = mock(RunningService.class);
|
||||
ConnectionPorts ports = mock(ConnectionPorts.class);
|
||||
given(ports.get(1234)).willReturn(mappedPort);
|
||||
given(service.host()).willReturn("myhost");
|
||||
given(service.ports()).willReturn(ports);
|
||||
given(service.labels()).willReturn(labels);
|
||||
return service;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mariadb;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Tests for {@link MariaDbEnvironment}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MariaDbEnvironmentTests {
|
||||
|
||||
@Test
|
||||
void createWhenHasMariadbRandomRootPasswordThrowsException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_RANDOM_ROOT_PASSWORD", "true")))
|
||||
.withMessage("MARIADB_RANDOM_ROOT_PASSWORD is not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenHasMysqlRandomRootPasswordThrowsException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new MariaDbEnvironment(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true")))
|
||||
.withMessage("MYSQL_RANDOM_ROOT_PASSWORD is not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenHasMariadbRootPasswordHashThrowsException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_ROOT_PASSWORD_HASH", "0FF")))
|
||||
.withMessage("MARIADB_ROOT_PASSWORD_HASH is not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenHasNoPasswordThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> new MariaDbEnvironment(Collections.emptyMap()))
|
||||
.withMessage("No MariaDB password found");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenHasNoDatabaseThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_PASSWORD", "secret")))
|
||||
.withMessage("No MARIADB_DATABASE defined");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenHasMariadbUser() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MARIADB_USER", "myself", "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getUsername()).isEqualTo("myself");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenHasMySqlUser() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MYSQL_USER", "myself", "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getUsername()).isEqualTo("myself");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenHasMariadbUserAndMySqlUser() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(Map.of("MARIADB_USER", "myself", "MYSQL_USER", "me",
|
||||
"MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getUsername()).isEqualTo("myself");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenHasNoMariadbUserOrMySqlUser() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getUsername()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasMariadbPassword() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasMysqlPassword() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MYSQL_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasMysqlRootPassword() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MYSQL_ROOT_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasMariadbPasswordAndMysqlPassword() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MARIADB_PASSWORD", "secret", "MYSQL_PASSWORD", "donttell", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasMariadbPasswordAndMysqlRootPassword() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MARIADB_PASSWORD", "secret", "MYSQL_ROOT_PASSWORD", "donttell", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasNoPasswordAndMariadbAllowEmptyPassword() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getPassword()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasNoPasswordAndMysqlAllowEmptyPassword() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getPassword()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDatabaseWhenHasMariadbDatabase() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db"));
|
||||
assertThat(environment.getDatabase()).isEqualTo("db");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDatabaseWhenHasMysqlDatabase() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db"));
|
||||
assertThat(environment.getDatabase()).isEqualTo("db");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDatabaseWhenHasMariadbAndMysqlDatabase() {
|
||||
MariaDbEnvironment environment = new MariaDbEnvironment(
|
||||
Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db", "MYSQL_DATABASE", "otherdb"));
|
||||
assertThat(environment.getDatabase()).isEqualTo("db");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mariadb;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MariaDbJdbcDockerComposeConnectionDetailsFactory}
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("mariadb-compose.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
JdbcConnectionDetails connectionDetails = run(JdbcConnectionDetails.class);
|
||||
assertThat(connectionDetails.getUsername()).isEqualTo("myuser");
|
||||
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
|
||||
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:mariadb://").endsWith("/mydatabase");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mariadb;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactoryOptions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MariaDbR2dbcDockerComposeConnectionDetailsFactory}
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("mariadb-compose.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
R2dbcConnectionDetails connectionDetails = run(R2dbcConnectionDetails.class);
|
||||
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
|
||||
assertThat(connectionFactoryOptions.toString()).contains("database=mydatabase", "driver=mariadb",
|
||||
"password=REDACTED", "user=myuser");
|
||||
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mariadb;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link XMariaDbDockerComposeConnectionDetailsFactoryTests}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class XMariaDbDockerComposeConnectionDetailsFactoryTests {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@Test
|
||||
void usernameUsesMariaDbVariables() {
|
||||
RunningService service = createService(Map.of("MARIADB_USER", "user-1"));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getUsername()).isEqualTo("user-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void usernameUsesMysqlVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_USER", "user-1"));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getUsername()).isEqualTo("user-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void usernameDefaultsToRoot() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getUsername()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesMariaDbVariables() {
|
||||
RunningService service = createService(Map.of("MARIADB_PASSWORD", "password-1"));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getPassword()).isEqualTo("password-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesMysqlVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_PASSWORD", "password-1"));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getPassword()).isEqualTo("password-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesMariaDbRootVariables() {
|
||||
RunningService service = createService(Map.of("MARIADB_ROOT_PASSWORD", "root-password-1"));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getPassword()).isEqualTo("root-password-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesMysqlRootVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_ROOT_PASSWORD", "root-password-1"));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getPassword()).isEqualTo("root-password-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordSupportsEmptyRootPasswordMariaDb() {
|
||||
RunningService service = createService(Map.of("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD", ""));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getPassword()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordDoesNotSupportRootPasswordHash() {
|
||||
RunningService service = createService(Map.of("MARIADB_ROOT_PASSWORD_HASH", "true"));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThatThrownBy(mariaDbService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("MARIADB_ROOT_PASSWORD_HASH");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordDoesNotSupportRandomRootPasswordMariaDb() {
|
||||
RunningService service = createService(Map.of("MARIADB_RANDOM_ROOT_PASSWORD", "true"));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThatThrownBy(mariaDbService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("MARIADB_RANDOM_ROOT_PASSWORD");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordDoesNotSupportRandomRootPasswordMysql() {
|
||||
RunningService service = createService(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true"));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThatThrownBy(mariaDbService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("MYSQL_RANDOM_ROOT_PASSWORD");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordHasNoFallback() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThatThrownBy(mariaDbService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Can't find password for user");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordSupportsEmptyRootPasswordMysql() {
|
||||
RunningService service = createService(Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", ""));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getPassword()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseUsesMariaDbVariables() {
|
||||
RunningService service = createService(Map.of("MARIADB_DATABASE", "database-1"));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getDatabase()).isEqualTo("database-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseUsesMysqlVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_DATABASE", "database-1"));
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getDatabase()).isEqualTo("database-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseHasNoFallback() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThatThrownBy(mariaDbService::getDatabase).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("MARIADB_DATABASE")
|
||||
.hasMessageContaining("MYSQL_DATABASE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPort() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MariaDbService mariaDbService = new MariaDbService(service);
|
||||
assertThat(mariaDbService.getPort()).isEqualTo(33060);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matches() {
|
||||
assertThat(MariaDbService.matches(createService(Collections.emptyMap()))).isTrue();
|
||||
assertThat(MariaDbService.matches(createService(ImageReference.parse("redis:7.1"), Collections.emptyMap())))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private RunningService createService(Map<String, String> env) {
|
||||
return createService(ImageReference.parse("mariadb:10.10"), env);
|
||||
}
|
||||
|
||||
private RunningService createService(ImageReference image, Map<String, String> env) {
|
||||
return RunningServiceBuilder.create("service-1", image).addTcpPort(3306, 33060).env(env).build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mongo;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MongoDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MongoDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
MongoDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("mongo-compose.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
MongoConnectionDetails connectionDetails = run(MongoConnectionDetails.class);
|
||||
assertThat(connectionDetails.getConnectionString().toString()).startsWith("mongodb://root:secret@")
|
||||
.endsWith("/mydatabase");
|
||||
assertThat(connectionDetails.getGridFs()).isNull();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mongo;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Tests for {@link MongoEnvironment}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MongoEnvironmentTests {
|
||||
|
||||
@Test
|
||||
void createWhenMonoInitdbRootUsernameFileSetThrowsException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new MongoEnvironment(Map.of("MONGO_INITDB_ROOT_USERNAME_FILE", "file")))
|
||||
.withMessage("MONGO_INITDB_ROOT_USERNAME_FILE is not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenMonoInitdbRootPasswordFileSetThrowsException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new MongoEnvironment(Map.of("MONGO_INITDB_ROOT_PASSWORD_FILE", "file")))
|
||||
.withMessage("MONGO_INITDB_ROOT_PASSWORD_FILE is not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenHasNoMongoInitdbRootUsernameSet() {
|
||||
MongoEnvironment environment = new MongoEnvironment(Collections.emptyMap());
|
||||
assertThat(environment.getUsername()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenHasMongoInitdbRootUsernameSet() {
|
||||
MongoEnvironment environment = new MongoEnvironment(Map.of("MONGO_INITDB_ROOT_USERNAME", "user"));
|
||||
assertThat(environment.getUsername()).isEqualTo("user");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasNoMongoInitdbRootPasswordSet() {
|
||||
MongoEnvironment environment = new MongoEnvironment(Collections.emptyMap());
|
||||
assertThat(environment.getPassword()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasMongoInitdbRootPasswordSet() {
|
||||
MongoEnvironment environment = new MongoEnvironment(Map.of("MONGO_INITDB_ROOT_PASSWORD", "secret"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDatabaseWhenHasNoMongoInitdbDatabaseSet() {
|
||||
MongoEnvironment environment = new MongoEnvironment(Collections.emptyMap());
|
||||
assertThat(environment.getDatabase()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDatabaseWhenHasMongoInitdbDatabaseSet() {
|
||||
MongoEnvironment environment = new MongoEnvironment(Map.of("MONGO_INITDB_DATABASE", "db"));
|
||||
assertThat(environment.getDatabase()).isEqualTo("db");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mongo;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link MongoDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class XMongoDockerComposeConnectionDetailsFactoryTests {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@Test
|
||||
void usernameUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("MONGO_INITDB_ROOT_USERNAME", "user-1"));
|
||||
MongoService mongoService = new MongoService(service);
|
||||
assertThat(mongoService.getUsername()).isEqualTo("user-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotSupportUsernameFile() {
|
||||
RunningService service = createService(Map.of("MONGO_INITDB_ROOT_USERNAME_FILE", "/username.txt"));
|
||||
MongoService mongoService = new MongoService(service);
|
||||
assertThatThrownBy(mongoService::getUsername).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("MONGO_INITDB_ROOT_USERNAME_FILE is not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void usernameHasDefault() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MongoService mongoService = new MongoService(service);
|
||||
assertThat(mongoService.getUsername()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("MONGO_INITDB_ROOT_PASSWORD", "some-secret-1"));
|
||||
MongoService mongoService = new MongoService(service);
|
||||
assertThat(mongoService.getPassword()).isEqualTo("some-secret-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotSupportPasswordFile() {
|
||||
RunningService service = createService(Map.of("MONGO_INITDB_ROOT_PASSWORD_FILE", "/username.txt"));
|
||||
MongoService mongoService = new MongoService(service);
|
||||
assertThatThrownBy(mongoService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("MONGO_INITDB_ROOT_PASSWORD_FILE is not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordHasDefault() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MongoService mongoService = new MongoService(service);
|
||||
assertThat(mongoService.getPassword()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("MONGO_INITDB_DATABASE", "database-1"));
|
||||
MongoService mongoService = new MongoService(service);
|
||||
assertThat(mongoService.getDatabase()).isEqualTo("database-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseHasDefault() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MongoService mongoService = new MongoService(service);
|
||||
assertThat(mongoService.getDatabase()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPort() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MongoService mongoService = new MongoService(service);
|
||||
assertThat(mongoService.getPort()).isEqualTo(12345);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matches() {
|
||||
assertThat(MongoService.matches(createService(Collections.emptyMap()))).isTrue();
|
||||
assertThat(MongoService.matches(createService(ImageReference.parse("redis:7.1"), Collections.emptyMap())))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private RunningService createService(Map<String, String> env) {
|
||||
return createService(ImageReference.parse("mongo:6.0"), env);
|
||||
}
|
||||
|
||||
private RunningService createService(ImageReference image, Map<String, String> env) {
|
||||
return RunningServiceBuilder.create("service-1", image).addTcpPort(27017, 12345).env(env).build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mysql;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Tests for {@link MySqlEnvironment}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MySqlEnvironmentTests {
|
||||
|
||||
@Test
|
||||
void createWhenHasMysqlRandomRootPasswordThrowsException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new MySqlEnvironment(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true")))
|
||||
.withMessage("MYSQL_RANDOM_ROOT_PASSWORD is not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenHasNoPasswordThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> new MySqlEnvironment(Collections.emptyMap()))
|
||||
.withMessage("No MySQL password found");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenHasNoDatabaseThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret")))
|
||||
.withMessage("No MYSQL_DATABASE defined");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenHasMySqlUser() {
|
||||
MySqlEnvironment environment = new MySqlEnvironment(
|
||||
Map.of("MYSQL_USER", "myself", "MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db"));
|
||||
assertThat(environment.getUsername()).isEqualTo("myself");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenHasNoMySqlUser() {
|
||||
MySqlEnvironment environment = new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db"));
|
||||
assertThat(environment.getUsername()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasMysqlPassword() {
|
||||
MySqlEnvironment environment = new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasMysqlRootPassword() {
|
||||
MySqlEnvironment environment = new MySqlEnvironment(
|
||||
Map.of("MYSQL_ROOT_PASSWORD", "secret", "MYSQL_DATABASE", "db"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasNoPasswordAndMysqlAllowEmptyPassword() {
|
||||
MySqlEnvironment environment = new MySqlEnvironment(
|
||||
Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db"));
|
||||
assertThat(environment.getPassword()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDatabaseWhenHasMysqlDatabase() {
|
||||
MySqlEnvironment environment = new MySqlEnvironment(
|
||||
Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db"));
|
||||
assertThat(environment.getDatabase()).isEqualTo("db");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mysql;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MySqlJdbcDockerComposeConnectionDetailsFactory}
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("mysql-compose.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
JdbcConnectionDetails connectionDetails = run(JdbcConnectionDetails.class);
|
||||
assertThat(connectionDetails.getUsername()).isEqualTo("myuser");
|
||||
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
|
||||
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:mysql://").endsWith("/mydatabase");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mysql;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactoryOptions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MySqlR2dbcDockerComposeConnectionDetailsFactory}
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("mysql-compose.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
R2dbcConnectionDetails connectionDetails = run(R2dbcConnectionDetails.class);
|
||||
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
|
||||
assertThat(connectionFactoryOptions.toString()).contains("database=mydatabase", "driver=mysql",
|
||||
"password=REDACTED", "user=myuser");
|
||||
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mysql;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Test for {@link MySqlR2dbcDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class XMySqlDbR2dbcDockerComposeConnectionDetailsFactoryTests {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@Test
|
||||
void usernameUsesMysqlVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_USER", "user-1"));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getUsername()).isEqualTo("user-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void usernameDefaultsToRoot() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getUsername()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesMysqlVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_PASSWORD", "password-1"));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getPassword()).isEqualTo("password-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesMysqlRootVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_ROOT_PASSWORD", "root-password-1"));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getPassword()).isEqualTo("root-password-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordDoesNotSupportRandomRootPasswordMysql() {
|
||||
RunningService service = createService(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true"));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThatThrownBy(mysqlService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("MYSQL_RANDOM_ROOT_PASSWORD");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordHasNoFallback() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThatThrownBy(mysqlService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Can't find password for user");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordSupportsEmptyRootPasswordMysql() {
|
||||
RunningService service = createService(Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", ""));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getPassword()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseUsesMysqlVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_DATABASE", "database-1"));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getDatabase()).isEqualTo("database-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseHasNoFallback() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThatThrownBy(mysqlService::getDatabase).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("MYSQL_DATABASE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPort() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getPort()).isEqualTo(33060);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matches() {
|
||||
assertThat(MySqlService.matches(createService(Collections.emptyMap()))).isTrue();
|
||||
assertThat(MySqlService.matches(createService(ImageReference.parse("redis:7.1"), Collections.emptyMap())))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private RunningService createService(Map<String, String> env) {
|
||||
return createService(ImageReference.parse("mysql:8.0"), env);
|
||||
}
|
||||
|
||||
private RunningService createService(ImageReference image, Map<String, String> env) {
|
||||
return RunningServiceBuilder.create("service-1", image).addTcpPort(3306, 33060).env(env).build();
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.mysql;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Test for {@link MySqlJdbcDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class XMySqlJdbcDockerComposeConnectionDetailsFactoryTests {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@Test
|
||||
void usernameUsesMysqlVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_USER", "user-1"));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getUsername()).isEqualTo("user-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void usernameDefaultsToRoot() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getUsername()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesMysqlVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_PASSWORD", "password-1"));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getPassword()).isEqualTo("password-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesMysqlRootVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_ROOT_PASSWORD", "root-password-1"));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getPassword()).isEqualTo("root-password-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordDoesNotSupportRandomRootPasswordMysql() {
|
||||
RunningService service = createService(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true"));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThatThrownBy(mysqlService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("MYSQL_RANDOM_ROOT_PASSWORD");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordHasNoFallback() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThatThrownBy(mysqlService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Can't find password for user");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordSupportsEmptyRootPasswordMysql() {
|
||||
RunningService service = createService(Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", ""));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getPassword()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseUsesMysqlVariables() {
|
||||
RunningService service = createService(Map.of("MYSQL_DATABASE", "database-1"));
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getDatabase()).isEqualTo("database-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseHasNoFallback() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThatThrownBy(mysqlService::getDatabase).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("MYSQL_DATABASE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPort() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
MySqlService mysqlService = new MySqlService(service);
|
||||
assertThat(mysqlService.getPort()).isEqualTo(33060);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matches() {
|
||||
assertThat(MySqlService.matches(createService(Collections.emptyMap()))).isTrue();
|
||||
assertThat(MySqlService.matches(createService(ImageReference.parse("redis:7.1"), Collections.emptyMap())))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private RunningService createService(Map<String, String> env) {
|
||||
return createService(ImageReference.parse("mysql:8.0"), env);
|
||||
}
|
||||
|
||||
private RunningService createService(ImageReference image, Map<String, String> env) {
|
||||
return RunningServiceBuilder.create("service-1", image).addTcpPort(3306, 33060).env(env).build();
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.postgres;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Tests for {@link PostgresEnvironment}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class PostgresEnvironmentTests {
|
||||
|
||||
@Test
|
||||
void createWhenNoPostgresPasswordThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> new PostgresEnvironment(Collections.emptyMap()))
|
||||
.withMessage("No POSTGRES_PASSWORD defined");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenNoPostgresUser() {
|
||||
PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret"));
|
||||
assertThat(environment.getUsername()).isEqualTo("postgres");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenHasPostgresUser() {
|
||||
PostgresEnvironment environment = new PostgresEnvironment(
|
||||
Map.of("POSTGRES_USER", "me", "POSTGRES_PASSWORD", "secret"));
|
||||
assertThat(environment.getUsername()).isEqualTo("me");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPasswordWhenHasPostgresPassword() {
|
||||
PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDatabaseWhenNoPostgresDbOrPostgressUser() {
|
||||
PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret"));
|
||||
assertThat(environment.getDatabase()).isEqualTo("postgress");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDatabaseWhenNoPostgresDbAndPostgressUser() {
|
||||
PostgresEnvironment environment = new PostgresEnvironment(
|
||||
Map.of("POSTGRES_USER", "me", "POSTGRES_PASSWORD", "secret"));
|
||||
assertThat(environment.getDatabase()).isEqualTo("me");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDatabaseWhenHasPostgresDb() {
|
||||
PostgresEnvironment environment = new PostgresEnvironment(
|
||||
Map.of("POSTGRES_DB", "db", "POSTGRES_PASSWORD", "secret"));
|
||||
assertThat(environment.getDatabase()).isEqualTo("db");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.postgres;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link PostgresJdbcDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("postgres-compose.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
JdbcConnectionDetails connectionDetails = run(JdbcConnectionDetails.class);
|
||||
assertThat(connectionDetails.getUsername()).isEqualTo("myuser");
|
||||
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
|
||||
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:postgresql://").endsWith("/mydatabase");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.postgres;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactoryOptions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link PostgresR2dbcDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("postgres-compose.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
R2dbcConnectionDetails connectionDetails = run(R2dbcConnectionDetails.class);
|
||||
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
|
||||
assertThat(connectionFactoryOptions.toString()).contains("database=mydatabase", "driver=postgresql",
|
||||
"password=REDACTED", "user=myuser");
|
||||
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.postgres;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link PostgresR2dbcDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class XPostgresDbR2dbcDockerComposeConnectionDetailsFactoryTests {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@Test
|
||||
void usernameUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("POSTGRES_USER", "user-1"));
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getUsername()).isEqualTo("user-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void usernameHasFallback() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getUsername()).isEqualTo("postgres");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("POSTGRES_PASSWORD", "password-1"));
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getPassword()).isEqualTo("password-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordHasNoFallback() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThatThrownBy(postgresService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("POSTGRES_PASSWORD");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("POSTGRES_DB", "database-1"));
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getDatabase()).isEqualTo("database-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseFallsBackToUsername() {
|
||||
RunningService service = createService(Map.of("POSTGRES_USER", "user-1"));
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getDatabase()).isEqualTo("user-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPort() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getPort()).isEqualTo(54320);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matches() {
|
||||
assertThat(PostgresService.matches(createService(Collections.emptyMap()))).isTrue();
|
||||
assertThat(PostgresService.matches(createService(ImageReference.parse("redis:7.1"), Collections.emptyMap())))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private RunningService createService(Map<String, String> env) {
|
||||
return createService(ImageReference.parse("postgres:15.2"), env);
|
||||
}
|
||||
|
||||
private RunningService createService(ImageReference image, Map<String, String> env) {
|
||||
return RunningServiceBuilder.create("service-1", image).addTcpPort(5432, 54320).env(env).build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.postgres;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link PostgresJdbcDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class XPostgresJdbcDockerComposeConnectionDetailsFactoryTests {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@Test
|
||||
void usernameUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("POSTGRES_USER", "user-1"));
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getUsername()).isEqualTo("user-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void usernameHasFallback() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getUsername()).isEqualTo("postgres");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("POSTGRES_PASSWORD", "password-1"));
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getPassword()).isEqualTo("password-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordHasNoFallback() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThatThrownBy(postgresService::getPassword).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("POSTGRES_PASSWORD");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("POSTGRES_DB", "database-1"));
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getDatabase()).isEqualTo("database-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void databaseFallsBackToUsername() {
|
||||
RunningService service = createService(Map.of("POSTGRES_USER", "user-1"));
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getDatabase()).isEqualTo("user-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPort() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
PostgresService postgresService = new PostgresService(service);
|
||||
assertThat(postgresService.getPort()).isEqualTo(54320);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matches() {
|
||||
assertThat(PostgresService.matches(createService(Collections.emptyMap()))).isTrue();
|
||||
assertThat(PostgresService.matches(createService(ImageReference.parse("redis:7.1"), Collections.emptyMap())))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private RunningService createService(Map<String, String> env) {
|
||||
return createService(ImageReference.parse("postgres:15.2"), env);
|
||||
}
|
||||
|
||||
private RunningService createService(ImageReference image, Map<String, String> env) {
|
||||
return RunningServiceBuilder.create("service-1", image).addTcpPort(5432, 54320).env(env).build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.r2dbc;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactoryOptions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.docker.compose.core.ConnectionPorts;
|
||||
import org.springframework.boot.docker.compose.core.RunningService;
|
||||
import org.springframework.boot.docker.compose.service.connection.jdbc.JdbcUrlBuilder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConnectionFactoryOptionsBuilder}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ConnectionFactoryOptionsBuilderTests {
|
||||
|
||||
private ConnectionFactoryOptionsBuilder builder = new ConnectionFactoryOptionsBuilder("mydb", 1234);
|
||||
|
||||
@Test
|
||||
void createWhenDriverProtocolIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new JdbcUrlBuilder(null, 123))
|
||||
.withMessage("DriverProtocol must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildBuildsOptions() {
|
||||
RunningService service = mockService(456);
|
||||
ConnectionFactoryOptions options = this.builder.build(service, "mydb", "user", "pass");
|
||||
assertThat(options).hasToString(
|
||||
"ConnectionFactoryOptions{options={database=mydb, host=myhost, driver=mydb, password=REDACTED, port=456, user=user}}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildWhenHasParamsLabelBuildsOptions() {
|
||||
RunningService service = mockService(456, Map.of("org.springframework.boot.r2dbc.parameters", "foo=bar"));
|
||||
ConnectionFactoryOptions options = this.builder.build(service, "mydb", "user", "pass");
|
||||
assertThat(options).hasToString(
|
||||
"ConnectionFactoryOptions{options={foo=bar, database=mydb, host=myhost, driver=mydb, password=REDACTED, port=456, user=user}}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildWhenServiceIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.builder.build(null, "mydb", "user", "pass"))
|
||||
.withMessage("Service must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildWhenDatabaseIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.builder.build(mockService(456), null, "user", "pass"))
|
||||
.withMessage("Database must not be null");
|
||||
}
|
||||
|
||||
private RunningService mockService(int mappedPort) {
|
||||
return mockService(mappedPort, Collections.emptyMap());
|
||||
}
|
||||
|
||||
private RunningService mockService(int mappedPort, Map<String, String> labels) {
|
||||
RunningService service = mock(RunningService.class);
|
||||
ConnectionPorts ports = mock(ConnectionPorts.class);
|
||||
given(ports.get(1234)).willReturn(mappedPort);
|
||||
given(service.host()).willReturn("myhost");
|
||||
given(service.ports()).willReturn(ports);
|
||||
given(service.labels()).willReturn(labels);
|
||||
return service;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.rabbit;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails.Address;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link RabbitDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class RabbitDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
RabbitDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("rabbit-compose.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
RabbitConnectionDetails connectionDetails = run(RabbitConnectionDetails.class);
|
||||
assertThat(connectionDetails.getUsername()).isEqualTo("myuser");
|
||||
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
|
||||
assertThat(connectionDetails.getVirtualHost()).isEqualTo("/");
|
||||
assertThat(connectionDetails.getAddresses()).hasSize(1);
|
||||
Address address = connectionDetails.getFirstAddress();
|
||||
assertThat(address.host()).isNotNull();
|
||||
assertThat(address.port()).isGreaterThan(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.rabbit;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link RabbitEnvironment}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class RabbitEnvironmentTests {
|
||||
|
||||
@Test
|
||||
void getUsernameWhenNoRabbitmqDefaultUser() {
|
||||
RabbitEnvironment environment = new RabbitEnvironment(Collections.emptyMap());
|
||||
assertThat(environment.getUsername()).isEqualTo("guest");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenHasRabbitmqDefaultUser() {
|
||||
RabbitEnvironment environment = new RabbitEnvironment(Map.of("RABBITMQ_DEFAULT_USER", "me"));
|
||||
assertThat(environment.getUsername()).isEqualTo("me");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenNoRabbitmqDefaultPass() {
|
||||
RabbitEnvironment environment = new RabbitEnvironment(Collections.emptyMap());
|
||||
assertThat(environment.getPassword()).isEqualTo("guest");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsernameWhenHasRabbitmqDefaultPass() {
|
||||
RabbitEnvironment environment = new RabbitEnvironment(Map.of("RABBITMQ_DEFAULT_PASS", "secret"));
|
||||
assertThat(environment.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.rabbit;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link RabbitDockerComposeConnectionDetailsFactory}
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class XRabbitDockerComposeConnectionDetailsFactoryTests {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@Test
|
||||
void usernameUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("RABBITMQ_DEFAULT_USER", "user-1"));
|
||||
RabbitService rabbitService = new RabbitService(service);
|
||||
assertThat(rabbitService.getUsername()).isEqualTo("user-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void usernameHasDefault() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
RabbitService rabbitService = new RabbitService(service);
|
||||
assertThat(rabbitService.getUsername()).isEqualTo("guest");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordUsesEnvVariable() {
|
||||
RunningService service = createService(Map.of("RABBITMQ_DEFAULT_PASS", "secret-1"));
|
||||
RabbitService rabbitService = new RabbitService(service);
|
||||
assertThat(rabbitService.getPassword()).isEqualTo("secret-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passwordHasDefault() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
RabbitService rabbitService = new RabbitService(service);
|
||||
assertThat(rabbitService.getPassword()).isEqualTo("guest");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPort() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
RabbitService rabbitService = new RabbitService(service);
|
||||
assertThat(rabbitService.getPort()).isEqualTo(15672);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matches() {
|
||||
assertThat(RabbitService.matches(createService(Collections.emptyMap()))).isTrue();
|
||||
assertThat(RabbitService.matches(createService(ImageReference.parse("redis:7.1"), Collections.emptyMap())))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private RunningService createService(Map<String, String> env) {
|
||||
return createService(ImageReference.parse("rabbitmq:3.11"), env);
|
||||
}
|
||||
|
||||
private RunningService createService(ImageReference image, Map<String, String> env) {
|
||||
return RunningServiceBuilder.create("service-1", image).addTcpPort(5672, 15672).env(env).build();
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.redis;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails.Standalone;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration test for {@link RedisDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class RedisDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
RedisDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("redis-compose.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
RedisConnectionDetails connectionDetails = run(RedisConnectionDetails.class);
|
||||
Standalone standalone = connectionDetails.getStandalone();
|
||||
assertThat(connectionDetails.getUsername()).isNull();
|
||||
assertThat(connectionDetails.getPassword()).isNull();
|
||||
assertThat(connectionDetails.getCluster()).isNull();
|
||||
assertThat(connectionDetails.getSentinel()).isNull();
|
||||
assertThat(standalone).isNotNull();
|
||||
assertThat(standalone.getDatabase()).isZero();
|
||||
assertThat(standalone.getPort()).isGreaterThan(0);
|
||||
assertThat(standalone.getHost()).isNotNull();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.redis;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link RedisDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class RedisDockerComposeConnectionDetailsFactoryTests {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
|
||||
/*
|
||||
|
||||
@Test
|
||||
void getPort() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
RedisService redisService = new RedisService(service);
|
||||
assertThat(redisService.getPort()).isEqualTo(16379);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matches() {
|
||||
assertThat(RedisService.matches(createService(Collections.emptyMap()))).isTrue();
|
||||
assertThat(RedisService.matches(createService(ImageReference.parse("postgres:15.2"), Collections.emptyMap())))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private RunningService createService(Map<String, String> env) {
|
||||
return createService(ImageReference.parse("redis:7.0"), env);
|
||||
}
|
||||
|
||||
private RunningService createService(ImageReference image, Map<String, String> env) {
|
||||
return RunningServiceBuilder.create("service-1", image).addTcpPort(6379, 16379).env(env).build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.test;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.SpringApplicationShutdownHandlers;
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||
import org.springframework.boot.testsupport.process.DisabledIfProcessUnavailable;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.function.ThrowingSupplier;
|
||||
|
||||
/**
|
||||
* Abstract base class for integration tests.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@DisabledIfProcessUnavailable({ "docker", "compose" })
|
||||
public abstract class AbstractDockerComposeIntegrationTests {
|
||||
|
||||
private final Resource composeResource;
|
||||
|
||||
@AfterAll
|
||||
static void shutdown() {
|
||||
SpringApplicationShutdownHandlers shutdownHandlers = SpringApplication.getShutdownHandlers();
|
||||
((Runnable) shutdownHandlers).run();
|
||||
}
|
||||
|
||||
protected AbstractDockerComposeIntegrationTests(String composeResource) {
|
||||
this.composeResource = new ClassPathResource(composeResource, getClass());
|
||||
}
|
||||
|
||||
protected final <T extends ConnectionDetails> T run(Class<T> type) {
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
Map<String, Object> properties = new LinkedHashMap<>();
|
||||
properties.put("spring.docker.compose.skip.in-tests", "false");
|
||||
properties.put("spring.docker.compose.file",
|
||||
ThrowingSupplier.of(this.composeResource::getFile).get().getAbsolutePath());
|
||||
application.setDefaultProperties(properties);
|
||||
return application.run().getBean(type);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.test;
|
||||
|
||||
import org.springframework.boot.testsupport.testcontainers.DisabledIfDockerUnavailable;
|
||||
|
||||
/**
|
||||
* Abstract base class for integration tests.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@DisabledIfDockerUnavailable
|
||||
public abstract class AbstractIntegrationTests {
|
||||
|
||||
//// @formatter:off
|
||||
|
||||
/*
|
||||
|
||||
@TempDir
|
||||
static Path tempDir;
|
||||
|
||||
private static List<Runnable> shutdownHandler;
|
||||
|
||||
@BeforeAll
|
||||
static void beforeAll() {
|
||||
shutdownHandler = new ArrayList<>();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void afterAll() {
|
||||
for (Runnable runnable : shutdownHandler) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws IOException {
|
||||
createComposeYaml();
|
||||
}
|
||||
|
||||
protected abstract InputStream getComposeContent();
|
||||
|
||||
protected final <T extends ConnectionDetails> T runProvider(Class<T> serviceConnectionClass) {
|
||||
return runProvider(new MockEnvironment(), serviceConnectionClass);
|
||||
}
|
||||
|
||||
protected final <T extends ConnectionDetails> T runProvider(MockEnvironment environment,
|
||||
Class<T> serviceConnectionClass) {
|
||||
environment.setProperty("spring.dev-services.docker-compose.stop-mode", "down");
|
||||
DockerComposeListener dockerComposeListener = createProvider(environment);
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.setEnvironment(environment);
|
||||
dockerComposeListener
|
||||
.onApplicationEvent(new ApplicationPreparedEvent(new SpringApplication(), new String[0], context));
|
||||
context.refresh();
|
||||
T serviceConnection = context.getBean(serviceConnectionClass);
|
||||
assertThat(serviceConnection.getOrigin()).isInstanceOf(DockerComposeOrigin.class);
|
||||
return serviceConnection;
|
||||
}
|
||||
|
||||
private DockerComposeListener createProvider(Environment environment) {
|
||||
return new DockerComposeListener(getClass().getClassLoader(), environment, null, null, null, tempDir,
|
||||
new SpringApplicationShutdownHandlers() {
|
||||
|
||||
@Override
|
||||
public void add(Runnable action) {
|
||||
shutdownHandler.add(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Runnable action) {
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void createComposeYaml() throws IOException {
|
||||
try (InputStream stream = getComposeContent()) {
|
||||
byte[] content = stream.readAllBytes();
|
||||
Files.write(tempDir.resolve("compose.yaml"), content);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.zipkin;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link ZipkinDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Disabled
|
||||
class XZipkinDockerComposeConnectionDetailsFactoryTests {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@Test
|
||||
void getPort() {
|
||||
RunningService service = createService(Collections.emptyMap());
|
||||
ZipkinService zipkinService = new ZipkinService(service);
|
||||
assertThat(zipkinService.getPort()).isEqualTo(19411);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matches() {
|
||||
assertThat(ZipkinService.matches(createService(Collections.emptyMap()))).isTrue();
|
||||
assertThat(ZipkinService.matches(createService(ImageReference.parse("postgres:15.2"), Collections.emptyMap())))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private RunningService createService(Map<String, String> env) {
|
||||
return createService(ImageReference.parse("openzipkin/zipkin:2.24"), env);
|
||||
}
|
||||
|
||||
private RunningService createService(ImageReference image, Map<String, String> env) {
|
||||
return RunningServiceBuilder.create("service-1", image).addTcpPort(9411, 19411).env(env).build();
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.boot.docker.compose.service.connection.zipkin;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConnectionDetails;
|
||||
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link ZipkinDockerComposeConnectionDetailsFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
|
||||
|
||||
ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests() {
|
||||
super("zipkin-compose.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCreatesConnectionDetails() {
|
||||
ZipkinConnectionDetails connectionDetails = run(ZipkinConnectionDetails.class);
|
||||
assertThat(connectionDetails.getSpanEndpoint()).startsWith("http://").endsWith("/api/v2/spans");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "redis-docker",
|
||||
"services": {
|
||||
"redis": {
|
||||
"command": null,
|
||||
"entrypoint": null,
|
||||
"image": "redis:7.0",
|
||||
"networks": {
|
||||
"default": null
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"mode": "ingress",
|
||||
"target": 6379,
|
||||
"protocol": "tcp"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"networks": {
|
||||
"default": {
|
||||
"name": "redis-docker_default",
|
||||
"ipam": {
|
||||
|
||||
},
|
||||
"external": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"Command": "/command",
|
||||
"CreatedAt": "2023-02-21 13:35:10 +0100 CET",
|
||||
"ID": "f5af31dae7f6",
|
||||
"Image": "redis:7.0",
|
||||
"Labels": "com.docker.compose.project.config_files=/compose.yaml,com.docker.compose.project.working_dir=/,com.docker.compose.container-number=1,com.docker.compose.image=sha256:e79ba23ed43baa22054741136bf45bdb041824f41c5e16c0033ea044ca164b82,com.docker.compose.oneoff=False,com.docker.compose.project=redis-docker,com.docker.compose.config-hash=cfdc8e119d85a53c7d47edb37a3b160a8c83ba48b0428ebc07713befec991dd0,com.docker.compose.depends_on=,com.docker.compose.service=redis,com.docker.compose.version=2.16.0",
|
||||
"LocalVolumes": "1",
|
||||
"Mounts": "9edc7fa2fe6c9e…",
|
||||
"Name": "redis-docker-redis-1",
|
||||
"Networks": "redis-docker_default",
|
||||
"Ports": "0.0.0.0:32770-\\u003e6379/tcp, :::32770-\\u003e6379/tcp",
|
||||
"RunningFor": "2 days ago",
|
||||
"Size": "0B",
|
||||
"State": "running",
|
||||
"Status": "Up 3 seconds"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"version": "123"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Current": true,
|
||||
"Description": "Current DOCKER_HOST based configuration",
|
||||
"DockerEndpoint": "unix:///var/run/docker.sock",
|
||||
"Error": "",
|
||||
"KubernetesEndpoint": "",
|
||||
"Name": "default"
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
{
|
||||
"Id": "f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc",
|
||||
"Created": "2023-02-21T12:35:10.468917704Z",
|
||||
"Path": "docker-entrypoint.sh",
|
||||
"Args": [
|
||||
"redis-server"
|
||||
],
|
||||
"State": {
|
||||
"Status": "running",
|
||||
"Running": true,
|
||||
"Paused": false,
|
||||
"Restarting": false,
|
||||
"OOMKilled": false,
|
||||
"Dead": false,
|
||||
"Pid": 38657,
|
||||
"ExitCode": 0,
|
||||
"Error": "",
|
||||
"StartedAt": "2023-02-23T12:55:27.585705588Z",
|
||||
"FinishedAt": "2023-02-23T12:46:42.013469854Z"
|
||||
},
|
||||
"Image": "sha256:e79ba23ed43baa22054741136bf45bdb041824f41c5e16c0033ea044ca164b82",
|
||||
"ResolvConfPath": "/var/lib/docker/containers/f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc/resolv.conf",
|
||||
"HostnamePath": "/var/lib/docker/containers/f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc/hostname",
|
||||
"HostsPath": "/var/lib/docker/containers/f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc/hosts",
|
||||
"LogPath": "/var/lib/docker/containers/f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc/f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc-json.log",
|
||||
"Name": "/redis-docker-redis-1",
|
||||
"RestartCount": 0,
|
||||
"Driver": "btrfs",
|
||||
"Platform": "linux",
|
||||
"MountLabel": "",
|
||||
"ProcessLabel": "",
|
||||
"AppArmorProfile": "",
|
||||
"ExecIDs": null,
|
||||
"HostConfig": {
|
||||
"Binds": null,
|
||||
"ContainerIDFile": "",
|
||||
"LogConfig": {
|
||||
"Type": "json-file",
|
||||
"Config": {
|
||||
|
||||
}
|
||||
},
|
||||
"NetworkMode": "redis-docker_default",
|
||||
"PortBindings": {
|
||||
"6379/tcp": [
|
||||
{
|
||||
"HostIp": "",
|
||||
"HostPort": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Name": "",
|
||||
"MaximumRetryCount": 0
|
||||
},
|
||||
"AutoRemove": false,
|
||||
"VolumeDriver": "",
|
||||
"VolumesFrom": null,
|
||||
"ConsoleSize": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"CapAdd": null,
|
||||
"CapDrop": null,
|
||||
"CgroupnsMode": "private",
|
||||
"Dns": [],
|
||||
"DnsOptions": [],
|
||||
"DnsSearch": [],
|
||||
"ExtraHosts": [],
|
||||
"GroupAdd": null,
|
||||
"IpcMode": "private",
|
||||
"Cgroup": "",
|
||||
"Links": null,
|
||||
"OomScoreAdj": 0,
|
||||
"PidMode": "",
|
||||
"Privileged": false,
|
||||
"PublishAllPorts": false,
|
||||
"ReadonlyRootfs": false,
|
||||
"SecurityOpt": null,
|
||||
"UTSMode": "",
|
||||
"UsernsMode": "",
|
||||
"ShmSize": 67108864,
|
||||
"Runtime": "runc",
|
||||
"Isolation": "",
|
||||
"CpuShares": 0,
|
||||
"Memory": 0,
|
||||
"NanoCpus": 0,
|
||||
"CgroupParent": "",
|
||||
"BlkioWeight": 0,
|
||||
"BlkioWeightDevice": null,
|
||||
"BlkioDeviceReadBps": null,
|
||||
"BlkioDeviceWriteBps": null,
|
||||
"BlkioDeviceReadIOps": null,
|
||||
"BlkioDeviceWriteIOps": null,
|
||||
"CpuPeriod": 0,
|
||||
"CpuQuota": 0,
|
||||
"CpuRealtimePeriod": 0,
|
||||
"CpuRealtimeRuntime": 0,
|
||||
"CpusetCpus": "",
|
||||
"CpusetMems": "",
|
||||
"Devices": null,
|
||||
"DeviceCgroupRules": null,
|
||||
"DeviceRequests": null,
|
||||
"MemoryReservation": 0,
|
||||
"MemorySwap": 0,
|
||||
"MemorySwappiness": null,
|
||||
"OomKillDisable": null,
|
||||
"PidsLimit": null,
|
||||
"Ulimits": null,
|
||||
"CpuCount": 0,
|
||||
"CpuPercent": 0,
|
||||
"IOMaximumIOps": 0,
|
||||
"IOMaximumBandwidth": 0,
|
||||
"MaskedPaths": [
|
||||
"/proc/asound",
|
||||
"/proc/acpi",
|
||||
"/proc/kcore",
|
||||
"/proc/keys",
|
||||
"/proc/latency_stats",
|
||||
"/proc/timer_list",
|
||||
"/proc/timer_stats",
|
||||
"/proc/sched_debug",
|
||||
"/proc/scsi",
|
||||
"/sys/firmware"
|
||||
],
|
||||
"ReadonlyPaths": [
|
||||
"/proc/bus",
|
||||
"/proc/fs",
|
||||
"/proc/irq",
|
||||
"/proc/sys",
|
||||
"/proc/sysrq-trigger"
|
||||
]
|
||||
},
|
||||
"GraphDriver": {
|
||||
"Data": null,
|
||||
"Name": "btrfs"
|
||||
},
|
||||
"Mounts": [
|
||||
{
|
||||
"Type": "volume",
|
||||
"Name": "9edc7fa2fe6c9e8f67fd31a8649a4b5d7edbc9c1604462e04a5f35d6bfda87c3",
|
||||
"Source": "/var/lib/docker/volumes/9edc7fa2fe6c9e8f67fd31a8649a4b5d7edbc9c1604462e04a5f35d6bfda87c3/_data",
|
||||
"Destination": "/data",
|
||||
"Driver": "local",
|
||||
"Mode": "",
|
||||
"RW": true,
|
||||
"Propagation": ""
|
||||
}
|
||||
],
|
||||
"Config": {
|
||||
"Hostname": "f5af31dae7f6",
|
||||
"Domainname": "",
|
||||
"User": "",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": true,
|
||||
"AttachStderr": true,
|
||||
"ExposedPorts": {
|
||||
"6379/tcp": {
|
||||
|
||||
}
|
||||
},
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"GOSU_VERSION=1.16",
|
||||
"REDIS_VERSION=7.0.8",
|
||||
"REDIS_DOWNLOAD_URL=https://download.redis.io/releases/redis-7.0.8.tar.gz",
|
||||
"REDIS_DOWNLOAD_SHA=06a339e491306783dcf55b97f15a5dbcbdc01ccbde6dc23027c475cab735e914"
|
||||
],
|
||||
"Cmd": [
|
||||
"redis-server"
|
||||
],
|
||||
"Image": "redis:7.0",
|
||||
"Volumes": {
|
||||
"/data": {
|
||||
|
||||
}
|
||||
},
|
||||
"WorkingDir": "/data",
|
||||
"Entrypoint": [
|
||||
"docker-entrypoint.sh"
|
||||
],
|
||||
"OnBuild": null,
|
||||
"Labels": {
|
||||
"com.docker.compose.config-hash": "cfdc8e119d85a53c7d47edb37a3b160a8c83ba48b0428ebc07713befec991dd0",
|
||||
"com.docker.compose.container-number": "1",
|
||||
"com.docker.compose.depends_on": "",
|
||||
"com.docker.compose.image": "sha256:e79ba23ed43baa22054741136bf45bdb041824f41c5e16c0033ea044ca164b82",
|
||||
"com.docker.compose.oneoff": "False",
|
||||
"com.docker.compose.project": "redis-docker",
|
||||
"com.docker.compose.project.config_files": "/compose.yaml",
|
||||
"com.docker.compose.project.working_dir": "/",
|
||||
"com.docker.compose.service": "redis",
|
||||
"com.docker.compose.version": "2.16.0"
|
||||
}
|
||||
},
|
||||
"NetworkSettings": {
|
||||
"Bridge": "",
|
||||
"SandboxID": "3df878d8ed31b2686e41437f141bebba8afcf3bdf8c47ea07c34c2e0b365ec88",
|
||||
"HairpinMode": false,
|
||||
"LinkLocalIPv6Address": "",
|
||||
"LinkLocalIPv6PrefixLen": 0,
|
||||
"Ports": {
|
||||
"6379/tcp": [
|
||||
{
|
||||
"HostIp": "0.0.0.0",
|
||||
"HostPort": "32770"
|
||||
},
|
||||
{
|
||||
"HostIp": "::",
|
||||
"HostPort": "32770"
|
||||
}
|
||||
]
|
||||
},
|
||||
"SandboxKey": "/var/run/docker/netns/3df878d8ed31",
|
||||
"SecondaryIPAddresses": null,
|
||||
"SecondaryIPv6Addresses": null,
|
||||
"EndpointID": "",
|
||||
"Gateway": "",
|
||||
"GlobalIPv6Address": "",
|
||||
"GlobalIPv6PrefixLen": 0,
|
||||
"IPAddress": "",
|
||||
"IPPrefixLen": 0,
|
||||
"IPv6Gateway": "",
|
||||
"MacAddress": "",
|
||||
"Networks": {
|
||||
"redis-docker_default": {
|
||||
"IPAMConfig": null,
|
||||
"Links": null,
|
||||
"Aliases": [
|
||||
"redis-docker-redis-1",
|
||||
"redis",
|
||||
"f5af31dae7f6"
|
||||
],
|
||||
"NetworkID": "9cb2b8b6fb20703841b9337b48e65ed2a71e2da2e995e4782066d146c44fc205",
|
||||
"EndpointID": "e155c61c1608b20ba7a0bd34790fc342ec576310f75ef4399e96bf3a67e8b3f6",
|
||||
"Gateway": "192.168.32.1",
|
||||
"IPAddress": "192.168.32.2",
|
||||
"IPPrefixLen": 20,
|
||||
"IPv6Gateway": "",
|
||||
"GlobalIPv6Address": "",
|
||||
"GlobalIPv6PrefixLen": 0,
|
||||
"MacAddress": "02:42:c0:a8:20:02",
|
||||
"DriverOpts": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
{
|
||||
"Id": "111b22dba993f3282257cbafc87c77763cb4f8a8e534804ef1feae9c8ef282a1",
|
||||
"Created": "2023-02-23T14:19:06.668158561Z",
|
||||
"Path": "docker-entrypoint.sh",
|
||||
"Args": [
|
||||
"redis-server"
|
||||
],
|
||||
"State": {
|
||||
"Status": "running",
|
||||
"Running": true,
|
||||
"Paused": false,
|
||||
"Restarting": false,
|
||||
"OOMKilled": false,
|
||||
"Dead": false,
|
||||
"Pid": 46377,
|
||||
"ExitCode": 0,
|
||||
"Error": "",
|
||||
"StartedAt": "2023-02-23T14:19:07.001096801Z",
|
||||
"FinishedAt": "0001-01-01T00:00:00Z"
|
||||
},
|
||||
"Image": "sha256:e79ba23ed43baa22054741136bf45bdb041824f41c5e16c0033ea044ca164b82",
|
||||
"ResolvConfPath": "/var/lib/docker/containers/111b22dba993f3282257cbafc87c77763cb4f8a8e534804ef1feae9c8ef282a1/resolv.conf",
|
||||
"HostnamePath": "/var/lib/docker/containers/111b22dba993f3282257cbafc87c77763cb4f8a8e534804ef1feae9c8ef282a1/hostname",
|
||||
"HostsPath": "/var/lib/docker/containers/111b22dba993f3282257cbafc87c77763cb4f8a8e534804ef1feae9c8ef282a1/hosts",
|
||||
"LogPath": "/var/lib/docker/containers/111b22dba993f3282257cbafc87c77763cb4f8a8e534804ef1feae9c8ef282a1/111b22dba993f3282257cbafc87c77763cb4f8a8e534804ef1feae9c8ef282a1-json.log",
|
||||
"Name": "/redis-docker-redis-1",
|
||||
"RestartCount": 0,
|
||||
"Driver": "btrfs",
|
||||
"Platform": "linux",
|
||||
"MountLabel": "",
|
||||
"ProcessLabel": "",
|
||||
"AppArmorProfile": "",
|
||||
"ExecIDs": null,
|
||||
"HostConfig": {
|
||||
"Binds": null,
|
||||
"ContainerIDFile": "",
|
||||
"LogConfig": {
|
||||
"Type": "json-file",
|
||||
"Config": {
|
||||
|
||||
}
|
||||
},
|
||||
"NetworkMode": "host",
|
||||
"PortBindings": {
|
||||
"6379/tcp": [
|
||||
{
|
||||
"HostIp": "",
|
||||
"HostPort": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Name": "",
|
||||
"MaximumRetryCount": 0
|
||||
},
|
||||
"AutoRemove": false,
|
||||
"VolumeDriver": "",
|
||||
"VolumesFrom": null,
|
||||
"ConsoleSize": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"CapAdd": null,
|
||||
"CapDrop": null,
|
||||
"CgroupnsMode": "private",
|
||||
"Dns": null,
|
||||
"DnsOptions": null,
|
||||
"DnsSearch": null,
|
||||
"ExtraHosts": [],
|
||||
"GroupAdd": null,
|
||||
"IpcMode": "private",
|
||||
"Cgroup": "",
|
||||
"Links": null,
|
||||
"OomScoreAdj": 0,
|
||||
"PidMode": "",
|
||||
"Privileged": false,
|
||||
"PublishAllPorts": false,
|
||||
"ReadonlyRootfs": false,
|
||||
"SecurityOpt": null,
|
||||
"UTSMode": "",
|
||||
"UsernsMode": "",
|
||||
"ShmSize": 67108864,
|
||||
"Runtime": "runc",
|
||||
"Isolation": "",
|
||||
"CpuShares": 0,
|
||||
"Memory": 0,
|
||||
"NanoCpus": 0,
|
||||
"CgroupParent": "",
|
||||
"BlkioWeight": 0,
|
||||
"BlkioWeightDevice": null,
|
||||
"BlkioDeviceReadBps": null,
|
||||
"BlkioDeviceWriteBps": null,
|
||||
"BlkioDeviceReadIOps": null,
|
||||
"BlkioDeviceWriteIOps": null,
|
||||
"CpuPeriod": 0,
|
||||
"CpuQuota": 0,
|
||||
"CpuRealtimePeriod": 0,
|
||||
"CpuRealtimeRuntime": 0,
|
||||
"CpusetCpus": "",
|
||||
"CpusetMems": "",
|
||||
"Devices": null,
|
||||
"DeviceCgroupRules": null,
|
||||
"DeviceRequests": null,
|
||||
"MemoryReservation": 0,
|
||||
"MemorySwap": 0,
|
||||
"MemorySwappiness": null,
|
||||
"OomKillDisable": null,
|
||||
"PidsLimit": null,
|
||||
"Ulimits": null,
|
||||
"CpuCount": 0,
|
||||
"CpuPercent": 0,
|
||||
"IOMaximumIOps": 0,
|
||||
"IOMaximumBandwidth": 0,
|
||||
"MaskedPaths": [
|
||||
"/proc/asound",
|
||||
"/proc/acpi",
|
||||
"/proc/kcore",
|
||||
"/proc/keys",
|
||||
"/proc/latency_stats",
|
||||
"/proc/timer_list",
|
||||
"/proc/timer_stats",
|
||||
"/proc/sched_debug",
|
||||
"/proc/scsi",
|
||||
"/sys/firmware"
|
||||
],
|
||||
"ReadonlyPaths": [
|
||||
"/proc/bus",
|
||||
"/proc/fs",
|
||||
"/proc/irq",
|
||||
"/proc/sys",
|
||||
"/proc/sysrq-trigger"
|
||||
]
|
||||
},
|
||||
"GraphDriver": {
|
||||
"Data": null,
|
||||
"Name": "btrfs"
|
||||
},
|
||||
"Mounts": [
|
||||
{
|
||||
"Type": "volume",
|
||||
"Name": "0ff245e74dc368da772d4d1139b2aafd423ca1ce1fbe502b4635d7d15f0faf8c",
|
||||
"Source": "/var/lib/docker/volumes/0ff245e74dc368da772d4d1139b2aafd423ca1ce1fbe502b4635d7d15f0faf8c/_data",
|
||||
"Destination": "/data",
|
||||
"Driver": "local",
|
||||
"Mode": "",
|
||||
"RW": true,
|
||||
"Propagation": ""
|
||||
}
|
||||
],
|
||||
"Config": {
|
||||
"Hostname": "fedora",
|
||||
"Domainname": "",
|
||||
"User": "",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": true,
|
||||
"AttachStderr": true,
|
||||
"ExposedPorts": {
|
||||
"6379/tcp": {
|
||||
|
||||
}
|
||||
},
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"GOSU_VERSION=1.16",
|
||||
"REDIS_VERSION=7.0.8",
|
||||
"REDIS_DOWNLOAD_URL=https://download.redis.io/releases/redis-7.0.8.tar.gz",
|
||||
"REDIS_DOWNLOAD_SHA=06a339e491306783dcf55b97f15a5dbcbdc01ccbde6dc23027c475cab735e914"
|
||||
],
|
||||
"Cmd": [
|
||||
"redis-server"
|
||||
],
|
||||
"Image": "redis:7.0",
|
||||
"Volumes": {
|
||||
"/data": {
|
||||
|
||||
}
|
||||
},
|
||||
"WorkingDir": "/data",
|
||||
"Entrypoint": [
|
||||
"docker-entrypoint.sh"
|
||||
],
|
||||
"OnBuild": null,
|
||||
"Labels": {
|
||||
"com.docker.compose.config-hash": "204d00fc2f8ffd749769e3f6c160b2a2366e76cf8980bb2984bc65674748b3ca",
|
||||
"com.docker.compose.container-number": "1",
|
||||
"com.docker.compose.depends_on": "",
|
||||
"com.docker.compose.image": "sha256:e79ba23ed43baa22054741136bf45bdb041824f41c5e16c0033ea044ca164b82",
|
||||
"com.docker.compose.oneoff": "False",
|
||||
"com.docker.compose.project": "redis-docker",
|
||||
"com.docker.compose.project.config_files": "/compose.yaml",
|
||||
"com.docker.compose.project.working_dir": "/",
|
||||
"com.docker.compose.service": "redis",
|
||||
"com.docker.compose.version": "2.16.0"
|
||||
}
|
||||
},
|
||||
"NetworkSettings": {
|
||||
"Bridge": "",
|
||||
"SandboxID": "6ec5c12e14078b424707534b8b64d0953ce9da21eaebd422daefff2d6a08f14d",
|
||||
"HairpinMode": false,
|
||||
"LinkLocalIPv6Address": "",
|
||||
"LinkLocalIPv6PrefixLen": 0,
|
||||
"Ports": {
|
||||
|
||||
},
|
||||
"SandboxKey": "/var/run/docker/netns/default",
|
||||
"SecondaryIPAddresses": null,
|
||||
"SecondaryIPv6Addresses": null,
|
||||
"EndpointID": "",
|
||||
"Gateway": "",
|
||||
"GlobalIPv6Address": "",
|
||||
"GlobalIPv6PrefixLen": 0,
|
||||
"IPAddress": "",
|
||||
"IPPrefixLen": 0,
|
||||
"IPv6Gateway": "",
|
||||
"MacAddress": "",
|
||||
"Networks": {
|
||||
"host": {
|
||||
"IPAMConfig": null,
|
||||
"Links": null,
|
||||
"Aliases": null,
|
||||
"NetworkID": "c8fa8aac531ce4630465de4baf8d0310a2ff3243b3986e5251611c1a4ee6e1b3",
|
||||
"EndpointID": "cfdc6016b0dd724f7714ae116c5fa33127401f5e6853f07c4c1db5e967871136",
|
||||
"Gateway": "",
|
||||
"IPAddress": "",
|
||||
"IPPrefixLen": 0,
|
||||
"IPv6Gateway": "",
|
||||
"GlobalIPv6Address": "",
|
||||
"GlobalIPv6PrefixLen": 0,
|
||||
"MacAddress": "",
|
||||
"DriverOpts": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
{
|
||||
"Id": "f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc",
|
||||
"Created": "2023-02-21T12:35:10.468917704Z",
|
||||
"Path": "docker-entrypoint.sh",
|
||||
"Args": [
|
||||
"redis-server"
|
||||
],
|
||||
"State": {
|
||||
"Status": "running",
|
||||
"Running": true,
|
||||
"Paused": false,
|
||||
"Restarting": false,
|
||||
"OOMKilled": false,
|
||||
"Dead": false,
|
||||
"Pid": 38657,
|
||||
"ExitCode": 0,
|
||||
"Error": "",
|
||||
"StartedAt": "2023-02-23T12:55:27.585705588Z",
|
||||
"FinishedAt": "2023-02-23T12:46:42.013469854Z"
|
||||
},
|
||||
"Image": "sha256:e79ba23ed43baa22054741136bf45bdb041824f41c5e16c0033ea044ca164b82",
|
||||
"ResolvConfPath": "/var/lib/docker/containers/f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc/resolv.conf",
|
||||
"HostnamePath": "/var/lib/docker/containers/f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc/hostname",
|
||||
"HostsPath": "/var/lib/docker/containers/f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc/hosts",
|
||||
"LogPath": "/var/lib/docker/containers/f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc/f5af31dae7f665bd194ec7261bdc84e5df9c64753abb4a6cec6c33f7cf64c3fc-json.log",
|
||||
"Name": "/redis-docker-redis-1",
|
||||
"RestartCount": 0,
|
||||
"Driver": "btrfs",
|
||||
"Platform": "linux",
|
||||
"MountLabel": "",
|
||||
"ProcessLabel": "",
|
||||
"AppArmorProfile": "",
|
||||
"ExecIDs": null,
|
||||
"HostConfig": {
|
||||
"Binds": null,
|
||||
"ContainerIDFile": "",
|
||||
"LogConfig": {
|
||||
"Type": "json-file",
|
||||
"Config": {
|
||||
|
||||
}
|
||||
},
|
||||
"NetworkMode": "redis-docker_default",
|
||||
"PortBindings": {
|
||||
"6379/tcp": [
|
||||
{
|
||||
"HostIp": "",
|
||||
"HostPort": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Name": "",
|
||||
"MaximumRetryCount": 0
|
||||
},
|
||||
"AutoRemove": false,
|
||||
"VolumeDriver": "",
|
||||
"VolumesFrom": null,
|
||||
"ConsoleSize": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"CapAdd": null,
|
||||
"CapDrop": null,
|
||||
"CgroupnsMode": "private",
|
||||
"Dns": [],
|
||||
"DnsOptions": [],
|
||||
"DnsSearch": [],
|
||||
"ExtraHosts": [],
|
||||
"GroupAdd": null,
|
||||
"IpcMode": "private",
|
||||
"Cgroup": "",
|
||||
"Links": null,
|
||||
"OomScoreAdj": 0,
|
||||
"PidMode": "",
|
||||
"Privileged": false,
|
||||
"PublishAllPorts": false,
|
||||
"ReadonlyRootfs": false,
|
||||
"SecurityOpt": null,
|
||||
"UTSMode": "",
|
||||
"UsernsMode": "",
|
||||
"ShmSize": 67108864,
|
||||
"Runtime": "runc",
|
||||
"Isolation": "",
|
||||
"CpuShares": 0,
|
||||
"Memory": 0,
|
||||
"NanoCpus": 0,
|
||||
"CgroupParent": "",
|
||||
"BlkioWeight": 0,
|
||||
"BlkioWeightDevice": null,
|
||||
"BlkioDeviceReadBps": null,
|
||||
"BlkioDeviceWriteBps": null,
|
||||
"BlkioDeviceReadIOps": null,
|
||||
"BlkioDeviceWriteIOps": null,
|
||||
"CpuPeriod": 0,
|
||||
"CpuQuota": 0,
|
||||
"CpuRealtimePeriod": 0,
|
||||
"CpuRealtimeRuntime": 0,
|
||||
"CpusetCpus": "",
|
||||
"CpusetMems": "",
|
||||
"Devices": null,
|
||||
"DeviceCgroupRules": null,
|
||||
"DeviceRequests": null,
|
||||
"MemoryReservation": 0,
|
||||
"MemorySwap": 0,
|
||||
"MemorySwappiness": null,
|
||||
"OomKillDisable": null,
|
||||
"PidsLimit": null,
|
||||
"Ulimits": null,
|
||||
"CpuCount": 0,
|
||||
"CpuPercent": 0,
|
||||
"IOMaximumIOps": 0,
|
||||
"IOMaximumBandwidth": 0,
|
||||
"MaskedPaths": [
|
||||
"/proc/asound",
|
||||
"/proc/acpi",
|
||||
"/proc/kcore",
|
||||
"/proc/keys",
|
||||
"/proc/latency_stats",
|
||||
"/proc/timer_list",
|
||||
"/proc/timer_stats",
|
||||
"/proc/sched_debug",
|
||||
"/proc/scsi",
|
||||
"/sys/firmware"
|
||||
],
|
||||
"ReadonlyPaths": [
|
||||
"/proc/bus",
|
||||
"/proc/fs",
|
||||
"/proc/irq",
|
||||
"/proc/sys",
|
||||
"/proc/sysrq-trigger"
|
||||
]
|
||||
},
|
||||
"GraphDriver": {
|
||||
"Data": null,
|
||||
"Name": "btrfs"
|
||||
},
|
||||
"Mounts": [
|
||||
{
|
||||
"Type": "volume",
|
||||
"Name": "9edc7fa2fe6c9e8f67fd31a8649a4b5d7edbc9c1604462e04a5f35d6bfda87c3",
|
||||
"Source": "/var/lib/docker/volumes/9edc7fa2fe6c9e8f67fd31a8649a4b5d7edbc9c1604462e04a5f35d6bfda87c3/_data",
|
||||
"Destination": "/data",
|
||||
"Driver": "local",
|
||||
"Mode": "",
|
||||
"RW": true,
|
||||
"Propagation": ""
|
||||
}
|
||||
],
|
||||
"Config": {
|
||||
"Hostname": "f5af31dae7f6",
|
||||
"Domainname": "",
|
||||
"User": "",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": true,
|
||||
"AttachStderr": true,
|
||||
"ExposedPorts": {
|
||||
"6379/tcp": {
|
||||
|
||||
}
|
||||
},
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"GOSU_VERSION=1.16",
|
||||
"REDIS_VERSION=7.0.8"
|
||||
],
|
||||
"Cmd": [
|
||||
"redis-server"
|
||||
],
|
||||
"Image": "redis:7.0",
|
||||
"Volumes": {
|
||||
"/data": {
|
||||
|
||||
}
|
||||
},
|
||||
"WorkingDir": "/data",
|
||||
"Entrypoint": [
|
||||
"docker-entrypoint.sh"
|
||||
],
|
||||
"OnBuild": null,
|
||||
"Labels": {
|
||||
"com.docker.compose.config-hash": "cfdc8e119d85a53c7d47edb37a3b160a8c83ba48b0428ebc07713befec991dd0",
|
||||
"com.docker.compose.container-number": "1",
|
||||
"com.docker.compose.depends_on": "",
|
||||
"com.docker.compose.image": "sha256:e79ba23ed43baa22054741136bf45bdb041824f41c5e16c0033ea044ca164b82",
|
||||
"com.docker.compose.oneoff": "False",
|
||||
"com.docker.compose.project": "redis-docker",
|
||||
"com.docker.compose.project.config_files": "compose.yaml",
|
||||
"com.docker.compose.project.working_dir": "/",
|
||||
"com.docker.compose.service": "redis",
|
||||
"com.docker.compose.version": "2.16.0"
|
||||
}
|
||||
},
|
||||
"NetworkSettings": {
|
||||
"Bridge": "",
|
||||
"SandboxID": "3df878d8ed31b2686e41437f141bebba8afcf3bdf8c47ea07c34c2e0b365ec88",
|
||||
"HairpinMode": false,
|
||||
"LinkLocalIPv6Address": "",
|
||||
"LinkLocalIPv6PrefixLen": 0,
|
||||
"Ports": {
|
||||
"6379/tcp": [
|
||||
{
|
||||
"HostIp": "0.0.0.0",
|
||||
"HostPort": "32770"
|
||||
},
|
||||
{
|
||||
"HostIp": "::",
|
||||
"HostPort": "32770"
|
||||
}
|
||||
]
|
||||
},
|
||||
"SandboxKey": "/var/run/docker/netns/3df878d8ed31",
|
||||
"SecondaryIPAddresses": null,
|
||||
"SecondaryIPv6Addresses": null,
|
||||
"EndpointID": "",
|
||||
"Gateway": "",
|
||||
"GlobalIPv6Address": "",
|
||||
"GlobalIPv6PrefixLen": 0,
|
||||
"IPAddress": "",
|
||||
"IPPrefixLen": 0,
|
||||
"IPv6Gateway": "",
|
||||
"MacAddress": "",
|
||||
"Networks": {
|
||||
"redis-docker_default": {
|
||||
"IPAMConfig": null,
|
||||
"Links": null,
|
||||
"Aliases": [
|
||||
"redis-docker-redis-1",
|
||||
"redis",
|
||||
"f5af31dae7f6"
|
||||
],
|
||||
"NetworkID": "9cb2b8b6fb20703841b9337b48e65ed2a71e2da2e995e4782066d146c44fc205",
|
||||
"EndpointID": "e155c61c1608b20ba7a0bd34790fc342ec576310f75ef4399e96bf3a67e8b3f6",
|
||||
"Gateway": "192.168.32.1",
|
||||
"IPAddress": "192.168.32.2",
|
||||
"IPPrefixLen": 20,
|
||||
"IPv6Gateway": "",
|
||||
"GlobalIPv6Address": "",
|
||||
"GlobalIPv6PrefixLen": 0,
|
||||
"MacAddress": "02:42:c0:a8:20:02",
|
||||
"DriverOpts": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
services:
|
||||
elasticsearch:
|
||||
image: 'elasticsearch:8.6.1'
|
||||
environment:
|
||||
- 'ELASTIC_PASSWORD=secret'
|
||||
- 'ES_JAVA_OPTS=-Xmx512m'
|
||||
- 'xpack.security.enabled=false'
|
||||
- 'discovery.type=single-node'
|
||||
ports:
|
||||
- '9200'
|
||||
- '9300'
|
||||
@@ -0,0 +1,11 @@
|
||||
services:
|
||||
database:
|
||||
image: 'mariadb:10.10'
|
||||
ports:
|
||||
- '3306'
|
||||
environment:
|
||||
- 'MARIADB_ROOT_PASSWORD=verysecret'
|
||||
- 'MARIADB_USER=myuser'
|
||||
- 'MARIADB_PASSWORD=secret'
|
||||
- 'MARIADB_DATABASE=mydatabase'
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
services:
|
||||
mongo:
|
||||
image: 'mongo:6.0'
|
||||
ports:
|
||||
- '27017'
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: 'root'
|
||||
MONGO_INITDB_ROOT_PASSWORD: 'secret'
|
||||
MONGO_INITDB_DATABASE: 'mydatabase'
|
||||
@@ -0,0 +1,10 @@
|
||||
services:
|
||||
database:
|
||||
image: 'mysql:8.0'
|
||||
ports:
|
||||
- '3306'
|
||||
environment:
|
||||
- 'MYSQL_ROOT_PASSWORD=verysecret'
|
||||
- 'MYSQL_USER=myuser'
|
||||
- 'MYSQL_PASSWORD=secret'
|
||||
- 'MYSQL_DATABASE=mydatabase'
|
||||
@@ -0,0 +1,9 @@
|
||||
services:
|
||||
database:
|
||||
image: 'postgres:15.2'
|
||||
ports:
|
||||
- '5432'
|
||||
environment:
|
||||
- 'POSTGRES_USER=myuser'
|
||||
- 'POSTGRES_DB=mydatabase'
|
||||
- 'POSTGRES_PASSWORD=secret'
|
||||
@@ -0,0 +1,8 @@
|
||||
services:
|
||||
rabbitmq:
|
||||
image: 'rabbitmq:3.11'
|
||||
environment:
|
||||
- 'RABBITMQ_DEFAULT_USER=myuser'
|
||||
- 'RABBITMQ_DEFAULT_PASS=secret'
|
||||
ports:
|
||||
- '5672'
|
||||
@@ -0,0 +1,5 @@
|
||||
services:
|
||||
redis:
|
||||
image: 'redis:7.0'
|
||||
ports:
|
||||
- '6379'
|
||||
@@ -0,0 +1,5 @@
|
||||
services:
|
||||
zipkin:
|
||||
image: 'openzipkin/zipkin:2.24'
|
||||
ports:
|
||||
- '9411'
|
||||
Reference in New Issue
Block a user