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/AbstractCSQueue.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/AbstractCSQueue.java index 21c385a8bcc..b62e8f7aaf0 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/AbstractCSQueue.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/AbstractCSQueue.java @@ -153,8 +153,7 @@ public AbstractCSQueue(CapacitySchedulerContext cs, this.activitiesManager = cs.getActivitiesManager(); // must be called after parent and queueName is set - this.metrics = old != null ? - (CSQueueMetrics) old.getMetrics() : + this.metrics = CSQueueMetrics.forQueue(getQueuePath(), parent, cs.getConfiguration().getEnableUserMetrics(), cs.getConf()); 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/TestParentQueue.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/TestParentQueue.java index 4ef9f7a5f7e..8b0fdc20b8a 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/TestParentQueue.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/TestParentQueue.java @@ -31,10 +31,9 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.when; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.QueueMetrics; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.hadoop.security.UserGroupInformation; @@ -430,6 +429,8 @@ public void testSingleLevelQueuesPrecision() throws Exception { private static final String B1 = "b1"; private static final String B2 = "b2"; private static final String B3 = "b3"; + + private static final String DUP_QNAME = "DUP"; private void setupMultiLevelQueues(CapacitySchedulerConfiguration conf) { @@ -476,6 +477,52 @@ private void setupMultiLevelQueues(CapacitySchedulerConfiguration conf) { conf.setCapacity(Q_C1111, 100); } + private void setupParentQueuesWithNonUniqueName( + CapacitySchedulerConfiguration csConfig) { + + /* + * Structure of queue: + * Two parent queues with DUP name . + * + * Root + * | + * A + * / \ + * B DUP + * / \ + * DUP C + * \ + * D + */ + + // Define top-level queue + csConf.setQueues(CapacitySchedulerConfiguration.ROOT, new String[] {A}); + final String Q_A = CapacitySchedulerConfiguration.ROOT + "." + A; + csConfig.setCapacity(Q_A, 100); + + // Define 2-nd level queues + csConfig.setQueues(Q_A, new String[] {B, DUP_QNAME}); + final String Q_DUP1 = Q_A + "." + DUP_QNAME; + final String Q_B = Q_A + "." + B; + csConfig.setCapacity(Q_B, 75); + csConfig.setCapacity(Q_DUP1, 25); + + // Leaf Queue C + csConfig.setQueues(Q_DUP1, new String[] {C}); + final String Q_C = Q_DUP1 + "." + C; + csConfig.setCapacity(Q_C, 100); + + // Another DUP under parent B + csConfig.setQueues(Q_B, new String[] {DUP_QNAME}); + final String Q_DUP2 = Q_B + "." + DUP_QNAME; + csConfig.setCapacity(Q_DUP2, 100); + + // Leaf Queue D + csConfig.setQueues(Q_DUP2, new String[] {D}); + final String Q_D = Q_DUP2 + "." + D; + csConfig.setCapacity(Q_D, 100); + } + @Test public void testMultiLevelQueues() throws Exception { /* @@ -1026,6 +1073,34 @@ public void testAbsoluteResourceWithChangeInClusterResource() QUEUE_B_RESOURCE_70PERC); } + @Test + public void testMetricsInitializedWithNonUniqueName() + throws Exception { + // Setup 7 queues total. One parent queue named DUP present twice. + setupParentQueuesWithNonUniqueName(csConf); + Map queues = new HashMap(); + CSQueue root = CapacitySchedulerQueueManager.parseQueue(csContext, csConf, + null, CapacitySchedulerConfiguration.ROOT, queues, queues, + TestUtils.spyHook); + List allQueues = new ArrayList<>(); + allQueues(root, allQueues); + Set metrics = new HashSet<>(); + for(CSQueue q : allQueues) { + metrics.add(q.getMetrics()); + } + assertEquals("Metrics not created for all " + allQueues.size() + + " queues", allQueues.size(), metrics.size()); + } + + private void allQueues(CSQueue root, List queues) { + queues.add(root); + if(root instanceof ParentQueue) { + for(CSQueue q : root.getChildQueues()) { + allQueues(q, queues); + } + } + } + @After public void tearDown() throws Exception { }