@@ -148,7 +148,8 @@ class WithMetaTest : public SingleThreadedEPBucketTest {
148148 int options,
149149 protocol_binary_response_status expectedResponseStatus,
150150 const std::string& key,
151- const std::string& value) {
151+ const std::string& value,
152+ const std::vector<char >& emd) {
152153 auto swm = buildWithMetaPacket (op,
153154 0 /* datatype*/ ,
154155 vbid,
@@ -157,7 +158,7 @@ class WithMetaTest : public SingleThreadedEPBucketTest {
157158 itemMeta,
158159 key,
159160 value,
160- {} ,
161+ emd ,
161162 options);
162163 if (expectedResponseStatus == PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET) {
163164 EXPECT_EQ (ENGINE_NOT_MY_VBUCKET, callEngine (op, swm));
@@ -175,18 +176,14 @@ class WithMetaTest : public SingleThreadedEPBucketTest {
175176 int options,
176177 bool withValue,
177178 protocol_binary_response_status expectedResponseStatus,
178- ENGINE_ERROR_CODE expectedGetReturnValue) {
179+ ENGINE_ERROR_CODE expectedGetReturnValue,
180+ const std::vector<char >& emd = {}) {
179181 std::string key = " mykey" ;
180182 std::string value;
181183 if (withValue) {
182184 value = createXattrValue (" myvalue" ); // xattr but stored as raw
183185 }
184- oneOp (op,
185- itemMeta,
186- options,
187- expectedResponseStatus,
188- key,
189- value);
186+ oneOp (op, itemMeta, options, expectedResponseStatus, key, value, emd);
190187 checkGetItem (key, value, itemMeta, expectedGetReturnValue);
191188 }
192189
@@ -655,7 +652,7 @@ void WithMetaTest::conflict_lose(protocol_binary_command op,
655652 EXPECT_EQ (PROTOCOL_BINARY_RESPONSE_SUCCESS, getAddResponseStatus ());
656653
657654 for (const auto & td : testData) {
658- oneOp (op, td.meta , options, td.expectedStatus , key, value);
655+ oneOp (op, td.meta , options, td.expectedStatus , key, value, {} );
659656 }
660657}
661658
@@ -1359,6 +1356,63 @@ TEST_P(DelWithMetaTest, setting_deleteTime) {
13591356 EXPECT_EQ (itemMeta.exptime , metadata.exptime );
13601357}
13611358
1359+ TEST_P (DelWithMetaTest, MB_31141) {
1360+ ItemMetaData itemMeta{0xdeadbeef , 0xf00dcafe , 0xfacefeed , expiry};
1361+ // Do a delete with valid extended meta
1362+ // see - ep-engine/docs/protocol/del_with_meta.md
1363+ oneOpAndCheck (op,
1364+ itemMeta,
1365+ 0 , // no-options
1366+ withValue,
1367+ PROTOCOL_BINARY_RESPONSE_SUCCESS,
1368+ withValue ? ENGINE_SUCCESS : ENGINE_EWOULDBLOCK,
1369+ {0x01 , 0x01 , 0x00 , 0x01 , 0x01 });
1370+
1371+ EXPECT_EQ (std::make_pair (false , size_t (1 )),
1372+ getEPBucket ().flushVBucket (vbid));
1373+
1374+ auto options = get_options_t (QUEUE_BG_FETCH | GET_DELETED_VALUE);
1375+ auto result = store->get (
1376+ {" mykey" , DocNamespace::DefaultCollection}, vbid, cookie, options);
1377+ EXPECT_EQ (ENGINE_EWOULDBLOCK, result.getStatus ());
1378+
1379+ // Run the BGFetcher task
1380+ MockGlobalTask mockTask (engine->getTaskable (), TaskId::MultiBGFetcherTask);
1381+ store->getVBucket (vbid)->getShard ()->getBgFetcher ()->run (&mockTask);
1382+
1383+ result = store->get (
1384+ {" mykey" , DocNamespace::DefaultCollection}, vbid, cookie, options);
1385+ ASSERT_EQ (ENGINE_SUCCESS, result.getStatus ());
1386+
1387+ // Before the fix 5.0+ could of left the value as 5, the size of the
1388+ // extended metadata
1389+ int expectedSize = withValue ? 275 : 0 ;
1390+ EXPECT_EQ (expectedSize, result.item ->getNBytes ());
1391+ }
1392+
1393+ TEST_P (AddSetWithMetaTest, MB_31141) {
1394+ ItemMetaData itemMeta{0xdeadbeef , 0xf00dcafe , 0xfacefeed , expiry};
1395+ // Do a set/add with valid extended meta
1396+ // see - ep-engine/docs/protocol/del_with_meta.md
1397+ oneOpAndCheck (GetParam (),
1398+ itemMeta,
1399+ 0 , // no-options
1400+ true ,
1401+ PROTOCOL_BINARY_RESPONSE_SUCCESS,
1402+ ENGINE_SUCCESS,
1403+ {0x01 , 0x01 , 0x00 , 0x01 , 0x01 });
1404+
1405+ EXPECT_EQ (std::make_pair (false , size_t (1 )),
1406+ getEPBucket ().flushVBucket (vbid));
1407+
1408+ auto options = get_options_t (QUEUE_BG_FETCH);
1409+ auto result = store->get (
1410+ {" mykey" , DocNamespace::DefaultCollection}, vbid, cookie, options);
1411+ ASSERT_EQ (ENGINE_SUCCESS, result.getStatus ());
1412+ // Only the value should come back
1413+ EXPECT_EQ (275 , result.item ->getNBytes ());
1414+ }
1415+
13621416auto opcodeValues = ::testing::Values(PROTOCOL_BINARY_CMD_SET_WITH_META,
13631417 PROTOCOL_BINARY_CMD_SETQ_WITH_META,
13641418 PROTOCOL_BINARY_CMD_ADD_WITH_META,
0 commit comments