LUCENE-3111: more intense checking from LuceneTestCase for setUp/tearDown bugs in tests

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1104452 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2011-05-17 18:32:07 +00:00
parent 808ccbc021
commit fc85939864
6 changed files with 43 additions and 17 deletions

View File

@ -17,8 +17,6 @@ package org.apache.lucene.ant;
* limitations under the License. * limitations under the License.
*/ */
import java.io.IOException;
import org.apache.lucene.ant.DocumentTestCase; import org.apache.lucene.ant.DocumentTestCase;
import org.apache.lucene.ant.HtmlDocument; import org.apache.lucene.ant.HtmlDocument;
@ -27,7 +25,8 @@ public class HtmlDocumentTest extends DocumentTestCase
HtmlDocument doc; HtmlDocument doc;
@Override @Override
public void setUp() throws IOException { public void setUp() throws Exception {
super.setUp();
doc = new HtmlDocument(getFile("test.html")); doc = new HtmlDocument(getFile("test.html"));
} }
@ -37,8 +36,9 @@ public class HtmlDocumentTest extends DocumentTestCase
} }
@Override @Override
public void tearDown() { public void tearDown() throws Exception {
doc = null; doc = null;
super.tearDown();
} }
} }

View File

@ -17,8 +17,6 @@ package org.apache.lucene.ant;
* limitations under the License. * limitations under the License.
*/ */
import java.io.IOException;
import org.apache.lucene.ant.DocumentTestCase; import org.apache.lucene.ant.DocumentTestCase;
import org.apache.lucene.ant.TextDocument; import org.apache.lucene.ant.TextDocument;
@ -27,7 +25,8 @@ public class TextDocumentTest extends DocumentTestCase
TextDocument doc; TextDocument doc;
@Override @Override
public void setUp() throws IOException { public void setUp() throws Exception {
super.setUp();
doc = new TextDocument(getFile("test.txt")); doc = new TextDocument(getFile("test.txt"));
} }
@ -36,8 +35,9 @@ public class TextDocumentTest extends DocumentTestCase
} }
@Override @Override
public void tearDown() { public void tearDown() throws Exception {
doc = null; doc = null;
super.tearDown();
} }
} }

View File

@ -631,8 +631,9 @@ public class TestPrecedenceQueryParser extends LuceneTestCase {
} }
@Override @Override
public void tearDown() { public void tearDown() throws Exception {
BooleanQuery.setMaxClauseCount(originalMaxClauses); BooleanQuery.setMaxClauseCount(originalMaxClauses);
super.tearDown();
} }
} }

View File

@ -171,7 +171,14 @@ public abstract class LuceneTestCase extends Assert {
private volatile Thread.UncaughtExceptionHandler savedUncaughtExceptionHandler = null; private volatile Thread.UncaughtExceptionHandler savedUncaughtExceptionHandler = null;
/** Used to track if setUp and tearDown are called correctly from subclasses */ /** Used to track if setUp and tearDown are called correctly from subclasses */
private boolean setup; private static State state = State.INITIAL;
private static enum State {
INITIAL, // no tests ran yet
SETUP, // test has called setUp()
RANTEST, // test is running
TEARDOWN // test has called tearDown()
};
/** /**
* Some tests expect the directory to contain a single segment, and want to do tests on that segment's reader. * Some tests expect the directory to contain a single segment, and want to do tests on that segment's reader.
@ -326,6 +333,7 @@ public abstract class LuceneTestCase extends Assert {
@BeforeClass @BeforeClass
public static void beforeClassLuceneTestCaseJ4() { public static void beforeClassLuceneTestCaseJ4() {
state = State.INITIAL;
staticSeed = "random".equals(TEST_SEED) ? seedRand.nextLong() : TwoLongs.fromString(TEST_SEED).l1; staticSeed = "random".equals(TEST_SEED) ? seedRand.nextLong() : TwoLongs.fromString(TEST_SEED).l1;
random.setSeed(staticSeed); random.setSeed(staticSeed);
tempDirs.clear(); tempDirs.clear();
@ -375,6 +383,11 @@ public abstract class LuceneTestCase extends Assert {
@AfterClass @AfterClass
public static void afterClassLuceneTestCaseJ4() { public static void afterClassLuceneTestCaseJ4() {
if (!testsFailed) {
assertTrue("ensure your setUp() calls super.setUp() and your tearDown() calls super.tearDown()!!!",
state == State.INITIAL || state == State.TEARDOWN);
}
state = State.INITIAL;
if (! "false".equals(TEST_CLEAN_THREADS)) { if (! "false".equals(TEST_CLEAN_THREADS)) {
int rogueThreads = threadCleanup("test class"); int rogueThreads = threadCleanup("test class");
if (rogueThreads > 0) { if (rogueThreads > 0) {
@ -483,17 +496,22 @@ public abstract class LuceneTestCase extends Assert {
public void starting(FrameworkMethod method) { public void starting(FrameworkMethod method) {
// set current method name for logging // set current method name for logging
LuceneTestCase.this.name = method.getName(); LuceneTestCase.this.name = method.getName();
if (!testsFailed) {
assertTrue("ensure your setUp() calls super.setUp()!!!", state == State.SETUP);
}
state = State.RANTEST;
super.starting(method); super.starting(method);
} }
}; };
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
seed = "random".equals(TEST_SEED) ? seedRand.nextLong() : TwoLongs.fromString(TEST_SEED).l2; seed = "random".equals(TEST_SEED) ? seedRand.nextLong() : TwoLongs.fromString(TEST_SEED).l2;
random.setSeed(seed); random.setSeed(seed);
assertFalse("ensure your tearDown() calls super.tearDown()!!!", setup); if (!testsFailed) {
setup = true; assertTrue("ensure your tearDown() calls super.tearDown()!!!", (state == State.INITIAL || state == State.TEARDOWN));
}
state = State.SETUP;
savedUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); savedUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) { public void uncaughtException(Thread t, Throwable e) {
@ -529,8 +547,12 @@ public abstract class LuceneTestCase extends Assert {
@After @After
public void tearDown() throws Exception { public void tearDown() throws Exception {
assertTrue("ensure your setUp() calls super.setUp()!!!", setup); if (!testsFailed) {
setup = false; // Note: we allow a test to go straight from SETUP -> TEARDOWN (without ever entering the RANTEST state)
// because if you assume() inside setUp(), it skips the test and the TestWatchman has no way to know...
assertTrue("ensure your setUp() calls super.setUp()!!!", state == State.RANTEST || state == State.SETUP);
}
state = State.TEARDOWN;
BooleanQuery.setMaxClauseCount(savedBoolMaxClauseCount); BooleanQuery.setMaxClauseCount(savedBoolMaxClauseCount);
if ("perMethod".equals(TEST_CLEAN_THREADS)) { if ("perMethod".equals(TEST_CLEAN_THREADS)) {
int rogueThreads = threadCleanup("test method: '" + getName() + "'"); int rogueThreads = threadCleanup("test method: '" + getName() + "'");

View File

@ -65,6 +65,7 @@ public class TestTermScorer extends LuceneTestCase {
indexSearcher.close(); indexSearcher.close();
indexReader.close(); indexReader.close();
directory.close(); directory.close();
super.tearDown();
} }
public void test() throws IOException { public void test() throws IOException {

View File

@ -54,14 +54,16 @@ public class TestFSTs extends LuceneTestCase {
private MockDirectoryWrapper dir; private MockDirectoryWrapper dir;
@Override @Override
public void setUp() throws IOException { public void setUp() throws Exception {
super.setUp();
dir = newDirectory(); dir = newDirectory();
dir.setPreventDoubleWrite(false); dir.setPreventDoubleWrite(false);
} }
@Override @Override
public void tearDown() throws IOException { public void tearDown() throws Exception {
dir.close(); dir.close();
super.tearDown();
} }
private static BytesRef toBytesRef(IntsRef ir) { private static BytesRef toBytesRef(IntsRef ir) {