/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2002, 2015 Oracle and/or its affiliates. All rights reserved. * */ /* * Alexg 23-4-06 * Based on scr016 TestAppendRecno test application. */ package com.sleepycat.db.test; import org.junit.Before; import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.File; import java.io.FileNotFoundException; import com.sleepycat.db.*; import com.sleepycat.db.DatabaseException; import com.sleepycat.db.test.TestUtils; public class AppendRecnoTest implements RecordNumberAppender { public static final String RECNOTEST_DBNAME = "appendrecnotest.db"; public static final String[] EXPECTED_ENTRIES = { "data0_xyz", "data1_xy", "ata4_xyz", "ata5_xy", "abc", "", "data9_xyz" }; int callback_count = 0; boolean callback_throws = false; @BeforeClass public static void ClassInit() { TestUtils.loadConfig(null); TestUtils.check_file_removed(TestUtils.getDBFileName(RECNOTEST_DBNAME), true, true); } @AfterClass public static void ClassShutdown() { TestUtils.check_file_removed(TestUtils.getDBFileName(RECNOTEST_DBNAME), true, true); } @Before public void PerTestInit() throws Exception { TestUtils.removeall(true, false, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(RECNOTEST_DBNAME)); } @After public void PerTestShutdown() throws Exception { } /* * Test creating a new database. */ @Test public void test1() throws DatabaseException, FileNotFoundException { DatabaseConfig dbConfig = new DatabaseConfig(); dbConfig.setErrorStream(TestUtils.getErrorStream()); dbConfig.setErrorPrefix("AppendRecnoTest"); dbConfig.setType(DatabaseType.RECNO); dbConfig.setPageSize(1024); dbConfig.setAllowCreate(true); dbConfig.setRecordNumberAppender(this); Database db = new Database(TestUtils.getDBFileName(RECNOTEST_DBNAME), null, dbConfig); for (int i=0; i<10; i++) { TestUtils.DEBUGOUT("\n*** Iteration " + i ); boolean gotExcept = false; try { RecnoEntry key = new RecnoEntry(77+i); DatabaseEntry data = new DatabaseEntry((new String("data" + i + "_xyz")).getBytes()); db.append(null, key, data); } catch (DatabaseException dbe) { gotExcept = true; // Can be expected since testing throwing from the appendRecordNumber callback. TestUtils.DEBUGOUT("dbe: " + dbe); } catch (ArrayIndexOutOfBoundsException e) { gotExcept = true; TestUtils.DEBUGOUT("ArrayIndex: " + e); } if((gotExcept && callback_throws == false ) || (!gotExcept && callback_throws == true)) TestUtils.DEBUGOUT(3, "appendRecordNumber callback exception or non-exception condition dealt with incorrectly. Case " + callback_count); } Cursor dbcp = db.openCursor(null, CursorConfig.DEFAULT); // Walk through the table, validating the key/data pairs. RecnoEntry readkey = new RecnoEntry(); DatabaseEntry readdata = new DatabaseEntry(); TestUtils.DEBUGOUT("Dbc.get"); int itemcount = 0; while (dbcp.getNext(readkey, readdata, LockMode.DEFAULT) == OperationStatus.SUCCESS) { String gotString = new String(readdata.getData(), readdata.getOffset(), readdata.getSize()); TestUtils.DEBUGOUT(1, readkey.getRecno() + " : " + gotString); if(readkey.getRecno() != ++itemcount) TestUtils.DEBUGOUT(3, "Recno iteration out of order. key: " + readkey.getRecno() + " item: " + itemcount); if(itemcount > EXPECTED_ENTRIES.length) TestUtils.ERR("More entries in recno DB than expected."); if(gotString.compareTo(EXPECTED_ENTRIES[itemcount-1]) != 0) TestUtils.DEBUGOUT(3, "Recno - stored data mismatch. Expected: " + EXPECTED_ENTRIES[itemcount-1] + " received: " + gotString); } dbcp.close(); db.close(false); } public void appendRecordNumber(Database db, DatabaseEntry data, int recno) throws DatabaseException { callback_throws = false; TestUtils.DEBUGOUT("AppendRecnoTest::appendRecordNumber. data " + new String(data.getData()) + " recno: " + recno); switch (callback_count++) { case 0: // nothing break; case 1: data.setSize(data.getSize() - 1); break; case 2: // Should result in an error. callback_throws = true; TestUtils.DEBUGOUT("throwing..."); throw new DatabaseException("appendRecordNumber thrown"); //not reached case 3: // Should result in an error (size unchanged). callback_throws = true; data.setOffset(1); break; case 4: data.setOffset(1); data.setSize(data.getSize() - 1); break; case 5: data.setOffset(1); data.setSize(data.getSize() - 2); break; case 6: data.setData(new String("abc").getBytes()); data.setSize(3); break; case 7: // Should result in an error. callback_throws = true; data.setData(new String("abc").getBytes()); data.setSize(4); break; // TODO: Broken - does not throw an exception. case 8: // TODO: Should this result in an error? data.setData(null); break; default: break; } } static class RecnoEntry extends DatabaseEntry { public RecnoEntry() { super(); } public RecnoEntry(int value) { setReuseBuffer(false); arr = new byte[4]; setData(arr); // use our local array for data setRecno(value); } public void setRecno(int value) { setRecordNumber(value); } public int getRecno() { return getRecordNumber(); } byte arr[]; } // end of RecnoEntry sub-class. }