Search in sources :

Example 6 with JobStatus

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

the class ExpiredJobReaperTest method testExpiredJobReaper.

@Test
public void testExpiredJobReaper() throws Exception {
    when(mockClock.now()).thenReturn(new Instant(CURRENT_TS));
    when(masterModel.getJobs()).thenReturn(JOBS);
    when(masterModel.getJobStatus(any(JobId.class))).then(new Answer<JobStatus>() {

        @Override
        public JobStatus answer(final InvocationOnMock invocation) throws Throwable {
            final JobId jobId = (JobId) invocation.getArguments()[0];
            final Map<String, Deployment> deployments = ImmutableMap.of("hostA", Deployment.of(jobId, Goal.START), "hostB", Deployment.of(jobId, Goal.START));
            return JobStatus.newBuilder().setJob(JOBS.get(jobId)).setDeployments(deployments).build();
        }
    });
    ExpiredJobReaper.newBuilder().setClock(mockClock).setMasterModel(masterModel).build().runOneIteration();
    // Make sure that the expiring job was removed, but that the non-expiring job
    // and the job that expires far in the future were not.
    verify(masterModel).undeployJob(eq("hostA"), eq(EXPIRING_JOB_ID), eq(""));
    verify(masterModel).undeployJob(eq("hostB"), eq(EXPIRING_JOB_ID), eq(""));
    verify(masterModel).removeJob(eq(EXPIRING_JOB_ID), eq(""));
    verifyNoMoreInteractions(ignoreStubs(masterModel));
}
Also used : JobStatus(com.spotify.helios.common.descriptors.JobStatus) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Instant(org.joda.time.Instant) ImmutableMap(com.google.common.collect.ImmutableMap) Map(java.util.Map) JobId(com.spotify.helios.common.descriptors.JobId) Test(org.junit.Test)

Example 7 with JobStatus

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

the class TemporaryJob method verifyHealthy.

void verifyHealthy() throws AssertionError {
    log.debug("Checking health of {}", job.getImage());
    final JobStatus status = Futures.getUnchecked(client.jobStatus(job.getId()));
    if (status == null) {
        return;
    }
    for (final Map.Entry<String, TaskStatus> entry : status.getTaskStatuses().entrySet()) {
        verifyHealthy(entry.getKey(), entry.getValue());
    }
}
Also used : JobStatus(com.spotify.helios.common.descriptors.JobStatus) TaskStatus(com.spotify.helios.common.descriptors.TaskStatus) Map(java.util.Map) Maps.newHashMap(com.google.common.collect.Maps.newHashMap) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 8 with JobStatus

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

the class TemporaryJobs method removeOldJobs.

/**
   * Undeploys and deletes jobs leftover from previous runs of TemporaryJobs. This would happen if
   * the test was terminated before the cleanup code was called. This method will iterate over each
   * file in the specified directory. Each filename is the prefix that was used for job names
   * during previous runs. The method will undeploy and delete any jobs that have a matching
   * prefix, and the delete the file. If the file is locked, it is currently in use, and will be
   * skipped.
   */
private void removeOldJobs() throws ExecutionException, InterruptedException, IOException {
    // is used as a @Rule in a test class with many test methods
    if (removedOldJobs) {
        return;
    }
    final File[] files = prefixDirectory.toFile().listFiles();
    if (files == null || files.length == 0) {
        return;
    }
    log.info("Removing old temporary jobs");
    final Map<JobId, Job> jobs = client.jobs().get();
    // Iterate over all files in the directory
    for (final File file : files) {
        // directories. We don't expect any, but skip them just in case.
        if (file.getName().endsWith(".tmp") || file.isDirectory()) {
            continue;
        }
        // used by another process. In either case, skip over it.
        try (JobPrefixFile prefixFile = JobPrefixFile.tryFromExistingFile(file.toPath())) {
            if (prefixFile == null) {
                log.debug("Unable to create JobPrefixFile for {}", file.getPath());
                continue;
            }
            boolean jobRemovalFailed = false;
            // Iterate over jobs, looking for ones with a matching prefix.
            for (final Map.Entry<JobId, Job> entry : jobs.entrySet()) {
                final JobId jobId = entry.getKey();
                // Skip over job if the id doesn't start with current filename.
                if (!jobId.getName().startsWith(prefixFile.prefix())) {
                    continue;
                }
                // Get list of all hosts where this job is deployed, and undeploy
                final JobStatus status = client.jobStatus(entry.getKey()).get();
                final List<String> hosts = ImmutableList.copyOf(status.getDeployments().keySet());
                final List<AssertionError> errors = undeploy(client, entry.getValue(), hosts, new ArrayList<AssertionError>());
                // Set flag indicating if any errors occur
                if (!errors.isEmpty()) {
                    jobRemovalFailed = true;
                }
            }
            // leave it there so we can try again next time.
            if (!jobRemovalFailed) {
                prefixFile.delete();
            }
        } catch (NoSuchFileException e) {
            log.debug("File {} already processed by somebody else.", file.getPath());
        } catch (Exception e) {
            // log exception and continue on to next file
            log.warn("Exception processing file {}", file.getPath(), e);
        }
    }
    removedOldJobs = true;
}
Also used : NoSuchFileException(java.nio.file.NoSuchFileException) NoSuchFileException(java.nio.file.NoSuchFileException) URISyntaxException(java.net.URISyntaxException) MultipleFailureException(org.junit.runners.model.MultipleFailureException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) JobStatus(com.spotify.helios.common.descriptors.JobStatus) Job(com.spotify.helios.common.descriptors.Job) File(java.io.File) Map(java.util.Map) JobId(com.spotify.helios.common.descriptors.JobId)

Example 9 with JobStatus

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

the class JobNamePrefixTest method testJobNamePrefix.

@Test
public void testJobNamePrefix() throws Exception {
    // Create four jobs which represent these use cases:
    //  job1 - Created, deployed, locked. Simulates a job being used by another process. The
    //         job should not get undeployed or deleted since it is in use.
    //  job2 - Created, not deployed, locked. Simulates a job being used by another process. The
    //         job should not get deleted since it is in use.
    //  job3 - Created, deployed, not locked. Simulates an old job no longer in use, which should
    //         be undeployed and deleted.
    //  job4 - Created, not deployed, not locked. Simulates an old job no longer in use, which
    //         should be deleted.
    // job1 - create and deploy
    final JobId jobId1 = createJob(testJobName + "_1", testJobVersion, BUSYBOX, IDLE_COMMAND);
    deployJob(jobId1, testHost1);
    // job2 - create
    final JobId jobId2 = createJob(testJobName + "_2", testJobVersion, BUSYBOX, IDLE_COMMAND);
    // job3 - create and deploy
    final JobId jobId3 = createJob(testJobName + "_3", testJobVersion, BUSYBOX, IDLE_COMMAND);
    deployJob(jobId3, testHost1);
    // job4 - create
    final JobId jobId4 = createJob(testJobName + "_4", testJobVersion, BUSYBOX, IDLE_COMMAND);
    try (// Create prefix files for all four jobs. They will be locked by default.
    JobPrefixFile file1 = JobPrefixFile.create(jobId1.getName(), prefixDirectory);
        JobPrefixFile file2 = JobPrefixFile.create(jobId2.getName(), prefixDirectory);
        JobPrefixFile file3 = JobPrefixFile.create(jobId3.getName(), prefixDirectory);
        JobPrefixFile file4 = JobPrefixFile.create(jobId4.getName(), prefixDirectory)) {
        // Release the locks of jobs 3 and 4 so they can be cleaned up
        file3.release();
        file4.release();
        assertThat(testResult(JobNamePrefixTestImpl.class), isSuccessful());
        final Map<JobId, Job> jobs = client.jobs().get();
        // Verify job1 is still deployed and the prefix file has not been deleted.
        assertThat(jobs, hasKey(jobId1));
        final JobStatus status1 = client.jobStatus(jobId1).get();
        assertThat(status1.getDeployments().size(), is(1));
        assertTrue(fileExists(prefixDirectory, jobId1.getName()));
        // Verify job2 still exists, is not deployed, and the prefix file is still there.
        assertThat(jobs, hasKey(jobId2));
        final JobStatus status2 = client.jobStatus(jobId2).get();
        assertThat(status2.getDeployments().size(), is(0));
        assertTrue(fileExists(prefixDirectory, jobId2.getName()));
        // Verify that job3 has been deleted (which means it has also been undeployed), and
        // the prefix file has been deleted.
        assertThat(jobs, not(hasKey(jobId3)));
        assertFalse(fileExists(prefixDirectory, jobId3.getName()));
        // Verify that job4 and its prefix file have been deleted.
        assertThat(jobs, not(hasKey(jobId4)));
        assertFalse(fileExists(prefixDirectory, jobId4.getName()));
        // Verify the prefix file created during the run of JobNamePrefixTest was deleted
        assertFalse(fileExists(prefixDirectory, jobPrefixFile.prefix()));
    }
}
Also used : JobStatus(com.spotify.helios.common.descriptors.JobStatus) Job(com.spotify.helios.common.descriptors.Job) JobId(com.spotify.helios.common.descriptors.JobId) Test(org.junit.Test)

Example 10 with JobStatus

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

the class JobStatusCommand method run.

@Override
int run(final Namespace options, final HeliosClient client, final PrintStream out, final boolean json, final BufferedReader stdin) throws ExecutionException, InterruptedException {
    final String jobIdString = options.getString(jobArg.getDest());
    final String hostPattern = options.getString(hostArg.getDest());
    final boolean full = options.getBoolean(fullArg.getDest());
    final Map<JobId, Job> jobs;
    if (Strings.isNullOrEmpty(jobIdString)) {
        jobs = client.jobs().get();
    } else {
        jobs = client.jobs(jobIdString).get();
    }
    if (jobs == null) {
        out.printf("The specified Helios master either returned an error or job id matcher " + "\"%s\" matched no jobs%n", jobIdString);
        return 1;
    }
    final Set<JobId> jobIds = jobs.keySet();
    if (!Strings.isNullOrEmpty(jobIdString) && jobIds.isEmpty()) {
        if (json) {
            out.println("{ }");
        } else {
            out.printf("job id matcher \"%s\" matched no jobs%n", jobIdString);
        }
        return 1;
    }
    final Map<JobId, JobStatus> statuses = Maps.newTreeMap();
    statuses.putAll(client.jobStatuses(jobIds).get());
    if (json) {
        showJsonStatuses(out, hostPattern, jobIds, statuses);
        return 0;
    }
    final JobStatusTable table = jobStatusTable(out, full);
    final boolean noHostMatchedEver = showStatusesForHosts(hostPattern, jobIds, statuses, new HostStatusDisplayer() {

        @Override
        public void matchedStatus(JobStatus jobStatus, Iterable<String> matchingHosts, Map<String, TaskStatus> taskStatuses) {
            displayTask(full, table, jobStatus.getJob().getId(), jobStatus, taskStatuses, matchingHosts);
        }
    });
    if (noHostMatchedEver) {
        String domainsSwitchString = "";
        final List<String> domains = options.get("domains");
        if (domains.size() > 0) {
            domainsSwitchString = "-d " + Joiner.on(",").join(domains);
        }
        out.printf("There are no jobs deployed to hosts with the host pattern '%s'%n" + "Run 'helios %s hosts %s' to check your host exists and is up.%n", hostPattern, domainsSwitchString, hostPattern);
        return 1;
    }
    table.print();
    return 0;
}
Also used : JobStatusTable(com.spotify.helios.cli.JobStatusTable) TaskStatus(com.spotify.helios.common.descriptors.TaskStatus) JobStatus(com.spotify.helios.common.descriptors.JobStatus) Job(com.spotify.helios.common.descriptors.Job) JobId(com.spotify.helios.common.descriptors.JobId)

Aggregations

JobStatus (com.spotify.helios.common.descriptors.JobStatus)23 JobId (com.spotify.helios.common.descriptors.JobId)19 Job (com.spotify.helios.common.descriptors.Job)11 Test (org.junit.Test)9 TaskStatus (com.spotify.helios.common.descriptors.TaskStatus)8 HeliosClient (com.spotify.helios.client.HeliosClient)6 Map (java.util.Map)6 ImmutableMap (com.google.common.collect.ImmutableMap)4 Deployment (com.spotify.helios.common.descriptors.Deployment)4 Matchers.containsString (org.hamcrest.Matchers.containsString)4 IOException (java.io.IOException)3 PortMapping (com.spotify.helios.common.descriptors.PortMapping)2 ServiceEndpoint (com.spotify.helios.common.descriptors.ServiceEndpoint)2 TaskStatusEvent (com.spotify.helios.common.descriptors.TaskStatusEvent)2 JobUndeployResponse (com.spotify.helios.common.protocol.JobUndeployResponse)2 Integer.toHexString (java.lang.Integer.toHexString)2 List (java.util.List)2 ExecutionException (java.util.concurrent.ExecutionException)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 ImmutableList (com.google.common.collect.ImmutableList)1