|
25 | 25 | import static org.mockito.Mockito.when; |
26 | 26 |
|
27 | 27 | import java.io.IOException; |
| 28 | +import java.net.InetSocketAddress; |
| 29 | +import java.security.PrivilegedAction; |
28 | 30 | import java.util.Collections; |
29 | 31 | import java.util.Comparator; |
| 32 | +import java.util.HashMap; |
30 | 33 | import java.util.List; |
| 34 | +import java.util.Map; |
| 35 | +import java.util.concurrent.BrokenBarrierException; |
| 36 | +import java.util.concurrent.CyclicBarrier; |
31 | 37 |
|
32 | 38 | import org.apache.commons.logging.Log; |
33 | 39 | import org.apache.commons.logging.LogFactory; |
34 | 40 | import org.apache.hadoop.conf.Configuration; |
35 | 41 | import org.apache.hadoop.net.NetworkTopology; |
| 42 | +import org.apache.hadoop.security.Credentials; |
| 43 | +import org.apache.hadoop.security.UserGroupInformation; |
| 44 | +import org.apache.hadoop.security.token.Token; |
| 45 | +import org.apache.hadoop.security.token.TokenIdentifier; |
36 | 46 | import org.apache.hadoop.yarn.LocalConfigurationProvider; |
| 47 | +import org.apache.hadoop.yarn.api.ApplicationMasterProtocol; |
| 48 | +import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest; |
| 49 | +import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterRequest; |
| 50 | +import org.apache.hadoop.yarn.api.records.ApplicationAccessType; |
37 | 51 | import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; |
38 | 52 | import org.apache.hadoop.yarn.api.records.ApplicationId; |
39 | 53 | import org.apache.hadoop.yarn.api.records.ContainerId; |
|
46 | 60 | import org.apache.hadoop.yarn.event.AsyncDispatcher; |
47 | 61 | import org.apache.hadoop.yarn.exceptions.YarnException; |
48 | 62 | import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; |
| 63 | +import org.apache.hadoop.yarn.ipc.YarnRPC; |
49 | 64 | import org.apache.hadoop.yarn.server.resourcemanager.Application; |
| 65 | +import org.apache.hadoop.yarn.server.resourcemanager.MockNM; |
50 | 66 | import org.apache.hadoop.yarn.server.resourcemanager.MockNodes; |
51 | 67 | import org.apache.hadoop.yarn.server.resourcemanager.MockRM; |
52 | 68 | import org.apache.hadoop.yarn.server.resourcemanager.RMContext; |
53 | 69 | import org.apache.hadoop.yarn.server.resourcemanager.RMContextImpl; |
54 | 70 | import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager; |
55 | 71 | import org.apache.hadoop.yarn.server.resourcemanager.Task; |
| 72 | +import org.apache.hadoop.yarn.server.resourcemanager.TestAMAuthorization.MockRMWithAMS; |
| 73 | +import org.apache.hadoop.yarn.server.resourcemanager.TestAMAuthorization.MyContainerManager; |
| 74 | +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp; |
| 75 | +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt; |
| 76 | +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptState; |
56 | 77 | import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode; |
57 | 78 | import org.apache.hadoop.yarn.server.resourcemanager.scheduler.AbstractYarnScheduler; |
58 | 79 | import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler; |
@@ -686,4 +707,125 @@ public void testAsyncScheduling() throws Exception { |
686 | 707 | } |
687 | 708 | } |
688 | 709 |
|
| 710 | + @Test(timeout = 30000) |
| 711 | + public void testAllocateDoesNotBlockOnSchedulerLock() throws Exception { |
| 712 | + final YarnConfiguration conf = new YarnConfiguration(); |
| 713 | + conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, |
| 714 | + ResourceScheduler.class); |
| 715 | + MyContainerManager containerManager = new MyContainerManager(); |
| 716 | + final MockRMWithAMS rm = |
| 717 | + new MockRMWithAMS(conf, containerManager); |
| 718 | + rm.start(); |
| 719 | + |
| 720 | + MockNM nm1 = rm.registerNode("localhost:1234", 5120); |
| 721 | + |
| 722 | + Map<ApplicationAccessType, String> acls = |
| 723 | + new HashMap<ApplicationAccessType, String>(2); |
| 724 | + acls.put(ApplicationAccessType.VIEW_APP, "*"); |
| 725 | + RMApp app = rm.submitApp(1024, "appname", "appuser", acls); |
| 726 | + |
| 727 | + nm1.nodeHeartbeat(true); |
| 728 | + |
| 729 | + RMAppAttempt attempt = app.getCurrentAppAttempt(); |
| 730 | + ApplicationAttemptId applicationAttemptId = attempt.getAppAttemptId(); |
| 731 | + int msecToWait = 10000; |
| 732 | + int msecToSleep = 100; |
| 733 | + while (attempt.getAppAttemptState() != RMAppAttemptState.LAUNCHED |
| 734 | + && msecToWait > 0) { |
| 735 | + LOG.info("Waiting for AppAttempt to reach LAUNCHED state. " |
| 736 | + + "Current state is " + attempt.getAppAttemptState()); |
| 737 | + Thread.sleep(msecToSleep); |
| 738 | + msecToWait -= msecToSleep; |
| 739 | + } |
| 740 | + Assert.assertEquals(attempt.getAppAttemptState(), |
| 741 | + RMAppAttemptState.LAUNCHED); |
| 742 | + |
| 743 | + // Create a client to the RM. |
| 744 | + final YarnRPC rpc = YarnRPC.create(conf); |
| 745 | + |
| 746 | + UserGroupInformation currentUser = |
| 747 | + UserGroupInformation.createRemoteUser(applicationAttemptId.toString()); |
| 748 | + Credentials credentials = containerManager.getContainerCredentials(); |
| 749 | + final InetSocketAddress rmBindAddress = |
| 750 | + rm.getApplicationMasterService().getBindAddress(); |
| 751 | + Token<? extends TokenIdentifier> amRMToken = |
| 752 | + MockRMWithAMS.setupAndReturnAMRMToken(rmBindAddress, |
| 753 | + credentials.getAllTokens()); |
| 754 | + currentUser.addToken(amRMToken); |
| 755 | + ApplicationMasterProtocol client = |
| 756 | + currentUser.doAs(new PrivilegedAction<ApplicationMasterProtocol>() { |
| 757 | + @Override |
| 758 | + public ApplicationMasterProtocol run() { |
| 759 | + return (ApplicationMasterProtocol) rpc.getProxy( |
| 760 | + ApplicationMasterProtocol.class, rmBindAddress, conf); |
| 761 | + } |
| 762 | + }); |
| 763 | + |
| 764 | + RegisterApplicationMasterRequest request = |
| 765 | + RegisterApplicationMasterRequest.newInstance("localhost", 12345, ""); |
| 766 | + client.registerApplicationMaster(request); |
| 767 | + |
| 768 | + // grab the scheduler lock from another thread |
| 769 | + // and verify an allocate call in this thread doesn't block on it |
| 770 | + final CapacityScheduler cs = (CapacityScheduler) rm.getResourceScheduler(); |
| 771 | + final CyclicBarrier barrier = new CyclicBarrier(2); |
| 772 | + Thread otherThread = new Thread(new Runnable() { |
| 773 | + @Override |
| 774 | + public void run() { |
| 775 | + synchronized(cs) { |
| 776 | + try { |
| 777 | + barrier.await(); |
| 778 | + barrier.await(); |
| 779 | + } catch (InterruptedException e) { |
| 780 | + e.printStackTrace(); |
| 781 | + } catch (BrokenBarrierException e) { |
| 782 | + e.printStackTrace(); |
| 783 | + } |
| 784 | + } |
| 785 | + } |
| 786 | + }); |
| 787 | + otherThread.start(); |
| 788 | + barrier.await(); |
| 789 | + AllocateRequest allocateRequest = |
| 790 | + AllocateRequest.newInstance(0, 0.0f, null, null, null); |
| 791 | + client.allocate(allocateRequest); |
| 792 | + barrier.await(); |
| 793 | + otherThread.join(); |
| 794 | + |
| 795 | + rm.stop(); |
| 796 | + } |
| 797 | + |
| 798 | + @Test |
| 799 | + public void testNumClusterNodes() throws Exception { |
| 800 | + YarnConfiguration conf = new YarnConfiguration(); |
| 801 | + CapacityScheduler cs = new CapacityScheduler(); |
| 802 | + cs.setConf(conf); |
| 803 | + RMContextImpl rmContext = new RMContextImpl(null, null, null, null, null, |
| 804 | + null, new RMContainerTokenSecretManager(conf), |
| 805 | + new NMTokenSecretManagerInRM(conf), |
| 806 | + new ClientToAMTokenSecretManagerInRM(), null); |
| 807 | + cs.setRMContext(rmContext); |
| 808 | + CapacitySchedulerConfiguration csConf = |
| 809 | + new CapacitySchedulerConfiguration(); |
| 810 | + setupQueueConfiguration(csConf); |
| 811 | + cs.init(csConf); |
| 812 | + cs.start(); |
| 813 | + assertEquals(0, cs.getNumClusterNodes()); |
| 814 | + |
| 815 | + RMNode n1 = MockNodes.newNodeInfo(0, MockNodes.newResource(4 * GB), 1); |
| 816 | + RMNode n2 = MockNodes.newNodeInfo(0, MockNodes.newResource(2 * GB), 2); |
| 817 | + cs.handle(new NodeAddedSchedulerEvent(n1)); |
| 818 | + cs.handle(new NodeAddedSchedulerEvent(n2)); |
| 819 | + assertEquals(2, cs.getNumClusterNodes()); |
| 820 | + |
| 821 | + cs.handle(new NodeRemovedSchedulerEvent(n1)); |
| 822 | + assertEquals(1, cs.getNumClusterNodes()); |
| 823 | + cs.handle(new NodeAddedSchedulerEvent(n1)); |
| 824 | + assertEquals(2, cs.getNumClusterNodes()); |
| 825 | + cs.handle(new NodeRemovedSchedulerEvent(n2)); |
| 826 | + cs.handle(new NodeRemovedSchedulerEvent(n1)); |
| 827 | + assertEquals(0, cs.getNumClusterNodes()); |
| 828 | + |
| 829 | + cs.stop(); |
| 830 | + } |
689 | 831 | } |
0 commit comments