Sfoglia il codice sorgente

HDFS-12118. Ozone: Ozone shell: Add more testing for volume shell commands. Contributed by Yiqun Lin.

Chen Liang 7 anni fa
parent
commit
27262d8889

+ 2 - 2
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/UpdateVolumeHandler.java

@@ -73,8 +73,8 @@ public class UpdateVolumeHandler extends Handler {
       quota = cmd.getOptionValue(Shell.QUOTA);
     }
 
-    if (cmd.hasOption(Shell.OWNER)) {
-      ownerName = cmd.getOptionValue(Shell.OWNER);
+    if (cmd.hasOption(Shell.USER)) {
+      ownerName = cmd.getOptionValue(Shell.USER);
     }
 
     client.setEndPointURI(ozoneURI);

+ 231 - 2
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java

@@ -18,7 +18,9 @@
 package org.apache.hadoop.ozone.ozShell;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -26,6 +28,8 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Random;
 
 import org.apache.commons.lang.RandomStringUtils;
@@ -36,11 +40,16 @@ import org.apache.hadoop.ozone.OzoneConfigKeys;
 import org.apache.hadoop.ozone.OzoneConfiguration;
 import org.apache.hadoop.ozone.OzoneConsts;
 import org.apache.hadoop.ozone.protocol.proto.KeySpaceManagerProtocolProtos.Status;
+import org.apache.hadoop.ozone.web.client.OzoneRestClient;
+import org.apache.hadoop.ozone.web.client.OzoneVolume;
 import org.apache.hadoop.ozone.web.exceptions.OzoneException;
 import org.apache.hadoop.ozone.web.ozShell.Shell;
+import org.apache.hadoop.ozone.web.request.OzoneQuota;
 import org.apache.hadoop.test.GenericTestUtils;
 import org.apache.hadoop.util.ToolRunner;
+import org.junit.After;
 import org.junit.AfterClass;
+import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
@@ -50,6 +59,7 @@ import org.junit.rules.Timeout;
  * This test class specified for testing Ozone shell command.
  */
 public class TestOzoneShell {
+
   /**
    * Set the timeout for every test.
    */
@@ -60,10 +70,13 @@ public class TestOzoneShell {
   private static File baseDir;
   private static OzoneConfiguration conf = null;
   private static MiniOzoneCluster cluster = null;
+  private static OzoneRestClient client = null;
   private static Shell shell = null;
 
   private final ByteArrayOutputStream out = new ByteArrayOutputStream();
   private final ByteArrayOutputStream err = new ByteArrayOutputStream();
+  private static final PrintStream OLD_OUT = System.out;
+  private static final PrintStream OLD_ERR = System.err;
 
   /**
    * Create a MiniDFSCluster for testing with using distributed Ozone
@@ -94,6 +107,8 @@ public class TestOzoneShell {
     DataNode dataNode = cluster.getDataNodes().get(0);
     final int port = dataNode.getInfoPort();
     url = String.format("http://localhost:%d", port);
+    client = new OzoneRestClient(String.format("http://localhost:%d", port));
+    client.setUserAuth(OzoneConsts.OZONE_SIMPLE_HDFS_USER);
   }
 
   /**
@@ -110,6 +125,203 @@ public class TestOzoneShell {
     }
   }
 
+  @Before
+  public void setup() {
+    System.setOut(new PrintStream(out));
+    System.setErr(new PrintStream(err));
+  }
+
+  @After
+  public void reset() {
+    // reset stream after each unit test
+    out.reset();
+    err.reset();
+
+    // restore system streams
+    System.setOut(OLD_OUT);
+    System.setErr(OLD_ERR);
+  }
+
+  @Test
+  public void testCreateVolume() throws Exception {
+    String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
+    String userName = "bilbo";
+    String[] args = new String[] {"-createVolume", url + "/" + volumeName,
+        "-user", userName, "-root"};
+
+    assertEquals(0, ToolRunner.run(shell, args));
+    OzoneVolume volumeInfo = client.getVolume(volumeName);
+    assertEquals(volumeName, volumeInfo.getVolumeName());
+    assertEquals(userName, volumeInfo.getOwnerName());
+  }
+
+  @Test
+  public void testDeleteVolume() throws Exception {
+    String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
+    OzoneVolume vol = client.createVolume(volumeName, "bilbo", "100TB");
+    assertNotNull(vol);
+
+    String[] args = new String[] {"-deleteVolume", url + "/" + volumeName,
+        "-root"};
+    assertEquals(0, ToolRunner.run(shell, args));
+
+    // verify if volume has been deleted
+    try {
+      client.getVolume(volumeName);
+      fail("Get volume call should have thrown.");
+    } catch (OzoneException e) {
+      GenericTestUtils.assertExceptionContains(
+          "Info Volume failed, error:VOLUME_NOT_FOUND", e);
+    }
+  }
+
+  @Test
+  public void testInfoVolume() throws Exception {
+    String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
+    client.createVolume(volumeName, "bilbo", "100TB");
+
+    String[] args = new String[] {"-infoVolume", url + "/" + volumeName,
+        "-root"};
+    assertEquals(0, ToolRunner.run(shell, args));
+    assertTrue(out.toString().contains(volumeName));
+
+    // get info for non-exist volume
+    args = new String[] {"-infoVolume", url + "/invalid-volume", "-root"};
+    assertEquals(1, ToolRunner.run(shell, args));
+    assertTrue(err.toString().contains(
+        "Info Volume failed, error:VOLUME_NOT_FOUND"));
+  }
+
+  @Test
+  public void testUpdateVolume() throws Exception {
+    String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
+    String userName = "bilbo";
+    OzoneVolume vol = client.createVolume(volumeName, userName, "100TB");
+    assertEquals(userName, vol.getOwnerName());
+    assertEquals(100, vol.getQuota().getSize(), 100);
+    assertEquals(OzoneQuota.Units.TB, vol.getQuota().getUnit());
+
+    String[] args = new String[] {"-updateVolume", url + "/" + volumeName,
+        "-quota", "500MB", "-root"};
+    assertEquals(0, ToolRunner.run(shell, args));
+    vol = client.getVolume(volumeName);
+    assertEquals(userName, vol.getOwnerName());
+    assertEquals(500, vol.getQuota().getSize(), 500);
+    assertEquals(OzoneQuota.Units.MB, vol.getQuota().getUnit());
+
+    String newUser = "new-user";
+    args = new String[] {"-updateVolume", url + "/" + volumeName,
+        "-user", newUser, "-root"};
+    assertEquals(0, ToolRunner.run(shell, args));
+    vol = client.getVolume(volumeName);
+    assertEquals(newUser, vol.getOwnerName());
+
+    // test error conditions
+    args = new String[] {"-updateVolume", url + "/invalid-volume",
+        "-user", newUser, "-root"};
+    assertEquals(1, ToolRunner.run(shell, args));
+    assertTrue(err.toString().contains(
+        "Volume owner change failed, error:VOLUME_NOT_FOUND"));
+
+    err.reset();
+    args = new String[] {"-updateVolume", url + "/invalid-volume",
+        "-quota", "500MB", "-root"};
+    assertEquals(1, ToolRunner.run(shell, args));
+    assertTrue(err.toString().contains(
+        "Volume quota change failed, error:VOLUME_NOT_FOUND"));
+  }
+
+  @Test
+  public void testListVolumes() throws Exception {
+    final int volCount = 20;
+    final String user1 = "test-user-a";
+    final String user2 = "test-user-b";
+
+    // Create 20 volumes, 10 for user1 and another 10 for user2.
+    for (int x = 0; x < volCount; x++) {
+      String volumeName;
+      String userName;
+
+      if (x % 2 == 0) {
+        // create volume [test-vol0, test-vol2, ..., test-vol18] for user1
+        userName = user1;
+        volumeName = "test-vol" + x;
+      } else {
+        // create volume [test-vol1, test-vol3, ..., test-vol19] for user2
+        userName = user2;
+        volumeName = "test-vol" + x;
+      }
+      OzoneVolume vol = client.createVolume(volumeName, userName, "100TB");
+      assertNotNull(vol);
+    }
+
+    // test -length option
+    String[] args = new String[] {"-listVolume", url + "/", "-user",
+        user1, "-length", "100"};
+    assertEquals(0, ToolRunner.run(shell, args));
+
+    List<String> names = getValueLines("name", out.toString());
+    List<String> volumes = getValueLines("volumeName", out.toString());
+    assertEquals(10, volumes.size());
+    assertEquals(10, names.size());
+    for (String user : names) {
+      assertTrue(user.contains(user1));
+    }
+
+    out.reset();
+    args = new String[] {"-listVolume", url + "/", "-user",
+        user1, "-length", "2"};
+    assertEquals(0, ToolRunner.run(shell, args));
+
+    volumes = getValueLines("volumeName", out.toString());
+    assertEquals(2, volumes.size());
+
+    // test -prefix option
+    out.reset();
+    args = new String[] {"-listVolume", url + "/", "-user",
+        user1, "-length", "100", "-prefix", "test-vol1"};
+    assertEquals(0, ToolRunner.run(shell, args));
+
+    names = getValueLines("name", out.toString());
+    volumes = getValueLines("volumeName", out.toString());
+    assertEquals(5, volumes.size());
+    assertEquals(5, names.size());
+    // return volume names should be [test-vol10, test-vol12, ..., test-vol18]
+    for (int i = 0; i < volumes.size(); i++) {
+      assertTrue(volumes.get(i).contains("test-vol" + ((i + 5) * 2)));
+      assertTrue(names.get(i).contains(user1));
+    }
+
+    // test -start option
+    out.reset();
+    args = new String[] {"-listVolume", url + "/", "-user",
+        user2, "-length", "100", "-start", "test-vol15"};
+    assertEquals(0, ToolRunner.run(shell, args));
+
+    names = getValueLines("name", out.toString());
+    volumes = getValueLines("volumeName", out.toString());
+    assertEquals(2, volumes.size());
+    assertTrue(volumes.get(0).contains("test-vol17")
+        && volumes.get(1).contains("test-vol19"));
+    assertTrue(names.get(0).contains(user2)
+        && names.get(1).contains(user2));
+
+    // test error conditions
+    err.reset();
+    args  = new String[] {"-listVolume", url + "/", "-user",
+        user2, "-length", "-1"};
+    assertEquals(1, ToolRunner.run(shell, args));
+    assertTrue(err.toString().contains(
+        "the vaule should be a positive number"));
+
+    err.reset();
+    args  = new String[] {"-listVolume", url + "/", "-user",
+        user2, "-length", "invalid-length"};
+    assertEquals(1, ToolRunner.run(shell, args));
+    assertTrue(err.toString().contains(
+        "the vaule should be digital"));
+  }
+
   @Test
   public void testGetKeyInfo() throws Exception {
     // create a volume
@@ -140,8 +352,6 @@ public class TestOzoneShell {
         tmpFile.getAbsolutePath()};
     assertEquals(0, ToolRunner.run(shell, args));
 
-    System.setOut(new PrintStream(out));
-    System.setErr(new PrintStream(err));
     args = new String[] {"-infoKey",
         url + "/" + volume + "/" + bucket + "/" + key};
 
@@ -162,4 +372,23 @@ public class TestOzoneShell {
     assertEquals(1, ToolRunner.run(shell, args));
     assertTrue(err.toString().contains(Status.KEY_NOT_FOUND.toString()));
   }
+
+  /**
+   * Extract lines from output string that contains specified key name.
+   * @param keyName Key name that line should contained.
+   * @param outputStr Response output content.
+   * @return List of string.
+   */
+  private List<String> getValueLines(String keyName, String outputStr) {
+    List<String> nameLines = new ArrayList<>();
+    String[] lines = outputStr.split("\n");
+
+    for (String line : lines) {
+      if (line.contains(keyName)) {
+        nameLines.add(line);
+      }
+    }
+
+    return nameLines;
+  }
 }