/* * Copyright 2017 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.server.service.materials; import com.thoughtworks.go.config.materials.PluggableSCMMaterial; import com.thoughtworks.go.domain.MaterialInstance; import com.thoughtworks.go.domain.config.Configuration; import com.thoughtworks.go.domain.config.ConfigurationProperty; import com.thoughtworks.go.domain.materials.Modification; import com.thoughtworks.go.domain.materials.scm.PluggableSCMMaterialRevision; import com.thoughtworks.go.domain.packagerepository.ConfigurationPropertyMother; import com.thoughtworks.go.domain.scm.SCM; import com.thoughtworks.go.domain.scm.SCMMother; import com.thoughtworks.go.plugin.access.scm.SCMExtension; import com.thoughtworks.go.plugin.access.scm.SCMPropertyConfiguration; import com.thoughtworks.go.plugin.access.scm.material.MaterialPollResult; import com.thoughtworks.go.plugin.access.scm.revision.ModifiedAction; import com.thoughtworks.go.plugin.access.scm.revision.ModifiedFile; import com.thoughtworks.go.plugin.access.scm.revision.SCMRevision; import com.thoughtworks.go.plugin.api.config.Property; import com.thoughtworks.go.server.persistence.MaterialRepository; import com.thoughtworks.go.server.transaction.TransactionTemplate; import com.thoughtworks.go.util.json.JsonHelper; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import java.io.File; import java.util.*; import static java.util.Arrays.asList; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNull.notNullValue; import static org.hamcrest.core.IsNull.nullValue; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; public class PluggableSCMMaterialPollerTest { @Mock private MaterialRepository materialRepository; @Mock private SCMExtension scmExtension; @Mock private TransactionTemplate transactionTemplate; private PluggableSCMMaterial material; private ArgumentCaptor<SCMPropertyConfiguration> scmConfiguration; private ArgumentCaptor<Map> materialData; private PluggableSCMMaterialPoller poller; private String flyweightFolderPath; @Before public void setup() { initMocks(this); ConfigurationProperty k1 = ConfigurationPropertyMother.create("k1", false, "v1"); ConfigurationProperty k2 = ConfigurationPropertyMother.create("k2", true, "v2"); SCM scmConfig = SCMMother.create("scm-id", "scm-name", "plugin-id", "1.0", new Configuration(k1, k2)); material = new PluggableSCMMaterial(); material.setSCMConfig(scmConfig); MaterialInstance materialInstance = material.createMaterialInstance(); Map<String, String> data = new HashMap<>(); data.put("mk-1", "mv-1"); materialInstance.setAdditionalData(JsonHelper.toJsonString(data)); when(materialRepository.findMaterialInstance(material)).thenReturn(materialInstance); poller = new PluggableSCMMaterialPoller(materialRepository, scmExtension, transactionTemplate); scmConfiguration = ArgumentCaptor.forClass(SCMPropertyConfiguration.class); materialData = ArgumentCaptor.forClass(Map.class); flyweightFolderPath = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath(); } @Test public void shouldTalkToPlugInToGetLatestModifications() { Date timestamp = new Date(); SCMRevision scmRevision = new SCMRevision("revision-123", timestamp, "user", "comment", null, null); MaterialPollResult materialPollResult = new MaterialPollResult(null, scmRevision); when(scmExtension.getLatestRevision(eq(material.getPluginId()), scmConfiguration.capture(), materialData.capture(), eq(flyweightFolderPath))).thenReturn(materialPollResult); List<Modification> modifications = poller.latestModification(material, new File(flyweightFolderPath), null); assertThat(modifications.get(0).getRevision(), is("revision-123")); assertThat(modifications.get(0).getModifiedTime(), is(timestamp)); assertThat(modifications.get(0).getUserName(), is("user")); assertThat(modifications.get(0).getComment(), is("comment")); assertConfiguration(scmConfiguration.getValue(), "k1", "v1"); assertConfiguration(scmConfiguration.getValue(), "k2", "v2"); assertThat(materialData.getValue().size(), is(1)); assertThat(materialData.getValue().get("mk-1"), is("mv-1")); } @Test public void shouldReturnEmptyModificationWhenSCMRevisionIsNull_latestModification() { when(scmExtension.getLatestRevision(eq(material.getPluginId()), scmConfiguration.capture(), materialData.capture(), eq(flyweightFolderPath))).thenReturn(new MaterialPollResult()); List<Modification> modifications = poller.latestModification(material, new File(flyweightFolderPath), null); assertThat(modifications, is(notNullValue())); assertThat(modifications.isEmpty(), is(true)); } @Test public void shouldGetLatestModificationAlongWithAdditionalDataFromTheSCMRevision() { Date timestamp = new Date(); Map<String, String> data = new HashMap<>(); String dataKey = "revision_data"; String dataValue = "revision_value"; data.put(dataKey, dataValue); List<ModifiedFile> modifiedFiles = new ArrayList<>(asList(new ModifiedFile("f1", ModifiedAction.added), new ModifiedFile("f2", ModifiedAction.modified), new ModifiedFile("f3", ModifiedAction.deleted))); SCMRevision scmRevision = new SCMRevision("revision-123", timestamp, "user", "comment", data, modifiedFiles); MaterialPollResult materialPollResult = new MaterialPollResult(null, scmRevision); when(scmExtension.getLatestRevision(eq(material.getPluginId()), scmConfiguration.capture(), materialData.capture(), eq(flyweightFolderPath))).thenReturn(materialPollResult); List<Modification> modifications = poller.latestModification(material, new File(flyweightFolderPath), null); assertThat(modifications.get(0).getRevision(), is("revision-123")); assertThat(modifications.get(0).getModifiedTime(), is(timestamp)); assertThat(modifications.get(0).getUserName(), is("user")); assertThat(modifications.get(0).getComment(), is("comment")); assertThat(modifications.get(0).getAdditionalData(), is(JsonHelper.toJsonString(data))); assertThat(modifications.get(0).getModifiedFiles().size(), is(3)); com.thoughtworks.go.domain.materials.ModifiedFile f1 = new com.thoughtworks.go.domain.materials.ModifiedFile("f1", null, com.thoughtworks.go.domain.materials.ModifiedAction.added); com.thoughtworks.go.domain.materials.ModifiedFile f2 = new com.thoughtworks.go.domain.materials.ModifiedFile("f2", null, com.thoughtworks.go.domain.materials.ModifiedAction.modified); com.thoughtworks.go.domain.materials.ModifiedFile f3 = new com.thoughtworks.go.domain.materials.ModifiedFile("f3", null, com.thoughtworks.go.domain.materials.ModifiedAction.deleted); assertThat(new HashSet(modifications.get(0).getModifiedFiles()), is(new HashSet(asList(f1, f2, f3)))); assertConfiguration(scmConfiguration.getValue(), material.getScmConfig().getConfiguration()); assertThat(materialData.getValue().size(), is(1)); assertThat(materialData.getValue().get("mk-1"), is("mv-1")); } @Test public void shouldTalkToPlugInToGetModificationsSinceAGivenRevision() { Date timestamp = new Date(); PluggableSCMMaterialRevision knownRevision = new PluggableSCMMaterialRevision("rev-122", timestamp); ArgumentCaptor<SCMRevision> knownSCMRevision = ArgumentCaptor.forClass(SCMRevision.class); SCMRevision latestRevision = new SCMRevision("rev-123", timestamp, "user", null, null, null); MaterialPollResult materialPollResult = new MaterialPollResult(null, asList(latestRevision)); when(scmExtension.latestModificationSince(eq(material.getPluginId()), scmConfiguration.capture(), materialData.capture(), eq(flyweightFolderPath), knownSCMRevision.capture())).thenReturn(materialPollResult); List<Modification> modifications = poller.modificationsSince(material, new File(flyweightFolderPath), knownRevision, null); assertThat(modifications.get(0).getRevision(), is("rev-123")); assertThat(modifications.get(0).getModifiedTime(), is(timestamp)); assertThat(modifications.get(0).getUserName(), is("user")); assertThat(modifications.get(0).getComment(), is(nullValue())); assertConfiguration(scmConfiguration.getValue(), "k1", "v1"); assertConfiguration(scmConfiguration.getValue(), "k2", "v2"); assertThat(knownSCMRevision.getValue().getRevision(), is("rev-122")); assertThat(knownSCMRevision.getValue().getTimestamp(), is(timestamp)); assertThat(materialData.getValue().size(), is(1)); assertThat(materialData.getValue().get("mk-1"), is("mv-1")); } @Test public void shouldReturnEmptyModificationWhenSCMRevisionIsNullFor_latestModificationSince() { PluggableSCMMaterialRevision knownRevision = new PluggableSCMMaterialRevision("rev-122", new Date()); ArgumentCaptor<SCMRevision> knownSCMRevision = ArgumentCaptor.forClass(SCMRevision.class); when(scmExtension.latestModificationSince(eq(material.getPluginId()), scmConfiguration.capture(), materialData.capture(), eq(flyweightFolderPath), knownSCMRevision.capture())).thenReturn(new MaterialPollResult()); List<Modification> modifications = poller.modificationsSince(material, new File(flyweightFolderPath), knownRevision, null); assertThat(modifications, is(notNullValue())); assertThat(modifications.isEmpty(), is(true)); } @Test public void shouldGetModificationsSinceAGivenRevisionAlongWithAdditionalDataFromTheSCMRevision() { String previousRevision = "rev-122"; Date timestamp = new Date(); Map<String, String> dataInPreviousRevision = new HashMap<>(); dataInPreviousRevision.put("1", "one"); PluggableSCMMaterialRevision knownRevision = new PluggableSCMMaterialRevision(previousRevision, timestamp, dataInPreviousRevision); ArgumentCaptor<SCMRevision> knownSCMRevision = ArgumentCaptor.forClass(SCMRevision.class); Map<String, String> data = new HashMap<>(); String dataKey = "2"; String dataValue = "two"; data.put(dataKey, dataValue); SCMRevision latestRevision = new SCMRevision("rev-123", timestamp, "user", "comment-123", data, null); MaterialPollResult materialPollResult = new MaterialPollResult(null, asList(latestRevision)); when(scmExtension.latestModificationSince(eq(material.getPluginId()), scmConfiguration.capture(), materialData.capture(), eq(flyweightFolderPath), knownSCMRevision.capture())).thenReturn(materialPollResult); List<Modification> modifications = poller.modificationsSince(material, new File(flyweightFolderPath), knownRevision, null); assertThat(knownSCMRevision.getValue().getRevision(), is(previousRevision)); assertThat(knownSCMRevision.getValue().getTimestamp(), is(timestamp)); assertThat(knownSCMRevision.getValue().getData(), is(notNullValue())); assertThat(knownSCMRevision.getValue().getData().size(), is(dataInPreviousRevision.size())); assertThat(knownSCMRevision.getValue().getData().get("1"), is(dataInPreviousRevision.get("1"))); HashMap<String, String> expected = new HashMap<>(); expected.put(dataKey, dataValue); Modification firstModification = modifications.get(0); assertThat(firstModification.getRevision(), is("rev-123")); assertThat(firstModification.getModifiedTime(), is(timestamp)); assertThat(firstModification.getUserName(), is("user")); assertThat(firstModification.getComment(), is("comment-123")); assertThat(firstModification.getAdditionalData(), is(JsonHelper.toJsonString(expected))); assertThat(firstModification.getModifiedFiles().isEmpty(), is(true)); assertThat(materialData.getValue().size(), is(1)); assertThat(materialData.getValue().get("mk-1"), is("mv-1")); } private void assertConfiguration(com.thoughtworks.go.plugin.api.config.Configuration configurationsSentToPlugin, Configuration configurationInMaterial) { assertThat(configurationsSentToPlugin.size(), is(configurationInMaterial.size())); for (ConfigurationProperty property : configurationInMaterial) { Property configuration = configurationsSentToPlugin.get(property.getConfigurationKey().getName()); assertThat(configuration.getValue(), is(property.getValue())); } } private void assertConfiguration(com.thoughtworks.go.plugin.api.config.Configuration actualSCMConfiguration, String key, String value) { assertThat(actualSCMConfiguration.get(key), is(notNullValue())); assertThat(actualSCMConfiguration.get(key).getValue(), is(value)); } }