ReadOnlySchedulerImpl implements ReadOnlyScheduler.Iface { @Override public Response getPendingReason(TaskQuery query) throws TException { requireNonNull(query); if (query.isSetSlaveHosts() && !query.getSlaveHosts().isEmpty()) { return invalidRequest( "SlaveHosts are not supported in " + query.toString()); } if (query.isSetStatuses() && !query.getStatuses().isEmpty()) { return invalidRequest( "Statuses is not supported in " + query.toString()); } query.setStatuses(ImmutableSet.of(ScheduleStatus.PENDING)); Set<PendingReason> reasons = FluentIterable.from(getTasks(query)) .transform(scheduledTask -> { TaskGroupKey groupKey = TaskGroupKey.from( ITaskConfig.build(scheduledTask.getAssignedTask().getTask())); String reason = Joiner.on(',').join(Iterables.transform( nearestFit.getNearestFit(groupKey), Veto::getReason)); return new PendingReason() .setTaskId(scheduledTask.getAssignedTask().getTaskId()) .setReason(reason); }).toSet(); return ok(Result.getPendingReasonResult(new GetPendingReasonResult(reasons))); } @Inject  ReadOnlySchedulerImpl(
      ConfigurationManager configurationManager,
      Storage storage,
      NearestFit nearestFit,
      CronPredictor cronPredictor,
      QuotaManager quotaManager); @Override Response populateJobConfig(JobConfiguration description); @Override Response getTasksStatus(TaskQuery query); @Override Response getTasksWithoutConfigs(TaskQuery query); @Override Response getPendingReason(TaskQuery query); @Override Response getConfigSummary(JobKey job); @Override Response getRoleSummary(); @Override Response getJobSummary(@Nullable String maybeNullRole); @Override Response getJobs(@Nullable String maybeNullRole); @Override Response getQuota(String ownerRole); @Override Response getJobUpdateSummaries(JobUpdateQuery mutableQuery); @Override Response getJobUpdateDetails(JobUpdateKey mutableKey); @Override Response getJobUpdateDiff(JobUpdateRequest mutableRequest);  }
@Test public void testGetPendingReason() throws Exception { Builder query = Query.unscoped().byJob(JOB_KEY); Builder filterQuery = Query.unscoped().byJob(JOB_KEY).byStatus(ScheduleStatus.PENDING); String taskId1 = "task_id_test1"; String taskId2 = "task_id_test2"; ImmutableSet<Veto> result = ImmutableSet.of( Veto.constraintMismatch("first"), Veto.constraintMismatch("second")); ITaskConfig taskConfig = ITaskConfig.build(defaultTask(true)); IScheduledTask pendingTask1 = IScheduledTask.build(new ScheduledTask() .setAssignedTask(new AssignedTask() .setTaskId(taskId1) .setTask(taskConfig.newBuilder())) .setStatus(ScheduleStatus.PENDING)); IScheduledTask pendingTask2 = IScheduledTask.build(new ScheduledTask() .setAssignedTask(new AssignedTask() .setTaskId(taskId2) .setTask(taskConfig.newBuilder())) .setStatus(ScheduleStatus.PENDING)); storageUtil.expectTaskFetch(filterQuery, pendingTask1, pendingTask2); expect(nearestFit.getNearestFit(TaskGroupKey.from(taskConfig))).andReturn(result).times(2); control.replay(); String reason = "Constraint not satisfied: first,Constraint not satisfied: second"; Set<PendingReason> expected = ImmutableSet.of( new PendingReason().setTaskId(taskId1).setReason(reason), new PendingReason().setTaskId(taskId2).setReason(reason)); Response response = assertOkResponse(thrift.getPendingReason(query.get().newBuilder())); assertEquals(expected, response.getResult().getGetPendingReasonResult().getReasons()); }
@Test public void testGetPendingReasonFailsSlavesSet() throws Exception { Builder query = Query.unscoped().bySlave("host1"); control.replay(); assertResponse(INVALID_REQUEST, thrift.getPendingReason(query.get().newBuilder())); }
@Test public void testGetPendingReasonFailsStatusSet() throws Exception { Builder query = Query.unscoped().byStatus(ScheduleStatus.ASSIGNED); control.replay(); assertResponse(INVALID_REQUEST, thrift.getPendingReason(query.get().newBuilder())); }