/*******************************************************************************
* 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 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;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.eclipse.che.plugin.docker.machine.ServerEvaluationStrategy.SERVER_CONF_LABEL_PATH_KEY;
import static org.eclipse.che.plugin.docker.machine.ServerEvaluationStrategy.SERVER_CONF_LABEL_PROTOCOL_KEY;
import static org.eclipse.che.plugin.docker.machine.ServerEvaluationStrategy.SERVER_CONF_LABEL_REF_KEY;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
/**
* @author Angel Misevski <amisevsk@redhat.com>
* @author Alexander Garagatyi
*/
@Listeners(MockitoTestNGListener.class)
public class ServerEvaluationStrategyTest {
private static final String ALL_IP_ADDRESS = "0.0.0.0";
private static final String DEFAULT_HOSTNAME = "localhost";
@Mock
private ContainerInfo containerInfo;
@Mock
private ContainerConfig containerConfig;
@Mock
private NetworkSettings networkSettings;
private Map<String, ServerConfImpl> serverConfs;
private Map<String, String> labels;
private ServerEvaluationStrategy strategy;
@BeforeMethod
public void setUp() {
strategy = spy(new TestServerEvaluationStrategyImpl());
serverConfs = new HashMap<>();
labels = new HashMap<>();
when(containerInfo.getConfig()).thenReturn(containerConfig);
when(containerInfo.getNetworkSettings()).thenReturn(networkSettings);
when(containerConfig.getLabels()).thenReturn(labels);
}
@Test
public void shouldConvertAddressAndExposedPortsInMapOfExposedPortToAddressPort() throws Exception {
// given
Map<String, List<PortBinding>> ports = new HashMap<>();
ports.put("8080/tcp", Collections.singletonList(new PortBinding().withHostIp(ALL_IP_ADDRESS)
.withHostPort("32100")));
ports.put("9090/udp", Collections.singletonList(new PortBinding().withHostIp(ALL_IP_ADDRESS)
.withHostPort("32101")));
Map<String, String> expected = new HashMap<>();
expected.put("8080/tcp", DEFAULT_HOSTNAME + ":" + "32100");
expected.put("9090/udp", DEFAULT_HOSTNAME + ":" + "32101");
// when
Map<String, String> actual = strategy.getExposedPortsToAddressPorts(DEFAULT_HOSTNAME, ports);
// then
assertEquals(actual, expected);
}
@Test
public void shouldIgnoreMultiplePortBindingEntries() throws Exception {
// given
Map<String, List<PortBinding>> ports = new HashMap<>();
ports.put("8080/tcp", Arrays.asList(new PortBinding().withHostIp(ALL_IP_ADDRESS)
.withHostPort("32100"),
new PortBinding().withHostIp(DEFAULT_HOSTNAME)
.withHostPort("32102")));
ports.put("9090/udp", Arrays.asList(new PortBinding().withHostIp(ALL_IP_ADDRESS)
.withHostPort("32101"),
new PortBinding().withHostIp(ALL_IP_ADDRESS)
.withHostPort("32103"),
new PortBinding().withHostIp(DEFAULT_HOSTNAME)
.withHostPort("32104")));
Map<String, String> expected = new HashMap<>();
expected.put("8080/tcp", DEFAULT_HOSTNAME + ":" + "32100");
expected.put("9090/udp", DEFAULT_HOSTNAME + ":" + "32101");
// when
Map<String, String> actual = strategy.getExposedPortsToAddressPorts(DEFAULT_HOSTNAME, ports);
// then
assertEquals(actual, expected);
}
@Test
public void shouldReturnServerForEveryExposedPort() throws Exception {
// given
Map<String, List<PortBinding>> ports = prepareStrategyAndContainerInfoMocks();
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo,
DEFAULT_HOSTNAME,
serverConfs);
// then
assertEquals(servers.keySet(), ports.keySet());
}
@Test
public void shouldAddDefaultReferenceIfReferenceIsNotSet() throws Exception {
// given
prepareStrategyAndContainerInfoMocks();
final HashMap<String, ServerImpl> expectedServers = new HashMap<>();
expectedServers.put("8080/tcp", new ServerImpl("Server-8080-tcp",
null,
DEFAULT_HOSTNAME + ":32100",
null,
new ServerPropertiesImpl(null, DEFAULT_HOSTNAME + ":32100",
null)));
expectedServers.put("9090/udp", new ServerImpl("Server-9090-udp",
null,
DEFAULT_HOSTNAME + ":32101",
null,
new ServerPropertiesImpl(null, DEFAULT_HOSTNAME + ":32101",
null)));
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo, DEFAULT_HOSTNAME, serverConfs);
// then
assertEquals(servers, expectedServers);
}
@Test
public void shouldAddRefUrlProtocolPathToServerFromMachineConfig() throws Exception {
// given
prepareStrategyAndContainerInfoMocks();
serverConfs.put("8080/tcp", new ServerConfImpl("myserv1", "8080/tcp", "http", null));
serverConfs.put("9090/udp", new ServerConfImpl("myserv2", "9090/udp", "dhcp", "/some/path"));
final HashMap<String, ServerImpl> expectedServers = new HashMap<>();
expectedServers.put("8080/tcp", new ServerImpl("myserv1",
"http",
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME + ":32100",
new ServerPropertiesImpl(null,
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME +
":32100")));
expectedServers.put("9090/udp", new ServerImpl("myserv2",
"dhcp",
DEFAULT_HOSTNAME + ":32101",
"dhcp://" + DEFAULT_HOSTNAME + ":32101/some/path",
new ServerPropertiesImpl("/some/path",
DEFAULT_HOSTNAME + ":32101",
"dhcp://" + DEFAULT_HOSTNAME +
":32101/some/path")));
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo, DEFAULT_HOSTNAME, serverConfs);
// then
assertEquals(servers, expectedServers);
}
@Test
public void shouldAllowToUsePortFromMachineConfigWithoutTransportProtocol() throws Exception {
// given
prepareStrategyAndContainerInfoMocks();
serverConfs.put("8080", new ServerConfImpl("myserv1", "8080", "http", "/some"));
serverConfs.put("9090/udp", new ServerConfImpl("myserv1-tftp", "9090/udp", "tftp", "/path"));
final HashMap<String, ServerImpl> expectedServers = new HashMap<>();
expectedServers.put("8080/tcp", new ServerImpl("myserv1",
"http",
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME + ":32100/some",
new ServerPropertiesImpl("/some",
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME +
":32100/some")));
expectedServers.put("9090/udp", new ServerImpl("myserv1-tftp",
"tftp",
DEFAULT_HOSTNAME + ":32101",
"tftp://" + DEFAULT_HOSTNAME + ":32101/path",
new ServerPropertiesImpl("/path",
DEFAULT_HOSTNAME + ":32101",
"tftp://" + DEFAULT_HOSTNAME +
":32101/path")));
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo, DEFAULT_HOSTNAME, serverConfs);
// then
assertEquals(servers, expectedServers);
}
@Test
public void shouldAddRefUrlPathToServerFromLabels() throws Exception {
// given
Map<String, List<PortBinding>> ports = prepareStrategyAndContainerInfoMocks();
Map<String, String> labels = new HashMap<>();
when(containerConfig.getLabels()).thenReturn(labels);
ports.put("8080/tcp", Collections.singletonList(new PortBinding().withHostIp(ALL_IP_ADDRESS)
.withHostPort("32100")));
ports.put("9090/udp", Collections.singletonList(new PortBinding().withHostIp(ALL_IP_ADDRESS)
.withHostPort("32101")));
labels.put(String.format(SERVER_CONF_LABEL_REF_KEY, "8080/tcp"), "myserv1");
labels.put(String.format(SERVER_CONF_LABEL_PROTOCOL_KEY, "8080/tcp"), "http");
labels.put(String.format(SERVER_CONF_LABEL_PATH_KEY, "8080/tcp"), "/some/path");
labels.put(String.format(SERVER_CONF_LABEL_PROTOCOL_KEY, "9090/udp"), "dhcp");
labels.put(String.format(SERVER_CONF_LABEL_PATH_KEY, "9090/udp"), "some/path");
final HashMap<String, ServerImpl> expectedServers = new HashMap<>();
expectedServers.put("8080/tcp", new ServerImpl("myserv1",
"http",
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME + ":32100/some/path",
new ServerPropertiesImpl("/some/path",
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME +
":32100/some/path")));
expectedServers.put("9090/udp", new ServerImpl("Server-9090-udp",
"dhcp",
DEFAULT_HOSTNAME + ":32101",
"dhcp://" + DEFAULT_HOSTNAME + ":32101/some/path",
new ServerPropertiesImpl("some/path",
DEFAULT_HOSTNAME + ":32101",
"dhcp://" + DEFAULT_HOSTNAME +
":32101/some/path")));
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo, DEFAULT_HOSTNAME, serverConfs);
// then
assertEquals(servers, expectedServers);
}
@Test
public void shouldAllowToUsePortFromDockerLabelsWithoutTransportProtocol() throws Exception {
// given
prepareStrategyAndContainerInfoMocks();
labels.put(String.format(SERVER_CONF_LABEL_REF_KEY, "8080"), "myserv1");
labels.put(String.format(SERVER_CONF_LABEL_PROTOCOL_KEY, "8080"), "http");
labels.put(String.format(SERVER_CONF_LABEL_REF_KEY, "9090/udp"), "myserv1-tftp");
labels.put(String.format(SERVER_CONF_LABEL_PROTOCOL_KEY, "9090/udp"), "tftp");
final HashMap<String, ServerImpl> expectedServers = new HashMap<>();
expectedServers.put("8080/tcp", new ServerImpl("myserv1",
"http",
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME + ":32100",
new ServerPropertiesImpl(null,
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME +
":32100")));
expectedServers.put("9090/udp", new ServerImpl("myserv1-tftp",
"tftp",
DEFAULT_HOSTNAME + ":32101",
"tftp://" + DEFAULT_HOSTNAME + ":32101",
new ServerPropertiesImpl(null,
DEFAULT_HOSTNAME + ":32101",
"tftp://" + DEFAULT_HOSTNAME +
":32101")));
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo, DEFAULT_HOSTNAME, serverConfs);
// then
assertEquals(servers, expectedServers);
}
@Test
public void shouldPreferMachineConfOverDockerLabels() throws Exception {
// given
prepareStrategyAndContainerInfoMocks();
labels.put(String.format(SERVER_CONF_LABEL_REF_KEY, "8080/tcp"), "myserv1label");
labels.put(String.format(SERVER_CONF_LABEL_PROTOCOL_KEY, "8080/tcp"), "https");
labels.put(String.format(SERVER_CONF_LABEL_REF_KEY, "9090/udp"), "myserv2label");
labels.put(String.format(SERVER_CONF_LABEL_PROTOCOL_KEY, "9090/udp"), "dhcp");
labels.put(String.format(SERVER_CONF_LABEL_PATH_KEY, "9090/udp"), "/path");
serverConfs.put("8080/tcp", new ServerConfImpl("myserv1conf", "8080/tcp", "http", null));
final HashMap<String, ServerImpl> expectedServers = new HashMap<>();
expectedServers.put("8080/tcp", new ServerImpl("myserv1conf",
"http",
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME + ":32100",
new ServerPropertiesImpl(null,
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME +
":32100")));
expectedServers.put("9090/udp", new ServerImpl("myserv2label",
"dhcp",
DEFAULT_HOSTNAME + ":32101",
"dhcp://" + DEFAULT_HOSTNAME + ":32101/path",
new ServerPropertiesImpl("/path",
DEFAULT_HOSTNAME + ":32101",
"dhcp://" + DEFAULT_HOSTNAME +
":32101/path")));
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo, DEFAULT_HOSTNAME, serverConfs);
// then
assertEquals(servers, expectedServers);
}
@Test
public void shouldAddPathCorrectlyWithoutLeadingSlash() throws Exception {
// given
prepareStrategyAndContainerInfoMocks();
serverConfs.put("8080", new ServerConfImpl("myserv1", "8080", "http", "some"));
serverConfs.put("9090/udp", new ServerConfImpl("myserv1-tftp", "9090/udp", "tftp", "some/path"));
final HashMap<String, ServerImpl> expectedServers = new HashMap<>();
expectedServers.put("8080/tcp", new ServerImpl("myserv1",
"http",
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME + ":32100/some",
new ServerPropertiesImpl("some",
DEFAULT_HOSTNAME + ":32100",
"http://" + DEFAULT_HOSTNAME +
":32100/some")));
expectedServers.put("9090/udp", new ServerImpl("myserv1-tftp",
"tftp",
DEFAULT_HOSTNAME + ":32101",
"tftp://" + DEFAULT_HOSTNAME + ":32101/some/path",
new ServerPropertiesImpl("some/path",
DEFAULT_HOSTNAME + ":32101",
"tftp://" + DEFAULT_HOSTNAME +
":32101/some/path")));
// when
final Map<String, ServerImpl> servers = strategy.getServers(containerInfo, DEFAULT_HOSTNAME, serverConfs);
// then
assertEquals(servers, expectedServers);
}
private Map<String, List<PortBinding>> prepareStrategyAndContainerInfoMocks() {
Map<String, List<PortBinding>> ports = new HashMap<>();
ports.put("8080/tcp", Collections.singletonList(new PortBinding().withHostIp(ALL_IP_ADDRESS)
.withHostPort("32100")));
ports.put("9090/udp", Collections.singletonList(new PortBinding().withHostIp(ALL_IP_ADDRESS)
.withHostPort("32101")));
when(networkSettings.getPorts()).thenReturn(ports);
Map<String, String> exposedPortsToAddressPorts =
strategy.getExposedPortsToAddressPorts(DEFAULT_HOSTNAME, ports);
when(strategy.getExternalAddressesAndPorts(containerInfo, DEFAULT_HOSTNAME))
.thenReturn(exposedPortsToAddressPorts);
when(strategy.getInternalAddressesAndPorts(containerInfo, DEFAULT_HOSTNAME))
.thenReturn(exposedPortsToAddressPorts);
return ports;
}
private static class TestServerEvaluationStrategyImpl extends ServerEvaluationStrategy {
@Override
protected Map<String, String> getInternalAddressesAndPorts(ContainerInfo containerInfo,
String internalAddress) {
return null;
}
@Override
protected Map<String, String> getExternalAddressesAndPorts(ContainerInfo containerInfo,
String internalAddress) {
return null;
}
}
}