diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSLeafQueue.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSLeafQueue.java index 7e4dab8..394eb0d 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSLeafQueue.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSLeafQueue.java @@ -638,6 +638,21 @@ protected void dumpStateInternal(StringBuilder sb) { "}"); } + @Override + public boolean isEmpty() { + int appNum = 0; + readLock.lock(); + try { + appNum += runnableApps.size(); + appNum += nonRunnableApps.size(); + appNum += assignedApps.size(); + } finally { + readLock.unlock(); + } + + return appNum == 0; + } + /** * This method is called when an application is assigned to this queue * for book-keeping purposes (to be able to determine if the queue is empty). @@ -651,4 +666,18 @@ public void addAssignedApp(ApplicationId applicationId) { writeLock.unlock(); } } + + /** + * This method is called when an application is removed from this queue + * during the submit process. + * @param applicationId the application's id + */ + public void removeAssignedApp(ApplicationId applicationId) { + writeLock.lock(); + try { + assignedApps.remove(applicationId); + } finally { + writeLock.unlock(); + } + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSParentQueue.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSParentQueue.java index e9f4af6..8edbdf8 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSParentQueue.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSParentQueue.java @@ -309,4 +309,19 @@ protected void dumpStateInternal(StringBuilder sb) { child.dumpStateInternal(sb); } } + + @Override + public boolean isEmpty() { + readLock.lock(); + try { + for (FSQueue child : getChildQueues()) { + if (!child.isEmpty()) { + return false; + } + } + } finally { + readLock.unlock(); + } + return true; + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSQueue.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSQueue.java index 6217f55..28e793b 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSQueue.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSQueue.java @@ -601,4 +601,11 @@ public boolean isDynamic() { public void setDynamic(boolean dynamic) { this.isDynamic = dynamic; } + + /** + * Returns true if there are no applications, running or not, in the + * queue or any of its descendants. + * @return true if there is no application in the queue + */ + public abstract boolean isEmpty(); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java index da5e4c9..e5d2a06 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java @@ -473,7 +473,7 @@ protected void addApplication(ApplicationId applicationId, writeLock.lock(); try { RMApp rmApp = rmContext.getRMApps().get(applicationId); - FSLeafQueue queue = assignToQueue(rmApp, queueName, user); + FSLeafQueue queue = assignToQueue(rmApp, queueName, user, applicationId); if (queue == null) { return; } @@ -499,6 +499,7 @@ protected void addApplication(ApplicationId applicationId, applicationId, queue.getName(), invalidAMResourceRequests, queue.getMaxShare()); rejectApplicationWithMessage(applicationId, msg); + queue.removeAssignedApp(applicationId); return; } } @@ -513,6 +514,7 @@ protected void addApplication(ApplicationId applicationId, + " cannot submit applications to queue " + queue.getName() + "(requested queuename is " + queueName + ")"; rejectApplicationWithMessage(applicationId, msg); + queue.removeAssignedApp(applicationId); return; } @@ -520,7 +522,6 @@ protected void addApplication(ApplicationId applicationId, new SchedulerApplication(queue, user); applications.put(applicationId, application); queue.getMetrics().submitApp(user); - queue.addAssignedApp(applicationId); LOG.info("Accepted application " + applicationId + " from user: " + user + ", in queue: " + queue.getName() @@ -597,11 +598,19 @@ protected void addApplicationAttempt( } /** - * Helper method that attempts to assign the app to a queue. The method is - * responsible to call the appropriate event-handler if the app is rejected. + * Helper method for the tests to assign the app to a queue. */ @VisibleForTesting FSLeafQueue assignToQueue(RMApp rmApp, String queueName, String user) { + return assignToQueue(rmApp, queueName, user, null); + } + + /** + * Helper method that attempts to assign the app to a queue. The method is + * responsible to call the appropriate event-handler if the app is rejected. + */ + private FSLeafQueue assignToQueue(RMApp rmApp, String queueName, String user, + ApplicationId applicationId) { FSLeafQueue queue = null; String appRejectMsg = null; @@ -611,7 +620,7 @@ FSLeafQueue assignToQueue(RMApp rmApp, String queueName, String user) { if (queueName == null) { appRejectMsg = "Application rejected by queue placement policy"; } else { - queue = queueMgr.getLeafQueue(queueName, true); + queue = queueMgr.getLeafQueue(queueName, true, applicationId); if (queue == null) { appRejectMsg = queueName + " is not a leaf queue"; } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/QueueManager.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/QueueManager.java index 8371765..321055f 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/QueueManager.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/QueueManager.java @@ -38,6 +38,7 @@ import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.classification.InterfaceStability.Unstable; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.policies.FifoPolicy; import org.xml.sax.SAXException; @@ -124,29 +125,55 @@ public void initialize(Configuration conf) throws IOException, /** * Get a leaf queue by name, creating it if the create param is - * true and is necessary. - * If the queue is not or can not be a leaf queue, i.e. it already exists as a - * parent queue, or one of the parents in its name is already a leaf queue, - * null is returned. + * true and the queue does not exist. + * If the queue is not or can not be a leaf queue, i.e. it already exists as + * a parent queue, or one of the parents in its name is already a leaf queue, + * null is returned. * * The root part of the name is optional, so a queue underneath the root * named "queue1" could be referred to as just "queue1", and a queue named * "queue2" underneath a parent named "parent1" that is underneath the root * could be referred to as just "parent1.queue2". + * @param name name of the queue + * @param create true if the queue must be created if it does + * not exist, false otherwise + * @return the leaf queue or null if the queue cannot be found */ public FSLeafQueue getLeafQueue(String name, boolean create) { - return getLeafQueue(name, create, true); + return getLeafQueue(name, create, null, true); + } + + /** + * Get a leaf queue by name, creating it if the create param is + * true and the queue does not exist. + * If the queue is not or can not be a leaf queue, i.e. it already exists as + * a parent queue, or one of the parents in its name is already a leaf queue, + * null is returned. + * + * If the application will be assigned to the queue if the applicationId is + * not null + * @param name name of the queue + * @param create true if the queue must be created if it does + * not exist, false otherwise + * @param applicationId the application to assign to the queue + * @return the leaf queue or null if the queue cannot be found + */ + public FSLeafQueue getLeafQueue(String name, boolean create, + ApplicationId applicationId) { + return getLeafQueue(name, create, applicationId, true); } private FSLeafQueue getLeafQueue( String name, boolean create, + ApplicationId applicationId, boolean recomputeSteadyShares) { FSQueue queue = getQueue( name, create, FSQueueType.LEAF, - recomputeSteadyShares + recomputeSteadyShares, + applicationId ); if (queue instanceof FSParentQueue) { return null; @@ -165,27 +192,46 @@ public boolean removeLeafQueue(String name) { removeEmptyIncompatibleQueues(name, FSQueueType.PARENT).orElse(null)); } - /** * Get a parent queue by name, creating it if the create param is - * true and is necessary. - * If the queue is not or can not be a parent queue, - * i.e. it already exists as a - * leaf queue, or one of the parents in its name is already a leaf queue, - * null is returned. + * true and the queue does not exist. + * If the queue is not or can not be a parent queue, i.e. it already exists + * as a leaf queue, or one of the parents in its name is already a leaf + * queue, null is returned. * * The root part of the name is optional, so a queue underneath the root * named "queue1" could be referred to as just "queue1", and a queue named * "queue2" underneath a parent named "parent1" that is underneath the root * could be referred to as just "parent1.queue2". + * @param name name of the queue + * @param create true if the queue must be created if it does + * not exist, false otherwise + * @return the parent queue or null if the queue cannot be found */ public FSParentQueue getParentQueue(String name, boolean create) { return getParentQueue(name, create, true); } - public FSParentQueue getParentQueue( - String name, - boolean create, + /** + * Get a parent queue by name, creating it if the create param is + * true and the queue does not exist. + * If the queue is not or can not be a parent queue, i.e. it already exists + * as a leaf queue, or one of the parents in its name is already a leaf + * queue, null is returned. + * + * The root part of the name is optional, so a queue underneath the root + * named "queue1" could be referred to as just "queue1", and a queue named + * "queue2" underneath a parent named "parent1" that is underneath the root + * could be referred to as just "parent1.queue2". + * @param name name of the queue + * @param create true if the queue must be created if it does + * not exist, false otherwise + * @param recomputeSteadyShares true if the steady fair share + * should be recalculated when a queue is added, + * false otherwise + * @return the parent queue or null if the queue cannot be found + */ + public FSParentQueue getParentQueue(String name, boolean create, boolean recomputeSteadyShares) { FSQueue queue = getQueue( name, @@ -199,11 +245,13 @@ public FSParentQueue getParentQueue( return (FSParentQueue) queue; } - private FSQueue getQueue( - String name, - boolean create, - FSQueueType queueType, - boolean recomputeSteadyShares) { + private FSQueue getQueue(String name, boolean create, FSQueueType queueType, + boolean recomputeSteadyShares) { + return getQueue(name, create, queueType, recomputeSteadyShares, null); + } + + private FSQueue getQueue(String name, boolean create, FSQueueType queueType, + boolean recomputeSteadyShares, ApplicationId applicationId) { boolean recompute = recomputeSteadyShares; name = ensureRootPrefix(name); FSQueue queue; @@ -215,6 +263,11 @@ private FSQueue getQueue( } else { recompute = false; } + // At this point the queue exists and we need to assign the app + // but only to a leaf queue + if (applicationId != null && queue instanceof FSLeafQueue) { + ((FSLeafQueue)queue).addAssignedApp(applicationId); + } } if (recompute) { rootQueue.recomputeSteadyShares(); @@ -484,12 +537,12 @@ public void removePendingIncompatibleQueues() { } /** - * Remove the queue if it and its descendents are all empty. + * Remove the queue if it and its descendants are all empty. * @param queue * @return true if removed, false otherwise */ private boolean removeQueueIfEmpty(FSQueue queue) { - if (isEmpty(queue)) { + if (queue.isEmpty()) { removeQueue(queue); return true; } @@ -513,26 +566,6 @@ private void removeQueue(FSQueue queue) { parent.removeChildQueue(queue); } } - - /** - * Returns true if there are no applications, running or not, in the given - * queue or any of its descendents. - */ - protected boolean isEmpty(FSQueue queue) { - if (queue instanceof FSLeafQueue) { - FSLeafQueue leafQueue = (FSLeafQueue)queue; - return queue.getNumRunnableApps() == 0 && - leafQueue.getNumNonRunnableApps() == 0 && - leafQueue.getNumAssignedApps() == 0; - } else { - for (FSQueue child : queue.getChildQueues()) { - if (!isEmpty(child)) { - return false; - } - } - return true; - } - } /** * Gets a queue by name. diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFSParentQueue.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFSParentQueue.java index 671b94b..0203939 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFSParentQueue.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFSParentQueue.java @@ -34,7 +34,6 @@ private FairSchedulerConfiguration conf; private QueueManager queueManager; - private Set notEmptyQueues; @Before public void setUp() throws Exception { @@ -47,13 +46,7 @@ public void setUp() throws Exception { new DefaultResourceCalculator()); SystemClock clock = SystemClock.getInstance(); when(scheduler.getClock()).thenReturn(clock); - notEmptyQueues = new HashSet(); - queueManager = new QueueManager(scheduler) { - @Override - public boolean isEmpty(FSQueue queue) { - return !notEmptyQueues.contains(queue); - } - }; + queueManager = new QueueManager(scheduler); FSQueueMetrics.forQueue("root", null, true, conf); queueManager.initialize(conf); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestQueueManager.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestQueueManager.java index 3674ffb..a1e26a6 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestQueueManager.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestQueueManager.java @@ -41,7 +41,6 @@ public class TestQueueManager { private FairSchedulerConfiguration conf; private QueueManager queueManager; - private Set notEmptyQueues; private FairScheduler scheduler; @Before @@ -64,13 +63,7 @@ public void setUp() throws Exception { SystemClock clock = SystemClock.getInstance(); when(scheduler.getClock()).thenReturn(clock); - notEmptyQueues = new HashSet<>(); - queueManager = new QueueManager(scheduler) { - @Override - public boolean isEmpty(FSQueue queue) { - return !notEmptyQueues.contains(queue); - } - }; + queueManager = new QueueManager(scheduler); FSQueueMetrics.forQueue("root", null, true, conf); @@ -95,16 +88,19 @@ public void testReloadTurnsLeafQueueIntoParent() throws Exception { // When apps exist in leaf queue, we shouldn't be able to create // children under it, but things should work otherwise. - notEmptyQueues.add(queueManager.getLeafQueue("queue1", false)); + FSLeafQueue q1 = queueManager.getLeafQueue("queue1", false); + ApplicationId applicationId = ApplicationId.newInstance(0, 0); + q1.addAssignedApp(applicationId); updateConfiguredLeafQueues(queueManager, "queue1.queue2"); assertNull(queueManager.getLeafQueue("queue1.queue2", false)); assertNotNull(queueManager.getLeafQueue("queue1", false)); // When apps exist in leaf queues under a parent queue, shouldn't be // able to turn it into a leaf queue, but things should work otherwise. - notEmptyQueues.clear(); + q1.removeAssignedApp(applicationId); updateConfiguredLeafQueues(queueManager, "queue1.queue2"); - notEmptyQueues.add(queueManager.getQueue("root.queue1")); + FSLeafQueue q2 = queueManager.getLeafQueue("queue1.queue2", false); + q2.addAssignedApp(applicationId); updateConfiguredLeafQueues(queueManager, "queue1"); assertNotNull(queueManager.getLeafQueue("queue1.queue2", false)); assertNull(queueManager.getLeafQueue("queue1", false)); @@ -126,7 +122,9 @@ public void testReloadTurnsLeafToParentWithNoLeaf() { // Lets say later on admin makes queue1 a parent queue by // specifying "type=parent" in the alloc xml and lets say apps running in // queue1 - notEmptyQueues.add(queueManager.getLeafQueue("root.queue1", false)); + FSLeafQueue q1 = queueManager.getLeafQueue("root.queue1", false); + ApplicationId applicationId = ApplicationId.newInstance(0, 0); + q1.addAssignedApp(applicationId); allocConf = new AllocationConfiguration(conf); allocConf.configuredQueues.get(FSQueueType.PARENT) .add("root.queue1"); @@ -137,7 +135,7 @@ public void testReloadTurnsLeafToParentWithNoLeaf() { assertNull(queueManager.getParentQueue("root.queue1", false)); // Now lets assume apps completed and there are no apps in queue1 - notEmptyQueues.clear(); + q1.removeAssignedApp(applicationId); // We should see queue1 transform from leaf queue to parent queue. queueManager.updateAllocationConfiguration(allocConf); assertNull(queueManager.getLeafQueue("root.queue1", false)); @@ -319,7 +317,7 @@ public void testRemovalOfDynamicLeafQueue() { queueManager.updateAllocationConfiguration(allocConf); - FSQueue q1 = queueManager.getLeafQueue("root.test.childB.dynamic1", true); + FSLeafQueue q1 = queueManager.getLeafQueue("root.test.childB.dynamic1", true); assertNotNull("Queue root.test.childB.dynamic1 was not created", q1); assertEquals("createQueue() returned wrong queue", @@ -328,7 +326,8 @@ public void testRemovalOfDynamicLeafQueue() { q1.isDynamic()); // an application is submitted to root.test.childB.dynamic1 - notEmptyQueues.add(q1); + ApplicationId applicationId = ApplicationId.newInstance(0, 0); + q1.addAssignedApp(applicationId); // root.test.childB.dynamic1 is not empty and should not be removed queueManager.removePendingIncompatibleQueues(); @@ -338,7 +337,7 @@ public void testRemovalOfDynamicLeafQueue() { // the application finishes, the next removeEmptyDynamicQueues() should // clean root.test.childB.dynamic1 up, but keep its static parent - notEmptyQueues.remove(q1); + q1.removeAssignedApp(applicationId); queueManager.removePendingIncompatibleQueues(); queueManager.removeEmptyDynamicQueues(); @@ -388,7 +387,8 @@ public void testNonEmptyDynamicQueueBecomingStaticQueue() { assertTrue("root.leaf1 is not a dynamic queue", q1.isDynamic()); // pretend that we submitted an app to the queue - notEmptyQueues.add(q1); + ApplicationId applicationId = ApplicationId.newInstance(0, 0); + q1.addAssignedApp(applicationId); // non-empty queues should not be deleted queueManager.removePendingIncompatibleQueues(); @@ -406,7 +406,7 @@ public void testNonEmptyDynamicQueueBecomingStaticQueue() { // application finished now and the queue is empty, but since leaf1 is a // static queue at this point, hence not affected by // removeEmptyDynamicQueues() - notEmptyQueues.clear(); + q1.removeAssignedApp(applicationId); queueManager.removePendingIncompatibleQueues(); queueManager.removeEmptyDynamicQueues(); q1 = queueManager.getLeafQueue("root.leaf1", false); @@ -427,7 +427,8 @@ public void testNonEmptyStaticQueueBecomingDynamicQueue() { assertFalse("root.test.childA is not a static queue", q1.isDynamic()); // we submitted an app to the queue - notEmptyQueues.add(q1); + ApplicationId applicationId = ApplicationId.newInstance(0, 0); + q1.addAssignedApp(applicationId); // the next removeEmptyDynamicQueues() call should not modify // root.test.childA @@ -451,7 +452,7 @@ public void testNonEmptyStaticQueueBecomingDynamicQueue() { // application finished - the queue does not have runnable app // the next removeEmptyDynamicQueues() call should remove the queues - notEmptyQueues.remove(q1); + q1.removeAssignedApp(applicationId); queueManager.removePendingIncompatibleQueues(); queueManager.removeEmptyDynamicQueues(); @@ -549,20 +550,20 @@ public void testApplicationAssignmentPreventsRemovalOfDynamicQueue() FSLeafQueue q = queueManager.getLeafQueue("root.leaf1", true); assertNotNull("root.leaf1 does not exist", q); - assertTrue("root.leaf1 is not empty", queueManager.isEmpty(q)); + assertTrue("root.leaf1 is not empty", q.isEmpty()); // assigning an application (without an appAttempt so far) to the queue // removeEmptyDynamicQueues() should not remove the queue ApplicationId applicationId = ApplicationId.newInstance(1L, 0); q.addAssignedApp(applicationId); q = queueManager.getLeafQueue("root.leaf1", false); - assertFalse("root.leaf1 is empty", queueManager.isEmpty(q)); + assertFalse("root.leaf1 is empty", q.isEmpty()); queueManager.removePendingIncompatibleQueues(); queueManager.removeEmptyDynamicQueues(); q = queueManager.getLeafQueue("root.leaf1", false); assertNotNull("root.leaf1 has been removed", q); - assertFalse("root.leaf1 is empty", queueManager.isEmpty(q)); + assertFalse("root.leaf1 is empty", q.isEmpty()); ApplicationAttemptId applicationAttemptId = ApplicationAttemptId.newInstance(applicationId, 0); @@ -578,12 +579,12 @@ public void testApplicationAssignmentPreventsRemovalOfDynamicQueue() queueManager.removeEmptyDynamicQueues(); q = queueManager.getLeafQueue("root.leaf1", false); assertNotNull("root.leaf1 has been removed", q); - assertFalse("root.leaf1 is empty", queueManager.isEmpty(q)); + assertFalse("root.leaf1 is empty", q.isEmpty()); // the appAttempt finished, the queue should be empty q.removeApp(appAttempt); q = queueManager.getLeafQueue("root.leaf1", false); - assertTrue("root.leaf1 is not empty", queueManager.isEmpty(q)); + assertTrue("root.leaf1 is not empty", q.isEmpty()); // removeEmptyDynamicQueues() should remove the queue queueManager.removePendingIncompatibleQueues(); @@ -602,13 +603,14 @@ public void testRemovalOfIncompatibleNonEmptyQueue() FSLeafQueue q = queueManager.getLeafQueue("root.a", true); assertNotNull("root.a does not exist", q); - assertTrue("root.a is not empty", queueManager.isEmpty(q)); + assertTrue("root.a is not empty", q.isEmpty()); // we start to run an application on root.a - notEmptyQueues.add(q); + ApplicationId applicationId = ApplicationId.newInstance(0, 0); + q.addAssignedApp(applicationId); q = queueManager.getLeafQueue("root.a", false); assertNotNull("root.a does not exist", q); - assertFalse("root.a is empty", queueManager.isEmpty(q)); + assertFalse("root.a is empty", q.isEmpty()); // root.a should not be removed by removeEmptyDynamicQueues or by // removePendingIncompatibleQueues @@ -626,16 +628,16 @@ public void testRemovalOfIncompatibleNonEmptyQueue() // since root.a has running applications, it should be still a leaf queue q = queueManager.getLeafQueue("root.a", false); assertNotNull("root.a has been removed", q); - assertFalse("root.a is empty", queueManager.isEmpty(q)); + assertFalse("root.a is empty", q.isEmpty()); // removePendingIncompatibleQueues should still keep root.a as a leaf queue queueManager.removePendingIncompatibleQueues(); q = queueManager.getLeafQueue("root.a", false); assertNotNull("root.a has been removed", q); - assertFalse("root.a is empty", queueManager.isEmpty(q)); + assertFalse("root.a is empty", q.isEmpty()); // when the application finishes, root.a should be a parent queue - notEmptyQueues.clear(); + q.removeAssignedApp(applicationId); queueManager.removePendingIncompatibleQueues(); queueManager.removeEmptyDynamicQueues(); FSParentQueue p = queueManager.getParentQueue("root.a", false);