|
30 | 30 | import org.apache.hadoop.yarn.server.resourcemanager.MockRM; |
31 | 31 | import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceLimits; |
32 | 32 | import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler; |
| 33 | +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeRemovedSchedulerEvent; |
33 | 34 | import org.apache.hadoop.yarn.util.resource.Resources; |
34 | 35 | import org.junit.Assert; |
35 | 36 | import org.junit.Test; |
@@ -100,6 +101,21 @@ public class TestAbsoluteResourceConfiguration { |
100 | 101 | private static Set<String> resourceTypes = new HashSet<>( |
101 | 102 | Arrays.asList("memory", "vcores")); |
102 | 103 |
|
| 104 | + private CapacitySchedulerConfiguration setupNormalizationConfiguration() { |
| 105 | + CapacitySchedulerConfiguration csConf = new CapacitySchedulerConfiguration(); |
| 106 | + csConf.setQueues(CapacitySchedulerConfiguration.ROOT, |
| 107 | + new String[]{QUEUEA, QUEUEB}); |
| 108 | + csConf.setQueues(QUEUEA_FULL.getFullPath(), new String[]{QUEUEA1, QUEUEA2}); |
| 109 | + |
| 110 | +// 60, 28 |
| 111 | + csConf.setMinimumResourceRequirement("", QUEUEA_FULL, Resource.newInstance(50 * GB, 20)); |
| 112 | + csConf.setMinimumResourceRequirement("", QUEUEA1_FULL, Resource.newInstance(30 * GB, 15)); |
| 113 | + csConf.setMinimumResourceRequirement("", QUEUEA2_FULL, Resource.newInstance(20 * GB, 5)); |
| 114 | + csConf.setMinimumResourceRequirement("", QUEUEB_FULL, Resource.newInstance(10 * GB, 8)); |
| 115 | + |
| 116 | + return csConf; |
| 117 | + } |
| 118 | + |
103 | 119 | private CapacitySchedulerConfiguration setupSimpleQueueConfiguration( |
104 | 120 | boolean isCapacityNeeded) { |
105 | 121 | CapacitySchedulerConfiguration csConf = new CapacitySchedulerConfiguration(); |
@@ -292,6 +308,37 @@ public void testSimpleMinMaxResourceConfigurartionPerQueue() |
292 | 308 | rm.close(); |
293 | 309 | } |
294 | 310 |
|
| 311 | + @Test |
| 312 | + public void testNormalizationAfterNodeRemoval() throws Exception { |
| 313 | + CapacitySchedulerConfiguration csConf = setupNormalizationConfiguration(); |
| 314 | + csConf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, |
| 315 | + ResourceScheduler.class); |
| 316 | + |
| 317 | + MockRM rm = new MockRM(csConf); |
| 318 | + |
| 319 | + rm.start(); |
| 320 | + rm.registerNode("h1:1234", 8 * GB, 4); |
| 321 | + rm.registerNode("h2:1234", 8 * GB, 4); |
| 322 | + rm.registerNode("h3:1234", 8 * GB, 4); |
| 323 | + MockNM nm = rm.registerNode("h4:1234", 8 * GB, 4); |
| 324 | + rm.registerNode("h5:1234", 28 * GB, 12); |
| 325 | + |
| 326 | + // Send a removal event to CS. MockRM#unregisterNode does not reflect the real world scenario, |
| 327 | + // therefore we manually need to invoke this removal event. |
| 328 | + CapacityScheduler cs = (CapacityScheduler) rm.getResourceScheduler(); |
| 329 | + cs.handle(new NodeRemovedSchedulerEvent(rm.getRMContext().getRMNodes().get(nm.getNodeId()))); |
| 330 | + |
| 331 | + Resource res = Resources.add( |
| 332 | + cs.getQueue(QUEUEA1_FULL.getFullPath()).getEffectiveCapacity(""), |
| 333 | + cs.getQueue(QUEUEA2_FULL.getFullPath()).getEffectiveCapacity("")); |
| 334 | + Resource resParent = cs.getQueue(QUEUEA_FULL.getFullPath()).getEffectiveCapacity(""); |
| 335 | + |
| 336 | + // Check if there is no overcommitment on behalf of the child queues |
| 337 | + Assert.assertTrue(String.format("Summarized resource %s of all children is greater than " + |
| 338 | + "their parent's %s", res, resParent), |
| 339 | + Resources.lessThan(cs.getResourceCalculator(), cs.getClusterResource(), res, resParent)); |
| 340 | + } |
| 341 | + |
295 | 342 | @Test |
296 | 343 | public void testEffectiveMinMaxResourceConfigurartionPerQueue() |
297 | 344 | throws Exception { |
|
0 commit comments