/* This file is part of Delivery Pipeline Plugin. Delivery Pipeline Plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Delivery Pipeline Plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Delivery Pipeline Plugin. If not, see <http://www.gnu.org/licenses/>. */ package se.diabol.jenkins.pipeline.domain.status; import au.com.centrumsystems.hudson.plugin.buildpipeline.BuildPipelineView; import au.com.centrumsystems.hudson.plugin.buildpipeline.DownstreamProjectGridBuilder; import au.com.centrumsystems.hudson.plugin.buildpipeline.trigger.BuildPipelineTrigger; import hudson.Launcher; import hudson.model.AbstractBuild; import hudson.model.BuildListener; import hudson.model.FreeStyleProject; import hudson.model.Result; import hudson.util.OneShotEvent; import org.junit.After; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.jvnet.hudson.test.FailureBuilder; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MockBuilder; import org.jvnet.hudson.test.TestBuilder; import org.jvnet.hudson.test.UnstableBuilder; import org.jvnet.hudson.test.WithoutJenkins; import org.kohsuke.stapler.StaplerRequest; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import se.diabol.jenkins.pipeline.domain.Component; import se.diabol.jenkins.pipeline.domain.Pipeline; import se.diabol.jenkins.pipeline.domain.status.promotion.AbstractPromotionStatusProvider; import se.diabol.jenkins.pipeline.domain.status.promotion.PromotionStatus; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @RunWith(MockitoJUnitRunner.class) public class SimpleStatusTest { @Rule public JenkinsRule jenkins = new JenkinsRule(); private final static boolean pagingEnabledFalse = false; private final static boolean showChanges = true; private SimpleStatus.PromotionStatusProviderWrapper defaultNotMockedPromotionStatusProviderWrapper = new SimpleStatus.PromotionStatusProviderWrapper(); @After public void tearDown() { SimpleStatus.setPromotionStatusProviderWrapper(defaultNotMockedPromotionStatusProviderWrapper); } @Test(expected=IllegalStateException.class) public void testResolveStatusNotRecognized() throws Exception { final AbstractBuild build = Mockito.mock(AbstractBuild.class); Mockito.when(build.getResult()).thenReturn(null); FreeStyleProject project = jenkins.createFreeStyleProject(); SimpleStatus.resolveStatus(project, build, null); fail("Should throw exception"); } @Test public void testResolveStatusIdle() throws Exception { FreeStyleProject project = jenkins.createFreeStyleProject(); Status status = SimpleStatus.resolveStatus(project, null, null); assertTrue(status.isIdle()); assertEquals("IDLE", status.toString()); assertEquals(-1, status.getLastActivity()); assertEquals(-1, status.getDuration()); assertNull(status.getTimestamp()); assertTrue(status.getType().equals(StatusType.IDLE)); assertFalse(status.isPromoted()); } @Test public void testResolveStatusDisabled() throws Exception { FreeStyleProject project = jenkins.createFreeStyleProject(); project.makeDisabled(true); Status status = SimpleStatus.resolveStatus(project, null, null); assertTrue(status.isDisabled()); assertEquals("DISABLED", status.toString()); assertEquals(-1, status.getLastActivity()); assertEquals(-1, status.getDuration()); assertNull(status.getTimestamp()); assertTrue(status.getType().equals(StatusType.DISABLED)); assertFalse(status.isPromoted()); } @Test public void testResolveStatusSuccess() throws Exception { FreeStyleProject project = jenkins.createFreeStyleProject(); jenkins.buildAndAssertSuccess(project); jenkins.waitUntilNoActivity(); Status status = SimpleStatus.resolveStatus(project, project.getLastBuild(), null); assertTrue(status.isSuccess()); assertEquals("SUCCESS", status.toString()); assertEquals(project.getLastBuild().getTimeInMillis(), status.getLastActivity()); assertEquals(project.getLastBuild().getDuration(), status.getDuration()); assertNotNull(status.getTimestamp()); assertTrue(status.getType().equals(StatusType.SUCCESS)); assertFalse(status.isPromoted()); } @Test public void testResolveStatusSuccessWithPromotions() { final AbstractBuild build = Mockito.mock(AbstractBuild.class); Mockito.when(build.getResult()).thenReturn(Result.SUCCESS); final List<PromotionStatus> promotionStatusList = new ArrayList<PromotionStatus>(); promotionStatusList.add(Mockito.mock(PromotionStatus.class)); promotionStatusList.add(Mockito.mock(PromotionStatus.class)); promotionStatusList.add(Mockito.mock(PromotionStatus.class)); final AbstractPromotionStatusProvider promotionStatusProvider = Mockito.mock(AbstractPromotionStatusProvider.class); Mockito.when(promotionStatusProvider.isBuildPromoted(build)).thenReturn(true); Mockito.when(promotionStatusProvider.getPromotionStatusList(build)).thenReturn(promotionStatusList); final List<AbstractPromotionStatusProvider> promotionStatusProviders = new ArrayList<AbstractPromotionStatusProvider>(); promotionStatusProviders.add(promotionStatusProvider); final SimpleStatus.PromotionStatusProviderWrapper promotionStatusProviderWrapper = Mockito.mock(SimpleStatus.PromotionStatusProviderWrapper.class); Mockito.when(promotionStatusProviderWrapper.getAllPromotionStatusProviders()).thenReturn(promotionStatusProviders); SimpleStatus.setPromotionStatusProviderWrapper(promotionStatusProviderWrapper); final Status resolvedStatus = SimpleStatus.resolveStatus(null, build, null); assertTrue(resolvedStatus.isSuccess()); assertEquals("SUCCESS", resolvedStatus.toString()); assertTrue(resolvedStatus.getType().equals(StatusType.SUCCESS)); assertEquals(3, resolvedStatus.getPromotions().size()); assertTrue(resolvedStatus.isPromoted()); } @Test public void testResolveStatusSuccessWithNoPromotionsPlugin() { final AbstractBuild build = Mockito.mock(AbstractBuild.class); Mockito.when(build.getResult()).thenReturn(Result.SUCCESS); final SimpleStatus.PromotionStatusProviderWrapper promotionStatusProviderWrapper = Mockito.mock(SimpleStatus.PromotionStatusProviderWrapper.class); Mockito.when(promotionStatusProviderWrapper.getAllPromotionStatusProviders()).thenReturn(null); SimpleStatus.setPromotionStatusProviderWrapper(promotionStatusProviderWrapper); final Status resolvedStatus = SimpleStatus.resolveStatus(null, build, null); assertTrue(resolvedStatus.isSuccess()); assertEquals("SUCCESS", resolvedStatus.toString()); assertTrue(resolvedStatus.getType().equals(StatusType.SUCCESS)); assertTrue(resolvedStatus.getPromotions().isEmpty()); assertFalse(resolvedStatus.isPromoted()); } @Test public void testResolveStatusFailure() throws Exception { FreeStyleProject project = jenkins.createFreeStyleProject(); project.getBuildersList().add(new FailureBuilder()); project.scheduleBuild2(0); jenkins.waitUntilNoActivity(); Status status = SimpleStatus.resolveStatus(project, project.getLastBuild(), null); assertTrue(status.isFailed()); assertEquals("FAILED", status.toString()); assertEquals(project.getLastBuild().getTimeInMillis(), status.getLastActivity()); assertEquals(project.getLastBuild().getDuration(), status.getDuration()); assertNotNull(status.getTimestamp()); assertTrue(status.getType().equals(StatusType.FAILED)); assertFalse(status.isPromoted()); } @Test public void testResolveStatusFailureWithPromotions() { final AbstractBuild build = Mockito.mock(AbstractBuild.class); Mockito.when(build.getResult()).thenReturn(Result.FAILURE); final List<PromotionStatus> promotionStatusList = new ArrayList<PromotionStatus>(); promotionStatusList.add(Mockito.mock(PromotionStatus.class)); promotionStatusList.add(Mockito.mock(PromotionStatus.class)); promotionStatusList.add(Mockito.mock(PromotionStatus.class)); final AbstractPromotionStatusProvider promotionStatusProvider = Mockito.mock(AbstractPromotionStatusProvider.class); Mockito.when(promotionStatusProvider.isBuildPromoted(build)).thenReturn(true); Mockito.when(promotionStatusProvider.getPromotionStatusList(build)).thenReturn(promotionStatusList); final List<AbstractPromotionStatusProvider> promotionStatusProviders = new ArrayList<AbstractPromotionStatusProvider>(); promotionStatusProviders.add(promotionStatusProvider); final SimpleStatus.PromotionStatusProviderWrapper promotionStatusProviderWrapper = Mockito.mock(SimpleStatus.PromotionStatusProviderWrapper.class); Mockito.when(promotionStatusProviderWrapper.getAllPromotionStatusProviders()).thenReturn(promotionStatusProviders); SimpleStatus.setPromotionStatusProviderWrapper(promotionStatusProviderWrapper); final Status resolvedStatus = SimpleStatus.resolveStatus(null, build, null); assertFalse(resolvedStatus.isSuccess()); assertEquals("FAILED", resolvedStatus.toString()); assertTrue(resolvedStatus.getType().equals(StatusType.FAILED)); assertEquals(3, resolvedStatus.getPromotions().size()); assertTrue(resolvedStatus.isPromoted()); } @Test public void testResolveStatusFailureWithNoPromotionsPlugin() { final AbstractBuild build = Mockito.mock(AbstractBuild.class); Mockito.when(build.getResult()).thenReturn(Result.FAILURE); final SimpleStatus.PromotionStatusProviderWrapper promotionStatusProviderWrapper = Mockito.mock(SimpleStatus.PromotionStatusProviderWrapper.class); Mockito.when(promotionStatusProviderWrapper.getAllPromotionStatusProviders()).thenReturn(null); SimpleStatus.setPromotionStatusProviderWrapper(promotionStatusProviderWrapper); final Status resolvedStatus = SimpleStatus.resolveStatus(null, build, null); assertFalse(resolvedStatus.isSuccess()); assertEquals("FAILED", resolvedStatus.toString()); assertTrue(resolvedStatus.getType().equals(StatusType.FAILED)); assertTrue(resolvedStatus.getPromotions().isEmpty()); assertFalse(resolvedStatus.isPromoted()); } @Test public void testResolveStatusUnstable() throws Exception { FreeStyleProject project = jenkins.createFreeStyleProject(); project.getBuildersList().add(new UnstableBuilder()); project.scheduleBuild2(0); jenkins.waitUntilNoActivity(); Status status = SimpleStatus.resolveStatus(project, project.getLastBuild(), null); assertTrue(status.isUnstable()); assertEquals("UNSTABLE", status.toString()); assertEquals(project.getLastBuild().getTimeInMillis(), status.getLastActivity()); assertEquals(project.getLastBuild().getDuration(), status.getDuration()); assertNotNull(status.getTimestamp()); assertTrue(status.getType().equals(StatusType.UNSTABLE)); assertFalse(status.isPromoted()); } @Test public void testResolveStatusAborted() throws Exception { FreeStyleProject project = jenkins.createFreeStyleProject(); project.getBuildersList().add(new MockBuilder(Result.ABORTED)); project.scheduleBuild2(0); jenkins.waitUntilNoActivity(); Status status = SimpleStatus.resolveStatus(project, project.getLastBuild(), null); assertTrue(status.isCancelled()); assertEquals("CANCELLED", status.toString()); assertEquals(project.getLastBuild().getTimeInMillis(), status.getLastActivity()); assertEquals(project.getLastBuild().getDuration(), status.getDuration()); assertNotNull(status.getTimestamp()); assertTrue(status.getType().equals(StatusType.CANCELLED)); assertFalse(status.isPromoted()); } @Test public void testResolveStatusNotBuilt() throws Exception { FreeStyleProject project = jenkins.createFreeStyleProject(); project.getBuildersList().add(new MockBuilder(Result.NOT_BUILT)); project.scheduleBuild2(0); jenkins.waitUntilNoActivity(); Status status = SimpleStatus.resolveStatus(project, project.getLastBuild(), null); assertTrue(status.isNotBuilt()); assertEquals("NOT_BUILT", status.toString()); assertEquals(project.getLastBuild().getTimeInMillis(), status.getLastActivity()); assertEquals(project.getLastBuild().getDuration(), status.getDuration()); assertNotNull(status.getTimestamp()); assertTrue(status.getType().equals(StatusType.NOT_BUILT)); assertFalse(status.isPromoted()); } @Test public void testResolveStatusQueued() throws Exception { FreeStyleProject project = jenkins.createFreeStyleProject(); project.scheduleBuild2(2); Status status = SimpleStatus.resolveStatus(project, null, null); assertTrue(status.isQueued()); assertFalse(status.isRunning()); assertTrue(status.getType().equals(StatusType.QUEUED)); assertEquals("QUEUED", status.toString()); jenkins.waitUntilNoActivity(); status = SimpleStatus.resolveStatus(project, project.getLastBuild(), null); assertTrue(status.isSuccess()); assertTrue(status.getType().equals(StatusType.SUCCESS)); assertEquals(project.getLastBuild().getDuration(), status.getDuration()); assertNotNull(status.getTimestamp()); assertFalse(status.isPromoted()); } @Test public void testResolveStatusBuilding() throws Exception { final OneShotEvent buildStarted = new OneShotEvent(); final OneShotEvent buildBuilding = new OneShotEvent(); FreeStyleProject project = jenkins.createFreeStyleProject(); project.getBuildersList().add(new TestBuilder() { public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { buildStarted.signal(); buildBuilding.block(); return true; } }); project.scheduleBuild2(0); buildStarted.block(); // wait for the build to really start Status status = SimpleStatus.resolveStatus(project, project.getFirstBuild(), null); assertTrue(status.isRunning()); buildBuilding.signal(); jenkins.waitUntilNoActivity(); assertNotNull(status.getTimestamp()); assertTrue(status instanceof Running); Running running = (Running) status; assertTrue(running.getPercentage() > 0); assertTrue(running.isRunning()); assertTrue(status.getType().equals(StatusType.RUNNING)); assertNotNull(status.toString()); } @Test @WithoutJenkins public void shouldCalculateBuildProgressProperly() { final long currentTime = 200; final long buildStarted = 100; final long estimatedLength = 200; assertThat(SimpleStatus.calculateBuildProgress(currentTime, buildStarted, estimatedLength), is(50)); } @Test @WithoutJenkins public void shouldCalculateBuildProgressForDurationLongerThanExpected() { final long currentTime = 301; final long buildStarted = 100; final long estimatedLength = 200; assertThat(SimpleStatus.calculateBuildProgress(currentTime, buildStarted, estimatedLength), is(99)); } @Test @WithoutJenkins public void shouldCalculateBuildProgressForNotStartedBuild() { final long currentTime = 50; final long buildStarted = 100; final long estimatedLength = 200; assertThat(SimpleStatus.calculateBuildProgress(currentTime, buildStarted, estimatedLength), is(0)); } @Test @WithoutJenkins public void shouldCalculateBuildProgressWhenNoEstimationAvailable() { int progress = SimpleStatus.calculateBuildProgress(1478897029931L, 1478897023907L, -1L); assertTrue(progress > 0); assertThat(progress, is(99)); } @Test @WithoutJenkins public void testBuildingProgressGreaterThanEstimated() { AbstractBuild build = Mockito.mock(AbstractBuild.class); Mockito.when(build.isBuilding()).thenReturn(true); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MILLISECOND, -10000); Mockito.when(build.getTimestamp()).thenReturn(calendar); Mockito.when(build.getEstimatedDuration()).thenReturn(10l); assertEquals(99, ((Running) SimpleStatus.resolveStatus(null, build, null)).getPercentage()); } @Test public void testCheckThatAllOnlyQueuedBuildIsResolvedAsQueued() throws Exception { StaplerRequest request = Mockito.mock(StaplerRequest.class); FreeStyleProject project1 = jenkins.createFreeStyleProject("project1"); jenkins.createFreeStyleProject("project2"); project1.getPublishersList().add(new BuildPipelineTrigger("project2", null)); jenkins.getInstance().rebuildDependencyGraph(); Pipeline pipeline = Pipeline.extractPipeline("name", project1); jenkins.buildAndAssertSuccess(project1); jenkins.buildAndAssertSuccess(project1); jenkins.waitUntilNoActivity(); Component component = new Component("Component","project1", null, false, 3, pagingEnabledFalse, 1); List<Pipeline> pipelines = pipeline.createPipelineLatest(2, jenkins.getInstance(), pagingEnabledFalse, showChanges, component); assertEquals(2, pipelines.size()); assertEquals(StatusType.IDLE, pipelines.get(0).getStages().get(1).getTasks().get(0).getStatus().getType()); assertEquals(StatusType.IDLE, pipelines.get(1).getStages().get(1).getTasks().get(0).getStatus().getType()); BuildPipelineView view = new BuildPipelineView("", "", new DownstreamProjectGridBuilder("project1"), "0", false, ""); project1.setQuietPeriod(3); view.triggerManualBuild(1, "project2", "project1"); pipelines = pipeline.createPipelineLatest(2, jenkins.getInstance(), pagingEnabledFalse, showChanges, component); assertEquals(2, pipelines.size()); assertEquals(StatusType.IDLE, pipelines.get(0).getStages().get(1).getTasks().get(0).getStatus().getType()); assertEquals(StatusType.QUEUED, pipelines.get(1).getStages().get(1).getTasks().get(0).getStatus().getType()); jenkins.waitUntilNoActivity(); pipelines = pipeline.createPipelineLatest(2, jenkins.getInstance(), pagingEnabledFalse, showChanges, component); assertEquals(2, pipelines.size()); assertEquals(StatusType.IDLE, pipelines.get(0).getStages().get(1).getTasks().get(0).getStatus().getType()); assertEquals(StatusType.SUCCESS, pipelines.get(1).getStages().get(1).getTasks().get(0).getStatus().getType()); } }