From c2ee93182f40ddc8637166ccd4e85b80296f40ac Mon Sep 17 00:00:00 2001 From: Sergii Kabashniuk Date: Mon, 1 Jul 2019 10:12:03 +0200 Subject: [PATCH] Deploy legacy variable only for che6 workspaces * Deploy legacy variable only for che6 workspaces Signed-off-by: Sergii Kabashniuk * Add tests to the new legacy env var provisioner. Signed-off-by: Lukas Krejci --- .../che/api/deploy/WsMasterModule.java | 28 ++- .../env/AgentAuthEnableEnvVarProvider.java | 2 +- .../env/JavaOptsEnvVariableProvider.java | 2 +- .../LegacyEnvVarEnvironmentProvisioner.java | 78 ++++++++ .../provision/env/LegacyEnvVarProvider.java | 18 ++ .../env/MavenOptsEnvVariableProvider.java | 2 +- ...entCorsAllowCredentialsEnvVarProvider.java | 2 +- ...AgentCorsAllowedOriginsEnvVarProvider.java | 2 +- ...rkspaceAgentCorsEnabledEnvVarProvider.java | 2 +- ...spaceAgentJavaOptsEnvVariableProvider.java | 2 +- ...egacyEnvVarEnvironmentProvisionerTest.java | 173 ++++++++++++++++++ 11 files changed, 296 insertions(+), 15 deletions(-) create mode 100644 wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarEnvironmentProvisioner.java create mode 100644 wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarProvider.java create mode 100644 wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarEnvironmentProvisionerTest.java diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java index b8988d9ccf..acfecbf0a2 100644 --- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java +++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java @@ -62,6 +62,8 @@ import org.eclipse.che.api.workspace.server.spi.provision.env.CheApiInternalEnvV import org.eclipse.che.api.workspace.server.spi.provision.env.EnvVarEnvironmentProvisioner; import org.eclipse.che.api.workspace.server.spi.provision.env.EnvVarProvider; import org.eclipse.che.api.workspace.server.spi.provision.env.JavaOptsEnvVariableProvider; +import org.eclipse.che.api.workspace.server.spi.provision.env.LegacyEnvVarEnvironmentProvisioner; +import org.eclipse.che.api.workspace.server.spi.provision.env.LegacyEnvVarProvider; import org.eclipse.che.api.workspace.server.spi.provision.env.MachineTokenEnvVarProvider; import org.eclipse.che.api.workspace.server.spi.provision.env.MavenOptsEnvVariableProvider; import org.eclipse.che.api.workspace.server.spi.provision.env.ProjectsRootEnvVariableProvider; @@ -176,6 +178,7 @@ public class WsMasterModule extends AbstractModule { Multibinder.newSetBinder(binder(), InternalEnvironmentProvisioner.class); internalEnvironmentProvisioners.addBinding().to(InstallerConfigProvisioner.class); internalEnvironmentProvisioners.addBinding().to(EnvVarEnvironmentProvisioner.class); + internalEnvironmentProvisioners.addBinding().to(LegacyEnvVarEnvironmentProvisioner.class); internalEnvironmentProvisioners.addBinding().to(ProjectsVolumeForWsAgentProvisioner.class); internalEnvironmentProvisioners.addBinding().to(MachineNameProvisioner.class); @@ -188,16 +191,25 @@ public class WsMasterModule extends AbstractModule { envVarProviders.addBinding().to(WorkspaceIdEnvVarProvider.class); envVarProviders.addBinding().to(WorkspaceNamespaceNameEnvVarProvider.class); envVarProviders.addBinding().to(WorkspaceNameEnvVarProvider.class); - - envVarProviders.addBinding().to(JavaOptsEnvVariableProvider.class); - envVarProviders.addBinding().to(MavenOptsEnvVariableProvider.class); envVarProviders.addBinding().to(ProjectsRootEnvVariableProvider.class); - envVarProviders.addBinding().to(AgentAuthEnableEnvVarProvider.class); - envVarProviders.addBinding().to(WorkspaceAgentJavaOptsEnvVariableProvider.class); - envVarProviders.addBinding().to(WorkspaceAgentCorsAllowedOriginsEnvVarProvider.class); - envVarProviders.addBinding().to(WorkspaceAgentCorsAllowCredentialsEnvVarProvider.class); - envVarProviders.addBinding().to(WorkspaceAgentCorsEnabledEnvVarProvider.class); + Multibinder legacyEnvVarProviderMultibinders = + Multibinder.newSetBinder(binder(), LegacyEnvVarProvider.class); + legacyEnvVarProviderMultibinders.addBinding().to(JavaOptsEnvVariableProvider.class); + legacyEnvVarProviderMultibinders.addBinding().to(MavenOptsEnvVariableProvider.class); + + legacyEnvVarProviderMultibinders.addBinding().to(AgentAuthEnableEnvVarProvider.class); + legacyEnvVarProviderMultibinders + .addBinding() + .to(WorkspaceAgentJavaOptsEnvVariableProvider.class); + + legacyEnvVarProviderMultibinders + .addBinding() + .to(WorkspaceAgentCorsAllowedOriginsEnvVarProvider.class); + legacyEnvVarProviderMultibinders + .addBinding() + .to(WorkspaceAgentCorsAllowCredentialsEnvVarProvider.class); + legacyEnvVarProviderMultibinders.addBinding().to(WorkspaceAgentCorsEnabledEnvVarProvider.class); bind(org.eclipse.che.api.workspace.server.bootstrap.InstallerService.class); bind(org.eclipse.che.api.workspace.server.event.WorkspaceJsonRpcMessenger.class) diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/AgentAuthEnableEnvVarProvider.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/AgentAuthEnableEnvVarProvider.java index 3bada06af0..cc3ecc6151 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/AgentAuthEnableEnvVarProvider.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/AgentAuthEnableEnvVarProvider.java @@ -21,7 +21,7 @@ import org.eclipse.che.commons.lang.Pair; * * @author Sergii Leshchenko */ -public class AgentAuthEnableEnvVarProvider implements EnvVarProvider { +public class AgentAuthEnableEnvVarProvider implements LegacyEnvVarProvider { public static final String CHE_AUTH_ENABLED_ENV = "CHE_AUTH_ENABLED"; diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/JavaOptsEnvVariableProvider.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/JavaOptsEnvVariableProvider.java index e91bb722c7..15175c305e 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/JavaOptsEnvVariableProvider.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/JavaOptsEnvVariableProvider.java @@ -23,7 +23,7 @@ import org.eclipse.che.commons.lang.Pair; * @author Roman Iuvshyn * @author Alexander Garagatyi */ -public class JavaOptsEnvVariableProvider implements EnvVarProvider { +public class JavaOptsEnvVariableProvider implements LegacyEnvVarProvider { /** Env variable for jvm settings */ public static final String JAVA_OPTS_VARIABLE = "JAVA_OPTS"; diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarEnvironmentProvisioner.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarEnvironmentProvisioner.java new file mode 100644 index 0000000000..df7b474db6 --- /dev/null +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarEnvironmentProvisioner.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012-2018 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.api.workspace.server.spi.provision.env; + +import java.util.Set; +import javax.inject.Inject; +import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; +import org.eclipse.che.api.workspace.server.spi.InfrastructureException; +import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment; +import org.eclipse.che.api.workspace.server.spi.provision.InternalEnvironmentProvisioner; +import org.eclipse.che.commons.lang.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Adds the legacy environment variables to the workspaces that contain some machines with + * installers. Because the new (Che 7) workspaces don't use installers we can be sure the new + * workspaces are never provisioned with legacy env vars (which would make them unable to override + * JAVA_OPTS for example). + * + * @author Sergii Kabashniuk + */ +public class LegacyEnvVarEnvironmentProvisioner implements InternalEnvironmentProvisioner { + + private static final Logger LOG = + LoggerFactory.getLogger(LegacyEnvVarEnvironmentProvisioner.class); + + private final Set envVarProviders; + + @Inject + public LegacyEnvVarEnvironmentProvisioner(Set envVarProviders) { + this.envVarProviders = envVarProviders; + } + + @Override + public void provision(RuntimeIdentity id, InternalEnvironment internalEnvironment) + throws InfrastructureException { + if (!hasInstallers(internalEnvironment)) { + LOG.debug( + "Legacy environment variables not provisioned to workspace '{}'.", id.getWorkspaceId()); + return; + } + + for (EnvVarProvider envVarProvider : envVarProviders) { + Pair envVar = envVarProvider.get(id); + if (envVar != null) { + LOG.debug( + "Provisioning legacy environment variables for workspace '{}' from {} with {} variable", + id.getWorkspaceId(), + envVarProvider.getClass().getSimpleName(), + envVar.first); + internalEnvironment + .getMachines() + .values() + .forEach(m -> m.getEnv().putIfAbsent(envVar.first, envVar.second)); + } + } + LOG.info( + "Environment legacy variables provisioning done for workspace '{}'", id.getWorkspaceId()); + } + + private boolean hasInstallers(InternalEnvironment internalEnvironment) { + return internalEnvironment + .getMachines() + .values() + .stream() + .anyMatch(m -> !m.getInstallers().isEmpty()); + } +} diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarProvider.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarProvider.java new file mode 100644 index 0000000000..e35557a86b --- /dev/null +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarProvider.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2012-2018 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.api.workspace.server.spi.provision.env; + +/** + * Marker interface for environment variable providers which keeps backward-compatibility with Che 6 + * workspaces. + */ +public interface LegacyEnvVarProvider extends EnvVarProvider {} diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/MavenOptsEnvVariableProvider.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/MavenOptsEnvVariableProvider.java index 8b360b49b9..869c09582d 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/MavenOptsEnvVariableProvider.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/MavenOptsEnvVariableProvider.java @@ -23,7 +23,7 @@ import org.eclipse.che.commons.lang.Pair; * * @author Yevhenii Voevodin */ -public class MavenOptsEnvVariableProvider implements EnvVarProvider { +public class MavenOptsEnvVariableProvider implements LegacyEnvVarProvider { private final String javaOpts; diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsAllowCredentialsEnvVarProvider.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsAllowCredentialsEnvVarProvider.java index 4ad973ab6e..6db5012de2 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsAllowCredentialsEnvVarProvider.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsAllowCredentialsEnvVarProvider.java @@ -24,7 +24,7 @@ import org.eclipse.che.commons.lang.Pair; * * @author Mykhailo Kuznietsov */ -public class WorkspaceAgentCorsAllowCredentialsEnvVarProvider implements EnvVarProvider { +public class WorkspaceAgentCorsAllowCredentialsEnvVarProvider implements LegacyEnvVarProvider { private String wsAgentCorsAllowCredentials; diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsAllowedOriginsEnvVarProvider.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsAllowedOriginsEnvVarProvider.java index 9e892847e7..fc8b1f9e1b 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsAllowedOriginsEnvVarProvider.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsAllowedOriginsEnvVarProvider.java @@ -23,7 +23,7 @@ import org.eclipse.che.commons.lang.Pair; * * @author Mykhailo Kuznietsov */ -public class WorkspaceAgentCorsAllowedOriginsEnvVarProvider implements EnvVarProvider { +public class WorkspaceAgentCorsAllowedOriginsEnvVarProvider implements LegacyEnvVarProvider { private String wsAgentCorsAllowedOrigins; diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsEnabledEnvVarProvider.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsEnabledEnvVarProvider.java index b5fce1b1dc..eda7a1404a 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsEnabledEnvVarProvider.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentCorsEnabledEnvVarProvider.java @@ -23,7 +23,7 @@ import org.eclipse.che.commons.lang.Pair; * * @author Mykhailo Kuznietsov */ -public class WorkspaceAgentCorsEnabledEnvVarProvider implements EnvVarProvider { +public class WorkspaceAgentCorsEnabledEnvVarProvider implements LegacyEnvVarProvider { private String wsAgentCorsEnabled; diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentJavaOptsEnvVariableProvider.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentJavaOptsEnvVariableProvider.java index 872aff4fff..c592cf9b27 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentJavaOptsEnvVariableProvider.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/provision/env/WorkspaceAgentJavaOptsEnvVariableProvider.java @@ -17,7 +17,7 @@ import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.commons.lang.Pair; -public class WorkspaceAgentJavaOptsEnvVariableProvider implements EnvVarProvider { +public class WorkspaceAgentJavaOptsEnvVariableProvider implements LegacyEnvVarProvider { /** Env variable for jvm settings */ public static final String WSAGENT_JAVA_OPTIONS_ENV = "CHE_WORKSPACE_WSAGENT__JAVA__OPTIONS"; diff --git a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarEnvironmentProvisionerTest.java b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarEnvironmentProvisionerTest.java new file mode 100644 index 0000000000..89259e21ed --- /dev/null +++ b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/spi/provision/env/LegacyEnvVarEnvironmentProvisionerTest.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2012-2018 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.api.workspace.server.spi.provision.env; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +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 com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import java.util.HashMap; +import java.util.Map; +import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; +import org.eclipse.che.api.installer.server.model.impl.InstallerImpl; +import org.eclipse.che.api.workspace.server.model.impl.RuntimeIdentityImpl; +import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment; +import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig; +import org.eclipse.che.commons.lang.Pair; +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 LegacyEnvVarEnvironmentProvisionerTest { + + private static final RuntimeIdentity RUNTIME_IDENTITY = + new RuntimeIdentityImpl("testWsId", "testEnv", "testOwnerId"); + + @Mock private LegacyEnvVarProvider provider1; + @Mock private LegacyEnvVarProvider provider2; + @Mock private InternalEnvironment internalEnvironment; + @Mock private InternalMachineConfig machineConfig1; + @Mock private InternalMachineConfig machineConfig2; + private Map machine1Env; + private Map machine2Env; + + @BeforeMethod + public void setup() { + machine1Env = new HashMap<>(); + machine2Env = new HashMap<>(); + + when(internalEnvironment.getMachines()) + .thenReturn(ImmutableMap.of("machine1", machineConfig1, "machine2", machineConfig2)); + + lenient().when(machineConfig2.getInstallers()).thenReturn(emptyList()); + + when(machineConfig1.getEnv()).thenReturn(machine1Env); + when(machineConfig2.getEnv()).thenReturn(machine2Env); + } + + @Test + public void shouldProvisionWorkspacesWithInstallers() throws Exception { + // given + + // make 1 of the machine configs have an installer - this should make the whole environment + // be considered legacy and therefore the legacy env vars should be applied. + when(machineConfig1.getInstallers()).thenReturn(singletonList(mock(InstallerImpl.class))); + + LegacyEnvVarEnvironmentProvisioner provisioner = + new LegacyEnvVarEnvironmentProvisioner(ImmutableSet.of(provider1, provider2)); + + when(provider1.get(any())).thenReturn(Pair.of("test", "test")); + when(provider2.get(any())).thenReturn(Pair.of("test", "test")); + + // when + provisioner.provision(RUNTIME_IDENTITY, internalEnvironment); + + // then + verify(provider1).get(eq(RUNTIME_IDENTITY)); + verify(provider2).get(eq(RUNTIME_IDENTITY)); + } + + @Test + public void shouldNotProvisionWorkspacesWithoutInstallers() throws Exception { + // given + + // none of the machines has installers. Therefore we should see no legacy env var provisioning + when(machineConfig1.getInstallers()).thenReturn(emptyList()); + + LegacyEnvVarEnvironmentProvisioner provisioner = + new LegacyEnvVarEnvironmentProvisioner(ImmutableSet.of(provider1, provider2)); + + // when + provisioner.provision(RUNTIME_IDENTITY, internalEnvironment); + + // then + verify(provider1, never()).get(eq(RUNTIME_IDENTITY)); + verify(provider2, never()).get(eq(RUNTIME_IDENTITY)); + } + + @Test + public void shouldAddAllEnvVarsToAllContainers() throws Exception { + // given + when(machineConfig1.getInstallers()).thenReturn(singletonList(mock(InstallerImpl.class))); + LegacyEnvVarEnvironmentProvisioner provisioner = + new LegacyEnvVarEnvironmentProvisioner(ImmutableSet.of(provider1, provider2)); + Pair envVar1 = Pair.of("env1", "value1"); + Pair envVar2 = Pair.of("env2", "value2"); + ImmutableMap envVarsFromProviders = + ImmutableMap.of( + envVar1.first, envVar1.second, + envVar2.first, envVar2.second); + when(provider1.get(any(RuntimeIdentity.class))).thenReturn(envVar1); + when(provider2.get(any(RuntimeIdentity.class))).thenReturn(envVar2); + + // when + provisioner.provision(RUNTIME_IDENTITY, internalEnvironment); + + // then + assertEquals(machine1Env, envVarsFromProviders); + assertEquals(machine2Env, envVarsFromProviders); + } + + @Test + public void shouldNotRemoveExistingEnvVarsWithDifferentNames() throws Exception { + // given + when(machineConfig1.getInstallers()).thenReturn(singletonList(mock(InstallerImpl.class))); + LegacyEnvVarEnvironmentProvisioner provisioner = + new LegacyEnvVarEnvironmentProvisioner(ImmutableSet.of(provider1)); + Pair existingEnvVar = Pair.of("existingEnvVar", "some-value"); + machine1Env.put(existingEnvVar.first, existingEnvVar.second); + + Pair envVar1 = Pair.of("env1", "value1"); + when(provider1.get(any(RuntimeIdentity.class))).thenReturn(envVar1); + + // when + provisioner.provision(RUNTIME_IDENTITY, internalEnvironment); + + // then + assertEquals( + ImmutableMap.of(existingEnvVar.first, existingEnvVar.second, envVar1.first, envVar1.second), + machine1Env); + } + + @Test + public void shouldNotReplaceExistingEnvVarsWithMatchingNames() throws Exception { + // given + when(machineConfig1.getInstallers()).thenReturn(singletonList(mock(InstallerImpl.class))); + LegacyEnvVarEnvironmentProvisioner provisioner = + new LegacyEnvVarEnvironmentProvisioner(ImmutableSet.of(provider1)); + String existingEnvVarName = "existingEnvVar"; + String oldEnvVarValue = "some-value"; + machine1Env.put(existingEnvVarName, oldEnvVarValue); + + String envVarValueFromProvider = "value1"; + when(provider1.get(any(RuntimeIdentity.class))) + .thenReturn(Pair.of(existingEnvVarName, envVarValueFromProvider)); + + // when + provisioner.provision(RUNTIME_IDENTITY, internalEnvironment); + + // then + assertEquals(ImmutableMap.of(existingEnvVarName, oldEnvVarValue), machine1Env); + } +}