db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From andre...@apache.org
Subject svn commit: r419847 - in /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests: tests/jdbcapi/BLOBDataModelSetup.java tests/jdbcapi/BLOBTest.java tests/jdbcapi/BLOBTest_app.properties util/TestInputStream.java
Date Fri, 07 Jul 2006 09:05:52 GMT
Author: andreask
Date: Fri Jul  7 02:05:52 2006
New Revision: 419847

URL: http://svn.apache.org/viewvc?rev=419847&view=rev
Log:
DERBY-1477 create JUnit tests for testing BLOB OutOfMemory problems. New tests for testing
really big blobs (64MB). Not included in any suites.

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBDataModelSetup.java
  (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBTest.java
  (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBTest_app.properties
  (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/TestInputStream.java
  (with props)

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBDataModelSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBDataModelSetup.java?rev=419847&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBDataModelSetup.java
(added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBDataModelSetup.java
Fri Jul  7 02:05:52 2006
@@ -0,0 +1,137 @@
+/**
+ *
+ * Derby - Class BLOBDataModelSetup
+ *
+ * Copyright 2006 The Apache Software Foundation or its
+ * licensors, as applicable.
+ *
+ * Licensed 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.jdbcapi;
+import org.apache.derbyTesting.functionTests.util.BaseJDBCTestCase;
+import org.apache.derbyTesting.functionTests.util.TestInputStream;
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.io.InputStream;
+
+/**
+ * Sets up a data model with very large BLOBs.
+ * The table created will have three fields: 
+ *  1. a value field (val), which is the value for every byte in the BLOB.
+ *  2. a length (length) field which is the actual size of the BLOB
+ *  3. the data field (data), which is the actual BLOB data.
+ *
+ * @author Andreas Korneliussen
+ */
+final public class BLOBDataModelSetup extends TestSetup
+{
+    
+    /** 
+     * Constructor
+     * @param test test object being decorated by this TestSetup
+     */
+    public BLOBDataModelSetup(Test test) 
+    {
+        super(test);
+    }
+
+    /**
+     * The setup creates a Connection to the database, and creates a table
+     * with blob columns.
+     * @exception Exception any exception will cause test to fail with error.
+     */
+    public final void setUp() 
+        throws Exception
+    {
+        con = BaseJDBCTestCase.getConnection();
+        con.setAutoCommit(false);
+        
+        // Create table:
+        final Statement statement = con.createStatement();
+        statement.executeUpdate("CREATE TABLE " + tableName + " ("+
+                                " val INTEGER," +
+                                " length INTEGER, " +
+                                " data BLOB(2G) NOT NULL)");
+        statement.close();
+        // Insert some data:
+        final PreparedStatement preparedStatement =
+            con.prepareStatement
+            ("INSERT INTO " + tableName + "(val, length, data) VALUES (?,?, ?)");
+        
+        // Insert 10 records with size of 1MB
+        final int size = 1024*1024;
+        for (int i = 0; i < 10; i++) {
+            final int val = i;
+            final InputStream stream = new TestInputStream(size, val);
+            preparedStatement.setInt(1, val);
+            preparedStatement.setInt(2, size);
+            preparedStatement.setBinaryStream(3, stream, size);
+            preparedStatement.executeUpdate();
+        }
+        
+        // Insert 1 record with size of 64 MB
+        final int bigsize = 1024 * 1024 * 64;
+        final int val = 11;
+        
+        BaseJDBCTestCase.println("Insert BLOB with size = " + bigsize);
+        preparedStatement.setInt(1, val);
+        preparedStatement.setInt(2, bigsize);
+        final InputStream stream = new TestInputStream(bigsize, val);
+        preparedStatement.setBinaryStream(3, stream, bigsize);
+        
+        BaseJDBCTestCase.println("Execute update");
+        preparedStatement.executeUpdate();
+        preparedStatement.close();
+        
+        BaseJDBCTestCase.println("Commit");
+        con.commit();
+    }
+    
+    /**
+     * Teardown test.
+     * Rollback connection and close it.
+     * @exception Exceptions causes the test to fail with error
+     */
+    public final void tearDown() 
+        throws Exception
+    {
+        try { 
+            Statement statement = con.createStatement();
+            statement.execute("DROP TABLE " + tableName);
+            statement.close();
+            con.commit();
+            con.close();
+        } catch (SQLException e) {
+            BaseJDBCTestCase.printStackTrace(e);
+        }      
+    }
+
+    /**
+     * Return table name 
+     * @return table name
+     */
+    public static final String getBlobTableName() 
+    {
+        return tableName;
+    }
+    
+    /** JDBC Connection */        
+    private Connection con;
+    
+    /** Name of table */
+    private static final String tableName = "TESTBLOBTABLE";
+}

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

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBTest.java?rev=419847&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBTest.java
(added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBTest.java
Fri Jul  7 02:05:52 2006
@@ -0,0 +1,338 @@
+/**
+ *
+ * Derby - Class BLOBTest
+ *
+ * Copyright 2006 The Apache Software Foundation or its
+ * licensors, as applicable.
+ *
+ * Licensed 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.jdbcapi;
+import org.apache.derbyTesting.functionTests.util.BaseJDBCTestCase;
+import org.apache.derbyTesting.functionTests.util.TestInputStream;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Tests reading and updating binary large objects (BLOBs).
+ * @author Andreas Korneliussen
+ */
+final public class BLOBTest extends BaseJDBCTestCase
+{
+    /** 
+     * Constructor
+     * @param name name of test case (method).
+     */
+    public BLOBTest(String name) 
+    {
+        super(name);
+        con = null;
+    }
+
+    
+    /**
+     * Tests updating a Blob from a scollable resultset, using
+     * result set update methods.
+     * @exception SQLException causes test to fail with error
+     * @exception IOException causes test to fail with error
+     */
+    public void testUpdateBlobFromScrollableResultSetUsingResultSetMethods()
+        throws SQLException, IOException
+    {
+        final Statement stmt = 
+            con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
+                                ResultSet.CONCUR_UPDATABLE);
+        final ResultSet rs = 
+            stmt.executeQuery("SELECT * from " + 
+                              BLOBDataModelSetup.getBlobTableName());
+        println("Last");
+        rs.last();
+        
+        final int newVal = rs.getInt(1) + 11;
+        final int newSize = rs.getInt(2) / 2;
+        testUpdateBlobWithResultSetMethods(rs, newVal, newSize);
+        
+        println("Verify updated blob using result set");
+        verifyBlob(newVal, newSize, rs.getBlob(3));
+        
+        rs.close();
+    }
+
+    /**
+     * Tests updating a Blob from a forward only resultset, using
+     * result set update methods.
+     * @exception SQLException causes test to fail with error
+     * @exception IOException causes test to fail with error
+     */
+    public void testUpdateBlobFromForwardOnlyResultSetUsingResultSetMethods()
+        throws SQLException, IOException
+    {
+        final Statement stmt = 
+            con.createStatement(ResultSet.TYPE_FORWARD_ONLY,
+                                ResultSet.CONCUR_UPDATABLE);
+        final ResultSet rs = 
+            stmt.executeQuery("SELECT * from " + 
+                              BLOBDataModelSetup.getBlobTableName());
+        
+        while (rs.next()) {
+            println("Next");
+            final int size = rs.getInt(2);
+            if (size>1024*1024) break;
+        }
+        
+        final int newVal = rs.getInt(1) + 11;
+        final int newSize = rs.getInt(2) / 2;
+        testUpdateBlobWithResultSetMethods(rs, newVal, newSize);
+        
+        rs.close();
+    }
+
+    /**
+     * Tests updating a Blob from a scollable resultset, using
+     * result set update methods.
+     * @exception SQLException causes test to fail with error
+     * @exception IOException causes test to fail with error
+     */
+    public void testUpdateBlobFromScrollableResultSetUsingPositionedUpdates()
+        throws SQLException, IOException
+    {
+        final Statement stmt = 
+            con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
+                                ResultSet.CONCUR_UPDATABLE);
+        final ResultSet rs = 
+            stmt.executeQuery("SELECT * from " + 
+                              BLOBDataModelSetup.getBlobTableName());
+        println("Last");
+        rs.last();
+        
+        final int newVal = rs.getInt(1) + 11;
+        final int newSize = rs.getInt(2) / 2;
+        testUpdateBlobWithPositionedUpdate(rs, newVal, newSize);
+
+        rs.relative(0); // Necessary after a positioned update
+        
+        println("Verify updated blob using result set");
+        verifyBlob(newVal, newSize, rs.getBlob(3));
+        
+        rs.close();
+    }
+
+    /**
+     * Tests updating a Blob from a forward only resultset, using
+     * result set update methods.
+     * @exception SQLException causes test to fail with error
+     * @exception IOException causes test to fail with error
+     */
+    public void testUpdateBlobFromForwardOnlyResultSetUsingPositionedUpdates()
+        throws SQLException, IOException
+    {
+        final Statement stmt = 
+            con.createStatement(ResultSet.TYPE_FORWARD_ONLY,
+                                ResultSet.CONCUR_UPDATABLE);
+        final ResultSet rs = 
+            stmt.executeQuery("SELECT * from " + 
+                              BLOBDataModelSetup.getBlobTableName());
+        
+        while (rs.next()) {
+            println("Next");
+            final int size = rs.getInt(2);
+            if (size>1024*1024) break;
+        }
+        
+        final int newVal = rs.getInt(1) + 11;
+        final int newSize = rs.getInt(2) / 2;
+        testUpdateBlobWithPositionedUpdate(rs, newVal, newSize);
+        
+        
+        rs.close();
+    }
+    
+    /**
+     * Tests updating the Blob using result set update methods.
+     * @param rs result set, currently positioned on row to be updated
+     * @param newVal new value in val column and blob data
+     * @param newSize new size of Blob
+     * @exception SQLException causes test to fail with error
+     * @exception IOException causes test to fail with error
+     */
+    private void testUpdateBlobWithResultSetMethods(final ResultSet rs,
+                                                    final int newVal,
+                                                    final int newSize) 
+        throws SQLException, IOException
+    {
+        int val = rs.getInt(1);
+        int size = rs.getInt(2);
+        println("VerifyBlob");
+        verifyBlob(val, size, rs.getBlob(3));
+        
+        println("UpdateBlob");
+        final TestInputStream newStream = new TestInputStream(newSize, newVal);
+        
+        rs.updateInt(1, newVal);
+        rs.updateInt(2, newSize);
+        rs.updateBinaryStream(3, newStream, newSize);
+        rs.updateRow();
+        
+        println("Verify updated blob with another query");
+        verifyNewValueInTable(newVal, newSize);
+    }
+
+    /**
+     * Tests updating the Blob using positioned updates
+     * @param rs result set, currently positioned on row to be updated
+     * @param newVal new value in val column and blob data
+     * @param newSize new size of Blob
+     * @exception SQLException causes test to fail with error
+     * @exception IOException causes test to fail with error
+     */
+    private void testUpdateBlobWithPositionedUpdate(final ResultSet rs,
+                                                    final int newVal,
+                                                    final int newSize) 
+        throws SQLException, IOException
+    {
+        final PreparedStatement preparedStatement = con.prepareStatement
+            ("UPDATE " + BLOBDataModelSetup.getBlobTableName() +
+             " SET val=?, length = ?, data = ? WHERE CURRENT OF " +
+             rs.getCursorName());
+        
+        println("UpdateBlob");
+        
+        final TestInputStream newStream = new TestInputStream(newSize, newVal);
+        
+        preparedStatement.setInt(1, newVal);
+        preparedStatement.setInt(2, newSize);
+        preparedStatement.setBinaryStream(3, newStream, newSize);
+        preparedStatement.executeUpdate();
+        
+        println("Verify updated blob with another query");
+        verifyNewValueInTable(newVal, newSize);
+    }
+    
+    
+    /**
+     * Verifies that the table has row with column val=newVal
+     * and that it its data and size columns are consistent.
+     * @param newVal value expected to be found in the val column of a row
+     * @param newSize expected size of size column and size of blob
+     * @exception SQLException causes test to fail with error
+     * @exception IOException causes test to fail with error
+     */
+    private void verifyNewValueInTable(final int newVal,
+                                       final int newSize)
+        throws IOException, SQLException
+    {
+        println("Verify new value in table: " + newVal);
+        
+        final Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                                                   ResultSet.CONCUR_READ_ONLY);
+        
+        final ResultSet rs = 
+            stmt.executeQuery("SELECT * FROM " +  
+                              BLOBDataModelSetup.getBlobTableName() +
+                              " WHERE val = " + newVal);
+        
+        println("Query executed, calling next");
+        
+        boolean foundVal = false;
+        
+        while (rs.next()) {
+            println("Next called, verifying row");
+            
+            assertEquals("Unexpected value in val column", 
+                         newVal, rs.getInt(1));
+            
+            verifyBlob(newVal, newSize, rs.getBlob(3));
+            foundVal = true;
+        }
+        assertTrue("No column with value= " + newVal + " found ", foundVal);
+    }
+                          
+    /**
+     * Verifies that the blob is consistent
+     * @param expectedVal the InputStream for the Blob should return this value
+     *                    for every byte
+     * @param expecteSize the Blob should have this size
+     * @exception SQLException causes test to fail with error
+     * @exception IOException causes test to fail with error
+     */
+    private void verifyBlob(final int expectedVal, 
+                            final int expectedSize, 
+                            final Blob blob) 
+        throws IOException, SQLException
+    {
+        final InputStream stream = blob.getBinaryStream();
+        int blobSize = 0;
+        for (int val = stream.read(); val!=-1; val = stream.read()) {
+            blobSize++;
+            
+            // avoid doing a string-concat for every byte in blob
+            if (expectedVal!=val) {
+                assertEquals("Unexpected value in stream at position " + 
+                             blobSize,
+                             expectedVal, val);
+            }
+        }
+        stream.close();
+        assertEquals("Unexpected size of stream ", expectedSize, blobSize);
+    }
+
+    /**
+     * The suite decorates the tests of this class with 
+     * a setup which creates and populates the data model.
+     */
+    public static Test suite() 
+    {
+        TestSuite mainSuite = new TestSuite(BLOBTest.class);
+        return new BLOBDataModelSetup(mainSuite);
+    }
+
+    /**
+     * The setup creates a Connection to the database.
+     * @exception Exception any exception will cause test to fail with error.
+     */
+    public final void setUp() 
+        throws Exception
+    {
+        println("Setup of: " + getName());
+        con = getConnection();
+        con.setAutoCommit(false);
+    }
+    
+    /**
+     * Teardown test.
+     * Rollback connection and close it.
+     * @exception Exceptions causes the test to fail with error
+     */
+    public final void tearDown() 
+        throws Exception
+    {
+        println("Teardown of: " + getName());
+        try { 
+            con.rollback();
+            con.close();
+        } catch (SQLException e) {
+            printStackTrace(e);
+        }      
+    }
+    
+    /** JDBC Connection */        
+    private Connection con;
+}

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

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBTest_app.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBTest_app.properties?rev=419847&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBTest_app.properties
(added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BLOBTest_app.properties
Fri Jul  7 02:05:52 2006
@@ -0,0 +1,3 @@
+runwithibm13=false
+runwithjdk13=false
+runwithjdk12=false

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

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/TestInputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/TestInputStream.java?rev=419847&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/TestInputStream.java
(added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/TestInputStream.java
Fri Jul  7 02:05:52 2006
@@ -0,0 +1,62 @@
+/*
+ *
+ * Derby - Class TestInputStream
+ *
+ * Copyright 2006 The Apache Software Foundation or its
+ * licensors, as applicable.
+ *
+ * Licensed 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.util;
+import java.io.InputStream;
+import java.io.IOException;
+
+/** 
+ * TestInputStream class is a InputStream which returns
+ * a lot of data which can be inserted into a LOB.
+ */
+public final class TestInputStream extends InputStream 
+{
+    /**
+     * Constructor for TestInputStream
+     * @param length length of stream
+     * @param value value to return
+     */
+    public TestInputStream(long length, int value) 
+    {
+        this.value = value;
+        this.length = length;
+        this.pos = 0;
+    }
+    
+    /**
+     * Implementation of InputStream.read(). Returns 
+     * the value specified in constructor, unless the 
+     * end of the stream has been reached.
+     */
+    public int read() 
+        throws IOException 
+    {
+        if (++pos>length) return -1;
+        return value;
+    }
+    
+    /** Current position in stream */
+    private long pos;
+    
+    /** Value to return */
+    final int value;
+    
+    /** Length of stream */
+    final long length;
+}

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



Mime
View raw message