Add properties to specify arguments to Docker Compose commands

These new properties take a List<String>:

- spring.docker.compose.start.arguments
- spring.docker.compose.stop.arguments

Closes gh-38763
This commit is contained in:
Moritz Halbritter
2024-06-18 12:27:18 +02:00
parent 17ca0421e7
commit 6c0c9b9a80
13 changed files with 244 additions and 112 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@@ -51,31 +51,31 @@ class DefaultDockerComposeTests {
@Test
void upRunsUpCommand() {
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
compose.up(LogLevel.OFF);
then(this.cli).should().run(new DockerCliCommand.ComposeUp(LogLevel.OFF));
compose.up(LogLevel.OFF, Collections.emptyList());
then(this.cli).should().run(new DockerCliCommand.ComposeUp(LogLevel.OFF, Collections.emptyList()));
}
@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));
compose.down(timeout, Collections.emptyList());
then(this.cli).should().run(new DockerCliCommand.ComposeDown(timeout, Collections.emptyList()));
}
@Test
void startRunsStartCommand() {
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
compose.start(LogLevel.OFF);
then(this.cli).should().run(new DockerCliCommand.ComposeStart(LogLevel.OFF));
compose.start(LogLevel.OFF, Collections.emptyList());
then(this.cli).should().run(new DockerCliCommand.ComposeStart(LogLevel.OFF, Collections.emptyList()));
}
@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));
compose.stop(timeout, Collections.emptyList());
then(this.cli).should().run(new DockerCliCommand.ComposeStop(timeout, Collections.emptyList()));
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@@ -68,35 +68,37 @@ class DockerCliCommandTests {
@Test
void composeUp() {
DockerCliCommand<?> command = new DockerCliCommand.ComposeUp(LogLevel.INFO);
DockerCliCommand<?> command = new DockerCliCommand.ComposeUp(LogLevel.INFO, List.of("--renew-anon-volumes"));
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER_COMPOSE);
assertThat(command.getLogLevel()).isEqualTo(LogLevel.INFO);
assertThat(command.getCommand()).containsExactly("up", "--no-color", "--detach", "--wait");
assertThat(command.getCommand()).containsExactly("up", "--no-color", "--detach", "--wait",
"--renew-anon-volumes");
assertThat(command.deserialize("[]")).isNull();
}
@Test
void composeDown() {
DockerCliCommand<?> command = new DockerCliCommand.ComposeDown(Duration.ofSeconds(1));
DockerCliCommand<?> command = new DockerCliCommand.ComposeDown(Duration.ofSeconds(1),
List.of("--remove-orphans"));
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER_COMPOSE);
assertThat(command.getCommand()).containsExactly("down", "--timeout", "1");
assertThat(command.getCommand()).containsExactly("down", "--timeout", "1", "--remove-orphans");
assertThat(command.deserialize("[]")).isNull();
}
@Test
void composeStart() {
DockerCliCommand<?> command = new DockerCliCommand.ComposeStart(LogLevel.INFO);
DockerCliCommand<?> command = new DockerCliCommand.ComposeStart(LogLevel.INFO, List.of("--dry-run"));
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER_COMPOSE);
assertThat(command.getLogLevel()).isEqualTo(LogLevel.INFO);
assertThat(command.getCommand()).containsExactly("start");
assertThat(command.getCommand()).containsExactly("start", "--dry-run");
assertThat(command.deserialize("[]")).isNull();
}
@Test
void composeStop() {
DockerCliCommand<?> command = new DockerCliCommand.ComposeStop(Duration.ofSeconds(1));
DockerCliCommand<?> command = new DockerCliCommand.ComposeStop(Duration.ofSeconds(1), List.of("--dry-run"));
assertThat(command.getType()).isEqualTo(DockerCliCommand.Type.DOCKER_COMPOSE);
assertThat(command.getCommand()).containsExactly("stop", "--timeout", "1");
assertThat(command.getCommand()).containsExactly("stop", "--timeout", "1", "--dry-run");
assertThat(command.deserialize("[]")).isNull();
}

View File

@@ -77,7 +77,7 @@ class DockerCliIntegrationTests {
DockerCliComposeConfigResponse config = cli.run(new ComposeConfig());
assertThat(config.services()).containsOnlyKeys("redis");
// Run up
cli.run(new ComposeUp(LogLevel.INFO));
cli.run(new ComposeUp(LogLevel.INFO, Collections.emptyList()));
// Run ps and use id to run inspect on the id
ps = cli.run(new ComposePs());
assertThat(ps).hasSize(1);
@@ -86,14 +86,14 @@ class DockerCliIntegrationTests {
assertThat(inspect).isNotEmpty();
assertThat(inspect.get(0).id()).startsWith(id);
// Run stop, then run ps and verify the services are stopped
cli.run(new ComposeStop(Duration.ofSeconds(10)));
cli.run(new ComposeStop(Duration.ofSeconds(10), Collections.emptyList()));
ps = cli.run(new ComposePs());
assertThat(ps).isEmpty();
// Run start, verify service is there, then run down and verify they are gone
cli.run(new ComposeStart(LogLevel.INFO));
cli.run(new ComposeStart(LogLevel.INFO, Collections.emptyList()));
ps = cli.run(new ComposePs());
assertThat(ps).hasSize(1);
cli.run(new ComposeDown(Duration.ofSeconds(10)));
cli.run(new ComposeDown(Duration.ofSeconds(10), Collections.emptyList()));
ps = cli.run(new ComposePs());
assertThat(ps).isEmpty();
}
@@ -105,7 +105,7 @@ class DockerCliIntegrationTests {
private static void quietComposeDown(DockerCli cli) {
try {
cli.run(new ComposeDown(Duration.ZERO));
cli.run(new ComposeDown(Duration.ZERO, Collections.emptyList()));
}
catch (RuntimeException ex) {
// Ignore

View File

@@ -182,10 +182,10 @@ class DockerComposeLifecycleManagerTests {
this.lifecycleManager.start();
assertThat(listener.getEvent()).isNull();
then(this.dockerCompose).should().hasDefinedServices();
then(this.dockerCompose).should(never()).up(any());
then(this.dockerCompose).should(never()).start(any());
then(this.dockerCompose).should(never()).down(any());
then(this.dockerCompose).should(never()).stop(any());
then(this.dockerCompose).should(never()).up(any(), any());
then(this.dockerCompose).should(never()).start(any(), any());
then(this.dockerCompose).should(never()).down(any(), any());
then(this.dockerCompose).should(never()).stop(any(), any());
}
@Test
@@ -197,10 +197,10 @@ class DockerComposeLifecycleManagerTests {
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should().up(any());
then(this.dockerCompose).should(never()).start(any());
then(this.dockerCompose).should().stop(any());
then(this.dockerCompose).should(never()).down(any());
then(this.dockerCompose).should().up(any(), any());
then(this.dockerCompose).should(never()).start(any(), any());
then(this.dockerCompose).should().stop(any(), any());
then(this.dockerCompose).should(never()).down(any(), any());
}
@Test
@@ -212,10 +212,10 @@ class DockerComposeLifecycleManagerTests {
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should(never()).up(any());
then(this.dockerCompose).should(never()).start(any());
then(this.dockerCompose).should(never()).down(any());
then(this.dockerCompose).should(never()).stop(any());
then(this.dockerCompose).should(never()).up(any(), any());
then(this.dockerCompose).should(never()).start(any(), any());
then(this.dockerCompose).should(never()).down(any(), any());
then(this.dockerCompose).should(never()).stop(any(), any());
}
@Test
@@ -227,10 +227,10 @@ class DockerComposeLifecycleManagerTests {
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should(never()).up(any());
then(this.dockerCompose).should(never()).start(any());
then(this.dockerCompose).should(never()).down(any());
then(this.dockerCompose).should(never()).stop(any());
then(this.dockerCompose).should(never()).up(any(), any());
then(this.dockerCompose).should(never()).start(any(), any());
then(this.dockerCompose).should(never()).down(any(), any());
then(this.dockerCompose).should(never()).stop(any(), any());
}
@Test
@@ -242,10 +242,10 @@ class DockerComposeLifecycleManagerTests {
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should().up(any());
then(this.dockerCompose).should(never()).start(any());
then(this.dockerCompose).should(never()).down(any());
then(this.dockerCompose).should(never()).stop(any());
then(this.dockerCompose).should().up(any(), any());
then(this.dockerCompose).should(never()).start(any(), any());
then(this.dockerCompose).should(never()).down(any(), any());
then(this.dockerCompose).should(never()).stop(any(), any());
this.shutdownHandlers.assertNoneAdded();
}
@@ -259,10 +259,10 @@ class DockerComposeLifecycleManagerTests {
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should(never()).up(any());
then(this.dockerCompose).should().start(any());
then(this.dockerCompose).should().stop(any());
then(this.dockerCompose).should(never()).down(any());
then(this.dockerCompose).should(never()).up(any(), any());
then(this.dockerCompose).should().start(any(), any());
then(this.dockerCompose).should().stop(any(), any());
then(this.dockerCompose).should(never()).down(any(), any());
}
@Test
@@ -275,10 +275,10 @@ class DockerComposeLifecycleManagerTests {
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should().up(any());
then(this.dockerCompose).should(never()).start(any());
then(this.dockerCompose).should(never()).stop(any());
then(this.dockerCompose).should().down(any());
then(this.dockerCompose).should().up(any(), any());
then(this.dockerCompose).should(never()).start(any(), any());
then(this.dockerCompose).should(never()).stop(any(), any());
then(this.dockerCompose).should().down(any(), any());
}
@Test
@@ -292,7 +292,7 @@ class DockerComposeLifecycleManagerTests {
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should().stop(timeout);
then(this.dockerCompose).should().stop(timeout, Collections.emptyList());
}
@Test
@@ -390,7 +390,7 @@ class DockerComposeLifecycleManagerTests {
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
this.properties.getStart().setSkip(Skip.IF_RUNNING);
this.lifecycleManager.start();
then(this.dockerCompose).should().up(any());
then(this.dockerCompose).should().up(any(), any());
}
@Test
@@ -398,7 +398,7 @@ class DockerComposeLifecycleManagerTests {
setUpRunningServices();
this.properties.getStart().setSkip(Skip.IF_RUNNING);
this.lifecycleManager.start();
then(this.dockerCompose).should(never()).up(any());
then(this.dockerCompose).should(never()).up(any(), any());
}
@Test
@@ -406,7 +406,7 @@ class DockerComposeLifecycleManagerTests {
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
this.properties.getStart().setSkip(Skip.NEVER);
this.lifecycleManager.start();
then(this.dockerCompose).should().up(any());
then(this.dockerCompose).should().up(any(), any());
}
@Test
@@ -414,7 +414,7 @@ class DockerComposeLifecycleManagerTests {
setUpRunningServices();
this.properties.getStart().setSkip(Skip.NEVER);
this.lifecycleManager.start();
then(this.dockerCompose).should().up(any());
then(this.dockerCompose).should().up(any(), any());
}
private void setUpRunningServices() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@@ -16,6 +16,9 @@
package org.springframework.boot.docker.compose.lifecycle;
import java.util.Collections;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.docker.compose.core.DockerCompose;
@@ -33,18 +36,23 @@ import static org.mockito.Mockito.mock;
*/
class StartCommandTests {
private DockerCompose dockerCompose = mock(DockerCompose.class);
private DockerCompose dockerCompose;
@BeforeEach
void setUp() {
this.dockerCompose = mock(DockerCompose.class);
}
@Test
void applyToWhenUp() {
StartCommand.UP.applyTo(this.dockerCompose, LogLevel.INFO);
then(this.dockerCompose).should().up(LogLevel.INFO);
StartCommand.UP.applyTo(this.dockerCompose, LogLevel.INFO, Collections.emptyList());
then(this.dockerCompose).should().up(LogLevel.INFO, Collections.emptyList());
}
@Test
void applyToWhenStart() {
StartCommand.START.applyTo(this.dockerCompose, LogLevel.INFO);
then(this.dockerCompose).should().start(LogLevel.INFO);
StartCommand.START.applyTo(this.dockerCompose, LogLevel.INFO, Collections.emptyList());
then(this.dockerCompose).should().start(LogLevel.INFO, Collections.emptyList());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@@ -17,7 +17,9 @@
package org.springframework.boot.docker.compose.lifecycle;
import java.time.Duration;
import java.util.Collections;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.docker.compose.core.DockerCompose;
@@ -34,20 +36,25 @@ import static org.mockito.Mockito.mock;
*/
class StopCommandTests {
private DockerCompose dockerCompose = mock(DockerCompose.class);
private DockerCompose dockerCompose;
private Duration duration = Duration.ofSeconds(10);
private final Duration duration = Duration.ofSeconds(10);
@BeforeEach
void setUp() {
this.dockerCompose = mock(DockerCompose.class);
}
@Test
void applyToWhenDown() {
StopCommand.DOWN.applyTo(this.dockerCompose, this.duration);
then(this.dockerCompose).should().down(this.duration);
StopCommand.DOWN.applyTo(this.dockerCompose, this.duration, Collections.emptyList());
then(this.dockerCompose).should().down(this.duration, Collections.emptyList());
}
@Test
void applyToWhenStart() {
StopCommand.STOP.applyTo(this.dockerCompose, this.duration);
then(this.dockerCompose).should().stop(this.duration);
StopCommand.STOP.applyTo(this.dockerCompose, this.duration, Collections.emptyList());
then(this.dockerCompose).should().stop(this.duration, Collections.emptyList());
}
}