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);