From 27262d88891f16288b21488cceecf71f6fd8addb Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Mon, 17 Jul 2017 11:35:15 -0700 Subject: [PATCH] HDFS-12118. Ozone: Ozone shell: Add more testing for volume shell commands. Contributed by Yiqun Lin. --- .../ozShell/volume/UpdateVolumeHandler.java | 4 +- .../hadoop/ozone/ozShell/TestOzoneShell.java | 233 +++++++++++++++++- 2 files changed, 233 insertions(+), 4 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/UpdateVolumeHandler.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/UpdateVolumeHandler.java index effc5c202ef..bdc2c59216b 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/UpdateVolumeHandler.java +++ b/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); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java index 7865b67cdcf..762e0c7f260 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java +++ b/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 names = getValueLines("name", out.toString()); + List 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 getValueLines(String keyName, String outputStr) { + List nameLines = new ArrayList<>(); + String[] lines = outputStr.split("\n"); + + for (String line : lines) { + if (line.contains(keyName)) { + nameLines.add(line); + } + } + + return nameLines; + } }