|
@@ -134,6 +134,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerNode;
|
|
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerNodeReport;
|
|
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.TestSchedulerUtils;
|
|
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.YarnScheduler;
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.ResourceCommitRequest;
|
|
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.fica.FiCaSchedulerApp;
|
|
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.fica.FiCaSchedulerNode;
|
|
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.AppAddedSchedulerEvent;
|
|
@@ -170,6 +171,8 @@ import com.google.common.base.Supplier;
|
|
|
import com.google.common.collect.ImmutableMap;
|
|
|
import com.google.common.collect.ImmutableSet;
|
|
|
import com.google.common.collect.Sets;
|
|
|
+import org.mockito.invocation.InvocationOnMock;
|
|
|
+import org.mockito.stubbing.Answer;
|
|
|
|
|
|
public class TestCapacityScheduler extends CapacitySchedulerTestBase {
|
|
|
private static final Log LOG = LogFactory.getLog(TestCapacityScheduler.class);
|
|
@@ -4857,4 +4860,54 @@ public class TestCapacityScheduler extends CapacitySchedulerTestBase {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ @Test (timeout = 60000)
|
|
|
+ public void testClearRequestsBeforeApplyTheProposal()
|
|
|
+ throws Exception {
|
|
|
+ // init RM & NMs & Nodes
|
|
|
+ final MockRM rm = new MockRM(new CapacitySchedulerConfiguration());
|
|
|
+ rm.start();
|
|
|
+ final MockNM nm = rm.registerNode("h1:1234", 200 * GB);
|
|
|
+
|
|
|
+ // submit app
|
|
|
+ final RMApp app = rm.submitApp(200, "app", "user");
|
|
|
+ MockRM.launchAndRegisterAM(app, rm, nm);
|
|
|
+
|
|
|
+ // spy capacity scheduler to handle CapacityScheduler#apply
|
|
|
+ final Priority priority = Priority.newInstance(1);
|
|
|
+ final CapacityScheduler cs = (CapacityScheduler) rm.getResourceScheduler();
|
|
|
+ final CapacityScheduler spyCs = Mockito.spy(cs);
|
|
|
+ Mockito.doAnswer(new Answer<Object>() {
|
|
|
+ public Object answer(InvocationOnMock invocation) throws Exception {
|
|
|
+ // clear resource request before applying the proposal for container_2
|
|
|
+ spyCs.allocate(app.getCurrentAppAttempt().getAppAttemptId(),
|
|
|
+ Arrays.asList(ResourceRequest.newInstance(priority, "*",
|
|
|
+ Resources.createResource(1 * GB), 0)), null,
|
|
|
+ Collections.<ContainerId>emptyList(), null, null,
|
|
|
+ NULL_UPDATE_REQUESTS);
|
|
|
+ // trigger real apply which can raise NPE before YARN-6629
|
|
|
+ try {
|
|
|
+ FiCaSchedulerApp schedulerApp = cs.getApplicationAttempt(
|
|
|
+ app.getCurrentAppAttempt().getAppAttemptId());
|
|
|
+ schedulerApp.apply((Resource) invocation.getArguments()[0],
|
|
|
+ (ResourceCommitRequest) invocation.getArguments()[1],
|
|
|
+ (Boolean) invocation.getArguments()[2]);
|
|
|
+ // the proposal of removed request should be rejected
|
|
|
+ Assert.assertEquals(1, schedulerApp.getLiveContainers().size());
|
|
|
+ } catch (Throwable e) {
|
|
|
+ Assert.fail();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }).when(spyCs).tryCommit(Mockito.any(Resource.class),
|
|
|
+ Mockito.any(ResourceCommitRequest.class), Mockito.anyBoolean());
|
|
|
+
|
|
|
+ // rm allocates container_2 to reproduce the process that can raise NPE
|
|
|
+ spyCs.allocate(app.getCurrentAppAttempt().getAppAttemptId(),
|
|
|
+ Arrays.asList(ResourceRequest.newInstance(priority, "*",
|
|
|
+ Resources.createResource(1 * GB), 1)), null,
|
|
|
+ Collections.<ContainerId>emptyList(), null, null, NULL_UPDATE_REQUESTS);
|
|
|
+ spyCs.handle(new NodeUpdateSchedulerEvent(
|
|
|
+ spyCs.getNode(nm.getNodeId()).getRMNode()));
|
|
|
+ }
|
|
|
}
|