/* * 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.config.materials.dependency; import com.thoughtworks.go.config.*; import com.thoughtworks.go.config.materials.MaterialConfigs; import com.thoughtworks.go.domain.materials.Material; import com.thoughtworks.go.domain.materials.Modification; import com.thoughtworks.go.domain.materials.Modifications; import com.thoughtworks.go.domain.materials.dependency.DependencyMaterialRevision; import com.thoughtworks.go.helper.GoConfigMother; import org.junit.Before; import org.junit.Test; import java.util.*; import static com.thoughtworks.go.domain.materials.dependency.DependencyMaterialRevision.create; import static org.hamcrest.Matchers.not; import static org.hamcrest.collection.IsMapContaining.hasEntry; import static org.hamcrest.core.Is.is; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class DependencyMaterialTest { private DependencyMaterial dependencyMaterial; @Before public void setup() { dependencyMaterial = new DependencyMaterial(new CaseInsensitiveString("pipeline"), new CaseInsensitiveString("stage")); } @Test public void shouldReturnCruiseAsUser() { assertThat(dependencyMaterial.getUserName(), is("cruise")); } @Test public void shouldReturnJson() { Map<String, String> json = new LinkedHashMap<>(); dependencyMaterial.toJson(json, create("pipeline", 10, "1.0.123", "stage", 1)); assertThat(json.get("location"), is("pipeline/stage")); assertThat(json.get("scmType"), is("Dependency")); assertThat(json.get("folder"), is("")); assertThat(json.get("action"), is("Completed")); } @Test public void shouldDifferIfStageCounterHasChanged() { DependencyMaterialRevision rev1 = create("pipeline", 10, "1.0.123", "stage", 1); DependencyMaterialRevision rev2 = create("pipeline", 10, "1.0.123", "stage", 2); DependencyMaterialRevision rev3 = create("pipeline", 11, "1.0.123", "stage", 1); assertThat(rev1, is(not(rev2))); assertThat(rev2, is(not(rev3))); assertThat(rev3, is(not(rev1))); } @Test public void shouldParseMaterialRevisionWithPipelineLabel() { ArrayList<Modification> mods = new ArrayList<>(); Modification mod = new Modification(new Date(), "pipelineName/123/stageName/2", "pipeline-label-123", null); mods.add(mod); DependencyMaterialRevision revision = (DependencyMaterialRevision) new Modifications(mods).latestRevision(dependencyMaterial); assertThat(revision.getRevision(), is("pipelineName/123/stageName/2")); assertThat(revision.getPipelineLabel(), is("pipeline-label-123")); assertThat(revision.getPipelineCounter(), is(123)); assertThat(revision.getPipelineName(), is("pipelineName")); assertThat(revision.getStageName(), is("stageName")); assertThat(revision.getStageCounter(), is(2)); } @Test public void shouldBeUniqueBasedOnpipelineAndStageName() throws Exception { DependencyMaterial material1 = new DependencyMaterial(new CaseInsensitiveString("pipeline1"), new CaseInsensitiveString("stage1")); Map<String, Object> map = new HashMap<>(); material1.appendCriteria(map); assertThat(map, hasEntry("pipelineName", "pipeline1")); assertThat(map, hasEntry("stageName", "stage1")); assertThat(map.size(), is(2)); } @Test public void shouldUsePipelineNameAsMaterialNameIfItIsNotSet() throws Exception { assertThat(new DependencyMaterial(new CaseInsensitiveString("pipeline1"), new CaseInsensitiveString("stage1")).getName(), is(new CaseInsensitiveString("pipeline1"))); } @Test public void shouldUseMaterialNameAsMaterialNameIfItIsSet() throws Exception { DependencyMaterial material = new DependencyMaterial(new CaseInsensitiveString("pipeline1"), new CaseInsensitiveString("stage1")); material.setName(new CaseInsensitiveString("my-material-name")); assertThat(material.getName(), is(new CaseInsensitiveString("my-material-name"))); } @Test public void shouldGenerateSqlCriteriaMapInSpecificOrder() throws Exception { Map<String, Object> map = dependencyMaterial.getSqlCriteria(); assertThat(map.size(), is(3)); Iterator<Map.Entry<String, Object>> iter = map.entrySet().iterator(); assertThat(iter.next().getKey(), is("type")); assertThat(iter.next().getKey(), is("pipelineName")); assertThat(iter.next().getKey(), is("stageName")); } @Test public void equalsImplementation() throws Exception { DependencyMaterial one = new DependencyMaterial(new CaseInsensitiveString("pipelineName"), new CaseInsensitiveString("stage")); DependencyMaterial two = new DependencyMaterial(new CaseInsensitiveString("pipelineName"), new CaseInsensitiveString("stage")); two.setName(new CaseInsensitiveString("other-name-that-should-be-ignored-in-equals-comparison")); assertEquals(two, one); DependencyMaterial three = new DependencyMaterial(new CaseInsensitiveString("otherPipelineName"), new CaseInsensitiveString("stage")); assertNotEquals(one, three); } @Test public void hashCodeImplementation() throws Exception { DependencyMaterial one = new DependencyMaterial(new CaseInsensitiveString("pipelineName"), new CaseInsensitiveString("stage")); DependencyMaterial two = new DependencyMaterial(new CaseInsensitiveString("pipelineName"), new CaseInsensitiveString("stage")); two.setName(new CaseInsensitiveString("other-name-that-should-be-ignored-in-hashcode-generation")); assertEquals(two.hashCode(), one.hashCode()); DependencyMaterial three = new DependencyMaterial(new CaseInsensitiveString("otherPipelineName"), new CaseInsensitiveString("stage")); assertNotEquals(one.hashCode(), three.hashCode()); } @Test public void shouldReturnUpstreamPipelineNameAsDisplayNameIfMaterialNameIsNotDefined() throws Exception { DependencyMaterial material = new DependencyMaterial(new CaseInsensitiveString("upstream"), new CaseInsensitiveString("first")); assertThat(material.getDisplayName(), is("upstream")); } @Test public void shouldReturnMaterialNameIfDefined() throws Exception { DependencyMaterial material = new DependencyMaterial(new CaseInsensitiveString("upstream"), new CaseInsensitiveString("first")); material.setName(new CaseInsensitiveString("my_name")); assertThat(material.getDisplayName(), is("my_name")); } @Test public void shouldNotTruncateshortRevision() throws Exception { Material material = new DependencyMaterial(new CaseInsensitiveString("upstream"), new CaseInsensitiveString("first")); assertThat(material.getShortRevision("pipeline-name/1/stage-name/5"), is("pipeline-name/1/stage-name/5")); } @Test public void shouldUseACombinationOfPipelineAndStageNameAsURI() { Material material = new DependencyMaterial(new CaseInsensitiveString("pipeline-foo"), new CaseInsensitiveString("stage-bar")); assertThat(material.getUriForDisplay(), is("pipeline-foo / stage-bar")); } @Test public void shouldDetectDependencyMaterialUsedInFetchArtifact() { DependencyMaterial material = new DependencyMaterial(new CaseInsensitiveString("pipeline-foo"), new CaseInsensitiveString("stage-bar")); PipelineConfig pipelineConfig = mock(PipelineConfig.class); ArrayList<FetchTask> fetchTasks = new ArrayList<>(); fetchTasks.add(new FetchTask(new CaseInsensitiveString("something"), new CaseInsensitiveString("new"), "src", "dest")); fetchTasks.add(new FetchTask(new CaseInsensitiveString("pipeline-foo"), new CaseInsensitiveString("stage-bar"), new CaseInsensitiveString("job"), "src", "dest")); when(pipelineConfig.getFetchTasks()).thenReturn(fetchTasks); assertThat(material.isUsedInFetchArtifact(pipelineConfig), is(true)); } @Test public void shouldDetectDependencyMaterialUsedInFetchArtifactFromAncestor() { DependencyMaterial material = new DependencyMaterial(new CaseInsensitiveString("parent-pipeline"), new CaseInsensitiveString("stage-bar")); PipelineConfig pipelineConfig = mock(PipelineConfig.class); ArrayList<FetchTask> fetchTasks = new ArrayList<>(); fetchTasks.add(new FetchTask(new CaseInsensitiveString("grandparent-pipeline/parent-pipeline"), new CaseInsensitiveString("grandparent-stage"), new CaseInsensitiveString("grandparent-job"), "src", "dest")); when(pipelineConfig.getFetchTasks()).thenReturn(fetchTasks); assertThat(material.isUsedInFetchArtifact(pipelineConfig), is(true)); } @Test public void shouldDetectDependencyMaterialNotUsedInFetchArtifact() { DependencyMaterial material = new DependencyMaterial(new CaseInsensitiveString("pipeline-foo"), new CaseInsensitiveString("stage-bar")); PipelineConfig pipelineConfig = mock(PipelineConfig.class); ArrayList<FetchTask> fetchTasks = new ArrayList<>(); fetchTasks.add(new FetchTask(new CaseInsensitiveString("something"), new CaseInsensitiveString("new"), "src", "dest")); fetchTasks.add(new FetchTask(new CaseInsensitiveString("another"), new CaseInsensitiveString("boo"),new CaseInsensitiveString("foo"), "src", "dest")); when(pipelineConfig.getFetchTasks()).thenReturn(fetchTasks); assertThat(material.isUsedInFetchArtifact(pipelineConfig), is(false)); } @Test public void shouldGetAttributesAllFields() { DependencyMaterial material = new DependencyMaterial(new CaseInsensitiveString("pipeline-name"), new CaseInsensitiveString("stage-name")); Map<String, Object> attributesWithSecureFields = material.getAttributes(true); assertAttributes(attributesWithSecureFields); Map<String, Object> attributesWithoutSecureFields = material.getAttributes(false); assertAttributes(attributesWithoutSecureFields); } @Test public void shouldHandleNullOriginDuringValidationWhenUpstreamPipelineDoesNotExist() { DependencyMaterialConfig dependencyMaterialConfig = new DependencyMaterialConfig(new CaseInsensitiveString("upstream_stage"), new CaseInsensitiveString("upstream_pipeline"), new CaseInsensitiveString("stage")); PipelineConfig pipeline = new PipelineConfig(new CaseInsensitiveString("p"), new MaterialConfigs()); pipeline.setOrigin(null); dependencyMaterialConfig.validateTree(PipelineConfigSaveValidationContext.forChain(true, "group", new BasicCruiseConfig(), pipeline)); assertThat(dependencyMaterialConfig.errors().on(DependencyMaterialConfig.PIPELINE_STAGE_NAME), is("Pipeline with name 'upstream_pipeline' does not exist, it is defined as a dependency for pipeline 'p' (cruise-config.xml)")); } @Test public void shouldHandleNullOriginDuringValidationWhenUpstreamStageDoesNotExist() { CruiseConfig cruiseConfig = GoConfigMother.pipelineHavingJob("upstream_pipeline", "upstream_stage", "j1", null, null); DependencyMaterialConfig dependencyMaterialConfig = new DependencyMaterialConfig(new CaseInsensitiveString("upstream_pipeline"), new CaseInsensitiveString("does_not_exist")); PipelineConfig pipeline = new PipelineConfig(new CaseInsensitiveString("downstream"), new MaterialConfigs()); pipeline.setOrigin(null); dependencyMaterialConfig.validateTree(PipelineConfigSaveValidationContext.forChain(true, "group", cruiseConfig, pipeline)); assertThat(dependencyMaterialConfig.errors().on(DependencyMaterialConfig.PIPELINE_STAGE_NAME), is("Stage with name 'does_not_exist' does not exist on pipeline 'upstream_pipeline', it is being referred to from pipeline 'downstream' (cruise-config.xml)")); } private void assertAttributes(Map<String, Object> attributes) { assertThat(attributes.get("type"), is("pipeline")); Map<String, Object> configuration = (Map<String, Object>) attributes.get("pipeline-configuration"); assertThat(configuration.get("pipeline-name"), is("pipeline-name")); assertThat(configuration.get("stage-name"), is("stage-name")); } @Test public void shouldReturnFalseForDependencyMaterial_supportsDestinationFolder() throws Exception { DependencyMaterial material = new DependencyMaterial(); assertThat(material.supportsDestinationFolder(), is(false)); } }