|
|
|
@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2012-2024 the original author or authors. |
|
|
|
* Copyright 2012-2025 the original author or authors. |
|
|
|
* |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
@ -51,6 +51,7 @@ import org.springframework.boot.availability.AvailabilityChangeEvent; |
|
|
|
import org.springframework.boot.testsupport.system.CapturedOutput; |
|
|
|
import org.springframework.boot.testsupport.system.CapturedOutput; |
|
|
|
import org.springframework.boot.testsupport.system.OutputCaptureExtension; |
|
|
|
import org.springframework.boot.testsupport.system.OutputCaptureExtension; |
|
|
|
import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; |
|
|
|
import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; |
|
|
|
|
|
|
|
import org.springframework.boot.web.server.WebServer; |
|
|
|
import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; |
|
|
|
import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; |
|
|
|
import org.springframework.boot.web.servlet.FilterRegistrationBean; |
|
|
|
import org.springframework.boot.web.servlet.FilterRegistrationBean; |
|
|
|
import org.springframework.boot.web.servlet.ServletContextInitializer; |
|
|
|
import org.springframework.boot.web.servlet.ServletContextInitializer; |
|
|
|
@ -81,6 +82,7 @@ import static org.mockito.ArgumentMatchers.any; |
|
|
|
import static org.mockito.ArgumentMatchers.anyString; |
|
|
|
import static org.mockito.ArgumentMatchers.anyString; |
|
|
|
import static org.mockito.BDDMockito.given; |
|
|
|
import static org.mockito.BDDMockito.given; |
|
|
|
import static org.mockito.BDDMockito.then; |
|
|
|
import static org.mockito.BDDMockito.then; |
|
|
|
|
|
|
|
import static org.mockito.BDDMockito.willThrow; |
|
|
|
import static org.mockito.Mockito.atMost; |
|
|
|
import static org.mockito.Mockito.atMost; |
|
|
|
import static org.mockito.Mockito.inOrder; |
|
|
|
import static org.mockito.Mockito.inOrder; |
|
|
|
import static org.mockito.Mockito.mock; |
|
|
|
import static org.mockito.Mockito.mock; |
|
|
|
@ -211,6 +213,48 @@ class ServletWebServerApplicationContextTests { |
|
|
|
assertThat(listener.receivedEvents()).isEmpty(); |
|
|
|
assertThat(listener.receivedEvents()).isEmpty(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
void whenContextRefreshFailedThenWebServerIsStoppedAndDestroyed() { |
|
|
|
|
|
|
|
addWebServerFactoryBean(); |
|
|
|
|
|
|
|
this.context.registerBeanDefinition("refreshFailure", new RootBeanDefinition(RefreshFailure.class)); |
|
|
|
|
|
|
|
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(this.context::refresh); |
|
|
|
|
|
|
|
WebServer webServer = this.context.getWebServer(); |
|
|
|
|
|
|
|
then(webServer).should(times(2)).stop(); |
|
|
|
|
|
|
|
then(webServer).should().destroy(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
void whenContextRefreshFailedThenWebServerStopFailedCatchStopException() { |
|
|
|
|
|
|
|
addWebServerFactoryBean(); |
|
|
|
|
|
|
|
this.context.registerBeanDefinition("refreshFailure", new RootBeanDefinition(RefreshFailure.class, () -> { |
|
|
|
|
|
|
|
willThrow(new RuntimeException("WebServer has failed to stop")).willCallRealMethod() |
|
|
|
|
|
|
|
.given(this.context.getWebServer()) |
|
|
|
|
|
|
|
.stop(); |
|
|
|
|
|
|
|
return new RefreshFailure(); |
|
|
|
|
|
|
|
})); |
|
|
|
|
|
|
|
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(this.context::refresh) |
|
|
|
|
|
|
|
.withStackTraceContaining("WebServer has failed to stop"); |
|
|
|
|
|
|
|
WebServer webServer = this.context.getWebServer(); |
|
|
|
|
|
|
|
then(webServer).should().stop(); |
|
|
|
|
|
|
|
then(webServer).should(times(0)).destroy(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
void whenContextRefreshFailedThenWebServerIsStoppedAndDestroyFailedCatchDestroyException() { |
|
|
|
|
|
|
|
addWebServerFactoryBean(); |
|
|
|
|
|
|
|
this.context.registerBeanDefinition("refreshFailure", new RootBeanDefinition(RefreshFailure.class, () -> { |
|
|
|
|
|
|
|
willThrow(new RuntimeException("WebServer has failed to destroy")).willCallRealMethod() |
|
|
|
|
|
|
|
.given(this.context.getWebServer()) |
|
|
|
|
|
|
|
.destroy(); |
|
|
|
|
|
|
|
return new RefreshFailure(); |
|
|
|
|
|
|
|
})); |
|
|
|
|
|
|
|
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(this.context::refresh) |
|
|
|
|
|
|
|
.withStackTraceContaining("WebServer has failed to destroy"); |
|
|
|
|
|
|
|
WebServer webServer = this.context.getWebServer(); |
|
|
|
|
|
|
|
then(webServer).should().stop(); |
|
|
|
|
|
|
|
then(webServer).should().destroy(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
void cannotSecondRefresh() { |
|
|
|
void cannotSecondRefresh() { |
|
|
|
addWebServerFactoryBean(); |
|
|
|
addWebServerFactoryBean(); |
|
|
|
|