diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/QueuePath.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/QueuePath.java index 440742b908..692be1132e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/QueuePath.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/QueuePath.java @@ -96,6 +96,11 @@ private void setFromFullPath(String fullPath) { * @return true if there is at least one empty part of the path */ public boolean hasEmptyPart() { + // iterator will not contain an empty leaf queue, so check directly + if (leaf.isEmpty()) { + return true; + } + for (String part : this) { if (part.isEmpty()) { return true; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestCapacitySchedulerAutoQueueCreation.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestCapacitySchedulerAutoQueueCreation.java index ca5069d221..590b0a4b76 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestCapacitySchedulerAutoQueueCreation.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestCapacitySchedulerAutoQueueCreation.java @@ -109,6 +109,8 @@ public class TestCapacitySchedulerAutoQueueCreation private static final Logger LOG = LoggerFactory.getLogger( TestCapacitySchedulerAutoQueueCreation.class); + private static final String SPECIFIED_QUEUE_MAPPING = "%specified"; + private static final String CURRENT_USER_MAPPING = "%user"; private static final Resource TEMPLATE_MAX_RES = Resource.newInstance(16 * @@ -1054,4 +1056,40 @@ public RMNodeLabelsManager createNodeLabelManager() { } } } + + @Test(timeout = 10000) + public void testAutoCreateLeafQueueFailsWithSpecifiedEmptyStringLeafQueue() + throws Exception { + + final String invalidQueue = ""; + + MockRM newMockRM = setupSchedulerInstance(); + CapacityScheduler newCS = + (CapacityScheduler) newMockRM.getResourceScheduler(); + + //queue mapping to place app in queue specified by user + setupQueueMapping(newCS, "app_user", "root.c", SPECIFIED_QUEUE_MAPPING); + newCS.updatePlacementRules(); + + try { + //submitting to root.c. should fail WITHOUT crashing the RM + submitApp(newCS, "app_user", invalidQueue, "root.c"); + + RMContext rmContext = mock(RMContext.class); + when(rmContext.getDispatcher()).thenReturn(dispatcher); + newCS.setRMContext(rmContext); + + ApplicationId appId = BuilderUtils.newApplicationId(1, 1); + SchedulerEvent addAppEvent = new AppAddedSchedulerEvent( + appId, "root.c." + invalidQueue, "app_user"); + newCS.handle(addAppEvent); + + RMAppEvent event = new RMAppEvent(appId, RMAppEventType.APP_REJECTED, + "error"); + dispatcher.spyOnNextEvent(event, 10000); + } finally { + ((CapacityScheduler) newMockRM.getResourceScheduler()).stop(); + newMockRM.stop(); + } + } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestQueuePath.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestQueuePath.java index 7eb577d9c1..91171966c1 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestQueuePath.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestQueuePath.java @@ -48,9 +48,11 @@ public void testCreation() { @Test public void testEmptyPart() { QueuePath queuePathWithEmptyPart = new QueuePath("root..level_2"); + QueuePath queuePathWithEmptyLeaf = new QueuePath("root.level_1."); QueuePath queuePathWithoutEmptyPart = new QueuePath(TEST_QUEUE); Assert.assertTrue(queuePathWithEmptyPart.hasEmptyPart()); + Assert.assertTrue(queuePathWithEmptyLeaf.hasEmptyPart()); Assert.assertFalse(queuePathWithoutEmptyPart.hasEmptyPart()); }