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 [1/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/...
Author: acmurthy
Date: Thu Dec 29 08:06:04 2011
New Revision: 1225463
URL: http://svn.apache.org/viewvc?rev=1225463&view=rev
Log:
MAPREDUCE-3547. Added a bunch of unit tests for the the RM/NM webservices. Contributed by Thomas Graves.
Added:
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/webapp/WebServicesTestUtils.java
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/MockApp.java
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/MockContainer.java
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServices.java
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServicesApps.java
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServicesContainers.java
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
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
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
Modified:
hadoop/common/trunk/hadoop-mapreduce-project/CHANGES.txt
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMWebServices.java
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/dao/ContainerInfo.java
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/CapacitySchedulerInfo.java
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/CapacitySchedulerQueueInfo.java
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/ClusterInfo.java
hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/MockRM.java
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/TestRMWebServices.java
Modified: hadoop/common/trunk/hadoop-mapreduce-project/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/CHANGES.txt?rev=1225463&r1=1225462&r2=1225463&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/CHANGES.txt (original)
+++ hadoop/common/trunk/hadoop-mapreduce-project/CHANGES.txt Thu Dec 29 08:06:04 2011
@@ -172,6 +172,9 @@ Release 0.23.1 - Unreleased
MAPREDUCE-3391. Making a trivial change to correct a log message in
DistributedShell app's AM. (Subroto Sanyal via vinodkv)
+ MAPREDUCE-3547. Added a bunch of unit tests for the the RM/NM webservices.
+ (Thomas Graves via acmurthy)
+
OPTIMIZATIONS
MAPREDUCE-3567. Extraneous JobConf objects in AM heap. (Vinod Kumar
Added: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/webapp/WebServicesTestUtils.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/webapp/WebServicesTestUtils.java?rev=1225463&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/webapp/WebServicesTestUtils.java (added)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/webapp/WebServicesTestUtils.java Thu Dec 29 08:06:04 2011
@@ -0,0 +1,79 @@
+/**
+ * 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.webapp;
+
+import static org.junit.Assert.assertTrue;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class WebServicesTestUtils {
+
+ public static long getXmlLong(Element element, String name) {
+ String val = getXmlString(element, name);
+ return Long.parseLong(val);
+ }
+
+ public static int getXmlInt(Element element, String name) {
+ String val = getXmlString(element, name);
+ return Integer.parseInt(val);
+ }
+
+ public static Boolean getXmlBoolean(Element element, String name) {
+ String val = getXmlString(element, name);
+ return Boolean.parseBoolean(val);
+ }
+
+ public static float getXmlFloat(Element element, String name) {
+ String val = getXmlString(element, name);
+ return Float.parseFloat(val);
+ }
+
+ public static String getXmlString(Element element, String name) {
+ NodeList id = element.getElementsByTagName(name);
+ Element line = (Element) id.item(0);
+ Node first = line.getFirstChild();
+ // handle empty <key></key>
+ if (first == null) {
+ return "";
+ }
+ String val = first.getNodeValue();
+ if (val == null) {
+ return "";
+ }
+ return val;
+ }
+
+ public static String getXmlAttrString(Element element, String name) {
+ Attr at = element.getAttributeNode(name);
+ if (at != null) {
+ return at.getValue();
+ }
+ return null;
+ }
+
+ public static void checkStringMatch(String print, String expected, String got) {
+ assertTrue(
+ print + " doesn't match, got: " + got + " expected: " + expected,
+ got.matches(expected));
+ }
+
+}
Modified: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMWebServices.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMWebServices.java?rev=1225463&r1=1225462&r2=1225463&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMWebServices.java (original)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMWebServices.java Thu Dec 29 08:06:04 2011
@@ -42,6 +42,7 @@ import org.apache.hadoop.yarn.server.nod
import org.apache.hadoop.yarn.server.nodemanager.webapp.dao.ContainersInfo;
import org.apache.hadoop.yarn.server.nodemanager.webapp.dao.NodeInfo;
import org.apache.hadoop.yarn.util.ConverterUtils;
+import org.apache.hadoop.yarn.webapp.BadRequestException;
import org.apache.hadoop.yarn.webapp.NotFoundException;
import org.apache.hadoop.yarn.webapp.WebApp;
@@ -92,12 +93,16 @@ public class NMWebServices {
AppInfo appInfo = new AppInfo(entry.getValue());
if (stateQuery != null && !stateQuery.isEmpty()) {
- ApplicationState state = ApplicationState.valueOf(stateQuery);
+ ApplicationState.valueOf(stateQuery);
if (!appInfo.getState().equalsIgnoreCase(stateQuery)) {
continue;
}
}
- if (userQuery != null && !userQuery.isEmpty()) {
+ if (userQuery != null) {
+ if (userQuery.isEmpty()) {
+ String msg = "Error: You must specify a non-empty string for the user";
+ throw new BadRequestException(msg);
+ }
if (!appInfo.getUser().toString().equals(userQuery)) {
continue;
}
@@ -146,11 +151,12 @@ public class NMWebServices {
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public ContainerInfo getNodeContainer(@PathParam("containerid") String id) {
ContainerId containerId = null;
- containerId = ConverterUtils.toContainerId(id);
- if (containerId == null) {
- throw new NotFoundException("container with id, " + id
- + ", is empty or null");
+ try {
+ containerId = ConverterUtils.toContainerId(id);
+ } catch (Exception e) {
+ throw new BadRequestException("invalid container id, " + id);
}
+
Container container = nmContext.getContainers().get(containerId);
if (container == null) {
throw new NotFoundException("container with id, " + id + ", not found");
Modified: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/dao/ContainerInfo.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/dao/ContainerInfo.java?rev=1225463&r1=1225462&r2=1225463&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/dao/ContainerInfo.java (original)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/dao/ContainerInfo.java Thu Dec 29 08:06:04 2011
@@ -27,6 +27,7 @@ import javax.xml.bind.annotation.XmlRoot
import javax.xml.bind.annotation.XmlTransient;
import org.apache.hadoop.yarn.api.records.ContainerStatus;
+import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.server.nodemanager.Context;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
@@ -56,7 +57,7 @@ public class ContainerInfo {
}
public ContainerInfo(final Context nmContext, final Container container,
- final String requestUri, final String pathPrefix) {
+ String requestUri, String pathPrefix) {
this.id = container.getContainerID().toString();
this.nodeId = nmContext.getNodeId().toString();
@@ -71,10 +72,19 @@ public class ContainerInfo {
}
this.user = container.getUser();
- this.totalMemoryNeededMB = container.getLaunchContext().getResource()
- .getMemory();
+ Resource res = container.getLaunchContext().getResource();
+ if (res != null) {
+ this.totalMemoryNeededMB = res.getMemory();
+ }
this.containerLogsShortLink = ujoin("containerlogs", this.id,
container.getUser());
+
+ if (requestUri == null) {
+ requestUri = "";
+ }
+ if (pathPrefix == null) {
+ pathPrefix = "";
+ }
this.containerLogsLink = join(requestUri, pathPrefix,
this.containerLogsShortLink);
}
Added: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/MockApp.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/MockApp.java?rev=1225463&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/MockApp.java (added)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/MockApp.java Thu Dec 29 08:06:04 2011
@@ -0,0 +1,83 @@
+/**
+ * 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.nodemanager;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.factories.RecordFactory;
+import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.ApplicationEvent;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.ApplicationState;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
+import org.apache.hadoop.yarn.util.BuilderUtils;
+
+public class MockApp implements Application {
+
+ final String user;
+ final ApplicationId appId;
+ Map<ContainerId, Container> containers = new HashMap<ContainerId, Container>();
+ ApplicationState appState;
+ Application app;
+
+ public MockApp(int uniqId) {
+ this("mockUser", 1234, uniqId);
+ }
+
+ public MockApp(String user, long clusterTimeStamp, int uniqId) {
+ super();
+ this.user = user;
+ // Add an application and the corresponding containers
+ RecordFactory recordFactory = RecordFactoryProvider
+ .getRecordFactory(new Configuration());
+ this.appId = BuilderUtils.newApplicationId(recordFactory, clusterTimeStamp,
+ uniqId);
+ appState = ApplicationState.NEW;
+ }
+
+ public void setState(ApplicationState state) {
+ this.appState = state;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public Map<ContainerId, Container> getContainers() {
+ return containers;
+ }
+
+ public ApplicationId getAppId() {
+ return appId;
+ }
+
+ public ApplicationState getApplicationState() {
+ return appState;
+ }
+
+ public void handle(ApplicationEvent event) {}
+
+}
Added: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/MockContainer.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/MockContainer.java?rev=1225463&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/MockContainer.java (added)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/MockContainer.java Thu Dec 29 08:06:04 2011
@@ -0,0 +1,120 @@
+/**
+ * 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.nodemanager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.Credentials;
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
+import org.apache.hadoop.yarn.api.records.ContainerStatus;
+import org.apache.hadoop.yarn.event.Dispatcher;
+import org.apache.hadoop.yarn.factories.RecordFactory;
+import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerEvent;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerState;
+import org.apache.hadoop.yarn.util.BuilderUtils;
+
+public class MockContainer implements Container {
+
+ private ContainerId id;
+ private ContainerState state;
+ private String user;
+ private ContainerLaunchContext launchContext;
+ private final Map<Path, String> resource = new HashMap<Path, String>();
+ private RecordFactory recordFactory;
+
+ public MockContainer(ApplicationAttemptId appAttemptId,
+ Dispatcher dispatcher, Configuration conf, String user,
+ ApplicationId appId, int uniqId) {
+
+ this.user = user;
+ this.recordFactory = RecordFactoryProvider.getRecordFactory(conf);
+ this.id = BuilderUtils.newContainerId(recordFactory, appId, appAttemptId,
+ uniqId);
+ this.launchContext = recordFactory
+ .newRecordInstance(ContainerLaunchContext.class);
+ launchContext.setContainerId(id);
+ launchContext.setUser(user);
+ this.state = ContainerState.NEW;
+
+ }
+
+ public void setState(ContainerState state) {
+ this.state = state;
+ }
+
+ @Override
+ public ContainerId getContainerID() {
+ return id;
+ }
+
+ @Override
+ public String getUser() {
+ return user;
+ }
+
+ @Override
+ public ContainerState getContainerState() {
+ return state;
+ }
+
+ @Override
+ public ContainerLaunchContext getLaunchContext() {
+ return launchContext;
+ }
+
+ @Override
+ public Credentials getCredentials() {
+ return null;
+ }
+
+ @Override
+ public Map<Path, String> getLocalizedResources() {
+ return resource;
+ }
+
+ @Override
+ public ContainerStatus cloneAndGetContainerStatus() {
+ ContainerStatus containerStatus = recordFactory
+ .newRecordInstance(ContainerStatus.class);
+ containerStatus
+ .setState(org.apache.hadoop.yarn.api.records.ContainerState.RUNNING);
+ containerStatus.setContainerId(this.launchContext.getContainerId());
+ containerStatus.setDiagnostics("testing");
+ containerStatus.setExitStatus(0);
+ return containerStatus;
+ }
+
+ @Override
+ public String toString() {
+ return "";
+ }
+
+ @Override
+ public void handle(ContainerEvent event) {
+ }
+
+}
Added: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServices.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServices.java?rev=1225463&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServices.java (added)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServices.java Thu Dec 29 08:06:04 2011
@@ -0,0 +1,361 @@
+/**
+ * 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.nodemanager.webapp;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+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.fs.FileUtil;
+import org.apache.hadoop.util.VersionInfo;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.server.nodemanager.Context;
+import org.apache.hadoop.yarn.server.nodemanager.LocalDirsHandlerService;
+import org.apache.hadoop.yarn.server.nodemanager.NodeHealthCheckerService;
+import org.apache.hadoop.yarn.server.nodemanager.NodeManager;
+import org.apache.hadoop.yarn.server.nodemanager.ResourceView;
+import org.apache.hadoop.yarn.server.nodemanager.webapp.WebServer.NMWebApp;
+import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
+import org.apache.hadoop.yarn.util.YarnVersionInfo;
+import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
+import org.apache.hadoop.yarn.webapp.WebApp;
+import org.apache.hadoop.yarn.webapp.WebServicesTestUtils;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.junit.AfterClass;
+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;
+
+/**
+ * Test the nodemanager node info web services api's
+ */
+public class TestNMWebServices extends JerseyTest {
+
+ private static Context nmContext;
+ private static ResourceView resourceView;
+ private static ApplicationACLsManager aclsManager;
+ private static LocalDirsHandlerService dirsHandler;
+ private static WebApp nmWebApp;
+
+ private static final File testRootDir = new File("target",
+ TestNMWebServices.class.getSimpleName());
+ private static File testLogDir = new File("target",
+ TestNMWebServices.class.getSimpleName() + "LogDir");
+
+ private Injector injector = Guice.createInjector(new ServletModule() {
+ @Override
+ protected void configureServlets() {
+ nmContext = new NodeManager.NMContext();
+ nmContext.getNodeId().setHost("testhost.foo.com");
+ nmContext.getNodeId().setPort(9999);
+ resourceView = new ResourceView() {
+ @Override
+ public long getVmemAllocatedForContainers() {
+ // 15.5G in bytes
+ return new Long("16642998272");
+ }
+
+ @Override
+ public long getPmemAllocatedForContainers() {
+ // 16G in bytes
+ return new Long("17179869184");
+ }
+ };
+ Configuration conf = new Configuration();
+ conf.set(YarnConfiguration.NM_LOCAL_DIRS, testRootDir.getAbsolutePath());
+ conf.set(YarnConfiguration.NM_LOG_DIRS, testLogDir.getAbsolutePath());
+ NodeHealthCheckerService healthChecker = new NodeHealthCheckerService();
+ healthChecker.init(conf);
+ dirsHandler = healthChecker.getDiskHandler();
+ aclsManager = new ApplicationACLsManager(conf);
+ nmWebApp = new NMWebApp(resourceView, aclsManager, dirsHandler);
+ bind(JAXBContextResolver.class);
+ bind(NMWebServices.class);
+ bind(GenericExceptionHandler.class);
+ bind(Context.class).toInstance(nmContext);
+ bind(WebApp.class).toInstance(nmWebApp);
+ bind(ResourceView.class).toInstance(resourceView);
+ bind(ApplicationACLsManager.class).toInstance(aclsManager);
+ bind(LocalDirsHandlerService.class).toInstance(dirsHandler);
+
+ serve("/*").with(GuiceContainer.class);
+ }
+ });
+
+ public class GuiceServletConfig extends GuiceServletContextListener {
+
+ @Override
+ protected Injector getInjector() {
+ return injector;
+ }
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ testRootDir.mkdirs();
+ testLogDir.mkdir();
+ }
+
+ @AfterClass
+ static public void stop() {
+ FileUtil.fullyDelete(testRootDir);
+ FileUtil.fullyDelete(testLogDir);
+ }
+
+ public TestNMWebServices() {
+ super(new WebAppDescriptor.Builder(
+ "org.apache.hadoop.yarn.server.nodemanager.webapp")
+ .contextListenerClass(GuiceServletConfig.class)
+ .filterClass(com.google.inject.servlet.GuiceFilter.class)
+ .contextPath("jersey-guice-filter").servletPath("/").build());
+ }
+
+ @Test
+ public void testInvalidUri() throws JSONException, Exception {
+ WebResource r = resource();
+ String responseStr = "";
+ try {
+ responseStr = r.path("ws").path("v1").path("node").path("bogus")
+ .accept(MediaType.APPLICATION_JSON).get(String.class);
+ fail("should have thrown exception on invalid uri");
+ } catch (UniformInterfaceException ue) {
+ ClientResponse response = ue.getResponse();
+ assertEquals(Status.NOT_FOUND, response.getClientResponseStatus());
+ WebServicesTestUtils.checkStringMatch(
+ "error string exists and shouldn't", "", responseStr);
+ }
+ }
+
+ @Test
+ public void testInvalidAccept() throws JSONException, Exception {
+ WebResource r = resource();
+ String responseStr = "";
+ try {
+ responseStr = r.path("ws").path("v1").path("node")
+ .accept(MediaType.TEXT_PLAIN).get(String.class);
+ fail("should have thrown exception on invalid uri");
+ } catch (UniformInterfaceException ue) {
+ ClientResponse response = ue.getResponse();
+ assertEquals(Status.INTERNAL_SERVER_ERROR,
+ response.getClientResponseStatus());
+ WebServicesTestUtils.checkStringMatch(
+ "error string exists and shouldn't", "", responseStr);
+ }
+ }
+
+ @Test
+ public void testInvalidUri2() throws JSONException, Exception {
+ WebResource r = resource();
+ String responseStr = "";
+ try {
+ responseStr = r.accept(MediaType.APPLICATION_JSON).get(String.class);
+ fail("should have thrown exception on invalid uri");
+ } catch (UniformInterfaceException ue) {
+ ClientResponse response = ue.getResponse();
+ assertEquals(Status.NOT_FOUND, response.getClientResponseStatus());
+ WebServicesTestUtils.checkStringMatch(
+ "error string exists and shouldn't", "", responseStr);
+ }
+ }
+
+ @Test
+ public void testNode() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("node")
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyNodeInfo(json);
+ }
+
+ @Test
+ public void testNodeSlash() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("node/")
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyNodeInfo(json);
+ }
+
+ // make sure default is json output
+ @Test
+ public void testNodeDefault() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("node")
+ .get(ClientResponse.class);
+
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyNodeInfo(json);
+ }
+
+ @Test
+ public void testNodeInfo() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("node").path("info")
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyNodeInfo(json);
+ }
+
+ @Test
+ public void testNodeInfoSlash() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("node")
+ .path("info/").accept(MediaType.APPLICATION_JSON)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyNodeInfo(json);
+ }
+
+ // make sure default is json output
+ @Test
+ public void testNodeInfoDefault() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("node").path("info")
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyNodeInfo(json);
+ }
+
+ @Test
+ public void testSingleNodesXML() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("node")
+ .path("info/").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("nodeInfo");
+ assertEquals("incorrect number of elements", 1, nodes.getLength());
+ verifyNodesXML(nodes);
+ }
+
+ public void verifyNodesXML(NodeList nodes) throws JSONException, Exception {
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Element element = (Element) nodes.item(i);
+
+ verifyNodeInfoGeneric(WebServicesTestUtils.getXmlString(element, "id"),
+ WebServicesTestUtils.getXmlString(element, "healthReport"),
+ WebServicesTestUtils.getXmlLong(element,
+ "totalVmemAllocatedContainersMB"),
+ WebServicesTestUtils.getXmlLong(element,
+ "totalPmemAllocatedContainersMB"),
+ WebServicesTestUtils.getXmlLong(element, "lastNodeUpdateTime"),
+ WebServicesTestUtils.getXmlBoolean(element, "nodeHealthy"),
+ WebServicesTestUtils.getXmlString(element, "nodeHostName"),
+ WebServicesTestUtils.getXmlString(element, "hadoopVersionBuiltOn"),
+ WebServicesTestUtils.getXmlString(element, "hadoopBuildVersion"),
+ WebServicesTestUtils.getXmlString(element, "hadoopVersion"),
+ WebServicesTestUtils.getXmlString(element,
+ "nodeManagerVersionBuiltOn"), WebServicesTestUtils.getXmlString(
+ element, "nodeManagerBuildVersion"),
+ WebServicesTestUtils.getXmlString(element, "nodeManagerVersion"));
+ }
+ }
+
+ public void verifyNodeInfo(JSONObject json) throws JSONException, Exception {
+ assertEquals("incorrect number of elements", 1, json.length());
+ JSONObject info = json.getJSONObject("nodeInfo");
+ assertEquals("incorrect number of elements", 13, info.length());
+ verifyNodeInfoGeneric(info.getString("id"), info.getString("healthReport"),
+ info.getLong("totalVmemAllocatedContainersMB"),
+ info.getLong("totalPmemAllocatedContainersMB"),
+ info.getLong("lastNodeUpdateTime"), info.getBoolean("nodeHealthy"),
+ info.getString("nodeHostName"), info.getString("hadoopVersionBuiltOn"),
+ info.getString("hadoopBuildVersion"), info.getString("hadoopVersion"),
+ info.getString("nodeManagerVersionBuiltOn"),
+ info.getString("nodeManagerBuildVersion"),
+ info.getString("nodeManagerVersion"));
+
+ }
+
+ public void verifyNodeInfoGeneric(String id, String healthReport,
+ long totalVmemAllocatedContainersMB, long totalPmemAllocatedContainersMB,
+ long lastNodeUpdateTime, Boolean nodeHealthy, String nodeHostName,
+ String hadoopVersionBuiltOn, String hadoopBuildVersion,
+ String hadoopVersion, String resourceManagerVersionBuiltOn,
+ String resourceManagerBuildVersion, String resourceManagerVersion) {
+
+ WebServicesTestUtils.checkStringMatch("id", "testhost.foo.com:9999", id);
+ WebServicesTestUtils.checkStringMatch("healthReport", "Healthy",
+ healthReport);
+ assertEquals("totalVmemAllocatedContainersMB incorrect", 15872,
+ totalVmemAllocatedContainersMB);
+ assertEquals("totalPmemAllocatedContainersMB incorrect", 16384,
+ totalPmemAllocatedContainersMB);
+ assertTrue("lastNodeUpdateTime incorrect", lastNodeUpdateTime == nmContext
+ .getNodeHealthStatus().getLastHealthReportTime());
+ assertTrue("nodeHealthy isn't true", nodeHealthy);
+ WebServicesTestUtils.checkStringMatch("nodeHostName", "testhost.foo.com",
+ nodeHostName);
+
+ WebServicesTestUtils.checkStringMatch("hadoopVersionBuiltOn",
+ VersionInfo.getDate(), hadoopVersionBuiltOn);
+ WebServicesTestUtils.checkStringMatch("hadoopBuildVersion",
+ VersionInfo.getBuildVersion(), hadoopBuildVersion);
+ WebServicesTestUtils.checkStringMatch("hadoopVersion",
+ VersionInfo.getVersion(), hadoopVersion);
+
+ WebServicesTestUtils.checkStringMatch("resourceManagerVersionBuiltOn",
+ YarnVersionInfo.getDate(), resourceManagerVersionBuiltOn);
+ WebServicesTestUtils.checkStringMatch("resourceManagerBuildVersion",
+ YarnVersionInfo.getBuildVersion(), resourceManagerBuildVersion);
+ WebServicesTestUtils.checkStringMatch("resourceManagerVersion",
+ YarnVersionInfo.getVersion(), resourceManagerVersion);
+ }
+
+}
Added: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServicesApps.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServicesApps.java?rev=1225463&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServicesApps.java (added)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServicesApps.java Thu Dec 29 08:06:04 2011
@@ -0,0 +1,607 @@
+/**
+ * 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.nodemanager.webapp;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.StringReader;
+import java.util.HashMap;
+
+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.fs.FileUtil;
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.hadoop.yarn.event.Dispatcher;
+import org.apache.hadoop.yarn.server.nodemanager.Context;
+import org.apache.hadoop.yarn.server.nodemanager.LocalDirsHandlerService;
+import org.apache.hadoop.yarn.server.nodemanager.MockApp;
+import org.apache.hadoop.yarn.server.nodemanager.MockContainer;
+import org.apache.hadoop.yarn.server.nodemanager.NodeHealthCheckerService;
+import org.apache.hadoop.yarn.server.nodemanager.NodeManager;
+import org.apache.hadoop.yarn.server.nodemanager.ResourceView;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.ApplicationState;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
+import org.apache.hadoop.yarn.server.nodemanager.webapp.WebServer.NMWebApp;
+import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
+import org.apache.hadoop.yarn.util.BuilderUtils;
+import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
+import org.apache.hadoop.yarn.webapp.WebApp;
+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.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+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 TestNMWebServicesApps extends JerseyTest {
+
+ private static Context nmContext;
+ private static ResourceView resourceView;
+ private static ApplicationACLsManager aclsManager;
+ private static LocalDirsHandlerService dirsHandler;
+ private static WebApp nmWebApp;
+ private static Configuration conf = new Configuration();
+
+ private static final File testRootDir = new File("target",
+ TestNMWebServicesApps.class.getSimpleName());
+ private static File testLogDir = new File("target",
+ TestNMWebServicesApps.class.getSimpleName() + "LogDir");
+
+ private Injector injector = Guice.createInjector(new ServletModule() {
+ @Override
+ protected void configureServlets() {
+ nmContext = new NodeManager.NMContext();
+ nmContext.getNodeId().setHost("testhost.foo.com");
+ nmContext.getNodeId().setPort(9999);
+ resourceView = new ResourceView() {
+ @Override
+ public long getVmemAllocatedForContainers() {
+ // 15.5G in bytes
+ return new Long("16642998272");
+ }
+
+ @Override
+ public long getPmemAllocatedForContainers() {
+ // 16G in bytes
+ return new Long("17179869184");
+ }
+ };
+ conf.set(YarnConfiguration.NM_LOCAL_DIRS, testRootDir.getAbsolutePath());
+ conf.set(YarnConfiguration.NM_LOG_DIRS, testLogDir.getAbsolutePath());
+ NodeHealthCheckerService healthChecker = new NodeHealthCheckerService();
+ healthChecker.init(conf);
+ dirsHandler = healthChecker.getDiskHandler();
+ aclsManager = new ApplicationACLsManager(conf);
+ nmWebApp = new NMWebApp(resourceView, aclsManager, dirsHandler);
+ bind(JAXBContextResolver.class);
+ bind(NMWebServices.class);
+ bind(GenericExceptionHandler.class);
+ bind(Context.class).toInstance(nmContext);
+ bind(WebApp.class).toInstance(nmWebApp);
+ bind(ResourceView.class).toInstance(resourceView);
+ bind(ApplicationACLsManager.class).toInstance(aclsManager);
+ bind(LocalDirsHandlerService.class).toInstance(dirsHandler);
+
+ serve("/*").with(GuiceContainer.class);
+ }
+ });
+
+ public class GuiceServletConfig extends GuiceServletContextListener {
+
+ @Override
+ protected Injector getInjector() {
+ return injector;
+ }
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ testRootDir.mkdirs();
+ testLogDir.mkdir();
+ }
+
+ @AfterClass
+ static public void cleanup() {
+ FileUtil.fullyDelete(testRootDir);
+ FileUtil.fullyDelete(testLogDir);
+ }
+
+ public TestNMWebServicesApps() {
+ super(new WebAppDescriptor.Builder(
+ "org.apache.hadoop.yarn.server.nodemanager.webapp")
+ .contextListenerClass(GuiceServletConfig.class)
+ .filterClass(com.google.inject.servlet.GuiceFilter.class)
+ .contextPath("jersey-guice-filter").servletPath("/").build());
+ }
+
+ @Test
+ public void testNodeAppsNone() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("node").path("apps")
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("apps isn't NULL", JSONObject.NULL, json.get("apps"));
+ }
+
+ private HashMap<String, String> addAppContainers(Application app) {
+ Dispatcher dispatcher = new AsyncDispatcher();
+ ApplicationAttemptId appAttemptId = BuilderUtils.newApplicationAttemptId(
+ app.getAppId(), 1);
+ Container container1 = new MockContainer(appAttemptId, dispatcher, conf,
+ app.getUser(), app.getAppId(), 1);
+ Container container2 = new MockContainer(appAttemptId, dispatcher, conf,
+ app.getUser(), app.getAppId(), 2);
+ nmContext.getContainers().put(container1.getContainerID(), container1);
+ nmContext.getContainers().put(container2.getContainerID(), container2);
+
+ app.getContainers().put(container1.getContainerID(), container1);
+ app.getContainers().put(container2.getContainerID(), container2);
+ HashMap<String, String> hash = new HashMap<String, String>();
+ hash.put(container1.getContainerID().toString(), container1
+ .getContainerID().toString());
+ hash.put(container2.getContainerID().toString(), container2
+ .getContainerID().toString());
+ return hash;
+ }
+
+ @Test
+ public void testNodeApps() throws JSONException, Exception {
+ testNodeHelper("apps", MediaType.APPLICATION_JSON);
+ }
+
+ @Test
+ public void testNodeAppsSlash() throws JSONException, Exception {
+ testNodeHelper("apps/", MediaType.APPLICATION_JSON);
+ }
+
+ // make sure default is json output
+ @Test
+ public void testNodeAppsDefault() throws JSONException, Exception {
+ testNodeHelper("apps/", "");
+
+ }
+
+ public void testNodeHelper(String path, String media) throws JSONException,
+ Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ HashMap<String, String> hash = addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ HashMap<String, String> hash2 = addAppContainers(app2);
+
+ ClientResponse response = r.path("ws").path("v1").path("node").path(path)
+ .accept(media).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ JSONObject info = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, info.length());
+ JSONArray appInfo = info.getJSONArray("app");
+ assertEquals("incorrect number of elements", 2, appInfo.length());
+ String id = appInfo.getJSONObject(0).getString("id");
+ if (id.matches(app.getAppId().toString())) {
+ verifyNodeAppInfo(appInfo.getJSONObject(0), app, hash);
+ verifyNodeAppInfo(appInfo.getJSONObject(1), app2, hash2);
+ } else {
+ verifyNodeAppInfo(appInfo.getJSONObject(0), app2, hash2);
+ verifyNodeAppInfo(appInfo.getJSONObject(1), app, hash);
+ }
+ }
+
+ @Test
+ public void testNodeAppsUser() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ HashMap<String, String> hash = addAppContainers(app);
+ Application app2 = new MockApp("foo", 1234, 2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ ClientResponse response = r.path("ws").path("v1").path("node").path("apps")
+ .queryParam("user", "mockUser").accept(MediaType.APPLICATION_JSON)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+
+ JSONObject info = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, info.length());
+ JSONArray appInfo = info.getJSONArray("app");
+ assertEquals("incorrect number of elements", 1, appInfo.length());
+ verifyNodeAppInfo(appInfo.getJSONObject(0), app, hash);
+ }
+
+ @Test
+ public void testNodeAppsUserNone() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp("foo", 1234, 2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ ClientResponse response = r.path("ws").path("v1").path("node").path("apps")
+ .queryParam("user", "george").accept(MediaType.APPLICATION_JSON)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("apps is not null", JSONObject.NULL, json.get("apps"));
+ }
+
+ @Test
+ public void testNodeAppsUserEmpty() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp("foo", 1234, 2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ try {
+ r.path("ws").path("v1").path("node").path("apps").queryParam("user", "")
+ .accept(MediaType.APPLICATION_JSON).get(JSONObject.class);
+ fail("should have thrown exception on invalid user 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",
+ "java.lang.Exception: Error: You must specify a non-empty string for the user",
+ message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "BadRequestException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "org.apache.hadoop.yarn.webapp.BadRequestException", classname);
+ }
+ }
+
+ @Test
+ public void testNodeAppsState() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ MockApp app2 = new MockApp("foo", 1234, 2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ HashMap<String, String> hash2 = addAppContainers(app2);
+ app2.setState(ApplicationState.RUNNING);
+
+ ClientResponse response = r.path("ws").path("v1").path("node").path("apps")
+ .queryParam("state", ApplicationState.RUNNING.toString())
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+
+ JSONObject info = json.getJSONObject("apps");
+ assertEquals("incorrect number of elements", 1, info.length());
+ JSONArray appInfo = info.getJSONArray("app");
+ assertEquals("incorrect number of elements", 1, appInfo.length());
+ verifyNodeAppInfo(appInfo.getJSONObject(0), app2, hash2);
+
+ }
+
+ @Test
+ public void testNodeAppsStateNone() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp("foo", 1234, 2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ ClientResponse response = r.path("ws").path("v1").path("node").path("apps")
+ .queryParam("state", ApplicationState.INITING.toString())
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+
+ assertEquals("apps is not null", JSONObject.NULL, json.get("apps"));
+ }
+
+ @Test
+ public void testNodeAppsStateInvalid() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp("foo", 1234, 2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ try {
+ r.path("ws").path("v1").path("node").path("apps")
+ .queryParam("state", "FOO_STATE").accept(MediaType.APPLICATION_JSON)
+ .get(JSONObject.class);
+ fail("should have thrown exception on invalid user 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.nodemanager.containermanager.application.ApplicationState.FOO_STATE",
+ message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "IllegalArgumentException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "java.lang.IllegalArgumentException", classname);
+ }
+ }
+
+ @Test
+ public void testNodeSingleApps() throws JSONException, Exception {
+ testNodeSingleAppHelper(MediaType.APPLICATION_JSON);
+ }
+
+ // make sure default is json output
+ @Test
+ public void testNodeSingleAppsDefault() throws JSONException, Exception {
+ testNodeSingleAppHelper("");
+ }
+
+ public void testNodeSingleAppHelper(String media) throws JSONException,
+ Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ HashMap<String, String> hash = addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ ClientResponse response = r.path("ws").path("v1").path("node").path("apps")
+ .path(app.getAppId().toString()).accept(media)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyNodeAppInfo(json.getJSONObject("app"), app, hash);
+ }
+
+ @Test
+ public void testNodeSingleAppsSlash() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ HashMap<String, String> hash = addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+ ClientResponse response = r.path("ws").path("v1").path("node").path("apps")
+ .path(app.getAppId().toString() + "/")
+ .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyNodeAppInfo(json.getJSONObject("app"), app, hash);
+ }
+
+ @Test
+ public void testNodeSingleAppsInvalid() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ try {
+ r.path("ws").path("v1").path("node").path("apps").path("app_foo_0000")
+ .accept(MediaType.APPLICATION_JSON).get(JSONObject.class);
+ fail("should have thrown exception on invalid user 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",
+ "For input string: \"foo\"", message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "NumberFormatException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "java.lang.NumberFormatException", classname);
+ }
+ }
+
+ @Test
+ public void testNodeSingleAppsMissing() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ try {
+ r.path("ws").path("v1").path("node").path("apps")
+ .path("application_1234_0009").accept(MediaType.APPLICATION_JSON)
+ .get(JSONObject.class);
+ fail("should have thrown exception on invalid user query");
+ } 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_1234_0009 not found",
+ message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "NotFoundException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "org.apache.hadoop.yarn.webapp.NotFoundException", classname);
+ }
+ }
+
+ @Test
+ public void testNodeAppsXML() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ ClientResponse response = r.path("ws").path("v1").path("node").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 nodes = dom.getElementsByTagName("app");
+ assertEquals("incorrect number of elements", 2, nodes.getLength());
+ }
+
+ @Test
+ public void testNodeSingleAppsXML() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ HashMap<String, String> hash = addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ ClientResponse response = r.path("ws").path("v1").path("node").path("apps")
+ .path(app.getAppId().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());
+ verifyNodeAppInfoXML(nodes, app, hash);
+ }
+
+ public void verifyNodeAppInfoXML(NodeList nodes, Application app,
+ HashMap<String, String> hash) throws JSONException, Exception {
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Element element = (Element) nodes.item(i);
+
+ verifyNodeAppInfoGeneric(app,
+ WebServicesTestUtils.getXmlString(element, "id"),
+ WebServicesTestUtils.getXmlString(element, "state"),
+ WebServicesTestUtils.getXmlString(element, "user"));
+
+ NodeList ids = element.getElementsByTagName("containerids");
+ for (int j = 0; j < ids.getLength(); j++) {
+ Element line = (Element) ids.item(j);
+ Node first = line.getFirstChild();
+ String val = first.getNodeValue();
+ assertEquals("extra containerid: " + val, val, hash.remove(val));
+ }
+ assertTrue("missing containerids", hash.isEmpty());
+ }
+ }
+
+ public void verifyNodeAppInfo(JSONObject info, Application app,
+ HashMap<String, String> hash) throws JSONException, Exception {
+ assertEquals("incorrect number of elements", 4, info.length());
+
+ verifyNodeAppInfoGeneric(app, info.getString("id"),
+ info.getString("state"), info.getString("user"));
+
+ JSONArray containerids = info.getJSONArray("containerids");
+ for (int i = 0; i < containerids.length(); i++) {
+ String id = containerids.getString(i);
+ assertEquals("extra containerid: " + id, id, hash.remove(id));
+ }
+ assertTrue("missing containerids", hash.isEmpty());
+ }
+
+ public void verifyNodeAppInfoGeneric(Application app, String id,
+ String state, String user) throws JSONException, Exception {
+ WebServicesTestUtils.checkStringMatch("id", app.getAppId().toString(), id);
+ WebServicesTestUtils.checkStringMatch("state", app.getApplicationState()
+ .toString(), state);
+ WebServicesTestUtils.checkStringMatch("user", app.getUser().toString(),
+ user);
+ }
+
+}
Added: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServicesContainers.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServicesContainers.java?rev=1225463&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServicesContainers.java (added)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebServicesContainers.java Thu Dec 29 08:06:04 2011
@@ -0,0 +1,481 @@
+/**
+ * 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.nodemanager.webapp;
+
+import static org.apache.hadoop.yarn.util.StringHelper.ujoin;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.StringReader;
+import java.util.HashMap;
+
+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.fs.FileUtil;
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.hadoop.yarn.event.Dispatcher;
+import org.apache.hadoop.yarn.server.nodemanager.Context;
+import org.apache.hadoop.yarn.server.nodemanager.LocalDirsHandlerService;
+import org.apache.hadoop.yarn.server.nodemanager.MockApp;
+import org.apache.hadoop.yarn.server.nodemanager.MockContainer;
+import org.apache.hadoop.yarn.server.nodemanager.NodeHealthCheckerService;
+import org.apache.hadoop.yarn.server.nodemanager.NodeManager;
+import org.apache.hadoop.yarn.server.nodemanager.ResourceView;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
+import org.apache.hadoop.yarn.server.nodemanager.webapp.WebServer.NMWebApp;
+import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
+import org.apache.hadoop.yarn.util.BuilderUtils;
+import org.apache.hadoop.yarn.util.ConverterUtils;
+import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
+import org.apache.hadoop.yarn.webapp.WebApp;
+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.AfterClass;
+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 TestNMWebServicesContainers extends JerseyTest {
+
+ private static Context nmContext;
+ private static ResourceView resourceView;
+ private static ApplicationACLsManager aclsManager;
+ private static LocalDirsHandlerService dirsHandler;
+ private static WebApp nmWebApp;
+ private static Configuration conf = new Configuration();
+
+ private static final File testRootDir = new File("target",
+ TestNMWebServicesContainers.class.getSimpleName());
+ private static File testLogDir = new File("target",
+ TestNMWebServicesContainers.class.getSimpleName() + "LogDir");
+
+ private Injector injector = Guice.createInjector(new ServletModule() {
+ @Override
+ protected void configureServlets() {
+ nmContext = new NodeManager.NMContext();
+ nmContext.getNodeId().setHost("testhost.foo.com");
+ nmContext.getNodeId().setPort(9999);
+ resourceView = new ResourceView() {
+ @Override
+ public long getVmemAllocatedForContainers() {
+ // 15.5G in bytes
+ return new Long("16642998272");
+ }
+
+ @Override
+ public long getPmemAllocatedForContainers() {
+ // 16G in bytes
+ return new Long("17179869184");
+ }
+ };
+ conf.set(YarnConfiguration.NM_LOCAL_DIRS, testRootDir.getAbsolutePath());
+ conf.set(YarnConfiguration.NM_LOG_DIRS, testLogDir.getAbsolutePath());
+ NodeHealthCheckerService healthChecker = new NodeHealthCheckerService();
+ healthChecker.init(conf);
+ dirsHandler = healthChecker.getDiskHandler();
+ aclsManager = new ApplicationACLsManager(conf);
+ nmWebApp = new NMWebApp(resourceView, aclsManager, dirsHandler);
+ bind(JAXBContextResolver.class);
+ bind(NMWebServices.class);
+ bind(GenericExceptionHandler.class);
+ bind(Context.class).toInstance(nmContext);
+ bind(WebApp.class).toInstance(nmWebApp);
+ bind(ResourceView.class).toInstance(resourceView);
+ bind(ApplicationACLsManager.class).toInstance(aclsManager);
+ bind(LocalDirsHandlerService.class).toInstance(dirsHandler);
+
+ serve("/*").with(GuiceContainer.class);
+ }
+ });
+
+ public class GuiceServletConfig extends GuiceServletContextListener {
+
+ @Override
+ protected Injector getInjector() {
+ return injector;
+ }
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ testRootDir.mkdirs();
+ testLogDir.mkdir();
+ }
+
+ @AfterClass
+ static public void cleanup() {
+ FileUtil.fullyDelete(testRootDir);
+ FileUtil.fullyDelete(testLogDir);
+ }
+
+ public TestNMWebServicesContainers() {
+ super(new WebAppDescriptor.Builder(
+ "org.apache.hadoop.yarn.server.nodemanager.webapp")
+ .contextListenerClass(GuiceServletConfig.class)
+ .filterClass(com.google.inject.servlet.GuiceFilter.class)
+ .contextPath("jersey-guice-filter").servletPath("/").build());
+ }
+
+ @Test
+ public void testNodeContainersNone() throws JSONException, Exception {
+ WebResource r = resource();
+ ClientResponse response = r.path("ws").path("v1").path("node")
+ .path("containers").accept(MediaType.APPLICATION_JSON)
+ .get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ assertEquals("apps isn't NULL", JSONObject.NULL, json.get("containers"));
+ }
+
+ private HashMap<String, String> addAppContainers(Application app) {
+ Dispatcher dispatcher = new AsyncDispatcher();
+ ApplicationAttemptId appAttemptId = BuilderUtils.newApplicationAttemptId(
+ app.getAppId(), 1);
+ Container container1 = new MockContainer(appAttemptId, dispatcher, conf,
+ app.getUser(), app.getAppId(), 1);
+ Container container2 = new MockContainer(appAttemptId, dispatcher, conf,
+ app.getUser(), app.getAppId(), 2);
+ nmContext.getContainers().put(container1.getContainerID(), container1);
+ nmContext.getContainers().put(container2.getContainerID(), container2);
+
+ app.getContainers().put(container1.getContainerID(), container1);
+ app.getContainers().put(container2.getContainerID(), container2);
+ HashMap<String, String> hash = new HashMap<String, String>();
+ hash.put(container1.getContainerID().toString(), container1
+ .getContainerID().toString());
+ hash.put(container2.getContainerID().toString(), container2
+ .getContainerID().toString());
+ return hash;
+ }
+
+ @Test
+ public void testNodeContainers() throws JSONException, Exception {
+ testNodeHelper("containers", MediaType.APPLICATION_JSON);
+ }
+
+ @Test
+ public void testNodeContainersSlash() throws JSONException, Exception {
+ testNodeHelper("containers/", MediaType.APPLICATION_JSON);
+ }
+
+ // make sure default is json output
+ @Test
+ public void testNodeContainersDefault() throws JSONException, Exception {
+ testNodeHelper("containers/", "");
+
+ }
+
+ public void testNodeHelper(String path, String media) throws JSONException,
+ Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ ClientResponse response = r.path("ws").path("v1").path("node").path(path)
+ .accept(media).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ JSONObject info = json.getJSONObject("containers");
+ assertEquals("incorrect number of elements", 1, info.length());
+ JSONArray conInfo = info.getJSONArray("container");
+ assertEquals("incorrect number of elements", 4, conInfo.length());
+
+ for (int i = 0; i < conInfo.length(); i++) {
+ verifyNodeContainerInfo(
+ conInfo.getJSONObject(i),
+ nmContext.getContainers().get(
+ ConverterUtils.toContainerId(conInfo.getJSONObject(i).getString(
+ "id"))));
+ }
+ }
+
+ @Test
+ public void testNodeSingleContainers() throws JSONException, Exception {
+ testNodeSingleContainersHelper(MediaType.APPLICATION_JSON);
+ }
+
+ @Test
+ public void testNodeSingleContainersSlash() throws JSONException, Exception {
+ testNodeSingleContainersHelper(MediaType.APPLICATION_JSON);
+ }
+
+ @Test
+ public void testNodeSingleContainersDefault() throws JSONException, Exception {
+ testNodeSingleContainersHelper("");
+ }
+
+ public void testNodeSingleContainersHelper(String media)
+ throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ HashMap<String, String> hash = addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ for (String id : hash.keySet()) {
+ ClientResponse response = r.path("ws").path("v1").path("node")
+ .path("containers").path(id).accept(media).get(ClientResponse.class);
+ assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+ JSONObject json = response.getEntity(JSONObject.class);
+ verifyNodeContainerInfo(json.getJSONObject("container"), nmContext
+ .getContainers().get(ConverterUtils.toContainerId(id)));
+ }
+ }
+
+ @Test
+ public void testSingleContainerInvalid() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+ try {
+ r.path("ws").path("v1").path("node").path("containers")
+ .path("container_foo_1234").accept(MediaType.APPLICATION_JSON)
+ .get(JSONObject.class);
+ fail("should have thrown exception on invalid user 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",
+ "java.lang.Exception: invalid container id, container_foo_1234",
+ message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "BadRequestException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "org.apache.hadoop.yarn.webapp.BadRequestException", classname);
+ }
+ }
+
+ @Test
+ public void testSingleContainerInvalid2() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+ try {
+ r.path("ws").path("v1").path("node").path("containers")
+ .path("container_1234_0001").accept(MediaType.APPLICATION_JSON)
+ .get(JSONObject.class);
+ fail("should have thrown exception on invalid user 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",
+ "java.lang.Exception: invalid container id, container_1234_0001",
+ message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "BadRequestException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "org.apache.hadoop.yarn.webapp.BadRequestException", classname);
+ }
+ }
+
+ @Test
+ public void testSingleContainerWrong() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+ try {
+ r.path("ws").path("v1").path("node").path("containers")
+ .path("container_1234_0001_01_000005")
+ .accept(MediaType.APPLICATION_JSON).get(JSONObject.class);
+ fail("should have thrown exception on invalid user query");
+ } 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: container with id, container_1234_0001_01_000005, not found",
+ message);
+ WebServicesTestUtils.checkStringMatch("exception type",
+ "NotFoundException", type);
+ WebServicesTestUtils.checkStringMatch("exception classname",
+ "org.apache.hadoop.yarn.webapp.NotFoundException", classname);
+ }
+ }
+
+ @Test
+ public void testNodeSingleContainerXML() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ HashMap<String, String> hash = addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ for (String id : hash.keySet()) {
+ ClientResponse response = r.path("ws").path("v1").path("node")
+ .path("containers").path(id).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("container");
+ assertEquals("incorrect number of elements", 1, nodes.getLength());
+ verifyContainersInfoXML(nodes,
+ nmContext.getContainers().get(ConverterUtils.toContainerId(id)));
+
+ }
+ }
+
+ @Test
+ public void testNodeContainerXML() throws JSONException, Exception {
+ WebResource r = resource();
+ Application app = new MockApp(1);
+ nmContext.getApplications().put(app.getAppId(), app);
+ addAppContainers(app);
+ Application app2 = new MockApp(2);
+ nmContext.getApplications().put(app2.getAppId(), app2);
+ addAppContainers(app2);
+
+ ClientResponse response = r.path("ws").path("v1").path("node")
+ .path("containers").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("container");
+ assertEquals("incorrect number of elements", 4, nodes.getLength());
+ }
+
+ public void verifyContainersInfoXML(NodeList nodes, Container cont)
+ throws JSONException, Exception {
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Element element = (Element) nodes.item(i);
+
+ verifyNodeContainerInfoGeneric(cont,
+ WebServicesTestUtils.getXmlString(element, "id"),
+ WebServicesTestUtils.getXmlString(element, "state"),
+ WebServicesTestUtils.getXmlString(element, "user"),
+ WebServicesTestUtils.getXmlInt(element, "exitCode"),
+ WebServicesTestUtils.getXmlString(element, "diagnostics"),
+ WebServicesTestUtils.getXmlString(element, "nodeId"),
+ WebServicesTestUtils.getXmlInt(element, "totalMemoryNeededMB"),
+ WebServicesTestUtils.getXmlString(element, "containerLogsLink"));
+ }
+ }
+
+ public void verifyNodeContainerInfo(JSONObject info, Container cont)
+ throws JSONException, Exception {
+ assertEquals("incorrect number of elements", 8, info.length());
+
+ verifyNodeContainerInfoGeneric(cont, info.getString("id"),
+ info.getString("state"), info.getString("user"),
+ info.getInt("exitCode"), info.getString("diagnostics"),
+ info.getString("nodeId"), info.getInt("totalMemoryNeededMB"),
+ info.getString("containerLogsLink"));
+ }
+
+ public void verifyNodeContainerInfoGeneric(Container cont, String id,
+ String state, String user, int exitCode, String diagnostics,
+ String nodeId, int totalMemoryNeededMB, String logsLink)
+ throws JSONException, Exception {
+ WebServicesTestUtils.checkStringMatch("id", cont.getContainerID()
+ .toString(), id);
+ WebServicesTestUtils.checkStringMatch("state", cont.getContainerState()
+ .toString(), state);
+ WebServicesTestUtils.checkStringMatch("user", cont.getUser().toString(),
+ user);
+ assertEquals("exitCode wrong", 0, exitCode);
+ WebServicesTestUtils
+ .checkStringMatch("diagnostics", "testing", diagnostics);
+
+ WebServicesTestUtils.checkStringMatch("nodeId", nmContext.getNodeId()
+ .toString(), nodeId);
+ assertEquals("totalMemoryNeededMB wrong", 0, totalMemoryNeededMB);
+ String shortLink = ujoin("containerlogs", cont.getContainerID().toString(),
+ cont.getUser());
+ assertTrue("containerLogsLink wrong", logsLink.contains(shortLink));
+ }
+
+}
Modified: hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/CapacitySchedulerInfo.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/CapacitySchedulerInfo.java?rev=1225463&r1=1225462&r2=1225463&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/CapacitySchedulerInfo.java (original)
+++ hadoop/common/trunk/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/CapacitySchedulerInfo.java Thu Dec 29 08:06:04 2011
@@ -26,6 +26,7 @@ import javax.xml.bind.annotation.XmlRoot
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
+import org.apache.hadoop.yarn.api.records.QueueState;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CSQueue;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.ParentQueue;
@@ -90,7 +91,7 @@ public class CapacitySchedulerInfo exten
if (max < EPSILON || max > 1f)
max = 1f;
float maxCapacity = max * 100;
- String state = queue.getState().toString();
+ QueueState state = queue.getState();
CapacitySchedulerQueueInfo info = new CapacitySchedulerQueueInfo(
capacity, usedCapacity, maxCapacity, queueName, state, queuePath);