/**
* Copyright 2005-2012 Akiban Technologies, Inc.
*
* 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 com.persistit;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.Properties;
import org.junit.After;
import org.junit.Before;
import com.persistit.exception.PersistitException;
import com.persistit.unit.UnitTestProperties;
import com.persistit.util.ThreadSequencer;
public abstract class PersistitUnitTestCase {
private final static long TEN_SECONDS = 10L * 1000L * 1000L * 1000L;
protected final static String RED_FOX = "The quick red fox jumped over the lazy brown dog.";
protected static String createString(final int exactLength) {
final StringBuilder sb = new StringBuilder(exactLength);
// Simple 0..9a..z string
for (int i = 0; i < 36; ++i) {
sb.append(Character.forDigit(i, 36));
}
final String numAndLetters = sb.toString();
while (sb.length() < exactLength) {
sb.append(numAndLetters);
}
return sb.toString().substring(0, exactLength);
}
protected Persistit _persistit = new Persistit();
protected Configuration _config;
protected Properties getProperties(final boolean cleanup) {
return UnitTestProperties.getProperties(cleanup);
}
@Before
public void setUp() throws Exception {
checkNoPersistitThreads();
_persistit.setProperties(getProperties(true));
_persistit.initialize();
_config = _persistit.getConfiguration();
}
@After
public void tearDown() throws Exception {
// Ensure sequencer is disabled after each test.
ThreadSequencer.disableSequencer();
final WeakReference<Persistit> ref = new WeakReference<Persistit>(_persistit);
_persistit.close(false);
_persistit = null;
if (!doesRefBecomeNull(ref)) {
System.out.println("Persistit has a leftover strong reference");
}
checkNoPersistitThreads();
}
public void runAllTests() throws Exception {
}
public void setPersistit(final Persistit persistit) {
_persistit = persistit;
}
protected void initAndRunTest() throws Exception {
setUp();
try {
runAllTests();
} catch (final Throwable t) {
t.printStackTrace();
} finally {
tearDown();
}
}
private final static String[] PERSISTIT_THREAD_NAMES = { "CHECKPOINT_WRITER", "JOURNAL_COPIER", "JOURNAL_FLUSHER",
"PAGE_WRITER", "TXN_UPDATE" };
protected boolean checkNoPersistitThreads() {
boolean alive = false;
final Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
for (final Thread t : map.keySet()) {
final String name = t.getName();
for (final String p : PERSISTIT_THREAD_NAMES) {
if (name.contains(p)) {
alive = true;
System.err.println("Thread " + t + " is still alive");
}
}
}
return alive;
}
protected void safeCrashAndRestoreProperties() throws PersistitException {
_persistit.flush();
_persistit.crash();
_persistit = new Persistit(_config);
}
protected void crashWithoutFlushAndRestoreProperties() throws PersistitException {
_persistit.crash();
_persistit = new Persistit(_config);
}
public static boolean doesRefBecomeNull(final WeakReference<?> ref) throws InterruptedException {
final long expires = System.nanoTime() + TEN_SECONDS;
while (ref.get() != null && System.nanoTime() < expires) {
System.gc();
Thread.sleep(10);
}
return ref.get() == null;
}
protected void disableBackgroundCleanup() {
_persistit.getCleanupManager().setPollInterval(-1);
_persistit.getJournalManager().setWritePagePruningEnabled(false);
}
protected void drainJournal() throws Exception {
_persistit.flush();
/*
* Causes all TreeStatistics to be marked clean so that the subsequent
* checkpoint will not add another dirty page.
*/
_persistit.flushStatistics();
_persistit.checkpoint();
_persistit.getJournalManager().copyBack();
}
}