diff options
author | Bernard Gorman <bernard.gorman@gmail.com> | 2018-10-06 11:28:49 +0100 |
---|---|---|
committer | Bernard Gorman <bernard.gorman@gmail.com> | 2018-10-10 16:03:27 +0100 |
commit | 1b51df8420ef3c57afb2d753d7188814e90eee51 (patch) | |
tree | cdb3247e7ea95521c5b4ac1330341a13b9713622 /jstests | |
parent | 549616025c9d471767bc7ede342a9919cb3e6f94 (diff) | |
download | mongo-1b51df8420ef3c57afb2d753d7188814e90eee51.tar.gz |
SERVER-31698 Move wildcard_index integration tests to /core/
Diffstat (limited to 'jstests')
-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.js | 32 | ||||
-rw-r--r-- | jstests/libs/parallelTester.js | 3 |
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)); } |