remove che.infra.kubernetes.pvc.name and che.infra.kubernetes.pvc.quantity properties
Signed-off-by: Andrew Obuchowicz <aobuchow@redhat.com>pull/344/head
parent
97b7431bda
commit
18c12861a0
|
|
@ -415,18 +415,13 @@ che.infra.kubernetes.pvc.strategy=common
|
|||
# the {prod-short} Operator that this property has effect only if the `common` PVC strategy used.
|
||||
che.infra.kubernetes.pvc.precreate_subpaths=true
|
||||
|
||||
# Defines the settings of PVC name for {prod-short} workspaces.
|
||||
# Each PVC strategy supplies this value differently.
|
||||
# See documentation for `che.infra.kubernetes.pvc.strategy` property
|
||||
che.infra.kubernetes.pvc.name=claim-che-workspace
|
||||
|
||||
|
||||
# Defines the storage class of Persistent Volume Claim for the workspaces.
|
||||
# Empty strings means "use default".
|
||||
che.infra.kubernetes.pvc.storage_class_name=
|
||||
|
||||
# Defines the size of Persistent Volume Claim of {prod-short} workspace.
|
||||
# See: link:https://docs.openshift.com/container-platform/4.4/storage/understanding-persistent-storage.html[Understanding persistent storage]
|
||||
che.infra.kubernetes.pvc.quantity=10Gi
|
||||
|
||||
|
||||
# Pod that is launched when performing persistent volume claim maintenance jobs on OpenShift
|
||||
che.infra.kubernetes.pvc.jobs.image=registry.access.redhat.com/ubi8-minimal:8.3-230
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
# Copyright (c) 2012-2022 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -20,8 +20,6 @@ che.infra.kubernetes.bootstrapper.server_check_period_sec=che.infra.openshift.bo
|
|||
che.infra.kubernetes.pvc.enabled=che.infra.openshift.pvc.enabled
|
||||
che.infra.kubernetes.pvc.strategy=che.infra.openshift.pvc.strategy
|
||||
che.infra.kubernetes.pvc.precreate_subpaths=che.infra.openshift.pvc.precreate_subpaths
|
||||
che.infra.kubernetes.pvc.name=che.infra.openshift.pvc.name
|
||||
che.infra.kubernetes.pvc.quantity=che.infra.openshift.pvc.quantity
|
||||
che.infra.kubernetes.pvc.jobs.image=che.infra.openshift.pvc.jobs.image
|
||||
che.infra.kubernetes.pvc.jobs.memorylimit=che.infra.openshift.pvc.jobs.memorylimit
|
||||
che.infra.kubernetes.pvc.access_mode=che.infra.openshift.pvc.access_mode
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ package org.eclipse.che.workspace.infrastructure.kubernetes;
|
|||
import static com.google.inject.name.Names.named;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.DOCKERIMAGE_COMPONENT_TYPE;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.CommonPVCStrategy.COMMON_STRATEGY;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.PerWorkspacePVCStrategy.PER_WORKSPACE_STRATEGY;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.UniqueWorkspacePVCStrategy.UNIQUE_STRATEGY;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.server.external.DefaultHostExternalServiceExposureStrategy.DEFAULT_HOST_STRATEGY;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.server.external.MultiHostExternalServiceExposureStrategy.MULTI_HOST_STRATEGY;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.server.external.SingleHostExternalServiceExposureStrategy.SINGLE_HOST_STRATEGY;
|
||||
|
|
@ -57,12 +54,7 @@ import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurato
|
|||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.UserPreferencesConfigurator;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.UserProfileConfigurator;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.WorkspaceServiceAccountConfigurator;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.CommonPVCStrategy;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.PerWorkspacePVCStrategy;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.UniqueWorkspacePVCStrategy;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.WorkspacePVCCleaner;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.WorkspaceVolumeStrategyProvider;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.WorkspaceVolumesStrategy;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.AsyncStorageProvisioner;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.GatewayTlsProvisioner;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.IngressTlsProvisioner;
|
||||
|
|
@ -160,13 +152,6 @@ public class KubernetesInfraModule extends AbstractModule {
|
|||
bind(CheApiInternalEnvVarProvider.class).to(KubernetesCheApiInternalEnvVarProvider.class);
|
||||
bind(CheApiExternalEnvVarProvider.class).to(KubernetesCheApiExternalEnvVarProvider.class);
|
||||
|
||||
MapBinder<String, WorkspaceVolumesStrategy> volumesStrategies =
|
||||
MapBinder.newMapBinder(binder(), String.class, WorkspaceVolumesStrategy.class);
|
||||
volumesStrategies.addBinding(COMMON_STRATEGY).to(CommonPVCStrategy.class);
|
||||
volumesStrategies.addBinding(PER_WORKSPACE_STRATEGY).to(PerWorkspacePVCStrategy.class);
|
||||
volumesStrategies.addBinding(UNIQUE_STRATEGY).to(UniqueWorkspacePVCStrategy.class);
|
||||
bind(WorkspaceVolumesStrategy.class).toProvider(WorkspaceVolumeStrategyProvider.class);
|
||||
|
||||
Multibinder.newSetBinder(binder(), ServiceTermination.class)
|
||||
.addBinding()
|
||||
.to(KubernetesClientTermination.class);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2022 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -105,8 +105,6 @@ public class CommonPVCStrategy implements WorkspaceVolumesStrategy {
|
|||
|
||||
@Inject
|
||||
public CommonPVCStrategy(
|
||||
@Named("che.infra.kubernetes.pvc.name") String configuredPVCName,
|
||||
@Named("che.infra.kubernetes.pvc.quantity") String pvcQuantity,
|
||||
@Named("che.infra.kubernetes.pvc.access_mode") String pvcAccessMode,
|
||||
@Named("che.infra.kubernetes.pvc.precreate_subpaths") boolean preCreateDirs,
|
||||
@Named("che.infra.kubernetes.pvc.storage_class_name") String pvcStorageClassName,
|
||||
|
|
@ -118,8 +116,8 @@ public class CommonPVCStrategy implements WorkspaceVolumesStrategy {
|
|||
PodsVolumes podsVolumes,
|
||||
SubPathPrefixes subpathPrefixes,
|
||||
WorkspaceManager workspaceManager) {
|
||||
this.configuredPVCName = configuredPVCName;
|
||||
this.pvcQuantity = pvcQuantity;
|
||||
this.configuredPVCName = "test";
|
||||
this.pvcQuantity = "test";
|
||||
this.pvcAccessMode = pvcAccessMode;
|
||||
this.preCreateDirs = preCreateDirs;
|
||||
this.pvcStorageClassName = pvcStorageClassName;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2022 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -55,13 +55,11 @@ public class PVCProvisioner {
|
|||
|
||||
@Inject
|
||||
public PVCProvisioner(
|
||||
@Named("che.infra.kubernetes.pvc.name") String pvcNamePrefix,
|
||||
@Named("che.infra.kubernetes.pvc.quantity") String pvcQuantity,
|
||||
@Named("che.infra.kubernetes.pvc.access_mode") String pvcAccessMode,
|
||||
@Named("che.infra.kubernetes.pvc.storage_class_name") String pvcStorageClassName,
|
||||
PodsVolumes podsVolumes) {
|
||||
this.pvcNamePrefix = pvcNamePrefix;
|
||||
this.pvcQuantity = pvcQuantity;
|
||||
this.pvcNamePrefix = "TEST";
|
||||
this.pvcQuantity = "test";
|
||||
this.pvcAccessMode = pvcAccessMode;
|
||||
this.pvcStorageClassName = pvcStorageClassName;
|
||||
this.podsVolumes = podsVolumes;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2022 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -52,8 +52,6 @@ public class PerWorkspacePVCStrategy extends CommonPVCStrategy {
|
|||
|
||||
@Inject
|
||||
public PerWorkspacePVCStrategy(
|
||||
@Named("che.infra.kubernetes.pvc.name") String pvcName,
|
||||
@Named("che.infra.kubernetes.pvc.quantity") String pvcQuantity,
|
||||
@Named("che.infra.kubernetes.pvc.access_mode") String pvcAccessMode,
|
||||
@Named("che.infra.kubernetes.pvc.precreate_subpaths") boolean preCreateDirs,
|
||||
@Named("che.infra.kubernetes.pvc.storage_class_name") String pvcStorageClassName,
|
||||
|
|
@ -66,8 +64,6 @@ public class PerWorkspacePVCStrategy extends CommonPVCStrategy {
|
|||
SubPathPrefixes subpathPrefixes,
|
||||
WorkspaceManager workspaceManager) {
|
||||
super(
|
||||
pvcName,
|
||||
pvcQuantity,
|
||||
pvcAccessMode,
|
||||
preCreateDirs,
|
||||
pvcStorageClassName,
|
||||
|
|
@ -79,10 +75,10 @@ public class PerWorkspacePVCStrategy extends CommonPVCStrategy {
|
|||
podsVolumes,
|
||||
subpathPrefixes,
|
||||
workspaceManager);
|
||||
this.pvcNamePrefix = pvcName;
|
||||
this.pvcNamePrefix = "TEST";
|
||||
this.factory = factory;
|
||||
this.pvcAccessMode = pvcAccessMode;
|
||||
this.pvcQuantity = pvcQuantity;
|
||||
this.pvcQuantity = "test";
|
||||
this.pvcStorageClassName = pvcStorageClassName;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2022 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -127,20 +127,18 @@ public class AsyncStorageProvisioner {
|
|||
@Inject
|
||||
public AsyncStorageProvisioner(
|
||||
@Named("che.workspace.sidecar.image_pull_policy") String sidecarImagePullPolicy,
|
||||
@Named("che.infra.kubernetes.pvc.quantity") String pvcQuantity,
|
||||
@Named("che.infra.kubernetes.async.storage.image") String asyncStorageImage,
|
||||
@Named("che.infra.kubernetes.pvc.access_mode") String pvcAccessMode,
|
||||
@Named("che.infra.kubernetes.pvc.strategy") String pvcStrategy,
|
||||
@Named("che.infra.kubernetes.pvc.name") String pvcName,
|
||||
@Named("che.infra.kubernetes.pvc.storage_class_name") String pvcStorageClassName,
|
||||
SshManager sshManager,
|
||||
KubernetesClientFactory kubernetesClientFactory) {
|
||||
this.sidecarImagePullPolicy = sidecarImagePullPolicy;
|
||||
this.pvcQuantity = pvcQuantity;
|
||||
this.pvcQuantity = "test";
|
||||
this.asyncStorageImage = asyncStorageImage;
|
||||
this.pvcAccessMode = pvcAccessMode;
|
||||
this.pvcStrategy = pvcStrategy;
|
||||
this.pvcName = pvcName;
|
||||
this.pvcName = "TEST";
|
||||
this.pvcStorageClassName = pvcStorageClassName;
|
||||
this.sshManager = sshManager;
|
||||
this.kubernetesClientFactory = kubernetesClientFactory;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2022 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -40,10 +40,9 @@ public class ChePluginsVolumeApplier {
|
|||
|
||||
@Inject
|
||||
public ChePluginsVolumeApplier(
|
||||
@Named("che.infra.kubernetes.pvc.quantity") String pvcQuantity,
|
||||
@Named("che.infra.kubernetes.pvc.access_mode") String pvcAccessMode,
|
||||
@Named("che.infra.kubernetes.pvc.storage_class_name") String pvcStorageClassName) {
|
||||
this.pvcQuantity = pvcQuantity;
|
||||
this.pvcQuantity = "test";
|
||||
this.pvcAccessMode = pvcAccessMode;
|
||||
this.pvcStorageClassName = pvcStorageClassName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,468 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static org.eclipse.che.api.user.server.UserManager.PERSONAL_ACCOUNT;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.PERSIST_VOLUMES_ATTRIBUTE;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.CommonPVCStrategy.SUBPATHS_PROPERTY_FMT;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
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.assertNotEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.PersistentVolumeClaim;
|
||||
import io.fabric8.kubernetes.api.model.PersistentVolumeClaimBuilder;
|
||||
import io.fabric8.kubernetes.api.model.Quantity;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceManager;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.RuntimeIdentityImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespace;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespaceFactory;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesPersistentVolumeClaims;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link CommonPVCStrategy}.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
* @author Sergii Leshchenko
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class CommonPVCStrategyTest {
|
||||
|
||||
private static final String WORKSPACE_ID = "workspace123";
|
||||
private static final String NAMESPACE = "infraNamespace";
|
||||
private static final String PVC_NAME = "che-claim";
|
||||
|
||||
private static final String PVC_QUANTITY = "10Gi";
|
||||
private static final String PVC_ACCESS_MODE = "RWO";
|
||||
private static final String PVC_STORAGE_CLASS_NAME = "special";
|
||||
|
||||
private static final String[] WORKSPACE_SUBPATHS = {"/projects", "/logs"};
|
||||
|
||||
private static final RuntimeIdentity IDENTITY =
|
||||
new RuntimeIdentityImpl(WORKSPACE_ID, "env1", "id1", NAMESPACE);
|
||||
|
||||
private KubernetesEnvironment k8sEnv;
|
||||
|
||||
@Mock private PVCSubPathHelper pvcSubPathHelper;
|
||||
|
||||
@Mock private KubernetesNamespaceFactory factory;
|
||||
@Mock private KubernetesNamespace k8sNamespace;
|
||||
@Mock private KubernetesPersistentVolumeClaims pvcs;
|
||||
|
||||
@Mock private EphemeralWorkspaceAdapter ephemeralWorkspaceAdapter;
|
||||
@Mock private PVCProvisioner volumeConverter;
|
||||
@Mock private PodsVolumes podsVolumes;
|
||||
@Mock private SubPathPrefixes subpathPrefixes;
|
||||
@Mock private WorkspaceManager workspaceManager;
|
||||
|
||||
private InOrder provisionOrder;
|
||||
|
||||
private CommonPVCStrategy commonPVCStrategy;
|
||||
|
||||
@BeforeMethod
|
||||
public void setup() throws Exception {
|
||||
commonPVCStrategy =
|
||||
new CommonPVCStrategy(
|
||||
PVC_NAME,
|
||||
PVC_QUANTITY,
|
||||
PVC_ACCESS_MODE,
|
||||
true,
|
||||
PVC_STORAGE_CLASS_NAME,
|
||||
true,
|
||||
pvcSubPathHelper,
|
||||
factory,
|
||||
ephemeralWorkspaceAdapter,
|
||||
volumeConverter,
|
||||
podsVolumes,
|
||||
subpathPrefixes,
|
||||
workspaceManager);
|
||||
|
||||
k8sEnv = KubernetesEnvironment.builder().build();
|
||||
|
||||
provisionOrder = inOrder(volumeConverter, subpathPrefixes, podsVolumes);
|
||||
|
||||
lenient().doNothing().when(pvcSubPathHelper).execute(any(), any(), any(), any());
|
||||
lenient()
|
||||
.doReturn(CompletableFuture.completedFuture(null))
|
||||
.when(pvcSubPathHelper)
|
||||
.removeDirsAsync(anyString(), anyString(), any(String.class));
|
||||
|
||||
lenient().when(factory.getOrCreate(IDENTITY)).thenReturn(k8sNamespace);
|
||||
lenient().when(k8sNamespace.persistentVolumeClaims()).thenReturn(pvcs);
|
||||
|
||||
lenient().when(subpathPrefixes.getWorkspaceSubPath(WORKSPACE_ID)).thenReturn(WORKSPACE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProvisionVolumesIntoKubernetesEnvironment() throws Exception {
|
||||
// given
|
||||
k8sEnv.getPersistentVolumeClaims().put("pvc1", newPVC("pvc1"));
|
||||
k8sEnv.getPersistentVolumeClaims().put("pvc2", newPVC("pvc2"));
|
||||
|
||||
// when
|
||||
commonPVCStrategy.provision(k8sEnv, IDENTITY);
|
||||
|
||||
// then
|
||||
provisionOrder.verify(volumeConverter).convertCheVolumes(k8sEnv, WORKSPACE_ID);
|
||||
provisionOrder.verify(subpathPrefixes).prefixVolumeMountsSubpaths(k8sEnv, WORKSPACE_ID);
|
||||
provisionOrder.verify(podsVolumes).replacePVCVolumesWithCommon(k8sEnv.getPodsData(), PVC_NAME);
|
||||
assertEquals(k8sEnv.getPersistentVolumeClaims().size(), 1);
|
||||
PersistentVolumeClaim commonPVC = k8sEnv.getPersistentVolumeClaims().get(PVC_NAME);
|
||||
assertNotNull(commonPVC);
|
||||
assertEquals(commonPVC.getMetadata().getName(), PVC_NAME);
|
||||
assertEquals(commonPVC.getSpec().getAccessModes(), Collections.singletonList(PVC_ACCESS_MODE));
|
||||
assertEquals(
|
||||
commonPVC.getSpec().getResources().getRequests().get("storage"),
|
||||
new Quantity(PVC_QUANTITY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacePVCWhenItsAlreadyInKubernetesEnvironment() throws Exception {
|
||||
PersistentVolumeClaim provisioned = newPVC(PVC_NAME);
|
||||
k8sEnv.getPersistentVolumeClaims().put(PVC_NAME, provisioned);
|
||||
|
||||
commonPVCStrategy.provision(k8sEnv, IDENTITY);
|
||||
|
||||
assertNotEquals(k8sEnv.getPersistentVolumeClaims().get(PVC_NAME), provisioned);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoNotAddsSubpathsPropertyWhenPreCreationIsNotNeeded() throws Exception {
|
||||
commonPVCStrategy =
|
||||
new CommonPVCStrategy(
|
||||
PVC_NAME,
|
||||
PVC_QUANTITY,
|
||||
PVC_ACCESS_MODE,
|
||||
false,
|
||||
PVC_STORAGE_CLASS_NAME,
|
||||
true,
|
||||
pvcSubPathHelper,
|
||||
factory,
|
||||
ephemeralWorkspaceAdapter,
|
||||
volumeConverter,
|
||||
podsVolumes,
|
||||
subpathPrefixes,
|
||||
workspaceManager);
|
||||
|
||||
commonPVCStrategy.provision(k8sEnv, IDENTITY);
|
||||
|
||||
final Map<String, PersistentVolumeClaim> actual = k8sEnv.getPersistentVolumeClaims();
|
||||
assertFalse(actual.isEmpty());
|
||||
assertTrue(actual.containsKey(PVC_NAME));
|
||||
assertFalse(
|
||||
actual
|
||||
.get(PVC_NAME)
|
||||
.getAdditionalProperties()
|
||||
.containsKey(format(SUBPATHS_PROPERTY_FMT, WORKSPACE_ID)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatesPVCsWithSubpathsOnPrepare() throws Exception {
|
||||
final PersistentVolumeClaim pvc = newPVC(PVC_NAME);
|
||||
pvc.getAdditionalProperties()
|
||||
.put(format(SUBPATHS_PROPERTY_FMT, WORKSPACE_ID), WORKSPACE_SUBPATHS);
|
||||
k8sEnv.getPersistentVolumeClaims().put(PVC_NAME, pvc);
|
||||
doNothing()
|
||||
.when(pvcSubPathHelper)
|
||||
.createDirs(IDENTITY, WORKSPACE_ID, PVC_NAME, emptyMap(), WORKSPACE_SUBPATHS);
|
||||
|
||||
commonPVCStrategy.prepare(k8sEnv, IDENTITY, 100, emptyMap());
|
||||
|
||||
verify(pvcs).get();
|
||||
verify(pvcs).create(pvc);
|
||||
verify(pvcs).waitBound(PVC_NAME, 100);
|
||||
verify(pvcSubPathHelper)
|
||||
.createDirs(IDENTITY, WORKSPACE_ID, PVC_NAME, emptyMap(), WORKSPACE_SUBPATHS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatesPVCsWithSubpathsOnPrepareIfWaitIsDisabled() throws Exception {
|
||||
commonPVCStrategy =
|
||||
new CommonPVCStrategy(
|
||||
PVC_NAME,
|
||||
PVC_QUANTITY,
|
||||
PVC_ACCESS_MODE,
|
||||
true,
|
||||
PVC_STORAGE_CLASS_NAME,
|
||||
false, // wait bound PVCs
|
||||
pvcSubPathHelper,
|
||||
factory,
|
||||
ephemeralWorkspaceAdapter,
|
||||
volumeConverter,
|
||||
podsVolumes,
|
||||
subpathPrefixes,
|
||||
workspaceManager);
|
||||
final PersistentVolumeClaim pvc = newPVC(PVC_NAME);
|
||||
pvc.getAdditionalProperties()
|
||||
.put(format(SUBPATHS_PROPERTY_FMT, WORKSPACE_ID), WORKSPACE_SUBPATHS);
|
||||
k8sEnv.getPersistentVolumeClaims().put(PVC_NAME, pvc);
|
||||
doNothing()
|
||||
.when(pvcSubPathHelper)
|
||||
.createDirs(IDENTITY, WORKSPACE_ID, PVC_NAME, emptyMap(), WORKSPACE_SUBPATHS);
|
||||
|
||||
commonPVCStrategy.prepare(k8sEnv, IDENTITY, 100, emptyMap());
|
||||
|
||||
verify(pvcs).get();
|
||||
verify(pvcs).create(pvc);
|
||||
verify(pvcs, never()).waitBound(anyString(), anyLong());
|
||||
verify(pvcSubPathHelper)
|
||||
.createDirs(IDENTITY, WORKSPACE_ID, PVC_NAME, emptyMap(), WORKSPACE_SUBPATHS);
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = InfrastructureException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"The only one PVC MUST be present in common strategy while it contains: pvc1, pvc2\\.")
|
||||
public void shouldThrowExceptionIfK8sEnvHasMoreThanOnePVCOnPreparing() throws Exception {
|
||||
final PersistentVolumeClaim pvc1 = newPVC("pvc1");
|
||||
final PersistentVolumeClaim pvc2 = newPVC("pvc2");
|
||||
k8sEnv.getPersistentVolumeClaims().put("pvc1", pvc1);
|
||||
k8sEnv.getPersistentVolumeClaims().put("pvc2", pvc2);
|
||||
|
||||
commonPVCStrategy.prepare(k8sEnv, IDENTITY, 100, emptyMap());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = InfrastructureException.class)
|
||||
public void throwsInfrastructureExceptionWhenFailedToGetExistingPVCs() throws Exception {
|
||||
k8sEnv.getPersistentVolumeClaims().put(PVC_NAME, mock(PersistentVolumeClaim.class));
|
||||
doThrow(InfrastructureException.class).when(pvcs).get();
|
||||
|
||||
commonPVCStrategy.prepare(k8sEnv, IDENTITY, 100, emptyMap());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = InfrastructureException.class)
|
||||
public void throwsInfrastructureExceptionWhenPVCCreationFailed() throws Exception {
|
||||
final PersistentVolumeClaim claim = newPVC(PVC_NAME);
|
||||
k8sEnv.getPersistentVolumeClaims().put(PVC_NAME, claim);
|
||||
when(pvcs.get()).thenReturn(emptyList());
|
||||
doThrow(InfrastructureException.class).when(pvcs).create(any());
|
||||
|
||||
commonPVCStrategy.prepare(k8sEnv, IDENTITY, 100, emptyMap());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeletePVCsIfThereIsNoPersistAttributeInWorkspaceConfigWhenCleanupCalled()
|
||||
throws Exception {
|
||||
// given
|
||||
WorkspaceImpl workspace = mock(WorkspaceImpl.class);
|
||||
Page workspaces = mock(Page.class);
|
||||
|
||||
when(workspace.getId()).thenReturn(WORKSPACE_ID);
|
||||
|
||||
when(workspaceManager.getWorkspaces(anyString(), eq(false), anyInt(), anyLong()))
|
||||
.thenReturn((workspaces));
|
||||
when(workspaces.isEmpty()).thenReturn(false);
|
||||
|
||||
WorkspaceConfigImpl workspaceConfig = mock(WorkspaceConfigImpl.class);
|
||||
when(workspace.getConfig()).thenReturn(workspaceConfig);
|
||||
|
||||
AccountImpl account = mock(AccountImpl.class);
|
||||
when(account.getType()).thenReturn(PERSONAL_ACCOUNT);
|
||||
when(account.getId()).thenReturn("id123");
|
||||
when(workspace.getAccount()).thenReturn(account);
|
||||
|
||||
Map<String, String> workspaceConfigAttributes = new HashMap<>();
|
||||
when(workspaceConfig.getAttributes()).thenReturn(workspaceConfigAttributes);
|
||||
|
||||
KubernetesNamespace ns = mock(KubernetesNamespace.class);
|
||||
when(factory.get(eq(workspace))).thenReturn(ns);
|
||||
when(ns.getName()).thenReturn("ns");
|
||||
|
||||
// when
|
||||
commonPVCStrategy.cleanup(workspace);
|
||||
|
||||
// then
|
||||
verify(pvcSubPathHelper).removeDirsAsync(WORKSPACE_ID, "ns", PVC_NAME, WORKSPACE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeletePVCsIfPersistAttributeIsSetToTrueInWorkspaceConfigWhenCleanupCalled()
|
||||
throws Exception {
|
||||
// given
|
||||
WorkspaceImpl workspace = mock(WorkspaceImpl.class);
|
||||
Page workspaces = mock(Page.class);
|
||||
|
||||
when(workspaceManager.getWorkspaces(anyString(), eq(false), anyInt(), anyLong()))
|
||||
.thenReturn((workspaces));
|
||||
when(workspaces.isEmpty()).thenReturn(false);
|
||||
when(workspace.getId()).thenReturn(WORKSPACE_ID);
|
||||
|
||||
WorkspaceConfigImpl workspaceConfig = mock(WorkspaceConfigImpl.class);
|
||||
when(workspace.getConfig()).thenReturn(workspaceConfig);
|
||||
|
||||
AccountImpl account = mock(AccountImpl.class);
|
||||
when(account.getType()).thenReturn(PERSONAL_ACCOUNT);
|
||||
when(account.getId()).thenReturn("id123");
|
||||
when(workspace.getAccount()).thenReturn(account);
|
||||
|
||||
Map<String, String> workspaceConfigAttributes = new HashMap<>();
|
||||
when(workspaceConfig.getAttributes()).thenReturn(workspaceConfigAttributes);
|
||||
workspaceConfigAttributes.put(PERSIST_VOLUMES_ATTRIBUTE, "true");
|
||||
|
||||
KubernetesNamespace ns = mock(KubernetesNamespace.class);
|
||||
when(factory.get(eq(workspace))).thenReturn(ns);
|
||||
when(ns.getName()).thenReturn("ns");
|
||||
|
||||
// when
|
||||
commonPVCStrategy.cleanup(workspace);
|
||||
|
||||
// then
|
||||
verify(pvcSubPathHelper).removeDirsAsync(WORKSPACE_ID, "ns", PVC_NAME, WORKSPACE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeleteCommonPVCIfUserHasNoWorkspaces() throws Exception {
|
||||
// given
|
||||
WorkspaceImpl workspace = mock(WorkspaceImpl.class);
|
||||
Page workspaces = mock(Page.class);
|
||||
KubernetesPersistentVolumeClaims persistentVolumeClaims =
|
||||
mock(KubernetesPersistentVolumeClaims.class);
|
||||
|
||||
when(workspaceManager.getWorkspaces(anyString(), eq(false), anyInt(), anyLong()))
|
||||
.thenReturn((workspaces));
|
||||
when(workspaces.isEmpty()).thenReturn(true);
|
||||
|
||||
AccountImpl account = mock(AccountImpl.class);
|
||||
when(account.getType()).thenReturn(PERSONAL_ACCOUNT);
|
||||
when(account.getId()).thenReturn("id123");
|
||||
when(workspace.getAccount()).thenReturn(account);
|
||||
|
||||
KubernetesNamespace ns = mock(KubernetesNamespace.class);
|
||||
when(factory.get(eq(workspace))).thenReturn(ns);
|
||||
when(ns.persistentVolumeClaims()).thenReturn(persistentVolumeClaims);
|
||||
|
||||
// when
|
||||
commonPVCStrategy.cleanup(workspace);
|
||||
|
||||
// then
|
||||
verify(ns).persistentVolumeClaims();
|
||||
verify(persistentVolumeClaims).delete(PVC_NAME);
|
||||
verify(pvcSubPathHelper, never()).removeDirsAsync(WORKSPACE_ID, "ns", PVC_NAME, WORKSPACE_ID);
|
||||
verify(workspace, never()).getConfig();
|
||||
verify(workspace, never()).getDevfile();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotDeleteCommonPVCIfUserHasWorkspaces() throws Exception {
|
||||
// given
|
||||
WorkspaceImpl workspace = mock(WorkspaceImpl.class);
|
||||
Page workspaces = mock(Page.class);
|
||||
KubernetesPersistentVolumeClaims persistentVolumeClaims =
|
||||
mock(KubernetesPersistentVolumeClaims.class);
|
||||
|
||||
when(workspaceManager.getWorkspaces(anyString(), eq(false), anyInt(), anyLong()))
|
||||
.thenReturn((workspaces));
|
||||
when(workspaces.isEmpty()).thenReturn(false);
|
||||
when(workspace.getId()).thenReturn(WORKSPACE_ID);
|
||||
|
||||
WorkspaceConfigImpl workspaceConfig = mock(WorkspaceConfigImpl.class);
|
||||
when(workspace.getConfig()).thenReturn(workspaceConfig);
|
||||
|
||||
AccountImpl account = mock(AccountImpl.class);
|
||||
when(account.getType()).thenReturn(PERSONAL_ACCOUNT);
|
||||
when(account.getId()).thenReturn("id123");
|
||||
when(workspace.getAccount()).thenReturn(account);
|
||||
|
||||
Map<String, String> workspaceConfigAttributes = new HashMap<>();
|
||||
when(workspaceConfig.getAttributes()).thenReturn(workspaceConfigAttributes);
|
||||
workspaceConfigAttributes.put(PERSIST_VOLUMES_ATTRIBUTE, "true");
|
||||
|
||||
KubernetesNamespace ns = mock(KubernetesNamespace.class);
|
||||
when(factory.get(eq(workspace))).thenReturn(ns);
|
||||
when(ns.getName()).thenReturn("ns");
|
||||
|
||||
// when
|
||||
commonPVCStrategy.cleanup(workspace);
|
||||
|
||||
// then
|
||||
verify(ns, never()).persistentVolumeClaims();
|
||||
verify(persistentVolumeClaims, never()).delete(PVC_NAME);
|
||||
verify(pvcSubPathHelper).removeDirsAsync(WORKSPACE_ID, "ns", PVC_NAME, WORKSPACE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void
|
||||
shouldDoNothingIfPersistAttributeIsSetToFalseInWorkspaceConfigAndWorkspacesNotEmptyWhenCleanupCalled()
|
||||
throws Exception {
|
||||
// given
|
||||
WorkspaceImpl workspace = mock(WorkspaceImpl.class);
|
||||
Page workspaces = mock(Page.class);
|
||||
KubernetesPersistentVolumeClaims persistentVolumeClaims =
|
||||
mock(KubernetesPersistentVolumeClaims.class);
|
||||
|
||||
when(workspaceManager.getWorkspaces(anyString(), eq(false), anyInt(), anyLong()))
|
||||
.thenReturn((workspaces));
|
||||
when(workspaces.isEmpty()).thenReturn(false);
|
||||
|
||||
AccountImpl account = mock(AccountImpl.class);
|
||||
when(account.getType()).thenReturn(PERSONAL_ACCOUNT);
|
||||
when(account.getId()).thenReturn("id123");
|
||||
when(workspace.getAccount()).thenReturn(account);
|
||||
|
||||
WorkspaceConfigImpl workspaceConfig = mock(WorkspaceConfigImpl.class);
|
||||
when(workspace.getConfig()).thenReturn(workspaceConfig);
|
||||
Map<String, String> workspaceConfigAttributes = new HashMap<>();
|
||||
when(workspaceConfig.getAttributes()).thenReturn(workspaceConfigAttributes);
|
||||
workspaceConfigAttributes.put(PERSIST_VOLUMES_ATTRIBUTE, "false");
|
||||
|
||||
// when
|
||||
commonPVCStrategy.cleanup(workspace);
|
||||
|
||||
// then
|
||||
verify(persistentVolumeClaims, never()).delete(PVC_NAME);
|
||||
verify(pvcSubPathHelper, never()).removeDirsAsync(WORKSPACE_ID, "ns", PVC_NAME, WORKSPACE_ID);
|
||||
}
|
||||
|
||||
private static PersistentVolumeClaim newPVC(String name) {
|
||||
return new PersistentVolumeClaimBuilder()
|
||||
.withNewMetadata()
|
||||
.withName(name)
|
||||
.endMetadata()
|
||||
.withNewSpec()
|
||||
.endSpec()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,331 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc;
|
||||
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.Constants.CHE_VOLUME_NAME_LABEL;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.TestObjects.newContainer;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.TestObjects.newPod;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.fabric8.kubernetes.api.model.Container;
|
||||
import io.fabric8.kubernetes.api.model.PersistentVolumeClaim;
|
||||
import io.fabric8.kubernetes.api.model.PersistentVolumeClaimBuilder;
|
||||
import io.fabric8.kubernetes.api.model.PersistentVolumeClaimVolumeSourceBuilder;
|
||||
import io.fabric8.kubernetes.api.model.Pod;
|
||||
import io.fabric8.kubernetes.api.model.PodSpec;
|
||||
import io.fabric8.kubernetes.api.model.VolumeBuilder;
|
||||
import io.fabric8.kubernetes.api.model.VolumeMount;
|
||||
import io.fabric8.kubernetes.api.model.VolumeMountBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.RuntimeIdentityImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.VolumeImpl;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/** @author Sergii Leshchenko */
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class PVCProvisionerTest {
|
||||
|
||||
private static final String WORKSPACE_ID = "workspace123";
|
||||
private static final String PVC_NAME_PREFIX = "che-claim";
|
||||
|
||||
private static final String POD_1_NAME = "main";
|
||||
private static final String CONTAINER_1_NAME = "app";
|
||||
private static final String CONTAINER_2_NAME = "db";
|
||||
private static final String MACHINE_1_NAME = POD_1_NAME + '/' + CONTAINER_1_NAME;
|
||||
private static final String MACHINE_2_NAME = POD_1_NAME + '/' + CONTAINER_2_NAME;
|
||||
|
||||
private static final String POD_2_NAME = "second";
|
||||
private static final String CONTAINER_3_NAME = "app2";
|
||||
private static final String MACHINE_3_NAME = POD_2_NAME + '/' + CONTAINER_3_NAME;
|
||||
|
||||
private static final String VOLUME_1_NAME = "vol1";
|
||||
private static final String VOLUME_2_NAME = "vol2";
|
||||
|
||||
private static final String PVC_QUANTITY = "10Gi";
|
||||
private static final String PVC_ACCESS_MODE = "RWO";
|
||||
private static final String PVC_STORAGE_CLASS_NAME = "default";
|
||||
|
||||
private static final RuntimeIdentity IDENTITY =
|
||||
new RuntimeIdentityImpl(WORKSPACE_ID, "env1", "id1", "infraNamespace");
|
||||
|
||||
private KubernetesEnvironment k8sEnv;
|
||||
|
||||
private Pod pod;
|
||||
private Pod pod2;
|
||||
|
||||
@Mock private PodsVolumes podsVolumes;
|
||||
private PVCProvisioner provisioner;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() {
|
||||
provisioner =
|
||||
new PVCProvisioner(
|
||||
PVC_NAME_PREFIX, PVC_QUANTITY, PVC_ACCESS_MODE, PVC_STORAGE_CLASS_NAME, podsVolumes);
|
||||
|
||||
k8sEnv = KubernetesEnvironment.builder().build();
|
||||
|
||||
k8sEnv
|
||||
.getMachines()
|
||||
.put(
|
||||
MACHINE_1_NAME,
|
||||
TestObjects.newMachineConfig()
|
||||
.withVolume(VOLUME_1_NAME, "/path")
|
||||
.withVolume(VOLUME_2_NAME, "/path2")
|
||||
.build());
|
||||
|
||||
k8sEnv
|
||||
.getMachines()
|
||||
.put(
|
||||
MACHINE_2_NAME,
|
||||
TestObjects.newMachineConfig().withVolume(VOLUME_2_NAME, "/path2").build());
|
||||
|
||||
k8sEnv
|
||||
.getMachines()
|
||||
.put(
|
||||
MACHINE_3_NAME,
|
||||
TestObjects.newMachineConfig().withVolume(VOLUME_1_NAME, "/path").build());
|
||||
|
||||
pod =
|
||||
newPod(POD_1_NAME)
|
||||
.withContainers(
|
||||
newContainer(CONTAINER_1_NAME).build(), newContainer(CONTAINER_2_NAME).build())
|
||||
.build();
|
||||
|
||||
pod2 = newPod(POD_2_NAME).withContainers(newContainer(CONTAINER_3_NAME).build()).build();
|
||||
|
||||
k8sEnv.addPod(pod);
|
||||
k8sEnv.addPod(pod2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProvisionPVCsForEachVolumeWithUniqueName() throws Exception {
|
||||
// given
|
||||
k8sEnv.getPersistentVolumeClaims().clear();
|
||||
|
||||
// when
|
||||
provisioner.convertCheVolumes(k8sEnv, WORKSPACE_ID);
|
||||
|
||||
// then
|
||||
assertEquals(pod.getSpec().getVolumes().size(), 2);
|
||||
assertEquals(pod.getSpec().getContainers().get(0).getVolumeMounts().size(), 2);
|
||||
assertEquals(pod.getSpec().getContainers().get(1).getVolumeMounts().size(), 1);
|
||||
|
||||
assertEquals(pod2.getSpec().getVolumes().size(), 1);
|
||||
assertEquals(pod2.getSpec().getContainers().get(0).getVolumeMounts().size(), 1);
|
||||
assertEquals(k8sEnv.getPersistentVolumeClaims().size(), 2);
|
||||
|
||||
PersistentVolumeClaim pvcForVolume1 =
|
||||
findPvc(VOLUME_1_NAME, k8sEnv.getPersistentVolumeClaims());
|
||||
assertNotNull(pvcForVolume1);
|
||||
assertTrue(pvcForVolume1.getMetadata().getName().startsWith(PVC_NAME_PREFIX));
|
||||
|
||||
PersistentVolumeClaim pvcForVolume2 =
|
||||
findPvc(VOLUME_2_NAME, k8sEnv.getPersistentVolumeClaims());
|
||||
assertNotNull(pvcForVolume2);
|
||||
assertTrue(pvcForVolume2.getMetadata().getName().startsWith(PVC_NAME_PREFIX));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchingUserDefinedPVCWithCheVolume() throws Exception {
|
||||
// given
|
||||
k8sEnv.getPersistentVolumeClaims().put("userDataPVC", newPVC("userDataPVC"));
|
||||
|
||||
pod.getSpec()
|
||||
.getVolumes()
|
||||
.add(
|
||||
new VolumeBuilder()
|
||||
.withName("userData")
|
||||
.withPersistentVolumeClaim(
|
||||
new PersistentVolumeClaimVolumeSourceBuilder()
|
||||
.withClaimName("userDataPVC")
|
||||
.build())
|
||||
.build());
|
||||
|
||||
pod.getSpec()
|
||||
.getContainers()
|
||||
.get(0)
|
||||
.getVolumeMounts()
|
||||
.add(new VolumeMountBuilder().withName("userData").withSubPath("/home/user/data").build());
|
||||
|
||||
k8sEnv.getMachines().values().forEach(m -> m.getVolumes().clear());
|
||||
k8sEnv
|
||||
.getMachines()
|
||||
.get(MACHINE_2_NAME)
|
||||
.getVolumes()
|
||||
.put("userDataPVC", new VolumeImpl().withPath("/"));
|
||||
|
||||
// when
|
||||
provisioner.convertCheVolumes(k8sEnv, WORKSPACE_ID);
|
||||
|
||||
// then
|
||||
assertEquals(k8sEnv.getPersistentVolumeClaims().size(), 1);
|
||||
PersistentVolumeClaim pvcForUserData =
|
||||
findPvc("userDataPVC", k8sEnv.getPersistentVolumeClaims());
|
||||
assertNotNull(pvcForUserData);
|
||||
assertEquals("userDataPVC", pvcForUserData.getMetadata().getName());
|
||||
|
||||
PodSpec podSpec = k8sEnv.getPodsData().get(POD_1_NAME).getSpec();
|
||||
|
||||
io.fabric8.kubernetes.api.model.Volume userPodVolume = podSpec.getVolumes().get(0);
|
||||
assertEquals(
|
||||
userPodVolume.getPersistentVolumeClaim().getClaimName(),
|
||||
pvcForUserData.getMetadata().getName());
|
||||
assertEquals(
|
||||
podSpec.getVolumes().get(0).getPersistentVolumeClaim().getClaimName(),
|
||||
pvcForUserData.getMetadata().getName());
|
||||
|
||||
// check container bound to user-defined PVC
|
||||
Container container1 = podSpec.getContainers().get(0);
|
||||
assertEquals(container1.getVolumeMounts().size(), 1);
|
||||
VolumeMount volumeMount = container1.getVolumeMounts().get(0);
|
||||
assertEquals(volumeMount.getName(), userPodVolume.getName());
|
||||
|
||||
// check container that is bound to Che Volume via Machine configuration
|
||||
Container container2 = podSpec.getContainers().get(1);
|
||||
VolumeMount cheVolumeMount2 = container2.getVolumeMounts().get(0);
|
||||
assertEquals(cheVolumeMount2.getName(), userPodVolume.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoNotProvisionPVCsWhenItIsAlreadyProvisionedForGivenVolumeAndWorkspace()
|
||||
throws Exception {
|
||||
final String pvcUniqueName1 = PVC_NAME_PREFIX + "-3121";
|
||||
PersistentVolumeClaim pvc1 =
|
||||
newPVC(pvcUniqueName1, ImmutableMap.of(CHE_VOLUME_NAME_LABEL, VOLUME_1_NAME));
|
||||
pvc1.getAdditionalProperties().put("CHE_PROVISIONED", true);
|
||||
final String pvcUniqueName2 = PVC_NAME_PREFIX + "-71333";
|
||||
PersistentVolumeClaim pvc2 =
|
||||
newPVC(pvcUniqueName2, ImmutableMap.of(CHE_VOLUME_NAME_LABEL, VOLUME_2_NAME));
|
||||
pvc2.getAdditionalProperties().put("CHE_PROVISIONED", true);
|
||||
|
||||
k8sEnv.getPersistentVolumeClaims().put(pvc1.getMetadata().getName(), pvc1);
|
||||
k8sEnv.getPersistentVolumeClaims().put(pvc2.getMetadata().getName(), pvc2);
|
||||
|
||||
provisioner.convertCheVolumes(k8sEnv, WORKSPACE_ID);
|
||||
|
||||
assertEquals(pod.getSpec().getVolumes().size(), 2);
|
||||
assertEquals(pod.getSpec().getContainers().get(0).getVolumeMounts().size(), 2);
|
||||
assertEquals(pod.getSpec().getContainers().get(1).getVolumeMounts().size(), 1);
|
||||
assertEquals(pod2.getSpec().getVolumes().size(), 1);
|
||||
assertEquals(pod2.getSpec().getContainers().get(0).getVolumeMounts().size(), 1);
|
||||
assertEquals(k8sEnv.getPersistentVolumeClaims().size(), 2);
|
||||
assertTrue(k8sEnv.getPersistentVolumeClaims().containsKey(pvcUniqueName1));
|
||||
assertTrue(k8sEnv.getPersistentVolumeClaims().containsKey(pvcUniqueName2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProvisioningPVCsToK8sEnvironment() throws Exception {
|
||||
// given
|
||||
k8sEnv = KubernetesEnvironment.builder().build();
|
||||
Map<String, PersistentVolumeClaim> toProvision = new HashMap<>();
|
||||
toProvision.put("appStorage", newPVC("appStorage"));
|
||||
|
||||
Pod pod =
|
||||
newPod(POD_1_NAME)
|
||||
.withContainers(
|
||||
newContainer(CONTAINER_1_NAME)
|
||||
.withVolumeMount("appStorage", "/data", "data")
|
||||
.withVolumeMount("appStorage", "/config", "config")
|
||||
.build())
|
||||
.withPVCVolume("appStorage", "appStorage")
|
||||
.build();
|
||||
|
||||
k8sEnv.addPod(pod);
|
||||
|
||||
// when
|
||||
provisioner.provision(k8sEnv, toProvision);
|
||||
|
||||
// then
|
||||
assertEquals(k8sEnv.getPersistentVolumeClaims().size(), 1);
|
||||
PersistentVolumeClaim pvcForUserData =
|
||||
findPvc("appStorage", k8sEnv.getPersistentVolumeClaims());
|
||||
assertNotNull(pvcForUserData);
|
||||
assertTrue(pvcForUserData.getMetadata().getName().startsWith(PVC_NAME_PREFIX));
|
||||
|
||||
verify(podsVolumes)
|
||||
.changePVCReferences(
|
||||
k8sEnv.getPodsData().values(), "appStorage", pvcForUserData.getMetadata().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchEnvPVCsByVolumeNameWhenProvisioningPVCsToK8sEnvironment() throws Exception {
|
||||
// given
|
||||
k8sEnv = KubernetesEnvironment.builder().build();
|
||||
k8sEnv
|
||||
.getPersistentVolumeClaims()
|
||||
.put(
|
||||
"appStorage",
|
||||
newPVC("pvc123123", ImmutableMap.of(CHE_VOLUME_NAME_LABEL, "appStorage")));
|
||||
|
||||
Map<String, PersistentVolumeClaim> toProvision = new HashMap<>();
|
||||
toProvision.put("appStorage", newPVC("appStorage"));
|
||||
|
||||
Pod pod =
|
||||
newPod(POD_1_NAME)
|
||||
.withContainers(
|
||||
newContainer(CONTAINER_1_NAME)
|
||||
.withVolumeMount("appStorage", "/data", "data")
|
||||
.withVolumeMount("appStorage", "/config", "config")
|
||||
.build())
|
||||
.withPVCVolume("appStorage", "appStorage")
|
||||
.build();
|
||||
|
||||
k8sEnv.addPod(pod);
|
||||
|
||||
// when
|
||||
provisioner.provision(k8sEnv, toProvision);
|
||||
|
||||
// then
|
||||
assertEquals(k8sEnv.getPersistentVolumeClaims().size(), 1);
|
||||
PersistentVolumeClaim pvcForUserData =
|
||||
findPvc("appStorage", k8sEnv.getPersistentVolumeClaims());
|
||||
assertNotNull(pvcForUserData);
|
||||
assertEquals("pvc123123", pvcForUserData.getMetadata().getName());
|
||||
|
||||
verify(podsVolumes)
|
||||
.changePVCReferences(k8sEnv.getPodsData().values(), "appStorage", "pvc123123");
|
||||
}
|
||||
|
||||
private static PersistentVolumeClaim newPVC(String name) {
|
||||
return newPVC(name, new HashMap<>());
|
||||
}
|
||||
|
||||
private static PersistentVolumeClaim newPVC(String name, Map<String, String> labels) {
|
||||
return new PersistentVolumeClaimBuilder()
|
||||
.withNewMetadata()
|
||||
.withName(name)
|
||||
.withLabels(labels)
|
||||
.endMetadata()
|
||||
.withNewSpec()
|
||||
.endSpec()
|
||||
.build();
|
||||
}
|
||||
|
||||
private PersistentVolumeClaim findPvc(
|
||||
String volumeName, Map<String, PersistentVolumeClaim> claims) {
|
||||
return claims.values().stream()
|
||||
.filter(c -> volumeName.equals(c.getMetadata().getLabels().get(CHE_VOLUME_NAME_LABEL)))
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,274 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.PERSIST_VOLUMES_ATTRIBUTE;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.Constants.CHE_WORKSPACE_ID_LABEL;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.CommonPVCStrategy.SUBPATHS_PROPERTY_FMT;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.fabric8.kubernetes.api.model.PersistentVolumeClaim;
|
||||
import io.fabric8.kubernetes.api.model.PersistentVolumeClaimBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
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.runtime.RuntimeIdentity;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceManager;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.RuntimeIdentityImpl;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespace;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespaceFactory;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesPersistentVolumeClaims;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link PerWorkspacePVCStrategy}
|
||||
*
|
||||
* @author Sergii Leshchenko
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class PerWorkspacePVCStrategyTest {
|
||||
|
||||
private static final String WORKSPACE_ID = "workspace123";
|
||||
private static final String INFRA_NAMESPACE = "infraNamespace";
|
||||
private static final String PVC_NAME_PREFIX = "che-claim";
|
||||
|
||||
private static final String PVC_QUANTITY = "10Gi";
|
||||
private static final String PVC_ACCESS_MODE = "RWO";
|
||||
private static final String PVC_STORAGE_CLASS_NAME = "special";
|
||||
|
||||
private static final RuntimeIdentity IDENTITY =
|
||||
new RuntimeIdentityImpl(WORKSPACE_ID, "userid", null, INFRA_NAMESPACE);
|
||||
|
||||
@Mock private PVCSubPathHelper pvcSubPathHelper;
|
||||
@Mock private KubernetesNamespaceFactory factory;
|
||||
@Mock private KubernetesNamespace k8sNamespace;
|
||||
@Mock private KubernetesPersistentVolumeClaims pvcs;
|
||||
@Mock private EphemeralWorkspaceAdapter ephemeralWorkspaceAdapter;
|
||||
|
||||
@Mock private PVCProvisioner volumeConverter;
|
||||
@Mock private PodsVolumes podsVolumes;
|
||||
@Mock private SubPathPrefixes subpathPrefixes;
|
||||
@Mock private WorkspaceManager workspaceManager;
|
||||
|
||||
private PerWorkspacePVCStrategy strategy;
|
||||
|
||||
@BeforeMethod
|
||||
public void setup() throws Exception {
|
||||
strategy =
|
||||
new PerWorkspacePVCStrategy(
|
||||
PVC_NAME_PREFIX,
|
||||
PVC_QUANTITY,
|
||||
PVC_ACCESS_MODE,
|
||||
true,
|
||||
PVC_STORAGE_CLASS_NAME,
|
||||
true,
|
||||
pvcSubPathHelper,
|
||||
factory,
|
||||
ephemeralWorkspaceAdapter,
|
||||
volumeConverter,
|
||||
podsVolumes,
|
||||
subpathPrefixes,
|
||||
workspaceManager);
|
||||
|
||||
lenient().when(factory.getOrCreate(IDENTITY)).thenReturn(k8sNamespace);
|
||||
lenient().when(factory.get(any(Workspace.class))).thenReturn(k8sNamespace);
|
||||
lenient().when(k8sNamespace.persistentVolumeClaims()).thenReturn(pvcs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldPreparePerWorkspacePVCWithSubPaths() throws Exception {
|
||||
// given
|
||||
final PersistentVolumeClaim pvc = newPVC(PVC_NAME_PREFIX + "-" + WORKSPACE_ID);
|
||||
String perWorkspacePVCName = pvc.getMetadata().getName();
|
||||
|
||||
KubernetesEnvironment k8sEnv = KubernetesEnvironment.builder().build();
|
||||
k8sEnv.getPersistentVolumeClaims().put(perWorkspacePVCName, pvc);
|
||||
|
||||
String[] subPaths = {"/projects", "/plugins"};
|
||||
pvc.getAdditionalProperties().put(format(SUBPATHS_PROPERTY_FMT, WORKSPACE_ID), subPaths);
|
||||
|
||||
// when
|
||||
strategy.prepare(k8sEnv, IDENTITY, 100, emptyMap());
|
||||
|
||||
// then
|
||||
verify(pvcs).get();
|
||||
verify(pvcs).create(pvc);
|
||||
verify(pvcs).waitBound(perWorkspacePVCName, 100);
|
||||
verify(pvcSubPathHelper)
|
||||
.createDirs(IDENTITY, WORKSPACE_ID, perWorkspacePVCName, emptyMap(), subPaths);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldPreparePerWorkspacePVCWithSubPathsWhenWaitBoundIsDisabled() throws Exception {
|
||||
// given
|
||||
strategy =
|
||||
new PerWorkspacePVCStrategy(
|
||||
PVC_NAME_PREFIX,
|
||||
PVC_QUANTITY,
|
||||
PVC_ACCESS_MODE,
|
||||
true,
|
||||
PVC_STORAGE_CLASS_NAME,
|
||||
false,
|
||||
pvcSubPathHelper,
|
||||
factory,
|
||||
ephemeralWorkspaceAdapter,
|
||||
volumeConverter,
|
||||
podsVolumes,
|
||||
subpathPrefixes,
|
||||
workspaceManager);
|
||||
final PersistentVolumeClaim pvc = newPVC(PVC_NAME_PREFIX + "-" + WORKSPACE_ID);
|
||||
String perWorkspacePVCName = pvc.getMetadata().getName();
|
||||
|
||||
KubernetesEnvironment k8sEnv = KubernetesEnvironment.builder().build();
|
||||
k8sEnv.getPersistentVolumeClaims().put(perWorkspacePVCName, pvc);
|
||||
|
||||
String[] subPaths = {"/projects", "/plugins"};
|
||||
pvc.getAdditionalProperties().put(format(SUBPATHS_PROPERTY_FMT, WORKSPACE_ID), subPaths);
|
||||
|
||||
// when
|
||||
strategy.prepare(k8sEnv, IDENTITY, 100, emptyMap());
|
||||
|
||||
// then
|
||||
verify(pvcs).get();
|
||||
verify(pvcs).create(pvc);
|
||||
verify(pvcs, never()).waitBound(anyString(), anyLong());
|
||||
verify(pvcSubPathHelper)
|
||||
.createDirs(IDENTITY, WORKSPACE_ID, perWorkspacePVCName, emptyMap(), subPaths);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnPVCPerWorkspace() throws Exception {
|
||||
// when
|
||||
PersistentVolumeClaim commonPVC = strategy.createCommonPVC(WORKSPACE_ID);
|
||||
|
||||
// then
|
||||
assertEquals(commonPVC.getMetadata().getName(), PVC_NAME_PREFIX + "-" + WORKSPACE_ID);
|
||||
assertEquals(commonPVC.getMetadata().getLabels().get(CHE_WORKSPACE_ID_LABEL), WORKSPACE_ID);
|
||||
assertEquals(commonPVC.getSpec().getStorageClassName(), PVC_STORAGE_CLASS_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnNullStorageClassNameWhenStorageClassNameIsEmptyOrNull() throws Exception {
|
||||
String[] storageClassNames = {"", null};
|
||||
|
||||
for (String storageClassName : storageClassNames) {
|
||||
final PerWorkspacePVCStrategy strategy =
|
||||
new PerWorkspacePVCStrategy(
|
||||
PVC_NAME_PREFIX,
|
||||
PVC_QUANTITY,
|
||||
PVC_ACCESS_MODE,
|
||||
true,
|
||||
storageClassName,
|
||||
true,
|
||||
pvcSubPathHelper,
|
||||
factory,
|
||||
ephemeralWorkspaceAdapter,
|
||||
volumeConverter,
|
||||
podsVolumes,
|
||||
subpathPrefixes,
|
||||
workspaceManager);
|
||||
|
||||
final PersistentVolumeClaim commonPVC = strategy.createCommonPVC(WORKSPACE_ID);
|
||||
|
||||
assertNull(commonPVC.getSpec().getStorageClassName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeletePVCsIfThereIsNoPersistAttributeInWorkspaceConfigWhenCleanupCalled()
|
||||
throws Exception {
|
||||
// given
|
||||
Workspace workspace = mock(Workspace.class);
|
||||
lenient().when(workspace.getId()).thenReturn(WORKSPACE_ID);
|
||||
|
||||
WorkspaceConfig workspaceConfig = mock(WorkspaceConfig.class);
|
||||
lenient().when(workspace.getConfig()).thenReturn(workspaceConfig);
|
||||
|
||||
Map<String, String> workspaceConfigAttributes = new HashMap<>();
|
||||
lenient().when(workspaceConfig.getAttributes()).thenReturn(workspaceConfigAttributes);
|
||||
|
||||
// when
|
||||
strategy.cleanup(workspace);
|
||||
|
||||
// then
|
||||
verify(pvcs).delete(ImmutableMap.of(CHE_WORKSPACE_ID_LABEL, WORKSPACE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeletePVCsIfPersistAttributeIsSetToTrueInWorkspaceConfigWhenCleanupCalled()
|
||||
throws Exception {
|
||||
// given
|
||||
Workspace workspace = mock(Workspace.class);
|
||||
lenient().when(workspace.getId()).thenReturn(WORKSPACE_ID);
|
||||
|
||||
WorkspaceConfig workspaceConfig = mock(WorkspaceConfig.class);
|
||||
lenient().when(workspace.getConfig()).thenReturn(workspaceConfig);
|
||||
|
||||
Map<String, String> workspaceConfigAttributes = new HashMap<>();
|
||||
lenient().when(workspaceConfig.getAttributes()).thenReturn(workspaceConfigAttributes);
|
||||
workspaceConfigAttributes.put(PERSIST_VOLUMES_ATTRIBUTE, "true");
|
||||
|
||||
// when
|
||||
strategy.cleanup(workspace);
|
||||
|
||||
// then
|
||||
verify(pvcs).delete(ImmutableMap.of(CHE_WORKSPACE_ID_LABEL, WORKSPACE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDoNothingIfPersistAttributeIsSetToFalseInWorkspaceConfigWhenCleanupCalled()
|
||||
throws Exception {
|
||||
// given
|
||||
Workspace workspace = mock(Workspace.class);
|
||||
lenient().when(workspace.getId()).thenReturn(WORKSPACE_ID);
|
||||
|
||||
WorkspaceConfig workspaceConfig = mock(WorkspaceConfig.class);
|
||||
lenient().when(workspace.getConfig()).thenReturn(workspaceConfig);
|
||||
|
||||
Map<String, String> workspaceConfigAttributes = new HashMap<>();
|
||||
lenient().when(workspaceConfig.getAttributes()).thenReturn(workspaceConfigAttributes);
|
||||
workspaceConfigAttributes.put(PERSIST_VOLUMES_ATTRIBUTE, "false");
|
||||
|
||||
// when
|
||||
strategy.cleanup(workspace);
|
||||
|
||||
// then
|
||||
verify(pvcs, never()).delete(ImmutableMap.of(CHE_WORKSPACE_ID_LABEL, WORKSPACE_ID));
|
||||
}
|
||||
|
||||
private static PersistentVolumeClaim newPVC(String name) {
|
||||
return new PersistentVolumeClaimBuilder()
|
||||
.withNewMetadata()
|
||||
.withName(name)
|
||||
.endMetadata()
|
||||
.withNewSpec()
|
||||
.endSpec()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,370 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.workspace.infrastructure.kubernetes.provision;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static java.util.UUID.randomUUID;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.ASYNC_PERSIST_ATTRIBUTE;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.PERSIST_VOLUMES_ATTRIBUTE;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.provision.AsyncStorageProvisioner.ASYNC_STORAGE;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.provision.AsyncStorageProvisioner.ASYNC_STORAGE_CONFIG;
|
||||
import static org.eclipse.che.workspace.infrastructure.kubernetes.provision.AsyncStorageProvisioner.SSH_KEY_NAME;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMap;
|
||||
import io.fabric8.kubernetes.api.model.ObjectMeta;
|
||||
import io.fabric8.kubernetes.api.model.PersistentVolumeClaim;
|
||||
import io.fabric8.kubernetes.api.model.Pod;
|
||||
import io.fabric8.kubernetes.api.model.Service;
|
||||
import io.fabric8.kubernetes.api.model.apps.Deployment;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.Watcher;
|
||||
import io.fabric8.kubernetes.client.dsl.AppsAPIGroupDSL;
|
||||
import io.fabric8.kubernetes.client.dsl.MixedOperation;
|
||||
import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
|
||||
import io.fabric8.kubernetes.client.dsl.PodResource;
|
||||
import io.fabric8.kubernetes.client.dsl.Resource;
|
||||
import io.fabric8.kubernetes.client.dsl.RollableScalableResource;
|
||||
import io.fabric8.kubernetes.client.dsl.ServiceResource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
|
||||
import org.eclipse.che.api.ssh.server.SshManager;
|
||||
import org.eclipse.che.api.ssh.server.model.impl.SshPairImpl;
|
||||
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFactory;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
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 AsyncStorageProvisionerTest {
|
||||
|
||||
private static final String WORKSPACE_ID = UUID.randomUUID().toString();
|
||||
private static final String NAMESPACE = UUID.randomUUID().toString();
|
||||
private static final String CONFIGMAP_NAME = NAMESPACE + ASYNC_STORAGE_CONFIG;
|
||||
private static final String VPC_NAME = UUID.randomUUID().toString();
|
||||
private static final String USER = "user";
|
||||
|
||||
@Mock private KubernetesEnvironment kubernetesEnvironment;
|
||||
@Mock private RuntimeIdentity identity;
|
||||
@Mock private KubernetesClientFactory clientFactory;
|
||||
@Mock private KubernetesClient kubernetesClient;
|
||||
@Mock private SshManager sshManager;
|
||||
@Mock private Resource<PersistentVolumeClaim> pvcResource;
|
||||
@Mock private Resource<ConfigMap> mapResource;
|
||||
@Mock private PodResource<Pod> podResource;
|
||||
@Mock private RollableScalableResource<Deployment> deploymentResource;
|
||||
@Mock private ServiceResource<Service> serviceResource;
|
||||
@Mock private MixedOperation mixedOperationPvc;
|
||||
@Mock private MixedOperation mixedOperationConfigMap;
|
||||
@Mock private MixedOperation mixedOperationPod;
|
||||
@Mock private MixedOperation mixedOperationDeployment;
|
||||
@Mock private MixedOperation mixedOperationService;
|
||||
@Mock private NonNamespaceOperation namespacePvcOperation;
|
||||
@Mock private NonNamespaceOperation namespaceConfigMapOperation;
|
||||
@Mock private NonNamespaceOperation namespacePodOperation;
|
||||
@Mock private NonNamespaceOperation namespaceDeploymentOperation;
|
||||
@Mock private NonNamespaceOperation namespaceServiceOperation;
|
||||
@Mock private AppsAPIGroupDSL apps;
|
||||
@Captor private ArgumentCaptor<Watcher<Pod>> watcherCaptor;
|
||||
|
||||
private Map<String, String> attributes;
|
||||
private AsyncStorageProvisioner asyncStorageProvisioner;
|
||||
private SshPairImpl sshPair;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() {
|
||||
asyncStorageProvisioner =
|
||||
new AsyncStorageProvisioner(
|
||||
"Always",
|
||||
"10Gi",
|
||||
"org/image:tag",
|
||||
"ReadWriteOnce",
|
||||
"common",
|
||||
VPC_NAME,
|
||||
"storage",
|
||||
sshManager,
|
||||
clientFactory);
|
||||
attributes = new HashMap<>(2);
|
||||
attributes.put(ASYNC_PERSIST_ATTRIBUTE, "true");
|
||||
attributes.put(PERSIST_VOLUMES_ATTRIBUTE, "false");
|
||||
sshPair = new SshPairImpl(USER, "internal", SSH_KEY_NAME, "", "");
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = InfrastructureException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"Workspace configuration not valid: Asynchronous storage available only for 'common' PVC strategy.*")
|
||||
public void shouldThrowExceptionIfNotCommonStrategy() throws Exception {
|
||||
AsyncStorageProvisioner asyncStorageProvisioner =
|
||||
new AsyncStorageProvisioner(
|
||||
"Always",
|
||||
"10Gi",
|
||||
"org/image:tag",
|
||||
"ReadWriteOnce",
|
||||
randomUUID().toString(),
|
||||
VPC_NAME,
|
||||
"storageClass",
|
||||
sshManager,
|
||||
clientFactory);
|
||||
when(kubernetesEnvironment.getAttributes()).thenReturn(attributes);
|
||||
asyncStorageProvisioner.provision(kubernetesEnvironment, identity);
|
||||
verifyNoMoreInteractions(sshManager);
|
||||
verifyNoMoreInteractions(clientFactory);
|
||||
verifyNoMoreInteractions(identity);
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = InfrastructureException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"Workspace configuration not valid: Asynchronous storage available only if 'persistVolumes' attribute set to false")
|
||||
public void shouldThrowExceptionIfAsyncStorageForNotEphemeralWorkspace() throws Exception {
|
||||
Map attributes = new HashMap<>(2);
|
||||
attributes.put(ASYNC_PERSIST_ATTRIBUTE, "true");
|
||||
attributes.put(PERSIST_VOLUMES_ATTRIBUTE, "true");
|
||||
when(kubernetesEnvironment.getAttributes()).thenReturn(attributes);
|
||||
asyncStorageProvisioner.provision(kubernetesEnvironment, identity);
|
||||
verifyNoMoreInteractions(sshManager);
|
||||
verifyNoMoreInteractions(clientFactory);
|
||||
verifyNoMoreInteractions(identity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDoNothingIfNotSetAttribute() throws InfrastructureException {
|
||||
when(kubernetesEnvironment.getAttributes()).thenReturn(emptyMap());
|
||||
asyncStorageProvisioner.provision(kubernetesEnvironment, identity);
|
||||
verifyNoMoreInteractions(sshManager);
|
||||
verifyNoMoreInteractions(clientFactory);
|
||||
verifyNoMoreInteractions(identity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDoNothingIfAttributesAsyncPersistOnly() throws InfrastructureException {
|
||||
when(kubernetesEnvironment.getAttributes())
|
||||
.thenReturn(singletonMap(PERSIST_VOLUMES_ATTRIBUTE, "false"));
|
||||
asyncStorageProvisioner.provision(kubernetesEnvironment, identity);
|
||||
verifyNoMoreInteractions(sshManager);
|
||||
verifyNoMoreInteractions(clientFactory);
|
||||
verifyNoMoreInteractions(identity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateAll() throws InfrastructureException, ServerException, ConflictException {
|
||||
when(kubernetesEnvironment.getAttributes()).thenReturn(attributes);
|
||||
when(clientFactory.create(anyString())).thenReturn(kubernetesClient);
|
||||
when(identity.getWorkspaceId()).thenReturn(WORKSPACE_ID);
|
||||
when(identity.getInfrastructureNamespace()).thenReturn(NAMESPACE);
|
||||
when(identity.getOwnerId()).thenReturn(USER);
|
||||
when(sshManager.getPairs(USER, "internal")).thenReturn(singletonList(sshPair));
|
||||
|
||||
when(kubernetesClient.persistentVolumeClaims()).thenReturn(mixedOperationPvc);
|
||||
when(mixedOperationPvc.inNamespace(NAMESPACE)).thenReturn(namespacePvcOperation);
|
||||
when(namespacePvcOperation.withName(VPC_NAME)).thenReturn(pvcResource);
|
||||
when(pvcResource.get()).thenReturn(null);
|
||||
|
||||
when(kubernetesClient.configMaps()).thenReturn(mixedOperationConfigMap);
|
||||
when(mixedOperationConfigMap.inNamespace(NAMESPACE)).thenReturn(namespaceConfigMapOperation);
|
||||
when(namespaceConfigMapOperation.withName(anyString())).thenReturn(mapResource);
|
||||
when(mapResource.get()).thenReturn(null);
|
||||
|
||||
when(kubernetesClient.apps()).thenReturn(apps);
|
||||
when(apps.deployments()).thenReturn(mixedOperationDeployment);
|
||||
when(mixedOperationDeployment.inNamespace(NAMESPACE)).thenReturn(namespaceDeploymentOperation);
|
||||
when(namespaceDeploymentOperation.withName(ASYNC_STORAGE)).thenReturn(deploymentResource);
|
||||
when(deploymentResource.get()).thenReturn(null);
|
||||
|
||||
when(kubernetesClient.services()).thenReturn(mixedOperationService);
|
||||
when(mixedOperationService.inNamespace(NAMESPACE)).thenReturn(namespaceServiceOperation);
|
||||
when(namespaceServiceOperation.withName(ASYNC_STORAGE)).thenReturn(serviceResource);
|
||||
when(serviceResource.get()).thenReturn(null);
|
||||
|
||||
asyncStorageProvisioner.provision(kubernetesEnvironment, identity);
|
||||
|
||||
verify(identity, times(1)).getInfrastructureNamespace();
|
||||
verify(identity, times(1)).getOwnerId();
|
||||
verify(sshManager, times(1)).getPairs(USER, "internal");
|
||||
verify(sshManager, never()).generatePair(USER, "internal", SSH_KEY_NAME);
|
||||
verify(kubernetesClient.services().inNamespace(NAMESPACE), times(1)).create(any(Service.class));
|
||||
verify(kubernetesClient.configMaps().inNamespace(NAMESPACE), times(1))
|
||||
.create(any(ConfigMap.class));
|
||||
verify(kubernetesClient.apps().deployments().inNamespace(NAMESPACE), times(1))
|
||||
.create(any(Deployment.class));
|
||||
verify(kubernetesClient.persistentVolumeClaims().inNamespace(NAMESPACE), times(1))
|
||||
.create(any(PersistentVolumeClaim.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotCreateConfigMap()
|
||||
throws InfrastructureException, ServerException, ConflictException {
|
||||
when(kubernetesEnvironment.getAttributes()).thenReturn(attributes);
|
||||
when(clientFactory.create(anyString())).thenReturn(kubernetesClient);
|
||||
when(identity.getWorkspaceId()).thenReturn(WORKSPACE_ID);
|
||||
when(identity.getInfrastructureNamespace()).thenReturn(NAMESPACE);
|
||||
when(identity.getOwnerId()).thenReturn(USER);
|
||||
|
||||
when(kubernetesClient.persistentVolumeClaims()).thenReturn(mixedOperationPvc);
|
||||
when(mixedOperationPvc.inNamespace(NAMESPACE)).thenReturn(namespacePvcOperation);
|
||||
when(namespacePvcOperation.withName(VPC_NAME)).thenReturn(pvcResource);
|
||||
when(pvcResource.get()).thenReturn(null);
|
||||
|
||||
when(kubernetesClient.configMaps()).thenReturn(mixedOperationConfigMap);
|
||||
when(mixedOperationConfigMap.inNamespace(NAMESPACE)).thenReturn(namespaceConfigMapOperation);
|
||||
when(namespaceConfigMapOperation.withName(CONFIGMAP_NAME)).thenReturn(mapResource);
|
||||
ObjectMeta meta = new ObjectMeta();
|
||||
meta.setName(CONFIGMAP_NAME);
|
||||
ConfigMap configMap = new ConfigMap();
|
||||
configMap.setMetadata(meta);
|
||||
when(mapResource.get()).thenReturn(configMap);
|
||||
|
||||
when(kubernetesClient.apps()).thenReturn(apps);
|
||||
when(apps.deployments()).thenReturn(mixedOperationDeployment);
|
||||
when(mixedOperationDeployment.inNamespace(NAMESPACE)).thenReturn(namespaceDeploymentOperation);
|
||||
when(namespaceDeploymentOperation.withName(ASYNC_STORAGE)).thenReturn(deploymentResource);
|
||||
when(deploymentResource.get()).thenReturn(null);
|
||||
|
||||
when(kubernetesClient.services()).thenReturn(mixedOperationService);
|
||||
when(mixedOperationService.inNamespace(NAMESPACE)).thenReturn(namespaceServiceOperation);
|
||||
when(namespaceServiceOperation.withName(ASYNC_STORAGE)).thenReturn(serviceResource);
|
||||
when(serviceResource.get()).thenReturn(null);
|
||||
|
||||
asyncStorageProvisioner.provision(kubernetesEnvironment, identity);
|
||||
verify(identity, times(1)).getInfrastructureNamespace();
|
||||
verify(identity, times(1)).getOwnerId();
|
||||
verify(identity, times(1)).getWorkspaceId();
|
||||
verify(sshManager, never()).getPairs(USER, "internal");
|
||||
verify(sshManager, never()).generatePair(USER, "internal", SSH_KEY_NAME);
|
||||
verify(kubernetesClient.services().inNamespace(NAMESPACE), times(1)).create(any(Service.class));
|
||||
verify(kubernetesClient.configMaps().inNamespace(NAMESPACE), never())
|
||||
.create(any(ConfigMap.class));
|
||||
verify(kubernetesClient.apps().deployments().inNamespace(NAMESPACE), times(1))
|
||||
.create(any(Deployment.class));
|
||||
verify(kubernetesClient.persistentVolumeClaims().inNamespace(NAMESPACE), times(1))
|
||||
.create(any(PersistentVolumeClaim.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotCreatePod()
|
||||
throws InfrastructureException, ServerException, ConflictException {
|
||||
when(kubernetesEnvironment.getAttributes()).thenReturn(attributes);
|
||||
when(clientFactory.create(anyString())).thenReturn(kubernetesClient);
|
||||
when(identity.getWorkspaceId()).thenReturn(WORKSPACE_ID);
|
||||
when(identity.getInfrastructureNamespace()).thenReturn(NAMESPACE);
|
||||
when(identity.getOwnerId()).thenReturn(USER);
|
||||
when(sshManager.getPairs(USER, "internal")).thenReturn(singletonList(sshPair));
|
||||
|
||||
when(kubernetesClient.persistentVolumeClaims()).thenReturn(mixedOperationPvc);
|
||||
when(mixedOperationPvc.inNamespace(NAMESPACE)).thenReturn(namespacePvcOperation);
|
||||
when(namespacePvcOperation.withName(VPC_NAME)).thenReturn(pvcResource);
|
||||
when(pvcResource.get()).thenReturn(null);
|
||||
|
||||
when(kubernetesClient.configMaps()).thenReturn(mixedOperationConfigMap);
|
||||
when(mixedOperationConfigMap.inNamespace(NAMESPACE)).thenReturn(namespaceConfigMapOperation);
|
||||
when(namespaceConfigMapOperation.withName(CONFIGMAP_NAME)).thenReturn(mapResource);
|
||||
when(mapResource.get()).thenReturn(null);
|
||||
|
||||
when(kubernetesClient.pods()).thenReturn(mixedOperationPod);
|
||||
when(mixedOperationPod.inNamespace(NAMESPACE)).thenReturn(namespacePodOperation);
|
||||
|
||||
when(kubernetesClient.apps()).thenReturn(apps);
|
||||
when(apps.deployments()).thenReturn(mixedOperationDeployment);
|
||||
when(mixedOperationDeployment.inNamespace(NAMESPACE)).thenReturn(namespaceDeploymentOperation);
|
||||
when(namespaceDeploymentOperation.withName(ASYNC_STORAGE)).thenReturn(deploymentResource);
|
||||
ObjectMeta meta = new ObjectMeta();
|
||||
meta.setName(ASYNC_STORAGE);
|
||||
Deployment deployment = new Deployment();
|
||||
deployment.setMetadata(meta);
|
||||
when(deploymentResource.get()).thenReturn(deployment);
|
||||
|
||||
when(kubernetesClient.services()).thenReturn(mixedOperationService);
|
||||
when(mixedOperationService.inNamespace(NAMESPACE)).thenReturn(namespaceServiceOperation);
|
||||
when(namespaceServiceOperation.withName(ASYNC_STORAGE)).thenReturn(serviceResource);
|
||||
when(serviceResource.get()).thenReturn(null);
|
||||
|
||||
asyncStorageProvisioner.provision(kubernetesEnvironment, identity);
|
||||
verify(identity, times(1)).getInfrastructureNamespace();
|
||||
verify(identity, times(1)).getOwnerId();
|
||||
verify(sshManager, times(1)).getPairs(USER, "internal");
|
||||
verify(sshManager, never()).generatePair(USER, "internal", SSH_KEY_NAME);
|
||||
verify(kubernetesClient.services().inNamespace(NAMESPACE), times(1)).create(any(Service.class));
|
||||
verify(kubernetesClient.configMaps().inNamespace(NAMESPACE), times(1))
|
||||
.create(any(ConfigMap.class));
|
||||
verify(kubernetesClient.pods().inNamespace(NAMESPACE), never()).create(any(Pod.class));
|
||||
verify(kubernetesClient.persistentVolumeClaims().inNamespace(NAMESPACE), times(1))
|
||||
.create(any(PersistentVolumeClaim.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotCreateService()
|
||||
throws InfrastructureException, ServerException, ConflictException {
|
||||
when(kubernetesEnvironment.getAttributes()).thenReturn(attributes);
|
||||
when(clientFactory.create(anyString())).thenReturn(kubernetesClient);
|
||||
when(identity.getWorkspaceId()).thenReturn(WORKSPACE_ID);
|
||||
when(identity.getInfrastructureNamespace()).thenReturn(NAMESPACE);
|
||||
when(identity.getOwnerId()).thenReturn(USER);
|
||||
when(sshManager.getPairs(USER, "internal")).thenReturn(singletonList(sshPair));
|
||||
|
||||
when(kubernetesClient.persistentVolumeClaims()).thenReturn(mixedOperationPvc);
|
||||
when(mixedOperationPvc.inNamespace(NAMESPACE)).thenReturn(namespacePvcOperation);
|
||||
when(namespacePvcOperation.withName(VPC_NAME)).thenReturn(pvcResource);
|
||||
when(pvcResource.get()).thenReturn(null);
|
||||
|
||||
when(kubernetesClient.configMaps()).thenReturn(mixedOperationConfigMap);
|
||||
when(mixedOperationConfigMap.inNamespace(NAMESPACE)).thenReturn(namespaceConfigMapOperation);
|
||||
when(namespaceConfigMapOperation.withName(CONFIGMAP_NAME)).thenReturn(mapResource);
|
||||
when(mapResource.get()).thenReturn(null);
|
||||
|
||||
when(kubernetesClient.apps()).thenReturn(apps);
|
||||
when(apps.deployments()).thenReturn(mixedOperationDeployment);
|
||||
when(mixedOperationDeployment.inNamespace(NAMESPACE)).thenReturn(namespaceDeploymentOperation);
|
||||
when(namespaceDeploymentOperation.withName(ASYNC_STORAGE)).thenReturn(deploymentResource);
|
||||
when(deploymentResource.get()).thenReturn(null);
|
||||
|
||||
when(kubernetesClient.services()).thenReturn(mixedOperationService);
|
||||
when(mixedOperationService.inNamespace(NAMESPACE)).thenReturn(namespaceServiceOperation);
|
||||
when(namespaceServiceOperation.withName(ASYNC_STORAGE)).thenReturn(serviceResource);
|
||||
ObjectMeta meta = new ObjectMeta();
|
||||
meta.setName(ASYNC_STORAGE);
|
||||
Service service = new Service();
|
||||
service.setMetadata(meta);
|
||||
when(serviceResource.get()).thenReturn(service);
|
||||
|
||||
asyncStorageProvisioner.provision(kubernetesEnvironment, identity);
|
||||
verify(identity, times(1)).getInfrastructureNamespace();
|
||||
verify(identity, times(1)).getOwnerId();
|
||||
verify(sshManager, times(1)).getPairs(USER, "internal");
|
||||
verify(sshManager, never()).generatePair(USER, "internal", SSH_KEY_NAME);
|
||||
verify(kubernetesClient.services().inNamespace(NAMESPACE), never()).create(any(Service.class));
|
||||
verify(kubernetesClient.configMaps().inNamespace(NAMESPACE), times(1))
|
||||
.create(any(ConfigMap.class));
|
||||
verify(kubernetesClient.apps().deployments().inNamespace(NAMESPACE), times(1))
|
||||
.create(any(Deployment.class));
|
||||
verify(kubernetesClient.persistentVolumeClaims().inNamespace(NAMESPACE), times(1))
|
||||
.create(any(PersistentVolumeClaim.class));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2022 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -525,78 +525,6 @@ public class KubernetesPluginsToolingApplierTest {
|
|||
verifyContainers(nonUserContainers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applyPluginContainerWithOneVolume() throws InfrastructureException {
|
||||
lenient().when(podSpec.getContainers()).thenReturn(new ArrayList<>());
|
||||
|
||||
ChePlugin chePlugin = createChePlugin();
|
||||
CheContainer cheContainer = chePlugin.getContainers().get(0);
|
||||
|
||||
applier.apply(runtimeIdentity, internalEnvironment, singletonList(chePlugin));
|
||||
|
||||
verifyPodAndContainersNumber(1);
|
||||
Container container = getOneAndOnlyNonUserContainer(internalEnvironment);
|
||||
verifyContainer(container);
|
||||
|
||||
verify(chePluginsVolumeApplier)
|
||||
.applyVolumes(
|
||||
any(PodData.class),
|
||||
eq(container),
|
||||
eq(cheContainer.getVolumes()),
|
||||
eq(internalEnvironment));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applyPluginInitContainerWithOneVolume() throws InfrastructureException {
|
||||
lenient().when(podSpec.getInitContainers()).thenReturn(new ArrayList<>());
|
||||
|
||||
ChePlugin chePlugin = createChePlugin();
|
||||
CheContainer initContainer = createContainer();
|
||||
chePlugin.setInitContainers(singletonList(initContainer));
|
||||
|
||||
applier.apply(runtimeIdentity, internalEnvironment, singletonList(chePlugin));
|
||||
|
||||
verifyPodAndInitContainersNumber(1);
|
||||
Container toolingInitContainer = getOnlyOneInitContainerFromPod(internalEnvironment);
|
||||
verifyContainer(toolingInitContainer);
|
||||
|
||||
verify(chePluginsVolumeApplier)
|
||||
.applyVolumes(
|
||||
any(PodData.class),
|
||||
eq(toolingInitContainer),
|
||||
eq(initContainer.getVolumes()),
|
||||
eq(internalEnvironment));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsMachinesWithVolumesToAllToolingContainer() throws Exception {
|
||||
// given
|
||||
ChePlugin chePluginWithNonDefaultVolume = createChePlugin();
|
||||
String anotherVolumeName = VOLUME_NAME + "1";
|
||||
String anotherVolumeMountPath = VOLUME_MOUNT_PATH + "/something";
|
||||
List<Volume> volumes =
|
||||
singletonList(new Volume().name(anotherVolumeName).mountPath(anotherVolumeMountPath));
|
||||
CheContainer toolingContainer = chePluginWithNonDefaultVolume.getContainers().get(0);
|
||||
toolingContainer.setVolumes(volumes);
|
||||
|
||||
ChePlugin chePlugin = createChePlugin();
|
||||
|
||||
// when
|
||||
applier.apply(
|
||||
runtimeIdentity, internalEnvironment, asList(chePlugin, chePluginWithNonDefaultVolume));
|
||||
|
||||
// then
|
||||
Collection<InternalMachineConfig> machineConfigs = getNonUserMachines(internalEnvironment);
|
||||
assertEquals(machineConfigs.size(), 2);
|
||||
|
||||
verify(chePluginsVolumeApplier)
|
||||
.applyVolumes(
|
||||
any(PodData.class),
|
||||
any(Container.class),
|
||||
eq(chePlugin.getContainers().get(0).getVolumes()),
|
||||
eq(internalEnvironment));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsMachineWithVolumeFromChePlugin() throws Exception {
|
||||
// given
|
||||
|
|
|
|||
Loading…
Reference in New Issue