|
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals;
|
|
|
import static org.junit.Assert.assertFalse;
|
|
|
import static org.junit.Assert.assertNotNull;
|
|
|
import static org.junit.Assert.assertTrue;
|
|
|
+import static org.junit.Assert.fail;
|
|
|
import static org.mockito.Matchers.any;
|
|
|
import static org.mockito.Mockito.doAnswer;
|
|
|
import static org.mockito.Mockito.doReturn;
|
|
@@ -40,6 +41,7 @@ import java.io.OutputStream;
|
|
|
import java.net.InetSocketAddress;
|
|
|
import java.nio.ByteBuffer;
|
|
|
import java.security.PrivilegedExceptionAction;
|
|
|
+import java.util.Arrays;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
@@ -93,6 +95,8 @@ import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
|
|
|
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
|
|
|
import org.apache.hadoop.yarn.api.records.Priority;
|
|
|
import org.apache.hadoop.yarn.api.records.QueueInfo;
|
|
|
+import org.apache.hadoop.yarn.api.records.Resource;
|
|
|
+import org.apache.hadoop.yarn.api.records.ResourceRequest;
|
|
|
import org.apache.hadoop.yarn.api.records.YarnApplicationState;
|
|
|
import org.apache.hadoop.yarn.api.records.YarnClusterMetrics;
|
|
|
import org.apache.hadoop.yarn.client.api.impl.YarnClientImpl;
|
|
@@ -575,6 +579,169 @@ public class TestYARNRunner {
|
|
|
.getNodeLabelExpression(), "highMem");
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void testResourceRequestLocalityAny() throws Exception {
|
|
|
+ ResourceRequest amAnyResourceRequest =
|
|
|
+ createResourceRequest(ResourceRequest.ANY, true);
|
|
|
+ verifyResourceRequestLocality(null, null, amAnyResourceRequest);
|
|
|
+ verifyResourceRequestLocality(null, "label1", amAnyResourceRequest);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testResourceRequestLocalityRack() throws Exception {
|
|
|
+ ResourceRequest amAnyResourceRequest =
|
|
|
+ createResourceRequest(ResourceRequest.ANY, false);
|
|
|
+ ResourceRequest amRackResourceRequest =
|
|
|
+ createResourceRequest("/rack1", true);
|
|
|
+ verifyResourceRequestLocality("/rack1", null, amAnyResourceRequest,
|
|
|
+ amRackResourceRequest);
|
|
|
+ verifyResourceRequestLocality("/rack1", "label1", amAnyResourceRequest,
|
|
|
+ amRackResourceRequest);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testResourceRequestLocalityNode() throws Exception {
|
|
|
+ ResourceRequest amAnyResourceRequest =
|
|
|
+ createResourceRequest(ResourceRequest.ANY, false);
|
|
|
+ ResourceRequest amRackResourceRequest =
|
|
|
+ createResourceRequest("/rack1", false);
|
|
|
+ ResourceRequest amNodeResourceRequest =
|
|
|
+ createResourceRequest("node1", true);
|
|
|
+ verifyResourceRequestLocality("/rack1/node1", null, amAnyResourceRequest,
|
|
|
+ amRackResourceRequest, amNodeResourceRequest);
|
|
|
+ verifyResourceRequestLocality("/rack1/node1", "label1",
|
|
|
+ amAnyResourceRequest, amRackResourceRequest, amNodeResourceRequest);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testResourceRequestLocalityNodeDefaultRack() throws Exception {
|
|
|
+ ResourceRequest amAnyResourceRequest =
|
|
|
+ createResourceRequest(ResourceRequest.ANY, false);
|
|
|
+ ResourceRequest amRackResourceRequest =
|
|
|
+ createResourceRequest("/default-rack", false);
|
|
|
+ ResourceRequest amNodeResourceRequest =
|
|
|
+ createResourceRequest("node1", true);
|
|
|
+ verifyResourceRequestLocality("node1", null,
|
|
|
+ amAnyResourceRequest, amRackResourceRequest, amNodeResourceRequest);
|
|
|
+ verifyResourceRequestLocality("node1", "label1",
|
|
|
+ amAnyResourceRequest, amRackResourceRequest, amNodeResourceRequest);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testResourceRequestLocalityMultipleNodes() throws Exception {
|
|
|
+ ResourceRequest amAnyResourceRequest =
|
|
|
+ createResourceRequest(ResourceRequest.ANY, false);
|
|
|
+ ResourceRequest amRackResourceRequest =
|
|
|
+ createResourceRequest("/rack1", false);
|
|
|
+ ResourceRequest amNodeResourceRequest =
|
|
|
+ createResourceRequest("node1", true);
|
|
|
+ ResourceRequest amNode2ResourceRequest =
|
|
|
+ createResourceRequest("node2", true);
|
|
|
+ verifyResourceRequestLocality("/rack1/node1,/rack1/node2", null,
|
|
|
+ amAnyResourceRequest, amRackResourceRequest, amNodeResourceRequest,
|
|
|
+ amNode2ResourceRequest);
|
|
|
+ verifyResourceRequestLocality("/rack1/node1,/rack1/node2", "label1",
|
|
|
+ amAnyResourceRequest, amRackResourceRequest, amNodeResourceRequest,
|
|
|
+ amNode2ResourceRequest);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testResourceRequestLocalityMultipleNodesDifferentRack()
|
|
|
+ throws Exception {
|
|
|
+ ResourceRequest amAnyResourceRequest =
|
|
|
+ createResourceRequest(ResourceRequest.ANY, false);
|
|
|
+ ResourceRequest amRackResourceRequest =
|
|
|
+ createResourceRequest("/rack1", false);
|
|
|
+ ResourceRequest amNodeResourceRequest =
|
|
|
+ createResourceRequest("node1", true);
|
|
|
+ ResourceRequest amRack2ResourceRequest =
|
|
|
+ createResourceRequest("/rack2", false);
|
|
|
+ ResourceRequest amNode2ResourceRequest =
|
|
|
+ createResourceRequest("node2", true);
|
|
|
+ verifyResourceRequestLocality("/rack1/node1,/rack2/node2", null,
|
|
|
+ amAnyResourceRequest, amRackResourceRequest, amNodeResourceRequest,
|
|
|
+ amRack2ResourceRequest, amNode2ResourceRequest);
|
|
|
+ verifyResourceRequestLocality("/rack1/node1,/rack2/node2", "label1",
|
|
|
+ amAnyResourceRequest, amRackResourceRequest, amNodeResourceRequest,
|
|
|
+ amRack2ResourceRequest, amNode2ResourceRequest);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testResourceRequestLocalityMultipleNodesDefaultRack()
|
|
|
+ throws Exception {
|
|
|
+ ResourceRequest amAnyResourceRequest =
|
|
|
+ createResourceRequest(ResourceRequest.ANY, false);
|
|
|
+ ResourceRequest amRackResourceRequest =
|
|
|
+ createResourceRequest("/rack1", false);
|
|
|
+ ResourceRequest amNodeResourceRequest =
|
|
|
+ createResourceRequest("node1", true);
|
|
|
+ ResourceRequest amRack2ResourceRequest =
|
|
|
+ createResourceRequest("/default-rack", false);
|
|
|
+ ResourceRequest amNode2ResourceRequest =
|
|
|
+ createResourceRequest("node2", true);
|
|
|
+ verifyResourceRequestLocality("/rack1/node1,node2", null,
|
|
|
+ amAnyResourceRequest, amRackResourceRequest, amNodeResourceRequest,
|
|
|
+ amRack2ResourceRequest, amNode2ResourceRequest);
|
|
|
+ verifyResourceRequestLocality("/rack1/node1,node2", "label1",
|
|
|
+ amAnyResourceRequest, amRackResourceRequest, amNodeResourceRequest,
|
|
|
+ amRack2ResourceRequest, amNode2ResourceRequest);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testResourceRequestLocalityInvalid() throws Exception {
|
|
|
+ try {
|
|
|
+ verifyResourceRequestLocality("rack/node1", null,
|
|
|
+ new ResourceRequest[]{});
|
|
|
+ fail("Should have failed due to invalid resource but did not");
|
|
|
+ } catch (IOException ioe) {
|
|
|
+ assertTrue(ioe.getMessage().contains("Invalid resource name"));
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ verifyResourceRequestLocality("/rack/node1/blah", null,
|
|
|
+ new ResourceRequest[]{});
|
|
|
+ fail("Should have failed due to invalid resource but did not");
|
|
|
+ } catch (IOException ioe) {
|
|
|
+ assertTrue(ioe.getMessage().contains("Invalid resource name"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void verifyResourceRequestLocality(String strictResource,
|
|
|
+ String label, ResourceRequest... expectedReqs) throws Exception {
|
|
|
+ JobConf jobConf = new JobConf();
|
|
|
+ if (strictResource != null) {
|
|
|
+ jobConf.set(MRJobConfig.AM_STRICT_LOCALITY, strictResource);
|
|
|
+ }
|
|
|
+ if (label != null) {
|
|
|
+ jobConf.set(MRJobConfig.AM_NODE_LABEL_EXP, label);
|
|
|
+ for (ResourceRequest expectedReq : expectedReqs) {
|
|
|
+ expectedReq.setNodeLabelExpression(label);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ YARNRunner yarnRunner = new YARNRunner(jobConf);
|
|
|
+ ApplicationSubmissionContext appSubCtx =
|
|
|
+ buildSubmitContext(yarnRunner, jobConf);
|
|
|
+ assertEquals(Arrays.asList(expectedReqs),
|
|
|
+ appSubCtx.getAMContainerResourceRequests());
|
|
|
+ }
|
|
|
+
|
|
|
+ private ResourceRequest createResourceRequest(String name,
|
|
|
+ boolean relaxLocality) {
|
|
|
+ Resource capability = recordFactory.newRecordInstance(Resource.class);
|
|
|
+ capability.setMemorySize(MRJobConfig.DEFAULT_MR_AM_VMEM_MB);
|
|
|
+ capability.setVirtualCores(MRJobConfig.DEFAULT_MR_AM_CPU_VCORES);
|
|
|
+
|
|
|
+ ResourceRequest req =
|
|
|
+ recordFactory.newRecordInstance(ResourceRequest.class);
|
|
|
+ req.setPriority(YARNRunner.AM_CONTAINER_PRIORITY);
|
|
|
+ req.setResourceName(name);
|
|
|
+ req.setCapability(capability);
|
|
|
+ req.setNumContainers(1);
|
|
|
+ req.setRelaxLocality(relaxLocality);
|
|
|
+
|
|
|
+ return req;
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void testAMStandardEnvWithDefaultLibPath() throws Exception {
|
|
|
testAMStandardEnv(false);
|