@ -16,6 +16,9 @@
package org.springframework.boot.web.embedded.tomcat ;
import java.io.IOException ;
import java.net.InetSocketAddress ;
import java.net.ServerSocket ;
import java.util.Arrays ;
import org.apache.catalina.Context ;
@ -32,10 +35,15 @@ import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor ;
import org.mockito.InOrder ;
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory ;
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactoryTests ;
import org.springframework.boot.web.server.PortInUseException ;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests ;
import org.springframework.http.server.reactive.HttpHandler ;
import org.springframework.util.SocketUtils ;
import static org.assertj.core.api.Assertions.assertThat ;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType ;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException ;
import static org.mockito.ArgumentMatchers.any ;
import static org.mockito.Mockito.inOrder ;
@ -188,4 +196,41 @@ class TomcatReactiveWebServerFactoryTests extends AbstractReactiveWebServerFacto
assertThat ( context . getClearReferencesThreadLocals ( ) ) . isFalse ( ) ;
}
@Test
protected void portClashOfPrimaryConnectorResultsInPortInUseException ( ) throws IOException {
doWithBlockedPort ( ( port ) - > {
assertThatExceptionOfType ( RuntimeException . class ) . isThrownBy ( ( ) - > {
AbstractReactiveWebServerFactory factory = getFactory ( ) ;
factory . setPort ( port ) ;
this . webServer = factory . getWebServer ( mock ( HttpHandler . class ) ) ;
this . webServer . start ( ) ;
} ) . satisfies ( ( ex ) - > handleExceptionCausedByBlockedPortOnPrimaryConnector ( ex , port ) ) ;
} ) ;
}
protected final void doWithBlockedPort ( AbstractServletWebServerFactoryTests . BlockedPortAction action )
throws IOException {
int port = SocketUtils . findAvailableTcpPort ( 40000 ) ;
ServerSocket serverSocket = new ServerSocket ( ) ;
for ( int i = 0 ; i < 10 ; i + + ) {
try {
serverSocket . bind ( new InetSocketAddress ( port ) ) ;
break ;
}
catch ( Exception ex ) {
}
}
try {
action . run ( port ) ;
}
finally {
serverSocket . close ( ) ;
}
}
protected void handleExceptionCausedByBlockedPortOnPrimaryConnector ( RuntimeException ex , int blockedPort ) {
assertThat ( ex ) . isInstanceOf ( PortInUseException . class ) ;
assertThat ( ( ( PortInUseException ) ex ) . getPort ( ) ) . isEqualTo ( blockedPort ) ;
}
}