/*
* 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;
import com.thoughtworks.go.config.materials.MaterialConfigs;
import com.thoughtworks.go.config.materials.PackageMaterialConfig;
import com.thoughtworks.go.config.materials.PluggableSCMMaterialConfig;
import com.thoughtworks.go.config.materials.ScmMaterialConfig;
import com.thoughtworks.go.config.materials.dependency.DependencyMaterialConfig;
import com.thoughtworks.go.config.materials.git.GitMaterialConfig;
import com.thoughtworks.go.config.materials.mercurial.HgMaterialConfig;
import com.thoughtworks.go.config.materials.perforce.P4MaterialConfig;
import com.thoughtworks.go.config.materials.svn.SvnMaterialConfig;
import com.thoughtworks.go.config.materials.tfs.TfsMaterialConfig;
import com.thoughtworks.go.config.merge.MergeEnvironmentConfig;
import com.thoughtworks.go.config.merge.MergePipelineConfigs;
import com.thoughtworks.go.config.remote.*;
import com.thoughtworks.go.domain.*;
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.materials.MaterialConfig;
import com.thoughtworks.go.domain.packagerepository.*;
import com.thoughtworks.go.domain.scm.SCM;
import com.thoughtworks.go.domain.scm.SCMMother;
import com.thoughtworks.go.helper.*;
import com.thoughtworks.go.security.GoCipher;
import com.thoughtworks.go.util.ReflectionUtil;
import com.thoughtworks.go.util.command.UrlArgument;
import org.hamcrest.Matchers;
import org.hamcrest.core.Is;
import org.junit.Test;
import java.util.*;
import static com.thoughtworks.go.helper.PipelineConfigMother.*;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
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.*;
import static org.mockito.Mockito.*;
public abstract class CruiseConfigTestBase {
public GoConfigMother goConfigMother;
protected BasicPipelineConfigs pipelines;
protected CruiseConfig cruiseConfig;
protected abstract CruiseConfig createCruiseConfig(BasicPipelineConfigs pipelineConfigs);
protected abstract BasicCruiseConfig createCruiseConfig();
protected PartialConfig createPartial() {
return PartialConfigMother.withPipelineInGroup("remote-pipe-1", "remote_group");
}
@Test
public void cloneForValidationShouldKeepProposedPartials(){
cruiseConfig.setPartials(Arrays.asList(createPartial()));
assertThat(cruiseConfig.getPartials().size(),is(1));
cruiseConfig = cruiseConfig.cloneForValidation();
assertThat(cruiseConfig.getPartials().size(),is(1));
}
@Test
public void shouldLoadPasswordForGivenMaterialFingerprint() {
MaterialConfig svnConfig = new SvnMaterialConfig("url", "loser", "boozer", true);
PipelineConfig one = PipelineConfigMother.pipelineConfig("one", svnConfig, new JobConfigs(new JobConfig("job")));
cruiseConfig.addPipeline("group-1", one);
P4MaterialConfig p4One = new P4MaterialConfig("server_and_port", "outside_the_window");
p4One.setPassword("abcdef");
PipelineConfig two = PipelineConfigMother.pipelineConfig("two", p4One, new JobConfigs(new JobConfig("job")));
cruiseConfig.addPipeline("group-2", two);
P4MaterialConfig p4Two = new P4MaterialConfig("port_and_server", "inside_yourself");
p4Two.setPassword("fedcba");
PipelineConfig three = PipelineConfigMother.pipelineConfig("three", p4Two, new JobConfigs(new JobConfig("job")));
cruiseConfig.addPipeline("group-3", three);
assertThat(cruiseConfig.materialConfigFor(svnConfig.getFingerprint()), is(svnConfig));
assertThat(cruiseConfig.materialConfigFor(p4One.getFingerprint()), is(p4One));
assertThat(cruiseConfig.materialConfigFor(p4Two.getFingerprint()), is(p4Two));
assertThat(cruiseConfig.materialConfigFor("some_crazy_fingerprint"), is(nullValue()));
}
@Test
public void canFindMaterialConfigForUnderGivenPipelineWithMaterialFingerprint() {
MaterialConfig fullClone = new GitMaterialConfig("url", "master", false);
PipelineConfig one = PipelineConfigMother.pipelineConfig("one", fullClone, new JobConfigs(new JobConfig("job")));
cruiseConfig.addPipeline("group-1", one);
MaterialConfig shallowClone = new GitMaterialConfig("url", "master", true);
PipelineConfig two = PipelineConfigMother.pipelineConfig("two", shallowClone, new JobConfigs(new JobConfig("job")));
cruiseConfig.addPipeline("group-2", two);
MaterialConfig others = new GitMaterialConfig("bar", "master", true);
PipelineConfig three = PipelineConfigMother.pipelineConfig("three", others, new JobConfigs(new JobConfig("job")));
cruiseConfig.addPipeline("group-3", three);
String fingerprint = new GitMaterialConfig("url", "master").getFingerprint();
assertThat(((GitMaterialConfig) cruiseConfig.materialConfigFor(one.name(), fingerprint)).isShallowClone(), is(false));
assertThat(((GitMaterialConfig) cruiseConfig.materialConfigFor(two.name(), fingerprint)).isShallowClone(), is(true));
assertThat(cruiseConfig.materialConfigFor(three.name(), fingerprint), is(nullValue()));
}
@Test
public void shouldFindAllAgentResources() {
cruiseConfig.agents().add(new AgentConfig("uuid", "host1", "127.0.0.1", new Resources("from-agent")));
assertThat(cruiseConfig.getAllResources(), hasItem(new Resource("from-agent")));
}
@Test
public void shouldFindBuildPlanWithStages() throws Exception {
try {
cruiseConfig.jobConfigByName("cetaceans", "whales", "right whale", true);
fail("Expected not to find right whale in stage whales in pipeline cetaceans");
} catch (RuntimeException ex) {
// ignore
}
addPipeline("cetaceans", "whales", jobConfig("whale"));
try {
cruiseConfig.jobConfigByName("cetaceans", "whales", "dolphin", true);
} catch (Exception e) {
assertThat(e.getMessage(), is("Job [dolphin] is not found in pipeline [cetaceans] stage [whales]."));
}
try {
cruiseConfig.jobConfigByName("primates", "whales", "dolphin", true);
fail("Expected not to find primates in stage whales in pipeline cetaceans");
} catch (RuntimeException ex) {
// ignore
}
JobConfig plan = jobConfig("baboon");
addPipeline("primates", "apes", plan);
assertThat(cruiseConfig.jobConfigByName("primates", "apes", "baboon", true), is(plan));
}
@Test
public void shouldFindNextStage() {
addPipelineWithStages("mingle", "dev", jobConfig("ut"), jobConfig("ft"));
assertThat(cruiseConfig.hasNextStage(new CaseInsensitiveString("mingle"), new CaseInsensitiveString("dev")), is(true));
StageConfig nextStage = cruiseConfig.nextStage(new CaseInsensitiveString("mingle"), new CaseInsensitiveString("dev"));
assertThat(nextStage.name(), is(new CaseInsensitiveString("dev2")));
assertThat(cruiseConfig.hasNextStage(new CaseInsensitiveString("mingle"), nextStage.name()), is(false));
}
@Test
public void shouldFindPreviousStage() {
addPipelineWithStages("mingle", "dev", jobConfig("ut"), jobConfig("ft"));
assertThat(cruiseConfig.hasPreviousStage(new CaseInsensitiveString("mingle"), new CaseInsensitiveString("dev2")), is(true));
StageConfig previousStage = cruiseConfig.previousStage(new CaseInsensitiveString("mingle"), new CaseInsensitiveString("dev2"));
assertThat(previousStage.name(), is(new CaseInsensitiveString("dev")));
assertThat(cruiseConfig.hasPreviousStage(new CaseInsensitiveString("mingle"), previousStage.name()), is(false));
}
@Test
public void shouldKnowWhenBuildPlanNotInConfigFile() {
pipelines.add(createPipelineConfig("pipeline", "stage", "build1", "build2"));
assertThat(cruiseConfig.hasBuildPlan(new CaseInsensitiveString("pipeline"), new CaseInsensitiveString("stage"), "build1", true), is(true));
assertThat(cruiseConfig.hasBuildPlan(new CaseInsensitiveString("pipeline"), new CaseInsensitiveString("stage"), "build2", true), is(true));
assertThat(cruiseConfig.hasBuildPlan(new CaseInsensitiveString("pipeline"), new CaseInsensitiveString("stage"), "build3", true), is(false));
}
@Test
public void shouldTellIfSMTPIsEnabled() {
assertThat(cruiseConfig.isSmtpEnabled(), is(false));
MailHost mailHost = new MailHost("abc", 12, "admin", "p", true, true, "anc@mail.com", "anc@mail.com");
cruiseConfig.setServerConfig(new ServerConfig(null, mailHost, null, null));
cruiseConfig.server().updateMailHost(mailHost);
assertThat(cruiseConfig.isSmtpEnabled(), is(true));
}
@Test
public void shouldReturnAMapOfTemplateNamesToListOfAssociatedPipelinesCaseInsensitively() {
PipelineTemplateConfig template = template("first_template");
PipelineConfig pipelineConfig1 = PipelineConfigMother.pipelineConfig("first");
pipelineConfig1.clear();
pipelineConfig1.setTemplateName(new CaseInsensitiveString("first_template"));
pipelineConfig1.usingTemplate(template);
PipelineConfig pipelineConfig2 = PipelineConfigMother.pipelineConfig("second");
pipelineConfig2.clear();
pipelineConfig2.setTemplateName(new CaseInsensitiveString("FIRST_template"));
pipelineConfig2.usingTemplate(template);
PipelineConfig pipelineConfigWithoutTemplate = PipelineConfigMother.pipelineConfig("third");
BasicPipelineConfigs pipelineConfigs = new BasicPipelineConfigs(pipelineConfig1, pipelineConfig2, pipelineConfigWithoutTemplate);
CruiseConfig cruiseConfig = createCruiseConfig(pipelineConfigs);
cruiseConfig.addTemplate(template);
SecurityConfig securityConfig = new SecurityConfig(new LdapConfig(new GoCipher()), new PasswordFileConfig("foo"), false);
securityConfig.adminsConfig().add(new AdminUser(new CaseInsensitiveString("root")));
cruiseConfig.server().useSecurity(securityConfig);
Map<CaseInsensitiveString, List<CaseInsensitiveString>> templateWithPipelines = cruiseConfig.templatesWithPipelinesForUser("root", null);
assertThat(templateWithPipelines.size(), is(1));
assertThat(templateWithPipelines.get(new CaseInsensitiveString("first_template")), is(Arrays.asList(new CaseInsensitiveString("first"), new CaseInsensitiveString("second"))));
}
@Test
public void shouldReturnAMapOfTemplateNamesToListOfAssociatedPipelinesBasedOnUserPermissions() {
PipelineTemplateConfig firstTemplate = PipelineTemplateConfigMother.createTemplate("first_template", new Authorization(new AdminsConfig(
new AdminUser(new CaseInsensitiveString("firstTemplate-admin")))), StageConfigMother.manualStage("stage-one"));
PipelineConfig pipelineConfig1 = PipelineConfigMother.pipelineConfig("first");
pipelineConfig1.clear();
pipelineConfig1.setTemplateName(new CaseInsensitiveString("first_template"));
pipelineConfig1.usingTemplate(firstTemplate);
PipelineTemplateConfig secondTemplate = PipelineTemplateConfigMother.createTemplate("second_template", new Authorization(new AdminsConfig(
new AdminUser(new CaseInsensitiveString("secondTemplate-admin")))), StageConfigMother.stageConfig("one-more"));
PipelineConfig pipelineConfig2 = PipelineConfigMother.pipelineConfig("second");
pipelineConfig2.clear();
pipelineConfig2.setTemplateName(new CaseInsensitiveString("second_template"));
pipelineConfig2.usingTemplate(secondTemplate);
PipelineConfig pipelineConfigWithoutTemplate = PipelineConfigMother.pipelineConfig("third");
BasicPipelineConfigs pipelineConfigs = new BasicPipelineConfigs(pipelineConfig1, pipelineConfig2, pipelineConfigWithoutTemplate);
pipelineConfigs.setOrigin(new FileConfigOrigin());
CruiseConfig cruiseConfig = createCruiseConfig(pipelineConfigs);
cruiseConfig.addTemplate(firstTemplate);
cruiseConfig.addTemplate(secondTemplate);
SecurityConfig securityConfig = new SecurityConfig(new LdapConfig(new GoCipher()), new PasswordFileConfig("foo"), false);
securityConfig.adminsConfig().add(new AdminUser(new CaseInsensitiveString("root")));
cruiseConfig.server().useSecurity(securityConfig);
Map<CaseInsensitiveString, List<CaseInsensitiveString>> templateWithPipelines = cruiseConfig.templatesWithPipelinesForUser("firstTemplate-admin", null);
assertThat(templateWithPipelines.size(), is(1));
assertThat(templateWithPipelines.get(new CaseInsensitiveString("first_template")), is(Arrays.asList(new CaseInsensitiveString("first"))));
}
@Test
public void shouldReturnAMapOfAllTemplateNamesToListOfAssociatedPipelinesIfUserIsSuperAdmin() {
PipelineTemplateConfig firstTemplate = PipelineTemplateConfigMother.createTemplate("first_template", new Authorization(new AdminsConfig(
new AdminUser(new CaseInsensitiveString("firstTemplate-admin")))), StageConfigMother.manualStage("stage-one"));
PipelineConfig pipelineConfig1 = PipelineConfigMother.pipelineConfig("first");
pipelineConfig1.clear();
pipelineConfig1.setTemplateName(new CaseInsensitiveString("first_template"));
pipelineConfig1.usingTemplate(firstTemplate);
PipelineTemplateConfig secondTemplate = PipelineTemplateConfigMother.createTemplate("second_template", new Authorization(new AdminsConfig(
new AdminUser(new CaseInsensitiveString("secondTemplate-admin")))), StageConfigMother.stageConfig("one-more"));
PipelineConfig pipelineConfig2 = PipelineConfigMother.pipelineConfig("second");
pipelineConfig2.clear();
pipelineConfig2.setTemplateName(new CaseInsensitiveString("second_template"));
pipelineConfig2.usingTemplate(secondTemplate);
PipelineConfig pipelineConfigWithoutTemplate = PipelineConfigMother.pipelineConfig("third");
CruiseConfig cruiseConfig = createCruiseConfig(new BasicPipelineConfigs(pipelineConfig1, pipelineConfig2, pipelineConfigWithoutTemplate));
SecurityConfig securityConfig = new SecurityConfig(new LdapConfig(new GoCipher()), new PasswordFileConfig("foo"), false);
securityConfig.adminsConfig().add(new AdminUser(new CaseInsensitiveString("root")));
cruiseConfig.server().useSecurity(securityConfig);
cruiseConfig.addTemplate(firstTemplate);
cruiseConfig.addTemplate(secondTemplate);
Map<CaseInsensitiveString, List<CaseInsensitiveString>> templateWithPipelines = cruiseConfig.templatesWithPipelinesForUser("root", null);
assertThat(templateWithPipelines.size(), is(2));
assertThat(templateWithPipelines.get(new CaseInsensitiveString("first_template")), is(Arrays.asList(new CaseInsensitiveString("first"))));
assertThat(templateWithPipelines.get(new CaseInsensitiveString("second_template")), is(Arrays.asList(new CaseInsensitiveString("second"))));
}
private PipelineTemplateConfig template(final String name) {
return new PipelineTemplateConfig(new CaseInsensitiveString(name), StageConfigMother.stageConfig("some_stage"));
}
@Test
public void shouldThrowExceptionWhenThereIsNoGroup() {
CruiseConfig config = createCruiseConfig();
try {
config.isInFirstGroup(new CaseInsensitiveString("any-pipeline"));
fail("should throw exception when there is no group");
} catch (Exception e) {
assertThat(e.getMessage(), is("No pipeline group defined yet!"));
}
}
@Test
public void shouldOfferAllTasksToVisitors() throws Exception {
CruiseConfig config = createCruiseConfig();
Task task1 = new ExecTask("ls", "-a", "");
Task task2 = new AntTask();
setupJobWithTasks(config, task1, task2);
final List<Task> tasksVisited = new ArrayList<>();
config.accept(new TaskConfigVisitor() {
public void visit(PipelineConfig pipelineConfig, StageConfig stageConfig, JobConfig jobConfig, Task task) {
tasksVisited.add(task);
}
});
assertThat(tasksVisited.size(), is(2));
assertThat(tasksVisited.get(0), is(task1));
assertThat(tasksVisited.get(1), is(task2));
}
@Test
public void shouldOfferNothingToVisitorsIfThereAreNoTasks() throws Exception {
CruiseConfig config = createCruiseConfig();
setupJobWithTasks(config, new NullTask());
final List<Task> tasksVisited = new ArrayList<>();
config.accept(new TaskConfigVisitor() {
public void visit(PipelineConfig pipelineConfig, StageConfig stageConfig, JobConfig jobConfig, Task task) {
tasksVisited.add(task);
}
});
assertThat(tasksVisited.size(), is(0));
}
@Test
public void shouldReturnTrueIfThereAreTwoPipelineGroups() throws Exception {
CruiseConfig config = goConfigMother.cruiseConfigWithTwoPipelineGroups();
assertThat("shouldReturnTrueIfThereAreTwoPipelineGroups", config.hasMultiplePipelineGroups(), is(true));
}
@Test
public void shouldReturnFalseIfThereIsOnePipelineGroup() throws Exception {
CruiseConfig config = goConfigMother.cruiseConfigWithOnePipelineGroup();
assertThat("shouldReturnFalseIfThereIsOnePipelineGroup", config.hasMultiplePipelineGroups(), is(false));
}
@Test
public void shouldFindDownstreamPipelines() throws Exception {
CruiseConfig config = goConfigMother.defaultCruiseConfig();
goConfigMother.addPipeline(config, "pipeline-1", "stage-1", "job-1");
PipelineConfig pipeline2 = goConfigMother.addPipeline(config, "pipeline-2", "stage-2", "job-2");
PipelineConfig pipeline3 = goConfigMother.addPipeline(config, "pipeline-3", "stage-3", "job-3");
goConfigMother.setDependencyOn(config, pipeline2, "pipeline-1", "stage-1");
goConfigMother.setDependencyOn(config, pipeline3, "pipeline-1", "stage-1");
Iterable<PipelineConfig> downstream = config.getDownstreamPipelines("pipeline-1");
assertThat(downstream, hasItem(pipeline2));
assertThat(downstream, hasItem(pipeline3));
}
@Test
public void shouldReturnFalseForEmptyCruiseConfig() throws Exception {
CruiseConfig config = createCruiseConfig();
assertThat("shouldReturnFalseForEmptyCruiseConfig", config.hasMultiplePipelineGroups(), is(false));
}
@Test
public void shouldReturnFalseIfNoMailHost() throws Exception {
assertThat(createCruiseConfig().isMailHostConfigured(), is(false));
}
@Test
public void shouldReturnTrueIfMailHostIsConfigured() throws Exception {
MailHost mailHost = new MailHost("hostName", 1234, "user", "pass", true, true, "from", "admin@local.com");
assertThat(GoConfigMother.cruiseConfigWithMailHost(mailHost).isMailHostConfigured(), is(true));
}
@Test
public void shouldNotLockAPipelineWhenItIsAddedToAnEnvironment() throws Exception {
CruiseConfig config = GoConfigMother.configWithPipelines("pipeline-1");
EnvironmentConfig env = config.addEnvironment("environment");
env.addPipeline(new CaseInsensitiveString("pipeline-1"));
assertThat(config.isPipelineLocked("pipeline-1"), is(false));
}
@Test
public void shouldBeAbleToExplicitlyLockAPipeline() throws Exception {
CruiseConfig config = GoConfigMother.configWithPipelines("pipeline-1");
PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("pipeline-1"));
pipelineConfig.lockExplicitly();
assertThat(config.isPipelineLocked("pipeline-1"), is(true));
}
@Test
public void shouldCollectAllTheErrorsInTheChildren() {
CruiseConfig config = GoConfigMother.configWithPipelines("pipeline-1");
shouldCollectAllTheErrorsInTheChilderHelper(config);
}
protected void shouldCollectAllTheErrorsInTheChilderHelper(CruiseConfig config) {
config.server().security().ldapConfig().errors().add("uri", "invalid ldap uri");
config.server().security().ldapConfig().errors().add("searchBase", "invalid search base");
PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("pipeline-1"));
pipelineConfig.errors().add("base", "Some base errors");
P4MaterialConfig p4MaterialConfig = new P4MaterialConfig("localhost:1999", "view");
p4MaterialConfig.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "p4_folder"));
pipelineConfig.addMaterialConfig(p4MaterialConfig);
p4MaterialConfig.errors().add("materialName", "material name does not follow pattern");
StageConfig stage = pipelineConfig.first();
stage.errors().add("role", "Roles must be proper");
List<ConfigErrors> allErrors = config.validateAfterPreprocess();
assertThat(allErrors.size(), is(5));
assertThat(allErrors.get(0).on("uri"), is("invalid ldap uri"));
assertThat(allErrors.get(0).on("searchBase"), is("invalid search base"));
assertThat(allErrors.get(1).on("base"), is("Some base errors"));
assertThat(allErrors.get(2).on("role"), is("Roles must be proper"));
assertThat(allErrors.get(3).on(ScmMaterialConfig.FOLDER), is("Destination directory is required when specifying multiple scm materials"));
assertThat(allErrors.get(4).on("materialName"), is("material name does not follow pattern"));
}
@Test
public void getAllErrors_shouldCollectAllErrorsInTheChildren() {
CruiseConfig config = GoConfigMother.configWithPipelines("pipeline-1");
config.server().security().ldapConfig().errors().add("uri", "invalid ldap uri");
config.server().security().ldapConfig().errors().add("searchBase", "invalid search base");
PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("pipeline-1"));
pipelineConfig.errors().add("base", "Some base errors");
P4MaterialConfig p4MaterialConfig = new P4MaterialConfig("localhost:1999", "view");
pipelineConfig.addMaterialConfig(p4MaterialConfig);
p4MaterialConfig.errors().add("materialName", "material name does not follow pattern");
StageConfig stage = pipelineConfig.first();
stage.errors().add("role", "Roles must be proper");
List<ConfigErrors> allErrors = config.getAllErrors();
assertThat(allErrors.size(), is(4));
assertThat(allErrors.get(0).on("uri"), is("invalid ldap uri"));
assertThat(allErrors.get(0).on("searchBase"), is("invalid search base"));
assertThat(allErrors.get(1).on("base"), is("Some base errors"));
assertThat(allErrors.get(2).on("role"), is("Roles must be proper"));
assertThat(allErrors.get(3).on("materialName"), is("material name does not follow pattern"));
}
@Test
public void getAllErrors_shouldIgnoreErrorsOnElementToBeSkipped() {
CruiseConfig config = GoConfigMother.configWithPipelines("pipeline-1");
config.server().security().ldapConfig().errors().add("uri", "invalid ldap uri");
config.server().security().ldapConfig().errors().add("searchBase", "invalid search base");
PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("pipeline-1"));
pipelineConfig.errors().add("base", "Some base errors");
P4MaterialConfig p4MaterialConfig = new P4MaterialConfig("localhost:1999", "view");
pipelineConfig.addMaterialConfig(p4MaterialConfig);
p4MaterialConfig.errors().add("materialName", "material name does not follow pattern");
StageConfig stage = pipelineConfig.first();
stage.errors().add("role", "Roles must be proper");
List<ConfigErrors> allErrors = config.getAllErrorsExceptFor(p4MaterialConfig);
assertThat(allErrors.size(), is(3));
assertThat(allErrors.get(0).on("uri"), is("invalid ldap uri"));
assertThat(allErrors.get(0).on("searchBase"), is("invalid search base"));
assertThat(allErrors.get(1).on("base"), is("Some base errors"));
assertThat(allErrors.get(2).on("role"), is("Roles must be proper"));
}
@Test
public void getAllErrors_shouldRetainAllErrorsWhenNoSubjectGiven() {
CruiseConfig config = GoConfigMother.configWithPipelines("pipeline-1");
config.server().security().ldapConfig().errors().add("uri", "invalid ldap uri");
config.server().security().ldapConfig().errors().add("searchBase", "invalid search base");
PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("pipeline-1"));
pipelineConfig.errors().add("base", "Some base errors");
P4MaterialConfig p4MaterialConfig = new P4MaterialConfig("localhost:1999", "view");
pipelineConfig.addMaterialConfig(p4MaterialConfig);
p4MaterialConfig.errors().add("materialName", "material name does not follow pattern");
StageConfig stage = pipelineConfig.first();
stage.errors().add("role", "Roles must be proper");
List<ConfigErrors> allErrors = config.getAllErrorsExceptFor(null);
assertThat(allErrors.size(), is(4));
}
@Test
public void shouldBuildTheValidationContextForAnOnCancelTask() {
CruiseConfig config = GoConfigMother.configWithPipelines("pipeline-1");
PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("pipeline-1"));
StageConfig stageConfig = pipelineConfig.get(0);
JobConfig jobConfig = stageConfig.getJobs().get(0);
ExecTask execTask = new ExecTask("ls", "-la", "dir");
Task mockTask = mock(Task.class);
when(mockTask.errors()).thenReturn(new ConfigErrors());
execTask.setCancelTask(mockTask);
jobConfig.addTask(execTask);
config.validateAfterPreprocess();
verify(mockTask).validate(ConfigSaveValidationContext.forChain(
config,
config.getGroups(),
config.getGroups().findGroup("defaultGroup"),
pipelineConfig,
stageConfig,
stageConfig.getJobs(),
jobConfig,
jobConfig.getTasks(),
execTask,
execTask.onCancelConfig()));
}
@Test
public void shouldNotConsiderEqualObjectsAsSame() {
MyValidatable foo = new AlwaysEqualMyValidatable();
MyValidatable bar = new AlwaysEqualMyValidatable();
foo.innerValidatable = bar;
GoConfigGraphWalker.Handler handler = mock(GoConfigGraphWalker.Handler.class);
new GoConfigGraphWalker(foo).walk(handler);
verify(handler).handle(same(foo), any(ValidationContext.class));
verify(handler).handle(same(bar), any(ValidationContext.class));
}
@Test
public void shouldIgnoreConstantFieldsWhileCollectingErrorsToAvoidPotentialCycles() {
CruiseConfig config = GoConfigMother.configWithPipelines("pipeline-1");
List<ConfigErrors> allErrors = config.validateAfterPreprocess();
assertThat(allErrors.size(), is(0));
}
@Test
public void shouldErrorOutWhenDependsOnItself() throws Exception {
CruiseConfig cruiseConfig = createCruiseConfig();
PipelineConfig pipelineConfig = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build");
goConfigMother.addStageToPipeline(cruiseConfig, "pipeline1", "ft", "build");
goConfigMother.setDependencyOn(cruiseConfig, pipelineConfig, "pipeline1", "ft");
cruiseConfig.validate(null);
ConfigErrors errors = pipelineConfig.materialConfigs().errors();
assertThat(errors.on("base"), is("Circular dependency: pipeline1 <- pipeline1"));
}
@Test
public void shouldNotDuplicateErrorWhenPipelineDoesnotExist() throws Exception {
CruiseConfig cruiseConfig = createCruiseConfig();
PipelineConfig pipelineConfig = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build");
PipelineConfig pipelineConfig2 = goConfigMother.addPipeline(cruiseConfig, "pipeline2", "stage", "build");
goConfigMother.addStageToPipeline(cruiseConfig, "pipeline1", "ft", "build");
goConfigMother.setDependencyOn(cruiseConfig, pipelineConfig2, "pipeline1", "ft");
goConfigMother.setDependencyOn(cruiseConfig, pipelineConfig, "invalid", "invalid");
cruiseConfig.validate(null);
List<ConfigErrors> allErrors = cruiseConfig.getAllErrors();
List<String> errors = new ArrayList<>();
for (ConfigErrors allError : allErrors) {
errors.addAll(allError.getAllOn("base"));
}
assertThat(errors.size(), is(1));
assertThat(errors.get(0), is("Pipeline \"invalid\" does not exist. It is used from pipeline \"pipeline1\"."));
}
@Test
public void shouldErrorOutWhenTwoPipelinesDependsOnEachOther() throws Exception {
CruiseConfig cruiseConfig = createCruiseConfig();
PipelineConfig pipeline1 = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build");
PipelineConfig pipeline2 = goConfigMother.addPipeline(cruiseConfig, "pipeline2", "stage", "build");
goConfigMother.setDependencyOn(cruiseConfig, pipeline2, "pipeline1", "stage");
goConfigMother.setDependencyOn(cruiseConfig, pipeline1, "pipeline2", "stage");
cruiseConfig.validate(null);
assertThat(pipeline1.materialConfigs().errors().isEmpty(), is(false));
assertThat(pipeline2.materialConfigs().errors().isEmpty(), is(false));
}
@Test
public void shouldAddPipelineWithoutValidationInAnExistingGroup() {
CruiseConfig cruiseConfig = createCruiseConfig();
PipelineConfig pipeline1 = PipelineConfigMother.pipelineConfig("first");
PipelineConfig pipeline2 = PipelineConfigMother.pipelineConfig("first");
cruiseConfig.addPipelineWithoutValidation("first-group", pipeline1);
assertThat(cruiseConfig.getGroups().size(), is(1));
assertThat(cruiseConfig.findGroup("first-group").get(0), is(pipeline1));
cruiseConfig.addPipelineWithoutValidation("first-group", pipeline2);
assertThat(cruiseConfig.findGroup("first-group").get(0), is(pipeline1));
assertThat(cruiseConfig.findGroup("first-group").get(1), is(pipeline2));
}
@Test
public void shouldErrorOutWhenThreePipelinesFormACycle() throws Exception {
CruiseConfig cruiseConfig = createCruiseConfig();
PipelineConfig pipeline1 = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build");
SvnMaterialConfig material = (SvnMaterialConfig) pipeline1.materialConfigs().get(0);
material.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "svn_dir"));
P4MaterialConfig p4MaterialConfig = new P4MaterialConfig("localhost:1999", "view");
p4MaterialConfig.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "p4_folder"));
pipeline1.addMaterialConfig(p4MaterialConfig);
PipelineConfig pipeline2 = goConfigMother.addPipeline(cruiseConfig, "pipeline3", "stage", "build");
PipelineConfig pipeline3 = goConfigMother.addPipeline(cruiseConfig, "pipeline2", "stage", "build");
goConfigMother.setDependencyOn(cruiseConfig, pipeline3, "pipeline3", "stage");
goConfigMother.setDependencyOn(cruiseConfig, pipeline2, "pipeline1", "stage");
goConfigMother.setDependencyOn(cruiseConfig, pipeline1, "pipeline2", "stage");
cruiseConfig.validate(null);
assertThat(pipeline1.materialConfigs().errors().isEmpty(), is(false));
assertThat(pipeline2.materialConfigs().errors().isEmpty(), is(false));
assertThat(pipeline3.materialConfigs().errors().isEmpty(), is(false));
}
@Test
public void shouldAllowCleanupOfNonExistentStages() {
CruiseConfig cruiseConfig = createCruiseConfig();
assertThat(cruiseConfig.isArtifactCleanupProhibited("foo", "bar"), is(false));
PipelineConfig pipelineConfig = PipelineConfigMother.createPipelineConfig("foo-pipeline", "bar-stage", "baz-job");
cruiseConfig.addPipeline("defaultGrp", pipelineConfig);
assertThat(cruiseConfig.isArtifactCleanupProhibited("foo-pipeline", "baz-stage"), is(false));
assertThat(cruiseConfig.isArtifactCleanupProhibited("foo-pipeline", "bar-stage"), is(false));
ReflectionUtil.setField(pipelineConfig.getFirstStageConfig(), "artifactCleanupProhibited", true);
assertThat(cruiseConfig.isArtifactCleanupProhibited("foo-pipeline", "bar-stage"), is(true));
assertThat(cruiseConfig.isArtifactCleanupProhibited("fOO-pipeLINE", "BaR-StagE"), is(true));
}
@Test
public void shouldReturnDefaultGroupNameIfNoGroupNameIsSpecified() {
CruiseConfig cfg = createCruiseConfig();
assertThat(cfg.sanitizedGroupName(null), is(BasicPipelineConfigs.DEFAULT_GROUP));
cfg.addPipeline("grp1", PipelineConfigMother.pipelineConfig("foo"));
assertThat(cfg.sanitizedGroupName(null), is(BasicPipelineConfigs.DEFAULT_GROUP));
}
@Test
public void shouldReturnSelectedGroupNameIfGroupNameIsSpecified() {
CruiseConfig cfg = createCruiseConfig();
cfg.addPipeline("grp1", PipelineConfigMother.pipelineConfig("foo"));
assertThat(cfg.sanitizedGroupName("gr1"), is("gr1"));
}
@Test
public void shouldAddPackageRepository() throws Exception {
PackageRepository packageRepository = new PackageRepository();
cruiseConfig.savePackageRepository(packageRepository);
assertThat(cruiseConfig.getPackageRepositories().size(), is(1));
assertThat(cruiseConfig.getPackageRepositories().get(0), is(packageRepository));
assertThat(cruiseConfig.getPackageRepositories().get(0).getId(), is(notNullValue()));
}
@Test
public void shouldUpdatePackageRepository() throws Exception {
PackageRepository packageRepository = new PackageRepository();
packageRepository.setName("old");
cruiseConfig.savePackageRepository(packageRepository);
packageRepository.setName("new");
cruiseConfig.savePackageRepository(packageRepository);
assertThat(cruiseConfig.getPackageRepositories().size(), is(1));
assertThat(cruiseConfig.getPackageRepositories().get(0), is(packageRepository));
assertThat(cruiseConfig.getPackageRepositories().get(0).getId(), is(notNullValue()));
assertThat(cruiseConfig.getPackageRepositories().get(0).getName(), is("new"));
}
@Test
public void shouldAddPackageDefinitionToGivenRepository() throws Exception {
String repoId = "repo-id";
PackageRepository packageRepository = PackageRepositoryMother.create(repoId, "repo-name", "plugin-id", "1.0", new Configuration());
PackageDefinition existing = PackageDefinitionMother.create("pkg-1", "pkg1-name", new Configuration(), packageRepository);
packageRepository.setPackages(new Packages(existing));
cruiseConfig.setPackageRepositories(new PackageRepositories(packageRepository));
Configuration configuration = new Configuration();
configuration.add(new ConfigurationProperty(new ConfigurationKey("key"), new ConfigurationValue("value")));
configuration.add(new ConfigurationProperty(new ConfigurationKey("key-with-no-value"), new ConfigurationValue("")));
PackageDefinition packageDefinition = PackageDefinitionMother.create(null, "pkg2-name", configuration, packageRepository);
cruiseConfig.savePackageDefinition(packageDefinition);
assertThat(cruiseConfig.getPackageRepositories().size(), is(1));
assertThat(cruiseConfig.getPackageRepositories().get(0).getId(), is(repoId));
assertThat(cruiseConfig.getPackageRepositories().get(0).getPackages().size(), is(2));
assertThat(cruiseConfig.getPackageRepositories().get(0).getPackages().get(0).getId(), is(existing.getId()));
PackageDefinition createdPkgDef = cruiseConfig.getPackageRepositories().get(0).getPackages().get(1);
assertThat(createdPkgDef.getId(), is(notNullValue()));
assertThat(createdPkgDef.getConfiguration().getProperty("key"), is(Matchers.notNullValue()));
assertThat(createdPkgDef.getConfiguration().getProperty("key-with-no-value"), is(nullValue()));
}
@Test
public void shouldClearPackageRepositoryConfigurationsWhichAreEmptyWithNoErrors() throws Exception {
PackageRepository packageRepository = mock(PackageRepository.class);
when(packageRepository.isNew()).thenReturn(true);
cruiseConfig.savePackageRepository(packageRepository);
verify(packageRepository).clearEmptyConfigurations();
}
@Test
public void shouldRemovePackageRepositoryById() throws Exception {
PackageRepository packageRepository = PackageRepositoryMother.create(null, "repo", "pid", "1.3", new Configuration());
cruiseConfig.savePackageRepository(packageRepository);
cruiseConfig.removePackageRepository(packageRepository.getId());
assertThat(cruiseConfig.getPackageRepositories().find(packageRepository.getId()), is(Matchers.nullValue()));
}
@Test
public void shouldDecideIfRepoCanBeDeleted_BasedOnPackageRepositoryBeingUsedByPipelines() throws Exception {
PackageRepository repo1 = PackageRepositoryMother.create(null, "repo1", "plugin", "1.3", new Configuration());
PackageRepository repo2 = PackageRepositoryMother.create(null, "repo2", "plugin", "1.3", new Configuration());
PackageDefinition packageDefinition = PackageDefinitionMother.create("package", repo2);
repo2.addPackage(packageDefinition);
PipelineConfig pipeline = PipelineConfigMother.pipelineConfig("pipeline");
pipeline.addMaterialConfig(new PackageMaterialConfig(new CaseInsensitiveString("p1"), packageDefinition.getId(), packageDefinition));
cruiseConfig.addPipeline("existing_group", pipeline);
cruiseConfig.savePackageRepository(repo1);
cruiseConfig.savePackageRepository(repo2);
assertThat(cruiseConfig.canDeletePackageRepository(repo1), is(true));
assertThat(cruiseConfig.canDeletePackageRepository(repo2), is(false));
}
@Test
public void shouldDecideIfPluggableSCMMaterialCanBeDeleted_BasedOnPluggableSCMMaterialBeingUsedByPipelines() throws Exception {
SCM scmConfigOne = SCMMother.create("scm-id-1");
SCM scmConfigTwo = SCMMother.create("scm-id-2");
cruiseConfig.getSCMs().addAll(Arrays.asList(scmConfigOne, scmConfigTwo));
PipelineConfig pipeline = PipelineConfigMother.pipelineConfig("pipeline");
pipeline.addMaterialConfig(new PluggableSCMMaterialConfig(null, scmConfigOne, null, null));
cruiseConfig.addPipeline("existing_group", pipeline);
assertThat(cruiseConfig.canDeletePluggableSCMMaterial(scmConfigOne), is(false));
assertThat(cruiseConfig.canDeletePluggableSCMMaterial(scmConfigTwo), is(true));
}
@Test
public void shouldReturnConfigRepos(){
assertNotNull(cruiseConfig.getConfigRepos());
}
@Test
public void shouldReturnTrueWhenHasGroup()
{
assertThat(cruiseConfig.hasPipelineGroup("existing_group"), is(true));
}
@Test
public void shouldReturnFalseWhenDoesNotHaveGroup()
{
assertThat(cruiseConfig.hasPipelineGroup("non_existing_group"),is(false));
}
@Test
public void getAllLocalPipelines_shouldReturnPipelinesOnlyFromMainPart() {
PipelineConfig pipe1 = PipelineConfigMother.pipelineConfig("pipe1");
pipelines = new BasicPipelineConfigs("group_main", new Authorization(), pipe1);
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,
PartialConfigMother.withPipeline("pipe2"));
assertThat(cruiseConfig.getAllLocalPipelineConfigs(false).size(), is(1));
assertThat(cruiseConfig.getAllLocalPipelineConfigs(false), hasItem(pipe1));
}
@Test
public void shouldReturnTrueHasPipelinesFrom2Parts()
{
pipelines = new BasicPipelineConfigs("group_main", new Authorization(), PipelineConfigMother.pipelineConfig("pipe1"));
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,
PartialConfigMother.withPipeline("pipe2"));
assertThat(cruiseConfig.hasPipelineNamed(new CaseInsensitiveString("pipe1")),is(true));
assertThat(cruiseConfig.hasPipelineNamed(new CaseInsensitiveString("pipe2")),is(true));
}
@Test
public void shouldReturnFalseWhenHasNotPipelinesFrom2Parts()
{
pipelines = new BasicPipelineConfigs("group_main", new Authorization(), PipelineConfigMother.pipelineConfig("pipe1"));
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,
PartialConfigMother.withPipeline("pipe2"));
assertThat(cruiseConfig.hasPipelineNamed(new CaseInsensitiveString("pipe3")), is(false));
}
@Test
public void shouldReturnGroupsFrom2Parts()
{
pipelines = new BasicPipelineConfigs("group_main", new Authorization(), PipelineConfigMother.pipelineConfig("pipe1"));
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,
PartialConfigMother.withPipelineInGroup("pipe2", "g2"));
assertThat(cruiseConfig.hasPipelineGroup("g2"),is(true));
}
@Test
public void shouldAddPipelineToMain()
{
pipelines = new BasicPipelineConfigs("group_main", new Authorization(), PipelineConfigMother.pipelineConfig("pipe1"));
pipelines.setOrigin(new FileConfigOrigin());
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,
PartialConfigMother.withPipeline("pipe2"));
cruiseConfig.addPipeline("group_main", PipelineConfigMother.pipelineConfig("pipe3"));
assertThat(mainCruiseConfig.hasPipelineNamed(new CaseInsensitiveString("pipe3")), is(true));
assertThat(cruiseConfig.hasPipelineNamed(new CaseInsensitiveString("pipe3")), is(true));
}
@Test
public void shouldGetAllPipelineNamesFromAllParts()
{
pipelines = new BasicPipelineConfigs("group_main", new Authorization(), PipelineConfigMother.pipelineConfig("pipe1"));
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,
PartialConfigMother.withPipelineInGroup("pipe2", "g2"),PartialConfigMother.withPipelineInGroup("pipe3", "g3"));
assertThat(cruiseConfig.getAllPipelineNames(), hasItem(new CaseInsensitiveString("pipe1")));
assertThat(cruiseConfig.getAllPipelineNames(), hasItem(new CaseInsensitiveString("pipe2")));
assertThat(cruiseConfig.getAllPipelineNames(), hasItem(new CaseInsensitiveString("pipe3")));
}
@Test
public void shouldGetJobConfigByName()
{
goConfigMother.addPipeline(cruiseConfig, "cruise", "dev", "linux-firefox");
JobConfig job = cruiseConfig.jobConfigByName("cruise", "dev", "linux-firefox", true);
assertNotNull(job);
}
@Test
public void shouldReturnAllUniqueSchedulableScmMaterials() {
final MaterialConfig svnMaterialConfig = new SvnMaterialConfig("http://svn_url_1", "username", "password", false);
svnMaterialConfig.setAutoUpdate(false);
final MaterialConfig svnMaterialConfigWithAutoUpdate = new SvnMaterialConfig("http://svn_url_2", "username", "password", false);
svnMaterialConfigWithAutoUpdate.setAutoUpdate(true);
final MaterialConfig hgMaterialConfig = new HgMaterialConfig("http://hg_url", null);
hgMaterialConfig.setAutoUpdate(false);
final MaterialConfig gitMaterialConfig = new GitMaterialConfig("http://git_url");
gitMaterialConfig.setAutoUpdate(false);
final MaterialConfig tfsMaterialConfig = new TfsMaterialConfig(mock(GoCipher.class), new UrlArgument("http://tfs_url"), "username", "domain", "password", "project_path");
tfsMaterialConfig.setAutoUpdate(false);
final MaterialConfig p4MaterialConfig = new P4MaterialConfig("http://p4_url", "view", "username");
p4MaterialConfig.setAutoUpdate(false);
final MaterialConfig dependencyMaterialConfig = MaterialConfigsMother.dependencyMaterialConfig();
final PluggableSCMMaterialConfig pluggableSCMMaterialConfig = MaterialConfigsMother.pluggableSCMMaterialConfig("scm-id-1", null, null);
pluggableSCMMaterialConfig.getSCMConfig().setAutoUpdate(false);
final PipelineConfig p1 = PipelineConfigMother.pipelineConfig("pipeline1", new MaterialConfigs(svnMaterialConfig), new JobConfigs(new JobConfig(new CaseInsensitiveString("jobName"))));
final PipelineConfig p2 = PipelineConfigMother.pipelineConfig("pipeline2", new MaterialConfigs(svnMaterialConfig, gitMaterialConfig),
new JobConfigs(new JobConfig(new CaseInsensitiveString("jobName"))));
final PipelineConfig p3 = PipelineConfigMother.pipelineConfig("pipeline3", new MaterialConfigs(hgMaterialConfig, dependencyMaterialConfig),
new JobConfigs(new JobConfig(new CaseInsensitiveString("jobName"))));
final PipelineConfig p4 = PipelineConfigMother.pipelineConfig("pipeline4", new MaterialConfigs(p4MaterialConfig, pluggableSCMMaterialConfig), new JobConfigs(new JobConfig(new CaseInsensitiveString("jobName"))));
final PipelineConfig p5 = PipelineConfigMother.pipelineConfig("pipeline5", new MaterialConfigs(svnMaterialConfigWithAutoUpdate, tfsMaterialConfig),
new JobConfigs(new JobConfig(new CaseInsensitiveString("jobName"))));
cruiseConfig.getGroups().add( new BasicPipelineConfigs(p1, p2, p3, p4, p5));
final Set<MaterialConfig> materials = cruiseConfig.getAllUniquePostCommitSchedulableMaterials();
assertThat(materials.size(), is(6));
assertThat(materials, hasItems(svnMaterialConfig, hgMaterialConfig, gitMaterialConfig, tfsMaterialConfig, p4MaterialConfig, pluggableSCMMaterialConfig));
assertThat(materials, not(hasItem(svnMaterialConfigWithAutoUpdate)));
}
@Test
public void getAllUniquePostCommitSchedulableMaterials_shouldReturnMaterialsWithAutoUpdateFalse(){
GitMaterialConfig gitAutoMaterial = MaterialConfigsMother.gitMaterialConfig("url");
PipelineConfig pipelineAuto = pipelineConfig("pipelineAuto", new MaterialConfigs(gitAutoMaterial));
GitMaterialConfig gitNonAutoMaterial = new GitMaterialConfig(new UrlArgument("other-url"),"master","dest",false,null,false,null,new CaseInsensitiveString("git"),false);
PipelineConfig pipelineTriggerable = pipelineConfig("pipelineTriggerable", new MaterialConfigs(gitNonAutoMaterial));
PipelineConfigs defaultGroup = createGroup("defaultGroup", pipelineAuto,pipelineTriggerable);
cruiseConfig.getGroups().add(defaultGroup);
Set<MaterialConfig> materials = cruiseConfig.getAllUniquePostCommitSchedulableMaterials();
assertThat(materials.size(),is(1));
assertThat(materials,hasItem(gitNonAutoMaterial));
}
@Test
public void getAllUniquePostCommitSchedulableMaterials_shouldReturnMaterialsWithAutoUpdateFalseAndConfigRepos(){
GitMaterialConfig gitAutoMaterial = MaterialConfigsMother.gitMaterialConfig("url");
PipelineConfig pipelineAuto = pipelineConfig("pipelineAuto", new MaterialConfigs(gitAutoMaterial));
GitMaterialConfig gitNonAutoMaterial = new GitMaterialConfig(new UrlArgument("other-url"),"master","dest",false,null,false,null,new CaseInsensitiveString("git"),false);
PipelineConfig pipelineTriggerable = pipelineConfig("pipelineTriggerable", new MaterialConfigs(gitNonAutoMaterial));
PipelineConfigs defaultGroup = createGroup("defaultGroup", pipelineAuto,pipelineTriggerable);
cruiseConfig = new BasicCruiseConfig(defaultGroup);
ConfigReposConfig reposConfig = new ConfigReposConfig();
GitMaterialConfig configRepoMaterial = new GitMaterialConfig("http://git");
reposConfig.add(new ConfigRepoConfig(configRepoMaterial,"myplug"));
cruiseConfig.setConfigRepos(reposConfig);
PipelineGroups pipelineGroups = new PipelineGroups(defaultGroup);
Set<MaterialConfig> materials = cruiseConfig.getAllUniquePostCommitSchedulableMaterials();
assertThat(materials.size(),is(2));
assertThat(materials,hasItem(gitNonAutoMaterial));
assertThat(materials,hasItem(configRepoMaterial));
}
@Test
public void shouldCheckCyclicDependency() throws Exception {
PipelineConfig p1 = createPipelineConfig("p1", "s1", "j1");
PipelineConfig p2 = createPipelineConfig("p2", "s2", "j1");
p2.addMaterialConfig(new DependencyMaterialConfig(new CaseInsensitiveString("p1"), new CaseInsensitiveString("s1")));
PipelineConfig p3 = createPipelineConfig("p3", "s3", "j1");
p3.addMaterialConfig(new DependencyMaterialConfig(new CaseInsensitiveString("p2"), new CaseInsensitiveString("s2")));
p1.addMaterialConfig(new DependencyMaterialConfig(new CaseInsensitiveString("p3"), new CaseInsensitiveString("s3")));
pipelines.addAll(Arrays.asList(p1,p2,p3));
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
ConfigReposConfig reposConfig = new ConfigReposConfig();
GitMaterialConfig configRepo = new GitMaterialConfig("http://git");
reposConfig.add(new ConfigRepoConfig(configRepo,"myplug"));
mainCruiseConfig.setConfigRepos(reposConfig);
PartialConfig partialConfig = PartialConfigMother.withPipeline("pipe2");
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig, partialConfig);
cruiseConfig.validate(mock(ValidationContext.class));
List<ConfigErrors> allErrors = cruiseConfig.getAllErrors();
assertThat((allErrors.get(0).on("base")),is("Circular dependency: p1 <- p2 <- p3 <- p1"));
}
// UI-like scenarios
@Test
public void shouldCreateEmptyEnvironmentConfigForEditsWithUIOrigin_WhenFileHasNoEnvironment_AndForEdit()
{
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
PartialConfig partialConfig = PartialConfigMother.withEnvironment("remoteEnv");
partialConfig.setOrigins(new RepoConfigOrigin());
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,true, partialConfig);
assertThat(cruiseConfig.getEnvironments().size(),is(1));
assertThat(cruiseConfig.getEnvironments().get(0) instanceof MergeEnvironmentConfig,is(true));
assertThat(cruiseConfig.getEnvironments().get(0).name(), is(new CaseInsensitiveString("remoteEnv")));
MergeEnvironmentConfig mergedEnv = (MergeEnvironmentConfig)cruiseConfig.getEnvironments().get(0);
assertThat(mergedEnv.size(),is(2));
}
@Test
public void shouldCreateEmptyEnvironmentConfigForEditsWithUIOrigin_WhenFileHasNoEnvironmentAnd2RemoteParts_AndForEdit()
{
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
PartialConfig partialConfig1 = PartialConfigMother.withEnvironment("remoteEnv");
partialConfig1.setOrigins(new RepoConfigOrigin());
PartialConfig partialConfig2 = PartialConfigMother.withEnvironment("remoteEnv");
partialConfig2.setOrigins(new RepoConfigOrigin());
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,true, partialConfig1,partialConfig2);
assertThat(cruiseConfig.getEnvironments().size(),is(1));
assertThat(cruiseConfig.getEnvironments().get(0) instanceof MergeEnvironmentConfig,is(true));
assertThat(cruiseConfig.getEnvironments().get(0).name(), is(new CaseInsensitiveString("remoteEnv")));
MergeEnvironmentConfig mergedEnv = (MergeEnvironmentConfig)cruiseConfig.getEnvironments().get(0);
assertThat(mergedEnv.size(),is(3));
}
@Test
public void shouldNotCreateMergeEnvironmentConfig_WhenFileHasNoEnvironment_AndNotForEdit()
{
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
PartialConfig partialConfig = PartialConfigMother.withEnvironment("remoteEnv");
partialConfig.setOrigins(new RepoConfigOrigin());
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,false, partialConfig);
assertThat(cruiseConfig.getEnvironments().size(),is(1));
assertThat(cruiseConfig.getEnvironments().get(0) instanceof MergeEnvironmentConfig, is(false));
assertThat(cruiseConfig.getEnvironments().get(0).name(), is(new CaseInsensitiveString("remoteEnv")));
assertThat(cruiseConfig.getEnvironments().get(0).isLocal(), is(false));
}
@Test
public void shouldNotCreateEmptyEnvironmentConfigForEditsWithUIOrigin_WhenFileHasEnvironment_AndForEdit()
{
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
mainCruiseConfig.addEnvironment(new BasicEnvironmentConfig(new CaseInsensitiveString("Env")));
mainCruiseConfig.setOrigins(new FileConfigOrigin());
PartialConfig partialConfig = PartialConfigMother.withEnvironment("Env");
partialConfig.setOrigins(new RepoConfigOrigin());
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,true, partialConfig);
assertThat(cruiseConfig.getEnvironments().size(),is(1));
assertThat(cruiseConfig.getEnvironments().get(0) instanceof MergeEnvironmentConfig,is(true));
assertThat(cruiseConfig.getEnvironments().get(0).name(), is(new CaseInsensitiveString("Env")));
MergeEnvironmentConfig mergedEnv = (MergeEnvironmentConfig)cruiseConfig.getEnvironments().get(0);
assertThat(mergedEnv.size(),is(2));
assertThat(mergedEnv.get(0).isLocal(), is(true));
assertThat(mergedEnv.get(1).isLocal(), is(false));
}
@Test
public void shouldModifyEmptyEnvironmentConfigWithUIOrigin()
{
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
PartialConfig partialConfig = PartialConfigMother.withEnvironment("remoteEnv");
partialConfig.setOrigins(new RepoConfigOrigin());
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,true, partialConfig);
cruiseConfig.getEnvironments().get(0).addAgent("agent");
MergeEnvironmentConfig mergedEnv = (MergeEnvironmentConfig)cruiseConfig.getEnvironments().get(0);
assertThat(mergedEnv.getFirstEditablePart().getAgents(),hasItem(new EnvironmentAgentConfig("agent")));
}
@Test
public void shouldModifyEnvironmentConfigWithFileOrigin()
{
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines);
BasicEnvironmentConfig envInFile = new BasicEnvironmentConfig(new CaseInsensitiveString("Env"));
mainCruiseConfig.addEnvironment(envInFile);
mainCruiseConfig.setOrigins(new FileConfigOrigin());
PartialConfig partialConfig = PartialConfigMother.withEnvironment("Env");
partialConfig.setOrigins(new RepoConfigOrigin());
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,true, partialConfig);
cruiseConfig.getEnvironments().get(0).addAgent("agent");
assertThat(envInFile.getAgents(),hasItem(new EnvironmentAgentConfig("agent")));
}
@Test
public void shouldAddAuthorizationToPipelinesConfigForEditsWithUIOrigin_WhenFileHasNoPipelineGroupYet_AndForEdit()
{
BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig();
// only remotely defined group
PartialConfig partialConfig = PartialConfigMother.withPipelineInGroup("pipe1","group1");
partialConfig.setOrigins(new RepoConfigOrigin());
cruiseConfig = new BasicCruiseConfig(mainCruiseConfig,true, partialConfig);
assertThat(cruiseConfig.getGroups().size(),is(1));
assertThat(cruiseConfig.getGroups().get(0) instanceof MergePipelineConfigs,is(true));
assertThat(cruiseConfig.getGroups().get(0).getGroup(), is("group1"));
MergePipelineConfigs mergedEnv = (MergePipelineConfigs)cruiseConfig.getGroups().get(0);
assertThat(mergedEnv.getLocal().getOrigin(), Is.<ConfigOrigin>is(new UIConfigOrigin()));
Authorization authorization = new Authorization(new AdminsConfig(
new AdminUser(new CaseInsensitiveString("firstTemplate-admin"))));
cruiseConfig.getGroups().get(0).setAuthorization(authorization);
assertThat(mergedEnv.getLocal().getAuthorization(),is(authorization));
}
private Role setupSecurityWithRole() {
SecurityConfig securityConfig = new SecurityConfig(new LdapConfig(new GoCipher()), new PasswordFileConfig("foo"), false);
securityConfig.adminsConfig().add(new AdminUser(new CaseInsensitiveString("root")));
final Role ldapUsersRole = goConfigMother.createRole("ldap-users", "root");
securityConfig.addRole(ldapUsersRole);
cruiseConfig.server().useSecurity(securityConfig);
return ldapUsersRole;
}
private StageConfig stageConfig(String pipelineName, String stageName) {
return cruiseConfig.stageConfigByName(new CaseInsensitiveString(pipelineName), new CaseInsensitiveString(stageName));
}
private void setupJobWithTasks(CruiseConfig config, Task... tasks) throws Exception {
goConfigMother.addPipeline(config, "cruise", "dev", "linux-firefox");
JobConfig job = config.jobConfigByName("cruise", "dev", "linux-firefox", true);
for (Task task : tasks) {
job.addTask(task);
}
}
private JobConfig jobConfig(String jobConfigName) {
return new JobConfig(new CaseInsensitiveString(jobConfigName), null, null);
}
private PipelineConfig addPipeline(String pipelineName, String stageName, JobConfig... jobConfigs) {
PipelineConfig pipeline = new PipelineConfig(new CaseInsensitiveString(pipelineName), new MaterialConfigs());
pipeline.add(new StageConfig(new CaseInsensitiveString(stageName), new JobConfigs(jobConfigs)));
pipelines.add(pipeline);
return pipeline;
}
private void addPipelineWithStages(String pipelineName, String stageName, JobConfig... jobConfigs) {
PipelineConfig pipeline = new PipelineConfig(new CaseInsensitiveString(pipelineName), null);
pipeline.add(new StageConfig(new CaseInsensitiveString(stageName), new JobConfigs(jobConfigs)));
pipeline.add(new StageConfig(new CaseInsensitiveString(stageName + "2"), new JobConfigs(jobConfigs)));
pipelines.add(pipeline);
}
private static class MyValidatable implements Validatable {
public Validatable innerValidatable;
public void validate(ValidationContext validationContext) {
}
public ConfigErrors errors() {
return new ConfigErrors();
}
public void addError(String fieldName, String message) {
}
}
private static class AlwaysEqualMyValidatable extends MyValidatable {
@Override
public final int hashCode() {
return 42;
}
@Override
public final boolean equals(Object obj) {
return true;
}
}
}