aurora-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject [1/2] aurora git commit: Moving resource-related classes into a new package
Date Mon, 11 Apr 2016 21:45:50 GMT
Repository: aurora
Updated Branches:
  refs/heads/master bafdd71a0 -> 46ce98d8c


http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/AcceptedOfferTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/AcceptedOfferTest.java b/src/test/java/org/apache/aurora/scheduler/AcceptedOfferTest.java
deleted file mode 100644
index 49ced12..0000000
--- a/src/test/java/org/apache/aurora/scheduler/AcceptedOfferTest.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/**
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.aurora.scheduler;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-import org.apache.aurora.common.quantity.Amount;
-import org.apache.aurora.common.quantity.Data;
-import org.apache.aurora.scheduler.base.TaskTestUtil;
-import org.apache.mesos.Protos;
-import org.apache.mesos.Protos.Resource;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class AcceptedOfferTest {
-
-  private static final Optional<String> TEST_ROLE = Optional.of("test-role");
-  private static final Optional<String> ABSENT_ROLE = Optional.absent();
-  private static final ResourceSlot TASK_SLOT = new ResourceSlot(
-      4, Amount.of(100L, Data.MB), Amount.of(200L, Data.MB), 0);
-  private static final ResourceSlot EXECUTOR_SLOT = new ResourceSlot(
-      0.25, Amount.of(25L, Data.MB), Amount.of(75L, Data.MB), 0);
-  private static final ResourceSlot TOTAL_SLOT = EXECUTOR_SLOT.add(TASK_SLOT);
-  private static final Integer[] TASK_PORTS = {80, 90};
-  private static final Set<Integer> TASK_PORTS_SET = ImmutableSet.copyOf(TASK_PORTS);
-
-  @Test
-  public void testReservedPredicates() {
-    Protos.Resource withRole = makeScalar(ResourceType.CPUS.getName(), TEST_ROLE, false, 1.0);
-    assertTrue(AcceptedOffer.RESERVED.apply(withRole));
-    assertFalse(AcceptedOffer.NOT_RESERVED.apply(withRole));
-    Protos.Resource absentRole = makeScalar(ResourceType.CPUS.getName(), ABSENT_ROLE, false, 1.0);
-    assertFalse(AcceptedOffer.RESERVED.apply(absentRole));
-    assertTrue(AcceptedOffer.NOT_RESERVED.apply(absentRole));
-  }
-
-  @Test
-  public void testAllocateEmpty() {
-    AcceptedOffer acceptedOffer = AcceptedOffer.create(
-        fakeOffer(Collections.emptyList()),
-        ResourceSlot.NONE,
-        ResourceSlot.NONE,
-        ImmutableSet.of(),
-        TaskTestUtil.DEV_TIER);
-    assertEquals(Collections.emptyList(), acceptedOffer.getTaskResources());
-    assertEquals(Collections.emptyList(), acceptedOffer.getExecutorResources());
-  }
-
-  @Test
-  public void testAllocateRange() {
-    List<Resource> resources = ImmutableList.<Resource>builder()
-        .add(makePortResource(Optional.absent(), 80, 81, 90, 91, 92, 93))
-        .add(makePortResource(TEST_ROLE, 100, 101))
-        .build();
-    AcceptedOffer acceptedOffer = AcceptedOffer.create(
-        fakeOffer(resources),
-        ResourceSlot.NONE,
-        ResourceSlot.NONE,
-        ImmutableSet.of(80, 90, 100),
-        TaskTestUtil.DEV_TIER);
-
-    List<Resource> expected = ImmutableList.<Resource>builder()
-        // Because we prefer reserved resources and handle them before non-reserved resources,
-        // result should have ports for the reserved resources first.
-        .add(makePortResource(TEST_ROLE, 100))
-        .add(makePortResource(Optional.absent(), 80, 90))
-        .build();
-    assertEquals(expected, acceptedOffer.getTaskResources());
-    assertEquals(Collections.emptyList(), acceptedOffer.getExecutorResources());
-  }
-
-  @Test(expected = Resources.InsufficientResourcesException.class)
-  public void testAllocateRangeInsufficent() {
-    List<Resource> resources = ImmutableList.of(
-        makePortResource(ABSENT_ROLE, 80),
-        makePortResource(ABSENT_ROLE, 100, 101));
-    AcceptedOffer.create(
-        fakeOffer(resources),
-        ResourceSlot.NONE,
-        ResourceSlot.NONE,
-        ImmutableSet.of(80, 90, 100),
-        TaskTestUtil.DEV_TIER);
-  }
-
-  @Test
-  public void testAllocateSingleRole() {
-    runAllocateSingleRole(ABSENT_ROLE, false);
-    runAllocateSingleRole(ABSENT_ROLE, true);
-    runAllocateSingleRole(TEST_ROLE, false);
-    runAllocateSingleRole(TEST_ROLE, true);
-  }
-
-  private void runAllocateSingleRole(Optional<String> role, boolean cpuRevocable) {
-    List<Resource> resources = ImmutableList.<Resource>builder()
-        .add(makeScalar(
-            ResourceType.CPUS.getName(), role, cpuRevocable, TOTAL_SLOT.getNumCpus()))
-        .add(makeScalar(
-            ResourceType.RAM_MB.getName(), role, false, TOTAL_SLOT.getRam().as(Data.MB)))
-        .add(makeScalar(
-            ResourceType.DISK_MB.getName(), role, false, TOTAL_SLOT.getDisk().as(Data.MB)))
-        .add(makePortResource(role, TASK_PORTS))
-        .build();
-    Protos.Offer offer = fakeOffer(resources);
-
-    AcceptedOffer offerAllocation = AcceptedOffer.create(
-        offer, TASK_SLOT, EXECUTOR_SLOT, TASK_PORTS_SET, new TierInfo(false, cpuRevocable));
-
-    List<Resource> taskList = ImmutableList.<Resource>builder()
-        .add(makeScalar(ResourceType.CPUS.getName(), role, cpuRevocable, TASK_SLOT.getNumCpus()))
-        .add(makeScalar(ResourceType.RAM_MB.getName(), role, false, TASK_SLOT.getRam().as(Data.MB)))
-        .add(makeScalar(
-            ResourceType.DISK_MB.getName(), role, false, TASK_SLOT.getDisk().as(Data.MB)))
-        .add(makePortResource(role, TASK_PORTS))
-        .build();
-    assertEquals(taskList, offerAllocation.getTaskResources());
-
-    List<Resource> executorList = ImmutableList.<Resource>builder()
-        .add(makeScalar(
-            ResourceType.CPUS.getName(), role, cpuRevocable, EXECUTOR_SLOT.getNumCpus()))
-        .add(makeScalar(
-            ResourceType.RAM_MB.getName(), role, false, EXECUTOR_SLOT.getRam().as(Data.MB)))
-        .add(makeScalar(
-            ResourceType.DISK_MB.getName(), role, false, EXECUTOR_SLOT.getDisk().as(Data.MB)))
-        .build();
-    assertEquals(executorList, offerAllocation.getExecutorResources());
-  }
-
-  @Test(expected = Resources.InsufficientResourcesException.class)
-  public void testAllocateSingleRoleInsufficient() {
-    List<Resource> resources = ImmutableList.<Resource>builder()
-        // EXECUTOR_SLOT's CPU is not included here.
-        .add(makeScalar(ResourceType.CPUS.getName(), TEST_ROLE, false, TASK_SLOT.getNumCpus()))
-        .add(makeScalar(
-            ResourceType.RAM_MB.getName(), TEST_ROLE, false, TOTAL_SLOT.getRam().as(Data.MB)))
-        .add(makeScalar(
-            ResourceType.DISK_MB.getName(), TEST_ROLE, false, TOTAL_SLOT.getDisk().as(Data.MB)))
-        .add(makePortResource(TEST_ROLE, TASK_PORTS))
-        .build();
-    Protos.Offer offer = fakeOffer(resources);
-
-    AcceptedOffer.create(
-        offer, TASK_SLOT, EXECUTOR_SLOT, TASK_PORTS_SET, new TierInfo(false, false));
-  }
-
-  @Test
-  public void testMultipleRoles() {
-    runMultipleRoles(false);
-    runMultipleRoles(true);
-  }
-
-  private void runMultipleRoles(boolean cpuRevocable) {
-    List<Resource> resources = ImmutableList.<Resource>builder()
-        // Make cpus come from two roles.
-        .add(makeScalar(
-            ResourceType.CPUS.getName(),
-            TEST_ROLE,
-            cpuRevocable,
-            EXECUTOR_SLOT.getNumCpus()))
-        .add(makeScalar(
-            ResourceType.CPUS.getName(),
-            ABSENT_ROLE,
-            cpuRevocable,
-            TASK_SLOT.getNumCpus()))
-        // Make ram come from default role
-        .add(makeScalar(
-            ResourceType.RAM_MB.getName(),
-            ABSENT_ROLE,
-            false,
-            TOTAL_SLOT.getRam().as(Data.MB)))
-        // Make disk come from non-default role.
-        .add(makeScalar(
-            ResourceType.DISK_MB.getName(),
-            TEST_ROLE,
-            false,
-            TOTAL_SLOT.getDisk().as(Data.MB)))
-        .add(makePortResource(TEST_ROLE, 80))
-        .add(makePortResource(ABSENT_ROLE, 90))
-        .build();
-
-    Protos.Offer offer = fakeOffer(resources);
-
-    AcceptedOffer offerAllocation = AcceptedOffer.create(
-        offer, TASK_SLOT, EXECUTOR_SLOT, TASK_PORTS_SET, new TierInfo(false, cpuRevocable));
-
-    List<Resource> taskList = ImmutableList.<Resource>builder()
-        // We intentionally sliced the offer resource to not align with TASK_SLOT's num cpus.
-        .add(makeScalar(
-            ResourceType.CPUS.getName(), TEST_ROLE, cpuRevocable, EXECUTOR_SLOT.getNumCpus()))
-        .add(makeScalar(
-            ResourceType.CPUS.getName(),
-            ABSENT_ROLE,
-            cpuRevocable,
-            TASK_SLOT.subtract(EXECUTOR_SLOT).getNumCpus()))
-        .add(makeScalar(
-            ResourceType.RAM_MB.getName(), ABSENT_ROLE, false, TASK_SLOT.getRam().as(Data.MB)))
-        .add(makeScalar(
-            ResourceType.DISK_MB.getName(), TEST_ROLE, false, TASK_SLOT.getDisk().as(Data.MB)))
-        .add(makePortResource(TEST_ROLE, 80))
-        .add(makePortResource(ABSENT_ROLE, 90))
-        .build();
-    assertEquals(taskList, offerAllocation.getTaskResources());
-
-    List<Resource> executorList = ImmutableList.<Resource>builder()
-        .add(makeScalar(
-            ResourceType.CPUS.getName(), ABSENT_ROLE, cpuRevocable, EXECUTOR_SLOT.getNumCpus()))
-        .add(makeScalar(
-            ResourceType.RAM_MB.getName(), ABSENT_ROLE, false, EXECUTOR_SLOT.getRam().as(Data.MB)))
-        .add(makeScalar(
-            ResourceType.DISK_MB.getName(), TEST_ROLE, false, EXECUTOR_SLOT.getDisk().as(Data.MB)))
-        .build();
-    assertEquals(executorList, offerAllocation.getExecutorResources());
-  }
-
-  @Test(expected = Resources.InsufficientResourcesException.class)
-  public void testMultipleRolesInsufficient() {
-    // Similar to testMultipleRoles, but make some of cpus as revocable
-    List<Resource> resources = ImmutableList.<Resource>builder()
-        // Make cpus come from two roles.
-        .add(makeScalar(
-            ResourceType.CPUS.getName(),
-            TEST_ROLE,
-            true,
-            EXECUTOR_SLOT.getNumCpus()))
-        .add(makeScalar(
-            ResourceType.CPUS.getName(),
-            ABSENT_ROLE,
-            false,
-            TASK_SLOT.getNumCpus()))
-        // Make ram come from default role
-        .add(makeScalar(
-            ResourceType.RAM_MB.getName(),
-            ABSENT_ROLE,
-            false,
-            TOTAL_SLOT.getRam().as(Data.MB)))
-        // Make disk come from non-default role.
-        .add(makeScalar(
-            ResourceType.DISK_MB.getName(),
-            TEST_ROLE,
-            false,
-            TOTAL_SLOT.getDisk().as(Data.MB)))
-        .add(makePortResource(TEST_ROLE, 80))
-        .add(makePortResource(ABSENT_ROLE, 90))
-        .build();
-    Protos.Offer offer = fakeOffer(resources);
-    // We don't have enough resource to satisfy a non-revocable request.
-    AcceptedOffer.create(
-        offer, TASK_SLOT, EXECUTOR_SLOT, TASK_PORTS_SET, new TierInfo(false, false));
-  }
-
-  private static Resource makePortResource(Optional<String> role, Integer... values) {
-    Resource.Builder prototype = Resource.newBuilder()
-        .setType(Protos.Value.Type.RANGES)
-        .setName(ResourceType.PORTS.getName());
-    if (role.isPresent()) {
-      prototype.setRole(role.get());
-    }
-    return AcceptedOffer.makeMesosRangeResource(prototype.build(), ImmutableSet.copyOf(values));
-  }
-
-  private static Resource makeScalar(
-      String name, Optional<String> role, boolean revocable, double value) {
-    Resource.Builder resource = Resource.newBuilder()
-        .setName(name)
-        .setType(Protos.Value.Type.SCALAR)
-        .setScalar(Protos.Value.Scalar.newBuilder().setValue(value));
-    if (role.isPresent()) {
-      resource.setRole(role.get());
-    }
-    if (revocable) {
-      resource.setRevocable(Resource.RevocableInfo.getDefaultInstance());
-    }
-    return resource.build();
-  }
-
-  private static Protos.Offer fakeOffer(List<Resource> resources) {
-    return Protos.Offer.newBuilder()
-        .setId(Protos.OfferID.newBuilder().setValue("offer-id"))
-        .setFrameworkId(Protos.FrameworkID.newBuilder().setValue("framework-id"))
-        .setSlaveId(Protos.SlaveID.newBuilder().setValue("slave-id"))
-        .setHostname("hostname")
-        .addAllResources(resources)
-        .build();
-  }
-}

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/ResourceSlotTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/ResourceSlotTest.java b/src/test/java/org/apache/aurora/scheduler/ResourceSlotTest.java
deleted file mode 100644
index 6564e82..0000000
--- a/src/test/java/org/apache/aurora/scheduler/ResourceSlotTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.aurora.scheduler;
-
-import java.util.Set;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-import org.apache.aurora.common.collections.Pair;
-import org.apache.aurora.common.quantity.Amount;
-import org.apache.aurora.common.quantity.Data;
-import org.apache.aurora.gen.TaskConfig;
-import org.apache.aurora.scheduler.storage.entities.ITaskConfig;
-import org.apache.mesos.Protos;
-import org.junit.Test;
-
-import static org.apache.aurora.scheduler.ResourceSlot.makeMesosRangeResource;
-import static org.apache.aurora.scheduler.ResourceSlot.makeMesosResource;
-import static org.apache.aurora.scheduler.ResourceSlot.sum;
-import static org.apache.aurora.scheduler.ResourceType.CPUS;
-import static org.apache.aurora.scheduler.ResourceType.DISK_MB;
-import static org.apache.aurora.scheduler.ResourceType.PORTS;
-import static org.apache.aurora.scheduler.ResourceType.RAM_MB;
-import static org.apache.aurora.scheduler.base.TaskTestUtil.DEV_TIER;
-import static org.apache.aurora.scheduler.base.TaskTestUtil.REVOCABLE_TIER;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-public class ResourceSlotTest {
-
-  private static final ResourceSlot NEGATIVE_ONE =
-      new ResourceSlot(-1.0, Amount.of(-1L, Data.MB), Amount.of(-1L, Data.MB), -1);
-  private static final ResourceSlot ONE =
-      new ResourceSlot(1.0, Amount.of(1L, Data.MB), Amount.of(1L, Data.MB), 1);
-  private static final ResourceSlot TWO =
-      new ResourceSlot(2.0, Amount.of(2L, Data.MB), Amount.of(2L, Data.MB), 2);
-  private static final ResourceSlot THREE =
-      new ResourceSlot(3.0, Amount.of(3L, Data.MB), Amount.of(3L, Data.MB), 3);
-  private static final ITaskConfig TASK = ITaskConfig.build(new TaskConfig()
-      .setNumCpus(1.0)
-      .setRamMb(1024)
-      .setDiskMb(2048)
-      .setRequestedPorts(ImmutableSet.of("http", "debug")));
-
-  @Test
-  public void testMaxElements() {
-    ResourceSlot highRAM = new ResourceSlot(1, Amount.of(8L, Data.GB), Amount.of(10L, Data.MB), 0);
-    ResourceSlot rest = new ResourceSlot(10, Amount.of(1L, Data.MB), Amount.of(10L, Data.GB), 1);
-
-    ResourceSlot result = ResourceSlot.maxElements(highRAM, rest);
-    assertEquals(result.getNumCpus(), 10, 0.001);
-    assertEquals(result.getRam(), Amount.of(8L, Data.GB));
-    assertEquals(result.getDisk(), Amount.of(10L, Data.GB));
-    assertEquals(result.getNumPorts(), 1);
-  }
-
-  @Test
-  public void testSubtract() {
-    assertEquals(ONE, TWO.subtract(ONE));
-    assertEquals(TWO, THREE.subtract(ONE));
-    assertEquals(NEGATIVE_ONE, ONE.subtract(TWO));
-    assertEquals(NEGATIVE_ONE, TWO.subtract(THREE));
-  }
-
-  @Test
-  public void testAdd() {
-    assertEquals(TWO, ONE.add(ONE));
-    assertEquals(THREE, ONE.add(TWO));
-    assertEquals(THREE, TWO.add(ONE));
-  }
-
-  @Test
-  public void testSum() {
-    assertEquals(THREE, sum(ImmutableList.of(ONE, ONE, ONE)));
-  }
-
-  @Test
-  public void testToResourceListNoRevoca() {
-    ResourceSlot resources = ResourceSlot.from(TASK);
-    assertEquals(
-        ImmutableSet.of(
-            makeMesosResource(CPUS, TASK.getNumCpus(), false),
-            makeMesosResource(RAM_MB, TASK.getRamMb(), false),
-            makeMesosResource(DISK_MB, TASK.getDiskMb(), false)),
-        ImmutableSet.copyOf(resources.toResourceList(DEV_TIER)));
-  }
-
-  @Test
-  public void testToResourceListRevocable() {
-    ResourceSlot resources = ResourceSlot.from(TASK);
-    assertEquals(
-        ImmutableSet.of(
-            makeMesosResource(CPUS, TASK.getNumCpus(), true),
-            makeMesosResource(RAM_MB, TASK.getRamMb(), false),
-            makeMesosResource(DISK_MB, TASK.getDiskMb(), false)),
-        ImmutableSet.copyOf(resources.toResourceList(REVOCABLE_TIER)));
-  }
-
-  @Test
-  public void testToResourceListNoPorts() {
-    ResourceSlot resources = ResourceSlot.from(TASK);
-    assertEquals(
-        ImmutableSet.of(
-            makeMesosResource(CPUS, TASK.getNumCpus(), true),
-            makeMesosResource(RAM_MB, TASK.getRamMb(), false),
-            makeMesosResource(DISK_MB, TASK.getDiskMb(), false)),
-        ImmutableSet.copyOf(resources.toResourceList(REVOCABLE_TIER)));
-  }
-
-  @Test
-  public void testRangeResourceEmpty() {
-    expectRanges(ImmutableSet.of(), ImmutableSet.of());
-  }
-
-  @Test
-  public void testRangeResourceOneEntry() {
-    expectRanges(ImmutableSet.of(Pair.of(5L, 5L)), ImmutableSet.of(5));
-    expectRanges(ImmutableSet.of(Pair.of(0L, 0L)), ImmutableSet.of(0));
-  }
-
-  @Test
-  public void testRangeResourceNonContiguous() {
-    expectRanges(ImmutableSet.of(Pair.of(1L, 1L), Pair.of(3L, 3L), Pair.of(5L, 5L)),
-        ImmutableSet.of(5, 1, 3));
-  }
-
-  @Test
-  public void testRangeResourceContiguous() {
-    expectRanges(ImmutableSet.of(Pair.of(1L, 2L), Pair.of(4L, 5L), Pair.of(7L, 9L)),
-        ImmutableSet.of(8, 2, 4, 5, 7, 9, 1));
-  }
-
-  @Test
-  public void testEqualsBadType() {
-    ResourceSlot resources = ResourceSlot.from(TASK);
-    assertNotEquals(resources, "Hello");
-    assertNotEquals(resources, null);
-  }
-
-  @Test
-  public void testOrder() {
-    assertEquals(
-        ImmutableList.of(ONE, TWO, THREE, THREE),
-        ResourceSlot.ORDER.sortedCopy(ImmutableList.of(THREE, ONE, TWO, THREE)));
-  }
-
-  private void expectRanges(Set<Pair<Long, Long>> expected, Set<Integer> values) {
-    Protos.Resource resource = makeMesosRangeResource(PORTS, values);
-    assertEquals(Protos.Value.Type.RANGES, resource.getType());
-    assertEquals(PORTS.getName(), resource.getName());
-
-    Set<Pair<Long, Long>> actual = ImmutableSet.copyOf(Iterables.transform(
-        resource.getRanges().getRangeList(),
-        range -> Pair.of(range.getBegin(), range.getEnd())));
-    assertEquals(expected, actual);
-  }
-}

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/ResourcesTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/ResourcesTest.java b/src/test/java/org/apache/aurora/scheduler/ResourcesTest.java
deleted file mode 100644
index ea74842..0000000
--- a/src/test/java/org/apache/aurora/scheduler/ResourcesTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.aurora.scheduler;
-
-import java.util.Set;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-import org.apache.aurora.common.collections.Pair;
-import org.apache.aurora.common.quantity.Amount;
-import org.apache.aurora.scheduler.Resources.InsufficientResourcesException;
-import org.apache.mesos.Protos;
-import org.apache.mesos.Protos.Resource;
-import org.apache.mesos.Protos.Value.Range;
-import org.apache.mesos.Protos.Value.Ranges;
-import org.junit.Test;
-
-import static org.apache.aurora.common.quantity.Data.MB;
-import static org.apache.aurora.scheduler.ResourceSlot.makeMesosResource;
-import static org.apache.aurora.scheduler.ResourceType.CPUS;
-import static org.apache.aurora.scheduler.ResourceType.DISK_MB;
-import static org.apache.aurora.scheduler.ResourceType.PORTS;
-import static org.apache.aurora.scheduler.ResourceType.RAM_MB;
-import static org.apache.aurora.scheduler.base.TaskTestUtil.DEV_TIER;
-import static org.apache.aurora.scheduler.base.TaskTestUtil.REVOCABLE_TIER;
-import static org.apache.mesos.Protos.Value.Type.RANGES;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-public class ResourcesTest {
-  @Test
-  public void testPortRangeExact() {
-    Resource portsResource = createPortRange(Pair.of(1, 5));
-    Set<Integer> ports = Resources.from(createOffer(portsResource)).getPorts(5);
-    assertEquals(5, ports.size());
-  }
-
-  @Test
-  public void testOnePortAvailable() {
-    Resource portsResource = createPortRange(Pair.of(3, 3));
-    Set<Integer> ports = Resources.from(createOffer(portsResource)).getPorts(1);
-    assertEquals(1, ports.size());
-  }
-
-  @Test
-  public void testPortRangeAbundance() {
-    Resource portsResource = createPortRange(Pair.of(1, 10));
-    Set<Integer> ports = Resources.from(createOffer(portsResource)).getPorts(5);
-    assertEquals(5, ports.size());
-  }
-
-  @Test
-  public void testPortRangeExhaust() {
-    Resource portsResource = createPortRanges(Pair.of(1, 2), Pair.of(10, 15));
-
-    Set<Integer> ports = Resources.from(createOffer(portsResource)).getPorts(7);
-    assertEquals(7, ports.size());
-
-    ports = Resources.from(createOffer(portsResource)).getPorts(8);
-    assertEquals(8, ports.size());
-
-    try {
-      Resources.from(createOffer(portsResource)).getPorts(9);
-      fail("Ports should not have been sufficient");
-    } catch (InsufficientResourcesException e) {
-      // Expected.
-    }
-  }
-
-  @Test
-  public void testGetNoPorts() {
-    Resource portsResource = createPortRange(Pair.of(1, 5));
-    assertEquals(ImmutableSet.of(), Resources.from(createOffer(portsResource)).getPorts(0));
-  }
-
-  @Test(expected = Resources.InsufficientResourcesException.class)
-  public void testPortRangeScarcity() {
-    Resource portsResource = createPortRange(Pair.of(1, 2));
-    Resources.from(createOffer(portsResource)).getPorts(5);
-  }
-
-  @Test
-  public void testGetSlot() {
-    ImmutableList<Resource> resources = ImmutableList.<Resource>builder()
-        .add(makeMesosResource(CPUS, 8.0, false))
-        .add(makeMesosResource(RAM_MB, 1024, false))
-        .add(makeMesosResource(DISK_MB, 2048, false))
-        .add(createPortRange(Pair.of(1, 10)))
-        .build();
-
-    ResourceSlot expected = new ResourceSlot(8.0, Amount.of(1024L, MB), Amount.of(2048L, MB), 10);
-    assertEquals(expected, Resources.from(createOffer(resources)).slot());
-  }
-
-  @Test
-  public void testMissingResourcesHandledGracefully() {
-    ImmutableList<Resource> resources = ImmutableList.<Resource>builder().build();
-    assertEquals(ResourceSlot.NONE, Resources.from(createOffer(resources)).slot());
-  }
-
-  @Test
-  public void testFilter() {
-    ImmutableList<Resource> resources = ImmutableList.<Resource>builder()
-        .add(makeMesosResource(CPUS, 8.0, true))
-        .add(makeMesosResource(RAM_MB, 1024, false))
-        .build();
-
-    assertEquals(
-        new ResourceSlot(8.0, Amount.of(1024L, MB), Amount.of(0L, MB), 0),
-        Resources.from(createOffer(resources)).filter(Resources.REVOCABLE).slot());
-  }
-
-  @Test
-  public void testFilterByTier() {
-    ImmutableList<Resource> resources = ImmutableList.<Resource>builder()
-        .add(makeMesosResource(CPUS, 8.0, true))
-        .add(makeMesosResource(CPUS, 8.0, false))
-        .add(makeMesosResource(RAM_MB, 1024, false))
-        .build();
-
-    assertEquals(
-        new ResourceSlot(8.0, Amount.of(1024L, MB), Amount.of(0L, MB), 0),
-        Resources.from(createOffer(resources)).filter(REVOCABLE_TIER).slot());
-
-    assertEquals(
-        new ResourceSlot(8.0, Amount.of(1024L, MB), Amount.of(0L, MB), 0),
-        Resources.from(createOffer(resources)).filter(DEV_TIER).slot());
-  }
-
-  private Resource createPortRange(Pair<Integer, Integer> range) {
-    return createPortRanges(ImmutableSet.of(range));
-  }
-
-  private Resource createPortRanges(Pair<Integer, Integer> rangeA, Pair<Integer, Integer> rangeB) {
-    return createPortRanges(
-        ImmutableSet.<Pair<Integer, Integer>>builder().add(rangeA).add(rangeB).build());
-  }
-
-  private Resource createPortRanges(Set<Pair<Integer, Integer>> ports) {
-    Ranges.Builder ranges = Ranges.newBuilder();
-    for (Pair<Integer, Integer> range : ports) {
-      ranges.addRange(Range.newBuilder().setBegin(range.getFirst()).setEnd(range.getSecond()));
-    }
-
-    return Resource.newBuilder()
-        .setName(PORTS.getName())
-        .setType(RANGES)
-        .setRanges(ranges)
-        .build();
-  }
-
-  private static Protos.Offer createOffer(Resource resource) {
-    return createOffer(ImmutableList.of(resource));
-  }
-
-  private static Protos.Offer createOffer(Iterable<Resource> resources) {
-    return Protos.Offer.newBuilder()
-        .setId(Protos.OfferID.newBuilder().setValue("offer-id"))
-        .setFrameworkId(Protos.FrameworkID.newBuilder().setValue("framework-id"))
-        .setSlaveId(Protos.SlaveID.newBuilder().setValue("slave-id"))
-        .setHostname("hostname")
-        .addAllResources(resources).build();
-  }
-}

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java b/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java
index b1426bc..89b2813 100644
--- a/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java
+++ b/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java
@@ -59,7 +59,6 @@ import org.apache.aurora.gen.storage.Snapshot;
 import org.apache.aurora.gen.storage.Transaction;
 import org.apache.aurora.gen.storage.storageConstants;
 import org.apache.aurora.scheduler.AppStartup;
-import org.apache.aurora.scheduler.ResourceSlot;
 import org.apache.aurora.scheduler.TierModule;
 import org.apache.aurora.scheduler.base.TaskTestUtil;
 import org.apache.aurora.scheduler.configuration.executor.ExecutorSettings;
@@ -71,6 +70,7 @@ import org.apache.aurora.scheduler.log.Log.Stream;
 import org.apache.aurora.scheduler.mesos.DriverFactory;
 import org.apache.aurora.scheduler.mesos.DriverSettings;
 import org.apache.aurora.scheduler.mesos.TestExecutorSettings;
+import org.apache.aurora.scheduler.resources.ResourceSlot;
 import org.apache.aurora.scheduler.storage.backup.BackupModule;
 import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
 import org.apache.aurora.scheduler.storage.entities.IServerInfo;

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/app/local/simulator/ClusterSimulatorModule.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/app/local/simulator/ClusterSimulatorModule.java b/src/test/java/org/apache/aurora/scheduler/app/local/simulator/ClusterSimulatorModule.java
index ea87688..48a665f 100644
--- a/src/test/java/org/apache/aurora/scheduler/app/local/simulator/ClusterSimulatorModule.java
+++ b/src/test/java/org/apache/aurora/scheduler/app/local/simulator/ClusterSimulatorModule.java
@@ -29,11 +29,11 @@ import org.apache.mesos.Protos.Offer;
 
 import static java.util.Objects.requireNonNull;
 
-import static org.apache.aurora.scheduler.ResourceType.CPUS;
-import static org.apache.aurora.scheduler.ResourceType.DISK_MB;
-import static org.apache.aurora.scheduler.ResourceType.PORTS;
-import static org.apache.aurora.scheduler.ResourceType.RAM_MB;
 import static org.apache.aurora.scheduler.configuration.ConfigurationManager.DEDICATED_ATTRIBUTE;
+import static org.apache.aurora.scheduler.resources.ResourceType.CPUS;
+import static org.apache.aurora.scheduler.resources.ResourceType.DISK_MB;
+import static org.apache.aurora.scheduler.resources.ResourceType.PORTS;
+import static org.apache.aurora.scheduler.resources.ResourceType.RAM_MB;
 import static org.apache.mesos.Protos.Value.Type.RANGES;
 import static org.apache.mesos.Protos.Value.Type.SCALAR;
 

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/events/NotifyingSchedulingFilterTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/events/NotifyingSchedulingFilterTest.java b/src/test/java/org/apache/aurora/scheduler/events/NotifyingSchedulingFilterTest.java
index b9f9f52..1474fa9 100644
--- a/src/test/java/org/apache/aurora/scheduler/events/NotifyingSchedulingFilterTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/events/NotifyingSchedulingFilterTest.java
@@ -21,7 +21,6 @@ import org.apache.aurora.common.testing.easymock.EasyMockTest;
 import org.apache.aurora.gen.HostAttributes;
 import org.apache.aurora.gen.MaintenanceMode;
 import org.apache.aurora.gen.TaskConfig;
-import org.apache.aurora.scheduler.ResourceSlot;
 import org.apache.aurora.scheduler.base.TaskGroupKey;
 import org.apache.aurora.scheduler.events.PubsubEvent.Vetoed;
 import org.apache.aurora.scheduler.filter.AttributeAggregate;
@@ -29,6 +28,7 @@ import org.apache.aurora.scheduler.filter.SchedulingFilter;
 import org.apache.aurora.scheduler.filter.SchedulingFilter.ResourceRequest;
 import org.apache.aurora.scheduler.filter.SchedulingFilter.UnusedResource;
 import org.apache.aurora.scheduler.filter.SchedulingFilter.Veto;
+import org.apache.aurora.scheduler.resources.ResourceSlot;
 import org.apache.aurora.scheduler.storage.entities.IHostAttributes;
 import org.apache.aurora.scheduler.storage.entities.ITaskConfig;
 import org.junit.Before;

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/filter/SchedulingFilterImplTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/filter/SchedulingFilterImplTest.java b/src/test/java/org/apache/aurora/scheduler/filter/SchedulingFilterImplTest.java
index 17101f1..1d9d5fc 100644
--- a/src/test/java/org/apache/aurora/scheduler/filter/SchedulingFilterImplTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/filter/SchedulingFilterImplTest.java
@@ -32,8 +32,6 @@ import org.apache.aurora.gen.MaintenanceMode;
 import org.apache.aurora.gen.TaskConfig;
 import org.apache.aurora.gen.TaskConstraint;
 import org.apache.aurora.gen.ValueConstraint;
-import org.apache.aurora.scheduler.ResourceSlot;
-import org.apache.aurora.scheduler.Resources;
 import org.apache.aurora.scheduler.base.JobKeys;
 import org.apache.aurora.scheduler.filter.SchedulingFilter.ResourceRequest;
 import org.apache.aurora.scheduler.filter.SchedulingFilter.UnusedResource;
@@ -42,6 +40,8 @@ import org.apache.aurora.scheduler.filter.SchedulingFilter.VetoGroup;
 import org.apache.aurora.scheduler.filter.SchedulingFilter.VetoType;
 import org.apache.aurora.scheduler.mesos.Offers;
 import org.apache.aurora.scheduler.mesos.TaskExecutors;
+import org.apache.aurora.scheduler.resources.ResourceSlot;
+import org.apache.aurora.scheduler.resources.Resources;
 import org.apache.aurora.scheduler.storage.entities.IAttribute;
 import org.apache.aurora.scheduler.storage.entities.IHostAttributes;
 import org.apache.aurora.scheduler.storage.entities.IJobKey;

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/mesos/MesosTaskFactoryImplTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/mesos/MesosTaskFactoryImplTest.java b/src/test/java/org/apache/aurora/scheduler/mesos/MesosTaskFactoryImplTest.java
index 4f5ac15..bf18d5d 100644
--- a/src/test/java/org/apache/aurora/scheduler/mesos/MesosTaskFactoryImplTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/mesos/MesosTaskFactoryImplTest.java
@@ -29,14 +29,14 @@ import org.apache.aurora.gen.DockerParameter;
 import org.apache.aurora.gen.MesosContainer;
 import org.apache.aurora.gen.ServerInfo;
 import org.apache.aurora.gen.TaskConfig;
-import org.apache.aurora.scheduler.ResourceSlot;
-import org.apache.aurora.scheduler.ResourceType;
-import org.apache.aurora.scheduler.Resources;
 import org.apache.aurora.scheduler.TierManager;
 import org.apache.aurora.scheduler.base.TaskTestUtil;
 import org.apache.aurora.scheduler.configuration.executor.ExecutorConfig;
 import org.apache.aurora.scheduler.configuration.executor.ExecutorSettings;
 import org.apache.aurora.scheduler.mesos.MesosTaskFactory.MesosTaskFactoryImpl;
+import org.apache.aurora.scheduler.resources.ResourceSlot;
+import org.apache.aurora.scheduler.resources.ResourceType;
+import org.apache.aurora.scheduler.resources.Resources;
 import org.apache.aurora.scheduler.storage.entities.IAssignedTask;
 import org.apache.aurora.scheduler.storage.entities.IJobKey;
 import org.apache.aurora.scheduler.storage.entities.IServerInfo;
@@ -56,7 +56,6 @@ import org.apache.mesos.Protos.Volume.Mode;
 import org.junit.Before;
 import org.junit.Test;
 
-import static org.apache.aurora.scheduler.ResourceSlot.makeMesosRangeResource;
 import static org.apache.aurora.scheduler.base.TaskTestUtil.DEV_TIER;
 import static org.apache.aurora.scheduler.base.TaskTestUtil.REVOCABLE_TIER;
 import static org.apache.aurora.scheduler.mesos.MesosTaskFactory.MesosTaskFactoryImpl.DEFAULT_PORT_PROTOCOL;
@@ -66,6 +65,7 @@ import static org.apache.aurora.scheduler.mesos.TaskExecutors.NO_OVERHEAD_EXECUT
 import static org.apache.aurora.scheduler.mesos.TaskExecutors.SOME_OVERHEAD_EXECUTOR;
 import static org.apache.aurora.scheduler.mesos.TestExecutorSettings.THERMOS_CONFIG;
 import static org.apache.aurora.scheduler.mesos.TestExecutorSettings.THERMOS_EXECUTOR;
+import static org.apache.aurora.scheduler.resources.ResourceSlot.makeMesosRangeResource;
 import static org.easymock.EasyMock.expect;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/mesos/Offers.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/mesos/Offers.java b/src/test/java/org/apache/aurora/scheduler/mesos/Offers.java
index 13f41e3..a7fb4b0 100644
--- a/src/test/java/org/apache/aurora/scheduler/mesos/Offers.java
+++ b/src/test/java/org/apache/aurora/scheduler/mesos/Offers.java
@@ -24,10 +24,10 @@ import org.apache.mesos.Protos.Value.Ranges;
 import org.apache.mesos.Protos.Value.Scalar;
 import org.apache.mesos.Protos.Value.Type;
 
-import static org.apache.aurora.scheduler.ResourceType.CPUS;
-import static org.apache.aurora.scheduler.ResourceType.DISK_MB;
-import static org.apache.aurora.scheduler.ResourceType.PORTS;
-import static org.apache.aurora.scheduler.ResourceType.RAM_MB;
+import static org.apache.aurora.scheduler.resources.ResourceType.CPUS;
+import static org.apache.aurora.scheduler.resources.ResourceType.DISK_MB;
+import static org.apache.aurora.scheduler.resources.ResourceType.PORTS;
+import static org.apache.aurora.scheduler.resources.ResourceType.RAM_MB;
 
 public final class Offers {
   private Offers() {

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/mesos/TaskExecutors.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/mesos/TaskExecutors.java b/src/test/java/org/apache/aurora/scheduler/mesos/TaskExecutors.java
index 155ece4..651cfa7 100644
--- a/src/test/java/org/apache/aurora/scheduler/mesos/TaskExecutors.java
+++ b/src/test/java/org/apache/aurora/scheduler/mesos/TaskExecutors.java
@@ -15,8 +15,8 @@ package org.apache.aurora.scheduler.mesos;
 
 import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.common.quantity.Data;
-import org.apache.aurora.scheduler.ResourceSlot;
 import org.apache.aurora.scheduler.configuration.executor.ExecutorSettings;
+import org.apache.aurora.scheduler.resources.ResourceSlot;
 
 /**
  * Utility class to contain constants related to setting up executor settings.

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/preemptor/PreemptionVictimFilterTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/preemptor/PreemptionVictimFilterTest.java b/src/test/java/org/apache/aurora/scheduler/preemptor/PreemptionVictimFilterTest.java
index bb1b01e..0739877 100644
--- a/src/test/java/org/apache/aurora/scheduler/preemptor/PreemptionVictimFilterTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/preemptor/PreemptionVictimFilterTest.java
@@ -34,13 +34,13 @@ import org.apache.aurora.gen.ScheduledTask;
 import org.apache.aurora.gen.TaskConfig;
 import org.apache.aurora.gen.TaskEvent;
 import org.apache.aurora.scheduler.HostOffer;
-import org.apache.aurora.scheduler.ResourceSlot;
 import org.apache.aurora.scheduler.TierInfo;
 import org.apache.aurora.scheduler.TierManager;
 import org.apache.aurora.scheduler.filter.SchedulingFilter;
 import org.apache.aurora.scheduler.filter.SchedulingFilter.Veto;
 import org.apache.aurora.scheduler.filter.SchedulingFilterImpl;
 import org.apache.aurora.scheduler.mesos.TaskExecutors;
+import org.apache.aurora.scheduler.resources.ResourceSlot;
 import org.apache.aurora.scheduler.stats.CachedCounters;
 import org.apache.aurora.scheduler.storage.entities.IAssignedTask;
 import org.apache.aurora.scheduler.storage.entities.IHostAttributes;
@@ -55,12 +55,12 @@ import org.junit.Test;
 
 import static org.apache.aurora.gen.MaintenanceMode.NONE;
 import static org.apache.aurora.gen.ScheduleStatus.RUNNING;
-import static org.apache.aurora.scheduler.ResourceType.CPUS;
 import static org.apache.aurora.scheduler.base.TaskTestUtil.DEV_TIER;
 import static org.apache.aurora.scheduler.base.TaskTestUtil.PREFERRED_TIER;
 import static org.apache.aurora.scheduler.base.TaskTestUtil.REVOCABLE_TIER;
 import static org.apache.aurora.scheduler.filter.AttributeAggregate.EMPTY;
 import static org.apache.aurora.scheduler.preemptor.PreemptorMetrics.MISSING_ATTRIBUTES_NAME;
+import static org.apache.aurora.scheduler.resources.ResourceType.CPUS;
 import static org.apache.mesos.Protos.Offer;
 import static org.apache.mesos.Protos.Resource;
 import static org.easymock.EasyMock.expect;

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/quota/QuotaManagerImplTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/quota/QuotaManagerImplTest.java b/src/test/java/org/apache/aurora/scheduler/quota/QuotaManagerImplTest.java
index aedeab3..fc01821 100644
--- a/src/test/java/org/apache/aurora/scheduler/quota/QuotaManagerImplTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/quota/QuotaManagerImplTest.java
@@ -54,10 +54,10 @@ import org.easymock.IExpectationSetters;
 import org.junit.Before;
 import org.junit.Test;
 
-import static org.apache.aurora.scheduler.ResourceAggregates.EMPTY;
 import static org.apache.aurora.scheduler.quota.QuotaCheckResult.Result.INSUFFICIENT_QUOTA;
 import static org.apache.aurora.scheduler.quota.QuotaCheckResult.Result.SUFFICIENT_QUOTA;
 import static org.apache.aurora.scheduler.quota.QuotaManager.QuotaManagerImpl.updateQuery;
+import static org.apache.aurora.scheduler.resources.ResourceAggregates.EMPTY;
 import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.expect;
 import static org.junit.Assert.assertEquals;

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/resources/AcceptedOfferTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/resources/AcceptedOfferTest.java b/src/test/java/org/apache/aurora/scheduler/resources/AcceptedOfferTest.java
new file mode 100644
index 0000000..319ffea
--- /dev/null
+++ b/src/test/java/org/apache/aurora/scheduler/resources/AcceptedOfferTest.java
@@ -0,0 +1,305 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aurora.scheduler.resources;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import org.apache.aurora.common.quantity.Amount;
+import org.apache.aurora.common.quantity.Data;
+import org.apache.aurora.scheduler.TierInfo;
+import org.apache.aurora.scheduler.base.TaskTestUtil;
+import org.apache.mesos.Protos;
+import org.apache.mesos.Protos.Resource;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class AcceptedOfferTest {
+
+  private static final Optional<String> TEST_ROLE = Optional.of("test-role");
+  private static final Optional<String> ABSENT_ROLE = Optional.absent();
+  private static final ResourceSlot TASK_SLOT = new ResourceSlot(
+      4, Amount.of(100L, Data.MB), Amount.of(200L, Data.MB), 0);
+  private static final ResourceSlot EXECUTOR_SLOT = new ResourceSlot(
+      0.25, Amount.of(25L, Data.MB), Amount.of(75L, Data.MB), 0);
+  private static final ResourceSlot TOTAL_SLOT = EXECUTOR_SLOT.add(TASK_SLOT);
+  private static final Integer[] TASK_PORTS = {80, 90};
+  private static final Set<Integer> TASK_PORTS_SET = ImmutableSet.copyOf(TASK_PORTS);
+
+  @Test
+  public void testReservedPredicates() {
+    Protos.Resource withRole = makeScalar(ResourceType.CPUS.getName(), TEST_ROLE, false, 1.0);
+    assertTrue(AcceptedOffer.RESERVED.apply(withRole));
+    assertFalse(AcceptedOffer.NOT_RESERVED.apply(withRole));
+    Protos.Resource absentRole = makeScalar(ResourceType.CPUS.getName(), ABSENT_ROLE, false, 1.0);
+    assertFalse(AcceptedOffer.RESERVED.apply(absentRole));
+    assertTrue(AcceptedOffer.NOT_RESERVED.apply(absentRole));
+  }
+
+  @Test
+  public void testAllocateEmpty() {
+    AcceptedOffer acceptedOffer = AcceptedOffer.create(
+        fakeOffer(Collections.emptyList()),
+        ResourceSlot.NONE,
+        ResourceSlot.NONE,
+        ImmutableSet.of(),
+        TaskTestUtil.DEV_TIER);
+    assertEquals(Collections.emptyList(), acceptedOffer.getTaskResources());
+    assertEquals(Collections.emptyList(), acceptedOffer.getExecutorResources());
+  }
+
+  @Test
+  public void testAllocateRange() {
+    List<Resource> resources = ImmutableList.<Resource>builder()
+        .add(makePortResource(Optional.absent(), 80, 81, 90, 91, 92, 93))
+        .add(makePortResource(TEST_ROLE, 100, 101))
+        .build();
+    AcceptedOffer acceptedOffer = AcceptedOffer.create(
+        fakeOffer(resources),
+        ResourceSlot.NONE,
+        ResourceSlot.NONE,
+        ImmutableSet.of(80, 90, 100),
+        TaskTestUtil.DEV_TIER);
+
+    List<Resource> expected = ImmutableList.<Resource>builder()
+        // Because we prefer reserved resources and handle them before non-reserved resources,
+        // result should have ports for the reserved resources first.
+        .add(makePortResource(TEST_ROLE, 100))
+        .add(makePortResource(Optional.absent(), 80, 90))
+        .build();
+    assertEquals(expected, acceptedOffer.getTaskResources());
+    assertEquals(Collections.emptyList(), acceptedOffer.getExecutorResources());
+  }
+
+  @Test(expected = Resources.InsufficientResourcesException.class)
+  public void testAllocateRangeInsufficent() {
+    List<Resource> resources = ImmutableList.of(
+        makePortResource(ABSENT_ROLE, 80),
+        makePortResource(ABSENT_ROLE, 100, 101));
+    AcceptedOffer.create(
+        fakeOffer(resources),
+        ResourceSlot.NONE,
+        ResourceSlot.NONE,
+        ImmutableSet.of(80, 90, 100),
+        TaskTestUtil.DEV_TIER);
+  }
+
+  @Test
+  public void testAllocateSingleRole() {
+    runAllocateSingleRole(ABSENT_ROLE, false);
+    runAllocateSingleRole(ABSENT_ROLE, true);
+    runAllocateSingleRole(TEST_ROLE, false);
+    runAllocateSingleRole(TEST_ROLE, true);
+  }
+
+  private void runAllocateSingleRole(Optional<String> role, boolean cpuRevocable) {
+    List<Resource> resources = ImmutableList.<Resource>builder()
+        .add(makeScalar(
+            ResourceType.CPUS.getName(), role, cpuRevocable, TOTAL_SLOT.getNumCpus()))
+        .add(makeScalar(
+            ResourceType.RAM_MB.getName(), role, false, TOTAL_SLOT.getRam().as(Data.MB)))
+        .add(makeScalar(
+            ResourceType.DISK_MB.getName(), role, false, TOTAL_SLOT.getDisk().as(Data.MB)))
+        .add(makePortResource(role, TASK_PORTS))
+        .build();
+    Protos.Offer offer = fakeOffer(resources);
+
+    AcceptedOffer offerAllocation = AcceptedOffer.create(
+        offer, TASK_SLOT, EXECUTOR_SLOT, TASK_PORTS_SET, new TierInfo(false, cpuRevocable));
+
+    List<Resource> taskList = ImmutableList.<Resource>builder()
+        .add(makeScalar(ResourceType.CPUS.getName(), role, cpuRevocable, TASK_SLOT.getNumCpus()))
+        .add(makeScalar(ResourceType.RAM_MB.getName(), role, false, TASK_SLOT.getRam().as(Data.MB)))
+        .add(makeScalar(
+            ResourceType.DISK_MB.getName(), role, false, TASK_SLOT.getDisk().as(Data.MB)))
+        .add(makePortResource(role, TASK_PORTS))
+        .build();
+    assertEquals(taskList, offerAllocation.getTaskResources());
+
+    List<Resource> executorList = ImmutableList.<Resource>builder()
+        .add(makeScalar(
+            ResourceType.CPUS.getName(), role, cpuRevocable, EXECUTOR_SLOT.getNumCpus()))
+        .add(makeScalar(
+            ResourceType.RAM_MB.getName(), role, false, EXECUTOR_SLOT.getRam().as(Data.MB)))
+        .add(makeScalar(
+            ResourceType.DISK_MB.getName(), role, false, EXECUTOR_SLOT.getDisk().as(Data.MB)))
+        .build();
+    assertEquals(executorList, offerAllocation.getExecutorResources());
+  }
+
+  @Test(expected = Resources.InsufficientResourcesException.class)
+  public void testAllocateSingleRoleInsufficient() {
+    List<Resource> resources = ImmutableList.<Resource>builder()
+        // EXECUTOR_SLOT's CPU is not included here.
+        .add(makeScalar(ResourceType.CPUS.getName(), TEST_ROLE, false, TASK_SLOT.getNumCpus()))
+        .add(makeScalar(
+            ResourceType.RAM_MB.getName(), TEST_ROLE, false, TOTAL_SLOT.getRam().as(Data.MB)))
+        .add(makeScalar(
+            ResourceType.DISK_MB.getName(), TEST_ROLE, false, TOTAL_SLOT.getDisk().as(Data.MB)))
+        .add(makePortResource(TEST_ROLE, TASK_PORTS))
+        .build();
+    Protos.Offer offer = fakeOffer(resources);
+
+    AcceptedOffer.create(
+        offer, TASK_SLOT, EXECUTOR_SLOT, TASK_PORTS_SET, new TierInfo(false, false));
+  }
+
+  @Test
+  public void testMultipleRoles() {
+    runMultipleRoles(false);
+    runMultipleRoles(true);
+  }
+
+  private void runMultipleRoles(boolean cpuRevocable) {
+    List<Resource> resources = ImmutableList.<Resource>builder()
+        // Make cpus come from two roles.
+        .add(makeScalar(
+            ResourceType.CPUS.getName(),
+            TEST_ROLE,
+            cpuRevocable,
+            EXECUTOR_SLOT.getNumCpus()))
+        .add(makeScalar(
+            ResourceType.CPUS.getName(),
+            ABSENT_ROLE,
+            cpuRevocable,
+            TASK_SLOT.getNumCpus()))
+        // Make ram come from default role
+        .add(makeScalar(
+            ResourceType.RAM_MB.getName(),
+            ABSENT_ROLE,
+            false,
+            TOTAL_SLOT.getRam().as(Data.MB)))
+        // Make disk come from non-default role.
+        .add(makeScalar(
+            ResourceType.DISK_MB.getName(),
+            TEST_ROLE,
+            false,
+            TOTAL_SLOT.getDisk().as(Data.MB)))
+        .add(makePortResource(TEST_ROLE, 80))
+        .add(makePortResource(ABSENT_ROLE, 90))
+        .build();
+
+    Protos.Offer offer = fakeOffer(resources);
+
+    AcceptedOffer offerAllocation = AcceptedOffer.create(
+        offer, TASK_SLOT, EXECUTOR_SLOT, TASK_PORTS_SET, new TierInfo(false, cpuRevocable));
+
+    List<Resource> taskList = ImmutableList.<Resource>builder()
+        // We intentionally sliced the offer resource to not align with TASK_SLOT's num cpus.
+        .add(makeScalar(
+            ResourceType.CPUS.getName(), TEST_ROLE, cpuRevocable, EXECUTOR_SLOT.getNumCpus()))
+        .add(makeScalar(
+            ResourceType.CPUS.getName(),
+            ABSENT_ROLE,
+            cpuRevocable,
+            TASK_SLOT.subtract(EXECUTOR_SLOT).getNumCpus()))
+        .add(makeScalar(
+            ResourceType.RAM_MB.getName(), ABSENT_ROLE, false, TASK_SLOT.getRam().as(Data.MB)))
+        .add(makeScalar(
+            ResourceType.DISK_MB.getName(), TEST_ROLE, false, TASK_SLOT.getDisk().as(Data.MB)))
+        .add(makePortResource(TEST_ROLE, 80))
+        .add(makePortResource(ABSENT_ROLE, 90))
+        .build();
+    assertEquals(taskList, offerAllocation.getTaskResources());
+
+    List<Resource> executorList = ImmutableList.<Resource>builder()
+        .add(makeScalar(
+            ResourceType.CPUS.getName(), ABSENT_ROLE, cpuRevocable, EXECUTOR_SLOT.getNumCpus()))
+        .add(makeScalar(
+            ResourceType.RAM_MB.getName(), ABSENT_ROLE, false, EXECUTOR_SLOT.getRam().as(Data.MB)))
+        .add(makeScalar(
+            ResourceType.DISK_MB.getName(), TEST_ROLE, false, EXECUTOR_SLOT.getDisk().as(Data.MB)))
+        .build();
+    assertEquals(executorList, offerAllocation.getExecutorResources());
+  }
+
+  @Test(expected = Resources.InsufficientResourcesException.class)
+  public void testMultipleRolesInsufficient() {
+    // Similar to testMultipleRoles, but make some of cpus as revocable
+    List<Resource> resources = ImmutableList.<Resource>builder()
+        // Make cpus come from two roles.
+        .add(makeScalar(
+            ResourceType.CPUS.getName(),
+            TEST_ROLE,
+            true,
+            EXECUTOR_SLOT.getNumCpus()))
+        .add(makeScalar(
+            ResourceType.CPUS.getName(),
+            ABSENT_ROLE,
+            false,
+            TASK_SLOT.getNumCpus()))
+        // Make ram come from default role
+        .add(makeScalar(
+            ResourceType.RAM_MB.getName(),
+            ABSENT_ROLE,
+            false,
+            TOTAL_SLOT.getRam().as(Data.MB)))
+        // Make disk come from non-default role.
+        .add(makeScalar(
+            ResourceType.DISK_MB.getName(),
+            TEST_ROLE,
+            false,
+            TOTAL_SLOT.getDisk().as(Data.MB)))
+        .add(makePortResource(TEST_ROLE, 80))
+        .add(makePortResource(ABSENT_ROLE, 90))
+        .build();
+    Protos.Offer offer = fakeOffer(resources);
+    // We don't have enough resource to satisfy a non-revocable request.
+    AcceptedOffer.create(
+        offer, TASK_SLOT, EXECUTOR_SLOT, TASK_PORTS_SET, new TierInfo(false, false));
+  }
+
+  private static Resource makePortResource(Optional<String> role, Integer... values) {
+    Resource.Builder prototype = Resource.newBuilder()
+        .setType(Protos.Value.Type.RANGES)
+        .setName(ResourceType.PORTS.getName());
+    if (role.isPresent()) {
+      prototype.setRole(role.get());
+    }
+    return AcceptedOffer.makeMesosRangeResource(prototype.build(), ImmutableSet.copyOf(values));
+  }
+
+  private static Resource makeScalar(
+      String name, Optional<String> role, boolean revocable, double value) {
+    Resource.Builder resource = Resource.newBuilder()
+        .setName(name)
+        .setType(Protos.Value.Type.SCALAR)
+        .setScalar(Protos.Value.Scalar.newBuilder().setValue(value));
+    if (role.isPresent()) {
+      resource.setRole(role.get());
+    }
+    if (revocable) {
+      resource.setRevocable(Resource.RevocableInfo.getDefaultInstance());
+    }
+    return resource.build();
+  }
+
+  private static Protos.Offer fakeOffer(List<Resource> resources) {
+    return Protos.Offer.newBuilder()
+        .setId(Protos.OfferID.newBuilder().setValue("offer-id"))
+        .setFrameworkId(Protos.FrameworkID.newBuilder().setValue("framework-id"))
+        .setSlaveId(Protos.SlaveID.newBuilder().setValue("slave-id"))
+        .setHostname("hostname")
+        .addAllResources(resources)
+        .build();
+  }
+}

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/resources/ResourceSlotTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/resources/ResourceSlotTest.java b/src/test/java/org/apache/aurora/scheduler/resources/ResourceSlotTest.java
new file mode 100644
index 0000000..8d5a143
--- /dev/null
+++ b/src/test/java/org/apache/aurora/scheduler/resources/ResourceSlotTest.java
@@ -0,0 +1,170 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aurora.scheduler.resources;
+
+import java.util.Set;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+import org.apache.aurora.common.collections.Pair;
+import org.apache.aurora.common.quantity.Amount;
+import org.apache.aurora.common.quantity.Data;
+import org.apache.aurora.gen.TaskConfig;
+import org.apache.aurora.scheduler.storage.entities.ITaskConfig;
+import org.apache.mesos.Protos;
+import org.junit.Test;
+
+import static org.apache.aurora.scheduler.base.TaskTestUtil.DEV_TIER;
+import static org.apache.aurora.scheduler.base.TaskTestUtil.REVOCABLE_TIER;
+import static org.apache.aurora.scheduler.resources.ResourceSlot.makeMesosRangeResource;
+import static org.apache.aurora.scheduler.resources.ResourceSlot.makeMesosResource;
+import static org.apache.aurora.scheduler.resources.ResourceSlot.sum;
+import static org.apache.aurora.scheduler.resources.ResourceType.CPUS;
+import static org.apache.aurora.scheduler.resources.ResourceType.DISK_MB;
+import static org.apache.aurora.scheduler.resources.ResourceType.PORTS;
+import static org.apache.aurora.scheduler.resources.ResourceType.RAM_MB;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+public class ResourceSlotTest {
+
+  private static final ResourceSlot NEGATIVE_ONE =
+      new ResourceSlot(-1.0, Amount.of(-1L, Data.MB), Amount.of(-1L, Data.MB), -1);
+  private static final ResourceSlot ONE =
+      new ResourceSlot(1.0, Amount.of(1L, Data.MB), Amount.of(1L, Data.MB), 1);
+  private static final ResourceSlot TWO =
+      new ResourceSlot(2.0, Amount.of(2L, Data.MB), Amount.of(2L, Data.MB), 2);
+  private static final ResourceSlot THREE =
+      new ResourceSlot(3.0, Amount.of(3L, Data.MB), Amount.of(3L, Data.MB), 3);
+  private static final ITaskConfig TASK = ITaskConfig.build(new TaskConfig()
+      .setNumCpus(1.0)
+      .setRamMb(1024)
+      .setDiskMb(2048)
+      .setRequestedPorts(ImmutableSet.of("http", "debug")));
+
+  @Test
+  public void testMaxElements() {
+    ResourceSlot highRAM = new ResourceSlot(1, Amount.of(8L, Data.GB), Amount.of(10L, Data.MB), 0);
+    ResourceSlot rest = new ResourceSlot(10, Amount.of(1L, Data.MB), Amount.of(10L, Data.GB), 1);
+
+    ResourceSlot result = ResourceSlot.maxElements(highRAM, rest);
+    assertEquals(result.getNumCpus(), 10, 0.001);
+    assertEquals(result.getRam(), Amount.of(8L, Data.GB));
+    assertEquals(result.getDisk(), Amount.of(10L, Data.GB));
+    assertEquals(result.getNumPorts(), 1);
+  }
+
+  @Test
+  public void testSubtract() {
+    assertEquals(ONE, TWO.subtract(ONE));
+    assertEquals(TWO, THREE.subtract(ONE));
+    assertEquals(NEGATIVE_ONE, ONE.subtract(TWO));
+    assertEquals(NEGATIVE_ONE, TWO.subtract(THREE));
+  }
+
+  @Test
+  public void testAdd() {
+    assertEquals(TWO, ONE.add(ONE));
+    assertEquals(THREE, ONE.add(TWO));
+    assertEquals(THREE, TWO.add(ONE));
+  }
+
+  @Test
+  public void testSum() {
+    assertEquals(THREE, sum(ImmutableList.of(ONE, ONE, ONE)));
+  }
+
+  @Test
+  public void testToResourceListNoRevoca() {
+    ResourceSlot resources = ResourceSlot.from(TASK);
+    assertEquals(
+        ImmutableSet.of(
+            makeMesosResource(CPUS, TASK.getNumCpus(), false),
+            makeMesosResource(RAM_MB, TASK.getRamMb(), false),
+            makeMesosResource(DISK_MB, TASK.getDiskMb(), false)),
+        ImmutableSet.copyOf(resources.toResourceList(DEV_TIER)));
+  }
+
+  @Test
+  public void testToResourceListRevocable() {
+    ResourceSlot resources = ResourceSlot.from(TASK);
+    assertEquals(
+        ImmutableSet.of(
+            makeMesosResource(CPUS, TASK.getNumCpus(), true),
+            makeMesosResource(RAM_MB, TASK.getRamMb(), false),
+            makeMesosResource(DISK_MB, TASK.getDiskMb(), false)),
+        ImmutableSet.copyOf(resources.toResourceList(REVOCABLE_TIER)));
+  }
+
+  @Test
+  public void testToResourceListNoPorts() {
+    ResourceSlot resources = ResourceSlot.from(TASK);
+    assertEquals(
+        ImmutableSet.of(
+            makeMesosResource(CPUS, TASK.getNumCpus(), true),
+            makeMesosResource(RAM_MB, TASK.getRamMb(), false),
+            makeMesosResource(DISK_MB, TASK.getDiskMb(), false)),
+        ImmutableSet.copyOf(resources.toResourceList(REVOCABLE_TIER)));
+  }
+
+  @Test
+  public void testRangeResourceEmpty() {
+    expectRanges(ImmutableSet.of(), ImmutableSet.of());
+  }
+
+  @Test
+  public void testRangeResourceOneEntry() {
+    expectRanges(ImmutableSet.of(Pair.of(5L, 5L)), ImmutableSet.of(5));
+    expectRanges(ImmutableSet.of(Pair.of(0L, 0L)), ImmutableSet.of(0));
+  }
+
+  @Test
+  public void testRangeResourceNonContiguous() {
+    expectRanges(ImmutableSet.of(Pair.of(1L, 1L), Pair.of(3L, 3L), Pair.of(5L, 5L)),
+        ImmutableSet.of(5, 1, 3));
+  }
+
+  @Test
+  public void testRangeResourceContiguous() {
+    expectRanges(ImmutableSet.of(Pair.of(1L, 2L), Pair.of(4L, 5L), Pair.of(7L, 9L)),
+        ImmutableSet.of(8, 2, 4, 5, 7, 9, 1));
+  }
+
+  @Test
+  public void testEqualsBadType() {
+    ResourceSlot resources = ResourceSlot.from(TASK);
+    assertNotEquals(resources, "Hello");
+    assertNotEquals(resources, null);
+  }
+
+  @Test
+  public void testOrder() {
+    assertEquals(
+        ImmutableList.of(ONE, TWO, THREE, THREE),
+        ResourceSlot.ORDER.sortedCopy(ImmutableList.of(THREE, ONE, TWO, THREE)));
+  }
+
+  private void expectRanges(Set<Pair<Long, Long>> expected, Set<Integer> values) {
+    Protos.Resource resource = makeMesosRangeResource(PORTS, values);
+    assertEquals(Protos.Value.Type.RANGES, resource.getType());
+    assertEquals(PORTS.getName(), resource.getName());
+
+    Set<Pair<Long, Long>> actual = ImmutableSet.copyOf(Iterables.transform(
+        resource.getRanges().getRangeList(),
+        range -> Pair.of(range.getBegin(), range.getEnd())));
+    assertEquals(expected, actual);
+  }
+}

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/resources/ResourcesTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/resources/ResourcesTest.java b/src/test/java/org/apache/aurora/scheduler/resources/ResourcesTest.java
new file mode 100644
index 0000000..bc2700c
--- /dev/null
+++ b/src/test/java/org/apache/aurora/scheduler/resources/ResourcesTest.java
@@ -0,0 +1,176 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aurora.scheduler.resources;
+
+import java.util.Set;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import org.apache.aurora.common.collections.Pair;
+import org.apache.aurora.common.quantity.Amount;
+import org.apache.aurora.scheduler.resources.Resources.InsufficientResourcesException;
+import org.apache.mesos.Protos;
+import org.apache.mesos.Protos.Resource;
+import org.apache.mesos.Protos.Value.Range;
+import org.apache.mesos.Protos.Value.Ranges;
+import org.junit.Test;
+
+import static org.apache.aurora.common.quantity.Data.MB;
+import static org.apache.aurora.scheduler.base.TaskTestUtil.DEV_TIER;
+import static org.apache.aurora.scheduler.base.TaskTestUtil.REVOCABLE_TIER;
+import static org.apache.aurora.scheduler.resources.ResourceSlot.makeMesosResource;
+import static org.apache.aurora.scheduler.resources.ResourceType.CPUS;
+import static org.apache.aurora.scheduler.resources.ResourceType.DISK_MB;
+import static org.apache.aurora.scheduler.resources.ResourceType.PORTS;
+import static org.apache.aurora.scheduler.resources.ResourceType.RAM_MB;
+import static org.apache.mesos.Protos.Value.Type.RANGES;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class ResourcesTest {
+  @Test
+  public void testPortRangeExact() {
+    Resource portsResource = createPortRange(Pair.of(1, 5));
+    Set<Integer> ports = Resources.from(createOffer(portsResource)).getPorts(5);
+    assertEquals(5, ports.size());
+  }
+
+  @Test
+  public void testOnePortAvailable() {
+    Resource portsResource = createPortRange(Pair.of(3, 3));
+    Set<Integer> ports = Resources.from(createOffer(portsResource)).getPorts(1);
+    assertEquals(1, ports.size());
+  }
+
+  @Test
+  public void testPortRangeAbundance() {
+    Resource portsResource = createPortRange(Pair.of(1, 10));
+    Set<Integer> ports = Resources.from(createOffer(portsResource)).getPorts(5);
+    assertEquals(5, ports.size());
+  }
+
+  @Test
+  public void testPortRangeExhaust() {
+    Resource portsResource = createPortRanges(Pair.of(1, 2), Pair.of(10, 15));
+
+    Set<Integer> ports = Resources.from(createOffer(portsResource)).getPorts(7);
+    assertEquals(7, ports.size());
+
+    ports = Resources.from(createOffer(portsResource)).getPorts(8);
+    assertEquals(8, ports.size());
+
+    try {
+      Resources.from(createOffer(portsResource)).getPorts(9);
+      fail("Ports should not have been sufficient");
+    } catch (InsufficientResourcesException e) {
+      // Expected.
+    }
+  }
+
+  @Test
+  public void testGetNoPorts() {
+    Resource portsResource = createPortRange(Pair.of(1, 5));
+    assertEquals(ImmutableSet.of(), Resources.from(createOffer(portsResource)).getPorts(0));
+  }
+
+  @Test(expected = Resources.InsufficientResourcesException.class)
+  public void testPortRangeScarcity() {
+    Resource portsResource = createPortRange(Pair.of(1, 2));
+    Resources.from(createOffer(portsResource)).getPorts(5);
+  }
+
+  @Test
+  public void testGetSlot() {
+    ImmutableList<Resource> resources = ImmutableList.<Resource>builder()
+        .add(makeMesosResource(CPUS, 8.0, false))
+        .add(makeMesosResource(RAM_MB, 1024, false))
+        .add(makeMesosResource(DISK_MB, 2048, false))
+        .add(createPortRange(Pair.of(1, 10)))
+        .build();
+
+    ResourceSlot expected = new ResourceSlot(8.0, Amount.of(1024L, MB), Amount.of(2048L, MB), 10);
+    assertEquals(expected, Resources.from(createOffer(resources)).slot());
+  }
+
+  @Test
+  public void testMissingResourcesHandledGracefully() {
+    ImmutableList<Resource> resources = ImmutableList.<Resource>builder().build();
+    assertEquals(ResourceSlot.NONE, Resources.from(createOffer(resources)).slot());
+  }
+
+  @Test
+  public void testFilter() {
+    ImmutableList<Resource> resources = ImmutableList.<Resource>builder()
+        .add(makeMesosResource(CPUS, 8.0, true))
+        .add(makeMesosResource(RAM_MB, 1024, false))
+        .build();
+
+    assertEquals(
+        new ResourceSlot(8.0, Amount.of(1024L, MB), Amount.of(0L, MB), 0),
+        Resources.from(createOffer(resources)).filter(Resources.REVOCABLE).slot());
+  }
+
+  @Test
+  public void testFilterByTier() {
+    ImmutableList<Resource> resources = ImmutableList.<Resource>builder()
+        .add(makeMesosResource(CPUS, 8.0, true))
+        .add(makeMesosResource(CPUS, 8.0, false))
+        .add(makeMesosResource(RAM_MB, 1024, false))
+        .build();
+
+    assertEquals(
+        new ResourceSlot(8.0, Amount.of(1024L, MB), Amount.of(0L, MB), 0),
+        Resources.from(createOffer(resources)).filter(REVOCABLE_TIER).slot());
+
+    assertEquals(
+        new ResourceSlot(8.0, Amount.of(1024L, MB), Amount.of(0L, MB), 0),
+        Resources.from(createOffer(resources)).filter(DEV_TIER).slot());
+  }
+
+  private Resource createPortRange(Pair<Integer, Integer> range) {
+    return createPortRanges(ImmutableSet.of(range));
+  }
+
+  private Resource createPortRanges(Pair<Integer, Integer> rangeA, Pair<Integer, Integer> rangeB) {
+    return createPortRanges(
+        ImmutableSet.<Pair<Integer, Integer>>builder().add(rangeA).add(rangeB).build());
+  }
+
+  private Resource createPortRanges(Set<Pair<Integer, Integer>> ports) {
+    Ranges.Builder ranges = Ranges.newBuilder();
+    for (Pair<Integer, Integer> range : ports) {
+      ranges.addRange(Range.newBuilder().setBegin(range.getFirst()).setEnd(range.getSecond()));
+    }
+
+    return Resource.newBuilder()
+        .setName(PORTS.getName())
+        .setType(RANGES)
+        .setRanges(ranges)
+        .build();
+  }
+
+  private static Protos.Offer createOffer(Resource resource) {
+    return createOffer(ImmutableList.of(resource));
+  }
+
+  private static Protos.Offer createOffer(Iterable<Resource> resources) {
+    return Protos.Offer.newBuilder()
+        .setId(Protos.OfferID.newBuilder().setValue("offer-id"))
+        .setFrameworkId(Protos.FrameworkID.newBuilder().setValue("framework-id"))
+        .setSlaveId(Protos.SlaveID.newBuilder().setValue("slave-id"))
+        .setHostname("hostname")
+        .addAllResources(resources).build();
+  }
+}

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/state/TaskAssignerImplTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/state/TaskAssignerImplTest.java b/src/test/java/org/apache/aurora/scheduler/state/TaskAssignerImplTest.java
index 0698f78..a2df311 100644
--- a/src/test/java/org/apache/aurora/scheduler/state/TaskAssignerImplTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/state/TaskAssignerImplTest.java
@@ -27,7 +27,6 @@ import org.apache.aurora.gen.JobKey;
 import org.apache.aurora.gen.ScheduledTask;
 import org.apache.aurora.gen.TaskConfig;
 import org.apache.aurora.scheduler.HostOffer;
-import org.apache.aurora.scheduler.Resources;
 import org.apache.aurora.scheduler.TierManager;
 import org.apache.aurora.scheduler.base.TaskGroupKey;
 import org.apache.aurora.scheduler.base.Tasks;
@@ -37,6 +36,7 @@ import org.apache.aurora.scheduler.filter.SchedulingFilter.UnusedResource;
 import org.apache.aurora.scheduler.filter.SchedulingFilter.Veto;
 import org.apache.aurora.scheduler.mesos.MesosTaskFactory;
 import org.apache.aurora.scheduler.offers.OfferManager;
+import org.apache.aurora.scheduler.resources.Resources;
 import org.apache.aurora.scheduler.state.TaskAssigner.TaskAssignerImpl;
 import org.apache.aurora.scheduler.storage.entities.IHostAttributes;
 import org.apache.aurora.scheduler.storage.entities.IScheduledTask;

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/stats/AsyncStatsModuleTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/stats/AsyncStatsModuleTest.java b/src/test/java/org/apache/aurora/scheduler/stats/AsyncStatsModuleTest.java
index f6bbbb8..c23efed 100644
--- a/src/test/java/org/apache/aurora/scheduler/stats/AsyncStatsModuleTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/stats/AsyncStatsModuleTest.java
@@ -19,8 +19,8 @@ import org.apache.aurora.common.testing.easymock.EasyMockTest;
 import org.apache.aurora.gen.HostAttributes;
 import org.apache.aurora.gen.ResourceAggregate;
 import org.apache.aurora.scheduler.HostOffer;
-import org.apache.aurora.scheduler.ResourceType;
 import org.apache.aurora.scheduler.offers.OfferManager;
+import org.apache.aurora.scheduler.resources.ResourceType;
 import org.apache.aurora.scheduler.stats.SlotSizeCounter.MachineResource;
 import org.apache.aurora.scheduler.storage.entities.IHostAttributes;
 import org.apache.aurora.scheduler.storage.entities.IResourceAggregate;

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/stats/SlotSizeCounterTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/stats/SlotSizeCounterTest.java b/src/test/java/org/apache/aurora/scheduler/stats/SlotSizeCounterTest.java
index 6af1fff..bbf1097 100644
--- a/src/test/java/org/apache/aurora/scheduler/stats/SlotSizeCounterTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/stats/SlotSizeCounterTest.java
@@ -22,7 +22,7 @@ import com.google.common.collect.ImmutableMap;
 import org.apache.aurora.common.stats.StatsProvider;
 import org.apache.aurora.common.testing.easymock.EasyMockTest;
 import org.apache.aurora.gen.ResourceAggregate;
-import org.apache.aurora.scheduler.ResourceAggregates;
+import org.apache.aurora.scheduler.resources.ResourceAggregates;
 import org.apache.aurora.scheduler.stats.SlotSizeCounter.MachineResource;
 import org.apache.aurora.scheduler.stats.SlotSizeCounter.MachineResourceProvider;
 import org.apache.aurora.scheduler.storage.entities.IResourceAggregate;

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImplIT.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImplIT.java b/src/test/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImplIT.java
index b5fd204..ff9c1d0 100644
--- a/src/test/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImplIT.java
+++ b/src/test/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImplIT.java
@@ -49,9 +49,9 @@ import org.apache.aurora.gen.storage.SchedulerMetadata;
 import org.apache.aurora.gen.storage.Snapshot;
 import org.apache.aurora.gen.storage.StoredCronJob;
 import org.apache.aurora.gen.storage.StoredJobUpdateDetails;
-import org.apache.aurora.scheduler.ResourceAggregates;
 import org.apache.aurora.scheduler.base.JobKeys;
 import org.apache.aurora.scheduler.base.TaskTestUtil;
+import org.apache.aurora.scheduler.resources.ResourceAggregates;
 import org.apache.aurora.scheduler.storage.SnapshotStore;
 import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.db.MigrationManager;

http://git-wip-us.apache.org/repos/asf/aurora/blob/46ce98d8/src/test/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImplTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImplTest.java b/src/test/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImplTest.java
index c3240cd..50a1fdb 100644
--- a/src/test/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImplTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImplTest.java
@@ -89,12 +89,12 @@ import org.junit.Before;
 import org.junit.Test;
 
 import static org.apache.aurora.gen.ResponseCode.INVALID_REQUEST;
-import static org.apache.aurora.scheduler.ResourceAggregates.LARGE;
-import static org.apache.aurora.scheduler.ResourceAggregates.MEDIUM;
-import static org.apache.aurora.scheduler.ResourceAggregates.SMALL;
-import static org.apache.aurora.scheduler.ResourceAggregates.XLARGE;
 import static org.apache.aurora.scheduler.base.Numbers.convertRanges;
 import static org.apache.aurora.scheduler.base.Numbers.toRanges;
+import static org.apache.aurora.scheduler.resources.ResourceAggregates.LARGE;
+import static org.apache.aurora.scheduler.resources.ResourceAggregates.MEDIUM;
+import static org.apache.aurora.scheduler.resources.ResourceAggregates.SMALL;
+import static org.apache.aurora.scheduler.resources.ResourceAggregates.XLARGE;
 import static org.apache.aurora.scheduler.thrift.Fixtures.CRON_JOB;
 import static org.apache.aurora.scheduler.thrift.Fixtures.CRON_SCHEDULE;
 import static org.apache.aurora.scheduler.thrift.Fixtures.IDENTITY;


Mime
View raw message