Merge branch '3.4.x'

Closes gh-44698
This commit is contained in:
Andy Wilkinson 2025-03-12 15:49:41 +00:00
commit 19c386040b
24 changed files with 210 additions and 408 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -50,6 +50,7 @@ public class ConventionsPlugin implements Plugin<Project> {
new KotlinConventions().apply(project);
new WarConventions().apply(project);
new EclipseConventions().apply(project);
new TestFixturesConventions().apply(project);
RepositoryTransformersExtension.apply(project);
}

View File

@ -0,0 +1,50 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.build;
import org.gradle.api.Project;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.component.AdhocComponentWithVariants;
import org.gradle.api.plugins.JavaTestFixturesPlugin;
/**
* Conventions that are applied in the presence of the {@link JavaTestFixturesPlugin}.
* When the plugin is applied:
*
* <ul>
* <li>Publishing of the test fixtures is disabled.
* </ul>
*
* @author Andy Wilkinson
*/
class TestFixturesConventions {
void apply(Project project) {
project.getPlugins().withType(JavaTestFixturesPlugin.class, (testFixtures) -> disablePublishing(project));
}
private void disablePublishing(Project project) {
ConfigurationContainer configurations = project.getConfigurations();
AdhocComponentWithVariants javaComponent = (AdhocComponentWithVariants) project.getComponents()
.getByName("java");
javaComponent.withVariantsFromConfiguration(configurations.getByName("testFixturesApiElements"),
(variant) -> variant.skip());
javaComponent.withVariantsFromConfiguration(configurations.getByName("testFixturesRuntimeElements"),
(variant) -> variant.skip());
}
}

View File

@ -134,6 +134,7 @@ dependencies {
testImplementation(project(":spring-boot-project:spring-boot-test"))
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
testImplementation(testFixtures(project(":spring-boot-project:spring-boot")))
testImplementation("io.micrometer:micrometer-observation-test")
testImplementation("io.micrometer:micrometer-tracing-test")
testImplementation("io.projectreactor:reactor-test")

View File

@ -1,79 +0,0 @@
/*
* Copyright 2012-2023 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.web.servlet;
import java.util.Arrays;
import jakarta.servlet.ServletContext;
import org.springframework.boot.testsupport.web.servlet.MockServletWebServer.RegisteredFilter;
import org.springframework.boot.testsupport.web.servlet.MockServletWebServer.RegisteredServlet;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import static org.mockito.Mockito.spy;
/**
* Mock {@link ServletWebServerFactory}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
public class MockServletWebServerFactory extends AbstractServletWebServerFactory {
private MockServletWebServer webServer;
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
this.webServer = spy(new MockServletWebServer(mergeInitializers(initializers), getPort()));
return this.webServer;
}
public MockServletWebServer getWebServer() {
return this.webServer;
}
public ServletContext getServletContext() {
return (getWebServer() != null) ? getWebServer().getServletContext() : null;
}
public RegisteredServlet getRegisteredServlet(int index) {
return (getWebServer() != null) ? getWebServer().getRegisteredServlet(index) : null;
}
public RegisteredFilter getRegisteredFilter(int index) {
return (getWebServer() != null) ? getWebServer().getRegisteredFilters(index) : null;
}
static class MockServletWebServer extends org.springframework.boot.testsupport.web.servlet.MockServletWebServer
implements WebServer {
MockServletWebServer(ServletContextInitializer[] initializers, int port) {
super(Arrays.stream(initializers)
.map((initializer) -> (Initializer) initializer::onStartup)
.toArray(Initializer[]::new), port);
}
@Override
public void start() {
}
}
}

View File

@ -24,6 +24,7 @@ dependencies {
dockerTestImplementation(project(":spring-boot-project:spring-boot-test"))
dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker"))
dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot")))
dockerTestImplementation("com.redis:testcontainers-redis")
dockerTestImplementation("org.assertj:assertj-core")
dockerTestImplementation("org.awaitility:awaitility")
@ -234,6 +235,7 @@ dependencies {
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
testImplementation(project(":spring-boot-project:spring-boot-test"))
testImplementation(testFixtures(project(":spring-boot-project:spring-boot")))
testImplementation("ch.qos.logback:logback-classic")
testImplementation("commons-fileupload:commons-fileupload")
testImplementation("com.github.h-thurow:simple-jndi")

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,10 +19,10 @@ package org.springframework.boot.autoconfigure.condition;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import org.springframework.boot.autoconfigure.web.reactive.MockReactiveWebServerFactory;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory;
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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.
@ -21,8 +21,8 @@ import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.web.reactive.MockReactiveWebServerFactory;
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext;
import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory;
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 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,11 +19,11 @@ package org.springframework.boot.autoconfigure.session;
import java.util.Collections;
import java.util.function.Consumer;
import org.springframework.boot.autoconfigure.web.reactive.MockReactiveWebServerFactory;
import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext;
import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;

View File

@ -1,90 +0,0 @@
/*
* Copyright 2012-2021 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.web.reactive;
import java.util.Map;
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServer;
import org.springframework.http.server.reactive.HttpHandler;
import static org.mockito.Mockito.spy;
/**
* Mock {@link ReactiveWebServerFactory}.
*
* @author Brian Clozel
*/
public class MockReactiveWebServerFactory extends AbstractReactiveWebServerFactory {
private MockReactiveWebServer webServer;
@Override
public WebServer getWebServer(HttpHandler httpHandler) {
this.webServer = spy(new MockReactiveWebServer(httpHandler, getPort()));
return this.webServer;
}
public MockReactiveWebServer getWebServer() {
return this.webServer;
}
static class MockReactiveWebServer implements WebServer {
private final int port;
private HttpHandler httpHandler;
private Map<String, HttpHandler> httpHandlerMap;
MockReactiveWebServer(HttpHandler httpHandler, int port) {
this.httpHandler = httpHandler;
this.port = port;
}
MockReactiveWebServer(Map<String, HttpHandler> httpHandlerMap, int port) {
this.httpHandlerMap = httpHandlerMap;
this.port = port;
}
HttpHandler getHttpHandler() {
return this.httpHandler;
}
Map<String, HttpHandler> getHttpHandlerMap() {
return this.httpHandlerMap;
}
@Override
public void start() {
}
@Override
public void stop() {
}
@Override
public int getPort() {
return this.port;
}
}
}

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.
@ -45,6 +45,7 @@ import org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerF
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext;
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory;
import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory;
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.ApplicationContextException;

View File

@ -61,6 +61,7 @@ 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;
import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.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.
@ -28,11 +28,12 @@ import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConf
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.testsupport.web.servlet.MockServletWebServer.RegisteredFilter;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter;
import org.springframework.boot.web.servlet.server.MockServletWebServer.RegisteredFilter;
import org.springframework.boot.web.servlet.server.MockServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnection;

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.
@ -33,6 +33,7 @@ import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostPro
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.boot.web.servlet.filter.OrderedFormContentFilter;
import org.springframework.boot.web.servlet.filter.OrderedHiddenHttpMethodFilter;
import org.springframework.boot.web.servlet.server.MockServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;

View File

@ -1,79 +0,0 @@
/*
* Copyright 2012-2023 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.web.servlet;
import java.util.Arrays;
import jakarta.servlet.ServletContext;
import org.springframework.boot.testsupport.web.servlet.MockServletWebServer.RegisteredFilter;
import org.springframework.boot.testsupport.web.servlet.MockServletWebServer.RegisteredServlet;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import static org.mockito.Mockito.spy;
/**
* Mock {@link ServletWebServerFactory}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
public class MockServletWebServerFactory extends AbstractServletWebServerFactory {
private MockServletWebServer webServer;
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
this.webServer = spy(new MockServletWebServer(mergeInitializers(initializers), getPort()));
return this.webServer;
}
public MockServletWebServer getWebServer() {
return this.webServer;
}
public ServletContext getServletContext() {
return (getWebServer() != null) ? getWebServer().getServletContext() : null;
}
public RegisteredServlet getRegisteredServlet(int index) {
return (getWebServer() != null) ? getWebServer().getRegisteredServlet(index) : null;
}
public RegisteredFilter getRegisteredFilter(int index) {
return (getWebServer() != null) ? getWebServer().getRegisteredFilters(index) : null;
}
static class MockServletWebServer extends org.springframework.boot.testsupport.web.servlet.MockServletWebServer
implements WebServer {
MockServletWebServer(ServletContextInitializer[] initializers, int port) {
super(Arrays.stream(initializers)
.map((initializer) -> (Initializer) initializer::onStartup)
.toArray(Initializer[]::new), port);
}
@Override
public void start() {
}
}
}

View File

@ -47,6 +47,7 @@ import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebSe
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier;
import org.springframework.boot.web.servlet.server.MockServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -64,6 +64,7 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.filter.OrderedFormContentFilter;
import org.springframework.boot.web.servlet.server.MockServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;

View File

@ -18,21 +18,26 @@ package org.springframework.boot.testsupport.classpath.resources;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.util.Assert;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.function.ThrowingConsumer;
/**
* A collection of resources.
@ -50,27 +55,43 @@ class Resources {
}
Resources addPackage(Package root, String[] resourceNames) {
String packageName = root.getName();
Set<String> unmatchedNames = new HashSet<>(Arrays.asList(resourceNames));
withPathsForPackage(packageName, (packagePath) -> {
for (String resourceName : resourceNames) {
Path resource = packagePath.resolve(resourceName);
if (Files.exists(resource) && !Files.isDirectory(resource)) {
Path target = this.root.resolve(resourceName);
Path targetDirectory = target.getParent();
if (!Files.isDirectory(targetDirectory)) {
Files.createDirectories(targetDirectory);
}
Files.copy(resource, target);
register(resourceName, target, true);
unmatchedNames.remove(resourceName);
}
}
});
Assert.isTrue(unmatchedNames.isEmpty(),
"Package '" + packageName + "' did not contain resources: " + unmatchedNames);
return this;
}
private void withPathsForPackage(String packageName, ThrowingConsumer<Path> consumer) {
try {
Enumeration<URL> sources = getClass().getClassLoader().getResources(root.getName().replace(".", "/"));
for (URL source : Collections.list(sources)) {
Path sourceRoot = Paths.get(source.toURI());
for (String resourceName : resourceNames) {
Path resource = sourceRoot.resolve(resourceName);
if (Files.isRegularFile(resource)) {
Path target = this.root.resolve(resourceName);
Path targetDirectory = target.getParent();
if (!Files.isDirectory(targetDirectory)) {
Files.createDirectories(targetDirectory);
}
Files.copy(resource, target);
register(resourceName, target, true);
unmatchedNames.remove(resourceName);
List<URL> sources = Collections
.list(getClass().getClassLoader().getResources(packageName.replace(".", "/")));
for (URL source : sources) {
URI sourceUri = source.toURI();
try {
consumer.accept(Paths.get(sourceUri));
}
catch (FileSystemNotFoundException ex) {
try (FileSystem fileSystem = FileSystems.newFileSystem(sourceUri, Collections.emptyMap())) {
consumer.accept(Paths.get(sourceUri));
}
}
}
Assert.isTrue(unmatchedNames.isEmpty(),
"Package '" + root.getName() + "' did not contain resources: " + unmatchedNames);
}
catch (IOException ex) {
throw new UncheckedIOException(ex);
@ -78,7 +99,6 @@ class Resources {
catch (URISyntaxException ex) {
throw new RuntimeException(ex);
}
return this;
}
Resources addResource(String name, String content, boolean additional) {

View File

@ -1,56 +0,0 @@
/*
* Copyright 2012-2023 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.testsupport.web.servlet;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockSessionCookieConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link MockServletWebServer}.
*
* @author Stephane Nicoll
*/
class MockServletWebServerTests {
@Test
void servletContextIsConfigured() {
MockServletWebServer server = TestMockServletWebServer.create();
assertThat(server.getServletContext()).isNotNull();
}
@Test
void servletContextHasSessionCookieConfigConfigured() {
MockServletWebServer server = TestMockServletWebServer.create();
assertThat(server.getServletContext().getSessionCookieConfig()).isInstanceOf(MockSessionCookieConfig.class);
}
private static final class TestMockServletWebServer extends MockServletWebServer {
private TestMockServletWebServer(Initializer[] initializers, int port) {
super(initializers, port);
}
static MockServletWebServer create(Initializer... initializers) {
return new TestMockServletWebServer(initializers, 8080);
}
}
}

View File

@ -1,6 +1,7 @@
plugins {
id "dev.adamko.dokkatoo-html"
id "java-library"
id "java-test-fixtures"
id "org.jetbrains.kotlin.jvm"
id "org.springframework.boot.configuration-properties"
id "org.springframework.boot.deployed"
@ -104,6 +105,10 @@ dependencies {
exclude(group: "commons-logging", module: "commons-logging")
}
testFixturesCompileOnly("jakarta.servlet:jakarta.servlet-api")
testFixturesCompileOnly("org.mockito:mockito-core")
testFixturesCompileOnly("org.springframework:spring-web")
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
testImplementation("org.springframework:spring-core-test")
testImplementation("com.ibm.db2:jcc")

View File

@ -0,0 +1,70 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.web.reactive.server;
import java.util.Map;
import org.springframework.boot.web.server.WebServer;
import org.springframework.http.server.reactive.HttpHandler;
/**
* A mock reactive {@link WebServer}.
*
* @author Brian Clozel
*/
public class MockReactiveWebServer implements WebServer {
private final int port;
private HttpHandler httpHandler;
private Map<String, HttpHandler> httpHandlerMap;
MockReactiveWebServer(HttpHandler httpHandler, int port) {
this.httpHandler = httpHandler;
this.port = port;
}
MockReactiveWebServer(Map<String, HttpHandler> httpHandlerMap, int port) {
this.httpHandlerMap = httpHandlerMap;
this.port = port;
}
public HttpHandler getHttpHandler() {
return this.httpHandler;
}
public Map<String, HttpHandler> getHttpHandlerMap() {
return this.httpHandlerMap;
}
@Override
public void start() {
}
@Override
public void stop() {
}
@Override
public int getPort() {
return this.port;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 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,8 +16,6 @@
package org.springframework.boot.web.reactive.server;
import java.util.Map;
import org.springframework.boot.web.server.WebServer;
import org.springframework.http.server.reactive.HttpHandler;
@ -42,47 +40,4 @@ public class MockReactiveWebServerFactory extends AbstractReactiveWebServerFacto
return this.webServer;
}
public static class MockReactiveWebServer implements WebServer {
private final int port;
private HttpHandler httpHandler;
private Map<String, HttpHandler> httpHandlerMap;
MockReactiveWebServer(HttpHandler httpHandler, int port) {
this.httpHandler = httpHandler;
this.port = port;
}
MockReactiveWebServer(Map<String, HttpHandler> httpHandlerMap, int port) {
this.httpHandlerMap = httpHandlerMap;
this.port = port;
}
public HttpHandler getHttpHandler() {
return this.httpHandler;
}
public Map<String, HttpHandler> getHttpHandlerMap() {
return this.httpHandlerMap;
}
@Override
public void start() {
}
@Override
public void stop() {
}
@Override
public int getPort() {
return this.port;
}
}
}

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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.testsupport.web.servlet;
package org.springframework.boot.web.servlet.server;
import java.util.ArrayList;
import java.util.Arrays;
@ -31,6 +31,9 @@ import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRegistration;
import jakarta.servlet.SessionCookieConfig;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.server.WebServerException;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.mock.web.MockSessionCookieConfig;
import static org.mockito.ArgumentMatchers.any;
@ -40,14 +43,12 @@ import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
/**
* Base class for Mock {@code ServletWebServer} implementations. Reduces the amount of
* code that would otherwise be duplicated in {@code spring-boot},
* {@code spring-boot-autoconfigure} and {@code spring-boot-actuator}.
* A mock servlet {@link WebServer}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
public abstract class MockServletWebServer {
public class MockServletWebServer implements WebServer {
private ServletContext servletContext;
@ -59,7 +60,13 @@ public abstract class MockServletWebServer {
private final int port;
public MockServletWebServer(Initializer[] initializers, int port) {
MockServletWebServer(ServletContextInitializer[] initializers, int port) {
this(Arrays.stream(initializers)
.map((initializer) -> (Initializer) initializer::onStartup)
.toArray(Initializer[]::new), port);
}
MockServletWebServer(Initializer[] initializers, int port) {
this.initializers = initializers;
this.port = port;
initialize();
@ -100,6 +107,11 @@ public abstract class MockServletWebServer {
}
}
@Override
public void start() throws WebServerException {
}
@Override
public void stop() {
this.servletContext = null;
this.registeredServlets.clear();
@ -131,6 +143,7 @@ public abstract class MockServletWebServer {
return this.registeredFilters;
}
@Override
public int getPort() {
return this.port;
}
@ -184,7 +197,7 @@ public abstract class MockServletWebServer {
}
/**
* Initializer (usually implement by adapting {@code Initializer}).
* Initializer (usually implement by adapting {@code ServletContextInitializer}).
*/
@FunctionalInterface
protected interface Initializer {

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,14 +16,12 @@
package org.springframework.boot.web.servlet.server;
import java.util.Arrays;
import jakarta.servlet.ServletContext;
import org.springframework.boot.testsupport.web.servlet.MockServletWebServer.RegisteredFilter;
import org.springframework.boot.testsupport.web.servlet.MockServletWebServer.RegisteredServlet;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.server.MockServletWebServer.RegisteredFilter;
import org.springframework.boot.web.servlet.server.MockServletWebServer.RegisteredServlet;
import static org.mockito.Mockito.spy;
@ -59,19 +57,4 @@ public class MockServletWebServerFactory extends AbstractServletWebServerFactory
return (getWebServer() != null) ? getWebServer().getRegisteredFilters(index) : null;
}
public static class MockServletWebServer
extends org.springframework.boot.testsupport.web.servlet.MockServletWebServer implements WebServer {
MockServletWebServer(ServletContextInitializer[] initializers, int port) {
super(Arrays.stream(initializers)
.map((initializer) -> (Initializer) initializer::onStartup)
.toArray(Initializer[]::new), port);
}
@Override
public void start() {
}
}
}

View File

@ -22,7 +22,7 @@
<suppress files="[\\/]src[\\/]test[\\/]java[\\/]cli[\\/]command[\\/]" checks="ImportControl" />
<suppress files="[\\/]src[\\/]main[\\/]java[\\/]sample[\\/]" checks="ImportControl" />
<suppress files="[\\/]src[\\/]test[\\/]java[\\/]sample[\\/]" checks="ImportControl" />
<suppress files="[\\/]src[\\/]test[\\/]java[\\/]" checks="Javadoc*" />
<suppress files="[\\/]src[\\/]test(Fixtures)?[\\/]java[\\/]" checks="Javadoc*" />
<suppress files="[\\/]src[\\/]test[\\/]java[\\/]" id="mainCodeIllegalImportCheck" />
<suppress files="[\\/]src[\\/]test[\\/]java[\\/]" checks="NonEmptyAtclauseDescription" />
<suppress files="[\\/]autoconfigure[\\/].*Properties\.java" checks="JavadocType" />