@Test public void testNormalContainerAllocationWhenDNSUnavailable() throws Exception { YarnConfiguration conf = new YarnConfiguration(); YarnAPIStorageFactory.setConfiguration(conf); RMStorageFactory.setConfiguration(conf); MockRM rm1 = new MockRM(conf); try { rm1.start(); MockNM nm1 = rm1.registerNode("unknownhost:1234", 8000); RMApp app1 = rm1.submitApp(200); MockAM am1 = MockRM.launchAndRegisterAM(app1, rm1, nm1); // request a container. am1.allocate("127.0.0.1", 1024, 1, new ArrayList<ContainerId>()); ContainerId containerId2 = ContainerId.newInstance(am1.getApplicationAttemptId(), 2); rm1.waitForState(nm1, containerId2, RMContainerState.ALLOCATED); // acquire the container. SecurityUtilTestHelper.setTokenServiceUseIp(true); List<Container> containers = am1.allocate(new ArrayList<ResourceRequest>(), new ArrayList<ContainerId>()) .getAllocatedContainers(); // not able to fetch the container; Assert.assertEquals(0, containers.size()); SecurityUtilTestHelper.setTokenServiceUseIp(false); containers = am1.allocate(new ArrayList<ResourceRequest>(), new ArrayList<ContainerId>()) .getAllocatedContainers(); // should be able to fetch the container; Assert.assertEquals(1, containers.size()); } finally { rm1.stop(); } }
// This is to test container tokens are generated when the containers are // acquired by the AM, not when the containers are allocated @Test public void testContainerTokenGeneratedOnPullRequest() throws Exception { YarnConfiguration conf = new YarnConfiguration(); YarnAPIStorageFactory.setConfiguration(conf); RMStorageFactory.setConfiguration(conf); conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, ResourceScheduler.class); MockRM rm1 = new MockRM(conf); try { rm1.start(); MockNM nm1 = rm1.registerNode("127.0.0.1:1234", 8000); RMApp app1 = rm1.submitApp(200); MockAM am1 = MockRM.launchAndRegisterAM(app1, rm1, nm1); // request a container. am1.allocate("127.0.0.1", 1024, 1, new ArrayList<ContainerId>()); ContainerId containerId2 = ContainerId.newInstance(am1.getApplicationAttemptId(), 2); rm1.waitForState(nm1, containerId2, RMContainerState.ALLOCATED); RMContainer container = rm1.getResourceScheduler().getRMContainer(containerId2); // no container token is generated. Assert.assertEquals(containerId2, container.getContainerId()); Assert.assertNull(container.getContainer().getContainerToken()); // acquire the container. List<Container> containers = am1.allocate(new ArrayList<ResourceRequest>(), new ArrayList<ContainerId>()) .getAllocatedContainers(); Assert.assertEquals(containerId2, containers.get(0).getId()); // container token is generated. Assert.assertNotNull(containers.get(0).getContainerToken()); } finally { rm1.stop(); } }
@Test public void testPriorityWithPendingApplications() throws Exception { Configuration conf = new Configuration(); conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, ResourceScheduler.class); // Set Max Application Priority as 10 conf.setInt(YarnConfiguration.MAX_CLUSTER_LEVEL_APPLICATION_PRIORITY, 10); MockRM rm = new MockRM(conf); rm.start(); Priority appPriority1 = Priority.newInstance(5); MockNM nm1 = rm.registerNode("127.0.0.1:1234", 8 * GB); RMApp app1 = rm.submitApp(1 * GB, appPriority1); // kick the scheduler, 1 GB given to AM1, remaining 7GB on nm1 MockAM am1 = MockRM.launchAM(app1, rm, nm1); am1.registerAppAttempt(); // kick the scheduler, 7 containers will be allocated for App1 List<Container> allocated1 = am1.allocateAndWaitForContainers("127.0.0.1", 7, 1 * GB, nm1); Assert.assertEquals(7, allocated1.size()); Assert.assertEquals(1 * GB, allocated1.get(0).getResource().getMemory()); // check node report, 8 GB used (1 AM and 7 containers) and 0 GB available SchedulerNodeReport report_nm1 = rm.getResourceScheduler().getNodeReport(nm1.getNodeId()); Assert.assertEquals(8 * GB, report_nm1.getUsedResource().getMemory()); Assert.assertEquals(0 * GB, report_nm1.getAvailableResource().getMemory()); // Submit the second app App2 with priority 7 Priority appPriority2 = Priority.newInstance(7); RMApp app2 = rm.submitApp(1 * GB, appPriority2); // Submit the third app App3 with priority 8 Priority appPriority3 = Priority.newInstance(8); RMApp app3 = rm.submitApp(1 * GB, appPriority3); // Submit the second app App4 with priority 6 Priority appPriority4 = Priority.newInstance(6); RMApp app4 = rm.submitApp(1 * GB, appPriority4); // Only one app can run as AM resource limit restricts it. Kill app1, // If app3 (highest priority among rest) gets active, it indicates that // priority is working with pendingApplications. rm.killApp(app1.getApplicationId()); // kick the scheduler, app3 (high among pending) gets free space MockAM am3 = MockRM.launchAM(app3, rm, nm1); am3.registerAppAttempt(); // check node report, 1 GB used and 7 GB available report_nm1 = rm.getResourceScheduler().getNodeReport(nm1.getNodeId()); Assert.assertEquals(1 * GB, report_nm1.getUsedResource().getMemory()); Assert.assertEquals(7 * GB, report_nm1.getAvailableResource().getMemory()); rm.stop(); }
@Test(timeout = 15000) public void testRMDTMasterKeyStateOnRollingMasterKey() throws Exception { MemoryRMStateStore memStore = new MemoryRMStateStore(); memStore.init(conf); RMState rmState = memStore.getState(); Map<RMDelegationTokenIdentifier, Long> rmDTState = rmState.getRMDTSecretManagerState().getTokenState(); Set<DelegationKey> rmDTMasterKeyState = rmState.getRMDTSecretManagerState().getMasterKeyState(); MockRM rm1 = new MyMockRM(conf, memStore); rm1.start(); // on rm start, two master keys are created. // One is created at RMDTSecretMgr.startThreads.updateCurrentKey(); // the other is created on the first run of // tokenRemoverThread.rollMasterKey() RMDelegationTokenSecretManager dtSecretManager = rm1.getRMDTSecretManager(); // assert all master keys are saved Assert.assertEquals(dtSecretManager.getAllMasterKeys(), rmDTMasterKeyState); Set<DelegationKey> expiringKeys = new HashSet<DelegationKey>(); expiringKeys.addAll(dtSecretManager.getAllMasterKeys()); // record the current key DelegationKey oldCurrentKey = ((TestRMDelegationTokenSecretManager) dtSecretManager).getCurrentKey(); // request to generate a RMDelegationToken GetDelegationTokenRequest request = mock(GetDelegationTokenRequest.class); when(request.getRenewer()).thenReturn("renewer1"); GetDelegationTokenResponse response = rm1.getClientRMService().getDelegationToken(request); org.apache.hadoop.yarn.api.records.Token delegationToken = response.getRMDelegationToken(); Token<RMDelegationTokenIdentifier> token1 = ConverterUtils.convertFromYarn(delegationToken, null); RMDelegationTokenIdentifier dtId1 = token1.decodeIdentifier(); // wait for the first rollMasterKey while (((TestRMDelegationTokenSecretManager) dtSecretManager).numUpdatedKeys.get() < 1) { Thread.sleep(200); } // assert old-current-key and new-current-key exist Assert.assertTrue(rmDTMasterKeyState.contains(oldCurrentKey)); DelegationKey newCurrentKey = ((TestRMDelegationTokenSecretManager) dtSecretManager).getCurrentKey(); Assert.assertTrue(rmDTMasterKeyState.contains(newCurrentKey)); // wait for token to expire // rollMasterKey is called every 1 second. while (((TestRMDelegationTokenSecretManager) dtSecretManager).numUpdatedKeys.get() < 6) { Thread.sleep(200); } Assert.assertFalse(rmDTState.containsKey(dtId1)); rm1.stop(); }
@Test public void testMaxPriorityValidation() throws Exception { Configuration conf = new Configuration(); conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, ResourceScheduler.class); // Set Max Application Priority as 10 conf.setInt(YarnConfiguration.MAX_CLUSTER_LEVEL_APPLICATION_PRIORITY, 10); Priority maxPriority = Priority.newInstance(10); MockRM rm = new MockRM(conf); rm.start(); Priority appPriority1 = Priority.newInstance(15); rm.registerNode("127.0.0.1:1234", 8 * GB); RMApp app1 = rm.submitApp(1 * GB, appPriority1); // Application submission should be successful and verify priority Assert.assertEquals(app1.getApplicationSubmissionContext().getPriority(), maxPriority); rm.stop(); }
@Test(timeout = 30000) public void testApplicationTypeLimit() throws Exception { Logger rootLogger = LogManager.getRootLogger(); rootLogger.setLevel(Level.DEBUG); MockRM rm = new MockRM(); rm.start(); RMApp app1 = rm.submitApp( 200, "name", "user", new HashMap<ApplicationAccessType, String>(), false, "default", -1, null, "MAPREDUCE-LENGTH-IS-20"); Assert.assertEquals("MAPREDUCE-LENGTH-IS-", app1.getApplicationType()); rm.stop(); }
// This is to test fetching AM container will be retried, if AM container is // not fetchable since DNS is unavailable causing container token/NMtoken // creation failure. @Test(timeout = 60000) public void testAMContainerAllocationWhenDNSUnavailable() throws Exception { final YarnConfiguration conf = new YarnConfiguration(); YarnAPIStorageFactory.setConfiguration(conf); RMStorageFactory.setConfiguration(conf); MockRM rm1 = new MockRM(conf) { @Override protected RMSecretManagerService createRMSecretManagerService() { return new TestRMSecretManagerService(conf, rmContext); } }; try { rm1.start(); MockNM nm1 = rm1.registerNode("unknownhost:1234", 8000); SecurityUtilTestHelper.setTokenServiceUseIp(true); RMApp app1 = rm1.submitApp(200); RMAppAttempt attempt = app1.getCurrentAppAttempt(); nm1.nodeHeartbeat(true); // fetching am container will fail, keep retrying 5 times. while (numRetries <= 5) { nm1.nodeHeartbeat(true); Thread.sleep(1000); Assert.assertEquals(RMAppAttemptState.SCHEDULED, attempt.getState()); System.out.println("Waiting for am container to be allocated."); } SecurityUtilTestHelper.setTokenServiceUseIp(false); rm1.waitForState(attempt.getAppAttemptId(), RMAppAttemptState.ALLOCATED); MockRM.launchAndRegisterAM(app1, rm1, nm1); } finally { rm1.stop(); } }
@Test public void testNonLeaderKeyReception() throws InterruptedException, StorageInitializtionException, Exception { // create a groupMembershipService that will be leader RMContextImpl rmContext = new RMContextImpl(); rmContext.setDistributedEnabled(true); rmContext.setHAEnabled(true); GroupMembershipService groupMembershipService = new GroupMembershipService(null, rmContext); groupMembershipService.init(conf); NMTokenSecretManagerInRM nmTokenSecretManager = new NMTokenSecretManagerInRM(conf, rmContext); // create a resrouce tracker conf.setBoolean(YarnConfiguration.RM_HA_ENABLED, true); conf.setBoolean(YarnConfiguration.DISTRIBUTED_RM, true); MockRM mockRM = new MockRM(conf); mockRM.init(conf); try { groupMembershipService.start(); rmContext.setRMGroupMembershipService(groupMembershipService); rmContext.setStateStore(new NDBRMStateStore()); while (!rmContext.isLeader()) { Thread.sleep(1000); } mockRM.start(); if (mockRM.getRMContext().isDistributedEnabled() && !mockRM.getRMContext().isLeader()) { conf.set( YarnConfiguration.EVENT_RT_CONFIG_PATH, "target/test-classes/RT_EventAPIConfig.ini"); NdbRtStreamingProcessor rtStreamingProcessor = new NdbRtStreamingProcessor(mockRM.getRMContext()); RMStorageFactory.kickTheNdbEventStreamingAPI(false, conf); new Thread(rtStreamingProcessor).start(); } // this should be a resource tracker not a scheduler assertFalse(mockRM.getRMContext().isLeader()); // simulate creation of a token on the sheduler nmTokenSecretManager.start(); assertNotNull("did not roll master key", nmTokenSecretManager.getCurrentKey()); Thread.sleep(1000); dummyUpdate(); Thread.sleep(1000); RMStateStore.RMState state = rmContext.getStateStore().loadState(rmContext); assertEquals( "key not persisted to the database", state.getSecretTokenMamagerKey(RMStateStore.KeyType.CURRENTNMTOKENMASTERKEY), nmTokenSecretManager.getCurrentKey()); assertEquals( nmTokenSecretManager.getCurrentKey(), mockRM.getRMContext().getNMTokenSecretManager().getCurrentKey()); assertEquals( nmTokenSecretManager.getNextKey(), mockRM.getRMContext().getNMTokenSecretManager().getNextKey()); } finally { groupMembershipService.stop(); mockRM.stop(); nmTokenSecretManager.stop(); DefaultMetricsSystem.shutdown(); } }
@Test(timeout = 30000) public void testExcessReservationThanNodeManagerCapacity() throws Exception { YarnConfiguration conf = new YarnConfiguration(); YarnAPIStorageFactory.setConfiguration(conf); RMStorageFactory.setConfiguration(conf); MockRM rm = new MockRM(conf); try { rm.start(); // Register node1 MockNM nm1 = rm.registerNode("127.0.0.1:1234", 2 * GB, 4); MockNM nm2 = rm.registerNode("127.0.0.1:2234", 3 * GB, 4); nm1.nodeHeartbeat(true); nm2.nodeHeartbeat(true); // HOP :: Sleep to allow previous events to be processed Thread.sleep( conf.getInt( YarnConfiguration.HOPS_PENDING_EVENTS_RETRIEVAL_PERIOD, YarnConfiguration.DEFAULT_HOPS_PENDING_EVENTS_RETRIEVAL_PERIOD) * 2); // wait.. int waitCount = 20; int size = rm.getRMContext().getActiveRMNodes().size(); while ((size = rm.getRMContext().getActiveRMNodes().size()) != 2 && waitCount-- > 0) { LOG.info("Waiting for node managers to register : " + size); Thread.sleep(100); } Assert.assertEquals(2, rm.getRMContext().getActiveRMNodes().size()); // Submit an application RMApp app1 = rm.submitApp(128); // kick the scheduling nm1.nodeHeartbeat(true); RMAppAttempt attempt1 = app1.getCurrentAppAttempt(); MockAM am1 = rm.sendAMLaunched(attempt1.getAppAttemptId(), nm1); am1.registerAppAttempt(); LOG.info("sending container requests "); am1.addRequests(new String[] {"*"}, 3 * GB, 1, 1); AllocateResponse alloc1Response = am1.schedule(); // send the request // kick the scheduler nm1.nodeHeartbeat(true); int waitCounter = 20; LOG.info("heartbeating nm1"); while (alloc1Response.getAllocatedContainers().size() < 1 && waitCounter-- > 0) { LOG.info("Waiting for containers to be created for app 1..."); Thread.sleep(500); alloc1Response = am1.schedule(); } LOG.info("received container : " + alloc1Response.getAllocatedContainers().size()); // No container should be allocated. // Internally it should not been reserved. Assert.assertTrue(alloc1Response.getAllocatedContainers().size() == 0); LOG.info("heartbeating nm2"); waitCounter = 20; nm2.nodeHeartbeat(true); while (alloc1Response.getAllocatedContainers().size() < 1 && waitCounter-- > 0) { LOG.info("Waiting for containers to be created for app 1..."); Thread.sleep(500); alloc1Response = am1.schedule(); } LOG.info("received container : " + alloc1Response.getAllocatedContainers().size()); Assert.assertTrue(alloc1Response.getAllocatedContainers().size() == 1); } finally { rm.stop(); } }
@Test public void testApplicationOrderingWithPriority() throws Exception { Configuration conf = new Configuration(); conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, ResourceScheduler.class); MockRM rm = new MockRM(conf); rm.start(); CapacityScheduler cs = (CapacityScheduler) rm.getResourceScheduler(); LeafQueue q = (LeafQueue) cs.getQueue("default"); Assert.assertNotNull(q); String host = "127.0.0.1"; RMNode node = MockNodes.newNodeInfo(0, MockNodes.newResource(16 * GB), 1, host); cs.handle(new NodeAddedSchedulerEvent(node)); // add app 1 start ApplicationId appId1 = BuilderUtils.newApplicationId(100, 1); ApplicationAttemptId appAttemptId1 = BuilderUtils.newApplicationAttemptId(appId1, 1); RMAppAttemptMetrics attemptMetric1 = new RMAppAttemptMetrics(appAttemptId1, rm.getRMContext()); RMAppImpl app1 = mock(RMAppImpl.class); when(app1.getApplicationId()).thenReturn(appId1); RMAppAttemptImpl attempt1 = mock(RMAppAttemptImpl.class); when(attempt1.getAppAttemptId()).thenReturn(appAttemptId1); when(attempt1.getRMAppAttemptMetrics()).thenReturn(attemptMetric1); when(app1.getCurrentAppAttempt()).thenReturn(attempt1); rm.getRMContext().getRMApps().put(appId1, app1); SchedulerEvent addAppEvent1 = new AppAddedSchedulerEvent(appId1, "default", "user", null, Priority.newInstance(5)); cs.handle(addAppEvent1); SchedulerEvent addAttemptEvent1 = new AppAttemptAddedSchedulerEvent(appAttemptId1, false); cs.handle(addAttemptEvent1); // add app1 end // add app2 begin ApplicationId appId2 = BuilderUtils.newApplicationId(100, 2); ApplicationAttemptId appAttemptId2 = BuilderUtils.newApplicationAttemptId(appId2, 1); RMAppAttemptMetrics attemptMetric2 = new RMAppAttemptMetrics(appAttemptId2, rm.getRMContext()); RMAppImpl app2 = mock(RMAppImpl.class); when(app2.getApplicationId()).thenReturn(appId2); RMAppAttemptImpl attempt2 = mock(RMAppAttemptImpl.class); when(attempt2.getAppAttemptId()).thenReturn(appAttemptId2); when(attempt2.getRMAppAttemptMetrics()).thenReturn(attemptMetric2); when(app2.getCurrentAppAttempt()).thenReturn(attempt2); rm.getRMContext().getRMApps().put(appId2, app2); SchedulerEvent addAppEvent2 = new AppAddedSchedulerEvent(appId2, "default", "user", null, Priority.newInstance(8)); cs.handle(addAppEvent2); SchedulerEvent addAttemptEvent2 = new AppAttemptAddedSchedulerEvent(appAttemptId2, false); cs.handle(addAttemptEvent2); // add app end // Now, the first assignment will be for app2 since app2 is of highest // priority assertEquals(q.getApplications().size(), 2); assertEquals(q.getApplications().iterator().next().getApplicationAttemptId(), appAttemptId2); rm.stop(); }
@Test public void testApplicationPriorityAllocation() throws Exception { Configuration conf = new Configuration(); conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, ResourceScheduler.class); // Set Max Application Priority as 10 conf.setInt(YarnConfiguration.MAX_CLUSTER_LEVEL_APPLICATION_PRIORITY, 10); MockRM rm = new MockRM(conf); rm.start(); Priority appPriority1 = Priority.newInstance(5); MockNM nm1 = rm.registerNode("127.0.0.1:1234", 16 * GB); RMApp app1 = rm.submitApp(1 * GB, appPriority1); // kick the scheduler, 1 GB given to AM1, remaining 15GB on nm1 MockAM am1 = MockRM.launchAM(app1, rm, nm1); am1.registerAppAttempt(); // allocate 7 containers for App1 List<Container> allocated1 = am1.allocateAndWaitForContainers("127.0.0.1", 7, 2 * GB, nm1); Assert.assertEquals(7, allocated1.size()); Assert.assertEquals(2 * GB, allocated1.get(0).getResource().getMemory()); // check node report, 15 GB used (1 AM and 7 containers) and 1 GB available SchedulerNodeReport report_nm1 = rm.getResourceScheduler().getNodeReport(nm1.getNodeId()); Assert.assertEquals(15 * GB, report_nm1.getUsedResource().getMemory()); Assert.assertEquals(1 * GB, report_nm1.getAvailableResource().getMemory()); // Submit the second app App2 with priority 8 (Higher than App1) Priority appPriority2 = Priority.newInstance(8); RMApp app2 = rm.submitApp(1 * GB, appPriority2); // kick the scheduler, 1 GB which was free is given to AM of App2 MockAM am2 = MockRM.launchAM(app2, rm, nm1); am2.registerAppAttempt(); // check node report, 16 GB used and 0 GB available report_nm1 = rm.getResourceScheduler().getNodeReport(nm1.getNodeId()); Assert.assertEquals(16 * GB, report_nm1.getUsedResource().getMemory()); Assert.assertEquals(0 * GB, report_nm1.getAvailableResource().getMemory()); // get scheduler CapacityScheduler cs = (CapacityScheduler) rm.getResourceScheduler(); // get scheduler app FiCaSchedulerApp schedulerAppAttempt = cs.getSchedulerApplications().get(app1.getApplicationId()).getCurrentAppAttempt(); // kill 2 containers of App1 to free up some space int counter = 0; for (Container c : allocated1) { if (++counter > 2) { break; } cs.killContainer(schedulerAppAttempt.getRMContainer(c.getId())); } // check node report, 12 GB used and 4 GB available report_nm1 = rm.getResourceScheduler().getNodeReport(nm1.getNodeId()); Assert.assertEquals(12 * GB, report_nm1.getUsedResource().getMemory()); Assert.assertEquals(4 * GB, report_nm1.getAvailableResource().getMemory()); // send updated request for App1 am1.allocate("127.0.0.1", 2 * GB, 10, new ArrayList<ContainerId>()); // kick the scheduler, since App2 priority is more than App1, it will get // remaining cluster space. List<Container> allocated2 = am2.allocateAndWaitForContainers("127.0.0.1", 2, 2 * GB, nm1); // App2 has got 2 containers now. Assert.assertEquals(2, allocated2.size()); // check node report, 16 GB used and 0 GB available report_nm1 = rm.getResourceScheduler().getNodeReport(nm1.getNodeId()); Assert.assertEquals(16 * GB, report_nm1.getUsedResource().getMemory()); Assert.assertEquals(0 * GB, report_nm1.getAvailableResource().getMemory()); rm.stop(); }