diff --git a/src/main/java/com/github/searls/jasmine/mojo/ServerMojo.java b/src/main/java/com/github/searls/jasmine/mojo/ServerMojo.java index 9f4a60a4d..712b2de90 100644 --- a/src/main/java/com/github/searls/jasmine/mojo/ServerMojo.java +++ b/src/main/java/com/github/searls/jasmine/mojo/ServerMojo.java @@ -19,6 +19,7 @@ */ package com.github.searls.jasmine.mojo; +import com.github.searls.jasmine.config.ImmutableServerConfiguration; import com.github.searls.jasmine.config.JasmineConfiguration; import com.github.searls.jasmine.config.ServerConfiguration; import com.github.searls.jasmine.io.RelativizesFilePaths; @@ -84,10 +85,19 @@ public ServerMojo(MavenProject mavenProject, } @Override - public void run(ServerConfiguration serverConfiguration, + public void run(ServerConfiguration requestedServerConfiguration, JasmineConfiguration jasmineConfiguration) throws Exception { ServerManager serverManager = serverManagerFactory.create(); - serverManager.start(serverConfiguration.getServerPort(), resourceHandlerConfigurator.createHandler(jasmineConfiguration)); + int assignedPort = serverManager.start( + requestedServerConfiguration.getServerPort(), + resourceHandlerConfigurator.createHandler(jasmineConfiguration) + ); + + ServerConfiguration serverConfiguration = ImmutableServerConfiguration.builder() + .from(requestedServerConfiguration) + .serverPort(assignedPort) + .build(); + LOGGER.info(this.buildServerInstructions(serverConfiguration, jasmineConfiguration)); openBrowser(serverConfiguration); serverManager.join(); diff --git a/src/main/java/com/github/searls/jasmine/server/ServerManager.java b/src/main/java/com/github/searls/jasmine/server/ServerManager.java index a7650b75f..f6bcbcb32 100644 --- a/src/main/java/com/github/searls/jasmine/server/ServerManager.java +++ b/src/main/java/com/github/searls/jasmine/server/ServerManager.java @@ -7,9 +7,9 @@ * 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 - * + * * http://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. @@ -22,10 +22,17 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; public class ServerManager { + private static final Logger LOGGER = LoggerFactory.getLogger(ServerManager.class); + private static final int ANY_PORT = 0; + public static final String FAILED_TO_BIND = "Failed to bind"; private final ServerConnector connector; @@ -40,7 +47,17 @@ public int start(Handler handler) throws Exception { public int start(int port, Handler handler) throws Exception { connector.setPort(port); connector.getServer().setHandler(handler); - connector.getServer().start(); + try { + connector.getServer().start(); + } catch (IOException e) { + if (ANY_PORT != port && e.getMessage().contains(FAILED_TO_BIND)) { + LOGGER.debug("Unable to start on port {}. Trying a random port.", port, e); + connector.setPort(ANY_PORT); + connector.getServer().start(); + } else { + throw e; + } + } return connector.getLocalPort(); } diff --git a/src/main/resources/instructions.template b/src/main/resources/instructions.template index 1e83da03e..9d8c233c1 100644 --- a/src/main/resources/instructions.template +++ b/src/main/resources/instructions.template @@ -3,7 +3,7 @@ Jasmine testing environment started! You can run your specs as you develop by visiting this URL in a web browser: - %s + %s The server will monitor these two directories for scripts that you add, remove, and change: diff --git a/src/test/java/com/github/searls/jasmine/mojo/ServerMojoTest.java b/src/test/java/com/github/searls/jasmine/mojo/ServerMojoTest.java index cefb2b42d..7468eb994 100644 --- a/src/test/java/com/github/searls/jasmine/mojo/ServerMojoTest.java +++ b/src/test/java/com/github/searls/jasmine/mojo/ServerMojoTest.java @@ -7,9 +7,9 @@ * 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 - * + * * http://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. @@ -19,6 +19,7 @@ */ package com.github.searls.jasmine.mojo; +import com.github.searls.jasmine.config.ImmutableServerConfiguration; import com.github.searls.jasmine.config.JasmineConfiguration; import com.github.searls.jasmine.config.ServerConfiguration; import com.github.searls.jasmine.io.RelativizesFilePaths; @@ -28,7 +29,6 @@ import com.github.searls.jasmine.server.ServerManagerFactory; import org.apache.maven.project.MavenProject; import org.eclipse.jetty.server.Handler; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; @@ -48,21 +48,12 @@ public class ServerMojoTest { @Mock private MavenProject mavenProject; - @Mock - private ServerConfiguration serverConfiguration; - @Mock private JasmineConfiguration jasmineConfiguration; @Mock private RelativizesFilePaths relativizesFilePaths; - @Mock - private File baseDir; - - @Mock - private File targetDir; - @Mock private File sourceDir; @@ -90,9 +81,8 @@ public class ServerMojoTest { @InjectMocks private ServerMojo subject; - @Before - public void before() throws Exception { - when(serverConfiguration.getServerPort()).thenReturn(PORT); + @Test + public void testRunMojo() throws Exception { when(jasmineConfiguration.getSources()).thenReturn(sources); when(jasmineConfiguration.getSpecs()).thenReturn(specs); @@ -101,18 +91,17 @@ public void before() throws Exception { when(specs.getDirectory()).thenReturn(specDir); when(serverManagerFactory.create()).thenReturn(serverManager); when(configurator.createHandler(jasmineConfiguration)).thenReturn(handler); + when(serverManager.start(PORT, handler)).thenReturn(PORT); + ServerConfiguration serverConfiguration = ImmutableServerConfiguration.builder() + .uriScheme("http") + .serverHostname("localhost") + .serverPort(PORT) + .build(); subject.run(serverConfiguration, jasmineConfiguration); - } - @Test - public void startsTheServer() throws Exception { verify(serverManager).start(PORT, handler); - } - - @Test - public void joinsTheServer() throws Exception { verify(serverManager).join(); } }