/*
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
licenses@blazegraph.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Oct 2, 2008
*/
package com.bigdata.journal;
import java.nio.ByteBuffer;
import java.util.Properties;
import java.util.concurrent.Callable;
import junit.framework.TestCase;
import com.bigdata.io.TestCase3;
/**
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
*/
public abstract class AbstractIndexManagerTestCase<S extends IIndexManager> extends TestCase3 {
// private final static boolean INFO = log.isInfoEnabled();
// private final static boolean DEBUG = log.isDebugEnabled();
//
// Constructors.
//
public AbstractIndexManagerTestCase() {}
public AbstractIndexManagerTestCase(String name) {super(name);}
//************************************************************
//************************************************************
//************************************************************
/**
* Invoked from {@link TestCase#setUp()} for each test in the suite.
*/
public void setUp(final ProxyTestCase<S> testCase) throws Exception {
if(log.isInfoEnabled())
log.info("\n\n================:BEGIN:" + testCase.getName()
+ ":BEGIN:====================");
}
/**
* Invoked from {@link TestCase#tearDown()} for each test in the suite.
*/
public void tearDown(final ProxyTestCase<S> testCase) throws Exception {
if(log.isInfoEnabled())
log.info("\n================:END:" + testCase.getName()
+ ":END:====================\n");
TestHelper.checkJournalsClosed(testCase, this);
}
// /**
// * A random number generated - the seed is NOT fixed.
// *
// * This is not required. The problem was that the base class field
// * of the same name was winding up not initialized because nobody was.
// * calling super.setUp() and super.tearDown().
// */
// protected Random r = new Random();
@Override
public void setUp() throws Exception {
super.setUp();
// r = new Random();
}
@Override
public void tearDown() throws Exception {
super.tearDown();
// r = null;
}
//
// Properties
//
@Override
public Properties getProperties() {
return super.getProperties();
}
/**
* Open/create an {@link IIndexManager} using the given properties.
*/
abstract protected S getStore(Properties properties);
/**
* Close and then re-open an {@link IIndexManager} backed by the same
* persistent data.
*
* @param store
* the existing store.
*
* @return A new store.
*
* @exception Throwable
* if the existing store is closed or if the store can not be
* re-opened, e.g., from failure to obtain a file lock, etc.
*/
abstract protected S reopenStore(S store);
/**
* This method is invoked from methods that MUST be proxied to this class.
* {@link GenericProxyTestCase} extends this class, as do the concrete
* classes that drive the test suite for specific GOM integration test
* configuration. Many methods on this class must be proxied from
* {@link GenericProxyTestCase} to the delegate. Invoking this method from
* the implementations of those methods in this class provides a means of
* catching omissions where the corresponding method is NOT being delegated.
* Failure to delegate these methods means that you are not able to share
* properties or object manager instances across tests, which means that you
* can not do configuration-based testing of integrations and can also wind
* up with mutually inconsistent test fixtures between the delegate and each
* proxy test.
*/
final protected void checkIfProxy() {
if( this instanceof ProxyTestCase ) {
throw new AssertionError();
}
}
//************************************************************
//************************************************************
//************************************************************
//
// Test helpers.
//
/**
// * <p>
// * Return the name of a journal file to be used for a unit test. The file is
// * created using the temporary file creation mechanism, but it is then
// * deleted. Ideally the returned filename is unique for the scope of the
// * test and will not be reported by the journal as a "pre-existing" file.
// * </p>
// * <p>
// * Note: This method is not advised for performance tests in which the disk
// * allocation matters since the file is allocated in a directory choosen by
// * the OS.
// * </p>
// *
// * @param properties
// * The configured properties. This is used to extract metadata
// * about the journal test configuration that is included in the
// * generated filename. Therefore this method should be invoked
// * after you have set the properties, or at least the
// * {@link Options#BUFFER_MODE}.
// *
// * @return The unique filename.
// *
// * @see {@link #getProperties()}, which sets the "deleteOnClose" flag for
// * unit tests.
// */
// protected String getTestJournalFile(Properties properties) {
//
// return getTestJournalFile(getName(),properties);
//
// }
//
// static public String getTestJournalFile(String name,Properties properties) {
//
// // Used to name the file.
// String bufferMode = properties.getProperty(Options.BUFFER_MODE);
//
// // Used to name the file.
// if( bufferMode == null ) bufferMode = "default";
//
// try {
//
// // Create the temp. file.
// File tmp = File.createTempFile("test-" + bufferMode + "-"
// + name + "-", ".jnl");
//
// // Delete the file otherwise the Journal will attempt to open it.
// if (!tmp.delete()) {
//
// throw new RuntimeException("Unable to remove empty test file: "
// + tmp);
//
// }
//
// // make sure that the file is eventually removed.
// tmp.deleteOnExit();
//
// return tmp.toString();
//
// } catch (IOException ex) {
//
// throw new RuntimeException(ex);
//
// }
//
// }
//
// /**
// * Version of {@link #deleteTestJournalFile(String)} that obtains the name
// * of the journal file from the {@link Options#FILE} property (if any) on
// * {@link #getProperties()}.
// */
// protected void deleteTestJournalFile() {
//
// String filename = getProperties().getProperty(Options.FILE);
//
// if( filename != null ) {
//
// deleteTestJournalFile(filename);
//
// }
//
// }
//
// /**
// * Delete the test file (if any). Note that test files are NOT created when
// * testing the {@link BufferMode#Transient} journal. A warning message that
// * the file could not be deleted generally means that you forgot to close
// * the journal in your test.
// *
// * @param filename
// * The filename (optional).
// */
// protected void deleteTestJournalFile(String filename) {
//
// if( filename == null ) return;
//
// try {
//
// File file = new File(filename);
//
// if ( file.exists() && ! file.delete()) {
//
// System.err.println("Warning: could not delete: " + file.getAbsolutePath());
//
// }
//
// } catch (Throwable t) {
//
// System.err.println("Warning: " + t);
//
// }
//
// }
// /**
// * Helper method verifies that the contents of <i>actual</i> from
// * position() to limit() are consistent with the expected byte[]. A
// * read-only view of <i>actual</i> is used to avoid side effects on the
// * position, mark or limit properties of the buffer.
// *
// * @param expected
// * Non-null byte[].
// * @param actual
// * Buffer.
// */
// public static void assertEquals(final byte[] expected, ByteBuffer actual) {
//
// if (expected == null)
// throw new IllegalArgumentException();
//
// if (actual == null)
// fail("actual is null");
//
// if (actual.hasArray() && actual.arrayOffset() == 0
// && actual.position() == 0
// && actual.limit() == actual.capacity()) {
//
// assertEquals(expected, actual.array());
//
// return;
//
// }
//
// /* Create a read-only view on the buffer so that we do not mess with
// * its position, mark, or limit.
// */
// actual = actual.asReadOnlyBuffer();
//
// final int len = actual.remaining();
//
// final byte[] actual2 = new byte[len];
//
// actual.get(actual2);
//
// assertEquals(expected,actual2);
//
// }
// /**
// * Helper method verifies that the contents of <i>actual</i> from
// * position() to limit() are consistent with the expected byte[]. A
// * read-only view of <i>actual</i> is used to avoid side effects on the
// * position, mark or limit properties of the buffer.
// *
// * @param expected
// * Non-null byte[].
// * @param actual
// * Buffer.
// */
// public static void assertEquals(byte[] expected, ByteBuffer actual ) {
//
// if( expected == null ) throw new IllegalArgumentException();
//
// if( actual == null ) fail("actual is null");
//
// if( actual.hasArray() && actual.arrayOffset() == 0 ) {
//
// assertEquals(expected,actual.array());
//
// return;
//
// }
//
// /* Create a read-only view on the buffer so that we do not mess with
// * its position, mark, or limit.
// */
// actual = actual.asReadOnlyBuffer();
//
// final int len = actual.remaining();
//
// final byte[] actual2 = new byte[len];
//
// actual.get(actual2);
//
// assertEquals(expected,actual2);
//
// }
/**
* Returns random data that will fit in N bytes. N is chosen randomly in
* 1:1024.
*
* @return A new {@link ByteBuffer} wrapping a new <code>byte[]</code> of
* random length and having random contents.
*/
public ByteBuffer getRandomData() {
final int nbytes = r.nextInt(1024) + 1;
final byte[] bytes = new byte[nbytes];
r.nextBytes(bytes);
return ByteBuffer.wrap(bytes);
}
/**
* Test helper evaluates a {@link Callable} and fails unless the expected
* exception is thrown. This is typically used to perform correct rejection
* tests for methods.
*
* @param c
* The {@link Callable}.
* @param expected
* The expected exception.
*
* @todo refactor into junit-ext.
*/
protected void fail(final Callable<?> c,
final Class<? extends Throwable> expected) {
if (c == null)
throw new IllegalArgumentException();
if (expected == null)
throw new IllegalArgumentException();
try {
c.call();
} catch (Throwable t) {
if (t.getClass().isAssignableFrom(expected)) {
if (log.isInfoEnabled())
log.info("Ignoring expected exception: " + t);
return;
} else {
fail("Expecting: " + expected + ", not " + t, t);
}
}
fail("Expecting: " + expected);
}
// /**
// * Helper method verifies that the contents of <i>actual</i> from
// * position() to limit() are consistent with the expected byte[]. A
// * read-only view of <i>actual</i> is used to avoid side effects on the
// * position, mark or limit properties of the buffer.
// *
// * @param expected
// * Non-null byte[].
// * @param actual
// * Buffer.
// */
// public static void assertEquals(ByteBuffer expectedBuffer, ByteBuffer actual) {
//
// if (expectedBuffer == null)
// throw new IllegalArgumentException();
//
// if (actual == null)
// fail("actual is null");
//
// if (expectedBuffer.hasArray() && expectedBuffer.arrayOffset() == 0) {
//
// // evaluate byte[] against actual.
// assertEquals(expectedBuffer.array(), actual);
//
// return;
//
// }
//
// /*
// * Copy the expected data into a byte[] using a read-only view on the
// * buffer so that we do not mess with its position, mark, or limit.
// */
// final byte[] expected;
// {
//
// expectedBuffer = expectedBuffer.asReadOnlyBuffer();
//
// final int len = expectedBuffer.remaining();
//
// expected = new byte[len];
//
// expectedBuffer.get(expected);
//
// }
//
// // evaluate byte[] against actual.
// assertEquals(expected, actual);
//
// }
//
// /**
// * Helper method verifies that the contents of <i>actual</i> from
// * position() to limit() are consistent with the expected byte[]. A
// * read-only view of <i>actual</i> is used to avoid side effects on the
// * position, mark or limit properties of the buffer.
// *
// * @param expected
// * Non-null byte[].
// * @param actual
// * Buffer.
// */
// public static void assertEquals(final byte[] expected, ByteBuffer actual) {
//
// if (expected == null)
// throw new IllegalArgumentException();
//
// if (actual == null)
// fail("actual is null");
//
// if (actual.hasArray() && actual.arrayOffset() == 0) {
//
// assertEquals(expected, actual.array());
//
// return;
//
// }
//
// /*
// * Create a read-only view on the buffer so that we do not mess with its
// * position, mark, or limit.
// */
// actual = actual.asReadOnlyBuffer();
//
// final int len = actual.remaining();
//
// final byte[] actual2 = new byte[len];
//
// actual.get(actual2);
//
// // compare byte[]s.
// assertEquals(expected, actual2);
//
// }
}