/* * 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; import com.thoughtworks.go.config.Agents; import com.thoughtworks.go.config.CaseInsensitiveString; import com.thoughtworks.go.config.GoConfigDao; import com.thoughtworks.go.domain.DefaultSchedulingContext; import com.thoughtworks.go.domain.JobIdentifier; import com.thoughtworks.go.domain.JobInstance; import com.thoughtworks.go.domain.Pipeline; import com.thoughtworks.go.domain.Stage; import com.thoughtworks.go.domain.StageIdentifier; import com.thoughtworks.go.fixture.PipelineWithTwoStages; import com.thoughtworks.go.server.dao.DatabaseAccessHelper; import com.thoughtworks.go.server.dao.StageDao; import com.thoughtworks.go.server.persistence.MaterialRepository; import com.thoughtworks.go.server.transaction.TransactionTemplate; import com.thoughtworks.go.util.GoConfigFileHelper; import com.thoughtworks.go.util.TimeProvider; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static com.thoughtworks.go.util.DataStructureUtils.a; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNot.not; import static org.junit.Assert.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:WEB-INF/applicationContext-global.xml", "classpath:WEB-INF/applicationContext-dataLocalAccess.xml", "classpath:WEB-INF/applicationContext-acegi-security.xml" }) public class RestfulServiceTest { @Autowired private RestfulService restfulService; @Autowired private DatabaseAccessHelper dbHelper; @Autowired private GoConfigDao cruiseConfigDao; @Autowired private MaterialRepository materialRepository; @Autowired private StageDao stageDao; @Autowired private TransactionTemplate transactionTemplate; @Autowired private InstanceFactory instanceFactory; private PipelineWithTwoStages fixture; private GoConfigFileHelper configHelper ; @Before public void setUp() throws Exception { fixture = new PipelineWithTwoStages(materialRepository, transactionTemplate); configHelper = new GoConfigFileHelper().usingCruiseConfigDao(cruiseConfigDao); configHelper.onSetUp(); dbHelper.onSetUp(); fixture.usingThreeJobs(); fixture.usingConfigHelper(configHelper).usingDbHelper(dbHelper).onSetUp(); } @After public void teardown() throws Exception { dbHelper.onTearDown(); fixture.onTearDown(); } @Test public void shouldShouldTranslateLatestPipelineLabel() throws Exception { fixture.createdPipelineWithAllStagesPassed(); Pipeline latestPipleine = fixture.createdPipelineWithAllStagesPassed(); final JobIdentifier jobIdentifier1 = new JobIdentifier(latestPipleine.getName(), JobIdentifier.LATEST, fixture.devStage, JobIdentifier.LATEST, PipelineWithTwoStages.JOB_FOR_DEV_STAGE); JobIdentifier jobIdentifier = restfulService.findJob(jobIdentifier1.getPipelineName(), jobIdentifier1.getPipelineLabel(), jobIdentifier1.getStageName(), jobIdentifier1.getStageCounter(), jobIdentifier1.getBuildName()); assertThat(jobIdentifier.getPipelineLabel(), is(latestPipleine.getLabel())); } @Test public void shouldTranslateLatestToRealPipelineLabel() throws Exception { fixture.createdPipelineWithAllStagesPassed(); Pipeline latestPipleine = fixture.createdPipelineWithAllStagesPassed(); JobIdentifier jobIdentifier = restfulService.findJob(latestPipleine.getName(), JobIdentifier.LATEST, fixture.devStage, JobIdentifier.LATEST, PipelineWithTwoStages.JOB_FOR_DEV_STAGE); assertThat(jobIdentifier.getPipelineLabel(), is(latestPipleine.getLabel())); } @Test public void shouldTranslateLatestToRealStageCounter() throws Exception { Pipeline pipeline = fixture.createdPipelineWithAllStagesPassed(); JobIdentifier jobIdentifier = restfulService.findJob(pipeline.getName(), pipeline.getLabel(), fixture.devStage, JobIdentifier.LATEST, PipelineWithTwoStages.JOB_FOR_DEV_STAGE); assertThat(Integer.valueOf(jobIdentifier.getStageCounter()), is(pipeline.getStages().byName(fixture.devStage).getCounter())); } @Test public void shouldTranslateEmtpyToLatestStageCounter() throws Exception { Pipeline pipeline = fixture.createdPipelineWithAllStagesPassed(); JobIdentifier jobIdentifier = restfulService.findJob(pipeline.getName(), pipeline.getLabel(), fixture.devStage, "", PipelineWithTwoStages.JOB_FOR_DEV_STAGE); assertThat(Integer.valueOf(jobIdentifier.getStageCounter()), is(pipeline.getStages().byName(fixture.devStage).getCounter())); } @Test public void canSupportQueryingUsingPipelineNameWithDifferentCase() throws Exception { Pipeline pipeline = fixture.createdPipelineWithAllStagesPassed(); JobIdentifier jobIdentifier = restfulService.findJob(pipeline.getName().toUpperCase(), JobIdentifier.LATEST, fixture.devStage, "", PipelineWithTwoStages.JOB_FOR_DEV_STAGE); assertThat(jobIdentifier.getPipelineName(), is(pipeline.getName())); } @Test public void canSupportQueryingUsingStageNameWithDifferentCase() throws Exception { Pipeline pipeline = fixture.createdPipelineWithAllStagesPassed(); JobIdentifier jobIdentifier = restfulService.findJob(pipeline.getName(), pipeline.getLabel(), fixture.devStage.toUpperCase(), "", PipelineWithTwoStages.JOB_FOR_DEV_STAGE); assertThat(jobIdentifier.getStageName(), is(fixture.devStage)); } @Test public void shouldFindJobByPipelineCounter() throws Exception { Pipeline pipeline = fixture.createdPipelineWithAllStagesPassed(); Stage stage = pipeline.getStages().byName(fixture.devStage); JobInstance job = stage.getJobInstances().first(); JobIdentifier result = restfulService.findJob(pipeline.getName(), String.valueOf(pipeline.getCounter()), stage.getName(), String.valueOf(stage.getCounter()), job.getName(), job.getId()); JobIdentifier expect = new JobIdentifier(pipeline, stage, job); assertThat(result, is(expect)); } @Test public void shouldFindOriginalWhenJobCopiedForRerun() throws Exception { Pipeline pipeline = fixture.createdPipelineWithAllStagesPassed(); Stage stage = pipeline.getStages().byName(fixture.devStage); JobInstance job = stage.findJob(PipelineWithTwoStages.JOB_FOR_DEV_STAGE); Stage rerunStage = instanceFactory.createStageForRerunOfJobs(stage, a(PipelineWithTwoStages.DEV_STAGE_SECOND_JOB), new DefaultSchedulingContext("loser", new Agents()), fixture.pipelineConfig().getStage( new CaseInsensitiveString(fixture.devStage)), new TimeProvider(), "md5"); stageDao.saveWithJobs(pipeline, rerunStage); dbHelper.passStage(rerunStage); JobIdentifier result = restfulService.findJob(pipeline.getName(), String.valueOf(pipeline.getCounter()), stage.getName(), String.valueOf(rerunStage.getCounter()), job.getName()); JobIdentifier expect = new JobIdentifier(pipeline, stage, job); assertThat(result, is(expect)); long copiedJobId = rerunStage.getJobInstances().getByName(job.getName()).getId(); assertThat(copiedJobId, is(not(job.getId())));//sanity check(its a copy, not the same) result = restfulService.findJob(pipeline.getName(), String.valueOf(pipeline.getCounter()), stage.getName(), String.valueOf(rerunStage.getCounter()), job.getName()); assertThat(result, is(expect));//still, the job identifier returned should be the same(because other one was a copy) result = restfulService.findJob(pipeline.getName(), String.valueOf(pipeline.getCounter()), stage.getName(), String.valueOf(rerunStage.getCounter()), job.getName(), copiedJobId); assertThat(result, is(not(expect)));//since caller knows the buildId, honor it(caller knows what she is doing) assertThat(result, is(new JobIdentifier(rerunStage.getIdentifier(), job.getName(), copiedJobId))); } @Test public void shouldReturnJobWithJobIdWhenSpecifyPipelineCounter() throws Exception { configHelper.setPipelineLabelTemplate(fixture.pipelineName, "label-${COUNT}"); Pipeline oldPipeline = fixture.createdPipelineWithAllStagesPassed(); fixture.createdPipelineWithAllStagesPassed(); Stage stage = oldPipeline.getStages().byName(fixture.devStage); JobInstance job = stage.getJobInstances().first(); JobIdentifier result = restfulService.findJob(oldPipeline.getName(), String.valueOf(oldPipeline.getCounter()), stage.getName(), String.valueOf(stage.getCounter()), job.getName(), null); JobIdentifier expect = new JobIdentifier(oldPipeline, stage, job); assertThat(result, is(expect)); } @Test public void shouldReturnJobWithLabelWhenSpecifyPipelineLabel() throws Exception { configHelper.setPipelineLabelTemplate(fixture.pipelineName, "label-${COUNT}"); Pipeline pipeline = fixture.createdPipelineWithAllStagesPassed(); Stage stage = pipeline.getStages().byName(fixture.devStage); JobInstance job = stage.getJobInstances().first(); JobIdentifier result = restfulService.findJob(pipeline.getName(), pipeline.getLabel(), stage.getName(), String.valueOf(stage.getCounter()), job.getName(), job.getId()); JobIdentifier expect = new JobIdentifier(pipeline, stage, job); assertThat(result, is(expect)); } @Test public void shouldReturnLatestJobWhenMultiplePipelinesWithSameLabel() throws Exception { configHelper.setPipelineLabelTemplate(fixture.pipelineName, "label-${COUNT}"); Pipeline pipeline = fixture.createdPipelineWithAllStagesPassed(); Pipeline newPipeline = createPipelineWithSameLabelButNoCounter(pipeline); Stage stage = newPipeline.getStages().byName(fixture.devStage); JobInstance job = stage.getJobInstances().first(); JobIdentifier result = restfulService.findJob(newPipeline.getName(), newPipeline.getLabel(), stage.getName(), String.valueOf(stage.getCounter()), job.getName(), null); JobIdentifier expect = new JobIdentifier(pipeline, stage, job); assertThat(result, is(expect)); } @Test public void shouldTranslateLatestStageCounter() { Pipeline pipeline = fixture.createdPipelineWithAllStagesPassed(); StageIdentifier stageIdentifier = restfulService.translateStageCounter(pipeline.getIdentifier(), fixture.devStage, "latest"); assertThat(stageIdentifier, is(new StageIdentifier(pipeline, pipeline.getStages().byName(fixture.devStage)))); } private Pipeline createPipelineWithSameLabelButNoCounter(Pipeline pipeline) { pipeline.setCounter(null); return dbHelper.save(pipeline); } }