db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From krist...@apache.org
Subject svn commit: r671840 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/jdbc/ testing/org/apache/derbyTesting/functionTests/tests/store/ testing/org/apache/derbyTesting/functionTests/util/streams/
Date Thu, 26 Jun 2008 10:00:26 GMT
Author: kristwaa
Date: Thu Jun 26 03:00:25 2008
New Revision: 671840

URL: http://svn.apache.org/viewvc?rev=671840&view=rev
Log:
DERBY-3735: Incorrect position calculation in PositionedStoreStream with read(byte[],...).
Fixed calculation by only adding positive integers (not allowing -1).
Added a general test and a regression test.
Made LoopingAlphabetStream implement Resetable to allow it to be used for testing where a
resetable stream is expected.
Patch file: derby-3735-1b.diff

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
  (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/_Suite.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/streams/LoopingAlphabetStream.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java?rev=671840&r1=671839&r2=671840&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
Thu Jun 26 03:00:25 2008
@@ -96,9 +96,7 @@
      */
     public int read(byte[] b)
             throws IOException {
-        int ret = this.stream.read(b);
-        this.pos += ret;
-        return ret;
+        return read(b, 0, b.length);
     }
 
     /**
@@ -112,7 +110,9 @@
     public int read(byte[] b, int off, int len)
             throws IOException {
         int ret = this.stream.read(b, off, len);
-        this.pos += ret;
+        if (ret > 0) {
+            this.pos += ret;
+        }
         return ret;
     }
 
@@ -125,7 +125,7 @@
     public int read()
             throws IOException {
         int ret = this.stream.read();
-        if (ret > -1) {
+        if (ret > 0) {
             this.pos++;
         }
         return ret;

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java?rev=671840&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
(added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
Thu Jun 26 03:00:25 2008
@@ -0,0 +1,206 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.tests.store.PositionedStoreStreamTest
+
+   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.derbyTesting.functionTests.tests.store;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import java.util.Arrays;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.impl.jdbc.PositionedStoreStream;
+import org.apache.derbyTesting.functionTests.util.streams.LoopingAlphabetStream;
+import org.apache.derbyTesting.junit.BaseTestCase;
+
+/**
+ * Tests of the repositioning logic in {@link PositionedStoreStream}.
+ */
+public class PositionedStoreStreamTest
+    extends BaseTestCase {
+
+    public PositionedStoreStreamTest(String name) {
+        super(name);
+    }
+
+    /**
+     * Verifies that reading after EOF doesn't change the position.
+     */
+    public void testPositionAfterEOFRead()
+            throws IOException, StandardException {
+        InputStream in = new LoopingAlphabetStream(10);
+        PositionedStoreStream pss = new PositionedStoreStream(in);
+        assertEquals(0, pss.getPosition());
+        for (int i=0; i < 10; i++) {
+            pss.read();
+            assertEquals(i +1, pss.getPosition());
+        }
+        assertEquals(10, pss.getPosition());
+        assertEquals(-1, pss.read());
+        assertEquals(10, pss.getPosition());
+        assertEquals(-1, pss.read());
+        assertEquals(0, pss.skip(199));
+        assertEquals(10, pss.getPosition());
+        pss.resetStream();
+        assertEquals(0, pss.getPosition());
+    }
+
+    /**
+     * Verifies that reading after EOF doesn't change the position.
+     */
+    public void testPositionAfterEOFReadArray()
+            throws IOException, StandardException {
+        InputStream in = new LoopingAlphabetStream(10);
+        PositionedStoreStream pss = new PositionedStoreStream(in);
+        assertEquals(0, pss.getPosition());
+        byte[] two = new byte[2];
+        for (int i=0; i < 10; i += 2) {
+            assertEquals(2, pss.read(two, 0, 2));
+            assertEquals(i +2, pss.getPosition());
+        }
+        assertEquals(10, pss.getPosition());
+        assertEquals(-1, pss.read(two, 0, 2));
+        assertEquals(10, pss.getPosition());
+        assertEquals(-1, pss.read(two, 0, 2));
+        assertEquals(0, pss.skip(21));
+        assertEquals(-1, pss.read());
+        assertEquals(10, pss.getPosition());
+        pss.resetStream();
+        assertEquals(0, pss.getPosition());
+    }
+
+    /**
+     * Reads the whole stream repeatedly in one go, and resets it after each
+     * read.
+     */
+    public void testReadEverythingInOneGo()
+            throws IOException, StandardException {
+        InputStream in = new LoopingAlphabetStream(127);
+        PositionedStoreStream pss = new PositionedStoreStream(in);
+        byte[] b = new byte[256];
+        for (int i=0; i < 3; i++) {
+            Arrays.fill(b, (byte)-1);
+            assertEquals(127, pss.read(b, 0, 256));
+            assertEquals(-1, pss.read(b, 127, 10));
+            assertEquals(-1, b[127]);
+            assertTrue( -1 != b[126]);
+            assertEquals('a', b[0]);
+            pss.reposition(0);
+        }
+    }
+
+    public void testRepositionForwards()
+            throws IOException, StandardException {
+        final long length = 20L;
+        InputStream in = new LoopingAlphabetStream(length);
+        PositionedStoreStream pss = new PositionedStoreStream(in);
+        assertEquals(0, pss.getPosition());
+        //  Position forwards one by one.
+        for (int i=0; i < length; i++) {
+            InputStream inComp = new LoopingAlphabetStream(length);
+            pss.reposition(i);
+            inComp.skip(i);
+            assertEquals(inComp.read(), pss.read());
+        }
+        // Position forwards two by two.
+        for (int i=1; i < length; i += 2) {
+            InputStream inComp = new LoopingAlphabetStream(length);
+            pss.reposition(i);
+            inComp.skip(i);
+            assertEquals(inComp.read(), pss.read());
+        }
+    }
+    
+    public void testRepositionBackwards()
+            throws IOException, StandardException {
+        final long length = 20L;
+        InputStream in = new LoopingAlphabetStream(length);
+        PositionedStoreStream pss = new PositionedStoreStream(in);
+        assertEquals(0, pss.getPosition());
+        // Position backwards one by one.
+        for (int i=(int)length; i >= 0; i--) {
+            InputStream inComp = new LoopingAlphabetStream(length);
+            pss.reposition(i);
+            inComp.skip(i);
+            assertEquals(inComp.read(), pss.read());
+        }
+        // Position backwards two by two.
+        for (int i=(int)length -1; i >= 0; i -= 2) {
+            InputStream inComp = new LoopingAlphabetStream(length);
+            pss.reposition(i);
+            inComp.skip(i);
+            assertEquals(inComp.read(), pss.read());
+        }
+    }
+
+    /**
+     * Executes a simple read sequence against the lower case modern latin
+     * alphabet, which involves some repositioning.
+     */
+    public void testSimpleReadSequence()
+            throws IOException, StandardException {
+        InputStream in = new LoopingAlphabetStream(26);
+        PositionedStoreStream pss = new PositionedStoreStream(in);
+        assertEquals('a', pss.read());
+        pss.reposition(9);
+        assertEquals('j', pss.read());
+        pss.reposition(10);
+        assertEquals('k', pss.read());
+        pss.reposition(9);
+        assertEquals('j', pss.read());
+        pss.reposition(25);
+        assertEquals('z', pss.read());
+        assertEquals(-1, pss.read());
+        pss.reposition(1);
+        assertEquals('b', pss.read());
+        pss.reposition(1);
+        assertEquals('b', pss.read());
+    }
+
+    /**
+     * A regression test for DERBY-3735.
+     * <p>
+     * If the bug is present, the repositioning will cause an EOF-exception to
+     * be thrown in {@code skipFully}.
+     */
+    public void testDerby3735()
+            throws IOException, StandardException {
+        InputStream in = new LoopingAlphabetStream(2);
+        PositionedStoreStream pss = new PositionedStoreStream(in);
+        byte[] b = new byte[2];
+        for (int i=0; i < 10; i++) {
+            // After the first iteration, the position will be decreased and
+            // eventually become negative.
+            pss.read(b);
+            println("Position at iteration " + i + ": " + pss.getPosition());
+        }
+        // This failed, because we tried skipping more bytes than there are in
+        // the stream to get to position 0.
+        pss.reposition(0);
+    }
+
+    public static Test suite() {
+        return new TestSuite(
+                PositionedStoreStreamTest.class, "PositionedStoreStreamTest");
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/_Suite.java?rev=671840&r1=671839&r2=671840&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/_Suite.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/_Suite.java
Thu Jun 26 03:00:25 2008
@@ -54,6 +54,7 @@
         suite.addTest(BootAllTest.suite());
         suite.addTest(StreamingColumnTest.suite());
         suite.addTest(Derby3625Test.suite());
+        suite.addTest(PositionedStoreStreamTest.suite());
         // Encryption only supported for Derby in J2SE/J2EE environments.
         // J2ME (JSR169) does not support encryption.
         if (JDBC.vmSupportsJDBC3()) {

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/streams/LoopingAlphabetStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/streams/LoopingAlphabetStream.java?rev=671840&r1=671839&r2=671840&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/streams/LoopingAlphabetStream.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/streams/LoopingAlphabetStream.java
Thu Jun 26 03:00:25 2008
@@ -22,14 +22,16 @@
 package org.apache.derbyTesting.functionTests.util.streams;
 
 import java.io.InputStream;
-import java.io.IOException;
+
+import org.apache.derby.iapi.types.Resetable;
 
 /**
  * A stream returning a cycle of the 26 lowercase letters of the modern Latin
  * alphabet.
  */
 public class LoopingAlphabetStream
-    extends InputStream {
+    extends InputStream
+    implements Resetable {
 
     /**
      * Maximum size of buffer.
@@ -56,7 +58,18 @@
         this(length, 0);
     }
 
+    /**
+     * Creates a looping alphabet stream with the specified length, in which the
+     * last characters are blanks.
+     *
+     * @param length total length of the stream
+     * @param trailingBlanks number of trailing blanks
+     */
     public LoopingAlphabetStream(long length, int trailingBlanks) {
+        if (trailingBlanks > length) {
+            throw new IllegalArgumentException("Number of trailing blanks " +
+                    "cannot be greater than the total length.");
+        }
         this.length = length;
         this.trailingBlanks = trailingBlanks;
         this.remainingNonBlanks = length - trailingBlanks;
@@ -184,4 +197,18 @@
         }
         return i;
     }
+
+    // Resetable interface
+
+    public void resetStream() {
+        reset();
+    }
+
+    public void initStream() {
+        reset();
+    }
+
+    public void closeStream() {
+        // Does nothing for this stream.
+    }
 } // End class LoopingAlphabetStream



Mime
View raw message