Skip to content

Commit

Permalink
Update tests for EphemeralWorkspaceAdapter
Browse files Browse the repository at this point in the history
Signed-off-by: Angel Misevski <amisevsk@redhat.com>
  • Loading branch information
amisevsk committed Oct 7, 2019
1 parent 027f2f8 commit 5be73ff
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,30 @@
package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc;

import static org.eclipse.che.api.workspace.shared.Constants.PERSIST_VOLUMES_ATTRIBUTE;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.ContainerBuilder;
import io.fabric8.kubernetes.api.model.EmptyDirVolumeSource;
import io.fabric8.kubernetes.api.model.PersistentVolumeClaim;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodBuilder;
import io.fabric8.kubernetes.api.model.VolumeBuilder;
import io.fabric8.kubernetes.api.model.VolumeMount;
import io.fabric8.kubernetes.api.model.VolumeMountBuilder;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.eclipse.che.api.core.model.workspace.Workspace;
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.config.Volume;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.model.impl.VolumeImpl;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.BeforeMethod;
Expand All @@ -60,24 +53,24 @@ public class EphemeralWorkspaceAdapterTest {
private static final String EPHEMERAL_WORKSPACE_ID = "workspace123";
private static final String NON_EPHEMERAL_WORKSPACE_ID = "workspace234";
private static final String POD_NAME = "pod1";
private static final String VOL1_ID = "vol1";
private static final String VOL2_ID = "vol2";

@Mock private Workspace nonEphemeralWorkspace;
@Mock private Workspace ephemeralWorkspace;

@Mock private PVCProvisioner pvcProvisioner;
@Mock private SubPathPrefixes subPathPrefixes;

private KubernetesEnvironment k8sEnv;
@Mock private RuntimeIdentity runtimeIdentity;
@Mock private Map<String, InternalMachineConfig> machines;
@Mock private InternalMachineConfig machine;
@Mock private RuntimeIdentity identity;

private EphemeralWorkspaceAdapter ephemeralWorkspaceAdapter;
private InOrder provisionOrder;
@Captor private ArgumentCaptor<KubernetesEnvironment> k8sEnvCaptor;

private Map<String, Volume> volumes;
private EphemeralWorkspaceAdapter ephemeralWorkspaceAdapter;

@BeforeMethod
public void setup() throws Exception {
ephemeralWorkspaceAdapter = new EphemeralWorkspaceAdapter();
ephemeralWorkspaceAdapter = new EphemeralWorkspaceAdapter(pvcProvisioner, subPathPrefixes);

// ephemeral workspace configuration
lenient().when(ephemeralWorkspace.getId()).thenReturn(EPHEMERAL_WORKSPACE_ID);
Expand All @@ -95,15 +88,7 @@ public void setup() throws Exception {
lenient().when(nonEphemeralWorkspace.getAttributes()).thenReturn(nonEphemeralConfigAttributes);

k8sEnv = KubernetesEnvironment.builder().build();

k8sEnv.setMachines(machines);
lenient().when(machines.get(anyString())).thenReturn(machine);

volumes =
ImmutableMap.of(
VOL1_ID, new VolumeImpl().withPath(VOL1_ID),
VOL2_ID, new VolumeImpl().withPath(VOL2_ID));
lenient().when(machine.getVolumes()).thenReturn(volumes);
provisionOrder = inOrder(pvcProvisioner, subPathPrefixes);
}

@Test
Expand All @@ -113,7 +98,29 @@ public void testIsEphemeralWorkspace() throws Exception {
}

@Test
public void testReplacingUserDefinedPVCsWithWithEmptyDirVolumes() throws Exception {
public void testProvisioningAllPVCsInWorkspace() throws Exception {
// given
PersistentVolumeClaim pvc1 = UniqueWorkspacePVCStrategyTest.newPVC("pvc1");
PersistentVolumeClaim pvc2 = UniqueWorkspacePVCStrategyTest.newPVC("pvc2");
k8sEnv.getPersistentVolumeClaims().put("pvc1", pvc1);
k8sEnv.getPersistentVolumeClaims().put("pvc2", pvc2);
when(identity.getWorkspaceId()).thenReturn(EPHEMERAL_WORKSPACE_ID);

// when
ephemeralWorkspaceAdapter.provision(k8sEnv, identity);

// then
provisionOrder
.verify(pvcProvisioner)
.provision(k8sEnv, ImmutableMap.of("pvc1", pvc1, "pvc2", pvc2));
provisionOrder.verify(pvcProvisioner).convertCheVolumes(k8sEnv, EPHEMERAL_WORKSPACE_ID);
provisionOrder
.verify(subPathPrefixes)
.prefixVolumeMountsSubpaths(k8sEnv, EPHEMERAL_WORKSPACE_ID);
}

@Test
public void testConvertsAllPVCsToEmptyDir() throws Exception {
// given
k8sEnv.getPersistentVolumeClaims().put("pvc1", mock(PersistentVolumeClaim.class));
k8sEnv.getPersistentVolumeClaims().put("pvc2", mock(PersistentVolumeClaim.class));
Expand Down Expand Up @@ -143,138 +150,12 @@ public void testReplacingUserDefinedPVCsWithWithEmptyDirVolumes() throws Excepti

k8sEnv.addPod(pod);

// when
ephemeralWorkspaceAdapter.provision(k8sEnv, runtimeIdentity);
ephemeralWorkspaceAdapter.provision(k8sEnv, identity);

// then
assertTrue(k8sEnv.getPersistentVolumeClaims().isEmpty());
assertNull(pod.getSpec().getVolumes().get(0).getPersistentVolumeClaim());
assertEquals(pod.getSpec().getVolumes().get(0).getEmptyDir(), new EmptyDirVolumeSource());
assertEquals(pod.getSpec().getVolumes().get(1), configMapVolume);
assertEquals(pod.getSpec().getVolumes().get(2), emptyDirVolume);
}

@Test
public void testMatchingUserDefinedPVCsWithCheVolumes() throws Exception {
// given
k8sEnv.getPersistentVolumeClaims().put("pvc1", mock(PersistentVolumeClaim.class));

io.fabric8.kubernetes.api.model.Volume pvcVolume =
new VolumeBuilder()
.withName("pvc1volume")
.withNewPersistentVolumeClaim()
.withClaimName("pvc1")
.endPersistentVolumeClaim()
.build();
Pod pod =
new PodBuilder()
.withNewMetadata()
.withName("pod")
.endMetadata()
.withNewSpec()
.withContainers(
new ContainerBuilder()
.withName("c1")
.withVolumeMounts(new VolumeMountBuilder().withName("pvc1volume").build())
.build(),
new ContainerBuilder().withName("c2").build())
.withVolumes(new VolumeBuilder(pvcVolume).build())
.endSpec()
.build();
k8sEnv.addPod(pod);

k8sEnv.setMachines(new HashMap<>());
k8sEnv.getMachines().put("pod/c1", new InternalMachineConfig());
InternalMachineConfig machine2 = new InternalMachineConfig();
machine2.getVolumes().put("pvc1", new VolumeImpl().withPath("/tmp/pvc1"));
k8sEnv.getMachines().put("pod/c2", machine2);

// when
ephemeralWorkspaceAdapter.provision(k8sEnv, runtimeIdentity);

// then
assertTrue(k8sEnv.getPersistentVolumeClaims().isEmpty());
List<io.fabric8.kubernetes.api.model.Volume> podVolumes = pod.getSpec().getVolumes();
assertEquals(podVolumes.size(), 1);
io.fabric8.kubernetes.api.model.Volume podVolume = podVolumes.get(0);
assertNull(podVolume.getPersistentVolumeClaim());
assertEquals(podVolume.getEmptyDir(), new EmptyDirVolumeSource());

Container c1 = pod.getSpec().getContainers().get(0);
VolumeMount c1VolumeMount = c1.getVolumeMounts().get(0);
assertEquals(c1VolumeMount.getName(), podVolume.getName());

Container c2 = pod.getSpec().getContainers().get(1);
VolumeMount c2VolumeMount = c2.getVolumeMounts().get(0);
assertEquals(c2VolumeMount.getName(), podVolume.getName());
}

@Test
public void testEmptyDirVolumeMountsAdded() throws Exception {
Container container = new Container();
Pod pod = buildPod(POD_NAME, container);
k8sEnv.addPod(pod);

ephemeralWorkspaceAdapter.provision(k8sEnv, runtimeIdentity);

Container podContainer = pod.getSpec().getContainers().get(0);
assertEquals(podContainer.getVolumeMounts().size(), volumes.values().size());
assertEquals(pod.getSpec().getVolumes().size(), volumes.values().size());
assertTrue(pod.getSpec().getVolumes().stream().allMatch(vol -> (vol.getEmptyDir() != null)));
}

@Test
public void testEmptyDirVolumeMountsSharedBetweenContainers() throws Exception {
Container container1 = new Container();
Container container2 = new Container();
Pod pod = buildPod(POD_NAME, container1, container2);
k8sEnv.addPod(pod);

ephemeralWorkspaceAdapter.provision(k8sEnv, runtimeIdentity);

List<Container> podContainers = pod.getSpec().getContainers();
List<VolumeMount> container1Mounts = podContainers.get(0).getVolumeMounts();
List<VolumeMount> container2Mounts = podContainers.get(1).getVolumeMounts();
assertTrue(container1Mounts.stream().allMatch(container2Mounts::contains));
assertEquals(pod.getSpec().getVolumes().size(), volumes.size());

List<String> podVolumeNames =
pod.getSpec()
.getVolumes()
.stream()
.map(io.fabric8.kubernetes.api.model.Volume::getName)
.collect(Collectors.toList());
assertTrue(
container1Mounts.stream().map(VolumeMount::getName).allMatch(podVolumeNames::contains));
}

@Test
public void testInitContainerMountsIncluded() throws Exception {
Container container1 = new Container();
Container container2 = new Container();
Container initContainer = new Container();
Pod pod = buildPod(POD_NAME, container1, container2);
pod.getSpec().setInitContainers(ImmutableList.of(initContainer));

k8sEnv.addPod(pod);

ephemeralWorkspaceAdapter.provision(k8sEnv, runtimeIdentity);

List<Container> podInitContainers = pod.getSpec().getInitContainers();
assertEquals(podInitContainers.size(), 1);
Container podInitContainer = podInitContainers.iterator().next();
List<VolumeMount> initContainerVolumeMounts = podInitContainer.getVolumeMounts();
assertEquals(initContainerVolumeMounts.size(), 2);
}

private Pod buildPod(String name, Container... containers) throws Exception {
return new PodBuilder()
.withNewMetadata()
.withName(name)
.endMetadata()
.withNewSpec()
.withContainers(containers)
.endSpec()
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,11 @@ public void shouldDoNothingIfPersistAttributeIsSetToFalseInWorkspaceConfigWhenCl
verify(pvcs, never()).delete(any());
}

private static PersistentVolumeClaim newPVC(String name) {
static PersistentVolumeClaim newPVC(String name) {
return newPVC(name, new HashMap<>());
}

private static PersistentVolumeClaim newPVC(String name, Map<String, String> labels) {
static PersistentVolumeClaim newPVC(String name, Map<String, String> labels) {
return new PersistentVolumeClaimBuilder()
.withNewMetadata()
.withName(name)
Expand Down

0 comments on commit 5be73ff

Please sign in to comment.