|
34 | 34 | import java.util.concurrent.ExecutorService;
|
35 | 35 | import java.util.concurrent.TimeUnit;
|
36 | 36 |
|
| 37 | +import com.google.common.collect.ImmutableMap; |
37 | 38 | import org.apache.hadoop.util.concurrent.HadoopExecutors;
|
38 | 39 | import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
|
39 | 40 | import org.apache.hadoop.yarn.api.records.Resource;
|
|
42 | 43 | import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
|
43 | 44 | import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
44 | 45 | import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
|
| 46 | +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.QueueMetricsCustomResource; |
45 | 47 | import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
46 | 48 | import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeAddedSchedulerEvent;
|
47 | 49 | import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeUpdateSchedulerEvent;
|
| 50 | +import org.apache.hadoop.yarn.util.resource.ResourceUtils; |
48 | 51 | import org.apache.hadoop.yarn.util.resource.Resources;
|
49 | 52 | import org.junit.After;
|
50 | 53 | import org.junit.Before;
|
51 | 54 | import org.junit.Test;
|
52 | 55 | import org.mockito.Mockito;
|
| 56 | +import java.util.Map; |
| 57 | +import static org.junit.Assert.assertFalse; |
| 58 | +import static org.junit.Assert.assertNotNull; |
53 | 59 |
|
54 | 60 | public class TestFSLeafQueue extends FairSchedulerTestBase {
|
55 | 61 | private final static String ALLOC_FILE = new File(TEST_DIR,
|
56 | 62 | TestFSLeafQueue.class.getName() + ".xml").getAbsolutePath();
|
57 | 63 | private Resource maxResource = Resources.createResource(1024 * 8);
|
| 64 | + private static final float MAX_AM_SHARE = 0.5f; |
| 65 | + private static final String CUSTOM_RESOURCE = "test1"; |
58 | 66 |
|
59 | 67 | @Before
|
60 | 68 | public void setup() throws IOException {
|
@@ -105,6 +113,8 @@ public void test() throws Exception {
|
105 | 113 | PrintWriter out = new PrintWriter(new FileWriter(ALLOC_FILE));
|
106 | 114 | out.println("<?xml version=\"1.0\"?>");
|
107 | 115 | out.println("<allocations>");
|
| 116 | + out.println("<queueMaxAMShareDefault>" + MAX_AM_SHARE + |
| 117 | + "</queueMaxAMShareDefault>"); |
108 | 118 | out.println("<queue name=\"queueA\"></queue>");
|
109 | 119 | out.println("<queue name=\"queueB\"></queue>");
|
110 | 120 | out.println("</allocations>");
|
@@ -221,4 +231,128 @@ public void run() {
|
221 | 231 | assertTrue("Test failed with exception(s)" + exceptions,
|
222 | 232 | exceptions.isEmpty());
|
223 | 233 | }
|
| 234 | + |
| 235 | + @Test |
| 236 | + public void testCanRunAppAMReturnsTrue() { |
| 237 | + conf.set(YarnConfiguration.RESOURCE_TYPES, CUSTOM_RESOURCE); |
| 238 | + ResourceUtils.resetResourceTypes(conf); |
| 239 | + |
| 240 | + resourceManager = new MockRM(conf); |
| 241 | + resourceManager.start(); |
| 242 | + scheduler = (FairScheduler) resourceManager.getResourceScheduler(); |
| 243 | + |
| 244 | + Resource maxShare = Resource.newInstance(1024 * 8, 4, |
| 245 | + ImmutableMap.of(CUSTOM_RESOURCE, 10L)); |
| 246 | + |
| 247 | + // Add a node to increase available memory and vcores in scheduler's |
| 248 | + // root queue metrics |
| 249 | + addNodeToScheduler(Resource.newInstance(4096, 10, |
| 250 | + ImmutableMap.of(CUSTOM_RESOURCE, 25L))); |
| 251 | + |
| 252 | + FSLeafQueue queue = setupQueue(maxShare); |
| 253 | + |
| 254 | + //Min(availableMemory, maxShareMemory (maxResourceOverridden)) |
| 255 | + // --> Min(4096, 8192) = 4096 |
| 256 | + //Min(availableVCores, maxShareVCores (maxResourceOverridden)) |
| 257 | + // --> Min(10, 4) = 4 |
| 258 | + //Min(available test1, maxShare test1 (maxResourceOverridden)) |
| 259 | + // --> Min(25, 10) = 10 |
| 260 | + //MaxAMResource: (4096 MB memory, 4 vcores, 10 test1) * MAX_AM_SHARE |
| 261 | + // --> 2048 MB memory, 2 vcores, 5 test1 |
| 262 | + Resource expectedAMShare = Resource.newInstance(2048, 2, |
| 263 | + ImmutableMap.of(CUSTOM_RESOURCE, 5L)); |
| 264 | + |
| 265 | + Resource appAMResource = Resource.newInstance(2048, 2, |
| 266 | + ImmutableMap.of(CUSTOM_RESOURCE, 3L)); |
| 267 | + |
| 268 | + Map<String, Long> customResourceValues = |
| 269 | + verifyQueueMetricsForCustomResources(queue); |
| 270 | + |
| 271 | + boolean result = queue.canRunAppAM(appAMResource); |
| 272 | + assertTrue("AM should have been allocated!", result); |
| 273 | + |
| 274 | + verifyAMShare(queue, expectedAMShare, customResourceValues); |
| 275 | + } |
| 276 | + |
| 277 | + private FSLeafQueue setupQueue(Resource maxShare) { |
| 278 | + String queueName = "root.queue1"; |
| 279 | + FSLeafQueue schedulable = new FSLeafQueue(queueName, scheduler, null); |
| 280 | + schedulable.setMaxShare(new ConfigurableResource(maxShare)); |
| 281 | + schedulable.setMaxAMShare(MAX_AM_SHARE); |
| 282 | + return schedulable; |
| 283 | + } |
| 284 | + |
| 285 | + @Test |
| 286 | + public void testCanRunAppAMReturnsFalse() { |
| 287 | + conf.set(YarnConfiguration.RESOURCE_TYPES, CUSTOM_RESOURCE); |
| 288 | + ResourceUtils.resetResourceTypes(conf); |
| 289 | + |
| 290 | + resourceManager = new MockRM(conf); |
| 291 | + resourceManager.start(); |
| 292 | + scheduler = (FairScheduler) resourceManager.getResourceScheduler(); |
| 293 | + |
| 294 | + Resource maxShare = Resource.newInstance(1024 * 8, 4, |
| 295 | + ImmutableMap.of(CUSTOM_RESOURCE, 10L)); |
| 296 | + |
| 297 | + // Add a node to increase available memory and vcores in scheduler's |
| 298 | + // root queue metrics |
| 299 | + addNodeToScheduler(Resource.newInstance(4096, 10, |
| 300 | + ImmutableMap.of(CUSTOM_RESOURCE, 25L))); |
| 301 | + |
| 302 | + FSLeafQueue queue = setupQueue(maxShare); |
| 303 | + |
| 304 | + //Min(availableMemory, maxShareMemory (maxResourceOverridden)) |
| 305 | + // --> Min(4096, 8192) = 4096 |
| 306 | + //Min(availableVCores, maxShareVCores (maxResourceOverridden)) |
| 307 | + // --> Min(10, 4) = 4 |
| 308 | + //Min(available test1, maxShare test1 (maxResourceOverridden)) |
| 309 | + // --> Min(25, 10) = 10 |
| 310 | + //MaxAMResource: (4096 MB memory, 4 vcores, 10 test1) * MAX_AM_SHARE |
| 311 | + // --> 2048 MB memory, 2 vcores, 5 test1 |
| 312 | + Resource expectedAMShare = Resource.newInstance(2048, 2, |
| 313 | + ImmutableMap.of(CUSTOM_RESOURCE, 5L)); |
| 314 | + |
| 315 | + Resource appAMResource = Resource.newInstance(2048, 2, |
| 316 | + ImmutableMap.of(CUSTOM_RESOURCE, 6L)); |
| 317 | + |
| 318 | + Map<String, Long> customResourceValues = |
| 319 | + verifyQueueMetricsForCustomResources(queue); |
| 320 | + |
| 321 | + boolean result = queue.canRunAppAM(appAMResource); |
| 322 | + assertFalse("AM should not have been allocated!", result); |
| 323 | + |
| 324 | + verifyAMShare(queue, expectedAMShare, customResourceValues); |
| 325 | + } |
| 326 | + |
| 327 | + private void addNodeToScheduler(Resource node1Resource) { |
| 328 | + RMNode node1 = MockNodes.newNodeInfo(0, node1Resource, 1, "127.0.0.2"); |
| 329 | + scheduler.handle(new NodeAddedSchedulerEvent(node1)); |
| 330 | + } |
| 331 | + |
| 332 | + private void verifyAMShare(FSLeafQueue schedulable, |
| 333 | + Resource expectedAMShare, Map<String, Long> customResourceValues) { |
| 334 | + Resource actualAMShare = Resource.newInstance( |
| 335 | + schedulable.getMetrics().getMaxAMShareMB(), |
| 336 | + schedulable.getMetrics().getMaxAMShareVCores(), customResourceValues); |
| 337 | + long customResourceValue = |
| 338 | + actualAMShare.getResourceValue(CUSTOM_RESOURCE); |
| 339 | + |
| 340 | + //make sure to verify custom resource value explicitly! |
| 341 | + assertEquals(5L, customResourceValue); |
| 342 | + assertEquals("AM share is not the expected!", expectedAMShare, |
| 343 | + actualAMShare); |
| 344 | + } |
| 345 | + |
| 346 | + private Map<String, Long> verifyQueueMetricsForCustomResources( |
| 347 | + FSLeafQueue schedulable) { |
| 348 | + QueueMetricsCustomResource maxAMShareCustomResources = |
| 349 | + schedulable.getMetrics().getCustomResources().getMaxAMShare(); |
| 350 | + Map<String, Long> customResourceValues = maxAMShareCustomResources |
| 351 | + .getValues(); |
| 352 | + assertNotNull("Queue metrics for custom resources should not be null!", |
| 353 | + maxAMShareCustomResources); |
| 354 | + assertNotNull("Queue metrics for custom resources resource values " + |
| 355 | + "should not be null!", customResourceValues); |
| 356 | + return customResourceValues; |
| 357 | + } |
224 | 358 | }
|
0 commit comments