Skip to content

Commit aedfd7a

Browse files
jimwwalkerdaverigby
authored andcommitted
MB-23086: Always use SynchronousEPEngine::build
Ensure the various tests which use SynchronousEPEngine use the factory build method to give better control around the setup/teardown of this object. Change-Id: Iedc019f3bae151746775af62ba1a9de7b645621c Reviewed-on: http://review.couchbase.org/107946 Reviewed-by: Dave Rigby <[email protected]> Tested-by: Build Bot <[email protected]>
1 parent 5f13d18 commit aedfd7a

File tree

9 files changed

+66
-56
lines changed

9 files changed

+66
-56
lines changed

engines/ep/benchmarks/engine_fixture.cc

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,8 @@ void EngineFixture::SetUp(const benchmark::State& state) {
3333
ExecutorPool::get());
3434
std::string config = "dbname=benchmarks-test;ht_locks=47;" + varConfig;
3535

36-
engine.reset(new SynchronousEPEngine(config));
36+
engine = SynchronousEPEngine::build(config);
3737

38-
ObjectRegistry::onSwitchThread(engine.get());
39-
40-
engine->setKVBucket(
41-
engine->public_makeBucket(engine->getConfiguration()));
42-
43-
engine->public_initializeEngineCallbacks();
4438
initialize_time_functions(get_mock_server_api()->core);
4539
cookie = create_mock_cookie();
4640
} else {

engines/ep/benchmarks/engine_fixture.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
#include <benchmark/benchmark.h>
2121

2222
#include "item.h"
23+
#include "tests/mock/mock_synchronous_ep_engine.h"
2324

2425
class BenchmarkMemoryTracker;
2526
class SingleThreadedExecutorPool;
26-
class SynchronousEPEngine;
2727

2828
/**
2929
* A fixture for benchmarking EpEngine and related classes.
@@ -36,7 +36,7 @@ class EngineFixture : public benchmark::Fixture {
3636

3737
Item make_item(Vbid vbid, const std::string& key, const std::string& value);
3838

39-
std::unique_ptr<SynchronousEPEngine> engine;
39+
SynchronousEPEngineUniquePtr engine;
4040
const void* cookie = nullptr;
4141
const Vbid vbid = Vbid(0);
4242

engines/ep/tests/mock/mock_synchronous_ep_engine.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,9 @@ void SynchronousEPEngine::setDcpConnMap(
7171
dcpConnMap_ = std::move(dcpConnMap);
7272
}
7373

74-
std::unique_ptr<SynchronousEPEngine> SynchronousEPEngine::build(
74+
SynchronousEPEngineUniquePtr SynchronousEPEngine::build(
7575
const std::string& config) {
76-
std::unique_ptr<SynchronousEPEngine> engine(
77-
new SynchronousEPEngine(config));
76+
SynchronousEPEngineUniquePtr engine(new SynchronousEPEngine(config));
7877

7978
// switch current thread to this new engine, so all sub-created objects
8079
// are accounted in it's mem_used.
@@ -90,6 +89,12 @@ std::unique_ptr<SynchronousEPEngine> SynchronousEPEngine::build(
9089
return engine;
9190
}
9291

92+
void SynchronousEPEngineDeleter::operator()(SynchronousEPEngine* engine) {
93+
ObjectRegistry::onSwitchThread(engine);
94+
delete engine;
95+
ObjectRegistry::onSwitchThread(nullptr);
96+
}
97+
9398
void SynchronousEPEngine::initializeConnmap() {
9499
dcpConnMap_->initialize();
95100
}

engines/ep/tests/mock/mock_synchronous_ep_engine.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424
#include <ep_bucket.h>
2525
#include <ep_engine.h>
2626

27+
class SynchronousEPEngine;
28+
29+
struct SynchronousEPEngineDeleter {
30+
void operator()(SynchronousEPEngine*);
31+
};
32+
33+
using SynchronousEPEngineUniquePtr =
34+
std::unique_ptr<SynchronousEPEngine, SynchronousEPEngineDeleter>;
35+
2736
/* A class which subclasses the real EPEngine. Its main purpose is to allow
2837
* us to construct and setup an EPStore without starting all the various
2938
* background tasks which are normally started by EPEngine as part of creating
@@ -43,8 +52,7 @@ class SynchronousEPEngine : public EventuallyPersistentEngine {
4352

4453
/// Constructs a SynchronousEPEngine instance, along with the necessary
4554
/// sub-components.
46-
static std::unique_ptr<SynchronousEPEngine> build(
47-
const std::string& config);
55+
static SynchronousEPEngineUniquePtr build(const std::string& config);
4856

4957
/* Allow us to call normally protected methods */
5058

engines/ep/tests/module_tests/dcp_reflection_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ class DCPLoopbackStreamTest : public SingleThreadedKVBucketTest {
182182

183183
void takeoverTest(EnableExpiryOutput enableExpiryOutput);
184184

185-
std::unique_ptr<SynchronousEPEngine> replicaEngine;
185+
SynchronousEPEngineUniquePtr replicaEngine;
186186
std::shared_ptr<MockDcpConsumer> consumer;
187187
// Non-owning ptr to consumer stream (owned by consumer).
188188
PassiveStream* consumerStream;

engines/ep/tests/module_tests/dcp_test.cc

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,15 +1656,12 @@ TEST_P(ConnectionTest, test_mb21784) {
16561656
class DcpConnMapTest : public ::testing::Test {
16571657
protected:
16581658
void SetUp() override {
1659-
/* Set up the bare minimum stuff needed by the 'SynchronousEPEngine'
1660-
(mock engine) */
1661-
ObjectRegistry::onSwitchThread(&engine);
1662-
engine.setKVBucket(engine.public_makeBucket(engine.getConfiguration()));
1663-
engine.public_initializeEngineCallbacks();
1659+
engine = SynchronousEPEngine::build({});
1660+
16641661
initialize_time_functions(get_mock_server_api()->core);
16651662

16661663
/* Set up one vbucket in the bucket */
1667-
engine.getKVBucket()->setVBucketState(vbid, vbucket_state_active);
1664+
engine->getKVBucket()->setVBucketState(vbid, vbucket_state_active);
16681665
}
16691666

16701667
void TearDown() override {
@@ -1682,7 +1679,7 @@ class DcpConnMapTest : public ::testing::Test {
16821679
return ENGINE_SUCCESS;
16831680
}
16841681

1685-
SynchronousEPEngine engine;
1682+
SynchronousEPEngineUniquePtr engine;
16861683
const Vbid vbid = Vbid(0);
16871684
};
16881685

@@ -1695,9 +1692,9 @@ class DcpConnMapTest : public ::testing::Test {
16951692
TEST_F(DcpConnMapTest, DeleteProducerOnUncleanDCPConnMapDelete) {
16961693
/* Create a new Dcp producer */
16971694
const void* dummyMockCookie = create_mock_cookie();
1698-
DcpProducer* producer = engine.getDcpConnMap().newProducer(dummyMockCookie,
1699-
"test_producer",
1700-
/*flags*/ 0);
1695+
DcpProducer* producer = engine->getDcpConnMap().newProducer(dummyMockCookie,
1696+
"test_producer",
1697+
/*flags*/ 0);
17011698
/* Open stream */
17021699
uint64_t rollbackSeqno = 0;
17031700
uint32_t opaque = 0;
@@ -1719,7 +1716,7 @@ TEST_F(DcpConnMapTest, DeleteProducerOnUncleanDCPConnMapDelete) {
17191716
/* Delete the connmap, connection should be deleted as the owner of
17201717
the connection (connmap) is deleted. Checks that there is no cyclic
17211718
reference between conn (producer) and stream or any other object */
1722-
engine.setDcpConnMap(nullptr);
1719+
engine->setDcpConnMap(nullptr);
17231720
}
17241721

17251722
/* Tests that there is no memory loss due to cyclic reference between a
@@ -1728,7 +1725,7 @@ TEST_F(DcpConnMapTest, DeleteProducerOnUncleanDCPConnMapDelete) {
17281725
TEST_F(DcpConnMapTest, DeleteNotifierConnOnUncleanDCPConnMapDelete) {
17291726
/* Create a new Dcp producer */
17301727
const void* dummyMockCookie = create_mock_cookie();
1731-
DcpProducer* producer = engine.getDcpConnMap().newProducer(
1728+
DcpProducer* producer = engine->getDcpConnMap().newProducer(
17321729
dummyMockCookie,
17331730
"test_producer",
17341731
cb::mcbp::request::DcpOpenPayload::Notifier);
@@ -1753,20 +1750,20 @@ TEST_F(DcpConnMapTest, DeleteNotifierConnOnUncleanDCPConnMapDelete) {
17531750
/* Delete the connmap, connection should be deleted as the owner of
17541751
the connection (connmap) is deleted. Checks that there is no cyclic
17551752
reference between conn (producer) and stream or any other object */
1756-
engine.setDcpConnMap(nullptr);
1753+
engine->setDcpConnMap(nullptr);
17571754
}
17581755

17591756
/* Tests that there is no memory loss due to cyclic reference between a
17601757
* consumer connection and a passive stream.
17611758
*/
17621759
TEST_F(DcpConnMapTest, DeleteConsumerConnOnUncleanDCPConnMapDelete) {
17631760
/* Consumer stream needs a replica vbucket */
1764-
engine.getKVBucket()->setVBucketState(vbid, vbucket_state_replica);
1761+
engine->getKVBucket()->setVBucketState(vbid, vbucket_state_replica);
17651762

17661763
/* Create a new Dcp consumer */
17671764
const void* dummyMockCookie = create_mock_cookie();
1768-
DcpConsumer* consumer = engine.getDcpConnMap().newConsumer(dummyMockCookie,
1769-
"test_consumer");
1765+
DcpConsumer* consumer = engine->getDcpConnMap().newConsumer(
1766+
dummyMockCookie, "test_consumer");
17701767

17711768
/* Add passive stream */
17721769
ASSERT_EQ(ENGINE_SUCCESS,
@@ -1779,7 +1776,7 @@ TEST_F(DcpConnMapTest, DeleteConsumerConnOnUncleanDCPConnMapDelete) {
17791776
/* Delete the connmap, connection should be deleted as the owner of
17801777
the connection (connmap) is deleted. Checks that there is no cyclic
17811778
reference between conn (consumer) and stream or any other object */
1782-
engine.setDcpConnMap(nullptr);
1779+
engine->setDcpConnMap(nullptr);
17831780
}
17841781

17851782
class NotifyTest : public DCPTest {

engines/ep/tests/module_tests/kv_bucket_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "dcp/flow-control-manager.h"
3131
#include "ep_engine.h"
3232
#include "ep_time.h"
33+
#include "fakes/fake_executorpool.h"
3334
#include "flusher.h"
3435
#include "globaltask.h"
3536
#include "lambda_task.h"
@@ -105,7 +106,6 @@ void KVBucketTest::destroy() {
105106
destroy_mock_cookie(cookie);
106107
destroy_mock_event_callbacks();
107108
engine->getDcpConnMap().manageConnections();
108-
ObjectRegistry::onSwitchThread(nullptr);
109109
engine.reset();
110110
}
111111

engines/ep/tests/module_tests/kv_bucket_test.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@
2727

2828
#include "callbacks.h"
2929
#include "item.h"
30+
#include <tests/mock/mock_synchronous_ep_engine.h>
3031

3132
#include <folly/portability/GTest.h>
3233
#include <memcached/protocol_binary.h>
3334

3435
#include <memory>
3536

3637
class KVBucket;
37-
class SynchronousEPEngine;
3838

3939
namespace Collections {
4040
class Manager;
@@ -239,7 +239,7 @@ class KVBucketTest : virtual public ::testing::Test {
239239
const Vbid vbid = Vbid(0);
240240

241241
// The mock engine (needed to construct the store).
242-
std::unique_ptr<SynchronousEPEngine> engine;
242+
SynchronousEPEngineUniquePtr engine;
243243

244244
// The store under test. Wrapped in a mock to expose some normally
245245
// protected members. Uses a raw pointer as this is owned by the engine.

engines/ep/tests/module_tests/objectregistry_test.cc

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "bucket_logger.h"
2323
#include "bucket_logger_test.h"
24+
#include "fakes/fake_executorpool.h"
2425
#include "item.h"
2526
#include "memory_tracker.h"
2627
#include "objectregistry.h"
@@ -34,39 +35,43 @@
3435
class ObjectRegistryTest : virtual public ::testing::Test {
3536
protected:
3637
void SetUp() override {
37-
ObjectRegistry::onSwitchThread(&engine);
38+
SingleThreadedExecutorPool::replaceExecutorPoolWithFake();
39+
engine = SynchronousEPEngine::build({});
3840
}
41+
3942
void TearDown() override {
40-
ObjectRegistry::onSwitchThread(nullptr);
43+
destroy_mock_event_callbacks();
44+
engine.reset();
45+
ExecutorPool::shutdown();
4146
}
4247

43-
SynchronousEPEngine engine;
48+
SynchronousEPEngineUniquePtr engine;
4449
};
4550

4651
// Check that constructing & destructing an Item is correctly tracked in
4752
// EpStats::numItem via ObjectRegistry::on{Create,Delete}Item.
4853
TEST_F(ObjectRegistryTest, NumItem) {
49-
ASSERT_EQ(0, engine.getEpStats().getNumItem());
54+
ASSERT_EQ(0, engine->getEpStats().getNumItem());
5055

5156
{
5257
auto item = make_item(Vbid(0), makeStoredDocKey("key"), "value");
53-
EXPECT_EQ(1, engine.getEpStats().getNumItem());
58+
EXPECT_EQ(1, engine->getEpStats().getNumItem());
5459
}
55-
EXPECT_EQ(0, engine.getEpStats().getNumItem());
60+
EXPECT_EQ(0, engine->getEpStats().getNumItem());
5661
}
5762

5863
// Check that constructing & destructing an Item is correctly tracked in
5964
// EpStats::memOverhead via ObjectRegistry::on{Create,Delete}Item.
6065
TEST_F(ObjectRegistryTest, MemOverhead) {
61-
ASSERT_EQ(0, engine.getEpStats().getMemOverhead());
66+
auto baseline = engine->getEpStats().getMemOverhead();
6267

6368
{
6469
auto item = make_item(Vbid(0), makeStoredDocKey("key"), "value");
6570
// Currently just checking the overhead is non-zero; could expand
6671
// to calculate expected size based on the Item's size.
67-
EXPECT_NE(0, engine.getEpStats().getMemOverhead());
72+
EXPECT_NE(baseline, engine->getEpStats().getMemOverhead());
6873
}
69-
EXPECT_EQ(0, engine.getEpStats().getMemOverhead());
74+
EXPECT_EQ(baseline, engine->getEpStats().getMemOverhead());
7075
}
7176

7277
/**
@@ -100,15 +105,16 @@ class ObjectRegistrySpdlogTest : public BucketLoggerTest,
100105

101106
// Enable memory tracking hooks
102107
MemoryTracker::getInstance(*get_mock_server_api()->alloc_hooks);
103-
engine.getEpStats().memoryTrackerEnabled.store(true);
108+
engine->getEpStats().memoryTrackerEnabled.store(true);
104109
}
105110

106111
void TearDown() override {
107112
MemoryTracker::destroyInstance();
108113

109114
// Parent classes TearDown methods are sufficient here.
110-
ObjectRegistryTest::TearDown();
111115
BucketLoggerTest::TearDown();
116+
// called last so that the engine is destroyed last
117+
ObjectRegistryTest::TearDown();
112118
}
113119
};
114120

@@ -119,13 +125,13 @@ TEST_F(ObjectRegistrySpdlogTest, SpdlogMemoryTrackedCorrectly) {
119125
::testing::UnitTest::GetInstance()->current_test_info()->name();
120126

121127
// const char* - uses the single argument overload of warn().
122-
auto baselineMemory = engine.getEpStats().getPreciseTotalMemoryUsed();
128+
auto baselineMemory = engine->getEpStats().getPreciseTotalMemoryUsed();
123129
{
124130
auto logger = BucketLogger::createBucketLogger(testName);
125131
logger->log(spdlog::level::warn, "const char* message");
126132
logger->flush();
127133
}
128-
EXPECT_EQ(baselineMemory, engine.getEpStats().getPreciseTotalMemoryUsed());
134+
EXPECT_EQ(baselineMemory, engine->getEpStats().getPreciseTotalMemoryUsed());
129135

130136
// multiple arguments using format string, with a short (< sizeof(sync_msg)
131137
// log string.
@@ -146,25 +152,25 @@ TEST_F(ObjectRegistrySpdlogTest, SpdlogMemoryTrackedCorrectly) {
146152
std::string(asyncMsgCapacity, 's'));
147153
logger->flush();
148154
}
149-
EXPECT_EQ(baselineMemory, engine.getEpStats().getPreciseTotalMemoryUsed());
155+
EXPECT_EQ(baselineMemory, engine->getEpStats().getPreciseTotalMemoryUsed());
150156

151157
// As previous, but looping with multiple warn() calls - check that we
152158
// correctly account even when multiple messages are created & destroyed.
153159
{
154160
auto logger = BucketLogger::createBucketLogger(testName);
155161
auto afterLoggerMemory =
156-
engine.getEpStats().getPreciseTotalMemoryUsed();
162+
engine->getEpStats().getPreciseTotalMemoryUsed();
157163

158164
for (int i = 0; i < 100; i++) {
159165
logger->warn("short+variable loop ({}) {} ",
160166
i,
161167
std::string(asyncMsgCapacity, 's'));
162168
logger->flush();
163169
EXPECT_EQ(afterLoggerMemory,
164-
engine.getEpStats().getPreciseTotalMemoryUsed());
170+
engine->getEpStats().getPreciseTotalMemoryUsed());
165171
}
166172
}
167-
EXPECT_EQ(baselineMemory, engine.getEpStats().getPreciseTotalMemoryUsed());
173+
EXPECT_EQ(baselineMemory, engine->getEpStats().getPreciseTotalMemoryUsed());
168174

169175
// Multiple arguments with a very long string (greater than
170176
// asyncMsgCapacity)
@@ -178,23 +184,23 @@ TEST_F(ObjectRegistrySpdlogTest, SpdlogMemoryTrackedCorrectly) {
178184
std::string(asyncMsgCapacity * 2, 'x'));
179185
logger->flush();
180186
}
181-
EXPECT_EQ(baselineMemory, engine.getEpStats().getPreciseTotalMemoryUsed());
187+
EXPECT_EQ(baselineMemory, engine->getEpStats().getPreciseTotalMemoryUsed());
182188

183189
// Multiple log messages; each with a log string - check that we correctly
184190
// account even when multiple messages are created & destroyed.
185191
{
186192
auto logger = BucketLogger::createBucketLogger(testName);
187193
auto afterLoggerMemory =
188-
engine.getEpStats().getPreciseTotalMemoryUsed();
194+
engine->getEpStats().getPreciseTotalMemoryUsed();
189195

190196
for (int i = 0; i < 100; i++) {
191197
logger->warn("long+variable loop ({}) {}",
192198
i,
193199
std::string(asyncMsgCapacity * 2, 'x'));
194200
logger->flush();
195201
EXPECT_EQ(afterLoggerMemory,
196-
engine.getEpStats().getPreciseTotalMemoryUsed());
202+
engine->getEpStats().getPreciseTotalMemoryUsed());
197203
}
198204
}
199-
EXPECT_EQ(baselineMemory, engine.getEpStats().getPreciseTotalMemoryUsed());
205+
EXPECT_EQ(baselineMemory, engine->getEpStats().getPreciseTotalMemoryUsed());
200206
}

0 commit comments

Comments
 (0)