package com.hubspot.singularity.scheduler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.WebApplicationException;
import org.apache.mesos.Protos.TaskState;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.base.Optional;
import com.hubspot.baragon.models.BaragonRequestState;
import com.hubspot.mesos.Resources;
import com.hubspot.singularity.DeployState;
import com.hubspot.singularity.LoadBalancerRequestType;
import com.hubspot.singularity.RequestState;
import com.hubspot.singularity.SingularityDeploy;
import com.hubspot.singularity.SingularityDeployBuilder;
import com.hubspot.singularity.SingularityDeployProgress;
import com.hubspot.singularity.SingularityPendingDeploy;
import com.hubspot.singularity.SingularityPendingRequest.PendingType;
import com.hubspot.singularity.SingularityPendingTask;
import com.hubspot.singularity.SingularityPendingTaskId;
import com.hubspot.singularity.SingularityRequest;
import com.hubspot.singularity.SingularityTask;
import com.hubspot.singularity.SingularityTaskId;
import com.hubspot.singularity.SingularityUpdatePendingDeployRequest;
import com.hubspot.singularity.TaskCleanupType;
import com.hubspot.singularity.api.SingularityDeployRequest;
public class SingularityDeploysTest extends SingularitySchedulerTestBase {
public SingularityDeploysTest() {
super(false);
}
@Test
public void testDeployManagerHandlesFailedLBTask() {
initLoadBalancedRequest();
initFirstDeploy();
SingularityTask firstTask = startTask(firstDeploy);
initSecondDeploy();
SingularityTask secondTask = startTask(secondDeploy);
// this should cause an LB call to happen:
deployChecker.checkDeploys();
Assert.assertTrue(taskManager.getLoadBalancerState(secondTask.getTaskId(), LoadBalancerRequestType.ADD).isPresent());
Assert.assertTrue(!taskManager.getLoadBalancerState(secondTask.getTaskId(), LoadBalancerRequestType.DEPLOY).isPresent());
Assert.assertTrue(!taskManager.getLoadBalancerState(secondTask.getTaskId(), LoadBalancerRequestType.REMOVE).isPresent());
statusUpdate(secondTask, TaskState.TASK_FAILED);
statusUpdate(firstTask, TaskState.TASK_FAILED);
deployChecker.checkDeploys();
Assert.assertTrue(deployManager.getDeployResult(requestId, secondDeployId).get().getDeployState() == DeployState.FAILED);
List<SingularityPendingTask> pendingTasks = taskManager.getPendingTasks();
Assert.assertTrue(pendingTasks.size() == 1);
Assert.assertTrue(pendingTasks.get(0).getPendingTaskId().getDeployId().equals(firstDeployId));
}
@Test
public void testDeployClearsObsoleteScheduledTasks() {
initRequest();
initFirstDeploy();
initSecondDeploy();
SingularityPendingTaskId taskIdOne = new SingularityPendingTaskId(requestId, firstDeployId, System.currentTimeMillis() + TimeUnit.DAYS.toMillis(3), 1, PendingType.IMMEDIATE, System.currentTimeMillis());
SingularityPendingTask taskOne = new SingularityPendingTask(taskIdOne, Optional.<List<String>> absent(), Optional.<String> absent(), Optional.<String> absent(), Optional.<Boolean> absent(), Optional.<String> absent(), Optional.<Resources>absent(), Optional.<String>absent());
SingularityPendingTaskId taskIdTwo = new SingularityPendingTaskId(requestId, firstDeployId, System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1), 2, PendingType.IMMEDIATE, System.currentTimeMillis());
SingularityPendingTask taskTwo = new SingularityPendingTask(taskIdTwo, Optional.<List<String>> absent(), Optional.<String> absent(), Optional.<String> absent(), Optional.<Boolean> absent(), Optional.<String> absent(), Optional.<Resources>absent(), Optional.<String>absent());
SingularityPendingTaskId taskIdThree = new SingularityPendingTaskId(requestId, secondDeployId, System.currentTimeMillis() + TimeUnit.DAYS.toMillis(3), 1, PendingType.IMMEDIATE, System.currentTimeMillis());
SingularityPendingTask taskThree = new SingularityPendingTask(taskIdThree, Optional.<List<String>> absent(), Optional.<String> absent(), Optional.<String> absent(), Optional.<Boolean> absent(), Optional.<String> absent(), Optional.<Resources>absent(), Optional.<String>absent());
SingularityPendingTaskId taskIdFour = new SingularityPendingTaskId(requestId + "hi", firstDeployId, System.currentTimeMillis() + TimeUnit.DAYS.toMillis(3), 5, PendingType.IMMEDIATE, System.currentTimeMillis());
SingularityPendingTask taskFour = new SingularityPendingTask(taskIdFour,Optional.<List<String>> absent(), Optional.<String> absent(), Optional.<String> absent(), Optional.<Boolean> absent(), Optional.<String> absent(), Optional.<Resources>absent(), Optional.<String>absent());
taskManager.savePendingTask(taskOne);
taskManager.savePendingTask(taskTwo);
taskManager.savePendingTask(taskThree);
taskManager.savePendingTask(taskFour);
launchTask(request, secondDeploy, 1, TaskState.TASK_RUNNING);
deployChecker.checkDeploys();
List<SingularityPendingTaskId> pendingTaskIds = taskManager.getPendingTaskIds();
Assert.assertTrue(!pendingTaskIds.contains(taskIdOne));
Assert.assertTrue(!pendingTaskIds.contains(taskIdTwo));
Assert.assertTrue(pendingTaskIds.contains(taskIdThree));
Assert.assertTrue(pendingTaskIds.contains(taskIdFour));
}
@Test
public void testDeployAllInstancesAtOnce() {
initRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
requestResource.postRequest(request.toBuilder().setInstances(Optional.of(2)).build());
initFirstDeploy();
launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
launchTask(request, firstDeploy, 2, TaskState.TASK_RUNNING);
deploy(secondDeployId);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(2, taskManager.getActiveTaskIds().size());
Assert.assertEquals(2, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(2, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
for (SingularityTaskId taskId : taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId)) {
statusUpdate(taskManager.getTask(taskId).get(), TaskState.TASK_RUNNING);
}
deployChecker.checkDeploys();
Assert.assertEquals(2, taskManager.getCleanupTaskIds().size());
Assert.assertEquals(DeployState.SUCCEEDED, deployManager.getDeployResult(requestId, secondDeployId).get().getDeployState());
Assert.assertEquals(2, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
}
@Test
public void testDeployOneInstanceAtATime() {
initRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
requestResource.postRequest(request.toBuilder().setInstances(Optional.of(2)).build());
initFirstDeploy();
SingularityTask firstTask = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
SingularityTask secondTask = launchTask(request, firstDeploy, 2, TaskState.TASK_RUNNING);
deploy(secondDeployId, Optional.<Boolean> absent(), Optional.of(1), Optional.<Boolean> absent(), false);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(1, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(1, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
SingularityTaskId firstNewTaskId = taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).get(0);
statusUpdate(taskManager.getTask(firstNewTaskId).get(), TaskState.TASK_RUNNING);
deployChecker.checkDeploys();
Assert.assertEquals(1, taskManager.getCleanupTaskIds().size());
Assert.assertTrue(taskManager.getCleanupTaskIds().contains(firstTask.getTaskId()));
SingularityDeployProgress deployProgressStepOne = deployManager.getPendingDeploys().get(0).getDeployProgress().get();
Assert.assertTrue(deployProgressStepOne.isStepComplete());
Assert.assertEquals(1, deployProgressStepOne.getTargetActiveInstances());
cleaner.drainCleanupQueue();
statusUpdate(firstTask, TaskState.TASK_KILLED);
deployChecker.checkDeploys();
SingularityDeployProgress deployProgressStepTwo = deployManager.getPendingDeploys().get(0).getDeployProgress().get();
Assert.assertFalse(deployProgressStepTwo.isStepComplete());
Assert.assertEquals(2, deployProgressStepTwo.getTargetActiveInstances());
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(1, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(2, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
for (SingularityTaskId taskId : taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId)) {
statusUpdate(taskManager.getTask(taskId).get(), TaskState.TASK_RUNNING);
}
deployChecker.checkDeploys();
Assert.assertEquals(2, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
Assert.assertEquals(DeployState.SUCCEEDED, deployManager.getDeployResult(requestId, secondDeployId).get().getDeployState());
}
@Test
public void testIncrementalDeployCancel() {
initRequest();
// Set up incremental deploy that is partly finished
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
requestResource.postRequest(request.toBuilder().setInstances(Optional.of(2)).build());
initFirstDeploy();
SingularityTask firstTask = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
launchTask(request, firstDeploy, 2, TaskState.TASK_RUNNING);
deploy(secondDeployId, Optional.<Boolean> absent(), Optional.of(1), Optional.<Boolean> absent(), false);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
resourceOffers();
SingularityTaskId firstNewTaskId = taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).get(0);
statusUpdate(taskManager.getTask(firstNewTaskId).get(), TaskState.TASK_RUNNING);
deployChecker.checkDeploys();
cleaner.drainCleanupQueue();
statusUpdate(firstTask, TaskState.TASK_KILLED);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
resourceOffers();
// End in-progress incremental deploy setup
deployResource.cancelDeploy(requestId, secondDeployId);
deployChecker.checkDeploys();
Assert.assertEquals(taskManager.getCleanupTasks().get(0).getCleanupType(), TaskCleanupType.INCREMENTAL_DEPLOY_CANCELLED);
// Incremental deploy task should not be shut down while active deploy is below target instances
cleaner.drainCleanupQueue();
Assert.assertTrue(taskManager.getKilledTaskIdRecords().isEmpty());
Assert.assertEquals(taskManager.getCleanupTasks().get(0).getCleanupType(), TaskCleanupType.INCREMENTAL_DEPLOY_CANCELLED);
launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
cleaner.drainCleanupQueue();
Assert.assertFalse(taskManager.getKilledTaskIdRecords().isEmpty());
}
@Test
public void testScaleDownDuringDeploy() {
initRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
requestResource.postRequest(request.toBuilder().setInstances(Optional.of(2)).build());
initFirstDeploy();
launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
launchTask(request, firstDeploy, 2, TaskState.TASK_RUNNING);
deploy(secondDeployId);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
resourceOffers();
Assert.assertEquals(2, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
for (SingularityTaskId taskId : taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId)) {
statusUpdate(taskManager.getTask(taskId).get(), TaskState.TASK_RUNNING);
}
requestResource.postRequest(request.toBuilder().setInstances(Optional.of(1)).build());
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(1, taskManager.getCleanupTaskIds().size());
deployChecker.checkDeploys();
Assert.assertEquals(2, taskManager.getCleanupTaskIds().size());
// Extra task from the new deploy should get cleaned up as well
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(3, taskManager.getCleanupTaskIds().size());
}
@Test
public void testDeployWithManualStep() {
initRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
requestResource.postRequest(request.toBuilder().setInstances(Optional.of(2)).build());
initFirstDeploy();
SingularityTask firstTask = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
SingularityTask secondTask = launchTask(request, firstDeploy, 2, TaskState.TASK_RUNNING);
deploy(secondDeployId, Optional.<Boolean>absent(), Optional.of(1), Optional.of(false), false);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(1, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(1, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
SingularityTaskId firstNewTaskId = taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).get(0);
statusUpdate(taskManager.getTask(firstNewTaskId).get(), TaskState.TASK_RUNNING);
deployChecker.checkDeploys();
Assert.assertEquals(1, taskManager.getCleanupTaskIds().size());
Assert.assertTrue(taskManager.getCleanupTaskIds().contains(firstTask.getTaskId()));
SingularityDeployProgress deployProgressStepOne = deployManager.getPendingDeploys().get(0).getDeployProgress().get();
Assert.assertTrue(deployProgressStepOne.isStepComplete());
Assert.assertEquals(1, deployProgressStepOne.getTargetActiveInstances());
cleaner.drainCleanupQueue();
statusUpdate(firstTask, TaskState.TASK_KILLED);
deployChecker.checkDeploys();
// Deploy should not have moved to next step even though instances are launched
deployProgressStepOne = deployManager.getPendingDeploys().get(0).getDeployProgress().get();
Assert.assertTrue(deployProgressStepOne.isStepComplete());
Assert.assertEquals(1, deployProgressStepOne.getTargetActiveInstances());
// Add the 'ok' to move to the next step
deployResource.updatePendingDeploy(new SingularityUpdatePendingDeployRequest(requestId, secondDeployId, 2));
deployChecker.checkDeploys();
SingularityDeployProgress deployProgressStepTwo = deployManager.getPendingDeploys().get(0).getDeployProgress().get();
Assert.assertFalse(deployProgressStepTwo.isStepComplete());
Assert.assertEquals(2, deployProgressStepTwo.getTargetActiveInstances());
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(1, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(2, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
for (SingularityTaskId taskId : taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId)) {
statusUpdate(taskManager.getTask(taskId).get(), TaskState.TASK_RUNNING);
}
deployChecker.checkDeploys();
Assert.assertEquals(2, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
Assert.assertEquals(DeployState.SUCCEEDED, deployManager.getDeployResult(requestId, secondDeployId).get().getDeployState());
}
@Test
public void testDeployMultipleInstancesAtOnce() {
initRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
requestResource.postRequest(request.toBuilder().setInstances(Optional.of(4)).build());
initFirstDeploy();
SingularityTask firstTask = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
SingularityTask secondTask = launchTask(request, firstDeploy, 2, TaskState.TASK_RUNNING);
SingularityTask thirdTask = launchTask(request, firstDeploy, 3, TaskState.TASK_RUNNING);
SingularityTask fourthTask = launchTask(request, firstDeploy, 4, TaskState.TASK_RUNNING);
deploy(secondDeployId, Optional.<Boolean>absent(), Optional.of(2), Optional.<Boolean> absent(), false);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(2, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(2, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
for (SingularityTaskId taskId : taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId)) {
statusUpdate(taskManager.getTask(taskId).get(), TaskState.TASK_RUNNING);
}
deployChecker.checkDeploys();
Assert.assertEquals(2, taskManager.getCleanupTaskIds().size());
List<SingularityTaskId> cleanupTaskIds = taskManager.getCleanupTaskIds();
Assert.assertTrue(cleanupTaskIds.contains(firstTask.getTaskId()) && cleanupTaskIds.contains(secondTask.getTaskId()));
SingularityDeployProgress deployProgressStepOne = deployManager.getPendingDeploys().get(0).getDeployProgress().get();
Assert.assertTrue(deployProgressStepOne.isStepComplete());
Assert.assertEquals(2, deployProgressStepOne.getTargetActiveInstances());
cleaner.drainCleanupQueue();
statusUpdate(firstTask, TaskState.TASK_KILLED);
statusUpdate(secondTask, TaskState.TASK_KILLED);
deployChecker.checkDeploys();
SingularityDeployProgress deployProgressStepTwo = deployManager.getPendingDeploys().get(0).getDeployProgress().get();
Assert.assertFalse(deployProgressStepTwo.isStepComplete());
Assert.assertEquals(4, deployProgressStepTwo.getTargetActiveInstances());
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(2, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(4, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
for (SingularityTaskId taskId : taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId)) {
statusUpdate(taskManager.getTask(taskId).get(), TaskState.TASK_RUNNING);
}
deployChecker.checkDeploys();
Assert.assertEquals(4, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
Assert.assertEquals(DeployState.SUCCEEDED, deployManager.getDeployResult(requestId, secondDeployId).get().getDeployState());
}
@Test
public void testCancelDeploy() {
initRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
initFirstDeploy();
SingularityTask firstTask = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
deploy(secondDeployId, Optional.<Boolean>absent(), Optional.of(1), Optional.of(false), false);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(1, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(1, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
SingularityTaskId firstNewTaskId = taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).get(0);
statusUpdate(taskManager.getTask(firstNewTaskId).get(), TaskState.TASK_RUNNING);
deployResource.cancelDeploy(requestId, secondDeployId);
deployChecker.checkDeploys();
Assert.assertTrue(taskManager.getCleanupTaskIds().contains(firstNewTaskId));
Assert.assertFalse(taskManager.getCleanupTaskIds().contains(firstTask.getTaskId()));
Assert.assertEquals(DeployState.CANCELED, deployManager.getDeployResult(requestId, secondDeployId).get().getDeployState());
}
@Test
public void testDeployFails() {
initRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
initFirstDeploy();
SingularityTask firstTask = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
deploy(secondDeployId, Optional.<Boolean>absent(), Optional.of(1), Optional.of(false), false);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(1, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(1, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
SingularityTaskId firstNewTaskId = taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).get(0);
statusUpdate(taskManager.getTask(firstNewTaskId).get(), TaskState.TASK_FAILED);
deployChecker.checkDeploys();
Assert.assertFalse(taskManager.getCleanupTaskIds().contains(firstTask.getTaskId()));
Assert.assertEquals(DeployState.FAILED, deployManager.getDeployResult(requestId, secondDeployId).get().getDeployState());
}
@Test
public void testDeployFailsForInvalidRequestState() {
initRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
initFirstDeploy();
deploy(secondDeployId, Optional.<Boolean>absent(), Optional.of(1), Optional.of(false), false);
requestManager.pause(request, System.currentTimeMillis(), Optional.<String>absent(), Optional.<String>absent());
deployChecker.checkDeploys();
Assert.assertEquals(DeployState.FAILED, deployManager.getDeployResult(requestId, secondDeployId).get().getDeployState());
}
@Test
public void testDeployFailsAfterMaxTaskRetries() {
initRequest();
SingularityDeployBuilder db = new SingularityDeployBuilder(requestId, firstDeployId);
db.setMaxTaskRetries(Optional.of(1));
SingularityDeploy deploy = initDeploy(db, System.currentTimeMillis());
deployChecker.checkDeploys();
Assert.assertTrue(!deployManager.getDeployResult(requestId, firstDeployId).isPresent());
SingularityTask task = launchTask(request, deploy, System.currentTimeMillis(), 1, TaskState.TASK_FAILED);
deployChecker.checkDeploys();
Assert.assertEquals(deployManager.getPendingDeploys().get(0).getCurrentDeployState(), DeployState.WAITING);
SingularityTask taskTryTwo = launchTask(request, deploy, System.currentTimeMillis(), 1, TaskState.TASK_FAILED);
deployChecker.checkDeploys();
Assert.assertEquals(deployManager.getDeployResult(requestId, firstDeployId).get().getDeployState(), DeployState.FAILED);
}
@Test
public void testDeploySucceedsWithTaskRetries() {
initRequest();
SingularityDeployBuilder db = new SingularityDeployBuilder(requestId, firstDeployId);
db.setMaxTaskRetries(Optional.of(1));
SingularityDeploy deploy = initDeploy(db, System.currentTimeMillis());
deployChecker.checkDeploys();
Assert.assertTrue(!deployManager.getDeployResult(requestId, firstDeployId).isPresent());
SingularityTask task = launchTask(request, deploy, System.currentTimeMillis(), 1, TaskState.TASK_FAILED);
deployChecker.checkDeploys();
Assert.assertEquals(deployManager.getPendingDeploys().get(0).getCurrentDeployState(), DeployState.WAITING);
SingularityTask taskTryTwo = launchTask(request, deploy, System.currentTimeMillis(), 1, TaskState.TASK_RUNNING);
deployChecker.checkDeploys();
Assert.assertEquals(deployManager.getDeployResult(requestId, firstDeployId).get().getDeployState(), DeployState.SUCCEEDED);
}
@Test
public void testLbUpdatesAfterEachDeployStep() {
initLoadBalancedRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
requestResource.postRequest(request.toBuilder().setInstances(Optional.of(2)).build());
initFirstDeploy();
SingularityTask firstTask = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
SingularityTask secondTask = launchTask(request, firstDeploy, 2, TaskState.TASK_RUNNING);
deploy(secondDeployId, Optional.<Boolean>absent(), Optional.of(1), Optional.<Boolean> absent(), true);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(1, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(1, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
SingularityTaskId firstNewTaskId = taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).get(0);
statusUpdate(taskManager.getTask(firstNewTaskId).get(), TaskState.TASK_RUNNING);
deployChecker.checkDeploys();
SingularityPendingDeploy pendingDeploy = deployManager.getPendingDeploy(requestId).get();
Assert.assertEquals(DeployState.WAITING, pendingDeploy.getCurrentDeployState());
testingLbClient.setNextBaragonRequestState(BaragonRequestState.WAITING);
deployChecker.checkDeploys();
pendingDeploy = deployManager.getPendingDeploy(requestId).get();
Assert.assertEquals(DeployState.WAITING, pendingDeploy.getCurrentDeployState());
testingLbClient.setNextBaragonRequestState(BaragonRequestState.SUCCESS);
deployChecker.checkDeploys();
Assert.assertTrue(taskManager.getCleanupTaskIds().contains(firstTask.getTaskId()));
pendingDeploy = deployManager.getPendingDeploy(requestId).get();
SingularityDeployProgress deployProgressStepOne = pendingDeploy.getDeployProgress().get();
Assert.assertTrue(deployProgressStepOne.isStepComplete());
Assert.assertEquals(1, deployProgressStepOne.getTargetActiveInstances());
cleaner.drainCleanupQueue();
statusUpdate(firstTask, TaskState.TASK_KILLED);
deployChecker.checkDeploys();
pendingDeploy = deployManager.getPendingDeploy(requestId).get();
Assert.assertFalse(pendingDeploy.getDeployProgress().get().isStepComplete());
Assert.assertEquals(2, pendingDeploy.getDeployProgress().get().getTargetActiveInstances());
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(1, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(2, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
SingularityTaskId secondNewTaskId = null;
for (SingularityTaskId taskId : taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId)) {
if (taskId.getInstanceNo() == 2) {
secondNewTaskId = taskId;
}
}
statusUpdate(taskManager.getTask(secondNewTaskId).get(), TaskState.TASK_RUNNING);
testingLbClient.setNextBaragonRequestState(BaragonRequestState.WAITING);
deployChecker.checkDeploys();
pendingDeploy = deployManager.getPendingDeploy(requestId).get();
Assert.assertEquals(DeployState.WAITING, pendingDeploy.getCurrentDeployState());
testingLbClient.setNextBaragonRequestState(BaragonRequestState.SUCCESS);
deployChecker.checkDeploys();
Assert.assertEquals(2, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
Assert.assertEquals(DeployState.SUCCEEDED, deployManager.getDeployResult(requestId, secondDeployId).get().getDeployState());
}
@Test
public void testCanceledDeployTasksStayActiveUntilReplaced() {
initRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
requestResource.postRequest(request.toBuilder().setInstances(Optional.of(2)).build());
initFirstDeploy();
SingularityTask firstTask = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
SingularityTask secondTask = launchTask(request, firstDeploy, 2, TaskState.TASK_RUNNING);
deploy(secondDeployId, Optional.<Boolean> absent(), Optional.of(1), Optional.<Boolean> absent(), false);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(1, taskManager.getPendingTaskIds().size());
resourceOffers();
Assert.assertEquals(1, taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).size());
SingularityTaskId firstNewTaskId = taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).get(0);
statusUpdate(taskManager.getTask(firstNewTaskId).get(), TaskState.TASK_RUNNING);
deployChecker.checkDeploys();
Assert.assertEquals(1, taskManager.getCleanupTaskIds().size());
Assert.assertTrue(taskManager.getCleanupTaskIds().contains(firstTask.getTaskId()));
SingularityDeployProgress deployProgressStepOne = deployManager.getPendingDeploys().get(0).getDeployProgress().get();
Assert.assertTrue(deployProgressStepOne.isStepComplete());
Assert.assertEquals(1, deployProgressStepOne.getTargetActiveInstances());
cleaner.drainCleanupQueue();
statusUpdate(firstTask, TaskState.TASK_KILLED);
deployChecker.checkDeploys();
deployResource.cancelDeploy(requestId, secondDeployId);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
List<SingularityPendingTaskId> pendingTaskIds = taskManager.getPendingTaskIds();
Assert.assertEquals(1, pendingTaskIds.size());
Assert.assertEquals(firstDeployId, pendingTaskIds.get(0).getDeployId());
cleaner.drainCleanupQueue();
List<SingularityTaskId> cleanupTaskIds = taskManager.getCleanupTaskIds();
Assert.assertEquals(1, cleanupTaskIds.size());
Assert.assertEquals(secondDeployId, cleanupTaskIds.get(0).getDeployId());
resourceOffers();
for (SingularityTaskId taskId : taskManager.getActiveTaskIdsForDeploy(requestId, firstDeployId)) {
statusUpdate(taskManager.getTask(taskId).get(), TaskState.TASK_RUNNING);
}
cleaner.drainCleanupQueue();
Assert.assertEquals(0, taskManager.getCleanupTaskIds().size());
Assert.assertEquals(2, taskManager.getActiveTaskIdsForDeploy(requestId, firstDeployId).size());
}
@Test
public void testAfterDeployWaitsForScheduledTaskToFinish() {
initScheduledRequest();
initFirstDeploy();
SingularityTask firstTask = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
Assert.assertTrue(taskManager.getPendingTasks().isEmpty());
Assert.assertTrue(taskManager.getActiveTaskIds().contains(firstTask.getTaskId()));
Assert.assertEquals(1, taskManager.getActiveTaskIds().size());
Assert.assertTrue(taskManager.getCleanupTaskIds().isEmpty());
deploy("nextDeployId");
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
// no second task should be scheduled
Assert.assertTrue(taskManager.getPendingTasks().isEmpty());
Assert.assertTrue(taskManager.getActiveTaskIds().contains(firstTask.getTaskId()));
Assert.assertEquals(1, taskManager.getActiveTaskIds().size());
Assert.assertTrue(!taskManager.getCleanupTaskIds().isEmpty());
statusUpdate(firstTask, TaskState.TASK_FINISHED);
scheduler.drainPendingQueue(stateCacheProvider.get());
cleaner.drainCleanupQueue();
Assert.assertTrue(!taskManager.getPendingTasks().isEmpty());
Assert.assertTrue(taskManager.getActiveTaskIds().isEmpty());
Assert.assertTrue(taskManager.getCleanupTaskIds().isEmpty());
SingularityPendingTaskId pendingTaskId = taskManager.getPendingTaskIds().get(0);
Assert.assertEquals("nextDeployId", pendingTaskId.getDeployId());
Assert.assertEquals(requestId, pendingTaskId.getRequestId());
}
@Test
public void testScheduledJobLivesThroughDeploy() {
initScheduledRequest();
initFirstDeploy();
createAndSchedulePendingTask(firstDeployId);
Assert.assertTrue(!taskManager.getPendingTaskIds().isEmpty());
deploy("d2");
scheduler.drainPendingQueue(stateCacheProvider.get());
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertTrue(!taskManager.getPendingTaskIds().isEmpty());
}
@Test
public void testUnpauseOnDeploy() {
initRequest();
initFirstDeploy();
requestManager.pause(request, System.currentTimeMillis(), Optional.<String>absent(), Optional.<String>absent());
boolean exception = false;
try {
deploy("d2");
} catch (Exception e) {
exception = true;
}
Assert.assertTrue(exception);
deploy("d3", Optional.of(true));
Assert.assertTrue(requestManager.getRequest(requestId).get().getState() == RequestState.DEPLOYING_TO_UNPAUSE);
scheduler.drainPendingQueue(stateCacheProvider.get());
sms.resourceOffers(driver, Arrays.asList(createOffer(20, 20000, "slave1", "host1")));
statusUpdate(taskManager.getActiveTasks().get(0), TaskState.TASK_FAILED);
deployChecker.checkDeploys();
Assert.assertTrue(requestManager.getRequest(requestId).get().getState() == RequestState.PAUSED);
Assert.assertTrue(taskManager.getActiveTaskIds().isEmpty());
Assert.assertTrue(taskManager.getPendingTaskIds().isEmpty());
Assert.assertTrue(requestManager.getPendingRequests().isEmpty());
deploy("d4", Optional.of(true));
Assert.assertTrue(requestManager.getRequest(requestId).get().getState() == RequestState.DEPLOYING_TO_UNPAUSE);
scheduler.drainPendingQueue(stateCacheProvider.get());
sms.resourceOffers(driver, Arrays.asList(createOffer(20, 20000, "slave1", "host1")));
statusUpdate(taskManager.getActiveTasks().get(0), TaskState.TASK_RUNNING);
deployChecker.checkDeploys();
RequestState requestState = requestManager.getRequest(requestId).get().getState();
Assert.assertTrue(requestState == RequestState.ACTIVE);
}
@Test
public void testSkipDeployHealthchecks() {
initRequest();
final String deployId = "deploy_test";
SingularityDeployBuilder db = new SingularityDeployBuilder(requestId, deployId);
db.setHealthcheckUri(Optional.of("http://uri"));
db.setSkipHealthchecksOnDeploy(Optional.of(true));
SingularityDeploy deploy = initDeploy(db, System.currentTimeMillis());
deployChecker.checkDeploys();
Assert.assertTrue(!deployManager.getDeployResult(requestId, deployId).isPresent());
launchTask(request, deploy, System.currentTimeMillis(), 1, TaskState.TASK_RUNNING);
deployChecker.checkDeploys();
Assert.assertEquals(DeployState.SUCCEEDED, deployManager.getDeployResult(requestId, deployId).get().getDeployState());
}
@Test
public void testUsesNewRequestDataFromPendingDeploy() {
initRequest();
initFirstDeploy();
saveAndSchedule(request.toBuilder().setInstances(Optional.of(2)));
scheduler.drainPendingQueue(stateCacheProvider.get());
Assert.assertEquals(2, taskManager.getPendingTaskIds().size());
Assert.assertEquals(2, requestManager.getRequest(requestId).get().getRequest().getInstancesSafe());
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
SingularityRequest newRequest = request.toBuilder().setInstances(Optional.of(1)).build();
String deployId = "test_new_request_data";
SingularityDeploy deploy = new SingularityDeployBuilder(request.getId(), deployId).setCommand(Optional.of("sleep 100")).build();
deployResource.deploy(new SingularityDeployRequest(deploy, Optional.<Boolean>absent(), Optional.<String>absent(), Optional.of(newRequest)));
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
List<SingularityPendingTaskId> pendingTaskIdsForNewDeploy = new ArrayList<>();
for (SingularityPendingTaskId pendingTaskId : taskManager.getPendingTaskIds()) {
if (pendingTaskId.getDeployId().equals(deployId)) {
pendingTaskIdsForNewDeploy.add(pendingTaskId);
}
}
Assert.assertEquals(1, pendingTaskIdsForNewDeploy.size());
Assert.assertEquals(2, requestManager.getRequest(requestId).get().getRequest().getInstancesSafe());
resourceOffers();
for (SingularityTaskId taskId : taskManager.getActiveTaskIdsForDeploy(requestId, deployId)) {
statusUpdate(taskManager.getTask(taskId).get(), TaskState.TASK_RUNNING);
}
deployChecker.checkDeploys();
Assert.assertEquals(1, requestManager.getRequest(requestId).get().getRequest().getInstancesSafe());
}
@Test(expected = WebApplicationException.class)
public void testCannotUpdateRequestDuringPendingDeployWithNewData() {
initRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
SingularityRequest newRequest = request.toBuilder().setInstances(Optional.of(1)).build();
String deployId = "test_new_request_data";
SingularityDeploy deploy = new SingularityDeployBuilder(request.getId(), deployId).setCommand(Optional.of("sleep 100")).build();
deployResource.deploy(new SingularityDeployRequest(deploy, Optional.<Boolean>absent(), Optional.<String>absent(), Optional.of(newRequest)));
requestResource.postRequest(newRequest);
}
@Test
public void testDeployTimesOut() {
initRequest();
final long hourAgo = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1);
final String deployId = "timeout_test";
SingularityDeployBuilder db = new SingularityDeployBuilder(requestId, deployId);
db.setDeployHealthTimeoutSeconds(Optional.of(TimeUnit.MINUTES.toSeconds(1)));
initDeploy(db, hourAgo);
deployChecker.checkDeploys();
Assert.assertEquals(DeployState.OVERDUE, deployManager.getDeployResult(requestId, deployId).get().getDeployState());
}
@Test
public void testIncrementalDeployInstanceCounter() {
initRequest();
SingularityRequest request = requestResource.getRequest(requestId).getRequest();
requestResource.postRequest(request.toBuilder().setInstances(Optional.of(4)).build());
initFirstDeploy();
SingularityTask firstTask = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
SingularityTask secondTask = launchTask(request, firstDeploy, 2, TaskState.TASK_RUNNING);
SingularityTask thirdTask = launchTask(request, firstDeploy, 3, TaskState.TASK_RUNNING);
deploy(secondDeployId, Optional.<Boolean>absent(), Optional.of(1), Optional.<Boolean>absent(), false);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
resourceOffers();
SingularityTaskId firstNewTaskId = taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId).get(0);
statusUpdate(taskManager.getTask(firstNewTaskId).get(), TaskState.TASK_RUNNING);
deployChecker.checkDeploys();
SingularityDeployProgress deployProgress = deployManager.getPendingDeploy(requestId).get().getDeployProgress().get();
Assert.assertEquals(1, deployProgress.getTargetActiveInstances());
Assert.assertEquals(1, deployProgress.getCurrentActiveInstances());
cleaner.drainCleanupQueue();
statusUpdate(firstTask, TaskState.TASK_KILLED);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
resourceOffers();
for (SingularityTaskId taskId : taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId)) {
statusUpdate(taskManager.getTask(taskId).get(), TaskState.TASK_RUNNING);
}
deployChecker.checkDeploys();
deployProgress = deployManager.getPendingDeploy(requestId).get().getDeployProgress().get();
Assert.assertEquals(2, deployProgress.getTargetActiveInstances());
Assert.assertEquals(2, deployProgress.getCurrentActiveInstances());
cleaner.drainCleanupQueue();
statusUpdate(secondTask, TaskState.TASK_KILLED);
deployChecker.checkDeploys();
scheduler.drainPendingQueue(stateCacheProvider.get());
resourceOffers();
for (SingularityTaskId taskId : taskManager.getActiveTaskIdsForDeploy(requestId, secondDeployId)) {
statusUpdate(taskManager.getTask(taskId).get(), TaskState.TASK_RUNNING);
}
deployChecker.checkDeploys();
deployProgress = deployManager.getPendingDeploy(requestId).get().getDeployProgress().get();
Assert.assertEquals(3, deployProgress.getTargetActiveInstances());
Assert.assertEquals(3, deployProgress.getCurrentActiveInstances());
}
}