use of com.spotify.helios.common.descriptors.HostStatus 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.getDefault()).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)));
}
use of com.spotify.helios.common.descriptors.HostStatus in project helios by spotify.
the class JobsResourceTest method testListJobsWithMultipleDeployments.
@Test
public void testListJobsWithMultipleDeployments() throws Exception {
// two hosts match this name patterns
final String namePattern = "foo";
when(model.listHosts(namePattern)).thenReturn(ImmutableList.of("foobar.example.net", "barfoo.example.net"));
final JobId jobId1 = JobId.parse("foobar:1");
final JobId jobId2 = JobId.parse("foobat:2");
final Job job1 = Job.newBuilder().build();
final Job job2 = Job.newBuilder().build();
// and they have two jobs deployed
final HostStatus hostStatus = mockHostStatus(ImmutableMap.of(jobId1, Deployment.of(jobId1, Goal.START), jobId2, Deployment.of(jobId2, Goal.START)));
when(model.getHostStatus("foobar.example.net")).thenReturn(hostStatus);
when(model.getHostStatus("barfoo.example.net")).thenReturn(hostStatus);
when(model.getJob(jobId1)).thenReturn(job1);
when(model.getJob(jobId2)).thenReturn(job2);
assertThat(resource.list("", namePattern), is(ImmutableMap.of(jobId1, job1, jobId2, job2)));
}
use of com.spotify.helios.common.descriptors.HostStatus in project helios by spotify.
the class HeliosSoloDeploymentTest method testUndeployLeftoverJobs.
@Test
public void testUndeployLeftoverJobs() throws Exception {
final HeliosSoloDeployment solo = buildHeliosSoloDeployment();
final ListenableFuture<List<String>> hostsFuture = Futures.<List<String>>immediateFuture(ImmutableList.of(HOST1, HOST2));
when(heliosClient.listHosts()).thenReturn(hostsFuture);
// These futures represent HostStatuses when the job is still deployed
final ListenableFuture<HostStatus> statusFuture11 = Futures.immediateFuture(HostStatus.newBuilder().setStatus(Status.UP).setStatuses(ImmutableMap.of(JOB_ID1, TASK_STATUS1)).setJobs(ImmutableMap.of(JOB_ID1, Deployment.of(JOB_ID1, Goal.START))).build());
final ListenableFuture<HostStatus> statusFuture21 = Futures.immediateFuture(HostStatus.newBuilder().setStatus(Status.UP).setStatuses(ImmutableMap.of(JOB_ID2, TASK_STATUS2)).setJobs(ImmutableMap.of(JOB_ID2, Deployment.of(JOB_ID2, Goal.START))).build());
// These futures represent HostStatuses when the job is undeployed
final ListenableFuture<HostStatus> statusFuture12 = Futures.immediateFuture(HostStatus.newBuilder().setStatus(Status.UP).setStatuses(Collections.<JobId, TaskStatus>emptyMap()).setJobs(ImmutableMap.of(JOB_ID1, Deployment.of(JOB_ID1, Goal.START))).build());
final ListenableFuture<HostStatus> statusFuture22 = Futures.immediateFuture(HostStatus.newBuilder().setStatus(Status.UP).setStatuses(Collections.<JobId, TaskStatus>emptyMap()).setJobs(ImmutableMap.of(JOB_ID2, Deployment.of(JOB_ID2, Goal.START))).build());
// noinspection unchecked
when(heliosClient.hostStatus(HOST1)).thenReturn(statusFuture11);
// noinspection unchecked
when(heliosClient.hostStatus(HOST2)).thenReturn(statusFuture21);
final ListenableFuture<JobUndeployResponse> undeployFuture1 = Futures.immediateFuture(new JobUndeployResponse(JobUndeployResponse.Status.OK, HOST1, JOB_ID1));
final ListenableFuture<JobUndeployResponse> undeployFuture2 = Futures.immediateFuture(new JobUndeployResponse(JobUndeployResponse.Status.OK, HOST2, JOB_ID2));
// when undeploy is called, respond correctly & patch the mock to return
// the undeployed HostStatus
when(heliosClient.undeploy(JOB_ID1, HOST1)).thenAnswer(new Answer<ListenableFuture<JobUndeployResponse>>() {
@Override
public ListenableFuture<JobUndeployResponse> answer(final InvocationOnMock invocation) throws Throwable {
when(heliosClient.hostStatus(HOST1)).thenReturn(statusFuture12);
return undeployFuture1;
}
});
when(heliosClient.undeploy(JOB_ID2, HOST2)).thenAnswer(new Answer<ListenableFuture<JobUndeployResponse>>() {
@Override
public ListenableFuture<JobUndeployResponse> answer(final InvocationOnMock invocation) throws Throwable {
when(heliosClient.hostStatus(HOST1)).thenReturn(statusFuture22);
return undeployFuture2;
}
});
solo.undeployLeftoverJobs();
verify(heliosClient).undeploy(JOB_ID1, HOST1);
verify(heliosClient).undeploy(JOB_ID2, HOST2);
}
use of com.spotify.helios.common.descriptors.HostStatus in project helios by spotify.
the class TemporaryJob method deploy.
void deploy() {
final TemporaryJobReports.Step createJob = reportWriter.step("create job").tag("jobId", job.getId());
try {
// Create job
log.info("Creating job {}", job.getId().toShortString());
final CreateJobResponse createResponse = get(client.createJob(job));
if (createResponse.getStatus() != CreateJobResponse.Status.OK) {
fail(format("Failed to create job %s - %s", job.getId(), createResponse.toString()));
}
createJob.markSuccess();
} catch (InterruptedException | ExecutionException | TimeoutException e) {
fail(format("Failed to create job %s %s - %s", job.getId(), job.toString(), e));
} finally {
createJob.finish();
}
final TemporaryJobReports.Step deployJob = reportWriter.step("deploy job").tag("jobId", job.getId());
try {
// Deploy job
final Deployment deployment = Deployment.of(job.getId(), Goal.START);
for (final String host : hosts) {
// HELIOS_HOST_ADDRESS is the IP address we should use to reach the host, instead of
// the hostname. This is used when running a helios cluster inside a VM, and the containers
// can be reached by IP address only, since DNS won't be able to resolve the host name of
// the helios agent running in the VM.
final HostStatus hostStatus = client.hostStatus(host).get();
final String hostAddress = hostStatus.getEnvironment().get("HELIOS_HOST_ADDRESS");
if (hostAddress != null) {
hostToIp.put(host, hostAddress);
}
log.info("Deploying {} to {}", getJobDescription(job), host);
final JobDeployResponse deployResponse = get(client.deploy(deployment, host));
if (deployResponse.getStatus() != JobDeployResponse.Status.OK) {
fail(format("Failed to deploy job %s %s - %s", job.getId(), job.toString(), deployResponse));
}
}
deployJob.markSuccess();
} catch (InterruptedException | ExecutionException | TimeoutException e) {
fail(format("Failed to deploy job %s %s - %s", job.getId(), job.toString(), e));
} finally {
deployJob.finish();
}
try {
// Wait for job to come up
for (final String host : hosts) {
awaitUp(host);
}
} catch (TimeoutException e) {
fail(format("Failed while probing job %s %s - %s", job.getId(), job.toString(), e));
}
}
use of com.spotify.helios.common.descriptors.HostStatus in project helios by spotify.
the class CliHostListTest method testHostListJson.
@Test
public void testHostListJson() throws Exception {
final String jsonOutput = cli("hosts", "-f", "--json");
final Map<String, HostStatus> statuses = Json.readUnchecked(jsonOutput, new TypeReference<Map<String, HostStatus>>() {
});
final HeliosClient client = defaultClient();
final Map<String, HostStatus> expectedStatuses = client.hostStatuses(ImmutableList.of(hostname1, hostname2)).get();
assertThat(expectedStatuses, equalTo(statuses));
}
Aggregations