/*******************************************************************************
* Copyright (c) 2016-2017 Red Hat Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.plugin.docker.machine;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.che.api.core.model.machine.MachineConfig;
import org.eclipse.che.api.machine.server.model.impl.ServerConfImpl;
import org.eclipse.che.api.machine.server.model.impl.ServerImpl;
import org.eclipse.che.api.machine.server.model.impl.ServerPropertiesImpl;
import org.eclipse.che.plugin.docker.client.json.ContainerConfig;
import org.eclipse.che.plugin.docker.client.json.ContainerInfo;
import org.eclipse.che.plugin.docker.client.json.NetworkSettings;
import org.eclipse.che.plugin.docker.client.json.PortBinding;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners(MockitoTestNGListener.class)
public class LocalDockerServerEvaluationStrategyTest {
private static final String CHE_DOCKER_IP = "container-host.com";
private static final String CHE_DOCKER_IP_EXTERNAL = "container-host-ext.com";
private static final String ALL_IP_ADDRESS = "0.0.0.0";
private static final String CONTAINERINFO_GATEWAY = "172.17.0.1";
private static final String CONTAINERINFO_IP_ADDRESS = "172.17.0.200";
private static final String DEFAULT_HOSTNAME = "localhost";
@Mock
private ContainerInfo containerInfo;
@Mock
private MachineConfig machineConfig;
@Mock
private ContainerConfig containerConfig;
@Mock
private NetworkSettings networkSettings;
private ServerEvaluationStrategy strategy;
private Map<String, ServerConfImpl> serverConfs;
private Map<String, List<PortBinding>> ports;
@BeforeMethod
public void setUp() {
serverConfs = new HashMap<>();
serverConfs.put("4301/tcp", new ServerConfImpl("sysServer1-tcp", "4301/tcp", "http", "/some/path1"));
serverConfs.put("4305/udp", new ServerConfImpl("devSysServer1-udp", "4305/udp", null, "some/path4"));
ports = new HashMap<>();
ports.put("4301/tcp", Collections.singletonList(new PortBinding().withHostIp(ALL_IP_ADDRESS )
.withHostPort("32100")));
ports.put("4305/udp", Collections.singletonList(new PortBinding().withHostIp(ALL_IP_ADDRESS )
.withHostPort("32103")));
when(containerInfo.getNetworkSettings()).thenReturn(networkSettings);
when(networkSettings.getGateway()).thenReturn(CONTAINERINFO_GATEWAY);
when(networkSettings.getIpAddress()).thenReturn(CONTAINERINFO_IP_ADDRESS);
when(networkSettings.getPorts()).thenReturn(ports);
when(containerInfo.getConfig()).thenReturn(containerConfig);
when(containerConfig.getLabels()).thenReturn(Collections.emptyMap());
}
/**
* Test: local docker strategy should use internal container address when it can.
* @throws Exception
*/
@Test
public void localDockerStrategyShouldUseContainerIpAddressWhenAvailable() throws Exception {
// given
strategy = new LocalDockerServerEvaluationStrategy(null, null);
final Map<String, ServerImpl> expectedServers = getExpectedServers(CONTAINERINFO_GATEWAY,
CONTAINERINFO_IP_ADDRESS,
true);
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo,
DEFAULT_HOSTNAME,
serverConfs);
// then
assertEquals(servers, expectedServers);
}
/**
* Test: local docker strategy should ignore che.docker.ip property.
* @throws Exception
*/
@Test
public void localDockerStrategyShouldIgnoreCheDockerIpProperty() throws Exception {
// given
strategy = new LocalDockerServerEvaluationStrategy(CHE_DOCKER_IP, null);
final Map<String, ServerImpl> expectedServers = getExpectedServers(CONTAINERINFO_GATEWAY,
CONTAINERINFO_IP_ADDRESS,
true);
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo,
DEFAULT_HOSTNAME,
serverConfs);
// then
assertEquals(servers, expectedServers);
}
/**
* Test: local docker strategy should use passed parameter internalHost when containerInfo.getIpAddress() is null.
* @throws Exception
*/
@Test
public void localDockerStrategyShouldUseProvidedInternalHostWhenContainerInfoUnavailable() throws Exception {
// given
strategy = new LocalDockerServerEvaluationStrategy(CHE_DOCKER_IP, null);
when(networkSettings.getIpAddress()).thenReturn("");
final Map<String, ServerImpl> expectedServers = getExpectedServers(CONTAINERINFO_GATEWAY,
DEFAULT_HOSTNAME,
false);
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo,
DEFAULT_HOSTNAME,
serverConfs);
// then
assertEquals(servers, expectedServers);
}
/**
* Test: local docker strategy should let che.docker.ip.external take precedence if available
* @throws Exception
*/
@Test
public void localDockerStrategyShouldUseExternalDockerIpPropertyIfAvailable() throws Exception {
// given
strategy = new LocalDockerServerEvaluationStrategy(CHE_DOCKER_IP, CHE_DOCKER_IP_EXTERNAL);
final Map<String, ServerImpl> expectedServers = getExpectedServers(CHE_DOCKER_IP_EXTERNAL,
CONTAINERINFO_IP_ADDRESS,
true);
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo,
DEFAULT_HOSTNAME,
serverConfs);
// then
assertEquals(servers, expectedServers);
}
/**
* Test: local docker strategy should use containerInfo for externalHost if property is null
* @throws Exception
*/
@Test
public void localDockerStrategyShouldUseContainerInfoForExternalWhenPropertyIsNull() throws Exception {
// given
strategy = new LocalDockerServerEvaluationStrategy(CHE_DOCKER_IP, null);
final Map<String, ServerImpl> expectedServers = getExpectedServers(CONTAINERINFO_GATEWAY,
CONTAINERINFO_IP_ADDRESS,
true);
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo,
DEFAULT_HOSTNAME,
serverConfs);
// then
assertEquals(servers, expectedServers);
}
/**
* Test: local docker strategy should use containerInfo for externalHost if property is null
* @throws Exception
*/
@Test
public void localDockerStrategyShouldUseInternalHostWhenContainerInfoIsUnavailable() throws Exception {
// given
strategy = new LocalDockerServerEvaluationStrategy(CHE_DOCKER_IP, null);
when(networkSettings.getGateway()).thenReturn("");
final Map<String, ServerImpl> expectedServers = getExpectedServers(DEFAULT_HOSTNAME,
CONTAINERINFO_IP_ADDRESS,
true);
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo,
DEFAULT_HOSTNAME,
serverConfs);
// then
assertEquals(servers, expectedServers);
}
private Map<String, ServerImpl> getExpectedServers(String externalAddress,
String internalAddress,
boolean useExposedPorts) {
String port1;
String port2;
if (useExposedPorts) {
port1 = ":4301";
port2 = ":4305";
} else {
port1 = ":32100";
port2 = ":32103";
}
Map<String, ServerImpl> expectedServers = new HashMap<>();
expectedServers.put("4301/tcp", new ServerImpl("sysServer1-tcp",
"http",
externalAddress + ":32100",
"http://" + externalAddress + ":32100/some/path1",
new ServerPropertiesImpl("/some/path1",
internalAddress + port1,
"http://" + internalAddress + port1 + "/some/path1")));
expectedServers.put("4305/udp", new ServerImpl("devSysServer1-udp",
null,
externalAddress + ":32103",
null,
new ServerPropertiesImpl("some/path4",
internalAddress + port2,
null)));
return expectedServers;
}
}