diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt index d287bb82c33..9c10375a9a0 100644 --- a/hadoop-yarn-project/CHANGES.txt +++ b/hadoop-yarn-project/CHANGES.txt @@ -29,6 +29,9 @@ Release 2.0.3-alpha - Unreleased YARN-23. FairScheduler: FSQueueSchedulable#updateDemand() - potential redundant aggregation. (kkambatl via tucu) + YARN-127. Move RMAdmin tool to its correct location - the client module. + (vinodkv) + OPTIMIZATIONS BUG FIXES @@ -100,8 +103,8 @@ Release 0.23.5 - UNRELEASED IMPROVEMENTS - YARN-127. Move RMAdmin tool to its correct location - the client module. - (vinodkv) + YARN-40. Provided support for missing YARN commands (Devaraj K and Vinod + Kumar Vavilapalli via vinodkv) OPTIMIZATIONS diff --git a/hadoop-yarn-project/hadoop-yarn/bin/yarn b/hadoop-yarn-project/hadoop-yarn/bin/yarn index 2225ef41266..2a648f3a091 100644 --- a/hadoop-yarn-project/hadoop-yarn/bin/yarn +++ b/hadoop-yarn-project/hadoop-yarn/bin/yarn @@ -67,6 +67,8 @@ if [ $# = 0 ]; then echo " rmadmin admin tools" echo " version print the version" echo " jar run a jar file" + echo " application prints application(s) report/kill application" + echo " node prints node report(s)" echo " logs dump container logs" echo " classpath prints the class path needed to get the" echo " Hadoop jar and the required libraries" @@ -171,6 +173,12 @@ if [ "$COMMAND" = "classpath" ] ; then elif [ "$COMMAND" = "rmadmin" ] ; then CLASS='org.apache.hadoop.yarn.client.RMAdmin' YARN_OPTS="$YARN_OPTS $YARN_CLIENT_OPTS" +elif [ "$COMMAND" = "application" ] ; then + CLASS=org.apache.hadoop.yarn.client.cli.ApplicationCLI + YARN_OPTS="$YARN_OPTS $YARN_CLIENT_OPTS" +elif [ "$COMMAND" = "node" ] ; then + CLASS=org.apache.hadoop.yarn.client.cli.NodeCLI + YARN_OPTS="$YARN_OPTS $YARN_CLIENT_OPTS" elif [ "$COMMAND" = "resourcemanager" ] ; then CLASSPATH=${CLASSPATH}:$YARN_CONF_DIR/rm-config/log4j.properties CLASS='org.apache.hadoop.yarn.server.resourcemanager.ResourceManager' diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java new file mode 100644 index 00000000000..b8ecae7122d --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java @@ -0,0 +1,159 @@ +/** + * 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.client.cli; + +import java.io.PrintWriter; +import java.util.List; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.GnuParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; +import org.apache.hadoop.util.ToolRunner; +import org.apache.hadoop.yarn.api.records.ApplicationId; +import org.apache.hadoop.yarn.api.records.ApplicationReport; +import org.apache.hadoop.yarn.exceptions.YarnRemoteException; +import org.apache.hadoop.yarn.util.ConverterUtils; + +public class ApplicationCLI extends YarnCLI { + private static final String APPLICATIONS_PATTERN = "%30s\t%20s\t%10s\t%10s\t%18s\t%18s\t%35s\n"; + + public static void main(String[] args) throws Exception { + ApplicationCLI cli = new ApplicationCLI(); + cli.setSysOutPrintStream(System.out); + cli.setSysErrPrintStream(System.err); + int res = ToolRunner.run(cli, args); + cli.stop(); + System.exit(res); + } + + @Override + public int run(String[] args) throws Exception { + + Options opts = new Options(); + opts.addOption(STATUS_CMD, true, "Prints the status of the application."); + opts.addOption(LIST_CMD, false, "Lists all the Applications from RM."); + opts.addOption(KILL_CMD, true, "Kills the application."); + CommandLine cliParser = new GnuParser().parse(opts, args); + + int exitCode = -1; + if (cliParser.hasOption(STATUS_CMD)) { + if (args.length != 2) { + printUsage(opts); + return exitCode; + } + printApplicationReport(cliParser.getOptionValue(STATUS_CMD)); + } else if (cliParser.hasOption(LIST_CMD)) { + listAllApplications(); + } else if (cliParser.hasOption(KILL_CMD)) { + if (args.length != 2) { + printUsage(opts); + return exitCode; + } + killApplication(cliParser.getOptionValue(KILL_CMD)); + } else { + syserr.println("Invalid Command Usage : "); + printUsage(opts); + } + return 0; + } + + /** + * It prints the usage of the command + * + * @param opts + */ + private void printUsage(Options opts) { + new HelpFormatter().printHelp("application", opts); + } + + /** + * Lists all the applications present in the Resource Manager + * + * @throws YarnRemoteException + */ + private void listAllApplications() throws YarnRemoteException { + PrintWriter writer = new PrintWriter(sysout); + List appsReport = client.getApplicationList(); + + writer.println("Total Applications:" + appsReport.size()); + writer.printf(APPLICATIONS_PATTERN, "Application-Id", + "Application-Name", "User", "Queue", "State", "Final-State", + "Tracking-URL"); + for (ApplicationReport appReport : appsReport) { + writer.printf(APPLICATIONS_PATTERN, appReport.getApplicationId(), + appReport.getName(), appReport.getUser(), appReport.getQueue(), + appReport.getYarnApplicationState(), appReport + .getFinalApplicationStatus(), appReport.getOriginalTrackingUrl()); + } + writer.flush(); + } + + /** + * Kills the application with the application id as appId + * + * @param applicationId + * @throws YarnRemoteException + */ + private void killApplication(String applicationId) throws YarnRemoteException { + ApplicationId appId = ConverterUtils.toApplicationId(applicationId); + sysout.println("Killing application " + applicationId); + client.killApplication(appId); + } + + /** + * Prints the application report for an application id. + * + * @param applicationId + * @throws YarnRemoteException + */ + private void printApplicationReport(String applicationId) + throws YarnRemoteException { + ApplicationReport appReport = client.getApplicationReport(ConverterUtils + .toApplicationId(applicationId)); + StringBuffer appReportStr = new StringBuffer(); + if (appReport != null) { + appReportStr.append("Application Report : "); + appReportStr.append("\n\tApplication-Id : "); + appReportStr.append(appReport.getApplicationId()); + appReportStr.append("\n\tApplication-Name : "); + appReportStr.append(appReport.getName()); + appReportStr.append("\n\tUser : "); + appReportStr.append(appReport.getUser()); + appReportStr.append("\n\tQueue : "); + appReportStr.append(appReport.getQueue()); + appReportStr.append("\n\tStart-Time : "); + appReportStr.append(appReport.getStartTime()); + appReportStr.append("\n\tFinish-Time : "); + appReportStr.append(appReport.getFinishTime()); + appReportStr.append("\n\tState : "); + appReportStr.append(appReport.getYarnApplicationState()); + appReportStr.append("\n\tFinal-State : "); + appReportStr.append(appReport.getFinalApplicationStatus()); + appReportStr.append("\n\tTracking-URL : "); + appReportStr.append(appReport.getOriginalTrackingUrl()); + appReportStr.append("\n\tDiagnostics : "); + appReportStr.append(appReport.getDiagnostics()); + } else { + appReportStr.append("Application with id '" + applicationId + + "' doesn't exist in RM."); + } + sysout.println(appReportStr.toString()); + } + +} \ No newline at end of file diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/NodeCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/NodeCLI.java new file mode 100644 index 00000000000..cfde538f147 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/NodeCLI.java @@ -0,0 +1,147 @@ +/** + * 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.client.cli; + +import java.io.PrintWriter; +import java.util.List; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.GnuParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; +import org.apache.hadoop.util.ToolRunner; +import org.apache.hadoop.yarn.api.records.NodeId; +import org.apache.hadoop.yarn.api.records.NodeReport; +import org.apache.hadoop.yarn.exceptions.YarnRemoteException; +import org.apache.hadoop.yarn.util.ConverterUtils; + +public class NodeCLI extends YarnCLI { + private static final String NODES_PATTERN = "%16s\t%10s\t%17s\t%26s\t%18s\n"; + public static void main(String[] args) throws Exception { + NodeCLI cli = new NodeCLI(); + cli.setSysOutPrintStream(System.out); + cli.setSysErrPrintStream(System.err); + int res = ToolRunner.run(cli, args); + cli.stop(); + System.exit(res); + } + + @Override + public int run(String[] args) throws Exception { + + Options opts = new Options(); + opts.addOption(STATUS_CMD, true, "Prints the status report of the node."); + opts.addOption(LIST_CMD, false, "Lists all the nodes."); + CommandLine cliParser = new GnuParser().parse(opts, args); + + int exitCode = -1; + if (cliParser.hasOption("status")) { + if (args.length != 2) { + printUsage(opts); + return exitCode; + } + printNodeStatus(cliParser.getOptionValue("status")); + } else if (cliParser.hasOption("list")) { + listClusterNodes(); + } else { + syserr.println("Invalid Command Usage : "); + printUsage(opts); + } + return 0; + } + + /** + * It prints the usage of the command + * + * @param opts + */ + private void printUsage(Options opts) { + new HelpFormatter().printHelp("node", opts); + } + + /** + * Lists all the nodes present in the cluster + * + * @throws YarnRemoteException + */ + private void listClusterNodes() throws YarnRemoteException { + PrintWriter writer = new PrintWriter(sysout); + List nodesReport = client.getNodeReports(); + writer.println("Total Nodes:" + nodesReport.size()); + writer.printf(NODES_PATTERN, "Node-Id", "Node-State", "Node-Http-Address", + "Health-Status(isNodeHealthy)", "Running-Containers"); + for (NodeReport nodeReport : nodesReport) { + writer.printf(NODES_PATTERN, nodeReport.getNodeId(), nodeReport + .getNodeState(), nodeReport.getHttpAddress(), nodeReport + .getNodeHealthStatus().getIsNodeHealthy(), nodeReport + .getNumContainers()); + } + writer.flush(); + } + + /** + * Prints the node report for node id. + * + * @param nodeIdStr + * @throws YarnRemoteException + */ + private void printNodeStatus(String nodeIdStr) throws YarnRemoteException { + NodeId nodeId = ConverterUtils.toNodeId(nodeIdStr); + List nodesReport = client.getNodeReports(); + StringBuffer nodeReportStr = new StringBuffer(); + NodeReport nodeReport = null; + for (NodeReport report : nodesReport) { + if (!report.getNodeId().equals(nodeId)) { + continue; + } + nodeReport = report; + nodeReportStr.append("Node Report : "); + nodeReportStr.append("\n\tNode-Id : "); + nodeReportStr.append(nodeReport.getNodeId()); + nodeReportStr.append("\n\tRack : "); + nodeReportStr.append(nodeReport.getRackName()); + nodeReportStr.append("\n\tNode-State : "); + nodeReportStr.append(nodeReport.getNodeState()); + nodeReportStr.append("\n\tNode-Http-Address : "); + nodeReportStr.append(nodeReport.getHttpAddress()); + nodeReportStr.append("\n\tHealth-Status(isNodeHealthy) : "); + nodeReportStr.append(nodeReport.getNodeHealthStatus() + .getIsNodeHealthy()); + nodeReportStr.append("\n\tLast-Last-Health-Update : "); + nodeReportStr.append(nodeReport.getNodeHealthStatus() + .getLastHealthReportTime()); + nodeReportStr.append("\n\tHealth-Report : "); + nodeReportStr + .append(nodeReport.getNodeHealthStatus().getHealthReport()); + nodeReportStr.append("\n\tContainers : "); + nodeReportStr.append(nodeReport.getNumContainers()); + nodeReportStr.append("\n\tMemory-Used : "); + nodeReportStr.append((nodeReport.getUsed() == null) ? "0M" + : (nodeReport.getUsed().getMemory() + "M")); + nodeReportStr.append("\n\tMemory-Capacity : "); + nodeReportStr.append(nodeReport.getCapability().getMemory()); + } + + if (nodeReport == null) { + nodeReportStr.append("Could not find the node report for node id : " + + nodeIdStr); + } + + sysout.println(nodeReportStr.toString()); + } +} \ No newline at end of file diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/YarnCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/YarnCLI.java new file mode 100644 index 00000000000..a36e671ffef --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/YarnCLI.java @@ -0,0 +1,63 @@ +/** + * 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.client.cli; + +import java.io.PrintStream; + +import org.apache.hadoop.conf.Configured; +import org.apache.hadoop.util.Tool; +import org.apache.hadoop.yarn.client.YarnClient; +import org.apache.hadoop.yarn.client.YarnClientImpl; +import org.apache.hadoop.yarn.conf.YarnConfiguration; + +public abstract class YarnCLI extends Configured implements Tool { + + public static final String STATUS_CMD = "status"; + public static final String LIST_CMD = "list"; + public static final String KILL_CMD = "kill"; + protected PrintStream sysout; + protected PrintStream syserr; + protected YarnClient client; + + public YarnCLI() { + super(new YarnConfiguration()); + client = new YarnClientImpl(); + client.init(getConf()); + client.start(); + } + + public void setSysOutPrintStream(PrintStream sysout) { + this.sysout = sysout; + } + + public void setSysErrPrintStream(PrintStream syserr) { + this.syserr = syserr; + } + + public YarnClient getClient() { + return client; + } + + public void setClient(YarnClient client) { + this.client = client; + } + + public void stop() { + this.client.stop(); + } +} \ No newline at end of file diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java new file mode 100644 index 00000000000..146f9380020 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java @@ -0,0 +1,228 @@ +/** + * 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.client.cli; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.Assert; + +import org.apache.hadoop.yarn.api.records.ApplicationId; +import org.apache.hadoop.yarn.api.records.ApplicationReport; +import org.apache.hadoop.yarn.api.records.FinalApplicationStatus; +import org.apache.hadoop.yarn.api.records.NodeHealthStatus; +import org.apache.hadoop.yarn.api.records.NodeId; +import org.apache.hadoop.yarn.api.records.NodeReport; +import org.apache.hadoop.yarn.api.records.NodeState; +import org.apache.hadoop.yarn.api.records.Resource; +import org.apache.hadoop.yarn.api.records.YarnApplicationState; +import org.apache.hadoop.yarn.client.YarnClient; +import org.apache.hadoop.yarn.util.BuilderUtils; +import org.apache.hadoop.yarn.util.Records; +import org.junit.Before; +import org.junit.Test; + +public class TestYarnCLI { + + private YarnClient client = mock(YarnClient.class); + ByteArrayOutputStream sysOutStream; + private PrintStream sysOut; + ByteArrayOutputStream sysErrStream; + private PrintStream sysErr; + + @Before + public void setup() { + sysOutStream = new ByteArrayOutputStream(); + sysOut = spy(new PrintStream(sysOutStream)); + sysErrStream = new ByteArrayOutputStream(); + sysErr = spy(new PrintStream(sysErrStream)); + } + + @Test + public void testGetApplicationReport() throws Exception { + ApplicationCLI cli = createAndGetAppCLI(); + ApplicationId applicationId = BuilderUtils.newApplicationId(1234, 5); + ApplicationReport newApplicationReport = BuilderUtils.newApplicationReport( + applicationId, BuilderUtils.newApplicationAttemptId(applicationId, 1), + "user", "queue", "appname", "host", 124, null, + YarnApplicationState.FINISHED, "diagnostics", "url", 0, 0, + FinalApplicationStatus.SUCCEEDED, null, "N/A"); + when(client.getApplicationReport(any(ApplicationId.class))).thenReturn( + newApplicationReport); + int result = cli.run(new String[] { "-status", applicationId.toString() }); + assertEquals(0, result); + verify(client).getApplicationReport(applicationId); + String appReportStr = "Application Report : \n\t" + + "Application-Id : application_1234_0005\n\t" + + "Application-Name : appname\n\tUser : user\n\t" + + "Queue : queue\n\tStart-Time : 0\n\tFinish-Time : 0\n\t" + + "State : FINISHED\n\tFinal-State : SUCCEEDED\n\t" + + "Tracking-URL : N/A\n\tDiagnostics : diagnostics\n"; + Assert.assertEquals(appReportStr, sysOutStream.toString()); + verify(sysOut, times(1)).println(isA(String.class)); + } + + @Test + public void testGetAllApplications() throws Exception { + ApplicationCLI cli = createAndGetAppCLI(); + ApplicationId applicationId = BuilderUtils.newApplicationId(1234, 5); + ApplicationReport newApplicationReport = BuilderUtils.newApplicationReport( + applicationId, BuilderUtils.newApplicationAttemptId(applicationId, 1), + "user", "queue", "appname", "host", 124, null, + YarnApplicationState.FINISHED, "diagnostics", "url", 0, 0, + FinalApplicationStatus.SUCCEEDED, null, "N/A"); + List applicationReports = new ArrayList(); + applicationReports.add(newApplicationReport); + when(client.getApplicationList()).thenReturn(applicationReports); + int result = cli.run(new String[] { "-list" }); + assertEquals(0, result); + verify(client).getApplicationList(); + + StringBuffer appsReportStrBuf = new StringBuffer(); + appsReportStrBuf.append("Total Applications:1\n"); + appsReportStrBuf + .append(" Application-Id\t Application-Name" + + "\t User\t Queue\t State\t " + + "Final-State\t Tracking-URL\n"); + appsReportStrBuf.append(" application_1234_0005\t " + + "appname\t user\t queue\t FINISHED\t " + + "SUCCEEDED\t N/A\n"); + Assert.assertEquals(appsReportStrBuf.toString(), sysOutStream.toString()); + verify(sysOut, times(1)).write(any(byte[].class), anyInt(), anyInt()); + } + + @Test + public void testKillApplication() throws Exception { + ApplicationCLI cli = createAndGetAppCLI(); + ApplicationId applicationId = BuilderUtils.newApplicationId(1234, 5); + int result = cli.run(new String[] { "-kill", applicationId.toString() }); + assertEquals(0, result); + verify(client).killApplication(any(ApplicationId.class)); + verify(sysOut).println("Killing application application_1234_0005"); + } + + @Test + public void testListClusterNodes() throws Exception { + NodeCLI cli = new NodeCLI(); + when(client.getNodeReports()).thenReturn(getNodeReports(3)); + cli.setClient(client); + cli.setSysOutPrintStream(sysOut); + int result = cli.run(new String[] { "-list" }); + assertEquals(0, result); + verify(client).getNodeReports(); + StringBuffer nodesReportStr = new StringBuffer(); + nodesReportStr.append("Total Nodes:3"); + nodesReportStr + .append("\n Node-Id\tNode-State\tNode-Http-Address\t" + + "Health-Status(isNodeHealthy)\tRunning-Containers"); + nodesReportStr.append("\n host0:0\t RUNNING\t host1:8888" + + "\t false\t 0"); + nodesReportStr.append("\n host1:0\t RUNNING\t host1:8888" + + "\t false\t 0"); + nodesReportStr.append("\n host2:0\t RUNNING\t host1:8888" + + "\t false\t 0\n"); + Assert.assertEquals(nodesReportStr.toString(), sysOutStream.toString()); + verify(sysOut, times(1)).write(any(byte[].class), anyInt(), anyInt()); + } + + @Test + public void testNodeStatus() throws Exception { + NodeId nodeId = BuilderUtils.newNodeId("host0", 0); + NodeCLI cli = new NodeCLI(); + when(client.getNodeReports()).thenReturn(getNodeReports(3)); + cli.setClient(client); + cli.setSysOutPrintStream(sysOut); + cli.setSysErrPrintStream(sysErr); + int result = cli.run(new String[] { "-status", nodeId.toString() }); + assertEquals(0, result); + verify(client).getNodeReports(); + String nodeStatusStr = "Node Report : \n\tNode-Id : host0:0\n\t" + + "Rack : rack1\n\tNode-State : RUNNING\n\t" + + "Node-Http-Address : host1:8888\n\tHealth-Status(isNodeHealthy) " + + ": false\n\tLast-Last-Health-Update : 0\n\tHealth-Report : null" + + "\n\tContainers : 0\n\tMemory-Used : 0M\n\tMemory-Capacity : 0"; + verify(sysOut, times(1)).println(isA(String.class)); + verify(sysOut).println(nodeStatusStr); + } + + @Test + public void testAbsentNodeStatus() throws Exception { + NodeId nodeId = BuilderUtils.newNodeId("Absenthost0", 0); + NodeCLI cli = new NodeCLI(); + when(client.getNodeReports()).thenReturn(getNodeReports(0)); + cli.setClient(client); + cli.setSysOutPrintStream(sysOut); + cli.setSysErrPrintStream(sysErr); + int result = cli.run(new String[] { "-status", nodeId.toString() }); + assertEquals(0, result); + verify(client).getNodeReports(); + verify(sysOut, times(1)).println(isA(String.class)); + verify(sysOut).println( + "Could not find the node report for node id : " + nodeId.toString()); + } + + @Test + public void testAppCLIUsageInfo() throws Exception { + verifyUsageInfo(new ApplicationCLI()); + } + + @Test + public void testNodeCLIUsageInfo() throws Exception { + verifyUsageInfo(new NodeCLI()); + } + + private void verifyUsageInfo(YarnCLI cli) throws Exception { + cli.setSysErrPrintStream(sysErr); + cli.run(new String[0]); + verify(sysErr).println("Invalid Command Usage : "); + } + + private List getNodeReports(int noOfNodes) { + List nodeReports = new ArrayList(); + + for (int i = 0; i < noOfNodes; i++) { + NodeReport nodeReport = BuilderUtils.newNodeReport(BuilderUtils + .newNodeId("host" + i, 0), NodeState.RUNNING, "host" + 1 + ":8888", + "rack1", Records.newRecord(Resource.class), Records + .newRecord(Resource.class), 0, Records + .newRecord(NodeHealthStatus.class)); + nodeReports.add(nodeReport); + } + return nodeReports; + } + + private ApplicationCLI createAndGetAppCLI() { + ApplicationCLI cli = new ApplicationCLI(); + cli.setClient(client); + cli.setSysOutPrintStream(sysOut); + return cli; + } + +} \ No newline at end of file diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/apt/YarnCommands.apt.vm b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/apt/YarnCommands.apt.vm index a57f07c2280..386be09d483 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/apt/YarnCommands.apt.vm +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/apt/YarnCommands.apt.vm @@ -52,6 +52,40 @@ Usage: yarn [--config confdir] COMMAND Usage: yarn jar [mainClass] args... ------- +** application + + Prints application(s) report/kill application + +------- + Usage: yarn application +------- + +*---------------+--------------+ +|| COMMAND_OPTIONS || Description | +*---------------+--------------+ +| -status ApplicationId | Specify an application id | +*---------------+--------------+ +| -list | Lists all the Applications from RM | +*---------------+--------------+ +| -kill ApplicationId | Specify an application id | +*---------------+--------------+ + +** node + + Prints node report(s) + +------- + Usage: yarn node +------- + +*---------------+--------------+ +|| COMMAND_OPTIONS || Description | +*---------------+--------------+ +| -status NodeId | Specify a node id | +*---------------+--------------+ +| -list | Lists all the Nodes | +*---------------+--------------+ + ** logs Dump the container logs