Merge branch '3.3.x' into 3.4.x
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Trigger Docs Build (push) Blocked by required conditions Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[early-access:true toolchain:true version:24], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[early-access:true toolchain:true version:24], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:21], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:21], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:22], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:22], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:windows-latest name:Windows]) (push) Waiting to run Details
Run System Tests / Java ${{ matrix.java.version}} (map[toolchain:false version:17]) (push) Waiting to run Details
Run System Tests / Java ${{ matrix.java.version}} (map[toolchain:true version:21]) (push) Waiting to run Details

This commit is contained in:
Moritz Halbritter 2025-03-19 09:49:43 +01:00
commit 6567609cbc
5 changed files with 30 additions and 38 deletions

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,13 +20,11 @@ import java.sql.Driver;
import java.time.Duration; import java.time.Duration;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.testsupport.container.TestImage; import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SimpleDriverDataSource; import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -38,8 +36,6 @@ import static org.assertj.core.api.Assertions.assertThat;
* *
* @author Andy Wilkinson * @author Andy Wilkinson
*/ */
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests { class OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,13 +21,11 @@ import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories; import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions; import io.r2dbc.spi.ConnectionFactoryOptions;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.testsupport.container.TestImage; import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.r2dbc.core.DatabaseClient;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -37,8 +35,6 @@ import static org.assertj.core.api.Assertions.assertThat;
* *
* @author Andy Wilkinson * @author Andy Wilkinson
*/ */
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests { class OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "oracle-compose.yaml", image = TestImage.ORACLE_FREE) @DockerComposeTest(composeFile = "oracle-compose.yaml", image = TestImage.ORACLE_FREE)

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.boot.docker.compose.service.connection.test; package org.springframework.boot.docker.compose.service.connection.test;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -39,6 +40,7 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.fail; 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}. * {@link Extension} for {@link DockerComposeTest @DockerComposeTest}.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Moritz Halbritter
*/ */
class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback, ParameterResolver { class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback, ParameterResolver {
private static final Namespace NAMESPACE = Namespace.create(DockerComposeTestExtension.class); 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"; private static final String STORE_KEY_APPLICATION_CONTEXT = "application-context";
@Override @Override
public void beforeTestExecution(ExtensionContext context) throws Exception { public void beforeTestExecution(ExtensionContext context) throws Exception {
Path transformedComposeFile = prepareComposeFile(context);
Store store = context.getStore(NAMESPACE); Store store = context.getStore(NAMESPACE);
store.put(STORE_KEY_COMPOSE_FILE, transformedComposeFile); Path workspace = Files.createTempDirectory("DockerComposeTestExtension-");
store.put(STORE_KEY_WORKSPACE, workspace);
try { try {
SpringApplication application = prepareApplication(transformedComposeFile); Path composeFile = prepareComposeFile(workspace, context);
SpringApplication application = prepareApplication(composeFile);
store.put(STORE_KEY_APPLICATION_CONTEXT, application.run()); store.put(STORE_KEY_APPLICATION_CONTEXT, application.run());
} }
catch (Exception ex) { catch (Exception ex) {
@ -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); DockerComposeTest dockerComposeTest = context.getRequiredTestMethod().getAnnotation(DockerComposeTest.class);
TestImage image = dockerComposeTest.image(); TestImage image = dockerComposeTest.image();
Resource composeResource = new ClassPathResource(dockerComposeTest.composeFile(), Resource composeResource = new ClassPathResource(dockerComposeTest.composeFile(),
context.getRequiredTestClass()); 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 { try {
Path composeFile = composeFileResource.getFile().toPath(); String template = composeFileResource.getContentAsString(StandardCharsets.UTF_8);
Path transformedComposeFile = Files.createTempFile("", "-" + composeFile.getFileName().toString()); String content = template.replace("{imageName}", image.toString());
String transformedContent = Files.readString(composeFile).replace("{imageName}", image.toString()); Path composeFile = workspace.resolve("compose.yaml");
Files.writeString(transformedComposeFile, transformedContent); Files.writeString(composeFile, content);
return transformedComposeFile; return composeFile;
} }
catch (IOException ex) { 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); SpringApplication application = new SpringApplication(Config.class);
Map<String, Object> properties = new LinkedHashMap<>(); Map<String, Object> properties = new LinkedHashMap<>();
properties.put("spring.docker.compose.skip.in-tests", "false"); 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"); properties.put("spring.docker.compose.stop.command", "down");
application.setDefaultProperties(properties); application.setDefaultProperties(properties);
return application; return application;
@ -110,7 +114,7 @@ class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTe
private void cleanUp(ExtensionContext context) throws Exception { private void cleanUp(ExtensionContext context) throws Exception {
Store store = context.getStore(NAMESPACE); Store store = context.getStore(NAMESPACE);
runShutdownHandlers(); runShutdownHandlers();
deleteComposeFile(store); deleteWorkspace(store);
} }
private void runShutdownHandlers() { private void runShutdownHandlers() {
@ -118,10 +122,10 @@ class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTe
((Runnable) shutdownHandlers).run(); ((Runnable) shutdownHandlers).run();
} }
private void deleteComposeFile(Store store) throws IOException { private void deleteWorkspace(Store store) throws IOException {
Path composeFile = store.get(STORE_KEY_COMPOSE_FILE, Path.class); Path workspace = (Path) store.get(STORE_KEY_WORKSPACE);
if (composeFile != null) { if (workspace != null) {
Files.delete(composeFile); FileSystemUtils.deleteRecursively(workspace);
} }
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,7 +20,6 @@ import java.time.Duration;
import io.r2dbc.spi.ConnectionFactory; import io.r2dbc.spi.ConnectionFactory;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;
import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.oracle.OracleContainer; import org.testcontainers.oracle.OracleContainer;
@ -31,7 +30,6 @@ import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage; import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@ -45,8 +43,6 @@ import static org.assertj.core.api.Assertions.assertThat;
*/ */
@SpringJUnitConfig @SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true) @Testcontainers(disabledWithoutDocker = true)
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleFreeR2dbcContainerConnectionDetailsFactoryIntegrationTests { class OracleFreeR2dbcContainerConnectionDetailsFactoryIntegrationTests {
@Container @Container

View File

@ -182,7 +182,7 @@ public enum TestImage {
/** /**
* A container image suitable for testing Oracle Free. * A container image suitable for testing Oracle Free.
*/ */
ORACLE_FREE("gvenzl/oracle-free", "23.3-slim", () -> org.testcontainers.oracle.OracleContainer.class, ORACLE_FREE("gvenzl/oracle-free", "23.6-slim", () -> org.testcontainers.oracle.OracleContainer.class,
(container) -> ((org.testcontainers.oracle.OracleContainer) container) (container) -> ((org.testcontainers.oracle.OracleContainer) container)
.withStartupTimeout(Duration.ofMinutes(2))), .withStartupTimeout(Duration.ofMinutes(2))),