package com.hubspot.blazar.data.util;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.hubspot.blazar.base.BuildOptions;
import com.hubspot.blazar.base.BuildTrigger;
import com.hubspot.blazar.base.GitInfo;
import com.hubspot.blazar.base.MalformedFile;
import com.hubspot.blazar.base.Module;
import com.hubspot.blazar.base.ModuleBuild;
import com.hubspot.blazar.base.ModuleBuildInfo;
import com.hubspot.blazar.base.ModuleState;
import com.hubspot.blazar.base.RepositoryBuild;
import com.hubspot.blazar.base.branch.BranchStatus;
import com.hubspot.blazar.data.dao.BranchDao;
import com.hubspot.blazar.data.dao.MalformedFileDao;
import com.hubspot.blazar.data.dao.RepositoryBuildDao;
import com.hubspot.blazar.data.dao.StateDao;
import com.hubspot.blazar.data.service.BranchStatusService;
public class BranchStatusServiceTest {
private static final BuildTrigger manualTrigger = BuildTrigger.forUser("user");
private static final BuildOptions defaultOptions = BuildOptions.defaultOptions();
private static final GitInfo branch1 = new GitInfo(Optional.of(1), "git.example.com", "example", "example", 1337, "master", true, System.currentTimeMillis(), System.currentTimeMillis());
private static final GitInfo branch2 = new GitInfo(Optional.of(2), "git.example.com", "example", "example", 1337, "notMaster", true, System.currentTimeMillis(), System.currentTimeMillis());
private static final Module module1 = new Module(Optional.of(1), "module", "config", "/", "/*", true, System.currentTimeMillis(), System.currentTimeMillis(), Optional.absent());
private static final ModuleBuild module1Build1Succeded = ModuleBuild.newBuilder(1, 1, 1, ModuleBuild.State.SUCCEEDED).build();
private static final ModuleBuild module1Build2Skipped = ModuleBuild.newBuilder(2, 1, 2, ModuleBuild.State.SKIPPED).build();
private static final ModuleBuild module1Build3Failed = ModuleBuild.newBuilder(3, 1, 3, ModuleBuild.State.FAILED).build();
private static final ModuleBuild module1Build4Queued = ModuleBuild.newBuilder(4, 1, 4, ModuleBuild.State.QUEUED).build();
private static final ModuleBuild module1Build4Launching = ModuleBuild.newBuilder(4, 1, 4, ModuleBuild.State.LAUNCHING).build();
// #5 does not exist repo build #5 is queued
private static final RepositoryBuild branch1Build1 = RepositoryBuild.newBuilder(1, 1, RepositoryBuild.State.SUCCEEDED, manualTrigger, defaultOptions).build();
private static final ModuleBuildInfo module1Build1Info = new ModuleBuildInfo(module1Build1Succeded, branch1Build1);
private static final RepositoryBuild branch1Build2 = RepositoryBuild.newBuilder(1, 2, RepositoryBuild.State.SUCCEEDED, manualTrigger, defaultOptions).build();
private static final ModuleBuildInfo module1Build2Info = new ModuleBuildInfo(module1Build2Skipped, branch1Build2);
private static final RepositoryBuild branch1Build3 = RepositoryBuild.newBuilder(1, 3, RepositoryBuild.State.FAILED, manualTrigger, defaultOptions).build();
private static final ModuleBuildInfo module1Build3Info = new ModuleBuildInfo(module1Build3Failed, branch1Build3);
private static final RepositoryBuild branch1Build4 = RepositoryBuild.newBuilder(1, 4, RepositoryBuild.State.LAUNCHING, manualTrigger, defaultOptions).build();
private static final ModuleBuildInfo module1Build4Info = new ModuleBuildInfo(module1Build4Launching, branch1Build4);
private static final RepositoryBuild branch1Build5 = RepositoryBuild.newBuilder(1, 5, RepositoryBuild.State.QUEUED, manualTrigger, defaultOptions).build();
private static final RepositoryBuild branch1Build6 = RepositoryBuild.newBuilder(1, 6, RepositoryBuild.State.QUEUED, manualTrigger, defaultOptions).build();
private static final BranchDao branchDao = mock(BranchDao.class);
private static final StateDao stateDao = mock(StateDao.class);
private static final RepositoryBuildDao branchBuildDao = mock(RepositoryBuildDao.class);
private static final MalformedFileDao malformedFileDao = mock(MalformedFileDao.class);
private static final BranchStatusService branchStatusService = new BranchStatusService(branchDao, stateDao, malformedFileDao, branchBuildDao);
private static final Set<MalformedFile> malformedFiles = ImmutableSet.of(new MalformedFile(1, "config", "/broken/.blazar.yaml", "Testing 123"));
@Before
public void before() {
when(branchDao.get(eq(1))).thenReturn(Optional.of(branch1));
when(branchDao.getByRepository(eq(1337))).thenReturn(Sets.newHashSet(branch1, branch2));
when(stateDao.getLastSuccessfulAndNonSkippedModuleBuilds(eq(1)))
.thenReturn(ImmutableSet.of(module1Build1Info, module1Build3Info));
when(branchBuildDao.getRepositoryBuildsByState(eq(1), eq(ImmutableList.of(RepositoryBuild.State.QUEUED))))
.thenReturn(ImmutableSet.of(branch1Build5, branch1Build6));
when(branchBuildDao.getRepositoryBuildsByState(eq(1), eq(ImmutableList.of(RepositoryBuild.State.LAUNCHING, RepositoryBuild.State.IN_PROGRESS))))
.thenReturn(ImmutableSet.of(branch1Build4));
when(malformedFileDao.getMalformedFiles(eq(1)))
.thenReturn(malformedFiles);
}
@Test
public void itReturnsTheExpectedBranchStatusWhenAModuleBuildIsPendingAndBranchBuildsAreQueued() {
when(stateDao.getLastAndInProgressAndPendingBuildsForBranchAndIncludedModules(eq(1)))
.thenReturn(ImmutableSet.of(ModuleState.newBuilder(module1)
.setLastBranchBuild(Optional.of(branch1Build3))
.setLastModuleBuild(Optional.of(module1Build3Failed))
.setPendingBranchBuild(Optional.of(branch1Build4))
.setPendingModuleBuild(Optional.of(module1Build4Queued))
.build()));
ModuleState expectedState = ModuleState.newBuilder(module1)
.setLastBranchBuild(Optional.of(branch1Build3))
.setLastModuleBuild(Optional.of(module1Build3Failed))
.setLastSuccessfulModuleBuild(Optional.of(module1Build1Succeded))
.setLastSuccessfulBranchBuild(Optional.of(branch1Build1))
.setLastNonSkippedModuleBuild(Optional.of(module1Build3Failed))
.setLastNonSkippedBranchBuild(Optional.of(branch1Build3))
.setPendingBranchBuild(Optional.of(branch1Build4))
.setPendingModuleBuild(Optional.of(module1Build4Queued))
.build();
Optional<BranchStatus> status = branchStatusService.getBranchStatusById(1);
assertThat(status.isPresent()).isTrue();
assertThat(status.get().getQueuedBuilds()).isEqualTo(ImmutableList.of(branch1Build5, branch1Build6));
assertThat(status.get().getOtherBranches()).doesNotContain(branch1).contains(branch2);
assertThat(status.get().getModuleStates()).isEqualTo(ImmutableSet.of(expectedState));
assertThat(status.get().getActiveBuild()).isEqualTo(Optional.of(branch1Build4));
assertThat(status.get().getMalformedFiles()).isEqualTo(malformedFiles);
}
@Test
public void itReturnsTheExpectedBranchStatusWhenAModuleBuildIsLaunchingAndBranchBuildsAreQueued() {
when(stateDao.getLastAndInProgressAndPendingBuildsForBranchAndIncludedModules(eq(1)))
.thenReturn(ImmutableSet.of(ModuleState.newBuilder(module1)
.setLastBranchBuild(Optional.of(branch1Build3))
.setLastModuleBuild(Optional.of(module1Build3Failed))
.setInProgressBranchBuild(Optional.of(branch1Build4))
.setInProgressModuleBuild(Optional.of(module1Build4Launching))
.build()));
ModuleState expectedState = ModuleState.newBuilder(module1)
.setLastBranchBuild(Optional.of(branch1Build3))
.setLastModuleBuild(Optional.of(module1Build3Failed))
.setLastSuccessfulModuleBuild(Optional.of(module1Build1Succeded))
.setLastSuccessfulBranchBuild(Optional.of(branch1Build1))
.setLastNonSkippedModuleBuild(Optional.of(module1Build3Failed))
.setLastNonSkippedBranchBuild(Optional.of(branch1Build3))
.setInProgressBranchBuild(Optional.of(branch1Build4))
.setInProgressModuleBuild(Optional.of(module1Build4Launching))
.build();
Optional<BranchStatus> status = branchStatusService.getBranchStatusById(1);
assertThat(status.isPresent()).isTrue();
assertThat(status.get().getQueuedBuilds()).isEqualTo(ImmutableList.of(branch1Build5, branch1Build6));
assertThat(status.get().getOtherBranches()).doesNotContain(branch1).contains(branch2);
assertThat(status.get().getModuleStates()).isEqualTo(ImmutableSet.of(expectedState));
assertThat(status.get().getActiveBuild()).isEqualTo(Optional.of(branch1Build4));
assertThat(status.get().getMalformedFiles()).isEqualTo(malformedFiles);
}
@Test
public void itReturnsAbsentForMissingBranch() {
// there is no branch 2
when(branchDao.get(eq(2))).thenReturn(Optional.absent());
Optional<BranchStatus> status = branchStatusService.getBranchStatusById(2);
assertThat(status.isPresent()).isFalse();
}
}