Skip to content

Commit cbf9eb2

Browse files
committed
Merge remote-tracking branch 'couchbase/morpheus'
* couchbase/morpheus: CBD-6348: Fix compile warnings CBD-6348: [BP] Replace sprintf with snprintf CBD-6348: [BP] Use std::string_view instead of gsl::cstring_span MB-68916: Fix exception throw at EPE::initilize MB-68916: Fix ep_testsuite_dcp MB-68916: Remove continuous_dcp_ctx boilerplate from ep_testsuite_dcp Change-Id: Ibe7c0b6c05f0c9c487c22113ac466d10c76b8c67
2 parents 9e6c2c2 + 9a39e31 commit cbf9eb2

3 files changed

Lines changed: 106 additions & 100 deletions

File tree

engines/ep/src/ep_engine.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1892,6 +1892,24 @@ cb::engine_errc EventuallyPersistentEngine::initialize(
18921892
const nlohmann::json& encryption,
18931893
std::string_view chronicleAuthToken,
18941894
const nlohmann::json& collectionManifest) {
1895+
auto handle = acquireEngine(this);
1896+
try {
1897+
return handle->initializeInner(
1898+
config, encryption, chronicleAuthToken, collectionManifest);
1899+
} catch (const cb::engine_error& e) {
1900+
NonBucketAllocationGuard guard;
1901+
throw cb::engine_error(e.engine_code(), e.what());
1902+
} catch (const std::exception& e) {
1903+
NonBucketAllocationGuard guard;
1904+
throw std::runtime_error(e.what());
1905+
}
1906+
}
1907+
1908+
cb::engine_errc EventuallyPersistentEngine::initializeInner(
1909+
std::string_view config,
1910+
const nlohmann::json& encryption,
1911+
std::string_view chronicleAuthToken,
1912+
const nlohmann::json& collectionManifest) {
18951913
if (config.empty()) {
18961914
return cb::engine_errc::invalid_arguments;
18971915
}

engines/ep/src/ep_engine.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,11 @@ class EventuallyPersistentEngine : public EngineIface, public DcpIface {
12011201
protected:
12021202
friend class EpEngineValueChangeListener;
12031203

1204+
cb::engine_errc initializeInner(std::string_view,
1205+
const nlohmann::json&,
1206+
std::string_view,
1207+
const nlohmann::json&);
1208+
12041209
cb::engine_errc compactDatabaseInner(
12051210
CookieIface& cookie,
12061211
Vbid vbid,

engines/ep/tests/ep_testsuite_dcp.cc

Lines changed: 83 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ class TestDcpConsumer {
237237
stream_ctxs.push_back(ctx);
238238
}
239239

240+
void openConnectionAndStreams();
241+
240242
void run(bool openConn = true);
241243

242244
// Stop the thread if it is running. This is safe to be called from
@@ -381,23 +383,23 @@ void TestDcpConsumer::deleteOrExpireCase(TestDcpConsumer::VBStats& stats,
381383
}
382384
}
383385

384-
void TestDcpConsumer::run(bool openConn) {
386+
void TestDcpConsumer::openConnectionAndStreams() {
385387
checkle(size_t{1}, stream_ctxs.size(), "No dcp_stream arguments provided!");
386-
387-
/* Open the connection with the DCP producer */
388-
if (openConn) {
389-
openConnection();
390-
}
391-
388+
openConnection();
392389
if (collectionFilter) {
393390
// Enable noop ops needed for collections
394391
checkeq(cb::engine_errc::success,
395392
dcp->control(
396393
*cookie, opaque, DcpControlKeys::EnableNoop, "true"),
397394
"Failed to enable noop");
398395
}
399-
/* Open streams in the above open connection */
400396
openStreams();
397+
}
398+
399+
void TestDcpConsumer::run(bool openConn) {
400+
if (openConn) {
401+
openConnectionAndStreams();
402+
}
401403

402404
size_t num_stream_ends_received = 0;
403405
uint32_t bytes_read = 0;
@@ -1132,15 +1134,6 @@ struct writer_thread_ctx {
11321134
Vbid vbid;
11331135
};
11341136

1135-
struct continuous_dcp_ctx {
1136-
EngineIface* h;
1137-
const void *cookie;
1138-
Vbid vbid;
1139-
const std::string &name;
1140-
uint64_t start_seqno;
1141-
std::unique_ptr<TestDcpConsumer> dcpConsumer;
1142-
};
1143-
11441137
//Forward declaration required for dcp_thread_func
11451138
static uint32_t add_stream_for_consumer(EngineIface* h,
11461139
CookieIface* cookie,
@@ -1263,21 +1256,6 @@ static void writer_thread(void* args) {
12631256
}
12641257
}
12651258

1266-
static void continuous_dcp_thread(void* args) {
1267-
auto* cdc = static_cast<continuous_dcp_ctx*>(args);
1268-
1269-
DcpStreamCtx ctx;
1270-
ctx.vbucket = cdc->vbid;
1271-
std::string vbuuid_entry("vb_" + std::to_string(cdc->vbid.get()) + ":0:id");
1272-
ctx.vb_uuid = get_ull_stat(cdc->h, vbuuid_entry, "failovers");
1273-
ctx.seqno = {cdc->start_seqno, std::numeric_limits<uint64_t>::max()};
1274-
ctx.snapshot = {cdc->start_seqno, cdc->start_seqno};
1275-
ctx.skip_verification = true;
1276-
1277-
cdc->dcpConsumer->addStreamCtx(ctx);
1278-
cdc->dcpConsumer->run();
1279-
}
1280-
12811259
/* DCP step thread that keeps running till it reads upto 'exp_mutations'.
12821260
Note: the exp_mutations is cumulative across all streams in the DCP
12831261
connection */
@@ -2183,7 +2161,7 @@ static test_result testDcpProducerExpiredItemBackfill(
21832161
}
21842162

21852163
tdc.addStreamCtx(ctx);
2186-
2164+
tdc.openStreams();
21872165
tdc.run(false);
21882166

21892167
testHarness->destroy_cookie(cookie);
@@ -2447,6 +2425,7 @@ static enum test_result test_dcp_producer_stream_req_coldness(EngineIface* h) {
24472425
ctx.flags |= cb::mcbp::DcpAddStreamFlag::DiskOnly;
24482426

24492427
tdc.addStreamCtx(ctx);
2428+
tdc.openStreams();
24502429
tdc.run(false);
24512430

24522431
checkeq(tdc.getNruCounters()[1],
@@ -2581,27 +2560,28 @@ static enum test_result test_dcp_producer_stream_latest(EngineIface* h) {
25812560
}
25822561

25832562
static enum test_result test_dcp_producer_keep_stream_open(EngineIface* h) {
2584-
const std::string conn_name("unittest");
2585-
const int num_items = 2, vb = 0;
2563+
const int num_items = 2;
25862564

25872565
write_items(h, num_items);
25882566

25892567
wait_for_flusher_to_settle(h);
25902568
verify_curr_items(h, num_items, "Wrong amount of items");
25912569

2570+
// We want to stream items till end and keep the stream open. Then we want
2571+
// to verify the stream is still open
25922572
auto* cookie = testHarness->create_cookie(h);
2593-
2594-
/* We want to stream items till end and keep the stream open. Then we want
2595-
to verify the stream is still open */
2596-
struct continuous_dcp_ctx cdc = {
2597-
h,
2598-
cookie,
2599-
Vbid(0),
2600-
conn_name,
2601-
0,
2602-
std::make_unique<TestDcpConsumer>(conn_name, cookie, h)};
2603-
auto dcp_thread = create_thread([&cdc]() { continuous_dcp_thread(&cdc); },
2604-
"dcp_thread");
2573+
const std::string conn_name = "test-consumer";
2574+
auto consumer = std::make_unique<TestDcpConsumer>(conn_name, cookie, h);
2575+
DcpStreamCtx ctx;
2576+
ctx.vbucket = Vbid(0);
2577+
ctx.vb_uuid = get_ull_stat(h, "vb_0:0:id", "failovers");
2578+
ctx.seqno = {0, std::numeric_limits<uint64_t>::max()};
2579+
ctx.snapshot = {0, 0};
2580+
ctx.skip_verification = true;
2581+
consumer->addStreamCtx(ctx);
2582+
consumer->openConnectionAndStreams();
2583+
auto dcp_thread =
2584+
create_thread([&]() { consumer->run(false); }, "dcp_thread");
26052585

26062586
/* Wait for producer to be created */
26072587
wait_for_stat_to_be(h, "ep_dcp_producer_count", 1, "dcp");
@@ -2613,19 +2593,17 @@ static enum test_result test_dcp_producer_keep_stream_open(EngineIface* h) {
26132593

26142594
/* Wait for the dcp test client to receive upto highest seqno we have */
26152595
cb::RelaxedAtomic<uint64_t> exp_items(num_items);
2616-
wait_for_val_to_be("last_sent_seqno",
2617-
cdc.dcpConsumer->producers.last_byseqno,
2618-
exp_items);
2596+
wait_for_val_to_be(
2597+
"last_sent_seqno", consumer->producers.last_byseqno, exp_items);
26192598

2620-
/* Check if the stream is still open after sending out latest items */
2621-
std::string stat_stream_state("eq_dcpq:" + conn_name + ":stream_" +
2622-
std::to_string(vb) + "_state");
2599+
// Check if the stream is still open after sending out latest items
2600+
std::string stat_stream_state("eq_dcpq:" + conn_name + ":stream_0_state");
26232601
std::string state = get_str_stat(h, stat_stream_state, "dcp");
26242602
checkeq(state.compare("in-memory"), 0, "Stream is not open");
26252603

2626-
/* Before closing the connection stop the thread that continuously polls
2627-
for dcp data */
2628-
cdc.dcpConsumer->stop();
2604+
// Before closing the connection stop the thread that continuously polls for
2605+
// dcp data
2606+
consumer->stop();
26292607
cookie->notifyIoComplete(cb::engine_errc::success);
26302608
dcp_thread.join();
26312609
testHarness->destroy_cookie(cookie);
@@ -2724,16 +2702,18 @@ static enum test_result test_dcp_producer_keep_stream_open_replica(
27242702
/* We want to stream items till end and keep the stream open. Then we want
27252703
to verify the stream is still open */
27262704
auto* cookie1 = testHarness->create_cookie(h);
2727-
const std::string conn_name1("unittest1");
2728-
struct continuous_dcp_ctx cdc = {
2729-
h,
2730-
cookie1,
2731-
Vbid(0),
2732-
conn_name1,
2733-
0,
2734-
std::make_unique<TestDcpConsumer>(conn_name1, cookie1, h)};
2735-
auto dcp_thread = create_thread([&cdc]() { continuous_dcp_thread(&cdc); },
2736-
"dcp_thread");
2705+
const std::string conn_name1 = "test-consumer";
2706+
auto consumer = std::make_unique<TestDcpConsumer>(conn_name1, cookie1, h);
2707+
DcpStreamCtx ctx;
2708+
ctx.vbucket = Vbid(0);
2709+
ctx.vb_uuid = get_ull_stat(h, "vb_0:0:id", "failovers");
2710+
ctx.seqno = {0, std::numeric_limits<uint64_t>::max()};
2711+
ctx.snapshot = {0, 0};
2712+
ctx.skip_verification = true;
2713+
consumer->addStreamCtx(ctx);
2714+
consumer->openConnectionAndStreams();
2715+
auto dcp_thread =
2716+
create_thread([&]() { consumer->run(false); }, "dcp_thread");
27372717

27382718
/* Wait for producer to be created */
27392719
wait_for_stat_to_be(h, "ep_dcp_producer_count", 1, "dcp");
@@ -2745,9 +2725,8 @@ static enum test_result test_dcp_producer_keep_stream_open_replica(
27452725

27462726
/* Wait for the dcp test client to receive upto highest seqno we have */
27472727
cb::RelaxedAtomic<uint64_t> exp_items(3 * num_items);
2748-
wait_for_val_to_be("last_sent_seqno",
2749-
cdc.dcpConsumer->producers.last_byseqno,
2750-
exp_items);
2728+
wait_for_val_to_be(
2729+
"last_sent_seqno", consumer->producers.last_byseqno, exp_items);
27512730

27522731
/* Check if correct snap end seqno is sent */
27532732
std::string stat_stream_last_sent_snap_end_seqno("eq_dcpq:" + conn_name1 +
@@ -2765,7 +2744,7 @@ static enum test_result test_dcp_producer_keep_stream_open_replica(
27652744

27662745
/* Before closing the connection stop the thread that continuously polls
27672746
for dcp data */
2768-
cdc.dcpConsumer->stop();
2747+
consumer->stop();
27692748
cookie1->notifyIoComplete(cb::engine_errc::success);
27702749
dcp_thread.join();
27712750

@@ -2777,7 +2756,6 @@ static enum test_result test_dcp_producer_keep_stream_open_replica(
27772756

27782757
static enum test_result test_dcp_producer_stream_cursor_movement(
27792758
EngineIface* h) {
2780-
const std::string conn_name("unittest");
27812759
const int num_items = 30;
27822760
for (int j = 0; j < num_items; ++j) {
27832761
if (j % 10 == 0) {
@@ -2795,19 +2773,21 @@ static enum test_result test_dcp_producer_stream_cursor_movement(
27952773
wait_for_flusher_to_settle(h);
27962774
verify_curr_items(h, num_items, "Wrong amount of items");
27972775

2776+
// We want to stream items till end and keep the stream open. We want to
2777+
// verify if the DCP cursor has moved to new open checkpoint
27982778
auto* cookie = testHarness->create_cookie(h);
2799-
2800-
/* We want to stream items till end and keep the stream open. We want to
2801-
verify if the DCP cursor has moved to new open checkpoint */
2802-
struct continuous_dcp_ctx cdc = {
2803-
h,
2804-
cookie,
2805-
Vbid(0),
2806-
conn_name,
2807-
20,
2808-
std::make_unique<TestDcpConsumer>(conn_name, cookie, h)};
2809-
auto dcp_thread = create_thread([&cdc]() { continuous_dcp_thread(&cdc); },
2810-
"dcp_thread");
2779+
const std::string conn_name = "test-consumer";
2780+
auto consumer = std::make_unique<TestDcpConsumer>(conn_name, cookie, h);
2781+
DcpStreamCtx ctx;
2782+
ctx.vbucket = Vbid(0);
2783+
ctx.vb_uuid = get_ull_stat(h, "vb_0:0:id", "failovers");
2784+
ctx.seqno = {20, std::numeric_limits<uint64_t>::max()};
2785+
ctx.snapshot = {20, 20};
2786+
ctx.skip_verification = true;
2787+
consumer->addStreamCtx(ctx);
2788+
consumer->openConnectionAndStreams();
2789+
auto dcp_thread =
2790+
create_thread([&]() { consumer->run(false); }, "dcp_thread");
28112791

28122792
/* Wait for producer to be created */
28132793
wait_for_stat_to_be(h, "ep_dcp_producer_count", 1, "dcp");
@@ -2819,9 +2799,8 @@ static enum test_result test_dcp_producer_stream_cursor_movement(
28192799

28202800
/* Wait for the dcp test client to receive upto highest seqno we have */
28212801
cb::RelaxedAtomic<uint64_t> exp_items(num_items);
2822-
wait_for_val_to_be("last_sent_seqno",
2823-
cdc.dcpConsumer->producers.last_byseqno,
2824-
exp_items);
2802+
wait_for_val_to_be(
2803+
"last_sent_seqno", consumer->producers.last_byseqno, exp_items);
28252804

28262805
/* We want to make sure that no cursors are lingering on any of the previous
28272806
checkpoints. For that we wait for checkpoint remover to remove all but
@@ -2830,7 +2809,7 @@ static enum test_result test_dcp_producer_stream_cursor_movement(
28302809

28312810
/* Before closing the connection stop the thread that continuously polls
28322811
for dcp data */
2833-
cdc.dcpConsumer->stop();
2812+
consumer->stop();
28342813
cookie->notifyIoComplete(cb::engine_errc::success);
28352814
dcp_thread.join();
28362815
testHarness->destroy_cookie(cookie);
@@ -5793,6 +5772,7 @@ static test_result test_dcp_replica_stream_expiries(
57935772
"Failed to enable_expiry_opcode");
57945773
}
57955774
tdc.addStreamCtx(ctx);
5775+
tdc.openStreams();
57965776
tdc.run(false);
57975777

57985778
testHarness->destroy_cookie(cookie1);
@@ -5878,7 +5858,7 @@ static test_result test_stream_deleteWithMeta_expiration(
58785858
}
58795859

58805860
tdc.addStreamCtx(ctx);
5881-
5861+
tdc.openStreams();
58825862
tdc.run(false);
58835863

58845864
testHarness->destroy_cookie(cookie);
@@ -7084,19 +7064,21 @@ static enum test_result test_dcp_multiple_streams(EngineIface* h) {
70847064
}
70857065

70867066
static enum test_result test_dcp_on_vbucket_state_change(EngineIface* h) {
7087-
const std::string conn_name = "unittest";
7067+
// Set up a DcpTestConsumer that would remain in in-memory mode
70887068
auto* cookie = testHarness->create_cookie(h);
70897069

7090-
// Set up a DcpTestConsumer that would remain in in-memory mode
7091-
struct continuous_dcp_ctx cdc = {
7092-
h,
7093-
cookie,
7094-
Vbid(0),
7095-
conn_name,
7096-
0,
7097-
std::make_unique<TestDcpConsumer>(conn_name, cookie, h)};
7098-
auto dcp_thread = create_thread([&cdc]() { continuous_dcp_thread(&cdc); },
7099-
"dcp_thread");
7070+
const std::string conn_name = "test-consumer";
7071+
auto consumer = std::make_unique<TestDcpConsumer>(conn_name, cookie, h);
7072+
DcpStreamCtx ctx;
7073+
ctx.vbucket = Vbid(0);
7074+
ctx.vb_uuid = get_ull_stat(h, "vb_0:0:id", "failovers");
7075+
ctx.seqno = {0, std::numeric_limits<uint64_t>::max()};
7076+
ctx.snapshot = {0, 0};
7077+
ctx.skip_verification = true;
7078+
consumer->addStreamCtx(ctx);
7079+
consumer->openConnectionAndStreams();
7080+
auto dcp_thread =
7081+
create_thread([&]() { consumer->run(false); }, "dcp_thread");
71007082

71017083
// Wait for producer to be created
71027084
wait_for_stat_to_be(h, "ep_dcp_producer_count", 1, "dcp");
@@ -7120,7 +7102,7 @@ static enum test_result test_dcp_on_vbucket_state_change(EngineIface* h) {
71207102
// Expect producers->last_end_status to carry StateChanged as reason
71217103
// for stream closure
71227104
check_expression(cb::mcbp::DcpStreamEndStatus::StateChanged ==
7123-
cdc.dcpConsumer->producers.last_end_status,
7105+
consumer->producers.last_end_status,
71247106
"Last DCP flag not StateChanged");
71257107

71267108
testHarness->destroy_cookie(cookie);
@@ -7933,6 +7915,7 @@ static enum test_result testDcpOsoBackfill(EngineIface* h) {
79337915
"Failed control enable_out_of_order_snapshots");
79347916

79357917
tdc.addStreamCtx(ctx);
7918+
tdc.openStreams();
79367919
tdc.run(false);
79377920

79387921
testHarness->destroy_cookie(cookie);

0 commit comments

Comments
 (0)