Browse Source

Improve debuggability of DockerComposeTestExtension

pull/44786/head
Moritz Halbritter 9 months ago
parent
commit
80b6c59669
  1. 48
      spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/test/DockerComposeTestExtension.java

48
spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/test/DockerComposeTestExtension.java

@ -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);
}
}

Loading…
Cancel
Save