You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mapreduce-commits@hadoop.apache.org by ac...@apache.org on 2011/12/29 09:06:05 UTC
svn commit: r1225463 [3/3] - in
/hadoop/common/trunk/hadoop-mapreduce-project: ./
hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/webapp/
hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/...
Added: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java?rev=1225463&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java (added)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java Thu Dec 29 08:06:04 2011
@@ -0,0 +1,756 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.yarn.server.resourcemanager.webapp;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.StringReader;
+
+import javax.ws.rs.core.MediaType;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.yarn.server.resourcemanager.MockAM;
+import org.apache.hadoop.yarn.server.resourcemanager.MockNM;
+import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
+import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
+import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
+import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
+import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
+import org.apache.hadoop.yarn.webapp.WebServicesTestUtils;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.servlet.GuiceServletContextListener;
+import com.google.inject.servlet.ServletModule;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.ClientResponse.Status;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
+import com.sun.jersey.test.framework.JerseyTest;
+import com.sun.jersey.test.framework.WebAppDescriptor;
+
+public class TestRMWebServicesApps extends JerseyTest {
+
+ private static MockRM rm;
+
+ private Injector injector = Guice.createInjector(new ServletModule() {
+ @Override
+ protected void configureServlets() {
+ bind(JAXBContextResolver.class);
+ bind(RMWebServices.class);
+ bind(GenericExceptionHandler.class);
+ rm = new MockRM(new Configuration());
+ bind(ResourceManager.class).toInstance(rm);
+ bind(RMContext.class).toInstance(rm.getRMContext());
+ bind(ApplicationACLsManager.class).toInstance(
+ rm.getApplicationACLsManager());
+ serve("/*").with(GuiceContainer.class);
+ }
+ });
+
+ public class GuiceServletConfig extends GuiceServletContextListener {
+
+ @Override
+ protected Injector getInjector() {
+ return injector;
+ }
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public TestRMWebServicesApps() {
+ super(new WebAppDescriptor.Builder(
+ "org.apache.hadoop.yarn.server.resourcemanager.webapp")
+ .contextListenerClass(GuiceServletConfig.class)
+ .filterClass(com.google.inject.servlet.GuiceFilter.class)
+ .contextPath("jersey-guice-filter").servletPath("/").build());
+ }
+
+ @Test
+ public void testApps() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ RMApp app1 = rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ testAppsHelper("apps", app1, MediaType.APPLICATION_JSON);
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsSlash() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ RMApp app1 = rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ testAppsHelper("apps/", app1, MediaType.APPLICATION_JSON);
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsDefault() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ RMApp app1 = rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ testAppsHelper("apps/", app1, "");
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsXML() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ RMApp app1 = rm.submitApp(1024, "testwordcount", "user1");
+ amNodeManager.nodeHeartbeat(true);
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").accept(MediaType.APPLICATION_XML)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+ String xml = response.getEntity(String.class);
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ InputSource is = new InputSource();
+ is.setCharacterStream(new StringReader(xml));
+ Document dom = db.parse(is);
+ NodeList nodesApps = dom.getElementsByTagName("apps");
+ assertEquals("incorrect number of elements", 1, nodesApps.getLength());
+ NodeList nodes = dom.getElementsByTagName("app");
+ assertEquals("incorrect number of elements", 1, nodes.getLength());
+ verifyAppsXML(nodes, app1);
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsXMLMulti() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ rm.submitApp(1024, "testwordcount", "user1");
+ rm.submitApp(2048, "testwordcount2", "user1");
+
+ amNodeManager.nodeHeartbeat(true);
+ WebResource r = resource();
+
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").accept(MediaType.APPLICATION_XML)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+ String xml = response.getEntity(String.class);
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ InputSource is = new InputSource();
+ is.setCharacterStream(new StringReader(xml));
+ Document dom = db.parse(is);
+ NodeList nodesApps = dom.getElementsByTagName("apps");
+ assertEquals("incorrect number of elements", 1, nodesApps.getLength());
+ NodeList nodes = dom.getElementsByTagName("app");
+ assertEquals("incorrect number of elements", 2, nodes.getLength());
+ rm.stop();
+ }
+
+ public void testAppsHelper(String path, RMApp app, String media)
+ throws JSONException, Exception {
+ WebResource r = resource();
+
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path(path).accept(media).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject apps = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, apps.length());
+ JSONArray array = apps.getJSONArray("app");
+ assertEquals("incorrect number of elements", 1, array.length());
+ verifyAppInfo(array.getJSONObject(0), app);
+
+ }
+
+ @Test
+ public void testAppsQueryState() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ RMApp app1 = rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ WebResource r = resource();
+
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").queryParam("state", RMAppState.ACCEPTED.toString())
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject apps = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, apps.length());
+ JSONArray array = apps.getJSONArray("app");
+ assertEquals("incorrect number of elements", 1, array.length());
+ verifyAppInfo(array.getJSONObject(0), app1);
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsQueryStateNone() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ WebResource r = resource();
+
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").queryParam("state", RMAppState.RUNNING.toString())
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ assertEquals("apps is not null", JSONObject.NULL, json.get("apps"));
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsQueryStateInvalid() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ WebResource r = resource();
+
+ try {
+ r.path("ws").path("v1").path("cluster").path("apps")
+ .queryParam("state", "INVALID_test")
+ .accept(MediaType.APPLICATION_JSON).get(JSONObject.class);
+ fail("should have thrown exception on invalid state query");
+ } catch (UniformInterfaceException ue) {
+ ClientResponse response = ue.getResponse();
+ assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject msg = response.getEntity(JSONObject.class);
+ JSONObject exception = msg.getJSONObject("RemoteException");
+ assertEquals("incorrect number of elements", 3, exception.length());
+ String message = exception.getString("message");
+ String type = exception.getString("exception");
+ String classname = exception.getString("javaClassName");
+ WebServicesTestUtils
+ .checkStringMatch(
+ "exception message",
+ "No enum const class org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState.INVALID_test",
+ message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "IllegalArgumentException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "java.lang.IllegalArgumentException", classname);
+
+ } finally {
+ rm.stop();
+ }
+ }
+
+ @Test
+ public void testAppsQueryUser() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+
+ amNodeManager.nodeHeartbeat(true);
+ WebResource r = resource();
+ ClientResponse response = r
+ .path("ws")
+ .path("v1")
+ .path("cluster")
+ .path("apps")
+ .queryParam("user",
+ UserGroupInformation.getCurrentUser().getShortUserName())
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject apps = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, apps.length());
+ JSONArray array = apps.getJSONArray("app");
+ assertEquals("incorrect number of elements", 2, array.length());
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsQueryQueue() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+
+ amNodeManager.nodeHeartbeat(true);
+ WebResource r = resource();
+
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").queryParam("queue", "default")
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject apps = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, apps.length());
+ JSONArray array = apps.getJSONArray("app");
+ assertEquals("incorrect number of elements", 2, array.length());
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsQueryLimit() throws JSONException, Exception {
+ rm.start();
+ rm.registerNode("amNM:1234", 2048);
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").queryParam("limit", "2")
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject apps = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, apps.length());
+ JSONArray array = apps.getJSONArray("app");
+ assertEquals("incorrect number of elements", 2, array.length());
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsQueryStartBegin() throws JSONException, Exception {
+ rm.start();
+ long start = System.currentTimeMillis();
+ Thread.sleep(1);
+ rm.registerNode("amNM:1234", 2048);
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").queryParam("startedTimeBegin", String.valueOf(start))
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject apps = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, apps.length());
+ JSONArray array = apps.getJSONArray("app");
+ assertEquals("incorrect number of elements", 3, array.length());
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsQueryStartBeginSome() throws JSONException, Exception {
+ rm.start();
+ rm.registerNode("amNM:1234", 2048);
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+ long start = System.currentTimeMillis();
+ Thread.sleep(1);
+ rm.submitApp(1024);
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").queryParam("startedTimeBegin", String.valueOf(start))
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject apps = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, apps.length());
+ JSONArray array = apps.getJSONArray("app");
+ assertEquals("incorrect number of elements", 1, array.length());
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsQueryStartEnd() throws JSONException, Exception {
+ rm.start();
+ rm.registerNode("amNM:1234", 2048);
+ long end = System.currentTimeMillis();
+ Thread.sleep(1);
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").queryParam("startedTimeEnd", String.valueOf(end))
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ assertEquals("apps is not null", JSONObject.NULL, json.get("apps"));
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsQueryStartBeginEnd() throws JSONException, Exception {
+ rm.start();
+ rm.registerNode("amNM:1234", 2048);
+ long start = System.currentTimeMillis();
+ Thread.sleep(1);
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+ long end = System.currentTimeMillis();
+ Thread.sleep(1);
+ rm.submitApp(1024);
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").queryParam("startedTimeBegin", String.valueOf(start))
+ .queryParam("startedTimeEnd", String.valueOf(end))
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject apps = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, apps.length());
+ JSONArray array = apps.getJSONArray("app");
+ assertEquals("incorrect number of elements", 2, array.length());
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsQueryFinishBegin() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ long start = System.currentTimeMillis();
+ Thread.sleep(1);
+ RMApp app1 = rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ // finish App
+ MockAM am = rm
+ .sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId());
+ am.registerAppAttempt();
+ am.unregisterAppAttempt();
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").queryParam("finishedTimeBegin", String.valueOf(start))
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject apps = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, apps.length());
+ JSONArray array = apps.getJSONArray("app");
+ assertEquals("incorrect number of elements", 1, array.length());
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsQueryFinishEnd() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ RMApp app1 = rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ // finish App
+ MockAM am = rm
+ .sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId());
+ am.registerAppAttempt();
+ am.unregisterAppAttempt();
+
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+ long end = System.currentTimeMillis();
+
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").queryParam("finishedTimeEnd", String.valueOf(end))
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject apps = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, apps.length());
+ JSONArray array = apps.getJSONArray("app");
+ assertEquals("incorrect number of elements", 3, array.length());
+ rm.stop();
+ }
+
+ @Test
+ public void testAppsQueryFinishBeginEnd() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ long start = System.currentTimeMillis();
+ Thread.sleep(1);
+ RMApp app1 = rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ // finish App
+ MockAM am = rm
+ .sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId());
+ am.registerAppAttempt();
+ am.unregisterAppAttempt();
+
+ rm.submitApp(1024);
+ rm.submitApp(1024);
+ long end = System.currentTimeMillis();
+
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").queryParam("finishedTimeBegin", String.valueOf(start))
+ .queryParam("finishedTimeEnd", String.valueOf(end))
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject apps = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, apps.length());
+ JSONArray array = apps.getJSONArray("app");
+ assertEquals("incorrect number of elements", 1, array.length());
+ rm.stop();
+ }
+
+ @Test
+ public void testSingleApp() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ RMApp app1 = rm.submitApp(1024, "testwordcount", "user1");
+ amNodeManager.nodeHeartbeat(true);
+ testSingleAppsHelper(app1.getApplicationId().toString(), app1,
+ MediaType.APPLICATION_JSON);
+ rm.stop();
+ }
+
+ @Test
+ public void testSingleAppsSlash() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ RMApp app1 = rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ testSingleAppsHelper(app1.getApplicationId().toString() + "/", app1,
+ MediaType.APPLICATION_JSON);
+ rm.stop();
+ }
+
+ @Test
+ public void testSingleAppsDefault() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ RMApp app1 = rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ testSingleAppsHelper(app1.getApplicationId().toString() + "/", app1, "");
+ rm.stop();
+ }
+
+ @Test
+ public void testInvalidApp() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ rm.submitApp(1024);
+ amNodeManager.nodeHeartbeat(true);
+ WebResource r = resource();
+
+ try {
+ r.path("ws").path("v1").path("cluster").path("apps")
+ .path("application_invalid_12").accept(MediaType.APPLICATION_JSON)
+ .get(JSONObject.class);
+ fail("should have thrown exception on invalid appid");
+ } catch (UniformInterfaceException ue) {
+ ClientResponse response = ue.getResponse();
+
+ assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject msg = response.getEntity(JSONObject.class);
+ JSONObject exception = msg.getJSONObject("RemoteException");
+ assertEquals("incorrect number of elements", 3, exception.length());
+ String message = exception.getString("message");
+ String type = exception.getString("exception");
+ String classname = exception.getString("javaClassName");
+ WebServicesTestUtils.checkStringMatch("exception message",
+ "For input string: \"invalid\"", message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "NumberFormatException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "java.lang.NumberFormatException", classname);
+
+ } finally {
+ rm.stop();
+ }
+ }
+
+ @Test
+ public void testNonexistApp() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ rm.submitApp(1024, "testwordcount", "user1");
+ amNodeManager.nodeHeartbeat(true);
+ WebResource r = resource();
+
+ try {
+ r.path("ws").path("v1").path("cluster").path("apps")
+ .path("application_00000_0099").accept(MediaType.APPLICATION_JSON)
+ .get(JSONObject.class);
+ fail("should have thrown exception on invalid appid");
+ } catch (UniformInterfaceException ue) {
+ ClientResponse response = ue.getResponse();
+
+ assertEquals(Status.NOT_FOUND, response.getClientResponseStatus());
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+
+ JSONObject msg = response.getEntity(JSONObject.class);
+ JSONObject exception = msg.getJSONObject("RemoteException");
+ assertEquals("incorrect number of elements", 3, exception.length());
+ String message = exception.getString("message");
+ String type = exception.getString("exception");
+ String classname = exception.getString("javaClassName");
+ WebServicesTestUtils.checkStringMatch("exception message",
+ "java.lang.Exception: app with id: application_00000_0099 not found",
+ message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "NotFoundException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "org.apache.hadoop.yarn.webapp.NotFoundException", classname);
+ } finally {
+ rm.stop();
+ }
+ }
+
+ public void testSingleAppsHelper(String path, RMApp app, String media)
+ throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").path(path).accept(media).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+
+ assertEquals("incorrect number of elements", 1, json.length());
+ verifyAppInfo(json.getJSONObject("app"), app);
+ }
+
+ @Test
+ public void testSingleAppsXML() throws JSONException, Exception {
+ rm.start();
+ MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
+ RMApp app1 = rm.submitApp(1024, "testwordcount", "user1");
+ amNodeManager.nodeHeartbeat(true);
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("apps").path(app1.getApplicationId().toString())
+ .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+ String xml = response.getEntity(String.class);
+
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ InputSource is = new InputSource();
+ is.setCharacterStream(new StringReader(xml));
+ Document dom = db.parse(is);
+ NodeList nodes = dom.getElementsByTagName("app");
+ assertEquals("incorrect number of elements", 1, nodes.getLength());
+ verifyAppsXML(nodes, app1);
+ rm.stop();
+ }
+
+ public void verifyAppsXML(NodeList nodes, RMApp app) throws JSONException,
+ Exception {
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Element element = (Element) nodes.item(i);
+
+ verifyAppInfoGeneric(app,
+ WebServicesTestUtils.getXmlString(element, "id"),
+ WebServicesTestUtils.getXmlString(element, "user"),
+ WebServicesTestUtils.getXmlString(element, "name"),
+ WebServicesTestUtils.getXmlString(element, "queue"),
+ WebServicesTestUtils.getXmlString(element, "state"),
+ WebServicesTestUtils.getXmlString(element, "finalStatus"),
+ WebServicesTestUtils.getXmlFloat(element, "progress"),
+ WebServicesTestUtils.getXmlString(element, "trackingUI"),
+ WebServicesTestUtils.getXmlString(element, "diagnostics"),
+ WebServicesTestUtils.getXmlLong(element, "clusterId"),
+ WebServicesTestUtils.getXmlLong(element, "startedTime"),
+ WebServicesTestUtils.getXmlLong(element, "finishedTime"),
+ WebServicesTestUtils.getXmlLong(element, "elapsedTime"),
+ WebServicesTestUtils.getXmlString(element, "amHostHttpAddress"),
+ WebServicesTestUtils.getXmlString(element, "amContainerLogs"));
+ }
+ }
+
+ public void verifyAppInfo(JSONObject info, RMApp app) throws JSONException,
+ Exception {
+
+ // 15 because trackingUrl not assigned yet
+ assertEquals("incorrect number of elements", 15, info.length());
+
+ verifyAppInfoGeneric(app, info.getString("id"), info.getString("user"),
+ info.getString("name"), info.getString("queue"),
+ info.getString("state"), info.getString("finalStatus"),
+ (float) info.getDouble("progress"), info.getString("trackingUI"),
+ info.getString("diagnostics"), info.getLong("clusterId"),
+ info.getLong("startedTime"), info.getLong("finishedTime"),
+ info.getLong("elapsedTime"), info.getString("amHostHttpAddress"),
+ info.getString("amContainerLogs"));
+ }
+
+ public void verifyAppInfoGeneric(RMApp app, String id, String user,
+ String name, String queue, String state, String finalStatus,
+ float progress, String trackingUI, String diagnostics, long clusterId,
+ long startedTime, long finishedTime, long elapsedTime,
+ String amHostHttpAddress, String amContainerLogs) throws JSONException,
+ Exception {
+
+ WebServicesTestUtils.checkStringMatch("id", app.getApplicationId()
+ .toString(), id);
+ WebServicesTestUtils.checkStringMatch("user", app.getUser(), user);
+ WebServicesTestUtils.checkStringMatch("name", app.getName(), name);
+ WebServicesTestUtils.checkStringMatch("queue", app.getQueue(), queue);
+ WebServicesTestUtils.checkStringMatch("state", app.getState().toString(),
+ state);
+ WebServicesTestUtils.checkStringMatch("finalStatus", app
+ .getFinalApplicationStatus().toString(), finalStatus);
+ assertEquals("progress doesn't match", 0, progress, 0.0);
+ WebServicesTestUtils.checkStringMatch("trackingUI", "UNASSIGNED",
+ trackingUI);
+ WebServicesTestUtils.checkStringMatch("diagnostics", app.getDiagnostics()
+ .toString(), diagnostics);
+ assertEquals("clusterId doesn't match", ResourceManager.clusterTimeStamp,
+ clusterId);
+ assertEquals("startedTime doesn't match", app.getStartTime(), startedTime);
+ assertEquals("finishedTime doesn't match", app.getFinishTime(),
+ finishedTime);
+ assertTrue("elapsed time not greater than 0", elapsedTime > 0);
+ WebServicesTestUtils.checkStringMatch("amHostHttpAddress", app
+ .getCurrentAppAttempt().getMasterContainer().getNodeHttpAddress(),
+ amHostHttpAddress);
+ assertTrue("amContainerLogs doesn't match",
+ amContainerLogs.startsWith("http://"));
+ }
+
+}
Added: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesCapacitySched.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesCapacitySched.java?rev=1225463&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesCapacitySched.java (added)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesCapacitySched.java Thu Dec 29 08:06:04 2011
@@ -0,0 +1,316 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.yarn.server.resourcemanager.webapp;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.StringReader;
+
+import javax.ws.rs.core.MediaType;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
+import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
+import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration;
+import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
+import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
+import org.apache.hadoop.yarn.webapp.WebServicesTestUtils;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.servlet.GuiceServletContextListener;
+import com.google.inject.servlet.ServletModule;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
+import com.sun.jersey.test.framework.JerseyTest;
+import com.sun.jersey.test.framework.WebAppDescriptor;
+
+public class TestRMWebServicesCapacitySched extends JerseyTest {
+
+ private static MockRM rm;
+ private CapacitySchedulerConfiguration csConf;
+
+ private Injector injector = Guice.createInjector(new ServletModule() {
+ @Override
+ protected void configureServlets() {
+ bind(JAXBContextResolver.class);
+ bind(RMWebServices.class);
+ bind(GenericExceptionHandler.class);
+ csConf = new CapacitySchedulerConfiguration();
+ csConf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class,
+ ResourceScheduler.class);
+ setupQueueConfiguration(csConf);
+ rm = new MockRM(csConf);
+ bind(ResourceManager.class).toInstance(rm);
+ bind(RMContext.class).toInstance(rm.getRMContext());
+ bind(ApplicationACLsManager.class).toInstance(
+ rm.getApplicationACLsManager());
+ serve("/*").with(GuiceContainer.class);
+ }
+ });
+
+ public class GuiceServletConfig extends GuiceServletContextListener {
+
+ @Override
+ protected Injector getInjector() {
+ return injector;
+ }
+ }
+
+ private static void setupQueueConfiguration(
+ CapacitySchedulerConfiguration conf) {
+
+ // Define top-level queues
+ conf.setQueues(CapacityScheduler.ROOT, new String[] { "a", "b" });
+ conf.setCapacity(CapacityScheduler.ROOT, 100);
+
+ final String A = CapacityScheduler.ROOT + ".a";
+ conf.setCapacity(A, 10);
+ conf.setMaximumCapacity(A, 50);
+
+ final String B = CapacityScheduler.ROOT + ".b";
+ conf.setCapacity(B, 90);
+
+ // Define 2nd-level queues
+ final String A1 = A + ".a1";
+ final String A2 = A + ".a2";
+ conf.setQueues(A, new String[] { "a1", "a2" });
+ conf.setCapacity(A1, 30);
+ conf.setMaximumCapacity(A1, 50);
+
+ conf.setUserLimitFactor(A1, 100.0f);
+ conf.setCapacity(A2, 70);
+ conf.setUserLimitFactor(A2, 100.0f);
+
+ final String B1 = B + ".b1";
+ final String B2 = B + ".b2";
+ final String B3 = B + ".b3";
+ conf.setQueues(B, new String[] { "b1", "b2", "b3" });
+ conf.setCapacity(B1, 50);
+ conf.setUserLimitFactor(B1, 100.0f);
+ conf.setCapacity(B2, 30);
+ conf.setUserLimitFactor(B2, 100.0f);
+ conf.setCapacity(B3, 20);
+ conf.setUserLimitFactor(B3, 100.0f);
+
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public TestRMWebServicesCapacitySched() {
+ super(new WebAppDescriptor.Builder(
+ "org.apache.hadoop.yarn.server.resourcemanager.webapp")
+ .contextListenerClass(GuiceServletConfig.class)
+ .filterClass(com.google.inject.servlet.GuiceFilter.class)
+ .contextPath("jersey-guice-filter").servletPath("/").build());
+ }
+
+ @Test
+ public void testClusterScheduler() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("scheduler").accept(MediaType.APPLICATION_JSON)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyClusterScheduler(json);
+ }
+
+ @Test
+ public void testClusterSchedulerSlash() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("scheduler/").accept(MediaType.APPLICATION_JSON)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyClusterScheduler(json);
+ }
+
+ @Test
+ public void testClusterSchedulerDefault() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("scheduler").get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyClusterScheduler(json);
+ }
+
+ @Test
+ public void testClusterSchedulerXML() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("scheduler/").accept(MediaType.APPLICATION_XML)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+ String xml = response.getEntity(String.class);
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ InputSource is = new InputSource();
+ is.setCharacterStream(new StringReader(xml));
+ Document dom = db.parse(is);
+ NodeList scheduler = dom.getElementsByTagName("scheduler");
+ assertEquals("incorrect number of elements", 1, scheduler.getLength());
+ NodeList schedulerInfo = dom.getElementsByTagName("schedulerInfo");
+ assertEquals("incorrect number of elements", 1, schedulerInfo.getLength());
+ verifyClusterSchedulerXML(schedulerInfo);
+ }
+
+ public void verifyClusterSchedulerXML(NodeList nodes) throws Exception {
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Element element = (Element) nodes.item(i);
+
+ verifyClusterSchedulerGeneric(
+ WebServicesTestUtils.getXmlAttrString(element, "xsi:type"),
+ WebServicesTestUtils.getXmlFloat(element, "usedCapacity"),
+ WebServicesTestUtils.getXmlFloat(element, "capacity"),
+ WebServicesTestUtils.getXmlFloat(element, "maxCapacity"),
+ WebServicesTestUtils.getXmlString(element, "queueName"));
+
+ NodeList queues = element.getElementsByTagName("queues");
+ for (int j = 0; j < queues.getLength(); j++) {
+ Element qElem = (Element) queues.item(j);
+ String qName = WebServicesTestUtils.getXmlString(qElem, "queueName");
+ String q = CapacityScheduler.ROOT + "." + qName;
+ verifySubQueueXML(qElem, q);
+ }
+ }
+ }
+
+ public void verifySubQueueXML(Element qElem, String q) throws Exception {
+
+ verifySubQueueGeneric(q,
+ WebServicesTestUtils.getXmlFloat(qElem, "usedCapacity"),
+ WebServicesTestUtils.getXmlFloat(qElem, "capacity"),
+ WebServicesTestUtils.getXmlFloat(qElem, "maxCapacity"),
+ WebServicesTestUtils.getXmlString(qElem, "queueName"),
+ WebServicesTestUtils.getXmlString(qElem, "state"));
+
+ NodeList queues = qElem.getElementsByTagName("subQueues");
+ if (queues != null) {
+ for (int j = 0; j < queues.getLength(); j++) {
+ Element subqElem = (Element) queues.item(j);
+ String qName = WebServicesTestUtils.getXmlString(subqElem, "queueName");
+ String q2 = q + "." + qName;
+ verifySubQueueXML(subqElem, q2);
+ }
+ }
+ }
+
+ private void verifyClusterScheduler(JSONObject json) throws JSONException,
+ Exception {
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject info = json.getJSONObject("scheduler");
+ assertEquals("incorrect number of elements", 1, info.length());
+ info = info.getJSONObject("schedulerInfo");
+ assertEquals("incorrect number of elements", 6, info.length());
+ verifyClusterSchedulerGeneric(info.getString("type"),
+ (float) info.getDouble("usedCapacity"),
+ (float) info.getDouble("capacity"),
+ (float) info.getDouble("maxCapacity"), info.getString("queueName"));
+
+ JSONArray arr = info.getJSONArray("queues");
+ assertEquals("incorrect number of elements", 2, arr.length());
+
+ // test subqueues
+ for (int i = 0; i < arr.length(); i++) {
+ JSONObject obj = arr.getJSONObject(i);
+ String q = CapacityScheduler.ROOT + "." + obj.getString("queueName");
+ verifySubQueue(obj, q);
+ }
+ }
+
+ private void verifyClusterSchedulerGeneric(String type, float usedCapacity,
+ float capacity, float maxCapacity, String queueName) throws Exception {
+
+ assertTrue("type doesn't match", "capacityScheduler".matches(type));
+ assertEquals("usedCapacity doesn't match", 0, usedCapacity, 1e-3f);
+ assertEquals("capacity doesn't match", 100, capacity, 1e-3f);
+ assertEquals("maxCapacity doesn't match", 100, maxCapacity, 1e-3f);
+ assertTrue("queueName doesn't match", "root".matches(queueName));
+ }
+
+ private void verifySubQueue(JSONObject info, String q) throws JSONException,
+ Exception {
+ if (info.has("subQueues")) {
+ assertEquals("incorrect number of elements", 6, info.length());
+ } else {
+ assertEquals("incorrect number of elements", 5, info.length());
+ }
+ verifySubQueueGeneric(q, (float) info.getDouble("usedCapacity"),
+ (float) info.getDouble("capacity"),
+ (float) info.getDouble("maxCapacity"), info.getString("queueName"),
+ info.getString("state"));
+
+ if (info.has("subQueues")) {
+ JSONArray arr = info.getJSONArray("subQueues");
+ // test subqueues
+ for (int i = 0; i < arr.length(); i++) {
+ JSONObject obj = arr.getJSONObject(i);
+ String q2 = q + "." + obj.getString("queueName");
+ verifySubQueue(obj, q2);
+ }
+ }
+ }
+
+ private void verifySubQueueGeneric(String q, float usedCapacity,
+ float capacity, float maxCapacity, String qname, String state)
+ throws Exception {
+ String[] qArr = q.split("\\.");
+ assertTrue("q name invalid: " + q, qArr.length > 1);
+ String qshortName = qArr[qArr.length - 1];
+
+ assertEquals("usedCapacity doesn't match", 0, usedCapacity, 1e-3f);
+ assertEquals("capacity doesn't match", csConf.getCapacity(q), capacity,
+ 1e-3f);
+ float expectCapacity = csConf.getMaximumCapacity(q);
+ if (CapacitySchedulerConfiguration.UNDEFINED == expectCapacity) {
+ expectCapacity = 100;
+ }
+ assertEquals("maxCapacity doesn't match", expectCapacity, maxCapacity,
+ 1e-3f);
+ assertTrue("queueName doesn't match, got: " + qname + " expected: " + q,
+ qshortName.matches(qname));
+ assertTrue("state doesn't match",
+ (csConf.getState(q).toString()).matches(state));
+
+ }
+}
Added: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesNodes.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesNodes.java?rev=1225463&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesNodes.java (added)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesNodes.java Thu Dec 29 08:06:04 2011
@@ -0,0 +1,601 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.yarn.server.resourcemanager.webapp;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+
+import javax.ws.rs.core.MediaType;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.yarn.api.records.ContainerStatus;
+import org.apache.hadoop.yarn.api.records.NodeHealthStatus;
+import org.apache.hadoop.yarn.server.resourcemanager.MockNM;
+import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
+import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
+import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
+import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
+import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeImpl;
+import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeState;
+import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeStatusEvent;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerNodeReport;
+import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
+import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
+import org.apache.hadoop.yarn.webapp.WebServicesTestUtils;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.servlet.GuiceServletContextListener;
+import com.google.inject.servlet.ServletModule;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.ClientResponse.Status;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
+import com.sun.jersey.test.framework.JerseyTest;
+import com.sun.jersey.test.framework.WebAppDescriptor;
+
+public class TestRMWebServicesNodes extends JerseyTest {
+
+ private static MockRM rm;
+
+ private Injector injector = Guice.createInjector(new ServletModule() {
+ @Override
+ protected void configureServlets() {
+ bind(JAXBContextResolver.class);
+ bind(RMWebServices.class);
+ bind(GenericExceptionHandler.class);
+ rm = new MockRM(new Configuration());
+ bind(ResourceManager.class).toInstance(rm);
+ bind(RMContext.class).toInstance(rm.getRMContext());
+ bind(ApplicationACLsManager.class).toInstance(
+ rm.getApplicationACLsManager());
+ serve("/*").with(GuiceContainer.class);
+ }
+ });
+
+ public class GuiceServletConfig extends GuiceServletContextListener {
+
+ @Override
+ protected Injector getInjector() {
+ return injector;
+ }
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public TestRMWebServicesNodes() {
+ super(new WebAppDescriptor.Builder(
+ "org.apache.hadoop.yarn.server.resourcemanager.webapp")
+ .contextListenerClass(GuiceServletConfig.class)
+ .filterClass(com.google.inject.servlet.GuiceFilter.class)
+ .contextPath("jersey-guice-filter").servletPath("/").build());
+ }
+
+ @Test
+ public void testNodes() throws JSONException, Exception {
+ testNodesHelper("nodes", MediaType.APPLICATION_JSON);
+ }
+
+ @Test
+ public void testNodesSlash() throws JSONException, Exception {
+ testNodesHelper("nodes/", MediaType.APPLICATION_JSON);
+ }
+
+ @Test
+ public void testNodesDefault() throws JSONException, Exception {
+ testNodesHelper("nodes/", "");
+ }
+
+ @Test
+ public void testNodesQueryState() throws JSONException, Exception {
+ WebResource r = resource();
+ MockNM nm1 = rm.registerNode("h1:1234", 5120);
+ MockNM nm2 = rm.registerNode("h2:1235", 5121);
+ rm.sendNodeStarted(nm1);
+ rm.NMwaitForState(nm1.getNodeId(), RMNodeState.RUNNING);
+ rm.NMwaitForState(nm2.getNodeId(), RMNodeState.NEW);
+
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("nodes").queryParam("state", RMNodeState.RUNNING.toString())
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject nodes = json.getJSONObject("nodes");
+ assertEquals("incorrect number of elements", 1, nodes.length());
+ JSONArray nodeArray = nodes.getJSONArray("node");
+ assertEquals("incorrect number of elements", 1, nodeArray.length());
+ JSONObject info = nodeArray.getJSONObject(0);
+
+ verifyNodeInfo(info, nm1);
+ }
+
+ @Test
+ public void testNodesQueryStateNone() throws JSONException, Exception {
+ WebResource r = resource();
+ rm.registerNode("h1:1234", 5120);
+ rm.registerNode("h2:1235", 5121);
+
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("nodes")
+ .queryParam("state", RMNodeState.DECOMMISSIONED.toString())
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ assertEquals("nodes is not null", JSONObject.NULL, json.get("nodes"));
+ }
+
+ @Test
+ public void testNodesQueryStateInvalid() throws JSONException, Exception {
+ WebResource r = resource();
+ rm.registerNode("h1:1234", 5120);
+ rm.registerNode("h2:1235", 5121);
+
+ try {
+ r.path("ws").path("v1").path("cluster").path("nodes")
+ .queryParam("state", "BOGUSSTATE").accept(MediaType.APPLICATION_JSON)
+ .get(JSONObject.class);
+
+ fail("should have thrown exception querying invalid state");
+ } catch (UniformInterfaceException ue) {
+ ClientResponse response = ue.getResponse();
+
+ assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+
+ JSONObject msg = response.getEntity(JSONObject.class);
+ JSONObject exception = msg.getJSONObject("RemoteException");
+ assertEquals("incorrect number of elements", 3, exception.length());
+ String message = exception.getString("message");
+ String type = exception.getString("exception");
+ String classname = exception.getString("javaClassName");
+ WebServicesTestUtils
+ .checkStringMatch(
+ "exception message",
+ "No enum const class org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeState.BOGUSSTATE",
+ message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "IllegalArgumentException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "java.lang.IllegalArgumentException", classname);
+
+ } finally {
+ rm.stop();
+ }
+ }
+
+ @Test
+ public void testNodesQueryHealthy() throws JSONException, Exception {
+ WebResource r = resource();
+ MockNM nm1 = rm.registerNode("h1:1234", 5120);
+ MockNM nm2 = rm.registerNode("h2:1235", 5121);
+ rm.sendNodeStarted(nm1);
+ rm.NMwaitForState(nm1.getNodeId(), RMNodeState.RUNNING);
+ rm.NMwaitForState(nm2.getNodeId(), RMNodeState.NEW);
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("nodes").queryParam("healthy", "true")
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject nodes = json.getJSONObject("nodes");
+ assertEquals("incorrect number of elements", 1, nodes.length());
+ JSONArray nodeArray = nodes.getJSONArray("node");
+ assertEquals("incorrect number of elements", 2, nodeArray.length());
+ }
+
+ @Test
+ public void testNodesQueryHealthyCase() throws JSONException, Exception {
+ WebResource r = resource();
+ MockNM nm1 = rm.registerNode("h1:1234", 5120);
+ MockNM nm2 = rm.registerNode("h2:1235", 5121);
+ rm.sendNodeStarted(nm1);
+ rm.NMwaitForState(nm1.getNodeId(), RMNodeState.RUNNING);
+ rm.NMwaitForState(nm2.getNodeId(), RMNodeState.NEW);
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("nodes").queryParam("healthy", "TRUe")
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject nodes = json.getJSONObject("nodes");
+ assertEquals("incorrect number of elements", 1, nodes.length());
+ JSONArray nodeArray = nodes.getJSONArray("node");
+ assertEquals("incorrect number of elements", 2, nodeArray.length());
+
+ }
+
+ @Test
+ public void testNodesQueryHealthyAndState() throws JSONException, Exception {
+ WebResource r = resource();
+ MockNM nm1 = rm.registerNode("h1:1234", 5120);
+ MockNM nm2 = rm.registerNode("h2:1235", 5121);
+ rm.sendNodeStarted(nm1);
+ rm.NMwaitForState(nm2.getNodeId(), RMNodeState.NEW);
+ rm.NMwaitForState(nm1.getNodeId(), RMNodeState.RUNNING);
+ RMNodeImpl node = (RMNodeImpl) rm.getRMContext().getRMNodes()
+ .get(nm1.getNodeId());
+ NodeHealthStatus nodeHealth = node.getNodeHealthStatus();
+ nodeHealth.setHealthReport("test health report");
+ nodeHealth.setIsNodeHealthy(false);
+ node.handle(new RMNodeStatusEvent(nm1.getNodeId(), nodeHealth,
+ new ArrayList<ContainerStatus>(), null, null));
+ rm.NMwaitForState(nm1.getNodeId(), RMNodeState.UNHEALTHY);
+
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("nodes").queryParam("healthy", "true")
+ .queryParam("state", RMNodeState.RUNNING.toString())
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ assertEquals("nodes is not null", JSONObject.NULL, json.get("nodes"));
+ }
+
+ @Test
+ public void testNodesQueryHealthyFalse() throws JSONException, Exception {
+ WebResource r = resource();
+ MockNM nm1 = rm.registerNode("h1:1234", 5120);
+ MockNM nm2 = rm.registerNode("h2:1235", 5121);
+ rm.sendNodeStarted(nm1);
+ rm.NMwaitForState(nm1.getNodeId(), RMNodeState.RUNNING);
+ rm.NMwaitForState(nm2.getNodeId(), RMNodeState.NEW);
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("nodes").queryParam("healthy", "false")
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ assertEquals("nodes is not null", JSONObject.NULL, json.get("nodes"));
+ }
+
+ @Test
+ public void testNodesQueryHealthyInvalid() throws JSONException, Exception {
+ WebResource r = resource();
+ rm.registerNode("h1:1234", 5120);
+ rm.registerNode("h2:1235", 5121);
+
+ try {
+ r.path("ws").path("v1").path("cluster").path("nodes")
+ .queryParam("healthy", "tr").accept(MediaType.APPLICATION_JSON)
+ .get(JSONObject.class);
+ fail("should have thrown exception querying invalid healthy string");
+ } catch (UniformInterfaceException ue) {
+ ClientResponse response = ue.getResponse();
+ assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject msg = response.getEntity(JSONObject.class);
+ JSONObject exception = msg.getJSONObject("RemoteException");
+ assertEquals("incorrect number of elements", 3, exception.length());
+ String message = exception.getString("message");
+ String type = exception.getString("exception");
+ String classname = exception.getString("javaClassName");
+ WebServicesTestUtils
+ .checkStringMatch(
+ "exception message",
+ "java.lang.Exception: Error: You must specify either true or false to query on health",
+ message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "BadRequestException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "org.apache.hadoop.yarn.webapp.BadRequestException", classname);
+
+ } finally {
+ rm.stop();
+ }
+ }
+
+ public void testNodesHelper(String path, String media) throws JSONException,
+ Exception {
+ WebResource r = resource();
+ MockNM nm1 = rm.registerNode("h1:1234", 5120);
+ MockNM nm2 = rm.registerNode("h2:1235", 5121);
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path(path).accept(media).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject nodes = json.getJSONObject("nodes");
+ assertEquals("incorrect number of elements", 1, nodes.length());
+ JSONArray nodeArray = nodes.getJSONArray("node");
+ assertEquals("incorrect number of elements", 2, nodeArray.length());
+ JSONObject info = nodeArray.getJSONObject(0);
+ String id = info.get("id").toString();
+
+ if (id.matches("h1:1234")) {
+ verifyNodeInfo(info, nm1);
+ verifyNodeInfo(nodeArray.getJSONObject(1), nm2);
+ } else {
+ verifyNodeInfo(info, nm2);
+ verifyNodeInfo(nodeArray.getJSONObject(1), nm1);
+ }
+ }
+
+ @Test
+ public void testSingleNode() throws JSONException, Exception {
+ rm.registerNode("h1:1234", 5120);
+ MockNM nm2 = rm.registerNode("h2:1235", 5121);
+ testSingleNodeHelper("h2:1235", nm2, MediaType.APPLICATION_JSON);
+ }
+
+ @Test
+ public void testSingleNodeSlash() throws JSONException, Exception {
+ MockNM nm1 = rm.registerNode("h1:1234", 5120);
+ rm.registerNode("h2:1235", 5121);
+ testSingleNodeHelper("h1:1234/", nm1, MediaType.APPLICATION_JSON);
+ }
+
+ @Test
+ public void testSingleNodeDefault() throws JSONException, Exception {
+ MockNM nm1 = rm.registerNode("h1:1234", 5120);
+ rm.registerNode("h2:1235", 5121);
+ testSingleNodeHelper("h1:1234/", nm1, "");
+ }
+
+ public void testSingleNodeHelper(String nodeid, MockNM nm, String media)
+ throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("nodes").path(nodeid).accept(media).get(ClientResponse.class);
+
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject info = json.getJSONObject("node");
+ verifyNodeInfo(info, nm);
+ }
+
+ @Test
+ public void testNonexistNode() throws JSONException, Exception {
+ rm.registerNode("h1:1234", 5120);
+ rm.registerNode("h2:1235", 5121);
+ WebResource r = resource();
+ try {
+ r.path("ws").path("v1").path("cluster").path("nodes")
+ .path("node_invalid:99").accept(MediaType.APPLICATION_JSON)
+ .get(JSONObject.class);
+
+ fail("should have thrown exception on non-existent nodeid");
+ } catch (UniformInterfaceException ue) {
+ ClientResponse response = ue.getResponse();
+ assertEquals(Status.NOT_FOUND, response.getClientResponseStatus());
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject msg = response.getEntity(JSONObject.class);
+ JSONObject exception = msg.getJSONObject("RemoteException");
+ assertEquals("incorrect number of elements", 3, exception.length());
+ String message = exception.getString("message");
+ String type = exception.getString("exception");
+ String classname = exception.getString("javaClassName");
+ WebServicesTestUtils
+ .checkStringMatch("exception message",
+ "java.lang.Exception: nodeId, node_invalid:99, is not found",
+ message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "NotFoundException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "org.apache.hadoop.yarn.webapp.NotFoundException", classname);
+
+ } finally {
+ rm.stop();
+ }
+ }
+
+ @Test
+ public void testInvalidNode() throws JSONException, Exception {
+ rm.registerNode("h1:1234", 5120);
+ rm.registerNode("h2:1235", 5121);
+
+ WebResource r = resource();
+ try {
+ r.path("ws").path("v1").path("cluster").path("nodes")
+ .path("node_invalid_foo").accept(MediaType.APPLICATION_JSON)
+ .get(JSONObject.class);
+
+ fail("should have thrown exception on non-existent nodeid");
+ } catch (UniformInterfaceException ue) {
+ ClientResponse response = ue.getResponse();
+
+ assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject msg = response.getEntity(JSONObject.class);
+ JSONObject exception = msg.getJSONObject("RemoteException");
+ assertEquals("incorrect number of elements", 3, exception.length());
+ String message = exception.getString("message");
+ String type = exception.getString("exception");
+ String classname = exception.getString("javaClassName");
+ WebServicesTestUtils.checkStringMatch("exception message",
+ "Invalid NodeId \\[node_invalid_foo\\]. Expected host:port", message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "IllegalArgumentException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "java.lang.IllegalArgumentException", classname);
+ } finally {
+ rm.stop();
+ }
+ }
+
+ @Test
+ public void testNodesXML() throws JSONException, Exception {
+ rm.start();
+ WebResource r = resource();
+ MockNM nm1 = rm.registerNode("h1:1234", 5120);
+ // MockNM nm2 = rm.registerNode("h2:1235", 5121);
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("nodes").accept(MediaType.APPLICATION_XML)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+ String xml = response.getEntity(String.class);
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ InputSource is = new InputSource();
+ is.setCharacterStream(new StringReader(xml));
+ Document dom = db.parse(is);
+ NodeList nodesApps = dom.getElementsByTagName("nodes");
+ assertEquals("incorrect number of elements", 1, nodesApps.getLength());
+ NodeList nodes = dom.getElementsByTagName("node");
+ assertEquals("incorrect number of elements", 1, nodes.getLength());
+ verifyNodesXML(nodes, nm1);
+ rm.stop();
+ }
+
+ @Test
+ public void testSingleNodesXML() throws JSONException, Exception {
+ rm.start();
+ WebResource r = resource();
+ MockNM nm1 = rm.registerNode("h1:1234", 5120);
+ // MockNM nm2 = rm.registerNode("h2:1235", 5121);
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("nodes").path("h1:1234").accept(MediaType.APPLICATION_XML)
+ .get(ClientResponse.class);
+
+ assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+ String xml = response.getEntity(String.class);
+
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ InputSource is = new InputSource();
+ is.setCharacterStream(new StringReader(xml));
+ Document dom = db.parse(is);
+ NodeList nodes = dom.getElementsByTagName("node");
+ assertEquals("incorrect number of elements", 1, nodes.getLength());
+ verifyNodesXML(nodes, nm1);
+ rm.stop();
+ }
+
+ @Test
+ public void testNodes2XML() throws JSONException, Exception {
+ rm.start();
+ WebResource r = resource();
+ rm.registerNode("h1:1234", 5120);
+ rm.registerNode("h2:1235", 5121);
+ ClientResponse response = r.path("ws").path("v1").path("cluster")
+ .path("nodes").accept(MediaType.APPLICATION_XML)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+ String xml = response.getEntity(String.class);
+
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ InputSource is = new InputSource();
+ is.setCharacterStream(new StringReader(xml));
+ Document dom = db.parse(is);
+ NodeList nodesApps = dom.getElementsByTagName("nodes");
+ assertEquals("incorrect number of elements", 1, nodesApps.getLength());
+ NodeList nodes = dom.getElementsByTagName("node");
+ assertEquals("incorrect number of elements", 2, nodes.getLength());
+ rm.stop();
+ }
+
+ public void verifyNodesXML(NodeList nodes, MockNM nm) throws JSONException,
+ Exception {
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Element element = (Element) nodes.item(i);
+ verifyNodeInfoGeneric(nm,
+ WebServicesTestUtils.getXmlString(element, "state"),
+ WebServicesTestUtils.getXmlString(element, "rack"),
+ WebServicesTestUtils.getXmlString(element, "healthStatus"),
+ WebServicesTestUtils.getXmlString(element, "id"),
+ WebServicesTestUtils.getXmlString(element, "nodeHostName"),
+ WebServicesTestUtils.getXmlString(element, "nodeHTTPAddress"),
+ WebServicesTestUtils.getXmlLong(element, "lastHealthUpdate"),
+ WebServicesTestUtils.getXmlString(element, "healthReport"),
+ WebServicesTestUtils.getXmlInt(element, "numContainers"),
+ WebServicesTestUtils.getXmlLong(element, "usedMemoryMB"),
+ WebServicesTestUtils.getXmlLong(element, "availMemoryMB"));
+ }
+ }
+
+ public void verifyNodeInfo(JSONObject nodeInfo, MockNM nm)
+ throws JSONException, Exception {
+ assertEquals("incorrect number of elements", 11, nodeInfo.length());
+
+ verifyNodeInfoGeneric(nm, nodeInfo.getString("state"),
+ nodeInfo.getString("rack"), nodeInfo.getString("healthStatus"),
+ nodeInfo.getString("id"), nodeInfo.getString("nodeHostName"),
+ nodeInfo.getString("nodeHTTPAddress"),
+ nodeInfo.getLong("lastHealthUpdate"),
+ nodeInfo.getString("healthReport"), nodeInfo.getInt("numContainers"),
+ nodeInfo.getLong("usedMemoryMB"), nodeInfo.getLong("availMemoryMB"));
+
+ }
+
+ public void verifyNodeInfoGeneric(MockNM nm, String state, String rack,
+ String healthStatus, String id, String nodeHostName,
+ String nodeHTTPAddress, long lastHealthUpdate, String healthReport,
+ int numContainers, long usedMemoryMB, long availMemoryMB)
+ throws JSONException, Exception {
+
+ RMNode node = rm.getRMContext().getRMNodes().get(nm.getNodeId());
+ NodeHealthStatus health = node.getNodeHealthStatus();
+ ResourceScheduler sched = rm.getResourceScheduler();
+ SchedulerNodeReport report = sched.getNodeReport(nm.getNodeId());
+
+ WebServicesTestUtils.checkStringMatch("state", node.getState().toString(),
+ state);
+ WebServicesTestUtils.checkStringMatch("rack", node.getRackName(), rack);
+ WebServicesTestUtils.checkStringMatch("healthStatus", "Healthy",
+ healthStatus);
+ WebServicesTestUtils.checkStringMatch("id", nm.getNodeId().toString(), id);
+ WebServicesTestUtils.checkStringMatch("nodeHostName", nm.getNodeId()
+ .getHost(), nodeHostName);
+ WebServicesTestUtils.checkStringMatch("healthReport",
+ String.valueOf(health.getHealthReport()), healthReport);
+ String expectedHttpAddress = nm.getNodeId().getHost() + ":"
+ + nm.getHttpPort();
+ WebServicesTestUtils.checkStringMatch("nodeHTTPAddress",
+ expectedHttpAddress, nodeHTTPAddress);
+
+ long expectedHealthUpdate = health.getLastHealthReportTime();
+ assertEquals("lastHealthUpdate doesn't match, got: " + lastHealthUpdate
+ + " expected: " + expectedHealthUpdate, expectedHealthUpdate,
+ lastHealthUpdate);
+
+ if (report != null) {
+ assertEquals("numContainers doesn't match: " + numContainers,
+ report.getNumContainers(), numContainers);
+ assertEquals("usedMemoryMB doesn't match: " + usedMemoryMB, report
+ .getUsedResource().getMemory(), usedMemoryMB);
+ assertEquals("availMemoryMB doesn't match: " + availMemoryMB, report
+ .getAvailableResource().getMemory(), availMemoryMB);
+ }
+ }
+
+}