Browse Source

HDDS-438. 'ozone oz' should print usage when command or sub-command is missing. Contributed by Dinesh Chitlangia.

Arpit Agarwal 6 years ago
parent
commit
a12f12f1af

+ 4 - 1
hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/cli/GenericCli.java

@@ -67,11 +67,14 @@ public class GenericCli implements Callable<Void>, GenericParentCommand {
     } else {
     } else {
       System.err.println(error.getMessage().split("\n")[0]);
       System.err.println(error.getMessage().split("\n")[0]);
     }
     }
+    if(error instanceof MissingSubcommandException){
+      System.err.println(((MissingSubcommandException) error).getUsage());
+    }
   }
   }
 
 
   @Override
   @Override
   public Void call() throws Exception {
   public Void call() throws Exception {
-    throw new MissingSubcommandException();
+    throw new MissingSubcommandException(cmd.getUsageMessage());
   }
   }
 
 
   public OzoneConfiguration createOzoneConfiguration() {
   public OzoneConfiguration createOzoneConfiguration() {

+ 8 - 2
hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/cli/MissingSubcommandException.java

@@ -22,8 +22,14 @@ package org.apache.hadoop.hdds.cli;
  */
  */
 public class MissingSubcommandException extends RuntimeException {
 public class MissingSubcommandException extends RuntimeException {
 
 
-  public MissingSubcommandException() {
-    super("Please select a subcommand");
+  private String usage;
+
+  public MissingSubcommandException(String usage) {
+    super("Incomplete command");
+    this.usage = usage;
   }
   }
 
 
+  public String getUsage() {
+    return usage;
+  }
 }
 }

+ 64 - 5
hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java

@@ -33,6 +33,7 @@ import java.util.UUID;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 import org.apache.hadoop.fs.FileUtil;
 import org.apache.hadoop.fs.FileUtil;
+import org.apache.hadoop.hdds.cli.MissingSubcommandException;
 import org.apache.hadoop.hdds.client.ReplicationFactor;
 import org.apache.hadoop.hdds.client.ReplicationFactor;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
@@ -236,10 +237,10 @@ public class TestOzoneShell {
     assertEquals(userName, volumeInfo.getOwner());
     assertEquals(userName, volumeInfo.getOwner());
   }
   }
 
 
-  private void execute(Shell shell, String[] args) {
+  private void execute(Shell ozoneShell, String[] args) {
     List<String> arguments = new ArrayList(Arrays.asList(args));
     List<String> arguments = new ArrayList(Arrays.asList(args));
     LOG.info("Executing shell command with args {}", arguments);
     LOG.info("Executing shell command with args {}", arguments);
-    CommandLine cmd = shell.getCmd();
+    CommandLine cmd = ozoneShell.getCmd();
 
 
     IExceptionHandler2<List<Object>> exceptionHandler =
     IExceptionHandler2<List<Object>> exceptionHandler =
         new IExceptionHandler2<List<Object>>() {
         new IExceptionHandler2<List<Object>>() {
@@ -309,6 +310,29 @@ public class TestOzoneShell {
     executeWithError(shell, args, "VOLUME_NOT_FOUND");
     executeWithError(shell, args, "VOLUME_NOT_FOUND");
   }
   }
 
 
+  @Test
+  public void testShellIncompleteCommand() throws Exception {
+    LOG.info("Running testShellIncompleteCommand");
+    String expectedError = "Incomplete command";
+    String[] args = new String[] {}; //executing 'ozone oz'
+
+    executeWithError(shell, args, expectedError,
+        "Usage: ozone oz [-hV] [--verbose] [-D=<String=String>]..." +
+            " [COMMAND]");
+
+    args = new String[] {"volume"}; //executing 'ozone oz volume'
+    executeWithError(shell, args, expectedError,
+        "Usage: ozone oz volume [-hV] [COMMAND]");
+
+    args = new String[] {"bucket"}; //executing 'ozone oz bucket'
+    executeWithError(shell, args, expectedError,
+        "Usage: ozone oz bucket [-hV] [COMMAND]");
+
+    args = new String[] {"key"}; //executing 'ozone oz key'
+    executeWithError(shell, args, expectedError,
+        "Usage: ozone oz key [-hV] [COMMAND]");
+  }
+
   @Test
   @Test
   public void testUpdateVolume() throws Exception {
   public void testUpdateVolume() throws Exception {
     LOG.info("Running testUpdateVolume");
     LOG.info("Running testUpdateVolume");
@@ -352,13 +376,43 @@ public class TestOzoneShell {
    * Execute command, assert exeception message and returns true if error
    * Execute command, assert exeception message and returns true if error
    * was thrown.
    * was thrown.
    */
    */
-  private void executeWithError(Shell shell, String[] args,
+  private void executeWithError(Shell ozoneShell, String[] args,
       String expectedError) {
       String expectedError) {
     if (Strings.isNullOrEmpty(expectedError)) {
     if (Strings.isNullOrEmpty(expectedError)) {
-      execute(shell, args);
+      execute(ozoneShell, args);
+    } else {
+      try {
+        execute(ozoneShell, args);
+        fail("Exception is expected from command execution " + Arrays
+            .asList(args));
+      } catch (Exception ex) {
+        if (!Strings.isNullOrEmpty(expectedError)) {
+          Throwable exceptionToCheck = ex;
+          if (exceptionToCheck.getCause() != null) {
+            exceptionToCheck = exceptionToCheck.getCause();
+          }
+          Assert.assertTrue(
+              String.format(
+                  "Error of shell code doesn't contain the " +
+                      "exception [%s] in [%s]",
+                  expectedError, exceptionToCheck.getMessage()),
+              exceptionToCheck.getMessage().contains(expectedError));
+        }
+      }
+    }
+  }
+
+  /**
+   * Execute command, assert exception message and returns true if error
+   * was thrown and contains the specified usage string.
+   */
+  private void executeWithError(Shell ozoneShell, String[] args,
+      String expectedError, String usage) {
+    if (Strings.isNullOrEmpty(expectedError)) {
+      execute(ozoneShell, args);
     } else {
     } else {
       try {
       try {
-        execute(shell, args);
+        execute(ozoneShell, args);
         fail("Exception is expected from command execution " + Arrays
         fail("Exception is expected from command execution " + Arrays
             .asList(args));
             .asList(args));
       } catch (Exception ex) {
       } catch (Exception ex) {
@@ -373,6 +427,11 @@ public class TestOzoneShell {
                       "exception [%s] in [%s]",
                       "exception [%s] in [%s]",
                   expectedError, exceptionToCheck.getMessage()),
                   expectedError, exceptionToCheck.getMessage()),
               exceptionToCheck.getMessage().contains(expectedError));
               exceptionToCheck.getMessage().contains(expectedError));
+          Assert.assertTrue(
+              exceptionToCheck instanceof MissingSubcommandException);
+          Assert.assertTrue(
+              ((MissingSubcommandException)exceptionToCheck)
+                  .getUsage().contains(usage));
         }
         }
       }
       }
     }
     }

+ 2 - 1
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/BucketCommands.java

@@ -49,7 +49,8 @@ public class BucketCommands implements GenericParentCommand, Callable<Void> {
 
 
   @Override
   @Override
   public Void call() throws Exception {
   public Void call() throws Exception {
-    throw new MissingSubcommandException();
+    throw new MissingSubcommandException(
+        this.shell.getCmd().getSubcommands().get("bucket").getUsageMessage());
   }
   }
 
 
   @Override
   @Override

+ 2 - 1
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/KeyCommands.java

@@ -49,7 +49,8 @@ public class KeyCommands implements GenericParentCommand, Callable<Void> {
 
 
   @Override
   @Override
   public Void call() throws Exception {
   public Void call() throws Exception {
-    throw new MissingSubcommandException();
+    throw new MissingSubcommandException(
+        this.shell.getCmd().getSubcommands().get("key").getUsageMessage());
   }
   }
 
 
   @Override
   @Override

+ 2 - 1
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/VolumeCommands.java

@@ -50,7 +50,8 @@ public class VolumeCommands implements GenericParentCommand, Callable<Void> {
 
 
   @Override
   @Override
   public Void call() throws Exception {
   public Void call() throws Exception {
-    throw new MissingSubcommandException();
+    throw new MissingSubcommandException(
+        this.shell.getCmd().getSubcommands().get("volume").getUsageMessage());
   }
   }
 
 
   @Override
   @Override