Merge branch '3.4.x'

Closes gh-44580
This commit is contained in:
Andy Wilkinson 2025-03-05 17:32:10 +00:00
commit 46b4d45983
189 changed files with 1717 additions and 829 deletions

View File

@ -166,6 +166,8 @@ class AutoConfigurationImportSelectorTests {
}
@Test
@WithTestAutoConfigurationImportsResource
@WithTestAutoConfigurationReplacementsResource
void removedExclusionsAreApplied() {
TestAutoConfigurationImportSelector importSelector = new TestAutoConfigurationImportSelector(
TestAutoConfiguration.class);
@ -234,7 +236,9 @@ class AutoConfigurationImportSelectorTests {
}
@Test
void soringConsidersReplacements() {
@WithTestAutoConfigurationImportsResource
@WithTestAutoConfigurationReplacementsResource
void sortingConsidersReplacements() {
TestAutoConfigurationImportSelector importSelector = new TestAutoConfigurationImportSelector(
TestAutoConfiguration.class);
setupImportSelector(importSelector);
@ -397,4 +401,28 @@ class AutoConfigurationImportSelectorTests {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(
name = "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$TestAutoConfiguration.imports",
content = """
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$AfterDeprecatedAutoConfiguration
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$ReplacementAutoConfiguration
""")
@interface WithTestAutoConfigurationImportsResource {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(
name = "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$TestAutoConfiguration.replacements",
content = """
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$DeprecatedAutoConfiguration=\
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$ReplacementAutoConfiguration
""")
@interface WithTestAutoConfigurationReplacementsResource {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 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.
@ -20,6 +20,8 @@ import java.util.Collections;
import org.junit.jupiter.api.Test;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import static org.assertj.core.api.Assertions.assertThat;
/**
@ -27,6 +29,12 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Phillip Webb
*/
@WithResource(name = "metadata.properties", content = """
test=
test.string=abc
test.int=123
test.set=a,b,b,c
""")
class AutoConfigurationMetadataLoaderTests {
@Test
@ -90,8 +98,8 @@ class AutoConfigurationMetadataLoaderTests {
}
private AutoConfigurationMetadata load() {
return AutoConfigurationMetadataLoader.loadMetadata(null,
"META-INF/AutoConfigurationMetadataLoaderTests.properties");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
return AutoConfigurationMetadataLoader.loadMetadata(classLoader, "metadata.properties");
}
}

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");
* you may not use this file except in compliance with the License.
@ -24,8 +24,11 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import static org.assertj.core.api.Assertions.assertThat;
/**
@ -33,10 +36,21 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Phillip Webb
*/
@WithResource(
name = "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfigurationReplacementsTests$TestAutoConfigurationReplacements.replacements",
content = """
com.example.A1=com.example.A2
com.example.B1=com.example.B2
""")
class AutoConfigurationReplacementsTests {
private final AutoConfigurationReplacements replacements = AutoConfigurationReplacements
.load(TestAutoConfigurationReplacements.class, null);
private AutoConfigurationReplacements replacements;
@BeforeEach
void loadReplacements() {
this.replacements = AutoConfigurationReplacements.load(TestAutoConfigurationReplacements.class,
Thread.currentThread().getContextClassLoader());
}
@Test
void replaceWhenMatchReplacesClassName() {

View File

@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.core.annotation.AliasFor;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
@ -74,6 +75,12 @@ class ImportAutoConfigurationImportSelectorTests {
}
@Test
@WithResource(
name = "META-INF/spring/org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$FromImportsFile.imports",
content = """
org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$ImportedAutoConfiguration
org.springframework.boot.autoconfigure.missing.MissingAutoConfiguration
""")
void importsAreSelectedFromImportsFile() throws Exception {
AnnotationMetadata annotationMetadata = getAnnotationMetadata(FromImportsFile.class);
String[] imports = this.importSelector.selectImports(annotationMetadata);
@ -83,9 +90,15 @@ class ImportAutoConfigurationImportSelectorTests {
}
@Test
@WithResource(
name = "META-INF/spring/org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$FromImportsFile.imports",
content = """
optional:org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$ImportedAutoConfiguration
optional:org.springframework.boot.autoconfigure.missing.MissingAutoConfiguration
org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$AnotherImportedAutoConfiguration
""")
void importsSelectedFromImportsFileIgnoreMissingOptionalClasses() throws Exception {
AnnotationMetadata annotationMetadata = getAnnotationMetadata(
FromImportsFileIgnoresMissingOptionalClasses.class);
AnnotationMetadata annotationMetadata = getAnnotationMetadata(FromImportsFile.class);
String[] imports = this.importSelector.selectImports(annotationMetadata);
assertThat(imports).containsExactly(
"org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$ImportedAutoConfiguration",

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");
* you may not use this file except in compliance with the License.
@ -910,9 +910,8 @@ class RabbitAutoConfigurationTests {
void enableSslWithBundle() {
this.contextRunner.withUserConfiguration(TestConfiguration.class)
.withPropertyValues("spring.rabbitmq.ssl.bundle=test-bundle",
"spring.ssl.bundle.jks.test-bundle.keystore.location=classpath:test.jks",
"spring.ssl.bundle.jks.test-bundle.keystore.password=secret",
"spring.ssl.bundle.jks.test-bundle.key.password=password")
"spring.ssl.bundle.jks.test-bundle.keystore.location=classpath:org/springframework/boot/autoconfigure/amqp/test.jks",
"spring.ssl.bundle.jks.test-bundle.keystore.password=secret")
.run((context) -> {
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory(context);
assertThat(rabbitConnectionFactory.isSSL()).isTrue();

View File

@ -72,6 +72,8 @@ import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -288,13 +290,13 @@ class BatchAutoConfigurationTests {
}
@Test
@WithPackageResources("custom-schema.sql")
void testRenamePrefix() {
this.contextRunner
.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class,
HibernateJpaAutoConfiguration.class)
.withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.batch.jdbc.schema:classpath:batch/custom-schema.sql",
"spring.batch.jdbc.tablePrefix:PREFIX_")
"spring.batch.jdbc.schema:classpath:custom-schema.sql", "spring.batch.jdbc.tablePrefix:PREFIX_")
.run((context) -> {
assertThat(context).hasSingleBean(JobLauncher.class);
assertThat(context.getBean(BatchProperties.class).getJdbc().getInitializeSchema())
@ -412,6 +414,7 @@ class BatchAutoConfigurationTests {
}
@Test
@WithResource(name = "db/changelog/db.changelog-master.yaml", content = "databaseChangeLog:")
void jobRepositoryBeansDependOnLiquibase() {
this.contextRunner.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class)
.withUserConfiguration(LiquibaseAutoConfiguration.class)

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");
* you may not use this file except in compliance with the License.
@ -34,6 +34,7 @@ import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfigu
import org.springframework.boot.sql.init.DatabaseInitializationMode;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Isolation;
@ -70,11 +71,11 @@ class BatchAutoConfigurationWithoutJpaTests {
}
@Test
@WithPackageResources("custom-schema.sql")
void jdbcWithCustomPrefix() {
this.contextRunner.withUserConfiguration(DefaultConfiguration.class, EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.batch.jdbc.schema:classpath:batch/custom-schema.sql",
"spring.batch.jdbc.tablePrefix:PREFIX_")
"spring.batch.jdbc.schema:classpath:custom-schema.sql", "spring.batch.jdbc.tablePrefix:PREFIX_")
.run((context) -> {
assertThat(new JdbcTemplate(context.getBean(DataSource.class))
.queryForList("select * from PREFIX_JOB_EXECUTION")).isEmpty();

View File

@ -16,6 +16,10 @@
package org.springframework.boot.autoconfigure.cache;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -48,6 +52,7 @@ import org.springframework.boot.autoconfigure.cache.support.MockCachingProvider.
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.cache.CacheManager;
@ -481,6 +486,7 @@ class CacheAutoConfigurationTests extends AbstractCacheAutoConfigurationTests {
}
@Test
@WithHazelcastXmlResource
void hazelcastCacheExplicit() {
this.contextRunner.withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class))
.withUserConfiguration(DefaultCacheConfiguration.class)
@ -496,6 +502,7 @@ class CacheAutoConfigurationTests extends AbstractCacheAutoConfigurationTests {
}
@Test
@WithHazelcastXmlResource
void hazelcastCacheWithCustomizers() {
this.contextRunner.withUserConfiguration(HazelcastCacheAndCustomizersConfiguration.class)
.withPropertyValues("spring.cache.type=hazelcast")
@ -548,10 +555,31 @@ class CacheAutoConfigurationTests extends AbstractCacheAutoConfigurationTests {
}
@Test
@WithResource(name = "hazelcast-specific.xml", content = """
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-5.0.xsd"
xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<queue name="foobar"/>
<map name="foobar">
<time-to-live-seconds>3600</time-to-live-seconds>
<max-idle-seconds>600</max-idle-seconds>
</map>
<network>
<join>
<auto-detection enabled="false" />
<multicast enabled="false"/>
</join>
</network>
</hazelcast>
""")
void hazelcastAsJCacheWithConfig() {
String cachingProviderFqn = HazelcastServerCachingProvider.class.getName();
try {
String configLocation = "org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml";
String configLocation = "hazelcast-specific.xml";
this.contextRunner.withUserConfiguration(DefaultCacheConfiguration.class)
.withPropertyValues("spring.cache.type=jcache", "spring.cache.jcache.provider=" + cachingProviderFqn,
"spring.cache.jcache.config=" + configLocation)
@ -568,6 +596,7 @@ class CacheAutoConfigurationTests extends AbstractCacheAutoConfigurationTests {
}
@Test
@WithHazelcastXmlResource
void hazelcastAsJCacheWithExistingHazelcastInstance() {
String cachingProviderFqn = HazelcastServerCachingProvider.class.getName();
this.contextRunner.withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class))
@ -587,6 +616,7 @@ class CacheAutoConfigurationTests extends AbstractCacheAutoConfigurationTests {
}
@Test
@WithInfinispanXmlResource
void infinispanCacheWithConfig() {
this.contextRunner.withUserConfiguration(DefaultCacheConfiguration.class)
.withPropertyValues("spring.cache.type=infinispan", "spring.cache.infinispan.config=infinispan.xml")
@ -635,6 +665,7 @@ class CacheAutoConfigurationTests extends AbstractCacheAutoConfigurationTests {
}
@Test
@WithInfinispanXmlResource
void infinispanAsJCacheWithConfig() {
String cachingProviderClassName = JCachingProvider.class.getName();
String configLocation = "infinispan.xml";
@ -1078,4 +1109,45 @@ class CacheAutoConfigurationTests extends AbstractCacheAutoConfigurationTests {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "infinispan.xml", content = """
<?xml version="1.0" encoding="UTF-8"?>
<infinispan>
<!-- ************************************** -->
<!-- Corresponds to @Cacheable("cache-name") -->
<!-- ************************************** -->
<cache-container default-cache="default">
<local-cache name="default"/>
<local-cache name="foo"/>
<local-cache name="bar" />
</cache-container>
</infinispan>
""")
@interface WithInfinispanXmlResource {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "hazelcast.xml", content = """
<hazelcast
xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-5.0.xsd"
xmlns="http://www.hazelcast.com/schema/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<instance-name>default-instance</instance-name>
<map name="defaultCache" />
<network>
<join>
<auto-detection enabled="false" />
<multicast enabled="false" />
</join>
</network>
</hazelcast>
""")
@interface WithHazelcastXmlResource {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.cache.CacheAutoConfigurationTests.DefaultCacheConfiguration;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.cache.jcache.JCacheCacheManager;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
@ -49,6 +50,34 @@ class EhCache3CacheAutoConfigurationTests extends AbstractCacheAutoConfiguration
}
@Test
@WithResource(name = "ehcache3.xml", content = """
<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
xsi:schemaLocation="
http://www.ehcache.org/v3 https://www.ehcache.org/schema/ehcache-core-3.10.xsd
http://www.ehcache.org/v3/jsr107 https://www.ehcache.org/schema/ehcache-107-ext-3.10.xsd">
<cache-template name="example">
<heap unit="entries">200</heap>
</cache-template>
<cache alias="foo" uses-template="example">
<expiry>
<ttl unit="seconds">600</ttl>
</expiry>
<jsr107:mbeans enable-statistics="true"/>
</cache>
<cache alias="bar" uses-template="example">
<expiry>
<ttl unit="seconds">400</ttl>
</expiry>
</cache>
</config>
""")
void ehcache3AsJCacheWithConfig() {
String cachingProviderFqn = EhcacheCachingProvider.class.getName();
String configLocation = "ehcache3.xml";

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -38,6 +38,7 @@ import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfigurati
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.ssl.NoSuchSslBundleException;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -89,6 +90,7 @@ class CassandraAutoConfigurationTests {
}
@Test
@WithPackageResources("test.jks")
void cqlSessionBuilderWithSslBundle() {
this.contextRunner
.withPropertyValues("spring.cassandra.ssl.bundle=test-bundle",

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 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.
@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.condition;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -35,6 +36,7 @@ class ConditionalOnResourceTests {
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@Test
@WithResource(name = "schema.sql")
void testResourceExists() {
this.context.register(BasicConfiguration.class);
this.context.refresh();
@ -43,6 +45,7 @@ class ConditionalOnResourceTests {
}
@Test
@WithResource(name = "schema.sql")
void testResourceExistsWithPlaceholder() {
TestPropertyValues.of("schema=schema.sql").applyTo(this.context);
this.context.register(PlaceholderConfiguration.class);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 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.
@ -20,6 +20,7 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@ -45,6 +46,7 @@ class ResourceConditionTests {
}
@Test
@WithResource(name = "logging.properties")
void defaultResourceAndNoExplicitKey() {
load(DefaultLocationConfiguration.class);
assertThat(this.context.containsBean("foo")).isTrue();

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");
* you may not use this file except in compliance with the License.
@ -16,6 +16,10 @@
package org.springframework.boot.autoconfigure.context;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Locale;
import org.junit.jupiter.api.Disabled;
@ -28,6 +32,7 @@ import org.springframework.boot.autoconfigure.context.MessageSourceAutoConfigura
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.annotation.Bean;
@ -59,6 +64,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void propertiesBundleWithSlashIsDetected() {
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages").run((context) -> {
assertThat(context).hasSingleBean(MessageSource.class);
@ -67,6 +73,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void propertiesBundleWithDotIsDetected() {
this.contextRunner.withPropertyValues("spring.messages.basename=test.messages").run((context) -> {
assertThat(context).hasSingleBean(MessageSource.class);
@ -75,6 +82,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestSwedishPropertiesResource
void testEncodingWorks() {
this.contextRunner.withPropertyValues("spring.messages.basename=test/swedish")
.run((context) -> assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
@ -82,6 +90,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void testCacheDurationNoUnit() {
this.contextRunner
.withPropertyValues("spring.messages.basename=test/messages", "spring.messages.cache-duration=10")
@ -89,6 +98,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void testCacheDurationWithUnit() {
this.contextRunner
.withPropertyValues("spring.messages.basename=test/messages", "spring.messages.cache-duration=1m")
@ -103,6 +113,8 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
@WithTestMessages2PropertiesResource
void testMultipleMessageSourceCreated() {
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages,test/messages2")
.run((context) -> {
@ -112,13 +124,17 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
@Disabled("Expected to fail per gh-1075")
@WithResource(name = "application-switch-messages.properties", content = "spring.messages.basename:test/messages")
void testMessageSourceFromPropertySourceAnnotation() {
this.contextRunner.withUserConfiguration(Config.class)
.run((context) -> assertThat(context.getMessage("foo", null, "Foo message", Locale.UK)).isEqualTo("bar"));
}
@Test
@WithTestMessagesPropertiesResource
@WithResource(name = "test/common-messages.properties", content = "hello=world")
void testCommonMessages() {
this.contextRunner
.withPropertyValues("spring.messages.basename=test/messages",
@ -127,16 +143,18 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void testCommonMessagesWhenNotFound() {
this.contextRunner
.withPropertyValues("spring.messages.basename=test/messages",
"spring.messages.common-messages=classpath:test/common-messages-missing.properties")
"spring.messages.common-messages=classpath:test/common-messages.properties")
.run((context) -> assertThat(context).getFailure()
.hasMessageContaining(
"Failed to load common messages from 'class path resource [test/common-messages-missing.properties]'"));
"Failed to load common messages from 'class path resource [test/common-messages.properties]'"));
}
@Test
@WithTestMessagesPropertiesResource
void testFallbackDefault() {
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages")
.run((context) -> assertThat(context.getBean(MessageSource.class))
@ -144,6 +162,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void testFallbackTurnOff() {
this.contextRunner
.withPropertyValues("spring.messages.basename=test/messages",
@ -153,6 +172,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void testFormatMessageDefault() {
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages")
.run((context) -> assertThat(context.getBean(MessageSource.class))
@ -160,6 +180,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void testFormatMessageOn() {
this.contextRunner
.withPropertyValues("spring.messages.basename=test/messages",
@ -169,6 +190,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void testUseCodeAsDefaultMessageDefault() {
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages")
.run((context) -> assertThat(context.getBean(MessageSource.class))
@ -176,6 +198,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void testUseCodeAsDefaultMessageOn() {
this.contextRunner
.withPropertyValues("spring.messages.basename=test/messages",
@ -191,6 +214,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void existingMessageSourceInParentIsIgnored() {
this.contextRunner.run((parent) -> this.contextRunner.withParent(parent)
.withPropertyValues("spring.messages.basename=test/messages")
@ -198,6 +222,7 @@ class MessageSourceAutoConfigurationTests {
}
@Test
@WithTestMessagesPropertiesResource
void messageSourceWithNonStandardBeanNameIsIgnored() {
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages")
.withUserConfiguration(CustomBeanNameMessageSourceConfiguration.class)
@ -258,4 +283,25 @@ class MessageSourceAutoConfigurationTests {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "test/messages.properties", content = "foo=bar")
@interface WithTestMessagesPropertiesResource {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "test/messages2.properties", content = "foo-foo=bar-bar")
@interface WithTestMessages2PropertiesResource {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "test/swedish.properties", content = "foo=Some text with some swedish öäå!")
@interface WithTestSwedishPropertiesResource {
}
}

View File

@ -42,6 +42,7 @@ import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.ssl.NoSuchSslBundleException;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -201,13 +202,14 @@ class CouchbaseAutoConfigurationTests {
}
@Test
@WithPackageResources("test.jks")
void enableSslWithBundle() {
testClusterEnvironment((env) -> {
SecurityConfig securityConfig = env.securityConfig();
assertThat(securityConfig.tlsEnabled()).isTrue();
assertThat(securityConfig.trustManagerFactory()).isNotNull();
}, "spring.ssl.bundle.jks.test-bundle.keystore.location=classpath:test.jks",
"spring.ssl.bundle.jks.test-bundle.keystore.password=secret",
}, "spring.ssl.bundle.jks.test-bundle.truststore.location=classpath:test.jks",
"spring.ssl.bundle.jks.test-bundle.truststore.password=secret",
"spring.couchbase.env.ssl.bundle=test-bundle");
}

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");
* you may not use this file except in compliance with the License.
@ -33,6 +33,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerA
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.ManagedTypes;
@ -61,6 +62,17 @@ import static org.mockito.Mockito.mock;
* @author Mark Paluch
* @author Jens Schauder
*/
@WithResource(name = "schema.sql", content = """
CREATE TABLE CITY (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(30),
state VARCHAR(30),
country VARCHAR(30),
map VARCHAR(30)
);
""")
@WithResource(name = "data.sql",
content = "INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google');")
class JdbcRepositoriesAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
@ -208,8 +220,8 @@ class JdbcRepositoriesAutoConfigurationTests {
return (runner) -> runner
.withConfiguration(
AutoConfigurations.of(DataSourceAutoConfiguration.class, SqlInitializationAutoConfiguration.class))
.withPropertyValues("spring.sql.init.schema-locations=classpath:data-city-schema.sql",
"spring.sql.init.data-locations=classpath:city.sql", "spring.datasource.generate-unique-name:true");
.withPropertyValues("spring.sql.init.schema-locations=classpath:schema.sql",
"spring.sql.init.data-locations=classpath:data.sql", "spring.datasource.generate-unique-name:true");
}
@TestAutoConfigurationPackage(City.class)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -31,6 +31,7 @@ import org.springframework.boot.autoconfigure.data.r2dbc.city.CityRepository;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
@ -48,6 +49,17 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Mark Paluch
*/
@WithResource(name = "schema.sql", content = """
CREATE TABLE CITY (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(30),
state VARCHAR(30),
country VARCHAR(30),
map VARCHAR(30)
);
""")
@WithResource(name = "data.sql",
content = "INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google');")
class R2dbcRepositoriesAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
@ -117,8 +129,8 @@ class R2dbcRepositoriesAutoConfigurationTests {
@Autowired
void initializeDatabase(ConnectionFactory connectionFactory) {
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource[] scripts = new Resource[] { resourceLoader.getResource("classpath:data-city-schema.sql"),
resourceLoader.getResource("classpath:city.sql") };
Resource[] scripts = new Resource[] { resourceLoader.getResource("classpath:schema.sql"),
resourceLoader.getResource("classpath:data.sql") };
new ResourceDatabasePopulator(scripts).populate(connectionFactory).block();
}

View File

@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.assertj.SimpleAsyncTaskExecutorAssert;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
@ -255,6 +256,7 @@ class RedisAutoConfigurationJedisTests {
}
@Test
@WithPackageResources("test.jks")
void testRedisConfigurationWithSslBundle() {
this.contextRunner
.withPropertyValues("spring.data.redis.ssl.bundle:test-bundle",

View File

@ -51,6 +51,7 @@ import org.springframework.boot.test.context.assertj.AssertableApplicationContex
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.testsupport.assertj.SimpleAsyncTaskExecutorAssert;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
@ -635,6 +636,7 @@ class RedisAutoConfigurationTests {
}
@Test
@WithPackageResources("test.jks")
void testRedisConfigurationWithSslBundle() {
this.contextRunner
.withPropertyValues("spring.data.redis.ssl.bundle:test-bundle",

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -41,6 +41,7 @@ import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestCli
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.util.ReflectionTestUtils;
@ -288,6 +289,7 @@ class ElasticsearchRestClientAutoConfigurationTests {
}
@Test
@WithPackageResources("test.jks")
@SuppressWarnings("unchecked")
void configureWithSslBundle() {
List<String> properties = new ArrayList<>();

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");
* you may not use this file except in compliance with the License.
@ -16,6 +16,11 @@
package org.springframework.boot.autoconfigure.flyway;
import java.io.Serializable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
@ -25,6 +30,10 @@ import java.util.UUID;
import javax.sql.DataSource;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.Location;
import org.flywaydb.core.api.MigrationVersion;
@ -68,6 +77,8 @@ import org.springframework.boot.test.context.assertj.AssertableApplicationContex
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.boot.testsupport.classpath.resources.ResourcePath;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@ -411,7 +422,9 @@ class FlywayAutoConfigurationTests {
}
@Test
void failOnMissingLocationsAllExist() {
@WithResource(name = "db/changelog/V1.1__refine.sql")
@WithResource(name = "db/migration/V1__init.sql", content = "DROP TABLE IF EXISTS TEST")
void failOnMissingLocationsDoesNotFailWhenAllExist() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.fail-on-missing-locations=true")
.withPropertyValues("spring.flyway.locations:classpath:db/changelog,classpath:db/migration")
@ -419,6 +432,8 @@ class FlywayAutoConfigurationTests {
}
@Test
@WithResource(name = "db/changelog/V1.1__refine.sql")
@WithResource(name = "db/migration/V1__init.sql", content = "DROP TABLE IF EXISTS TEST")
void failOnMissingLocationsAllExistWithImplicitClasspathPrefix() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.fail-on-missing-locations=true")
@ -427,10 +442,11 @@ class FlywayAutoConfigurationTests {
}
@Test
void failOnMissingLocationsAllExistWithFilesystemPrefix() {
@WithResource(name = "db/migration/V1__init.sql", content = "DROP TABLE IF EXISTS TEST")
void failOnMissingLocationsFilesystemPrefixDoesNotFailWhenAllExist(@ResourcePath("db/migration") String migration) {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.fail-on-missing-locations=true")
.withPropertyValues("spring.flyway.locations:filesystem:src/test/resources/db/migration")
.withPropertyValues("spring.flyway.locations:filesystem:" + migration)
.run((context) -> assertThat(context).hasNotFailed());
}
@ -466,6 +482,7 @@ class FlywayAutoConfigurationTests {
}
@Test
@WithMetaInfPersistenceXmlResource
void customFlywayWithJpa() {
this.contextRunner
.withUserConfiguration(EmbeddedDataSourceConfiguration.class, CustomFlywayWithJpaConfiguration.class)
@ -480,6 +497,7 @@ class FlywayAutoConfigurationTests {
}
@Test
@WithMetaInfPersistenceXmlResource
void customFlywayMigrationInitializerWithJpa() {
this.contextRunner
.withUserConfiguration(EmbeddedDataSourceConfiguration.class,
@ -518,6 +536,7 @@ class FlywayAutoConfigurationTests {
}
@Test
@WithResource(name = "db/vendors/h2/V1__init.sql", content = "DROP TABLE IF EXISTS TEST;")
void useVendorDirectory() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.locations=classpath:db/vendors/{vendor},classpath:db/changelog")
@ -530,6 +549,7 @@ class FlywayAutoConfigurationTests {
}
@Test
@WithResource(name = "db/vendors/h2/V1__init.sql", content = "DROP TABLE IF EXISTS TEST;")
void useOneLocationWithVendorDirectory() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.locations=classpath:db/vendors/{vendor}")
@ -1336,4 +1356,74 @@ class FlywayAutoConfigurationTests {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "META-INF/persistence.xml",
content = """
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="manually-configured">
<class>org.springframework.boot.autoconfigure.flyway.FlywayAutoConfigurationTests$City</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>
""")
@interface WithMetaInfPersistenceXmlResource {
}
@Entity
public static class City implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String state;
@Column(nullable = false)
private String country;
@Column(nullable = false)
private String map;
protected City() {
}
City(String name, String state, String country, String map) {
this.name = name;
this.state = state;
this.country = country;
this.map = map;
}
public String getName() {
return this.name;
}
public String getState() {
return this.state;
}
public String getCountry() {
return this.country;
}
public String getMap() {
return this.map;
}
@Override
public String toString() {
return getName() + "," + getState() + "," + getCountry();
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 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.
@ -24,6 +24,8 @@ import org.flywaydb.core.api.resource.LoadableResource;
import org.flywaydb.core.internal.resource.NoopResourceProvider;
import org.junit.jupiter.api.Test;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import static org.assertj.core.api.Assertions.assertThat;
/**
@ -44,6 +46,7 @@ class NativeImageResourceProviderCustomizerTests {
}
@Test
@WithResource(name = "db/migration/V1__init.sql")
void nativeImageResourceProviderShouldFindMigrations() {
FluentConfiguration configuration = new FluentConfiguration();
this.customizer.customize(configuration);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -20,11 +20,15 @@ import java.io.StringWriter;
import java.time.Duration;
import java.util.Locale;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.ApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
@ -46,6 +50,12 @@ class FreeMarkerAutoConfigurationReactiveIntegrationTests {
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(FreeMarkerAutoConfiguration.class));
@BeforeEach
@AfterEach
void clearReactorSchedulers() {
Schedulers.shutdownNow();
}
@Test
void defaultConfiguration() {
this.contextRunner.run((context) -> {
@ -57,6 +67,7 @@ class FreeMarkerAutoConfigurationReactiveIntegrationTests {
}
@Test
@WithResource(name = "templates/home.ftlh", content = "home")
void defaultViewResolution() {
this.contextRunner.run((context) -> {
MockServerWebExchange exchange = render(context, "home");
@ -67,6 +78,7 @@ class FreeMarkerAutoConfigurationReactiveIntegrationTests {
}
@Test
@WithResource(name = "templates/prefix/prefixed.ftlh", content = "prefixed")
void customPrefix() {
this.contextRunner.withPropertyValues("spring.freemarker.prefix:prefix/").run((context) -> {
MockServerWebExchange exchange = render(context, "prefixed");
@ -76,6 +88,7 @@ class FreeMarkerAutoConfigurationReactiveIntegrationTests {
}
@Test
@WithResource(name = "templates/suffixed.freemarker", content = "suffixed")
void customSuffix() {
this.contextRunner.withPropertyValues("spring.freemarker.suffix:.freemarker").run((context) -> {
MockServerWebExchange exchange = render(context, "suffixed");
@ -85,6 +98,7 @@ class FreeMarkerAutoConfigurationReactiveIntegrationTests {
}
@Test
@WithResource(name = "custom-templates/custom.ftlh", content = "custom")
void customTemplateLoaderPath() {
this.contextRunner.withPropertyValues("spring.freemarker.templateLoaderPath:classpath:/custom-templates/")
.run((context) -> {
@ -104,6 +118,7 @@ class FreeMarkerAutoConfigurationReactiveIntegrationTests {
}
@Test
@WithResource(name = "templates/message.ftlh", content = "Message: ${greeting}")
void renderTemplate() {
this.contextRunner.withPropertyValues().run((context) -> {
FreeMarkerConfigurer freemarker = context.getBean(FreeMarkerConfigurer.class);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -29,6 +29,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
@ -75,6 +76,7 @@ class FreeMarkerAutoConfigurationServletIntegrationTests {
}
@Test
@WithResource(name = "templates/home.ftlh", content = "home")
void defaultViewResolution() throws Exception {
load();
MockHttpServletResponse response = render("home");
@ -84,6 +86,7 @@ class FreeMarkerAutoConfigurationServletIntegrationTests {
}
@Test
@WithResource(name = "templates/home.ftlh", content = "home")
void customContentType() throws Exception {
load("spring.freemarker.contentType:application/json");
MockHttpServletResponse response = render("home");
@ -93,6 +96,7 @@ class FreeMarkerAutoConfigurationServletIntegrationTests {
}
@Test
@WithResource(name = "templates/prefix/prefixed.ftlh", content = "prefixed")
void customPrefix() throws Exception {
load("spring.freemarker.prefix:prefix/");
MockHttpServletResponse response = render("prefixed");
@ -101,6 +105,7 @@ class FreeMarkerAutoConfigurationServletIntegrationTests {
}
@Test
@WithResource(name = "templates/suffixed.freemarker", content = "suffixed")
void customSuffix() throws Exception {
load("spring.freemarker.suffix:.freemarker");
MockHttpServletResponse response = render("suffixed");
@ -109,6 +114,7 @@ class FreeMarkerAutoConfigurationServletIntegrationTests {
}
@Test
@WithResource(name = "custom-templates/custom.ftlh", content = "custom")
void customTemplateLoaderPath() throws Exception {
load("spring.freemarker.templateLoaderPath:classpath:/custom-templates/");
MockHttpServletResponse response = render("custom");
@ -138,6 +144,7 @@ class FreeMarkerAutoConfigurationServletIntegrationTests {
}
@Test
@WithResource(name = "templates/message.ftlh", content = "Message: ${greeting}")
void renderTemplate() throws Exception {
load();
FreeMarkerConfigurer freemarker = this.context.getBean(FreeMarkerConfigurer.class);

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");
* you may not use this file except in compliance with the License.
@ -27,6 +27,7 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
@ -51,6 +52,7 @@ class FreeMarkerAutoConfigurationTests {
.withConfiguration(AutoConfigurations.of(FreeMarkerAutoConfiguration.class));
@Test
@WithResource(name = "templates/message.ftlh", content = "Message: ${greeting}")
void renderNonWebAppTemplate() {
this.contextRunner.run((context) -> {
freemarker.template.Configuration freemarker = context.getBean(freemarker.template.Configuration.class);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -25,6 +25,7 @@ import org.springframework.beans.factory.aot.AotServices;
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider.FreeMarkerTemplateAvailabilityProperties;
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider.FreeMarkerTemplateAvailabilityRuntimeHints;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.mock.env.MockEnvironment;
@ -45,6 +46,7 @@ class FreeMarkerTemplateAvailabilityProviderTests {
private final MockEnvironment environment = new MockEnvironment();
@Test
@WithResource(name = "templates/home.ftlh")
void availabilityOfTemplateInDefaultLocation() {
assertThat(this.provider.isTemplateAvailable("home", this.environment, getClass().getClassLoader(),
this.resourceLoader))
@ -59,6 +61,7 @@ class FreeMarkerTemplateAvailabilityProviderTests {
}
@Test
@WithResource(name = "custom-templates/custom.ftlh")
void availabilityOfTemplateWithCustomLoaderPath() {
this.environment.setProperty("spring.freemarker.template-loader-path", "classpath:/custom-templates/");
assertThat(this.provider.isTemplateAvailable("custom", this.environment, getClass().getClassLoader(),
@ -67,6 +70,7 @@ class FreeMarkerTemplateAvailabilityProviderTests {
}
@Test
@WithResource(name = "custom-templates/custom.ftlh")
void availabilityOfTemplateWithCustomLoaderPathConfiguredAsAList() {
this.environment.setProperty("spring.freemarker.template-loader-path[0]", "classpath:/custom-templates/");
assertThat(this.provider.isTemplateAvailable("custom", this.environment, getClass().getClassLoader(),
@ -75,6 +79,7 @@ class FreeMarkerTemplateAvailabilityProviderTests {
}
@Test
@WithResource(name = "templates/prefix/prefixed.ftlh")
void availabilityOfTemplateWithCustomPrefix() {
this.environment.setProperty("spring.freemarker.prefix", "prefix/");
assertThat(this.provider.isTemplateAvailable("prefixed", this.environment, getClass().getClassLoader(),
@ -83,6 +88,7 @@ class FreeMarkerTemplateAvailabilityProviderTests {
}
@Test
@WithResource(name = "templates/suffixed.freemarker")
void availabilityOfTemplateWithCustomSuffix() {
this.environment.setProperty("spring.freemarker.suffix", ".freemarker");
assertThat(this.provider.isTemplateAvailable("suffixed", this.environment, getClass().getClassLoader(),

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");
* you may not use this file except in compliance with the License.
@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -38,6 +39,8 @@ class DefaultGraphQlSchemaConditionTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
@Test
@WithResource(name = "graphql/one.graphqls")
@WithResource(name = "graphql/two.graphqls")
void matchesWhenSchemaFilesAreDetected() {
this.contextRunner.withUserConfiguration(TestingConfiguration.class).run((context) -> {
didMatch(context);

View File

@ -35,10 +35,13 @@ import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration.GraphQlResourcesRuntimeHints;
import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener;
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ByteArrayResource;
@ -59,6 +62,25 @@ import static org.mockito.Mockito.mock;
/**
* Tests for {@link GraphQlAutoConfiguration}.
*/
@WithResource(name = "graphql/types/book.graphqls", content = """
type Book {
id: ID
name: String
pageCount: Int
author: String
}
""")
@WithResource(name = "graphql/schema.graphqls", content = """
type Query {
greeting(name: String! = "Spring"): String!
bookById(id: ID): Book
books: BookConnection
}
type Subscription {
booksOnSale(minPages: Int) : Book!
}
""")
@ExtendWith(OutputCaptureExtension.class)
class GraphQlAutoConfigurationTests {
@ -67,11 +89,12 @@ class GraphQlAutoConfigurationTests {
@Test
void shouldContributeDefaultBeans() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(GraphQlSource.class)
.hasSingleBean(BatchLoaderRegistry.class)
.hasSingleBean(ExecutionGraphQlService.class)
.hasSingleBean(AnnotatedControllerConfigurer.class)
.hasSingleBean(EncodingCursorStrategy.class));
this.contextRunner.withInitializer(ConditionEvaluationReportLoggingListener.forLogLevel(LogLevel.INFO))
.run((context) -> assertThat(context).hasSingleBean(GraphQlSource.class)
.hasSingleBean(BatchLoaderRegistry.class)
.hasSingleBean(ExecutionGraphQlService.class)
.hasSingleBean(AnnotatedControllerConfigurer.class)
.hasSingleBean(EncodingCursorStrategy.class));
}
@Test
@ -99,6 +122,12 @@ class GraphQlAutoConfigurationTests {
}
@Test
@WithResource(name = "graphql/types/person.custom", content = """
type Person {
id: ID
name: String
}
""")
void shouldScanLocationsWithCustomExtension() {
this.contextRunner.withPropertyValues("spring.graphql.schema.file-extensions:.graphqls,.custom")
.run((context) -> {
@ -111,6 +140,12 @@ class GraphQlAutoConfigurationTests {
}
@Test
@WithResource(name = "graphql/types/person.custom", content = """
type Person {
id: ID
name: String
}
""")
void shouldConfigureAdditionalSchemaFiles() {
this.contextRunner
.withPropertyValues("spring.graphql.schema.additional-files=classpath:graphql/types/person.custom")

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -18,12 +18,11 @@ package org.springframework.boot.autoconfigure.graphql.data;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.graphql.Book;
import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.repository.CrudRepository;
@ -41,6 +40,25 @@ import static org.mockito.Mockito.mock;
*
* @author Brian Clozel
*/
@WithResource(name = "graphql/types/book.graphqls", content = """
type Book {
id: ID
name: String
pageCount: Int
author: String
}
""")
@WithResource(name = "graphql/schema.graphqls", content = """
type Query {
greeting(name: String! = "Spring"): String!
bookById(id: ID): Book
books: BookConnection
}
type Subscription {
booksOnSale(minPages: Int) : Book!
}
""")
class GraphQlQueryByExampleAutoConfigurationTests {
private static final Book book = new Book("42", "Test title", 42, "Test Author");
@ -51,7 +69,6 @@ class GraphQlQueryByExampleAutoConfigurationTests {
.withUserConfiguration(MockRepositoryConfig.class)
.withPropertyValues("spring.main.web-application-type=servlet");
@Test
void shouldRegisterDataFetcherForQueryByExampleRepositories() {
this.contextRunner.run((context) -> {
ExecutionGraphQlService graphQlService = context.getBean(ExecutionGraphQlService.class);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.graphql.Book;
import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
@ -44,6 +45,25 @@ import static org.mockito.Mockito.mock;
*
* @author Brian Clozel
*/
@WithResource(name = "graphql/types/book.graphqls", content = """
type Book {
id: ID
name: String
pageCount: Int
author: String
}
""")
@WithResource(name = "graphql/schema.graphqls", content = """
type Query {
greeting(name: String! = "Spring"): String!
bookById(id: ID): Book
books: BookConnection
}
type Subscription {
booksOnSale(minPages: Int) : Book!
}
""")
class GraphQlQuerydslAutoConfigurationTests {
private static final Book book = new Book("42", "Test title", 42, "Test Author");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -23,6 +23,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.graphql.Book;
import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor;
@ -41,6 +42,25 @@ import static org.mockito.Mockito.mock;
*
* @author Brian Clozel
*/
@WithResource(name = "graphql/types/book.graphqls", content = """
type Book {
id: ID
name: String
pageCount: Int
author: String
}
""")
@WithResource(name = "graphql/schema.graphqls", content = """
type Query {
greeting(name: String! = "Spring"): String!
bookById(id: ID): Book
books: BookConnection
}
type Subscription {
booksOnSale(minPages: Int) : Book!
}
""")
class GraphQlReactiveQueryByExampleAutoConfigurationTests {
private static final Mono<Book> bookPublisher = Mono.just(new Book("42", "Test title", 42, "Test Author"));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -24,6 +24,7 @@ import org.springframework.boot.autoconfigure.graphql.Book;
import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor;
@ -43,6 +44,25 @@ import static org.mockito.Mockito.mock;
*
* @author Brian Clozel
*/
@WithResource(name = "graphql/types/book.graphqls", content = """
type Book {
id: ID
name: String
pageCount: Int
author: String
}
""")
@WithResource(name = "graphql/schema.graphqls", content = """
type Query {
greeting(name: String! = "Spring"): String!
bookById(id: ID): Book
books: BookConnection
}
type Subscription {
booksOnSale(minPages: Int) : Book!
}
""")
class GraphQlReactiveQuerydslAutoConfigurationTests {
private static final Mono<Book> bookPublisher = Mono.just(new Book("42", "Test title", 42, "Test Author"));

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");
* you may not use this file except in compliance with the License.
@ -34,6 +34,7 @@ import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
@ -57,6 +58,25 @@ import static org.hamcrest.Matchers.containsString;
*
* @author Brian Clozel
*/
@WithResource(name = "graphql/types/book.graphqls", content = """
type Book {
id: ID
name: String
pageCount: Int
author: String
}
""")
@WithResource(name = "graphql/schema.graphqls", content = """
type Query {
greeting(name: String! = "Spring"): String!
bookById(id: ID): Book
books: BookConnection
}
type Subscription {
booksOnSale(minPages: Int) : Book!
}
""")
class GraphQlWebFluxAutoConfigurationTests {
private static final String BASE_URL = "https://spring.example.org/";

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -36,6 +36,7 @@ import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfigurat
import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration;
import org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer;
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.boot.web.embedded.netty.NettyRouteProvider;
@ -53,6 +54,25 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Brian Clozel
*/
@WithResource(name = "graphql/types/book.graphqls", content = """
type Book {
id: ID
name: String
pageCount: Int
author: String
}
""")
@WithResource(name = "graphql/schema.graphqls", content = """
type Query {
greeting(name: String! = "Spring"): String!
bookById(id: ID): Book
books: BookConnection
}
type Subscription {
booksOnSale(minPages: Int) : Book!
}
""")
class GraphQlRSocketAutoConfigurationTests {
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner()

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2024 the original author or authors.
* Copyright 2020-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.
@ -34,6 +34,7 @@ import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurity
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.execution.ErrorType;
@ -60,6 +61,25 @@ import static org.springframework.security.config.Customizer.withDefaults;
*
* @author Brian Clozel
*/
@WithResource(name = "graphql/types/book.graphqls", content = """
type Book {
id: ID
name: String
pageCount: Int
author: String
}
""")
@WithResource(name = "graphql/schema.graphqls", content = """
type Query {
greeting(name: String! = "Spring"): String!
bookById(id: ID): Book
books: BookConnection
}
type Subscription {
booksOnSale(minPages: Int) : Book!
}
""")
class GraphQlWebFluxSecurityAutoConfigurationTests {
private static final String BASE_URL = "https://spring.example.org/graphql";

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2020-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.
@ -31,6 +31,7 @@ import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfi
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.execution.ErrorType;
@ -60,6 +61,25 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
*
* @author Brian Clozel
*/
@WithResource(name = "graphql/types/book.graphqls", content = """
type Book {
id: ID
name: String
pageCount: Int
author: String
}
""")
@WithResource(name = "graphql/schema.graphqls", content = """
type Query {
greeting(name: String! = "Spring"): String!
bookById(id: ID): Book
books: BookConnection
}
type Subscription {
booksOnSale(minPages: Int) : Book!
}
""")
class GraphQlWebMvcSecurityAutoConfigurationTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()

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");
* you may not use this file except in compliance with the License.
@ -34,6 +34,7 @@ import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
@ -61,6 +62,25 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
*
* @author Brian Clozel
*/
@WithResource(name = "graphql/types/book.graphqls", content = """
type Book {
id: ID
name: String
pageCount: Int
author: String
}
""")
@WithResource(name = "graphql/schema.graphqls", content = """
type Query {
greeting(name: String! = "Spring"): String!
bookById(id: ID): Book
books: BookConnection
}
type Subscription {
booksOnSale(minPages: Int) : Book!
}
""")
class GraphQlWebMvcAutoConfigurationTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()

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");
* you may not use this file except in compliance with the License.
@ -31,6 +31,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.io.ClassPathResource;
@ -83,6 +84,7 @@ class GroovyTemplateAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/home.tpl", content = "yield 'home'")
void defaultViewResolution() throws Exception {
registerAndRefreshContext();
MockHttpServletResponse response = render("home");
@ -92,6 +94,11 @@ class GroovyTemplateAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/includes.tpl", content = """
yield 'include'
include template: 'included.tpl'
""")
@WithResource(name = "templates/included.tpl", content = "yield 'here'")
void includesViewResolution() throws Exception {
registerAndRefreshContext();
MockHttpServletResponse response = render("includes");
@ -108,6 +115,11 @@ class GroovyTemplateAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/includes.tpl", content = """
yield 'include'
include template: 'included.tpl'
""")
@WithResource(name = "templates/included_fr.tpl", content = "yield 'voila'")
void localeViewResolution() throws Exception {
registerAndRefreshContext();
MockHttpServletResponse response = render("includes", Locale.FRENCH);
@ -117,6 +129,7 @@ class GroovyTemplateAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/home.tpl", content = "yield 'home'")
void customContentType() throws Exception {
registerAndRefreshContext("spring.groovy.template.contentType:application/json");
MockHttpServletResponse response = render("home");
@ -126,6 +139,7 @@ class GroovyTemplateAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/prefix/prefixed.tpl", content = "yield \"prefixed\"")
void customPrefix() throws Exception {
registerAndRefreshContext("spring.groovy.template.prefix:prefix/");
MockHttpServletResponse response = render("prefixed");
@ -134,6 +148,7 @@ class GroovyTemplateAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/suffixed.groovytemplate", content = "yield \"suffixed\"")
void customSuffix() throws Exception {
registerAndRefreshContext("spring.groovy.template.suffix:.groovytemplate");
MockHttpServletResponse response = render("suffixed");
@ -142,6 +157,7 @@ class GroovyTemplateAutoConfigurationTests {
}
@Test
@WithResource(name = "custom-templates/custom.tpl", content = "yield \"custom\"")
void customTemplateLoaderPath() throws Exception {
registerAndRefreshContext("spring.groovy.template.resource-loader-path:classpath:/custom-templates/");
MockHttpServletResponse response = render("custom");
@ -156,6 +172,7 @@ class GroovyTemplateAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/message.tpl", content = "yield \"Message: ${greeting}\"")
void renderTemplate() throws Exception {
registerAndRefreshContext();
GroovyMarkupConfig config = this.context.getBean(GroovyMarkupConfig.class);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -25,6 +25,7 @@ import org.springframework.beans.factory.aot.AotServices;
import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider.GroovyTemplateAvailabilityProperties;
import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider.GroovyTemplateAvailabilityRuntimeHints;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.mock.env.MockEnvironment;
@ -45,6 +46,7 @@ class GroovyTemplateAvailabilityProviderTests {
private final MockEnvironment environment = new MockEnvironment();
@Test
@WithResource(name = "templates/home.tpl")
void availabilityOfTemplateInDefaultLocation() {
assertThat(this.provider.isTemplateAvailable("home", this.environment, getClass().getClassLoader(),
this.resourceLoader))
@ -59,6 +61,7 @@ class GroovyTemplateAvailabilityProviderTests {
}
@Test
@WithResource(name = "custom-templates/custom.tpl")
void availabilityOfTemplateWithCustomLoaderPath() {
this.environment.setProperty("spring.groovy.template.resource-loader-path", "classpath:/custom-templates/");
assertThat(this.provider.isTemplateAvailable("custom", this.environment, getClass().getClassLoader(),
@ -67,6 +70,7 @@ class GroovyTemplateAvailabilityProviderTests {
}
@Test
@WithResource(name = "custom-templates/custom.tpl")
void availabilityOfTemplateWithCustomLoaderPathConfiguredAsAList() {
this.environment.setProperty("spring.groovy.template.resource-loader-path[0]", "classpath:/custom-templates/");
assertThat(this.provider.isTemplateAvailable("custom", this.environment, getClass().getClassLoader(),
@ -75,6 +79,7 @@ class GroovyTemplateAvailabilityProviderTests {
}
@Test
@WithResource(name = "templates/prefix/prefixed.tpl")
void availabilityOfTemplateWithCustomPrefix() {
this.environment.setProperty("spring.groovy.template.prefix", "prefix/");
assertThat(this.provider.isTemplateAvailable("prefixed", this.environment, getClass().getClassLoader(),
@ -83,6 +88,7 @@ class GroovyTemplateAvailabilityProviderTests {
}
@Test
@WithResource(name = "templates/suffixed.groovytemplate")
void availabilityOfTemplateWithCustomSuffix() {
this.environment.setProperty("spring.groovy.template.suffix", ".groovytemplate");
assertThat(this.provider.isTemplateAvailable("suffixed", this.environment, getClass().getClassLoader(),

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -16,6 +16,10 @@
package org.springframework.boot.autoconfigure.hazelcast;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Map;
import com.hazelcast.config.Config;
@ -38,6 +42,7 @@ import org.springframework.boot.test.context.assertj.AssertableApplicationContex
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@ -57,6 +62,7 @@ class HazelcastAutoConfigurationServerTests {
.withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class));
@Test
@WithHazelcastXmlResource
void defaultConfigFile() {
// hazelcast.xml present in root classpath
this.contextRunner.run((context) -> {
@ -201,6 +207,7 @@ class HazelcastAutoConfigurationServerTests {
}
@Test
@WithHazelcastXmlResource
void autoConfiguredConfigUsesApplicationClassLoader() {
this.contextRunner.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
@ -209,6 +216,7 @@ class HazelcastAutoConfigurationServerTests {
}
@Test
@WithHazelcastXmlResource
void autoConfiguredConfigUsesSpringManagedContext() {
this.contextRunner.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
@ -217,6 +225,7 @@ class HazelcastAutoConfigurationServerTests {
}
@Test
@WithHazelcastXmlResource
void autoConfiguredConfigCanUseSpringAwareComponent() {
this.contextRunner.withPropertyValues("test.hazelcast.key=42").run((context) -> {
HazelcastInstance hz = context.getBean(HazelcastInstance.class);
@ -226,14 +235,19 @@ class HazelcastAutoConfigurationServerTests {
}
@Test
@WithHazelcastXmlResource
void autoConfiguredConfigWithoutHazelcastSpringDoesNotUseSpringManagedContext() {
this.contextRunner.withClassLoader(new FilteredClassLoader(SpringManagedContext.class)).run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getManagedContext()).isNull();
});
this.contextRunner
.withClassLoader(
new FilteredClassLoader(Thread.currentThread().getContextClassLoader(), SpringManagedContext.class))
.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
assertThat(config.getManagedContext()).isNull();
});
}
@Test
@WithHazelcastXmlResource
void autoConfiguredContextCanOverrideManagementContextUsingCustomizer() {
this.contextRunner.withBean(TestHazelcastConfigCustomizer.class).run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
@ -242,6 +256,7 @@ class HazelcastAutoConfigurationServerTests {
}
@Test
@WithHazelcastXmlResource
void autoConfiguredConfigSetsHazelcastLoggingToSlf4j() {
this.contextRunner.run((context) -> {
Config config = context.getBean(HazelcastInstance.class).getConfig();
@ -322,4 +337,24 @@ class HazelcastAutoConfigurationServerTests {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "hazelcast.xml", content = """
<hazelcast
xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-5.0.xsd"
xmlns="http://www.hazelcast.com/schema/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<instance-name>default-instance</instance-name>
<map name="defaultCache" />
<network>
<join>
<auto-detection enabled="false" />
<multicast enabled="false" />
</join>
</network>
</hazelcast>
""")
@interface WithHazelcastXmlResource {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -22,6 +22,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.core.io.ClassPathResource;
import static org.assertj.core.api.Assertions.assertThat;
@ -37,7 +38,39 @@ class HazelcastAutoConfigurationTests {
.withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class));
@Test
void defaultConfigFile() {
@WithResource(name = "hazelcast.xml", content = """
<hazelcast
xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-5.0.xsd"
xmlns="http://www.hazelcast.com/schema/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<instance-name>default-instance</instance-name>
<map name="defaultCache" />
<network>
<join>
<auto-detection enabled="false" />
<multicast enabled="false" />
</join>
</network>
</hazelcast>
""")
@WithResource(name = "hazelcast.yml", content = """
hazelcast:
network:
join:
auto-detection:
enabled: false
multicast:
enabled: false
""")
@WithResource(name = "hazelcast.yaml", content = """
hazelcast:
network:
join:
auto-detection:
enabled: false
multicast:
enabled: false
""")
void defaultConfigFileIsHazelcastXml() {
// no hazelcast-client.xml and hazelcast.xml is present in root classpath
// this also asserts that XML has priority over YAML
// as hazelcast.yaml, hazelcast.yml, and hazelcast.xml are available.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon
import org.springframework.boot.info.BuildProperties;
import org.springframework.boot.info.GitProperties;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -90,6 +91,13 @@ class ProjectInfoAutoConfigurationTests {
}
@Test
@WithResource(name = "META-INF/build-info.properties", content = """
build.group=com.example
build.artifact=demo
build.name=Demo Project
build.version=0.0.1-SNAPSHOT
build.time=2016-03-04T14:16:05.000Z
""")
void buildPropertiesDefaultLocation() {
this.contextRunner.run((context) -> {
BuildProperties buildProperties = context.getBean(BuildProperties.class);

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");
* you may not use this file except in compliance with the License.
@ -57,6 +57,7 @@ import org.springframework.boot.sql.init.DatabaseInitializationMode;
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.assertj.SimpleAsyncTaskExecutorAssert;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@ -378,6 +379,8 @@ class IntegrationAutoConfigurationTests {
}
@Test
@WithResource(name = "META-INF/spring.integration.properties",
content = "spring.integration.endpoints.noAutoStartup=testService*")
void integrationGlobalPropertiesFromSpringIntegrationPropertiesFile() {
this.contextRunner
.withPropertyValues("spring.integration.channel.auto-create=false",
@ -558,7 +561,7 @@ class IntegrationAutoConfigurationTests {
}
@MessagingGateway
interface TestGateway extends RequestReplyExchanger {
public interface TestGateway extends RequestReplyExchanger {
}

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");
* you may not use this file except in compliance with the License.
@ -37,6 +37,7 @@ import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.origin.Origin;
import org.springframework.boot.origin.OriginLookup;
import org.springframework.boot.origin.TextResourceOrigin;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
@ -60,6 +61,8 @@ import static org.mockito.Mockito.mock;
class IntegrationPropertiesEnvironmentPostProcessorTests {
@Test
@WithResource(name = "META-INF/spring.integration.properties",
content = "spring.integration.endpoints.noAutoStartup=testService*")
void postProcessEnvironmentAddPropertySource() {
ConfigurableEnvironment environment = new StandardEnvironment();
new IntegrationPropertiesEnvironmentPostProcessor().postProcessEnvironment(environment,
@ -69,6 +72,8 @@ class IntegrationPropertiesEnvironmentPostProcessorTests {
}
@Test
@WithResource(name = "META-INF/spring.integration.properties",
content = "spring.integration.endpoints.noAutoStartup=testService*")
void postProcessEnvironmentAddPropertySourceLast() {
ConfigurableEnvironment environment = new StandardEnvironment();
environment.getPropertySources()

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -24,6 +24,7 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration;
import org.springframework.boot.diagnostics.FailureAnalysis;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
@ -37,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class HikariDriverConfigurationFailureAnalyzerTests {
@Test
@WithResource(name = "schema.sql", content = "")
void failureAnalysisIsPerformed() {
FailureAnalysis failureAnalysis = performAnalysis(TestConfiguration.class);
assertThat(failureAnalysis).isNotNull();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -22,6 +22,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.simple.JdbcClient;
@ -68,6 +69,16 @@ class JdbcClientAutoConfigurationTests {
}
@Test
@WithResource(name = "db/city/V1__init.sql", content = """
CREATE SEQUENCE city_seq INCREMENT BY 50;
CREATE TABLE CITY (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
name VARCHAR(30),
state VARCHAR(30),
country VARCHAR(30),
map VARCHAR(30)
);
""")
void jdbcClientIsOrderedAfterFlywayMigration() {
this.contextRunner.withUserConfiguration(JdbcClientDataSourceMigrationValidator.class)
.withPropertyValues("spring.flyway.locations:classpath:db/city")
@ -79,6 +90,31 @@ class JdbcClientAutoConfigurationTests {
}
@Test
@WithResource(name = "db/changelog/db.changelog-city.yaml", content = """
databaseChangeLog:
- changeSet:
id: 1
author: dsyer
changes:
- createSequence:
sequenceName: city_seq
incrementBy: 50
- createTable:
tableName: city
columns:
- column:
name: id
type: bigint
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: name
type: varchar(50)
constraints:
nullable: false
""")
void jdbcClientIsOrderedAfterLiquibaseMigration() {
this.contextRunner.withUserConfiguration(JdbcClientDataSourceMigrationValidator.class)
.withPropertyValues("spring.liquibase.change-log:classpath:db/changelog/db.changelog-city.yaml")

View File

@ -16,6 +16,10 @@
package org.springframework.boot.autoconfigure.jdbc;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Collections;
import javax.sql.DataSource;
@ -27,6 +31,7 @@ import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@ -151,6 +156,13 @@ class JdbcTemplateAutoConfigurationTests {
}
@Test
@WithResource(name = "schema.sql", content = """
CREATE TABLE BAR (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(30)
);
""")
@WithResource(name = "data.sql", content = "INSERT INTO BAR VALUES (1, 'Andy');")
void testDependencyToScriptBasedDataSourceInitialization() {
this.contextRunner.withConfiguration(AutoConfigurations.of(SqlInitializationAutoConfiguration.class))
.withUserConfiguration(DataSourceInitializationValidator.class)
@ -161,6 +173,16 @@ class JdbcTemplateAutoConfigurationTests {
}
@Test
@WithResource(name = "db/city/V1__init.sql", content = """
CREATE SEQUENCE city_seq INCREMENT BY 50;
CREATE TABLE CITY (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
name VARCHAR(30),
state VARCHAR(30),
country VARCHAR(30),
map VARCHAR(30)
);
""")
void testDependencyToFlyway() {
this.contextRunner.withUserConfiguration(DataSourceMigrationValidator.class)
.withPropertyValues("spring.flyway.locations:classpath:db/city")
@ -172,6 +194,16 @@ class JdbcTemplateAutoConfigurationTests {
}
@Test
@WithResource(name = "db/city/V1__init.sql", content = """
CREATE SEQUENCE city_seq INCREMENT BY 50;
CREATE TABLE CITY (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
name VARCHAR(30),
state VARCHAR(30),
country VARCHAR(30),
map VARCHAR(30)
);
""")
void testDependencyToFlywayWithJdbcTemplateMixed() {
this.contextRunner.withUserConfiguration(NamedParameterDataSourceMigrationValidator.class)
.withPropertyValues("spring.flyway.locations:classpath:db/city")
@ -184,6 +216,7 @@ class JdbcTemplateAutoConfigurationTests {
}
@Test
@WithDbChangelogCityYamlResource
void testDependencyToLiquibase() {
this.contextRunner.withUserConfiguration(DataSourceMigrationValidator.class)
.withPropertyValues("spring.liquibase.change-log:classpath:db/changelog/db.changelog-city.yaml")
@ -195,6 +228,7 @@ class JdbcTemplateAutoConfigurationTests {
}
@Test
@WithDbChangelogCityYamlResource
void testDependencyToLiquibaseWithJdbcTemplateMixed() {
this.contextRunner.withUserConfiguration(NamedParameterDataSourceMigrationValidator.class)
.withPropertyValues("spring.liquibase.change-log:classpath:db/changelog/db.changelog-city.yaml")
@ -318,4 +352,35 @@ class JdbcTemplateAutoConfigurationTests {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "db/changelog/db.changelog-city.yaml", content = """
databaseChangeLog:
- changeSet:
id: 1
author: dsyer
changes:
- createSequence:
sequenceName: city_seq
incrementBy: 50
- createTable:
tableName: city
columns:
- column:
name: id
type: bigint
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: name
type: varchar(50)
constraints:
nullable: false
""")
@interface WithDbChangelogCityYamlResource {
}
}

View File

@ -56,6 +56,7 @@ import org.springframework.boot.test.context.assertj.AssertableApplicationContex
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.testsupport.assertj.SimpleAsyncTaskExecutorAssert;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
@ -121,6 +122,8 @@ class KafkaAutoConfigurationTests {
.withConfiguration(AutoConfigurations.of(KafkaAutoConfiguration.class, SslAutoConfiguration.class));
@Test
@WithResource(name = "ksLoc")
@WithResource(name = "tsLoc")
void consumerProperties() {
this.contextRunner.withPropertyValues("spring.kafka.bootstrap-servers=foo:1234",
"spring.kafka.properties.foo=bar", "spring.kafka.properties.baz=qux",
@ -225,6 +228,8 @@ class KafkaAutoConfigurationTests {
}
@Test
@WithResource(name = "ksLocP")
@WithResource(name = "tsLocP")
void producerProperties() {
this.contextRunner.withPropertyValues("spring.kafka.clientId=cid",
"spring.kafka.properties.foo.bar.baz=qux.fiz.buz", "spring.kafka.producer.acks=all",
@ -318,6 +323,8 @@ class KafkaAutoConfigurationTests {
}
@Test
@WithResource(name = "ksLocP")
@WithResource(name = "tsLocP")
void adminProperties() {
this.contextRunner
.withPropertyValues("spring.kafka.clientId=cid", "spring.kafka.properties.foo.bar.baz=qux.fiz.buz",
@ -400,8 +407,10 @@ class KafkaAutoConfigurationTests {
});
}
@SuppressWarnings("unchecked")
@Test
@SuppressWarnings("unchecked")
@WithResource(name = "ksLocP")
@WithResource(name = "tsLocP")
void streamsProperties() {
this.contextRunner.withUserConfiguration(EnableKafkaStreamsConfiguration.class)
.withPropertyValues("spring.kafka.client-id=cid",

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -16,6 +16,11 @@
package org.springframework.boot.autoconfigure.ldap.embedded;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.sdk.BindResult;
import com.unboundid.ldap.sdk.DN;
@ -30,6 +35,7 @@ import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -100,6 +106,7 @@ class EmbeddedLdapAutoConfigurationTests {
}
@Test
@WithSchemaLdifResource
void testSetLdifFile() {
this.contextRunner.withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org").run((context) -> {
InMemoryDirectoryServer server = context.getBean(InMemoryDirectoryServer.class);
@ -108,6 +115,7 @@ class EmbeddedLdapAutoConfigurationTests {
}
@Test
@WithSchemaLdifResource
void testQueryEmbeddedLdap() {
this.contextRunner.withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org")
.withConfiguration(AutoConfigurations.of(LdapAutoConfiguration.class))
@ -130,6 +138,34 @@ class EmbeddedLdapAutoConfigurationTests {
}
@Test
@WithResource(name = "custom-schema.ldif", content = """
dn: cn=schema
attributeTypes: ( 1.3.6.1.4.1.32473.1.1.1
NAME 'exampleAttributeName'
DESC 'An example attribute type definition'
EQUALITY caseIgnoreMatch
ORDERING caseIgnoreOrderingMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE
X-ORIGIN 'Managing Schema Document' )
objectClasses: ( 1.3.6.1.4.1.32473.1.2.2
NAME 'exampleAuxiliaryClass'
DESC 'An example auxiliary object class definition'
SUP top
AUXILIARY
MAY exampleAttributeName
X-ORIGIN 'Managing Schema Document' )
""")
@WithResource(name = "custom-schema-sample.ldif", content = """
dn: dc=spring,dc=org
objectclass: top
objectclass: domain
objectclass: extensibleObject
objectClass: exampleAuxiliaryClass
dc: spring
exampleAttributeName: exampleAttributeName
""")
void testCustomSchemaValidation() {
this.contextRunner
.withPropertyValues("spring.ldap.embedded.validation.schema:classpath:custom-schema.ldif",
@ -144,6 +180,122 @@ class EmbeddedLdapAutoConfigurationTests {
}
@Test
@WithResource(name = "schema-multi-basedn.ldif", content = """
dn: dc=spring,dc=org
objectclass: top
objectclass: domain
objectclass: extensibleObject
dc: spring
dn: ou=groups,dc=spring,dc=org
objectclass: top
objectclass: organizationalUnit
ou: groups
dn: cn=ROLE_USER,ou=groups,dc=spring,dc=org
objectclass: top
objectclass: groupOfUniqueNames
cn: ROLE_USER
uniqueMember: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org
uniqueMember: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org
uniqueMember: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org
uniqueMember: cn=Some Person3,ou=company1,c=Sweden,dc=spring,dc=org
dn: cn=ROLE_ADMIN,ou=groups,dc=spring,dc=org
objectclass: top
objectclass: groupOfUniqueNames
cn: ROLE_ADMIN
uniqueMember: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org
dn: c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: country
c: Sweden
description: The country of Sweden
dn: ou=company1,c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: organizationalUnit
ou: company1
description: First company in Sweden
dn: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: some.person
userPassword: password
cn: Some Person
sn: Person
description: Sweden, Company1, Some Person
telephoneNumber: +46 555-123456
dn: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: some.person2
userPassword: password
cn: Some Person2
sn: Person2
description: Sweden, Company1, Some Person2
telephoneNumber: +46 555-654321
dn: cn=Some Person3,ou=company1,c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: some.person3
userPassword: password
cn: Some Person3
sn: Person3
description: Sweden, Company1, Some Person3
telephoneNumber: +46 555-123654
dn: cn=Some Person4,ou=company1,c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: some.person4
userPassword: password
cn: Some Person
sn: Person
description: Sweden, Company1, Some Person
telephoneNumber: +46 555-456321
dn: dc=vmware,dc=com
objectclass: top
objectclass: domain
objectclass: extensibleObject
dc: vmware
dn: ou=groups,dc=vmware,dc=com
objectclass: top
objectclass: organizationalUnit
ou: groups
dn: c=Sweden,dc=vmware,dc=com
objectclass: top
objectclass: country
c: Sweden
description:The country of Sweden
dn: cn=Some Random Person,c=Sweden,dc=vmware,dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: some.random.person
userPassword: password
cn: Some Random Person
sn: Person
description: Sweden, VMware, Some Random Person
telephoneNumber: +46 555-123456
""")
void testMultiBaseDn() {
this.contextRunner.withPropertyValues("spring.ldap.embedded.ldif:classpath:schema-multi-basedn.ldif",
"spring.ldap.embedded.base-dn[0]:dc=spring,dc=org", "spring.ldap.embedded.base-dn[1]:dc=vmware,dc=com")
@ -206,4 +358,97 @@ class EmbeddedLdapAutoConfigurationTests {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "schema.ldif", content = """
dn: dc=spring,dc=org
objectclass: top
objectclass: domain
objectclass: extensibleObject
dc: spring
dn: ou=groups,dc=spring,dc=org
objectclass: top
objectclass: organizationalUnit
ou: groups
dn: cn=ROLE_USER,ou=groups,dc=spring,dc=org
objectclass: top
objectclass: groupOfUniqueNames
cn: ROLE_USER
uniqueMember: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org
uniqueMember: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org
uniqueMember: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org
uniqueMember: cn=Some Person3,ou=company1,c=Sweden,dc=spring,dc=org
dn: cn=ROLE_ADMIN,ou=groups,dc=spring,dc=org
objectclass: top
objectclass: groupOfUniqueNames
cn: ROLE_ADMIN
uniqueMember: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org
dn: c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: country
c: Sweden
description: The country of Sweden
dn: ou=company1,c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: organizationalUnit
ou: company1
description: First company in Sweden
dn: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: some.person
userPassword: password
cn: Some Person
sn: Person
description: Sweden, Company1, Some Person
telephoneNumber: +46 555-123456
dn: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: some.person2
userPassword: password
cn: Some Person2
sn: Person2
description: Sweden, Company1, Some Person2
telephoneNumber: +46 555-654321
dn: cn=Some Person3,ou=company1,c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: some.person3
userPassword: password
cn: Some Person3
sn: Person3
description: Sweden, Company1, Some Person3
telephoneNumber: +46 555-123654
dn: cn=Some Person4,ou=company1,c=Sweden,dc=spring,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: some.person4
userPassword: password
cn: Some Person
sn: Person
description: Sweden, Company1, Some Person
telephoneNumber: +46 555-456321
""")
@interface WithSchemaLdifResource {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -27,6 +27,7 @@ import org.springframework.boot.test.context.assertj.AssertableApplicationContex
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.testsupport.classpath.ClassPathOverrides;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import static org.assertj.core.api.Assertions.assertThat;
@ -43,6 +44,7 @@ class Liquibase423AutoConfigurationTests {
.withPropertyValues("spring.datasource.generate-unique-name=true");
@Test
@WithResource(name = "db/changelog/db.changelog-master.yaml", content = "databaseChangeLog:")
void defaultSpringLiquibase() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.run(assertLiquibase((liquibase) -> {

View File

@ -18,6 +18,10 @@ package org.springframework.boot.autoconfigure.liquibase;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Connection;
@ -58,6 +62,7 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@ -100,6 +105,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void createsDataSourceWithNoDataSourceBeanAndLiquibaseUrl() {
String jdbcUrl = "jdbc:hsqldb:mem:liquibase" + UUID.randomUUID();
this.contextRunner.withPropertyValues("spring.liquibase.url:" + jdbcUrl).run(assertLiquibase((liquibase) -> {
@ -116,6 +122,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void defaultSpringLiquibase() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.run(assertLiquibase((liquibase) -> {
@ -138,6 +145,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void liquibaseDataSourceIsUsedOverJdbcConnectionDetails() {
this.contextRunner
.withUserConfiguration(LiquibaseDataSourceConfiguration.class, JdbcConnectionDetailsConfiguration.class)
@ -150,6 +158,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void liquibaseDataSourceIsUsedOverLiquibaseConnectionDetails() {
this.contextRunner
.withUserConfiguration(LiquibaseDataSourceConfiguration.class,
@ -163,6 +172,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void liquibasePropertiesAreUsedOverJdbcConnectionDetails() {
this.contextRunner
.withPropertyValues("spring.liquibase.url=jdbc:hsqldb:mem:liquibasetest", "spring.liquibase.user=some-user",
@ -193,6 +203,18 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithResource(name = "db/changelog/db.changelog-override.xml",
content = """
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
</databaseChangeLog>
""")
void changelogXml() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.change-log:classpath:/db/changelog/db.changelog-override.xml")
@ -201,6 +223,11 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithResource(name = "db/changelog/db.changelog-override.json", content = """
{
"databaseChangeLog": []
}
""")
void changelogJson() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.change-log:classpath:/db/changelog/db.changelog-override.json")
@ -209,6 +236,16 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithResource(name = "db/changelog/db.changelog-override.sql", content = """
--liquibase formatted sql
--changeset author:awilkinson
CREATE TABLE customer (
id int AUTO_INCREMENT NOT NULL PRIMARY KEY,
name varchar(50) NOT NULL
);
""")
void changelogSql() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.change-log:classpath:/db/changelog/db.changelog-override.sql")
@ -217,6 +254,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void defaultValues() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.run(assertLiquibase((liquibase) -> {
@ -235,6 +273,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideContexts() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.contexts:test, production")
@ -242,6 +281,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideDefaultSchema() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.default-schema:public")
@ -249,6 +289,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideLiquibaseInfrastructure() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.liquibase-schema:public",
@ -269,6 +310,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideDropFirst() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.drop-first:true")
@ -276,6 +318,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideClearChecksums() {
String jdbcUrl = "jdbc:hsqldb:mem:liquibase" + UUID.randomUUID();
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@ -287,6 +330,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideDataSource() {
String jdbcUrl = "jdbc:hsqldb:mem:liquibase" + UUID.randomUUID();
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@ -299,6 +343,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideDataSourceAndDriverClassName() {
String jdbcUrl = "jdbc:hsqldb:mem:liquibase" + UUID.randomUUID();
String driverClassName = "org.hsqldb.jdbcDriver";
@ -313,6 +358,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideUser() {
String databaseName = "normal" + UUID.randomUUID();
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@ -327,6 +373,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideUserWhenCustom() {
this.contextRunner.withUserConfiguration(CustomDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.user:test", "spring.liquibase.password:secret")
@ -340,6 +387,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void createDataSourceDoesNotFallbackToEmbeddedProperties() {
String jdbcUrl = "jdbc:hsqldb:mem:liquibase" + UUID.randomUUID();
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@ -352,6 +400,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideUserAndFallbackToEmbeddedProperties() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.user:sa")
@ -362,6 +411,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideTestRollbackOnUpdate() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.test-rollback-on-update:true")
@ -382,12 +432,14 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void logging(CapturedOutput output) {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.run(assertLiquibase((liquibase) -> assertThat(output).doesNotContain(": liquibase:")));
}
@Test
@WithDbChangelogMasterYamlResource
void overrideLabelFilter() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.label-filter:test, production")
@ -395,6 +447,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideShowSummary() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.show-summary=off")
@ -406,6 +459,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideShowSummaryOutput() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.show-summary-output=all")
@ -417,6 +471,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideUiService() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.ui-service=console")
@ -425,6 +480,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
@SuppressWarnings("unchecked")
void testOverrideParameters() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@ -438,6 +494,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void rollbackFile(@TempDir Path temp) throws IOException {
File file = Files.createTempFile(temp, "rollback-file", "sql").toFile();
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@ -451,6 +508,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void liquibaseDataSource() {
this.contextRunner
.withUserConfiguration(LiquibaseDataSourceConfiguration.class, EmbeddedDataSourceConfiguration.class)
@ -461,6 +519,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void liquibaseDataSourceWithoutDataSourceAutoConfiguration() {
this.contextRunner.withUserConfiguration(LiquibaseDataSourceConfiguration.class).run((context) -> {
SpringLiquibase liquibase = context.getBean(SpringLiquibase.class);
@ -469,6 +528,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void userConfigurationBeans() {
this.contextRunner
.withUserConfiguration(LiquibaseUserConfiguration.class, EmbeddedDataSourceConfiguration.class)
@ -479,6 +539,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void userConfigurationEntityManagerFactoryDependency() {
this.contextRunner.withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class))
.withUserConfiguration(LiquibaseUserConfiguration.class, EmbeddedDataSourceConfiguration.class)
@ -489,6 +550,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void userConfigurationJdbcTemplateDependency() {
this.contextRunner.withConfiguration(AutoConfigurations.of(JdbcTemplateAutoConfiguration.class))
.withUserConfiguration(LiquibaseUserConfiguration.class, EmbeddedDataSourceConfiguration.class)
@ -499,6 +561,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void overrideTag() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.tag:1.0.0")
@ -506,6 +569,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void whenLiquibaseIsAutoConfiguredThenJooqDslContextDependsOnSpringLiquibaseBeans() {
this.contextRunner.withConfiguration(AutoConfigurations.of(JooqAutoConfiguration.class))
.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@ -516,6 +580,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void whenCustomSpringLiquibaseIsDefinedThenJooqDslContextDependsOnSpringLiquibaseBeans() {
this.contextRunner.withConfiguration(AutoConfigurations.of(JooqAutoConfiguration.class))
.withUserConfiguration(LiquibaseUserConfiguration.class, EmbeddedDataSourceConfiguration.class)
@ -536,12 +601,14 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void whenCustomizerBeanIsDefinedThenItIsConfiguredOnSpringLiquibase() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, CustomizerConfiguration.class)
.run(assertLiquibase((liquibase) -> assertThat(liquibase.getCustomizer()).isNotNull()));
}
@Test
@WithDbChangelogMasterYamlResource
void whenAnalyticsEnabledIsFalseThenSpringLiquibaseHasAnalyticsDisabled() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.analytics-enabled=false")
@ -551,6 +618,7 @@ class LiquibaseAutoConfigurationTests {
}
@Test
@WithDbChangelogMasterYamlResource
void whenLicenseKeyIsSetThenSpringLiquibaseHasLicenseKey() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.license-key=a1b2c3d4")
@ -709,4 +777,32 @@ class LiquibaseAutoConfigurationTests {
}
@WithResource(name = "db/changelog/db.changelog-master.yaml", content = """
databaseChangeLog:
- changeSet:
id: 1
author: marceloverdijk
changes:
- createTable:
tableName: customer
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: name
type: varchar(50)
constraints:
nullable: false
""")
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface WithDbChangelogMasterYamlResource {
}
}

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");
* you may not use this file except in compliance with the License.
@ -32,6 +32,7 @@ import org.springframework.boot.autoconfigure.jndi.JndiPropertiesHidingClassLoad
import org.springframework.boot.autoconfigure.jndi.TestableInitialContextFactory;
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.MailSender;
@ -64,7 +65,8 @@ class MailSenderAutoConfigurationTests {
this.initialContextFactory = System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, TestableInitialContextFactory.class.getName());
this.threadContextClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(new JndiPropertiesHidingClassLoader(getClass().getClassLoader()));
Thread.currentThread()
.setContextClassLoader(new JndiPropertiesHidingClassLoader(Thread.currentThread().getContextClassLoader()));
}
@AfterEach
@ -254,6 +256,7 @@ class MailSenderAutoConfigurationTests {
}
@Test
@WithPackageResources("test.jks")
void smtpSslBundle() {
this.contextRunner
.withPropertyValues("spring.mail.host:localhost", "spring.mail.ssl.bundle:test-bundle",
@ -282,6 +285,7 @@ class MailSenderAutoConfigurationTests {
}
@Test
@WithPackageResources("test.jks")
void smtpsSslBundle() {
this.contextRunner
.withPropertyValues("spring.mail.host:localhost", "spring.mail.protocol:smtps",

View File

@ -32,6 +32,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -86,6 +87,7 @@ class MongoAutoConfigurationTests {
}
@Test
@WithPackageResources("test.jks")
void configuresSslWithBundle() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.ssl.bundle=test-bundle",

View File

@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -93,6 +94,7 @@ class MongoReactiveAutoConfigurationTests {
}
@Test
@WithPackageResources("test.jks")
void configuresSslWithBundle() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.ssl.bundle=test-bundle",

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -105,9 +105,10 @@ class MustacheAutoConfigurationReactiveIntegrationTests {
@Bean
MustacheViewResolver viewResolver() {
Mustache.Compiler compiler = Mustache.compiler()
.withLoader(new MustacheResourceTemplateLoader("classpath:/mustache-templates/", ".html"));
.withLoader(new MustacheResourceTemplateLoader(
"classpath:/org/springframework/boot/autoconfigure/mustache/", ".html"));
MustacheViewResolver resolver = new MustacheViewResolver(compiler);
resolver.setPrefix("classpath:/mustache-templates/");
resolver.setPrefix("classpath:/org/springframework/boot/autoconfigure/mustache/");
resolver.setSuffix(".html");
return resolver;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -115,9 +115,10 @@ class MustacheAutoConfigurationServletIntegrationTests {
@Bean
MustacheViewResolver viewResolver() {
Mustache.Compiler compiler = Mustache.compiler()
.withLoader(new MustacheResourceTemplateLoader("classpath:/mustache-templates/", ".html"));
.withLoader(new MustacheResourceTemplateLoader(
"classpath:/org/springframework/boot/autoconfigure/mustache/", ".html"));
MustacheViewResolver resolver = new MustacheViewResolver(compiler);
resolver.setPrefix("classpath:/mustache-templates/");
resolver.setPrefix("classpath:/org/springframework/boot/autoconfigure/mustache/");
resolver.setSuffix(".html");
return resolver;
}

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");
* you may not use this file except in compliance with the License.
@ -17,6 +17,10 @@
package org.springframework.boot.autoconfigure.orm.jpa;
import java.io.File;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@ -47,6 +51,7 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -209,6 +214,7 @@ abstract class AbstractJpaAutoConfigurationTests {
}
@Test
@WithMetaInfPersistenceXmlResource
void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanUsingBuilder() {
this.contextRunner.withPropertyValues("spring.jpa.properties.a=b")
.withUserConfiguration(TestConfigurationWithEntityManagerFactoryBuilder.class)
@ -221,6 +227,7 @@ abstract class AbstractJpaAutoConfigurationTests {
}
@Test
@WithMetaInfPersistenceXmlResource
void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanIfAvailable() {
this.contextRunner.withUserConfiguration(TestConfigurationWithLocalContainerEntityManagerFactoryBean.class)
.run((context) -> {
@ -232,6 +239,7 @@ abstract class AbstractJpaAutoConfigurationTests {
}
@Test
@WithMetaInfPersistenceXmlResource
void usesManuallyDefinedEntityManagerFactoryIfAvailable() {
this.contextRunner.withUserConfiguration(TestConfigurationWithLocalContainerEntityManagerFactoryBean.class)
.run((context) -> {
@ -501,4 +509,20 @@ abstract class AbstractJpaAutoConfigurationTests {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "META-INF/persistence.xml",
content = """
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="manually-configured">
<class>org.springframework.boot.autoconfigure.orm.jpa.test.City</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>
""")
@interface WithMetaInfPersistenceXmlResource {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -23,6 +23,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
@ -41,6 +42,20 @@ class Hibernate2ndLevelCacheIntegrationTests {
.withUserConfiguration(TestConfiguration.class);
@Test
@WithResource(name = "hazelcast.xml", content = """
<hazelcast
xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-5.0.xsd"
xmlns="http://www.hazelcast.com/schema/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<instance-name>default-instance</instance-name>
<map name="defaultCache" />
<network>
<join>
<auto-detection enabled="false" />
<multicast enabled="false" />
</join>
</network>
</hazelcast>
""")
void hibernate2ndLevelCacheWithJCacheAndHazelcast() {
String cachingProviderFqn = HazelcastServerCachingProvider.class.getName();
String configLocation = "classpath:hazelcast.xml";

View File

@ -72,6 +72,7 @@ import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform;
import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
@ -131,6 +132,8 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
}
@Test
@WithResource(name = "city.sql",
content = "INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google')")
void testDmlScriptRunsEarly() {
contextRunner().withUserConfiguration(TestInitializedJpaConfiguration.class)
.withClassLoader(new HideDataScriptClassLoader())
@ -141,6 +144,16 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
}
@Test
@WithResource(name = "db/city/V1__init.sql", content = """
CREATE SEQUENCE city_seq INCREMENT BY 50;
CREATE TABLE CITY (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
name VARCHAR(30),
state VARCHAR(30),
country VARCHAR(30),
map VARCHAR(30)
);
""")
void testFlywaySwitchOffDdlAuto() {
contextRunner().withPropertyValues("spring.sql.init.mode:never", "spring.flyway.locations:classpath:db/city")
.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class))
@ -148,6 +161,17 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
}
@Test
@WithResource(name = "db/city/V1__init.sql", content = """
CREATE SEQUENCE city_seq INCREMENT BY 50;
CREATE TABLE CITY (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
name VARCHAR(30),
state VARCHAR(30),
country VARCHAR(30),
map VARCHAR(30)
);
""")
void testFlywayPlusValidation() {
contextRunner()
.withPropertyValues("spring.sql.init.mode:never", "spring.flyway.locations:classpath:db/city",
@ -157,6 +181,46 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
}
@Test
@WithResource(name = "db/changelog/db.changelog-city.yaml", content = """
databaseChangeLog:
- changeSet:
id: 1
author: dsyer
changes:
- createSequence:
sequenceName: city_seq
incrementBy: 50
- createTable:
tableName: city
columns:
- column:
name: id
type: bigint
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: name
type: varchar(50)
constraints:
nullable: false
- column:
name: state
type: varchar(50)
constraints:
nullable: false
- column:
name: country
type: varchar(50)
constraints:
nullable: false
- column:
name: map
type: varchar(50)
constraints:
nullable: true
""")
void testLiquibasePlusValidation() {
contextRunner()
.withPropertyValues("spring.liquibase.change-log:classpath:db/changelog/db.changelog-city.yaml",
@ -316,9 +380,32 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
}
@Test
@WithResource(name = "META-INF/mappings/non-annotated.xml",
content = """
<?xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm https://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/orm_2_1.xsd"
version="2.1">
<entity class="org.springframework.boot.autoconfigure.orm.jpa.mapping.NonAnnotatedEntity">
<table name="NON_ANNOTATED"/>
<attributes>
<id name="id">
<column name="id"/>
<generated-value strategy="IDENTITY"/>
</id>
<basic name="item">
<column name="item"/>
</basic>
</attributes>
</entity>
</entity-mappings>
""")
@WithResource(name = "non-annotated-data.sql",
content = "INSERT INTO NON_ANNOTATED (id, item) values (2000, 'Test');")
void customResourceMapping() {
contextRunner().withClassLoader(new HideDataScriptClassLoader())
.withPropertyValues("spring.sql.init.data-locations:classpath:/db/non-annotated-data.sql",
.withPropertyValues("spring.sql.init.data-locations:classpath:non-annotated-data.sql",
"spring.jpa.mapping-resources=META-INF/mappings/non-annotated.xml",
"spring.jpa.defer-datasource-initialization=true")
.run((context) -> {
@ -388,6 +475,8 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
}
@Test
@WithResource(name = "city.sql",
content = "INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google')")
void eventListenerCanBeRegisteredAsBeans() {
contextRunner().withUserConfiguration(TestInitializedJpaConfiguration.class)
.withClassLoader(new HideDataScriptClassLoader())
@ -498,6 +587,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
}
@Test
@WithMetaInfPersistenceXmlResource
void whenLocalContainerEntityManagerFactoryBeanHasNoJpaVendorAdapterAutoConfigurationSucceeds() {
contextRunner()
.withUserConfiguration(
@ -718,7 +808,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
private static final List<String> HIDDEN_RESOURCES = Arrays.asList("schema-all.sql", "schema.sql");
HideDataScriptClassLoader() {
super(new URL[0], HideDataScriptClassLoader.class.getClassLoader());
super(new URL[0], Thread.currentThread().getContextClassLoader());
}
@Override

View File

@ -44,6 +44,8 @@ import org.springframework.boot.r2dbc.EmbeddedDatabaseConnection;
import org.springframework.boot.r2dbc.OptionsCapableConnectionFactory;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.ForkedClassPath;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.r2dbc.core.DatabaseClient;
@ -241,6 +243,9 @@ class R2dbcAutoConfigurationTests {
}
@Test
@WithResource(name = "META-INF/services/io.r2dbc.spi.ConnectionFactoryProvider",
content = "org.springframework.boot.autoconfigure.r2dbc.SimpleConnectionFactoryProvider")
@ForkedClassPath
void configureWithPoolShouldApplyAdditionalProperties() {
this.contextRunner
.withPropertyValues("spring.r2dbc.url:r2dbc:simple://foo", "spring.r2dbc.properties.test=value",

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -29,6 +29,7 @@ import org.springframework.boot.ssl.NoSuchSslBundleException;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -126,30 +127,32 @@ class RSocketServerAutoConfigurationTests {
}
@Test
@WithPackageResources("test.jks")
void shouldUseSslWhenRocketServerSslIsConfigured() {
reactiveWebContextRunner()
.withPropertyValues("spring.rsocket.server.ssl.keyStore=classpath:rsocket/test.jks",
.withPropertyValues("spring.rsocket.server.ssl.keyStore=classpath:test.jks",
"spring.rsocket.server.ssl.keyPassword=password", "spring.rsocket.server.port=0")
.run((context) -> assertThat(context).hasSingleBean(RSocketServerFactory.class)
.hasSingleBean(RSocketServerBootstrap.class)
.hasSingleBean(RSocketServerCustomizer.class)
.getBean(RSocketServerFactory.class)
.hasFieldOrPropertyWithValue("ssl.keyStore", "classpath:rsocket/test.jks")
.hasFieldOrPropertyWithValue("ssl.keyStore", "classpath:test.jks")
.hasFieldOrPropertyWithValue("ssl.keyPassword", "password"));
}
@Test
@Disabled
@WithPackageResources("test.jks")
void shouldUseSslWhenRocketServerSslIsConfiguredWithSslBundle() {
reactiveWebContextRunner()
.withPropertyValues("spring.rsocket.server.port=0", "spring.rsocket.server.ssl.bundle=test-bundle",
"spring.ssl.bundle.jks.test-bundle.keystore.location=classpath:rsocket/test.jks",
"spring.ssl.bundle.jks.test-bundle.keystore.location=classpath:test.jks",
"spring.ssl.bundle.jks.test-bundle.key.password=password")
.run((context) -> assertThat(context).hasSingleBean(RSocketServerFactory.class)
.hasSingleBean(RSocketServerBootstrap.class)
.hasSingleBean(RSocketServerCustomizer.class)
.getBean(RSocketServerFactory.class)
.hasFieldOrPropertyWithValue("sslBundle.details.keyStore", "classpath:rsocket/test.jks")
.hasFieldOrPropertyWithValue("sslBundle.details.keyStore", "classpath:test.jks")
.hasFieldOrPropertyWithValue("sslBundle.details.keyPassword", "password"));
}

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");
* you may not use this file except in compliance with the License.
@ -17,6 +17,10 @@
package org.springframework.boot.autoconfigure.security.oauth2.resource.reactive;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.net.URI;
import java.net.URL;
import java.time.Duration;
@ -49,6 +53,7 @@ import org.springframework.boot.autoconfigure.security.oauth2.resource.JwtConver
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
@ -173,6 +178,7 @@ class ReactiveOAuth2ResourceServerAutoConfigurationTests {
}
@Test
@WithPublicKeyResource
void autoConfigurationUsingPublicKeyValueShouldConfigureResourceServerUsingSingleJwsAlgorithm() {
this.contextRunner
.withPropertyValues(
@ -186,6 +192,7 @@ class ReactiveOAuth2ResourceServerAutoConfigurationTests {
}
@Test
@WithPublicKeyResource
void autoConfigurationUsingPublicKeyValueWithMultipleJwsAlgorithmsShouldFail() {
this.contextRunner
.withPropertyValues(
@ -284,6 +291,7 @@ class ReactiveOAuth2ResourceServerAutoConfigurationTests {
}
@Test
@WithPublicKeyResource
void autoConfigurationShouldConfigureResourceServerUsingPublicKeyValue() {
this.contextRunner
.withPropertyValues(
@ -539,6 +547,7 @@ class ReactiveOAuth2ResourceServerAutoConfigurationTests {
}
@Test
@WithPublicKeyResource
void autoConfigurationShouldConfigureAudienceValidatorIfPropertyProvidedAndPublicKey() throws Exception {
this.server = new MockWebServer();
this.server.start();
@ -891,4 +900,18 @@ class ReactiveOAuth2ResourceServerAutoConfigurationTests {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "public-key-location", content = """
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd
UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs
HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D
o2kQ+X5xK9cipRgEKwIDAQAB
-----END PUBLIC KEY-----
""")
@interface WithPublicKeyResource {
}
}

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");
* you may not use this file except in compliance with the License.
@ -16,6 +16,10 @@
package org.springframework.boot.autoconfigure.security.oauth2.resource.servlet;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.net.URI;
import java.net.URL;
import java.time.Instant;
@ -48,6 +52,7 @@ import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguratio
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
@ -174,6 +179,7 @@ class OAuth2ResourceServerAutoConfigurationTests {
}
@Test
@WithPublicKeyResource
void autoConfigurationUsingPublicKeyValueShouldConfigureResourceServerUsingSingleJwsAlgorithm() {
this.contextRunner
.withPropertyValues(
@ -187,6 +193,7 @@ class OAuth2ResourceServerAutoConfigurationTests {
}
@Test
@WithPublicKeyResource
void autoConfigurationUsingPublicKeyValueWithMultipleJwsAlgorithmsShouldFail() {
this.contextRunner
.withPropertyValues(
@ -277,6 +284,7 @@ class OAuth2ResourceServerAutoConfigurationTests {
}
@Test
@WithPublicKeyResource
void autoConfigurationShouldConfigureResourceServerUsingPublicKeyValue() throws Exception {
this.server = new MockWebServer();
this.server.start();
@ -304,6 +312,7 @@ class OAuth2ResourceServerAutoConfigurationTests {
}
@Test
@WithPublicKeyResource
void autoConfigurationShouldFailIfAlgorithmIsInvalid() {
this.contextRunner
.withPropertyValues(
@ -583,6 +592,7 @@ class OAuth2ResourceServerAutoConfigurationTests {
}
@Test
@WithPublicKeyResource
void autoConfigurationShouldConfigureAudienceValidatorIfPropertyProvidedAndPublicKey() throws Exception {
this.server = new MockWebServer();
this.server.start();
@ -877,4 +887,18 @@ class OAuth2ResourceServerAutoConfigurationTests {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "public-key-location", content = """
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd
UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs
HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D
o2kQ+X5xK9cipRgEKwIDAQAB
-----END PUBLIC KEY-----
""")
@interface WithPublicKeyResource {
}
}

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");
* you may not use this file except in compliance with the License.
@ -32,6 +32,7 @@ import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
@ -90,6 +91,7 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
@Test
@WithPackageResources({ "certificate-location", "private-key-location" })
void relyingPartyRegistrationRepositoryBeanShouldBeCreatedWhenPropertiesPresent() {
this.contextRunner.withPropertyValues(getPropertyValues()).run((context) -> {
RelyingPartyRegistrationRepository repository = context.getBean(RelyingPartyRegistrationRepository.class);
@ -124,6 +126,7 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
@Test
@WithPackageResources({ "certificate-location", "private-key-location" })
void autoConfigurationWhenSignRequestsTrueAndNoSigningCredentialsShouldThrowException() {
this.contextRunner.withPropertyValues(getPropertyValuesWithoutSigningCredentials(true)).run((context) -> {
assertThat(context).hasFailed();
@ -133,17 +136,19 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
@Test
@WithPackageResources({ "certificate-location", "private-key-location" })
void autoConfigurationWhenSignRequestsFalseAndNoSigningCredentialsShouldNotThrowException() {
this.contextRunner.withPropertyValues(getPropertyValuesWithoutSigningCredentials(false))
.run((context) -> assertThat(context).hasSingleBean(RelyingPartyRegistrationRepository.class));
}
@Test
@WithPackageResources("idp-metadata")
void autoconfigurationShouldQueryAssertingPartyMetadataWhenMetadataUrlIsPresent() throws Exception {
try (MockWebServer server = new MockWebServer()) {
server.start();
String metadataUrl = server.url("").toString();
setupMockResponse(server, new ClassPathResource("saml/idp-metadata"));
setupMockResponse(server, new ClassPathResource("idp-metadata"));
this.contextRunner.withPropertyValues(PREFIX + ".foo.assertingparty.metadata-uri=" + metadataUrl)
.run((context) -> {
assertThat(context).hasSingleBean(RelyingPartyRegistrationRepository.class);
@ -153,11 +158,12 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
@Test
@WithPackageResources("idp-metadata")
void autoconfigurationShouldUseBindingFromMetadataUrlIfPresent() throws Exception {
try (MockWebServer server = new MockWebServer()) {
server.start();
String metadataUrl = server.url("").toString();
setupMockResponse(server, new ClassPathResource("saml/idp-metadata"));
setupMockResponse(server, new ClassPathResource("idp-metadata"));
this.contextRunner.withPropertyValues(PREFIX + ".foo.assertingparty.metadata-uri=" + metadataUrl)
.run((context) -> {
RelyingPartyRegistrationRepository repository = context
@ -170,11 +176,12 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
@Test
@WithPackageResources("idp-metadata")
void autoconfigurationWhenMetadataUrlAndPropertyPresentShouldUseBindingFromProperty() throws Exception {
try (MockWebServer server = new MockWebServer()) {
server.start();
String metadataUrl = server.url("").toString();
setupMockResponse(server, new ClassPathResource("saml/idp-metadata"));
setupMockResponse(server, new ClassPathResource("idp-metadata"));
this.contextRunner
.withPropertyValues(PREFIX + ".foo.assertingparty.metadata-uri=" + metadataUrl,
PREFIX + ".foo.assertingparty.singlesignon.binding=redirect")
@ -189,6 +196,7 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
@Test
@WithPackageResources({ "certificate-location", "private-key-location" })
void autoconfigurationWhenNoMetadataUrlOrPropertyPresentShouldUseRedirectBinding() {
this.contextRunner.withPropertyValues(getPropertyValuesWithoutSsoBinding()).run((context) -> {
RelyingPartyRegistrationRepository repository = context.getBean(RelyingPartyRegistrationRepository.class);
@ -209,12 +217,14 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
@Test
@WithPackageResources({ "certificate-location", "private-key-location" })
void samlLoginShouldBeConfigured() {
this.contextRunner.withPropertyValues(getPropertyValues())
.run((context) -> assertThat(hasSecurityFilter(context, Saml2WebSsoAuthenticationFilter.class)).isTrue());
}
@Test
@WithPackageResources({ "private-key-location", "certificate-location" })
void samlLoginShouldBackOffWhenASecurityFilterChainBeanIsPresent() {
this.contextRunner.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class))
.withUserConfiguration(TestSecurityFilterChainConfig.class)
@ -223,13 +233,17 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
@Test
@WithPackageResources({ "certificate-location", "private-key-location" })
void samlLoginShouldShouldBeConditionalOnSecurityWebFilterClass() {
this.contextRunner.withClassLoader(new FilteredClassLoader(SecurityFilterChain.class))
this.contextRunner
.withClassLoader(
new FilteredClassLoader(Thread.currentThread().getContextClassLoader(), SecurityFilterChain.class))
.withPropertyValues(getPropertyValues())
.run((context) -> assertThat(context).doesNotHaveBean(SecurityFilterChain.class));
}
@Test
@WithPackageResources({ "certificate-location", "private-key-location" })
void samlLogoutShouldBeConfigured() {
this.contextRunner.withPropertyValues(getPropertyValues())
.run((context) -> assertThat(hasSecurityFilter(context, Saml2LogoutRequestFilter.class)).isTrue());
@ -241,26 +255,29 @@ class Saml2RelyingPartyAutoConfigurationTests {
PREFIX + ".foo.assertingparty.singlesignon.binding=post",
PREFIX + ".foo.assertingparty.singlesignon.sign-request=" + signRequests,
PREFIX + ".foo.assertingparty.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php",
PREFIX + ".foo.assertingparty.verification.credentials[0].certificate-location=classpath:saml/certificate-location" };
PREFIX + ".foo.assertingparty.verification.credentials[0].certificate-location=classpath:certificate-location" };
}
@Test
@WithPackageResources("idp-metadata-with-multiple-providers")
void autoconfigurationWhenMultipleProvidersAndNoSpecifiedEntityId() throws Exception {
testMultipleProviders(null, "https://idp.example.com/idp/shibboleth");
}
@Test
@WithPackageResources("idp-metadata-with-multiple-providers")
void autoconfigurationWhenMultipleProvidersAndSpecifiedEntityId() throws Exception {
testMultipleProviders("https://idp.example.com/idp/shibboleth", "https://idp.example.com/idp/shibboleth");
testMultipleProviders("https://idp2.example.com/idp/shibboleth", "https://idp2.example.com/idp/shibboleth");
}
@Test
@WithPackageResources("idp-metadata")
void signRequestShouldApplyIfMetadataUriIsSet() throws Exception {
try (MockWebServer server = new MockWebServer()) {
server.start();
String metadataUrl = server.url("").toString();
setupMockResponse(server, new ClassPathResource("saml/idp-metadata"));
setupMockResponse(server, new ClassPathResource("idp-metadata"));
this.contextRunner.withPropertyValues(PREFIX + ".foo.assertingparty.metadata-uri=" + metadataUrl,
PREFIX + ".foo.assertingparty.singlesignon.sign-request=true",
PREFIX + ".foo.signing.credentials[0].private-key-location=classpath:org/springframework/boot/autoconfigure/security/saml2/rsa.key",
@ -275,15 +292,16 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
@Test
@WithPackageResources("certificate-location")
void autoconfigurationWithInvalidPrivateKeyShouldFail() {
this.contextRunner.withPropertyValues(
PREFIX + ".foo.signing.credentials[0].private-key-location=classpath:saml/certificate-location",
PREFIX + ".foo.signing.credentials[0].certificate-location=classpath:saml/certificate-location",
PREFIX + ".foo.signing.credentials[0].private-key-location=classpath:certificate-location",
PREFIX + ".foo.signing.credentials[0].certificate-location=classpath:certificate-location",
PREFIX + ".foo.assertingparty.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php",
PREFIX + ".foo.assertingparty.singlesignon.binding=post",
PREFIX + ".foo.assertingparty.singlesignon.sign-request=false",
PREFIX + ".foo.assertingparty.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php",
PREFIX + ".foo.assertingparty.verification.credentials[0].certificate-location=classpath:saml/certificate-location")
PREFIX + ".foo.assertingparty.verification.credentials[0].certificate-location=classpath:certificate-location")
.run((context) -> assertThat(context).hasFailed()
.getFailure()
.rootCause()
@ -291,15 +309,16 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
@Test
@WithPackageResources("private-key-location")
void autoconfigurationWithInvalidCertificateShouldFail() {
this.contextRunner.withPropertyValues(
PREFIX + ".foo.signing.credentials[0].private-key-location=classpath:saml/private-key-location",
PREFIX + ".foo.signing.credentials[0].certificate-location=classpath:saml/private-key-location",
PREFIX + ".foo.signing.credentials[0].private-key-location=classpath:private-key-location",
PREFIX + ".foo.signing.credentials[0].certificate-location=classpath:private-key-location",
PREFIX + ".foo.assertingparty.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php",
PREFIX + ".foo.assertingparty.singlesignon.binding=post",
PREFIX + ".foo.assertingparty.singlesignon.sign-request=false",
PREFIX + ".foo.assertingparty.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php",
PREFIX + ".foo.assertingparty.verification.credentials[0].certificate-location=classpath:saml/certificate-location")
PREFIX + ".foo.assertingparty.verification.credentials[0].certificate-location=classpath:private-key-location")
.run((context) -> assertThat(context).hasFailed()
.getFailure()
.rootCause()
@ -310,7 +329,7 @@ class Saml2RelyingPartyAutoConfigurationTests {
try (MockWebServer server = new MockWebServer()) {
server.start();
String metadataUrl = server.url("").toString();
setupMockResponse(server, new ClassPathResource("saml/idp-metadata-with-multiple-providers"));
setupMockResponse(server, new ClassPathResource("idp-metadata-with-multiple-providers"));
WebApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues(PREFIX + ".foo.assertingparty.metadata-uri=" + metadataUrl);
if (specifiedEntityId != null) {
@ -333,15 +352,15 @@ class Saml2RelyingPartyAutoConfigurationTests {
+ ".foo.assertingparty.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php",
PREFIX + ".foo.assertingparty.singlesignon.sign-request=false",
PREFIX + ".foo.assertingparty.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php",
PREFIX + ".foo.assertingparty.verification.credentials[0].certificate-location=classpath:saml/certificate-location" };
PREFIX + ".foo.assertingparty.verification.credentials[0].certificate-location=classpath:certificate-location" };
}
private String[] getPropertyValues() {
return new String[] {
PREFIX + ".foo.signing.credentials[0].private-key-location=classpath:saml/private-key-location",
PREFIX + ".foo.signing.credentials[0].certificate-location=classpath:saml/certificate-location",
PREFIX + ".foo.decryption.credentials[0].private-key-location=classpath:saml/private-key-location",
PREFIX + ".foo.decryption.credentials[0].certificate-location=classpath:saml/certificate-location",
PREFIX + ".foo.signing.credentials[0].private-key-location=classpath:private-key-location",
PREFIX + ".foo.signing.credentials[0].certificate-location=classpath:certificate-location",
PREFIX + ".foo.decryption.credentials[0].private-key-location=classpath:private-key-location",
PREFIX + ".foo.decryption.credentials[0].certificate-location=classpath:certificate-location",
PREFIX + ".foo.singlelogout.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SLOService.php",
PREFIX + ".foo.singlelogout.response-url=https://simplesaml-for-spring-saml.cfapps.io/",
PREFIX + ".foo.singlelogout.binding=post",
@ -349,7 +368,7 @@ class Saml2RelyingPartyAutoConfigurationTests {
PREFIX + ".foo.assertingparty.singlesignon.binding=post",
PREFIX + ".foo.assertingparty.singlesignon.sign-request=false",
PREFIX + ".foo.assertingparty.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php",
PREFIX + ".foo.assertingparty.verification.credentials[0].certificate-location=classpath:saml/certificate-location",
PREFIX + ".foo.assertingparty.verification.credentials[0].certificate-location=classpath:certificate-location",
PREFIX + ".foo.asserting-party.singlelogout.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SLOService.php",
PREFIX + ".foo.asserting-party.singlelogout.response-url=https://simplesaml-for-spring-saml.cfapps.io/",
PREFIX + ".foo.asserting-party.singlelogout.binding=post",

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -16,6 +16,10 @@
package org.springframework.boot.autoconfigure.security.servlet;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.security.interfaces.RSAPublicKey;
import java.util.EnumSet;
@ -36,6 +40,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.convert.ApplicationConversionService;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean;
import org.springframework.boot.web.servlet.filter.OrderedFilter;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@ -193,6 +198,7 @@ class SecurityAutoConfigurationTests {
}
@Test
@WithPublicKeyResource
void whenAConfigurationPropertyBindingConverterIsDefinedThenBindingToAnRsaKeySucceeds() {
this.contextRunner.withUserConfiguration(ConverterConfiguration.class, PropertiesConfiguration.class)
.withPropertyValues("jwt.public-key=classpath:public-key-location")
@ -200,6 +206,7 @@ class SecurityAutoConfigurationTests {
}
@Test
@WithPublicKeyResource
void whenTheBeanFactoryHasAConversionServiceAndAConfigurationPropertyBindingConverterIsDefinedThenBindingToAnRsaKeySucceeds() {
this.contextRunner
.withInitializer(
@ -295,4 +302,18 @@ class SecurityAutoConfigurationTests {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "public-key-location", content = """
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd
UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs
HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D
o2kQ+X5xK9cipRgEKwIDAQAB
-----END PUBLIC KEY-----
""")
@interface WithPublicKeyResource {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -21,6 +21,7 @@ import java.time.Duration;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -37,6 +38,7 @@ import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.servlet.AbstractFilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -63,13 +65,19 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
*/
class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfigurationTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withClassLoader(new FilteredClassLoader(HazelcastIndexedSessionRepository.class,
MongoIndexedSessionRepository.class, RedisIndexedSessionRepository.class))
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class,
SessionAutoConfiguration.class))
.withPropertyValues("spring.datasource.generate-unique-name=true");
private WebApplicationContextRunner contextRunner;
@BeforeEach
void prepareRunner() {
this.contextRunner = new WebApplicationContextRunner()
.withClassLoader(new FilteredClassLoader(Thread.currentThread().getContextClassLoader(),
HazelcastIndexedSessionRepository.class, MongoIndexedSessionRepository.class,
RedisIndexedSessionRepository.class))
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class,
SessionAutoConfiguration.class))
.withPropertyValues("spring.datasource.generate-unique-name=true");
}
@Test
void defaultConfig() {
@ -127,9 +135,8 @@ class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfiguration
@Test
void customTableName() {
this.contextRunner
.withPropertyValues("spring.session.jdbc.table-name=FOO_BAR",
"spring.session.jdbc.schema=classpath:session/custom-schema-h2.sql")
this.contextRunner.withPropertyValues("spring.session.jdbc.table-name=FOO_BAR",
"spring.session.jdbc.schema=classpath:org/springframework/boot/autoconfigure/session/custom-schema-h2.sql")
.run((context) -> {
JdbcIndexedSessionRepository repository = validateSessionRepository(context,
JdbcIndexedSessionRepository.class);
@ -211,6 +218,7 @@ class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfiguration
}
@Test
@WithResource(name = "db/changelog/db.changelog-master.yaml", content = "databaseChangeLog:")
void sessionRepositoryBeansDependOnLiquibase() {
this.contextRunner.withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class))
.withPropertyValues("spring.session.jdbc.initialize-schema=never")

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");
* you may not use this file except in compliance with the License.
@ -67,9 +67,9 @@ class SslPropertiesBundleRegistrarTests {
void shouldWatchJksBundles() {
JksSslBundleProperties jks = new JksSslBundleProperties();
jks.setReloadOnUpdate(true);
jks.getKeystore().setLocation("classpath:test.jks");
jks.getKeystore().setLocation("classpath:org/springframework/boot/autoconfigure/ssl/test.jks");
jks.getKeystore().setPassword("secret");
jks.getTruststore().setLocation("classpath:test.jks");
jks.getTruststore().setLocation("classpath:org/springframework/boot/autoconfigure/ssl/test.jks");
jks.getTruststore().setPassword("secret");
this.properties.getBundle().getJks().put("bundle1", jks);
this.registrar.registerBundles(this.registry);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -43,6 +43,7 @@ import org.springframework.boot.test.context.runner.ReactiveWebApplicationContex
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
@ -70,6 +71,7 @@ class ThymeleafReactiveAutoConfigurationTests {
.withConfiguration(AutoConfigurations.of(ThymeleafAutoConfiguration.class));
@Test
@WithResource(name = "templates/template.html", content = "<html th:text=\"${foo}\">foo</html>")
void createFromConfigClass() {
this.contextRunner.withPropertyValues("spring.thymeleaf.suffix:.html").run((context) -> {
TemplateEngine engine = context.getBean(TemplateEngine.class);
@ -188,6 +190,7 @@ class ThymeleafReactiveAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/data-dialect.html", content = "<html><body data:foo=\"${foo}\"></body></html>")
void useDataDialect() {
this.contextRunner.run((context) -> {
ISpringWebFluxTemplateEngine engine = context.getBean(ISpringWebFluxTemplateEngine.class);
@ -198,6 +201,8 @@ class ThymeleafReactiveAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/java8time-dialect.html",
content = "<html><body th:text=\"${#temporals.create('2015','11','24')}\"></body></html>")
void useJava8TimeDialect() {
this.contextRunner.run((context) -> {
ISpringWebFluxTemplateEngine engine = context.getBean(ISpringWebFluxTemplateEngine.class);
@ -208,6 +213,8 @@ class ThymeleafReactiveAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/security-dialect.html",
content = "<html><body><div sec:authentication=\"name\"></div></body></html>\n")
void useSecurityDialect() {
this.contextRunner.run((context) -> {
ISpringWebFluxTemplateEngine engine = context.getBean(ISpringWebFluxTemplateEngine.class);
@ -229,6 +236,7 @@ class ThymeleafReactiveAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/home.html", content = "<html><body th:text=\"${foo}\">Home</body></html>")
void renderTemplate() {
this.contextRunner.run((context) -> {
ISpringWebFluxTemplateEngine engine = context.getBean(ISpringWebFluxTemplateEngine.class);

View File

@ -46,6 +46,7 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
import org.springframework.context.annotation.Bean;
@ -89,6 +90,7 @@ class ThymeleafServletAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/template.html", content = "<html th:text=\"${foo}\">foo</html>")
void createFromConfigClass() {
this.contextRunner.withPropertyValues("spring.thymeleaf.mode:HTML", "spring.thymeleaf.suffix:")
.run((context) -> {
@ -184,6 +186,19 @@ class ThymeleafServletAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/view.html",
content = """
<html xmlns:th="https://www.thymeleaf.org" xmlns:layout="https://www.ultraq.net.nz/web/thymeleaf/layout" layout:decorator="layout">
<head>
<title layout:fragment="title">Content</title>
</head>
<body>
<div layout:fragment="content">
<span th:text="${foo}">foo</span>
</div>
</body>
</html>
""")
void createLayoutFromConfigClass() {
this.contextRunner.run((context) -> {
ThymeleafView view = (ThymeleafView) context.getBean(ThymeleafViewResolver.class)
@ -200,6 +215,7 @@ class ThymeleafServletAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/data-dialect.html", content = "<html><body data:foo=\"${foo}\"></body></html>")
void useDataDialect() {
this.contextRunner.run((context) -> {
TemplateEngine engine = context.getBean(TemplateEngine.class);
@ -210,6 +226,8 @@ class ThymeleafServletAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/java8time-dialect.html",
content = "<html><body th:text=\"${#temporals.create('2015','11','24')}\"></body></html>")
void useJava8TimeDialect() {
this.contextRunner.run((context) -> {
TemplateEngine engine = context.getBean(TemplateEngine.class);
@ -220,6 +238,8 @@ class ThymeleafServletAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/security-dialect.html",
content = "<html><body><div sec:authentication=\"name\"></div></body></html>\n")
void useSecurityDialect() {
this.contextRunner.run((context) -> {
TemplateEngine engine = context.getBean(TemplateEngine.class);
@ -246,6 +266,7 @@ class ThymeleafServletAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/home.html", content = "<html><body th:text=\"${foo}\">Home</body></html>")
void renderTemplate() {
this.contextRunner.run((context) -> {
TemplateEngine engine = context.getBean(TemplateEngine.class);
@ -256,6 +277,8 @@ class ThymeleafServletAutoConfigurationTests {
}
@Test
@WithResource(name = "templates/message.html",
content = "<html><body>Message: <span th:text=\"${greeting}\">Hello</span></body></html>")
void renderNonWebAppTemplate() {
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(ThymeleafAutoConfiguration.class))
.run((context) -> {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.thymeleaf;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.mock.env.MockEnvironment;
@ -39,6 +40,7 @@ class ThymeleafTemplateAvailabilityProviderTests {
private final MockEnvironment environment = new MockEnvironment();
@Test
@WithResource(name = "templates/home.html")
void availabilityOfTemplateInDefaultLocation() {
assertThat(this.provider.isTemplateAvailable("home", this.environment, getClass().getClassLoader(),
this.resourceLoader))
@ -53,6 +55,7 @@ class ThymeleafTemplateAvailabilityProviderTests {
}
@Test
@WithResource(name = "custom-templates/custom.html")
void availabilityOfTemplateWithCustomPrefix() {
this.environment.setProperty("spring.thymeleaf.prefix", "classpath:/custom-templates/");
assertThat(this.provider.isTemplateAvailable("custom", this.environment, getClass().getClassLoader(),
@ -61,6 +64,7 @@ class ThymeleafTemplateAvailabilityProviderTests {
}
@Test
@WithResource(name = "templates/suffixed.thymeleaf")
void availabilityOfTemplateWithCustomSuffix() {
this.environment.setProperty("spring.thymeleaf.suffix", ".thymeleaf");
assertThat(this.provider.isTemplateAvailable("suffixed", this.environment, getClass().getClassLoader(),

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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,7 +17,6 @@
package org.springframework.boot.autoconfigure.web;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
@ -27,6 +26,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.ResourcePatternHint;
import org.springframework.aot.hint.ResourcePatternHints;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import static org.assertj.core.api.Assertions.assertThat;
@ -35,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Stephane Nicoll
*/
@WithResource(name = "web/custom-resource.txt")
class WebResourcesRuntimeHintsTests {
@Test
@ -71,12 +72,12 @@ class WebResourcesRuntimeHintsTests {
};
}
private static class TestClassLoader extends URLClassLoader {
private static class TestClassLoader extends ClassLoader {
private final List<String> availableResources;
TestClassLoader(List<String> availableResources) {
super(new URL[0], TestClassLoader.class.getClassLoader());
super(Thread.currentThread().getContextClassLoader());
this.availableResources = availableResources;
}

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");
* you may not use this file except in compliance with the License.
@ -57,6 +57,7 @@ import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfigurat
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.codec.CodecCustomizer;
import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext;
import org.springframework.boot.web.reactive.filter.OrderedHiddenHttpMethodFilter;
@ -530,6 +531,7 @@ class WebFluxAutoConfigurationTests {
}
@Test
@WithResource(name = "welcome-page/index.html", content = "welcome-page-static")
void welcomePageHandlerMapping() {
this.contextRunner.withPropertyValues("spring.web.resources.static-locations=classpath:/welcome-page/")
.run((context) -> {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -27,6 +27,7 @@ import reactor.core.publisher.Mono;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
@ -46,6 +47,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Brian Clozel
*/
@WithResource(name = "welcome-page/index.html", content = "welcome-page-static")
class WelcomePageRouterFunctionFactoryTests {
private StaticApplicationContext applicationContext;

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");
* you may not use this file except in compliance with the License.
@ -22,9 +22,12 @@ import java.util.LinkedHashMap;
import java.util.Map;
import jakarta.validation.Valid;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigurations;
@ -39,6 +42,7 @@ import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplic
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.error.ErrorAttributeOptions.Include;
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
@ -88,6 +92,12 @@ class DefaultErrorWebExceptionHandlerIntegrationTests {
.withPropertyValues("spring.main.web-application-type=reactive", "server.port=0")
.withUserConfiguration(Application.class);
@BeforeEach
@AfterEach
void clearReactorSchedulers() {
Schedulers.shutdownNow();
}
@Test
void jsonError(CapturedOutput output) {
this.contextRunner.run((context) -> {
@ -141,7 +151,18 @@ class DefaultErrorWebExceptionHandlerIntegrationTests {
}
@Test
@WithResource(name = "templates/error/error.mustache", content = """
<html>
<body>
<ul>
<li>status: {{status}}</li>
<li>message: {{message}}</li>
</ul>
</body>
</html>
""")
void htmlError() {
Schedulers.shutdownNow();
this.contextRunner.withPropertyValues("server.error.include-message=always").run((context) -> {
WebTestClient client = getWebClient(context);
String body = client.get()

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");
* you may not use this file except in compliance with the License.
@ -24,6 +24,7 @@ import reactor.core.publisher.Mono;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.WebProperties.Resources;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
@ -52,6 +53,16 @@ import static org.mockito.Mockito.mock;
class DefaultErrorWebExceptionHandlerTests {
@Test
@WithResource(name = "templates/error/error.mustache", content = """
<html>
<body>
<ul>
<li>status: {{status}}</li>
<li>message: {{message}}</li>
</ul>
</body>
</html>
""")
void nonStandardErrorStatusCodeShouldNotFail() {
ErrorAttributes errorAttributes = mock(ErrorAttributes.class);
given(errorAttributes.getErrorAttributes(any(), any())).willReturn(Collections.singletonMap("status", 498));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -22,6 +22,7 @@ import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslBundleKey;
import org.springframework.boot.ssl.jks.JksSslStoreBundle;
import org.springframework.boot.ssl.jks.JksSslStoreDetails;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.Ssl;
import org.springframework.boot.web.server.Ssl.ClientAuth;
@ -62,6 +63,7 @@ abstract class AbstractClientHttpConnectorFactoryTests {
}
@Test
@WithPackageResources("test.jks")
void secureConnection() throws Exception {
TomcatServletWebServerFactory webServerFactory = new TomcatServletWebServerFactory(0);
Ssl ssl = new Ssl();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -25,6 +25,7 @@ import org.springframework.boot.ssl.jks.JksSslStoreBundle;
import org.springframework.boot.ssl.jks.JksSslStoreDetails;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.reactive.HttpComponentsClientHttpConnector;
@ -42,6 +43,7 @@ import static org.mockito.Mockito.spy;
class ClientHttpConnectorFactoryConfigurationTests {
@Test
@WithPackageResources("test.jks")
void shouldApplyHttpClientMapper() {
JksSslStoreDetails storeDetails = JksSslStoreDetails.forLocation("classpath:test.jks");
JksSslStoreBundle stores = new JksSslStoreBundle(storeDetails, storeDetails);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 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.
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.web.servlet;
import org.junit.jupiter.api.Test;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.mock.env.MockEnvironment;
@ -43,15 +44,16 @@ class JspTemplateAvailabilityProviderTests {
}
@Test
@WithResource(name = "custom-templates/custom.jsp")
void availabilityOfTemplateWithCustomPrefix() {
this.environment.setProperty("spring.mvc.view.prefix", "classpath:/custom-templates/");
assertThat(isTemplateAvailable("custom.jsp")).isTrue();
}
@Test
@WithResource(name = "suffixed.java-server-pages")
void availabilityOfTemplateWithCustomSuffix() {
this.environment.setProperty("spring.mvc.view.prefix", "classpath:/custom-templates/");
this.environment.setProperty("spring.mvc.view.suffix", ".jsp");
this.environment.setProperty("spring.mvc.view.suffix", ".java-server-pages");
assertThat(isTemplateAvailable("suffixed")).isTrue();
}

View File

@ -57,6 +57,7 @@ import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguratio
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
@ -691,6 +692,7 @@ class WebMvcAutoConfigurationTests {
}
@Test
@WithResource(name = "welcome-page/index.html", content = "welcome-page-static")
void welcomePageHandlerMappingIsAutoConfigured() {
this.contextRunner.withPropertyValues("spring.web.resources.static-locations:classpath:/welcome-page/")
.run((context) -> {
@ -701,6 +703,7 @@ class WebMvcAutoConfigurationTests {
}
@Test
@WithResource(name = "welcome-page/index.html", content = "welcome-page-static")
void welcomePageHandlerIncludesCorsConfiguration() {
this.contextRunner.withPropertyValues("spring.web.resources.static-locations:classpath:/welcome-page/")
.withUserConfiguration(CorsConfigurer.class)

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");
* you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@
package org.springframework.boot.autoconfigure.web.servlet;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Map;
@ -39,7 +40,7 @@ import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
@ -173,7 +174,7 @@ class WelcomePageHandlerMappingTests {
@Bean
Resource staticIndexPage() {
return new FileSystemResource("src/test/resources/welcome-page/index.html");
return new ByteArrayResource("welcome-page-static".getBytes(StandardCharsets.UTF_8));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 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.
@ -41,9 +41,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Madhura Bhave
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "spring.web.resources.chain.strategy.content.enabled=true",
"spring.thymeleaf.prefix=classpath:/templates/thymeleaf/" })
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
"spring.web.resources.chain.strategy.content.enabled=true",
"spring.thymeleaf.prefix=classpath:/org/springframework/boot/autoconfigure/web/servlet/",
"spring.web.resources.static-locations=classpath:/org/springframework/boot/autoconfigure/web/servlet/static" })
class WelcomePageIntegrationTests {
@LocalServerPort

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");
* you may not use this file except in compliance with the License.
@ -46,6 +46,7 @@ import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoC
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.error.ErrorAttributeOptions.Include;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
@ -326,6 +327,7 @@ class BasicErrorControllerIntegrationTests {
}
@Test
@WithResource(name = "templates/error/507.ftlh", content = "We are out of storage")
void testConventionTemplateMapping() {
load();
RequestEntity<?> request = RequestEntity.get(URI.create(createUrl("/noStorage")))

View File

@ -19,10 +19,13 @@ package org.springframework.boot.autoconfigure.webservices;
import java.util.Collection;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition;
@ -87,17 +90,67 @@ class WebServicesAutoConfigurationTests {
.containsEntry("key2", "value2"));
}
@Test
void withWsdlBeans() {
this.contextRunner.withPropertyValues("spring.webservices.wsdl-locations=classpath:/wsdl").run((context) -> {
assertThat(context.getBeansOfType(SimpleWsdl11Definition.class)).containsOnlyKeys("service");
assertThat(context.getBeansOfType(SimpleXsdSchema.class)).containsOnlyKeys("types");
});
}
@Test
void withWsdlBeansAsList() {
this.contextRunner.withPropertyValues("spring.webservices.wsdl-locations[0]=classpath:/wsdl").run((context) -> {
@ParameterizedTest
@WithResource(name = "wsdl/service.wsdl", content = """
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="https://www.springframework.org/spring-ws/wsdl"
targetNamespace="https://www.springframework.org/spring-ws/wsdl">
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="https://www.springframework.org/spring-ws/wsdl">
<xsd:element name="request" type="xsd:string" />
<xsd:element name="response" type="xsd:string" />
</xsd:schema>
</wsdl:types>
<wsdl:message name="responseMessage">
<wsdl:part name="body" element="tns:response" />
</wsdl:message>
<wsdl:message name="requestMessage">
<wsdl:part name="body" element="tns:request" />
</wsdl:message>
<wsdl:portType name="portType">
<wsdl:operation name="operation">
<wsdl:input message="tns:requestMessage" name="request" />
<wsdl:output message="tns:responseMessage"
name="response" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="binding" type="tns:portType">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="operation">
<soap:operation soapAction="" />
<wsdl:input name="request">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="response">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="service">
<wsdl:port binding="tns:binding" name="port">
<soap:address location="/services" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
""")
@WithResource(name = "wsdl/types.xsd", content = """
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="https://www.springframework.org/spring-ws/wsdl/schemas">
<element name="request" type="string" />
<element name="response" type="string" />
</schema>
""")
@ValueSource(strings = { "spring.webservices.wsdl-locations", "spring.webservices.wsdl-locations[0]" })
void withWsdlBeans(String propertyName) {
this.contextRunner.withPropertyValues(propertyName + "=classpath:/wsdl").run((context) -> {
assertThat(context.getBeansOfType(SimpleWsdl11Definition.class)).containsOnlyKeys("service");
assertThat(context.getBeansOfType(SimpleXsdSchema.class)).containsOnlyKeys("types");
});

View File

@ -1,4 +0,0 @@
test=
test.string=abc
test.int=123
test.set=a,b,b,c

View File

@ -1,5 +0,0 @@
build.group=com.example
build.artifact=demo
build.name=Demo Project
build.version=0.0.1-SNAPSHOT
build.time=2016-03-04T14:16:05.000Z

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm https://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/orm_2_1.xsd"
version="2.1">
<entity class="org.springframework.boot.autoconfigure.orm.jpa.mapping.NonAnnotatedEntity">
<table name="NON_ANNOTATED"/>
<attributes>
<id name="id">
<column name="id"/>
<generated-value strategy="IDENTITY"/>
</id>
<basic name="item">
<column name="item"/>
</basic>
</attributes>
</entity>
</entity-mappings>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="manually-configured">
<class>org.springframework.boot.autoconfigure.orm.jpa.test.City</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>

View File

@ -1 +0,0 @@
spring.integration.endpoints.noAutoStartup=testService*

View File

@ -1,3 +0,0 @@
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$AfterDeprecatedAutoConfiguration
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$ReplacementAutoConfiguration

View File

@ -1,2 +0,0 @@
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$DeprecatedAutoConfiguration=\
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$ReplacementAutoConfiguration

View File

@ -1,2 +0,0 @@
org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$ImportedAutoConfiguration
org.springframework.boot.autoconfigure.missing.MissingAutoConfiguration

View File

@ -1,3 +0,0 @@
optional:org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$ImportedAutoConfiguration
optional:org.springframework.boot.autoconfigure.missing.MissingAutoConfiguration
org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$AnotherImportedAutoConfiguration

View File

@ -1,10 +0,0 @@
<ehcache>
<cache name="cacheOverrideTest1"
maxBytesLocalHeap="50m"
timeToLiveSeconds="100">
</cache>
<cache name="cacheOverrideTest2"
maxBytesLocalHeap="50m"
timeToLiveSeconds="100">
</cache>
</ehcache>

View File

@ -1 +0,0 @@
INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google');

View File

@ -1,7 +0,0 @@
dn: dc=spring,dc=org
objectclass: top
objectclass: domain
objectclass: extensibleObject
objectClass: exampleAuxiliaryClass
dc: spring
exampleAttributeName: exampleAttributeName

View File

@ -1,17 +0,0 @@
dn: cn=schema
attributeTypes: ( 1.3.6.1.4.1.32473.1.1.1
NAME 'exampleAttributeName'
DESC 'An example attribute type definition'
EQUALITY caseIgnoreMatch
ORDERING caseIgnoreOrderingMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE
X-ORIGIN 'Managing Schema Document' )
objectClasses: ( 1.3.6.1.4.1.32473.1.2.2
NAME 'exampleAuxiliaryClass'
DESC 'An example auxiliary object class definition'
SUP top
AUXILIARY
MAY exampleAttributeName
X-ORIGIN 'Managing Schema Document' )

Some files were not shown because too many files have changed in this diff Show More