/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.plugin.docker.machine;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.model.machine.Channels;
import org.eclipse.che.api.core.model.machine.MachineSource;
import org.eclipse.che.api.core.model.machine.MachineState;
import org.eclipse.che.api.core.model.machine.MachineStatus;
import org.eclipse.che.api.core.model.machine.Recipe;
import org.eclipse.che.api.core.util.LineConsumer;
import org.eclipse.che.api.machine.server.exception.MachineException;
import org.eclipse.che.api.machine.server.model.impl.ChannelsImpl;
import org.eclipse.che.api.machine.server.model.impl.LimitsImpl;
import org.eclipse.che.api.machine.server.model.impl.MachineSourceImpl;
import org.eclipse.che.api.machine.server.model.impl.MachineStateImpl;
import org.eclipse.che.api.machine.server.recipe.RecipeImpl;
import org.eclipse.che.commons.env.EnvironmentContext;
import org.eclipse.che.commons.user.UserImpl;
import org.eclipse.che.plugin.docker.client.DockerConnector;
import org.eclipse.che.plugin.docker.client.DockerConnectorConfiguration;
import org.eclipse.che.plugin.docker.client.ProgressMonitor;
import org.eclipse.che.plugin.docker.client.dto.AuthConfigs;
import org.eclipse.che.plugin.docker.client.json.ContainerConfig;
import org.eclipse.che.plugin.docker.client.json.ContainerCreated;
import org.eclipse.che.plugin.docker.client.json.HostConfig;
import org.eclipse.che.plugin.docker.machine.node.DockerNode;
import org.eclipse.che.plugin.docker.machine.node.WorkspaceFolderPathProvider;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static java.util.Arrays.asList;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.anyVararg;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@Listeners(MockitoTestNGListener.class)
public class DockerInstanceProviderTest {
private static final String PROJECT_FOLDER_PATH = "/projects";
private static final String CONTAINER_ID = "containerId";
private static final String WORKSPACE_ID = "wsId";
private static final String DISPLAY_NAME = "DisplayName";
private static final String USER_TOKEN = "userToken";
@Mock
private DockerConnector dockerConnector;
@Mock
private DockerConnectorConfiguration dockerConnectorConfiguration;
@Mock
private DockerMachineFactory dockerMachineFactory;
@Mock
private DockerInstanceStopDetector dockerInstanceStopDetector;
@Mock
private DockerNode dockerNode;
@Mock
private WorkspaceFolderPathProvider workspaceFolderPathProvider;
private DockerInstanceProvider dockerInstanceProvider;
@BeforeMethod
public void setUp() throws Exception {
when(dockerConnectorConfiguration.getDockerHostIp()).thenReturn("123.123.123.123");
dockerInstanceProvider = spy(new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.<ServerConf>emptySet(),
Collections.<ServerConf>emptySet(),
Collections.<String>emptySet(),
Collections.<String>emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet()));
EnvironmentContext envCont = new EnvironmentContext();
envCont.setUser(new UserImpl("user", "userId", USER_TOKEN, null, false));
EnvironmentContext.setCurrent(envCont);
when(dockerMachineFactory.createNode(anyString(), anyString())).thenReturn(dockerNode);
when(dockerConnector.createContainer(any(ContainerConfig.class), anyString()))
.thenReturn(new ContainerCreated(CONTAINER_ID, new String[0]));
}
@AfterMethod
public void tearDown() throws Exception {
EnvironmentContext.reset();
}
@Test
public void shouldReturnTypeDocker() throws Exception {
assertEquals(dockerInstanceProvider.getType(), "docker");
}
@Test
public void shouldReturnRecipeTypesDockerfile() throws Exception {
assertEquals(dockerInstanceProvider.getRecipeTypes(), Collections.singleton("Dockerfile"));
}
// TODO add tests for instance snapshot removal
@Test
public void shouldBuildDockerfileOnInstanceCreationFromRecipe() throws Exception {
String generatedContainerId = "genContainerId";
doReturn(generatedContainerId).when(dockerInstanceProvider).generateContainerName(eq(WORKSPACE_ID), eq(DISPLAY_NAME));
createInstanceFromRecipe();
verify(dockerConnector).buildImage(eq("eclipse-che/" + generatedContainerId),
any(ProgressMonitor.class),
any(AuthConfigs.class),
anyBoolean(),
anyVararg());
}
@Test
public void shouldPullDockerImageOnInstanceCreationFromSnapshot() throws Exception {
String repo = "repo";
String tag = "tag";
String registry = "localhost:1234";
createInstanceFromSnapshot(repo, tag, registry);
verify(dockerConnector).pull(eq(repo), eq(tag), eq(registry), any(ProgressMonitor.class));
}
@Test
public void shouldReTagBuiltImageWithPredictableOnInstanceCreationFromRecipe() throws Exception {
String generatedContainerId = "genContainerId";
doReturn(generatedContainerId).when(dockerInstanceProvider).generateContainerName(WORKSPACE_ID, DISPLAY_NAME);
String repo = "repo1";
String registry = "registry1";
String tag = "tag1";
createInstanceFromSnapshot(repo, tag, registry);
verify(dockerConnector).tag(eq(registry + "/" + repo + ":" + tag), eq("eclipse-che/" + generatedContainerId), eq(null));
verify(dockerConnector).removeImage(eq(registry + "/" + repo + ":" + tag), eq(false));
}
@Test
public void shouldCreateContainerOnInstanceCreationFromRecipe() throws Exception {
String generatedContainerId = "genContainerId";
doReturn(generatedContainerId).when(dockerInstanceProvider).generateContainerName(WORKSPACE_ID, DISPLAY_NAME);
createInstanceFromRecipe();
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(argumentCaptor.getValue().getImage(), "eclipse-che/" + generatedContainerId);
}
@Test
public void shouldStartContainerOnCreateInstanceFromRecipe() throws Exception {
createInstanceFromRecipe();
verify(dockerConnector).startContainer(eq(CONTAINER_ID), any(HostConfig.class));
}
@Test
public void shouldCreateContainerOnInstanceCreationFromSnapshot() throws Exception {
String generatedContainerId = "genContainerId";
doReturn(generatedContainerId).when(dockerInstanceProvider).generateContainerName(WORKSPACE_ID, DISPLAY_NAME);
createInstanceFromSnapshot();
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(argumentCaptor.getValue().getImage(), "eclipse-che/" + generatedContainerId);
}
@Test
public void shouldStartContainerOnCreateInstanceFromSnapshot() throws Exception {
createInstanceFromSnapshot();
verify(dockerConnector).startContainer(eq(CONTAINER_ID), any(HostConfig.class));
}
@Test
public void shouldCallCreationDockerInstanceWithFactoryOnCreateInstanceFromSnapshot() throws Exception {
String generatedContainerId = "genContainerId";
doReturn(generatedContainerId).when(dockerInstanceProvider).generateContainerName(eq(WORKSPACE_ID), eq(DISPLAY_NAME));
final MachineSourceImpl machineSource = new MachineSourceImpl("type", "location");
final MachineStateImpl machineState = new MachineStateImpl(false,
"machineType",
DISPLAY_NAME,
machineSource,
new LimitsImpl(64),
"machineId",
new ChannelsImpl("chan1", "chan2"),
WORKSPACE_ID,
"userId",
"envName",
MachineStatus.CREATING);
createInstanceFromSnapshot(machineState);
verify(dockerMachineFactory).createInstance(eq(machineState),
eq(CONTAINER_ID),
eq("eclipse-che/" + generatedContainerId),
eq(dockerNode),
any(LineConsumer.class));
}
@Test
public void shouldCallCreationDockerInstanceWithFactoryOnCreateInstanceFromRecipe() throws Exception {
String generatedContainerId = "genContainerId";
doReturn(generatedContainerId).when(dockerInstanceProvider).generateContainerName(eq(WORKSPACE_ID), eq(DISPLAY_NAME));
final MachineSourceImpl machineSource = new MachineSourceImpl("type", "location");
final Recipe recipe = new RecipeImpl().withType("Dockerfile").withScript("FROM busybox");
final MachineStateImpl machineState = new MachineStateImpl(false,
"machineType",
DISPLAY_NAME,
machineSource,
new LimitsImpl(64),
"machineId",
new ChannelsImpl("chan1", "chan2"),
WORKSPACE_ID,
"userId",
"envName",
MachineStatus.CREATING);
createInstanceFromRecipe(recipe, machineState);
verify(dockerMachineFactory).createInstance(eq(machineState),
eq(CONTAINER_ID),
eq("eclipse-che/" + generatedContainerId),
eq(dockerNode),
any(LineConsumer.class));
}
@Test
public void shouldBindWorkspaceOnDevInstanceCreationFromRecipe() throws Exception {
final boolean isDev = true;
final String hostProjectsFolder = "/tmp/projects";
when(dockerNode.getProjectsFolder()).thenReturn(hostProjectsFolder);
createInstanceFromRecipe(isDev, WORKSPACE_ID);
verify(dockerNode).bindWorkspace();
}
@Test
public void shouldBindWorkspaceOnDevInstanceCreationFromSnapshot() throws Exception {
final boolean isDev = true;
final String hostProjectsFolder = "/tmp/projects";
when(dockerNode.getProjectsFolder()).thenReturn(hostProjectsFolder);
createInstanceFromSnapshot(isDev, WORKSPACE_ID);
verify(dockerNode).bindWorkspace();
}
@Test
public void shouldNotBindWorkspaceOnNonDevInstanceCreationFromRecipe() throws Exception {
final boolean isDev = false;
when(dockerNode.getProjectsFolder()).thenReturn("/tmp/projects");
createInstanceFromRecipe(isDev, WORKSPACE_ID);
verify(dockerNode, never()).bindWorkspace();
}
@Test
public void shouldNotBindWorkspaceOnNonDevInstanceCreationFromSnapshot() throws Exception {
final boolean isDev = false;
when(dockerNode.getProjectsFolder()).thenReturn("/tmp/projects");
createInstanceFromSnapshot(isDev, WORKSPACE_ID);
verify(dockerNode, never()).bindWorkspace();
}
@Test
public void shouldSetMemorySizeInContainersOnInstanceCreationFromRecipe() throws Exception {
int memorySizeMB = 234;
createInstanceFromRecipe(memorySizeMB);
ArgumentCaptor<ContainerConfig> createContainerCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(createContainerCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
// docker accepts memory size in bytes
assertEquals(createContainerCaptor.getValue().getHostConfig().getMemory(), memorySizeMB * 1024 * 1024);
}
@Test
public void shouldSetMemorySizeInContainersOnInstanceCreationFromSnapshot() throws Exception {
int memorySizeMB = 234;
createInstanceFromSnapshot(memorySizeMB);
ArgumentCaptor<ContainerConfig> createContainerCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(createContainerCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
// docker accepts memory size in bytes
assertEquals(createContainerCaptor.getValue().getHostConfig().getMemory(), memorySizeMB * 1024 * 1024);
}
@Test
public void shouldDisableSwapMemorySizeInContainersOnInstanceCreationFromRecipe() throws Exception {
createInstanceFromRecipe();
ArgumentCaptor<ContainerConfig> createContainerCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(createContainerCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
assertEquals(createContainerCaptor.getValue().getHostConfig().getMemorySwap(), -1);
}
@Test
public void shouldDisableSwapMemorySizeInContainersOnInstanceCreationFromSnapshot() throws Exception {
createInstanceFromSnapshot();
ArgumentCaptor<ContainerConfig> createContainerCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(createContainerCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
assertEquals(createContainerCaptor.getValue().getHostConfig().getMemorySwap(), -1);
}
@Test
public void shouldAddCommonAndDevLabelsToContainerOnDevInstanceCreationFromRecipe() throws Exception {
final Map<String, String> expectedLabels = new HashMap<>();
final Set<ServerConf> commonServers = new HashSet<>(asList(new ServerConf("reference1", "8080", "http"),
new ServerConf("reference2", "8081", "ftp")));
for (ServerConf server : commonServers) {
expectedLabels.put("che:server:" + server.getPort() + ":ref", server.getRef());
expectedLabels.put("che:server:" + server.getPort() + ":protocol", server.getProtocol());
}
final Set<ServerConf> devServers = new HashSet<>(asList(new ServerConf("reference3", "8082", "https"),
new ServerConf("reference4", "8083", "sftp")));
for (ServerConf server : devServers) {
expectedLabels.put("che:server:" + server.getPort() + ":ref", server.getRef());
expectedLabels.put("che:server:" + server.getPort() + ":protocol", server.getProtocol());
}
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
devServers,
commonServers,
Collections.<String>emptySet(),
Collections.<String>emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
final boolean isDev = true;
createInstanceFromRecipe(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(argumentCaptor.getValue().getLabels(), expectedLabels);
}
@Test
public void shouldAddOnlyCommonLabelsToContainerOnNonDevInstanceCreationFromRecipe() throws Exception {
final Map<String, String> expectedLabels = new HashMap<>();
final Set<ServerConf> commonServers = new HashSet<>(asList(new ServerConf("reference1", "8080", "http"),
new ServerConf("reference2", "8081", "ftp")));
for (ServerConf server : commonServers) {
expectedLabels.put("che:server:" + server.getPort() + ":ref", server.getRef());
expectedLabels.put("che:server:" + server.getPort() + ":protocol", server.getProtocol());
}
final Set<ServerConf> devServers = new HashSet<>(asList(new ServerConf("reference3", "8082", "https"),
new ServerConf("reference4", "8083", "sftp")));
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
devServers,
commonServers,
Collections.<String>emptySet(),
Collections.<String>emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
final boolean isDev = false;
createInstanceFromRecipe(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(argumentCaptor.getValue().getLabels(), expectedLabels);
}
@Test
public void shouldAddCommonAndDevLabelsToContainerOnDevInstanceCreationFromSnapshot() throws Exception {
final Map<String, String> expectedLabels = new HashMap<>();
final Set<ServerConf> commonServers = new HashSet<>(asList(new ServerConf("reference1", "8080", "http"),
new ServerConf("reference2", "8081", "ftp")));
for (ServerConf server : commonServers) {
expectedLabels.put("che:server:" + server.getPort() + ":ref", server.getRef());
expectedLabels.put("che:server:" + server.getPort() + ":protocol", server.getProtocol());
}
final Set<ServerConf> devServers = new HashSet<>(asList(new ServerConf("reference3", "8082", "https"),
new ServerConf("reference4", "8083", "sftp")));
for (ServerConf server : devServers) {
expectedLabels.put("che:server:" + server.getPort() + ":ref", server.getRef());
expectedLabels.put("che:server:" + server.getPort() + ":protocol", server.getProtocol());
}
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
devServers,
commonServers,
Collections.<String>emptySet(),
Collections.<String>emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
final boolean isDev = true;
createInstanceFromSnapshot(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(argumentCaptor.getValue().getLabels(), expectedLabels);
}
@Test
public void shouldAddOnlyCommonLabelsToContainerOnNonDevInstanceCreationFromSnapshot() throws Exception {
final Map<String, String> expectedLabels = new HashMap<>();
final Set<ServerConf> commonServers = new HashSet<>(asList(new ServerConf("reference1", "8080", "http"),
new ServerConf("reference2", "8081", "ftp")));
for (ServerConf server : commonServers) {
expectedLabels.put("che:server:" + server.getPort() + ":ref", server.getRef());
expectedLabels.put("che:server:" + server.getPort() + ":protocol", server.getProtocol());
}
final Set<ServerConf> devServers = new HashSet<>(asList(new ServerConf("reference3", "8082", "https"),
new ServerConf("reference4", "8083", "sftp")));
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
devServers,
commonServers,
Collections.<String>emptySet(),
Collections.<String>emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
final boolean isDev = false;
createInstanceFromSnapshot(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(argumentCaptor.getValue().getLabels(), expectedLabels);
}
@Test
public void shouldExposeCommonAndDevPortsToContainerOnDevInstanceCreationFromRecipe() throws Exception {
Map<String, Map<String, String>> expectedExposedPorts = new HashMap<>();
final Set<ServerConf> commonServers = new HashSet<>(asList(new ServerConf("reference1", "8080", "http"),
new ServerConf("reference2", "8081", "ftp")));
for (ServerConf server : commonServers) {
expectedExposedPorts.put(server.getPort(), Collections.<String, String>emptyMap());
}
final Set<ServerConf> devServers = new HashSet<>(asList(new ServerConf("reference3", "8082", "https"),
new ServerConf("reference4", "8083", "sftp")));
for (ServerConf server : devServers) {
expectedExposedPorts.put(server.getPort(), Collections.<String, String>emptyMap());
}
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
devServers,
commonServers,
Collections.<String>emptySet(),
Collections.<String>emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
final boolean isDev = true;
createInstanceFromRecipe(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(argumentCaptor.getValue().getExposedPorts(), expectedExposedPorts);
}
@Test
public void shouldExposeOnlyCommonPortsToContainerOnNonDevInstanceCreationFromRecipe() throws Exception {
Map<String, Map<String, String>> expectedExposedPorts = new HashMap<>();
final Set<ServerConf> commonServers = new HashSet<>(asList(new ServerConf("reference1", "8080", "http"),
new ServerConf("reference2", "8081", "ftp")));
for (ServerConf server : commonServers) {
expectedExposedPorts.put(server.getPort(), Collections.<String, String>emptyMap());
}
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
commonServers,
Collections.emptySet(),
Collections.emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
final boolean isDev = false;
createInstanceFromRecipe(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(argumentCaptor.getValue().getExposedPorts(), expectedExposedPorts);
}
@Test
public void shouldExposeCommonAndDevPortsToContainerOnDevInstanceCreationFromSnapshot() throws Exception {
Map<String, Map<String, String>> expectedExposedPorts = new HashMap<>();
final Set<ServerConf> commonServers = new HashSet<>(asList(new ServerConf("reference1", "8080", "http"),
new ServerConf("reference2", "8081", "ftp")));
for (ServerConf server : commonServers) {
expectedExposedPorts.put(server.getPort(), Collections.<String, String>emptyMap());
}
final Set<ServerConf> devServers = new HashSet<>(asList(new ServerConf("reference3", "8082", "https"),
new ServerConf("reference4", "8083", "sftp")));
for (ServerConf server : devServers) {
expectedExposedPorts.put(server.getPort(), Collections.<String, String>emptyMap());
}
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
devServers,
commonServers,
Collections.<String>emptySet(),
Collections.<String>emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
final boolean isDev = true;
createInstanceFromSnapshot(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(argumentCaptor.getValue().getExposedPorts(), expectedExposedPorts);
}
@Test
public void shouldExposeOnlyCommonPortsToContainerOnNonDevInstanceCreationFromSnapshot() throws Exception {
Map<String, Map<String, String>> expectedExposedPorts = new HashMap<>();
final Set<ServerConf> commonServers = new HashSet<>(asList(new ServerConf("reference1", "8080", "http"),
new ServerConf("reference2", "8081", "ftp")));
for (ServerConf server : commonServers) {
expectedExposedPorts.put(server.getPort(), Collections.<String, String>emptyMap());
}
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
commonServers,
Collections.emptySet(),
Collections.emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
final boolean isDev = false;
createInstanceFromSnapshot(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(argumentCaptor.getValue().getExposedPorts(), expectedExposedPorts);
}
@Test
public void shouldBindProjectsFSVolumeToContainerOnDevInstanceCreationFromRecipe() throws Exception {
final String expectedHostPathOfProjects = "/tmp/projects";
String[] expectedVolumes = new String[]{expectedHostPathOfProjects + ":/projects"};
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
Collections.emptySet(),
Collections.emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(workspaceFolderPathProvider.getPath(anyString())).thenReturn(expectedHostPathOfProjects);
final boolean isDev = true;
createInstanceFromRecipe(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
assertEquals(argumentCaptor.getValue().getHostConfig().getBinds(), expectedVolumes);
}
@Test
public void shouldBindProjectsFSVolumeToContainerOnDevInstanceCreationFromSnapshot() throws Exception {
final String expectedHostPathOfProjects = "/tmp/projects";
final String[] expectedVolumes = new String[]{expectedHostPathOfProjects + ":/projects"};
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
Collections.emptySet(),
Collections.emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(workspaceFolderPathProvider.getPath(anyString())).thenReturn(expectedHostPathOfProjects);
final boolean isDev = true;
createInstanceFromSnapshot(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
assertEquals(argumentCaptor.getValue().getHostConfig().getBinds(), expectedVolumes);
}
@Test
public void shouldNotBindProjectsFSVolumeToContainerOnNonDevInstanceCreationFromRecipe() throws Exception {
String[] expectedVolumes = new String[0];
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
Collections.emptySet(),
Collections.emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(dockerNode.getProjectsFolder()).thenReturn("/tmp/projects");
final boolean isDev = false;
createInstanceFromRecipe(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
assertEquals(argumentCaptor.getValue().getHostConfig().getBinds(), expectedVolumes);
}
@Test
public void shouldNotBindProjectsFSVolumeToContainerOnNonDevInstanceCreationFromSnapshot() throws Exception {
String[] expectedVolumes = new String[0];
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
Collections.emptySet(),
Collections.emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(dockerNode.getProjectsFolder()).thenReturn("/tmp/projects");
final boolean isDev = false;
createInstanceFromSnapshot(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
assertEquals(argumentCaptor.getValue().getHostConfig().getBinds(), expectedVolumes);
}
@Test
public void shouldBindCommonAndDevVolumesToContainerOnDevInstanceCreationFromRecipe() throws Exception {
final String expectedHostPathOfProjects = "/tmp/projects";
Set<String> devVolumes = new HashSet<>(asList("/etc:/tmp/etc:ro", "/some/thing:/home/some/thing"));
Set<String> commonVolumes = new HashSet<>(asList("/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path"));
final ArrayList<String> expectedVolumes = new ArrayList<>();
expectedVolumes.addAll(devVolumes);
expectedVolumes.addAll(commonVolumes);
expectedVolumes.add(expectedHostPathOfProjects + ":/projects");
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
devVolumes,
commonVolumes,
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(workspaceFolderPathProvider.getPath(anyString())).thenReturn(expectedHostPathOfProjects);
final boolean isDev = true;
createInstanceFromRecipe(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
final String[] actualBinds = argumentCaptor.getValue().getHostConfig().getBinds();
assertEquals(actualBinds.length, expectedVolumes.size());
assertEquals(new HashSet<>(asList(actualBinds)), new HashSet<>(expectedVolumes));
}
@Test
public void shouldBindCommonAndDevVolumesToContainerOnDevInstanceCreationFromSnapshot() throws Exception {
final String expectedHostPathOfProjects = "/tmp/projects";
Set<String> devVolumes = new HashSet<>(asList("/etc:/tmp/etc:ro", "/some/thing:/home/some/thing"));
Set<String> commonVolumes = new HashSet<>(asList("/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path"));
final ArrayList<String> expectedVolumes = new ArrayList<>();
expectedVolumes.addAll(devVolumes);
expectedVolumes.addAll(commonVolumes);
expectedVolumes.add(expectedHostPathOfProjects + ":/projects");
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
devVolumes,
commonVolumes,
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(workspaceFolderPathProvider.getPath(anyString())).thenReturn(expectedHostPathOfProjects);
final boolean isDev = true;
createInstanceFromSnapshot(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
final String[] actualBinds = argumentCaptor.getValue().getHostConfig().getBinds();
assertEquals(actualBinds.length, expectedVolumes.size());
assertEquals(new HashSet<>(asList(actualBinds)), new HashSet<>(expectedVolumes));
}
@Test
public void shouldBindCommonVolumesOnlyToContainerOnNonDevInstanceCreationFromRecipe() throws Exception {
final String expectedHostPathOfProjects = "/tmp/projects";
Set<String> devVolumes = new HashSet<>(asList("/etc:/tmp/etc:ro", "/some/thing:/home/some/thing"));
Set<String> commonVolumes = new HashSet<>(asList("/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path"));
final ArrayList<String> expectedVolumes = new ArrayList<>();
expectedVolumes.addAll(commonVolumes);
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
devVolumes,
commonVolumes,
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(dockerNode.getProjectsFolder()).thenReturn(expectedHostPathOfProjects);
final boolean isDev = false;
createInstanceFromRecipe(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
final String[] actualBinds = argumentCaptor.getValue().getHostConfig().getBinds();
assertEquals(actualBinds.length, expectedVolumes.size());
assertEquals(new HashSet<>(asList(actualBinds)), new HashSet<>(expectedVolumes));
}
@Test
public void shouldAddExtraHostOnDevInstanceCreationFromRecipe() throws Exception {
//given
final String expectedHostPathOfProjects = "/tmp/projects";
Set<String> devVolumes = new HashSet<>(asList("/etc:/tmp/etc:ro", "/some/thing:/home/some/thing"));
Set<String> commonVolumes = new HashSet<>(asList("/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path"));
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
devVolumes,
commonVolumes,
"dev.box.com:192.168.0.1",
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(dockerNode.getProjectsFolder()).thenReturn(expectedHostPathOfProjects);
final boolean isDev = true;
//when
createInstanceFromRecipe(isDev);
//then
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
final String[] extraHosts = argumentCaptor.getValue().getHostConfig().getExtraHosts();
assertEquals(extraHosts.length, 2);
assertEquals(extraHosts[0], "dev.box.com:192.168.0.1");
}
@Test
public void shouldAddExtraHostOnDevInstanceCreationFromSnapshot() throws Exception {
//given
final String expectedHostPathOfProjects = "/tmp/projects";
Set<String> devVolumes = new HashSet<>(asList("/etc:/tmp/etc:ro", "/some/thing:/home/some/thing"));
Set<String> commonVolumes = new HashSet<>(asList("/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path"));
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
devVolumes,
commonVolumes,
"dev.box.com:192.168.0.1,codenvy.com.com:185",
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(dockerNode.getProjectsFolder()).thenReturn(expectedHostPathOfProjects);
final boolean isDev = true;
//when
createInstanceFromSnapshot(isDev);
//then
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
final String[] extraHosts = argumentCaptor.getValue().getHostConfig().getExtraHosts();
assertEquals(extraHosts.length, 3);
assertEquals(extraHosts[0], "dev.box.com:192.168.0.1");
assertEquals(extraHosts[1], "codenvy.com.com:185");
}
@Test
public void shouldAddExtraHostOnNonDevInstanceCreationFromRecipe() throws Exception {
//given
final String expectedHostPathOfProjects = "/tmp/projects";
Set<String> devVolumes = new HashSet<>(asList("/etc:/tmp/etc:ro", "/some/thing:/home/some/thing"));
Set<String> commonVolumes = new HashSet<>(asList("/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path"));
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
devVolumes,
commonVolumes,
"dev.box.com:192.168.0.1",
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(dockerNode.getProjectsFolder()).thenReturn(expectedHostPathOfProjects);
final boolean isDev = false;
//when
createInstanceFromRecipe(isDev);
//then
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
final String[] extraHosts = argumentCaptor.getValue().getHostConfig().getExtraHosts();
assertEquals(extraHosts.length, 2);
assertEquals(extraHosts[0], "dev.box.com:192.168.0.1");
}
@Test
public void shouldAddExtraHostOnNonDevInstanceCreationFromSnapshot() throws Exception {
//given
final String expectedHostPathOfProjects = "/tmp/projects";
Set<String> devVolumes = new HashSet<>(asList("/etc:/tmp/etc:ro", "/some/thing:/home/some/thing"));
Set<String> commonVolumes = new HashSet<>(asList("/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path"));
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
devVolumes,
commonVolumes,
"dev.box.com:192.168.0.1,codenvy.com.com:185",
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(dockerNode.getProjectsFolder()).thenReturn(expectedHostPathOfProjects);
final boolean isDev = false;
//when
createInstanceFromSnapshot(isDev);
//then
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
final String[] extraHosts = argumentCaptor.getValue().getHostConfig().getExtraHosts();
assertEquals(extraHosts.length, 3);
assertEquals(extraHosts[0], "dev.box.com:192.168.0.1");
assertEquals(extraHosts[1], "codenvy.com.com:185");
}
@Test
public void shouldBindCommonVolumesOnlyToContainerOnNonDevInstanceCreationFromSnapshot() throws Exception {
final String expectedHostPathOfProjects = "/tmp/projects";
Set<String> devVolumes = new HashSet<>(asList("/etc:/tmp/etc:ro", "/some/thing:/home/some/thing"));
Set<String> commonVolumes = new HashSet<>(asList("/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path"));
final ArrayList<String> expectedVolumes = new ArrayList<>();
expectedVolumes.addAll(commonVolumes);
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.emptySet(),
Collections.emptySet(),
devVolumes,
commonVolumes,
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
Collections.<String>emptySet(),
Collections.<String>emptySet());
when(dockerNode.getProjectsFolder()).thenReturn(expectedHostPathOfProjects);
final boolean isDev = false;
createInstanceFromSnapshot(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
verify(dockerConnector).startContainer(anyString(), eq(null));
final String[] actualBinds = argumentCaptor.getValue().getHostConfig().getBinds();
assertEquals(actualBinds.length, expectedVolumes.size());
assertEquals(new HashSet<>(asList(actualBinds)), new HashSet<>(expectedVolumes));
}
@Test
public void shouldGenerateValidNameForContainerFromPrefixWithValidCharacters() throws Exception {
final String userName = "user";
final String displayName = "displayName";
final String expectedPrefix = String.format("%s_%s_%s_", userName, WORKSPACE_ID, displayName);
final String containerName = dockerInstanceProvider.generateContainerName(WORKSPACE_ID, displayName);
assertTrue(containerName.startsWith(expectedPrefix),
"Unexpected container name " + containerName + " while expected " + expectedPrefix + "*");
}
@Test
public void shouldGenerateValidNameForContainerFromPrefixWithInvalidCharacters() throws Exception {
final String userName = "{use}r+";
final String displayName = "displ{[ayName@";
EnvironmentContext.getCurrent().setUser(new UserImpl(userName));
final String expectedPrefix = String.format("%s_%s_%s_", "user", "WORKSPACE_ID", "displayName");
final String containerName = dockerInstanceProvider.generateContainerName("WORKSPACE_ID", displayName);
assertTrue(containerName.startsWith(expectedPrefix),
"Unexpected container name " + containerName + " while expected " + expectedPrefix + "*");
}
@Test
public void shouldAddWorkspaceIdEnvVariableOnDevInstanceCreationFromRecipe() throws Exception {
String wsId = "myWs";
createInstanceFromRecipe(true, wsId);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertTrue(Arrays.asList(argumentCaptor.getValue().getEnv())
.contains(DockerInstanceMetadata.CHE_WORKSPACE_ID + "=" + wsId),
"Workspace Id variable is missing. Required " + DockerInstanceMetadata.CHE_WORKSPACE_ID + "=" + wsId +
". Found " + Arrays.toString(argumentCaptor.getValue().getEnv()));
}
@Test
public void shouldAddWorkspaceIdEnvVariableOnDevInstanceCreationFromSnapshot() throws Exception {
String wsId = "myWs";
createInstanceFromSnapshot(true, wsId);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertTrue(Arrays.asList(argumentCaptor.getValue().getEnv())
.contains(DockerInstanceMetadata.CHE_WORKSPACE_ID + "=" + wsId),
"Workspace Id variable is missing. Required " + DockerInstanceMetadata.CHE_WORKSPACE_ID + "=" + wsId +
". Found " + Arrays.toString(argumentCaptor.getValue().getEnv()));
}
@Test
public void shouldNotAddWorkspaceIdEnvVariableOnNonDevInstanceCreationFromRecipe() throws Exception {
String wsId = "myWs";
createInstanceFromRecipe(false, wsId);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertFalse(Arrays.asList(argumentCaptor.getValue().getEnv())
.contains(DockerInstanceMetadata.CHE_WORKSPACE_ID + "=" + wsId),
"Non dev machine should not contains " + DockerInstanceMetadata.CHE_WORKSPACE_ID);
}
@Test
public void shouldNotAddWorkspaceIdEnvVariableOnNonDevInstanceCreationFromSnapshot() throws Exception {
String wsId = "myWs";
createInstanceFromSnapshot(false, wsId);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertFalse(Arrays.asList(argumentCaptor.getValue().getEnv())
.contains(DockerInstanceMetadata.CHE_WORKSPACE_ID + "=" + wsId),
"Non dev machine should not contains " + DockerInstanceMetadata.CHE_WORKSPACE_ID);
}
/**
* E.g from https://github.com/boot2docker/boot2docker/blob/master/README.md#virtualbox-guest-additions
*
* Users should be /Users
* /Users should be /Users
* c/Users should be /c/Users
* /c/Users should be /c/Users
* c:/Users should be /c/Users
*/
@Test
public void shouldEscapePathForWindowsHost() {
assertEquals(dockerInstanceProvider.escapePath("Users"), "/Users");
assertEquals(dockerInstanceProvider.escapePath("/Users"), "/Users");
assertEquals(dockerInstanceProvider.escapePath("c/Users"), "/c/Users");
assertEquals(dockerInstanceProvider.escapePath("/c/Users"), "/c/Users");
assertEquals(dockerInstanceProvider.escapePath("c:/Users"), "/c/Users");
assertEquals(dockerInstanceProvider.escapePath("C:/Users"), "/c/Users");
assertEquals(dockerInstanceProvider.escapePath("C:/Users/path/dir/from/host:/name/of/dir/in/container"),
"/c/Users/path/dir/from/host:/name/of/dir/in/container");
}
@Test
public void shouldAddCommonAndDevEnvVariablesToContainerOnDevInstanceCreationFromRecipe() throws Exception {
Set<String> commonEnv = new HashSet<>(asList("ENV_VAR1=123", "ENV_VAR2=234"));
Set<String> devEnv = new HashSet<>(asList("DEV_ENV_VAR1=345", "DEV_ENV_VAR2=456", "DEV_ENV_VAR3=567"));
Set<String> expectedEnv = new HashSet<>();
expectedEnv.addAll(commonEnv);
expectedEnv.addAll(devEnv);
expectedEnv.add(DockerInstanceMetadata.USER_TOKEN + "=" + USER_TOKEN);
expectedEnv.add(DockerInstanceMetadata.CHE_WORKSPACE_ID + "=" + WORKSPACE_ID);
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.<ServerConf>emptySet(),
Collections.<ServerConf>emptySet(),
Collections.<String>emptySet(),
Collections.<String>emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
devEnv,
commonEnv);
final boolean isDev = true;
createInstanceFromRecipe(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(new HashSet<>(Arrays.asList(argumentCaptor.getValue().getEnv())), expectedEnv);
}
@Test
public void shouldNotAddDevEnvToCommonEnvVariablesToContainerOnNonDevInstanceCreationFromRecipe() throws Exception {
Set<String> commonEnv = new HashSet<>(asList("ENV_VAR1=123", "ENV_VAR2=234"));
Set<String> devEnv = new HashSet<>(asList("DEV_ENV_VAR1=345", "DEV_ENV_VAR2=456", "DEV_ENV_VAR3=567"));
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.<ServerConf>emptySet(),
Collections.<ServerConf>emptySet(),
Collections.<String>emptySet(),
Collections.<String>emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
devEnv,
commonEnv);
final boolean isDev = false;
createInstanceFromRecipe(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(new HashSet<>(Arrays.asList(argumentCaptor.getValue().getEnv())), commonEnv);
}
@Test
public void shouldAddCommonAndDevEnvVariablesToContainerOnDevInstanceCreationFromSnapshot() throws Exception {
Set<String> commonEnv = new HashSet<>(asList("ENV_VAR1=123", "ENV_VAR2=234"));
Set<String> devEnv = new HashSet<>(asList("DEV_ENV_VAR1=345", "DEV_ENV_VAR2=456", "DEV_ENV_VAR3=567"));
Set<String> expectedEnv = new HashSet<>();
expectedEnv.addAll(commonEnv);
expectedEnv.addAll(devEnv);
expectedEnv.add(DockerInstanceMetadata.USER_TOKEN + "=" + USER_TOKEN);
expectedEnv.add(DockerInstanceMetadata.CHE_WORKSPACE_ID + "=" + WORKSPACE_ID);
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.<ServerConf>emptySet(),
Collections.<ServerConf>emptySet(),
Collections.<String>emptySet(),
Collections.<String>emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
devEnv,
commonEnv);
final boolean isDev = true;
createInstanceFromSnapshot(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(new HashSet<>(Arrays.asList(argumentCaptor.getValue().getEnv())), expectedEnv);
}
@Test
public void shouldNotAddDevEnvToCommonEnvVariablesToContainerOnNonDevInstanceCreationFromSnapshot() throws Exception {
Set<String> commonEnv = new HashSet<>(asList("ENV_VAR1=123", "ENV_VAR2=234"));
Set<String> devEnv = new HashSet<>(asList("DEV_ENV_VAR1=345", "DEV_ENV_VAR2=456", "DEV_ENV_VAR3=567"));
dockerInstanceProvider = new DockerInstanceProvider(dockerConnector,
dockerConnectorConfiguration,
dockerMachineFactory,
dockerInstanceStopDetector,
Collections.<ServerConf>emptySet(),
Collections.<ServerConf>emptySet(),
Collections.<String>emptySet(),
Collections.<String>emptySet(),
null,
workspaceFolderPathProvider,
PROJECT_FOLDER_PATH,
false,
devEnv,
commonEnv);
final boolean isDev = false;
createInstanceFromSnapshot(isDev);
ArgumentCaptor<ContainerConfig> argumentCaptor = ArgumentCaptor.forClass(ContainerConfig.class);
verify(dockerConnector).createContainer(argumentCaptor.capture(), anyString());
assertEquals(new HashSet<>(Arrays.asList(argumentCaptor.getValue().getEnv())), commonEnv);
}
private void createInstanceFromRecipe() throws Exception {
createInstanceFromRecipe(false,
64,
"machineId",
"userId",
WORKSPACE_ID,
DISPLAY_NAME,
new RecipeImpl().withType("Dockerfile")
.withScript("FROM busybox"));
}
private void createInstanceFromRecipe(boolean isDev) throws Exception {
createInstanceFromRecipe(isDev, null, null, null, null, null, null);
}
private void createInstanceFromRecipe(boolean isDev, String workspaceId) throws Exception {
createInstanceFromRecipe(isDev, null, null, null, workspaceId, null, null);
}
private void createInstanceFromRecipe(int memorySizeInMB) throws Exception {
createInstanceFromRecipe(null, memorySizeInMB, null, null, null, null, null);
}
private void createInstanceFromRecipe(Boolean isDev,
Integer memorySizeInMB,
String machineId,
String userId,
String workspaceId,
String displayName,
Recipe recipe) throws Exception {
createInstanceFromRecipe(isDev == null ? false : isDev,
memorySizeInMB == null ? 64 : memorySizeInMB,
machineId == null ? "machineId" : machineId,
userId == null ? "userId" : userId,
workspaceId == null ? WORKSPACE_ID : workspaceId,
displayName == null ? DISPLAY_NAME : displayName,
recipe == null ? new RecipeImpl().withType("Dockerfile")
.withScript("FROM busybox") : recipe,
"machineType",
new MachineSourceImpl("source type", "source location"),
new ChannelsImpl("channel1", "channel2"),
MachineStatus.CREATING);
}
private void createInstanceFromRecipe(boolean isDev,
int memorySizeInMB,
String machineId,
String userId,
String workspaceId,
String displayName,
Recipe recipe,
String machineType,
MachineSource machineSource,
Channels channels,
MachineStatus machineStatus)
throws Exception {
dockerInstanceProvider.createInstance(recipe,
new MachineStateImpl(isDev,
machineType,
displayName,
machineSource,
new LimitsImpl(memorySizeInMB),
machineId,
channels,
workspaceId,
userId,
"envName",
machineStatus),
LineConsumer.DEV_NULL);
}
private void createInstanceFromRecipe(Recipe recipe, MachineState machineState) throws Exception {
dockerInstanceProvider.createInstance(recipe,
machineState,
LineConsumer.DEV_NULL);
}
private void createInstanceFromSnapshot() throws NotFoundException, MachineException {
createInstanceFromSnapshot(null, null, null, null, null, null, null, null, null);
}
private void createInstanceFromSnapshot(int memorySizeInMB) throws NotFoundException, MachineException {
createInstanceFromSnapshot(null, null, null, null, memorySizeInMB, null, null, null, null);
}
private void createInstanceFromSnapshot(boolean isDev) throws NotFoundException, MachineException {
createInstanceFromSnapshot(null, null, null, isDev, null, null, null, null, null);
}
private void createInstanceFromSnapshot(boolean isDev, String workspaceId) throws NotFoundException, MachineException {
createInstanceFromSnapshot(null, null, null, isDev, null, null, null, workspaceId, null);
}
private void createInstanceFromSnapshot(String repo, String tag, String registry) throws NotFoundException, MachineException {
createInstanceFromSnapshot(repo, tag, registry, null, null, null, null, null, null);
}
private void createInstanceFromSnapshot(String repo,
String tag,
String registry,
Boolean isDev,
Integer memorySizeInMB,
String machineId,
String userId,
String workspaceId,
String displayName)
throws NotFoundException, MachineException {
createInstanceFromSnapshot(repo == null ? "repo" : repo,
tag == null ? "tag" : tag,
registry == null ? "localhost:1234" : registry,
isDev == null ? false : isDev,
memorySizeInMB == null ? 64 : memorySizeInMB,
machineId == null ? "machineId" : machineId,
userId == null ? "userId" : userId,
workspaceId == null ? WORKSPACE_ID : workspaceId,
displayName == null ? DISPLAY_NAME : displayName,
"machineType",
new MachineSourceImpl("source type", "source location"),
new ChannelsImpl("channel1", "channel2"),
MachineStatus.CREATING,
"envName");
}
private void createInstanceFromSnapshot(String repo,
String tag,
String registry,
boolean isDev,
int memorySizeInMB,
String machineId,
String userId,
String workspaceId,
String displayName,
String machineType,
MachineSource machineSource,
Channels channels,
MachineStatus machineStatus,
String envName)
throws NotFoundException, MachineException {
dockerInstanceProvider.createInstance(new DockerInstanceKey(repo, tag, "imageId", registry),
new MachineStateImpl(isDev,
machineType,
displayName,
machineSource,
new LimitsImpl(memorySizeInMB),
machineId,
channels,
workspaceId,
userId,
envName,
machineStatus),
LineConsumer.DEV_NULL);
}
private void createInstanceFromSnapshot(MachineState machineState)
throws NotFoundException, MachineException {
dockerInstanceProvider.createInstance(new DockerInstanceKey("repo" ,
"tag",
"imageId",
"localhost:1234"),
machineState,
LineConsumer.DEV_NULL);
}
}