TaskMigrationDescheduler { DeschedulingFailure getDeschedulingFailure(Task task) { Job<?> job = jobsById.get(task.getJobId()); String message; if (job == null) { message = "No job record found"; } else { Node instance = evacuatedAgentsAllocationTracker.getAgent(task); Optional<String> blockedOpt = instance != null ? RelocationPredicates.checkIfRelocationBlocked(job, task, instance) : Optional.empty(); if (blockedOpt.isPresent()) { message = blockedOpt.get(); } else if (!canTerminate(task)) { message = "Migration deadline not reached yet"; } else if (evictionQuotaTracker.getJobEvictionQuota(job.getId()) <= 0) { message = "Not enough job quota"; } else { message = "Unknown"; } } return DeschedulingFailure.newBuilder().withReasonMessage(message).build(); } TaskMigrationDescheduler(Map<String, TaskRelocationPlan> plannedAheadTaskRelocationPlans,
                             EvacuatedAgentsAllocationTracker evacuatedAgentsAllocationTracker,
                             EvictionQuotaTracker evictionQuotaTracker,
                             Map<String, Job<?>> jobsById,
                             Map<String, Task> tasksById,
                             TitusRuntime titusRuntime);   }
@Test public void testFailures() { Task job1Task0 = jobOperations.getTasks("job1").get(0); dataGenerator.place("removable1", job1Task0); dataGenerator.setQuota("job1", 0); DeschedulingFailure failure = newDescheduler(Collections.emptyMap()).getDeschedulingFailure(job1Task0); assertThat(failure.getReasonMessage()).contains("job quota"); }