YARN-1117. Improved help messages for "yarn application" and "yarn node" commands. Contributed by Xuan Gong.

svn merge --ignore-ancestry -c 1519117 ../../trunk/


git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1519118 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Vinod Kumar Vavilapalli 2013-08-30 23:26:36 +00:00
parent 148db9d4f5
commit 3fea164bb1
6 changed files with 123 additions and 20 deletions

View File

@ -57,6 +57,9 @@ Release 2.1.1-beta - UNRELEASED
YARN-771. AMRMClient support for resource blacklisting (Junping Du via YARN-771. AMRMClient support for resource blacklisting (Junping Du via
bikas) bikas)
YARN-1117. Improved help messages for "yarn application" and "yarn node"
commands. (Xuan Gong via vinodkv)
OPTIMIZATIONS OPTIMIZATIONS
BUG FIXES BUG FIXES

View File

@ -29,6 +29,7 @@ import java.util.Set;
import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.MissingArgumentException;
import org.apache.commons.cli.Option; import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options; import org.apache.commons.cli.Options;
import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.classification.InterfaceAudience.Private;
@ -70,32 +71,38 @@ public class ApplicationCLI extends YarnCLI {
Options opts = new Options(); Options opts = new Options();
opts.addOption(STATUS_CMD, true, "Prints the status of the application."); opts.addOption(STATUS_CMD, true, "Prints the status of the application.");
opts.addOption(LIST_CMD, false, "List applications from the RM. " + opts.addOption(LIST_CMD, false, "List applications from the RM. " +
"Supports optional use of --appTypes to filter applications " + "Supports optional use of -appTypes to filter applications " +
"based on application type, " + "based on application type, " +
"and --appStates to filter applications based on application state"); "and -appStates to filter applications based on application state");
opts.addOption(KILL_CMD, true, "Kills the application."); opts.addOption(KILL_CMD, true, "Kills the application.");
opts.addOption(HELP_CMD, false, "Displays help for all commands."); opts.addOption(HELP_CMD, false, "Displays help for all commands.");
Option appTypeOpt = new Option(APP_TYPE_CMD, true, Option appTypeOpt = new Option(APP_TYPE_CMD, true, "Works with -list to " +
"Works with --list to filter applications based on their type."); "filter applications based on " +
"input comma-separated list of application types.");
appTypeOpt.setValueSeparator(','); appTypeOpt.setValueSeparator(',');
appTypeOpt.setArgs(Option.UNLIMITED_VALUES); appTypeOpt.setArgs(Option.UNLIMITED_VALUES);
appTypeOpt.setArgName("Comma-separated list of application types"); appTypeOpt.setArgName("Types");
opts.addOption(appTypeOpt); opts.addOption(appTypeOpt);
Option appStateOpt = Option appStateOpt = new Option(APP_STATE_CMD, true, "Works with -list " +
new Option( "to filter applications based on input comma-separated list of " +
APP_STATE_CMD, "application states. " + getAllValidApplicationStates());
true,
"Works with --list to filter applications based on their state. "
+ getAllValidApplicationStates());
appStateOpt.setValueSeparator(','); appStateOpt.setValueSeparator(',');
appStateOpt.setArgs(Option.UNLIMITED_VALUES); appStateOpt.setArgs(Option.UNLIMITED_VALUES);
appStateOpt.setArgName("Comma-separated list of application states"); appStateOpt.setArgName("States");
opts.addOption(appStateOpt); opts.addOption(appStateOpt);
opts.getOption(KILL_CMD).setArgName("Application ID"); opts.getOption(KILL_CMD).setArgName("Application ID");
opts.getOption(STATUS_CMD).setArgName("Application ID"); opts.getOption(STATUS_CMD).setArgName("Application ID");
CommandLine cliParser = new GnuParser().parse(opts, args);
int exitCode = -1; int exitCode = -1;
CommandLine cliParser = null;
try {
cliParser = new GnuParser().parse(opts, args);
} catch (MissingArgumentException ex) {
sysout.println("Missing argument for options");
printUsage(opts);
return exitCode;
}
if (cliParser.hasOption(STATUS_CMD)) { if (cliParser.hasOption(STATUS_CMD)) {
if (args.length != 2) { if (args.length != 2) {
printUsage(opts); printUsage(opts);

View File

@ -28,6 +28,7 @@ import java.util.Set;
import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.MissingArgumentException;
import org.apache.commons.cli.Option; import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options; import org.apache.commons.cli.Options;
import org.apache.commons.lang.time.DateFormatUtils; import org.apache.commons.lang.time.DateFormatUtils;
@ -64,20 +65,29 @@ public class NodeCLI extends YarnCLI {
Options opts = new Options(); Options opts = new Options();
opts.addOption(STATUS_CMD, true, "Prints the status report of the node."); opts.addOption(STATUS_CMD, true, "Prints the status report of the node.");
opts.addOption(LIST_CMD, false, "List all running nodes. " + opts.addOption(LIST_CMD, false, "List all running nodes. " +
"Supports optional use of --states to filter nodes " + "Supports optional use of -states to filter nodes " +
"based on node state, all --all to list all nodes."); "based on node state, all -all to list all nodes.");
Option nodeStateOpt = new Option(NODE_STATE_CMD, true, Option nodeStateOpt = new Option(NODE_STATE_CMD, true,
"Works with -list to filter nodes based on their states."); "Works with -list to filter nodes based on input comma-separated list of node states.");
nodeStateOpt.setValueSeparator(','); nodeStateOpt.setValueSeparator(',');
nodeStateOpt.setArgs(Option.UNLIMITED_VALUES); nodeStateOpt.setArgs(Option.UNLIMITED_VALUES);
nodeStateOpt.setArgName("Comma-separated list of node states"); nodeStateOpt.setArgName("States");
opts.addOption(nodeStateOpt); opts.addOption(nodeStateOpt);
Option allOpt = new Option(NODE_ALL, false, Option allOpt = new Option(NODE_ALL, false,
"Works with -list to list all nodes."); "Works with -list to list all nodes.");
opts.addOption(allOpt); opts.addOption(allOpt);
CommandLine cliParser = new GnuParser().parse(opts, args); opts.getOption(STATUS_CMD).setArgName("NodeId");
int exitCode = -1; int exitCode = -1;
CommandLine cliParser = null;
try {
cliParser = new GnuParser().parse(opts, args);
} catch (MissingArgumentException ex) {
sysout.println("Missing argument for options");
printUsage(opts);
return exitCode;
}
if (cliParser.hasOption("status")) { if (cliParser.hasOption("status")) {
if (args.length != 2) { if (args.length != 2) {
printUsage(opts); printUsage(opts);

View File

@ -86,6 +86,7 @@ public class TestYarnClient {
client.init(conf); client.init(conf);
client.start(); client.start();
client.stop(); client.stop();
rm.stop();
} }
@Test (timeout = 30000) @Test (timeout = 30000)

View File

@ -29,6 +29,7 @@ import static org.mockito.Mockito.when;
import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.doThrow;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
@ -72,6 +73,7 @@ public class TestYarnCLI {
sysOut = spy(new PrintStream(sysOutStream)); sysOut = spy(new PrintStream(sysOutStream));
sysErrStream = new ByteArrayOutputStream(); sysErrStream = new ByteArrayOutputStream();
sysErr = spy(new PrintStream(sysErrStream)); sysErr = spy(new PrintStream(sysErrStream));
System.setOut(sysOut);
} }
@Test @Test
@ -456,21 +458,40 @@ public class TestYarnCLI {
} }
@Test (timeout = 10000) @Test (timeout = 10000)
public void testHelpCommand() throws Exception { public void testAppsHelpCommand() throws Exception {
ApplicationCLI cli = createAndGetAppCLI(); ApplicationCLI cli = createAndGetAppCLI();
ApplicationCLI spyCli = spy(cli); ApplicationCLI spyCli = spy(cli);
int result = spyCli.run(new String[] { "-help" }); int result = spyCli.run(new String[] { "-help" });
Assert.assertTrue(result == 0); Assert.assertTrue(result == 0);
verify(spyCli).printUsage(any(Options.class)); verify(spyCli).printUsage(any(Options.class));
Assert.assertEquals(createApplicationCLIHelpMessage(),
sysOutStream.toString());
sysOutStream.reset();
ApplicationId applicationId = ApplicationId.newInstance(1234, 5); ApplicationId applicationId = ApplicationId.newInstance(1234, 5);
result = result =
cli.run(new String[] { "-kill", applicationId.toString(), "args" }); cli.run(new String[] { "-kill", applicationId.toString(), "args" });
verify(spyCli).printUsage(any(Options.class)); verify(spyCli).printUsage(any(Options.class));
Assert.assertEquals(createApplicationCLIHelpMessage(),
sysOutStream.toString());
sysOutStream.reset();
NodeId nodeId = NodeId.newInstance("host0", 0); NodeId nodeId = NodeId.newInstance("host0", 0);
result = cli.run(new String[] { "-status", nodeId.toString(), "args" }); result = cli.run(new String[] { "-status", nodeId.toString(), "args" });
verify(spyCli).printUsage(any(Options.class)); verify(spyCli).printUsage(any(Options.class));
Assert.assertEquals(createApplicationCLIHelpMessage(),
sysOutStream.toString());
}
@Test (timeout = 5000)
public void testNodesHelpCommand() throws Exception {
NodeCLI nodeCLI = new NodeCLI();
nodeCLI.setClient(client);
nodeCLI.setSysOutPrintStream(sysOut);
nodeCLI.setSysErrPrintStream(sysErr);
nodeCLI.run(new String[] {});
Assert.assertEquals(createNodeCLIHelpMessage(),
sysOutStream.toString());
} }
@Test @Test
@ -806,6 +827,25 @@ public class TestYarnCLI {
verifyUsageInfo(new NodeCLI()); verifyUsageInfo(new NodeCLI());
} }
@Test
public void testMissingArguments() throws Exception {
ApplicationCLI cli = createAndGetAppCLI();
int result = cli.run(new String[] { "-status" });
Assert.assertEquals(result, -1);
Assert.assertEquals("Missing argument for options\n"
+ createApplicationCLIHelpMessage(), sysOutStream.toString());
sysOutStream.reset();
NodeCLI nodeCLI = new NodeCLI();
nodeCLI.setClient(client);
nodeCLI.setSysOutPrintStream(sysOut);
nodeCLI.setSysErrPrintStream(sysErr);
result = nodeCLI.run(new String[] { "-status" });
Assert.assertEquals(result, -1);
Assert.assertEquals("Missing argument for options\n"
+ createNodeCLIHelpMessage(), sysOutStream.toString());
}
private void verifyUsageInfo(YarnCLI cli) throws Exception { private void verifyUsageInfo(YarnCLI cli) throws Exception {
cli.setSysErrPrintStream(sysErr); cli.setSysErrPrintStream(sysErr);
cli.run(new String[0]); cli.run(new String[0]);
@ -832,4 +872,45 @@ public class TestYarnCLI {
return cli; return cli;
} }
private String createApplicationCLIHelpMessage() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(baos);
pw.println("usage: application");
pw.println(" -appStates <States> Works with -list to filter applications based");
pw.println(" on input comma-separated list of application");
pw.println(" states. The valid application state can be one");
pw.println(" of the following:");
pw.println(" ALL,NEW,NEW_SAVING,SUBMITTED,ACCEPTED,RUNNING,");
pw.println(" FINISHED,FAILED,KILLED");
pw.println(" -appTypes <Types> Works with -list to filter applications based");
pw.println(" on input comma-separated list of application");
pw.println(" types.");
pw.println(" -help Displays help for all commands.");
pw.println(" -kill <Application ID> Kills the application.");
pw.println(" -list List applications from the RM. Supports");
pw.println(" optional use of -appTypes to filter");
pw.println(" applications based on application type, and");
pw.println(" -appStates to filter applications based on");
pw.println(" application state");
pw.println(" -status <Application ID> Prints the status of the application.");
pw.close();
String appsHelpStr = baos.toString("UTF-8");
return appsHelpStr;
}
private String createNodeCLIHelpMessage() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(baos);
pw.println("usage: node");
pw.println(" -all Works with -list to list all nodes.");
pw.println(" -list List all running nodes. Supports optional use of");
pw.println(" -states to filter nodes based on node state, all -all");
pw.println(" to list all nodes.");
pw.println(" -states <States> Works with -list to filter nodes based on input");
pw.println(" comma-separated list of node states.");
pw.println(" -status <NodeId> Prints the status report of the node.");
pw.close();
String nodesHelpStr = baos.toString("UTF-8");
return nodesHelpStr;
}
} }

View File

@ -198,7 +198,8 @@ public class ConverterUtils {
Iterator<String> it = _split(appIdStr).iterator(); Iterator<String> it = _split(appIdStr).iterator();
if (!it.next().equals(APPLICATION_PREFIX)) { if (!it.next().equals(APPLICATION_PREFIX)) {
throw new IllegalArgumentException("Invalid ApplicationId prefix: " throw new IllegalArgumentException("Invalid ApplicationId prefix: "
+ appIdStr); + appIdStr + ". The valid ApplicationId should start with prefix "
+ APPLICATION_PREFIX);
} }
try { try {
return toApplicationId(it); return toApplicationId(it);