diff --git a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserPreferencesConfigurator.java b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserPreferencesConfigurator.java index 040bcf8d20..e11c8b0b0c 100644 --- a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserPreferencesConfigurator.java +++ b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserPreferencesConfigurator.java @@ -73,7 +73,8 @@ public class UserPreferencesConfigurator implements NamespaceConfigurator { .inNamespace(namespace) .createOrReplace(userPreferencesSecret); } catch (KubernetesClientException e) { - throw new InfrastructureException(e); + throw new InfrastructureException( + "Error occurred while trying to create user preferences secret.", e); } } @@ -87,11 +88,18 @@ public class UserPreferencesConfigurator implements NamespaceConfigurator { user = userManager.getById(namespaceResolutionContext.getUserId()); preferences = preferenceManager.find(user.getId()); } catch (NotFoundException | ServerException e) { - throw new InfrastructureException(e); + throw new InfrastructureException( + String.format( + "Preferences of user with id:%s cannot be retrieved.", + namespaceResolutionContext.getUserId()), + e); } + if (preferences == null || preferences.isEmpty()) { throw new InfrastructureException( - "User preferences are empty. Skipping creation of user preferences secrets."); + String.format( + "Preferences of user with id:%s are empty. Cannot create user preferences secrets.", + namespaceResolutionContext.getUserId())); } Map preferencesEncoded = new HashMap<>(); diff --git a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserProfileConfigurator.java b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserProfileConfigurator.java index 4810d83514..ecfe5a2845 100644 --- a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserProfileConfigurator.java +++ b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserProfileConfigurator.java @@ -63,7 +63,8 @@ public class UserProfileConfigurator implements NamespaceConfigurator { try { clientFactory.create().secrets().inNamespace(namespace).createOrReplace(userProfileSecret); } catch (KubernetesClientException e) { - throw new InfrastructureException(e); + throw new InfrastructureException( + "Error occurred while trying to create user profile secret.", e); } } @@ -73,7 +74,10 @@ public class UserProfileConfigurator implements NamespaceConfigurator { try { user = userManager.getById(namespaceResolutionContext.getUserId()); } catch (NotFoundException | ServerException e) { - throw new InfrastructureException(e); + throw new InfrastructureException( + String.format( + "Could not find current user with id:%s.", namespaceResolutionContext.getUserId()), + e); } Base64.Encoder enc = Base64.getEncoder(); diff --git a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/provision/NamespaceProvisioner.java b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/provision/NamespaceProvisioner.java index 5ea07cf8fe..032476ab26 100644 --- a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/provision/NamespaceProvisioner.java +++ b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/provision/NamespaceProvisioner.java @@ -44,6 +44,7 @@ public class NamespaceProvisioner { this.userPreferencesConfigurator = userPreferencesConfigurator; } + /** Tests for this method are in KubernetesFactoryTest. */ public KubernetesNamespaceMeta provision(NamespaceResolutionContext namespaceResolutionContext) throws InfrastructureException { KubernetesNamespace namespace = diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesNamespaceFactoryTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesNamespaceFactoryTest.java index e51309fa2a..d8c99c683f 100644 --- a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesNamespaceFactoryTest.java +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesNamespaceFactoryTest.java @@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.lenient; @@ -86,6 +87,9 @@ import org.eclipse.che.workspace.infrastructure.kubernetes.CheServerKubernetesCl import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFactory; import org.eclipse.che.workspace.infrastructure.kubernetes.api.server.impls.KubernetesNamespaceMetaImpl; import org.eclipse.che.workspace.infrastructure.kubernetes.api.shared.KubernetesNamespaceMeta; +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.provision.NamespaceProvisioner; import org.eclipse.che.workspace.infrastructure.kubernetes.util.KubernetesSharedPool; import org.mockito.ArgumentCaptor; import org.mockito.Mock; @@ -136,6 +140,9 @@ public class KubernetesNamespaceFactoryTest { @Mock private NamespaceList namespaceList; + @Mock private UserProfileConfigurator userProfileConfigurator; + @Mock private UserPreferencesConfigurator userPreferencesConfigurator; + @BeforeMethod public void setUp() throws Exception { serverMock = new KubernetesServer(true, true); @@ -1248,7 +1255,7 @@ public class KubernetesNamespaceFactoryTest { // when NamespaceResolutionContext context = new NamespaceResolutionContext("workspace123", "user123", "jondoe"); - KubernetesNamespaceMeta actual = namespaceFactory.provision(context); + KubernetesNamespaceMeta actual = testProvisioning(context); // then assertEquals(actual.getName(), "jondoe-che"); @@ -1288,7 +1295,7 @@ public class KubernetesNamespaceFactoryTest { // when NamespaceResolutionContext context = new NamespaceResolutionContext("workspace123", "user123", "jondoe"); - namespaceFactory.provision(context); + testProvisioning(context); // then fail("should not reach this point since exception has to be thrown"); @@ -1329,7 +1336,8 @@ public class KubernetesNamespaceFactoryTest { // when NamespaceResolutionContext context = new NamespaceResolutionContext("workspace123", "user123", "jondoe"); - namespaceFactory.provision(context); + + testProvisioning(context); // then fail("should not reach this point since exception has to be thrown"); @@ -1535,4 +1543,13 @@ public class KubernetesNamespaceFactoryTest { .endStatus() .build(); } + + private KubernetesNamespaceMeta testProvisioning(NamespaceResolutionContext context) + throws InfrastructureException { + doNothing().when(userProfileConfigurator).configure(any()); + doNothing().when(userPreferencesConfigurator).configure(any()); + return new NamespaceProvisioner( + namespaceFactory, userProfileConfigurator, userPreferencesConfigurator) + .provision(context); + } } diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserPreferencesConfiguratorTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserPreferencesConfiguratorTest.java new file mode 100644 index 0000000000..a6bfaca9e6 --- /dev/null +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserPreferencesConfiguratorTest.java @@ -0,0 +1,113 @@ +package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; + +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.eclipse.che.api.core.NotFoundException; +import org.eclipse.che.api.core.ServerException; +import org.eclipse.che.api.user.server.PreferenceManager; +import org.eclipse.che.api.user.server.UserManager; +import org.eclipse.che.api.user.server.model.impl.UserImpl; +import org.eclipse.che.api.workspace.server.spi.InfrastructureException; +import org.eclipse.che.api.workspace.server.spi.NamespaceResolutionContext; +import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFactory; +import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespaceFactory; +import org.mockito.InjectMocks; +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; + +/** + * Tests for {@link UserPreferencesConfigurator}. + * + * @author Pavol Baran + */ +@Listeners(MockitoTestNGListener.class) +public class UserPreferencesConfiguratorTest { + + private static final String USER_ID = "user-id"; + private static final String USER_NAME = "user-name"; + private static final String USER_EMAIL = "user-email"; + private static final String USER_NAMESPACE = "user-namespace"; + + @Mock private KubernetesNamespaceFactory namespaceFactory; + @Mock private KubernetesClientFactory clientFactory; + @Mock private UserManager userManager; + @Mock private PreferenceManager preferenceManager; + + @InjectMocks private UserPreferencesConfigurator userPreferencesConfigurator; + + private KubernetesServer kubernetesServer; + private NamespaceResolutionContext context; + + @BeforeMethod + public void setUp() throws InfrastructureException, NotFoundException, ServerException { + context = new NamespaceResolutionContext(null, USER_ID, USER_NAME); + kubernetesServer = new KubernetesServer(true, true); + kubernetesServer.before(); + + Map preferences = new HashMap<>(); + preferences.put("preference-name", "preference"); + + lenient() + .when(userManager.getById(USER_ID)) + .thenReturn(new UserImpl(USER_ID, USER_EMAIL, USER_NAME)); + lenient().when(namespaceFactory.evaluateNamespaceName(any())).thenReturn(USER_NAMESPACE); + lenient().when(clientFactory.create()).thenReturn(kubernetesServer.getClient()); + lenient().when(preferenceManager.find(USER_ID)).thenReturn(preferences); + } + + @AfterMethod + public void cleanUp() { + kubernetesServer.after(); + } + + @Test + public void shouldCreatePreferencesSecret() throws InfrastructureException { + userPreferencesConfigurator.configure(context); + List secrets = + kubernetesServer.getClient().secrets().inNamespace(USER_NAMESPACE).list().getItems(); + assertEquals(secrets.size(), 1); + assertEquals(secrets.get(0).getMetadata().getName(), "user-preferences"); + } + + @Test( + expectedExceptions = InfrastructureException.class, + expectedExceptionsMessageRegExp = + "Preferences of user with id:" + USER_ID + " cannot be retrieved.") + public void shouldNotCreateSecretOnException() throws ServerException, InfrastructureException { + when(preferenceManager.find(USER_ID)).thenThrow(new ServerException("test exception")); + userPreferencesConfigurator.configure(context); + fail("InfrastructureException should have been thrown."); + } + + @Test + public void shouldNormalizePreferenceName() { + assertEquals( + userPreferencesConfigurator.normalizePreferenceName("codename:bond"), "codename-bond"); + assertEquals(userPreferencesConfigurator.normalizePreferenceName("some--:pref"), "some-pref"); + assertEquals( + userPreferencesConfigurator.normalizePreferenceName("pref[name].sub"), "pref-name-.sub"); + } + + @Test + public void shouldKeepPreferenceName() { + assertEquals( + userPreferencesConfigurator.normalizePreferenceName("codename.bond"), "codename.bond"); + assertEquals(userPreferencesConfigurator.normalizePreferenceName("pref_name"), "pref_name"); + assertEquals( + userPreferencesConfigurator.normalizePreferenceName("some-name.over_rainbow"), + "some-name.over_rainbow"); + } +} diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserProfileConfiguratorTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserProfileConfiguratorTest.java new file mode 100644 index 0000000000..288587e490 --- /dev/null +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/UserProfileConfiguratorTest.java @@ -0,0 +1,82 @@ +package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; + +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import java.util.List; +import org.eclipse.che.api.core.NotFoundException; +import org.eclipse.che.api.core.ServerException; +import org.eclipse.che.api.user.server.UserManager; +import org.eclipse.che.api.user.server.model.impl.UserImpl; +import org.eclipse.che.api.workspace.server.spi.InfrastructureException; +import org.eclipse.che.api.workspace.server.spi.NamespaceResolutionContext; +import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFactory; +import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespaceFactory; +import org.mockito.InjectMocks; +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; + +/** + * Tests for {@link UserProfileConfigurator}. + * + * @author Pavol Baran + */ +@Listeners(MockitoTestNGListener.class) +public class UserProfileConfiguratorTest { + private static final String USER_ID = "user-id"; + private static final String USER_NAME = "user-name"; + private static final String USER_EMAIL = "user-email"; + private static final String USER_NAMESPACE = "user-namespace"; + + @Mock private KubernetesNamespaceFactory namespaceFactory; + @Mock private KubernetesClientFactory clientFactory; + @Mock private UserManager userManager; + + @InjectMocks private UserProfileConfigurator userProfileConfigurator; + + private KubernetesServer kubernetesServer; + private NamespaceResolutionContext context; + + @BeforeMethod + public void setUp() throws InfrastructureException, NotFoundException, ServerException { + context = new NamespaceResolutionContext(null, USER_ID, USER_NAME); + kubernetesServer = new KubernetesServer(true, true); + kubernetesServer.before(); + + when(userManager.getById(USER_ID)).thenReturn(new UserImpl(USER_ID, USER_EMAIL, USER_NAME)); + when(namespaceFactory.evaluateNamespaceName(any())).thenReturn(USER_NAMESPACE); + when(clientFactory.create()).thenReturn(kubernetesServer.getClient()); + } + + @AfterMethod + public void cleanUp() { + kubernetesServer.after(); + } + + @Test + public void shouldCreateProfileSecret() throws InfrastructureException { + userProfileConfigurator.configure(context); + List secrets = + kubernetesServer.getClient().secrets().inNamespace(USER_NAMESPACE).list().getItems(); + assertEquals(secrets.size(), 1); + assertEquals(secrets.get(0).getMetadata().getName(), "user-profile"); + } + + @Test( + expectedExceptions = InfrastructureException.class, + expectedExceptionsMessageRegExp = "Could not find current user with id:" + USER_ID + ".") + public void shouldNotCreateSecretOnException() + throws NotFoundException, ServerException, InfrastructureException { + when(userManager.getById(USER_ID)).thenThrow(new ServerException("test exception")); + userProfileConfigurator.configure(context); + fail("InfrastructureException should have been thrown."); + } +} diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/provision/NamespaceProvisionerTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/provision/NamespaceProvisionerTest.java deleted file mode 100644 index 420df065b0..0000000000 --- a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/provision/NamespaceProvisionerTest.java +++ /dev/null @@ -1,132 +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 org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.when; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; - -import io.fabric8.kubernetes.api.model.Secret; -import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.eclipse.che.api.core.NotFoundException; -import org.eclipse.che.api.core.ServerException; -import org.eclipse.che.api.user.server.PreferenceManager; -import org.eclipse.che.api.user.server.UserManager; -import org.eclipse.che.api.user.server.model.impl.UserImpl; -import org.eclipse.che.api.workspace.server.spi.InfrastructureException; -import org.eclipse.che.api.workspace.server.spi.NamespaceResolutionContext; -import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFactory; -import org.eclipse.che.workspace.infrastructure.kubernetes.api.server.impls.KubernetesNamespaceMetaImpl; -import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespaceFactory; -import org.mockito.InjectMocks; -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; - -@Listeners(MockitoTestNGListener.class) -public class NamespaceProvisionerTest { - - @Mock private KubernetesNamespaceFactory namespaceFactory; - @Mock private KubernetesClientFactory clientFactory; - @Mock private UserManager userManager; - @Mock private PreferenceManager preferenceManager; - @InjectMocks private NamespaceProvisioner namespaceProvisioner; - - private static final String USER_ID = "user-id"; - private static final String USER_NAME = "user-name"; - private static final String USER_EMAIL = "user-email"; - private static final String USER_NAMESPACE = "user-namespace"; - - private KubernetesServer kubernetesServer; - - @BeforeMethod - public void setUp() throws InfrastructureException, NotFoundException, ServerException { - kubernetesServer = new KubernetesServer(true, true); - kubernetesServer.before(); - - Map preferences = new HashMap<>(); - preferences.put("preference-name", "preference"); - - lenient().when(clientFactory.create()).thenReturn(kubernetesServer.getClient()); - lenient() - .when(namespaceFactory.provision(any())) - .thenReturn(new KubernetesNamespaceMetaImpl(USER_NAMESPACE, Collections.emptyMap())); - lenient() - .when(userManager.getById(USER_ID)) - .thenReturn(new UserImpl(USER_ID, USER_EMAIL, USER_NAME)); - lenient().when(namespaceFactory.evaluateNamespaceName(any())).thenReturn(USER_NAMESPACE); - lenient().when(preferenceManager.find(USER_ID)).thenReturn(preferences); - } - - @AfterMethod - public void cleanUp() { - kubernetesServer.after(); - } - - @Test - public void shouldCreateSecretsOnNamespaceProvision() throws InfrastructureException { - namespaceProvisioner.provision(new NamespaceResolutionContext(null, USER_ID, USER_NAME)); - List createdSecrets = - kubernetesServer.getClient().secrets().inNamespace(USER_NAMESPACE).list().getItems(); - assertEquals(createdSecrets.size(), 2); - assertTrue( - createdSecrets - .stream() - .anyMatch(secret -> secret.getMetadata().getName().equals("user-profile"))); - assertTrue( - createdSecrets - .stream() - .anyMatch(secret -> secret.getMetadata().getName().equals("user-preferences"))); - } - - @Test - public void shouldCreateOnlyProfileSecret() throws InfrastructureException, ServerException { - when(preferenceManager.find(USER_ID)).thenReturn(Collections.emptyMap()); - namespaceProvisioner.provision(new NamespaceResolutionContext(null, USER_ID, USER_NAME)); - List createdSecrets = - kubernetesServer.getClient().secrets().inNamespace(USER_NAMESPACE).list().getItems(); - assertEquals(createdSecrets.size(), 1); - assertEquals(createdSecrets.get(0).getMetadata().getName(), "user-profile"); - } - - @Test(expectedExceptions = InfrastructureException.class) - public void shouldCreateNoSecretWithInvalidUser() - throws InfrastructureException, NotFoundException, ServerException { - when(userManager.getById(USER_ID)).thenThrow(new NotFoundException("Test exception")); - namespaceProvisioner.provision(new NamespaceResolutionContext(null, USER_ID, USER_NAME)); - } - - @Test - public void shouldNormalizePreferenceName() { - assertEquals(namespaceProvisioner.normalizePreferenceName("codename:bond"), "codename-bond"); - assertEquals(namespaceProvisioner.normalizePreferenceName("some--:pref"), "some-pref"); - assertEquals(namespaceProvisioner.normalizePreferenceName("pref[name].sub"), "pref-name-.sub"); - } - - @Test - public void shouldKeepPreferenceName() { - assertEquals(namespaceProvisioner.normalizePreferenceName("codename.bond"), "codename.bond"); - assertEquals(namespaceProvisioner.normalizePreferenceName("pref_name"), "pref_name"); - assertEquals( - namespaceProvisioner.normalizePreferenceName("some-name.over_rainbow"), - "some-name.over_rainbow"); - } -}