diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d0cc8c7f4..7495017a69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Usage: ./scripts/extract-changelog-for-version.sh 1.3.37 5 ``` ### 1.11-SNAPSHOT +* Fix #2003: check local port available on start remote-dev * Fix #1439: Add hint to use jkube.domain if createExternalUrls is used without domain * Fix #1459: Route Generation should support `8443` as default web port * Fix #1546: Migrate to JUnit5 testing framework diff --git a/jkube-kit/remote-dev/src/main/java/org/eclipse/jkube/kit/remotedev/RemoteDevelopmentService.java b/jkube-kit/remote-dev/src/main/java/org/eclipse/jkube/kit/remotedev/RemoteDevelopmentService.java index 805690529a..636a626773 100644 --- a/jkube-kit/remote-dev/src/main/java/org/eclipse/jkube/kit/remotedev/RemoteDevelopmentService.java +++ b/jkube-kit/remote-dev/src/main/java/org/eclipse/jkube/kit/remotedev/RemoteDevelopmentService.java @@ -62,12 +62,12 @@ public void stop() { private void checkEnvironment() { for (RemoteService remoteService : context.getRemoteDevelopmentConfig().getRemoteServices()) { - try (ServerSocket ignore = new ServerSocket(remoteService.getPort())) { + try (ServerSocket ignore = new ServerSocket(remoteService.getLocalPort())) { logger.debug("Local port '%s' for remote service '%s:%s' is available", remoteService.getLocalPort(), remoteService.getHostname(), remoteService.getPort()); } catch (Exception e) { throw new IllegalStateException( - "Local port '" + remoteService.getPort() + "' is already in use (" + remoteService.getHostname() + ")"); + "Local port '" + remoteService.getLocalPort() + "' is already in use (" + remoteService.getHostname() + ")"); } if (kubernetesClient.services().withName(remoteService.getHostname()).get() == null) { logger.warn("Service '%s' does not exist in the cluster, " + diff --git a/jkube-kit/remote-dev/src/test/java/org/eclipse/jkube/kit/remotedev/RemoteDevelopmentServiceTest.java b/jkube-kit/remote-dev/src/test/java/org/eclipse/jkube/kit/remotedev/RemoteDevelopmentServiceTest.java index 13ac70412d..b741e19062 100644 --- a/jkube-kit/remote-dev/src/test/java/org/eclipse/jkube/kit/remotedev/RemoteDevelopmentServiceTest.java +++ b/jkube-kit/remote-dev/src/test/java/org/eclipse/jkube/kit/remotedev/RemoteDevelopmentServiceTest.java @@ -17,14 +17,14 @@ import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; import org.eclipse.jkube.kit.common.KitLogger; +import org.eclipse.jkube.kit.common.util.IoUtil; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -35,6 +35,7 @@ class RemoteDevelopmentServiceTest { @SuppressWarnings("unused") private KubernetesClient kubernetesClient; private KitLogger logger; + private RemoteDevelopmentService remoteDevelopmentService; @BeforeEach void setUp() { @@ -42,6 +43,13 @@ void setUp() { logger = spy(new KitLogger.StdoutLogger()); } + @AfterEach + void tearDown() { + if (remoteDevelopmentService != null) { + remoteDevelopmentService.stop(); + } + } + @Test @DisplayName("service can be stopped before it is started") void canBeStoppedBeforeStart() { @@ -55,11 +63,11 @@ void canBeStoppedBeforeStart() { @DisplayName("service can be stopped multiple times before it is started") void canBeStoppedMultipleTimesBeforeStart() { // Given - final RemoteDevelopmentService remoteDev = new RemoteDevelopmentService( + remoteDevelopmentService = new RemoteDevelopmentService( logger, kubernetesClient, RemoteDevelopmentConfig.builder().build()); - remoteDev.stop(); + remoteDevelopmentService.stop(); // When - remoteDev.stop(); + remoteDevelopmentService.stop(); // Then verify(logger, times(2)).info("Remote development service stopped"); } @@ -67,18 +75,35 @@ void canBeStoppedMultipleTimesBeforeStart() { @Test @DisplayName("start initiates PortForwarder and KubernetesSshServiceForwarder") void startInitiatesChildProcesses() { - CompletableFuture future = null; - try { - // When - future = new RemoteDevelopmentService(logger, kubernetesClient, RemoteDevelopmentConfig.builder().build()) - .start(); - // Then - verify(logger, times(1)) - .debug("Starting Kubernetes SSH service forwarder..."); - verify(logger, times(1)) - .debug("Starting port forwarder..."); - } finally { - Optional.ofNullable(future).ifPresent(f -> f.cancel(true)); - } + // Given + remoteDevelopmentService = new RemoteDevelopmentService( + logger, kubernetesClient, RemoteDevelopmentConfig.builder().build()); + // When + remoteDevelopmentService.start(); + // Then + verify(logger, timeout(1000L).times(1)) + .debug("Starting Kubernetes SSH service forwarder..."); + verify(logger, timeout(1000L).times(1)) + .debug("Starting port forwarder..."); } + + @Test + @DisplayName("start initiates if LocalPort for remote service are available") + void startInitsIfLocalPortAvailable() { + RemoteService remoteService = RemoteService.builder() + .hostname("remote-host").localPort(IoUtil.getFreeRandomPort()).port(1234).build(); + remoteDevelopmentService = new RemoteDevelopmentService( + logger, kubernetesClient, RemoteDevelopmentConfig.builder().remoteService(remoteService).build()); + + // When + remoteDevelopmentService.start(); + + // Then + verify(logger, timeout(1000L).times(1)) + .debug("Local port '%s' for remote service '%s:%s' is available", + remoteService.getLocalPort(),remoteService.getHostname(),remoteService.getPort()); + verify(logger, timeout(1000L).times(1)) + .debug("Creating or replacing Kubernetes services for exposed ports from local environment"); + } + }