Пример #1
0
  @Test
  public void testStorageException() {
    IScheduledTask task = makeTask("a", PENDING);
    TaskInfo mesosTask =
        TaskInfo.newBuilder()
            .setName(Tasks.id(task))
            .setTaskId(TaskID.newBuilder().setValue(Tasks.id(task)))
            .setSlaveId(SlaveID.newBuilder().setValue("slaveId"))
            .build();

    Capture<Runnable> timeoutCapture = expectTaskGroupBackoff(10);
    expectAnyMaintenanceCalls();
    expectOfferDeclineIn(10);
    expect(assigner.maybeAssign(OFFER_A, task)).andThrow(new StorageException("Injected failure."));

    Capture<Runnable> timeoutCapture2 = expectTaskGroupBackoff(10, 20);
    expect(preemptor.findPreemptionSlotFor("a")).andReturn(Optional.<String>absent());
    expect(assigner.maybeAssign(OFFER_A, task)).andReturn(Optional.of(mesosTask));
    driver.launchTask(OFFER_A.getId(), mesosTask);
    expectLastCall();

    replayAndCreateScheduler();

    changeState(task, INIT, PENDING);
    offerQueue.addOffer(OFFER_A);
    timeoutCapture.getValue().run();
    timeoutCapture2.getValue().run();
  }
Пример #2
0
 private TaskInfo makeTaskInfo(IScheduledTask task) {
   return TaskInfo.newBuilder()
       .setName(Tasks.id(task))
       .setTaskId(TaskID.newBuilder().setValue(Tasks.id(task)))
       .setSlaveId(SlaveID.newBuilder().setValue("slave-id" + task.toString()))
       .build();
 }
Пример #3
0
  @Test
  public void testDriverNotReady() {
    IScheduledTask task = makeTask("a", PENDING);
    TaskInfo mesosTask =
        TaskInfo.newBuilder()
            .setName(Tasks.id(task))
            .setTaskId(TaskID.newBuilder().setValue(Tasks.id(task)))
            .setSlaveId(SlaveID.newBuilder().setValue("slaveId"))
            .build();

    Capture<Runnable> timeoutCapture = expectTaskGroupBackoff(10);
    expectAnyMaintenanceCalls();
    expectOfferDeclineIn(10);
    expect(assigner.maybeAssign(OFFER_A, task)).andReturn(Optional.of(mesosTask));
    driver.launchTask(OFFER_A.getId(), mesosTask);
    expectLastCall().andThrow(new IllegalStateException("Driver not ready."));
    expect(
            stateManager.changeState(
                Query.taskScoped("a").byStatus(PENDING), LOST, TaskScheduler.LAUNCH_FAILED_MSG))
        .andReturn(1);

    replayAndCreateScheduler();

    changeState(task, INIT, PENDING);
    offerQueue.addOffer(OFFER_A);
    timeoutCapture.getValue().run();
  }
Пример #4
0
 public static Offer makeOffer(String offerId, String hostName) {
   return Offer.newBuilder()
       .setId(OfferID.newBuilder().setValue(offerId))
       .setFrameworkId(FrameworkID.newBuilder().setValue("framework_id"))
       .setSlaveId(SlaveID.newBuilder().setValue("slave_id-" + offerId))
       .setHostname(hostName)
       .build();
 }
Пример #5
0
 @Override
 public void executorLost(SchedulerDriver driver, ExecutorID executor, SlaveID slave, int status) {
   LOG.warn(
       "Mesos Executor lost: executor: {} slave: {} status: {}",
       executor.getValue(),
       slave.getValue(),
       status);
 }
Пример #6
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)));
  }
  public void slaveLost(SlaveID slaveIdObj) {
    final String slaveId = slaveIdObj.getValue();

    Optional<SingularitySlave> slave = slaveManager.getObject(slaveId);

    if (slave.isPresent()) {
      slaveManager.changeState(slave.get(), MachineState.DEAD, Optional.<String>absent());

      checkRackAfterSlaveLoss(slave.get());
    } else {
      LOG.warn("Lost a slave {}, but didn't know about it", slaveId);
    }
  }
Пример #8
0
  @Test
  public void testTaskWithReservedSlaveLandsElsewhere() throws Exception {
    // Ensures slave/task reservation relationship is only enforced in slave->task direction
    // and permissive in task->slave direction. In other words, a task with a slave reservation
    // should still be tried against other unreserved slaves.
    HostOffer offer =
        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(offer, OFFER));
    expect(tierManager.getTier(TASK.getAssignedTask().getTask())).andReturn(DEFAULT);
    expect(filter.filter(UNUSED, RESOURCE_REQUEST)).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)));
  }
Пример #9
0
 @Override
 public void slaveLost(SchedulerDriver driver, SlaveID id) {
   LOG.warn("Lost slave id: {}", id.getValue());
 }
Пример #10
0
public class TaskAssignerImplTest extends EasyMockTest {

  private static final int PORT = 5000;
  private static final String SLAVE_ID = "slaveId";
  private static final Offer MESOS_OFFER =
      Offer.newBuilder()
          .setId(OfferID.newBuilder().setValue("offerId"))
          .setFrameworkId(FrameworkID.newBuilder().setValue("frameworkId"))
          .setSlaveId(SlaveID.newBuilder().setValue(SLAVE_ID))
          .setHostname("hostName")
          .addResources(
              Resource.newBuilder()
                  .setName("ports")
                  .setType(Type.RANGES)
                  .setRanges(
                      Ranges.newBuilder().addRange(Range.newBuilder().setBegin(PORT).setEnd(PORT))))
          .build();
  private static final HostOffer OFFER =
      new HostOffer(MESOS_OFFER, IHostAttributes.build(new HostAttributes()));
  private static final String PORT_NAME = "http";
  private static final IScheduledTask TASK =
      IScheduledTask.build(
          new ScheduledTask()
              .setAssignedTask(
                  new AssignedTask()
                      .setTaskId("taskId")
                      .setTask(
                          new TaskConfig()
                              .setJob(new JobKey("r", "e", "n"))
                              .setExecutorConfig(new ExecutorConfig().setData("opaque data"))
                              .setRequestedPorts(ImmutableSet.of(PORT_NAME)))));
  private static final TaskGroupKey GROUP_KEY = TaskGroupKey.from(TASK.getAssignedTask().getTask());
  private static final TaskInfo TASK_INFO =
      TaskInfo.newBuilder()
          .setName("taskName")
          .setTaskId(TaskID.newBuilder().setValue(Tasks.id(TASK)))
          .setSlaveId(MESOS_OFFER.getSlaveId())
          .build();
  private static final Map<String, TaskGroupKey> NO_RESERVATION = ImmutableMap.of();
  private static final UnusedResource UNUSED =
      new UnusedResource(Resources.from(MESOS_OFFER).slot(), OFFER.getAttributes());
  private static final ResourceRequest RESOURCE_REQUEST =
      new ResourceRequest(TASK.getAssignedTask().getTask(), EMPTY);

  private MutableStoreProvider storeProvider;
  private StateManager stateManager;
  private SchedulingFilter filter;
  private MesosTaskFactory taskFactory;
  private OfferManager offerManager;
  private TaskAssigner assigner;
  private TierManager tierManager;

  @Before
  public void setUp() throws Exception {
    storeProvider = createMock(MutableStoreProvider.class);
    filter = createMock(SchedulingFilter.class);
    taskFactory = createMock(MesosTaskFactory.class);
    stateManager = createMock(StateManager.class);
    offerManager = createMock(OfferManager.class);
    tierManager = createMock(TierManager.class);
    assigner = new TaskAssignerImpl(stateManager, filter, taskFactory, offerManager, tierManager);
  }

  @Test
  public void testAssignNoVetoes() throws Exception {
    expect(offerManager.getOffers(GROUP_KEY)).andReturn(ImmutableSet.of(OFFER));
    offerManager.launchTask(MESOS_OFFER.getId(), TASK_INFO);
    expect(tierManager.getTier(TASK.getAssignedTask().getTask())).andReturn(DEFAULT);
    expect(filter.filter(UNUSED, RESOURCE_REQUEST)).andReturn(ImmutableSet.of());
    expect(
            stateManager.assignTask(
                storeProvider,
                Tasks.id(TASK),
                MESOS_OFFER.getHostname(),
                MESOS_OFFER.getSlaveId(),
                ImmutableMap.of(PORT_NAME, PORT)))
        .andReturn(TASK.getAssignedTask());
    expect(taskFactory.createFrom(TASK.getAssignedTask(), MESOS_OFFER.getSlaveId()))
        .andReturn(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 testAssignVetoesWithStaticBan() throws Exception {
    expect(offerManager.getOffers(GROUP_KEY)).andReturn(ImmutableSet.of(OFFER));
    offerManager.banOffer(MESOS_OFFER.getId(), GROUP_KEY);
    expect(tierManager.getTier(TASK.getAssignedTask().getTask())).andReturn(DEFAULT);
    expect(filter.filter(UNUSED, RESOURCE_REQUEST))
        .andReturn(ImmutableSet.of(Veto.constraintMismatch("denied")));

    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 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 testAssignmentClearedOnError() throws Exception {
    expect(offerManager.getOffers(GROUP_KEY)).andReturn(ImmutableSet.of(OFFER));
    offerManager.launchTask(MESOS_OFFER.getId(), TASK_INFO);
    expectLastCall().andThrow(new OfferManager.LaunchException("expected"));
    expect(tierManager.getTier(TASK.getAssignedTask().getTask())).andReturn(DEFAULT);
    expect(filter.filter(UNUSED, RESOURCE_REQUEST)).andReturn(ImmutableSet.of());
    expect(
            stateManager.assignTask(
                storeProvider,
                Tasks.id(TASK),
                MESOS_OFFER.getHostname(),
                MESOS_OFFER.getSlaveId(),
                ImmutableMap.of(PORT_NAME, PORT)))
        .andReturn(TASK.getAssignedTask());
    expect(
            stateManager.changeState(
                storeProvider, Tasks.id(TASK), Optional.of(PENDING), LOST, LAUNCH_FAILED_MSG))
        .andReturn(StateChangeResult.SUCCESS);
    expect(taskFactory.createFrom(TASK.getAssignedTask(), MESOS_OFFER.getSlaveId()))
        .andReturn(TASK_INFO);

    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 testAssignmentSkippedForReservedSlave() throws Exception {
    expect(offerManager.getOffers(GROUP_KEY)).andReturn(ImmutableSet.of(OFFER));

    control.replay();

    assertFalse(
        assigner.maybeAssign(
            storeProvider,
            new ResourceRequest(TASK.getAssignedTask().getTask(), EMPTY),
            TaskGroupKey.from(TASK.getAssignedTask().getTask()),
            Tasks.id(TASK),
            ImmutableMap.of(
                SLAVE_ID,
                TaskGroupKey.from(
                    ITaskConfig.build(new TaskConfig().setJob(new JobKey("other", "e", "n")))))));
  }

  @Test
  public void testTaskWithReservedSlaveLandsElsewhere() throws Exception {
    // Ensures slave/task reservation relationship is only enforced in slave->task direction
    // and permissive in task->slave direction. In other words, a task with a slave reservation
    // should still be tried against other unreserved slaves.
    HostOffer offer =
        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(offer, OFFER));
    expect(tierManager.getTier(TASK.getAssignedTask().getTask())).andReturn(DEFAULT);
    expect(filter.filter(UNUSED, RESOURCE_REQUEST)).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 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)));
  }
}
Пример #11
0
public class TaskAssignerImplTest extends EasyMockTest {

  private static final int PORT = 5000;
  private static final Offer MESOS_OFFER =
      Offer.newBuilder()
          .setId(OfferID.newBuilder().setValue("offerId"))
          .setFrameworkId(FrameworkID.newBuilder().setValue("frameworkId"))
          .setSlaveId(SlaveID.newBuilder().setValue("slaveId"))
          .setHostname("hostName")
          .addResources(
              Resource.newBuilder()
                  .setName("ports")
                  .setType(Type.RANGES)
                  .setRanges(
                      Ranges.newBuilder().addRange(Range.newBuilder().setBegin(PORT).setEnd(PORT))))
          .build();
  private static final HostOffer OFFER =
      new HostOffer(MESOS_OFFER, IHostAttributes.build(new HostAttributes()));
  private static final String PORT_NAME = "http";
  private static final IScheduledTask TASK =
      IScheduledTask.build(
          new ScheduledTask()
              .setAssignedTask(
                  new AssignedTask()
                      .setTaskId("taskId")
                      .setTask(
                          new TaskConfig()
                              .setExecutorConfig(new ExecutorConfig().setData("opaque data"))
                              .setRequestedPorts(ImmutableSet.of(PORT_NAME)))));
  private static final TaskInfo TASK_INFO =
      TaskInfo.newBuilder()
          .setName("taskName")
          .setTaskId(TaskID.newBuilder().setValue(Tasks.id(TASK)))
          .setSlaveId(MESOS_OFFER.getSlaveId())
          .build();

  private MutableStoreProvider storeProvider;
  private StateManager stateManager;
  private SchedulingFilter filter;
  private MesosTaskFactory taskFactory;
  private TaskAssigner assigner;

  @Before
  public void setUp() throws Exception {
    storeProvider = createMock(MutableStoreProvider.class);
    stateManager = createMock(StateManager.class);
    filter = createMock(SchedulingFilter.class);
    taskFactory = createMock(MesosTaskFactory.class);
    assigner = new TaskAssignerImpl(stateManager, filter, taskFactory);
  }

  @Test
  public void testAssignNoVetoes() {
    expect(
            filter.filter(
                new UnusedResource(ResourceSlot.from(MESOS_OFFER), OFFER.getAttributes()),
                new ResourceRequest(TASK.getAssignedTask().getTask(), EMPTY)))
        .andReturn(ImmutableSet.of());
    expect(
            stateManager.assignTask(
                storeProvider,
                Tasks.id(TASK),
                MESOS_OFFER.getHostname(),
                MESOS_OFFER.getSlaveId(),
                ImmutableMap.of(PORT_NAME, PORT)))
        .andReturn(TASK.getAssignedTask());
    expect(taskFactory.createFrom(TASK.getAssignedTask(), MESOS_OFFER.getSlaveId()))
        .andReturn(TASK_INFO);

    control.replay();

    assertEquals(
        Assignment.success(TASK_INFO),
        assigner.maybeAssign(
            storeProvider,
            OFFER,
            new ResourceRequest(TASK.getAssignedTask().getTask(), EMPTY),
            Tasks.id(TASK)));
  }

  @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)));
  }
}