Merge trunk into HA branch.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/HDFS-1623@1225612 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
commit
f216303598
@ -12,6 +12,8 @@ Trunk (unreleased changes)
|
||||
HADOOP-7875. Add helper class to unwrap protobuf ServiceException.
|
||||
(suresh)
|
||||
|
||||
HADOOP-7910. Add Configuration.getLongBytes to handle human readable byte size values. (Sho Shimauchi via harsh)
|
||||
|
||||
IMPROVEMENTS
|
||||
|
||||
HADOOP-7595. Upgrade dependency to Avro 1.5.3. (Alejandro Abdelnur via atm)
|
||||
|
@ -737,6 +737,27 @@ public long getLong(String name, long defaultValue) {
|
||||
return Long.parseLong(valueString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the <code>name</code> property as a <code>long</code> or
|
||||
* human readable format. If no such property exists, the provided default
|
||||
* value is returned, or if the specified value is not a valid
|
||||
* <code>long</code> or human readable format, then an error is thrown. You
|
||||
* can use the following suffix (case insensitive): k(kilo), m(mega), g(giga),
|
||||
* t(tera), p(peta), e(exa)
|
||||
*
|
||||
* @param name property name.
|
||||
* @param defaultValue default value.
|
||||
* @throws NumberFormatException when the value is invalid
|
||||
* @return property value as a <code>long</code>,
|
||||
* or <code>defaultValue</code>.
|
||||
*/
|
||||
public long getLongBytes(String name, long defaultValue) {
|
||||
String valueString = getTrimmed(name);
|
||||
if (valueString == null)
|
||||
return defaultValue;
|
||||
return StringUtils.TraditionalBinaryPrefix.string2long(valueString);
|
||||
}
|
||||
|
||||
private String getHexDigits(String value) {
|
||||
boolean negative = false;
|
||||
String str = value;
|
||||
|
@ -661,7 +661,14 @@ public static long string2long(String s) {
|
||||
if (Character.isDigit(lastchar))
|
||||
return Long.parseLong(s);
|
||||
else {
|
||||
long prefix = TraditionalBinaryPrefix.valueOf(lastchar).value;
|
||||
long prefix;
|
||||
try {
|
||||
prefix = TraditionalBinaryPrefix.valueOf(lastchar).value;
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IllegalArgumentException("Invalid size prefix '" + lastchar
|
||||
+ "' in '" + s
|
||||
+ "'. Allowed prefixes are k, m, g, t, p, e(case insensitive)");
|
||||
}
|
||||
long num = Long.parseLong(s.substring(0, lastpos));
|
||||
if (num > (Long.MAX_VALUE/prefix) || num < (Long.MIN_VALUE/prefix)) {
|
||||
throw new IllegalArgumentException(s + " does not fit in a Long");
|
||||
|
@ -405,12 +405,16 @@ public void testIntegerValues() throws IOException{
|
||||
conf.addResource(fileResource);
|
||||
assertEquals(20, conf.getInt("test.int1", 0));
|
||||
assertEquals(20, conf.getLong("test.int1", 0));
|
||||
assertEquals(20, conf.getLongBytes("test.int1", 0));
|
||||
assertEquals(20, conf.getInt("test.int2", 0));
|
||||
assertEquals(20, conf.getLong("test.int2", 0));
|
||||
assertEquals(20, conf.getLongBytes("test.int2", 0));
|
||||
assertEquals(-20, conf.getInt("test.int3", 0));
|
||||
assertEquals(-20, conf.getLong("test.int3", 0));
|
||||
assertEquals(-20, conf.getLongBytes("test.int3", 0));
|
||||
assertEquals(-20, conf.getInt("test.int4", 0));
|
||||
assertEquals(-20, conf.getLong("test.int4", 0));
|
||||
assertEquals(-20, conf.getLongBytes("test.int4", 0));
|
||||
try {
|
||||
conf.getInt("test.int5", 0);
|
||||
fail("Property had invalid int value, but was read successfully.");
|
||||
@ -419,6 +423,26 @@ public void testIntegerValues() throws IOException{
|
||||
}
|
||||
}
|
||||
|
||||
public void testHumanReadableValues() throws IOException {
|
||||
out = new BufferedWriter(new FileWriter(CONFIG));
|
||||
startConfig();
|
||||
appendProperty("test.humanReadableValue1", "1m");
|
||||
appendProperty("test.humanReadableValue2", "1M");
|
||||
appendProperty("test.humanReadableValue5", "1MBCDE");
|
||||
|
||||
endConfig();
|
||||
Path fileResource = new Path(CONFIG);
|
||||
conf.addResource(fileResource);
|
||||
assertEquals(1048576, conf.getLongBytes("test.humanReadableValue1", 0));
|
||||
assertEquals(1048576, conf.getLongBytes("test.humanReadableValue2", 0));
|
||||
try {
|
||||
conf.getLongBytes("test.humanReadableValue5", 0);
|
||||
fail("Property had invalid human readable value, but was read successfully.");
|
||||
} catch (NumberFormatException e) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
|
||||
public void testBooleanValues() throws IOException {
|
||||
out=new BufferedWriter(new FileWriter(CONFIG));
|
||||
startConfig();
|
||||
|
@ -143,8 +143,62 @@ public void testTraditionalBinaryPrefix() throws Exception {
|
||||
}
|
||||
|
||||
assertEquals(0L, StringUtils.TraditionalBinaryPrefix.string2long("0"));
|
||||
assertEquals(-1259520L, StringUtils.TraditionalBinaryPrefix.string2long("-1230k"));
|
||||
assertEquals(956703965184L, StringUtils.TraditionalBinaryPrefix.string2long("891g"));
|
||||
assertEquals(1024L, StringUtils.TraditionalBinaryPrefix.string2long("1k"));
|
||||
assertEquals(-1024L, StringUtils.TraditionalBinaryPrefix.string2long("-1k"));
|
||||
assertEquals(1259520L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("1230K"));
|
||||
assertEquals(-1259520L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("-1230K"));
|
||||
assertEquals(104857600L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("100m"));
|
||||
assertEquals(-104857600L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("-100M"));
|
||||
assertEquals(956703965184L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("891g"));
|
||||
assertEquals(-956703965184L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("-891G"));
|
||||
assertEquals(501377302265856L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("456t"));
|
||||
assertEquals(-501377302265856L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("-456T"));
|
||||
assertEquals(11258999068426240L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("10p"));
|
||||
assertEquals(-11258999068426240L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("-10P"));
|
||||
assertEquals(1152921504606846976L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("1e"));
|
||||
assertEquals(-1152921504606846976L,
|
||||
StringUtils.TraditionalBinaryPrefix.string2long("-1E"));
|
||||
|
||||
String tooLargeNumStr = "10e";
|
||||
try {
|
||||
StringUtils.TraditionalBinaryPrefix.string2long(tooLargeNumStr);
|
||||
fail("Test passed for a number " + tooLargeNumStr + " too large");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals(tooLargeNumStr + " does not fit in a Long", e.getMessage());
|
||||
}
|
||||
|
||||
String tooSmallNumStr = "-10e";
|
||||
try {
|
||||
StringUtils.TraditionalBinaryPrefix.string2long(tooSmallNumStr);
|
||||
fail("Test passed for a number " + tooSmallNumStr + " too small");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals(tooSmallNumStr + " does not fit in a Long", e.getMessage());
|
||||
}
|
||||
|
||||
String invalidFormatNumStr = "10kb";
|
||||
char invalidPrefix = 'b';
|
||||
try {
|
||||
StringUtils.TraditionalBinaryPrefix.string2long(invalidFormatNumStr);
|
||||
fail("Test passed for a number " + invalidFormatNumStr
|
||||
+ " has invalid format");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Invalid size prefix '" + invalidPrefix + "' in '"
|
||||
+ invalidFormatNumStr
|
||||
+ "'. Allowed prefixes are k, m, g, t, p, e(case insensitive)",
|
||||
e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -117,6 +117,10 @@ Trunk (unreleased changes)
|
||||
|
||||
HDFS-2669 Enable protobuf rpc for ClientNamenodeProtocol
|
||||
|
||||
HDFS-2726. Fix a logging issue under DFSClient's createBlockOutputStream method (harsh)
|
||||
|
||||
HDFS-2729. Update BlockManager's comments regarding the invalid block set (harsh)
|
||||
|
||||
OPTIMIZATIONS
|
||||
HDFS-2477. Optimize computing the diff between a block report and the
|
||||
namenode state. (Tomasz Nykiel via hairong)
|
||||
|
@ -1056,7 +1056,7 @@ private boolean createBlockOutputStream(DatanodeInfo[] nodes, long newGS,
|
||||
|
||||
} catch (IOException ie) {
|
||||
|
||||
DFSClient.LOG.info("Exception in createBlockOutputStream " + ie);
|
||||
DFSClient.LOG.info("Exception in createBlockOutputStream", ie);
|
||||
|
||||
// find the datanode that matches
|
||||
if (firstBadLink.length() != 0) {
|
||||
|
@ -1838,7 +1838,7 @@ private Block addStoredBlock(final BlockInfo block,
|
||||
* Invalidate corrupt replicas.
|
||||
* <p>
|
||||
* This will remove the replicas from the block's location list,
|
||||
* add them to {@link #recentInvalidateSets} so that they could be further
|
||||
* add them to {@link #invalidateBlocks} so that they could be further
|
||||
* deleted from the respective data-nodes,
|
||||
* and remove the block from corruptReplicasMap.
|
||||
* <p>
|
||||
@ -2115,7 +2115,7 @@ private void chooseExcessReplicates(Collection<DatanodeDescriptor> nonExcess,
|
||||
//
|
||||
addToInvalidates(b, cur);
|
||||
NameNode.stateChangeLog.info("BLOCK* chooseExcessReplicates: "
|
||||
+"("+cur.getName()+", "+b+") is added to recentInvalidateSets");
|
||||
+"("+cur.getName()+", "+b+") is added to invalidated blocks set.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2540,7 +2540,7 @@ private int getReplication(Block block) {
|
||||
|
||||
/**
|
||||
* Get blocks to invalidate for <i>nodeId</i>
|
||||
* in {@link #recentInvalidateSets}.
|
||||
* in {@link #invalidateBlocks}.
|
||||
*
|
||||
* @return number of blocks scheduled for removal during this iteration.
|
||||
*/
|
||||
|
@ -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
|
||||
@ -369,6 +372,12 @@ Release 0.23.1 - Unreleased
|
||||
MAPREDUCE-3586. Modified CompositeService to avoid duplicate stop operations
|
||||
thereby solving race conditions in MR AM shutdown. (vinodkv)
|
||||
|
||||
MAPREDUCE-3604. Fixed streaming to use new mapreduce.framework.name to
|
||||
check for local mode. (acmurthy)
|
||||
|
||||
MAPREDUCE-3521. Fixed streaming to ensure it doesn't silently ignore
|
||||
unknown arguments. (Robert Evans via acmurthy)
|
||||
|
||||
Release 0.23.0 - 2011-11-01
|
||||
|
||||
INCOMPATIBLE CHANGES
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -42,6 +42,7 @@
|
||||
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 AppsInfo getNodeApps(@QueryParam("state") String stateQuery,
|
||||
|
||||
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 ContainersInfo getNodeContainers() {
|
||||
@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");
|
||||
|
@ -27,6 +27,7 @@
|
||||
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 ContainerInfo(final Context nmContext, final Container container) {
|
||||
}
|
||||
|
||||
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 ContainerInfo(final Context nmContext, final Container container,
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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) {}
|
||||
|
||||
}
|
@ -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) {
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -26,6 +26,7 @@
|
||||
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 @@ protected ArrayList<CapacitySchedulerQueueInfo> getQueues(CSQueue parent) {
|
||||
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);
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import org.apache.hadoop.yarn.api.records.QueueState;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CSQueue;
|
||||
|
||||
@XmlRootElement
|
||||
@ -43,14 +44,14 @@ public class CapacitySchedulerQueueInfo {
|
||||
protected float usedCapacity;
|
||||
protected float maxCapacity;
|
||||
protected String queueName;
|
||||
protected String state;
|
||||
protected QueueState state;
|
||||
protected ArrayList<CapacitySchedulerQueueInfo> subQueues;
|
||||
|
||||
CapacitySchedulerQueueInfo() {
|
||||
};
|
||||
|
||||
CapacitySchedulerQueueInfo(float cap, float used, float max, String name,
|
||||
String state, String path) {
|
||||
QueueState state, String path) {
|
||||
this.capacity = cap;
|
||||
this.usedCapacity = used;
|
||||
this.maxCapacity = max;
|
||||
@ -84,7 +85,7 @@ public String getQueueName() {
|
||||
}
|
||||
|
||||
public String getQueueState() {
|
||||
return this.state;
|
||||
return this.state.toString();
|
||||
}
|
||||
|
||||
public String getQueuePath() {
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
import org.apache.hadoop.util.VersionInfo;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||
import org.apache.hadoop.yarn.service.Service.STATE;
|
||||
import org.apache.hadoop.yarn.util.YarnVersionInfo;
|
||||
|
||||
@XmlRootElement
|
||||
@ -31,7 +32,7 @@ public class ClusterInfo {
|
||||
|
||||
protected long id;
|
||||
protected long startedOn;
|
||||
protected String state;
|
||||
protected STATE state;
|
||||
protected String resourceManagerVersion;
|
||||
protected String resourceManagerBuildVersion;
|
||||
protected String resourceManagerVersionBuiltOn;
|
||||
@ -46,7 +47,7 @@ public ClusterInfo(ResourceManager rm) {
|
||||
long ts = ResourceManager.clusterTimeStamp;
|
||||
|
||||
this.id = ts;
|
||||
this.state = rm.getServiceState().toString();
|
||||
this.state = rm.getServiceState();
|
||||
this.startedOn = ts;
|
||||
this.resourceManagerVersion = YarnVersionInfo.getVersion();
|
||||
this.resourceManagerBuildVersion = YarnVersionInfo.getBuildVersion();
|
||||
@ -57,7 +58,7 @@ public ClusterInfo(ResourceManager rm) {
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return this.state;
|
||||
return this.state.toString();
|
||||
}
|
||||
|
||||
public String getRMVersion() {
|
||||
|
@ -87,8 +87,12 @@ public GetNewApplicationResponse getNewAppId() throws Exception {
|
||||
.newRecord(GetNewApplicationRequest.class));
|
||||
}
|
||||
|
||||
// client
|
||||
public RMApp submitApp(int masterMemory) throws Exception {
|
||||
return submitApp(masterMemory, "", "");
|
||||
}
|
||||
|
||||
// client
|
||||
public RMApp submitApp(int masterMemory, String name, String user) throws Exception {
|
||||
ClientRMProtocol client = getClientRMService();
|
||||
GetNewApplicationResponse resp = client.getNewApplication(Records
|
||||
.newRecord(GetNewApplicationRequest.class));
|
||||
@ -99,8 +103,8 @@ public RMApp submitApp(int masterMemory) throws Exception {
|
||||
ApplicationSubmissionContext sub = Records
|
||||
.newRecord(ApplicationSubmissionContext.class);
|
||||
sub.setApplicationId(appId);
|
||||
sub.setApplicationName("");
|
||||
sub.setUser("");
|
||||
sub.setApplicationName(name);
|
||||
sub.setUser(user);
|
||||
ContainerLaunchContext clc = Records
|
||||
.newRecord(ContainerLaunchContext.class);
|
||||
Resource capability = Records.newRecord(Resource.class);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,756 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.security.UserGroupInformation;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.MockAM;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.MockNM;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
|
||||
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
|
||||
import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
|
||||
import org.apache.hadoop.yarn.webapp.WebServicesTestUtils;
|
||||
import org.codehaus.jettison.json.JSONArray;
|
||||
import org.codehaus.jettison.json.JSONException;
|
||||
import org.codehaus.jettison.json.JSONObject;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.servlet.GuiceServletContextListener;
|
||||
import com.google.inject.servlet.ServletModule;
|
||||
import com.sun.jersey.api.client.ClientResponse;
|
||||
import com.sun.jersey.api.client.ClientResponse.Status;
|
||||
import com.sun.jersey.api.client.UniformInterfaceException;
|
||||
import com.sun.jersey.api.client.WebResource;
|
||||
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
|
||||
import com.sun.jersey.test.framework.JerseyTest;
|
||||
import com.sun.jersey.test.framework.WebAppDescriptor;
|
||||
|
||||
public class TestRMWebServicesApps extends JerseyTest {
|
||||
|
||||
private static MockRM rm;
|
||||
|
||||
private Injector injector = Guice.createInjector(new ServletModule() {
|
||||
@Override
|
||||
protected void configureServlets() {
|
||||
bind(JAXBContextResolver.class);
|
||||
bind(RMWebServices.class);
|
||||
bind(GenericExceptionHandler.class);
|
||||
rm = new MockRM(new Configuration());
|
||||
bind(ResourceManager.class).toInstance(rm);
|
||||
bind(RMContext.class).toInstance(rm.getRMContext());
|
||||
bind(ApplicationACLsManager.class).toInstance(
|
||||
rm.getApplicationACLsManager());
|
||||
serve("/*").with(GuiceContainer.class);
|
||||
}
|
||||
});
|
||||
|
||||
public class GuiceServletConfig extends GuiceServletContextListener {
|
||||
|
||||
@Override
|
||||
protected Injector getInjector() {
|
||||
return injector;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public TestRMWebServicesApps() {
|
||||
super(new WebAppDescriptor.Builder(
|
||||
"org.apache.hadoop.yarn.server.resourcemanager.webapp")
|
||||
.contextListenerClass(GuiceServletConfig.class)
|
||||
.filterClass(com.google.inject.servlet.GuiceFilter.class)
|
||||
.contextPath("jersey-guice-filter").servletPath("/").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApps() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
RMApp app1 = rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
testAppsHelper("apps", app1, MediaType.APPLICATION_JSON);
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsSlash() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
RMApp app1 = rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
testAppsHelper("apps/", app1, MediaType.APPLICATION_JSON);
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsDefault() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
RMApp app1 = rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
testAppsHelper("apps/", app1, "");
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsXML() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
RMApp app1 = rm.submitApp(1024, "testwordcount", "user1");
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").accept(MediaType.APPLICATION_XML)
|
||||
.get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
|
||||
String xml = response.getEntity(String.class);
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
InputSource is = new InputSource();
|
||||
is.setCharacterStream(new StringReader(xml));
|
||||
Document dom = db.parse(is);
|
||||
NodeList nodesApps = dom.getElementsByTagName("apps");
|
||||
assertEquals("incorrect number of elements", 1, nodesApps.getLength());
|
||||
NodeList nodes = dom.getElementsByTagName("app");
|
||||
assertEquals("incorrect number of elements", 1, nodes.getLength());
|
||||
verifyAppsXML(nodes, app1);
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsXMLMulti() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
rm.submitApp(1024, "testwordcount", "user1");
|
||||
rm.submitApp(2048, "testwordcount2", "user1");
|
||||
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
WebResource r = resource();
|
||||
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").accept(MediaType.APPLICATION_XML)
|
||||
.get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
|
||||
String xml = response.getEntity(String.class);
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
InputSource is = new InputSource();
|
||||
is.setCharacterStream(new StringReader(xml));
|
||||
Document dom = db.parse(is);
|
||||
NodeList nodesApps = dom.getElementsByTagName("apps");
|
||||
assertEquals("incorrect number of elements", 1, nodesApps.getLength());
|
||||
NodeList nodes = dom.getElementsByTagName("app");
|
||||
assertEquals("incorrect number of elements", 2, nodes.getLength());
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
public void testAppsHelper(String path, RMApp app, String media)
|
||||
throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path(path).accept(media).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject apps = json.getJSONObject("apps");
|
||||
assertEquals("incorrect number of elements", 1, apps.length());
|
||||
JSONArray array = apps.getJSONArray("app");
|
||||
assertEquals("incorrect number of elements", 1, array.length());
|
||||
verifyAppInfo(array.getJSONObject(0), app);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryState() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
RMApp app1 = rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
WebResource r = resource();
|
||||
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").queryParam("state", RMAppState.ACCEPTED.toString())
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject apps = json.getJSONObject("apps");
|
||||
assertEquals("incorrect number of elements", 1, apps.length());
|
||||
JSONArray array = apps.getJSONArray("app");
|
||||
assertEquals("incorrect number of elements", 1, array.length());
|
||||
verifyAppInfo(array.getJSONObject(0), app1);
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryStateNone() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
WebResource r = resource();
|
||||
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").queryParam("state", RMAppState.RUNNING.toString())
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
assertEquals("apps is not null", JSONObject.NULL, json.get("apps"));
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryStateInvalid() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
WebResource r = resource();
|
||||
|
||||
try {
|
||||
r.path("ws").path("v1").path("cluster").path("apps")
|
||||
.queryParam("state", "INVALID_test")
|
||||
.accept(MediaType.APPLICATION_JSON).get(JSONObject.class);
|
||||
fail("should have thrown exception on invalid state query");
|
||||
} catch (UniformInterfaceException ue) {
|
||||
ClientResponse response = ue.getResponse();
|
||||
assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject msg = response.getEntity(JSONObject.class);
|
||||
JSONObject exception = msg.getJSONObject("RemoteException");
|
||||
assertEquals("incorrect number of elements", 3, exception.length());
|
||||
String message = exception.getString("message");
|
||||
String type = exception.getString("exception");
|
||||
String classname = exception.getString("javaClassName");
|
||||
WebServicesTestUtils
|
||||
.checkStringMatch(
|
||||
"exception message",
|
||||
"No enum const class org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState.INVALID_test",
|
||||
message);
|
||||
WebServicesTestUtils.checkStringMatch("exception type",
|
||||
"IllegalArgumentException", type);
|
||||
WebServicesTestUtils.checkStringMatch("exception classname",
|
||||
"java.lang.IllegalArgumentException", classname);
|
||||
|
||||
} finally {
|
||||
rm.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryUser() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r
|
||||
.path("ws")
|
||||
.path("v1")
|
||||
.path("cluster")
|
||||
.path("apps")
|
||||
.queryParam("user",
|
||||
UserGroupInformation.getCurrentUser().getShortUserName())
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject apps = json.getJSONObject("apps");
|
||||
assertEquals("incorrect number of elements", 1, apps.length());
|
||||
JSONArray array = apps.getJSONArray("app");
|
||||
assertEquals("incorrect number of elements", 2, array.length());
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryQueue() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
WebResource r = resource();
|
||||
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").queryParam("queue", "default")
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject apps = json.getJSONObject("apps");
|
||||
assertEquals("incorrect number of elements", 1, apps.length());
|
||||
JSONArray array = apps.getJSONArray("app");
|
||||
assertEquals("incorrect number of elements", 2, array.length());
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryLimit() throws JSONException, Exception {
|
||||
rm.start();
|
||||
rm.registerNode("amNM:1234", 2048);
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").queryParam("limit", "2")
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject apps = json.getJSONObject("apps");
|
||||
assertEquals("incorrect number of elements", 1, apps.length());
|
||||
JSONArray array = apps.getJSONArray("app");
|
||||
assertEquals("incorrect number of elements", 2, array.length());
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryStartBegin() throws JSONException, Exception {
|
||||
rm.start();
|
||||
long start = System.currentTimeMillis();
|
||||
Thread.sleep(1);
|
||||
rm.registerNode("amNM:1234", 2048);
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").queryParam("startedTimeBegin", String.valueOf(start))
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject apps = json.getJSONObject("apps");
|
||||
assertEquals("incorrect number of elements", 1, apps.length());
|
||||
JSONArray array = apps.getJSONArray("app");
|
||||
assertEquals("incorrect number of elements", 3, array.length());
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryStartBeginSome() throws JSONException, Exception {
|
||||
rm.start();
|
||||
rm.registerNode("amNM:1234", 2048);
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
long start = System.currentTimeMillis();
|
||||
Thread.sleep(1);
|
||||
rm.submitApp(1024);
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").queryParam("startedTimeBegin", String.valueOf(start))
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject apps = json.getJSONObject("apps");
|
||||
assertEquals("incorrect number of elements", 1, apps.length());
|
||||
JSONArray array = apps.getJSONArray("app");
|
||||
assertEquals("incorrect number of elements", 1, array.length());
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryStartEnd() throws JSONException, Exception {
|
||||
rm.start();
|
||||
rm.registerNode("amNM:1234", 2048);
|
||||
long end = System.currentTimeMillis();
|
||||
Thread.sleep(1);
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").queryParam("startedTimeEnd", String.valueOf(end))
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
assertEquals("apps is not null", JSONObject.NULL, json.get("apps"));
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryStartBeginEnd() throws JSONException, Exception {
|
||||
rm.start();
|
||||
rm.registerNode("amNM:1234", 2048);
|
||||
long start = System.currentTimeMillis();
|
||||
Thread.sleep(1);
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
long end = System.currentTimeMillis();
|
||||
Thread.sleep(1);
|
||||
rm.submitApp(1024);
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").queryParam("startedTimeBegin", String.valueOf(start))
|
||||
.queryParam("startedTimeEnd", String.valueOf(end))
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject apps = json.getJSONObject("apps");
|
||||
assertEquals("incorrect number of elements", 1, apps.length());
|
||||
JSONArray array = apps.getJSONArray("app");
|
||||
assertEquals("incorrect number of elements", 2, array.length());
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryFinishBegin() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
long start = System.currentTimeMillis();
|
||||
Thread.sleep(1);
|
||||
RMApp app1 = rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
// finish App
|
||||
MockAM am = rm
|
||||
.sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId());
|
||||
am.registerAppAttempt();
|
||||
am.unregisterAppAttempt();
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").queryParam("finishedTimeBegin", String.valueOf(start))
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject apps = json.getJSONObject("apps");
|
||||
assertEquals("incorrect number of elements", 1, apps.length());
|
||||
JSONArray array = apps.getJSONArray("app");
|
||||
assertEquals("incorrect number of elements", 1, array.length());
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryFinishEnd() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
RMApp app1 = rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
// finish App
|
||||
MockAM am = rm
|
||||
.sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId());
|
||||
am.registerAppAttempt();
|
||||
am.unregisterAppAttempt();
|
||||
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
long end = System.currentTimeMillis();
|
||||
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").queryParam("finishedTimeEnd", String.valueOf(end))
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject apps = json.getJSONObject("apps");
|
||||
assertEquals("incorrect number of elements", 1, apps.length());
|
||||
JSONArray array = apps.getJSONArray("app");
|
||||
assertEquals("incorrect number of elements", 3, array.length());
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsQueryFinishBeginEnd() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
long start = System.currentTimeMillis();
|
||||
Thread.sleep(1);
|
||||
RMApp app1 = rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
// finish App
|
||||
MockAM am = rm
|
||||
.sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId());
|
||||
am.registerAppAttempt();
|
||||
am.unregisterAppAttempt();
|
||||
|
||||
rm.submitApp(1024);
|
||||
rm.submitApp(1024);
|
||||
long end = System.currentTimeMillis();
|
||||
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").queryParam("finishedTimeBegin", String.valueOf(start))
|
||||
.queryParam("finishedTimeEnd", String.valueOf(end))
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject apps = json.getJSONObject("apps");
|
||||
assertEquals("incorrect number of elements", 1, apps.length());
|
||||
JSONArray array = apps.getJSONArray("app");
|
||||
assertEquals("incorrect number of elements", 1, array.length());
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleApp() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
RMApp app1 = rm.submitApp(1024, "testwordcount", "user1");
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
testSingleAppsHelper(app1.getApplicationId().toString(), app1,
|
||||
MediaType.APPLICATION_JSON);
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleAppsSlash() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
RMApp app1 = rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
testSingleAppsHelper(app1.getApplicationId().toString() + "/", app1,
|
||||
MediaType.APPLICATION_JSON);
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleAppsDefault() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
RMApp app1 = rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
testSingleAppsHelper(app1.getApplicationId().toString() + "/", app1, "");
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidApp() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
rm.submitApp(1024);
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
WebResource r = resource();
|
||||
|
||||
try {
|
||||
r.path("ws").path("v1").path("cluster").path("apps")
|
||||
.path("application_invalid_12").accept(MediaType.APPLICATION_JSON)
|
||||
.get(JSONObject.class);
|
||||
fail("should have thrown exception on invalid appid");
|
||||
} catch (UniformInterfaceException ue) {
|
||||
ClientResponse response = ue.getResponse();
|
||||
|
||||
assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject msg = response.getEntity(JSONObject.class);
|
||||
JSONObject exception = msg.getJSONObject("RemoteException");
|
||||
assertEquals("incorrect number of elements", 3, exception.length());
|
||||
String message = exception.getString("message");
|
||||
String type = exception.getString("exception");
|
||||
String classname = exception.getString("javaClassName");
|
||||
WebServicesTestUtils.checkStringMatch("exception message",
|
||||
"For input string: \"invalid\"", message);
|
||||
WebServicesTestUtils.checkStringMatch("exception type",
|
||||
"NumberFormatException", type);
|
||||
WebServicesTestUtils.checkStringMatch("exception classname",
|
||||
"java.lang.NumberFormatException", classname);
|
||||
|
||||
} finally {
|
||||
rm.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonexistApp() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
rm.submitApp(1024, "testwordcount", "user1");
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
WebResource r = resource();
|
||||
|
||||
try {
|
||||
r.path("ws").path("v1").path("cluster").path("apps")
|
||||
.path("application_00000_0099").accept(MediaType.APPLICATION_JSON)
|
||||
.get(JSONObject.class);
|
||||
fail("should have thrown exception on invalid appid");
|
||||
} catch (UniformInterfaceException ue) {
|
||||
ClientResponse response = ue.getResponse();
|
||||
|
||||
assertEquals(Status.NOT_FOUND, response.getClientResponseStatus());
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
|
||||
JSONObject msg = response.getEntity(JSONObject.class);
|
||||
JSONObject exception = msg.getJSONObject("RemoteException");
|
||||
assertEquals("incorrect number of elements", 3, exception.length());
|
||||
String message = exception.getString("message");
|
||||
String type = exception.getString("exception");
|
||||
String classname = exception.getString("javaClassName");
|
||||
WebServicesTestUtils.checkStringMatch("exception message",
|
||||
"java.lang.Exception: app with id: application_00000_0099 not found",
|
||||
message);
|
||||
WebServicesTestUtils.checkStringMatch("exception type",
|
||||
"NotFoundException", type);
|
||||
WebServicesTestUtils.checkStringMatch("exception classname",
|
||||
"org.apache.hadoop.yarn.webapp.NotFoundException", classname);
|
||||
} finally {
|
||||
rm.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void testSingleAppsHelper(String path, RMApp app, String media)
|
||||
throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").path(path).accept(media).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
verifyAppInfo(json.getJSONObject("app"), app);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleAppsXML() throws JSONException, Exception {
|
||||
rm.start();
|
||||
MockNM amNodeManager = rm.registerNode("amNM:1234", 2048);
|
||||
RMApp app1 = rm.submitApp(1024, "testwordcount", "user1");
|
||||
amNodeManager.nodeHeartbeat(true);
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("apps").path(app1.getApplicationId().toString())
|
||||
.accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
|
||||
String xml = response.getEntity(String.class);
|
||||
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
InputSource is = new InputSource();
|
||||
is.setCharacterStream(new StringReader(xml));
|
||||
Document dom = db.parse(is);
|
||||
NodeList nodes = dom.getElementsByTagName("app");
|
||||
assertEquals("incorrect number of elements", 1, nodes.getLength());
|
||||
verifyAppsXML(nodes, app1);
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
public void verifyAppsXML(NodeList nodes, RMApp app) throws JSONException,
|
||||
Exception {
|
||||
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Element element = (Element) nodes.item(i);
|
||||
|
||||
verifyAppInfoGeneric(app,
|
||||
WebServicesTestUtils.getXmlString(element, "id"),
|
||||
WebServicesTestUtils.getXmlString(element, "user"),
|
||||
WebServicesTestUtils.getXmlString(element, "name"),
|
||||
WebServicesTestUtils.getXmlString(element, "queue"),
|
||||
WebServicesTestUtils.getXmlString(element, "state"),
|
||||
WebServicesTestUtils.getXmlString(element, "finalStatus"),
|
||||
WebServicesTestUtils.getXmlFloat(element, "progress"),
|
||||
WebServicesTestUtils.getXmlString(element, "trackingUI"),
|
||||
WebServicesTestUtils.getXmlString(element, "diagnostics"),
|
||||
WebServicesTestUtils.getXmlLong(element, "clusterId"),
|
||||
WebServicesTestUtils.getXmlLong(element, "startedTime"),
|
||||
WebServicesTestUtils.getXmlLong(element, "finishedTime"),
|
||||
WebServicesTestUtils.getXmlLong(element, "elapsedTime"),
|
||||
WebServicesTestUtils.getXmlString(element, "amHostHttpAddress"),
|
||||
WebServicesTestUtils.getXmlString(element, "amContainerLogs"));
|
||||
}
|
||||
}
|
||||
|
||||
public void verifyAppInfo(JSONObject info, RMApp app) throws JSONException,
|
||||
Exception {
|
||||
|
||||
// 15 because trackingUrl not assigned yet
|
||||
assertEquals("incorrect number of elements", 15, info.length());
|
||||
|
||||
verifyAppInfoGeneric(app, info.getString("id"), info.getString("user"),
|
||||
info.getString("name"), info.getString("queue"),
|
||||
info.getString("state"), info.getString("finalStatus"),
|
||||
(float) info.getDouble("progress"), info.getString("trackingUI"),
|
||||
info.getString("diagnostics"), info.getLong("clusterId"),
|
||||
info.getLong("startedTime"), info.getLong("finishedTime"),
|
||||
info.getLong("elapsedTime"), info.getString("amHostHttpAddress"),
|
||||
info.getString("amContainerLogs"));
|
||||
}
|
||||
|
||||
public void verifyAppInfoGeneric(RMApp app, String id, String user,
|
||||
String name, String queue, String state, String finalStatus,
|
||||
float progress, String trackingUI, String diagnostics, long clusterId,
|
||||
long startedTime, long finishedTime, long elapsedTime,
|
||||
String amHostHttpAddress, String amContainerLogs) throws JSONException,
|
||||
Exception {
|
||||
|
||||
WebServicesTestUtils.checkStringMatch("id", app.getApplicationId()
|
||||
.toString(), id);
|
||||
WebServicesTestUtils.checkStringMatch("user", app.getUser(), user);
|
||||
WebServicesTestUtils.checkStringMatch("name", app.getName(), name);
|
||||
WebServicesTestUtils.checkStringMatch("queue", app.getQueue(), queue);
|
||||
WebServicesTestUtils.checkStringMatch("state", app.getState().toString(),
|
||||
state);
|
||||
WebServicesTestUtils.checkStringMatch("finalStatus", app
|
||||
.getFinalApplicationStatus().toString(), finalStatus);
|
||||
assertEquals("progress doesn't match", 0, progress, 0.0);
|
||||
WebServicesTestUtils.checkStringMatch("trackingUI", "UNASSIGNED",
|
||||
trackingUI);
|
||||
WebServicesTestUtils.checkStringMatch("diagnostics", app.getDiagnostics()
|
||||
.toString(), diagnostics);
|
||||
assertEquals("clusterId doesn't match", ResourceManager.clusterTimeStamp,
|
||||
clusterId);
|
||||
assertEquals("startedTime doesn't match", app.getStartTime(), startedTime);
|
||||
assertEquals("finishedTime doesn't match", app.getFinishTime(),
|
||||
finishedTime);
|
||||
assertTrue("elapsed time not greater than 0", elapsedTime > 0);
|
||||
WebServicesTestUtils.checkStringMatch("amHostHttpAddress", app
|
||||
.getCurrentAppAttempt().getMasterContainer().getNodeHttpAddress(),
|
||||
amHostHttpAddress);
|
||||
assertTrue("amContainerLogs doesn't match",
|
||||
amContainerLogs.startsWith("http://"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,316 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration;
|
||||
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
|
||||
import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
|
||||
import org.apache.hadoop.yarn.webapp.WebServicesTestUtils;
|
||||
import org.codehaus.jettison.json.JSONArray;
|
||||
import org.codehaus.jettison.json.JSONException;
|
||||
import org.codehaus.jettison.json.JSONObject;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.servlet.GuiceServletContextListener;
|
||||
import com.google.inject.servlet.ServletModule;
|
||||
import com.sun.jersey.api.client.ClientResponse;
|
||||
import com.sun.jersey.api.client.WebResource;
|
||||
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
|
||||
import com.sun.jersey.test.framework.JerseyTest;
|
||||
import com.sun.jersey.test.framework.WebAppDescriptor;
|
||||
|
||||
public class TestRMWebServicesCapacitySched extends JerseyTest {
|
||||
|
||||
private static MockRM rm;
|
||||
private CapacitySchedulerConfiguration csConf;
|
||||
|
||||
private Injector injector = Guice.createInjector(new ServletModule() {
|
||||
@Override
|
||||
protected void configureServlets() {
|
||||
bind(JAXBContextResolver.class);
|
||||
bind(RMWebServices.class);
|
||||
bind(GenericExceptionHandler.class);
|
||||
csConf = new CapacitySchedulerConfiguration();
|
||||
csConf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class,
|
||||
ResourceScheduler.class);
|
||||
setupQueueConfiguration(csConf);
|
||||
rm = new MockRM(csConf);
|
||||
bind(ResourceManager.class).toInstance(rm);
|
||||
bind(RMContext.class).toInstance(rm.getRMContext());
|
||||
bind(ApplicationACLsManager.class).toInstance(
|
||||
rm.getApplicationACLsManager());
|
||||
serve("/*").with(GuiceContainer.class);
|
||||
}
|
||||
});
|
||||
|
||||
public class GuiceServletConfig extends GuiceServletContextListener {
|
||||
|
||||
@Override
|
||||
protected Injector getInjector() {
|
||||
return injector;
|
||||
}
|
||||
}
|
||||
|
||||
private static void setupQueueConfiguration(
|
||||
CapacitySchedulerConfiguration conf) {
|
||||
|
||||
// Define top-level queues
|
||||
conf.setQueues(CapacityScheduler.ROOT, new String[] { "a", "b" });
|
||||
conf.setCapacity(CapacityScheduler.ROOT, 100);
|
||||
|
||||
final String A = CapacityScheduler.ROOT + ".a";
|
||||
conf.setCapacity(A, 10);
|
||||
conf.setMaximumCapacity(A, 50);
|
||||
|
||||
final String B = CapacityScheduler.ROOT + ".b";
|
||||
conf.setCapacity(B, 90);
|
||||
|
||||
// Define 2nd-level queues
|
||||
final String A1 = A + ".a1";
|
||||
final String A2 = A + ".a2";
|
||||
conf.setQueues(A, new String[] { "a1", "a2" });
|
||||
conf.setCapacity(A1, 30);
|
||||
conf.setMaximumCapacity(A1, 50);
|
||||
|
||||
conf.setUserLimitFactor(A1, 100.0f);
|
||||
conf.setCapacity(A2, 70);
|
||||
conf.setUserLimitFactor(A2, 100.0f);
|
||||
|
||||
final String B1 = B + ".b1";
|
||||
final String B2 = B + ".b2";
|
||||
final String B3 = B + ".b3";
|
||||
conf.setQueues(B, new String[] { "b1", "b2", "b3" });
|
||||
conf.setCapacity(B1, 50);
|
||||
conf.setUserLimitFactor(B1, 100.0f);
|
||||
conf.setCapacity(B2, 30);
|
||||
conf.setUserLimitFactor(B2, 100.0f);
|
||||
conf.setCapacity(B3, 20);
|
||||
conf.setUserLimitFactor(B3, 100.0f);
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public TestRMWebServicesCapacitySched() {
|
||||
super(new WebAppDescriptor.Builder(
|
||||
"org.apache.hadoop.yarn.server.resourcemanager.webapp")
|
||||
.contextListenerClass(GuiceServletConfig.class)
|
||||
.filterClass(com.google.inject.servlet.GuiceFilter.class)
|
||||
.contextPath("jersey-guice-filter").servletPath("/").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterScheduler() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("scheduler").accept(MediaType.APPLICATION_JSON)
|
||||
.get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
verifyClusterScheduler(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterSchedulerSlash() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("scheduler/").accept(MediaType.APPLICATION_JSON)
|
||||
.get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
verifyClusterScheduler(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterSchedulerDefault() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("scheduler").get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
verifyClusterScheduler(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterSchedulerXML() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("scheduler/").accept(MediaType.APPLICATION_XML)
|
||||
.get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
|
||||
String xml = response.getEntity(String.class);
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
InputSource is = new InputSource();
|
||||
is.setCharacterStream(new StringReader(xml));
|
||||
Document dom = db.parse(is);
|
||||
NodeList scheduler = dom.getElementsByTagName("scheduler");
|
||||
assertEquals("incorrect number of elements", 1, scheduler.getLength());
|
||||
NodeList schedulerInfo = dom.getElementsByTagName("schedulerInfo");
|
||||
assertEquals("incorrect number of elements", 1, schedulerInfo.getLength());
|
||||
verifyClusterSchedulerXML(schedulerInfo);
|
||||
}
|
||||
|
||||
public void verifyClusterSchedulerXML(NodeList nodes) throws Exception {
|
||||
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Element element = (Element) nodes.item(i);
|
||||
|
||||
verifyClusterSchedulerGeneric(
|
||||
WebServicesTestUtils.getXmlAttrString(element, "xsi:type"),
|
||||
WebServicesTestUtils.getXmlFloat(element, "usedCapacity"),
|
||||
WebServicesTestUtils.getXmlFloat(element, "capacity"),
|
||||
WebServicesTestUtils.getXmlFloat(element, "maxCapacity"),
|
||||
WebServicesTestUtils.getXmlString(element, "queueName"));
|
||||
|
||||
NodeList queues = element.getElementsByTagName("queues");
|
||||
for (int j = 0; j < queues.getLength(); j++) {
|
||||
Element qElem = (Element) queues.item(j);
|
||||
String qName = WebServicesTestUtils.getXmlString(qElem, "queueName");
|
||||
String q = CapacityScheduler.ROOT + "." + qName;
|
||||
verifySubQueueXML(qElem, q);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void verifySubQueueXML(Element qElem, String q) throws Exception {
|
||||
|
||||
verifySubQueueGeneric(q,
|
||||
WebServicesTestUtils.getXmlFloat(qElem, "usedCapacity"),
|
||||
WebServicesTestUtils.getXmlFloat(qElem, "capacity"),
|
||||
WebServicesTestUtils.getXmlFloat(qElem, "maxCapacity"),
|
||||
WebServicesTestUtils.getXmlString(qElem, "queueName"),
|
||||
WebServicesTestUtils.getXmlString(qElem, "state"));
|
||||
|
||||
NodeList queues = qElem.getElementsByTagName("subQueues");
|
||||
if (queues != null) {
|
||||
for (int j = 0; j < queues.getLength(); j++) {
|
||||
Element subqElem = (Element) queues.item(j);
|
||||
String qName = WebServicesTestUtils.getXmlString(subqElem, "queueName");
|
||||
String q2 = q + "." + qName;
|
||||
verifySubQueueXML(subqElem, q2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyClusterScheduler(JSONObject json) throws JSONException,
|
||||
Exception {
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject info = json.getJSONObject("scheduler");
|
||||
assertEquals("incorrect number of elements", 1, info.length());
|
||||
info = info.getJSONObject("schedulerInfo");
|
||||
assertEquals("incorrect number of elements", 6, info.length());
|
||||
verifyClusterSchedulerGeneric(info.getString("type"),
|
||||
(float) info.getDouble("usedCapacity"),
|
||||
(float) info.getDouble("capacity"),
|
||||
(float) info.getDouble("maxCapacity"), info.getString("queueName"));
|
||||
|
||||
JSONArray arr = info.getJSONArray("queues");
|
||||
assertEquals("incorrect number of elements", 2, arr.length());
|
||||
|
||||
// test subqueues
|
||||
for (int i = 0; i < arr.length(); i++) {
|
||||
JSONObject obj = arr.getJSONObject(i);
|
||||
String q = CapacityScheduler.ROOT + "." + obj.getString("queueName");
|
||||
verifySubQueue(obj, q);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyClusterSchedulerGeneric(String type, float usedCapacity,
|
||||
float capacity, float maxCapacity, String queueName) throws Exception {
|
||||
|
||||
assertTrue("type doesn't match", "capacityScheduler".matches(type));
|
||||
assertEquals("usedCapacity doesn't match", 0, usedCapacity, 1e-3f);
|
||||
assertEquals("capacity doesn't match", 100, capacity, 1e-3f);
|
||||
assertEquals("maxCapacity doesn't match", 100, maxCapacity, 1e-3f);
|
||||
assertTrue("queueName doesn't match", "root".matches(queueName));
|
||||
}
|
||||
|
||||
private void verifySubQueue(JSONObject info, String q) throws JSONException,
|
||||
Exception {
|
||||
if (info.has("subQueues")) {
|
||||
assertEquals("incorrect number of elements", 6, info.length());
|
||||
} else {
|
||||
assertEquals("incorrect number of elements", 5, info.length());
|
||||
}
|
||||
verifySubQueueGeneric(q, (float) info.getDouble("usedCapacity"),
|
||||
(float) info.getDouble("capacity"),
|
||||
(float) info.getDouble("maxCapacity"), info.getString("queueName"),
|
||||
info.getString("state"));
|
||||
|
||||
if (info.has("subQueues")) {
|
||||
JSONArray arr = info.getJSONArray("subQueues");
|
||||
// test subqueues
|
||||
for (int i = 0; i < arr.length(); i++) {
|
||||
JSONObject obj = arr.getJSONObject(i);
|
||||
String q2 = q + "." + obj.getString("queueName");
|
||||
verifySubQueue(obj, q2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verifySubQueueGeneric(String q, float usedCapacity,
|
||||
float capacity, float maxCapacity, String qname, String state)
|
||||
throws Exception {
|
||||
String[] qArr = q.split("\\.");
|
||||
assertTrue("q name invalid: " + q, qArr.length > 1);
|
||||
String qshortName = qArr[qArr.length - 1];
|
||||
|
||||
assertEquals("usedCapacity doesn't match", 0, usedCapacity, 1e-3f);
|
||||
assertEquals("capacity doesn't match", csConf.getCapacity(q), capacity,
|
||||
1e-3f);
|
||||
float expectCapacity = csConf.getMaximumCapacity(q);
|
||||
if (CapacitySchedulerConfiguration.UNDEFINED == expectCapacity) {
|
||||
expectCapacity = 100;
|
||||
}
|
||||
assertEquals("maxCapacity doesn't match", expectCapacity, maxCapacity,
|
||||
1e-3f);
|
||||
assertTrue("queueName doesn't match, got: " + qname + " expected: " + q,
|
||||
qshortName.matches(qname));
|
||||
assertTrue("state doesn't match",
|
||||
(csConf.getState(q).toString()).matches(state));
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,601 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.yarn.api.records.ContainerStatus;
|
||||
import org.apache.hadoop.yarn.api.records.NodeHealthStatus;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.MockNM;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeImpl;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeState;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeStatusEvent;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerNodeReport;
|
||||
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
|
||||
import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
|
||||
import org.apache.hadoop.yarn.webapp.WebServicesTestUtils;
|
||||
import org.codehaus.jettison.json.JSONArray;
|
||||
import org.codehaus.jettison.json.JSONException;
|
||||
import org.codehaus.jettison.json.JSONObject;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.servlet.GuiceServletContextListener;
|
||||
import com.google.inject.servlet.ServletModule;
|
||||
import com.sun.jersey.api.client.ClientResponse;
|
||||
import com.sun.jersey.api.client.ClientResponse.Status;
|
||||
import com.sun.jersey.api.client.UniformInterfaceException;
|
||||
import com.sun.jersey.api.client.WebResource;
|
||||
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
|
||||
import com.sun.jersey.test.framework.JerseyTest;
|
||||
import com.sun.jersey.test.framework.WebAppDescriptor;
|
||||
|
||||
public class TestRMWebServicesNodes extends JerseyTest {
|
||||
|
||||
private static MockRM rm;
|
||||
|
||||
private Injector injector = Guice.createInjector(new ServletModule() {
|
||||
@Override
|
||||
protected void configureServlets() {
|
||||
bind(JAXBContextResolver.class);
|
||||
bind(RMWebServices.class);
|
||||
bind(GenericExceptionHandler.class);
|
||||
rm = new MockRM(new Configuration());
|
||||
bind(ResourceManager.class).toInstance(rm);
|
||||
bind(RMContext.class).toInstance(rm.getRMContext());
|
||||
bind(ApplicationACLsManager.class).toInstance(
|
||||
rm.getApplicationACLsManager());
|
||||
serve("/*").with(GuiceContainer.class);
|
||||
}
|
||||
});
|
||||
|
||||
public class GuiceServletConfig extends GuiceServletContextListener {
|
||||
|
||||
@Override
|
||||
protected Injector getInjector() {
|
||||
return injector;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public TestRMWebServicesNodes() {
|
||||
super(new WebAppDescriptor.Builder(
|
||||
"org.apache.hadoop.yarn.server.resourcemanager.webapp")
|
||||
.contextListenerClass(GuiceServletConfig.class)
|
||||
.filterClass(com.google.inject.servlet.GuiceFilter.class)
|
||||
.contextPath("jersey-guice-filter").servletPath("/").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodes() throws JSONException, Exception {
|
||||
testNodesHelper("nodes", MediaType.APPLICATION_JSON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesSlash() throws JSONException, Exception {
|
||||
testNodesHelper("nodes/", MediaType.APPLICATION_JSON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesDefault() throws JSONException, Exception {
|
||||
testNodesHelper("nodes/", "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesQueryState() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
MockNM nm1 = rm.registerNode("h1:1234", 5120);
|
||||
MockNM nm2 = rm.registerNode("h2:1235", 5121);
|
||||
rm.sendNodeStarted(nm1);
|
||||
rm.NMwaitForState(nm1.getNodeId(), RMNodeState.RUNNING);
|
||||
rm.NMwaitForState(nm2.getNodeId(), RMNodeState.NEW);
|
||||
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("nodes").queryParam("state", RMNodeState.RUNNING.toString())
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject nodes = json.getJSONObject("nodes");
|
||||
assertEquals("incorrect number of elements", 1, nodes.length());
|
||||
JSONArray nodeArray = nodes.getJSONArray("node");
|
||||
assertEquals("incorrect number of elements", 1, nodeArray.length());
|
||||
JSONObject info = nodeArray.getJSONObject(0);
|
||||
|
||||
verifyNodeInfo(info, nm1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesQueryStateNone() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
rm.registerNode("h1:1234", 5120);
|
||||
rm.registerNode("h2:1235", 5121);
|
||||
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("nodes")
|
||||
.queryParam("state", RMNodeState.DECOMMISSIONED.toString())
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
assertEquals("nodes is not null", JSONObject.NULL, json.get("nodes"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesQueryStateInvalid() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
rm.registerNode("h1:1234", 5120);
|
||||
rm.registerNode("h2:1235", 5121);
|
||||
|
||||
try {
|
||||
r.path("ws").path("v1").path("cluster").path("nodes")
|
||||
.queryParam("state", "BOGUSSTATE").accept(MediaType.APPLICATION_JSON)
|
||||
.get(JSONObject.class);
|
||||
|
||||
fail("should have thrown exception querying invalid state");
|
||||
} catch (UniformInterfaceException ue) {
|
||||
ClientResponse response = ue.getResponse();
|
||||
|
||||
assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
|
||||
JSONObject msg = response.getEntity(JSONObject.class);
|
||||
JSONObject exception = msg.getJSONObject("RemoteException");
|
||||
assertEquals("incorrect number of elements", 3, exception.length());
|
||||
String message = exception.getString("message");
|
||||
String type = exception.getString("exception");
|
||||
String classname = exception.getString("javaClassName");
|
||||
WebServicesTestUtils
|
||||
.checkStringMatch(
|
||||
"exception message",
|
||||
"No enum const class org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeState.BOGUSSTATE",
|
||||
message);
|
||||
WebServicesTestUtils.checkStringMatch("exception type",
|
||||
"IllegalArgumentException", type);
|
||||
WebServicesTestUtils.checkStringMatch("exception classname",
|
||||
"java.lang.IllegalArgumentException", classname);
|
||||
|
||||
} finally {
|
||||
rm.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesQueryHealthy() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
MockNM nm1 = rm.registerNode("h1:1234", 5120);
|
||||
MockNM nm2 = rm.registerNode("h2:1235", 5121);
|
||||
rm.sendNodeStarted(nm1);
|
||||
rm.NMwaitForState(nm1.getNodeId(), RMNodeState.RUNNING);
|
||||
rm.NMwaitForState(nm2.getNodeId(), RMNodeState.NEW);
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("nodes").queryParam("healthy", "true")
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject nodes = json.getJSONObject("nodes");
|
||||
assertEquals("incorrect number of elements", 1, nodes.length());
|
||||
JSONArray nodeArray = nodes.getJSONArray("node");
|
||||
assertEquals("incorrect number of elements", 2, nodeArray.length());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesQueryHealthyCase() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
MockNM nm1 = rm.registerNode("h1:1234", 5120);
|
||||
MockNM nm2 = rm.registerNode("h2:1235", 5121);
|
||||
rm.sendNodeStarted(nm1);
|
||||
rm.NMwaitForState(nm1.getNodeId(), RMNodeState.RUNNING);
|
||||
rm.NMwaitForState(nm2.getNodeId(), RMNodeState.NEW);
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("nodes").queryParam("healthy", "TRUe")
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject nodes = json.getJSONObject("nodes");
|
||||
assertEquals("incorrect number of elements", 1, nodes.length());
|
||||
JSONArray nodeArray = nodes.getJSONArray("node");
|
||||
assertEquals("incorrect number of elements", 2, nodeArray.length());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesQueryHealthyAndState() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
MockNM nm1 = rm.registerNode("h1:1234", 5120);
|
||||
MockNM nm2 = rm.registerNode("h2:1235", 5121);
|
||||
rm.sendNodeStarted(nm1);
|
||||
rm.NMwaitForState(nm2.getNodeId(), RMNodeState.NEW);
|
||||
rm.NMwaitForState(nm1.getNodeId(), RMNodeState.RUNNING);
|
||||
RMNodeImpl node = (RMNodeImpl) rm.getRMContext().getRMNodes()
|
||||
.get(nm1.getNodeId());
|
||||
NodeHealthStatus nodeHealth = node.getNodeHealthStatus();
|
||||
nodeHealth.setHealthReport("test health report");
|
||||
nodeHealth.setIsNodeHealthy(false);
|
||||
node.handle(new RMNodeStatusEvent(nm1.getNodeId(), nodeHealth,
|
||||
new ArrayList<ContainerStatus>(), null, null));
|
||||
rm.NMwaitForState(nm1.getNodeId(), RMNodeState.UNHEALTHY);
|
||||
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("nodes").queryParam("healthy", "true")
|
||||
.queryParam("state", RMNodeState.RUNNING.toString())
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
assertEquals("nodes is not null", JSONObject.NULL, json.get("nodes"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesQueryHealthyFalse() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
MockNM nm1 = rm.registerNode("h1:1234", 5120);
|
||||
MockNM nm2 = rm.registerNode("h2:1235", 5121);
|
||||
rm.sendNodeStarted(nm1);
|
||||
rm.NMwaitForState(nm1.getNodeId(), RMNodeState.RUNNING);
|
||||
rm.NMwaitForState(nm2.getNodeId(), RMNodeState.NEW);
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("nodes").queryParam("healthy", "false")
|
||||
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
assertEquals("nodes is not null", JSONObject.NULL, json.get("nodes"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesQueryHealthyInvalid() throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
rm.registerNode("h1:1234", 5120);
|
||||
rm.registerNode("h2:1235", 5121);
|
||||
|
||||
try {
|
||||
r.path("ws").path("v1").path("cluster").path("nodes")
|
||||
.queryParam("healthy", "tr").accept(MediaType.APPLICATION_JSON)
|
||||
.get(JSONObject.class);
|
||||
fail("should have thrown exception querying invalid healthy string");
|
||||
} catch (UniformInterfaceException ue) {
|
||||
ClientResponse response = ue.getResponse();
|
||||
assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject msg = response.getEntity(JSONObject.class);
|
||||
JSONObject exception = msg.getJSONObject("RemoteException");
|
||||
assertEquals("incorrect number of elements", 3, exception.length());
|
||||
String message = exception.getString("message");
|
||||
String type = exception.getString("exception");
|
||||
String classname = exception.getString("javaClassName");
|
||||
WebServicesTestUtils
|
||||
.checkStringMatch(
|
||||
"exception message",
|
||||
"java.lang.Exception: Error: You must specify either true or false to query on health",
|
||||
message);
|
||||
WebServicesTestUtils.checkStringMatch("exception type",
|
||||
"BadRequestException", type);
|
||||
WebServicesTestUtils.checkStringMatch("exception classname",
|
||||
"org.apache.hadoop.yarn.webapp.BadRequestException", classname);
|
||||
|
||||
} finally {
|
||||
rm.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void testNodesHelper(String path, String media) throws JSONException,
|
||||
Exception {
|
||||
WebResource r = resource();
|
||||
MockNM nm1 = rm.registerNode("h1:1234", 5120);
|
||||
MockNM nm2 = rm.registerNode("h2:1235", 5121);
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path(path).accept(media).get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject nodes = json.getJSONObject("nodes");
|
||||
assertEquals("incorrect number of elements", 1, nodes.length());
|
||||
JSONArray nodeArray = nodes.getJSONArray("node");
|
||||
assertEquals("incorrect number of elements", 2, nodeArray.length());
|
||||
JSONObject info = nodeArray.getJSONObject(0);
|
||||
String id = info.get("id").toString();
|
||||
|
||||
if (id.matches("h1:1234")) {
|
||||
verifyNodeInfo(info, nm1);
|
||||
verifyNodeInfo(nodeArray.getJSONObject(1), nm2);
|
||||
} else {
|
||||
verifyNodeInfo(info, nm2);
|
||||
verifyNodeInfo(nodeArray.getJSONObject(1), nm1);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleNode() throws JSONException, Exception {
|
||||
rm.registerNode("h1:1234", 5120);
|
||||
MockNM nm2 = rm.registerNode("h2:1235", 5121);
|
||||
testSingleNodeHelper("h2:1235", nm2, MediaType.APPLICATION_JSON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleNodeSlash() throws JSONException, Exception {
|
||||
MockNM nm1 = rm.registerNode("h1:1234", 5120);
|
||||
rm.registerNode("h2:1235", 5121);
|
||||
testSingleNodeHelper("h1:1234/", nm1, MediaType.APPLICATION_JSON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleNodeDefault() throws JSONException, Exception {
|
||||
MockNM nm1 = rm.registerNode("h1:1234", 5120);
|
||||
rm.registerNode("h2:1235", 5121);
|
||||
testSingleNodeHelper("h1:1234/", nm1, "");
|
||||
}
|
||||
|
||||
public void testSingleNodeHelper(String nodeid, MockNM nm, String media)
|
||||
throws JSONException, Exception {
|
||||
WebResource r = resource();
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("nodes").path(nodeid).accept(media).get(ClientResponse.class);
|
||||
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
assertEquals("incorrect number of elements", 1, json.length());
|
||||
JSONObject info = json.getJSONObject("node");
|
||||
verifyNodeInfo(info, nm);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonexistNode() throws JSONException, Exception {
|
||||
rm.registerNode("h1:1234", 5120);
|
||||
rm.registerNode("h2:1235", 5121);
|
||||
WebResource r = resource();
|
||||
try {
|
||||
r.path("ws").path("v1").path("cluster").path("nodes")
|
||||
.path("node_invalid:99").accept(MediaType.APPLICATION_JSON)
|
||||
.get(JSONObject.class);
|
||||
|
||||
fail("should have thrown exception on non-existent nodeid");
|
||||
} catch (UniformInterfaceException ue) {
|
||||
ClientResponse response = ue.getResponse();
|
||||
assertEquals(Status.NOT_FOUND, response.getClientResponseStatus());
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject msg = response.getEntity(JSONObject.class);
|
||||
JSONObject exception = msg.getJSONObject("RemoteException");
|
||||
assertEquals("incorrect number of elements", 3, exception.length());
|
||||
String message = exception.getString("message");
|
||||
String type = exception.getString("exception");
|
||||
String classname = exception.getString("javaClassName");
|
||||
WebServicesTestUtils
|
||||
.checkStringMatch("exception message",
|
||||
"java.lang.Exception: nodeId, node_invalid:99, is not found",
|
||||
message);
|
||||
WebServicesTestUtils.checkStringMatch("exception type",
|
||||
"NotFoundException", type);
|
||||
WebServicesTestUtils.checkStringMatch("exception classname",
|
||||
"org.apache.hadoop.yarn.webapp.NotFoundException", classname);
|
||||
|
||||
} finally {
|
||||
rm.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidNode() throws JSONException, Exception {
|
||||
rm.registerNode("h1:1234", 5120);
|
||||
rm.registerNode("h2:1235", 5121);
|
||||
|
||||
WebResource r = resource();
|
||||
try {
|
||||
r.path("ws").path("v1").path("cluster").path("nodes")
|
||||
.path("node_invalid_foo").accept(MediaType.APPLICATION_JSON)
|
||||
.get(JSONObject.class);
|
||||
|
||||
fail("should have thrown exception on non-existent nodeid");
|
||||
} catch (UniformInterfaceException ue) {
|
||||
ClientResponse response = ue.getResponse();
|
||||
|
||||
assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
|
||||
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
|
||||
JSONObject msg = response.getEntity(JSONObject.class);
|
||||
JSONObject exception = msg.getJSONObject("RemoteException");
|
||||
assertEquals("incorrect number of elements", 3, exception.length());
|
||||
String message = exception.getString("message");
|
||||
String type = exception.getString("exception");
|
||||
String classname = exception.getString("javaClassName");
|
||||
WebServicesTestUtils.checkStringMatch("exception message",
|
||||
"Invalid NodeId \\[node_invalid_foo\\]. Expected host:port", message);
|
||||
WebServicesTestUtils.checkStringMatch("exception type",
|
||||
"IllegalArgumentException", type);
|
||||
WebServicesTestUtils.checkStringMatch("exception classname",
|
||||
"java.lang.IllegalArgumentException", classname);
|
||||
} finally {
|
||||
rm.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesXML() throws JSONException, Exception {
|
||||
rm.start();
|
||||
WebResource r = resource();
|
||||
MockNM nm1 = rm.registerNode("h1:1234", 5120);
|
||||
// MockNM nm2 = rm.registerNode("h2:1235", 5121);
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("nodes").accept(MediaType.APPLICATION_XML)
|
||||
.get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
|
||||
String xml = response.getEntity(String.class);
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
InputSource is = new InputSource();
|
||||
is.setCharacterStream(new StringReader(xml));
|
||||
Document dom = db.parse(is);
|
||||
NodeList nodesApps = dom.getElementsByTagName("nodes");
|
||||
assertEquals("incorrect number of elements", 1, nodesApps.getLength());
|
||||
NodeList nodes = dom.getElementsByTagName("node");
|
||||
assertEquals("incorrect number of elements", 1, nodes.getLength());
|
||||
verifyNodesXML(nodes, nm1);
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleNodesXML() throws JSONException, Exception {
|
||||
rm.start();
|
||||
WebResource r = resource();
|
||||
MockNM nm1 = rm.registerNode("h1:1234", 5120);
|
||||
// MockNM nm2 = rm.registerNode("h2:1235", 5121);
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("nodes").path("h1:1234").accept(MediaType.APPLICATION_XML)
|
||||
.get(ClientResponse.class);
|
||||
|
||||
assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
|
||||
String xml = response.getEntity(String.class);
|
||||
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
InputSource is = new InputSource();
|
||||
is.setCharacterStream(new StringReader(xml));
|
||||
Document dom = db.parse(is);
|
||||
NodeList nodes = dom.getElementsByTagName("node");
|
||||
assertEquals("incorrect number of elements", 1, nodes.getLength());
|
||||
verifyNodesXML(nodes, nm1);
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodes2XML() throws JSONException, Exception {
|
||||
rm.start();
|
||||
WebResource r = resource();
|
||||
rm.registerNode("h1:1234", 5120);
|
||||
rm.registerNode("h2:1235", 5121);
|
||||
ClientResponse response = r.path("ws").path("v1").path("cluster")
|
||||
.path("nodes").accept(MediaType.APPLICATION_XML)
|
||||
.get(ClientResponse.class);
|
||||
assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
|
||||
String xml = response.getEntity(String.class);
|
||||
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
InputSource is = new InputSource();
|
||||
is.setCharacterStream(new StringReader(xml));
|
||||
Document dom = db.parse(is);
|
||||
NodeList nodesApps = dom.getElementsByTagName("nodes");
|
||||
assertEquals("incorrect number of elements", 1, nodesApps.getLength());
|
||||
NodeList nodes = dom.getElementsByTagName("node");
|
||||
assertEquals("incorrect number of elements", 2, nodes.getLength());
|
||||
rm.stop();
|
||||
}
|
||||
|
||||
public void verifyNodesXML(NodeList nodes, MockNM nm) throws JSONException,
|
||||
Exception {
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Element element = (Element) nodes.item(i);
|
||||
verifyNodeInfoGeneric(nm,
|
||||
WebServicesTestUtils.getXmlString(element, "state"),
|
||||
WebServicesTestUtils.getXmlString(element, "rack"),
|
||||
WebServicesTestUtils.getXmlString(element, "healthStatus"),
|
||||
WebServicesTestUtils.getXmlString(element, "id"),
|
||||
WebServicesTestUtils.getXmlString(element, "nodeHostName"),
|
||||
WebServicesTestUtils.getXmlString(element, "nodeHTTPAddress"),
|
||||
WebServicesTestUtils.getXmlLong(element, "lastHealthUpdate"),
|
||||
WebServicesTestUtils.getXmlString(element, "healthReport"),
|
||||
WebServicesTestUtils.getXmlInt(element, "numContainers"),
|
||||
WebServicesTestUtils.getXmlLong(element, "usedMemoryMB"),
|
||||
WebServicesTestUtils.getXmlLong(element, "availMemoryMB"));
|
||||
}
|
||||
}
|
||||
|
||||
public void verifyNodeInfo(JSONObject nodeInfo, MockNM nm)
|
||||
throws JSONException, Exception {
|
||||
assertEquals("incorrect number of elements", 11, nodeInfo.length());
|
||||
|
||||
verifyNodeInfoGeneric(nm, nodeInfo.getString("state"),
|
||||
nodeInfo.getString("rack"), nodeInfo.getString("healthStatus"),
|
||||
nodeInfo.getString("id"), nodeInfo.getString("nodeHostName"),
|
||||
nodeInfo.getString("nodeHTTPAddress"),
|
||||
nodeInfo.getLong("lastHealthUpdate"),
|
||||
nodeInfo.getString("healthReport"), nodeInfo.getInt("numContainers"),
|
||||
nodeInfo.getLong("usedMemoryMB"), nodeInfo.getLong("availMemoryMB"));
|
||||
|
||||
}
|
||||
|
||||
public void verifyNodeInfoGeneric(MockNM nm, String state, String rack,
|
||||
String healthStatus, String id, String nodeHostName,
|
||||
String nodeHTTPAddress, long lastHealthUpdate, String healthReport,
|
||||
int numContainers, long usedMemoryMB, long availMemoryMB)
|
||||
throws JSONException, Exception {
|
||||
|
||||
RMNode node = rm.getRMContext().getRMNodes().get(nm.getNodeId());
|
||||
NodeHealthStatus health = node.getNodeHealthStatus();
|
||||
ResourceScheduler sched = rm.getResourceScheduler();
|
||||
SchedulerNodeReport report = sched.getNodeReport(nm.getNodeId());
|
||||
|
||||
WebServicesTestUtils.checkStringMatch("state", node.getState().toString(),
|
||||
state);
|
||||
WebServicesTestUtils.checkStringMatch("rack", node.getRackName(), rack);
|
||||
WebServicesTestUtils.checkStringMatch("healthStatus", "Healthy",
|
||||
healthStatus);
|
||||
WebServicesTestUtils.checkStringMatch("id", nm.getNodeId().toString(), id);
|
||||
WebServicesTestUtils.checkStringMatch("nodeHostName", nm.getNodeId()
|
||||
.getHost(), nodeHostName);
|
||||
WebServicesTestUtils.checkStringMatch("healthReport",
|
||||
String.valueOf(health.getHealthReport()), healthReport);
|
||||
String expectedHttpAddress = nm.getNodeId().getHost() + ":"
|
||||
+ nm.getHttpPort();
|
||||
WebServicesTestUtils.checkStringMatch("nodeHTTPAddress",
|
||||
expectedHttpAddress, nodeHTTPAddress);
|
||||
|
||||
long expectedHealthUpdate = health.getLastHealthReportTime();
|
||||
assertEquals("lastHealthUpdate doesn't match, got: " + lastHealthUpdate
|
||||
+ " expected: " + expectedHealthUpdate, expectedHealthUpdate,
|
||||
lastHealthUpdate);
|
||||
|
||||
if (report != null) {
|
||||
assertEquals("numContainers doesn't match: " + numContainers,
|
||||
report.getNumContainers(), numContainers);
|
||||
assertEquals("usedMemoryMB doesn't match: " + usedMemoryMB, report
|
||||
.getUsedResource().getMemory(), usedMemoryMB);
|
||||
assertEquals("availMemoryMB doesn't match: " + availMemoryMB, report
|
||||
.getAvailableResource().getMemory(), availMemoryMB);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -255,6 +255,13 @@ void parseArgv() {
|
||||
}
|
||||
|
||||
if (cmdLine != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> args = cmdLine.getArgList();
|
||||
if(args != null && args.size() > 0) {
|
||||
fail("Found " + args.size() + " unexpected arguments on the " +
|
||||
"command line " + args);
|
||||
}
|
||||
|
||||
detailedUsage_ = cmdLine.hasOption("info");
|
||||
if (cmdLine.hasOption("help") || detailedUsage_) {
|
||||
printUsage = true;
|
||||
|
@ -18,16 +18,19 @@
|
||||
|
||||
package org.apache.hadoop.streaming;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.fs.Path;
|
||||
import org.apache.hadoop.fs.FileSystem;
|
||||
import org.apache.hadoop.fs.FSDataInputStream;
|
||||
import org.apache.hadoop.fs.FileSystem;
|
||||
import org.apache.hadoop.fs.Path;
|
||||
import org.apache.hadoop.mapred.JobConf;
|
||||
import org.apache.hadoop.mapreduce.server.jobtracker.JTConfig;
|
||||
import org.apache.hadoop.mapreduce.MRConfig;
|
||||
|
||||
/**
|
||||
* Utilities used in streaming
|
||||
@ -189,6 +192,8 @@ static Environment env() {
|
||||
}
|
||||
|
||||
public static boolean isLocalJobTracker(JobConf job) {
|
||||
return job.get(JTConfig.JT_IPC_ADDRESS, "local").equals("local");
|
||||
String framework =
|
||||
job.get(MRConfig.FRAMEWORK_NAME, MRConfig.LOCAL_FRAMEWORK_NAME);
|
||||
return framework.equals(MRConfig.LOCAL_FRAMEWORK_NAME);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* 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.streaming;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.apache.hadoop.mapred.JobConf;
|
||||
import org.apache.hadoop.mapreduce.MRConfig;
|
||||
import org.apache.hadoop.mapreduce.server.jobtracker.JTConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestMRFramework {
|
||||
|
||||
@Test
|
||||
public void testFramework() {
|
||||
JobConf jobConf = new JobConf();
|
||||
jobConf.set(JTConfig.JT_IPC_ADDRESS, MRConfig.LOCAL_FRAMEWORK_NAME);
|
||||
jobConf.set(MRConfig.FRAMEWORK_NAME, MRConfig.YARN_FRAMEWORK_NAME);
|
||||
assertFalse("Expected 'isLocal' to be false",
|
||||
StreamUtil.isLocalJobTracker(jobConf));
|
||||
|
||||
jobConf.set(JTConfig.JT_IPC_ADDRESS, MRConfig.LOCAL_FRAMEWORK_NAME);
|
||||
jobConf.set(MRConfig.FRAMEWORK_NAME, MRConfig.CLASSIC_FRAMEWORK_NAME);
|
||||
assertFalse("Expected 'isLocal' to be false",
|
||||
StreamUtil.isLocalJobTracker(jobConf));
|
||||
|
||||
jobConf.set(JTConfig.JT_IPC_ADDRESS, "jthost:9090");
|
||||
jobConf.set(MRConfig.FRAMEWORK_NAME, MRConfig.LOCAL_FRAMEWORK_NAME);
|
||||
assertTrue("Expected 'isLocal' to be true",
|
||||
StreamUtil.isLocalJobTracker(jobConf));
|
||||
}
|
||||
|
||||
}
|
@ -32,7 +32,18 @@
|
||||
* This class tests hadoop Streaming's StreamJob class.
|
||||
*/
|
||||
public class TestStreamJob {
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateJobWithExtraArgs() throws IOException {
|
||||
ArrayList<String> dummyArgs = new ArrayList<String>();
|
||||
dummyArgs.add("-input"); dummyArgs.add("dummy");
|
||||
dummyArgs.add("-output"); dummyArgs.add("dummy");
|
||||
dummyArgs.add("-mapper"); dummyArgs.add("dummy");
|
||||
dummyArgs.add("dummy");
|
||||
dummyArgs.add("-reducer"); dummyArgs.add("dummy");
|
||||
StreamJob.createJob(dummyArgs.toArray(new String[] {}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateJob() throws IOException {
|
||||
JobConf job;
|
||||
|
Loading…
Reference in New Issue
Block a user