You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ma...@apache.org on 2020/07/27 13:57:51 UTC
[lucene-solr] branch reference_impl updated: @376 Solid tests
please. Solid as the sun.
This is an automated email from the ASF dual-hosted git repository.
markrmiller pushed a commit to branch reference_impl
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
The following commit(s) were added to refs/heads/reference_impl by this push:
new 63a44ad @376 Solid tests please. Solid as the sun.
63a44ad is described below
commit 63a44ada8dfcdbdfccf48454cd6d0413a0d2464b
Author: markrmiller@gmail.com <ma...@gmail.com>
AuthorDate: Mon Jul 27 08:57:30 2020 -0500
@376 Solid tests please. Solid as the sun.
---
.../apache/solr/cloud/TestRandomFlRTGCloud.java | 189 ++++++++++-----------
.../org/apache/solr/SolrIgnoredThreadsFilter.java | 5 +
2 files changed, 99 insertions(+), 95 deletions(-)
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestRandomFlRTGCloud.java b/solr/core/src/test/org/apache/solr/cloud/TestRandomFlRTGCloud.java
index 7f9cd7a..dfb952b 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestRandomFlRTGCloud.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestRandomFlRTGCloud.java
@@ -64,7 +64,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final String DEBUG_LABEL = MethodHandles.lookup().lookupClass().getName();
private static final String COLLECTION_NAME = DEBUG_LABEL + "_collection";
-
+
/** A basic client for operations at the cloud level, default collection will be set */
private static CloudHttp2SolrClient CLOUD_CLIENT;
/** One client per node */
@@ -75,8 +75,8 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
/** Since nested documents are not tested, when _root_ is declared in schema, it is always the same as id */
private static final FlValidator ROOT_VALIDATOR = new RenameFieldValueValidator("id" , "_root_");
-
- /**
+
+ /**
* Types of things we will randomly ask for in fl param, and validate in response docs.
*
* @see #addRandomFlValidators
@@ -100,7 +100,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
new SimpleFieldValueValidator("ccc_s"),
new RenameFieldValueValidator("ddd_s", "my_str_field_alias"),
//
- // SOLR-9376: RawValueTransformerFactory doesn't work in cloud mode
+ // SOLR-9376: RawValueTransformerFactory doesn't work in cloud mode
//
// new RawFieldValueValidator("json", "eee_s", "my_json_field_alias"),
// new RawFieldValueValidator("json", "fff_s"),
@@ -120,7 +120,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
new SubQueryValidator(),
new NotIncludedValidator("score"),
new NotIncludedValidator("score","score_alias:score")));
-
+
@BeforeClass
public static void createMiniSolrCloudCluster() throws Exception {
@@ -134,10 +134,10 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
final int numShards = singleCoreMode ? 1 : 2;
// ... including some forwarded requests from nodes not hosting a shard
final int numNodes = 1 + (singleCoreMode ? 0 : (numShards * repFactor));
-
+
final String configName = DEBUG_LABEL + "_config-set";
final Path configDir = Paths.get(TEST_HOME(), "collection1", "conf");
-
+
configureCluster(numNodes).addConfig(configName, configDir).configure();
CLOUD_CLIENT = cluster.getSolrClient();
@@ -163,7 +163,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
shutdownCluster();
}
- /**
+ /**
* Tests that all TransformerFactories that are implicitly provided by Solr are tested in this class
*
* @see FlValidator#getDefaultTransformerFactoryName
@@ -175,7 +175,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
for (String t : TransformerFactory.defaultFactories.keySet()) {
implicit.add(t);
}
-
+
final Set<String> covered = new LinkedHashSet<>();
for (FlValidator v : FL_VALIDATORS) {
String t = v.getDefaultTransformerFactoryName();
@@ -199,16 +199,15 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
"but it does not even exist in the set of 'implicit' TransformerFactories",
implicit.remove(buggy));
}
-
+
implicit.removeAll(covered);
assertEquals("Some implicit TransformerFactories are not yet tested by this class: " + implicit,
0, implicit.size());
}
-
-
+
public void testRandomizedUpdatesAndRTGs() throws Exception {
- final int maxNumDocs = atLeast(TEST_NIGHTLY ? 100 : 10);
+ final int maxNumDocs = atLeast( 100);
final int numSeedDocs = random().nextInt(maxNumDocs / 10); // at most ~10% of the max possible docs
final int numIters = atLeast(maxNumDocs * (TEST_NIGHTLY ? 10 : 2));
final SolrInputDocument[] knownDocs = new SolrInputDocument[maxNumDocs];
@@ -229,8 +228,8 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
}
}
- /**
- * Randomly chooses to do a commit, where the probability of doing so increases the longer it's been since
+ /**
+ * Randomly chooses to do a commit, where the probability of doing so increases the longer it's been since
* a commit was done.
*
* @returns <code>0</code> if a commit was done, else <code>itersSinceLastCommit + 1</code>
@@ -244,12 +243,12 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
}
return itersSinceLastCommit + 1;
}
-
+
private void assertOneIter(final SolrInputDocument[] knownDocs) throws IOException, SolrServerException {
// we want to occasionally test more then one doc per RTG
final int numDocsThisIter = TestUtil.nextInt(random(), 1, atLeast(2));
int numDocsThisIterThatExist = 0;
-
+
// pick some random docIds for this iteration and ...
final int[] docIds = new int[numDocsThisIter];
for (int i = 0; i < numDocsThisIter; i++) {
@@ -285,14 +284,14 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
* Does some random indexing of the specified docIds and adds them to knownDocs
*/
private void assertUpdate(final SolrInputDocument[] knownDocs, final int[] docIds) throws IOException, SolrServerException {
-
+
for (final int docId : docIds) {
// TODO: this method should also do some atomic update operations (ie: "inc" and "set")
// (but make sure to eval the updates locally as well before modifying knownDocs)
knownDocs[docId] = addRandomDocument(docId);
}
}
-
+
/**
* Deletes the docIds specified and asserts the results are valid, updateing knownDocs accordingly
*/
@@ -304,9 +303,9 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
}
assertEquals("Failed delete: " + docIds, 0, getRandClient(random()).deleteById(ids).getStatus());
}
-
+
/**
- * Adds one randomly generated document with the specified docId, asserting success, and returns
+ * Adds one randomly generated document with the specified docId, asserting success, and returns
* the document added
*/
private SolrInputDocument addRandomDocument(final int docId) throws IOException, SolrServerException {
@@ -332,13 +331,13 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
"axx_i", random().nextInt(),
"ayy_i", random().nextInt(),
"azz_s", TestUtil.randomSimpleString(random()));
-
+
log.info("ADD: {} = {}", docId, doc);
assertEquals(0, client.add(doc).getStatus());
return doc;
}
-
+
/**
* Does one or more RTG request for the specified docIds with a randomized fl & fq params, asserting
* that the returned document (if any) makes sense given the expected SolrInputDocuments
@@ -347,13 +346,13 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
final SolrClient client = getRandClient(random());
// NOTE: not using SolrClient.getById or getByIds because we want to force choice of "id" vs "ids" params
final ModifiableSolrParams params = params("qt","/get");
-
+
// random fq -- nothing fancy, secondary concern for our test
final Integer FQ_MAX = usually() ? null : random().nextInt();
if (null != FQ_MAX) {
params.add("fq", "aaa_i:[* TO " + FQ_MAX + "]");
}
-
+
final Set<FlValidator> validators = new LinkedHashSet<>();
validators.add(ID_VALIDATOR); // always include id so we can be confident which doc we're looking at
validators.add(ROOT_VALIDATOR); // always added in a nested schema, with the same value as id
@@ -365,7 +364,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
for (int docId : docIds) {
// every docId will be included in the request
idsToRequest.add("" + docId);
-
+
// only docs that should actually exist and match our (optional) filter will be expected in response
if (null != knownDocs[docId]) {
Integer filterVal = (Integer) knownDocs[docId].getFieldValue("aaa_i");
@@ -397,23 +396,23 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
assert 1 == idsToRequest.size();
params.add("id",idsToRequest.get(0));
}
-
+
final QueryResponse rsp = client.query(params);
assertNotNull(params.toString(), rsp);
final SolrDocumentList docs = getDocsFromRTGResponse(askForList, rsp);
assertNotNull(params + " => " + rsp, docs);
-
+
assertEquals("num docs mismatch: " + params + " => " + docsToExpect + " vs " + docs,
docsToExpect.size(), docs.size());
-
+
// NOTE: RTG makes no garuntees about the order docs will be returned in when multi requested
for (SolrDocument actual : docs) {
try {
int actualId = assertParseInt("id", actual.getFirstValue("id"));
final SolrInputDocument expected = knownDocs[actualId];
assertNotNull("expected null doc but RTG returned: " + actual, expected);
-
+
Set<String> expectedFieldNames = new TreeSet<>();
for (FlValidator v : validators) {
expectedFieldNames.addAll(v.assertRTGResults(validators, expected, actual));
@@ -427,20 +426,20 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
}
}
- /**
+ /**
* trivial helper method to deal with diff response structure between using a single 'id' param vs
* 2 or more 'id' params (or 1 or more 'ids' params).
*
- * @return List from response, or a synthetic one created from single response doc if
+ * @return List from response, or a synthetic one created from single response doc if
* <code>expectList</code> was false; May be empty; May be null if response included null list.
*/
private static SolrDocumentList getDocsFromRTGResponse(final boolean expectList, final QueryResponse rsp) {
if (expectList) {
return rsp.getResults();
}
-
+
// else: expect single doc, make our own list...
-
+
final SolrDocumentList result = new SolrDocumentList();
NamedList<Object> raw = rsp.getResponse();
Object doc = raw.get("doc");
@@ -450,10 +449,10 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
}
return result;
}
-
- /**
- * returns a random SolrClient -- either a CloudSolrClient, or an HttpSolrClient pointed
- * at a node in our cluster
+
+ /**
+ * returns a random SolrClient -- either a CloudSolrClient, or an HttpSolrClient pointed
+ * at a node in our cluster
*/
public static SolrClient getRandClient(Random rand) {
int numClients = CLIENTS.size();
@@ -461,14 +460,14 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
return (idx == numClients) ? CLOUD_CLIENT : CLIENTS.get(idx);
}
- /**
+ /**
* Abstraction for diff types of things that can be added to an 'fl' param that can validate
* the results are correct compared to an expected SolrInputDocument
*/
private interface FlValidator {
-
- /**
- * Given a list of FlValidators, adds one or more fl params that corrispond to the entire set,
+
+ /**
+ * Given a list of FlValidators, adds one or more fl params that corrispond to the entire set,
* as well as any other special case top level params required by the validators.
*/
public static void addParams(final Collection<FlValidator> validators, final ModifiableSolrParams params) {
@@ -481,10 +480,10 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
}
/**
- * Indicates if this validator is for a transformer that returns true from
- * {@link DocTransformer#needsSolrIndexSearcher}. Other validators for transformers that
- * do <em>not</em> require a re-opened searcher (but may have slightly diff behavior depending
- * on wether a doc comesfrom the index or from the update log) may use this information to
+ * Indicates if this validator is for a transformer that returns true from
+ * {@link DocTransformer#needsSolrIndexSearcher}. Other validators for transformers that
+ * do <em>not</em> require a re-opened searcher (but may have slightly diff behavior depending
+ * on wether a doc comesfrom the index or from the update log) may use this information to
* decide wether they wish to enforce stricter assertions on the resulting document.
*
* The default implementation always returns <code>false</code>
@@ -497,26 +496,26 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
/**
* the name of a transformer listed in {@link TransformerFactory#defaultFactories} that this validator
- * corrisponds to, or null if not applicable. Used for testing coverage of
+ * corrisponds to, or null if not applicable. Used for testing coverage of
* Solr's implicitly supported transformers.
*
* Default behavior is to return null
* @see #testCoverage
*/
public default String getDefaultTransformerFactoryName() { return null; }
-
+
/**
* Any special case params that must be added to the request for this validator
*/
public default SolrParams getExtraRequestParams() { return params(); }
-
- /**
- * Must return a non null String that can be used in an fl param -- either by itself,
+
+ /**
+ * Must return a non null String that can be used in an fl param -- either by itself,
* or with other items separated by commas
*/
public String getFlParam();
- /**
+ /**
* Given the expected document and the actual document returned from an RTG, this method
* should assert that relative to what {@link #getFlParam} returns, the actual document contained
* what it should relative to the expected document.
@@ -530,8 +529,8 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
final SolrInputDocument expected,
final SolrDocument actual);
}
-
- /**
+
+ /**
* Some validators behave in a way that "suppresses" real fields even when they would otherwise match a glob
* @see GlobValidator
*/
@@ -555,14 +554,14 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
return Collections.<String>singleton(actualFieldName);
}
}
-
+
private static class SimpleFieldValueValidator extends FieldValueValidator {
public SimpleFieldValueValidator(final String fieldName) {
super(fieldName, fieldName);
}
public String getFlParam() { return expectedFieldName; }
}
-
+
private static class RenameFieldValueValidator extends FieldValueValidator implements SuppressRealFields {
public RenameFieldValueValidator(final String origFieldName, final String alias) {
super(origFieldName, alias);
@@ -575,10 +574,10 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
* Validator for {@link RawValueTransformerFactory}
*
* This validator is fairly weak, because it doesn't do anything to verify the conditional logic
- * in RawValueTransformerFactory realted to the output format -- but that's out of the scope of
- * this randomized testing.
- *
- * What we're primarily concerned with is that the transformer does it's job and puts the string
+ * in RawValueTransformerFactory realted to the output format -- but that's out of the scope of
+ * this randomized testing.
+ *
+ * What we're primarily concerned with is that the transformer does it's job and puts the string
* in the response, regardless of cloud/RTG/uncommited state of the document.
*/
private static class RawFieldValueValidator extends RenameFieldValueValidator {
@@ -600,14 +599,14 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
return type;
}
}
-
-
- /**
- * enforces that a valid <code>[docid]</code> is present in the response, possibly using a
- * resultKey alias. By default the only validation of docId values is that they are an integer
- * greater than or equal to <code>-1</code> -- but if any other validator in use returns true
- * from {@link #requiresRealtimeSearcherReOpen} then the constraint is tightened and values must
- * be greater than or equal to <code>0</code>
+
+
+ /**
+ * enforces that a valid <code>[docid]</code> is present in the response, possibly using a
+ * resultKey alias. By default the only validation of docId values is that they are an integer
+ * greater than or equal to <code>-1</code> -- but if any other validator in use returns true
+ * from {@link #requiresRealtimeSearcherReOpen} then the constraint is tightened and values must
+ * be greater than or equal to <code>0</code>
*/
private static class DocIdValidator implements FlValidator {
private static final String NAME = "docid";
@@ -671,7 +670,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
private static class ValueAugmenterValidator implements FlValidator {
private static final String NAME = "value";
private static String trans(final int value) { return "[" + NAME + " v=" + value + " t=int]"; }
-
+
private final String resultKey;
private final String fl;
private final Integer expectedVal;
@@ -699,7 +698,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
}
}
-
+
/** Trivial validator of a ValueSourceAugmenter */
private static class FunctionValidator implements FlValidator {
private static String func(String fieldName) {
@@ -727,15 +726,15 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
final SolrDocument actual) {
final Object origVal = expected.getFieldValue(fieldName);
assertTrue("this validator only works on numeric fields: " + origVal, origVal instanceof Number);
-
+
assertEquals(fl, 1.3F, actual.getFirstValue(resultKey));
return Collections.<String>singleton(resultKey);
}
}
-
- /**
- * Trivial validator of a SubQueryAugmenter.
+
+ /**
+ * Trivial validator of a SubQueryAugmenter.
*
* This validator ignores 90% of the features/complexity
* of SubQueryAugmenter, and instead just focuses on the basics of:
@@ -747,11 +746,11 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
private static class SubQueryValidator implements FlValidator {
// HACK to work around SOLR-9396...
- //
+ //
// we're using "id" (and only "id") in the subquery.q as a workarround limitation in
// "$rows.foo" parsing -- it only works reliably if "foo" is in fl, so we only use "$rows.id",
// which we know is in every request (and is a valid integer)
-
+
public final static String NAME = "subquery";
public final static String SUBQ_KEY = "subq";
public final static String SUBQ_FIELD = "next_2_ids_i";
@@ -760,21 +759,21 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
final SolrInputDocument expected,
final SolrDocument actual) {
final int compVal = assertParseInt("expected id", expected.getFieldValue("id"));
-
+
final Object actualVal = actual.getFieldValue(SUBQ_KEY);
assertTrue("Expected a doclist: " + actualVal,
actualVal instanceof SolrDocumentList);
assertTrue("should be at most 2 docs in doc list: " + actualVal,
((SolrDocumentList) actualVal).getNumFound() <= 2);
-
+
for (SolrDocument subDoc : (SolrDocumentList) actualVal) {
final int subDocIdVal = assertParseInt("subquery id", subDoc.getFirstValue("id"));
assertTrue("subDocId="+subDocIdVal+" not in valid range for id="+compVal+" (expected "
+ (compVal-1) + " or " + (compVal-2) + ")",
((subDocIdVal < compVal) && ((compVal-2) <= subDocIdVal)));
-
+
}
-
+
return Collections.<String>singleton(SUBQ_KEY);
}
public String getDefaultTransformerFactoryName() { return NAME; }
@@ -783,18 +782,18 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
"{!field f=" + SubQueryValidator.SUBQ_FIELD + " v=$row.id}");
}
}
-
+
/** Trivial validator of a GeoTransformer */
private static class GeoTransformerValidator implements FlValidator, SuppressRealFields{
private static final String NAME = "geo";
- /**
+ /**
* we're not worried about testing the actual geo parsing/formatting of values,
* just that the transformer gets called with the expected field value.
* so have a small set of fixed input values we use when indexing docs,
* and the expected output for each
*/
private static final Map<String,String> VALUES = new HashMap<>();
- /**
+ /**
* The set of legal field values this validator is willing to test as a list so we can
* reliably index into it with random ints
*/
@@ -805,7 +804,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
}
ALLOWED_FIELD_VALUES = Collections.unmodifiableList(new ArrayList<>(VALUES.keySet()));
}
- /**
+ /**
* returns a random field value usable when indexing a document that this validator will
* be able to handle.
*/
@@ -837,19 +836,19 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
final SolrDocument actual) {
final Object origVal = expected.getFieldValue(fieldName);
assertTrue(fl + ": orig field value is not supported: " + origVal, VALUES.containsKey(origVal));
-
+
assertEquals(fl, VALUES.get(origVal), actual.getFirstValue(resultKey));
return Collections.<String>singleton(resultKey);
}
public Set<String> getSuppressedFields() { return Collections.singleton(fieldName); }
}
- /**
+ /**
* Glob based validator.
- * This class checks that every field in the expected doc exists in the actual doc with the expected
+ * This class checks that every field in the expected doc exists in the actual doc with the expected
* value -- with special exceptions for fields that are "suppressed" (usually via an alias)
*
- * By design, fields that are aliased are "moved" unless the original field name was explicitly included
+ * By design, fields that are aliased are "moved" unless the original field name was explicitly included
* in the fl, globs don't count.
*
* @see RenameFieldValueValidator
@@ -860,9 +859,9 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
this.glob = glob;
}
private final Set<String> matchingFieldsCache = new LinkedHashSet<>();
-
+
public String getFlParam() { return glob; }
-
+
private boolean matchesGlob(final String fieldName) {
if ( FilenameUtils.wildcardMatch(fieldName, glob) ) {
matchingFieldsCache.add(fieldName); // Don't calculate it again
@@ -870,7 +869,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
}
return false;
}
-
+
public Collection<String> assertRTGResults(final Collection<FlValidator> validators,
final SolrInputDocument expected,
final SolrDocument actual) {
@@ -881,7 +880,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
renamed.addAll(((SuppressRealFields)v).getSuppressedFields());
}
}
-
+
// every real field name matching the glob that is not renamed should be in the results
Set<String> result = new LinkedHashSet<>(expected.getFieldNames().size());
for (String f : expected.getFieldNames()) {
@@ -893,8 +892,8 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
return result;
}
}
-
- /**
+
+ /**
* for things like "score" and "[explain]" where we explicitly expect what we ask for in the fl
* to <b>not</b> be returned when using RTG.
*/
@@ -939,7 +938,7 @@ public class TestRandomFlRTGCloud extends SolrCloudTestCase {
}
/**
- * Given an ordered list of values to include in a (key) param, randomly groups them (ie: comma separated)
+ * Given an ordered list of values to include in a (key) param, randomly groups them (ie: comma separated)
* into actual param key=values which are returned as a new SolrParams instance
*/
private static SolrParams buildCommaSepParams(final Random rand, final String key, Collection<String> values) {
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrIgnoredThreadsFilter.java b/solr/test-framework/src/java/org/apache/solr/SolrIgnoredThreadsFilter.java
index 56555cb..ae676c6 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrIgnoredThreadsFilter.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrIgnoredThreadsFilter.java
@@ -56,6 +56,11 @@ public class SolrIgnoredThreadsFilter implements ThreadFilter {
if (threadName.startsWith("NIOWorkerThread-")) {
return true;
}
+ // can leak briefly in TERMINATED state
+ if (threadName.startsWith("JettyHttpClientScheduler")) {
+ return true;
+ }
+
if (threadName.startsWith("SessionTracker") || threadName.startsWith("ProcessThread")) { // zk thread that will stop in a moment.