Search in sources :

Example 1 with DeploymentGroup

use of com.spotify.helios.common.descriptors.DeploymentGroup in project helios by spotify.

the class DeploymentGroupTest method testUpdateFailedManualDeploymentGroupHosts.

// A test that ensures deployment groups that failed during a manual rolling update will not
// perform a new rolling update if the hosts change.
@Test
public void testUpdateFailedManualDeploymentGroupHosts() throws Exception {
    final ZooKeeperClient client = spy(this.client);
    final ZooKeeperMasterModel masterModel = spy(newMasterModel(client));
    // Return a job so we can add a real deployment group.
    final Job job = Job.newBuilder().setCommand(ImmutableList.of("COMMAND")).setImage("IMAGE").setName("JOB_NAME").setVersion("VERSION").build();
    doReturn(job).when(masterModel).getJob(job.getId());
    // Add a real deployment group.
    final DeploymentGroup dg = DeploymentGroup.newBuilder().setName(GROUP_NAME).setHostSelectors(ImmutableList.of(HostSelector.parse("role=melmac"))).setJobId(job.getId()).setRolloutOptions(RolloutOptions.newBuilder().build()).setRollingUpdateReason(MANUAL).build();
    masterModel.addDeploymentGroup(dg);
    // Give the deployment group a host.
    client.setData(Paths.statusDeploymentGroupHosts(dg.getName()), Json.asBytes(ImmutableList.of("host1")));
    // And a status...
    client.setData(Paths.statusDeploymentGroup(dg.getName()), DeploymentGroupStatus.newBuilder().setState(FAILED).build().toJsonBytes());
    // Pretend our new host is UP.
    final HostStatus statusUp = mock(HostStatus.class);
    doReturn(HostStatus.Status.UP).when(statusUp).getStatus();
    doReturn(statusUp).when(masterModel).getHostStatus("host2");
    // Switch out our host!
    masterModel.updateDeploymentGroupHosts(dg.getName(), ImmutableList.of("host2"));
    // Ensure we do not set the DG status to HOSTS_CHANGED.
    // We don't want to trigger a rolling update because the last one was manual, and failed.
    final ZooKeeperOperation setDeploymentGroupHostChanged = set(Paths.configDeploymentGroup(dg.getName()), dg.toBuilder().setRollingUpdateReason(HOSTS_CHANGED).build());
    verify(client, times(2)).transaction(opCaptor.capture());
    assertThat(opCaptor.getValue(), not(hasItem(setDeploymentGroupHostChanged)));
}
Also used : ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) DefaultZooKeeperClient(com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient) ZooKeeperOperation(com.spotify.helios.servicescommon.coordination.ZooKeeperOperation) HostStatus(com.spotify.helios.common.descriptors.HostStatus) Job(com.spotify.helios.common.descriptors.Job) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) Test(org.junit.Test)

Example 2 with DeploymentGroup

use of com.spotify.helios.common.descriptors.DeploymentGroup in project helios by spotify.

the class DeploymentGroupTest method testStopDeploymentGroup.

// A test that...
// * Verifies that the state in ZK is correct after running stop
// * Verifies that the correct exception is thrown when the DG does not exist or there is a
//   race condition
@Theory
public void testStopDeploymentGroup(@TestedOn(ints = { 0, 1 }) final int dgExistsInt, @TestedOn(ints = { 0, 1 }) final int tasksExistInt, @TestedOn(ints = { 0, 1 }) final int tasksExistWhenCommittingInt) throws Exception {
    final boolean dgExists = dgExistsInt != 0;
    final boolean tasksExist = tasksExistInt != 0;
    final boolean tasksExistWhenCommitting = tasksExistWhenCommittingInt != 0;
    // To be able to simulate triggering the race condition in stopDeploymentGroup we need to do
    // some mocking, relying on that the implementation uses client.exists() to check for the
    // presence of tasks.
    final ZooKeeperClient client = spy(this.client);
    when(client.exists(Paths.statusDeploymentGroupTasks(GROUP_NAME))).thenReturn(tasksExist ? mock(Stat.class) : null);
    final ZooKeeperMasterModel masterModel = newMasterModel(client);
    if (dgExists) {
        final DeploymentGroup dg = DeploymentGroup.newBuilder().setName(GROUP_NAME).build();
        masterModel.addDeploymentGroup(dg);
    }
    if (tasksExistWhenCommitting) {
        client.ensurePath(Paths.statusDeploymentGroupTasks());
        client.create(Paths.statusDeploymentGroupTasks(GROUP_NAME));
    }
    if (!dgExists) {
        exception.expect(DeploymentGroupDoesNotExistException.class);
    } else if (tasksExist != tasksExistWhenCommitting) {
        exception.expect(HeliosRuntimeException.class);
    }
    masterModel.stopDeploymentGroup(GROUP_NAME);
    // Verify that the state in ZK is correct:
    // * tasks are not present
    // * the status is set to FAILED
    //
    // When checking for the existence of the tasks make sure we use the client that doesn't have
    // the exists() method mocked out!
    assertNull(this.client.exists(Paths.statusDeploymentGroupTasks(GROUP_NAME)));
    final DeploymentGroupStatus status = masterModel.getDeploymentGroupStatus(GROUP_NAME);
    assertEquals(FAILED, status.getState());
}
Also used : ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) DefaultZooKeeperClient(com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient) HeliosRuntimeException(com.spotify.helios.common.HeliosRuntimeException) DeploymentGroupStatus(com.spotify.helios.common.descriptors.DeploymentGroupStatus) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) Theory(org.junit.experimental.theories.Theory)

Example 3 with DeploymentGroup

use of com.spotify.helios.common.descriptors.DeploymentGroup in project helios by spotify.

the class DeploymentGroupTest method testUpdateFailedHostsChangedDeploymentGroupHosts.

// A test that ensures deployment groups that failed during a rolling update triggered by
// changing hosts will perform a new rolling update if the hosts change again.
@Test
public void testUpdateFailedHostsChangedDeploymentGroupHosts() throws Exception {
    final ZooKeeperClient client = spy(this.client);
    final ZooKeeperMasterModel masterModel = spy(newMasterModel(client));
    // Return a job so we can add a real deployment group.
    final Job job = Job.newBuilder().setCommand(ImmutableList.of("COMMAND")).setImage("IMAGE").setName("JOB_NAME").setVersion("VERSION").build();
    doReturn(job).when(masterModel).getJob(job.getId());
    // Add a real deployment group.
    final DeploymentGroup dg = DeploymentGroup.newBuilder().setName(GROUP_NAME).setHostSelectors(ImmutableList.of(HostSelector.parse("role=melmac"))).setJobId(job.getId()).setRolloutOptions(RolloutOptions.newBuilder().build()).setRollingUpdateReason(HOSTS_CHANGED).build();
    masterModel.addDeploymentGroup(dg);
    // Give the deployment group a host.
    client.setData(Paths.statusDeploymentGroupHosts(dg.getName()), Json.asBytes(ImmutableList.of("host1")));
    // And a status...
    client.setData(Paths.statusDeploymentGroup(dg.getName()), DeploymentGroupStatus.newBuilder().setState(FAILED).build().toJsonBytes());
    // Pretend our new host is UP.
    final HostStatus statusUp = mock(HostStatus.class);
    doReturn(HostStatus.Status.UP).when(statusUp).getStatus();
    doReturn(statusUp).when(masterModel).getHostStatus("host2");
    // Switch out our host!
    masterModel.updateDeploymentGroupHosts(dg.getName(), ImmutableList.of("host2"));
    // Ensure we write the same DG status again.
    // This is a no-op, but it means we triggered a rolling update.
    final ZooKeeperOperation setDeploymentGroup = set(Paths.configDeploymentGroup(dg.getName()), dg);
    verify(client, times(2)).transaction(opCaptor.capture());
    assertThat(opCaptor.getValue(), hasItem(setDeploymentGroup));
}
Also used : ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) DefaultZooKeeperClient(com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient) ZooKeeperOperation(com.spotify.helios.servicescommon.coordination.ZooKeeperOperation) HostStatus(com.spotify.helios.common.descriptors.HostStatus) Job(com.spotify.helios.common.descriptors.Job) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) Test(org.junit.Test)

Example 4 with DeploymentGroup

use of com.spotify.helios.common.descriptors.DeploymentGroup in project helios by spotify.

the class HostMatcherTest method testDeploymentGroupWithNoSelectors.

@Test
public void testDeploymentGroupWithNoSelectors() {
    final DeploymentGroup deploymentGroup = group();
    assertThat(matcher.getMatchingHosts(deploymentGroup), empty());
}
Also used : DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) Test(org.junit.Test)

Example 5 with DeploymentGroup

use of com.spotify.helios.common.descriptors.DeploymentGroup in project helios by spotify.

the class RollingUndeployPlannerTest method testSerialRollout.

@Test
public void testSerialRollout() {
    final DeploymentGroup deploymentGroup = DeploymentGroup.newBuilder().setRolloutOptions(RolloutOptions.newBuilder().setParallelism(1).build()).build();
    final RolloutPlanner rolloutPlanner = RollingUndeployPlanner.of(deploymentGroup);
    final List<RolloutTask> tasks = rolloutPlanner.plan(HOSTS);
    final List<RolloutTask> expected = Lists.newArrayList(RolloutTask.of(RolloutTask.Action.FORCE_UNDEPLOY_JOBS, "agent1"), RolloutTask.of(RolloutTask.Action.AWAIT_UNDEPLOYED, "agent1"), RolloutTask.of(RolloutTask.Action.MARK_UNDEPLOYED, "agent1"), RolloutTask.of(RolloutTask.Action.FORCE_UNDEPLOY_JOBS, "agent2"), RolloutTask.of(RolloutTask.Action.AWAIT_UNDEPLOYED, "agent2"), RolloutTask.of(RolloutTask.Action.MARK_UNDEPLOYED, "agent2"), RolloutTask.of(RolloutTask.Action.FORCE_UNDEPLOY_JOBS, "agent3"), RolloutTask.of(RolloutTask.Action.AWAIT_UNDEPLOYED, "agent3"), RolloutTask.of(RolloutTask.Action.MARK_UNDEPLOYED, "agent3"), RolloutTask.of(RolloutTask.Action.FORCE_UNDEPLOY_JOBS, "agent4"), RolloutTask.of(RolloutTask.Action.AWAIT_UNDEPLOYED, "agent4"), RolloutTask.of(RolloutTask.Action.MARK_UNDEPLOYED, "agent4"));
    assertEquals(expected, tasks);
}
Also used : RolloutTask(com.spotify.helios.common.descriptors.RolloutTask) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) Test(org.junit.Test)

Aggregations

DeploymentGroup (com.spotify.helios.common.descriptors.DeploymentGroup)30 Test (org.junit.Test)18 RolloutTask (com.spotify.helios.common.descriptors.RolloutTask)10 ZooKeeperClient (com.spotify.helios.servicescommon.coordination.ZooKeeperClient)10 HeliosRuntimeException (com.spotify.helios.common.HeliosRuntimeException)6 ZooKeeperOperation (com.spotify.helios.servicescommon.coordination.ZooKeeperOperation)6 Job (com.spotify.helios.common.descriptors.Job)4 CreateDeploymentGroupResponse (com.spotify.helios.common.protocol.CreateDeploymentGroupResponse)4 RollingUpdateResponse (com.spotify.helios.common.protocol.RollingUpdateResponse)4 KeeperException (org.apache.zookeeper.KeeperException)4 NoNodeException (org.apache.zookeeper.KeeperException.NoNodeException)4 DeploymentGroupStatus (com.spotify.helios.common.descriptors.DeploymentGroupStatus)3 HostStatus (com.spotify.helios.common.descriptors.HostStatus)3 JobId (com.spotify.helios.common.descriptors.JobId)3 RemoveDeploymentGroupResponse (com.spotify.helios.common.protocol.RemoveDeploymentGroupResponse)3 DefaultZooKeeperClient (com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient)3 IOException (java.io.IOException)3 Response (javax.ws.rs.core.Response)3 ExceptionMetered (com.codahale.metrics.annotation.ExceptionMetered)2 Timed (com.codahale.metrics.annotation.Timed)2