summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline
diff options
context:
space:
mode:
authorCharlie Swanson <cswanson310@gmail.com>2016-08-29 15:03:03 -0400
committerCharlie Swanson <cswanson310@gmail.com>2016-09-02 12:41:16 -0400
commit0c6198abb7f17ba91c46ae73b4578580a3bb2b91 (patch)
treec1e251cb439bb8138c42814fd31e11e1bb4e2e70 /src/mongo/db/pipeline
parent63640ef8a5329c2093f1e0c0ed3ac358f1e5c73d (diff)
downloadmongo-0c6198abb7f17ba91c46ae73b4578580a3bb2b91.tar.gz
SERVER-24153 Make DocumentSourceMock hold GetNextResults
This is prep work for adding tests that all stages can correctly handle a kPauseExecution result.
Diffstat (limited to 'src/mongo/db/pipeline')
-rw-r--r--src/mongo/db/pipeline/document_source.h12
-rw-r--r--src/mongo/db/pipeline/document_source_add_fields_test.cpp3
-rw-r--r--src/mongo/db/pipeline/document_source_bucket_auto_test.cpp253
-rw-r--r--src/mongo/db/pipeline/document_source_facet_test.cpp27
-rw-r--r--src/mongo/db/pipeline/document_source_graph_lookup_test.cpp26
-rw-r--r--src/mongo/db/pipeline/document_source_group_test.cpp24
-rw-r--r--src/mongo/db/pipeline/document_source_mock.cpp39
-rw-r--r--src/mongo/db/pipeline/document_source_replace_root_test.cpp24
-rw-r--r--src/mongo/db/pipeline/document_source_sort_test.cpp3
-rw-r--r--src/mongo/db/pipeline/document_source_unwind_test.cpp38
-rw-r--r--src/mongo/db/pipeline/tee_buffer_test.cpp28
11 files changed, 259 insertions, 218 deletions
diff --git a/src/mongo/db/pipeline/document_source.h b/src/mongo/db/pipeline/document_source.h
index f87a81c9be1..56fbaf042bc 100644
--- a/src/mongo/db/pipeline/document_source.h
+++ b/src/mongo/db/pipeline/document_source.h
@@ -1037,8 +1037,8 @@ private:
*/
class DocumentSourceMock : public DocumentSource {
public:
- DocumentSourceMock(std::deque<Document> docs);
- DocumentSourceMock(std::deque<Document> docs,
+ DocumentSourceMock(std::deque<GetNextResult> results);
+ DocumentSourceMock(std::deque<GetNextResult> results,
const boost::intrusive_ptr<ExpressionContext>& expCtx);
GetNextResult getNext() override;
@@ -1054,8 +1054,10 @@ public:
static boost::intrusive_ptr<DocumentSourceMock> create();
- static boost::intrusive_ptr<DocumentSourceMock> create(const Document& doc);
- static boost::intrusive_ptr<DocumentSourceMock> create(std::deque<Document> documents);
+ static boost::intrusive_ptr<DocumentSourceMock> create(Document doc);
+
+ static boost::intrusive_ptr<DocumentSourceMock> create(const GetNextResult& result);
+ static boost::intrusive_ptr<DocumentSourceMock> create(std::deque<GetNextResult> results);
static boost::intrusive_ptr<DocumentSourceMock> create(const char* json);
static boost::intrusive_ptr<DocumentSourceMock> create(
@@ -1079,7 +1081,7 @@ public:
}
// Return documents from front of queue.
- std::deque<Document> queue;
+ std::deque<GetNextResult> queue;
bool isDisposed = false;
bool isDetachedFromOpCtx = false;
diff --git a/src/mongo/db/pipeline/document_source_add_fields_test.cpp b/src/mongo/db/pipeline/document_source_add_fields_test.cpp
index 63896f31e27..eabea7ff045 100644
--- a/src/mongo/db/pipeline/document_source_add_fields_test.cpp
+++ b/src/mongo/db/pipeline/document_source_add_fields_test.cpp
@@ -55,8 +55,7 @@ using AddFieldsTest = AggregationContextFixture;
TEST_F(AddFieldsTest, ShouldKeepUnspecifiedFieldsReplaceExistingFieldsAndAddNewFields) {
auto addFields =
DocumentSourceAddFields::create(BSON("e" << 2 << "b" << BSON("c" << 3)), getExpCtx());
- auto mock =
- DocumentSourceMock::create({Document{{"a", 1}, {"b", Document{{"c", 1}}}, {"d", 1}}});
+ auto mock = DocumentSourceMock::create(Document{{"a", 1}, {"b", Document{{"c", 1}}}, {"d", 1}});
addFields->setSource(mock.get());
auto next = addFields->getNext();
diff --git a/src/mongo/db/pipeline/document_source_bucket_auto_test.cpp b/src/mongo/db/pipeline/document_source_bucket_auto_test.cpp
index 1950c23f0d9..17e0c1d7a3b 100644
--- a/src/mongo/db/pipeline/document_source_bucket_auto_test.cpp
+++ b/src/mongo/db/pipeline/document_source_bucket_auto_test.cpp
@@ -30,6 +30,8 @@
#include <boost/intrusive_ptr.hpp>
#include <deque>
+#include <string>
+#include <utility>
#include <vector>
#include "mongo/bson/bsonobj.h"
@@ -45,8 +47,9 @@
namespace mongo {
namespace {
-using std::vector;
using std::deque;
+using std::vector;
+using std::string;
using boost::intrusive_ptr;
class BucketAutoTests : public AggregationContextFixture {
@@ -55,11 +58,17 @@ public:
return DocumentSourceBucketAuto::createFromBson(bucketAutoSpec.firstElement(), getExpCtx());
}
- vector<Document> getResults(BSONObj bucketAutoSpec, deque<Document> docs) {
+ vector<Document> getResults(BSONObj bucketAutoSpec, deque<Document> inputs) {
auto bucketAutoStage = createBucketAuto(bucketAutoSpec);
assertBucketAutoType(bucketAutoStage);
- auto source = DocumentSourceMock::create(docs);
+ // Convert Documents to GetNextResults.
+ deque<DocumentSource::GetNextResult> mockInputs;
+ for (auto&& input : inputs) {
+ mockInputs.emplace_back(std::move(input));
+ }
+
+ auto source = DocumentSourceMock::create(std::move(mockInputs));
bucketAutoStage->setSource(source.get());
vector<Document> results;
@@ -103,15 +112,16 @@ TEST_F(BucketAutoTests, Returns1Of1RequestedBucketWhenAllUniqueValues) {
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : '$x', buckets: 1}}");
// Values are 1, 2, 3, 4
- auto intDocs = {Document{{"x", 4}}, Document{{"x", 1}}, Document{{"x", 3}}, Document{{"x", 2}}};
- auto results = getResults(bucketAutoSpec, intDocs);
+ auto results = getResults(
+ bucketAutoSpec,
+ {Document{{"x", 4}}, Document{{"x", 1}}, Document{{"x", 3}}, Document{{"x", 2}}});
ASSERT_EQUALS(results.size(), 1UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 1, max : 4}, count : 4}")));
// Values are 'a', 'b', 'c', 'd'
- auto stringDocs = {
- Document{{"x", "d"}}, Document{{"x", "b"}}, Document{{"x", "a"}}, Document{{"x", "c"}}};
- results = getResults(bucketAutoSpec, stringDocs);
+ results = getResults(
+ bucketAutoSpec,
+ {Document{{"x", "d"}}, Document{{"x", "b"}}, Document{{"x", "a"}}, Document{{"x", "c"}}});
ASSERT_EQUALS(results.size(), 1UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 'a', max : 'd'}, count : 4}")));
}
@@ -120,25 +130,23 @@ TEST_F(BucketAutoTests, Returns1Of1RequestedBucketWithNonUniqueValues) {
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : '$x', buckets: 1}}");
// Values are 1, 2, 7, 7, 7
- auto docs = {Document{{"x", 7}},
- Document{{"x", 1}},
- Document{{"x", 7}},
- Document{{"x", 2}},
- Document{{"x", 7}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(bucketAutoSpec,
+ {Document{{"x", 7}},
+ Document{{"x", 1}},
+ Document{{"x", 7}},
+ Document{{"x", 2}},
+ Document{{"x", 7}}});
ASSERT_EQUALS(results.size(), 1UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 1, max : 7}, count : 5}")));
}
TEST_F(BucketAutoTests, Returns1Of1RequestedBucketWhen1ValueInSource) {
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : '$x', buckets: 1}}");
- auto intDocs = {Document{{"x", 1}}};
- auto results = getResults(bucketAutoSpec, intDocs);
+ auto results = getResults(bucketAutoSpec, {Document{{"x", 1}}});
ASSERT_EQUALS(results.size(), 1UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 1, max : 1}, count : 1}")));
- auto stringDocs = {Document{{"x", "a"}}};
- results = getResults(bucketAutoSpec, stringDocs);
+ results = getResults(bucketAutoSpec, {Document{{"x", "a"}}});
ASSERT_EQUALS(results.size(), 1UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 'a', max : 'a'}, count : 1}")));
}
@@ -147,12 +155,12 @@ TEST_F(BucketAutoTests, Returns2Of2RequestedBucketsWhenSmallestValueHasManyDupli
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2}}");
// Values are 1, 1, 1, 1, 2
- auto docs = {Document{{"x", 1}},
- Document{{"x", 1}},
- Document{{"x", 1}},
- Document{{"x", 2}},
- Document{{"x", 1}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(bucketAutoSpec,
+ {Document{{"x", 1}},
+ Document{{"x", 1}},
+ Document{{"x", 1}},
+ Document{{"x", 2}},
+ Document{{"x", 1}}});
ASSERT_EQUALS(results.size(), 2UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 1, max : 2}, count : 4}")));
ASSERT_DOCUMENT_EQ(results[1], Document(fromjson("{_id : {min : 2, max : 2}, count : 1}")));
@@ -162,16 +170,16 @@ TEST_F(BucketAutoTests, Returns2Of2RequestedBucketsWhenLargestValueHasManyDuplic
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2}}");
// Values are 0, 1, 2, 3, 4, 5, 5, 5, 5
- auto docs = {Document{{"x", 5}},
- Document{{"x", 0}},
- Document{{"x", 2}},
- Document{{"x", 3}},
- Document{{"x", 5}},
- Document{{"x", 1}},
- Document{{"x", 5}},
- Document{{"x", 4}},
- Document{{"x", 5}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(bucketAutoSpec,
+ {Document{{"x", 5}},
+ Document{{"x", 0}},
+ Document{{"x", 2}},
+ Document{{"x", 3}},
+ Document{{"x", 5}},
+ Document{{"x", 1}},
+ Document{{"x", 5}},
+ Document{{"x", 4}},
+ Document{{"x", 5}}});
ASSERT_EQUALS(results.size(), 2UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0, max : 5}, count : 5}")));
@@ -182,15 +190,15 @@ TEST_F(BucketAutoTests, Returns3Of3RequestedBucketsWhenAllUniqueValues) {
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : '$x', buckets : 3}}");
// Values are 0, 1, 2, 3, 4, 5, 6, 7
- auto docs = {Document{{"x", 2}},
- Document{{"x", 4}},
- Document{{"x", 1}},
- Document{{"x", 7}},
- Document{{"x", 0}},
- Document{{"x", 5}},
- Document{{"x", 3}},
- Document{{"x", 6}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(bucketAutoSpec,
+ {Document{{"x", 2}},
+ Document{{"x", 4}},
+ Document{{"x", 1}},
+ Document{{"x", 7}},
+ Document{{"x", 0}},
+ Document{{"x", 5}},
+ Document{{"x", 3}},
+ Document{{"x", 6}}});
ASSERT_EQUALS(results.size(), 3UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0, max : 3}, count : 3}")));
@@ -205,14 +213,14 @@ TEST_F(BucketAutoTests, Returns2Of3RequestedBucketsWhenLargestValueHasManyDuplic
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : '$x', buckets : 3}}");
// Values are 0, 1, 2, 2, 2, 2, 2
- auto docs = {Document{{"x", 2}},
- Document{{"x", 0}},
- Document{{"x", 2}},
- Document{{"x", 2}},
- Document{{"x", 1}},
- Document{{"x", 2}},
- Document{{"x", 2}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(bucketAutoSpec,
+ {Document{{"x", 2}},
+ Document{{"x", 0}},
+ Document{{"x", 2}},
+ Document{{"x", 2}},
+ Document{{"x", 1}},
+ Document{{"x", 2}},
+ Document{{"x", 2}}});
ASSERT_EQUALS(results.size(), 2UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0, max : 2}, count : 2}")));
@@ -227,15 +235,15 @@ TEST_F(BucketAutoTests, Returns1Of3RequestedBucketsWhenLargestValueHasManyDuplic
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : '$x', buckets : 3}}");
// Values are 0, 1, 2, 2, 2, 2, 2, 2
- auto docs = {Document{{"x", 2}},
- Document{{"x", 2}},
- Document{{"x", 0}},
- Document{{"x", 2}},
- Document{{"x", 2}},
- Document{{"x", 2}},
- Document{{"x", 1}},
- Document{{"x", 2}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(bucketAutoSpec,
+ {Document{{"x", 2}},
+ Document{{"x", 2}},
+ Document{{"x", 0}},
+ Document{{"x", 2}},
+ Document{{"x", 2}},
+ Document{{"x", 2}},
+ Document{{"x", 1}},
+ Document{{"x", 2}}});
ASSERT_EQUALS(results.size(), 1UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0, max : 2}, count : 8}")));
@@ -243,8 +251,8 @@ TEST_F(BucketAutoTests, Returns1Of3RequestedBucketsWhenLargestValueHasManyDuplic
TEST_F(BucketAutoTests, Returns3Of3RequestedBucketsWhen3ValuesInSource) {
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : '$x', buckets : 3}}");
- auto docs = {Document{{"x", 0}}, Document{{"x", 1}}, Document{{"x", 2}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results =
+ getResults(bucketAutoSpec, {Document{{"x", 0}}, Document{{"x", 1}}, Document{{"x", 2}}});
ASSERT_EQUALS(results.size(), 3UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0, max : 1}, count : 1}")));
@@ -254,8 +262,8 @@ TEST_F(BucketAutoTests, Returns3Of3RequestedBucketsWhen3ValuesInSource) {
TEST_F(BucketAutoTests, Returns3Of10RequestedBucketsWhen3ValuesInSource) {
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : '$x', buckets : 10}}");
- auto docs = {Document{{"x", 0}}, Document{{"x", 1}}, Document{{"x", 2}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results =
+ getResults(bucketAutoSpec, {Document{{"x", 0}}, Document{{"x", 1}}, Document{{"x", 2}}});
ASSERT_EQUALS(results.size(), 3UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0, max : 1}, count : 1}")));
@@ -266,8 +274,9 @@ TEST_F(BucketAutoTests, Returns3Of10RequestedBucketsWhen3ValuesInSource) {
TEST_F(BucketAutoTests, EvaluatesAccumulatorsInOutputField) {
auto bucketAutoSpec =
fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2, output : {avg : {$avg : '$x'}}}}");
- auto docs = {Document{{"x", 0}}, Document{{"x", 2}}, Document{{"x", 4}}, Document{{"x", 6}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(
+ bucketAutoSpec,
+ {Document{{"x", 0}}, Document{{"x", 2}}, Document{{"x", 4}}, Document{{"x", 6}}});
ASSERT_EQUALS(results.size(), 2UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0, max : 4}, avg : 1}")));
@@ -276,8 +285,9 @@ TEST_F(BucketAutoTests, EvaluatesAccumulatorsInOutputField) {
TEST_F(BucketAutoTests, EvaluatesNonFieldPathExpressionInGroupByField) {
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : {$add : ['$x', 1]}, buckets : 2}}");
- auto docs = {Document{{"x", 0}}, Document{{"x", 1}}, Document{{"x", 2}}, Document{{"x", 3}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(
+ bucketAutoSpec,
+ {Document{{"x", 0}}, Document{{"x", 1}}, Document{{"x", 2}}, Document{{"x", 3}}});
ASSERT_EQUALS(results.size(), 2UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 1, max : 3}, count : 2}")));
@@ -286,12 +296,12 @@ TEST_F(BucketAutoTests, EvaluatesNonFieldPathExpressionInGroupByField) {
TEST_F(BucketAutoTests, RespectsCanonicalTypeOrderingOfValues) {
auto bucketAutoSpec = fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2}}");
- auto docs = {Document{{"x", "a"}},
- Document{{"x", 1}},
- Document{{"x", "b"}},
- Document{{"x", 2}},
- Document{{"x", 0.0}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(bucketAutoSpec,
+ {Document{{"x", "a"}},
+ Document{{"x", 1}},
+ Document{{"x", "b"}},
+ Document{{"x", 2}},
+ Document{{"x", 0.0}}});
ASSERT_EQUALS(results.size(), 2UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0.0, max : 'a'}, count : 3}")));
@@ -300,7 +310,7 @@ TEST_F(BucketAutoTests, RespectsCanonicalTypeOrderingOfValues) {
TEST_F(BucketAutoTests, SourceNameIsBucketAuto) {
auto bucketAuto = createBucketAuto(fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2}}"));
- ASSERT_EQUALS(std::string(bucketAuto->getSourceName()), "$bucketAuto");
+ ASSERT_EQUALS(string(bucketAuto->getSourceName()), "$bucketAuto");
}
TEST_F(BucketAutoTests, ShouldAddDependenciesOfGroupByFieldAndComputedFields) {
@@ -399,8 +409,7 @@ TEST_F(BucketAutoTests, ShouldBeAbleToReParseSerializedStage) {
}
TEST_F(BucketAutoTests, ReturnsNoBucketsWhenNoBucketsAreSpecifiedInCreate) {
- auto docs = {Document{{"x", 1}}};
- auto mock = DocumentSourceMock::create(docs);
+ auto mock = DocumentSourceMock::create(Document{{"x", 1}});
auto bucketAuto = DocumentSourceBucketAuto::create(getExpCtx());
bucketAuto->setSource(mock.get());
@@ -501,12 +510,12 @@ TEST_F(BucketAutoTests, FailsWithInvalidOutputFieldName) {
}
TEST_F(BucketAutoTests, FailsWhenBufferingTooManyDocuments) {
- std::deque<Document> inputs;
- auto largeStr = std::string(1000, 'b');
+ deque<DocumentSource::GetNextResult> inputs;
+ auto largeStr = string(1000, 'b');
auto inputDoc = Document{{"a", largeStr}};
ASSERT_GTE(inputDoc.getApproximateSize(), 1000UL);
- inputs.push_back(inputDoc);
- inputs.push_back(Document{{"a", largeStr}});
+ inputs.emplace_back(std::move(inputDoc));
+ inputs.emplace_back(Document{{"a", largeStr}});
auto mock = DocumentSourceMock::create(inputs);
const uint64_t maxMemoryUsageBytes = 1000;
@@ -522,12 +531,12 @@ TEST_F(BucketAutoTests, ShouldRoundUpMaximumBoundariesWithGranularitySpecified)
fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2, granularity : 'R5'}}");
// Values are 0, 15, 24, 30, 50
- auto docs = {Document{{"x", 24}},
- Document{{"x", 15}},
- Document{{"x", 30}},
- Document{{"x", 50}},
- Document{{"x", 0}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(bucketAutoSpec,
+ {Document{{"x", 24}},
+ Document{{"x", 15}},
+ Document{{"x", 30}},
+ Document{{"x", 50}},
+ Document{{"x", 0}}});
ASSERT_EQUALS(results.size(), 2UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0, max : 25}, count : 3}")));
@@ -539,12 +548,12 @@ TEST_F(BucketAutoTests, ShouldRoundDownFirstMinimumBoundaryWithGranularitySpecif
fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2, granularity : 'R5'}}");
// Values are 1, 15, 24, 30, 50
- auto docs = {Document{{"x", 24}},
- Document{{"x", 15}},
- Document{{"x", 30}},
- Document{{"x", 50}},
- Document{{"x", 1}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(bucketAutoSpec,
+ {Document{{"x", 24}},
+ Document{{"x", 15}},
+ Document{{"x", 30}},
+ Document{{"x", 50}},
+ Document{{"x", 1}}});
ASSERT_EQUALS(results.size(), 2UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0.63, max : 25}, count : 3}")));
@@ -555,12 +564,12 @@ TEST_F(BucketAutoTests, ShouldAbsorbAllValuesSmallerThanAdjustedBoundaryWithGran
auto bucketAutoSpec =
fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2, granularity : 'R5'}}");
- auto docs = {Document{{"x", 0}},
- Document{{"x", 5}},
- Document{{"x", 10}},
- Document{{"x", 15}},
- Document{{"x", 30}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(bucketAutoSpec,
+ {Document{{"x", 0}},
+ Document{{"x", 5}},
+ Document{{"x", 10}},
+ Document{{"x", 15}},
+ Document{{"x", 30}}});
ASSERT_EQUALS(results.size(), 2UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0, max : 16}, count : 4}")));
@@ -571,12 +580,12 @@ TEST_F(BucketAutoTests, ShouldBeAbleToAbsorbAllValuesIntoOneBucketWithGranularit
auto bucketAutoSpec =
fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2, granularity : 'R5'}}");
- auto docs = {Document{{"x", 0}},
- Document{{"x", 5}},
- Document{{"x", 10}},
- Document{{"x", 14}},
- Document{{"x", 15}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(bucketAutoSpec,
+ {Document{{"x", 0}},
+ Document{{"x", 5}},
+ Document{{"x", 10}},
+ Document{{"x", 14}},
+ Document{{"x", 15}}});
ASSERT_EQUALS(results.size(), 1UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0, max : 16}, count : 5}")));
@@ -586,8 +595,9 @@ TEST_F(BucketAutoTests, ShouldNotRoundZeroInFirstBucketWithGranularitySpecified)
auto bucketAutoSpec =
fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2, granularity : 'R5'}}");
- auto docs = {Document{{"x", 0}}, Document{{"x", 0}}, Document{{"x", 1}}, Document{{"x", 1}}};
- auto results = getResults(bucketAutoSpec, docs);
+ auto results = getResults(
+ bucketAutoSpec,
+ {Document{{"x", 0}}, Document{{"x", 0}}, Document{{"x", 1}}, Document{{"x", 1}}});
ASSERT_EQUALS(results.size(), 2UL);
ASSERT_DOCUMENT_EQ(results[0], Document(fromjson("{_id : {min : 0, max : 0.63}, count : 2}")));
@@ -599,28 +609,37 @@ TEST_F(BucketAutoTests, ShouldFailOnNaNWhenGranularitySpecified) {
auto bucketAutoSpec =
fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2, granularity : 'R5'}}");
- auto docs = {Document{{"x", 0}},
- Document{{"x", std::nan("NaN")}},
- Document{{"x", 1}},
- Document{{"x", 1}}};
- ASSERT_THROWS_CODE(getResults(bucketAutoSpec, docs), UserException, 40259);
+ ASSERT_THROWS_CODE(getResults(bucketAutoSpec,
+ {Document{{"x", 0}},
+ Document{{"x", std::nan("NaN")}},
+ Document{{"x", 1}},
+ Document{{"x", 1}}}),
+ UserException,
+ 40259);
}
TEST_F(BucketAutoTests, ShouldFailOnNonNumericValuesWhenGranularitySpecified) {
auto bucketAutoSpec =
fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2, granularity : 'R5'}}");
- auto docs = {
- Document{{"x", 0}}, Document{{"x", "test"}}, Document{{"x", 1}}, Document{{"x", 1}}};
- ASSERT_THROWS_CODE(getResults(bucketAutoSpec, docs), UserException, 40258);
+ ASSERT_THROWS_CODE(
+ getResults(
+ bucketAutoSpec,
+ {Document{{"x", 0}}, Document{{"x", "test"}}, Document{{"x", 1}}, Document{{"x", 1}}}),
+ UserException,
+ 40258);
}
TEST_F(BucketAutoTests, ShouldFailOnNegativeNumbersWhenGranularitySpecified) {
auto bucketAutoSpec =
fromjson("{$bucketAuto : {groupBy : '$x', buckets : 2, granularity : 'R5'}}");
- auto docs = {Document{{"x", 0}}, Document{{"x", -1}}, Document{{"x", 1}}, Document{{"x", 2}}};
- ASSERT_THROWS_CODE(getResults(bucketAutoSpec, docs), UserException, 40260);
+ ASSERT_THROWS_CODE(
+ getResults(
+ bucketAutoSpec,
+ {Document{{"x", 0}}, Document{{"x", -1}}, Document{{"x", 1}}, Document{{"x", 2}}}),
+ UserException,
+ 40260);
}
} // namespace
} // namespace mongo
diff --git a/src/mongo/db/pipeline/document_source_facet_test.cpp b/src/mongo/db/pipeline/document_source_facet_test.cpp
index 0f4ee161f75..09424a1aceb 100644
--- a/src/mongo/db/pipeline/document_source_facet_test.cpp
+++ b/src/mongo/db/pipeline/document_source_facet_test.cpp
@@ -40,9 +40,11 @@
#include "mongo/db/pipeline/aggregation_context_fixture.h"
#include "mongo/db/pipeline/document.h"
#include "mongo/db/pipeline/document_value_test_util.h"
-#include "mongo/util/assert_util.h"
+#include "mongo/unittest/unittest.h"
namespace mongo {
+using std::deque;
+using std::vector;
// Crutch.
bool isMongos() {
@@ -193,7 +195,8 @@ TEST_F(DocumentSourceFacetTest, SingleFacetShouldReceiveAllDocuments) {
auto facetStage = DocumentSourceFacet::create({{"results", pipeline}}, ctx);
- deque<Document> inputs = {Document{{"_id", 0}}, Document{{"_id", 1}}, Document{{"_id", 2}}};
+ deque<DocumentSource::GetNextResult> inputs = {
+ Document{{"_id", 0}}, Document{{"_id", 1}}, Document{{"_id", 2}}};
auto mock = DocumentSourceMock::create(inputs);
facetStage->setSource(mock.get());
@@ -220,14 +223,18 @@ TEST_F(DocumentSourceFacetTest, MultipleFacetsShouldSeeTheSameDocuments) {
auto facetStage =
DocumentSourceFacet::create({{"first", firstPipeline}, {"second", secondPipeline}}, ctx);
- deque<Document> inputs = {Document{{"_id", 0}}, Document{{"_id", 1}}, Document{{"_id", 2}}};
+ deque<DocumentSource::GetNextResult> inputs = {
+ Document{{"_id", 0}}, Document{{"_id", 1}}, Document{{"_id", 2}}};
auto mock = DocumentSourceMock::create(inputs);
facetStage->setSource(mock.get());
auto output = facetStage->getNext();
// The output fields are in no guaranteed order.
- vector<Value> expectedOutputs(inputs.begin(), inputs.end());
+ vector<Value> expectedOutputs;
+ for (auto&& input : inputs) {
+ expectedOutputs.emplace_back(input.releaseDocument());
+ }
ASSERT(output.isAdvanced());
ASSERT_EQ(output.getDocument().size(), 2UL);
ASSERT_VALUE_EQ(output.getDocument()["first"], Value(expectedOutputs));
@@ -252,19 +259,23 @@ TEST_F(DocumentSourceFacetTest,
auto facetStage =
DocumentSourceFacet::create({{"all", passthroughPipe}, {"first", limitedPipe}}, ctx);
- deque<Document> inputs = {
+ deque<DocumentSource::GetNextResult> inputs = {
Document{{"_id", 0}}, Document{{"_id", 1}}, Document{{"_id", 2}}, Document{{"_id", 3}}};
auto mock = DocumentSourceMock::create(inputs);
facetStage->setSource(mock.get());
+ vector<Value> expectedPassthroughOutput;
+ for (auto&& input : inputs) {
+ expectedPassthroughOutput.emplace_back(input.getDocument());
+ }
auto output = facetStage->getNext();
// The output fields are in no guaranteed order.
ASSERT(output.isAdvanced());
ASSERT_EQ(output.getDocument().size(), 2UL);
- vector<Value> expectedPassthroughOutput(inputs.begin(), inputs.end());
ASSERT_VALUE_EQ(output.getDocument()["all"], Value(expectedPassthroughOutput));
- ASSERT_VALUE_EQ(output.getDocument()["first"], Value(vector<Value>{Value(inputs.front())}));
+ ASSERT_VALUE_EQ(output.getDocument()["first"],
+ Value(vector<Value>{Value(expectedPassthroughOutput.front())}));
// Should be exhausted now.
ASSERT(facetStage->getNext().isEOF());
@@ -281,7 +292,7 @@ TEST_F(DocumentSourceFacetTest, ShouldBeAbleToEvaluateMultipleStagesWithinOneSub
auto facetStage = DocumentSourceFacet::create({{"subPipe", pipeline}}, ctx);
- deque<Document> inputs = {Document{{"_id", 0}}, Document{{"_id", 1}}};
+ deque<DocumentSource::GetNextResult> inputs = {Document{{"_id", 0}}, Document{{"_id", 1}}};
auto mock = DocumentSourceMock::create(inputs);
facetStage->setSource(mock.get());
diff --git a/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp b/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
index 788b02e2825..398831cc728 100644
--- a/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
+++ b/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
@@ -62,7 +62,8 @@ using DocumentSourceGraphLookUpTest = AggregationContextFixture;
*/
class MockMongodImplementation final : public DocumentSourceNeedsMongod::MongodInterface {
public:
- MockMongodImplementation(std::deque<Document> documents) : _documents(documents) {}
+ MockMongodImplementation(std::deque<DocumentSource::GetNextResult> results)
+ : _results(std::move(results)) {}
void setOperationContext(OperationContext* opCtx) final {
MONGO_UNREACHABLE;
@@ -117,7 +118,7 @@ public:
return pipeline.getStatus();
}
- pipeline.getValue()->addInitialSource(DocumentSourceMock::create(_documents));
+ pipeline.getValue()->addInitialSource(DocumentSourceMock::create(_results));
pipeline.getValue()->injectExpressionContext(expCtx);
pipeline.getValue()->optimizePipeline();
@@ -125,17 +126,17 @@ public:
}
private:
- std::deque<Document> _documents;
+ std::deque<DocumentSource::GetNextResult> _results;
};
TEST_F(DocumentSourceGraphLookUpTest,
ShouldErrorWhenDoingInitialMatchIfDocumentInFromCollectionIsMissingId) {
auto expCtx = getExpCtx();
- std::deque<Document> inputs{Document{{"_id", 0}}};
+ std::deque<DocumentSource::GetNextResult> inputs{Document{{"_id", 0}}};
auto inputMock = DocumentSourceMock::create(std::move(inputs));
- std::deque<Document> fromContents{Document{{"to", 0}}};
+ std::deque<DocumentSource::GetNextResult> fromContents{Document{{"to", 0}}};
NamespaceString fromNs("test", "graph_lookup");
expCtx->resolvedNamespaces[fromNs.coll()] = {fromNs, std::vector<BSONObj>{}};
@@ -159,11 +160,11 @@ TEST_F(DocumentSourceGraphLookUpTest,
ShouldErrorWhenExploringGraphIfDocumentInFromCollectionIsMissingId) {
auto expCtx = getExpCtx();
- std::deque<Document> inputs{Document{{"_id", 0}}};
+ std::deque<DocumentSource::GetNextResult> inputs{Document{{"_id", 0}}};
auto inputMock = DocumentSourceMock::create(std::move(inputs));
- std::deque<Document> fromContents{Document{{"_id", "a"}, {"to", 0}, {"from", 1}},
- Document{{"to", 1}}};
+ std::deque<DocumentSource::GetNextResult> fromContents{
+ Document{{"_id", "a"}, {"to", 0}, {"from", 1}}, Document{{"to", 1}}};
NamespaceString fromNs("test", "graph_lookup");
expCtx->resolvedNamespaces[fromNs.coll()] = {fromNs, std::vector<BSONObj>{}};
@@ -187,10 +188,10 @@ TEST_F(DocumentSourceGraphLookUpTest,
ShouldErrorWhenHandlingUnwindIfDocumentInFromCollectionIsMissingId) {
auto expCtx = getExpCtx();
- std::deque<Document> inputs{Document{{"_id", 0}}};
+ std::deque<DocumentSource::GetNextResult> inputs{Document{{"_id", 0}}};
auto inputMock = DocumentSourceMock::create(std::move(inputs));
- std::deque<Document> fromContents{Document{{"to", 0}}};
+ std::deque<DocumentSource::GetNextResult> fromContents{Document{{"to", 0}}};
NamespaceString fromNs("test", "graph_lookup");
expCtx->resolvedNamespaces[fromNs.coll()] = {fromNs, std::vector<BSONObj>{}};
@@ -227,14 +228,15 @@ TEST_F(DocumentSourceGraphLookUpTest,
ShouldTraverseSubgraphIfIdOfDocumentsInFromCollectionAreNonUnique) {
auto expCtx = getExpCtx();
- std::deque<Document> inputs{Document{{"_id", 0}}};
+ std::deque<DocumentSource::GetNextResult> inputs{Document{{"_id", 0}}};
auto inputMock = DocumentSourceMock::create(std::move(inputs));
Document to0from1{{"_id", "a"}, {"to", 0}, {"from", 1}};
Document to0from2{{"_id", "a"}, {"to", 0}, {"from", 2}};
Document to1{{"_id", "b"}, {"to", 1}};
Document to2{{"_id", "c"}, {"to", 2}};
- std::deque<Document> fromContents{to1, to2, to0from1, to0from2};
+ std::deque<DocumentSource::GetNextResult> fromContents{
+ Document(to1), Document(to2), Document(to0from1), Document(to0from2)};
NamespaceString fromNs("test", "graph_lookup");
expCtx->resolvedNamespaces[fromNs.coll()] = {fromNs, std::vector<BSONObj>{}};
diff --git a/src/mongo/db/pipeline/document_source_group_test.cpp b/src/mongo/db/pipeline/document_source_group_test.cpp
index e86be1e96a8..850fc9589d1 100644
--- a/src/mongo/db/pipeline/document_source_group_test.cpp
+++ b/src/mongo/db/pipeline/document_source_group_test.cpp
@@ -29,6 +29,7 @@
#include "mongo/platform/basic.h"
#include <boost/intrusive_ptr.hpp>
+#include <deque>
#include <map>
#include <string>
#include <vector>
@@ -53,6 +54,7 @@ namespace mongo {
namespace {
using boost::intrusive_ptr;
+using std::deque;
using std::map;
using std::string;
using std::vector;
@@ -391,7 +393,7 @@ public:
}
protected:
- virtual std::deque<Document> inputData() {
+ virtual deque<DocumentSource::GetNextResult> inputData() {
return {};
}
virtual BSONObj groupSpec() {
@@ -444,7 +446,7 @@ class EmptyCollection : public CheckResultsBase {};
/** A $group performed on a single document. */
class SingleDocument : public CheckResultsBase {
- std::deque<Document> inputData() {
+ deque<DocumentSource::GetNextResult> inputData() {
return {DOC("a" << 1)};
}
virtual BSONObj groupSpec() {
@@ -458,7 +460,7 @@ class SingleDocument : public CheckResultsBase {
/** A $group performed on two values for a single key. */
class TwoValuesSingleKey : public CheckResultsBase {
- std::deque<Document> inputData() {
+ deque<DocumentSource::GetNextResult> inputData() {
return {DOC("a" << 1), DOC("a" << 2)};
}
virtual BSONObj groupSpec() {
@@ -472,7 +474,7 @@ class TwoValuesSingleKey : public CheckResultsBase {
/** A $group performed on two values with one key each. */
class TwoValuesTwoKeys : public CheckResultsBase {
- std::deque<Document> inputData() {
+ deque<DocumentSource::GetNextResult> inputData() {
return {DOC("_id" << 0 << "a" << 1), DOC("_id" << 1 << "a" << 2)};
}
virtual BSONObj groupSpec() {
@@ -489,7 +491,7 @@ class TwoValuesTwoKeys : public CheckResultsBase {
/** A $group performed on two values with two keys each. */
class FourValuesTwoKeys : public CheckResultsBase {
- std::deque<Document> inputData() {
+ deque<DocumentSource::GetNextResult> inputData() {
return {DOC("id" << 0 << "a" << 1),
DOC("id" << 1 << "a" << 2),
DOC("id" << 0 << "a" << 3),
@@ -509,7 +511,7 @@ class FourValuesTwoKeys : public CheckResultsBase {
/** A $group performed on two values with two keys each and two accumulator operations. */
class FourValuesTwoKeysTwoAccumulators : public CheckResultsBase {
- std::deque<Document> inputData() {
+ deque<DocumentSource::GetNextResult> inputData() {
return {DOC("id" << 0 << "a" << 1),
DOC("id" << 1 << "a" << 2),
DOC("id" << 0 << "a" << 3),
@@ -531,7 +533,7 @@ class FourValuesTwoKeysTwoAccumulators : public CheckResultsBase {
/** Null and undefined _id values are grouped together. */
class GroupNullUndefinedIds : public CheckResultsBase {
- std::deque<Document> inputData() {
+ deque<DocumentSource::GetNextResult> inputData() {
return {DOC("a" << BSONNULL << "b" << 100), DOC("b" << 10)};
}
virtual BSONObj groupSpec() {
@@ -548,7 +550,7 @@ class GroupNullUndefinedIds : public CheckResultsBase {
/** A complex _id expression. */
class ComplexId : public CheckResultsBase {
- std::deque<Document> inputData() {
+ deque<DocumentSource::GetNextResult> inputData() {
return {DOC("a"
<< "de"
<< "b"
@@ -579,7 +581,7 @@ class ComplexId : public CheckResultsBase {
/** An undefined accumulator value is dropped. */
class UndefinedAccumulatorValue : public CheckResultsBase {
- std::deque<Document> inputData() {
+ deque<DocumentSource::GetNextResult> inputData() {
return {Document()};
}
virtual BSONObj groupSpec() {
@@ -954,7 +956,7 @@ public:
* SERVER-6766
*/
class StringConstantIdAndAccumulatorExpressions : public CheckResultsBase {
- std::deque<Document> inputData() {
+ deque<DocumentSource::GetNextResult> inputData() {
return {Document()};
}
BSONObj groupSpec() {
@@ -974,7 +976,7 @@ public:
// Run standard base tests.
CheckResultsBase::run();
}
- std::deque<Document> inputData() {
+ deque<DocumentSource::GetNextResult> inputData() {
return {Document()};
}
BSONObj groupSpec() {
diff --git a/src/mongo/db/pipeline/document_source_mock.cpp b/src/mongo/db/pipeline/document_source_mock.cpp
index 2781bf12f9f..945aae771f7 100644
--- a/src/mongo/db/pipeline/document_source_mock.cpp
+++ b/src/mongo/db/pipeline/document_source_mock.cpp
@@ -34,16 +34,17 @@
namespace mongo {
using boost::intrusive_ptr;
+using std::deque;
-DocumentSourceMock::DocumentSourceMock(std::deque<Document> docs)
- : DocumentSource(NULL),
- queue(std::move(docs)),
+DocumentSourceMock::DocumentSourceMock(deque<GetNextResult> results)
+ : DocumentSource(nullptr),
+ queue(std::move(results)),
sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()) {}
-DocumentSourceMock::DocumentSourceMock(std::deque<Document> docs,
+DocumentSourceMock::DocumentSourceMock(deque<GetNextResult> results,
const boost::intrusive_ptr<ExpressionContext>& expCtx)
: DocumentSource(expCtx),
- queue(std::move(docs)),
+ queue(std::move(results)),
sorts(SimpleBSONObjComparator::kInstance.makeBSONObjSet()) {}
const char* DocumentSourceMock::getSourceName() const {
@@ -51,24 +52,28 @@ const char* DocumentSourceMock::getSourceName() const {
}
Value DocumentSourceMock::serialize(bool explain) const {
- return Value(DOC(getSourceName() << Document()));
+ return Value(Document{{getSourceName(), Document()}});
}
void DocumentSourceMock::dispose() {
isDisposed = true;
}
-intrusive_ptr<DocumentSourceMock> DocumentSourceMock::create(std::deque<Document> docs) {
- return new DocumentSourceMock(std::move(docs));
+intrusive_ptr<DocumentSourceMock> DocumentSourceMock::create(Document doc) {
+ return new DocumentSourceMock({std::move(doc)});
+}
+
+intrusive_ptr<DocumentSourceMock> DocumentSourceMock::create(deque<GetNextResult> results) {
+ return new DocumentSourceMock(std::move(results));
}
intrusive_ptr<DocumentSourceMock> DocumentSourceMock::create() {
- return new DocumentSourceMock(std::deque<Document>());
+ return new DocumentSourceMock(deque<GetNextResult>());
}
-intrusive_ptr<DocumentSourceMock> DocumentSourceMock::create(const Document& doc) {
- std::deque<Document> docs = {doc};
- return new DocumentSourceMock(std::move(docs));
+intrusive_ptr<DocumentSourceMock> DocumentSourceMock::create(const GetNextResult& result) {
+ deque<GetNextResult> results = {result};
+ return new DocumentSourceMock(std::move(results));
}
intrusive_ptr<DocumentSourceMock> DocumentSourceMock::create(const char* json) {
@@ -77,11 +82,11 @@ intrusive_ptr<DocumentSourceMock> DocumentSourceMock::create(const char* json) {
intrusive_ptr<DocumentSourceMock> DocumentSourceMock::create(
const std::initializer_list<const char*>& jsons) {
- std::deque<Document> docs;
+ deque<GetNextResult> results;
for (auto&& json : jsons) {
- docs.push_back(Document(fromjson(json)));
+ results.emplace_back(Document(fromjson(json)));
}
- return new DocumentSourceMock(std::move(docs));
+ return new DocumentSourceMock(std::move(results));
}
DocumentSource::GetNextResult DocumentSourceMock::getNext() {
@@ -92,8 +97,8 @@ DocumentSource::GetNextResult DocumentSourceMock::getNext() {
return GetNextResult::makeEOF();
}
- Document doc = std::move(queue.front());
+ auto next = std::move(queue.front());
queue.pop_front();
- return std::move(doc);
+ return next;
}
}
diff --git a/src/mongo/db/pipeline/document_source_replace_root_test.cpp b/src/mongo/db/pipeline/document_source_replace_root_test.cpp
index 0ba1c7ab2b9..8f7797d6890 100644
--- a/src/mongo/db/pipeline/document_source_replace_root_test.cpp
+++ b/src/mongo/db/pipeline/document_source_replace_root_test.cpp
@@ -68,7 +68,7 @@ TEST_F(ReplaceRootBasics, FieldPathAsNewRootPromotesSubdocument) {
auto replaceRoot = createReplaceRoot(BSON("newRoot"
<< "$a"));
Document subdoc = Document{{"b", 1}, {"c", "hello"}, {"d", Document{{"e", 2}}}};
- auto mock = DocumentSourceMock::create({Document{{"a", subdoc}}});
+ auto mock = DocumentSourceMock::create(Document{{"a", subdoc}});
replaceRoot->setSource(mock.get());
auto next = replaceRoot->getNext();
@@ -84,7 +84,7 @@ TEST_F(ReplaceRootBasics, DottedFieldPathAsNewRootPromotesSubdocument) {
<< "$a.b"));
// source document: {a: {b: {c: 3}}}
Document subdoc = Document{{"c", 3}};
- auto mock = DocumentSourceMock::create({Document{{"a", Document{{"b", subdoc}}}}});
+ auto mock = DocumentSourceMock::create(Document{{"a", Document{{"b", subdoc}}}});
replaceRoot->setSource(mock.get());
auto next = replaceRoot->getNext();
@@ -119,7 +119,7 @@ TEST_F(ReplaceRootBasics, FieldPathAsNewRootPromotesSubdocumentInMultipleDocumen
// object.
TEST_F(ReplaceRootBasics, ExpressionObjectForNewRootReplacesRootWithThatObject) {
auto replaceRoot = createReplaceRoot(BSON("newRoot" << BSON("b" << 1)));
- auto mock = DocumentSourceMock::create({Document{{"a", 2}}});
+ auto mock = DocumentSourceMock::create(Document{{"a", 2}});
replaceRoot->setSource(mock.get());
auto next = replaceRoot->getNext();
@@ -129,7 +129,7 @@ TEST_F(ReplaceRootBasics, ExpressionObjectForNewRootReplacesRootWithThatObject)
BSONObj newObject = BSON("a" << 1 << "b" << 2 << "arr" << BSON_ARRAY(3 << 4 << 5));
replaceRoot = createReplaceRoot(BSON("newRoot" << newObject));
- mock = DocumentSourceMock::create({Document{{"c", 2}}});
+ mock = DocumentSourceMock::create(Document{{"c", 2}});
replaceRoot->setSource(mock.get());
next = replaceRoot->getNext();
@@ -138,7 +138,7 @@ TEST_F(ReplaceRootBasics, ExpressionObjectForNewRootReplacesRootWithThatObject)
assertExhausted(replaceRoot);
replaceRoot = createReplaceRoot(BSON("newRoot" << BSON("a" << BSON("b" << 1))));
- mock = DocumentSourceMock::create({Document{{"c", 2}}});
+ mock = DocumentSourceMock::create(Document{{"c", 2}});
replaceRoot->setSource(mock.get());
next = replaceRoot->getNext();
@@ -147,7 +147,7 @@ TEST_F(ReplaceRootBasics, ExpressionObjectForNewRootReplacesRootWithThatObject)
assertExhausted(replaceRoot);
replaceRoot = createReplaceRoot(BSON("newRoot" << BSON("a" << 2)));
- mock = DocumentSourceMock::create({Document{{"b", 2}}});
+ mock = DocumentSourceMock::create(Document{{"b", 2}});
replaceRoot->setSource(mock.get());
next = replaceRoot->getNext();
@@ -189,18 +189,18 @@ TEST_F(ReplaceRootBasics, ErrorsWhenNewRootDoesNotEvaluateToAnObject) {
<< "$a"));
// A string is not an object.
- auto mock = DocumentSourceMock::create({Document{{"a", "hello"}}});
+ auto mock = DocumentSourceMock::create(Document{{"a", "hello"}});
replaceRoot->setSource(mock.get());
ASSERT_THROWS_CODE(replaceRoot->getNext(), UserException, 40228);
// An integer is not an object.
- mock = DocumentSourceMock::create({Document{{"a", 5}}});
+ mock = DocumentSourceMock::create(Document{{"a", 5}});
replaceRoot->setSource(mock.get());
ASSERT_THROWS_CODE(replaceRoot->getNext(), UserException, 40228);
// Literals are not objects.
replaceRoot = createReplaceRoot(BSON("newRoot" << BSON("$literal" << 1)));
- mock = DocumentSourceMock::create({Document()});
+ mock = DocumentSourceMock::create(Document());
replaceRoot->setSource(mock.get());
ASSERT_THROWS_CODE(replaceRoot->getNext(), UserException, 40228);
assertExhausted(replaceRoot);
@@ -208,7 +208,7 @@ TEST_F(ReplaceRootBasics, ErrorsWhenNewRootDoesNotEvaluateToAnObject) {
// Most operator expressions do not resolve to objects.
replaceRoot = createReplaceRoot(BSON("newRoot" << BSON("$and"
<< "$a")));
- mock = DocumentSourceMock::create({Document{{"a", true}}});
+ mock = DocumentSourceMock::create(Document{{"a", true}});
replaceRoot->setSource(mock.get());
ASSERT_THROWS_CODE(replaceRoot->getNext(), UserException, 40228);
assertExhausted(replaceRoot);
@@ -220,12 +220,12 @@ TEST_F(ReplaceRootBasics, ErrorsIfNewRootFieldPathDoesNotExist) {
auto replaceRoot = createReplaceRoot(BSON("newRoot"
<< "$a"));
- auto mock = DocumentSourceMock::create({Document()});
+ auto mock = DocumentSourceMock::create(Document());
replaceRoot->setSource(mock.get());
ASSERT_THROWS_CODE(replaceRoot->getNext(), UserException, 40232);
assertExhausted(replaceRoot);
- mock = DocumentSourceMock::create({Document{{"e", Document{{"b", Document{{"c", 3}}}}}}});
+ mock = DocumentSourceMock::create(Document{{"e", Document{{"b", Document{{"c", 3}}}}}});
replaceRoot->setSource(mock.get());
ASSERT_THROWS_CODE(replaceRoot->getNext(), UserException, 40232);
assertExhausted(replaceRoot);
diff --git a/src/mongo/db/pipeline/document_source_sort_test.cpp b/src/mongo/db/pipeline/document_source_sort_test.cpp
index ae409910fd0..1d54a9a5618 100644
--- a/src/mongo/db/pipeline/document_source_sort_test.cpp
+++ b/src/mongo/db/pipeline/document_source_sort_test.cpp
@@ -55,6 +55,7 @@ bool isMongos() {
namespace {
using boost::intrusive_ptr;
+using std::deque;
using std::string;
using std::vector;
@@ -184,7 +185,7 @@ TEST_F(DocumentSourceSortTest, OutputSort) {
class DocumentSourceSortExecutionTest : public DocumentSourceSortTest {
public:
- void checkResults(std::deque<Document> inputDocs,
+ void checkResults(deque<DocumentSource::GetNextResult> inputDocs,
BSONObj sortSpec,
string expectedResultSetString) {
createSort(sortSpec);
diff --git a/src/mongo/db/pipeline/document_source_unwind_test.cpp b/src/mongo/db/pipeline/document_source_unwind_test.cpp
index 5bb251a64b0..6be7ed5b703 100644
--- a/src/mongo/db/pipeline/document_source_unwind_test.cpp
+++ b/src/mongo/db/pipeline/document_source_unwind_test.cpp
@@ -104,7 +104,7 @@ protected:
return "index";
}
- virtual deque<Document> inputData() {
+ virtual deque<DocumentSource::GetNextResult> inputData() {
return {};
}
@@ -259,7 +259,7 @@ class Empty : public CheckResultsBase {};
* passed, the document is preserved.
*/
class EmptyArray : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << BSONArray())};
}
string expectedPreservedResultSetString() const override {
@@ -275,7 +275,7 @@ class EmptyArray : public CheckResultsBase {
* passed, the document is preserved.
*/
class MissingValue : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0)};
}
string expectedPreservedResultSetString() const override {
@@ -291,7 +291,7 @@ class MissingValue : public CheckResultsBase {
* the document is preserved.
*/
class Null : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << BSONNULL)};
}
string expectedPreservedResultSetString() const override {
@@ -307,7 +307,7 @@ class Null : public CheckResultsBase {
* passed, the document is preserved.
*/
class Undefined : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << BSONUndefined)};
}
string expectedPreservedResultSetString() const override {
@@ -320,7 +320,7 @@ class Undefined : public CheckResultsBase {
/** Unwind an array with one value. */
class OneValue : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << DOC_ARRAY(1))};
}
string expectedResultSetString() const override {
@@ -333,7 +333,7 @@ class OneValue : public CheckResultsBase {
/** Unwind an array with two values. */
class TwoValues : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << DOC_ARRAY(1 << 2))};
}
string expectedResultSetString() const override {
@@ -346,7 +346,7 @@ class TwoValues : public CheckResultsBase {
/** Unwind an array with two values, one of which is null. */
class ArrayWithNull : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << DOC_ARRAY(1 << BSONNULL))};
}
string expectedResultSetString() const override {
@@ -359,7 +359,7 @@ class ArrayWithNull : public CheckResultsBase {
/** Unwind two documents with arrays. */
class TwoDocuments : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << DOC_ARRAY(1 << 2)),
DOC("_id" << 1 << "a" << DOC_ARRAY(3 << 4))};
}
@@ -374,7 +374,7 @@ class TwoDocuments : public CheckResultsBase {
/** Unwind an array in a nested document. */
class NestedArray : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << DOC("b" << DOC_ARRAY(1 << 2) << "c" << 3))};
}
string unwindFieldPath() const override {
@@ -394,7 +394,7 @@ class NestedArray : public CheckResultsBase {
* preserveNullAndEmptyArrays is specified.
*/
class NonObjectParent : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << 4)};
}
string unwindFieldPath() const override {
@@ -410,7 +410,7 @@ class NonObjectParent : public CheckResultsBase {
/** Unwind an array in a doubly nested document. */
class DoubleNestedArray : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a"
<< DOC("b" << DOC("d" << DOC_ARRAY(1 << 2) << "e" << 4) << "c" << 3))};
}
@@ -428,7 +428,7 @@ class DoubleNestedArray : public CheckResultsBase {
/** Unwind several documents in a row. */
class SeveralDocuments : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << DOC_ARRAY(1 << 2 << 3)),
DOC("_id" << 1),
DOC("_id" << 2),
@@ -469,7 +469,7 @@ class SeveralDocuments : public CheckResultsBase {
/** Unwind several more documents in a row. */
class SeveralMoreDocuments : public CheckResultsBase {
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << BSONNULL),
DOC("_id" << 1),
DOC("_id" << 2 << "a" << DOC_ARRAY("a"
@@ -535,7 +535,7 @@ class IncludeArrayIndexSubObject : public CheckResultsBase {
string indexPath() const override {
return "b.index";
}
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << DOC_ARRAY(0) << "b" << DOC("x" << 100)),
DOC("_id" << 1 << "a" << 1 << "b" << DOC("x" << 100)),
DOC("_id" << 2 << "b" << DOC("x" << 100))};
@@ -563,7 +563,7 @@ class IncludeArrayIndexOverrideExisting : public CheckResultsBase {
string indexPath() const override {
return "b";
}
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << DOC_ARRAY(0) << "b" << 100),
DOC("_id" << 1 << "a" << 1 << "b" << 100),
DOC("_id" << 2 << "b" << 100)};
@@ -589,7 +589,7 @@ class IncludeArrayIndexOverrideExistingNested : public CheckResultsBase {
string indexPath() const override {
return "b.index";
}
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a" << DOC_ARRAY(0) << "b" << 100),
DOC("_id" << 1 << "a" << 1 << "b" << 100),
DOC("_id" << 2 << "b" << 100)};
@@ -618,7 +618,7 @@ class IncludeArrayIndexOverrideUnwindPath : public CheckResultsBase {
string indexPath() const override {
return "a";
}
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {
DOC("_id" << 0 << "a" << DOC_ARRAY(5)), DOC("_id" << 1 << "a" << 1), DOC("_id" << 2)};
}
@@ -644,7 +644,7 @@ class IncludeArrayIndexWithinUnwindPath : public CheckResultsBase {
string indexPath() const override {
return "a.index";
}
- deque<Document> inputData() override {
+ deque<DocumentSource::GetNextResult> inputData() override {
return {DOC("_id" << 0 << "a"
<< DOC_ARRAY(100 << DOC("b" << 1) << DOC("b" << 1 << "index" << -1)))};
}
diff --git a/src/mongo/db/pipeline/tee_buffer_test.cpp b/src/mongo/db/pipeline/tee_buffer_test.cpp
index ae6f6b614f3..172a6def935 100644
--- a/src/mongo/db/pipeline/tee_buffer_test.cpp
+++ b/src/mongo/db/pipeline/tee_buffer_test.cpp
@@ -64,25 +64,25 @@ TEST(TeeBufferTest, ShouldBeExhaustedIfInputIsExhausted) {
}
TEST(TeeBufferTest, ShouldProvideAllResultsWithoutPauseIfTheyFitInOneBatch) {
- std::deque<Document> inputDocs{Document{{"a", 1}}, Document{{"a", 2}}};
+ std::deque<DocumentSource::GetNextResult> inputDocs{Document{{"a", 1}}, Document{{"a", 2}}};
auto mock = DocumentSourceMock::create(inputDocs);
auto teeBuffer = TeeBuffer::create(1);
teeBuffer->setSource(mock.get());
auto next = teeBuffer->getNext(0);
ASSERT_TRUE(next.isAdvanced());
- ASSERT_DOCUMENT_EQ(next.getDocument(), inputDocs.front());
+ ASSERT_DOCUMENT_EQ(next.getDocument(), inputDocs.front().getDocument());
next = teeBuffer->getNext(0);
ASSERT_TRUE(next.isAdvanced());
- ASSERT_DOCUMENT_EQ(next.getDocument(), inputDocs.back());
+ ASSERT_DOCUMENT_EQ(next.getDocument(), inputDocs.back().getDocument());
ASSERT_TRUE(teeBuffer->getNext(0).isEOF());
ASSERT_TRUE(teeBuffer->getNext(0).isEOF());
}
TEST(TeeBufferTest, ShouldProvideAllResultsWithoutPauseIfOnlyOneConsumer) {
- std::deque<Document> inputDocs{Document{{"a", 1}}, Document{{"a", 2}}};
+ std::deque<DocumentSource::GetNextResult> inputDocs{Document{{"a", 1}}, Document{{"a", 2}}};
auto mock = DocumentSourceMock::create(inputDocs);
const size_t bufferBytes = 1; // Both docs won't fit in a single batch.
@@ -91,18 +91,18 @@ TEST(TeeBufferTest, ShouldProvideAllResultsWithoutPauseIfOnlyOneConsumer) {
auto next = teeBuffer->getNext(0);
ASSERT_TRUE(next.isAdvanced());
- ASSERT_DOCUMENT_EQ(next.getDocument(), inputDocs.front());
+ ASSERT_DOCUMENT_EQ(next.getDocument(), inputDocs.front().getDocument());
next = teeBuffer->getNext(0);
ASSERT_TRUE(next.isAdvanced());
- ASSERT_DOCUMENT_EQ(next.getDocument(), inputDocs.back());
+ ASSERT_DOCUMENT_EQ(next.getDocument(), inputDocs.back().getDocument());
ASSERT_TRUE(teeBuffer->getNext(0).isEOF());
ASSERT_TRUE(teeBuffer->getNext(0).isEOF());
}
TEST(TeeBufferTest, ShouldTellConsumerToPauseIfItFinishesBatchBeforeOtherConsumers) {
- std::deque<Document> inputDocs{Document{{"a", 1}}, Document{{"a", 2}}};
+ std::deque<DocumentSource::GetNextResult> inputDocs{Document{{"a", 1}}, Document{{"a", 2}}};
auto mock = DocumentSourceMock::create(inputDocs);
const size_t nConsumers = 2;
@@ -112,19 +112,19 @@ TEST(TeeBufferTest, ShouldTellConsumerToPauseIfItFinishesBatchBeforeOtherConsume
auto next0 = teeBuffer->getNext(0);
ASSERT_TRUE(next0.isAdvanced());
- ASSERT_DOCUMENT_EQ(next0.getDocument(), inputDocs.front());
+ ASSERT_DOCUMENT_EQ(next0.getDocument(), inputDocs.front().getDocument());
ASSERT_TRUE(teeBuffer->getNext(0).isPaused()); // Consumer #1 hasn't seen the first doc yet.
ASSERT_TRUE(teeBuffer->getNext(0).isPaused());
auto next1 = teeBuffer->getNext(1);
ASSERT_TRUE(next1.isAdvanced());
- ASSERT_DOCUMENT_EQ(next1.getDocument(), inputDocs.front());
+ ASSERT_DOCUMENT_EQ(next1.getDocument(), inputDocs.front().getDocument());
// Both consumers should be able to advance now. We'll advance consumer #1.
next1 = teeBuffer->getNext(1);
ASSERT_TRUE(next1.isAdvanced());
- ASSERT_DOCUMENT_EQ(next1.getDocument(), inputDocs.back());
+ ASSERT_DOCUMENT_EQ(next1.getDocument(), inputDocs.back().getDocument());
// Consumer #1 should be blocked now. The next input is EOF, but the TeeBuffer didn't get that
// far, since the first doc filled up the buffer.
@@ -134,7 +134,7 @@ TEST(TeeBufferTest, ShouldTellConsumerToPauseIfItFinishesBatchBeforeOtherConsume
// Now exhaust consumer #0.
next0 = teeBuffer->getNext(0);
ASSERT_TRUE(next0.isAdvanced());
- ASSERT_DOCUMENT_EQ(next0.getDocument(), inputDocs.back());
+ ASSERT_DOCUMENT_EQ(next0.getDocument(), inputDocs.back().getDocument());
ASSERT_TRUE(teeBuffer->getNext(0).isEOF());
ASSERT_TRUE(teeBuffer->getNext(0).isEOF());
@@ -145,7 +145,7 @@ TEST(TeeBufferTest, ShouldTellConsumerToPauseIfItFinishesBatchBeforeOtherConsume
}
TEST(TeeBufferTest, ShouldAllowOtherConsumersToAdvanceOnceTrailingConsumerIsDisposed) {
- std::deque<Document> inputDocs{Document{{"a", 1}}, Document{{"a", 2}}};
+ std::deque<DocumentSource::GetNextResult> inputDocs{Document{{"a", 1}}, Document{{"a", 2}}};
auto mock = DocumentSourceMock::create(inputDocs);
const size_t nConsumers = 2;
@@ -155,7 +155,7 @@ TEST(TeeBufferTest, ShouldAllowOtherConsumersToAdvanceOnceTrailingConsumerIsDisp
auto next0 = teeBuffer->getNext(0);
ASSERT_TRUE(next0.isAdvanced());
- ASSERT_DOCUMENT_EQ(next0.getDocument(), inputDocs.front());
+ ASSERT_DOCUMENT_EQ(next0.getDocument(), inputDocs.front().getDocument());
ASSERT_TRUE(teeBuffer->getNext(0).isPaused()); // Consumer #1 hasn't seen the first doc yet.
ASSERT_TRUE(teeBuffer->getNext(0).isPaused());
@@ -166,7 +166,7 @@ TEST(TeeBufferTest, ShouldAllowOtherConsumersToAdvanceOnceTrailingConsumerIsDisp
// Consumer #0 should be able to advance now.
next0 = teeBuffer->getNext(0);
ASSERT_TRUE(next0.isAdvanced());
- ASSERT_DOCUMENT_EQ(next0.getDocument(), inputDocs.back());
+ ASSERT_DOCUMENT_EQ(next0.getDocument(), inputDocs.back().getDocument());
ASSERT_TRUE(teeBuffer->getNext(0).isEOF());
ASSERT_TRUE(teeBuffer->getNext(0).isEOF());