From 6ab25dfcd9cedecd43c30039ace33d1c234a7b43 Mon Sep 17 00:00:00 2001 From: Allen Wittenauer Date: Wed, 13 Aug 2014 19:10:24 +0000 Subject: [PATCH] HADOOP-8944. Shell command fs -count should include human readable option (Jonathan Allen via aw) (continued) git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1617802 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/hadoop/fs/TestContentSummary.java | 248 ++++++++++++++++ .../org/apache/hadoop/fs/shell/TestCount.java | 270 ++++++++++++++++++ 2 files changed, 518 insertions(+) create mode 100644 hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestContentSummary.java create mode 100644 hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/TestCount.java diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestContentSummary.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestContentSummary.java new file mode 100644 index 0000000000..9c8a8a4e06 --- /dev/null +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestContentSummary.java @@ -0,0 +1,248 @@ +/** + * 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.fs; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import org.junit.Test; +import org.mockito.InOrder; + +public class TestContentSummary { + + // check the empty constructor correctly initialises the object + @Test + public void testConstructorEmpty() { + ContentSummary contentSummary = new ContentSummary(); + assertEquals("getLength", 0, contentSummary.getLength()); + assertEquals("getFileCount", 0, contentSummary.getFileCount()); + assertEquals("getDirectoryCount", 0, contentSummary.getDirectoryCount()); + assertEquals("getQuota", 0, contentSummary.getQuota()); + assertEquals("getSpaceConsumed", 0, contentSummary.getSpaceConsumed()); + assertEquals("getSpaceQuota", 0, contentSummary.getSpaceQuota()); + } + + // check the full constructor with quota information + @Test + public void testConstructorWithQuota() { + long length = 11111; + long fileCount = 22222; + long directoryCount = 33333; + long quota = 44444; + long spaceConsumed = 55555; + long spaceQuota = 66666; + + ContentSummary contentSummary = new ContentSummary(length, fileCount, + directoryCount, quota, spaceConsumed, spaceQuota); + assertEquals("getLength", length, contentSummary.getLength()); + assertEquals("getFileCount", fileCount, contentSummary.getFileCount()); + assertEquals("getDirectoryCount", directoryCount, + contentSummary.getDirectoryCount()); + assertEquals("getQuota", quota, contentSummary.getQuota()); + assertEquals("getSpaceConsumed", spaceConsumed, + contentSummary.getSpaceConsumed()); + assertEquals("getSpaceQuota", spaceQuota, contentSummary.getSpaceQuota()); + } + + // check the constructor with quota information + @Test + public void testConstructorNoQuota() { + long length = 11111; + long fileCount = 22222; + long directoryCount = 33333; + + ContentSummary contentSummary = new ContentSummary(length, fileCount, + directoryCount); + assertEquals("getLength", length, contentSummary.getLength()); + assertEquals("getFileCount", fileCount, contentSummary.getFileCount()); + assertEquals("getDirectoryCount", directoryCount, + contentSummary.getDirectoryCount()); + assertEquals("getQuota", -1, contentSummary.getQuota()); + assertEquals("getSpaceConsumed", length, contentSummary.getSpaceConsumed()); + assertEquals("getSpaceQuota", -1, contentSummary.getSpaceQuota()); + } + + // check the write method + @Test + public void testWrite() throws IOException { + long length = 11111; + long fileCount = 22222; + long directoryCount = 33333; + long quota = 44444; + long spaceConsumed = 55555; + long spaceQuota = 66666; + + ContentSummary contentSummary = new ContentSummary(length, fileCount, + directoryCount, quota, spaceConsumed, spaceQuota); + + DataOutput out = mock(DataOutput.class); + InOrder inOrder = inOrder(out); + + contentSummary.write(out); + inOrder.verify(out).writeLong(length); + inOrder.verify(out).writeLong(fileCount); + inOrder.verify(out).writeLong(directoryCount); + inOrder.verify(out).writeLong(quota); + inOrder.verify(out).writeLong(spaceConsumed); + inOrder.verify(out).writeLong(spaceQuota); + } + + // check the readFields method + @Test + public void testReadFields() throws IOException { + long length = 11111; + long fileCount = 22222; + long directoryCount = 33333; + long quota = 44444; + long spaceConsumed = 55555; + long spaceQuota = 66666; + + ContentSummary contentSummary = new ContentSummary(); + + DataInput in = mock(DataInput.class); + when(in.readLong()).thenReturn(length).thenReturn(fileCount) + .thenReturn(directoryCount).thenReturn(quota).thenReturn(spaceConsumed) + .thenReturn(spaceQuota); + + contentSummary.readFields(in); + assertEquals("getLength", length, contentSummary.getLength()); + assertEquals("getFileCount", fileCount, contentSummary.getFileCount()); + assertEquals("getDirectoryCount", directoryCount, + contentSummary.getDirectoryCount()); + assertEquals("getQuota", quota, contentSummary.getQuota()); + assertEquals("getSpaceConsumed", spaceConsumed, + contentSummary.getSpaceConsumed()); + assertEquals("getSpaceQuota", spaceQuota, contentSummary.getSpaceQuota()); + } + + // check the header with quotas + @Test + public void testGetHeaderWithQuota() { + String header = " name quota rem name quota space quota " + + "rem space quota directories files bytes "; + assertEquals(header, ContentSummary.getHeader(true)); + } + + // check the header without quotas + @Test + public void testGetHeaderNoQuota() { + String header = " directories files bytes "; + assertEquals(header, ContentSummary.getHeader(false)); + } + + // check the toString method with quotas + @Test + public void testToStringWithQuota() { + long length = 11111; + long fileCount = 22222; + long directoryCount = 33333; + long quota = 44444; + long spaceConsumed = 55555; + long spaceQuota = 66665; + + ContentSummary contentSummary = new ContentSummary(length, fileCount, + directoryCount, quota, spaceConsumed, spaceQuota); + String expected = " 44444 -11111 66665 11110" + + " 33333 22222 11111 "; + assertEquals(expected, contentSummary.toString(true)); + } + + // check the toString method with quotas + @Test + public void testToStringNoQuota() { + long length = 11111; + long fileCount = 22222; + long directoryCount = 33333; + + ContentSummary contentSummary = new ContentSummary(length, fileCount, + directoryCount); + String expected = " none inf none" + + " inf 33333 22222 11111 "; + assertEquals(expected, contentSummary.toString(true)); + } + + // check the toString method with quotas + @Test + public void testToStringNoShowQuota() { + long length = 11111; + long fileCount = 22222; + long directoryCount = 33333; + long quota = 44444; + long spaceConsumed = 55555; + long spaceQuota = 66665; + + ContentSummary contentSummary = new ContentSummary(length, fileCount, + directoryCount, quota, spaceConsumed, spaceQuota); + String expected = " 33333 22222 11111 "; + assertEquals(expected, contentSummary.toString(false)); + } + + // check the toString method (defaults to with quotas) + @Test + public void testToString() { + long length = 11111; + long fileCount = 22222; + long directoryCount = 33333; + long quota = 44444; + long spaceConsumed = 55555; + long spaceQuota = 66665; + + ContentSummary contentSummary = new ContentSummary(length, fileCount, + directoryCount, quota, spaceConsumed, spaceQuota); + String expected = " 44444 -11111 66665" + + " 11110 33333 22222 11111 "; + assertEquals(expected, contentSummary.toString()); + } + + // check the toString method with quotas + @Test + public void testToStringHumanWithQuota() { + long length = Long.MAX_VALUE; + long fileCount = 222222222; + long directoryCount = 33333; + long quota = 222256578; + long spaceConsumed = 1073741825; + long spaceQuota = 1; + + ContentSummary contentSummary = new ContentSummary(length, fileCount, + directoryCount, quota, spaceConsumed, spaceQuota); + String expected = " 212.0 M 1023 1 " + + " -1 G 32.6 K 211.9 M 8.0 E "; + assertEquals(expected, contentSummary.toString(true, true)); + } + + // check the toString method with quotas + @Test + public void testToStringHumanNoShowQuota() { + long length = Long.MAX_VALUE; + long fileCount = 222222222; + long directoryCount = 33333; + long quota = 222256578; + long spaceConsumed = 55555; + long spaceQuota = Long.MAX_VALUE; + + ContentSummary contentSummary = new ContentSummary(length, fileCount, + directoryCount, quota, spaceConsumed, spaceQuota); + String expected = " 32.6 K 211.9 M 8.0 E "; + assertEquals(expected, contentSummary.toString(false, true)); + } +} diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/TestCount.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/TestCount.java new file mode 100644 index 0000000000..6c753c6a8f --- /dev/null +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/TestCount.java @@ -0,0 +1,270 @@ +/** + * 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.fs.shell; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.io.PrintStream; +import java.io.IOException; +import java.net.URI; +import java.util.LinkedList; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.ContentSummary; +import org.apache.hadoop.fs.FileStatus; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.FilterFileSystem; +import org.apache.hadoop.fs.Path; +import org.junit.Test; +import org.junit.Before; +import org.junit.BeforeClass; + +/** + * JUnit test class for {@link org.apache.hadoop.fs.shell.Count} + * + */ +public class TestCount { + private static final String WITH_QUOTAS = "Content summary with quotas"; + private static final String NO_QUOTAS = "Content summary without quotas"; + private static final String HUMAN = "human: "; + private static final String BYTES = "bytes: "; + private static Configuration conf; + private static FileSystem mockFs; + private static FileStatus fileStat; + private static ContentSummary mockCs; + + @BeforeClass + public static void setup() { + conf = new Configuration(); + conf.setClass("fs.mockfs.impl", MockFileSystem.class, FileSystem.class); + mockFs = mock(FileSystem.class); + fileStat = mock(FileStatus.class); + mockCs = mock(ContentSummary.class); + when(fileStat.isFile()).thenReturn(true); + } + + @Before + public void resetMock() { + reset(mockFs); + } + + @Test + public void processOptionsHumanReadable() { + LinkedList options = new LinkedList(); + options.add("-h"); + options.add("dummy"); + Count count = new Count(); + count.processOptions(options); + assertFalse(count.isShowQuotas()); + assertTrue(count.isHumanReadable()); + } + + @Test + public void processOptionsAll() { + LinkedList options = new LinkedList(); + options.add("-q"); + options.add("-h"); + options.add("dummy"); + Count count = new Count(); + count.processOptions(options); + assertTrue(count.isShowQuotas()); + assertTrue(count.isHumanReadable()); + } + + // check quotas are reported correctly + @Test + public void processPathShowQuotas() throws Exception { + Path path = new Path("mockfs:/test"); + + when(mockFs.getFileStatus(eq(path))).thenReturn(fileStat); + PathData pathData = new PathData(path.toString(), conf); + + PrintStream out = mock(PrintStream.class); + + Count count = new Count(); + count.out = out; + + LinkedList options = new LinkedList(); + options.add("-q"); + options.add("dummy"); + count.processOptions(options); + + count.processPath(pathData); + verify(out).println(BYTES + WITH_QUOTAS + path.toString()); + verifyNoMoreInteractions(out); + } + + // check counts without quotas are reported correctly + @Test + public void processPathNoQuotas() throws Exception { + Path path = new Path("mockfs:/test"); + + when(mockFs.getFileStatus(eq(path))).thenReturn(fileStat); + PathData pathData = new PathData(path.toString(), conf); + + PrintStream out = mock(PrintStream.class); + + Count count = new Count(); + count.out = out; + + LinkedList options = new LinkedList(); + options.add("dummy"); + count.processOptions(options); + + count.processPath(pathData); + verify(out).println(BYTES + NO_QUOTAS + path.toString()); + verifyNoMoreInteractions(out); + } + + @Test + public void processPathShowQuotasHuman() throws Exception { + Path path = new Path("mockfs:/test"); + + when(mockFs.getFileStatus(eq(path))).thenReturn(fileStat); + PathData pathData = new PathData(path.toString(), conf); + + PrintStream out = mock(PrintStream.class); + + Count count = new Count(); + count.out = out; + + LinkedList options = new LinkedList(); + options.add("-q"); + options.add("-h"); + options.add("dummy"); + count.processOptions(options); + + count.processPath(pathData); + verify(out).println(HUMAN + WITH_QUOTAS + path.toString()); + } + + @Test + public void processPathNoQuotasHuman() throws Exception { + Path path = new Path("mockfs:/test"); + + when(mockFs.getFileStatus(eq(path))).thenReturn(fileStat); + PathData pathData = new PathData(path.toString(), conf); + + PrintStream out = mock(PrintStream.class); + + Count count = new Count(); + count.out = out; + + LinkedList options = new LinkedList(); + options.add("-h"); + options.add("dummy"); + count.processOptions(options); + + count.processPath(pathData); + verify(out).println(HUMAN + NO_QUOTAS + path.toString()); + } + + @Test + public void getCommandName() { + Count count = new Count(); + String actual = count.getCommandName(); + String expected = "count"; + assertEquals("Count.getCommandName", expected, actual); + } + + @Test + public void isDeprecated() { + Count count = new Count(); + boolean actual = count.isDeprecated(); + boolean expected = false; + assertEquals("Count.isDeprecated", expected, actual); + } + + @Test + public void getReplacementCommand() { + Count count = new Count(); + String actual = count.getReplacementCommand(); + String expected = null; + assertEquals("Count.getReplacementCommand", expected, actual); + } + + @Test + public void getName() { + Count count = new Count(); + String actual = count.getName(); + String expected = "count"; + assertEquals("Count.getName", expected, actual); + } + + @Test + public void getUsage() { + Count count = new Count(); + String actual = count.getUsage(); + String expected = "-count [-q] [-h] ..."; + assertEquals("Count.getUsage", expected, actual); + } + + + // mock content system + static class MockContentSummary extends ContentSummary { + + public MockContentSummary() {} + + @Override + public String toString(boolean qOption, boolean hOption) { + if (qOption) { + if (hOption) { + return(HUMAN + WITH_QUOTAS); + } else { + return(BYTES + WITH_QUOTAS); + } + } else { + if (hOption) { + return(HUMAN + NO_QUOTAS); + } else { + return(BYTES + NO_QUOTAS); + } + } + } + } + + // mock file system for use in testing + static class MockFileSystem extends FilterFileSystem { + Configuration conf; + + MockFileSystem() { + super(mockFs); + } + + @Override + public void initialize(URI uri, Configuration conf) { + this.conf = conf; + } + + @Override + public Path makeQualified(Path path) { + return path; + } + + @Override + public ContentSummary getContentSummary(Path f) throws IOException { + return new MockContentSummary(); + } + + @Override + public Configuration getConf() { + return conf; + } + } +}