@@ -173,6 +173,11 @@ class DurabilityEPBucketTest : public STParameterizedBucketTest {
173173 uint64_t expectedValue);
174174};
175175
176+ /* *
177+ * Test fixtures for persistent bucket tests that only run under couchstore
178+ */
179+ class DurabilityCouchstoreBucketTest : public DurabilityEPBucketTest {};
180+
176181/* *
177182 * Test fixture for Durability-related tests applicable to ephemeral and
178183 * persistent buckets with either eviction modes.
@@ -1801,6 +1806,95 @@ TEST_P(DurabilityEPBucketTest, DoNotExpirePendingItem) {
18011806 EXPECT_TRUE (gv.item ->isDeleted ());
18021807}
18031808
1809+ // @TODO Rocksdb when we have manual compaction/compaction filtering this test
1810+ // should be made to pass.
1811+ TEST_P (DurabilityCouchstoreBucketTest, RemoveCommittedPreparesAtCompaction) {
1812+ setVBucketToActiveWithValidTopology ();
1813+ using namespace cb ::durability;
1814+
1815+ auto key = makeStoredDocKey (" key" );
1816+ auto req = Requirements (Level::Majority, Timeout (1000 ));
1817+ auto pending = makePendingItem (key, " value" , req);
1818+ EXPECT_EQ (ENGINE_EWOULDBLOCK, store->set (*pending, cookie));
1819+
1820+ auto vb = store->getVBucket (vbid);
1821+ vb->commit (key,
1822+ 1 /* prepareSeqno*/ ,
1823+ {} /* commitSeqno*/ ,
1824+ vb->lockCollections (key));
1825+
1826+ flushVBucketToDiskIfPersistent (vbid, 2 );
1827+
1828+ CompactionConfig config;
1829+ compaction_ctx cctx (config, 0 );
1830+ cctx.expiryCallback = std::make_shared<FailOnExpiryCallback>();
1831+
1832+ auto * kvstore = store->getOneRWUnderlying ();
1833+
1834+ // Sanity - prepare exists before compaction
1835+ DiskDocKey prefixedKey (key, true /* prepare*/ );
1836+ auto gv = kvstore->get (prefixedKey, Vbid (0 ));
1837+ EXPECT_EQ (ENGINE_SUCCESS, gv.getStatus ());
1838+
1839+ EXPECT_TRUE (kvstore->compactDB (&cctx));
1840+
1841+ // Check the committed item on disk.
1842+ gv = kvstore->get (DiskDocKey (key), Vbid (0 ));
1843+ EXPECT_EQ (ENGINE_SUCCESS, gv.getStatus ());
1844+ EXPECT_EQ (" value" , gv.item ->getValue ()->to_s ());
1845+
1846+ // Check the Prepare on disk
1847+ gv = kvstore->get (prefixedKey, Vbid (0 ));
1848+ EXPECT_EQ (ENGINE_KEY_ENOENT, gv.getStatus ());
1849+ }
1850+
1851+ TEST_P (DurabilityCouchstoreBucketTest, RemoveAbortedPreparedAtCompaction) {
1852+ setVBucketToActiveWithValidTopology ();
1853+ using namespace cb ::durability;
1854+
1855+ auto key = makeStoredDocKey (" key" );
1856+ auto req = Requirements (Level::Majority, Timeout (1000 ));
1857+ auto pending = makePendingItem (key, " value" , req);
1858+ EXPECT_EQ (ENGINE_EWOULDBLOCK, store->set (*pending, cookie));
1859+
1860+ // Flush prepare
1861+ flushVBucketToDiskIfPersistent (vbid, 1 );
1862+
1863+ auto vb = store->getVBucket (vbid);
1864+ vb->abort (key,
1865+ 1 /* prepareSeqno*/ ,
1866+ {} /* commitSeqno*/ ,
1867+ vb->lockCollections (key));
1868+
1869+ // We can't purge the last item so write a dummy
1870+ auto dummyKey = makeStoredDocKey (" dummy" );
1871+ auto dummyItem = makeCommittedItem (dummyKey, " dummyValue" );
1872+ EXPECT_EQ (ENGINE_SUCCESS, store->set (*dummyItem, cookie));
1873+
1874+ // Flush Abort and dummy
1875+ flushVBucketToDiskIfPersistent (vbid, 2 );
1876+
1877+ CompactionConfig config;
1878+ compaction_ctx cctx (config, 0 );
1879+ cctx.expiryCallback = std::make_shared<FailOnExpiryCallback>();
1880+ auto * kvstore = store->getOneRWUnderlying ();
1881+ EXPECT_TRUE (kvstore->compactDB (&cctx));
1882+
1883+ // Check the Abort on disk. We won't remove it until the purge interval has
1884+ // passed because we need it to ensure we can resume a replica that had an
1885+ // outstanding prepare within the purge interval.
1886+ DiskDocKey prefixedKey (key, true /* prepare*/ );
1887+ auto gv = kvstore->get (prefixedKey, Vbid (0 ));
1888+ EXPECT_EQ (ENGINE_SUCCESS, gv.getStatus ());
1889+
1890+ cctx.compactConfig .purge_before_ts = std::numeric_limits<uint64_t >::max ();
1891+ EXPECT_TRUE (kvstore->compactDB (&cctx));
1892+
1893+ // Now the Abort should be gone
1894+ gv = kvstore->get (prefixedKey, Vbid (0 ));
1895+ EXPECT_EQ (ENGINE_KEY_ENOENT, gv.getStatus ());
1896+ }
1897+
18041898template <typename F>
18051899void DurabilityEphemeralBucketTest::testPurgeCompletedPrepare (F& func) {
18061900 setVBucketStateAndRunPersistTask (
@@ -1961,6 +2055,12 @@ TEST_P(DurabilityBucketTest, ActiveToReplicaAndCommit) {
19612055 ASSERT_EQ (ENGINE_SUCCESS, vb.commit (key, 1 , 4 , vb.lockCollections (key)));
19622056}
19632057
2058+ // Test cases which run against couchstore
2059+ INSTANTIATE_TEST_CASE_P (AllBackends,
2060+ DurabilityCouchstoreBucketTest,
2061+ STParameterizedBucketTest::persistentConfigValues (),
2062+ STParameterizedBucketTest::PrintToStringParamName);
2063+
19642064// Test cases which run against all persistent storage backends.
19652065INSTANTIATE_TEST_CASE_P (
19662066 AllBackends,
0 commit comments