3838public class MockMvcListener implements TestListener {
3939 private static final Set <String > DEFAULT_SCAN_PACKAGES =
4040 new HashSet <>(Arrays .asList ("modelengine.fit.server" , "modelengine.fit.http" ));
41+ private static final String TIMEOUT_PROPERTY_KEY = "fit.test.mockmvc.startup.timeout" ;
42+ private static final long DEFAULT_STARTUP_TIMEOUT = 30_000L ;
43+ private static final long MIN_STARTUP_TIMEOUT = 1_000L ;
44+ private static final long MAX_STARTUP_TIMEOUT = 600_000L ;
4145
4246 private final int port ;
4347
@@ -71,14 +75,60 @@ public void beforeTestClass(TestContext context) {
7175 }
7276 MockMvc mockMvc = new MockMvc (this .port );
7377 context .plugin ().container ().registry ().register (mockMvc );
78+ long timeout = this .getStartupTimeout ();
79+ long startTime = System .currentTimeMillis ();
7480 boolean started = this .isStarted (mockMvc );
7581 while (!started ) {
82+ long elapsed = System .currentTimeMillis () - startTime ;
83+ if (elapsed > timeout ) {
84+ throw new IllegalStateException (this .buildTimeoutErrorMessage (elapsed , this .port ));
85+ }
7686 ThreadUtils .sleep (100 );
7787 started = this .isStarted (mockMvc );
7888 }
7989 }
8090
81- private boolean isStarted (MockMvc mockMvc ) {
91+ private long getStartupTimeout () {
92+ String timeoutStr = System .getProperty (TIMEOUT_PROPERTY_KEY );
93+ if (StringUtils .isNotBlank (timeoutStr )) {
94+ try {
95+ long timeout = Long .parseLong (timeoutStr );
96+ if (timeout < MIN_STARTUP_TIMEOUT ) {
97+ return DEFAULT_STARTUP_TIMEOUT ;
98+ }
99+ if (timeout > MAX_STARTUP_TIMEOUT ) {
100+ return MAX_STARTUP_TIMEOUT ;
101+ }
102+ return timeout ;
103+ } catch (NumberFormatException e ) {
104+ return DEFAULT_STARTUP_TIMEOUT ;
105+ }
106+ }
107+ return DEFAULT_STARTUP_TIMEOUT ;
108+ }
109+
110+ private String buildTimeoutErrorMessage (long elapsed , int port ) {
111+ return StringUtils .format ("""
112+ Mock MVC server failed to start within {0}ms. [port={1}]
113+
114+ Possible causes:
115+ 1. Port {1} is already in use by another process
116+ 2. Network configuration issues
117+ 3. Server startup is slower than expected in this environment
118+
119+ Troubleshooting steps:
120+ - Check if port {1} is in use:
121+ * macOS/Linux: lsof -i :{1}
122+ * Windows: netstat -ano | findstr :{1}
123+ - Check server logs for detailed error messages
124+ - If running in a slow environment, increase timeout:
125+ mvn test -D{2}=60000""" ,
126+ elapsed ,
127+ port ,
128+ TIMEOUT_PROPERTY_KEY );
129+ }
130+
131+ protected boolean isStarted (MockMvc mockMvc ) {
82132 MockRequestBuilder builder = MockMvcRequestBuilders .get (MockController .PATH ).responseType (String .class );
83133 try (HttpClassicClientResponse <String > response = mockMvc .perform (builder )) {
84134 String content = response .textEntity ()
@@ -91,4 +141,4 @@ private boolean isStarted(MockMvc mockMvc) {
91141 return false ;
92142 }
93143 }
94- }
144+ }
0 commit comments