You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2014/04/08 15:44:40 UTC

svn commit: r1585724 [3/3] - in /jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java: com/ org/ org/apache/ org/apache/jena/ org/apache/jena/hadoop/ org/apache/jena/hadoop/rdf/ org/apache/jena/hadoop/rdf/io/ org/apache/jena/hadoop/rdf/io/input/ or...

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/BZippedTurtleInputTest.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/BZippedTurtleInputTest.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/BZippedTurtleInputTest.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/BZippedTurtleInputTest.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,37 @@
+/*
+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.jena.hadoop.rdf.io.input.compressed.turtle;
+
+import org.apache.hadoop.io.compress.BZip2Codec;
+
+/**
+ * Tests for BZipped NTriples input
+ * 
+ * @author rvesse
+ * 
+ */
+public class BZippedTurtleInputTest extends AbstractCompressedTurtleInputFormatTests {
+
+    /**
+     * Creates new tests
+     */
+    public BZippedTurtleInputTest() {
+        super(".nt.bz2", new BZip2Codec());
+    }
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/DeflatedTurtleInputTest.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/DeflatedTurtleInputTest.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/DeflatedTurtleInputTest.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/DeflatedTurtleInputTest.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,37 @@
+/*
+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.jena.hadoop.rdf.io.input.compressed.turtle;
+
+import org.apache.hadoop.io.compress.DefaultCodec;
+
+/**
+ * Tests for Deflated NTriples input
+ * 
+ * @author rvesse
+ * 
+ */
+public class DeflatedTurtleInputTest extends AbstractCompressedTurtleInputFormatTests {
+
+    /**
+     * Creates new tests
+     */
+    public DeflatedTurtleInputTest() {
+        super(".nt.deflate", new DefaultCodec());
+    }
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/GZippedTurtleInputTest.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/GZippedTurtleInputTest.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/GZippedTurtleInputTest.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/compressed/turtle/GZippedTurtleInputTest.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,37 @@
+/*
+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.jena.hadoop.rdf.io.input.compressed.turtle;
+
+import org.apache.hadoop.io.compress.GzipCodec;
+
+/**
+ * Tests for GZipped NTriples input
+ * 
+ * @author rvesse
+ * 
+ */
+public class GZippedTurtleInputTest extends AbstractCompressedTurtleInputFormatTests {
+
+    /**
+     * Creates new tests
+     */
+    public GZippedTurtleInputTest() {
+        super(".nt.gz", new GzipCodec());
+    }
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/AbstractTrackableInputStreamTests.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/AbstractTrackableInputStreamTests.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/AbstractTrackableInputStreamTests.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/AbstractTrackableInputStreamTests.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,701 @@
+/*
+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.jena.hadoop.rdf.io.input.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.jena.hadoop.rdf.io.input.util.TrackableInputStream;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Abstract tests for {@link TrackableInputStream} implementations
+ * 
+ * @author rvesse
+ * 
+ */
+public abstract class AbstractTrackableInputStreamTests {
+
+    protected static final int KILO = 1024;
+    protected static final int BYTES_PER_KB = KILO;
+    protected static final int BYTES_PER_MB = BYTES_PER_KB * KILO;
+
+    /**
+     * Gets the instance to test using the given input as the stream to track
+     * 
+     * @param input
+     *            Input Stream
+     * @return Trackable Input Stream
+     */
+    protected abstract TrackableInputStream getInstance(InputStream input);
+
+    /**
+     * Generates an input stream containing the given number of bytes
+     * 
+     * @param length
+     *            Number of bytes
+     * @return Input stream
+     */
+    protected final InputStream generateData(int length) {
+        ByteArrayOutputStream output = new ByteArrayOutputStream(length);
+        byte b = (byte) 'b';
+        for (int i = 0; i < length; i++) {
+            output.write(b);
+        }
+        return new ByteArrayInputStream(output.toByteArray());
+    }
+
+    protected final void testSingleByteRead(int length) throws IOException {
+        InputStream input = this.generateData(length);
+        TrackableInputStream trackable = this.getInstance(input);
+        long count = 0;
+        while (trackable.read() >= 0) {
+            count++;
+        }
+        Assert.assertEquals(length, count);
+        Assert.assertEquals(length, trackable.getBytesRead());
+        trackable.close();
+    }
+
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_single_01() throws IOException {
+        this.testSingleByteRead(0);
+    }
+
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_single_02() throws IOException {
+        this.testSingleByteRead(100);
+    }
+
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_single_03() throws IOException {
+        // 1KB
+        this.testSingleByteRead(BYTES_PER_KB);
+    }
+
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_single_04() throws IOException {
+        // 1 MB
+        this.testSingleByteRead(BYTES_PER_MB);
+    }
+
+    protected final void testMultiByteRead(int length, int bufferSize) throws IOException {
+        if (bufferSize < 1)
+            throw new IllegalArgumentException("bufferSize must be >= 1");
+        InputStream input = this.generateData(length);
+        TrackableInputStream trackable = this.getInstance(input);
+        long count = 0;
+        byte[] buffer = new byte[bufferSize];
+        long read;
+        do {
+            read = trackable.read(buffer);
+            if (read > 0)
+                count += read;
+        } while (read >= 0);
+        Assert.assertEquals(length, count);
+        Assert.assertEquals(length, trackable.getBytesRead());
+        trackable.close();
+    }
+
+    /**
+     * Test reading multiple bytes i.e. calling {@link InputStream#read(byte[])}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_01() throws IOException {
+        this.testMultiByteRead(0, 1);
+    }
+
+    /**
+     * Test reading multiple bytes i.e. calling {@link InputStream#read(byte[])}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_02() throws IOException {
+        this.testMultiByteRead(0, 16);
+    }
+
+    /**
+     * Test reading multiple bytes i.e. calling {@link InputStream#read(byte[])}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_03() throws IOException {
+        this.testMultiByteRead(0, BYTES_PER_KB);
+    }
+
+    /**
+     * Test reading multiple bytes i.e. calling {@link InputStream#read(byte[])}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_04() throws IOException {
+        // 1KB
+        this.testMultiByteRead(BYTES_PER_KB, 1);
+    }
+
+    /**
+     * Test reading multiple bytes i.e. calling {@link InputStream#read(byte[])}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_05() throws IOException {
+        // 1KB
+        this.testMultiByteRead(BYTES_PER_KB, 16);
+    }
+
+    /**
+     * Test reading multiple bytes i.e. calling {@link InputStream#read(byte[])}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_06() throws IOException {
+        // 1KB
+        this.testMultiByteRead(BYTES_PER_KB, BYTES_PER_KB);
+    }
+
+    /**
+     * Test reading multiple bytes i.e. calling {@link InputStream#read(byte[])}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_07() throws IOException {
+        // 1MB
+        this.testMultiByteRead(BYTES_PER_MB, 1);
+    }
+
+    /**
+     * Test reading multiple bytes i.e. calling {@link InputStream#read(byte[])}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_08() throws IOException {
+        // 1MB
+        this.testMultiByteRead(BYTES_PER_MB, 16);
+    }
+
+    /**
+     * Test reading multiple bytes i.e. calling {@link InputStream#read(byte[])}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_09() throws IOException {
+        // 1MB
+        this.testMultiByteRead(BYTES_PER_MB, BYTES_PER_KB);
+    }
+
+    protected final void testMultiByteRead(int length, int bufferSize, int readSize) throws IOException {
+        if (bufferSize < 1)
+            throw new IllegalArgumentException("bufferSize must be >= 1");
+        if (readSize < 1 || readSize > bufferSize)
+            throw new IllegalArgumentException("readSize must be >= 1 and <= bufferSize");
+        InputStream input = this.generateData(length);
+        TrackableInputStream trackable = this.getInstance(input);
+        long count = 0;
+        byte[] buffer = new byte[bufferSize];
+        long read;
+        do {
+            read = trackable.read(buffer, 0, readSize);
+            if (read > 0)
+                count += read;
+        } while (read >= 0);
+        Assert.assertEquals(length, count);
+        Assert.assertEquals(length, trackable.getBytesRead());
+        trackable.close();
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_01() throws IOException {
+        this.testMultiByteRead(0, 1, 1);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_02() throws IOException {
+        this.testMultiByteRead(0, 16, 1);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_03() throws IOException {
+        this.testMultiByteRead(0, 16, 16);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_04() throws IOException {
+        this.testMultiByteRead(0, BYTES_PER_KB, 1);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_05() throws IOException {
+        this.testMultiByteRead(0, BYTES_PER_KB, 16);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_06() throws IOException {
+        this.testMultiByteRead(0, BYTES_PER_KB, BYTES_PER_KB);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_07() throws IOException {
+        // 1KB
+        this.testMultiByteRead(BYTES_PER_KB, 1, 1);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_08() throws IOException {
+        // 1KB
+        this.testMultiByteRead(BYTES_PER_KB, 16, 1);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_09() throws IOException {
+        // 1KB
+        this.testMultiByteRead(BYTES_PER_KB, 16, 16);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_10() throws IOException {
+        // 1KB
+        this.testMultiByteRead(BYTES_PER_KB, BYTES_PER_KB, 1);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_11() throws IOException {
+        // 1KB
+        this.testMultiByteRead(BYTES_PER_KB, BYTES_PER_KB, 16);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_12() throws IOException {
+        // 1KB
+        this.testMultiByteRead(BYTES_PER_KB, BYTES_PER_KB, BYTES_PER_KB);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_13() throws IOException {
+        // 1MB
+        this.testMultiByteRead(BYTES_PER_MB, 1, 1);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_14() throws IOException {
+        // 1MB
+        this.testMultiByteRead(BYTES_PER_MB, 16, 1);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_15() throws IOException {
+        // 1MB
+        this.testMultiByteRead(BYTES_PER_MB, 16, 16);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_16() throws IOException {
+        // 1MB
+        this.testMultiByteRead(BYTES_PER_MB, BYTES_PER_KB, 1);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_17() throws IOException {
+        // 1MB
+        this.testMultiByteRead(BYTES_PER_MB, BYTES_PER_KB, 16);
+    }
+
+    /**
+     * Test reading multiple bytes while reading less than the buffer size bytes
+     * i.e. calling {@link InputStream#read(byte[], int, int)}
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_read_multiple_partial_18() throws IOException {
+        // 1MB
+        this.testMultiByteRead(BYTES_PER_MB, BYTES_PER_KB, BYTES_PER_KB);
+    }
+
+    protected final void testSkip(int length, long skipSize) throws IOException {
+        if (skipSize < 1)
+            throw new IllegalArgumentException("skipSize must be >= 1");
+        InputStream input = this.generateData(length);
+        TrackableInputStream trackable = this.getInstance(input);
+        long count = 0;
+        long skipped;
+        do {
+            skipped = trackable.skip(skipSize);
+            if (skipped > 0)
+                count += skipped;
+        } while (skipped > 0);
+        Assert.assertEquals(length, count);
+        Assert.assertEquals(length, trackable.getBytesRead());
+        trackable.close();
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_01() throws IOException {
+        this.testSkip(0, 1);
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_02() throws IOException {
+        this.testSkip(100, 1);
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_03() throws IOException {
+        this.testSkip(100, 16);
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_04() throws IOException {
+        this.testSkip(100, BYTES_PER_KB);
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_05() throws IOException {
+        // 1KB
+        this.testSkip(BYTES_PER_KB, 1);
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_06() throws IOException {
+        // 1KB
+        this.testSkip(BYTES_PER_KB, 16);
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_07() throws IOException {
+        // 1KB
+        this.testSkip(BYTES_PER_KB, BYTES_PER_KB);
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_08() throws IOException {
+        // 1KB
+        this.testSkip(BYTES_PER_KB, BYTES_PER_MB);
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_09() throws IOException {
+        // 1 MB
+        this.testSkip(BYTES_PER_MB, 1);
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_10() throws IOException {
+        // 1 MB
+        this.testSkip(BYTES_PER_MB, 16);
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_11() throws IOException {
+        // 1 MB
+        this.testSkip(BYTES_PER_MB, BYTES_PER_KB);
+    }
+
+    /**
+     * Test skipping
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_skip_single_12() throws IOException {
+        // 1 MB
+        this.testSkip(BYTES_PER_MB, BYTES_PER_MB);
+    }
+
+    /**
+     * Tests behaviour after closing
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_post_close_01() throws IOException {
+        InputStream input = this.generateData(0);
+        TrackableInputStream trackable = this.getInstance(input);
+        trackable.close();
+        Assert.assertEquals(-1, trackable.read());
+    }
+    
+    /**
+     * Tests behaviour after closing
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_post_close_02() throws IOException {
+        InputStream input = this.generateData(0);
+        TrackableInputStream trackable = this.getInstance(input);
+        trackable.close();
+        Assert.assertEquals(0, trackable.read(new byte[0]));
+    }
+    
+    /**
+     * Tests behaviour after closing
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_post_close_03() throws IOException {
+        InputStream input = this.generateData(0);
+        TrackableInputStream trackable = this.getInstance(input);
+        trackable.close();
+        Assert.assertEquals(-1, trackable.read(new byte[1]));
+    }
+    
+    /**
+     * Tests behaviour after closing
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_post_close_04() throws IOException {
+        InputStream input = this.generateData(0);
+        TrackableInputStream trackable = this.getInstance(input);
+        trackable.close();
+        Assert.assertEquals(0, trackable.read(new byte[16], 0, 0));
+    }
+    
+    /**
+     * Tests behaviour after closing
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_post_close_05() throws IOException {
+        InputStream input = this.generateData(0);
+        TrackableInputStream trackable = this.getInstance(input);
+        trackable.close();
+        Assert.assertEquals(-1, trackable.read(new byte[16], 0, 8));
+    }
+    
+    /**
+     * Tests behaviour after closing
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_post_close_06() throws IOException {
+        InputStream input = this.generateData(0);
+        TrackableInputStream trackable = this.getInstance(input);
+        trackable.close();
+        Assert.assertEquals(0, trackable.skip(0));
+    }
+    
+    /**
+     * Tests exceptions are thrown trying to perform actions after closing the
+     * input
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void trackable_input_post_close_07() throws IOException {
+        InputStream input = this.generateData(0);
+        TrackableInputStream trackable = this.getInstance(input);
+        trackable.close();
+        Assert.assertEquals(0, trackable.skip(1));
+    }
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/BlockInputStreamTest.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/BlockInputStreamTest.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/BlockInputStreamTest.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/BlockInputStreamTest.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,240 @@
+/*
+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.jena.hadoop.rdf.io.input.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.jena.hadoop.rdf.io.input.util.BlockInputStream;
+import org.apache.jena.hadoop.rdf.io.input.util.TrackableInputStream;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests for the {@link BlockInputStream}
+ * 
+ * @author rvesse
+ * 
+ */
+public class BlockInputStreamTest extends AbstractTrackableInputStreamTests {
+
+    @Override
+    protected TrackableInputStream getInstance(InputStream input) {
+        return new BlockInputStream(input, Long.MAX_VALUE);
+    }
+
+    /**
+     * Gets an instance of a block input stream
+     * 
+     * @param input
+     *            Underlying input stream
+     * @param limit
+     *            Limit on bytes to read
+     * @return Block input stream
+     */
+    protected BlockInputStream getInstance(InputStream input, long limit) {
+        return new BlockInputStream(input, limit);
+    }
+    
+    protected final void testSingleByteRead(int length, long limit) throws IOException {
+        InputStream input = this.generateData(length);
+        TrackableInputStream trackable = this.getInstance(input, limit);
+        long count = 0;
+        while (trackable.read() >= 0) {
+            count++;
+        }
+        int expected = (int) Math.min(length, limit);
+        Assert.assertEquals(expected, count);
+        Assert.assertEquals(expected, trackable.getBytesRead());
+        trackable.close();
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_01() throws IOException {
+        this.testSingleByteRead(0, 0);
+    }
+
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_02() throws IOException {
+        this.testSingleByteRead(100, 0);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_03() throws IOException {
+        this.testSingleByteRead(100, 50);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_04() throws IOException {
+        this.testSingleByteRead(100, 100);
+    }
+
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_05() throws IOException {
+        // 1KB
+        this.testSingleByteRead(BYTES_PER_KB, 1);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_06() throws IOException {
+        // 1KB
+        this.testSingleByteRead(BYTES_PER_KB, 100);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_07() throws IOException {
+        // 1KB
+        this.testSingleByteRead(BYTES_PER_KB, BYTES_PER_KB / 2);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_08() throws IOException {
+        // 1KB
+        this.testSingleByteRead(BYTES_PER_KB, BYTES_PER_KB);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_09() throws IOException {
+        // 1KB
+        this.testSingleByteRead(BYTES_PER_KB, BYTES_PER_MB);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_10() throws IOException {
+        // 1KB
+        this.testSingleByteRead(BYTES_PER_KB, BYTES_PER_MB * 10);
+    }
+
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_11() throws IOException {
+        // 1MB
+        this.testSingleByteRead(BYTES_PER_MB, 1);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_12() throws IOException {
+        // 1MB
+        this.testSingleByteRead(BYTES_PER_MB, 100);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_13() throws IOException {
+        // 1MB
+        this.testSingleByteRead(BYTES_PER_MB, BYTES_PER_KB);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_14() throws IOException {
+        // 1MB
+        this.testSingleByteRead(BYTES_PER_MB, BYTES_PER_MB / 2);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_15() throws IOException {
+        // 1MB
+        this.testSingleByteRead(BYTES_PER_MB, BYTES_PER_MB);
+    }
+    
+    /**
+     * Test reading byte by byte
+     * 
+     * @throws IOException
+     */
+    @Test
+    public final void block_input_read_single_16() throws IOException {
+        // 1MB
+        this.testSingleByteRead(BYTES_PER_MB, BYTES_PER_MB * 10);
+    }
+
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/TrackedInputStreamTest.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/TrackedInputStreamTest.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/TrackedInputStreamTest.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/input/util/TrackedInputStreamTest.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,39 @@
+/*
+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.jena.hadoop.rdf.io.input.util;
+
+import java.io.InputStream;
+
+import org.apache.jena.hadoop.rdf.io.input.util.TrackableInputStream;
+import org.apache.jena.hadoop.rdf.io.input.util.TrackedInputStream;
+
+/**
+ * Tests for the {@link TrackedInputStream}
+ * 
+ * @author rvesse
+ * 
+ */
+public class TrackedInputStreamTest extends AbstractTrackableInputStreamTests {
+
+    @Override
+    protected TrackableInputStream getInstance(InputStream input) {
+        return new TrackedInputStream(input);
+    }
+
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractNodeTupleOutputFormatTests.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractNodeTupleOutputFormatTests.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractNodeTupleOutputFormatTests.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractNodeTupleOutputFormatTests.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,247 @@
+/*
+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.jena.hadoop.rdf.io.output;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.LocatedFileStatus;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.RemoteIterator;
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.mapreduce.Job;
+import org.apache.hadoop.mapreduce.JobContext;
+import org.apache.hadoop.mapreduce.OutputFormat;
+import org.apache.hadoop.mapreduce.RecordWriter;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.apache.hadoop.mapreduce.TaskAttemptID;
+import org.apache.hadoop.mapreduce.TaskType;
+import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
+import org.apache.hadoop.mapreduce.task.JobContextImpl;
+import org.apache.hadoop.mapreduce.task.TaskAttemptContextImpl;
+import org.apache.jena.hadoop.rdf.types.AbstractNodeTupleWritable;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFDataMgr;
+import org.apache.jena.riot.lang.StreamRDFCounting;
+import org.apache.jena.riot.system.StreamRDFLib;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Abstract node tuple output format tests
+ * 
+ * @author rvesse
+ * @param <TValue>
+ *            Tuple type
+ * @param <T>
+ *            Writable tuple type
+ * 
+ */
+public abstract class AbstractNodeTupleOutputFormatTests<TValue, T extends AbstractNodeTupleWritable<TValue>> {
+
+    @SuppressWarnings("unused")
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractNodeTupleOutputFormatTests.class);
+
+    protected static final int EMPTY_SIZE = 0, SMALL_SIZE = 100, LARGE_SIZE = 10000, VERY_LARGE_SIZE = 100000;
+
+    /**
+     * Temporary folder for the tests
+     */
+    @Rule
+    public TemporaryFolder folder = new TemporaryFolder();
+
+    /**
+     * Prepares a fresh configuration
+     * 
+     * @return Configuration
+     */
+    protected Configuration prepareConfiguration() {
+        Configuration config = new Configuration(true);
+        // Nothing else to do
+        return config;
+    }
+
+    /**
+     * Gets the extra file extension to add to the filenames
+     * 
+     * @return File extension
+     */
+    protected abstract String getFileExtension();
+
+    /**
+     * Generates tuples to be output for testing
+     * 
+     * @param num
+     *            Number of tuples to generate
+     * @return Iterator of tuples
+     */
+    protected abstract Iterator<T> generateTuples(int num);
+
+    /**
+     * Counts tuples in the output file
+     * 
+     * @param f
+     *            Output file
+     * @return Tuple count
+     */
+    protected final long countTuples(File f) {
+        StreamRDFCounting counter = StreamRDFLib.count();
+        RDFDataMgr.parse(counter, f.getAbsolutePath(), this.getRdfLanguage(), null);
+        return counter.count();
+    }
+
+    protected final void checkTuples(File f, long expected) {
+        Assert.assertEquals(expected, this.countTuples(f));
+    }
+
+    /**
+     * Gets the RDF language of the produced output which is used to parse back
+     * in the output to validate the correct amount of output was produced
+     * 
+     * @return RDF language
+     */
+    protected abstract Lang getRdfLanguage();
+
+    /**
+     * Gets the output format to test
+     * 
+     * @return Output format
+     */
+    protected abstract OutputFormat<NullWritable, T> getOutputFormat();
+
+    /**
+     * Adds an output path to the job configuration
+     * 
+     * @param f
+     *            File
+     * @param config
+     *            Configuration
+     * @param job
+     *            Job
+     * @throws IOException
+     */
+    protected void addOutputPath(File f, Configuration config, Job job) throws IOException {
+        FileSystem fs = FileSystem.getLocal(config);
+        Path outputPath = fs.makeQualified(new Path(f.getAbsolutePath()));
+        FileOutputFormat.setOutputPath(job, outputPath);
+    }
+    
+    protected File findOutputFile(File dir, JobContext context) throws FileNotFoundException, IOException {
+        Path outputPath = FileOutputFormat.getOutputPath(context);
+        RemoteIterator<LocatedFileStatus> files = outputPath.getFileSystem(context.getConfiguration()).listFiles(outputPath, true);
+        while (files.hasNext()) {
+            LocatedFileStatus status = files.next();
+            if (status.isFile() && !status.getPath().getName().startsWith("_")) {
+                return new File(status.getPath().toUri());
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Tests output
+     * 
+     * @param f
+     *            File to output to
+     * @param num
+     *            Number of tuples to output
+     * @throws IOException
+     * @throws InterruptedException 
+     */
+    protected final void testOutput(File f, int num) throws IOException, InterruptedException {
+        // Prepare configuration
+        Configuration config = this.prepareConfiguration();
+
+        // Set up fake job
+        OutputFormat<NullWritable, T> outputFormat = this.getOutputFormat();
+        Job job = Job.getInstance(config);
+        job.setOutputFormatClass(outputFormat.getClass());
+        this.addOutputPath(f, job.getConfiguration(), job);
+        JobContext context = new JobContextImpl(job.getConfiguration(), job.getJobID());
+        Assert.assertNotNull(FileOutputFormat.getOutputPath(context));
+        
+        // Output the data
+        TaskAttemptID id = new TaskAttemptID("outputTest", 1, TaskType.MAP, 1, 1);
+        TaskAttemptContext taskContext = new TaskAttemptContextImpl(job.getConfiguration(), id);
+        RecordWriter<NullWritable, T> writer = outputFormat.getRecordWriter(taskContext);
+        Iterator<T> tuples = this.generateTuples(num);
+        while (tuples.hasNext()) {
+            writer.write(NullWritable.get(), tuples.next());
+        }
+        writer.close(taskContext);
+        
+        // Check output
+        File outputFile = this.findOutputFile(this.folder.getRoot(), context);
+        Assert.assertNotNull(outputFile);
+        this.checkTuples(outputFile, num);
+    }
+
+    /**
+     * Basic output tests
+     * 
+     * @throws IOException
+     * @throws InterruptedException 
+     */
+    @Test
+    public final void output_01() throws IOException, InterruptedException {
+        this.testOutput(this.folder.getRoot(), EMPTY_SIZE);
+    }
+    
+    /**
+     * Basic output tests
+     * 
+     * @throws IOException
+     * @throws InterruptedException 
+     */
+    @Test
+    public final void output_02() throws IOException, InterruptedException {
+        this.testOutput(this.folder.getRoot(), SMALL_SIZE);
+    }
+    
+    /**
+     * Basic output tests
+     * 
+     * @throws IOException
+     * @throws InterruptedException 
+     */
+    @Test
+    public final void output_03() throws IOException, InterruptedException {
+        this.testOutput(this.folder.getRoot(), LARGE_SIZE);
+    }
+    
+    /**
+     * Basic output tests
+     * 
+     * @throws IOException
+     * @throws InterruptedException 
+     */
+    @Test
+    public final void output_04() throws IOException, InterruptedException {
+        this.testOutput(this.folder.getRoot(), VERY_LARGE_SIZE);
+    }
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractQuadOutputFormatTests.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractQuadOutputFormatTests.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractQuadOutputFormatTests.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractQuadOutputFormatTests.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,51 @@
+/*
+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.jena.hadoop.rdf.io.output;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+
+import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
+import com.hp.hpl.jena.graph.NodeFactory;
+import com.hp.hpl.jena.sparql.core.Quad;
+
+/**
+ * Abstract tests for quad output formats
+ * 
+ * @author rvesse
+ * 
+ */
+public abstract class AbstractQuadOutputFormatTests extends AbstractNodeTupleOutputFormatTests<Quad, QuadWritable> {
+
+    @Override
+    protected Iterator<QuadWritable> generateTuples(int num) {
+        List<QuadWritable> qs = new ArrayList<QuadWritable>();
+        for (int i = 0; i < num; i++) {
+            Quad q = new Quad(NodeFactory.createURI("http://example.org/graphs/" + i),
+                    NodeFactory.createURI("http://example.org/subjects/" + i),
+                    NodeFactory.createURI("http://example.org/predicate"), NodeFactory.createLiteral(Integer.toString(i),
+                            XSDDatatype.XSDinteger));
+            qs.add(new QuadWritable(q));
+        }
+        return qs.iterator();
+    }
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractTripleOutputFormatTests.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractTripleOutputFormatTests.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractTripleOutputFormatTests.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/AbstractTripleOutputFormatTests.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,47 @@
+/*
+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.jena.hadoop.rdf.io.output;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+
+import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
+import com.hp.hpl.jena.graph.NodeFactory;
+import com.hp.hpl.jena.graph.Triple;
+
+/**
+ * Abstract tests for triple output formats
+ * @author rvesse
+ *
+ */
+public abstract class AbstractTripleOutputFormatTests extends AbstractNodeTupleOutputFormatTests<Triple, TripleWritable> {
+
+    @Override
+    protected Iterator<TripleWritable> generateTuples(int num) {
+        List<TripleWritable> ts = new ArrayList<TripleWritable>();
+        for (int i = 0; i < num; i++) {
+            Triple t = new Triple(NodeFactory.createURI("http://example.org/subjects/" + i), NodeFactory.createURI("http://example.org/predicate"), NodeFactory.createLiteral(Integer.toString(i), XSDDatatype.XSDinteger));
+            ts.add(new TripleWritable(t));
+        }
+        return ts.iterator();
+    }
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/NQuadsOutputTest.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/NQuadsOutputTest.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/NQuadsOutputTest.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/NQuadsOutputTest.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,51 @@
+/*
+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.jena.hadoop.rdf.io.output;
+
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.mapreduce.OutputFormat;
+import org.apache.jena.hadoop.rdf.io.output.NQuadsOutputFormat;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.riot.Lang;
+
+
+/**
+ * Tests for NQuads output format
+ * 
+ * @author rvesse
+ * 
+ */
+public class NQuadsOutputTest extends AbstractQuadOutputFormatTests {
+
+    @Override
+    protected String getFileExtension() {
+        return ".nq";
+    }
+
+    @Override
+    protected Lang getRdfLanguage() {
+        return Lang.NQUADS;
+    }
+
+    @Override
+    protected OutputFormat<NullWritable, QuadWritable> getOutputFormat() {
+        return new NQuadsOutputFormat<NullWritable>();
+    }
+
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/NTriplesOutputTest.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/NTriplesOutputTest.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/NTriplesOutputTest.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/NTriplesOutputTest.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,51 @@
+/*
+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.jena.hadoop.rdf.io.output;
+
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.mapreduce.OutputFormat;
+import org.apache.jena.hadoop.rdf.io.output.NTriplesOutputFormat;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+
+/**
+ * Tests for NTriples output format
+ * 
+ * @author rvesse
+ * 
+ */
+public class NTriplesOutputTest extends AbstractTripleOutputFormatTests {
+
+    @Override
+    protected String getFileExtension() {
+        return ".nt";
+    }
+
+    @Override
+    protected Lang getRdfLanguage() {
+        return Lang.NTRIPLES;
+    }
+
+    @Override
+    protected OutputFormat<NullWritable, TripleWritable> getOutputFormat() {
+        return new NTriplesOutputFormat<NullWritable>();
+    }
+
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/RdfJsonOutputTest.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/RdfJsonOutputTest.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/RdfJsonOutputTest.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/RdfJsonOutputTest.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,51 @@
+/*
+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.jena.hadoop.rdf.io.output;
+
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.mapreduce.OutputFormat;
+import org.apache.jena.hadoop.rdf.io.output.RdfJsonOutputFormat;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+
+/**
+ * Tests for RDF/JSON output
+ * 
+ * @author rvesse
+ * 
+ */
+public class RdfJsonOutputTest extends AbstractTripleOutputFormatTests {
+
+    @Override
+    protected String getFileExtension() {
+        return ".rj";
+    }
+
+    @Override
+    protected Lang getRdfLanguage() {
+        return Lang.RDFJSON;
+    }
+
+    @Override
+    protected OutputFormat<NullWritable, TripleWritable> getOutputFormat() {
+        return new RdfJsonOutputFormat<NullWritable>();
+    }
+
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/RdfXmlOutputTest.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/RdfXmlOutputTest.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/RdfXmlOutputTest.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/RdfXmlOutputTest.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,51 @@
+/*
+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.jena.hadoop.rdf.io.output;
+
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.mapreduce.OutputFormat;
+import org.apache.jena.hadoop.rdf.io.output.RdfXmlOutputFormat;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+
+/**
+ * Tests for RDF/XML output
+ * 
+ * @author rvesse
+ * 
+ */
+public class RdfXmlOutputTest extends AbstractTripleOutputFormatTests {
+
+    @Override
+    protected String getFileExtension() {
+        return ".rdf";
+    }
+
+    @Override
+    protected Lang getRdfLanguage() {
+        return Lang.RDFXML;
+    }
+
+    @Override
+    protected OutputFormat<NullWritable, TripleWritable> getOutputFormat() {
+        return new RdfXmlOutputFormat<NullWritable>();
+    }
+
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/TriGOutputTest.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/TriGOutputTest.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/TriGOutputTest.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/TriGOutputTest.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,92 @@
+/*
+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.jena.hadoop.rdf.io.output;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.mapreduce.OutputFormat;
+import org.apache.jena.hadoop.rdf.io.RdfIOConstants;
+import org.apache.jena.hadoop.rdf.io.output.TriGOutputFormat;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.riot.Lang;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+
+/**
+ * Tests for TriG output
+ * 
+ * @author rvesse
+ * 
+ */
+@RunWith(Parameterized.class)
+public class TriGOutputTest extends AbstractQuadOutputFormatTests {
+
+    static long $bs1 = RdfIOConstants.DEFAULT_OUTPUT_BATCH_SIZE;
+    static long $bs2 = 1000;
+    static long $bs3 = 100;
+    static long $bs4 = 1;
+
+    /**
+     * @return Test parameters
+     */
+    @Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] { { $bs1 }, { $bs2 }, { $bs3 }, { $bs4 } });
+    }
+
+    private final long batchSize;
+
+    /**
+     * Creates new tests
+     * 
+     * @param batchSize
+     *            Batch size
+     */
+    public TriGOutputTest(long batchSize) {
+        this.batchSize = batchSize;
+    }
+
+    @Override
+    protected String getFileExtension() {
+        return ".trig";
+    }
+
+    @Override
+    protected Lang getRdfLanguage() {
+        return Lang.TRIG;
+    }
+
+    @Override
+    protected Configuration prepareConfiguration() {
+        Configuration config = super.prepareConfiguration();
+        config.setLong(RdfIOConstants.OUTPUT_BATCH_SIZE, this.batchSize);
+        return config;
+    }
+
+    @Override
+    protected OutputFormat<NullWritable, QuadWritable> getOutputFormat() {
+        return new TriGOutputFormat<NullWritable>();
+    }
+
+}

Added: jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/TurtleOutputTest.java
URL: http://svn.apache.org/viewvc/jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/TurtleOutputTest.java?rev=1585724&view=auto
==============================================================================
--- jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/TurtleOutputTest.java (added)
+++ jena/Experimental/hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/output/TurtleOutputTest.java Tue Apr  8 13:44:38 2014
@@ -0,0 +1,92 @@
+/*
+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.jena.hadoop.rdf.io.output;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.mapreduce.OutputFormat;
+import org.apache.jena.hadoop.rdf.io.RdfIOConstants;
+import org.apache.jena.hadoop.rdf.io.output.TurtleOutputFormat;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+
+/**
+ * Tests for Turtle output
+ * 
+ * @author rvesse
+ * 
+ */
+@RunWith(Parameterized.class)
+public class TurtleOutputTest extends AbstractTripleOutputFormatTests {
+
+    static long $bs1 = RdfIOConstants.DEFAULT_OUTPUT_BATCH_SIZE;
+    static long $bs2 = 1000;
+    static long $bs3 = 100;
+    static long $bs4 = 1;
+
+    /**
+     * @return Test parameters
+     */
+    @Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] { { $bs1 }, { $bs2 }, { $bs3 }, { $bs4 } });
+    }
+
+    private final long batchSize;
+
+    /**
+     * Creates new tests
+     * 
+     * @param batchSize
+     *            Batch size
+     */
+    public TurtleOutputTest(long batchSize) {
+        this.batchSize = batchSize;
+    }
+
+    @Override
+    protected String getFileExtension() {
+        return ".ttl";
+    }
+
+    @Override
+    protected Lang getRdfLanguage() {
+        return Lang.TURTLE;
+    }
+    
+    @Override
+    protected Configuration prepareConfiguration() {
+        Configuration config = super.prepareConfiguration();
+        config.setLong(RdfIOConstants.OUTPUT_BATCH_SIZE, this.batchSize);
+        return config;
+    }
+
+    @Override
+    protected OutputFormat<NullWritable, TripleWritable> getOutputFormat() {
+        return new TurtleOutputFormat<NullWritable>();
+    }
+
+}