@Test
  public void should_NOT_markAsChangedWhenMaterialIsReIntroducedWithSameRevisionsToPipeline()
      throws Exception {
    SvnMaterial svn1 = SvnMaterial.createSvnMaterialWithMock(repository);
    svn1.setFolder("another_repo");
    mingleConfig = configHelper.replaceMaterialForPipeline(MINGLE_PIPELINE_NAME, svn1.config());
    runAndPassWith(svn1, "foo.c", svnRepository);

    SvnTestRepo svn2Repository = new SvnTestRepo("testSvnRepo2");
    Subversion repository2 = new SvnCommand(null, svn2Repository.projectRepositoryUrl());
    SvnMaterial svn2 = SvnMaterial.createSvnMaterialWithMock(repository2);
    svn2.setFolder("boulder");

    checkinFile(svn2, "bar.c", svn2Repository);

    mingleConfig = configHelper.addMaterialToPipeline(MINGLE_PIPELINE_NAME, svn2.config());

    scheduleHelper.autoSchedulePipelinesWithRealMaterials(MINGLE_PIPELINE_NAME);

    assertThat(pipelineScheduleQueue.toBeScheduled().keySet(), hasItem(MINGLE_PIPELINE_NAME));
    BuildCause mingleBuildCause = pipelineScheduleQueue.toBeScheduled().get(MINGLE_PIPELINE_NAME);
    verifyChanged(svn2, mingleBuildCause, true);
    verifyChanged(
        svn1,
        mingleBuildCause,
        false); // this should not have changed, as foo.c was already built in the previous instance

    runAndPass(mingleBuildCause.getMaterialRevisions());

    mingleConfig = configHelper.replaceMaterialForPipeline(MINGLE_PIPELINE_NAME, svn1.config());
    scheduleHelper.autoSchedulePipelinesWithRealMaterials(MINGLE_PIPELINE_NAME);

    assertThat(pipelineScheduleQueue.toBeScheduled().keySet(), hasItem(MINGLE_PIPELINE_NAME));
    mingleBuildCause = pipelineScheduleQueue.toBeScheduled().get(MINGLE_PIPELINE_NAME);
    verifyChanged(
        svn1,
        mingleBuildCause,
        false); // this should not have changed, as foo.c was already built in the previous instance
    runAndPassWith(svn1, "baz.c", svnRepository);

    mingleConfig = configHelper.addMaterialToPipeline(MINGLE_PIPELINE_NAME, svn2.config());

    checkinFile(svn1, "quux.c", svnRepository);

    scheduleHelper.autoSchedulePipelinesWithRealMaterials(MINGLE_PIPELINE_NAME);

    assertThat(pipelineScheduleQueue.toBeScheduled().keySet(), hasItem(MINGLE_PIPELINE_NAME));
    mingleBuildCause = pipelineScheduleQueue.toBeScheduled().get(MINGLE_PIPELINE_NAME);
    verifyChanged(svn2, mingleBuildCause, false);
    verifyChanged(svn1, mingleBuildCause, true);
  }
  @Test
  public void shouldScheduleIfAgentMatchingResources() throws Exception {
    JobConfig plan =
        evolveConfig
            .findBy(new CaseInsensitiveString(STAGE_NAME))
            .jobConfigByInstanceName("unit", true);
    plan.addResource("some-resource");

    scheduleHelper.schedule(evolveConfig, modifySomeFiles(evolveConfig), DEFAULT_APPROVED_BY);

    AgentConfig agentConfig = AgentMother.localAgent();
    agentConfig.addResource(new Resource("some-resource"));

    buildAssignmentService.onTimer();
    Work work = buildAssignmentService.assignWorkToAgent(agent(agentConfig));
    assertThat(work, is(not((Work) BuildAssignmentService.NO_WORK)));

    Pipeline pipeline =
        pipelineDao.mostRecentPipeline(CaseInsensitiveString.str(evolveConfig.name()));
    JobInstance job = pipeline.findStage(STAGE_NAME).findJob("unit");

    JobPlan loadedPlan = jobInstanceDao.loadPlan(job.getId());
    assertThat(loadedPlan.getResources(), is((List<Resource>) plan.resources()));

    assertThat(job.getState(), is(JobState.Assigned));
    assertThat(job.getAgentUuid(), is(agentConfig.getUuid()));
  }
 @Test
 public void shouldNotSchedulePipelineIfTheChangesAreIgnored() throws Exception {
   String ignoredFile = "a.doc";
   svnRepository.checkInOneFile(ignoredFile);
   scheduleHelper.autoSchedulePipelinesWithRealMaterials(MINGLE_PIPELINE_NAME);
   assertThat(pipelineScheduleQueue.toBeScheduled().keySet(), not(hasItem(MINGLE_PIPELINE_NAME)));
 }
 @Test
 public void shouldNotSchedulePipelineWithManualFirstStageForAutomaticBuild() throws Exception {
   configHelper.configureStageAsManualApproval(MINGLE_PIPELINE_NAME, STAGE_NAME);
   svnRepository.checkInOneFile("a.java");
   scheduleHelper.autoSchedulePipelinesWithRealMaterials(MINGLE_PIPELINE_NAME);
   assertThat(pipelineScheduleQueue.toBeScheduled().keySet(), not(hasItem(MINGLE_PIPELINE_NAME)));
 }
 private Pipeline manualSchedule(String pipelineName)
     throws Exception, StageAlreadyBuildingException {
   scheduleHelper.manuallySchedulePipelineWithRealMaterials(
       pipelineName, new Username(new CaseInsensitiveString("some user name")));
   scheduleService.autoSchedulePipelinesFromRequestBuffer();
   return pipelineService.mostRecentFullPipelineByName(pipelineName);
 }
 @Test
 public void hasModificationShouldBeTrueIfThereIsBuildCauseInBuffer() throws Exception {
   fixture.createNewCheckin();
   scheduleHelper.autoSchedulePipelinesWithRealMaterials(fixture.pipelineName);
   JsonMap jsonMap = requestPipelineHistoryPage();
   assertThat(getItemInJson(jsonMap, "showForceBuildButton"), is("true"));
 }
  @Test
  public void shouldUnderstandChangedMaterial_forManual_triggerWithOptions_DoneWithANewRevision()
      throws Exception {
    SvnMaterial svn = SvnMaterial.createSvnMaterialWithMock(repository);

    MaterialRevisions revsAfterFoo = checkinFile(svn, "foo.c", svnRepository);

    String revisionForFingerPrint =
        revsAfterFoo.findRevisionForFingerPrint(svn.getFingerprint()).getRevision().getRevision();
    scheduleHelper.manuallySchedulePipelineWithRealMaterials(
        MINGLE_PIPELINE_NAME,
        new Username(new CaseInsensitiveString("loser")),
        m(
            MaterialsMother.createMaterialFromMaterialConfig(mingleConfig.materialConfigs().get(0))
                .getPipelineUniqueFingerprint(),
            revisionForFingerPrint));

    assertThat(pipelineScheduleQueue.toBeScheduled().keySet(), hasItem(MINGLE_PIPELINE_NAME));
    BuildCause bisectAfterBisectBuildCause =
        pipelineScheduleQueue.toBeScheduled().get(MINGLE_PIPELINE_NAME);
    for (MaterialRevision materialRevision : bisectAfterBisectBuildCause.getMaterialRevisions()) {
      assertThat(
          "material revision " + materialRevision + " should have been considered changed.",
          materialRevision.isChanged(),
          is(true));
    }
    assertThat(bisectAfterBisectBuildCause.getMaterialRevisions().getRevisions().size(), is(1));
  }
 @Test
 public void shouldCreateGroupIfPipelineHasModificationEvenNoPipelineHistory() throws Exception {
   fixture.createNewCheckin();
   scheduleHelper.autoSchedulePipelinesWithRealMaterials(fixture.pipelineName);
   JsonMap jsonMap = requestPipelineHistoryPage();
   JsonList groups = jsonMap.getJsonList("groups");
   assertThat("Should create group for the coming pipeline", groups.size(), is(1));
 }
 @Test
 public void manualSchedulePipeline_canProduceShouldNotgetIntoCyclicLoopWithTriggerMonitor()
     throws Exception {
   OperationResult operationResult = new ServerHealthStateOperationResult();
   buildCauseProducer.manualProduceBuildCauseAndSave(
       MINGLE_PIPELINE_NAME, Username.ANONYMOUS, new ScheduleOptions(), operationResult);
   scheduleHelper.waitForAnyScheduled(5);
   assertThat(operationResult.canContinue(), is(true));
 }
 @Test
 public void shouldScheduleANewPipelineWhenManuallyTrigeredWithNoChanges() throws Exception {
   final HashMap<String, String> revisions = new HashMap<String, String>();
   final HashMap<String, String> environmentVariables = new HashMap<String, String>();
   buildCauseProducer.manualProduceBuildCauseAndSave(
       MINGLE_PIPELINE_NAME,
       Username.ANONYMOUS,
       new ScheduleOptions(revisions, environmentVariables, new HashMap<String, String>()),
       new ServerHealthStateOperationResult());
   assertThat(scheduleHelper.waitForAnyScheduled(5).keySet(), hasItem(MINGLE_PIPELINE_NAME));
 }
  @Test
  public void shouldStopAutoSchedulingIfDiskSpaceIsLessThanMinimum() throws Exception {
    diskSpaceSimulator.simulateDiskFull();

    scheduleHelper.autoSchedulePipelinesWithRealMaterials();

    assertThat(
        serverHealthService.getLogsAsText(),
        containsString(
            "Go Server has run out of artifacts disk space. Scheduling has been stopped"));
    assertThat(pipelineScheduleQueue.toBeScheduled().keySet(), not(hasItem(MINGLE_PIPELINE_NAME)));
  }
  @Test
  public void should_produceBuildCause_whenMaterialConfigurationChanges() throws Exception {
    SvnMaterial svn1 = SvnMaterial.createSvnMaterialWithMock(repository);
    mingleConfig = configHelper.replaceMaterialForPipeline(MINGLE_PIPELINE_NAME, svn1.config());
    runAndPassWith(svn1, "foo.c", svnRepository);

    scheduleHelper.autoSchedulePipelinesWithRealMaterials(MINGLE_PIPELINE_NAME);

    BuildCause mingleBuildCause = pipelineScheduleQueue.toBeScheduled().get(MINGLE_PIPELINE_NAME);
    assertThat(mingleBuildCause, is(nullValue()));

    svn1.setFolder("another_repo");
    mingleConfig = configHelper.replaceMaterialForPipeline(MINGLE_PIPELINE_NAME, svn1.config());

    scheduleHelper.autoSchedulePipelinesWithRealMaterials(MINGLE_PIPELINE_NAME);

    assertThat(pipelineScheduleQueue.toBeScheduled().keySet(), hasItem(MINGLE_PIPELINE_NAME));
    mingleBuildCause = pipelineScheduleQueue.toBeScheduled().get(MINGLE_PIPELINE_NAME);
    verifyChanged(
        svn1,
        mingleBuildCause,
        false); // because material configuration changed, and not actual revisions
  }
  @Test
  public void shouldNotThrowErrorWhenMaterialsChange() throws Exception {
    configHelper.addPipeline("cruise", "dev", repository);
    goConfigService.forceNotifyListeners();
    scheduleHelper.autoSchedulePipelinesWithRealMaterials("mingle", "evolve", "cruise");

    configHelper.replaceMaterialForPipeline(
        "cruise", svnMaterialConfig("http://new-material", null));
    goConfigService.forceNotifyListeners();
    try {
      scheduleService.autoSchedulePipelinesFromRequestBuffer();
    } catch (Exception e) {
      fail("#2520 - should not cause an error if materials have changed");
    }
  }
  /**
   * How we handle SVN Material and other Material(Hg Git and etc) is different, which caused the
   * bug #2375
   */
  @Test
  public void shouldNotGetModificationWhenCheckInFilesInIgnoredList() throws Exception {
    prepareAPipelineWithHistory();

    checkInFiles(
        "helper/resources/images/cruise/StageActivity.png",
        "helper/topics/upgrading_go.xml",
        "helper/topics/whats_new_in_go.xml");

    Map<String, BuildCause> beforeLoad = pipelineScheduleQueue.toBeScheduled();

    scheduleHelper.autoSchedulePipelinesWithRealMaterials();

    Map<String, BuildCause> afterLoad = pipelineScheduleQueue.toBeScheduled();
    assertThat(afterLoad.size(), is(beforeLoad.size()));
  }
  @Test
  public void shouldRemoveBuildCauseIfAnyExceptionIsThrown() throws Exception {
    configHelper.addPipeline("cruise", "dev", repository);
    goConfigService.forceNotifyListeners();
    goConfigService
        .getCurrentConfig()
        .pipelineConfigByName(new CaseInsensitiveString("cruise"))
        .get(0)
        .jobConfigByConfigName(new CaseInsensitiveString("unit"))
        .setRunOnAllAgents(true);
    scheduleHelper.autoSchedulePipelinesWithRealMaterials("cruise");

    goConfigService.forceNotifyListeners();

    scheduleService.autoSchedulePipelinesFromRequestBuffer();
    assertThat(pipelineScheduleQueue.toBeScheduled().size(), is(0));
  }
  @Test
  public void shouldRemoveBuildCauseIfPipelineNotExist() throws Exception {
    configHelper.addPipeline("cruise", "dev", repository);
    goConfigService.forceNotifyListeners();
    scheduleHelper.autoSchedulePipelinesWithRealMaterials("mingle", "evolve", "cruise");

    Assertions.assertWillHappen(
        2,
        PipelineScheduleQueueMatcher.numberOfScheduledPipelinesIsAtLeast(pipelineScheduleQueue),
        Timeout.FIVE_SECONDS);
    int originalSize = pipelineScheduleQueue.toBeScheduled().size();
    assertThat(originalSize, greaterThan(1));
    configHelper.initializeConfigFile();
    goConfigService.forceNotifyListeners();

    scheduleService.autoSchedulePipelinesFromRequestBuffer();
    assertThat(pipelineScheduleQueue.toBeScheduled().size(), is(0));
  }
 @Test
 public void should_NOT_schedulePipeline_whenOneOfTheMaterialsHasNoModificationsPresent()
     throws Exception {
   Pipeline latestGoInstance =
       PipelineMother.schedule(
           goPipelineConfig,
           BuildCause.createManualForced(
               svnMaterialRevs, new Username(new CaseInsensitiveString("loser"))));
   latestGoInstance = pipelineDao.saveWithStages(latestGoInstance);
   dbHelper.passStage(latestGoInstance.getStages().first());
   configHelper.addMaterialToPipeline(
       GO_PIPELINE_NAME,
       new DependencyMaterialConfig(
           new CaseInsensitiveString(GO_PIPELINE_UPSTREAM),
           new CaseInsensitiveString(STAGE_NAME)));
   svnRepository.checkInOneFile("a.java");
   scheduleHelper.autoSchedulePipelinesWithRealMaterials(GO_PIPELINE_NAME);
   assertThat(pipelineScheduleQueue.toBeScheduled().keySet(), not(hasItem(GO_PIPELINE_NAME)));
 }
  @Test
  public void shouldSchedulePipelineWithManualFirstStageWhenManuallyTriggered() throws Exception {
    configHelper.configureStageAsManualApproval(MINGLE_PIPELINE_NAME, STAGE_NAME);

    svnRepository.checkInOneFile("a.java");
    materialDatabaseUpdater.updateMaterial(svnRepository.material());

    final HashMap<String, String> revisions = new HashMap<String, String>();
    final HashMap<String, String> environmentVariables = new HashMap<String, String>();
    buildCauseProducer.manualProduceBuildCauseAndSave(
        MINGLE_PIPELINE_NAME,
        Username.ANONYMOUS,
        new ScheduleOptions(revisions, environmentVariables, new HashMap<String, String>()),
        new ServerHealthStateOperationResult());

    Map<String, BuildCause> afterLoad = scheduleHelper.waitForAnyScheduled(5);
    assertThat(afterLoad.keySet(), hasItem(MINGLE_PIPELINE_NAME));
    BuildCause cause = afterLoad.get(MINGLE_PIPELINE_NAME);
    assertThat(cause.getBuildCauseMessage(), containsString("Forced by anonymous"));
  }
  @Test
  public void shouldNotScheduleIfAgentDoesNotHaveResources() throws Exception {
    JobConfig plan =
        evolveConfig
            .findBy(new CaseInsensitiveString(STAGE_NAME))
            .jobConfigByInstanceName("unit", true);
    plan.addResource("some-resource");

    scheduleHelper.schedule(evolveConfig, modifySomeFiles(evolveConfig), DEFAULT_APPROVED_BY);

    Work work = buildAssignmentService.assignWorkToAgent(agent(AgentMother.localAgent()));

    Pipeline pipeline =
        pipelineDao.mostRecentPipeline(CaseInsensitiveString.str(evolveConfig.name()));
    JobInstance job = pipeline.findStage(STAGE_NAME).findJob("unit");

    assertThat(work, is((Work) BuildAssignmentService.NO_WORK));
    assertThat(job.getState(), is(JobState.Scheduled));
    assertThat(job.getAgentUuid(), is(nullValue()));
  }
  @Test
  public void shouldReScheduleToCorrectAgent() throws Exception {
    JobConfig plan =
        evolveConfig
            .findBy(new CaseInsensitiveString(STAGE_NAME))
            .jobConfigByInstanceName("unit", true);
    plan.addResource("some-resource");

    scheduleHelper.schedule(evolveConfig, modifySomeFiles(evolveConfig), DEFAULT_APPROVED_BY);

    buildAssignmentService.onTimer();

    AgentConfig agentConfig = AgentMother.localAgent();
    agentConfig.addResource(new Resource("some-resource"));
    Work work = buildAssignmentService.assignWorkToAgent(agent(agentConfig));
    assertThat(work, is(not((Work) BuildAssignmentService.NO_WORK)));

    Pipeline pipeline =
        pipelineDao.mostRecentPipeline(CaseInsensitiveString.str(evolveConfig.name()));
    JobInstance job = pipeline.findStage(STAGE_NAME).findJob("unit");

    JobInstance runningJob = jobInstanceDao.buildByIdWithTransitions(job.getId());

    scheduleService.rescheduleJob(runningJob);

    pipeline = pipelineDao.mostRecentPipeline(CaseInsensitiveString.str(evolveConfig.name()));
    JobInstance rescheduledJob = pipeline.findStage(STAGE_NAME).findJob("unit");

    assertThat(rescheduledJob.getId(), not(runningJob.getId()));

    buildAssignmentService.onTimer();
    Work noResourcesWork =
        buildAssignmentService.assignWorkToAgent(
            agent(AgentMother.localAgentWithResources("WITHOUT_RESOURCES")));
    assertThat(noResourcesWork, is((Work) BuildAssignmentService.NO_WORK));

    buildAssignmentService.onTimer();
    Work correctAgentWork = buildAssignmentService.assignWorkToAgent(agent(agentConfig));
    assertThat(correctAgentWork, is(not((Work) BuildAssignmentService.NO_WORK)));
  }
  @Test
  public void
      shouldUnderstandChangedMaterial_forCompatibleRevisionsBeingSelectedForChangedMaterials_whenTriggeringTheFirstTime()
          throws Exception {
    DependencyMaterialConfig mingleMaterialConfig =
        new DependencyMaterialConfig(
            new CaseInsensitiveString(MINGLE_PIPELINE_NAME), new CaseInsensitiveString(STAGE_NAME));
    String mingleDownstreamPipelineName = "down_of_mingle";
    SvnMaterial svn = SvnMaterial.createSvnMaterialWithMock(repository);

    runAndPassWith(svn, "foo.c", svnRepository);

    svnRepository.checkInOneFile("bar.c");
    materialDatabaseUpdater.updateMaterial(svn);

    configHelper.addPipeline(
        mingleDownstreamPipelineName,
        STAGE_NAME,
        new MaterialConfigs(svn.config(), mingleMaterialConfig),
        "unit");

    pipelineTimeline.update();
    scheduleHelper.autoSchedulePipelinesWithRealMaterials(mingleDownstreamPipelineName);

    assertThat(
        pipelineScheduleQueue.toBeScheduled().keySet(), hasItem(mingleDownstreamPipelineName));
    BuildCause downstreamBuildCause =
        pipelineScheduleQueue.toBeScheduled().get(mingleDownstreamPipelineName);
    for (MaterialRevision materialRevision : downstreamBuildCause.getMaterialRevisions()) {
      assertThat(
          "material revision " + materialRevision + " was marked as not changed",
          materialRevision.isChanged(),
          is(true));
    }
    assertThat(downstreamBuildCause.getMaterialRevisions().getRevisions().size(), is(2));
  }
 @Test
 public void shouldSchedulePipeline() throws Exception {
   checkinFile(SvnMaterial.createSvnMaterialWithMock(repository), "a.java", svnRepository);
   scheduleHelper.autoSchedulePipelinesWithRealMaterials(MINGLE_PIPELINE_NAME);
   assertThat(pipelineScheduleQueue.toBeScheduled().keySet(), hasItem(MINGLE_PIPELINE_NAME));
 }
 private void autoSchedulePipelines(String... pipelineNames) throws Exception {
   scheduleHelper.autoSchedulePipelinesWithRealMaterials(pipelineNames);
   scheduleService.autoSchedulePipelinesFromRequestBuffer();
 }