diff options
Diffstat (limited to 'src/mongo/db/query/query_shape/query_shape_test.cpp')
| -rw-r--r-- | src/mongo/db/query/query_shape/query_shape_test.cpp | 767 |
1 files changed, 0 insertions, 767 deletions
diff --git a/src/mongo/db/query/query_shape/query_shape_test.cpp b/src/mongo/db/query/query_shape/query_shape_test.cpp deleted file mode 100644 index d6185b5c5cb..00000000000 --- a/src/mongo/db/query/query_shape/query_shape_test.cpp +++ /dev/null @@ -1,767 +0,0 @@ -/** - * Copyright (C) 2023-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/bson/bsonmisc.h" -#include "mongo/bson/bsonobj.h" -#include "mongo/db/matcher/expression_geo.h" -#include "mongo/db/matcher/extensions_callback_real.h" -#include "mongo/db/matcher/parsed_match_expression_for_test.h" -#include "mongo/db/namespace_string.h" -#include "mongo/db/pipeline/expression_context_for_test.h" -#include "mongo/db/query/query_shape/query_shape.h" -#include "mongo/db/query/query_shape/query_shape_test_gen.h" -#include "mongo/db/query/query_shape/serialization_options.h" -#include "mongo/db/query/query_shape/shape_helpers.h" -#include "mongo/db/service_context_test_fixture.h" -#include "mongo/unittest/bson_test_util.h" -#include "mongo/unittest/unittest.h" - -namespace mongo::query_shape { - -namespace { -BSONObj predicateShape(const MatchExpression* expr) { - return expr->serialize(SerializationOptions::kDebugQueryShapeSerializeOptions); -} -BSONObj predicateShape(std::string filterJson) { - return predicateShape(ParsedMatchExpressionForTest(filterJson).get()); -} - -BSONObj predicateShapeRedacted(const MatchExpression* expr) { - return expr->serialize(SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST); -} -BSONObj predicateShapeRedacted(std::string filterJson) { - return predicateShapeRedacted(ParsedMatchExpressionForTest(filterJson).get()); -} - -// TODO SERVER-87736 There is no 'auto' here, make that more clear. -#define ASSERT_SHAPE_EQ_AUTO(expected, actual) \ - ASSERT_BSONOBJ_EQ_AUTO(expected, predicateShape(actual)) - -#define ASSERT_REDACTED_SHAPE_EQ_AUTO(expected, actual) \ - ASSERT_BSONOBJ_EQ_AUTO(expected, predicateShapeRedacted(actual)) - - -TEST(QueryPredicateShape, Equals) { - ASSERT_SHAPE_EQ_AUTO( // Implicit equals - R"({"a":{"$eq":"?number"}})", - "{a: 5}"); - ASSERT_SHAPE_EQ_AUTO( // Explicit equals - R"({"a":{"$eq":"?number"}})", - "{a: {$eq: 5}}"); - ASSERT_SHAPE_EQ_AUTO( // implicit $and - R"({"$and":[{"a":{"$eq":"?number"}},{"b":{"$eq":"?number"}}]})", - "{a: 5, b: 6}"); - ASSERT_REDACTED_SHAPE_EQ_AUTO( // Implicit equals - R"({"HASH<a>":{"$eq":"?number"}})", - "{a: 5}"); - ASSERT_REDACTED_SHAPE_EQ_AUTO( // Explicit equals - R"({"HASH<a>":{"$eq":"?number"}})", - "{a: {$eq: 5}}"); - ASSERT_REDACTED_SHAPE_EQ_AUTO( // NOLINT - R"({"$and":[{"HASH<a>":{"$eq":"?number"}},{"HASH<b>":{"$eq":"?number"}}]})", - "{a: 5, b: 6}"); - ASSERT_REDACTED_SHAPE_EQ_AUTO( // NOLINT - R"({"HASH<foo>.HASH<$bar>":{"$eq":"?number"}})", - R"({"foo.$bar":0})"); -} - -TEST(QueryPredicateShape, ArraySubTypes) { - ASSERT_SHAPE_EQ_AUTO( // NOLINT - "{a: {$eq: '[]'}}", - "{a: []}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - "{a: {$eq: '?array<?number>'}}", - "{a: [2]}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$eq":"?array<?number>"}})", - "{a: [2, 3]}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$eq":"?array<?object>"}})", - "{a: [{}]}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$eq":"?array<?object>"}})", - "{a: [{}, {}]}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$eq":"?array<?array>"}})", - "{a: [[], [], []]}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$eq":"?array<?array>"}})", - "{a: [[2, 3], ['string'], []]}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$eq":"?array<>"}})", - "{a: [{}, 2]}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$eq":"?array<>"}})", - "{a: [[], 2]}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$eq":"?array<>"}})", - "{a: [[{}, 'string'], 2]}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$eq":"?array<>"}})", - "{a: [[{}, 'string'], 2]}"); -} - -TEST(QueryPredicateShape, Comparisons) { - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({ - "$and": [ - { - "a": { - "$lt": "?number" - } - }, - { - "b": { - "$gt": "?number" - } - }, - { - "c": { - "$gte": "?number" - } - }, - { - "c": { - "$lte": "?number" - } - } - ] - })", - "{a: {$lt: 5}, b: {$gt: 6}, c: {$gte: 3, $lte: 10}}"); -} - -namespace { -void assertShapeIs(std::string filterJson, BSONObj expectedShape) { - ASSERT_BSONOBJ_EQ(expectedShape, predicateShape(filterJson)); -} - -void assertRedactedShapeIs(std::string filterJson, BSONObj expectedShape) { - ASSERT_BSONOBJ_EQ(expectedShape, predicateShapeRedacted(filterJson)); -} -} // namespace - -TEST(QueryPredicateShape, Regex) { - // Note/warning: 'fromjson' will parse $regex into a /regex/, so these tests can't use - // auto-updating BSON assertions. - assertShapeIs("{a: /a+/}", - BSON("a" << BSON("$regex" - << "?string"))); - assertShapeIs("{a: /a+/i}", - BSON("a" << BSON("$regex" - << "?string" - << "$options" - << "?string"))); - assertRedactedShapeIs("{a: /a+/}", - BSON("HASH<a>" << BSON("$regex" - << "?string"))); - assertRedactedShapeIs("{a: /a+/}", - BSON("HASH<a>" << BSON("$regex" - << "?string"))); -} - -TEST(QueryPredicateShape, Mod) { - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$mod":["?number","?number"]}})", - "{a: {$mod: [2, 0]}}"); -} - -TEST(QueryPredicateShape, Exists) { - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$exists":"?bool"}})", - "{a: {$exists: true}}"); -} - -TEST(QueryPredicateShape, In) { - // Any number of children in any order is always the same shape - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$in":"?array<?number>"}})", - "{a: {$in: [1]}}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$in":"?array<>"}})", - "{a: {$in: [1, 4, 'str', /regex/]}}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$in":"?array<>"}})", - "{a: {$in: ['str', /regex/, 1, 4]}}"); -} - -TEST(QueryPredicateShape, BitTestOperators) { - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$bitsAllSet":"?array<?number>"}})", - "{a: {$bitsAllSet: [1, 5]}}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$bitsAllSet":"?array<?number>"}})", - "{a: {$bitsAllSet: 50}}"); - - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$bitsAnySet":"?array<?number>"}})", - "{a: {$bitsAnySet: [1, 5]}}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$bitsAnySet":"?array<?number>"}})", - "{a: {$bitsAnySet: 50}}"); - - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$bitsAllClear":"?array<?number>"}})", - "{a: {$bitsAllClear: [1, 5]}}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$bitsAllClear":"?array<?number>"}})", - "{a: {$bitsAllClear: 50}}"); - - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$bitsAnyClear":"?array<?number>"}})", - "{a: {$bitsAnyClear: [1, 5]}}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$bitsAnyClear":"?array<?number>"}})", - "{a: {$bitsAnyClear: 50}}"); -} - -TEST(QueryPredicateShape, AlwaysBoolean) { - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"$alwaysTrue":"?number"})", - "{$alwaysTrue: 1}"); - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"$alwaysFalse":"?number"})", - "{$alwaysFalse: 1}"); -} - -TEST(QueryPredicateShape, And) { - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({ - "$and": [ - { - "a": { - "$lt": "?number" - } - }, - { - "b": { - "$gte": "?number" - } - }, - { - "c": { - "$lte": "?number" - } - } - ] - })", - "{$and: [{a: {$lt: 5}}, {b: {$gte: 3}}, {c: {$lte: 10}}]}"); -} - -TEST(QueryPredicateShape, Or) { - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({ - "$or": [ - { - "a": { - "$eq": "?number" - } - }, - { - "b": { - "$in": "?array<?number>" - } - }, - { - "c": { - "$gt": "?number" - } - } - ] - })", - "{$or: [{a: 5}, {b: {$in: [1,2,3]}}, {c: {$gt: 10}}]}"); -} - -TEST(QueryPredicateShape, ElemMatch) { - // ElemMatchObjectMatchExpression - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({ - "a": { - "$elemMatch": { - "$and": [ - { - "b": { - "$eq": "?number" - } - }, - { - "c": { - "$exists": "?bool" - } - } - ] - } - } - })", - "{a: {$elemMatch: {b: 5, c: {$exists: true}}}}"); - - // ElemMatchValueMatchExpression - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"a":{"$elemMatch":{"$gt":"?number","$lt":"?number"}}})", - "{a: {$elemMatch: {$gt: 5, $lt: 10}}}"); - - // Nested - ASSERT_REDACTED_SHAPE_EQ_AUTO( // NOLINT - R"({ - "HASH<a>": { - "$elemMatch": { - "$elemMatch": { - "$gt": "?number", - "$lt": "?number" - } - } - } - })", - "{a: {$elemMatch: {$elemMatch: {$gt: 5, $lt: 10}}}}"); -} - -TEST(QueryPredicateShape, InternalBucketGeoWithinMatchExpression) { - auto query = - "{ $_internalBucketGeoWithin: {withinRegion: {$centerSphere: [[0, 0], 10]}, field: " - "\"a\"} " - "}"; - ASSERT_REDACTED_SHAPE_EQ_AUTO( // NOLINT - R"({ - "$_internalBucketGeoWithin": { - "withinRegion": { - "$centerSphere": "?array<>" - }, - "field": "HASH<a>" - } - })", - query); -} - -TEST(QueryPredicateShape, NorMatchExpression) { - ASSERT_REDACTED_SHAPE_EQ_AUTO( // NOLINT - R"({"$nor":[{"HASH<a>":{"$lt":"?number"}},{"HASH<b>":{"$gt":"?number"}}]})", - "{ $nor: [ { a: {$lt: 5} }, { b: {$gt: 4} } ] }"); -} - -TEST(QueryPredicateShape, NotMatchExpression) { - ASSERT_REDACTED_SHAPE_EQ_AUTO( // NOLINT - R"({"HASH<price>":{"$not":{"$gt":"?number"}}})", - "{ price: { $not: { $gt: 1.99 } } }"); - // Test the special case where NotMatchExpression::serialize() reduces to $alwaysFalse. - auto emptyAnd = std::make_unique<AndMatchExpression>(); - const MatchExpression& notExpr = NotMatchExpression(std::move(emptyAnd)); - auto serialized = - notExpr.serialize(SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST); - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({"$alwaysFalse":"?number"})", - serialized); -} - -TEST(QueryPredicateShape, SizeMatchExpression) { - ASSERT_REDACTED_SHAPE_EQ_AUTO( // NOLINT - R"({"HASH<price>":{"$size":"?number"}})", - "{ price: { $size: 2 } }"); -} - -TEST(QueryPredicateShape, TextMatchExpression) { - TextMatchExpressionBase::TextParams params = {"coffee"}; - auto expr = ExtensionsCallbackNoop().createText(params); - auto literalAndFieldRedactOpts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST; - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({ - "$text": { - "$search": "?string", - "$language": "?string", - "$caseSensitive": "?bool", - "$diacriticSensitive": "?bool" - } - })", - expr->serialize(SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST)); -} - -TEST(QueryPredicateShape, TwoDPtInAnnulusExpression) { - const MatchExpression& expr = TwoDPtInAnnulusExpression({}, {}); - auto literalAndFieldRedactOpts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST; - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({"$TwoDPtInAnnulusExpression":true})", - expr.serialize(SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST)); -} - -TEST(QueryPredicateShape, WhereMatchExpression) { - ASSERT_SHAPE_EQ_AUTO( // NOLINT - R"({"$where":"?javascript"})", - "{$where: \"some_code()\"}"); -} - -BSONObj queryShapeForOptimizedExprExpression(std::string exprPredicateJson) { - ParsedMatchExpressionForTest expr(exprPredicateJson); - // We need to optimize an $expr expression in order to generate an $_internalExprEq. It's - // not clear we'd want to do optimization before computing the query shape, but we should - // support the computation on any MatchExpression, and this is the easiest way we can create - // this type of MatchExpression node. - auto optimized = MatchExpression::optimize(expr.release()); - return predicateShape(optimized.get()); -} - -TEST(QueryPredicateShape, OptimizedExprPredicates) { - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({ - "$and": [ - { - "a": { - "$_internalExprEq": "?number" - } - }, - { - "$expr": { - "$eq": [ - "$a", - "?number" - ] - } - } - ] - })", - queryShapeForOptimizedExprExpression("{$expr: {$eq: ['$a', 2]}}")); - - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({ - "$and": [ - { - "a": { - "$_internalExprLt": "?number" - } - }, - { - "$expr": { - "$lt": [ - "$a", - "?number" - ] - } - } - ] - })", - queryShapeForOptimizedExprExpression("{$expr: {$lt: ['$a', 2]}}")); - - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({ - "$and": [ - { - "a": { - "$_internalExprLte": "?number" - } - }, - { - "$expr": { - "$lte": [ - "$a", - "?number" - ] - } - } - ] - })", - queryShapeForOptimizedExprExpression("{$expr: {$lte: ['$a', 2]}}")); - - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({ - "$and": [ - { - "a": { - "$_internalExprGt": "?number" - } - }, - { - "$expr": { - "$gt": [ - "$a", - "?number" - ] - } - } - ] - })", - queryShapeForOptimizedExprExpression("{$expr: {$gt: ['$a', 2]}}")); - - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({ - "$and": [ - { - "a": { - "$_internalExprGte": "?number" - } - }, - { - "$expr": { - "$gte": [ - "$a", - "?number" - ] - } - } - ] - })", - queryShapeForOptimizedExprExpression("{$expr: {$gte: ['$a', 2]}}")); -} - -TEST(QueryShapeIDL, ShapifyIDLStruct) { - SerializationOptions options; - options.transformIdentifiers = true; - options.transformIdentifiersCallback = [](StringData s) -> std::string { - return str::stream() << "HASH<" << s << ">"; - }; - options.literalPolicy = LiteralSerializationPolicy::kToDebugTypeString; - - auto nested = NestedStruct("value", - ExampleEnumEnum::Value1, - "hello", - {1, 2, 3, 4}, - "field.path", - {"field.path.1", "fieldpath2"}, - NamespaceString{"db", "coll"}, - NamespaceString{"db", "coll"}, - 177, - true); - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({ - "stringField": "value", - "enumField": "EnumValue1", - "stringIntVariantEnum": "hello", - "arrayOfInts": [ - 1, - 2, - 3, - 4 - ], - "fieldpath": "field.path", - "fieldpathList": [ - "field.path.1", - "fieldpath2" - ], - "nss": "db.coll", - "plainNss": "db.coll", - "safeInt64Field": 177, - "boolField": true - })", - nested.toBSON()); - - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({ - "stringField": "?string", - "enumField": "EnumValue1", - "stringIntVariantEnum": "hello", - "arrayOfInts": "?array<?number>", - "fieldpath": "HASH<field>.HASH<path>", - "fieldpathList": [ - "HASH<field>.HASH<path>.HASH<1>", - "HASH<fieldpath2>" - ], - "nss": "HASH<db.coll>", - "plainNss": "db.coll", - "safeInt64Field": "?number", - "boolField": "?bool" - })", - nested.toBSON(options)); - - - auto parent = ParentStruct(nested, nested); - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({ - "nested_shape": { - "stringField": "value", - "enumField": "EnumValue1", - "stringIntVariantEnum": "hello", - "arrayOfInts": [ - 1, - 2, - 3, - 4 - ], - "fieldpath": "field.path", - "fieldpathList": [ - "field.path.1", - "fieldpath2" - ], - "nss": "db.coll", - "plainNss": "db.coll", - "safeInt64Field": 177, - "boolField": true - }, - "nested_no_shape": { - "stringField": "value", - "enumField": "EnumValue1", - "stringIntVariantEnum": "hello", - "arrayOfInts": [ - 1, - 2, - 3, - 4 - ], - "fieldpath": "field.path", - "fieldpathList": [ - "field.path.1", - "fieldpath2" - ], - "nss": "db.coll", - "plainNss": "db.coll", - "safeInt64Field": 177, - "boolField": true - } - })", - parent.toBSON()); - - ASSERT_BSONOBJ_EQ_AUTO( // NOLINT - R"({ - "nested_shape": { - "stringField": "?string", - "enumField": "EnumValue1", - "stringIntVariantEnum": "hello", - "arrayOfInts": "?array<?number>", - "fieldpath": "HASH<field>.HASH<path>", - "fieldpathList": [ - "HASH<field>.HASH<path>.HASH<1>", - "HASH<fieldpath2>" - ], - "nss": "HASH<db.coll>", - "plainNss": "db.coll", - "safeInt64Field": "?number", - "boolField": "?bool" - }, - "nested_no_shape": { - "stringField": "value", - "enumField": "EnumValue1", - "stringIntVariantEnum": "hello", - "arrayOfInts": [ - 1, - 2, - 3, - 4 - ], - "fieldpath": "field.path", - "fieldpathList": [ - "field.path.1", - "fieldpath2" - ], - "nss": "db.coll", - "plainNss": "db.coll", - "safeInt64Field": 177, - "boolField": true - } - })", - parent.toBSON(options)); -} - -} // namespace - -namespace { - -static const NamespaceString kDefaultTestNss = NamespaceString("testDB.testColl"); - -struct DummyShapeSpecificComponents : public query_shape::CmdSpecificShapeComponents { - DummyShapeSpecificComponents(){}; - void HashValue(absl::HashState state) const {} - size_t size() const final { - return sizeof(DummyShapeSpecificComponents); - } -}; - -class DummyShape : public Shape { -public: - DummyShape(NamespaceStringOrUUID nssOrUUID, - BSONObj collation, - DummyShapeSpecificComponents dummyComponents) - : Shape(nssOrUUID, collation) { - components = dummyComponents; - } - - const CmdSpecificShapeComponents& specificComponents() const final { - return components; - } - - void appendCmdSpecificShapeComponents(BSONObjBuilder&, - OperationContext*, - const SerializationOptions& opts) const final {} - DummyShapeSpecificComponents components; -}; - -class DummyShapeWithExtraSize : public Shape { -public: - DummyShapeWithExtraSize(NamespaceStringOrUUID nssOrUUID, - BSONObj collation, - DummyShapeSpecificComponents dummyComponents) - : Shape(nssOrUUID, collation) { - components = dummyComponents; - } - - const CmdSpecificShapeComponents& specificComponents() const final { - return components; - } - - // Random number for testing purposes. - size_t extraSize() const final override { - return 125; - } - void appendCmdSpecificShapeComponents(BSONObjBuilder&, - OperationContext*, - const SerializationOptions& opts) const final {} - - DummyShapeSpecificComponents components; -}; - -class UniversalShapeTest : public ServiceContextTest {}; - -TEST_F(UniversalShapeTest, SizeOfSpecificComponents) { - auto innerComponents = std::make_unique<DummyShapeSpecificComponents>(); - ASSERT_EQ(innerComponents->size(), sizeof(CmdSpecificShapeComponents)); - ASSERT_EQ(innerComponents->size(), sizeof(void*) /*vtable ptr*/); -} - -TEST_F(UniversalShapeTest, SizeOfShape) { - auto expCtx = make_intrusive<ExpressionContextForTest>(); - - // Make shape for testing. - auto collation = BSONObj{}; - auto innerComponents = std::make_unique<DummyShapeSpecificComponents>(); - auto shape = std::make_unique<DummyShape>(kDefaultTestNss, collation, *innerComponents); - - ASSERT_EQ(innerComponents->size(), shape->specificComponents().size()); - ASSERT_EQ(shape->size(), - sizeof(NamespaceStringOrUUID) + sizeof(BSONObj) + sizeof(void*) /*vtable ptr*/ + - shape->specificComponents().size() + static_cast<size_t>(collation.objsize())); -} - -TEST_F(UniversalShapeTest, SizeOfShapeWithExtraSize) { - auto expCtx = make_intrusive<ExpressionContextForTest>(); - - // Make shape for testing. - auto collation = BSONObj{}; - auto innerComponents = std::make_unique<DummyShapeSpecificComponents>(); - auto shape = std::make_unique<DummyShape>(kDefaultTestNss, collation, *innerComponents); - auto shapeWithExtraSize = - std::make_unique<DummyShapeWithExtraSize>(kDefaultTestNss, collation, *innerComponents); - - ASSERT_EQ(shapeWithExtraSize->size(), shape->size() + shapeWithExtraSize->extraSize()); -} -} // namespace -} // namespace mongo::query_shape |
