|
@@ -466,6 +466,83 @@ public class TestNodeLabelContainerAllocation {
|
|
|
rm1.close();
|
|
|
}
|
|
|
|
|
|
+ @Test (timeout = 120000)
|
|
|
+ public void testContainerReservationWithLabels() throws Exception {
|
|
|
+ // This test is pretty much similar to testContainerAllocateWithLabel.
|
|
|
+ // Difference is, this test doesn't specify label expression in
|
|
|
+ // ResourceRequest,
|
|
|
+ // instead, it uses default queue label expression
|
|
|
+
|
|
|
+ // set node -> label
|
|
|
+ mgr.addToCluserNodeLabelsWithDefaultExclusivity(ImmutableSet.of("x", "y",
|
|
|
+ "z"));
|
|
|
+ mgr.addLabelsToNode(ImmutableMap.of(NodeId.newInstance("h1", 0),
|
|
|
+ toSet("x"), NodeId.newInstance("h2", 0), toSet("y"),
|
|
|
+ NodeId.newInstance("h3", 0), toSet("x")));
|
|
|
+
|
|
|
+ // inject node label manager
|
|
|
+ MockRM rm1 = new MockRM(
|
|
|
+ TestUtils.getConfigurationWithDefaultQueueLabels(conf)) {
|
|
|
+ @Override
|
|
|
+ public RMNodeLabelsManager createNodeLabelManager() {
|
|
|
+ return mgr;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ rm1.getRMContext().setNodeLabelManager(mgr);
|
|
|
+ rm1.start();
|
|
|
+ MockNM nm1 = rm1.registerNode("h1:1234", 8 * GB); // label = x
|
|
|
+ rm1.registerNode("h2:1234", 8 * GB); // label = y
|
|
|
+ rm1.registerNode("h3:1234", 8 * GB); // label = x
|
|
|
+
|
|
|
+ ContainerId containerId;
|
|
|
+
|
|
|
+ // launch an app to queue a1 (label = x), and check all container will
|
|
|
+ // be allocated in h1
|
|
|
+ RMApp app1 = rm1.submitApp(1 * GB, "app", "user", null, "a1");
|
|
|
+ MockAM am1 = MockRM.launchAndRegisterAM(app1, rm1, nm1);
|
|
|
+
|
|
|
+ // request a container.
|
|
|
+ am1.allocate("*", 4 * GB, 2, new ArrayList<ContainerId>());
|
|
|
+ containerId = ContainerId.newContainerId(am1.getApplicationAttemptId(), 2);
|
|
|
+
|
|
|
+ CapacityScheduler cs = (CapacityScheduler) rm1.getResourceScheduler();
|
|
|
+ RMNode rmNode1 = rm1.getRMContext().getRMNodes().get(nm1.getNodeId());
|
|
|
+ LeafQueue leafQueue = (LeafQueue) cs.getQueue("a1");
|
|
|
+
|
|
|
+ // Do node heartbeats 2 times
|
|
|
+ // First time will allocate container for app1, second time will reserve
|
|
|
+ // container for app1
|
|
|
+ cs.handle(new NodeUpdateSchedulerEvent(rmNode1));
|
|
|
+ cs.handle(new NodeUpdateSchedulerEvent(rmNode1));
|
|
|
+ checkTaskContainersHost(am1.getApplicationAttemptId(), containerId, rm1,
|
|
|
+ "h1");
|
|
|
+
|
|
|
+ // Check if a 4G container allocated for app1, and 4G is reserved
|
|
|
+ FiCaSchedulerApp schedulerApp1 = cs.getApplicationAttempt(am1
|
|
|
+ .getApplicationAttemptId());
|
|
|
+ Assert.assertEquals(2, schedulerApp1.getLiveContainers().size());
|
|
|
+ Assert.assertTrue(schedulerApp1.getReservedContainers().size() > 0);
|
|
|
+ Assert.assertEquals(9 * GB, cs.getRootQueue().getQueueResourceUsage()
|
|
|
+ .getUsed("x").getMemorySize());
|
|
|
+ Assert.assertEquals(4 * GB, cs.getRootQueue().getQueueResourceUsage()
|
|
|
+ .getReserved("x").getMemorySize());
|
|
|
+ Assert.assertEquals(4 * GB,
|
|
|
+ leafQueue.getQueueResourceUsage().getReserved("x").getMemorySize());
|
|
|
+
|
|
|
+ // Cancel asks of app2 and re-kick RM
|
|
|
+ am1.allocate("*", 4 * GB, 0, new ArrayList<ContainerId>());
|
|
|
+ cs.handle(new NodeUpdateSchedulerEvent(rmNode1));
|
|
|
+
|
|
|
+ Assert.assertEquals(5 * GB, cs.getRootQueue().getQueueResourceUsage()
|
|
|
+ .getUsed("x").getMemorySize());
|
|
|
+ Assert.assertEquals(0, cs.getRootQueue().getQueueResourceUsage()
|
|
|
+ .getReserved("x").getMemorySize());
|
|
|
+ Assert.assertEquals(0, leafQueue.getQueueResourceUsage().getReserved("x")
|
|
|
+ .getMemorySize());
|
|
|
+ rm1.close();
|
|
|
+ }
|
|
|
+
|
|
|
private void checkPendingResource(MockRM rm, int priority,
|
|
|
ApplicationAttemptId attemptId, int memory) {
|
|
|
CapacityScheduler cs = (CapacityScheduler) rm.getRMContext().getScheduler();
|