/* * Copyright 2015 ThoughtWorks, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.thoughtworks.go.domain.scm; import com.thoughtworks.go.config.BasicCruiseConfig; import com.thoughtworks.go.config.ConfigSaveValidationContext; import com.thoughtworks.go.domain.packagerepository.ConfigurationPropertyMother; import com.thoughtworks.go.plugin.access.scm.SCMConfiguration; import com.thoughtworks.go.plugin.access.scm.SCMConfigurations; import com.thoughtworks.go.plugin.access.scm.SCMMetadataStore; import com.thoughtworks.go.plugin.access.scm.SCMPreference; import com.thoughtworks.go.security.GoCipher; import com.thoughtworks.go.util.DataStructureUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.*; import static com.thoughtworks.go.domain.packagerepository.ConfigurationPropertyMother.create; import static java.util.Arrays.asList; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNot.not; import static org.hamcrest.core.IsNull.notNullValue; import static org.hamcrest.core.IsNull.nullValue; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import com.thoughtworks.go.domain.config.PluginConfiguration; import com.thoughtworks.go.domain.config.Configuration; import com.thoughtworks.go.domain.config.ConfigurationKey; import com.thoughtworks.go.domain.config.ConfigurationProperty; import com.thoughtworks.go.domain.config.ConfigurationValue; import com.thoughtworks.go.domain.config.EncryptedConfigurationValue; import static com.thoughtworks.go.plugin.access.scm.SCMConfiguration.PART_OF_IDENTITY; import static com.thoughtworks.go.plugin.access.scm.SCMConfiguration.SECURE; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class SCMTest { @Before public void setup() throws Exception { SCMMetadataStore.getInstance().clear(); } @After public void tearDown() throws Exception { SCMMetadataStore.getInstance().clear(); } @Test public void shouldCheckEqualityOfSCM() { Configuration configuration = new Configuration(); SCM scm = SCMMother.create("id", "name", "plugin-id", "version", configuration); assertThat(scm, is(SCMMother.create("id", "name", "plugin-id", "version", configuration))); } @Test public void shouldCheckForFieldAssignments() { Configuration configuration = new Configuration(); SCM scm = SCMMother.create("id", "name", "plugin-id", "version", configuration); assertThat(scm.getId(), is("id")); assertThat(scm.getName(), is("name")); assertThat(scm.getPluginConfiguration().getId(), is("plugin-id")); assertThat(scm.getPluginConfiguration().getVersion(), is("version")); assertThat(scm.getConfiguration().listOfConfigKeys().isEmpty(), is(true)); } @Test public void shouldOnlyDisplayFieldsWhichAreNonSecureAndPartOfIdentityInGetConfigForDisplayWhenPluginExists() throws Exception { SCMConfigurations scmConfiguration = new SCMConfigurations(); scmConfiguration.add(new SCMConfiguration("key1").with(PART_OF_IDENTITY, true).with(SECURE, false)); scmConfiguration.add(new SCMConfiguration("key2").with(PART_OF_IDENTITY, false).with(SECURE, false)); scmConfiguration.add(new SCMConfiguration("key3").with(PART_OF_IDENTITY, true).with(SECURE, true)); scmConfiguration.add(new SCMConfiguration("key4").with(PART_OF_IDENTITY, false).with(SECURE, true)); scmConfiguration.add(new SCMConfiguration("key5").with(PART_OF_IDENTITY, true).with(SECURE, false)); SCMMetadataStore.getInstance().addMetadataFor("plugin-id", scmConfiguration, null); Configuration configuration = new Configuration(create("key1", false, "value1"), create("key2", false, "value2"), create("key3", true, "value3"), create("key4", true, "value4"), create("key5", false, "value5")); SCM scm = SCMMother.create("scm", "scm-name", "plugin-id", "1.0", configuration); assertThat(scm.getConfigForDisplay(), is("[key1=value1, key5=value5]")); } @Test public void shouldConvertKeysToLowercaseInGetConfigForDisplay() throws Exception { SCMMetadataStore.getInstance().addMetadataFor("plugin-id", new SCMConfigurations(), null); Configuration configuration = new Configuration(create("kEY1", false, "vALue1"), create("KEY_MORE_2", false, "VALUE_2"), create("key_3", false, "value3")); SCM scm = SCMMother.create("scm", "scm-name", "plugin-id", "1.0", configuration); assertThat(scm.getConfigForDisplay(), is("[key1=vALue1, key_more_2=VALUE_2, key_3=value3]")); } @Test public void shouldNotDisplayEmptyValuesInGetConfigForDisplay() throws Exception { SCMMetadataStore.getInstance().addMetadataFor("plugin-id", new SCMConfigurations(), null); Configuration configuration = new Configuration(create("rk1", false, ""), create("rk2", false, "some-non-empty-value"), create("rk3", false, null)); SCM scm = SCMMother.create("scm", "scm-name", "plugin-id", "1.0", configuration); assertThat(scm.getConfigForDisplay(), is("[rk2=some-non-empty-value]")); } @Test public void shouldDisplayAllNonSecureFieldsInGetConfigForDisplayWhenPluginDoesNotExist() { Configuration configuration = new Configuration(create("key1", false, "value1"), create("key2", true, "value2"), create("key3", false, "value3")); SCM scm = SCMMother.create("scm", "scm-name", "some-plugin-which-does-not-exist", "1.0", configuration); assertThat(scm.getConfigForDisplay(), is("WARNING! Plugin missing. [key1=value1, key3=value3]")); } @Test public void shouldMakeConfigurationSecureBasedOnMetadata() throws Exception { GoCipher goCipher = new GoCipher(); //meta data of SCM SCMConfigurations scmConfiguration = new SCMConfigurations(); scmConfiguration.add(new SCMConfiguration("key1").with(SECURE, true)); scmConfiguration.add(new SCMConfiguration("key2").with(SECURE, false)); SCMMetadataStore.getInstance().addMetadataFor("plugin-id", scmConfiguration, null); /*secure property is set based on metadata*/ ConfigurationProperty secureProperty = new ConfigurationProperty(new ConfigurationKey("key1"), new ConfigurationValue("value1"), null, goCipher); ConfigurationProperty nonSecureProperty = new ConfigurationProperty(new ConfigurationKey("key2"), new ConfigurationValue("value2"), null, goCipher); SCM scm = SCMMother.create("scm-id", "scm-name", "plugin-id", "1.0", new Configuration(secureProperty, nonSecureProperty)); scm.applyPluginMetadata(); //assert SCM properties assertThat(secureProperty.isSecure(), is(true)); assertThat(secureProperty.getEncryptedConfigurationValue(), is(notNullValue())); assertThat(secureProperty.getEncryptedValue(), is(goCipher.encrypt("value1"))); assertThat(nonSecureProperty.isSecure(), is(false)); assertThat(nonSecureProperty.getValue(), is("value2")); } @Test public void shouldNotUpdateSecurePropertyWhenPluginIsMissing() { GoCipher goCipher = new GoCipher(); ConfigurationProperty secureProperty = new ConfigurationProperty(new ConfigurationKey("key1"), null, new EncryptedConfigurationValue("value"), goCipher); ConfigurationProperty nonSecureProperty = new ConfigurationProperty(new ConfigurationKey("key2"), new ConfigurationValue("value1"), null, goCipher); SCM scm = SCMMother.create("scm-id", "scm-name", "plugin-id", "version", new Configuration(secureProperty, nonSecureProperty)); scm.applyPluginMetadata(); assertThat(secureProperty.getEncryptedConfigurationValue(), is(notNullValue())); assertThat(secureProperty.getConfigurationValue(), is(nullValue())); assertThat(nonSecureProperty.getConfigurationValue(), is(notNullValue())); assertThat(nonSecureProperty.getEncryptedConfigurationValue(), is(nullValue())); } @Test public void shouldThrowUpOnSetConfigAttributesIfPluginIsNotAvailable() throws Exception { try { Map<String, String> attributeMap = DataStructureUtils.m(SCM.SCM_ID, "scm-id", SCM.NAME, "scm-name", SCM.AUTO_UPDATE, "false", "url", "http://localhost"); SCM scm = new SCM(null, new PluginConfiguration("plugin-id", "1"), new Configuration()); scm.setConfigAttributes(attributeMap); fail("should have thrown exception"); } catch (Exception e) { assertThat(e, instanceOf(RuntimeException.class)); assertThat(e.getMessage(), is("metadata unavailable for plugin: plugin-id")); } } @Test public void shouldSetConfigAttributesAsAvailable() throws Exception { SCMConfigurations scmConfigurations = new SCMConfigurations(); scmConfigurations.add(new SCMConfiguration("url")); scmConfigurations.add(new SCMConfiguration("username")); scmConfigurations.add(new SCMConfiguration("password").with(SECURE, true)); SCMMetadataStore.getInstance().addMetadataFor("plugin-id", scmConfigurations, null); Map<String, String> attributeMap = DataStructureUtils.m(SCM.SCM_ID, "scm-id", SCM.NAME, "scm-name", SCM.AUTO_UPDATE, "false", "url", "http://localhost", "username", "user", "password", "pass"); SCM scm = new SCM(null, new PluginConfiguration("plugin-id", "1"), new Configuration()); scm.setConfigAttributes(attributeMap); assertThat(scm.getId(), is("scm-id")); assertThat(scm.getName(), is("scm-name")); assertThat(scm.isAutoUpdate(), is(false)); assertThat(scm.getPluginConfiguration().getId(), is("plugin-id")); assertThat(scm.getConfigAsMap().get("url").get(SCM.VALUE_KEY), is("http://localhost")); assertThat(scm.getConfigAsMap().get("username").get(SCM.VALUE_KEY), is("user")); assertThat(scm.getConfigAsMap().get("password").get(SCM.VALUE_KEY), is("pass")); assertThat(scm.getConfiguration().getProperty("password").getConfigurationValue(), is(nullValue())); assertThat(scm.getConfiguration().getProperty("password").getEncryptedConfigurationValue(), is(not(nullValue()))); } @Test public void shouldPopulateItselfFromConfigAttributesMap() throws Exception { SCMConfigurations scmConfigurations = new SCMConfigurations(); scmConfigurations.add(new SCMConfiguration("KEY1")); scmConfigurations.add(new SCMConfiguration("Key2")); SCMPreference scmPreference = mock(SCMPreference.class); when(scmPreference.getScmConfigurations()).thenReturn(scmConfigurations); SCMMetadataStore.getInstance().setPreferenceFor("plugin-id", scmPreference); Configuration configuration = new Configuration(ConfigurationPropertyMother.create("KEY1"), ConfigurationPropertyMother.create("Key2")); SCM scm = new SCM("scm-id", new PluginConfiguration("plugin-id", "1"), configuration); Map<String, String> attributeMap = DataStructureUtils.m("KEY1", "value1", "Key2", "value2"); scm.setConfigAttributes(attributeMap); assertThat(scm.getConfigAsMap().get("KEY1").get(SCM.VALUE_KEY), is("value1")); assertThat(scm.getConfigAsMap().get("Key2").get(SCM.VALUE_KEY), is("value2")); } @Test public void shouldNotOverwriteValuesIfTheyAreNotAvailableInConfigAttributesMap() throws Exception { SCMConfigurations scmConfigurations = new SCMConfigurations(); scmConfigurations.add(new SCMConfiguration("KEY1")); scmConfigurations.add(new SCMConfiguration("Key2")); SCMPreference scmPreference = mock(SCMPreference.class); when(scmPreference.getScmConfigurations()).thenReturn(scmConfigurations); SCMMetadataStore.getInstance().setPreferenceFor("plugin-id", scmPreference); Configuration configuration = new Configuration(ConfigurationPropertyMother.create("KEY1"), ConfigurationPropertyMother.create("Key2")); SCM scm = new SCM("scm-id", new PluginConfiguration("plugin-id", "1"), configuration); Map<String, String> attributeMap = DataStructureUtils.m("KEY1", "value1"); scm.setConfigAttributes(attributeMap); assertThat(scm.getConfigAsMap().get("KEY1").get(SCM.VALUE_KEY), is("value1")); assertThat(scm.getConfigAsMap().get("Key2").get(SCM.VALUE_KEY), is(nullValue())); } @Test public void shouldIgnoreKeysPresentInConfigAttributesMapButNotPresentInConfigStore() throws Exception { SCMConfigurations scmConfigurations = new SCMConfigurations(); scmConfigurations.add(new SCMConfiguration("KEY1")); SCMPreference scmPreference = mock(SCMPreference.class); when(scmPreference.getScmConfigurations()).thenReturn(scmConfigurations); SCMMetadataStore.getInstance().setPreferenceFor("plugin-id", scmPreference); Configuration configuration = new Configuration(ConfigurationPropertyMother.create("KEY1")); SCM scm = new SCM("scm-id", new PluginConfiguration("plugin-id", "1"), configuration); Map<String, String> attributeMap = DataStructureUtils.m("KEY1", "value1", "Key2", "value2"); scm.setConfigAttributes(attributeMap); assertThat(scm.getConfigAsMap().get("KEY1").get(SCM.VALUE_KEY), is("value1")); assertFalse(scm.getConfigAsMap().containsKey("Key2")); } @Test public void shouldAddPropertyComingFromAttributesMapIfPresentInConfigStoreEvenIfItISNotPresentInCurrentConfiguration() throws Exception { SCMConfigurations scmConfigurations = new SCMConfigurations(); scmConfigurations.add(new SCMConfiguration("KEY1")); scmConfigurations.add(new SCMConfiguration("Key2")); SCMPreference scmPreference = mock(SCMPreference.class); when(scmPreference.getScmConfigurations()).thenReturn(scmConfigurations); SCMMetadataStore.getInstance().setPreferenceFor("plugin-id", scmPreference); Configuration configuration = new Configuration(ConfigurationPropertyMother.create("KEY1")); SCM scm = new SCM("scm-id", new PluginConfiguration("plugin-id", "1"), configuration); Map<String, String> attributeMap = DataStructureUtils.m("KEY1", "value1", "Key2", "value2"); scm.setConfigAttributes(attributeMap); assertThat(scm.getConfigAsMap().get("KEY1").get(SCM.VALUE_KEY), is("value1")); assertThat(scm.getConfigAsMap().get("Key2").get(SCM.VALUE_KEY), is("value2")); } @Test public void shouldValidateIfNameIsMissing() { SCM scm = new SCM(); scm.validate(new ConfigSaveValidationContext(new BasicCruiseConfig(), null)); assertThat(scm.errors().getAllOn(SCM.NAME), is(asList("Please provide name"))); } @Test public void shouldClearConfigurationsWhichAreEmptyAndNoErrors() throws Exception { SCM scm = new SCM(); scm.getConfiguration().add(new ConfigurationProperty(new ConfigurationKey("name-one"), new ConfigurationValue())); scm.getConfiguration().add(new ConfigurationProperty(new ConfigurationKey("name-two"), new EncryptedConfigurationValue())); scm.getConfiguration().add(new ConfigurationProperty(new ConfigurationKey("name-three"), null, new EncryptedConfigurationValue(), null)); ConfigurationProperty configurationProperty = new ConfigurationProperty(new ConfigurationKey("name-four"), null, new EncryptedConfigurationValue(), null); configurationProperty.addErrorAgainstConfigurationValue("error"); scm.getConfiguration().add(configurationProperty); scm.clearEmptyConfigurations(); assertThat(scm.getConfiguration().size(), is(1)); assertThat(scm.getConfiguration().get(0).getConfigurationKey().getName(), is("name-four")); } @Test public void shouldValidateName() throws Exception { SCM scm = new SCM(); scm.setName("some name"); scm.validate(new ConfigSaveValidationContext(null)); assertThat(scm.errors().isEmpty(), is(false)); assertThat(scm.errors().getAllOn(SCM.NAME).get(0), is("Invalid SCM name 'some name'. This must be alphanumeric and can contain underscores and periods (however, it cannot start with a period). The maximum allowed length is 255 characters.")); } @Test public void shouldValidateUniqueKeysInConfiguration() { ConfigurationProperty one = create("one", false, "value1"); ConfigurationProperty duplicate1 = create("ONE", false, "value2"); ConfigurationProperty duplicate2 = create("ONE", false, "value3"); ConfigurationProperty two = create("two", false, null); SCM scm = new SCM(); scm.setConfiguration(new Configuration(one, duplicate1, duplicate2, two)); scm.setName("git"); scm.validate(null); assertThat(one.errors().isEmpty(), is(false)); assertThat(one.errors().getAllOn(ConfigurationProperty.CONFIGURATION_KEY).contains("Duplicate key 'ONE' found for SCM 'git'"), is(true)); assertThat(duplicate1.errors().isEmpty(), is(false)); assertThat(one.errors().getAllOn(ConfigurationProperty.CONFIGURATION_KEY).contains("Duplicate key 'ONE' found for SCM 'git'"), is(true)); assertThat(duplicate2.errors().isEmpty(), is(false)); assertThat(one.errors().getAllOn(ConfigurationProperty.CONFIGURATION_KEY).contains("Duplicate key 'ONE' found for SCM 'git'"), is(true)); assertThat(two.errors().isEmpty(), is(true)); } @Test public void shouldGetConfigAsMap() throws Exception { PluginConfiguration pluginConfiguration = new PluginConfiguration("test-plugin-id", "13.4"); GoCipher cipher = new GoCipher(); List<String> keys = Arrays.asList("Avengers 1", "Avengers 2", "Avengers 3", "Avengers 4"); List<String> values = Arrays.asList("Iron man", "Hulk", "Thor", "Captain America"); Configuration configuration = new Configuration( new ConfigurationProperty(new ConfigurationKey(keys.get(0)), new ConfigurationValue(values.get(0))), new ConfigurationProperty(new ConfigurationKey(keys.get(1)), new ConfigurationValue(values.get(1))), new ConfigurationProperty(new ConfigurationKey(keys.get(2)), new ConfigurationValue(values.get(2))), new ConfigurationProperty(new ConfigurationKey(keys.get(3)), new ConfigurationValue(values.get(3)), new EncryptedConfigurationValue(cipher.encrypt(values.get(3))), cipher)); SCM scm = new SCM("scm-id", pluginConfiguration, configuration); Map<String, Map<String, String>> configMap = scm.getConfigAsMap(); assertThat(configMap.keySet().size(), is(keys.size())); assertThat(configMap.values().size(), is(values.size())); assertThat(configMap.keySet().containsAll(keys), is(true)); for (int i = 0; i < keys.size(); i++) { assertThat(configMap.get(keys.get(i)).get(SCM.VALUE_KEY), is(values.get(i))); } } @Test public void shouldGenerateIdIfNotAssigned() { SCM scm = new SCM(); scm.ensureIdExists(); assertThat(scm.getId(), is(notNullValue())); scm = new SCM(); scm.setId("id"); scm.ensureIdExists(); assertThat(scm.getId(), is("id")); } @Test public void shouldAddConfigurationPropertiesForAnyPlugin() { List<ConfigurationProperty> configurationProperties = Arrays.asList(ConfigurationPropertyMother.create("key", "value", "encValue")); Configuration configuration = new Configuration(); SCM scm = SCMMother.create("id", "name", "does_not_exist", "1.1", configuration); assertThat(configuration.size(), is(0)); scm.addConfigurations(configurationProperties); assertThat(configuration.size(), is(1)); } @Test public void shouldGetSCMTypeCorrectly() { SCM scm = SCMMother.create("scm-id"); assertThat(scm.getSCMType(), is("pluggable_material_plugin")); scm.setPluginConfiguration(new PluginConfiguration("plugin-id-2", "1")); assertThat(scm.getSCMType(), is("pluggable_material_plugin_id_2")); } }