2121#include " tests/module_tests/test_helpers.h"
2222#include " vbucket.h"
2323
24+ #include < folly/portability/GMock.h>
25+ #include < folly/portability/GTest.h>
2426#include < spdlog/fmt/fmt.h>
2527
2628class CollectionsOSODcpTest : public CollectionsDcpParameterizedTest {
@@ -29,10 +31,12 @@ class CollectionsOSODcpTest : public CollectionsDcpParameterizedTest {
2931 }
3032
3133 void SetUp () override {
32- config_string += " collections_enabled=true" ;
3334 // Disable OSO backfill auto-selection to simplify most of the
3435 // functional tests - set to always.
35- config_string += " ;dcp_oso_backfill=enabled" ;
36+ if (!config_string.empty ()) {
37+ config_string += " ;" ;
38+ }
39+ config_string += " dcp_oso_backfill=enabled" ;
3640
3741 CollectionsDcpParameterizedTest::SetUp ();
3842 producers = std::make_unique<CollectionsDcpTestProducers>();
@@ -997,6 +1001,90 @@ TEST_P(CollectionsOSODcpAutoSelectTest, SmallThresholdDynamic) {
9971001 testDcpOsoBackfillAutomaticMode (0.004 , 0.006 , 300 );
9981002}
9991003
1004+ class CollectionsOSOMultiTest : public CollectionsOSODcpTest {
1005+ public:
1006+ void SetUp () override {
1007+ CollectionsOSODcpTest::SetUp ();
1008+ std::string msg;
1009+ ASSERT_EQ (cb::engine_errc::success,
1010+ engine->setDcpParam (
1011+ " dcp_oso_max_collections_per_backfill" , " 100" , msg));
1012+ }
1013+ };
1014+
1015+ // The test uses three collections and filters for two and expects the two
1016+ // filtered collections to be sent in the OSO snapshot
1017+ TEST_P (CollectionsOSOMultiTest, multi) {
1018+ using namespace cb ::mcbp;
1019+
1020+ CollectionsManifest cm;
1021+ setCollections (cookie,
1022+ cm.add (CollectionEntry::vegetable)
1023+ .add (CollectionEntry::fruit)
1024+ .add (CollectionEntry::dairy));
1025+ flush_vbucket_to_disk (vbid, 3 );
1026+
1027+ // 3 collections
1028+ std::array<CollectionID, 3 > collections = {CollectionUid::fruit,
1029+ CollectionUid::dairy,
1030+ CollectionUid::vegetable};
1031+ // 4 keys
1032+ std::array<std::string, 4 > keys = {{" a" , " b" , " c" , " d" }};
1033+
1034+ // combine!
1035+ for (auto cid : collections) {
1036+ for (const auto & key : keys) {
1037+ store_item (vbid, makeStoredDocKey (key, cid), " value" + key);
1038+ }
1039+ flush_vbucket_to_disk (vbid, keys.size ());
1040+ }
1041+
1042+ ensureDcpWillBackfill ();
1043+
1044+ // filter on collections 1 and 2 of the 3 that have been written to.
1045+ nlohmann::json filter = {{" collections" ,
1046+ {collections.at (1 ).to_string (false ),
1047+ collections.at (2 ).to_string (false )}}};
1048+ createDcpObjects (filter.dump (), OutOfOrderSnapshots::Yes, 0 );
1049+
1050+ runBackfill ();
1051+
1052+ stepAndExpect (ClientOpcode::DcpOsoSnapshot);
1053+ EXPECT_EQ (uint32_t (request::DcpOsoSnapshotFlags::Start),
1054+ producers->last_oso_snapshot_flags );
1055+
1056+ std::unordered_set<std::string> keys1, keys2;
1057+
1058+ // This test is written to not assume any ordering of the snapshot.
1059+ // This loop will collect all keys and check they are for the correct
1060+ // collections and the correct keys
1061+ while (producer->stepWithBorderGuard (*producers) ==
1062+ cb::engine_errc::success &&
1063+ producers->last_op != ClientOpcode::DcpOsoSnapshot) {
1064+ EXPECT_THAT (producers->last_op ,
1065+ testing::AnyOf (ClientOpcode::DcpSystemEvent,
1066+ ClientOpcode::DcpMutation));
1067+ EXPECT_THAT (producers->last_collection_id ,
1068+ testing::AnyOf (collections.at (1 ), collections.at (2 )));
1069+
1070+ if (producers->last_op == ClientOpcode::DcpMutation) {
1071+ EXPECT_THAT (producers->last_key , testing::AnyOfArray (keys));
1072+
1073+ if (producers->last_collection_id == collections.at (1 )) {
1074+ keys1.emplace (producers->last_key );
1075+ } else {
1076+ keys2.emplace (producers->last_key );
1077+ }
1078+ }
1079+ }
1080+
1081+ EXPECT_EQ (uint32_t (request::DcpOsoSnapshotFlags::End),
1082+ producers->last_oso_snapshot_flags );
1083+ // All Keys from each collection must of been observed
1084+ EXPECT_EQ (keys.size (), keys1.size ());
1085+ EXPECT_EQ (keys.size (), keys2.size ());
1086+ }
1087+
10001088INSTANTIATE_TEST_SUITE_P (CollectionsOSOEphemeralTests,
10011089 CollectionsOSOEphemeralTest,
10021090 STParameterizedBucketTest::ephConfigValues (),
@@ -1011,3 +1099,8 @@ INSTANTIATE_TEST_SUITE_P(CollectionsOSODcpAutoSelectTests,
10111099 CollectionsOSODcpAutoSelectTest,
10121100 STParameterizedBucketTest::persistentConfigValues (),
10131101 STParameterizedBucketTest::PrintToStringParamName);
1102+
1103+ INSTANTIATE_TEST_SUITE_P (CollectionsOSOMultiTests,
1104+ CollectionsOSOMultiTest,
1105+ STParameterizedBucketTest::persistentConfigValues (),
1106+ STParameterizedBucketTest::PrintToStringParamName);
0 commit comments