mirror of https://github.com/mongodb/mongo
178 lines
7.0 KiB
JavaScript
178 lines
7.0 KiB
JavaScript
// Tests representative query shapes and hashes of change stream pipelines.
|
|
// @tags: [
|
|
// requires_fcv80,
|
|
// uses_change_streams,
|
|
// change_stream_does_not_expect_txns,
|
|
// directly_against_shardsvrs_incompatible,
|
|
// does_not_support_stepdowns,
|
|
// assumes_against_mongod_not_mongos,
|
|
// ]
|
|
//
|
|
import {assertDropAndRecreateCollection} from "jstests/libs/collection_drop_recreate.js";
|
|
import {QuerySettingsUtils} from "jstests/libs/query/query_settings_utils.js";
|
|
|
|
const coll = assertDropAndRecreateCollection(db, jsTestName());
|
|
const qsutils = new QuerySettingsUtils(db, coll.getName());
|
|
|
|
// Verifies that the querySettings for 'query' can be applied successfully, and that the query shape
|
|
// hash of the query is identical to 'queryShapeHash'. Also verifies that the representative query
|
|
// shape of the query is identical to 'query'.
|
|
function checkQueryShapeAndHash(db, query, queryShapeHash) {
|
|
qsutils.withQuerySettings(query, {reject: true}, () => {
|
|
const hashFromSettings = qsutils.getQueryShapeHashFromQuerySettings(query);
|
|
assert.eq(
|
|
queryShapeHash,
|
|
hashFromSettings,
|
|
`Expected query shape (hash) for input query ${tojsononeline(query)}: (${
|
|
queryShapeHash
|
|
}), got ${hashFromSettings}. Full configuration: ${tojson(
|
|
qsutils.getQuerySettings({showDebugQueryShape: true}),
|
|
)}`,
|
|
);
|
|
});
|
|
}
|
|
|
|
// A general caveat regarding query shapes and query shape hashes:
|
|
// Many fields in "document_source_change_stream.idl" are optional fields with default values.
|
|
// Those fields will only be serialized and thus affect the representative query shape and hash if
|
|
// they are explicitly set to a value. If not explicitly set, these fields will not be serialized
|
|
// and not be part of the representative query shape nor hash. This is great for keeping
|
|
// downwards-compatibility of query shapes and query shape hashes when adding new fields. As a
|
|
// downside, this means that for semantically equivalent queries we can get different query shapes
|
|
// and hashes. The following semantically equivalent queries serve as an example for this, but the
|
|
// same is true for all optional fields:
|
|
// {$changeStream: {}} => representative query: {$changeStream: {}}
|
|
// {$changeStream: {showSystemEvents: false}} => representative
|
|
// query: {$changeStream: {showSystemEvents: false}}
|
|
|
|
//
|
|
// Database-level change streams.
|
|
//
|
|
|
|
// Check shape and hash for a basic change stream pipeline.
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{aggregate: 1, pipeline: [{$changeStream: {}}], $db: db.getName()},
|
|
"ABD13DBF8CFAE39BF22941780FFCF8BB111582FB30C6CDC832933EA0E29F1C3D",
|
|
);
|
|
|
|
// Check shape and hash for pipelines with 'showSystemEvents' flag.
|
|
// Using this flag changes the query shape and hash, regardless of whether the flag is set to the
|
|
// implicit default value (false) or not.
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{aggregate: 1, pipeline: [{$changeStream: {showSystemEvents: true}}], $db: db.getName()},
|
|
"989509505CA0513EF576E1DA3C3D1319D8BCB6EF3A91E436C9A08FEA39AE428A",
|
|
);
|
|
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{aggregate: 1, pipeline: [{$changeStream: {showSystemEvents: false}}], $db: db.getName()},
|
|
"06F4F2FAD655A12343302BCCFD2702EEEA00A6D797D5EA0B1D89FC9396D20ADB",
|
|
);
|
|
|
|
// Check shape and hash for pipelines with 'showExpandedEvents' flag.
|
|
// Using this flag changes the query shape and hash, regardless of whether the flag is set to the
|
|
// implicit default value (false) or not.
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{aggregate: 1, pipeline: [{$changeStream: {showExpandedEvents: true}}], $db: db.getName()},
|
|
"8F93080A29997E20EE5C90B1DDF681DB8D0F3419531C00C9DE4843D80C7FEC3E",
|
|
);
|
|
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{aggregate: 1, pipeline: [{$changeStream: {showExpandedEvents: false}}], $db: db.getName()},
|
|
"29524DD77A583945DFBDAC1909346D6565B2BEF5A607F6D9AD040982C12DEFCA",
|
|
);
|
|
|
|
//
|
|
// Collection-level change streams.
|
|
//
|
|
|
|
// Check shape and hash for a basic change stream pipeline.
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{aggregate: coll.getName(), pipeline: [{$changeStream: {}}], $db: db.getName()},
|
|
"FF65C1F81BEB9C930D7C2A94661E1106F77C59809E0B1D7FB2AC3C6232D03A4C",
|
|
);
|
|
|
|
// Check shape and hash for pipelines with 'showSystemEvents' flag.
|
|
// Using this flag changes the query shape and hash, regardless of whether the flag is set to the
|
|
// implicit default value (false) or not.
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{
|
|
aggregate: coll.getName(),
|
|
pipeline: [{$changeStream: {showSystemEvents: true}}],
|
|
$db: db.getName(),
|
|
},
|
|
"DBE479E988FF18FA2DD5B2188A97A797BF1A6BD9571DD3CF3CEFAE4BDEF4E1D3",
|
|
);
|
|
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{
|
|
aggregate: coll.getName(),
|
|
pipeline: [{$changeStream: {showSystemEvents: false}}],
|
|
$db: db.getName(),
|
|
},
|
|
"AFD4BD81AC43C813818444EA835F951E1112E18D513F0BA255A867764A9ED48E",
|
|
);
|
|
|
|
// Check shape and hash for pipelines with 'showExpandedEvents' flag.
|
|
// Using this flag changes the query shape and hash, regardless of whether the flag is set to
|
|
// the implicit default value (false) or not.
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{
|
|
aggregate: coll.getName(),
|
|
pipeline: [{$changeStream: {showExpandedEvents: true}}],
|
|
$db: db.getName(),
|
|
},
|
|
"97744EC94700017030246635FDFD4481C177EF25D2CFE7335ABD7E570BDE273E",
|
|
);
|
|
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{
|
|
aggregate: coll.getName(),
|
|
pipeline: [{$changeStream: {showExpandedEvents: false}}],
|
|
$db: db.getName(),
|
|
},
|
|
"8BFCDD5DA40E82A947514CD30503795B72B3B61DD2F5455133F1D7120F9394B2",
|
|
);
|
|
|
|
// The following tests rely on fields that were added to the $changeStreams stage in v8.2, and for
|
|
// which query shape hash computation was changed in v8.3, so we only execute them if the FCV
|
|
// version is high enough.
|
|
const fcvDoc = db.adminCommand({getParameter: 1, featureCompatibilityVersion: 1});
|
|
if (MongoRunner.compareBinVersions(fcvDoc.featureCompatibilityVersion.version, "8.3") >= 0) {
|
|
// Check shape and hash when setting the change stream reader version.
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{aggregate: 1, pipeline: [{$changeStream: {version: "v1"}}], $db: db.getName()},
|
|
"ABD13DBF8CFAE39BF22941780FFCF8BB111582FB30C6CDC832933EA0E29F1C3D",
|
|
);
|
|
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{aggregate: 1, pipeline: [{$changeStream: {version: "v2"}}], $db: db.getName()},
|
|
"ABD13DBF8CFAE39BF22941780FFCF8BB111582FB30C6CDC832933EA0E29F1C3D",
|
|
);
|
|
|
|
// Check shape and hash when setting the 'supportedEvents' field.
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{aggregate: 1, pipeline: [{$changeStream: {supportedEvents: ["foo"]}}], $db: db.getName()},
|
|
"ABD13DBF8CFAE39BF22941780FFCF8BB111582FB30C6CDC832933EA0E29F1C3D",
|
|
);
|
|
|
|
// Check shape and hash for a change stream pipeline using the 'ignoreRemovedShards' flag.
|
|
checkQueryShapeAndHash(
|
|
db,
|
|
{aggregate: 1, pipeline: [{$changeStream: {ignoreRemovedShards: true}}], $db: db.getName()},
|
|
"796AFF268E3D2A16D9FFCD9F5929CB6C78D704560AC6F19A2BE40DC2B688200D",
|
|
);
|
|
}
|