/*************************GO-LICENSE-START********************************* * Copyright 2014 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. *************************GO-LICENSE-END***********************************/ package com.thoughtworks.go.server.service; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.thoughtworks.go.domain.PipelineIdentifier; import com.thoughtworks.go.helper.PipelineConfigMother; import com.thoughtworks.go.server.scheduling.TriggerMonitor; import com.thoughtworks.go.server.service.result.OperationResult; import com.thoughtworks.go.server.service.result.ServerHealthStateOperationResult; import com.thoughtworks.go.serverhealth.HealthStateScope; import com.thoughtworks.go.serverhealth.HealthStateType; import com.thoughtworks.go.serverhealth.ServerHealthService; import com.thoughtworks.go.serverhealth.ServerHealthState; import com.thoughtworks.go.util.SystemEnvironment; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Matchers; import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; public class SchedulingCheckerServiceUnitTest { private SchedulingCheckerService schedulingChecker; private SecurityService securityService; private UserService userService; private CompositeChecker compositeChecker; private OperationResult operationResult; @Captor private ArgumentCaptor<List<SchedulingChecker>> argumentCaptor; @Before public void setUp() throws Exception { initMocks(this); securityService = mock(SecurityService.class); userService = mock(UserService.class); schedulingChecker = spy(new SchedulingCheckerService(mock(GoConfigService.class), mock(CurrentActivityService.class), mock(SystemEnvironment.class), securityService, mock(PipelineLockService.class), mock(TriggerMonitor.class), mock(PipelineScheduleQueue.class), userService, mock(ServerHealthService.class), mock(PipelinePauseService.class))); compositeChecker = mock(CompositeChecker.class); operationResult = mock(OperationResult.class); doReturn(compositeChecker).when(schedulingChecker).buildScheduleCheckers(Matchers.<List<SchedulingChecker>>any()); when(operationResult.getServerHealthState()).thenReturn(ServerHealthState.success(HealthStateType.general(HealthStateScope.GLOBAL))); } @Test public void shouldCheckIfScheduleCheckersCalledOnStageRerun() throws Exception { schedulingChecker.canRerunStage(new PipelineIdentifier("pipeline_name", 1), "stage_name", "user", operationResult); verify(schedulingChecker).buildScheduleCheckers(argumentCaptor.capture()); verify(compositeChecker).check(operationResult); assertFor(argumentCaptor.getValue(), StageAuthorizationChecker.class); assertFor(argumentCaptor.getValue(), PipelinePauseChecker.class); assertFor(argumentCaptor.getValue(), PipelineActiveChecker.class); assertFor(argumentCaptor.getValue(), StageActiveChecker.class); assertFor(argumentCaptor.getValue(), ArtifactsDiskSpaceFullChecker.class); assertFor(argumentCaptor.getValue(), DatabaseDiskSpaceFullChecker.class); } @Test public void shouldCheckIfScheduleCheckersCalledOnManuallyTrigger() throws Exception { schedulingChecker.canManuallyTrigger(PipelineConfigMother.pipelineConfig("p1"), "user", operationResult); verify(schedulingChecker).buildScheduleCheckers(argumentCaptor.capture()); verify(compositeChecker).check(operationResult); assertFor(argumentCaptor.getValue(), AboutToBeTriggeredChecker.class); assertFor(argumentCaptor.getValue(), StageAuthorizationChecker.class); assertFor(argumentCaptor.getValue(), PipelinePauseChecker.class); assertFor(argumentCaptor.getValue(), PipelineLockChecker.class); assertFor(argumentCaptor.getValue(), StageActiveChecker.class); assertFor(argumentCaptor.getValue(), ArtifactsDiskSpaceFullChecker.class); assertFor(argumentCaptor.getValue(), DatabaseDiskSpaceFullChecker.class); } @Test public void shouldCheckIfScheduleCheckersCalledOnScheduleStage() throws Exception { schedulingChecker.canScheduleStage(new PipelineIdentifier("name",1),"stage","user",operationResult ); verify(schedulingChecker).buildScheduleCheckers(argumentCaptor.capture()); verify(compositeChecker).check(operationResult); assertFor(argumentCaptor.getValue(), StageAuthorizationChecker.class); assertFor(argumentCaptor.getValue(), StageLockChecker.class); assertFor(argumentCaptor.getValue(), PipelinePauseChecker.class); assertFor(argumentCaptor.getValue(), PipelineActiveChecker.class); assertFor(argumentCaptor.getValue(), StageActiveChecker.class); assertFor(argumentCaptor.getValue(), ArtifactsDiskSpaceFullChecker.class); assertFor(argumentCaptor.getValue(), DatabaseDiskSpaceFullChecker.class); } @Test public void shouldCheckIfScheduleCheckersCalledOnSchedule() throws Exception { schedulingChecker.canSchedule(operationResult ); verify(schedulingChecker).buildScheduleCheckers(argumentCaptor.capture()); verify(compositeChecker).check(operationResult); assertFor(argumentCaptor.getValue(), ArtifactsDiskSpaceFullChecker.class); assertFor(argumentCaptor.getValue(), DatabaseDiskSpaceFullChecker.class); } @Test public void shouldCheckIfScheduleCheckersCalledOnCanTriggerPipelineWithTimer() throws Exception { schedulingChecker.canTriggerPipelineWithTimer(PipelineConfigMother.pipelineConfig("sample"), operationResult); verify(schedulingChecker).buildScheduleCheckers(argumentCaptor.capture()); verify(compositeChecker).check(operationResult); assertFor(argumentCaptor.getValue(), AboutToBeTriggeredChecker.class); assertFor(argumentCaptor.getValue(), PipelinePauseChecker.class); assertFor(argumentCaptor.getValue(), StageActiveChecker.class); assertFor(argumentCaptor.getValue(), PipelineLockChecker.class); assertFor(argumentCaptor.getValue(), ArtifactsDiskSpaceFullChecker.class); assertFor(argumentCaptor.getValue(), DatabaseDiskSpaceFullChecker.class); } @Test public void shouldCheckIfScheduleCheckersCalledOnTriggerManualPipeline() throws Exception { schedulingChecker.canTriggerManualPipeline(PipelineConfigMother.pipelineConfig("sample"), "user", operationResult); verify(schedulingChecker).buildScheduleCheckers(argumentCaptor.capture()); verify(compositeChecker).check(operationResult); assertFor(argumentCaptor.getValue(), AboutToBeTriggeredChecker.class); assertFor(argumentCaptor.getValue(), PipelinePauseChecker.class); assertFor(argumentCaptor.getValue(), StageActiveChecker.class); assertFor(argumentCaptor.getValue(), PipelineLockChecker.class); assertFor(argumentCaptor.getValue(), ArtifactsDiskSpaceFullChecker.class); assertFor(argumentCaptor.getValue(), DatabaseDiskSpaceFullChecker.class); } @Test public void shouldCheckIfScheduleCheckersCalledOnAutoTriggerProducer() throws Exception { schedulingChecker.canAutoTriggerProducer(PipelineConfigMother.pipelineConfig("sample"), operationResult); verify(schedulingChecker).buildScheduleCheckers(argumentCaptor.capture()); verify(compositeChecker).check(operationResult); assertFor(argumentCaptor.getValue(), PipelineLockChecker.class); assertFor(argumentCaptor.getValue(), ManualPipelineChecker.class); assertFor(argumentCaptor.getValue(), PipelinePauseChecker.class); assertFor(argumentCaptor.getValue(), StageActiveChecker.class); } private void assertFailedBecauseOfUserLimitBeingExceeded(ServerHealthStateOperationResult result) { assertThat(result.getServerHealthState().isSuccess(), is(false)); assertThat(result.getServerHealthState().getMessage(), is("License Violation")); assertThat(result.getServerHealthState().getDescription(), startsWith("Current Go licence allows only 2 users. There are currently 3 users enabled.")); } private void assertFailedBecauseOfEmptyLicense(ServerHealthStateOperationResult result) { assertThat(result.getServerHealthState().isSuccess(), is(false)); assertThat(result.getServerHealthState().getMessage(), is("License Violation")); assertThat(result.getServerHealthState().getDescription(), is("There is no license configured. Scheduling will resume once a valid license is used.")); } private void assertFailedBecauseOfInvalidLicense(ServerHealthStateOperationResult result) { assertThat(result.getServerHealthState().isSuccess(), is(false)); assertThat(result.getServerHealthState().getMessage(), is("Failed to schedule the pipeline because Go does not have a valid license.")); assertThat(result.getServerHealthState().getDescription(), is("Failed to schedule the pipeline because Go does not have a valid license.")); } private void assertFailedBecauseOfExpiredLicense(ServerHealthStateOperationResult result) { assertThat(result.getServerHealthState().isSuccess(), is(false)); assertThat(result.getServerHealthState().getMessage(), is("Failed to schedule the pipeline because your license has expired.")); assertThat(result.getServerHealthState().getDescription(), is("The server is running with an expired License. Please fix this to resume pipeline scheduling.")); } private void assertFor(List<SchedulingChecker> checkerList, Class typeOfScheduleChecker) { ArrayList containerForAllCheckers = new ArrayList(); flatten(checkerList, containerForAllCheckers); for (Object o : containerForAllCheckers) { if (o.getClass().equals(typeOfScheduleChecker)) { return; } } fail("could not find " + typeOfScheduleChecker); } private void flatten(List<SchedulingChecker> value, ArrayList containerForAllCheckers) { for (SchedulingChecker checker : value) { if (checker instanceof CompositeChecker) { List<SchedulingChecker> schedulingCheckers = Arrays.asList(((CompositeChecker) checker).getCheckers()); flatten(schedulingCheckers, containerForAllCheckers); } else { containerForAllCheckers.add(checker); } } } }