From e35baea5a56b59c0035c382846008d67ce527292 Mon Sep 17 00:00:00 2001 From: Benjamin Teke Date: Tue, 23 Nov 2021 16:54:51 +0100 Subject: [PATCH 1/4] YARN-11014. YARN incorrectly validates maximum capacity resources on the validation API --- .../scheduler/capacity/CapacityScheduler.java | 16 ++ .../CapacitySchedulerConfigValidator.java | 2 + .../TestCapacitySchedulerConfigValidator.java | 188 +++++++++++++++++- 3 files changed, 203 insertions(+), 3 deletions(-) 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/CapacityScheduler.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/CapacityScheduler.java index d2c84e79226d66..bd1089bd6b66ec 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/CapacityScheduler.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/CapacityScheduler.java @@ -2239,6 +2239,22 @@ private void refreshLabelToNodeCache(Set updateLabels) { } } + /** + * Add node to nodeTracker. Used when validating CS configuration by instantiating a new + * CS instance. + * @param nodesToAdd node to be added + */ + public void addNodes(List nodesToAdd) { + writeLock.lock(); + try { + for (FiCaSchedulerNode node : nodesToAdd) { + nodeTracker.addNode(node); + } + } finally { + writeLock.unlock(); + } + } + private void addNode(RMNode nodeManager) { writeLock.lock(); try { 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/CapacitySchedulerConfigValidator.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/CapacitySchedulerConfigValidator.java index ca0d586497d35c..fd601ac58170e6 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/CapacitySchedulerConfigValidator.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/CapacitySchedulerConfigValidator.java @@ -42,6 +42,7 @@ private CapacitySchedulerConfigValidator() { public static boolean validateCSConfiguration( final Configuration oldConf, final Configuration newConf, final RMContext rmContext) throws IOException { + CapacityScheduler liveScheduler = (CapacityScheduler) rmContext.getScheduler(); CapacityScheduler newCs = new CapacityScheduler(); try { //TODO: extract all the validation steps and replace reinitialize with @@ -49,6 +50,7 @@ public static boolean validateCSConfiguration( newCs.setConf(oldConf); newCs.setRMContext(rmContext); newCs.init(oldConf); + newCs.addNodes(liveScheduler.getAllNodes()); newCs.reinitialize(newConf, rmContext, true); return true; } finally { 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/TestCapacitySchedulerConfigValidator.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/TestCapacitySchedulerConfigValidator.java index 04f4349db1dada..616c44cb965a03 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/TestCapacitySchedulerConfigValidator.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/TestCapacitySchedulerConfigValidator.java @@ -20,12 +20,18 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.yarn.LocalConfigurationProvider; +import org.apache.hadoop.yarn.api.records.Resource; import org.apache.hadoop.yarn.api.records.impl.LightWeightResource; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; +import org.apache.hadoop.yarn.server.resourcemanager.MockNM; +import org.apache.hadoop.yarn.server.resourcemanager.MockRM; import org.apache.hadoop.yarn.server.resourcemanager.RMContext; import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager; import org.apache.hadoop.yarn.server.resourcemanager.placement.PlacementManager; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler; +import org.apache.hadoop.yarn.util.YarnVersionInfo; +import org.apache.hadoop.yarn.util.resource.DominantResourceCalculator; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; @@ -37,6 +43,42 @@ import static org.junit.Assert.fail; public class TestCapacitySchedulerConfigValidator { + public static final int NODE_MEMORY = 16; + public static final int NODE1_VCORES = 8; + public static final int NODE2_VCORES = 10; + public static final int NODE3_VCORES = 12; + public static final int GB = 1024; + + private static final String PARENT_A = "parentA"; + private static final String PARENT_B = "parentB"; + private static final String LEAF_A = "leafA"; + private static final String LEAF_B = "leafB"; + + private static final String PARENT_A_FULL_PATH = CapacitySchedulerConfiguration.ROOT + + "." + PARENT_A; + private static final String LEAF_A_FULL_PATH = PARENT_A_FULL_PATH + + "." + LEAF_A; + private static final String PARENT_B_FULL_PATH = CapacitySchedulerConfiguration.ROOT + + "." + PARENT_B; + private static final String LEAF_B_FULL_PATH = PARENT_B_FULL_PATH + + "." + LEAF_B; + + private static final Resource A_MINRES = Resource.newInstance(16 * GB, + 10); + private static final Resource B_MINRES = Resource.newInstance(32 * GB, + 5); + private static final Resource FULL_MAXRES = Resource.newInstance(48 * GB, + 30); + private static final Resource PARTIAL_MAXRES = Resource.newInstance(16 * GB, + 10); + private static final Resource VCORE_EXCEEDED_MAXRES = Resource.newInstance(16 * GB, + 50); + + protected MockRM mockRM = null; + protected MockNM nm1 = null; + protected MockNM nm2 = null; + protected MockNM nm3 = null; + protected CapacityScheduler cs; /** * Test for the case when the scheduler.minimum-allocation-mb == 0. @@ -69,7 +111,6 @@ public void testValidateMemoryAllocationHIgherMinThanMaxMem() { } - @Test public void testValidateMemoryAllocation() { Map configs = new HashMap(); @@ -115,7 +156,6 @@ public void testValidateVCoresHigherMinThanMaxVCore() { } - @Test public void testValidateVCores() { Map configs = new HashMap(); @@ -147,6 +187,86 @@ public void testValidateCSConfigInvalidCapacity() { } } + @Test + public void testValidateCSConfigDefaultRCAbsoluteModeParentMaxMemoryExceeded() + throws Exception { + setUpMockRM(false); + RMContext rmContext = mockRM.getRMContext(); + CapacitySchedulerConfiguration oldConfiguration = cs.getConfiguration(); + CapacitySchedulerConfiguration newConfiguration = + new CapacitySchedulerConfiguration(cs.getConfiguration()); + newConfiguration.setMaximumResourceRequirement("", LEAF_A_FULL_PATH, FULL_MAXRES); + try { + CapacitySchedulerConfigValidator + .validateCSConfiguration(oldConfiguration, newConfiguration, rmContext); + fail("Parent maximum capacity exceeded"); + } catch (IOException e) { + Assert.assertTrue(e.getCause().getMessage() + .startsWith("Max resource configuration")); + } finally { + mockRM.stop(); + } + } + + @Test + public void testValidateCSConfigDefaultRCAbsoluteModeParentMaxVcoreExceeded() throws Exception { + setUpMockRM(false); + RMContext rmContext = mockRM.getRMContext(); + CapacitySchedulerConfiguration oldConfiguration = cs.getConfiguration(); + CapacitySchedulerConfiguration newConfiguration = + new CapacitySchedulerConfiguration(cs.getConfiguration()); + newConfiguration.setMaximumResourceRequirement("", LEAF_A_FULL_PATH, VCORE_EXCEEDED_MAXRES); + try { + CapacitySchedulerConfigValidator + .validateCSConfiguration(oldConfiguration, newConfiguration, rmContext); + } catch (IOException e) { + fail("In DefaultResourceCalculator vcore limits are not enforced"); + } finally { + mockRM.stop(); + } + } + + @Test + public void testValidateCSConfigDominantRCAbsoluteModeParentMaxMemoryExceeded() + throws Exception { + setUpMockRM(true); + RMContext rmContext = mockRM.getRMContext(); + CapacitySchedulerConfiguration oldConfiguration = cs.getConfiguration(); + CapacitySchedulerConfiguration newConfiguration = + new CapacitySchedulerConfiguration(cs.getConfiguration()); + newConfiguration.setMaximumResourceRequirement("", LEAF_A_FULL_PATH, FULL_MAXRES); + try { + CapacitySchedulerConfigValidator + .validateCSConfiguration(oldConfiguration, newConfiguration, rmContext); + fail("Parent maximum capacity exceeded"); + } catch (IOException e) { + Assert.assertTrue(e.getCause().getMessage() + .startsWith("Max resource configuration")); + } finally { + mockRM.stop(); + } + } + + @Test + public void testValidateCSConfigDominantRCAbsoluteModeParentMaxVcoreExceeded() throws Exception { + setUpMockRM(true); + RMContext rmContext = mockRM.getRMContext(); + CapacitySchedulerConfiguration oldConfiguration = cs.getConfiguration(); + CapacitySchedulerConfiguration newConfiguration = + new CapacitySchedulerConfiguration(cs.getConfiguration()); + newConfiguration.setMaximumResourceRequirement("", LEAF_A_FULL_PATH, VCORE_EXCEEDED_MAXRES); + try { + CapacitySchedulerConfigValidator + .validateCSConfiguration(oldConfiguration, newConfiguration, rmContext); + fail("Parent maximum capacity exceeded"); + } catch (IOException e) { + Assert.assertTrue(e.getCause().getMessage() + .startsWith("Max resource configuration")); + } finally { + mockRM.stop(); + } + } + @Test public void testValidateCSConfigStopALeafQueue() throws IOException { Configuration oldConfig = CapacitySchedulerConfigGeneratorForTest @@ -340,7 +460,6 @@ public void testAddQueueToALeafQueue() throws IOException { Assert.assertTrue(isValidConfig); } - public static RMContext prepareRMContext() { RMContext rmContext = Mockito.mock(RMContext.class); LocalConfigurationProvider configProvider = Mockito @@ -361,4 +480,67 @@ public static RMContext prepareRMContext() { .thenReturn(queuePlacementManager); return rmContext; } + + private void setUpMockRM(boolean useDominantRC) throws Exception { + YarnConfiguration conf = new YarnConfiguration(); + conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, + ResourceScheduler.class); + CapacitySchedulerConfiguration csConf = setupCSConfiguration(conf, useDominantRC); + + mockRM = new MockRM(csConf); + + cs = (CapacityScheduler) mockRM.getResourceScheduler(); + mockRM.start(); + cs.start(); + + setupNodes(mockRM); + } + + private void setupNodes(MockRM newMockRM) throws Exception { + nm1 = + new MockNM("h1:1234", + Resource.newInstance(NODE_MEMORY * GB, NODE1_VCORES), + newMockRM.getResourceTrackerService(), + YarnVersionInfo.getVersion()); + + nm1.registerNode(); + + //Label = GPU + nm2 = new MockNM("h2:1234", + Resource.newInstance(NODE_MEMORY * GB, NODE2_VCORES), + newMockRM.getResourceTrackerService(), + YarnVersionInfo.getVersion()); + nm2.registerNode(); + + nm3 = // label = "" + new MockNM("h3:1234", NODE_MEMORY * GB, NODE3_VCORES, newMockRM + .getResourceTrackerService()); + nm3.registerNode(); + } + + private CapacitySchedulerConfiguration setupCSConfiguration(YarnConfiguration configuration, + boolean useDominantRC) { + CapacitySchedulerConfiguration csConf = new CapacitySchedulerConfiguration(configuration); + if (useDominantRC) { + csConf.set(CapacitySchedulerConfiguration.RESOURCE_CALCULATOR_CLASS, + DominantResourceCalculator.class.getName()); + } + + csConf.setQueues(CapacitySchedulerConfiguration.ROOT, + new String[]{PARENT_A, PARENT_B}); + csConf.setQueues(PARENT_A_FULL_PATH, new String[]{LEAF_A}); + csConf.setQueues(PARENT_B_FULL_PATH, new String[]{LEAF_B}); + + csConf.setMinimumResourceRequirement("", PARENT_A_FULL_PATH, A_MINRES); + csConf.setMinimumResourceRequirement("", PARENT_B_FULL_PATH, B_MINRES); + csConf.setMinimumResourceRequirement("", LEAF_A_FULL_PATH, A_MINRES); + csConf.setMinimumResourceRequirement("", LEAF_B_FULL_PATH, B_MINRES); + + csConf.setMaximumResourceRequirement("", PARENT_A_FULL_PATH, PARTIAL_MAXRES); + csConf.setMaximumResourceRequirement("", PARENT_B_FULL_PATH, FULL_MAXRES); + csConf.setMaximumResourceRequirement("", LEAF_A_FULL_PATH, PARTIAL_MAXRES); + csConf.setMaximumResourceRequirement("", LEAF_B_FULL_PATH, FULL_MAXRES); + + return csConf; + } } From c660d81ae167eb08ee6b397a2ebcb387042ecf5e Mon Sep 17 00:00:00 2001 From: Benjamin Teke Date: Wed, 24 Nov 2021 14:25:10 +0100 Subject: [PATCH 2/4] Fix test mock issue. --- .../capacity/TestCapacitySchedulerConfigValidator.java | 2 ++ 1 file changed, 2 insertions(+) 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/TestCapacitySchedulerConfigValidator.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/TestCapacitySchedulerConfigValidator.java index 616c44cb965a03..19a3a35fcf2dff 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/TestCapacitySchedulerConfigValidator.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/TestCapacitySchedulerConfigValidator.java @@ -462,6 +462,8 @@ public void testAddQueueToALeafQueue() throws IOException { public static RMContext prepareRMContext() { RMContext rmContext = Mockito.mock(RMContext.class); + CapacityScheduler mockCs = Mockito.mock(CapacityScheduler.class); + Mockito.when(rmContext.getScheduler()).thenReturn(mockCs); LocalConfigurationProvider configProvider = Mockito .mock(LocalConfigurationProvider.class); Mockito.when(rmContext.getConfigurationProvider()) From ec83030060d860ac959f794945525a5f3df9bf6a Mon Sep 17 00:00:00 2001 From: Benjamin Teke Date: Mon, 29 Nov 2021 20:12:42 +0100 Subject: [PATCH 3/4] Add GPU test case. --- .../TestCapacitySchedulerConfigValidator.java | 134 ++++++++++++++---- 1 file changed, 104 insertions(+), 30 deletions(-) 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/TestCapacitySchedulerConfigValidator.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/TestCapacitySchedulerConfigValidator.java index 19a3a35fcf2dff..bdb60ae559815e 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/TestCapacitySchedulerConfigValidator.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/TestCapacitySchedulerConfigValidator.java @@ -19,8 +19,11 @@ package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.thirdparty.com.google.common.collect.ImmutableMap; import org.apache.hadoop.yarn.LocalConfigurationProvider; +import org.apache.hadoop.yarn.api.protocolrecords.ResourceTypes; import org.apache.hadoop.yarn.api.records.Resource; +import org.apache.hadoop.yarn.api.records.ResourceInformation; import org.apache.hadoop.yarn.api.records.impl.LightWeightResource; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; @@ -32,6 +35,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler; import org.apache.hadoop.yarn.util.YarnVersionInfo; import org.apache.hadoop.yarn.util.resource.DominantResourceCalculator; +import org.apache.hadoop.yarn.util.resource.ResourceUtils; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; @@ -40,6 +44,7 @@ import java.util.HashMap; import java.util.Map; +import static org.apache.hadoop.yarn.api.records.ResourceInformation.GPU_URI; import static org.junit.Assert.fail; public class TestCapacitySchedulerConfigValidator { @@ -47,6 +52,7 @@ public class TestCapacitySchedulerConfigValidator { public static final int NODE1_VCORES = 8; public static final int NODE2_VCORES = 10; public static final int NODE3_VCORES = 12; + public static final Map NODE_GPU = ImmutableMap.of(GPU_URI, 2L); public static final int GB = 1024; private static final String PARENT_A = "parentA"; @@ -63,16 +69,13 @@ public class TestCapacitySchedulerConfigValidator { private static final String LEAF_B_FULL_PATH = PARENT_B_FULL_PATH + "." + LEAF_B; - private static final Resource A_MINRES = Resource.newInstance(16 * GB, - 10); - private static final Resource B_MINRES = Resource.newInstance(32 * GB, - 5); - private static final Resource FULL_MAXRES = Resource.newInstance(48 * GB, - 30); - private static final Resource PARTIAL_MAXRES = Resource.newInstance(16 * GB, - 10); - private static final Resource VCORE_EXCEEDED_MAXRES = Resource.newInstance(16 * GB, - 50); + private static Resource A_MINRES; + private static Resource B_MINRES; + private static Resource FULL_MAXRES; + private static Resource PARTIAL_MAXRES; + private static Resource VCORE_EXCEEDED_MAXRES; + private static Resource GPU_EXCEEDED_MAXRES; + protected MockRM mockRM = null; protected MockNM nm1 = null; @@ -80,6 +83,30 @@ public class TestCapacitySchedulerConfigValidator { protected MockNM nm3 = null; protected CapacityScheduler cs; + public static void setupResources(boolean useGpu) { + Map riMap = new HashMap<>(); + + ResourceInformation memory = ResourceInformation.newInstance( + ResourceInformation.MEMORY_MB.getName(), + ResourceInformation.MEMORY_MB.getUnits(), + YarnConfiguration.DEFAULT_RM_SCHEDULER_MINIMUM_ALLOCATION_MB, + YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB); + ResourceInformation vcores = ResourceInformation.newInstance( + ResourceInformation.VCORES.getName(), + ResourceInformation.VCORES.getUnits(), + YarnConfiguration.DEFAULT_RM_SCHEDULER_MINIMUM_ALLOCATION_VCORES, + YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES); + riMap.put(ResourceInformation.MEMORY_URI, memory); + riMap.put(ResourceInformation.VCORES_URI, vcores); + if (useGpu) { + riMap.put(ResourceInformation.GPU_URI, + ResourceInformation.newInstance(ResourceInformation.GPU_URI, "", 0, + ResourceTypes.COUNTABLE, 0, 10L)); + } + + ResourceUtils.initializeResourcesFromResourceInformationMap(riMap); + } + /** * Test for the case when the scheduler.minimum-allocation-mb == 0. */ @@ -267,6 +294,26 @@ public void testValidateCSConfigDominantRCAbsoluteModeParentMaxVcoreExceeded() t } } + @Test + public void testValidateCSConfigDominantRCAbsoluteModeParentMaxGPUExceeded() throws Exception { + setUpMockRM(true); + RMContext rmContext = mockRM.getRMContext(); + CapacitySchedulerConfiguration oldConfiguration = cs.getConfiguration(); + CapacitySchedulerConfiguration newConfiguration = + new CapacitySchedulerConfiguration(cs.getConfiguration()); + newConfiguration.setMaximumResourceRequirement("", LEAF_A_FULL_PATH, GPU_EXCEEDED_MAXRES); + try { + CapacitySchedulerConfigValidator + .validateCSConfiguration(oldConfiguration, newConfiguration, rmContext); + fail("Parent maximum capacity exceeded"); + } catch (IOException e) { + Assert.assertTrue(e.getCause().getMessage() + .startsWith("Max resource configuration")); + } finally { + mockRM.stop(); + } + } + @Test public void testValidateCSConfigStopALeafQueue() throws IOException { Configuration oldConfig = CapacitySchedulerConfigGeneratorForTest @@ -275,7 +322,7 @@ public void testValidateCSConfigStopALeafQueue() throws IOException { newConfig .set("yarn.scheduler.capacity.root.test1.state", "STOPPED"); RMContext rmContext = prepareRMContext(); - Boolean isValidConfig = CapacitySchedulerConfigValidator + boolean isValidConfig = CapacitySchedulerConfigValidator .validateCSConfiguration(oldConfig, newConfig, rmContext); Assert.assertTrue(isValidConfig); } @@ -461,6 +508,7 @@ public void testAddQueueToALeafQueue() throws IOException { } public static RMContext prepareRMContext() { + setupResources(false); RMContext rmContext = Mockito.mock(RMContext.class); CapacityScheduler mockCs = Mockito.mock(CapacityScheduler.class); Mockito.when(rmContext.getScheduler()).thenReturn(mockCs); @@ -487,6 +535,8 @@ private void setUpMockRM(boolean useDominantRC) throws Exception { YarnConfiguration conf = new YarnConfiguration(); conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, ResourceScheduler.class); + setupResources(useDominantRC); + setupResourceValues(useDominantRC); CapacitySchedulerConfiguration csConf = setupCSConfiguration(conf, useDominantRC); mockRM = new MockRM(csConf); @@ -499,25 +549,48 @@ private void setUpMockRM(boolean useDominantRC) throws Exception { } private void setupNodes(MockRM newMockRM) throws Exception { - nm1 = - new MockNM("h1:1234", - Resource.newInstance(NODE_MEMORY * GB, NODE1_VCORES), - newMockRM.getResourceTrackerService(), - YarnVersionInfo.getVersion()); - - nm1.registerNode(); - - //Label = GPU - nm2 = new MockNM("h2:1234", - Resource.newInstance(NODE_MEMORY * GB, NODE2_VCORES), - newMockRM.getResourceTrackerService(), - YarnVersionInfo.getVersion()); - nm2.registerNode(); - - nm3 = // label = "" - new MockNM("h3:1234", NODE_MEMORY * GB, NODE3_VCORES, newMockRM - .getResourceTrackerService()); - nm3.registerNode(); + nm1 = new MockNM("h1:1234", + Resource.newInstance(NODE_MEMORY * GB, NODE1_VCORES, NODE_GPU), + newMockRM.getResourceTrackerService(), + YarnVersionInfo.getVersion()); + + nm1.registerNode(); + + nm2 = new MockNM("h2:1234", + Resource.newInstance(NODE_MEMORY * GB, NODE2_VCORES, NODE_GPU), + newMockRM.getResourceTrackerService(), + YarnVersionInfo.getVersion()); + nm2.registerNode(); + + nm3 = new MockNM("h3:1234", + Resource.newInstance(NODE_MEMORY * GB, NODE3_VCORES, NODE_GPU), + newMockRM.getResourceTrackerService(), + YarnVersionInfo.getVersion()); + nm3.registerNode(); + } + + private void setupResourceValues(boolean useGpu) { + A_MINRES = Resource.newInstance(16 * GB, 10); + B_MINRES = Resource.newInstance(32 * GB, 5); + FULL_MAXRES = Resource.newInstance(48 * GB, 30); + PARTIAL_MAXRES = Resource.newInstance(16 * GB, 10); + VCORE_EXCEEDED_MAXRES = Resource.newInstance(16 * GB, 50); + GPU_EXCEEDED_MAXRES = Resource.newInstance(16 * GB, 10); + + if (useGpu) { + A_MINRES.setResourceInformation(GPU_URI, + ResourceInformation.newInstance(GPU_URI, "", 2)); + B_MINRES.setResourceInformation(GPU_URI, + ResourceInformation.newInstance(GPU_URI, "", 2)); + FULL_MAXRES.setResourceInformation(GPU_URI, + ResourceInformation.newInstance(GPU_URI, "", 6)); + PARTIAL_MAXRES.setResourceInformation(GPU_URI, + ResourceInformation.newInstance(GPU_URI, "", 4)); + VCORE_EXCEEDED_MAXRES.setResourceInformation(GPU_URI, + ResourceInformation.newInstance(GPU_URI, "", 6)); + GPU_EXCEEDED_MAXRES.setResourceInformation(GPU_URI, + ResourceInformation.newInstance(GPU_URI, "", 50)); + } } private CapacitySchedulerConfiguration setupCSConfiguration(YarnConfiguration configuration, @@ -526,6 +599,7 @@ private CapacitySchedulerConfiguration setupCSConfiguration(YarnConfiguration co if (useDominantRC) { csConf.set(CapacitySchedulerConfiguration.RESOURCE_CALCULATOR_CLASS, DominantResourceCalculator.class.getName()); + csConf.set(YarnConfiguration.RESOURCE_TYPES, ResourceInformation.GPU_URI); } csConf.setQueues(CapacitySchedulerConfiguration.ROOT, From 517b25db1696e0e7eaae01d43dbd82782515ca93 Mon Sep 17 00:00:00 2001 From: Benjamin Teke Date: Tue, 30 Nov 2021 16:56:36 +0100 Subject: [PATCH 4/4] Test fixes. --- .../TestCapacitySchedulerConfigValidator.java | 84 ++++++++++--------- 1 file changed, 44 insertions(+), 40 deletions(-) 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/TestCapacitySchedulerConfigValidator.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/TestCapacitySchedulerConfigValidator.java index bdb60ae559815e..ad114d901cf9b3 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/TestCapacitySchedulerConfigValidator.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/TestCapacitySchedulerConfigValidator.java @@ -69,13 +69,16 @@ public class TestCapacitySchedulerConfigValidator { private static final String LEAF_B_FULL_PATH = PARENT_B_FULL_PATH + "." + LEAF_B; - private static Resource A_MINRES; - private static Resource B_MINRES; - private static Resource FULL_MAXRES; - private static Resource PARTIAL_MAXRES; - private static Resource VCORE_EXCEEDED_MAXRES; - private static Resource GPU_EXCEEDED_MAXRES; - + private final Resource A_MINRES = Resource.newInstance(16 * GB, 10); + private final Resource B_MINRES = Resource.newInstance(32 * GB, 5); + private final Resource FULL_MAXRES = Resource.newInstance(48 * GB, 30); + private final Resource PARTIAL_MAXRES = Resource.newInstance(16 * GB, 10); + private final Resource VCORE_EXCEEDED_MAXRES = Resource.newInstance(16 * GB, 50); + private Resource A_MINRES_GPU; + private Resource B_MINRES_GPU; + private Resource FULL_MAXRES_GPU; + private Resource PARTIAL_MAXRES_GPU; + private Resource GPU_EXCEEDED_MAXRES_GPU; protected MockRM mockRM = null; protected MockNM nm1 = null; @@ -301,7 +304,7 @@ public void testValidateCSConfigDominantRCAbsoluteModeParentMaxGPUExceeded() thr CapacitySchedulerConfiguration oldConfiguration = cs.getConfiguration(); CapacitySchedulerConfiguration newConfiguration = new CapacitySchedulerConfiguration(cs.getConfiguration()); - newConfiguration.setMaximumResourceRequirement("", LEAF_A_FULL_PATH, GPU_EXCEEDED_MAXRES); + newConfiguration.setMaximumResourceRequirement("", LEAF_A_FULL_PATH, GPU_EXCEEDED_MAXRES_GPU); try { CapacitySchedulerConfigValidator .validateCSConfiguration(oldConfiguration, newConfiguration, rmContext); @@ -536,7 +539,6 @@ private void setUpMockRM(boolean useDominantRC) throws Exception { conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, ResourceScheduler.class); setupResources(useDominantRC); - setupResourceValues(useDominantRC); CapacitySchedulerConfiguration csConf = setupCSConfiguration(conf, useDominantRC); mockRM = new MockRM(csConf); @@ -569,28 +571,17 @@ private void setupNodes(MockRM newMockRM) throws Exception { nm3.registerNode(); } - private void setupResourceValues(boolean useGpu) { - A_MINRES = Resource.newInstance(16 * GB, 10); - B_MINRES = Resource.newInstance(32 * GB, 5); - FULL_MAXRES = Resource.newInstance(48 * GB, 30); - PARTIAL_MAXRES = Resource.newInstance(16 * GB, 10); - VCORE_EXCEEDED_MAXRES = Resource.newInstance(16 * GB, 50); - GPU_EXCEEDED_MAXRES = Resource.newInstance(16 * GB, 10); - - if (useGpu) { - A_MINRES.setResourceInformation(GPU_URI, - ResourceInformation.newInstance(GPU_URI, "", 2)); - B_MINRES.setResourceInformation(GPU_URI, - ResourceInformation.newInstance(GPU_URI, "", 2)); - FULL_MAXRES.setResourceInformation(GPU_URI, - ResourceInformation.newInstance(GPU_URI, "", 6)); - PARTIAL_MAXRES.setResourceInformation(GPU_URI, - ResourceInformation.newInstance(GPU_URI, "", 4)); - VCORE_EXCEEDED_MAXRES.setResourceInformation(GPU_URI, - ResourceInformation.newInstance(GPU_URI, "", 6)); - GPU_EXCEEDED_MAXRES.setResourceInformation(GPU_URI, - ResourceInformation.newInstance(GPU_URI, "", 50)); - } + private void setupGpuResourceValues() { + A_MINRES_GPU = Resource.newInstance(A_MINRES.getMemorySize(), A_MINRES.getVirtualCores(), + ImmutableMap.of(GPU_URI, 2L)); + B_MINRES_GPU = Resource.newInstance(B_MINRES.getMemorySize(), B_MINRES.getVirtualCores(), + ImmutableMap.of(GPU_URI, 2L)); + FULL_MAXRES_GPU = Resource.newInstance(FULL_MAXRES.getMemorySize(), + FULL_MAXRES.getVirtualCores(), ImmutableMap.of(GPU_URI, 6L)); + PARTIAL_MAXRES_GPU = Resource.newInstance(PARTIAL_MAXRES.getMemorySize(), + PARTIAL_MAXRES.getVirtualCores(), ImmutableMap.of(GPU_URI, 4L)); + GPU_EXCEEDED_MAXRES_GPU = Resource.newInstance(PARTIAL_MAXRES.getMemorySize(), + PARTIAL_MAXRES.getVirtualCores(), ImmutableMap.of(GPU_URI, 50L)); } private CapacitySchedulerConfiguration setupCSConfiguration(YarnConfiguration configuration, @@ -607,15 +598,28 @@ private CapacitySchedulerConfiguration setupCSConfiguration(YarnConfiguration co csConf.setQueues(PARENT_A_FULL_PATH, new String[]{LEAF_A}); csConf.setQueues(PARENT_B_FULL_PATH, new String[]{LEAF_B}); - csConf.setMinimumResourceRequirement("", PARENT_A_FULL_PATH, A_MINRES); - csConf.setMinimumResourceRequirement("", PARENT_B_FULL_PATH, B_MINRES); - csConf.setMinimumResourceRequirement("", LEAF_A_FULL_PATH, A_MINRES); - csConf.setMinimumResourceRequirement("", LEAF_B_FULL_PATH, B_MINRES); - - csConf.setMaximumResourceRequirement("", PARENT_A_FULL_PATH, PARTIAL_MAXRES); - csConf.setMaximumResourceRequirement("", PARENT_B_FULL_PATH, FULL_MAXRES); - csConf.setMaximumResourceRequirement("", LEAF_A_FULL_PATH, PARTIAL_MAXRES); - csConf.setMaximumResourceRequirement("", LEAF_B_FULL_PATH, FULL_MAXRES); + if (useDominantRC) { + setupGpuResourceValues(); + csConf.setMinimumResourceRequirement("", PARENT_A_FULL_PATH, A_MINRES_GPU); + csConf.setMinimumResourceRequirement("", PARENT_B_FULL_PATH, B_MINRES_GPU); + csConf.setMinimumResourceRequirement("", LEAF_A_FULL_PATH, A_MINRES_GPU); + csConf.setMinimumResourceRequirement("", LEAF_B_FULL_PATH, B_MINRES_GPU); + + csConf.setMaximumResourceRequirement("", PARENT_A_FULL_PATH, PARTIAL_MAXRES_GPU); + csConf.setMaximumResourceRequirement("", PARENT_B_FULL_PATH, FULL_MAXRES_GPU); + csConf.setMaximumResourceRequirement("", LEAF_A_FULL_PATH, PARTIAL_MAXRES_GPU); + csConf.setMaximumResourceRequirement("", LEAF_B_FULL_PATH, FULL_MAXRES_GPU); + } else { + csConf.setMinimumResourceRequirement("", PARENT_A_FULL_PATH, A_MINRES); + csConf.setMinimumResourceRequirement("", PARENT_B_FULL_PATH, B_MINRES); + csConf.setMinimumResourceRequirement("", LEAF_A_FULL_PATH, A_MINRES); + csConf.setMinimumResourceRequirement("", LEAF_B_FULL_PATH, B_MINRES); + + csConf.setMaximumResourceRequirement("", PARENT_A_FULL_PATH, PARTIAL_MAXRES); + csConf.setMaximumResourceRequirement("", PARENT_B_FULL_PATH, FULL_MAXRES); + csConf.setMaximumResourceRequirement("", LEAF_A_FULL_PATH, PARTIAL_MAXRES); + csConf.setMaximumResourceRequirement("", LEAF_B_FULL_PATH, FULL_MAXRES); + } return csConf; }