Bugs item #2016130, was opened at 2008-07-11 15:14 Message generated for change (Settings changed) made by stuartlewis You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=119984&aid=2016130&group_id=19984
Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: Batch tools Group: None >Status: Closed >Resolution: Fixed Priority: 5 Private: No Submitted By: Toebi (toebi) Assigned to: Nobody/Anonymous (nobody) Summary: checksum checker can not retrieve very large bitstream Initial Comment: in the database there is a field for the size of a bitstream. it`s defined as a int8 value which is at java the datatype long. the query in the checksum checker reads this value in as a "INT" VALUE INSTEAD OF A "LONG" VALUE. if it`s realy a big file and the size doesn`t fit into the int, that`s causes an exception of course, which is catched as a SQLException and logged as "Bitstream metadata could not be retrieved. ...". the size of the bitstream is handled at the hole checksum classes as an int. that`s regarding the following classes: - Class: org.dspace.checker.BitstreamInfoDAO + Line 277: Method: findByBitstreamId - Class: org.dspace.checker.BitstreamInfo + Line 144: Constructor + Line 207/218: Methods: get/setSize - Class: org.dspace.checker.DSpaceBitstreamInfo + Line 137: Constructor + Line 202/213: Methods: get/setSize - Class: org.dspace.checker.DSpaceBitstreamInfo + Line 137: Constructor + Line 202/213: Methods: get/setSize ---------------------------------------------------------------------- >Comment By: Stuart Lewis (stuartlewis) Date: 2008-12-15 16:52 Message: Patch applied ready for next release. Unit test not included as the relevant dependencies have not been added yet. ---------------------------------------------------------------------- Comment By: Elliot Metsger (emetsger) Date: 2008-07-25 03:55 Message: Logged In: YES user_id=1074632 Originator: NO There's a bogus testFoo() in the patch, applier should remove it. ---------------------------------------------------------------------- Comment By: Elliot Metsger (emetsger) Date: 2008-07-25 03:53 Message: Logged In: YES user_id=1074632 Originator: NO Patch breaks compatability. Requires unit test dependencies: https://sourceforge.net/tracker/index.php?func=detail&aid=2019976&group_id=19984&atid=319984 ---------------------------------------------------------------------- Comment By: Elliot Metsger (emetsger) Date: 2008-07-25 03:51 Message: Logged In: YES user_id=1074632 Originator: NO Patch and test case: Index: dspace-api/src/main/java/org/dspace/checker/BitstreamInfo.java =================================================================== --- dspace-api/src/main/java/org/dspace/checker/BitstreamInfo.java (revision 2964) +++ dspace-api/src/main/java/org/dspace/checker/BitstreamInfo.java (working copy) @@ -141,7 +141,7 @@ * @param procStartDate * When the last bitstream check started. */ - public BitstreamInfo(boolean del, int storeNo, int sz, String bitstrmFmt, + public BitstreamInfo(boolean del, int storeNo, long sz, String bitstrmFmt, int bitstrmId, String usrFmtDesc, String intrnlId, String src, String chksumAlgorthm, String chksum, String nm, Date procEndDate, boolean toBeProc, Date procStartDate) @@ -204,7 +204,7 @@ * * @return int */ - public int getSize() + public long getSize() { return dspaceBitstream.getSize(); } Index: dspace-api/src/main/java/org/dspace/checker/DSpaceBitstreamInfo.java =================================================================== --- dspace-api/src/main/java/org/dspace/checker/DSpaceBitstreamInfo.java (revision 2964) +++ dspace-api/src/main/java/org/dspace/checker/DSpaceBitstreamInfo.java (working copy) @@ -54,7 +54,7 @@ private String name; /** Stored size of the bitstream. */ - private int size; + private long size; /** the check sum value stored in the database. */ private String storedChecksum; @@ -134,7 +134,7 @@ * @param desc * Bitstream description */ - public DSpaceBitstreamInfo(boolean del, int storeNo, int sz, + public DSpaceBitstreamInfo(boolean del, int storeNo, long sz, String bitstrmFmt, int bitstrmId, String usrFmtDesc, String intrnlId, String src, String chksumAlgorthm, String chksum, String nm, String desc) @@ -199,7 +199,7 @@ * * @return int */ - public int getSize() + public long getSize() { return size; } Index: dspace-api/src/main/java/org/dspace/checker/BitstreamInfoDAO.java =================================================================== --- dspace-api/src/main/java/org/dspace/checker/BitstreamInfoDAO.java (revision 2964) +++ dspace-api/src/main/java/org/dspace/checker/BitstreamInfoDAO.java (working copy) @@ -274,7 +274,7 @@ if (rs.next()) { info = new BitstreamInfo(rs.getBoolean("deleted"), rs - .getInt("store_number"), rs.getInt("size_bytes"), rs + .getInt("store_number"), rs.getLong("size_bytes"), rs .getString("short_description"), rs .getInt("bitstream_id"), rs .getString("user_format_description"), rs Index: dspace-api/src/test/java/org/dspace/checker/BitstreamInfoDAOTest_SF2016130.java =================================================================== --- dspace-api/src/test/java/org/dspace/checker/BitstreamInfoDAOTest_SF2016130.java (revision 0) +++ dspace-api/src/test/java/org/dspace/checker/BitstreamInfoDAOTest_SF2016130.java (revision 0) @@ -0,0 +1,282 @@ +package org.dspace.checker; + +import org.junit.After; +import org.junit.Test; +import org.junit.Before; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; +import org.dspace.storage.rdbms.DatabaseManager; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.isA; +import static org.easymock.classextension.EasyMock.replay; +import mockit.Mockit; +import mockit.MockClass; +import mockit.Mock; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Timestamp; +import java.util.HashMap; +import java.util.Map; + +/** + * Tests for SF.net bug 2016130 + * https://sourceforge.net/tracker/index.php?func=detail&aid=2016130&group_id=19984&atid=119984 + */ +public class BitstreamInfoDAOTest_SF2016130 +{ + + /** Mock java.sql.Connection */ + private Connection mockConn; + + /** Mock java.sql.PreparedStatement */ + private PreparedStatement mockStmt; + + /** Mocks DatabaseManager */ + private MockDbm mockDbm; + + /** BitstreamInfoDAO, under test */ + private BitstreamInfoDAO underTest; + + @Before + public void setUp() + { + // EasyMock Connection and PreparedStatement + mockConn = createMock( Connection.class ); + mockStmt = createMock( PreparedStatement.class ); + + // JMockit for DatabaseManager + mockDbm = new MockDbm( mockConn ); + Mockit.setUpMock( mockDbm ); + + underTest = new BitstreamInfoDAO(); + } + + @After + public void tearDown() + { + Mockit.restoreAllOriginalDefinitions(); + } + + /** + * Fails to retrieve a BitstreamInfo for a bitstream, regardless of its size. The result + * set uses an int to store 'size_bytes'. + * + * <p>The mock result set uses an int to store the 'size_bytes' field. Any attempt by + * {...@link org.dspace.checker.BitstreamInfoDAO#findByBitstreamId(int)} must read the field + * as a Java long to succeed.</p> + * + * @throws Exception + */ + @Test( expected = ClassCastException.class ) + public void testIntBitstream() throws Exception + { + // Set the fields and values on the ResultSetFieldHolder, adds 'size_bytes' as an *int* + ResultSetFieldHolder rsFieldHolder = addDefaultFields( new ResultSetFieldHolder() ) + .putField( "size_bytes", Integer.MAX_VALUE ); + + // Use Mockit.setUpMock to proxy the ResultSet interface, but mocking the methods + // in ResultSetFieldHolder + ResultSet rs = Mockit.setUpMock( rsFieldHolder ); + + // Set expectations + expect( mockConn.prepareStatement( isA( String.class ) ) ).andReturn( mockStmt ); + mockStmt.setInt( 1, 1 ); + expect( mockStmt.executeQuery() ).andReturn( rs ); + mockStmt.close(); + mockConn.close(); + replay( mockConn, mockStmt ); + + // Results in ClassCastException because the size_bytes is read using ResultSet#getLong() on + // an int field. + underTest.findByBitstreamId( 1 ); + } + + /** + * Successfully retrieves a BitstreamInfo for a bitstream that exceeds the maximum value + * of a Java int (2^31-1). The result set uses a long to store 'size_bytes'. + * + * <p>The mock result set uses a long to store the 'size_bytes' field. Any attempt by + * {...@link org.dspace.checker.BitstreamInfoDAO#findByBitstreamId(int)} must read the field + * as a Java long to succeed.</p> + * + * @throws Exception + */ + @Test + public void testLongBitstreamLargeSize() throws Exception + { + // Set the fields and values on the ResultSetFieldHolder, adds 'size_bytes' as an *long* + ResultSetFieldHolder rsFieldHolder = addDefaultFields( new ResultSetFieldHolder() ).putField( "size_bytes", Long.MAX_VALUE ); + + // Use Mockit.setUpMock to proxy the ResultSet interface, but mocking the methods + // in ResultSetFieldHolder + ResultSet rs = Mockit.setUpMock( rsFieldHolder ); + + // Set expectations + expect( mockConn.prepareStatement( isA( String.class ) ) ).andReturn( mockStmt ); + mockStmt.setInt( 1, 1 ); + expect( mockStmt.executeQuery() ).andReturn( rs ); + mockStmt.close(); + mockConn.close(); + replay( mockConn, mockStmt ); + + // Execute test + BitstreamInfo bi = underTest.findByBitstreamId( 1 ); + + assertNotNull( "Error: Bitstream info should not be null", bi ); + assertEquals( "Incorrect bitstream size", Long.MAX_VALUE, bi.getSize() ); + } + + /** + * Successfully retrieves a BitstreamInfo for a bitstream that is less than the size + * of a Java int (2^31-1). The result set uses a long to store 'size_bytes'. + * + * <p>The mock result set uses a long to store the 'size_bytes' field. Any attempt by + * {...@link org.dspace.checker.BitstreamInfoDAO#findByBitstreamId(int)} must read the field + * as a Java long to succeed.</p> + * + * @throws Exception + */ + @Test + public void testLongBitstreamSmallSize() throws Exception + { + // Set the fields and values on the ResultSetFieldHolder, adds 'size_bytes' as an *long* + ResultSetFieldHolder rsFieldHolder = addDefaultFields( new ResultSetFieldHolder() ).putField( "size_bytes", 512L ); + + // Use Mockit.setUpMock to proxy the ResultSet interface, but mocking the methods + // in ResultSetFieldHolder + ResultSet rs = Mockit.setUpMock( rsFieldHolder ); + + // Set expectations + expect( mockConn.prepareStatement( isA( String.class ) ) ).andReturn( mockStmt ); + mockStmt.setInt( 1, 1 ); + expect( mockStmt.executeQuery() ).andReturn( rs ); + mockStmt.close(); + mockConn.close(); + replay( mockConn, mockStmt ); + + // Execute test + BitstreamInfo bi = underTest.findByBitstreamId( 1 ); + + assertNotNull( "Error: Bitstream info should not be null", bi ); + assertEquals( "Incorrect bitstream size", 512L, bi.getSize() ); + } + + @Test + public void testFoo() + { + + } + + /** + * Fills the ResultSetFieldHolder with default field names and values. + * + * @param rs the field holder + * @return the same <code>rs</code> instance, with fields added. + */ + private ResultSetFieldHolder addDefaultFields( ResultSetFieldHolder rs ) + { + // Set fields and values on the ResultSet + rs.putField( "deleted", true ) + .putField( "store_number", 1 ) + .putField( "short_description", "foo" ) + .putField( "bitstream_id", 1 ) + .putField( "user_format_description", "foo" ) + .putField( "internal_id", "someinternalid" ) + .putField( "source", "source" ) + .putField( "checksum_algorithm", "sha1" ) + .putField( "checksum", "12345" ) + .putField( "name", "filename" ) + .putField( "last_process_end_date", new Timestamp( System.currentTimeMillis() ) ) + .putField( "to_be_processed", true ); + + return rs; + } + + /** + * Mocks certain methods of the {...@link java.sql.ResultSet} interface. + * + * <p>Mocked methods look up their response from a member Map</p> + */ + @MockClass( realClass = ResultSet.class ) + public class ResultSetFieldHolder + { + private Map<String, Object> fields = new HashMap<String,Object>(); + + /** + * Puts a field name and value into the map. + * + * @param name the field/column name. + * @param val the value + * @return this instance for method chaining + */ + private ResultSetFieldHolder putField( String name, Object val ) + { + fields.put( name, val ); + return this; + } + + @Mock + public boolean next() + { + return true; + } + + @Mock + public int getInt( String field ) + { + return (Integer)fields.get( field ); + } + + @Mock + public String getString( String field ) + { + return (String)fields.get( field ); + } + + @Mock + public Timestamp getTimestamp( String field ) + { + return (Timestamp)fields.get( field ); + } + + @Mock + public boolean getBoolean( String field ) + { + return (Boolean)fields.get( field ); + } + + @Mock + public long getLong( String field ) + { + return (Long)fields.get( field ); + } + } + + /** + * Mocks the DSpace {...@link org.dspace.storage.rdbms.DatabaseManager#getConnection()} method. + */ + @MockClass( realClass = DatabaseManager.class ) + public class MockDbm + { + private Connection mockConnection; + + /** + * Construct the mock with the Connection to return. + * + * @param mockConnection the Connection to return in response to {...@link #getConnection()} + */ + MockDbm( Connection mockConnection ) + { + this.mockConnection = mockConnection; + } + + @Mock + public Connection getConnection() + { + return mockConnection; + } + } +} Property changes on: dspace-api/src/test/java/org/dspace/checker/BitstreamInfoDAOTest_SF2016130.java ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Id Name: svn:eol-style + native ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=119984&aid=2016130&group_id=19984 ------------------------------------------------------------------------------ SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ _______________________________________________ Dspace-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/dspace-devel
