summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/core/wildcard_and_text_indexes.js (renamed from jstests/noPassthroughWithMongod/wildcard_and_text_indexes.js)17
-rw-r--r--jstests/core/wildcard_index_basic_index_bounds.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_basic_index_bounds.js)27
-rw-r--r--jstests/core/wildcard_index_cached_plans.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_cached_plans.js)47
-rw-r--r--jstests/core/wildcard_index_collation.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_collation.js)27
-rw-r--r--jstests/core/wildcard_index_covered_queries.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_covered_queries.js)7
-rw-r--r--jstests/core/wildcard_index_empty_arrays.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_empty_arrays.js)0
-rw-r--r--jstests/core/wildcard_index_equality_to_empty_obj.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_equality_to_empty_obj.js)2
-rw-r--r--jstests/core/wildcard_index_filter.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_filter.js)7
-rw-r--r--jstests/core/wildcard_index_hint.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_hint.js)1
-rw-r--r--jstests/core/wildcard_index_minmax.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_minmax.js)7
-rw-r--r--jstests/core/wildcard_index_multikey.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_multikey.js)8
-rw-r--r--jstests/core/wildcard_index_nonblocking_sort.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_nonblocking_sort.js)5
-rw-r--r--jstests/core/wildcard_index_partial_index.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_partial_index.js)2
-rw-r--r--jstests/core/wildcard_index_return_key.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_return_key.js)1
-rw-r--r--jstests/core/wildcard_index_validindex.js (renamed from jstests/noPassthroughWithMongod/wildcard_index_validindex.js)1
-rw-r--r--jstests/libs/analyze_plan.js32
-rw-r--r--jstests/libs/parallelTester.js3
17 files changed, 119 insertions, 75 deletions
diff --git a/jstests/noPassthroughWithMongod/wildcard_and_text_indexes.js b/jstests/core/wildcard_and_text_indexes.js
index 945ef3502b7..4fd7ad34ac1 100644
--- a/jstests/noPassthroughWithMongod/wildcard_and_text_indexes.js
+++ b/jstests/core/wildcard_and_text_indexes.js
@@ -1,19 +1,12 @@
/**
* Tests that a {$**: 1} index can coexist with a {$**: 'text'} index in the same collection.
- *
- * Tagged as 'assumes_unsharded_collection' so that the expected relationship between the number of
- * IXSCANs in the explain output and the number of fields in the indexed documents is not distorted
- * by being spread across multiple shards.
- *
- * @tags: [assumes_unsharded_collection]
- *
- * TODO: SERVER-36198: Move this test back to jstests/core/
*/
(function() {
"use strict";
load("jstests/aggregation/extras/utils.js"); // For arrayEq.
load("jstests/libs/analyze_plan.js"); // For getPlanStages and planHasStage.
+ load("jstests/libs/fixture_helpers.js"); // For isMongos.
const assertArrayEq = (l, r) => assert(arrayEq(l, r), tojson(l) + " != " + tojson(r));
@@ -28,7 +21,7 @@
const explainOutput = coll.find(query).explain("executionStats");
const ixScans = getPlanStages(explainOutput.queryPlanner.winningPlan, "IXSCAN");
// Verify that the winning plan uses the $** index with the expected path.
- assert.eq(ixScans.length, 1);
+ assert.eq(ixScans.length, FixtureHelpers.numberOfShardsForCollection(coll));
assert.docEq(ixScans[0].keyPattern, {"$_path": 1, [expectedPath]: 1});
// Verify that the results obtained from the $** index are identical to a COLLSCAN.
assertArrayEq(coll.find(query).toArray(), coll.find(query).hint({$natural: 1}).toArray());
@@ -57,7 +50,7 @@
const textQuery = Object.assign(textIndex.a ? {a: 1} : {}, {$text: {$search: 'banana'}});
let explainOut = assert.commandWorked(coll.find(textQuery).explain("executionStats"));
assert(planHasStage(coll.getDB(), explainOut.queryPlanner.winningPlan, "TEXT"));
- assert.eq(explainOut.queryPlanner.rejectedPlans.length, 0);
+ assert.eq(getRejectedPlans(explainOut).length, 0);
assert.eq(explainOut.executionStats.nReturned, 2);
// Confirm that $** does not generate a candidate plan for $text search, including cases
@@ -66,13 +59,13 @@
assert.commandWorked(coll.find(Object.assign({_fts: {$gt: 0, $lt: 4}}, textQuery))
.explain("executionStats"));
assert(planHasStage(coll.getDB(), explainOut.queryPlanner.winningPlan, "TEXT"));
- assert.eq(explainOut.queryPlanner.rejectedPlans.length, 0);
+ assert.eq(getRejectedPlans(explainOut).length, 0);
assert.eq(explainOut.executionStats.nReturned, 2);
// Confirm that the $** index can be used alongside a $text predicate in an $or.
explainOut = assert.commandWorked(
coll.find({$or: [{_fts: 3}, textQuery]}).explain("executionStats"));
- assert.eq(explainOut.queryPlanner.rejectedPlans.length, 0);
+ assert.eq(getRejectedPlans(explainOut).length, 0);
assert.eq(explainOut.executionStats.nReturned, 3);
const textOrWildcard = getPlanStages(explainOut.queryPlanner.winningPlan, "OR").shift();
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_basic_index_bounds.js b/jstests/core/wildcard_index_basic_index_bounds.js
index 776c9d9fc50..5f1b3ec07a2 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_basic_index_bounds.js
+++ b/jstests/core/wildcard_index_basic_index_bounds.js
@@ -1,19 +1,17 @@
/**
* Tests basic index bounds generation and planning for $** indexes.
*
- * Tagged as 'assumes_unsharded_collection' so that the expected relationship between the number of
- * IXSCANs in the explain output and the number of fields in the indexed documents is not distorted
- * by being spread across multiple shards.
+ * Does not support stepdowns because the test issues getMores, which the stepdown/kill_primary
+ * passthroughs will reject.
*
- * @tags: [assumes_unsharded_collection]
- *
- * TODO: SERVER-36198: Move this test back to jstests/core/
+ * @tags: [does_not_support_stepdowns]
*/
(function() {
"use strict";
load("jstests/aggregation/extras/utils.js"); // For arrayEq.
load("jstests/libs/analyze_plan.js"); // For getPlanStages.
+ load("jstests/libs/fixture_helpers.js"); // For isMongos and numberOfShardsForCollection.
const assertArrayEq = (l, r) => assert(arrayEq(l, r));
@@ -126,7 +124,7 @@
}
// Verify that the winning plan uses the $** index with the expected bounds.
- assert.eq(ixScans.length, 1);
+ assert.eq(ixScans.length, FixtureHelpers.numberOfShardsForCollection(coll));
assert.docEq(ixScans[0].keyPattern, {$_path: 1, [path]: 1});
assert.docEq(ixScans[0].indexBounds, expectedBounds);
@@ -152,7 +150,13 @@
// We should find that each branch of the $or has used a separate $** sub-index.
const ixScanBounds = [];
ixScans.forEach((ixScan) => ixScanBounds.push(ixScan.indexBounds));
- assertArrayEq(ixScanBounds, orQueryBounds);
+ // In the sharded passthroughs, we expect to have 'orQueryBounds' on each shard.
+ const numShards = FixtureHelpers.numberOfShardsForCollection(coll);
+ let orQueryBoundsShards = [];
+ for (let i = 0; i < numShards; ++i) {
+ orQueryBoundsShards = orQueryBoundsShards.concat(orQueryBounds);
+ }
+ assertArrayEq(ixScanBounds, orQueryBoundsShards);
// Verify that the results obtained from the $** index are identical to a COLLSCAN.
assertArrayEq(coll.find({$or: multiFieldPreds}).toArray(),
@@ -167,8 +171,9 @@
// candidate that wasn't the winner. Before SERVER-36521 banned them for $** indexes, a
// number of AND_SORTED plans would also be generated here; we search for these in order
// to verify that no such plans now exist.
+ const rejectedPlans = getRejectedPlans(explainOutput);
let rejectedIxScans = [], rejectedAndSorted = [];
- for (let rejectedPlan of explainOutput.queryPlanner.rejectedPlans) {
+ for (let rejectedPlan of rejectedPlans) {
rejectedAndSorted =
rejectedAndSorted.concat(getPlanStages(rejectedPlan, "AND_SORTED"));
rejectedIxScans = rejectedIxScans.concat(getPlanStages(rejectedPlan, "IXSCAN"));
@@ -179,8 +184,8 @@
// We should find that one of the available $** subindexes has been chosen as the
// winner, and all other candidate $** indexes are present in 'rejectedPlans'.
- assert.eq(winningIxScan.length, 1);
- assert.eq(rejectedIxScans.length, expectedPaths.length - 1);
+ assert.eq(winningIxScan.length, numShards);
+ assert.eq(rejectedIxScans.length, numShards * (expectedPaths.length - 1));
// Verify that each of the IXSCANs have the expected bounds and $_path key.
for (let ixScan of winningIxScan.concat(rejectedIxScans)) {
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_cached_plans.js b/jstests/core/wildcard_index_cached_plans.js
index 704ce77cd7e..f1394273f13 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_cached_plans.js
+++ b/jstests/core/wildcard_index_cached_plans.js
@@ -1,14 +1,22 @@
/**
* Test that cached plans which use wildcard indexes work.
- * TODO: SERVER-36198: Move this test back to jstests/core/
+ *
+ * This test attempts to perform queries and introspect the server's plan cache entries using the
+ * $planCacheStats aggregation source. Both operations must be routed to the primary, and the latter
+ * only supports 'local' readConcern.
+ * @tags: [assumes_read_preference_unchanged, assumes_read_concern_unchanged,
+ * does_not_support_stepdowns]
*/
(function() {
"use strict";
- load('jstests/libs/analyze_plan.js'); // For getPlanStage().
+ load('jstests/libs/analyze_plan.js'); // For getPlanStage().
+ load("jstests/libs/collection_drop_recreate.js"); // For assert[Drop|Create]Collection.
+ load('jstests/libs/fixture_helpers.js'); // For getPrimaryForNodeHostingDatabase and isMongos.
const coll = db.wildcard_cached_plans;
coll.drop();
+
assert.commandWorked(coll.createIndex({"b.$**": 1}));
assert.commandWorked(coll.createIndex({"a": 1}));
@@ -22,7 +30,9 @@
function getCacheEntryForQuery(query) {
const aggRes =
- coll.aggregate([
+ FixtureHelpers.getPrimaryForNodeHostingDatabase(db)
+ .getCollection(coll.getFullName())
+ .aggregate([
{$planCacheStats: {}},
{$match: {createdFromQuery: {query: query, sort: {}, projection: {}}}}
])
@@ -34,13 +44,18 @@
return null;
}
- function getQueryHash(query) {
- const explainRes = assert.commandWorked(coll.explain().find(query).finish());
- const hash = explainRes.queryPlanner.queryHash;
+ function getQueryHashFromExplain(explainRes) {
+ const hash = FixtureHelpers.isMongos(db)
+ ? explainRes.queryPlanner.winningPlan.shards[0].queryHash
+ : explainRes.queryPlanner.queryHash;
assert.eq(typeof(hash), "string");
return hash;
}
+ function getQueryHash(query) {
+ return getQueryHashFromExplain(assert.commandWorked(coll.explain().find(query).finish()));
+ }
+
const query = {a: 1, b: 1};
// The plan cache should be empty.
@@ -81,9 +96,8 @@
// Check that indexability discriminators work with collations.
(function() {
// Create wildcard index with a collation.
- assert.eq(coll.drop(), true);
- assert.commandWorked(
- db.createCollection(coll.getName(), {collation: {locale: "en_US", strength: 1}}));
+ assertDropAndRecreateCollection(
+ db, coll.getName(), {collation: {locale: "en_US", strength: 1}});
assert.commandWorked(coll.createIndex({"b.$**": 1}));
// Run a query which uses a different collation from that of the index, but does not use
@@ -91,7 +105,7 @@
const queryWithoutStringExplain =
coll.explain().find({a: 5, b: 5}).collation({locale: "fr"}).finish();
let ixScans = getPlanStages(queryWithoutStringExplain.queryPlanner.winningPlan, "IXSCAN");
- assert.eq(ixScans.length, 1);
+ assert.eq(ixScans.length, FixtureHelpers.numberOfShardsForCollection(coll));
assert.eq(ixScans[0].keyPattern, {$_path: 1, b: 1});
// Run a query which uses a different collation from that of the index and does have string
@@ -103,21 +117,20 @@
// Check that the shapes are different since the query which matches on a string will not
// be eligible to use the b.$** index (since the index has a different collation).
- assert.neq(queryWithoutStringExplain.queryPlanner.queryHash,
- queryWithStringExplain.queryPlanner.queryHash);
+ assert.neq(getQueryHashFromExplain(queryWithoutStringExplain),
+ getQueryHashFromExplain(queryWithStringExplain));
})();
// Check that indexability discriminators work with partial wildcard indexes.
(function() {
- assert.eq(coll.drop(), true);
- assert.commandWorked(db.createCollection(coll.getName()));
+ assertDropAndRecreateCollection(db, coll.getName());
assert.commandWorked(
coll.createIndex({"$**": 1}, {partialFilterExpression: {a: {$lte: 5}}}));
// Run a query for a value included by the partial filter expression.
const queryIndexedExplain = coll.find({a: 4}).explain();
let ixScans = getPlanStages(queryIndexedExplain.queryPlanner.winningPlan, "IXSCAN");
- assert.eq(ixScans.length, 1);
+ assert.eq(ixScans.length, FixtureHelpers.numberOfShardsForCollection(coll));
assert.eq(ixScans[0].keyPattern, {$_path: 1, a: 1});
// Run a query which tries to get a value not included by the partial filter expression.
@@ -127,7 +140,7 @@
// Check that the shapes are different since the query which searches for a value not
// included by the partial filter expression won't be eligible to use the $** index.
- assert.neq(queryIndexedExplain.queryPlanner.queryHash,
- queryUnindexedExplain.queryPlanner.queryHash);
+ assert.neq(getQueryHashFromExplain(queryIndexedExplain),
+ getQueryHashFromExplain(queryUnindexedExplain));
})();
})();
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_collation.js b/jstests/core/wildcard_index_collation.js
index 6f31c12bafb..5e71100c7c2 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_collation.js
+++ b/jstests/core/wildcard_index_collation.js
@@ -2,22 +2,31 @@
* Test that $** indexes obey collation rules for document values, while the virtual $_path
* components stored alongside these values in the index always use simple binary comparison.
*
- * TODO: SERVER-36198: Move this test back into jstests/core/collation.js
+ * The tags below are necessary because collation requires that we use read/write commands rather
+ * than legacy operations. We also require that collections are unsharded, since we perform queries
+ * which we expect to be covered.
+ * @tags: [assumes_unsharded_collection, requires_find_command, requires_non_retryable_commands,
+ * requires_non_retryable_writes]
*/
(function() {
"user strict";
- load("jstests/aggregation/extras/utils.js"); // For arrayEq.
- load("jstests/libs/analyze_plan.js"); // For getPlanStages.
- load("jstests/libs/get_index_helpers.js"); // For GetIndexHelpers.
+ load("jstests/aggregation/extras/utils.js"); // For arrayEq.
+ load("jstests/libs/analyze_plan.js"); // For getPlanStages.
+ load("jstests/libs/get_index_helpers.js"); // For GetIndexHelpers.
+ load("jstests/libs/collection_drop_recreate.js"); // For assert[Drop|Create]Collection.
+ load("jstests/libs/fixture_helpers.js"); // For isMongos.
const assertArrayEq = (l, r) => assert(arrayEq(l, r));
- const coll = db.wildcard_collation;
- coll.drop();
+ // Create the collection and assign it a default case-insensitive collation.
+ const coll = assertDropAndRecreateCollection(
+ db, "wildcard_collation", {collation: {locale: "en_US", strength: 1}});
// Extracts the winning plan for the given query and projection from the explain output.
- const winningPlan = (query, proj) => coll.find(query, proj).explain().queryPlanner.winningPlan;
+ const winningPlan = (query, proj) => FixtureHelpers.isMongos(db)
+ ? coll.find(query, proj).explain().queryPlanner.winningPlan.shards[0].winningPlan
+ : coll.find(query, proj).explain().queryPlanner.winningPlan;
// Runs the given query and confirms that: (1) the $** was used to answer the query, (2) the
// results produced by the $** index match the given 'expectedResults', and (3) the same output
@@ -49,10 +58,6 @@
tojson(collation) + " not found: " + tojson(indexSpecs));
}
- // Recreate the collection with a default case-insensitive collation.
- assert.commandWorked(
- db.createCollection(coll.getName(), {collation: {locale: "en_US", strength: 1}}));
-
// Confirm that the $** index inherits the collection's default collation.
assert.commandWorked(coll.createIndex({"$**": 1}));
assertIndexHasCollation({"$**": 1}, {
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_covered_queries.js b/jstests/core/wildcard_index_covered_queries.js
index b70a0d1e5a3..df6142e859e 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_covered_queries.js
+++ b/jstests/core/wildcard_index_covered_queries.js
@@ -2,11 +2,10 @@
* Test that $** indexes can provide a covered solution, given an appropriate query and projection.
*
* Cannot implicitly shard accessed collections, because queries on a sharded collection cannot be
- * covered unless they include the shard key.
+ * covered unless they include the shard key. Does not support stepdowns because the test issues
+ * getMores, which the stepdown/kill_primary passthroughs will reject.
*
- * @tags: [assumes_unsharded_collection]
- *
- * TODO: SERVER-36198: Move this test back to jstests/core/
+ * @tags: [assumes_unsharded_collection, does_not_support_stepdowns]
*/
(function() {
"use strict";
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_empty_arrays.js b/jstests/core/wildcard_index_empty_arrays.js
index 7b5e763bbad..7b5e763bbad 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_empty_arrays.js
+++ b/jstests/core/wildcard_index_empty_arrays.js
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_equality_to_empty_obj.js b/jstests/core/wildcard_index_equality_to_empty_obj.js
index 10e1b1186ce..28e99534147 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_equality_to_empty_obj.js
+++ b/jstests/core/wildcard_index_equality_to_empty_obj.js
@@ -1,7 +1,5 @@
/**
* Tests that a $** index can support queries which test for equality to empty nested objects.
- *
- * TODO: SERVER-36198: Move this test back to jstests/core/
*/
(function() {
"use strict";
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_filter.js b/jstests/core/wildcard_index_filter.js
index f8dd7182267..74c81edf462 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_filter.js
+++ b/jstests/core/wildcard_index_filter.js
@@ -1,5 +1,9 @@
/**
* Test that $** indexes obey index filter rules.
+ *
+ * Does not support stepdowns, because the stepdown/kill_primary passthroughs will reject commands
+ * that may return different values after a failover; in this case, 'planCacheClearFilters'.
+ * @tags: [does_not_support_stepdowns]
*/
(function() {
"use strict";
@@ -39,7 +43,8 @@
coll.explain("executionStats").find(query).hint(hint).finish());
}
- let planStage = getPlanStage(explain.executionStats.executionStages, 'IXSCAN');
+ const executionStages = getExecutionStages(explain).shift();
+ let planStage = getPlanStage(executionStages, 'IXSCAN');
assert.neq(null, planStage);
assert.eq(planStage.indexName, expectedIndexName, tojson(planStage));
}
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_hint.js b/jstests/core/wildcard_index_hint.js
index 9f88e248c3d..64fc61880d4 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_hint.js
+++ b/jstests/core/wildcard_index_hint.js
@@ -1,6 +1,5 @@
/**
* Tests that $** indexes obey hinting.
- * TODO: SERVER-36198: Move this test back to jstests/core/
*/
(function() {
"use strict";
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_minmax.js b/jstests/core/wildcard_index_minmax.js
index 85b4eca86d0..14fbbaea42e 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_minmax.js
+++ b/jstests/core/wildcard_index_minmax.js
@@ -11,13 +11,14 @@
const assertArrayEq = (l, r) => assert(arrayEq(l, r), tojson(l) + " != " + tojson(r));
- assert.commandWorked(coll.createIndex({"$**": 1}));
-
assert.commandWorked(coll.insert({a: 1, b: 1}));
assert.commandWorked(coll.insert({a: 1, b: 2}));
assert.commandWorked(coll.insert({a: 2, b: 1}));
assert.commandWorked(coll.insert({a: 2, b: 2}));
+ assert.commandWorked(coll.createIndex({"$**": 1}));
+ assert.commandWorked(coll.createIndex({"a": 1}));
+
// Throws error for $** index min.
assert.commandFailedWithCode(
db.runCommand({find: coll.getName(), min: {"a": 0.5}, hint: {"$**": 1}}),
@@ -73,8 +74,6 @@
}),
ErrorCodes.BadValue);
- assert.commandWorked(coll.createIndex({"a": 1}));
-
// $** index does not interfere with valid min/max.
assertArrayEq(coll.find({}, {_id: 0}).min({"a": 0.5}).max({"a": 1.5}).toArray(),
[{a: 1, b: 1}, {a: 1, b: 2}]);
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_multikey.js b/jstests/core/wildcard_index_multikey.js
index d0887e810c9..93e9492d6de 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_multikey.js
+++ b/jstests/core/wildcard_index_multikey.js
@@ -1,7 +1,5 @@
/**
* Tests that queries using a multikey $** index, return correct results.
- *
- * TODO: SERVER-36198: Move this test back to jstests/core/.
*/
(function() {
"use strict";
@@ -81,15 +79,15 @@
function assertWildcardQuery(query, expectedPath, explainStats = {}) {
// Explain the query, and determine whether an indexed solution is available.
const explainOutput = coll.find(query).explain("executionStats");
- const ixScans = getPlanStages(explainOutput.queryPlanner.winningPlan, "IXSCAN");
// If we expect the current path to have been excluded based on the $** keyPattern
// or projection, confirm that no indexed solution was found.
if (!expectedPath) {
- assert.eq(ixScans.length, 0);
+ assert.gt(getPlanStages(explainOutput.queryPlanner.winningPlan, "COLLSCAN").length, 0);
return;
}
// Verify that the winning plan uses the $** index with the expected path.
- assert.eq(ixScans.length, 1);
+ const ixScans = getPlanStages(explainOutput.queryPlanner.winningPlan, "IXSCAN");
+ assert.eq(ixScans.length, FixtureHelpers.numberOfShardsForCollection(coll));
assert.docEq(ixScans[0].keyPattern, {"$_path": 1, [expectedPath]: 1});
// Verify that the results obtained from the $** index are identical to a COLLSCAN.
assertArrayEq(coll.find(query).toArray(), coll.find(query).hint({$natural: 1}).toArray());
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_nonblocking_sort.js b/jstests/core/wildcard_index_nonblocking_sort.js
index 09aaba0fd90..f27fdda6f0e 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_nonblocking_sort.js
+++ b/jstests/core/wildcard_index_nonblocking_sort.js
@@ -3,6 +3,7 @@
load("jstests/aggregation/extras/utils.js"); // For arrayEq().
load("jstests/libs/analyze_plan.js"); // For getPlanStages().
+ load("jstests/libs/fixture_helpers.js"); // For numberOfShardsForCollection().
const coll = db.wildcard_nonblocking_sort;
@@ -26,14 +27,14 @@
const sorts = getPlanStages(plan, "SORT");
if (isBlocking) {
- assert.eq(sorts.length, 1);
+ assert.eq(sorts.length, FixtureHelpers.numberOfShardsForCollection(coll));
assert.eq(sorts[0].sortPattern, sort);
// A blocking sort may or may not use the index, so we don't check the length of
// 'ixScans'.
} else {
assert.eq(sorts.length, 0);
- assert.eq(ixScans.length, 1);
+ assert.eq(ixScans.length, FixtureHelpers.numberOfShardsForCollection(coll));
const sortKey = Object.keys(sort)[0];
assert.docEq(ixScans[0].keyPattern, {$_path: 1, [sortKey]: 1});
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_partial_index.js b/jstests/core/wildcard_index_partial_index.js
index fe809c6030b..5961caea87a 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_partial_index.js
+++ b/jstests/core/wildcard_index_partial_index.js
@@ -1,7 +1,5 @@
/**
* Test that $** indexes work when provided with a partial filter expression.
- *
- * TODO: SERVER-36198: Move this test back to jstests/core/
*/
(function() {
"use strict";
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_return_key.js b/jstests/core/wildcard_index_return_key.js
index 7f8ed54e741..ceaf691aad8 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_return_key.js
+++ b/jstests/core/wildcard_index_return_key.js
@@ -1,6 +1,5 @@
/**
* Tests that $** indexes works with returnKey option.
- * TODO: SERVER-36198: Move this test back to jstests/core/
*/
(function() {
'use strict';
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_validindex.js b/jstests/core/wildcard_index_validindex.js
index 6759a900762..647986f55b4 100644
--- a/jstests/noPassthroughWithMongod/wildcard_index_validindex.js
+++ b/jstests/core/wildcard_index_validindex.js
@@ -4,7 +4,6 @@
* # Uses index building in background
* requires_background_index,
* ]
- * TODO: SERVER-36198: Move this test back to jstests/core/
*/
(function() {
"use strict";
diff --git a/jstests/libs/analyze_plan.js b/jstests/libs/analyze_plan.js
index 29244576ab4..8104cf1f8c9 100644
--- a/jstests/libs/analyze_plan.js
+++ b/jstests/libs/analyze_plan.js
@@ -58,6 +58,22 @@ function getPlanStage(root, stage) {
}
/**
+ * Returns the set of rejected plans from the given replset or sharded explain output.
+ */
+function getRejectedPlans(root) {
+ if (root.queryPlanner.winningPlan.hasOwnProperty("shards")) {
+ const rejectedPlans = [];
+ for (let shard of root.queryPlanner.winningPlan.shards) {
+ for (let rejectedPlan of shard.rejectedPlans) {
+ rejectedPlans.push(Object.assign({shardName: shard.shardName}, rejectedPlan));
+ }
+ }
+ return rejectedPlans;
+ }
+ return root.queryPlanner.rejectedPlans;
+}
+
+/**
* Given the root stage of explain's JSON representation of a query plan ('root'), returns true if
* the query planner reports at least one rejected alternative plan, and false otherwise.
*/
@@ -100,6 +116,22 @@ function hasRejectedPlans(root) {
}
/**
+ * Returns an array of execution stages from the given replset or sharded explain output.
+ */
+function getExecutionStages(root) {
+ if (root.executionStats.executionStages.hasOwnProperty("shards")) {
+ const executionStages = [];
+ for (let shard of root.executionStats.executionStages.shards) {
+ executionStages.push(Object.assign(
+ {shardName: shard.shardName, executionSuccess: shard.executionSuccess},
+ shard.executionStages));
+ }
+ return executionStages;
+ }
+ return [root.executionStats.executionStages];
+}
+
+/**
* Given the root stage of agg explain's JSON representation of a query plan ('root'), returns all
* subdocuments whose stage is 'stage'. This can either be an agg stage name like "$cursor" or
* "$sort", or a query stage name like "IXSCAN" or "SORT".
diff --git a/jstests/libs/parallelTester.js b/jstests/libs/parallelTester.js
index cc2a9d06bd7..f318eaa670a 100644
--- a/jstests/libs/parallelTester.js
+++ b/jstests/libs/parallelTester.js
@@ -215,7 +215,8 @@ if (typeof _threadInject != "undefined") {
"views/views_aggregation.js",
"views/views_change.js",
"views/views_drop.js",
- "views/views_find.js"
+ "views/views_find.js",
+ "wildcard_index_collation.js"
];
Object.assign(skipTests, makeKeys(requires_find_command));
}