You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by mi...@apache.org on 2005/05/12 02:09:33 UTC

svn commit: r169737 - in /incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests: master/ suites/ tests/store/ util/corruptio/

Author: mikem
Date: Wed May 11 17:09:32 2005
New Revision: 169737

URL: http://svn.apache.org/viewcvs?rev=169737&view=rev
Log:
committing tests for DERBY-96 for suresh.thalamati@gmail.com

Attached  are some  functional tests to test the transaction log checksum feature (Derby-96).
Log corruption is simulated using a proxy storage factory that allows corruption of
the log write request before being writing to the disk.  CorruptDiskStorage factory by default forwards
all the request to the underlying disk storage factory  except when corruption flags are  enabled.

Recovery tests need to  boot the same database many times and have to use the
different Subprotocol to enable the corruption instead of the default protocol. This seems to be
possible only  by adding  a new tests suite in the current test frame work.  Added a new suite
called "storerecovery" , may be all future recovery tests can be added to this suite.


Added:
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumRecovery.out
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumRecovery1.out
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumSetup.out
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.properties
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.runall
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery.java
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1.java
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1_app.properties
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1_derby.properties
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery_app.properties
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery_derby.properties
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup.java
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup_app.properties
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup_derby.properties
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptBaseStorageFactory.java
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptDiskStorageFactory.java
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptFile.java
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptRandomAccessFile.java
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptibleIo.java
Modified:
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storeall.properties
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumRecovery.out
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumRecovery.out?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumRecovery.out (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumRecovery.out Wed May 11 17:09:32 2005
@@ -0,0 +1,2 @@
+Begin LogCheckumRecovery Test
+End LogCheckumRecovery Test

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumRecovery1.out
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumRecovery1.out?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumRecovery1.out (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumRecovery1.out Wed May 11 17:09:32 2005
@@ -0,0 +1,2 @@
+Begin LogCheckumRecovery1 Test
+End LogCheckumRecovery1 Test

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumSetup.out
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumSetup.out?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumSetup.out (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogChecksumSetup.out Wed May 11 17:09:32 2005
@@ -0,0 +1,2 @@
+Begin LogCheckum Setup Test
+End LogChecksum Setup Test

Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storeall.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storeall.properties?rev=169737&r1=169736&r2=169737&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storeall.properties (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storeall.properties Wed May 11 17:09:32 2005
@@ -16,5 +16,7 @@
 #                                 storemats, but to be run nightly.
 #        storetests.runall      - set of store tests that use one database 
 #        storeunit.runall       - set of store unit tests 
+#        storerecovery.runall   - set of recovery tests that use one database
 #        
-suites=storemore storemats storetests storeunit
+suites=storemore storemats storetests storeunit storerecovery
+

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.properties?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.properties (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.properties Wed May 11 17:09:32 2005
@@ -0,0 +1,2 @@
+usesystem=storerecovery
+

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.runall
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.runall?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.runall (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.runall Wed May 11 17:09:32 2005
@@ -0,0 +1,3 @@
+store/LogChecksumSetup.java
+store/LogChecksumRecovery.java
+store/LogChecksumRecovery1.java

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery.java?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery.java Wed May 11 17:09:32 2005
@@ -0,0 +1,80 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.store.LogChecksumRecovery
+
+   Copyright 2005 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.store;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.zip.CRC32;
+import org.apache.derby.tools.ij;
+
+/*
+ * Purpose of this class is to test the database recovery of 
+ * the inserts executed with simulated log corruption in LogChecksumSetup.java
+ * and perform some updates after a successfully boot. 
+ * This test should be run after the store/LogChecksumSetup.java.
+ *
+ * @author <a href="mailto:suresh.thalamati@gmail.com">Suresh Thalamati</a>
+ * @version 1.0
+ * @see LogChecksumSetup
+ */
+
+public class LogChecksumRecovery extends LogChecksumSetup {
+
+	LogChecksumRecovery()
+	{
+		super();
+	}
+	
+	private void runTest(Connection conn) throws SQLException
+	{
+		logMessage("Begin LogCheckumRecovery Test");
+		verifyData(conn, 10);
+		updateAndCorrupt(conn, 10);
+		logMessage("End LogCheckumRecovery Test");
+	}
+	
+	public static void main(String[] argv) 
+        throws Throwable
+    {
+		
+        LogChecksumRecovery lctest = new LogChecksumRecovery();
+   		ij.getPropertyArg(argv); 
+        Connection conn = ij.startJBMS();
+        conn.setAutoCommit(false);
+
+        try {
+            lctest.runTest(conn);
+        }
+        catch (SQLException sqle) {
+			org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(
+                System.out, sqle);
+			sqle.printStackTrace(System.out);
+		}
+    }
+}
+
+
+
+
+
+
+
+
+

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1.java?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1.java Wed May 11 17:09:32 2005
@@ -0,0 +1,78 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.store.LogChecksumRecovery1
+
+   Copyright 2005 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.store;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.zip.CRC32;
+import org.apache.derby.tools.ij;
+
+/*
+ * Purpose of this class is to test the database recovery of the  
+ * updates statements executed in LogChecksumRecovery.java.
+ * This test should be run after the store/LogChecksumRecovery.java.
+ *
+ * @author <a href="mailto:suresh.thalamati@gmail.com">Suresh Thalamati</a>
+ * @version 1.0
+ * @see LogChecksumSetup
+ * @see LogChecksumRecovery
+ */
+
+public class LogChecksumRecovery1 extends LogChecksumSetup {
+
+	LogChecksumRecovery1() {
+		super();
+	}
+	
+	private void runTest(Connection conn) throws SQLException
+	{
+		logMessage("Begin LogCheckumRecovery1 Test");
+		verifyData(conn, 10);
+		logMessage("End LogCheckumRecovery1 Test");
+	}
+	
+	public static void main(String[] argv) 
+        throws Throwable
+    {
+		
+        LogChecksumRecovery1 lctest = new LogChecksumRecovery1();
+   		ij.getPropertyArg(argv); 
+        Connection conn = ij.startJBMS();
+        conn.setAutoCommit(false);
+
+        try {
+            lctest.runTest(conn);
+        }
+        catch (SQLException sqle) {
+			org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(
+                System.out, sqle);
+			sqle.printStackTrace(System.out);
+		}
+    }
+}
+
+
+
+
+
+
+
+
+

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1_app.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1_app.properties?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1_app.properties (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1_app.properties Wed May 11 17:09:32 2005
@@ -0,0 +1,3 @@
+ij.protocol=jdbc:derby:csf
+derby.subSubProtocol.csf=org.apache.derbyTesting.functionTests.util.corruptio.CorruptDiskStorageFactory
+database=jdbc:derby:csf:wombat

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1_derby.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1_derby.properties?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1_derby.properties (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery1_derby.properties Wed May 11 17:09:32 2005
@@ -0,0 +1,2 @@
+#set checkpoint interval to max to test recovery with full replay of log
+derby.storage.checkpointInterval=134217727

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery_app.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery_app.properties?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery_app.properties (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery_app.properties Wed May 11 17:09:32 2005
@@ -0,0 +1,3 @@
+ij.protocol=jdbc:derby:csf
+derby.subSubProtocol.csf=org.apache.derbyTesting.functionTests.util.corruptio.CorruptDiskStorageFactory
+database=jdbc:derby:csf:wombat

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery_derby.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery_derby.properties?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery_derby.properties (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumRecovery_derby.properties Wed May 11 17:09:32 2005
@@ -0,0 +1,2 @@
+#set checkpoint interval to max to test recovery with full replay of log
+derby.storage.checkpointInterval=134217727

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup.java?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup.java Wed May 11 17:09:32 2005
@@ -0,0 +1,263 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.store.LogChecksumSetup
+
+   Copyright 2005 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.store;
+import java.sql.*;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.zip.CRC32;
+import org.apache.derbyTesting.functionTests.util.corruptio.CorruptibleIo;
+import org.apache.derby.tools.ij;
+
+/*
+ * Purpose of this class is to simulate out of order incomplete 
+ * log write corruption (see derby-96 for details) using the proxy storage
+ * factory (org.apache.derbyTesting.functionTests.util.corruptio.
+ * CorruptDiskStorageFactory) instead of the default storage factory.
+ * By defailt all io is delegated to the default database storage factory,
+ * except when corruption is enabled through CorruptibleIo class.
+ * Proxy storage factory is loaded using the following properties in 
+ * the test properties file:
+ * derby.subSubProtocol.csf=org.apache.derbyTesting.functionTests.
+ *             util.corruptio.CorruptDiskStorageFactory
+ *  database=jdbc:derby:csf:wombat
+ *
+ * @author <a href="mailto:suresh.thalamati@gmail.com">Suresh Thalamati</a>
+ * @version 1.0
+ * @see CorruptibleIo
+ */
+
+public class LogChecksumSetup{
+
+	private CorruptibleIo cbio;
+
+	LogChecksumSetup()
+	{
+		cbio = CorruptibleIo.getInstance();
+	}
+	
+	/**
+	 * Insert some rows into the table and corrupt the log for the last row,
+	 * so when we recover , there should be one row less even though we committed.
+	 */
+	void insertAndCorrupt(Connection conn, int rowCount) throws SQLException {
+
+		PreparedStatement ps = conn.prepareStatement("INSERT INTO " + 
+													 "T1" + 
+													 " VALUES(?,?,?)");
+
+		java.util.Random r = new java.util.Random();
+		CRC32 checksum = new CRC32(); // holder for the checksum
+		boolean corrupt = false;
+		for (int i = 0; i < rowCount; i++) {
+			
+			//setup last row for log corruption
+			if (i == (rowCount -1 ))
+			{
+				// Note: offset/len for corruption  here refers to 
+				// the actual log write request
+				// that is being done for this insert. 
+				setupLogCorruption(50, 10);
+				corrupt = true;
+			}
+			ps.setInt(1, i); // ID
+			byte[] dataBytes  = generateBinaryData(r, 90000 , 1000 * i);
+			ps.setBytes(2, dataBytes); 
+			//calculate checksum for blob data 
+			checksum.update(dataBytes, 0, dataBytes.length);
+			checksum.reset();
+			checksum.update(dataBytes, 0, dataBytes.length);
+			ps.setLong(3, checksum.getValue());
+			ps.executeUpdate();
+			conn.commit();
+		}
+	}
+
+		
+	/**
+	 * update some rows in the table and corrupt the log for the last row,
+	 * so when we recover , All checsum should be correct because corrupted 
+	 * log transaction should been rolled back.
+	 */
+
+	void updateAndCorrupt(Connection conn, int rowCount) throws SQLException{
+
+		PreparedStatement ps = conn.prepareStatement("update " + "T1" + 
+													 " SET " +
+													 "DATA=?, DATACHECKSUM=? where ID=?");
+		
+		java.util.Random r = new java.util.Random();
+		CRC32 checksum = new CRC32(); // holder for the checksum
+		int updateCount = 0;
+		boolean corrupt = false;
+		for (int i = 0; i < rowCount; i++) {
+			
+			//setup last row for log corruption
+			if (i == (rowCount -1 ))
+			{
+				// Note: offset/len for corruption  here refers to 
+				// the actual log write request
+				// that is being done for this insert. 
+				setupLogCorruption(50, 10);
+				corrupt = true;
+			}
+			byte[] dataBytes  = generateBinaryData(r, 1234 , 5000 * i);
+			ps.setBytes(1, dataBytes); 
+
+			// calculate checksum for blob data 
+			checksum.update(dataBytes, 0, dataBytes.length);
+			checksum.reset();
+			checksum.update(dataBytes, 0, dataBytes.length);
+
+			ps.setLong(2, checksum.getValue());
+			ps.setInt(3, i); // ID
+			updateCount +=  ps.executeUpdate();
+			conn.commit();
+		}
+	}
+
+
+	/*
+	 * read the data from the table and verify the blob data using the 
+	 * checksum and make sure that expected number rows exist in the table. 
+	 * 
+	 */
+	void verifyData(Connection conn, int expectedRowCount) throws SQLException {
+		
+		Statement s = conn.createStatement();
+		CRC32 checksum = new CRC32(); // holder for the checksum
+		
+		ResultSet rs = s.executeQuery("SELECT DATA , DATACHECKSUM, ID FROM "
+									  + "T1" );
+		int count = 0;
+		while(rs.next())
+		{
+			byte[] dataBytes = rs.getBytes(1);
+			long ckmRead = rs.getLong(2);
+			int id = rs.getInt(3);
+
+			checksum.reset();
+			checksum.update(dataBytes, 0, dataBytes.length);
+
+			if(checksum.getValue() != ckmRead )
+			{
+				logMessage("CHECKSUMs ARE NOT MATCHING");
+				logMessage("ID=" + id + " Checksum From DB:" + ckmRead);
+				logMessage("Recalcaulted sum :" + checksum.getValue());
+				logMessage("Length of Data:" +  dataBytes.length);
+			}
+			
+			count++;
+		}
+		conn.commit();
+
+		if(count != expectedRowCount)
+		{
+			logMessage("Expected Number Of Rows (" + 
+					   expectedRowCount + ")" +  "!="  + 
+					   "No Of rows in the Table(" + 
+					   count + ")");
+		}
+	}
+
+	/* 
+	 * create the tables that are used by this test.
+	 */
+	private  void createTable(Connection conn) throws SQLException {
+
+		Statement s = conn.createStatement();
+		s.executeUpdate("CREATE TABLE " + "T1" + "(ID INT," +
+						"DATA BLOB(300000),"+ 
+						"DATACHECKSUM BIGINT)");
+		conn.commit();
+		s.close();
+	}
+
+	/*
+	 * Log is corrupted using the corrupt storage factory. 
+	 * setup offset/length where we want the transaction 
+	 * log to be corrupted. Transaction tat the corruption 
+	 * is simulated  on should be rolled back because the log check
+	 * should identify that the writes were incomplete.  
+	 */
+	private void setupLogCorruption(int off , int len)
+	{
+		cbio.setLogCorruption(true);
+		cbio.setOffset(off); 
+		cbio.setLength(len); 
+	}
+
+
+	/*
+	 * utility routine to generate random byte array of data.
+	 */
+	private  byte[] generateBinaryData(java.util.Random r, 
+											 int factor,
+											 int size)	{
+		
+		ByteArrayOutputStream baos = new ByteArrayOutputStream(64);
+		try{
+			DataOutputStream daos = new DataOutputStream(baos);
+			for(int i = 0 ; i < size ; i++)
+			{
+				int p = r.nextInt() % factor;
+				if (p < 0)
+					p = p * -1;
+				daos.writeInt(p);
+			}
+			
+		}catch(IOException ie) 
+		{
+			logMessage(ie.getMessage()) ;
+		}
+		return baos.toByteArray();
+	}
+
+
+	private void runTest(Connection conn) throws SQLException
+	{
+		logMessage("Begin LogCheckum Setup Test");
+		createTable(conn);
+		insertAndCorrupt(conn, 11);
+		logMessage("End LogChecksum Setup Test");
+	}
+	
+    void logMessage(String   str)
+    {
+        System.out.println(str);
+    }
+
+	public static void main(String[] argv) throws Throwable {
+        LogChecksumSetup lctest = new LogChecksumSetup();
+   		ij.getPropertyArg(argv); 
+        Connection conn = ij.startJBMS();
+        conn.setAutoCommit(false);
+
+        try {
+            lctest.runTest(conn);
+        }
+        catch (SQLException sqle) {
+			org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(
+                System.out, sqle);
+			sqle.printStackTrace(System.out);
+		}
+    }
+}

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup_app.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup_app.properties?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup_app.properties (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup_app.properties Wed May 11 17:09:32 2005
@@ -0,0 +1,3 @@
+ij.protocol=jdbc:derby:csf
+derby.subSubProtocol.csf=org.apache.derbyTesting.functionTests.util.corruptio.CorruptDiskStorageFactory
+database=jdbc:derby:csf:wombat;create=true

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup_derby.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup_derby.properties?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup_derby.properties (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogChecksumSetup_derby.properties Wed May 11 17:09:32 2005
@@ -0,0 +1,2 @@
+#set checkpoint interval to max to test recovery with full replay of log
+derby.storage.checkpointInterval=134217727

Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant?rev=169737&r1=169736&r2=169737&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant Wed May 11 17:09:32 2005
@@ -125,3 +125,9 @@
 xab2354_sed.properties
 OnlineCompressTest_app.properties
 OnlineCompressTest_derby.properties
+LogChecksumSetup_app.properties
+LogChecksumSetup_derby.properties
+LogChecksumRecovery_app.properties
+LogChecksumRecovery_derby.properties
+LogChecksumRecovery1_app.properties
+LogChecksumRecovery1_derby.properties

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptBaseStorageFactory.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptBaseStorageFactory.java?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptBaseStorageFactory.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptBaseStorageFactory.java Wed May 11 17:09:32 2005
@@ -0,0 +1,265 @@
+/*
+
+   Derby - Class org.apache.derby.impl.io.BaseStorageFactory
+
+   Copyright 2004 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.corruptio;
+import org.apache.derby.io.WritableStorageFactory;
+import org.apache.derby.io.StorageFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.SyncFailedException;
+
+/**
+ * This class provides a proxy base implementation of the 
+ * WritableStorageFactory interface to instrument I/O operations for testing 
+ * purposes. 
+ * Some methods in this class adds support for corrupting the I/O operation 
+ * sent by the engine before invoking the real storage factory underneath. 
+ * By deault all the calls will go to the real storage factory defined by the 
+ * concrete class, unless corruption is enabled through CorruptibleIo instance. 
+ * 
+ * @see CorruptibleIo
+ * @see WritableStorageFactory
+ * @see StorageFactory
+ * 
+ */
+
+abstract class CorruptBaseStorageFactory implements WritableStorageFactory
+{
+
+	protected WritableStorageFactory realStorageFactory;
+
+    /**
+     * Most of the initialization is done in the init method.
+     */
+    CorruptBaseStorageFactory()
+    {}
+
+    /**
+     * Classes implementing the StorageFactory interface must have a null
+     * constructor.  This method is called when the database is booted up to
+     * initialize the class. It should perform all actions necessary to start 
+     * the basic storage, such as creating a temporary file directory.
+     *
+     * The init method will be called once, before any other method is called, 
+     * and will not be called again.
+     *
+     * @param home          The name of the directory containing the database. 
+     *                      It comes from the system.home system property.
+     *                      It may be null. A storage factory may decide to 
+     *                      ignore this parameter. (For instance the classpath
+     *                      storage factory ignores it.)
+     *
+     * @param databaseName  The name of the database (directory). 
+     *                      All relative pathnames are relative to this 
+     *                      directory.
+     *                      If null then the storage factory will only be used 
+     *                      to deal with the directory containing the databases.
+     * @param create        If true then the database is being created.
+     * @param tempDirName   The name of the temporary file directory set in 
+     *                      properties. If null then a default directory should
+     *                      be used. Each database should get a separate 
+     *                      temporary file directory within this one to avoid 
+     *                      collisions.
+     *
+     * @param uniqueName    A unique name that can be used to create the 
+     *                      temporary file directory for this database.
+     *
+     * @exception IOException on an error (unexpected).
+     */
+    public void init( String home, String databaseName, String tempDirName, String uniqueName)
+        throws IOException
+    {
+		realStorageFactory = getRealStorageFactory();
+		realStorageFactory.init(home, databaseName, tempDirName,  uniqueName);
+    } // end of init
+
+    
+    public void shutdown()
+    {
+		realStorageFactory.shutdown();
+    }
+    
+
+    /**
+     * Get the canonical name of the database. 
+     *
+     * This is a name that uniquely identifies it. It is system dependent.
+     *
+     * The normal, disk based implementation uses method 
+     * java.io.File.getCanonicalPath on the directory holding the
+     * database to construct the canonical name.
+     *
+     * @return the canonical name
+     *
+     * @exception IOException if an IO error occurred during the construction 
+     *                        of the name.
+     */
+    public String getCanonicalName() throws IOException
+    {
+		return realStorageFactory.getCanonicalName();
+    }
+    
+    /**
+     * Construct a StorageFile from a path name.
+     *
+     * @param path The path name of the file
+     *
+     * @return A corresponding StorageFile object
+     */
+    public StorageFile newStorageFile( String path)
+    {
+        return new CorruptFile(realStorageFactory.newStorageFile(path));
+    }
+    
+    /**
+     * Construct a StorageFile from a directory and file name.
+     *
+     * @param directoryName The directory part of the path name.
+     * @param fileName The name of the file within the directory.
+     *
+     * @return A corresponding StorageFile object
+     */
+    public StorageFile newStorageFile( String directoryName, String fileName)
+    {
+		return new CorruptFile(realStorageFactory.newStorageFile(directoryName, fileName));
+    }
+    
+    /**
+     * Construct a StorageFile from a directory and file name.
+     *
+     * @param directoryName The directory part of the path name.
+     * @param fileName The name of the file within the directory.
+     *
+     * @return A corresponding StorageFile object
+     */
+    public StorageFile newStorageFile( StorageFile directoryName, String fileName)
+    {
+		StorageFile realDirFile = ((CorruptFile) directoryName).getRealFileInstance();
+		return new CorruptFile(realStorageFactory.newStorageFile(realDirFile, fileName));
+    }
+    
+    /**
+     * Get the pathname separator character used by the StorageFile 
+     * implementation.
+     *
+     * @return the pathname separator character. (Normally '/' or '\').
+     */
+    public char getSeparator()
+    {
+		return realStorageFactory.getSeparator();
+    }
+
+    /**
+     * Get the abstract name of the directory that holds temporary files.
+     *
+     * @return a directory name
+     */
+    public StorageFile getTempDir()
+    {
+		return new CorruptFile(realStorageFactory.getTempDir());
+    }
+
+    /**
+     * This method is used to determine whether the storage is fast 
+     * (RAM based) or slow (disk based).
+     *
+     * It may be used by the database engine to determine the default size of 
+     * the page cache.
+     *
+     * @return <b>true</b> if the storage is fast, <b>false</b> if it is slow.
+     */
+    public boolean isFast()
+    {
+		return realStorageFactory.isFast();
+    }
+
+    public boolean isReadOnlyDatabase()
+    {
+		return realStorageFactory.isReadOnlyDatabase();
+    }
+
+    /**
+     * Determine whether the storage supports random access. 
+     * If random access is not supported then it will only be accessed using 
+     * InputStreams and OutputStreams (if the database is writable).
+     *
+     * @return <b>true</b> if the storage supports random access, <b>false</b> if it is writable.
+     */
+    public boolean supportsRandomAccess()
+    {
+		return realStorageFactory.supportsRandomAccess();
+    }
+
+    public int getStorageFactoryVersion()
+    {
+		return realStorageFactory.getStorageFactoryVersion();
+    }
+
+
+	
+    /**
+     * Force the data of an output stream out to the underlying storage. 
+     *
+     * That is, ensure that it has been made persistent. If the database is to 
+     * be transient, that is, if the database does not survive a restart, then 
+     * the sync method implementation need not do anything.
+     *
+     * @param stream    The stream to be synchronized.
+     * @param metaData  If true then this method must force both changes to the
+     *                  file's contents and metadata to be written to storage; 
+     *                  if false, it need only force file content changes to be
+     *                  written. The implementation is allowed to ignore this 
+     *                  parameter and always force out metadata changes.
+     *
+     * @exception IOException if an I/O error occurs.
+     * @exception SyncFailedException Thrown when the buffers cannot be flushed,
+     *            or because the system cannot guarantee that all the buffers 
+     *            have been synchronized with physical media.
+     */
+    public void sync( OutputStream stream, boolean metaData) throws IOException, SyncFailedException
+    {
+		realStorageFactory.sync(stream, metaData);
+    }
+
+    /**
+     * This method tests whether the "rws" and "rwd" modes are implemented. 
+     *
+     * If the "rws" method is supported then the database engine will conclude 
+     * that the write methods of "rws" mode StorageRandomAccessFiles are
+     * slow but the sync method is fast and optimize accordingly.
+     *
+     * @return <b>true</b> if an StIRandomAccess file opened with "rws" or "rwd" modes immediately writes data to the
+     *         underlying storage, <b>false</b> if not.
+     */
+    public boolean supportsRws()
+    {
+		return realStorageFactory.supportsRws();
+    }
+
+	
+	/**
+     * get the  real storage factory
+     *
+     */
+	abstract WritableStorageFactory getRealStorageFactory();
+
+}

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptDiskStorageFactory.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptDiskStorageFactory.java?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptDiskStorageFactory.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptDiskStorageFactory.java Wed May 11 17:09:32 2005
@@ -0,0 +1,97 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.util.corruptio.CorruptDiskStorageFactory
+
+   Copyright 2004 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.corruptio;
+import org.apache.derby.io.WritableStorageFactory;
+import org.apache.derby.io.StorageFactory;
+import org.apache.derby.iapi.services.info.JVMInfo;
+
+/**
+ * This class provides proxy implementation of the StorageFactory
+ * interface for testing. 
+ *
+ * Storage Factory is used by the database engine to access 
+ * persistent data and transaction logs. By default all the method calls
+ * delegate the work to the real disk storage factory
+ * (org.apache.derby.impl.io.DirStorageFactory)
+ * based on the classes in the java.io packgs. In some cases this  factory
+ * instruments some methods to corrupt the io to simulate disk corruptions for
+ * testing. For example to simulate out of order partial writes to disk before
+ * the crash. 
+ * 
+ * Derby by default uses the storage factory implementation in 
+ * DirStorageFactory/DirStorageFactory4 when a database is accessed with 
+ * "jdbc:derby:<databaseName>". This factory can be specified instead using 
+ * derby.subSubProtocol.<sub protocol name>  For example:
+ *
+ *  derby.subSubProtocol.csf=org.apache.derbyTesting.functionTests.
+ *             util.corruptio.CorruptDiskStorageFactory
+ *  database need to be accessed by specifying the subporotocol name like
+ *  'jdbc:derby:csf:wombat'.
+ *
+ * Interaction between the tests that requires instrumenting the i/o and 
+ * this factory is through the flags in CorruptibleIo class. Tests should not 
+ * call the methods in this factory directly. Database engine invokes the 
+ * methods in this factory, so they can instrumented to do whatever is 
+ * required for testing.
+ * 
+ * @author <a href="mailto:suresh.thalamati@gmail.com">Suresh Thalamati</a>
+ * @version 1.0
+ * @see CorruptibleIo
+ * @see WritableStorageFactory
+ * @see StorageFactory
+ * 
+ */
+
+public class CorruptDiskStorageFactory extends CorruptBaseStorageFactory
+{
+	/*
+	 * returns the real storage factory to which all the call should be 
+	 * delegated from the proxy methods.  
+	 */
+	WritableStorageFactory getRealStorageFactory()
+	{
+		String dirStorageFactoryClass;
+		if( JVMInfo.JDK_ID >= JVMInfo.J2SE_14)
+        {
+            dirStorageFactoryClass = 
+                "org.apache.derby.impl.io.DirStorageFactory4";
+        }
+        else
+        {
+            dirStorageFactoryClass = 
+                "org.apache.derby.impl.io.DirStorageFactory";
+        }
+		
+		WritableStorageFactory storageFactory = null;
+		try{
+			Class storageFactoryClass = Class.forName(dirStorageFactoryClass);
+			storageFactory = 
+                (WritableStorageFactory) storageFactoryClass.newInstance();
+		}catch(Exception e)
+		{
+			System.out.println(
+                "Failed to instantiate the disk storeage classes");
+			e.printStackTrace();
+		}
+		
+		return  storageFactory;
+	}
+}

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptFile.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptFile.java?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptFile.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptFile.java Wed May 11 17:09:32 2005
@@ -0,0 +1,390 @@
+/*
+
+   Derby - Class org.apache.derby.impl.io.DirFile
+
+   Copyright 2004 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.corruptio;
+import org.apache.derby.io.StorageFile;
+import org.apache.derby.io.StorageRandomAccessFile;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.io.RandomAccessFile;
+
+/**
+ * This class provides proxy implementation of the StorageFile interface. It is
+ * used by CorruptDiskStorageFactory to instrument the database engine 
+ * i/o for testing.
+ *
+ * @see StorageFile
+ */
+class CorruptFile implements StorageFile {
+
+	private StorageFile realFile = null;
+
+	CorruptFile(StorageFile realFile)
+	{
+		this.realFile = realFile;
+	}
+
+
+    /**
+     * Get the names of all files and sub-directories in the directory named 
+     * by this path name.
+     *
+     * This method is only used in a writable database.
+     *
+     * @return An array of the names of the files and directories in this
+     *         directory denoted by this abstract pathname. The returned array 
+     *         will have length 0 if this directory is empty. Returns null if 
+     *         this StorageFile is not  a directory, or if an I/O error occurs.
+     *         The return value is undefined if the database is read-only.
+     */
+    public String[] list()
+	{
+		return realFile.list();
+	}
+
+    /**
+     * Determine whether the named file is writable.
+     *
+     * @return <b>true</b> if the file exists and is writable, <b>false</b> if not.
+     */
+    public boolean canWrite()
+	{
+		return realFile.canWrite();
+	}
+
+    /**
+     * Tests whether the named file exists.
+     *
+     * @return <b>true</b> if the named file exists, <b>false</b> if not.
+     */
+    public boolean exists()
+	{
+		return realFile.exists();
+	}
+
+    /**
+     * Tests whether the named file is a directory, or not. 
+     * This is only called in writable storage factories.
+     *
+     * @return <b>true</b> if named file exists and is a directory, 
+     *         <b>false</b> if not.
+     *         The return value is undefined if the storage is read-only.
+     */
+    public boolean isDirectory()
+	{
+		return realFile.isDirectory();
+	}	
+
+    /**
+     * Deletes the named file or empty directory. 
+     * This method does not delete non-empty directories.
+     *
+     * @return <b>true</b> if the named file or directory is successfully 
+     *         deleted, <b>false</b> if not
+     */
+    public boolean delete()
+	{
+		return realFile.delete();
+	}
+
+    /**
+     * Deletes the named file and, if it is a directory, all the files and 
+     * directories it contains.
+     *
+     * @return <b>true</b> if the named file or directory is successfully 
+     *         deleted, <b>false</b> if not
+     */
+    public boolean deleteAll()
+	{
+		return realFile.deleteAll();
+	}
+    /**
+     * Converts this StorageFile into a pathname string. 
+     * The character returned by StorageFactory.getSeparator()
+     * is used to separate the directory and file names in the sequence.
+     *
+     *<p>
+     *<b>The returned path may include the database directory. 
+     * Therefore it cannot be directly used to make an StorageFile
+     * equivalent to this one.</b>
+     *
+     * @return The pathname as a string.
+     *
+     * @see StorageFactory#getSeparator
+     */
+    public String getPath()
+	{
+		return realFile.getPath();
+	}
+    /**
+     * Converts this StorageFile into a canonical pathname string. 
+     * The form of the canonical path is system dependent.
+     *
+     * @return The pathname as a string.
+     *
+     * @exception IOException if an I/O error occurred while finding the 
+     *                        canonical name
+     */
+    public String getCanonicalPath() throws IOException
+	{
+		return realFile.getCanonicalPath();
+	}
+
+    /**
+     * @return The last segment in the path name, "" if the path name sequence 
+     *         is empty.
+     */
+    public String getName()
+    {
+		return realFile.getName();
+	}
+
+    /**
+     * If the named file does not already exist then create it as an empty 
+     * normal file.
+     *
+     * The implementation must synchronize with other threads accessing the 
+     * same file (in the same or a different process).
+     * If two threads both attempt to create a file with the same name
+     * at the same time then at most one should succeed.
+     *
+     * @return <b>true</b> if this thread's invocation of createNewFile 
+     *         successfully created the named file;
+     *         <b>false</b> if not, i.e. <b>false</b> if the named file 
+     *         already exists or if another concurrent thread created it.
+     *
+     * @exception IOException - If the directory does not exist or some 
+     *                          other I/O error occurred
+     */
+    public boolean createNewFile() throws IOException
+	{
+		return realFile.createNewFile();
+	}
+
+    /**
+     * Rename the file denoted by this name. 
+     *
+     * Note that StorageFile objects are immutable. This method renames the 
+     * underlying file, it does not change this StorageFile object. The 
+     * StorageFile object denotes the same name as before, however the exists()
+     * method will return false after the renameTo method executes successfully.
+     *
+     * <p> 
+     * It is not specified whether this method will succeed if a file 
+     * already exists under the new name.
+     *
+     * @param newName the new name.
+     *
+     * @return <b>true</b> if the rename succeeded, <b>false</b> if not.
+     */
+    public boolean renameTo( StorageFile newName)
+    {
+		return realFile.renameTo(newName);
+	}
+
+    /**
+     * Creates the named directory.
+     *
+     * @return <b>true</b> if the directory was created; <b>false</b> if not.
+     */
+    public boolean mkdir()
+	{
+		return realFile.mkdir();
+	}
+    /**
+     * Creates the named directory, and all nonexistent parent directories.
+     *
+     * @return <b>true</b> if the directory was created, <b>false</b> if not
+     */
+    public boolean mkdirs()
+	{
+		return realFile.mkdirs();
+	}
+
+
+    /**
+     * Returns the length of the named file if it is not a directory. 
+     *
+     * The return value is not specified if the file is a directory.
+     *
+     * @return The length, in bytes, of the named file if it exists and is not 
+     *         a directory, 0 if the file does not exist, or any value if the 
+     *         named file is a directory.
+     */
+    public long length()
+	{
+		return realFile.length();
+	}
+
+    /**
+     * Make the named file or directory read-only. 
+     *
+     * This interface does not specify whether this also makes the file 
+     * undeletable.
+     *
+     * @return <b>true</b> if the named file or directory was made read-only, 
+     *         or it already was read-only; <b>false</b> if not.
+     */
+    public boolean setReadOnly()
+	{
+		return realFile.setReadOnly();
+	}
+
+    /**
+     * Get the name of the parent directory if this name includes a parent.
+     *
+     * @return An StorageFile denoting the parent directory of this StorageFile,
+     *         if it has a parent, null if it does not have a parent.
+     */
+    public StorageFile getParentDir()
+    {
+		return realFile.getParentDir();
+    }
+    
+    /**
+     * Creates an output stream from a file name.
+     *
+     * @param name The file name.
+     *
+     * @return an output stream suitable for writing to the file.
+     *
+     * @exception FileNotFoundException if the file exists but is a directory
+     *            rather than a regular file, does not exist but cannot be 
+     *            created, or cannot be opened for any other reason.
+     */
+    public OutputStream getOutputStream( ) throws FileNotFoundException
+    {
+		return realFile.getOutputStream();
+    }
+    
+    /**
+     * Creates an output stream from a file name.
+     *
+     * @param append If true then data will be appended to the end of the file,
+     *               if it already exists.
+     *               If false and a normal file already exists with this name 
+     *               the file will first be truncated to zero length.
+     *
+     * @return an output stream suitable for writing to the file.
+     *
+     * @exception FileNotFoundException if the file exists but is a directory 
+     *                                  rather than a regular file, does not 
+     *                                  exist but cannot be created, or cannot 
+     *                                  be opened for any other reason.
+     */
+    public OutputStream getOutputStream( final boolean append) throws FileNotFoundException
+    {
+		return realFile.getOutputStream(append);
+    }
+
+    /**
+     * Creates an input stream from a file name.
+     *
+     * @param name The file name.
+     *
+     * @return an input stream suitable for reading from the file.
+     *
+     * @exception FileNotFoundException if the file is not found.
+     */
+    public InputStream getInputStream( ) throws FileNotFoundException
+    {
+		return realFile.getInputStream();
+    }
+
+    /**
+     * Get an exclusive lock. 
+     *
+     * This is used to ensure that two or more JVMs do not open the same 
+     * database at the same time.
+     *
+     * @param lockFile The name of the lock. In a file system implementation it
+     *                 will be the name of a lock file.
+     *
+     * @return EXCLUSIVE_FILE_LOCK_NOT_AVAILABLE if the lock cannot be 
+     *         acquired because it is already held.
+     *         <br> EXCLUSIVE_FILE_LOCK if the lock was successfully acquired.
+     *         <br> NO_FILE_LOCK_SUPPORT if the system does not support 
+     *         exclusive locks.<br>
+     */
+    public synchronized int getExclusiveFileLock()
+	{
+		return realFile.getExclusiveFileLock();
+
+	} // end of getExclusiveFileLock
+
+	/**
+     * Release the resource associated with an earlier acquired exclusive lock
+     *
+     * @param lockFile the name of the lock file
+     *
+     * @see #getExclusiveFileLock
+     */
+	public synchronized void releaseExclusiveFileLock()
+	{
+		realFile.releaseExclusiveFileLock();
+
+	} // End of releaseExclusiveFileLock
+
+
+    /**
+     * Get a random access (read/write) file.
+     *
+     * @param name The name of the file.
+     * @param mode "r", "rw", "rws", or "rwd". The "rws" and "rwd" modes specify
+     *             that the data is to be written to persistent store, 
+     *             consistent with the java.io.RandomAccessFile class 
+     *             ("synchronized" with the persistent storage, in the file 
+     *             system meaning of the word "synchronized").  However
+     *             the implementation is not required to implement the "rws" or
+     *             "rwd" modes. The implementation may treat "rws" and "rwd" as
+     *             "rw". It is up to the user of this interface to call the 
+     *             StorageRandomAccessFile.sync method. If the "rws" or "rwd" 
+     *             modes are supported and the RandomAccessFile was opened in 
+     *             "rws" or "rwd" mode then the implementation of 
+     *             StorageRandomAccessFile.sync need not do anything.
+     *
+     * @return an object that can be used for random access to the file.
+     *
+     * @exception IllegalArgumentException if the mode argument is not equal to
+     *                                     one of "r", "rw".
+     * @exception FileNotFoundException    if the file exists but is a directory
+     *                                     rather than a regular file, or cannot
+     *                                     be opened or created for any other 
+     *                                     reason .
+     */
+    public StorageRandomAccessFile getRandomAccessFile( String mode) throws FileNotFoundException
+    {
+		return new CorruptRandomAccessFile(realFile.getRandomAccessFile(mode), (File) realFile);
+    }
+
+	/**
+	 * retuns the real file handle that is used to delegate the calls
+	 */
+	protected StorageFile getRealFileInstance()
+	{
+		return realFile;
+	}
+
+}

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptRandomAccessFile.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptRandomAccessFile.java?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptRandomAccessFile.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptRandomAccessFile.java Wed May 11 17:09:32 2005
@@ -0,0 +1,359 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.util.corruptio.CorruptRandomAccessFile
+
+   Copyright 2004 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.corruptio;
+import org.apache.derby.io.StorageRandomAccessFile;
+import java.io.IOException;
+import java.io.File;
+
+
+/**
+ * This class provides a proxy implementation of the StorageRandomAccess File
+ * interface.  It is used by CorruptDiskStorageFactory to instrument the database engine 
+ * i/o for testing puproses. How the i/o operation are corrupted is based on the values
+ * set in the instance of the Singleton CorruptibleIo class by the tests.
+ * Methods in this class functon similar to java.io.RandomAccessFile except
+ * when modified to perform the corruptios.
+ *
+ * @author <a href="mailto:suresh.thalamati@gmail.com">Suresh Thalamati</a>
+ * @version 1.0
+ * @see java.io.RandomAccessFile
+ * @see StorageRandomAccessFile
+ */
+public class CorruptRandomAccessFile implements StorageRandomAccessFile
+{
+
+	private StorageRandomAccessFile realRaf;
+	private CorruptibleIo cbio;
+	private File realFile;
+
+    /**
+     * Construct a CorruptRandomAccessFile
+     *
+     * @param raf  The real random access file to which  calls are delegated fro
+     *              this proxy class.
+     */
+    CorruptRandomAccessFile(StorageRandomAccessFile raf, File realFile)
+    {
+		this.realRaf = raf;
+		cbio =  CorruptibleIo.getInstance();
+		this.realFile = realFile;
+    }
+
+	
+	/**
+     * Closes this file.
+     */
+    public void close() throws IOException
+	{
+		realRaf.close();
+	}
+
+    /**
+     * Get the current offset in this file.
+     */
+    public long getFilePointer() throws IOException
+	{
+		return realRaf.getFilePointer();
+	}
+
+    /**
+     * Gets the length of this file.
+     */
+    public long length() throws IOException
+	{
+		return realRaf.length();
+	}
+
+    /**
+     * Set the file pointer. 
+     */
+    public void seek(long newFilePointer) throws IOException
+	{
+		realRaf.seek(newFilePointer);
+	}
+
+    /**
+     * Sets the length of this file, either extending or truncating it.
+     */
+    public void setLength(long newLength) throws IOException
+	{
+		realRaf.setLength(newLength);
+	}
+    
+    /**
+     * Force any changes out to the persistent store. 
+     */
+    public void sync( boolean metaData) throws IOException
+	{
+		realRaf.sync(metaData);
+	}
+
+
+	/*** Following functions Implement DataInput interfaces ****/
+
+    /**
+     * Reads some bytes from an input  stream into the byte array.
+     */
+    public void readFully(byte b[]) throws IOException
+	{
+		realRaf.readFully(b);
+	}
+
+    /**
+     *
+     * Reads the specified number of  bytes from an input stream.
+     */
+    public void readFully(byte b[], int off, int len) throws IOException
+	{
+		realRaf.readFully(b , off, len);
+	}
+
+    /**
+     * skip over <code>nBytes</code> bytes of data 
+     */
+    public int skipBytes(int nBytes) throws IOException
+	{
+		return realRaf.skipBytes(nBytes);
+	}
+
+    /**
+     * Reads a  byte and returns true if the byte is not zero
+	 * otherwise false. 
+     */
+    public boolean readBoolean() throws IOException
+	{
+		return realRaf.readBoolean();
+	}
+
+    /**
+     * returns one input byte from the stream.
+     */
+    public byte readByte() throws IOException
+	{
+		return realRaf.readByte();
+	}
+
+    /**
+     * Reads one input byte in the unsigned form. 
+     */
+    public int readUnsignedByte() throws IOException
+	{
+		return realRaf.readUnsignedByte();
+	}
+
+    /**
+     * returns a short  value from the stream. 
+     */
+    public short readShort() throws IOException
+	{
+		return realRaf.readShort();
+	}
+
+    /**
+	 * returns unsigned short.
+     */
+    public int readUnsignedShort() throws IOException
+	{
+		return realRaf.readUnsignedShort();
+	}
+
+    /**
+	 * returns a char value from the stream.
+     */
+    public char readChar() throws IOException
+	{
+		return realRaf.readChar();
+	}
+
+    /**
+	 * returns an Int from the stream.
+     */
+    public int readInt() throws IOException
+	{
+		return realRaf.readInt();
+	}
+
+    /**
+	 * returns a long from the stream.
+     */
+    public long readLong() throws IOException
+	{
+		return realRaf.readLong();
+	}
+
+    /**
+     * returns a float from the stream. 
+     */
+    public float readFloat() throws IOException
+	{
+		return realRaf.readFloat();
+	}
+
+    /**
+     * returns a double from the stream.
+     */
+    public double readDouble() throws IOException
+	{
+		return realRaf.readDouble();
+	}
+
+    /**
+     * returns the next line of text from the input stream.
+     */
+    public String readLine() throws IOException
+	{
+		return realRaf.readLine();
+	}
+
+    /**
+     * returns a string that has been encoded using in the  UTF-8 format.
+     */
+    public String readUTF() throws IOException
+	{
+		return realRaf.readUTF();
+	}
+
+
+	/* Proxy Implementation of DataOutput interface */ 	   
+
+	/**
+     * Writes an int to the output stream .
+     */
+    public void write(int b) throws IOException
+	{
+		realRaf.write(b);
+	}
+
+    /**
+     * Writes all the bytes in array to the stream.
+     */
+    public void write(byte b[]) throws IOException
+	{
+		realRaf.write(b);
+	}
+
+    /**
+     * Writes specified number bytes from array to the stream.
+	 * If the corruption flags are enabled, byte array
+	 * is corrupted before doing the real write.
+     */
+    public void write(byte b[], int off, int len) throws IOException
+	{
+		if (cbio.isCorruptibleFile(realFile)){
+			//corrupt the input byte array
+			cbio.corrupt(b , off, len);
+		}
+		realRaf.write(b, off, len);
+	}
+
+    /**
+     * Writes a boolean value to this output stream.
+     */
+    public void writeBoolean(boolean value) throws IOException
+	{
+		realRaf.writeBoolean(value);
+	}
+
+    /**
+     * Writes to  the eight low-order bits of ant int.
+     *
+     */
+    public void writeByte(int value) throws IOException
+	{
+		realRaf.writeByte(value);
+	}
+
+    /**
+     * Writes a short value to the output stream  
+     */
+    public void writeShort(int value) throws IOException
+	{
+		realRaf.writeShort(value);
+	}
+
+    /**
+     * Writes a char value to the output stream.
+	 *
+     * @param      value   the <code>char</code> value to be written.
+     * @exception  IOException  if an I/O error occurs.
+     */
+    public void writeChar(int value) throws IOException
+	{
+		realRaf.writeChar(value);
+	}
+
+    /**
+     * Writes an int value to the output stream.
+     */
+    public void writeInt(int value) throws IOException
+	{
+		realRaf.writeInt(value);
+	}
+
+    /**
+     * Writes a long  value to the output stream.
+     */
+    public void writeLong(long value) throws IOException
+	{
+		realRaf.writeLong(value);
+	}
+
+    /**
+     * Writes a float value to the output stream.
+     */
+    public void writeFloat(float value) throws IOException
+	{
+		realRaf.writeFloat(value);
+	}
+
+    /**
+     * Writes a a double value to the stream.
+     */
+    public void writeDouble(double value) throws IOException
+	{
+		realRaf.writeDouble(value);
+	}
+
+    /**
+     * Writes a string as bytes to the stream.
+     */
+    public void writeBytes(String str) throws IOException
+	{
+		realRaf.writeBytes(str);
+	}
+
+    /**
+     * Writes  the string to the stream.
+     */
+    public void writeChars(String str) throws IOException
+	{
+		realRaf.writeChars(str);
+	}
+
+    /**
+     * Writes the string in the utf format. 
+     */
+    public void writeUTF(String str) throws IOException
+	{
+		realRaf.writeUTF(str);
+	}
+
+}

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptibleIo.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptibleIo.java?rev=169737&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptibleIo.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/corruptio/CorruptibleIo.java Wed May 11 17:09:32 2005
@@ -0,0 +1,124 @@
+/*
+
+   Derby -  Derby - Class org.apache.derbyTesting.functionTests.util.corruptio.CorruptibleIo
+
+   Copyright 2004 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.corruptio;
+import java.io.File;
+
+/*
+ * This is a helper class to instrument the CorruptDiskStorageFactory 
+ * to modify the i/o opertions before the request are sent to 
+ * a real storage factory. 
+ * 
+ * Tests can specify what type of corruption is required like log/data files
+ * and the at what and offset and the length of the corruption to be 
+ * done in the write requests. 
+ * 
+ * Only one instance of this class will exist in the system, Tests should hold
+ * onto the instance of this class until they are done sending the i/o 
+ * requests by executing statement that will actuall will trigger i/o , 
+ * for example a commit will flush the log buffers. Otherwise class garbage 
+ * collector can reinitialize the values. 
+ * 
+ * @author <a href="mailto:suresh.thalamati@gmail.com">Suresh Thalamati</a>
+ * @version 1.0
+ * @see WritableStorageFactory
+ * @see StorageFactory
+ */
+
+public class CorruptibleIo {
+
+	private static CorruptibleIo instance = new CorruptibleIo();
+	private boolean corruptLog = false; //corrupt the log i/o to log*.dat files
+	private boolean corruptData = false; //corrupt the files under seg0(data) 
+	private int corruptLength; // no of bytes to corrupt
+	private int corruptOffset; // offset inside the write request 
+
+
+	private CorruptibleIo() {
+    }
+
+	public static CorruptibleIo getInstance() {
+		return instance;
+	}
+
+	
+	public void setLogCorruption(boolean corrupt) {
+		corruptLog = corrupt;
+	}
+
+	public void setDataCorruption(boolean corrupt) {
+		corruptData = corrupt;
+	}
+	
+	public void setOffset(int off) {
+		corruptOffset = off ;
+	}
+
+	public void setLength(int len) {
+		corruptLength = len;
+	}
+		
+	public int getOffset() {
+		return corruptOffset;
+	}
+
+	public int getLength(){
+		return corruptLength;
+	}
+
+	public boolean isCorruptibleFile(File file)
+	{
+		String name = file.getName();
+		String parentName = file.getParent();
+		if (parentName.endsWith("log") && name.endsWith("dat")) {
+			return corruptLog;
+		}
+		else if (parentName.endsWith("seg0")) {
+			return corruptData;
+		}
+
+		return false;
+	}
+
+    /**
+	 * corrupt the byte array at the specified bytes, currenly this
+	 * metods just complemetns the bits at the specified offsets.
+     */
+    public byte[] corrupt(byte b[], int off, int len)
+	{
+		if (corruptOffset >= off && (corruptOffset + corruptLength) < (off + len))
+		{
+			for(int i = corruptOffset ;  i < corruptOffset + corruptLength ; i++)
+			{
+				//System.out.println(b[i]);
+				b[i] = (byte)~b[i];
+				//System.out.println(b[i]);
+			}
+			// System.out.println("Corrupted the write request : Off = " + off + " Length = " + len);
+		}else{
+			System.out.println("Not valid corrupt request :" + 
+							   "Write Request" + "Off=" + off + "size = " + len + 
+							   "Corrupt Request" + "Off=" + corruptOffset + 
+							   "size = " + corruptLength);
+		}
+		return b;
+	}
+
+}