Ensure @AutoConfigureTestDatabase does not replace test databases

Update `@AutoConfigureTestDatabase` support so that by default test
databases are not replaced.

Fixes gh-35253
This commit is contained in:
Phillip Webb
2024-06-27 17:25:36 -07:00
parent 2e28d2642d
commit 8628f7334f
16 changed files with 654 additions and 22 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.
@@ -24,6 +24,7 @@ import java.util.List;
import org.testcontainers.containers.Container;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.container.ContainerImageMetadata;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
@@ -65,7 +66,9 @@ class ContainerFieldsImporter {
}
private void registerBeanDefinition(BeanDefinitionRegistry registry, Field field, Container<?> container) {
ContainerImageMetadata containerMetadata = new ContainerImageMetadata(container.getDockerImageName());
TestcontainerFieldBeanDefinition beanDefinition = new TestcontainerFieldBeanDefinition(field, container);
containerMetadata.addTo(beanDefinition);
String beanName = generateBeanName(field);
registry.registerBeanDefinition(beanName, beanDefinition);
}

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.
@@ -32,6 +32,7 @@ import org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.autoconfigure.container.ContainerImageMetadata;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactories;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactoryNotFoundException;
@@ -100,12 +101,14 @@ class ConnectionDetailsRegistrar {
Arrays.asList(existingBeans))));
return;
}
ContainerImageMetadata containerMetadata = new ContainerImageMetadata(source.getContainerImageName());
String beanName = getBeanName(source, connectionDetails);
Class<T> beanType = (Class<T>) connectionDetails.getClass();
Supplier<T> beanSupplier = () -> (T) connectionDetails;
logger.debug(LogMessage.of(() -> "Registering '%s' for %s".formatted(beanName, source)));
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanType, beanSupplier);
beanDefinition.setAttribute(ServiceConnection.class.getName(), true);
containerMetadata.addTo(beanDefinition);
registry.registerBeanDefinition(beanName, beanDefinition);
}

View File

@@ -52,6 +52,8 @@ public final class ContainerConnectionSource<C extends Container<?>> implements
private final Class<C> containerType;
private final String containerImageName;
private final String connectionName;
private final Set<Class<?>> connectionDetailsTypes;
@@ -63,6 +65,7 @@ public final class ContainerConnectionSource<C extends Container<?>> implements
this.beanNameSuffix = beanNameSuffix;
this.origin = origin;
this.containerType = containerType;
this.containerImageName = containerImageName;
this.connectionName = getOrDeduceConnectionName(annotation.getString("name"), containerImageName);
this.connectionDetailsTypes = Set.of(annotation.getClassArray("type"));
this.containerSupplier = containerSupplier;
@@ -73,6 +76,7 @@ public final class ContainerConnectionSource<C extends Container<?>> implements
this.beanNameSuffix = beanNameSuffix;
this.origin = origin;
this.containerType = containerType;
this.containerImageName = containerImageName;
this.connectionName = getOrDeduceConnectionName(annotation.name(), containerImageName);
this.connectionDetailsTypes = Set.of(annotation.type());
this.containerSupplier = containerSupplier;
@@ -136,6 +140,10 @@ public final class ContainerConnectionSource<C extends Container<?>> implements
return this.origin;
}
String getContainerImageName() {
return this.containerImageName;
}
String getConnectionName() {
return this.connectionName;
}