public class NotifyingSchedulingFilterTest extends EasyMockTest {

  private static final ITaskConfig TASK =
      ITaskConfig.build(new TaskConfig().setNumCpus(1).setRamMb(1024).setDiskMb(1024));
  private static final TaskGroupKey GROUP_KEY = TaskGroupKey.from(TASK);
  private static final UnusedResource RESOURCE =
      new UnusedResource(
          ResourceSlot.from(TASK).withOverhead(TaskExecutors.NO_OVERHEAD_EXECUTOR),
          IHostAttributes.build(
              new HostAttributes().setHost("host").setMode(MaintenanceMode.NONE)));
  private static final ResourceRequest REQUEST =
      new ResourceRequest(TASK, AttributeAggregate.EMPTY);

  private static final Veto VETO_1 = Veto.insufficientResources("ram", 1);
  private static final Veto VETO_2 = Veto.insufficientResources("ram", 2);

  private SchedulingFilter filter;
  private EventSink eventSink;
  private SchedulingFilter delegate;

  @Before
  public void setUp() {
    delegate = createMock(SchedulingFilter.class);
    eventSink = createMock(EventSink.class);
    filter = new NotifyingSchedulingFilter(delegate, eventSink);
  }

  @Test
  public void testEvents() {
    Set<Veto> vetoes = ImmutableSet.of(VETO_1, VETO_2);
    expect(delegate.filter(RESOURCE, REQUEST)).andReturn(vetoes);
    eventSink.post(new Vetoed(GROUP_KEY, vetoes));

    control.replay();

    assertEquals(vetoes, filter.filter(RESOURCE, REQUEST));
  }

  @Test
  public void testNoVetoes() {
    Set<Veto> vetoes = ImmutableSet.of();
    expect(delegate.filter(RESOURCE, REQUEST)).andReturn(vetoes);

    control.replay();

    assertEquals(vetoes, filter.filter(RESOURCE, REQUEST));
  }
}
  @Test
  public void testDedicatedMismatchShortCircuits() {
    // Ensures that a dedicated mismatch short-circuits other filter operations, such as
    // evaluation of limit constraints.  Reduction of task queries is the desired outcome.

    control.replay();

    Constraint hostLimit = limitConstraint("host", 1);
    assertVetoes(
        makeTask(JOB_A, hostLimit, makeConstraint(DEDICATED_ATTRIBUTE, "xxx")),
        hostAttributes(HOST_A, host(HOST_A)),
        Veto.constraintMismatch(DEDICATED_ATTRIBUTE));
    assertVetoes(
        makeTask(JOB_A, hostLimit, makeConstraint(DEDICATED_ATTRIBUTE, "xxx")),
        hostAttributes(HOST_B, dedicated(dedicatedFor(JOB_B)), host(HOST_B)),
        Veto.constraintMismatch(DEDICATED_ATTRIBUTE));
  }
  @Test
  public void testDedicatedRole() {
    control.replay();

    IHostAttributes hostA = hostAttributes(HOST_A, dedicated(JOB_A.getRole()));
    checkConstraint(hostA, DEDICATED_ATTRIBUTE, true, JOB_A.getRole());
    assertVetoes(makeTask(JOB_B), hostA, Veto.dedicatedHostConstraintMismatch());
  }
  @Test
  public void testHostDrainedForMaintenance() {
    control.replay();

    assertVetoes(
        makeTask(),
        hostAttributes(HOST_A, MaintenanceMode.DRAINED, host(HOST_A), rack(RACK_A)),
        Veto.maintenance("drained"));
  }
示例#5
0
  @Test
  public void testAssignerDoesNotReturnOnFirstMismatch() throws Exception {
    // Ensures scheduling loop does not terminate prematurely when the first mismatch is identified.
    HostOffer mismatched =
        new HostOffer(
            Offer.newBuilder()
                .setId(OfferID.newBuilder().setValue("offerId0"))
                .setFrameworkId(FrameworkID.newBuilder().setValue("frameworkId"))
                .setSlaveId(SlaveID.newBuilder().setValue("slaveId0"))
                .setHostname("hostName0")
                .addResources(
                    Resource.newBuilder()
                        .setName("ports")
                        .setType(Type.RANGES)
                        .setRanges(
                            Ranges.newBuilder()
                                .addRange(Range.newBuilder().setBegin(PORT).setEnd(PORT))))
                .build(),
            IHostAttributes.build(new HostAttributes()));

    expect(offerManager.getOffers(GROUP_KEY)).andReturn(ImmutableSet.of(mismatched, OFFER));
    expect(tierManager.getTier(TASK.getAssignedTask().getTask())).andReturn(DEFAULT).times(2);
    expect(
            filter.filter(
                new UnusedResource(
                    Resources.from(mismatched.getOffer()).slot(), mismatched.getAttributes()),
                new ResourceRequest(TASK.getAssignedTask().getTask(), EMPTY)))
        .andReturn(ImmutableSet.of(Veto.constraintMismatch("constraint mismatch")));
    offerManager.banOffer(mismatched.getOffer().getId(), GROUP_KEY);
    expect(
            filter.filter(
                new UnusedResource(Resources.from(OFFER.getOffer()).slot(), OFFER.getAttributes()),
                new ResourceRequest(TASK.getAssignedTask().getTask(), EMPTY)))
        .andReturn(ImmutableSet.of());

    expect(
            stateManager.assignTask(
                storeProvider,
                Tasks.id(TASK),
                OFFER.getOffer().getHostname(),
                OFFER.getOffer().getSlaveId(),
                ImmutableMap.of(PORT_NAME, PORT)))
        .andReturn(TASK.getAssignedTask());
    expect(taskFactory.createFrom(TASK.getAssignedTask(), OFFER.getOffer().getSlaveId()))
        .andReturn(TASK_INFO);
    offerManager.launchTask(OFFER.getOffer().getId(), TASK_INFO);

    control.replay();

    assertTrue(
        assigner.maybeAssign(
            storeProvider,
            new ResourceRequest(TASK.getAssignedTask().getTask(), EMPTY),
            TaskGroupKey.from(TASK.getAssignedTask().getTask()),
            Tasks.id(TASK),
            ImmutableMap.of(SLAVE_ID, GROUP_KEY)));
  }
  @Test
  public void testAssignVetoes() {
    expect(
            filter.filter(
                new UnusedResource(ResourceSlot.from(MESOS_OFFER), OFFER.getAttributes()),
                new ResourceRequest(TASK.getAssignedTask().getTask(), EMPTY)))
        .andReturn(ImmutableSet.of(Veto.constraintMismatch("denied")));

    control.replay();

    assertEquals(
        Assignment.failure(ImmutableSet.of(Veto.constraintMismatch("denied"))),
        assigner.maybeAssign(
            storeProvider,
            OFFER,
            new ResourceRequest(TASK.getAssignedTask().getTask(), EMPTY),
            Tasks.id(TASK)));
  }
  @Test
  public void testLimitWithinJob() throws Exception {
    control.replay();

    AttributeAggregate stateA =
        AttributeAggregate.create(
            Suppliers.ofInstance(
                ImmutableList.of(
                    host(HOST_A),
                    rack(RACK_A),
                    host(HOST_B),
                    rack(RACK_A),
                    host(HOST_B),
                    rack(RACK_A),
                    host(HOST_C),
                    rack(RACK_B))));
    AttributeAggregate stateB =
        AttributeAggregate.create(
            Suppliers.ofInstance(
                ImmutableList.of(
                    host(HOST_A),
                    rack(RACK_A),
                    host(HOST_A),
                    rack(RACK_A),
                    host(HOST_B),
                    rack(RACK_A))));

    IHostAttributes hostA = hostAttributes(HOST_A, host(HOST_A), rack(RACK_A));
    IHostAttributes hostB = hostAttributes(HOST_B, host(HOST_B), rack(RACK_A));
    IHostAttributes hostC = hostAttributes(HOST_C, host(HOST_C), rack(RACK_B));
    assertNoVetoes(hostLimitTask(JOB_A, 2), hostA, stateA);
    assertVetoes(hostLimitTask(JOB_A, 1), hostB, stateA, Veto.unsatisfiedLimit(HOST_ATTRIBUTE));
    assertVetoes(hostLimitTask(JOB_A, 2), hostB, stateA, Veto.unsatisfiedLimit(HOST_ATTRIBUTE));
    assertNoVetoes(hostLimitTask(JOB_A, 3), hostB, stateA);

    assertVetoes(rackLimitTask(JOB_A, 2), hostB, stateB, Veto.unsatisfiedLimit(RACK_ATTRIBUTE));
    assertVetoes(rackLimitTask(JOB_A, 3), hostB, stateB, Veto.unsatisfiedLimit(RACK_ATTRIBUTE));
    assertNoVetoes(rackLimitTask(JOB_A, 4), hostB, stateB);

    assertNoVetoes(rackLimitTask(JOB_A, 1), hostC, stateB);

    assertVetoes(rackLimitTask(JOB_A, 1), hostC, stateA, Veto.unsatisfiedLimit(RACK_ATTRIBUTE));
    assertNoVetoes(rackLimitTask(JOB_A, 2), hostC, stateB);
  }
  @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()));
    assertEquals(expected, response.getResult().getGetPendingReasonResult().getReasons());
  }
  @Test
  public void testVetoGroups() {
    control.replay();

    assertEquals(VetoGroup.EMPTY, Veto.identifyGroup(ImmutableSet.of()));

    assertEquals(
        VetoGroup.STATIC,
        Veto.identifyGroup(
            ImmutableSet.of(
                Veto.constraintMismatch("denied"),
                Veto.insufficientResources("ram", 100),
                Veto.maintenance("draining"))));

    assertEquals(
        VetoGroup.DYNAMIC, Veto.identifyGroup(ImmutableSet.of(Veto.unsatisfiedLimit("denied"))));

    assertEquals(
        VetoGroup.MIXED,
        Veto.identifyGroup(
            ImmutableSet.of(
                Veto.insufficientResources("ram", 100), Veto.unsatisfiedLimit("denied"))));
  }
  @Test
  public void testMultipleTaskConstraints() {
    control.replay();

    Constraint constraint1 = makeConstraint("host", HOST_A);
    Constraint constraint2 = makeConstraint(DEDICATED_ATTRIBUTE, "xxx");

    assertVetoes(
        makeTask(JOB_A, constraint1, constraint2),
        hostAttributes(HOST_A, dedicated(HOST_A), host(HOST_A)),
        Veto.constraintMismatch(DEDICATED_ATTRIBUTE));
    assertNoVetoes(
        makeTask(JOB_B, constraint1, constraint2),
        hostAttributes(HOST_B, dedicated("xxx"), host(HOST_A)));
  }
示例#11
0
  @Test
  public void testAssignVetoesWithNoStaticBan() throws Exception {
    expect(offerManager.getOffers(GROUP_KEY)).andReturn(ImmutableSet.of(OFFER));
    expect(tierManager.getTier(TASK.getAssignedTask().getTask())).andReturn(DEFAULT);
    expect(filter.filter(UNUSED, RESOURCE_REQUEST))
        .andReturn(ImmutableSet.of(Veto.unsatisfiedLimit("limit")));

    control.replay();

    assertFalse(
        assigner.maybeAssign(
            storeProvider,
            new ResourceRequest(TASK.getAssignedTask().getTask(), EMPTY),
            TaskGroupKey.from(TASK.getAssignedTask().getTask()),
            Tasks.id(TASK),
            NO_RESERVATION));
  }
  @Test
  public void testAttributes() {
    control.replay();

    IHostAttributes hostA =
        hostAttributes(
            HOST_A,
            valueAttribute("jvm", "1.4", "1.6", "1.7"),
            valueAttribute("zone", "a", "b", "c"));

    // Matches attribute, matching value.
    checkConstraint(hostA, "jvm", true, "1.4");

    // Matches attribute, different value.
    checkConstraint(hostA, "jvm", false, "1.0");

    // Does not match attribute.
    checkConstraint(hostA, "xxx", false, "1.4");

    // Logical 'OR' with attribute and value match.
    checkConstraint(hostA, "jvm", true, "1.2", "1.4");

    // Does not match attribute.
    checkConstraint(hostA, "xxx", false, "1.0", "1.4");

    // Check that logical AND works.
    Constraint jvmConstraint = makeConstraint("jvm", "1.6");
    Constraint zoneConstraint = makeConstraint("zone", "c");

    ITaskConfig task = makeTask(JOB_A, jvmConstraint, zoneConstraint);
    assertEquals(
        ImmutableSet.of(),
        defaultFilter.filter(
            new UnusedResource(DEFAULT_OFFER, hostA), new ResourceRequest(task, EMPTY)));

    Constraint jvmNegated = jvmConstraint.deepCopy();
    jvmNegated.getConstraint().getValue().setNegated(true);
    Constraint zoneNegated = jvmConstraint.deepCopy();
    zoneNegated.getConstraint().getValue().setNegated(true);
    assertVetoes(makeTask(JOB_A, jvmNegated, zoneNegated), hostA, Veto.constraintMismatch("jvm"));
  }