SOLR-4951: Better randomization of MergePolicy in Solr tests

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1508521 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Chris M. Hostetter 2013-07-30 16:57:37 +00:00
parent 460a1be8a9
commit c78b4f80bb
7 changed files with 212 additions and 10 deletions

View File

@ -793,15 +793,8 @@ public abstract class LuceneTestCase extends Assert {
} }
} }
if (rarely(r)) { c.setMergePolicy(newMergePolicy(r));
c.setMergePolicy(new MockRandomMergePolicy(r));
} else if (r.nextBoolean()) {
c.setMergePolicy(newTieredMergePolicy());
} else if (r.nextInt(5) == 0) {
c.setMergePolicy(newAlcoholicMergePolicy());
} else {
c.setMergePolicy(newLogMergePolicy());
}
if (rarely(r)) { if (rarely(r)) {
c.setMergedSegmentWarmer(new SimpleMergedSegmentWarmer(c.getInfoStream())); c.setMergedSegmentWarmer(new SimpleMergedSegmentWarmer(c.getInfoStream()));
} }
@ -810,6 +803,21 @@ public abstract class LuceneTestCase extends Assert {
return c; return c;
} }
public static MergePolicy newMergePolicy(Random r) {
if (rarely(r)) {
return new MockRandomMergePolicy(r);
} else if (r.nextBoolean()) {
return newTieredMergePolicy(r);
} else if (r.nextInt(5) == 0) {
return newAlcoholicMergePolicy(r, classEnvRule.timeZone);
}
return newLogMergePolicy(r);
}
public static MergePolicy newMergePolicy() {
return newMergePolicy(random());
}
public static LogMergePolicy newLogMergePolicy() { public static LogMergePolicy newLogMergePolicy() {
return newLogMergePolicy(random()); return newLogMergePolicy(random());
} }

View File

@ -100,6 +100,8 @@ Other Changes
* SOLR-5056: Improve type safety of ConfigSolr class. (Alan Woodward) * SOLR-5056: Improve type safety of ConfigSolr class. (Alan Woodward)
* SOLR-4951: Better randomization of MergePolicy in Solr tests (hossman)
================== 4.4.0 ================== ================== 4.4.0 ==================
Versions of Major Components Versions of Major Components

View File

@ -25,5 +25,6 @@
<useCompoundFile>${useCompoundFile:false}</useCompoundFile> <useCompoundFile>${useCompoundFile:false}</useCompoundFile>
<maxIndexingThreads>123</maxIndexingThreads> <maxIndexingThreads>123</maxIndexingThreads>
<infoStream>true</infoStream> <infoStream>true</infoStream>
<mergePolicy class="org.apache.solr.util.RandomMergePolicy" />
</indexConfig> </indexConfig>
</config> </config>

View File

@ -23,4 +23,5 @@ A solrconfig.xml snippet containing indexConfig settings for randomized testing.
--> -->
<indexConfig> <indexConfig>
<useCompoundFile>${useCompoundFile:false}</useCompoundFile> <useCompoundFile>${useCompoundFile:false}</useCompoundFile>
<mergePolicy class="org.apache.solr.util.RandomMergePolicy" />
</indexConfig> </indexConfig>

View File

@ -17,8 +17,14 @@ package org.apache.solr.core;
* limitations under the License. * limitations under the License.
*/ */
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.LiveIndexWriterConfig;
import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.core.SolrCore;
import org.apache.solr.util.RefCounted;
import org.apache.solr.util.RandomMergePolicy;
import org.apache.solr.update.LoggingInfoStream; import org.apache.solr.update.LoggingInfoStream;
import org.junit.BeforeClass; import org.junit.BeforeClass;
@ -29,10 +35,30 @@ public class TestSolrIndexConfig extends SolrTestCaseJ4 {
initCore("solrconfig-indexconfig.xml","schema.xml"); initCore("solrconfig-indexconfig.xml","schema.xml");
} }
public void testIndexConfig() throws Exception { public void testLiveWriter() throws Exception {
SolrCore core = h.getCore();
RefCounted<IndexWriter> iw = core.getUpdateHandler().getSolrCoreState().getIndexWriter(core);
try {
checkIndexWriterConfig(iw.get().getConfig());
} finally {
if (null != iw) iw.decref();
}
}
public void testIndexConfigParsing() throws Exception {
IndexWriterConfig iwc = solrConfig.indexConfig.toIndexWriterConfig(h.getCore().getLatestSchema()); IndexWriterConfig iwc = solrConfig.indexConfig.toIndexWriterConfig(h.getCore().getLatestSchema());
checkIndexWriterConfig(iwc);
}
private void checkIndexWriterConfig(LiveIndexWriterConfig iwc) {
assertEquals(123, iwc.getMaxThreadStates()); assertEquals(123, iwc.getMaxThreadStates());
assertTrue(iwc.getInfoStream() instanceof LoggingInfoStream); assertTrue(iwc.getInfoStream() instanceof LoggingInfoStream);
assertTrue(iwc.getMergePolicy().getClass().toString(),
iwc.getMergePolicy() instanceof RandomMergePolicy);
} }
} }

View File

@ -0,0 +1,73 @@
/*
* 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.
*/
package org.apache.solr.util;
import org.apache.lucene.index.MergePolicy;
import org.apache.lucene.util.LuceneTestCase;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.InvocationTargetException;
/**
* A "test the test" sanity check using reflection to ensure that
* {@linke RandomMergePolicy} is working as expected
*/
public class TestRandomMergePolicy extends LuceneTestCase {
/**
* Ensure every MP method is overridden by RMP
* (future proof ourselves against new methods being added to MP)
*/
public void testMethodOverride() {
Class rmp = RandomMergePolicy.class;
for (Method meth : rmp.getMethods()) {
if (// ignore things like hashCode, equals, etc...
meth.getDeclaringClass().equals(Object.class)
// can't do anything about it regardless of what class declares it
|| Modifier.isFinal(meth.getModifiers())) {
continue;
}
assertEquals("method not overridden by RandomMergePolicy: " +
meth.toGenericString(),
rmp, meth.getDeclaringClass());
}
}
/**
* Ensure any "getter" methods return the same value as
* the wrapped MP
* (future proof ourselves against new final getter/setter pairs being
* added to MP w/o dealing with them in the RMP Constructor)
*/
public void testGetters() throws IllegalAccessException, InvocationTargetException {
final int iters = atLeast(20);
for (int i = 0; i < iters; i++) {
RandomMergePolicy rmp = new RandomMergePolicy();
Class mp = MergePolicy.class;
for (Method meth : mp.getDeclaredMethods()) {
if (meth.getName().startsWith("get") &&
(0 == meth.getParameterTypes().length)) {
assertEquals("MergePolicy getter gave diff results for RandomMergePolicy and the policy it wrapped: " + meth.toGenericString(),
meth.invoke(rmp), meth.invoke(rmp.inner));
}
}
}
}
}

View File

@ -0,0 +1,91 @@
/*
* 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.
*/
package org.apache.solr.util;
import org.apache.lucene.index.*;
import org.apache.lucene.index.MergePolicy.MergeSpecification;
import org.apache.lucene.util.LuceneTestCase;
import java.util.Map;
import java.io.IOException;
/**
* A {@link MergePolicy} with a no-arg constructor that proxies to a
* wrapped instance retrieved from {@link LuceneTestCase#newMergePolicy}.
* Solr tests utilizing the Lucene randomized test framework can refer
* to this class in solrconfig.xml to get a fully randomized merge policy.
*/
public final class RandomMergePolicy extends MergePolicy {
/**
* Not private so tests can inspect it,
* Not final so it can be set on clone
*/
MergePolicy inner;
public RandomMergePolicy() {
this(LuceneTestCase.newMergePolicy());
}
private RandomMergePolicy(MergePolicy inner) {
super(inner.getNoCFSRatio(),
(long) (inner.getMaxCFSSegmentSizeMB() * 1024 * 1024));
this.inner = inner;
}
public RandomMergePolicy clone() {
RandomMergePolicy clone = (RandomMergePolicy) super.clone();
clone.inner = this.inner.clone();
return clone;
}
public void close() {
inner.close();
}
public MergeSpecification findForcedDeletesMerges(SegmentInfos segmentInfos)
throws IOException {
return inner.findForcedDeletesMerges(segmentInfos);
}
public MergeSpecification findForcedMerges(SegmentInfos segmentInfos,
int maxSegmentCount,
Map<SegmentInfoPerCommit,Boolean> segmentsToMerge)
throws IOException {
return inner.findForcedMerges(segmentInfos, maxSegmentCount, segmentsToMerge);
}
public MergeSpecification findMerges(MergeTrigger mergeTrigger,
SegmentInfos segmentInfos)
throws IOException {
return inner.findMerges(mergeTrigger, segmentInfos);
}
public void setIndexWriter(IndexWriter writer) {
inner.setIndexWriter(writer);
}
public boolean useCompoundFile(SegmentInfos infos,
SegmentInfoPerCommit mergedInfo)
throws IOException {
return inner.useCompoundFile(infos, mergedInfo);
}
}