Skip to content

Commit

Permalink
Fix check local port available on start remote-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
juazugas committed Jan 14, 2023
1 parent 2cd5536 commit ddb9bd3
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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, " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIf;

import java.net.ServerSocket;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -67,18 +74,112 @@ void canBeStoppedMultipleTimesBeforeStart() {
@Test
@DisplayName("start initiates PortForwarder and KubernetesSshServiceForwarder")
void startInitiatesChildProcesses() {
RemoteDevelopmentConfig remoteDevelopmentConfig = RemoteDevelopmentConfig.builder().build();

// When
startDevelopmentServiceWithConfig(remoteDevelopmentConfig);

// Then
verify(logger, times(1))
.debug("Starting Kubernetes SSH service forwarder...");
verify(logger, times(1))
.debug("Starting port forwarder...");
}

@Test
@DisplayName("start initiates if LocalPort for remote service are available")
@DisabledIf(value = "unavailableLocalAndRemotePortCondition", disabledReason = "Testing ports not available")
void startInitsIfLocalPortAvailable() {
RemoteService remoteService = remoteServiceConfiguration();
RemoteDevelopmentConfig config = RemoteDevelopmentConfig.builder().remoteService(remoteService).build();

// When
startDevelopmentServiceWithConfig(config);

// Then
verify(logger, times(1))
.debug("Local port '%s' for remote service '%s:%s' is available",
remoteService.getLocalPort(),remoteService.getHostname(),remoteService.getPort());
verify(logger, times(1))
.debug("Starting port forwarder...");
}

@Test
@DisplayName("start fails if LocalPort for remote service is in use")
@DisabledIf(value = "unavailableLocalAndRemotePortCondition", disabledReason = "Testing ports not available")
void startFailsIfLocalPortInUse() {
RemoteService remoteService = remoteServiceConfiguration();
RemoteDevelopmentConfig config = RemoteDevelopmentConfig.builder().remoteService(remoteService).build();

Exception resultException = assertThrows(IllegalStateException.class, () ->{
try (ServerSocket localPortInUse = new ServerSocket(remoteService.getLocalPort())) {
// When
startDevelopmentServiceWithConfig(config);
}
});

// Then
verify(logger, never())
.debug("Local port '%s' for remote service '%s:%s' is available",
remoteService.getLocalPort(),remoteService.getHostname(),remoteService.getPort());
assertThat(resultException.getMessage(), containsString(
"Local port '" + remoteService.getLocalPort() + "' is already in use (" + remoteService.getHostname() + ")"));
}

@Test
@DisplayName("start initiates if Local Port for remote service are available but remote Port used locally")
@DisabledIf(value = "unavailableLocalAndRemotePortCondition", disabledReason = "Testing ports not available")
void startInitsIfLocalPortAvailableButRemotePortInUse() {
RemoteService remoteService = remoteServiceConfiguration();
RemoteDevelopmentConfig config = RemoteDevelopmentConfig.builder().remoteService(remoteService).build();

assertDoesNotThrow(() -> {
try (ServerSocket remotePortInUseLocally = new ServerSocket(remoteService.getPort())) {
// When
startDevelopmentServiceWithConfig(config);
}
});

// Then
verify(logger, times(1))
.debug("Local port '%s' for remote service '%s:%s' is available",
remoteService.getLocalPort(),remoteService.getHostname(),remoteService.getPort());
}

private void startDevelopmentServiceWithConfig(RemoteDevelopmentConfig remoteDevelopmentConfig) {
CompletableFuture<Void> future = null;
try {
// When
future = new RemoteDevelopmentService(logger, kubernetesClient, RemoteDevelopmentConfig.builder().build())
future = new RemoteDevelopmentService(logger, kubernetesClient, remoteDevelopmentConfig)
.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));
}
}

private RemoteService remoteServiceConfiguration() {
String remoteHostname = "remote-host";
int remotePort = 61235;
int freeLocalPort = 61234;
return RemoteService.builder()
.hostname(remoteHostname).localPort(freeLocalPort).port(remotePort).build();
}

boolean unavailableLocalAndRemotePortCondition() {

RemoteService service = remoteServiceConfiguration();

try (ServerSocket ignore = new ServerSocket(service.getLocalPort())) {

} catch (Exception e) {
return true;
}

try (ServerSocket ignore = new ServerSocket(service.getPort())) {

} catch (Exception e) {
return true;
}

return false;
}
}

0 comments on commit ddb9bd3

Please sign in to comment.