|
@@ -17,29 +17,592 @@
|
|
*/
|
|
*/
|
|
package org.apache.hadoop.io;
|
|
package org.apache.hadoop.io;
|
|
|
|
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.io.InputStream;
|
|
|
|
+import java.io.OutputStream;
|
|
|
|
+
|
|
import org.apache.hadoop.conf.Configuration;
|
|
import org.apache.hadoop.conf.Configuration;
|
|
import org.apache.hadoop.fs.FileSystem;
|
|
import org.apache.hadoop.fs.FileSystem;
|
|
|
|
+import org.apache.hadoop.fs.LocalFileSystem;
|
|
import org.apache.hadoop.fs.Path;
|
|
import org.apache.hadoop.fs.Path;
|
|
|
|
+import org.apache.hadoop.io.SequenceFile.CompressionType;
|
|
|
|
+import org.apache.hadoop.io.compress.CompressionCodec;
|
|
|
|
+import org.apache.hadoop.io.compress.CompressionInputStream;
|
|
|
|
+import org.apache.hadoop.io.compress.CompressionOutputStream;
|
|
|
|
+import org.apache.hadoop.io.compress.Compressor;
|
|
|
|
+import org.apache.hadoop.io.compress.Decompressor;
|
|
|
|
+import org.apache.hadoop.util.Progressable;
|
|
|
|
+import org.junit.Assert;
|
|
|
|
+import org.junit.Before;
|
|
|
|
+import org.junit.Test;
|
|
|
|
+
|
|
|
|
+import static org.junit.Assert.*;
|
|
|
|
|
|
-import junit.framework.TestCase;
|
|
|
|
|
|
+import static org.mockito.Mockito.*;
|
|
|
|
|
|
-public class TestMapFile extends TestCase {
|
|
|
|
|
|
+public class TestMapFile {
|
|
|
|
+
|
|
|
|
+ private static final Path TEST_DIR = new Path(
|
|
|
|
+ System.getProperty("test.build.data", "/tmp"),
|
|
|
|
+ TestMapFile.class.getSimpleName());
|
|
|
|
+
|
|
private static Configuration conf = new Configuration();
|
|
private static Configuration conf = new Configuration();
|
|
|
|
|
|
|
|
+ @Before
|
|
|
|
+ public void setup() throws Exception {
|
|
|
|
+ LocalFileSystem fs = FileSystem.getLocal(conf);
|
|
|
|
+ if (fs.exists(TEST_DIR) && !fs.delete(TEST_DIR, true)) {
|
|
|
|
+ Assert.fail("Can't clean up test root dir");
|
|
|
|
+ }
|
|
|
|
+ fs.mkdirs(TEST_DIR);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static final Progressable defaultProgressable = new Progressable() {
|
|
|
|
+ @Override
|
|
|
|
+ public void progress() {
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ private static final CompressionCodec defaultCodec = new CompressionCodec() {
|
|
|
|
+ @Override
|
|
|
|
+ public CompressionOutputStream createOutputStream(OutputStream out)
|
|
|
|
+ throws IOException {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public CompressionOutputStream createOutputStream(OutputStream out,
|
|
|
|
+ Compressor compressor) throws IOException {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Class<? extends Compressor> getCompressorType() {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Compressor createCompressor() {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public CompressionInputStream createInputStream(InputStream in)
|
|
|
|
+ throws IOException {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public CompressionInputStream createInputStream(InputStream in,
|
|
|
|
+ Decompressor decompressor) throws IOException {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Class<? extends Decompressor> getDecompressorType() {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Decompressor createDecompressor() {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String getDefaultExtension() {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ private MapFile.Writer createWriter(String fileName,
|
|
|
|
+ Class<? extends WritableComparable<?>> keyClass,
|
|
|
|
+ Class<? extends Writable> valueClass) throws IOException {
|
|
|
|
+ Path dirName = new Path(TEST_DIR, fileName);
|
|
|
|
+ MapFile.Writer.setIndexInterval(conf, 4);
|
|
|
|
+ return new MapFile.Writer(conf, dirName, MapFile.Writer.keyClass(keyClass),
|
|
|
|
+ MapFile.Writer.valueClass(valueClass));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private MapFile.Reader createReader(String fileName,
|
|
|
|
+ Class<? extends WritableComparable<?>> keyClass) throws IOException {
|
|
|
|
+ Path dirName = new Path(TEST_DIR, fileName);
|
|
|
|
+ return new MapFile.Reader(dirName, conf,
|
|
|
|
+ MapFile.Reader.comparator(new WritableComparator(keyClass)));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Reader.getClosest()} method
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testGetClosestOnCurrentApi() throws Exception {
|
|
|
|
+ final String TEST_PREFIX = "testGetClosestOnCurrentApi.mapfile";
|
|
|
|
+ MapFile.Writer writer = createWriter(TEST_PREFIX, Text.class, Text.class);
|
|
|
|
+ int FIRST_KEY = 1;
|
|
|
|
+ // Test keys: 11,21,31,...,91
|
|
|
|
+ for (int i = FIRST_KEY; i < 100; i += 10) {
|
|
|
|
+ Text t = new Text(Integer.toString(i));
|
|
|
|
+ writer.append(t, t);
|
|
|
|
+ }
|
|
|
|
+ writer.close();
|
|
|
|
+
|
|
|
|
+ MapFile.Reader reader = createReader(TEST_PREFIX, Text.class);
|
|
|
|
+ Text key = new Text("55");
|
|
|
|
+ Text value = new Text();
|
|
|
|
+
|
|
|
|
+ // Test get closest with step forward
|
|
|
|
+ Text closest = (Text) reader.getClosest(key, value);
|
|
|
|
+ assertEquals(new Text("61"), closest);
|
|
|
|
+
|
|
|
|
+ // Test get closest with step back
|
|
|
|
+ closest = (Text) reader.getClosest(key, value, true);
|
|
|
|
+ assertEquals(new Text("51"), closest);
|
|
|
|
+
|
|
|
|
+ // Test get closest when we pass explicit key
|
|
|
|
+ final Text explicitKey = new Text("21");
|
|
|
|
+ closest = (Text) reader.getClosest(explicitKey, value);
|
|
|
|
+ assertEquals(new Text("21"), explicitKey);
|
|
|
|
+
|
|
|
|
+ // Test what happens at boundaries. Assert if searching a key that is
|
|
|
|
+ // less than first key in the mapfile, that the first key is returned.
|
|
|
|
+ key = new Text("00");
|
|
|
|
+ closest = (Text) reader.getClosest(key, value);
|
|
|
|
+ assertEquals(FIRST_KEY, Integer.parseInt(closest.toString()));
|
|
|
|
+
|
|
|
|
+ // Assert that null is returned if key is > last entry in mapfile.
|
|
|
|
+ key = new Text("92");
|
|
|
|
+ closest = (Text) reader.getClosest(key, value);
|
|
|
|
+ assertNull("Not null key in testGetClosestWithNewCode", closest);
|
|
|
|
+
|
|
|
|
+ // If we were looking for the key before, we should get the last key
|
|
|
|
+ closest = (Text) reader.getClosest(key, value, true);
|
|
|
|
+ assertEquals(new Text("91"), closest);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Reader.midKey() } method
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testMidKeyOnCurrentApi() throws Exception {
|
|
|
|
+ // Write a mapfile of simple data: keys are
|
|
|
|
+ final String TEST_PREFIX = "testMidKeyOnCurrentApi.mapfile";
|
|
|
|
+ MapFile.Writer writer = createWriter(TEST_PREFIX, IntWritable.class,
|
|
|
|
+ IntWritable.class);
|
|
|
|
+ // 0,1,....9
|
|
|
|
+ int SIZE = 10;
|
|
|
|
+ for (int i = 0; i < SIZE; i++)
|
|
|
|
+ writer.append(new IntWritable(i), new IntWritable(i));
|
|
|
|
+ writer.close();
|
|
|
|
+
|
|
|
|
+ MapFile.Reader reader = createReader(TEST_PREFIX, IntWritable.class);
|
|
|
|
+ assertEquals(new IntWritable((SIZE - 1) / 2), reader.midKey());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Writer.rename()} method
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testRename() {
|
|
|
|
+ final String NEW_FILE_NAME = "test-new.mapfile";
|
|
|
|
+ final String OLD_FILE_NAME = "test-old.mapfile";
|
|
|
|
+ try {
|
|
|
|
+ FileSystem fs = FileSystem.getLocal(conf);
|
|
|
|
+ MapFile.Writer writer = createWriter(OLD_FILE_NAME, IntWritable.class,
|
|
|
|
+ IntWritable.class);
|
|
|
|
+ writer.close();
|
|
|
|
+ MapFile.rename(fs, new Path(TEST_DIR, OLD_FILE_NAME).toString(),
|
|
|
|
+ new Path(TEST_DIR, NEW_FILE_NAME).toString());
|
|
|
|
+ MapFile.delete(fs, new Path(TEST_DIR, NEW_FILE_NAME).toString());
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
+ fail("testRename error " + ex);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.rename()}
|
|
|
|
+ * method with throwing {@code IOException}
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testRenameWithException() {
|
|
|
|
+ final String ERROR_MESSAGE = "Can't rename file";
|
|
|
|
+ final String NEW_FILE_NAME = "test-new.mapfile";
|
|
|
|
+ final String OLD_FILE_NAME = "test-old.mapfile";
|
|
|
|
+ try {
|
|
|
|
+ FileSystem fs = FileSystem.getLocal(conf);
|
|
|
|
+ FileSystem spyFs = spy(fs);
|
|
|
|
+
|
|
|
|
+ MapFile.Writer writer = createWriter(OLD_FILE_NAME, IntWritable.class,
|
|
|
|
+ IntWritable.class);
|
|
|
|
+ writer.close();
|
|
|
|
+
|
|
|
|
+ Path oldDir = new Path(TEST_DIR, OLD_FILE_NAME);
|
|
|
|
+ Path newDir = new Path(TEST_DIR, NEW_FILE_NAME);
|
|
|
|
+ when(spyFs.rename(oldDir, newDir)).thenThrow(
|
|
|
|
+ new IOException(ERROR_MESSAGE));
|
|
|
|
+
|
|
|
|
+ MapFile.rename(spyFs, oldDir.toString(), newDir.toString());
|
|
|
|
+ fail("testRenameWithException no exception error !!!");
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
+ assertEquals("testRenameWithException invalid IOExceptionMessage !!!",
|
|
|
|
+ ex.getMessage(), ERROR_MESSAGE);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testRenameWithFalse() {
|
|
|
|
+ final String ERROR_MESSAGE = "Could not rename";
|
|
|
|
+ final String NEW_FILE_NAME = "test-new.mapfile";
|
|
|
|
+ final String OLD_FILE_NAME = "test-old.mapfile";
|
|
|
|
+ try {
|
|
|
|
+ FileSystem fs = FileSystem.getLocal(conf);
|
|
|
|
+ FileSystem spyFs = spy(fs);
|
|
|
|
+
|
|
|
|
+ MapFile.Writer writer = createWriter(OLD_FILE_NAME, IntWritable.class,
|
|
|
|
+ IntWritable.class);
|
|
|
|
+ writer.close();
|
|
|
|
+
|
|
|
|
+ Path oldDir = new Path(TEST_DIR, OLD_FILE_NAME);
|
|
|
|
+ Path newDir = new Path(TEST_DIR, NEW_FILE_NAME);
|
|
|
|
+ when(spyFs.rename(oldDir, newDir)).thenReturn(false);
|
|
|
|
+
|
|
|
|
+ MapFile.rename(spyFs, oldDir.toString(), newDir.toString());
|
|
|
|
+ fail("testRenameWithException no exception error !!!");
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
+ assertTrue("testRenameWithFalse invalid IOExceptionMessage error !!!", ex
|
|
|
|
+ .getMessage().startsWith(ERROR_MESSAGE));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test throwing {@code IOException} in {@code MapFile.Writer} constructor
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testWriteWithFailDirCreation() {
|
|
|
|
+ String ERROR_MESSAGE = "Mkdirs failed to create directory";
|
|
|
|
+ Path dirName = new Path(TEST_DIR, "fail.mapfile");
|
|
|
|
+ MapFile.Writer writer = null;
|
|
|
|
+ try {
|
|
|
|
+ FileSystem fs = FileSystem.getLocal(conf);
|
|
|
|
+ FileSystem spyFs = spy(fs);
|
|
|
|
+ Path pathSpy = spy(dirName);
|
|
|
|
+ when(pathSpy.getFileSystem(conf)).thenReturn(spyFs);
|
|
|
|
+ when(spyFs.mkdirs(dirName)).thenReturn(false);
|
|
|
|
+
|
|
|
|
+ writer = new MapFile.Writer(conf, pathSpy,
|
|
|
|
+ MapFile.Writer.keyClass(IntWritable.class),
|
|
|
|
+ MapFile.Writer.valueClass(Text.class));
|
|
|
|
+ fail("testWriteWithFailDirCreation error !!!");
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
+ assertTrue("testWriteWithFailDirCreation ex error !!!", ex.getMessage()
|
|
|
|
+ .startsWith(ERROR_MESSAGE));
|
|
|
|
+ } finally {
|
|
|
|
+ if (writer != null)
|
|
|
|
+ try {
|
|
|
|
+ writer.close();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Reader.finalKey()} method
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testOnFinalKey() {
|
|
|
|
+ final String TEST_METHOD_KEY = "testOnFinalKey.mapfile";
|
|
|
|
+ int SIZE = 10;
|
|
|
|
+ try {
|
|
|
|
+ MapFile.Writer writer = createWriter(TEST_METHOD_KEY, IntWritable.class,
|
|
|
|
+ IntWritable.class);
|
|
|
|
+ for (int i = 0; i < SIZE; i++)
|
|
|
|
+ writer.append(new IntWritable(i), new IntWritable(i));
|
|
|
|
+ writer.close();
|
|
|
|
+
|
|
|
|
+ MapFile.Reader reader = createReader(TEST_METHOD_KEY, IntWritable.class);
|
|
|
|
+ IntWritable expectedKey = new IntWritable(0);
|
|
|
|
+ reader.finalKey(expectedKey);
|
|
|
|
+ assertEquals("testOnFinalKey not same !!!", expectedKey, new IntWritable(
|
|
|
|
+ 9));
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
+ fail("testOnFinalKey error !!!");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Writer} constructor with key, value
|
|
|
|
+ * and validate it with {@code keyClass(), valueClass()} methods
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testKeyValueClasses() {
|
|
|
|
+ Class<? extends WritableComparable<?>> keyClass = IntWritable.class;
|
|
|
|
+ Class<?> valueClass = Text.class;
|
|
|
|
+ try {
|
|
|
|
+ createWriter("testKeyValueClasses.mapfile", IntWritable.class, Text.class);
|
|
|
|
+ assertNotNull("writer key class null error !!!",
|
|
|
|
+ MapFile.Writer.keyClass(keyClass));
|
|
|
|
+ assertNotNull("writer value class null error !!!",
|
|
|
|
+ MapFile.Writer.valueClass(valueClass));
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
+ fail(ex.getMessage());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Reader.getClosest() } with wrong class key
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testReaderGetClosest() throws Exception {
|
|
|
|
+ final String TEST_METHOD_KEY = "testReaderWithWrongKeyClass.mapfile";
|
|
|
|
+ try {
|
|
|
|
+ MapFile.Writer writer = createWriter(TEST_METHOD_KEY, IntWritable.class,
|
|
|
|
+ Text.class);
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < 10; i++)
|
|
|
|
+ writer.append(new IntWritable(i), new Text("value" + i));
|
|
|
|
+ writer.close();
|
|
|
|
+
|
|
|
|
+ MapFile.Reader reader = createReader(TEST_METHOD_KEY, Text.class);
|
|
|
|
+ reader.getClosest(new Text("2"), new Text(""));
|
|
|
|
+ fail("no excepted exception in testReaderWithWrongKeyClass !!!");
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
+ /* Should be thrown to pass the test */
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Writer.append() } with wrong key class
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testReaderWithWrongValueClass() {
|
|
|
|
+ final String TEST_METHOD_KEY = "testReaderWithWrongValueClass.mapfile";
|
|
|
|
+ try {
|
|
|
|
+ MapFile.Writer writer = createWriter(TEST_METHOD_KEY, IntWritable.class,
|
|
|
|
+ Text.class);
|
|
|
|
+ writer.append(new IntWritable(0), new IntWritable(0));
|
|
|
|
+ fail("no excepted exception in testReaderWithWrongKeyClass !!!");
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
+ /* Should be thrown to pass the test */
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Reader.next(key, value)} for iteration.
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testReaderKeyIteration() {
|
|
|
|
+ final String TEST_METHOD_KEY = "testReaderKeyIteration.mapfile";
|
|
|
|
+ int SIZE = 10;
|
|
|
|
+ int ITERATIONS = 5;
|
|
|
|
+ try {
|
|
|
|
+ MapFile.Writer writer = createWriter(TEST_METHOD_KEY, IntWritable.class,
|
|
|
|
+ Text.class);
|
|
|
|
+ int start = 0;
|
|
|
|
+ for (int i = 0; i < SIZE; i++)
|
|
|
|
+ writer.append(new IntWritable(i), new Text("Value:" + i));
|
|
|
|
+ writer.close();
|
|
|
|
+
|
|
|
|
+ MapFile.Reader reader = createReader(TEST_METHOD_KEY, IntWritable.class);
|
|
|
|
+ // test iteration
|
|
|
|
+ Writable startValue = new Text("Value:" + start);
|
|
|
|
+ int i = 0;
|
|
|
|
+ while (i++ < ITERATIONS) {
|
|
|
|
+ IntWritable key = new IntWritable(start);
|
|
|
|
+ Writable value = startValue;
|
|
|
|
+ while (reader.next(key, value)) {
|
|
|
|
+ assertNotNull(key);
|
|
|
|
+ assertNotNull(value);
|
|
|
|
+ }
|
|
|
|
+ reader.reset();
|
|
|
|
+ }
|
|
|
|
+ assertTrue("reader seek error !!!",
|
|
|
|
+ reader.seek(new IntWritable(SIZE / 2)));
|
|
|
|
+ assertFalse("reader seek error !!!",
|
|
|
|
+ reader.seek(new IntWritable(SIZE * 2)));
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
+ fail("reader seek error !!!");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Writer.testFix} method
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testFix() {
|
|
|
|
+ final String INDEX_LESS_MAP_FILE = "testFix.mapfile";
|
|
|
|
+ int PAIR_SIZE = 20;
|
|
|
|
+ try {
|
|
|
|
+ FileSystem fs = FileSystem.getLocal(conf);
|
|
|
|
+ Path dir = new Path(TEST_DIR, INDEX_LESS_MAP_FILE);
|
|
|
|
+ MapFile.Writer writer = createWriter(INDEX_LESS_MAP_FILE,
|
|
|
|
+ IntWritable.class, Text.class);
|
|
|
|
+ for (int i = 0; i < PAIR_SIZE; i++)
|
|
|
|
+ writer.append(new IntWritable(0), new Text("value"));
|
|
|
|
+ writer.close();
|
|
|
|
+
|
|
|
|
+ File indexFile = new File(".", "." + INDEX_LESS_MAP_FILE + "/index");
|
|
|
|
+ boolean isDeleted = false;
|
|
|
|
+ if (indexFile.exists())
|
|
|
|
+ isDeleted = indexFile.delete();
|
|
|
|
+
|
|
|
|
+ if (isDeleted)
|
|
|
|
+ assertTrue("testFix error !!!",
|
|
|
|
+ MapFile.fix(fs, dir, IntWritable.class, Text.class, true, conf) == PAIR_SIZE);
|
|
|
|
+ } catch (Exception ex) {
|
|
|
|
+ fail("testFix error !!!");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * test all available constructor for {@code MapFile.Writer}
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ @SuppressWarnings("deprecation")
|
|
|
|
+ public void testDeprecatedConstructors() {
|
|
|
|
+ String path = new Path(TEST_DIR, "writes.mapfile").toString();
|
|
|
|
+ try {
|
|
|
|
+ FileSystem fs = FileSystem.getLocal(conf);
|
|
|
|
+ MapFile.Writer writer = new MapFile.Writer(conf, fs, path,
|
|
|
|
+ IntWritable.class, Text.class, CompressionType.RECORD);
|
|
|
|
+ assertNotNull(writer);
|
|
|
|
+ writer = new MapFile.Writer(conf, fs, path, IntWritable.class,
|
|
|
|
+ Text.class, CompressionType.RECORD, defaultProgressable);
|
|
|
|
+ assertNotNull(writer);
|
|
|
|
+ writer = new MapFile.Writer(conf, fs, path, IntWritable.class,
|
|
|
|
+ Text.class, CompressionType.RECORD, defaultCodec, defaultProgressable);
|
|
|
|
+ assertNotNull(writer);
|
|
|
|
+ writer = new MapFile.Writer(conf, fs, path,
|
|
|
|
+ WritableComparator.get(Text.class), Text.class);
|
|
|
|
+ assertNotNull(writer);
|
|
|
|
+ writer = new MapFile.Writer(conf, fs, path,
|
|
|
|
+ WritableComparator.get(Text.class), Text.class,
|
|
|
|
+ SequenceFile.CompressionType.RECORD);
|
|
|
|
+ assertNotNull(writer);
|
|
|
|
+ writer = new MapFile.Writer(conf, fs, path,
|
|
|
|
+ WritableComparator.get(Text.class), Text.class,
|
|
|
|
+ CompressionType.RECORD, defaultProgressable);
|
|
|
|
+ assertNotNull(writer);
|
|
|
|
+ writer.close();
|
|
|
|
+
|
|
|
|
+ MapFile.Reader reader = new MapFile.Reader(fs, path,
|
|
|
|
+ WritableComparator.get(IntWritable.class), conf);
|
|
|
|
+ assertNotNull(reader);
|
|
|
|
+ assertNotNull("reader key is null !!!", reader.getKeyClass());
|
|
|
|
+ assertNotNull("reader value in null", reader.getValueClass());
|
|
|
|
+
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ fail(e.getMessage());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Writer} constructor
|
|
|
|
+ * with IllegalArgumentException
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testKeyLessWriterCreation() {
|
|
|
|
+ MapFile.Writer writer = null;
|
|
|
|
+ try {
|
|
|
|
+ writer = new MapFile.Writer(conf, TEST_DIR);
|
|
|
|
+ fail("fail in testKeyLessWriterCreation !!!");
|
|
|
|
+ } catch (IllegalArgumentException ex) {
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ fail("fail in testKeyLessWriterCreation. Other ex !!!");
|
|
|
|
+ } finally {
|
|
|
|
+ if (writer != null)
|
|
|
|
+ try {
|
|
|
|
+ writer.close();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Writer} constructor with IOException
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testPathExplosionWriterCreation() {
|
|
|
|
+ Path path = new Path(TEST_DIR, "testPathExplosionWriterCreation.mapfile");
|
|
|
|
+ String TEST_ERROR_MESSAGE = "Mkdirs failed to create directory "
|
|
|
|
+ + path.getName();
|
|
|
|
+ MapFile.Writer writer = null;
|
|
|
|
+ try {
|
|
|
|
+ FileSystem fsSpy = spy(FileSystem.get(conf));
|
|
|
|
+ Path pathSpy = spy(path);
|
|
|
|
+ when(fsSpy.mkdirs(path)).thenThrow(new IOException(TEST_ERROR_MESSAGE));
|
|
|
|
+
|
|
|
|
+ when(pathSpy.getFileSystem(conf)).thenReturn(fsSpy);
|
|
|
|
+
|
|
|
|
+ writer = new MapFile.Writer(conf, pathSpy,
|
|
|
|
+ MapFile.Writer.keyClass(IntWritable.class),
|
|
|
|
+ MapFile.Writer.valueClass(IntWritable.class));
|
|
|
|
+ fail("fail in testPathExplosionWriterCreation !!!");
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
+ assertEquals("testPathExplosionWriterCreation ex message error !!!",
|
|
|
|
+ ex.getMessage(), TEST_ERROR_MESSAGE);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ fail("fail in testPathExplosionWriterCreation. Other ex !!!");
|
|
|
|
+ } finally {
|
|
|
|
+ if (writer != null)
|
|
|
|
+ try {
|
|
|
|
+ writer.close();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * test {@code MapFile.Writer.append} method with desc order
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testDescOrderWithThrowExceptionWriterAppend() {
|
|
|
|
+ try {
|
|
|
|
+ MapFile.Writer writer = createWriter(".mapfile", IntWritable.class,
|
|
|
|
+ Text.class);
|
|
|
|
+ writer.append(new IntWritable(2), new Text("value: " + 1));
|
|
|
|
+ writer.append(new IntWritable(2), new Text("value: " + 2));
|
|
|
|
+ writer.append(new IntWritable(2), new Text("value: " + 4));
|
|
|
|
+ writer.append(new IntWritable(1), new Text("value: " + 3));
|
|
|
|
+ fail("testDescOrderWithThrowExceptionWriterAppend not expected exception error !!!");
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ fail("testDescOrderWithThrowExceptionWriterAppend other ex throw !!!");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testMainMethodMapFile() {
|
|
|
|
+ String path = new Path(TEST_DIR, "mainMethodMapFile.mapfile").toString();
|
|
|
|
+ String inFile = "mainMethodMapFile.mapfile";
|
|
|
|
+ String outFile = "mainMethodMapFile.mapfile";
|
|
|
|
+ String[] args = { path, outFile };
|
|
|
|
+ try {
|
|
|
|
+ MapFile.Writer writer = createWriter(inFile, IntWritable.class,
|
|
|
|
+ Text.class);
|
|
|
|
+ writer.append(new IntWritable(1), new Text("test_text1"));
|
|
|
|
+ writer.append(new IntWritable(2), new Text("test_text2"));
|
|
|
|
+ writer.close();
|
|
|
|
+ MapFile.main(args);
|
|
|
|
+ } catch (Exception ex) {
|
|
|
|
+ fail("testMainMethodMapFile error !!!");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Test getClosest feature.
|
|
* Test getClosest feature.
|
|
|
|
+ *
|
|
* @throws Exception
|
|
* @throws Exception
|
|
*/
|
|
*/
|
|
|
|
+ @Test
|
|
|
|
+ @SuppressWarnings("deprecation")
|
|
public void testGetClosest() throws Exception {
|
|
public void testGetClosest() throws Exception {
|
|
- // Write a mapfile of simple data: keys are
|
|
|
|
- Path dirName = new Path(System.getProperty("test.build.data",".") +
|
|
|
|
- getName() + ".mapfile");
|
|
|
|
|
|
+ // Write a mapfile of simple data: keys are
|
|
|
|
+ Path dirName = new Path(TEST_DIR, "testGetClosest.mapfile");
|
|
FileSystem fs = FileSystem.getLocal(conf);
|
|
FileSystem fs = FileSystem.getLocal(conf);
|
|
Path qualifiedDirName = fs.makeQualified(dirName);
|
|
Path qualifiedDirName = fs.makeQualified(dirName);
|
|
// Make an index entry for every third insertion.
|
|
// Make an index entry for every third insertion.
|
|
MapFile.Writer.setIndexInterval(conf, 3);
|
|
MapFile.Writer.setIndexInterval(conf, 3);
|
|
MapFile.Writer writer = new MapFile.Writer(conf, fs,
|
|
MapFile.Writer writer = new MapFile.Writer(conf, fs,
|
|
- qualifiedDirName.toString(), Text.class, Text.class);
|
|
|
|
|
|
+ qualifiedDirName.toString(), Text.class, Text.class);
|
|
// Assert that the index interval is 1
|
|
// Assert that the index interval is 1
|
|
assertEquals(3, writer.getIndexInterval());
|
|
assertEquals(3, writer.getIndexInterval());
|
|
// Add entries up to 100 in intervals of ten.
|
|
// Add entries up to 100 in intervals of ten.
|
|
@@ -51,74 +614,84 @@ public class TestMapFile extends TestCase {
|
|
}
|
|
}
|
|
writer.close();
|
|
writer.close();
|
|
// Now do getClosest on created mapfile.
|
|
// Now do getClosest on created mapfile.
|
|
- MapFile.Reader reader = new MapFile.Reader(fs, qualifiedDirName.toString(),
|
|
|
|
- conf);
|
|
|
|
|
|
+ MapFile.Reader reader = new MapFile.Reader(qualifiedDirName, conf);
|
|
|
|
+ try {
|
|
Text key = new Text("55");
|
|
Text key = new Text("55");
|
|
Text value = new Text();
|
|
Text value = new Text();
|
|
- Text closest = (Text)reader.getClosest(key, value);
|
|
|
|
|
|
+ Text closest = (Text) reader.getClosest(key, value);
|
|
// Assert that closest after 55 is 60
|
|
// Assert that closest after 55 is 60
|
|
assertEquals(new Text("60"), closest);
|
|
assertEquals(new Text("60"), closest);
|
|
// Get closest that falls before the passed key: 50
|
|
// Get closest that falls before the passed key: 50
|
|
- closest = (Text)reader.getClosest(key, value, true);
|
|
|
|
|
|
+ closest = (Text) reader.getClosest(key, value, true);
|
|
assertEquals(new Text("50"), closest);
|
|
assertEquals(new Text("50"), closest);
|
|
// Test get closest when we pass explicit key
|
|
// Test get closest when we pass explicit key
|
|
final Text TWENTY = new Text("20");
|
|
final Text TWENTY = new Text("20");
|
|
- closest = (Text)reader.getClosest(TWENTY, value);
|
|
|
|
|
|
+ closest = (Text) reader.getClosest(TWENTY, value);
|
|
assertEquals(TWENTY, closest);
|
|
assertEquals(TWENTY, closest);
|
|
- closest = (Text)reader.getClosest(TWENTY, value, true);
|
|
|
|
|
|
+ closest = (Text) reader.getClosest(TWENTY, value, true);
|
|
assertEquals(TWENTY, closest);
|
|
assertEquals(TWENTY, closest);
|
|
- // Test what happens at boundaries. Assert if searching a key that is
|
|
|
|
|
|
+ // Test what happens at boundaries. Assert if searching a key that is
|
|
// less than first key in the mapfile, that the first key is returned.
|
|
// less than first key in the mapfile, that the first key is returned.
|
|
key = new Text("00");
|
|
key = new Text("00");
|
|
- closest = (Text)reader.getClosest(key, value);
|
|
|
|
|
|
+ closest = (Text) reader.getClosest(key, value);
|
|
assertEquals(FIRST_KEY, Integer.parseInt(closest.toString()));
|
|
assertEquals(FIRST_KEY, Integer.parseInt(closest.toString()));
|
|
-
|
|
|
|
- // If we're looking for the first key before, and we pass in a key before
|
|
|
|
|
|
+
|
|
|
|
+ // If we're looking for the first key before, and we pass in a key before
|
|
// the first key in the file, we should get null
|
|
// the first key in the file, we should get null
|
|
- closest = (Text)reader.getClosest(key, value, true);
|
|
|
|
|
|
+ closest = (Text) reader.getClosest(key, value, true);
|
|
assertNull(closest);
|
|
assertNull(closest);
|
|
-
|
|
|
|
|
|
+
|
|
// Assert that null is returned if key is > last entry in mapfile.
|
|
// Assert that null is returned if key is > last entry in mapfile.
|
|
key = new Text("99");
|
|
key = new Text("99");
|
|
- closest = (Text)reader.getClosest(key, value);
|
|
|
|
|
|
+ closest = (Text) reader.getClosest(key, value);
|
|
assertNull(closest);
|
|
assertNull(closest);
|
|
|
|
|
|
// If we were looking for the key before, we should get the last key
|
|
// If we were looking for the key before, we should get the last key
|
|
- closest = (Text)reader.getClosest(key, value, true);
|
|
|
|
|
|
+ closest = (Text) reader.getClosest(key, value, true);
|
|
assertEquals(new Text("90"), closest);
|
|
assertEquals(new Text("90"), closest);
|
|
|
|
+ } finally {
|
|
|
|
+ reader.close();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Test
|
|
|
|
+ @SuppressWarnings("deprecation")
|
|
public void testMidKey() throws Exception {
|
|
public void testMidKey() throws Exception {
|
|
- // Write a mapfile of simple data: keys are
|
|
|
|
- Path dirName = new Path(System.getProperty("test.build.data",".") +
|
|
|
|
- getName() + ".mapfile");
|
|
|
|
|
|
+ // Write a mapfile of simple data: keys are
|
|
|
|
+ Path dirName = new Path(TEST_DIR, "testMidKey.mapfile");
|
|
FileSystem fs = FileSystem.getLocal(conf);
|
|
FileSystem fs = FileSystem.getLocal(conf);
|
|
Path qualifiedDirName = fs.makeQualified(dirName);
|
|
Path qualifiedDirName = fs.makeQualified(dirName);
|
|
-
|
|
|
|
|
|
+
|
|
MapFile.Writer writer = new MapFile.Writer(conf, fs,
|
|
MapFile.Writer writer = new MapFile.Writer(conf, fs,
|
|
- qualifiedDirName.toString(), IntWritable.class, IntWritable.class);
|
|
|
|
|
|
+ qualifiedDirName.toString(), IntWritable.class, IntWritable.class);
|
|
writer.append(new IntWritable(1), new IntWritable(1));
|
|
writer.append(new IntWritable(1), new IntWritable(1));
|
|
writer.close();
|
|
writer.close();
|
|
// Now do getClosest on created mapfile.
|
|
// Now do getClosest on created mapfile.
|
|
- MapFile.Reader reader = new MapFile.Reader(fs, qualifiedDirName.toString(),
|
|
|
|
- conf);
|
|
|
|
- assertEquals(new IntWritable(1), reader.midKey());
|
|
|
|
|
|
+ MapFile.Reader reader = new MapFile.Reader(qualifiedDirName, conf);
|
|
|
|
+ try {
|
|
|
|
+ assertEquals(new IntWritable(1), reader.midKey());
|
|
|
|
+ } finally {
|
|
|
|
+ reader.close();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
|
|
+ @Test
|
|
|
|
+ @SuppressWarnings("deprecation")
|
|
public void testMidKeyEmpty() throws Exception {
|
|
public void testMidKeyEmpty() throws Exception {
|
|
- // Write a mapfile of simple data: keys are
|
|
|
|
- Path dirName = new Path(System.getProperty("test.build.data",".") +
|
|
|
|
- getName() + ".mapfile");
|
|
|
|
|
|
+ // Write a mapfile of simple data: keys are
|
|
|
|
+ Path dirName = new Path(TEST_DIR, "testMidKeyEmpty.mapfile");
|
|
FileSystem fs = FileSystem.getLocal(conf);
|
|
FileSystem fs = FileSystem.getLocal(conf);
|
|
Path qualifiedDirName = fs.makeQualified(dirName);
|
|
Path qualifiedDirName = fs.makeQualified(dirName);
|
|
-
|
|
|
|
|
|
+
|
|
MapFile.Writer writer = new MapFile.Writer(conf, fs,
|
|
MapFile.Writer writer = new MapFile.Writer(conf, fs,
|
|
- qualifiedDirName.toString(), IntWritable.class, IntWritable.class);
|
|
|
|
|
|
+ qualifiedDirName.toString(), IntWritable.class, IntWritable.class);
|
|
writer.close();
|
|
writer.close();
|
|
// Now do getClosest on created mapfile.
|
|
// Now do getClosest on created mapfile.
|
|
- MapFile.Reader reader = new MapFile.Reader(fs, qualifiedDirName.toString(),
|
|
|
|
- conf);
|
|
|
|
- assertEquals(null, reader.midKey());
|
|
|
|
|
|
+ MapFile.Reader reader = new MapFile.Reader(qualifiedDirName, conf);
|
|
|
|
+ try {
|
|
|
|
+ assertEquals(null, reader.midKey());
|
|
|
|
+ } finally {
|
|
|
|
+ reader.close();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|