|
|
|
|
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
|
|
|
|
/* |
|
|
|
|
* Copyright 2012-2024 the original author or authors. |
|
|
|
|
* Copyright 2012-2025 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,6 +17,7 @@
@@ -17,6 +17,7 @@
|
|
|
|
|
package org.springframework.boot.docker.compose.service.connection.test; |
|
|
|
|
|
|
|
|
|
import java.io.IOException; |
|
|
|
|
import java.nio.charset.StandardCharsets; |
|
|
|
|
import java.nio.file.Files; |
|
|
|
|
import java.nio.file.Path; |
|
|
|
|
import java.util.LinkedHashMap; |
|
|
|
|
@ -39,6 +40,7 @@ import org.springframework.context.ConfigurableApplicationContext;
@@ -39,6 +40,7 @@ import org.springframework.context.ConfigurableApplicationContext;
|
|
|
|
|
import org.springframework.context.annotation.Configuration; |
|
|
|
|
import org.springframework.core.io.ClassPathResource; |
|
|
|
|
import org.springframework.core.io.Resource; |
|
|
|
|
import org.springframework.util.FileSystemUtils; |
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.fail; |
|
|
|
|
|
|
|
|
|
@ -46,22 +48,24 @@ import static org.assertj.core.api.Assertions.fail;
@@ -46,22 +48,24 @@ import static org.assertj.core.api.Assertions.fail;
|
|
|
|
|
* {@link Extension} for {@link DockerComposeTest @DockerComposeTest}. |
|
|
|
|
* |
|
|
|
|
* @author Andy Wilkinson |
|
|
|
|
* @author Moritz Halbritter |
|
|
|
|
*/ |
|
|
|
|
class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback, ParameterResolver { |
|
|
|
|
|
|
|
|
|
private static final Namespace NAMESPACE = Namespace.create(DockerComposeTestExtension.class); |
|
|
|
|
|
|
|
|
|
private static final String STORE_KEY_COMPOSE_FILE = "compose-file"; |
|
|
|
|
private static final String STORE_KEY_WORKSPACE = "workspace"; |
|
|
|
|
|
|
|
|
|
private static final String STORE_KEY_APPLICATION_CONTEXT = "application-context"; |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void beforeTestExecution(ExtensionContext context) throws Exception { |
|
|
|
|
Path transformedComposeFile = prepareComposeFile(context); |
|
|
|
|
Store store = context.getStore(NAMESPACE); |
|
|
|
|
store.put(STORE_KEY_COMPOSE_FILE, transformedComposeFile); |
|
|
|
|
Path workspace = Files.createTempDirectory("DockerComposeTestExtension-"); |
|
|
|
|
store.put(STORE_KEY_WORKSPACE, workspace); |
|
|
|
|
try { |
|
|
|
|
SpringApplication application = prepareApplication(transformedComposeFile); |
|
|
|
|
Path composeFile = prepareComposeFile(workspace, context); |
|
|
|
|
SpringApplication application = prepareApplication(composeFile); |
|
|
|
|
store.put(STORE_KEY_APPLICATION_CONTEXT, application.run()); |
|
|
|
|
} |
|
|
|
|
catch (Exception ex) { |
|
|
|
|
@ -70,33 +74,33 @@ class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTe
@@ -70,33 +74,33 @@ class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTe
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private Path prepareComposeFile(ExtensionContext context) { |
|
|
|
|
private Path prepareComposeFile(Path workspace, ExtensionContext context) { |
|
|
|
|
DockerComposeTest dockerComposeTest = context.getRequiredTestMethod().getAnnotation(DockerComposeTest.class); |
|
|
|
|
TestImage image = dockerComposeTest.image(); |
|
|
|
|
Resource composeResource = new ClassPathResource(dockerComposeTest.composeFile(), |
|
|
|
|
context.getRequiredTestClass()); |
|
|
|
|
return transformedComposeFile(composeResource, image); |
|
|
|
|
return transformedComposeFile(workspace, composeResource, image); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private Path transformedComposeFile(Resource composeFileResource, TestImage image) { |
|
|
|
|
private Path transformedComposeFile(Path workspace, Resource composeFileResource, TestImage image) { |
|
|
|
|
try { |
|
|
|
|
Path composeFile = composeFileResource.getFile().toPath(); |
|
|
|
|
Path transformedComposeFile = Files.createTempFile("", "-" + composeFile.getFileName().toString()); |
|
|
|
|
String transformedContent = Files.readString(composeFile).replace("{imageName}", image.toString()); |
|
|
|
|
Files.writeString(transformedComposeFile, transformedContent); |
|
|
|
|
return transformedComposeFile; |
|
|
|
|
String template = composeFileResource.getContentAsString(StandardCharsets.UTF_8); |
|
|
|
|
String content = template.replace("{imageName}", image.toString()); |
|
|
|
|
Path composeFile = workspace.resolve("compose.yaml"); |
|
|
|
|
Files.writeString(composeFile, content); |
|
|
|
|
return composeFile; |
|
|
|
|
} |
|
|
|
|
catch (IOException ex) { |
|
|
|
|
fail("Error transforming Docker compose file '" + composeFileResource + "': " + ex.getMessage()); |
|
|
|
|
fail("Error transforming Docker compose file '" + composeFileResource + "': " + ex.getMessage(), ex); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private SpringApplication prepareApplication(Path transformedComposeFile) { |
|
|
|
|
private SpringApplication prepareApplication(Path composeFile) { |
|
|
|
|
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", transformedComposeFile); |
|
|
|
|
properties.put("spring.docker.compose.file", composeFile); |
|
|
|
|
properties.put("spring.docker.compose.stop.command", "down"); |
|
|
|
|
application.setDefaultProperties(properties); |
|
|
|
|
return application; |
|
|
|
|
@ -110,7 +114,7 @@ class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTe
@@ -110,7 +114,7 @@ class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTe
|
|
|
|
|
private void cleanUp(ExtensionContext context) throws Exception { |
|
|
|
|
Store store = context.getStore(NAMESPACE); |
|
|
|
|
runShutdownHandlers(); |
|
|
|
|
deleteComposeFile(store); |
|
|
|
|
deleteWorkspace(store); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void runShutdownHandlers() { |
|
|
|
|
@ -118,10 +122,10 @@ class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTe
@@ -118,10 +122,10 @@ class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTe
|
|
|
|
|
((Runnable) shutdownHandlers).run(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void deleteComposeFile(Store store) throws IOException { |
|
|
|
|
Path composeFile = store.get(STORE_KEY_COMPOSE_FILE, Path.class); |
|
|
|
|
if (composeFile != null) { |
|
|
|
|
Files.delete(composeFile); |
|
|
|
|
private void deleteWorkspace(Store store) throws IOException { |
|
|
|
|
Path workspace = (Path) store.get(STORE_KEY_WORKSPACE); |
|
|
|
|
if (workspace != null) { |
|
|
|
|
FileSystemUtils.deleteRecursively(workspace); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|