LUCENE-4047: Cleanup of LuceneTestCase: moved blocks of initialization/ cleanup code into JUnit instance and class rules.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1338826 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dawid Weiss 2012-05-15 18:47:45 +00:00
parent eef4f63f08
commit 4652d65f0b
64 changed files with 1677 additions and 1690 deletions

View File

@ -170,6 +170,6 @@
<classpathentry kind="lib" path="solr/contrib/velocity/lib/commons-beanutils-1.7.0.jar"/>
<classpathentry kind="lib" path="solr/contrib/velocity/lib/commons-collections-3.2.1.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lucene/test-framework/lib/randomizedtesting-runner-1.4.0.jar"/>
<classpathentry kind="lib" path="lucene/test-framework/lib/randomizedtesting-runner-1.5.0.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -2,7 +2,7 @@
<library name="JUnit">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lucene/test-framework/lib/junit-4.10.jar!/" />
<root url="jar://$PROJECT_DIR$/lucene/test-framework/lib/randomizedtesting-runner-1.3.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lucene/test-framework/lib/randomizedtesting-runner-1.5.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />

View File

@ -383,7 +383,7 @@
<dependency>
<groupId>com.carrotsearch.randomizedtesting</groupId>
<artifactId>randomizedtesting-runner</artifactId>
<version>1.4.0</version>
<version>1.5.0</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -960,6 +960,9 @@ Documentation
Build
* LUCENE-4047: Cleanup of LuceneTestCase: moved blocks of initialization/ cleanup
code into JUnit instance and class rules. (Dawid Weiss)
* LUCENE-4016: Require ANT 1.8.2+ for the build.
* LUCENE-3808: Refactoring of testing infrastructure to use randomizedtesting

View File

@ -86,7 +86,7 @@ public class DocMakerTest extends BenchmarkTestCase {
Config config = new Config(props);
PerfRunData runData = new PerfRunData(config);
TaskSequence tasks = new TaskSequence(runData, getName(), null, false);
TaskSequence tasks = new TaskSequence(runData, getTestName(), null, false);
tasks.addTask(new CreateIndexTask(runData));
tasks.addTask(new AddDocTask(runData));
tasks.addTask(new CloseIndexTask(runData));

View File

@ -2,18 +2,15 @@ package org.apache.lucene.document;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.Locale;
import java.util.*;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.SystemPropertiesRestoreRule;
import org.junit.Rule;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with

View File

@ -70,7 +70,7 @@ public class TestDuelingCodecs extends LuceneTestCase {
// so this would make assertEquals complicated.
leftCodec = Codec.forName("SimpleText");
rightCodec = new RandomCodec(random(), null);
rightCodec = new RandomCodec(random());
leftDir = newDirectory();
rightDir = newDirectory();

View File

@ -53,12 +53,17 @@ public class TestPostingsOffsets extends LuceneTestCase {
public void setUp() throws Exception {
super.setUp();
// Currently only SimpleText and Lucene40 can index offsets into postings:
assumeTrue("codec does not support offsets", Codec.getDefault().getName().equals("SimpleText") || Codec.getDefault().getName().equals("Lucene40"));
String codecName = Codec.getDefault().getName();
assumeTrue("Codec does not support offsets: " + codecName,
codecName.equals("SimpleText") ||
codecName.equals("Lucene40"));
iwc = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
if (Codec.getDefault().getName().equals("Lucene40")) {
// sep etc are not implemented
if (codecName.equals("Lucene40")) {
// Sep etc are not implemented
switch(random().nextInt(4)) {
case 0: iwc.setCodec(_TestUtil.alwaysPostingsFormat(new Lucene40PostingsFormat())); break;
case 1: iwc.setCodec(_TestUtil.alwaysPostingsFormat(new MemoryPostingsFormat())); break;

View File

@ -84,7 +84,7 @@ public class TestBooleanMinShouldMatch extends LuceneTestCase {
public void verifyNrHits(Query q, int expected) throws Exception {
ScoreDoc[] h = s.search(q, null, 1000).scoreDocs;
if (expected != h.length) {
printHits(getName(), h, s);
printHits(getTestName(), h, s);
}
assertEquals("result count", expected, h.length);
//System.out.println("TEST: now check");

View File

@ -17,7 +17,6 @@ package org.apache.lucene.search;
* limitations under the License.
*/
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
@ -25,9 +24,12 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.LuceneTestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import com.carrotsearch.randomizedtesting.annotations.ThreadLeaks;
/**
* https://issues.apache.org/jira/browse/LUCENE-1974
*
@ -36,7 +38,6 @@ import org.junit.BeforeClass;
* BooleanScorer.score(Collector collector, int max, int firstDocID)
*
* Line 273, end=8192, subScorerDocID=11378, then more got false?
*
*/
public class TestPrefixInBooleanQuery extends LuceneTestCase {

View File

@ -603,7 +603,7 @@ public class TestSort extends LuceneTestCase {
}
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " IntParser");
assertSaneFieldCaches(getTestName() + " IntParser");
fc.purgeAllCaches();
sort.setSort (new SortField ("parser", new FieldCache.FloatParser(){
@ -612,7 +612,7 @@ public class TestSort extends LuceneTestCase {
}
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " FloatParser");
assertSaneFieldCaches(getTestName() + " FloatParser");
fc.purgeAllCaches();
sort.setSort (new SortField ("parser", new FieldCache.LongParser(){
@ -621,7 +621,7 @@ public class TestSort extends LuceneTestCase {
}
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " LongParser");
assertSaneFieldCaches(getTestName() + " LongParser");
fc.purgeAllCaches();
sort.setSort (new SortField ("parser", new FieldCache.DoubleParser(){
@ -630,7 +630,7 @@ public class TestSort extends LuceneTestCase {
}
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " DoubleParser");
assertSaneFieldCaches(getTestName() + " DoubleParser");
fc.purgeAllCaches();
sort.setSort (new SortField ("parser", new FieldCache.ByteParser(){
@ -639,7 +639,7 @@ public class TestSort extends LuceneTestCase {
}
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " ByteParser");
assertSaneFieldCaches(getTestName() + " ByteParser");
fc.purgeAllCaches();
sort.setSort (new SortField ("parser", new FieldCache.ShortParser(){
@ -648,7 +648,7 @@ public class TestSort extends LuceneTestCase {
}
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " ShortParser");
assertSaneFieldCaches(getTestName() + " ShortParser");
fc.purgeAllCaches();
}
@ -1229,7 +1229,7 @@ public class TestSort extends LuceneTestCase {
// up to this point, all of the searches should have "sane"
// FieldCache behavior, and should have reused hte cache in several cases
assertSaneFieldCaches(getName() + " various");
assertSaneFieldCaches(getTestName() + " various");
// next we'll check Locale based (String[]) for 'string', so purge first
FieldCache.DEFAULT.purgeAllCaches();
}

View File

@ -36,7 +36,6 @@ public class TestTermRangeFilter extends BaseTestRangeFilter {
@Test
public void testRangeFilterId() throws IOException {
IndexReader reader = signedIndexReader;
IndexSearcher search = newSearcher(reader);

View File

@ -17,17 +17,21 @@ package org.apache.lucene.store;
* limitations under the License.
*/
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util._TestUtil;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
public class TestDirectory extends LuceneTestCase {
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util._TestUtil;
public class TestDirectory extends LuceneTestCase {
public void testDetectClose() throws Throwable {
Directory[] dirs = new Directory[] { new RAMDirectory(), new SimpleFSDirectory(TEMP_DIR), new NIOFSDirectory(TEMP_DIR) };
Directory[] dirs = new Directory[] {
new RAMDirectory(),
new SimpleFSDirectory(TEMP_DIR),
new NIOFSDirectory(TEMP_DIR)
};
for (Directory dir : dirs) {
dir.close();
try {

View File

@ -60,14 +60,11 @@ public class TestWindowsMMap extends LuceneTestCase {
return fb.toString();
}
private final static String storePathname =
_TestUtil.getTempDir("testLuceneMmap").getAbsolutePath();
public void testMmapIndex() throws Exception {
// sometimes the directory is not cleaned by rmDir, because on Windows it
// may take some time until the files are finally dereferenced. So clean the
// directory up front, or otherwise new IndexWriter will fail.
File dirPath = new File(storePathname);
File dirPath = _TestUtil.getTempDir("testLuceneMmap");
rmDir(dirPath);
MMapDirectory dir = new MMapDirectory(dirPath, null);

View File

@ -108,7 +108,8 @@ public class TestFieldCacheSanityChecker extends LuceneTestCase {
FieldCacheSanityChecker.checkSanity(cache.getCacheEntries());
if (0 < insanity.length)
dumpArray(getTestLabel() + " INSANITY", insanity, System.err);
dumpArray(getTestClass().getName() + "#" + getTestName()
+ " INSANITY", insanity, System.err);
assertEquals("shouldn't be any cache insanity", 0, insanity.length);
cache.purgeAllCaches();

View File

@ -0,0 +1,65 @@
package org.apache.lucene.util.junitcompat;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
public class TestBeforeAfterOverrides extends WithNestedTests {
public TestBeforeAfterOverrides() {
super(true);
}
public static class Before1 extends WithNestedTests.AbstractNestedTest {
@Before
public void before() {}
}
public static class Before2 extends Before1 {}
public static class Before3 extends Before2 {
@Before
public void before() {}
}
public static class After1 extends WithNestedTests.AbstractNestedTest {
@After
public void after() {}
}
public static class After2 extends Before1 {}
public static class After3 extends Before2 {
@After
public void after() {}
}
@Test
public void testBefore() {
Result result = JUnitCore.runClasses(Before3.class);
Assert.assertEquals(1, result.getFailureCount());
Assert.assertTrue(result.getFailures().get(0).getTrace().contains("There are overridden methods"));
}
@Test
public void testAfter() {
Result result = JUnitCore.runClasses(Before3.class);
Assert.assertEquals(1, result.getFailureCount());
Assert.assertTrue(result.getFailures().get(0).getTrace().contains("There are overridden methods"));
}
}

View File

@ -25,7 +25,6 @@ import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
@ -119,14 +118,14 @@ public class TestReproduceMessage extends WithNestedTests {
super(true);
}
@Test @Ignore
@Test
public void testAssumeBeforeClass() throws Exception {
type = SoreType.ASSUMPTION;
where = SorePoint.BEFORE_CLASS;
Assert.assertTrue(runAndReturnSyserr().isEmpty());
}
@Test @Ignore
@Test
public void testAssumeInitializer() throws Exception {
type = SoreType.ASSUMPTION;
where = SorePoint.INITIALIZER;
@ -161,7 +160,7 @@ public class TestReproduceMessage extends WithNestedTests {
Assert.assertTrue(runAndReturnSyserr().isEmpty());
}
@Test @Ignore
@Test
public void testAssumeAfterClass() throws Exception {
type = SoreType.ASSUMPTION;
where = SorePoint.AFTER_CLASS;
@ -172,14 +171,14 @@ public class TestReproduceMessage extends WithNestedTests {
* FAILURES
*/
@Test @Ignore
@Test
public void testFailureBeforeClass() throws Exception {
type = SoreType.FAILURE;
where = SorePoint.BEFORE_CLASS;
Assert.assertTrue(runAndReturnSyserr().contains("NOTE: reproduce with:"));
}
@Test @Ignore
@Test
public void testFailureInitializer() throws Exception {
type = SoreType.FAILURE;
where = SorePoint.INITIALIZER;
@ -228,7 +227,7 @@ public class TestReproduceMessage extends WithNestedTests {
Assert.assertTrue(Arrays.asList(syserr.split("\\s")).contains("-Dtestcase=" + Nested.class.getSimpleName()));
}
@Test @Ignore
@Test
public void testFailureAfterClass() throws Exception {
type = SoreType.FAILURE;
where = SorePoint.AFTER_CLASS;
@ -239,14 +238,14 @@ public class TestReproduceMessage extends WithNestedTests {
* ERRORS
*/
@Test @Ignore
@Test
public void testErrorBeforeClass() throws Exception {
type = SoreType.ERROR;
where = SorePoint.BEFORE_CLASS;
Assert.assertTrue(runAndReturnSyserr().contains("NOTE: reproduce with:"));
}
@Test @Ignore
@Test
public void testErrorInitializer() throws Exception {
type = SoreType.ERROR;
where = SorePoint.INITIALIZER;
@ -293,7 +292,7 @@ public class TestReproduceMessage extends WithNestedTests {
Assert.assertTrue(Arrays.asList(syserr.split("\\s")).contains("-Dtestcase=" + Nested.class.getSimpleName()));
}
@Test @Ignore
@Test
public void testErrorAfterClass() throws Exception {
type = SoreType.ERROR;
where = SorePoint.AFTER_CLASS;

View File

@ -1,22 +1,16 @@
package org.apache.lucene.util.junitcompat;
import java.util.Locale;
import java.util.Random;
import java.util.TimeZone;
import java.util.*;
import org.apache.lucene.util.SystemPropertiesRestoreRule;
import org.apache.lucene.util._TestUtil;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.*;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import com.carrotsearch.randomizedtesting.RandomizedContext;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more

View File

@ -19,14 +19,15 @@ package org.apache.lucene.util.junitcompat;
import java.util.Properties;
import org.apache.lucene.util.SystemPropertiesInvariantRule;
import org.apache.lucene.util.SystemPropertiesRestoreRule;
import org.junit.*;
import org.junit.rules.TestRule;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesInvariantRule;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
/**
* @see SystemPropertiesRestoreRule
* @see SystemPropertiesInvariantRule

View File

@ -23,8 +23,8 @@
<dependency org="org.apache.ant" name="ant-junit" rev="1.7.1" transitive="false"/>
<dependency org="junit" name="junit" rev="4.10" transitive="false"/>
<dependency org="com.carrotsearch.randomizedtesting" name="junit4-ant" rev="1.4.0" transitive="false" />
<dependency org="com.carrotsearch.randomizedtesting" name="randomizedtesting-runner" rev="1.4.0" transitive="false"/>
<dependency org="com.carrotsearch.randomizedtesting" name="junit4-ant" rev="1.5.0" transitive="false" />
<dependency org="com.carrotsearch.randomizedtesting" name="randomizedtesting-runner" rev="1.5.0" transitive="false"/>
<exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/>
</dependencies>

View File

@ -1 +0,0 @@
b086d1665504ac99c6cdb2340044f0de94753eed

View File

@ -0,0 +1 @@
4e920288c2d2cd39b7e15f3abcaa3c5e2213ec9c

View File

@ -1 +0,0 @@
2af8c132f3f65e0f09a2ce59cbc5c649ff12ab1c

View File

@ -0,0 +1 @@
378731cc7f26d45b68a6e5f600d4c7d071d165b1

View File

@ -50,15 +50,14 @@ import org.apache.lucene.util._TestUtil;
* and reproducable.
*/
public class RandomCodec extends Lucene40Codec {
/** shuffled list of postingsformats to use for new mappings */
/** Shuffled list of postings formats to use for new mappings */
private List<PostingsFormat> formats = new ArrayList<PostingsFormat>();
/** memorized field->postingsformat mappings */
// note: we have to sync this map even though its just for debugging/toString,
// otherwise DWPT's .toString() calls that iterate over the map can
// cause concurrentmodificationexception if indexwriter's infostream is on
private Map<String,PostingsFormat> previousMappings = Collections.synchronizedMap(new HashMap<String,PostingsFormat>());
/** set of codec names to avoid */
private final Set<String> avoidCodecs;
private final int perFieldSeed;
@Override
@ -78,34 +77,41 @@ public class RandomCodec extends Lucene40Codec {
}
public RandomCodec(Random random, Set<String> avoidCodecs) {
this.avoidCodecs = avoidCodecs;
this.perFieldSeed = random.nextInt();
// TODO: make it possible to specify min/max iterms per
// block via CL:
int minItemsPerBlock = _TestUtil.nextInt(random, 2, 100);
int maxItemsPerBlock = 2*(Math.max(2, minItemsPerBlock-1)) + random.nextInt(100);
add(new Lucene40PostingsFormat(minItemsPerBlock, maxItemsPerBlock));
// TODO: make it possible to specify min/max iterms per
// block via CL:
// TODO: make it possible to specify min/max iterms per block via CL:
minItemsPerBlock = _TestUtil.nextInt(random, 2, 100);
maxItemsPerBlock = 2*(Math.max(1, minItemsPerBlock-1)) + random.nextInt(100);
add(new Pulsing40PostingsFormat(1 + random.nextInt(20), minItemsPerBlock, maxItemsPerBlock));
add(new MockSepPostingsFormat());
add(new MockFixedIntBlockPostingsFormat(_TestUtil.nextInt(random, 1, 2000)));
add(new MockVariableIntBlockPostingsFormat( _TestUtil.nextInt(random, 1, 127)));
add(new MockRandomPostingsFormat(random));
add(new NestedPulsingPostingsFormat());
add(new Lucene40WithOrds());
add(new SimpleTextPostingsFormat());
add(new MemoryPostingsFormat(random.nextBoolean()));
add(avoidCodecs,
new Lucene40PostingsFormat(minItemsPerBlock, maxItemsPerBlock),
new Pulsing40PostingsFormat(1 + random.nextInt(20), minItemsPerBlock, maxItemsPerBlock),
new MockSepPostingsFormat(),
new MockFixedIntBlockPostingsFormat(_TestUtil.nextInt(random, 1, 2000)),
new MockVariableIntBlockPostingsFormat( _TestUtil.nextInt(random, 1, 127)),
new MockRandomPostingsFormat(random),
new NestedPulsingPostingsFormat(),
new Lucene40WithOrds(),
new SimpleTextPostingsFormat(),
new MemoryPostingsFormat(random.nextBoolean()));
Collections.shuffle(formats, random);
}
private final void add(PostingsFormat p) {
if (avoidCodecs == null || !avoidCodecs.contains(p.getName())) {
public RandomCodec(Random random) {
this(random, Collections.<String> emptySet());
}
private final void add(Set<String> avoidCodecs, PostingsFormat... postings) {
for (PostingsFormat p : postings) {
if (!avoidCodecs.contains(p.getName())) {
formats.add(p);
}
}
}
@Override
public String toString() {

View File

@ -0,0 +1,63 @@
package org.apache.lucene.util;
import java.util.ArrayList;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.MultipleFailureException;
import org.junit.runners.model.Statement;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* A {@link TestRule} that guarantees the execution of {@link #after} even
* if an exception has been thrown from delegate {@link Statement}. This is much
* like {@link AfterClass} or {@link After} annotations but can be used with
* {@link RuleChain} to guarantee the order of execution.
*/
abstract class AbstractBeforeAfterRule implements TestRule {
@Override
public Statement apply(final Statement s, final Description d) {
return new Statement() {
public void evaluate() throws Throwable {
before();
final ArrayList<Throwable> errors = new ArrayList<Throwable>();
try {
s.evaluate();
} catch (Throwable t) {
errors.add(t);
}
try {
after();
} catch (Throwable t) {
errors.add(t);
}
MultipleFailureException.assertEmpty(errors);
}
};
}
protected void before() throws Exception {}
protected void after() throws Exception {}
}

View File

@ -0,0 +1,54 @@
package org.apache.lucene.util;
import java.io.Closeable;
import java.io.IOException;
import org.apache.lucene.store.MockDirectoryWrapper;
import org.junit.Assert;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* Attempts to close a {@link MockDirectoryWrapper}.
*
* @see LuceneTestCase#newDirectory(java.util.Random)
*/
final class CloseableDirectory implements Closeable {
private final MockDirectoryWrapper dir;
private final TestRuleMarkFailure failureMarker;
public CloseableDirectory(MockDirectoryWrapper dir,
TestRuleMarkFailure failureMarker) {
this.dir = dir;
this.failureMarker = failureMarker;
}
@Override
public void close() throws IOException {
// We only attempt to check open/closed state if there were no other test
// failures.
try {
if (failureMarker.wasSuccessful() && dir.isOpen()) {
Assert.fail("Directory not closed: " + dir);
}
} finally {
// TODO: perform real close of the delegate: LUCENE-4058
// dir.close();
}
}
}

View File

@ -0,0 +1,48 @@
package org.apache.lucene.util;
import java.io.*;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* A {@link Closeable} that attempts to remove a given file/folder.
*/
final class CloseableFile implements Closeable {
private final File file;
public CloseableFile(File file) {
this.file = file;
}
@Override
public void close() throws IOException {
if (file.exists()) {
try {
_TestUtil.rmDir(file);
} catch (IOException e) {
// Ignore the exception from rmDir.
}
// Re-check.
if (file.exists()) {
throw new IOException(
"Could not remove: " + file.getAbsolutePath());
}
}
}
}

View File

@ -1,57 +0,0 @@
package org.apache.lucene.util;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
import org.hamcrest.Description;
import org.junit.internal.AssumptionViolatedException;
/**
* We have our own "custom" assumption class because JUnit's {@link AssumptionViolatedException}
* does not allow a cause exception to be set.
*
* <p>We currently subclass and substitute JUnit's internal AVE.
*/
@SuppressWarnings("serial")
final class InternalAssumptionViolatedException extends AssumptionViolatedException {
private final String message;
public InternalAssumptionViolatedException(String message) {
this(message, null);
}
public InternalAssumptionViolatedException(String message, Throwable t) {
super(t, /* no matcher. */ null);
if (getCause() != t) {
throw new Error("AssumptionViolationException not setting up getCause() properly? Panic.");
}
this.message = message;
}
@Override
public String getMessage() {
return super.getMessage();
}
@Override
public void describeTo(Description description) {
description.appendText("failed assumption: " + message);
if (getCause() != null) {
description.appendText("(throwable: " + getCause().toString() + ")");
}
}
}

View File

@ -27,7 +27,6 @@ import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.util.Random;

View File

@ -1,140 +0,0 @@
package org.apache.lucene.util;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
import java.util.Random;
/**
* A random with a delegate, preventing calls to {@link Random#setSeed(long)} and
* permitting end-of-lifecycle markers.
*/
@SuppressWarnings("serial")
final class RandomNoSetSeed extends Random {
private final Random delegate;
/**
* If <code>false</code>, the object is dead. Any calls to any method will result
* in an exception.
*/
private volatile boolean alive = true;
void setDead() {
alive = false;
}
public RandomNoSetSeed(Random delegate) {
super(0);
this.delegate = delegate;
}
@Override
protected int next(int bits) {
throw new RuntimeException("Shouldn't be reachable.");
}
@Override
public boolean nextBoolean() {
checkAlive();
return delegate.nextBoolean();
}
@Override
public void nextBytes(byte[] bytes) {
checkAlive();
delegate.nextBytes(bytes);
}
@Override
public double nextDouble() {
checkAlive();
return delegate.nextDouble();
}
@Override
public float nextFloat() {
checkAlive();
return delegate.nextFloat();
}
@Override
public double nextGaussian() {
checkAlive();
return delegate.nextGaussian();
}
@Override
public int nextInt() {
checkAlive();
return delegate.nextInt();
}
@Override
public int nextInt(int n) {
checkAlive();
return delegate.nextInt(n);
}
@Override
public long nextLong() {
checkAlive();
return delegate.nextLong();
}
@Override
public void setSeed(long seed) {
// This is an interesting case of observing uninitialized object from an instance method
// (this method is called from the superclass constructor). We allow it.
if (seed == 0 && delegate == null) {
return;
}
throw new RuntimeException(
RandomNoSetSeed.class.getSimpleName() +
" prevents changing the seed of its random generators to assure repeatability" +
" of tests. If you need a mutable instance of Random, create a new instance," +
" preferably with the initial seed aquired from this Random instance.");
}
@Override
public String toString() {
checkAlive();
return delegate.toString();
}
@Override
public boolean equals(Object obj) {
checkAlive();
return delegate.equals(obj);
}
@Override
public int hashCode() {
checkAlive();
return delegate.hashCode();
}
/**
* Check the liveness status.
*/
private void checkAlive() {
if (!alive) {
throw new RuntimeException("This Random is dead. Do not store references to " +
"Random instances, acquire an instance when you need one.");
}
}
}

View File

@ -21,8 +21,8 @@ package org.apache.lucene.util;
* Sneaky: rethrowing checked exceptions as unchecked
* ones. Eh, it is sometimes useful...
*
* <p>Pulled from http://www.javapuzzlers.com (I
* think?).</p>
* <p>Pulled from <a href="http://www.javapuzzlers.com">Java Puzzlers</a>.</p>
* @see "http://www.amazon.com/Java-Puzzlers-Traps-Pitfalls-Corner/dp/032133678X"
*/
@SuppressWarnings({"unchecked","rawtypes"})
public final class Rethrow {

View File

@ -0,0 +1,174 @@
package org.apache.lucene.util;
import static org.apache.lucene.util.LuceneTestCase.DEFAULT_LINE_DOCS_FILE;
import static org.apache.lucene.util.LuceneTestCase.JENKINS_LARGE_LINE_DOCS_FILE;
import static org.apache.lucene.util.LuceneTestCase.RANDOM_MULTIPLIER;
import static org.apache.lucene.util.LuceneTestCase.TEST_CODEC;
import static org.apache.lucene.util.LuceneTestCase.TEST_DIRECTORY;
import static org.apache.lucene.util.LuceneTestCase.TEST_LINE_DOCS_FILE;
import static org.apache.lucene.util.LuceneTestCase.TEST_NIGHTLY;
import static org.apache.lucene.util.LuceneTestCase.TEST_POSTINGSFORMAT;
import static org.apache.lucene.util.LuceneTestCase.classEnvRule;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.lucene.codecs.Codec;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import com.carrotsearch.randomizedtesting.LifecycleScope;
import com.carrotsearch.randomizedtesting.RandomizedContext;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* A suite listener printing a "reproduce string". This ensures test result
* events are always captured properly even if exceptions happen at
* initialization or suite/ hooks level.
*/
public final class RunListenerPrintReproduceInfo extends RunListener {
/**
* A list of all test suite classes executed so far in this JVM (ehm,
* under this class's classloader).
*/
private static List<String> testClassesRun = new ArrayList<String>();
/**
* The currently executing scope.
*/
private LifecycleScope scope;
/** Current test failed. */
private boolean testFailed;
/** Suite-level code (initialization, rule, hook) failed. */
private boolean suiteFailed;
/** A marker to print full env. diagnostics after the suite. */
private boolean printDiagnosticsAfterClass;
@Override
public void testRunStarted(Description description) throws Exception {
suiteFailed = false;
testFailed = false;
scope = LifecycleScope.SUITE;
Class<?> targetClass = RandomizedContext.current().getTargetClass();
testClassesRun.add(targetClass.getSimpleName());
}
@Override
public void testStarted(Description description) throws Exception {
this.testFailed = false;
this.scope = LifecycleScope.TEST;
}
@Override
public void testFailure(Failure failure) throws Exception {
if (scope == LifecycleScope.TEST) {
testFailed = true;
} else {
suiteFailed = true;
}
printDiagnosticsAfterClass = true;
}
@Override
public void testFinished(Description description) throws Exception {
if (testFailed) {
reportAdditionalFailureInfo(description.getMethodName());
}
scope = LifecycleScope.SUITE;
testFailed = false;
}
@Override
public void testRunFinished(Result result) throws Exception {
if (printDiagnosticsAfterClass || LuceneTestCase.VERBOSE) {
RunListenerPrintReproduceInfo.printDebuggingInformation();
}
if (suiteFailed) {
reportAdditionalFailureInfo(null);
}
}
/** print some useful debugging information about the environment */
static void printDebuggingInformation() {
if (classEnvRule != null) {
System.err.println("NOTE: test params are: codec=" + Codec.getDefault() +
", sim=" + classEnvRule.similarity +
", locale=" + classEnvRule.locale +
", timezone=" + (classEnvRule.timeZone == null ? "(null)" : classEnvRule.timeZone.getID()));
}
System.err.println("NOTE: " + System.getProperty("os.name") + " "
+ System.getProperty("os.version") + " "
+ System.getProperty("os.arch") + "/"
+ System.getProperty("java.vendor") + " "
+ System.getProperty("java.version") + " "
+ (Constants.JRE_IS_64BIT ? "(64-bit)" : "(32-bit)") + "/"
+ "cpus=" + Runtime.getRuntime().availableProcessors() + ","
+ "threads=" + Thread.activeCount() + ","
+ "free=" + Runtime.getRuntime().freeMemory() + ","
+ "total=" + Runtime.getRuntime().totalMemory());
System.err.println("NOTE: All tests run in this JVM: " + Arrays.toString(testClassesRun.toArray()));
}
// We get here from InterceptTestCaseEvents on the 'failed' event....
public void reportAdditionalFailureInfo(final String testName) {
if (TEST_LINE_DOCS_FILE.endsWith(JENKINS_LARGE_LINE_DOCS_FILE)) {
System.err.println("NOTE: download the large Jenkins line-docs file by running 'ant get-jenkins-line-docs' in the lucene directory.");
}
StringBuilder b = new StringBuilder();
b.append("NOTE: reproduce with: ant test ")
.append("-Dtestcase=").append(RandomizedContext.current().getTargetClass().getSimpleName());
if (testName != null) {
b.append(" -Dtests.method=").append(testName);
}
b.append(" -Dtests.seed=")
.append(RandomizedContext.current().getRunnerSeedAsString())
.append(reproduceWithExtraParams());
System.err.println(b.toString());
}
// extra params that were overridden needed to reproduce the command
private static String reproduceWithExtraParams() {
StringBuilder sb = new StringBuilder();
if (classEnvRule != null) {
if (classEnvRule.locale != null) sb.append(" -Dtests.locale=").append(classEnvRule.locale);
if (classEnvRule.timeZone != null) sb.append(" -Dtests.timezone=").append(classEnvRule.timeZone.getID());
}
if (!TEST_CODEC.equals("random")) sb.append(" -Dtests.codec=").append(TEST_CODEC);
if (!TEST_POSTINGSFORMAT.equals("random")) sb.append(" -Dtests.postingsformat=").append(TEST_POSTINGSFORMAT);
if (!TEST_DIRECTORY.equals("random")) sb.append(" -Dtests.directory=").append(TEST_DIRECTORY);
if (RANDOM_MULTIPLIER > 1) sb.append(" -Dtests.multiplier=").append(RANDOM_MULTIPLIER);
if (TEST_NIGHTLY) sb.append(" -Dtests.nightly=true");
if (!TEST_LINE_DOCS_FILE.equals(DEFAULT_LINE_DOCS_FILE)) sb.append(" -Dtests.linedocsfile=" + TEST_LINE_DOCS_FILE);
// TODO we can't randomize this yet (it drives ant crazy) but this makes tests reproduce
// in case machines have different default charsets...
sb.append(" -Dargs=\"-Dfile.encoding=" + System.getProperty("file.encoding") + "\"");
return sb.toString();
}
}

View File

@ -1,146 +0,0 @@
package org.apache.lucene.util;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.MultipleFailureException;
import org.junit.runners.model.Statement;
public class SystemPropertiesInvariantRule implements TestRule {
/**
* Ignored property keys.
*/
private final HashSet<String> ignoredProperties;
/**
* Cares about all properties.
*/
public SystemPropertiesInvariantRule() {
this(Collections.<String>emptySet());
}
/**
* Don't care about the given set of properties.
*/
public SystemPropertiesInvariantRule(String... ignoredProperties) {
this.ignoredProperties = new HashSet<String>(Arrays.asList(ignoredProperties));
}
/**
* Don't care about the given set of properties.
*/
public SystemPropertiesInvariantRule(Set<String> ignoredProperties) {
this.ignoredProperties = new HashSet<String>(ignoredProperties);
}
@Override
public Statement apply(final Statement s, Description d) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
TreeMap<String,String> before = SystemPropertiesRestoreRule.cloneAsMap(System.getProperties());
ArrayList<Throwable> errors = new ArrayList<Throwable>();
try {
s.evaluate();
} catch (Throwable t) {
errors.add(t);
} finally {
final TreeMap<String,String> after = SystemPropertiesRestoreRule.cloneAsMap(System.getProperties());
// Remove ignored if they exist.
before.keySet().removeAll(ignoredProperties);
after.keySet().removeAll(ignoredProperties);
if (!after.equals(before)) {
errors.add(
new AssertionError("System properties invariant violated.\n" +
collectErrorMessage(before, after)));
}
// Restore original properties.
SystemPropertiesRestoreRule.restore(before, after, ignoredProperties);
}
MultipleFailureException.assertEmpty(errors);
}
private StringBuilder collectErrorMessage(
TreeMap<String,String> before, TreeMap<String,String> after) {
TreeSet<String> newKeys = new TreeSet<String>(after.keySet());
newKeys.removeAll(before.keySet());
TreeSet<String> missingKeys = new TreeSet<String>(before.keySet());
missingKeys.removeAll(after.keySet());
TreeSet<String> differentKeyValues = new TreeSet<String>(before.keySet());
differentKeyValues.retainAll(after.keySet());
for (Iterator<String> i = differentKeyValues.iterator(); i.hasNext();) {
String key = i.next();
String valueBefore = before.get(key);
String valueAfter = after.get(key);
if ((valueBefore == null && valueAfter == null) ||
(valueBefore.equals(valueAfter))) {
i.remove();
}
}
final StringBuilder b = new StringBuilder();
if (!missingKeys.isEmpty()) {
b.append("Missing keys:\n");
for (String key : missingKeys) {
b.append(" ").append(key)
.append("=")
.append(before.get(key))
.append("\n");
}
}
if (!newKeys.isEmpty()) {
b.append("New keys:\n");
for (String key : newKeys) {
b.append(" ").append(key)
.append("=")
.append(after.get(key))
.append("\n");
}
}
if (!differentKeyValues.isEmpty()) {
b.append("Different values:\n");
for (String key : differentKeyValues) {
b.append(" [old]").append(key)
.append("=")
.append(before.get(key)).append("\n");
b.append(" [new]").append(key)
.append("=")
.append(after.get(key)).append("\n");
}
}
return b;
}
};
}
}

View File

@ -1,120 +0,0 @@
package org.apache.lucene.util;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
import java.util.*;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* Restore system properties from before the nested {@link Statement}.
*/
public class SystemPropertiesRestoreRule implements TestRule {
/**
* Ignored property keys.
*/
private final HashSet<String> ignoredProperties;
/**
* Restores all properties.
*/
public SystemPropertiesRestoreRule() {
this(Collections.<String>emptySet());
}
/**
* @param ignoredProperties Properties that will be ignored (and will not be restored).
*/
public SystemPropertiesRestoreRule(Set<String> ignoredProperties) {
this.ignoredProperties = new HashSet<String>(ignoredProperties);
}
/**
* @param ignoredProperties Properties that will be ignored (and will not be restored).
*/
public SystemPropertiesRestoreRule(String... ignoredProperties) {
this.ignoredProperties = new HashSet<String>(Arrays.asList(ignoredProperties));
}
@Override
public Statement apply(final Statement s, Description d) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
TreeMap<String,String> before = cloneAsMap(System.getProperties());
try {
s.evaluate();
} finally {
TreeMap<String,String> after = cloneAsMap(System.getProperties());
if (!after.equals(before)) {
// Restore original properties.
restore(before, after, ignoredProperties);
}
}
}
};
}
static TreeMap<String,String> cloneAsMap(Properties properties) {
TreeMap<String,String> result = new TreeMap<String,String>();
for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) {
final Object key = e.nextElement();
// Skip non-string properties or values, they're abuse of Properties object.
if (key instanceof String) {
String value = properties.getProperty((String) key);
if (value == null) {
Object ovalue = properties.get(key);
if (ovalue != null) {
// ovalue has to be a non-string object. Skip the property because
// System.clearProperty won't be able to cast back the existing value.
continue;
}
}
result.put((String) key, value);
}
}
return result;
}
static void restore(
TreeMap<String,String> before,
TreeMap<String,String> after,
Set<String> ignoredKeys) {
// Clear anything that is present after but wasn't before.
after.keySet().removeAll(before.keySet());
for (String key : after.keySet()) {
if (!ignoredKeys.contains(key))
System.clearProperty(key);
}
// Restore original property values unless they are ignored (then leave).
for (Map.Entry<String,String> e : before.entrySet()) {
String key = e.getValue();
if (!ignoredKeys.contains(key)) {
if (key == null) {
System.clearProperty(e.getKey()); // Can this happen?
} else {
System.setProperty(e.getKey(), key);
}
}
}
}
}

View File

@ -0,0 +1,61 @@
package org.apache.lucene.util;
import org.apache.lucene.search.FieldCache;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
public class TestRuleFieldCacheSanity implements TestRule {
@Override
public Statement apply(final Statement s, final Description d) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
s.evaluate();
Throwable problem = null;
try {
// calling assertSaneFieldCaches here isn't as useful as having test
// classes call it directly from the scope where the index readers
// are used, because they could be gc'ed just before this tearDown
// method is called.
//
// But it's better then nothing.
//
// If you are testing functionality that you know for a fact
// "violates" FieldCache sanity, then you should either explicitly
// call purgeFieldCache at the end of your test method, or refactor
// your Test class so that the inconsistent FieldCache usages are
// isolated in distinct test methods
LuceneTestCase.assertSaneFieldCaches(d.getDisplayName());
} catch (Throwable t) {
problem = t;
}
FieldCache.DEFAULT.purgeAllCaches();
if (problem != null) {
Rethrow.rethrow(problem);
}
}
};
}
}

View File

@ -0,0 +1,55 @@
package org.apache.lucene.util;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
final class TestRuleIcuHack implements TestRule {
/** Globally only check hack once. */
private static volatile AtomicBoolean icuTested = new AtomicBoolean(false);
@Override
public Statement apply(final Statement s, Description d) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
// START hack to init ICU safely before we randomize locales.
// ICU fails during classloading when a special Java7-only locale is the default
// see: http://bugs.icu-project.org/trac/ticket/8734
if (!icuTested.getAndSet(true)) {
Locale previous = Locale.getDefault();
try {
Locale.setDefault(Locale.US);
Class.forName("com.ibm.icu.util.ULocale");
} catch (ClassNotFoundException cnfe) {
// ignore if no ICU is in classpath
} finally {
Locale.setDefault(previous);
}
}
s.evaluate();
}
};
}
}

View File

@ -0,0 +1,105 @@
package org.apache.lucene.util;
import java.util.ArrayList;
import java.util.List;
import org.junit.internal.AssumptionViolatedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* A rule for marking failed tests and suites.
*/
public final class TestRuleMarkFailure implements TestRule {
private final TestRuleMarkFailure [] chained;
private volatile boolean failures;
public TestRuleMarkFailure(TestRuleMarkFailure... chained) {
this.chained = chained;
}
@Override
public Statement apply(final Statement s, Description d) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
// Clear status at start.
failures = false;
try {
s.evaluate();
} catch (Throwable t) {
for (Throwable t2 : expandFromMultiple(t)) {
if (!(t2 instanceof AssumptionViolatedException)) {
markFailed();
break;
}
}
throw t;
}
}
};
}
/**
* Expand from multi-exception wrappers.
*/
private static List<Throwable> expandFromMultiple(Throwable t) {
return expandFromMultiple(t, new ArrayList<Throwable>());
}
/** Internal recursive routine. */
private static List<Throwable> expandFromMultiple(Throwable t, List<Throwable> list) {
if (t instanceof org.junit.runners.model.MultipleFailureException) {
for (Throwable sub : ((org.junit.runners.model.MultipleFailureException) t).getFailures()) {
expandFromMultiple(sub, list);
}
} else {
list.add(t);
}
return list;
}
/**
* Taints this object and any chained as having failures.
*/
public void markFailed() {
failures = true;
for (TestRuleMarkFailure next : chained) {
next.markFailed();
}
}
/**
* Check if this object had any marked failures.
*/
public boolean hadFailures() {
return failures;
}
/**
* Check if this object was successful (the opposite of {@link #hadFailures()}).
*/
public boolean wasSuccessful() {
return !hadFailures();
}
}

View File

@ -23,7 +23,6 @@ import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.List;
import org.junit.internal.AssumptionViolatedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.MultipleFailureException;
@ -34,17 +33,11 @@ import org.junit.runners.model.Statement;
* {@link Thread#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler)}
* and causes test/ suite failures if uncaught exceptions are detected.
*/
public class UncaughtExceptionsRule implements TestRule {
public class TestRuleReportUncaughtExceptions implements TestRule {
// This was originally volatile, but I don't think it needs to be. It's the same
// thread accessing it, always.
private UncaughtExceptionHandler savedUncaughtExceptionHandler;
private final LuceneTestCase ltc;
public UncaughtExceptionsRule(LuceneTestCase ltc) {
this.ltc = ltc;
}
public static class UncaughtExceptionEntry {
public final Thread thread;
public final Throwable exception;
@ -86,29 +79,11 @@ public class UncaughtExceptionsRule implements TestRule {
uncaughtExceptions.clear();
}
if (hasNonAssumptionErrors(errors)) {
if (ltc == null) {
// class level failure (e.g. afterclass)
LuceneTestCase.reportPartialFailureInfo();
} else {
// failure in a method
ltc.reportAdditionalFailureInfo();
}
}
MultipleFailureException.assertEmpty(errors);
}
};
}
private boolean hasNonAssumptionErrors(ArrayList<Throwable> errors) {
for (Throwable t : errors) {
if (!(t instanceof AssumptionViolatedException)) {
return true;
}
}
return false;
}
/**
* Just a check if anything's been caught.
*/

View File

@ -0,0 +1,225 @@
package org.apache.lucene.util;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TimeZone;
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.codecs.appending.AppendingCodec;
import org.apache.lucene.codecs.lucene3x.PreFlexRWCodec;
import org.apache.lucene.codecs.lucene40.Lucene40Codec;
import org.apache.lucene.codecs.simpletext.SimpleTextCodec;
import org.apache.lucene.index.RandomCodec;
import org.apache.lucene.search.RandomSimilarityProvider;
import org.apache.lucene.search.similarities.DefaultSimilarity;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
import com.carrotsearch.randomizedtesting.RandomizedContext;
import static org.apache.lucene.util.LuceneTestCase.VERBOSE;
import static org.apache.lucene.util.LuceneTestCase.INFOSTREAM;
import static org.apache.lucene.util.LuceneTestCase.TEST_CODEC;
import static org.apache.lucene.util.LuceneTestCase.*;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* Setup and restore suite-level environment (fine grained junk that
* doesn't fit anywhere else).
*/
final class TestRuleSetupAndRestoreClassEnv extends AbstractBeforeAfterRule {
/**
* Restore these system property values.
*/
private HashMap<String, String> restoreProperties = new HashMap<String,String>();
private Codec savedCodec;
private Locale savedLocale;
private TimeZone savedTimeZone;
private InfoStream savedInfoStream;
Locale locale;
TimeZone timeZone;
Similarity similarity;
/**
* @see SuppressCodecs
*/
HashSet<String> avoidCodecs;
@Override
protected void before() throws Exception {
// enable this by default, for IDE consistency with ant tests (as its the default from ant)
// TODO: really should be in solr base classes, but some extend LTC directly.
// we do this in beforeClass, because some tests currently disable it
restoreProperties.put("solr.directoryFactory", System.getProperty("solr.directoryFactory"));
if (System.getProperty("solr.directoryFactory") == null) {
System.setProperty("solr.directoryFactory", "org.apache.solr.core.MockDirectoryFactory");
}
// enable the Lucene 3.x PreflexRW codec explicitly, to work around bugs in IBM J9 / Harmony ServiceLoader:
try {
final java.lang.reflect.Field spiLoaderField = Codec.class.getDeclaredField("loader");
spiLoaderField.setAccessible(true);
final Object spiLoader = spiLoaderField.get(null);
final java.lang.reflect.Field modifiableServicesField = NamedSPILoader.class.getDeclaredField("modifiableServices");
modifiableServicesField.setAccessible(true);
@SuppressWarnings({"unchecked","rawtypes"}) final Map<String,Codec> serviceMap =
(Map) modifiableServicesField.get(spiLoader);
if (!(Codec.forName("Lucene3x") instanceof PreFlexRWCodec)) {
if (Constants.JAVA_VENDOR.startsWith("IBM")) {
// definitely a buggy version
System.err.println("ERROR: Your VM's java.util.ServiceLoader implementation is buggy"+
" and does not respect classpath order, please report this to the vendor.");
} else {
// could just be a classpath issue
System.err.println("ERROR: fix your classpath to have tests-framework.jar before lucene-core.jar!"+
" If you have already done this, then your VM's java.util.ServiceLoader implementation is buggy"+
" and does not respect classpath order, please report this to the vendor.");
}
serviceMap.put("Lucene3x", new PreFlexRWCodec());
}
} catch (Exception e) {
throw new RuntimeException("Cannot access internals of Codec and NamedSPILoader classes", e);
}
// if verbose: print some debugging stuff about which codecs are loaded
if (VERBOSE) {
Set<String> codecs = Codec.availableCodecs();
for (String codec : codecs) {
System.out.println("Loaded codec: '" + codec + "': " + Codec.forName(codec).getClass().getName());
}
Set<String> postingsFormats = PostingsFormat.availablePostingsFormats();
for (String postingsFormat : postingsFormats) {
System.out.println("Loaded postingsFormat: '" + postingsFormat + "': " + PostingsFormat.forName(postingsFormat).getClass().getName());
}
}
savedInfoStream = InfoStream.getDefault();
final Random random = RandomizedContext.current().getRandom();
final boolean v = random.nextBoolean();
if (INFOSTREAM) {
InfoStream.setDefault(new PrintStreamInfoStream(System.out));
} else if (v) {
InfoStream.setDefault(new NullInfoStream());
}
Class<?> targetClass = RandomizedContext.current().getTargetClass();
avoidCodecs = new HashSet<String>();
if (targetClass.isAnnotationPresent(SuppressCodecs.class)) {
SuppressCodecs a = targetClass.getAnnotation(SuppressCodecs.class);
avoidCodecs.addAll(Arrays.asList(a.value()));
System.err.println("NOTE: Suppressing codecs " + Arrays.toString(a.value())
+ " for " + targetClass.getSimpleName() + ".");
}
PREFLEX_IMPERSONATION_IS_ACTIVE = false;
savedCodec = Codec.getDefault();
final Codec codec;
int randomVal = random.nextInt(10);
if ("Lucene3x".equals(TEST_CODEC) || ("random".equals(TEST_CODEC) && randomVal < 2 && !shouldAvoidCodec("Lucene3x"))) { // preflex-only setup
codec = Codec.forName("Lucene3x");
assert (codec instanceof PreFlexRWCodec) : "fix your classpath to have tests-framework.jar before lucene-core.jar";
PREFLEX_IMPERSONATION_IS_ACTIVE = true;
} else if ("SimpleText".equals(TEST_CODEC) || ("random".equals(TEST_CODEC) && randomVal == 9 && !shouldAvoidCodec("SimpleText"))) {
codec = new SimpleTextCodec();
} else if ("Appending".equals(TEST_CODEC) || ("random".equals(TEST_CODEC) && randomVal == 8 && !shouldAvoidCodec("Appending"))) {
codec = new AppendingCodec();
} else if (!"random".equals(TEST_CODEC)) {
codec = Codec.forName(TEST_CODEC);
} else if ("random".equals(TEST_POSTINGSFORMAT)) {
codec = new RandomCodec(random, avoidCodecs);
} else {
codec = new Lucene40Codec() {
private final PostingsFormat format = PostingsFormat.forName(TEST_POSTINGSFORMAT);
@Override
public PostingsFormat getPostingsFormatForField(String field) {
return format;
}
@Override
public String toString() {
return super.toString() + ": " + format.toString();
}
};
}
Codec.setDefault(codec);
// Initialize locale/ timezone.
String testLocale = System.getProperty("tests.locale", "random");
String testTimeZone = System.getProperty("tests.timezone", "random");
// Always pick a random one for consistency (whether tests.locale was specified or not).
savedLocale = Locale.getDefault();
Locale randomLocale = randomLocale(random);
locale = testLocale.equals("random") ? randomLocale : localeForName(testLocale);
Locale.setDefault(locale);
// TimeZone.getDefault will set user.timezone to the default timezone of the user's locale.
// So store the original property value and restore it at end.
restoreProperties.put("user.timezone", System.getProperty("user.timezone"));
savedTimeZone = TimeZone.getDefault();
TimeZone randomTimeZone = randomTimeZone(random());
timeZone = testTimeZone.equals("random") ? randomTimeZone : TimeZone.getTimeZone(testTimeZone);
TimeZone.setDefault(timeZone);
similarity = random().nextBoolean() ? new DefaultSimilarity() : new RandomSimilarityProvider(random());
}
/**
* After suite cleanup (always invoked).
*/
@Override
protected void after() throws Exception {
for (Map.Entry<String,String> e : restoreProperties.entrySet()) {
if (e.getValue() == null) {
System.clearProperty(e.getKey());
} else {
System.setProperty(e.getKey(), e.getValue());
}
}
restoreProperties.clear();
Codec.setDefault(savedCodec);
InfoStream.setDefault(savedInfoStream);
Locale.setDefault(savedLocale);
TimeZone.setDefault(savedTimeZone);
System.clearProperty("solr.solr.home");
System.clearProperty("solr.data.dir");
}
/**
* Should a given codec be avoided for the currently executing suite?
*/
public boolean shouldAvoidCodec(String codec) {
return !avoidCodecs.isEmpty() && avoidCodecs.contains(codec);
}
}

View File

@ -0,0 +1,43 @@
package org.apache.lucene.util;
import org.apache.lucene.search.BooleanQuery;
import org.junit.internal.AssumptionViolatedException;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* Prepares and restores {@link LuceneTestCase} at instance level
* (fine grained junk that doesn't fit anywhere else).
*/
final class TestRuleSetupAndRestoreInstanceEnv extends AbstractBeforeAfterRule {
private int savedBoolMaxClauseCount;
protected void before() {
savedBoolMaxClauseCount = BooleanQuery.getMaxClauseCount();
final String defFormat = _TestUtil.getPostingsFormat("thisCodeMakesAbsolutelyNoSenseCanWeDeleteIt");
if (LuceneTestCase.shouldAvoidCodec(defFormat)) {
throw new AssumptionViolatedException(
"Method not allowed to use codec: " + defFormat + ".");
}
}
protected void after() {
BooleanQuery.setMaxClauseCount(savedBoolMaxClauseCount);
}
}

View File

@ -0,0 +1,63 @@
package org.apache.lucene.util;
import org.junit.Assert;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* Make sure {@link LuceneTestCase#setUp()} and {@link LuceneTestCase#tearDown()} were invoked even if they
* have been overriden. We assume nobody will call these out of non-overriden
* methods (they have to be public by contract, unfortunately). The top-level
* methods just set a flag that is checked upon successful execution of each test
* case.
*/
class TestRuleSetupTeardownChained implements TestRule {
/**
* @see TestRuleSetupTeardownChained
*/
public boolean setupCalled;
/**
* @see TestRuleSetupTeardownChained
*/
public boolean teardownCalled;
@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
setupCalled = false;
teardownCalled = false;
base.evaluate();
// I assume we don't want to check teardown chaining if something happens in the
// test because this would obscure the original exception?
if (!setupCalled) {
Assert.fail("One of the overrides of setUp does not propagate the call.");
}
if (!teardownCalled) {
Assert.fail("One of the overrides of tearDown does not propagate the call.");
}
}
};
}
}

View File

@ -21,7 +21,7 @@ import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class StoreClassNameRule implements TestRule {
public class TestRuleStoreClassName implements TestRule {
private volatile Description description;
@Override

View File

@ -0,0 +1,56 @@
package org.apache.lucene.util;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* Saves the executing thread and method name of the test case.
*/
final class TestRuleThreadAndTestName implements TestRule {
/**
* The thread executing the current test case.
* @see LuceneTestCase#isTestThread()
*/
public volatile Thread testCaseThread;
/**
* Test method name.
*/
public volatile String testMethodName = "<unknown>";
@Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
public void evaluate() throws Throwable {
try {
Thread current = Thread.currentThread();
testCaseThread = current;
testMethodName = description.getMethodName();
base.evaluate();
} finally {
testCaseThread = null;
testMethodName = null;
}
}
};
}
}

View File

@ -22,7 +22,7 @@ import com.carrotsearch.randomizedtesting.ClassValidator;
/**
* Require assertions for Lucene/Solr packages.
*/
public class RequireAssertions implements ClassValidator {
public class ValidateAssertionsRequired implements ClassValidator {
@Override
public void validate(Class<?> clazz) throws Throwable {
try {

View File

@ -0,0 +1,89 @@
package org.apache.lucene.util;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
import static com.carrotsearch.randomizedtesting.MethodCollector.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import com.carrotsearch.randomizedtesting.ClassValidator;
/**
* Don't allow {@link Before} and {@link After} hook overrides as it is most
* likely a user error and will result in superclass methods not being called
* (requires manual chaining).
*/
public class ValidateNoInstanceHooksOverrides implements ClassValidator {
@Override
public void validate(Class<?> clazz) throws Throwable {
List<List<Method>> all = allDeclaredMethods(clazz);
checkNoShadows(clazz, all, Before.class);
checkNoShadows(clazz, all, After.class);
}
private void checkNoShadows(Class<?> clazz, List<List<Method>> all, Class<? extends Annotation> ann) {
List<List<Method>> methodHierarchy = filterIgnored(annotatedWith(all, ann));
List<List<Method>> noOverrides = removeOverrides(methodHierarchy);
if (!noOverrides.equals(methodHierarchy)) {
Set<Method> shadowed = new HashSet<Method>(flatten(methodHierarchy));
shadowed.removeAll(flatten(noOverrides));
StringBuilder b = new StringBuilder();
for (Method m : shadowed) {
String sig = signature(m);
for (Method other : flatten(methodHierarchy)) {
if (other != m && sig.equals(signature(other))) {
b.append("Method: " + m.toString()
+ "#" + sig + " possibly overriden by " +
other.toString() + "#" + signature(other) + "\n");
}
}
}
throw new RuntimeException("There are overridden methods annotated with "
+ ann.getName() + ". These methods would not be executed by JUnit and need to manually chain themselves which can lead to" +
" maintenance problems. Consider using different method names or make hook methods private.\n" + b.toString().trim());
}
}
private List<List<Method>> filterIgnored(List<List<Method>> methods) {
Set<String> ignored = new HashSet<String>(Arrays.asList("setUp", "tearDown"));
List<List<Method>> copy = new ArrayList<List<Method>>();
for (List<Method> m : methods) {
if (!ignored.contains(m.get(0).getName())) {
copy.add(m);
}
}
return copy;
}
private String signature(Method m) {
return m.getName() + Arrays.toString(m.getParameterTypes());
}
}

View File

@ -34,7 +34,11 @@ import org.junit.BeforeClass;
import com.carrotsearch.randomizedtesting.ClassValidator;
public class NoStaticHooksShadowing implements ClassValidator {
/**
* Don't allow shadowing of {@link BeforeClass} or {@link AfterClass} hooks
* as it is very likely a user error and will prevent execution of shadowed hooks.
*/
public class ValidateNoStaticHooksShadowing implements ClassValidator {
@Override
public void validate(Class<?> clazz) throws Throwable {
List<List<Method>> all = allDeclaredMethods(clazz);

View File

@ -28,6 +28,8 @@ import java.io.PrintStream;
import java.lang.reflect.Method;
import java.nio.CharBuffer;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@ -80,7 +82,7 @@ public class _TestUtil {
try {
File f = createTempFile(desc, "tmp", LuceneTestCase.TEMP_DIR);
f.delete();
LuceneTestCase.registerTempDir(f);
LuceneTestCase.closeAfterSuite(new CloseableFile(f));
return f;
} catch (IOException e) {
throw new RuntimeException(e);
@ -122,7 +124,7 @@ public class _TestUtil {
rmDir(destDir);
destDir.mkdir();
LuceneTestCase.registerTempDir(destDir);
LuceneTestCase.closeAfterSuite(new CloseableFile(destDir));
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
@ -881,7 +883,21 @@ public class _TestUtil {
default:
return ref.utf8ToString();
}
}
/**
* Shutdown {@link ExecutorService} and wait for its.
*/
public static void shutdownExecutorService(ExecutorService ex) {
if (ex != null) {
try {
ex.shutdown();
ex.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// Just report it on the syserr.
System.err.println("Could not properly shutdown executor service.");
e.printStackTrace(System.err);
}
}
}
}

View File

@ -364,7 +364,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
// Thread.sleep(10000000000L);
purgeFieldCache(FieldCache.DEFAULT); // avoid FC insanity
FieldCache.DEFAULT.purgeAllCaches(); // avoid FC insanity
}
protected void queryPartialResults(final List<String> upShards,

View File

@ -440,7 +440,7 @@ public class TestGroupingSearch extends SolrTestCaseJ4 {
,"/grouped/"+f+"/matches==10"
,"/facet_counts/facet_fields/"+f+"==['1',3, '2',3, '3',2, '4',1, '5',1]"
);
purgeFieldCache(FieldCache.DEFAULT); // avoid FC insanity
FieldCache.DEFAULT.purgeAllCaches(); // avoid FC insanity
// test that grouping works with highlighting
assertJQ(req("fq",filt, "q","{!func}"+f2, "group","true", "group.field",f, "fl","id"

View File

@ -130,7 +130,7 @@ public class TestRandomFaceting extends SolrTestCaseJ4 {
}
}
} finally {
purgeFieldCache(FieldCache.DEFAULT); // avoid FC insanity
FieldCache.DEFAULT.purgeAllCaches(); // avoid FC insanity
}
}

View File

@ -42,7 +42,6 @@ public abstract class AbstractDistributedZkTestCase extends BaseDistributedSearc
@Override
public void setUp() throws Exception {
super.setUp();
log.info("####SETUP_START " + getName());
createTempDir();
String zkDir = testDir.getAbsolutePath() + File.separator

View File

@ -91,7 +91,7 @@ public class CloudStateUpdateTest extends SolrTestCaseJ4 {
AbstractZkTestCase.buildZooKeeper(zkServer.getZkHost(), zkServer
.getZkAddress(), "solrconfig.xml", "schema.xml");
log.info("####SETUP_START " + getName());
log.info("####SETUP_START " + getTestName());
dataDir1 = new File(dataDir + File.separator + "data1");
dataDir1.mkdirs();
@ -129,7 +129,7 @@ public class CloudStateUpdateTest extends SolrTestCaseJ4 {
System.clearProperty("hostPort");
System.clearProperty("solr.solr.home");
log.info("####SETUP_END " + getName());
log.info("####SETUP_END " + getTestName());
}

View File

@ -88,7 +88,7 @@ public class LeaderElectionIntegrationTest extends SolrTestCaseJ4 {
AbstractZkTestCase.buildZooKeeper(zkServer.getZkHost(),
zkServer.getZkAddress(), "solrconfig.xml", "schema.xml");
log.info("####SETUP_START " + getName());
log.info("####SETUP_START " + getTestName());
// set some system properties for use by tests
System.setProperty("solr.test.sys.prop1", "propone");
@ -129,7 +129,7 @@ public class LeaderElectionIntegrationTest extends SolrTestCaseJ4 {
if (!initSuccessful) {
fail("Init was not successful!");
}
log.info("####SETUP_END " + getName());
log.info("####SETUP_END " + getTestName());
}
private void setupContainer(int port, String shard) throws IOException,

View File

@ -23,21 +23,19 @@ import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.SystemPropertiesRestoreRule;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.beans.Field;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.*;
import org.apache.solr.core.SolrResourceLoader;
import org.apache.commons.io.IOUtils;
import org.junit.Rule;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
public class TestBinaryField extends LuceneTestCase {
HttpSolrServer server;
JettySolrRunner jetty;

View File

@ -198,7 +198,7 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
Arrays.asList("v1","\0:[* TO *]"), 88,12
);
purgeFieldCache(FieldCache.DEFAULT); // avoid FC insanity
FieldCache.DEFAULT.purgeAllCaches(); // avoid FC insanity
}
@Test
@ -281,7 +281,7 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
// System.out.println("Done test "+i);
}
purgeFieldCache(FieldCache.DEFAULT); // avoid FC insanity
FieldCache.DEFAULT.purgeAllCaches(); // avoid FC insanity
}
@Test
@ -421,7 +421,7 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
);
purgeFieldCache(FieldCache.DEFAULT); // avoid FC insanity
FieldCache.DEFAULT.purgeAllCaches(); // avoid FC insanity
}
/**
@ -642,7 +642,7 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
singleTest(fieldAsFunc, "sqrt(\0)");
assertTrue(orig != FileFloatSource.onlyForTesting);
purgeFieldCache(FieldCache.DEFAULT); // avoid FC insanity
FieldCache.DEFAULT.purgeAllCaches(); // avoid FC insanity
}
/**
@ -669,7 +669,7 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
100,10, 25,5, 0,0, 1,1);
singleTest(fieldAsFunc, "log(\0)", 1,0);
purgeFieldCache(FieldCache.DEFAULT); // avoid FC insanity
FieldCache.DEFAULT.purgeAllCaches(); // avoid FC insanity
}
@Test

View File

@ -43,7 +43,6 @@ import java.util.Set;
/**
* Test for LBHttpSolrServer
*
*
* @since solr 1.4
*/
public class TestLBHttpSolrServer extends LuceneTestCase {
@ -52,11 +51,13 @@ public class TestLBHttpSolrServer extends LuceneTestCase {
// TODO: fix this test to not require FSDirectory
static String savedFactory;
@BeforeClass
public static void beforeClass() throws Exception {
savedFactory = System.getProperty("solr.DirectoryFactory");
System.setProperty("solr.directoryFactory", "org.apache.solr.core.MockFSDirectoryFactory");
}
@AfterClass
public static void afterClass() throws Exception {
if (savedFactory == null) {
@ -100,6 +101,7 @@ public class TestLBHttpSolrServer extends LuceneTestCase {
for (SolrInstance aSolr : solr) {
aSolr.tearDown();
}
httpClient.getConnectionManager().shutdown();
super.tearDown();
}

View File

@ -23,7 +23,6 @@ import java.util.Random;
import org.apache.commons.io.IOUtils;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.SystemPropertiesRestoreRule;
import org.apache.solr.util.ExternalPaths;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
@ -34,6 +33,8 @@ import org.junit.Rule;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
/**
*
* @since solr 1.3

View File

@ -17,8 +17,12 @@ package org.apache.solr.client.solrj.embedded;
* limitations under the License.
*/
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import junit.framework.Assert;
import org.apache.lucene.util.SystemPropertiesRestoreRule;
import org.apache.solr.core.SolrCore;
import org.junit.Rule;
import org.junit.rules.RuleChain;
@ -26,9 +30,7 @@ import org.junit.rules.TestRule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
public class TestEmbeddedSolrServer extends AbstractEmbeddedSolrServerTestCase {

View File

@ -17,19 +17,23 @@
package org.apache.solr.client.solrj.embedded;
import java.io.File;
import java.io.FileInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import org.apache.commons.io.IOUtils;
import org.apache.lucene.util.SystemPropertiesRestoreRule;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.request.AbstractUpdateRequest.ACTION;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.client.solrj.request.*;
import org.apache.solr.client.solrj.response.CoreAdminResponse;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.util.FileUtils;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.util.FileUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
@ -39,14 +43,7 @@ import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.FileInputStream;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
/**
*

View File

@ -184,7 +184,7 @@ public abstract class BaseDistributedSearchTestCase extends SolrTestCaseJ4 {
if (!AbstractSolrTestCase.recurseDelete(testDir)) {
System.err.println("!!!! WARNING: best effort to remove " + testDir.getAbsolutePath() + " FAILED !!!!!");
}
purgeFieldCache(FieldCache.DEFAULT); // avoid FC insanity
FieldCache.DEFAULT.purgeAllCaches(); // avoid FC insanity
super.tearDown();
}

View File

@ -17,62 +17,41 @@
package org.apache.solr;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.io.*;
import java.util.*;
import java.util.logging.*;
import javax.xml.xpath.XPathExpressionException;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.SystemPropertiesRestoreRule;
import org.apache.noggit.CharArr;
import org.apache.noggit.JSONUtil;
import org.apache.noggit.ObjectBuilder;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.SolrInputField;
import org.apache.noggit.*;
import org.apache.solr.common.*;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.params.*;
import org.apache.solr.common.util.XML;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.JsonUpdateRequestHandler;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.request.*;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.servlet.DirectSolrConnection;
import org.apache.solr.util.AbstractSolrTestCase;
import org.apache.solr.util.TestHarness;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.*;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import com.carrotsearch.randomizedtesting.RandomizedContext;
import com.carrotsearch.randomizedtesting.annotations.ThreadLeaks;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
/**
* A junit4 Solr test harness that extends LuceneTestCaseJ4.
* Unlike AbstractSolrTestCase, a new core is not created for each test method.
*
* Unlike {@link AbstractSolrTestCase}, a new core is not created for each test method.
*/
public abstract class SolrTestCaseJ4 extends LuceneTestCase {
public static int DEFAULT_CONNECTION_TIMEOUT = 500; // default socket connection timeout in ms
@ -87,7 +66,8 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
RuleChain.outerRule(new SystemPropertiesRestoreRule());
@BeforeClass
public static void beforeClassSolrTestCase() throws Exception {
@SuppressWarnings("unused")
private static void beforeClass() throws Exception {
setupLogging();
startTrackingSearchers();
startTrackingZkClients();
@ -95,7 +75,8 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
}
@AfterClass
public static void afterClassSolrTestCase() throws Exception {
@SuppressWarnings("unused")
private static void afterClass() throws Exception {
deleteCore();
resetExceptionIgnores();
endTrackingSearchers();
@ -105,12 +86,12 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
log.info("###Starting " + getName()); // returns <unknown>???
log.info("###Starting " + getTestName()); // returns <unknown>???
}
@Override
public void tearDown() throws Exception {
log.info("###Ending " + getName());
log.info("###Ending " + getTestName());
super.tearDown();
}
@ -201,14 +182,6 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
if (endNumOpens-numOpens != endNumCloses-numCloses) {
String msg = "ERROR: SolrIndexSearcher opens=" + (endNumOpens-numOpens) + " closes=" + (endNumCloses-numCloses);
log.error(msg);
testsFailed = true;
// For debugging
// Set<Entry<SolrCore,Exception>> coreEntries = SolrCore.openHandles.entrySet();
// for (Entry<SolrCore,Exception> entry : coreEntries) {
// entry.getValue().printStackTrace();
// }
fail(msg);
}
}
@ -220,11 +193,9 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
SolrZkClient.numOpens.getAndSet(0);
SolrZkClient.numCloses.getAndSet(0);
if (endNumOpens-zkClientNumOpens != endNumCloses-zkClientNumCloses) {
String msg = "ERROR: SolrZkClient opens=" + (endNumOpens-zkClientNumOpens) + " closes=" + (endNumCloses-zkClientNumCloses);
log.error(msg);
testsFailed = true;
fail(msg);
}
}
@ -259,6 +230,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
protected static String schemaString;
protected static SolrConfig solrConfig;
/**
* Harness initialized by initTestHarness.
*
@ -267,6 +239,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
* </p>
*/
protected static TestHarness h;
/**
* LocalRequestFactory initialized by initTestHarness using sensible
* defaults.
@ -284,7 +257,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
*/
public static String getSchemaFile() {
return schemaString;
};
}
/**
* Subclasses must define this method to return the name of the
@ -292,7 +265,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
*/
public static String getSolrConfigFile() {
return configString;
};
}
/**
* The directory used to story the index managed by the TestHarness h
@ -358,7 +331,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
* to log the fact that their setUp process has ended.
*/
public void postSetUp() {
log.info("####POSTSETUP " + getName());
log.info("####POSTSETUP " + getTestName());
}
@ -368,7 +341,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
* tearDown method.
*/
public void preTearDown() {
log.info("####PRETEARDOWN " + getName());
log.info("####PRETEARDOWN " + getTestName());
}
/**

View File

@ -19,35 +19,28 @@
package org.apache.solr.util;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.io.*;
import java.util.*;
import javax.xml.xpath.XPathExpressionException;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.SystemPropertiesRestoreRule;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.SolrInputField;
import org.apache.solr.common.*;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.util.XML;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.request.SolrQueryRequest;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.*;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import com.carrotsearch.randomizedtesting.annotations.ThreadLeaks;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
/**
* An Abstract base class that makes writing Solr JUnit tests "easier"
*
@ -72,6 +65,7 @@ public abstract class AbstractSolrTestCase extends LuceneTestCase {
* </p>
*/
protected TestHarness h;
/**
* LocalRequestFactory initialized by initTestHarness using sensible
* defaults.
@ -125,6 +119,10 @@ public abstract class AbstractSolrTestCase extends LuceneTestCase {
*/
protected File dataDir;
public static Logger log = LoggerFactory.getLogger(AbstractSolrTestCase.class);
private String factoryProp;
/**
* Initializes things your test might need
*
@ -133,16 +131,11 @@ public abstract class AbstractSolrTestCase extends LuceneTestCase {
* <li>initializes the TestHarness h using this data directory, and getSchemaPath()</li>
* <li>initializes the LocalRequestFactory lrf using sensible defaults.</li>
* </ul>
*
*/
public static Logger log = LoggerFactory.getLogger(AbstractSolrTestCase.class);
private String factoryProp;
@Override
public void setUp() throws Exception {
super.setUp();
log.info("####SETUP_START " + getName());
log.info("####SETUP_START " + getTestName());
ignoreException("ignore_exception");
factoryProp = System.getProperty("solr.directoryFactory");
if (factoryProp == null) {
@ -162,7 +155,7 @@ public abstract class AbstractSolrTestCase extends LuceneTestCase {
lrf = h.getRequestFactory
("standard",0,20,CommonParams.VERSION,"2.2");
}
log.info("####SETUP_END " + getName());
log.info("####SETUP_END " + getTestName());
}
/** Causes an exception matching the regex pattern to not be logged. */
@ -181,7 +174,7 @@ public abstract class AbstractSolrTestCase extends LuceneTestCase {
* to log the fact that their setUp process has ended.
*/
public void postSetUp() {
log.info("####POSTSETUP " + getName());
log.info("####POSTSETUP " + getTestName());
}
@ -191,7 +184,7 @@ public abstract class AbstractSolrTestCase extends LuceneTestCase {
* tearDown method.
*/
public void preTearDown() {
log.info("####PRETEARDOWN " + getName());
log.info("####PRETEARDOWN " + getTestName());
}
/**
@ -201,7 +194,7 @@ public abstract class AbstractSolrTestCase extends LuceneTestCase {
*/
@Override
public void tearDown() throws Exception {
log.info("####TEARDOWN_START " + getName());
log.info("####TEARDOWN_START " + getTestName());
if (factoryProp == null) {
System.clearProperty("solr.directoryFactory");
}