diff options
Diffstat (limited to 'storage/src/tests')
60 files changed, 3407 insertions, 5492 deletions
diff --git a/storage/src/tests/CMakeLists.txt b/storage/src/tests/CMakeLists.txt index ae55c80c148..f93ea7ef00d 100644 --- a/storage/src/tests/CMakeLists.txt +++ b/storage/src/tests/CMakeLists.txt @@ -8,7 +8,6 @@ vespa_add_executable(storage_testrunner_app TEST DEPENDS storage_testcommon storage_testhostreporter - storage_testdistributor ) vespa_add_test( diff --git a/storage/src/tests/bucketdb/bucketmanagertest.cpp b/storage/src/tests/bucketdb/bucketmanagertest.cpp index 1f72347b7ed..e05648c62a2 100644 --- a/storage/src/tests/bucketdb/bucketmanagertest.cpp +++ b/storage/src/tests/bucketdb/bucketmanagertest.cpp @@ -200,7 +200,7 @@ void BucketManagerTest::addBucketsToDB(uint32_t count) // Make sure we have at least one empty bucket TestBucketInfo& info = (++_bucketInfo.begin())->second; - CPPUNIT_ASSERT(info.size != 0); + assert(info.size != 0); info.size = 0; info.count = 0; info.crc = 0; diff --git a/storage/src/tests/common/CMakeLists.txt b/storage/src/tests/common/CMakeLists.txt index 075dc263be9..1922d13ca61 100644 --- a/storage/src/tests/common/CMakeLists.txt +++ b/storage/src/tests/common/CMakeLists.txt @@ -2,6 +2,7 @@ vespa_add_library(storage_testcommon TEST SOURCES dummystoragelink.cpp + message_sender_stub.cpp testhelper.cpp testnodestateupdater.cpp teststorageapp.cpp diff --git a/storage/src/tests/common/hostreporter/CMakeLists.txt b/storage/src/tests/common/hostreporter/CMakeLists.txt index 7a4a23ba7aa..2fcb159cb08 100644 --- a/storage/src/tests/common/hostreporter/CMakeLists.txt +++ b/storage/src/tests/common/hostreporter/CMakeLists.txt @@ -1,9 +1,7 @@ # Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. vespa_add_library(storage_testhostreporter TEST SOURCES - hostinfotest.cpp util.cpp - versionreportertest.cpp DEPENDS storage ) @@ -11,8 +9,11 @@ vespa_add_library(storage_testhostreporter TEST vespa_add_executable(storage_hostreporter_gtest_runner_app TEST SOURCES gtest_runner.cpp + hostinfotest.cpp + versionreportertest.cpp DEPENDS storage + storage_testhostreporter gtest ) diff --git a/storage/src/tests/common/hostreporter/hostinfotest.cpp b/storage/src/tests/common/hostreporter/hostinfotest.cpp index 418884c2a38..467149154ee 100644 --- a/storage/src/tests/common/hostreporter/hostinfotest.cpp +++ b/storage/src/tests/common/hostreporter/hostinfotest.cpp @@ -1,15 +1,18 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include "util.h" #include <vespa/storage/common/hostreporter/hostinfo.h> #include <vespa/storage/common/hostreporter/hostreporter.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/vespalib/data/slime/slime.h> #include <vespa/vespalib/stllike/asciistream.h> #include <vespa/vespalib/util/jsonstream.h> -#include "util.h" +#include <vespa/vespalib/gtest/gtest.h> + +using namespace ::testing; namespace storage { namespace { + using Object = vespalib::JsonStream::Object; using End = vespalib::JsonStream::End; using JsonFormat = vespalib::slime::JsonFormat; @@ -21,22 +24,10 @@ public: jsonreport << "dummy" << Object() << "foo" << "bar" << End(); } }; -} - -struct HostInfoReporterTest : public CppUnit::TestFixture -{ - void testHostInfoReporter(); - CPPUNIT_TEST_SUITE(HostInfoReporterTest); - CPPUNIT_TEST(testHostInfoReporter); - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(HostInfoReporterTest); +} -void -HostInfoReporterTest::testHostInfoReporter() -{ +TEST(HostInfoReporterTest, host_info_reporter) { HostInfo hostinfo; DummyReporter dummyReporter; hostinfo.registerReporter(&dummyReporter); @@ -50,8 +41,8 @@ HostInfoReporterTest::testHostInfoReporter() std::string jsonData = json.str(); vespalib::Slime slime; JsonFormat::decode(Memory(jsonData), slime); - CPPUNIT_ASSERT(slime.get()["dummy"]["foo"].asString() == "bar"); - CPPUNIT_ASSERT(!slime.get()["vtag"]["version"].asString().make_string().empty()); + EXPECT_EQ(slime.get()["dummy"]["foo"].asString(), "bar"); + EXPECT_FALSE(slime.get()["vtag"]["version"].asString().make_string().empty()); } -} // storage +} // storage diff --git a/storage/src/tests/common/hostreporter/util.cpp b/storage/src/tests/common/hostreporter/util.cpp index e0563a431e6..02e66b1dcc7 100644 --- a/storage/src/tests/common/hostreporter/util.cpp +++ b/storage/src/tests/common/hostreporter/util.cpp @@ -2,12 +2,11 @@ #include "util.h" #include <vespa/storage/common/hostreporter/hostreporter.h> #include <vespa/vespalib/data/slime/slime.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/vespalib/util/jsonstream.h> #include <vespa/vespalib/stllike/asciistream.h> -namespace storage { -namespace util { +namespace storage::util { + namespace { using Object = vespalib::JsonStream::Object; using End = vespalib::JsonStream::End; @@ -27,8 +26,8 @@ reporterToSlime(HostReporter &hostReporter, vespalib::Slime &slime) { size_t parsed = JsonFormat::decode(Memory(jsonData), slime); if (parsed == 0) { - CPPUNIT_FAIL("jsonData is not json:\n" + jsonData); + throw std::runtime_error("jsonData is not json:\n" + jsonData); } } -} + } diff --git a/storage/src/tests/common/hostreporter/versionreportertest.cpp b/storage/src/tests/common/hostreporter/versionreportertest.cpp index dd58493f540..ee8fe2a5ff3 100644 --- a/storage/src/tests/common/hostreporter/versionreportertest.cpp +++ b/storage/src/tests/common/hostreporter/versionreportertest.cpp @@ -1,38 +1,29 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/log/log.h> + +#include "util.h" #include <vespa/storage/common/hostreporter/versionreporter.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/vespalib/data/slime/slime.h> #include <vespa/vespalib/util/jsonstream.h> -#include "util.h" +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> -LOG_SETUP(".test.versionreporter"); +using namespace ::testing; namespace storage { namespace { + using Object = vespalib::JsonStream::Object; using End = vespalib::JsonStream::End; -} -struct VersionReporterTest : public CppUnit::TestFixture -{ - void testVersionReporter(); - - CPPUNIT_TEST_SUITE(VersionReporterTest); - CPPUNIT_TEST(testVersionReporter); - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(VersionReporterTest); +} -void -VersionReporterTest::testVersionReporter() -{ +TEST(VersionReporterTest, version_reporter) { VersionReporter versionReporter; vespalib::Slime slime; util::reporterToSlime(versionReporter, slime); std::string version = slime.get()["vtag"]["version"].asString().make_string().c_str(); - CPPUNIT_ASSERT(version.length() > 2); - CPPUNIT_ASSERT(version.find(".") > 0); + EXPECT_GT(version.size(), 2); + EXPECT_THAT(version, HasSubstr(".")); } + } // storage diff --git a/storage/src/tests/distributor/messagesenderstub.cpp b/storage/src/tests/common/message_sender_stub.cpp index 55eaf344e71..c127f9071e5 100644 --- a/storage/src/tests/distributor/messagesenderstub.cpp +++ b/storage/src/tests/common/message_sender_stub.cpp @@ -1,15 +1,16 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include "messagesenderstub.h" -#include "distributortestutil.h" +#include "message_sender_stub.h" +#include <vespa/storageapi/messageapi/storagecommand.h> +#include <vespa/storageapi/messageapi/storagereply.h> +#include <string> +#include <sstream> +#include <stdexcept> namespace storage { -MessageSenderStub::MessageSenderStub() - : _clusterName("storage"), - _pendingMessageTracker(0) -{} -MessageSenderStub::~MessageSenderStub() {} +MessageSenderStub::MessageSenderStub() = default; +MessageSenderStub::~MessageSenderStub() = default; std::string MessageSenderStub::getLastCommand(bool verbose) const @@ -22,8 +23,8 @@ MessageSenderStub::getLastCommand(bool verbose) const std::string MessageSenderStub::dumpMessage(const api::StorageMessage& msg, - bool includeAddress, - bool verbose) const + bool includeAddress, + bool verbose) const { std::ostringstream ost; diff --git a/storage/src/tests/common/message_sender_stub.h b/storage/src/tests/common/message_sender_stub.h new file mode 100644 index 00000000000..73b1fcff9f4 --- /dev/null +++ b/storage/src/tests/common/message_sender_stub.h @@ -0,0 +1,47 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/storage/common/messagesender.h> +#include <vector> + +namespace storage { + +struct MessageSenderStub : MessageSender { + std::vector<std::shared_ptr<api::StorageCommand>> commands; + std::vector<std::shared_ptr<api::StorageReply>> replies; + + MessageSenderStub(); + ~MessageSenderStub() override; + + void clear() { + commands.clear(); + replies.clear(); + } + + void sendCommand(const std::shared_ptr<api::StorageCommand>& cmd) override { + commands.push_back(cmd); + } + + void sendReply(const std::shared_ptr<api::StorageReply>& reply) override { + replies.push_back(reply); + } + + std::string getLastCommand(bool verbose = true) const; + + std::string getCommands(bool includeAddress = false, + bool verbose = false, + uint32_t fromIndex = 0) const; + + std::string getLastReply(bool verbose = true) const; + + std::string getReplies(bool includeAddress = false, + bool verbose = false) const; + + std::string dumpMessage(const api::StorageMessage& msg, + bool includeAddress, + bool verbose) const; +}; + + +} diff --git a/storage/src/tests/common/metricstest.cpp b/storage/src/tests/common/metricstest.cpp index 9a9f05d500e..d1421845b81 100644 --- a/storage/src/tests/common/metricstest.cpp +++ b/storage/src/tests/common/metricstest.cpp @@ -14,6 +14,7 @@ #include <vespa/config/common/exceptions.h> #include <vespa/vespalib/stllike/hash_map.hpp> #include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> #include <thread> #include <vespa/log/log.h> @@ -211,16 +212,12 @@ TEST_F(MetricsTest, filestor_metrics) { std::ostringstream ost; framework::HttpUrlPath path("metrics?interval=-1&format=text"); bool retVal = _metricsConsumer->reportStatus(ost, path); - CPPUNIT_ASSERT_MESSAGE("_metricsConsumer->reportStatus failed", retVal); + ASSERT_TRUE(retVal) << "_metricsConsumer->reportStatus failed"; std::string s = ost.str(); - CPPUNIT_ASSERT_MESSAGE("No get statistics in:\n" + s, - s.find("vds.filestor.alldisks.allthreads.get.sum.count count=240") != std::string::npos); - CPPUNIT_ASSERT_MESSAGE("No put statistics in:\n" + s, - s.find("vds.filestor.alldisks.allthreads.put.sum.count count=200") != std::string::npos); - CPPUNIT_ASSERT_MESSAGE("No remove statistics in:\n" + s, - s.find("vds.filestor.alldisks.allthreads.remove.sum.count count=120") != std::string::npos); - CPPUNIT_ASSERT_MESSAGE("No removenotfound stats in:\n" + s, - s.find("vds.filestor.alldisks.allthreads.remove.sum.not_found count=20") != std::string::npos); + EXPECT_THAT(s, HasSubstr("vds.filestor.alldisks.allthreads.get.sum.count count=240")); + EXPECT_THAT(s, HasSubstr("vds.filestor.alldisks.allthreads.put.sum.count count=200")); + EXPECT_THAT(s, HasSubstr("vds.filestor.alldisks.allthreads.remove.sum.count count=120")); + EXPECT_THAT(s, HasSubstr("vds.filestor.alldisks.allthreads.remove.sum.not_found count=20")); } #define ASSERT_METRIC(interval, metric, count) \ diff --git a/storage/src/tests/common/testhelper.h b/storage/src/tests/common/testhelper.h index 1bcc53dfe12..cc7f503e028 100644 --- a/storage/src/tests/common/testhelper.h +++ b/storage/src/tests/common/testhelper.h @@ -1,25 +1,10 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once +#include <vespa/messagebus/testlib/slobrok.h> #include <vespa/vdstestlib/cppunit/dirconfig.h> -#include <vespa/vdstestlib/cppunit/macros.h> - - #include <fstream> -#include <vespa/messagebus/testlib/slobrok.h> #include <sstream> -#define ASSERT_REPLY_COUNT(count, dummylink) \ - { \ - std::ostringstream msgost; \ - if ((dummylink).getNumReplies() != count) { \ - for (uint32_t ijx=0; ijx<(dummylink).getNumReplies(); ++ijx) { \ - msgost << (dummylink).getReply(ijx)->toString(true) << "\n"; \ - } \ - } \ - CPPUNIT_ASSERT_EQUAL_MSG(msgost.str(), size_t(count), \ - (dummylink).getNumReplies()); \ - } - namespace storage { void addFileConfig(vdstestlib::DirConfig& dc, diff --git a/storage/src/tests/common/teststorageapp.cpp b/storage/src/tests/common/teststorageapp.cpp index a720cd191e4..dd89082d3e7 100644 --- a/storage/src/tests/common/teststorageapp.cpp +++ b/storage/src/tests/common/teststorageapp.cpp @@ -7,7 +7,6 @@ #include <vespa/config-load-type.h> #include <vespa/config-fleetcontroller.h> #include <vespa/persistence/dummyimpl/dummypersistence.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/vespalib/io/fileutil.h> #include <vespa/vespalib/util/exceptions.h> #include <vespa/config/config.h> @@ -122,7 +121,7 @@ TestStorageApp::waitUntilInitialized( error << " "; initializer->reportStatus(error, framework::HttpUrlPath("")); LOG(error, "%s", error.str().c_str()); - CPPUNIT_FAIL(error.str().c_str()); + throw std::runtime_error(error.str()); } } } @@ -170,9 +169,9 @@ TestServiceLayerApp::TestServiceLayerApp(DiskCount dc, NodeIndex index, lib::NodeState ns(*_nodeStateUpdater.getReportedNodeState()); ns.setDiskCount(dc); _nodeStateUpdater.setReportedNodeState(ns); - // Tests should know how many disks they want to use. If testing auto - // detection, you should not need this utility. - CPPUNIT_ASSERT(dc > 0); + // Tests should know how many disks they want to use. If testing auto + // detection, you should not need this utility. + assert(dc > 0); } TestServiceLayerApp::~TestServiceLayerApp() {} @@ -190,8 +189,7 @@ TestServiceLayerApp::setPersistenceProvider( spi::PersistenceProvider::UP provider) { _partitions = provider->getPartitionStates().getList(); - CPPUNIT_ASSERT_EQUAL(spi::PartitionId(_compReg.getDiskCount()), - _partitions.size()); + assert(spi::PartitionId(_compReg.getDiskCount()) == _partitions.size()); _persistenceProvider = std::move(provider); } diff --git a/storage/src/tests/distributor/CMakeLists.txt b/storage/src/tests/distributor/CMakeLists.txt index c5d23badfd6..cf6feca26aa 100644 --- a/storage/src/tests/distributor/CMakeLists.txt +++ b/storage/src/tests/distributor/CMakeLists.txt @@ -1,22 +1,29 @@ # Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_library(storage_testdistributor TEST + +vespa_add_executable(storage_distributor_gtest_runner_app TEST SOURCES blockingoperationstartertest.cpp + btree_bucket_database_test.cpp + bucket_db_prune_elision_test.cpp + bucketdatabasetest.cpp bucketdbmetricupdatertest.cpp + bucketdbupdatertest.cpp bucketgctimecalculatortest.cpp bucketstateoperationtest.cpp distributor_host_info_reporter_test.cpp + distributor_message_sender_stub.cpp distributortest.cpp distributortestutil.cpp externaloperationhandlertest.cpp garbagecollectiontest.cpp getoperationtest.cpp + gtest_runner.cpp idealstatemanagertest.cpp joinbuckettest.cpp maintenanceschedulertest.cpp + mapbucketdatabasetest.cpp mergelimitertest.cpp mergeoperationtest.cpp - messagesenderstub.cpp nodeinfotest.cpp nodemaintenancestatstrackertest.cpp operation_sequencer_test.cpp @@ -24,6 +31,7 @@ vespa_add_library(storage_testdistributor TEST ownership_transfer_safe_time_point_calculator_test.cpp pendingmessagetrackertest.cpp persistence_metrics_set_test.cpp + putoperationtest.cpp removebucketoperationtest.cpp removelocationtest.cpp removeoperationtest.cpp @@ -38,29 +46,11 @@ vespa_add_library(storage_testdistributor TEST updateoperationtest.cpp visitoroperationtest.cpp DEPENDS - storage_distributor storage_testcommon storage_testhostreporter -) - -vespa_add_executable(storage_distributor_gtest_runner_app TEST - SOURCES - btree_bucket_database_test.cpp - bucketdatabasetest.cpp - bucketdbupdatertest.cpp - mapbucketdatabasetest.cpp - putoperationtest.cpp - # TODO: Depend on storage_testdistributor when all tests have been migrated - # Fixture etc. dupes with non-gtest runner : - distributortestutil.cpp - bucket_db_prune_elision_test.cpp - messagesenderstub.cpp - gtest_runner.cpp - DEPENDS storage_distributor - storage_testcommon - storage_testhostreporter gtest + gmock ) vespa_add_test( diff --git a/storage/src/tests/distributor/blockingoperationstartertest.cpp b/storage/src/tests/distributor/blockingoperationstartertest.cpp index 0160f5c9e51..9a9e04f0f33 100644 --- a/storage/src/tests/distributor/blockingoperationstartertest.cpp +++ b/storage/src/tests/distributor/blockingoperationstartertest.cpp @@ -1,30 +1,23 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.h> #include <vespa/storage/distributor/blockingoperationstarter.h> #include <vespa/storage/distributor/pendingmessagetracker.h> #include <tests/distributor/maintenancemocks.h> #include <vespa/document/test/make_document_bucket.h> +#include <vespa/vespalib/gtest/gtest.h> using document::test::makeDocumentBucket; - -namespace storage { - -namespace distributor { - using document::BucketId; +using namespace ::testing; -class BlockingOperationStarterTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(BlockingOperationStarterTest); - CPPUNIT_TEST(testOperationNotBlockedWhenNoMessagesPending); - CPPUNIT_TEST(testOperationBlockedWhenMessagesPending); - CPPUNIT_TEST_SUITE_END(); +namespace storage::distributor { +struct BlockingOperationStarterTest : Test { std::shared_ptr<Operation> createMockOperation() { - return std::shared_ptr<Operation>(new MockOperation(makeDocumentBucket(BucketId(16, 1)))); + return std::make_shared<MockOperation>(makeDocumentBucket(BucketId(16, 1))); } std::shared_ptr<Operation> createBlockingMockOperation() { - std::shared_ptr<MockOperation> op(new MockOperation(makeDocumentBucket(BucketId(16, 1)))); + auto op = std::make_shared<MockOperation>(makeDocumentBucket(BucketId(16, 1))); op->setShouldBlock(true); return op; } @@ -35,43 +28,30 @@ class BlockingOperationStarterTest : public CppUnit::TestFixture { std::unique_ptr<PendingMessageTracker> _messageTracker; std::unique_ptr<BlockingOperationStarter> _operationStarter; -public: - void testOperationNotBlockedWhenNoMessagesPending(); - void testOperationBlockedWhenMessagesPending(); - - void setUp() override; + void SetUp() override; }; -CPPUNIT_TEST_SUITE_REGISTRATION(BlockingOperationStarterTest); - void -BlockingOperationStarterTest::setUp() +BlockingOperationStarterTest::SetUp() { - _starterImpl.reset(new MockOperationStarter()); - _compReg.reset(new StorageComponentRegisterImpl()); + _starterImpl = std::make_unique<MockOperationStarter>(); + _compReg = std::make_unique<StorageComponentRegisterImpl>(); _compReg->setClock(_clock); _clock.setAbsoluteTimeInSeconds(1); - _messageTracker.reset(new PendingMessageTracker(*_compReg)); - _operationStarter.reset(new BlockingOperationStarter(*_messageTracker, *_starterImpl)); + _messageTracker = std::make_unique<PendingMessageTracker>(*_compReg); + _operationStarter = std::make_unique<BlockingOperationStarter>(*_messageTracker, *_starterImpl); } -void -BlockingOperationStarterTest::testOperationNotBlockedWhenNoMessagesPending() -{ - CPPUNIT_ASSERT(_operationStarter->start(createMockOperation(), - OperationStarter::Priority(0))); - CPPUNIT_ASSERT_EQUAL(std::string("Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri 0\n"), - _starterImpl->toString()); +TEST_F(BlockingOperationStarterTest, operation_not_blocked_when_no_messages_pending) { + ASSERT_TRUE(_operationStarter->start(createMockOperation(), OperationStarter::Priority(0))); + EXPECT_EQ("Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri 0\n", + _starterImpl->toString()); } -void -BlockingOperationStarterTest::testOperationBlockedWhenMessagesPending() -{ +TEST_F(BlockingOperationStarterTest, operation_blocked_when_messages_pending) { // start should return true but not forward message to underlying starter. - CPPUNIT_ASSERT(_operationStarter->start(createBlockingMockOperation(), - OperationStarter::Priority(0))); - CPPUNIT_ASSERT_EQUAL(std::string(""), _starterImpl->toString()); + ASSERT_TRUE(_operationStarter->start(createBlockingMockOperation(), OperationStarter::Priority(0))); + EXPECT_EQ("", _starterImpl->toString()); } } -} diff --git a/storage/src/tests/distributor/bucketdatabasetest.cpp b/storage/src/tests/distributor/bucketdatabasetest.cpp index cfb54edbe78..6225865b153 100644 --- a/storage/src/tests/distributor/bucketdatabasetest.cpp +++ b/storage/src/tests/distributor/bucketdatabasetest.cpp @@ -113,7 +113,7 @@ struct StoppingProcessor : public BucketDatabase::EntryProcessor { } -TEST_P(BucketDatabaseTest, testIterating) { +TEST_P(BucketDatabaseTest, iterating) { // Do some insertions db().update(BucketDatabase::Entry(document::BucketId(16, 0x10), BI(1))); db().update(BucketDatabase::Entry(document::BucketId(16, 0x0b), BI(2))); @@ -186,7 +186,7 @@ BucketDatabaseTest::doFindParents(const std::vector<document::BucketId>& ids, return ost.str(); } -TEST_P(BucketDatabaseTest, testFindParents) { +TEST_P(BucketDatabaseTest, find_parents) { // test what parents in the DB (specified in vector) are parents of the // specified bucket. Result is a list of indexes into the vector. @@ -287,7 +287,7 @@ BucketDatabaseTest::doFindAll(const std::vector<document::BucketId>& ids, return ost.str(); } -TEST_P(BucketDatabaseTest, testFindAll) { +TEST_P(BucketDatabaseTest, find_all) { std::vector<document::BucketId> buckets; EXPECT_EQ( std::string(""), @@ -389,7 +389,7 @@ BucketDatabaseTest::doCreate(const std::vector<document::BucketId>& ids, } // TODO rewrite in terms of bucket getter, not creator -TEST_P(BucketDatabaseTest, testCreateAppropriateBucket) { +TEST_P(BucketDatabaseTest, create_appropriate_bucket) { // Use min split bits when no relevant bucket exist. EXPECT_EQ( document::BucketId(36,0x0000004d2), @@ -439,7 +439,7 @@ TEST_P(BucketDatabaseTest, testCreateAppropriateBucket) { document::BucketId(58, 0x00000000010004d2))); } -TEST_P(BucketDatabaseTest, testGetNext) { +TEST_P(BucketDatabaseTest, get_next) { db().update(BucketDatabase::Entry(document::BucketId(16, 16), BI(1))); db().update(BucketDatabase::Entry(document::BucketId(16, 11), BI(2))); db().update(BucketDatabase::Entry(document::BucketId(16, 42), BI(3))); @@ -492,7 +492,7 @@ BucketDatabaseTest::doTestUpperBound(const UBoundFunc& f) EXPECT_EQ(BucketId(8, 0xff), f(db(), BucketId(8, 0))); } -TEST_P(BucketDatabaseTest, testUpperBoundReturnsNextInOrderGreaterBucket) { +TEST_P(BucketDatabaseTest, upper_bound_returns_next_in_order_greater_bucket) { doTestUpperBound([](const BucketDatabase& bucketDb, const document::BucketId& id) { @@ -500,7 +500,7 @@ TEST_P(BucketDatabaseTest, testUpperBoundReturnsNextInOrderGreaterBucket) { }); } -TEST_P(BucketDatabaseTest, testGetNextReturnsUpperBoundBucket) { +TEST_P(BucketDatabaseTest, get_next_returns_upper_bound_bucket) { // getNext() would generally be implemented in terms of upperBound(), but // make sure it conforms to the same contract in case this changes. doTestUpperBound([](const BucketDatabase& bucketDb, @@ -510,7 +510,7 @@ TEST_P(BucketDatabaseTest, testGetNextReturnsUpperBoundBucket) { }); } -TEST_P(BucketDatabaseTest, testChildCount) { +TEST_P(BucketDatabaseTest, child_count) { // Empty tree; inserts cannot create inconsistencies. EXPECT_EQ(0u, db().childCount(BucketId(3, 1))); diff --git a/storage/src/tests/distributor/bucketdbmetricupdatertest.cpp b/storage/src/tests/distributor/bucketdbmetricupdatertest.cpp index 152a213a4f4..1008d3ee4f2 100644 --- a/storage/src/tests/distributor/bucketdbmetricupdatertest.cpp +++ b/storage/src/tests/distributor/bucketdbmetricupdatertest.cpp @@ -1,57 +1,32 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> -#include <string> -#include <sstream> #include <vespa/storage/bucketdb/bucketdatabase.h> #include <vespa/storage/distributor/bucketdb/bucketdbmetricupdater.h> #include <vespa/storage/distributor/distributormetricsset.h> #include <vespa/storage/distributor/idealstatemetricsset.h> #include <vespa/storage/config/config-stor-distributormanager.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <string> +#include <sstream> -namespace storage { -namespace distributor { +namespace storage::distributor { using document::BucketId; +using namespace ::testing; -class BucketDBMetricUpdaterTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(BucketDBMetricUpdaterTest); - CPPUNIT_TEST(testDocAndByteCountsAreUpdated); - CPPUNIT_TEST(testBucketsWithTooFewAndTooManyCopies); - CPPUNIT_TEST(testBucketsWithVaryingTrustedness); - CPPUNIT_TEST(testPickCountsFromTrustedCopy); - CPPUNIT_TEST(testPickLargestCopyIfNoTrusted); - CPPUNIT_TEST(testCompleteRoundClearsWorkingState); - CPPUNIT_TEST(testMinBucketReplicaTrackedAndReportedPerNode); - CPPUNIT_TEST(nonTrustedReplicasAlsoCountedInModeAny); - CPPUNIT_TEST(minimumReplicaCountReturnedForNodeInModeAny); - CPPUNIT_TEST_SUITE_END(); - +struct BucketDBMetricUpdaterTest : Test { void visitBucketWith2Copies1Trusted(BucketDBMetricUpdater& metricUpdater); void visitBucketWith2CopiesBothTrusted( BucketDBMetricUpdater& metricUpdater); void visitBucketWith1Copy(BucketDBMetricUpdater& metricUpdater); - using NodeToReplicasMap = std::unordered_map<uint16_t, uint32_t>; NodeToReplicasMap replicaStatsOf(BucketDBMetricUpdater& metricUpdater); metrics::LoadTypeSet _loadTypes; -public: - BucketDBMetricUpdaterTest(); - void testDocAndByteCountsAreUpdated(); - void testBucketsWithTooFewAndTooManyCopies(); - void testBucketsWithVaryingTrustedness(); - void testPickCountsFromTrustedCopy(); - void testPickLargestCopyIfNoTrusted(); - void testCompleteRoundClearsWorkingState(); - void testMinBucketReplicaTrackedAndReportedPerNode(); - void nonTrustedReplicasAlsoCountedInModeAny(); - void minimumReplicaCountReturnedForNodeInModeAny(); + BucketDBMetricUpdaterTest(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(BucketDBMetricUpdaterTest); - BucketDBMetricUpdaterTest::BucketDBMetricUpdaterTest() { _loadTypes.push_back(metrics::LoadType(0, "foo")); @@ -65,7 +40,7 @@ void addNode(BucketInfo& info, uint16_t node, uint32_t crc) { info.addNode(BucketCopy(1234, node, apiInfo), order); } -typedef bool Trusted; +using Trusted = bool; BucketInfo makeInfo(uint32_t copy0Crc) @@ -86,22 +61,20 @@ makeInfo(uint32_t copy0Crc, uint32_t copy1Crc) } // anonymous namespace -void -BucketDBMetricUpdaterTest::testDocAndByteCountsAreUpdated() -{ +TEST_F(BucketDBMetricUpdaterTest, doc_and_byte_counts_are_updated) { BucketDBMetricUpdater metricUpdater; IdealStateMetricSet ims; DistributorMetricSet dms(_loadTypes); - CPPUNIT_ASSERT_EQUAL(false, metricUpdater.hasCompletedRound()); + EXPECT_FALSE(metricUpdater.hasCompletedRound()); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); metricUpdater.completeRound(false); - CPPUNIT_ASSERT_EQUAL(true, metricUpdater.hasCompletedRound()); + EXPECT_TRUE(metricUpdater.hasCompletedRound()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), dms.docsStored.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), dms.bytesStored.getLast()); + EXPECT_EQ(0, dms.docsStored.getLast()); + EXPECT_EQ(0, dms.bytesStored.getLast()); { BucketDatabase::Entry e(document::BucketId(16, 1), makeInfo(10)); metricUpdater.visit(e, 1); @@ -110,10 +83,10 @@ BucketDBMetricUpdaterTest::testDocAndByteCountsAreUpdated() metricUpdater.completeRound(false); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(true, metricUpdater.hasCompletedRound()); + EXPECT_TRUE(metricUpdater.hasCompletedRound()); - CPPUNIT_ASSERT_EQUAL(int64_t(11), dms.docsStored.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(12), dms.bytesStored.getLast()); + EXPECT_EQ(11, dms.docsStored.getLast()); + EXPECT_EQ(12, dms.bytesStored.getLast()); { BucketDatabase::Entry e(document::BucketId(16, 1), makeInfo(20)); @@ -123,22 +96,20 @@ BucketDBMetricUpdaterTest::testDocAndByteCountsAreUpdated() metricUpdater.completeRound(false); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(32), dms.docsStored.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(34), dms.bytesStored.getLast()); + EXPECT_EQ(32, dms.docsStored.getLast()); + EXPECT_EQ(34, dms.bytesStored.getLast()); } -void -BucketDBMetricUpdaterTest::testBucketsWithTooFewAndTooManyCopies() -{ +TEST_F(BucketDBMetricUpdaterTest, buckets_with_too_few_and_too_many_copies) { BucketDBMetricUpdater metricUpdater; IdealStateMetricSet ims; DistributorMetricSet dms(_loadTypes); metricUpdater.completeRound(); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(0), ims.buckets_toofewcopies.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), ims.buckets_toomanycopies.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), ims.buckets.getLast()); + EXPECT_EQ(0, ims.buckets_toofewcopies.getLast()); + EXPECT_EQ(0, ims.buckets_toomanycopies.getLast()); + EXPECT_EQ(0, ims.buckets.getLast()); // 1 copy too little { @@ -148,9 +119,9 @@ BucketDBMetricUpdaterTest::testBucketsWithTooFewAndTooManyCopies() metricUpdater.completeRound(false); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(1), ims.buckets_toofewcopies.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), ims.buckets_toomanycopies.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), ims.buckets.getLast()); + EXPECT_EQ(1, ims.buckets_toofewcopies.getLast()); + EXPECT_EQ(0, ims.buckets_toomanycopies.getLast()); + EXPECT_EQ(1, ims.buckets.getLast()); // 1 copy too many { @@ -160,9 +131,9 @@ BucketDBMetricUpdaterTest::testBucketsWithTooFewAndTooManyCopies() metricUpdater.completeRound(false); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(1), ims.buckets_toofewcopies.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), ims.buckets_toomanycopies.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(2), ims.buckets.getLast()); + EXPECT_EQ(1, ims.buckets_toofewcopies.getLast()); + EXPECT_EQ(1, ims.buckets_toomanycopies.getLast()); + EXPECT_EQ(2, ims.buckets.getLast()); // Right amount of copies, just inc bucket counter. { @@ -172,21 +143,19 @@ BucketDBMetricUpdaterTest::testBucketsWithTooFewAndTooManyCopies() metricUpdater.completeRound(false); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(1), ims.buckets_toofewcopies.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), ims.buckets_toomanycopies.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(3), ims.buckets.getLast()); + EXPECT_EQ(1, ims.buckets_toofewcopies.getLast()); + EXPECT_EQ(1, ims.buckets_toomanycopies.getLast()); + EXPECT_EQ(3, ims.buckets.getLast()); } -void -BucketDBMetricUpdaterTest::testBucketsWithVaryingTrustedness() -{ +TEST_F(BucketDBMetricUpdaterTest, buckets_with_varying_trustedness) { BucketDBMetricUpdater metricUpdater; IdealStateMetricSet ims; DistributorMetricSet dms(_loadTypes); metricUpdater.completeRound(false); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(0), ims.buckets_notrusted.getLast()); + EXPECT_EQ(0, ims.buckets_notrusted.getLast()); // Has only trusted (implicit for first added) { BucketDatabase::Entry e(document::BucketId(16, 1), makeInfo(100)); @@ -194,7 +163,7 @@ BucketDBMetricUpdaterTest::testBucketsWithVaryingTrustedness() } metricUpdater.completeRound(false); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(0), ims.buckets_notrusted.getLast()); + EXPECT_EQ(0, ims.buckets_notrusted.getLast()); // Has at least one trusted (implicit for first added) { BucketDatabase::Entry e(document::BucketId(16, 2), makeInfo(100, 200)); @@ -202,7 +171,7 @@ BucketDBMetricUpdaterTest::testBucketsWithVaryingTrustedness() } metricUpdater.completeRound(false); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(0), ims.buckets_notrusted.getLast()); + EXPECT_EQ(0, ims.buckets_notrusted.getLast()); // Has no trusted { BucketInfo info(makeInfo(100, 200)); @@ -212,12 +181,10 @@ BucketDBMetricUpdaterTest::testBucketsWithVaryingTrustedness() } metricUpdater.completeRound(false); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(1), ims.buckets_notrusted.getLast()); + EXPECT_EQ(1, ims.buckets_notrusted.getLast()); } -void -BucketDBMetricUpdaterTest::testPickCountsFromTrustedCopy() -{ +TEST_F(BucketDBMetricUpdaterTest, pick_counts_from_trusted_copy) { BucketDBMetricUpdater metricUpdater; IdealStateMetricSet ims; DistributorMetricSet dms(_loadTypes); @@ -228,13 +195,11 @@ BucketDBMetricUpdaterTest::testPickCountsFromTrustedCopy() metricUpdater.completeRound(false); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(101), dms.docsStored.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(102), dms.bytesStored.getLast()); + EXPECT_EQ(101, dms.docsStored.getLast()); + EXPECT_EQ(102, dms.bytesStored.getLast()); } -void -BucketDBMetricUpdaterTest::testPickLargestCopyIfNoTrusted() -{ +TEST_F(BucketDBMetricUpdaterTest, pick_largest_copy_if_no_trusted) { BucketDBMetricUpdater metricUpdater; IdealStateMetricSet ims; DistributorMetricSet dms(_loadTypes); @@ -247,13 +212,11 @@ BucketDBMetricUpdaterTest::testPickLargestCopyIfNoTrusted() metricUpdater.completeRound(false); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(201), dms.docsStored.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(202), dms.bytesStored.getLast()); + EXPECT_EQ(201, dms.docsStored.getLast()); + EXPECT_EQ(202, dms.bytesStored.getLast()); } -void -BucketDBMetricUpdaterTest::testCompleteRoundClearsWorkingState() -{ +TEST_F(BucketDBMetricUpdaterTest, complete_round_clears_working_state) { BucketDBMetricUpdater metricUpdater; IdealStateMetricSet ims; DistributorMetricSet dms(_loadTypes); @@ -265,13 +228,13 @@ BucketDBMetricUpdaterTest::testCompleteRoundClearsWorkingState() metricUpdater.completeRound(); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(11), dms.docsStored.getLast()); + EXPECT_EQ(11, dms.docsStored.getLast()); // Completing the round again with no visits having been done will // propagate an empty working state to the complete state. metricUpdater.completeRound(); metricUpdater.getLastCompleteStats().propagateMetrics(ims, dms); - CPPUNIT_ASSERT_EQUAL(int64_t(0), dms.docsStored.getLast()); + EXPECT_EQ(0, dms.docsStored.getLast()); } // Replicas on nodes 0 and 1. @@ -316,8 +279,7 @@ BucketDBMetricUpdaterTest::replicaStatsOf(BucketDBMetricUpdater& metricUpdater) return metricUpdater.getLastCompleteStats()._minBucketReplica; } -void BucketDBMetricUpdaterTest::testMinBucketReplicaTrackedAndReportedPerNode() -{ +TEST_F(BucketDBMetricUpdaterTest, min_bucket_replica_tracked_and_reported_per_node) { BucketDBMetricUpdater metricUpdater; // Node 0 and 1 should have min replica 1, while node 2 should have min @@ -325,26 +287,22 @@ void BucketDBMetricUpdaterTest::testMinBucketReplicaTrackedAndReportedPerNode() visitBucketWith2Copies1Trusted(metricUpdater); visitBucketWith2CopiesBothTrusted(metricUpdater); - CPPUNIT_ASSERT_EQUAL(NodeToReplicasMap({{0, 1}, {1, 1}, {2, 2}}), - replicaStatsOf(metricUpdater)); + EXPECT_EQ(NodeToReplicasMap({{0, 1}, {1, 1}, {2, 2}}), + replicaStatsOf(metricUpdater)); } -void -BucketDBMetricUpdaterTest::nonTrustedReplicasAlsoCountedInModeAny() -{ +TEST_F(BucketDBMetricUpdaterTest, non_trusted_replicas_also_counted_in_mode_any) { BucketDBMetricUpdater metricUpdater; using CountingMode = BucketDBMetricUpdater::ReplicaCountingMode; metricUpdater.setMinimumReplicaCountingMode(CountingMode::ANY); visitBucketWith2Copies1Trusted(metricUpdater); visitBucketWith2CopiesBothTrusted(metricUpdater); - CPPUNIT_ASSERT_EQUAL(NodeToReplicasMap({{0, 2}, {1, 2}, {2, 2}}), - replicaStatsOf(metricUpdater)); + EXPECT_EQ(NodeToReplicasMap({{0, 2}, {1, 2}, {2, 2}}), + replicaStatsOf(metricUpdater)); } -void -BucketDBMetricUpdaterTest::minimumReplicaCountReturnedForNodeInModeAny() -{ +TEST_F(BucketDBMetricUpdaterTest, minimum_replica_count_returned_for_node_in_mode_any) { BucketDBMetricUpdater metricUpdater; using CountingMode = BucketDBMetricUpdater::ReplicaCountingMode; metricUpdater.setMinimumReplicaCountingMode(CountingMode::ANY); @@ -352,9 +310,8 @@ BucketDBMetricUpdaterTest::minimumReplicaCountReturnedForNodeInModeAny() visitBucketWith1Copy(metricUpdater); // Node 2 has a bucket with only 1 replica. - CPPUNIT_ASSERT_EQUAL(NodeToReplicasMap({{0, 2}, {2, 1}}), - replicaStatsOf(metricUpdater)); + EXPECT_EQ(NodeToReplicasMap({{0, 2}, {2, 1}}), + replicaStatsOf(metricUpdater)); } -} // distributor -} // storage +} // storage::distributor diff --git a/storage/src/tests/distributor/bucketdbupdatertest.cpp b/storage/src/tests/distributor/bucketdbupdatertest.cpp index 2ddf41236c9..321b0cc3bba 100644 --- a/storage/src/tests/distributor/bucketdbupdatertest.cpp +++ b/storage/src/tests/distributor/bucketdbupdatertest.cpp @@ -270,16 +270,16 @@ public: } }; - void sortSentMessagesByIndex(MessageSenderStub& sender, + void sortSentMessagesByIndex(DistributorMessageSenderStub& sender, size_t sortFromOffset = 0) { - std::sort(sender.commands.begin() + sortFromOffset, - sender.commands.end(), + std::sort(sender.commands().begin() + sortFromOffset, + sender.commands().end(), OrderByIncreasingNodeIndex()); } void setSystemState(const lib::ClusterState& state) { - const size_t sizeBeforeState = _sender.commands.size(); + const size_t sizeBeforeState = _sender.commands().size(); getBucketDBUpdater().onSetSystemState( std::make_shared<api::SetSystemStateCommand>(state)); // A lot of test logic has the assumption that all messages sent as a @@ -291,7 +291,7 @@ public: } void set_cluster_state_bundle(const lib::ClusterStateBundle& state) { - const size_t sizeBeforeState = _sender.commands.size(); + const size_t sizeBeforeState = _sender.commands().size(); getBucketDBUpdater().onSetSystemState( std::make_shared<api::SetSystemStateCommand>(state)); sortSentMessagesByIndex(_sender, sizeBeforeState); @@ -303,8 +303,8 @@ public: } void assert_has_activate_cluster_state_reply_with_actual_version(uint32_t version) { - ASSERT_EQ(size_t(1), _sender.replies.size()); - auto* response = dynamic_cast<api::ActivateClusterStateVersionReply*>(_sender.replies.back().get()); + ASSERT_EQ(size_t(1), _sender.replies().size()); + auto* response = dynamic_cast<api::ActivateClusterStateVersionReply*>(_sender.replies().back().get()); ASSERT_TRUE(response != nullptr); ASSERT_EQ(version, response->actualVersion()); _sender.clear(); @@ -315,10 +315,10 @@ public: uint32_t bucketCount = 1, uint32_t invalidBucketCount = 0) { - ASSERT_EQ(expectedMsgs, _sender.commands.size()); + ASSERT_EQ(expectedMsgs, _sender.commands().size()); - for (uint32_t i = 0; i < _sender.commands.size(); i++) { - ASSERT_NO_FATAL_FAILURE(fakeBucketReply(state, *_sender.commands[i], + for (uint32_t i = 0; i < _sender.commands().size(); i++) { + ASSERT_NO_FATAL_FAILURE(fakeBucketReply(state, *_sender.command(i), bucketCount, invalidBucketCount)); } } @@ -356,9 +356,9 @@ public: setSystemState(newState); for (uint32_t i=0; i< messageCount(numStorageNodes); i++) { - ASSERT_EQ(_sender.commands[i]->getType(), MessageType::REQUESTBUCKETINFO); + ASSERT_EQ(_sender.command(i)->getType(), MessageType::REQUESTBUCKETINFO); - const api::StorageMessageAddress *address = _sender.commands[i]->getAddress(); + const api::StorageMessageAddress *address = _sender.command(i)->getAddress(); ASSERT_EQ((uint32_t)(i / _bucketSpaces.size()), (uint32_t)address->getIndex()); } } @@ -373,7 +373,7 @@ public: lib::ClusterState newState(state); for (uint32_t i=0; i< messageCount(numStorageNodes); i++) { - ASSERT_NO_FATAL_FAILURE(fakeBucketReply(newState, *_sender.commands[i], numBuckets)); + ASSERT_NO_FATAL_FAILURE(fakeBucketReply(newState, *_sender.command(i), numBuckets)); } ASSERT_NO_FATAL_FAILURE(assertCorrectBuckets(numBuckets, state)); } @@ -495,7 +495,7 @@ public: } struct PendingClusterStateFixture { - MessageSenderStub sender; + DistributorMessageSenderStub sender; framework::defaultimplementation::FakeClock clock; std::unique_ptr<PendingClusterState> state; @@ -556,20 +556,20 @@ BucketDBUpdaterTest::BucketDBUpdaterTest() { } -TEST_F(BucketDBUpdaterTest, testNormalUsage) { +TEST_F(BucketDBUpdaterTest, normal_usage) { setSystemState(lib::ClusterState("distributor:2 .0.s:i .1.s:i storage:3")); - ASSERT_EQ(messageCount(3), _sender.commands.size()); + ASSERT_EQ(messageCount(3), _sender.commands().size()); // Ensure distribution hash is set correctly ASSERT_EQ( defaultDistributorBucketSpace().getDistribution() .getNodeGraph().getDistributionConfigHash(), dynamic_cast<const RequestBucketInfoCommand&>( - *_sender.commands[0]).getDistributionHash()); + *_sender.command(0)).getDistributionHash()); ASSERT_NO_FATAL_FAILURE(fakeBucketReply(lib::ClusterState("distributor:2 .0.s:i .1.s:i storage:3"), - *_sender.commands[0], 10)); + *_sender.command(0), 10)); _sender.clear(); @@ -577,9 +577,9 @@ TEST_F(BucketDBUpdaterTest, testNormalUsage) { // change is only implemented after completion of previous cluster state setSystemState(lib::ClusterState("distributor:2 .0.s:i storage:3")); - ASSERT_EQ(messageCount(3), _sender.commands.size()); + ASSERT_EQ(messageCount(3), _sender.commands().size()); // Expect reply of first set SystemState request. - ASSERT_EQ(size_t(1), _sender.replies.size()); + ASSERT_EQ(size_t(1), _sender.replies().size()); ASSERT_NO_FATAL_FAILURE(completeBucketInfoGathering( lib::ClusterState("distributor:2 .0.s:i .1.s:i storage:3"), @@ -587,74 +587,74 @@ TEST_F(BucketDBUpdaterTest, testNormalUsage) { ASSERT_NO_FATAL_FAILURE(assertCorrectBuckets(10, "distributor:2 storage:3")); } -TEST_F(BucketDBUpdaterTest, testDistributorChange) { +TEST_F(BucketDBUpdaterTest, distributor_change) { int numBuckets = 100; // First sends request setSystemState(lib::ClusterState("distributor:2 .0.s:i .1.s:i storage:3")); - ASSERT_EQ(messageCount(3), _sender.commands.size()); + ASSERT_EQ(messageCount(3), _sender.commands().size()); ASSERT_NO_FATAL_FAILURE(completeBucketInfoGathering(lib::ClusterState("distributor:2 .0.s:i .1.s:i storage:3"), messageCount(3), numBuckets)); _sender.clear(); // No change from initializing to up (when done with last job) setSystemState(lib::ClusterState("distributor:2 storage:3")); - ASSERT_EQ(size_t(0), _sender.commands.size()); + ASSERT_EQ(size_t(0), _sender.commands().size()); _sender.clear(); // Adding node. No new read requests, but buckets thrown setSystemState(lib::ClusterState("distributor:3 storage:3")); - ASSERT_EQ(size_t(0), _sender.commands.size()); + ASSERT_EQ(size_t(0), _sender.commands().size()); ASSERT_NO_FATAL_FAILURE(assertCorrectBuckets(numBuckets, "distributor:3 storage:3")); _sender.clear(); // Removing distributor. Need to refetch new data from all nodes. setSystemState(lib::ClusterState("distributor:2 storage:3")); - ASSERT_EQ(messageCount(3), _sender.commands.size()); + ASSERT_EQ(messageCount(3), _sender.commands().size()); ASSERT_NO_FATAL_FAILURE(completeBucketInfoGathering(lib::ClusterState("distributor:2 storage:3"), messageCount(3), numBuckets)); _sender.clear(); ASSERT_NO_FATAL_FAILURE(assertCorrectBuckets(numBuckets, "distributor:2 storage:3")); } -TEST_F(BucketDBUpdaterTest, testDistributorChangeWithGrouping) { +TEST_F(BucketDBUpdaterTest, distributor_change_with_grouping) { std::string distConfig(getDistConfig6Nodes2Groups()); setDistribution(distConfig); int numBuckets = 100; setSystemState(lib::ClusterState("distributor:6 storage:6")); - ASSERT_EQ(messageCount(6), _sender.commands.size()); + ASSERT_EQ(messageCount(6), _sender.commands().size()); ASSERT_NO_FATAL_FAILURE(completeBucketInfoGathering(lib::ClusterState("distributor:6 storage:6"), messageCount(6), numBuckets)); _sender.clear(); // Distributor going down in other group, no change setSystemState(lib::ClusterState("distributor:6 .5.s:d storage:6")); - ASSERT_EQ(size_t(0), _sender.commands.size()); + ASSERT_EQ(size_t(0), _sender.commands().size()); _sender.clear(); setSystemState(lib::ClusterState("distributor:6 storage:6")); - ASSERT_EQ(size_t(0), _sender.commands.size()); + ASSERT_EQ(size_t(0), _sender.commands().size()); ASSERT_NO_FATAL_FAILURE(assertCorrectBuckets(numBuckets, "distributor:6 storage:6")); _sender.clear(); // Unchanged grouping cause no change. setDistribution(distConfig); - ASSERT_EQ(size_t(0), _sender.commands.size()); + ASSERT_EQ(size_t(0), _sender.commands().size()); // Changed grouping cause change setDistribution(getDistConfig6Nodes4Groups()); - ASSERT_EQ(messageCount(6), _sender.commands.size()); + ASSERT_EQ(messageCount(6), _sender.commands().size()); } -TEST_F(BucketDBUpdaterTest, testNormalUsageInitializing) { +TEST_F(BucketDBUpdaterTest, normal_usage_initializing) { setSystemState(lib::ClusterState("distributor:1 .0.s:i storage:1 .0.s:i")); - ASSERT_EQ(_bucketSpaces.size(), _sender.commands.size()); + ASSERT_EQ(_bucketSpaces.size(), _sender.commands().size()); // Not yet passing on system state. - ASSERT_EQ(size_t(0), _senderDown.commands.size()); + ASSERT_EQ(size_t(0), _senderDown.commands().size()); ASSERT_NO_FATAL_FAILURE(completeBucketInfoGathering(lib::ClusterState("distributor:1 .0.s:i storage:1"), _bucketSpaces.size(), 10, 10)); @@ -666,7 +666,7 @@ TEST_F(BucketDBUpdaterTest, testNormalUsageInitializing) { } // Pass on cluster state and recheck buckets now. - ASSERT_EQ(size_t(1), _senderDown.commands.size()); + ASSERT_EQ(size_t(1), _senderDown.commands().size()); _sender.clear(); _senderDown.clear(); @@ -674,28 +674,28 @@ TEST_F(BucketDBUpdaterTest, testNormalUsageInitializing) { setSystemState(lib::ClusterState("distributor:1 .0.s:i storage:1")); // Send a new request bucket info up. - ASSERT_EQ(_bucketSpaces.size(), _sender.commands.size()); + ASSERT_EQ(_bucketSpaces.size(), _sender.commands().size()); ASSERT_NO_FATAL_FAILURE(completeBucketInfoGathering(lib::ClusterState("distributor:1 .0.s:i storage:1"), _bucketSpaces.size(), 20)); // Pass on cluster state and recheck buckets now. - ASSERT_EQ(size_t(1), _senderDown.commands.size()); + ASSERT_EQ(size_t(1), _senderDown.commands().size()); ASSERT_NO_FATAL_FAILURE(assertCorrectBuckets(20, "distributor:1 storage:1")); } -TEST_F(BucketDBUpdaterTest, testFailedRequestBucketInfo) { +TEST_F(BucketDBUpdaterTest, failed_request_bucket_info) { setSystemState(lib::ClusterState("distributor:1 .0.s:i storage:1")); // 2 messages sent up: 1 to the nodes, and one reply to the setsystemstate. - ASSERT_EQ(_bucketSpaces.size(), _sender.commands.size()); + ASSERT_EQ(_bucketSpaces.size(), _sender.commands().size()); { for (uint32_t i = 0; i < _bucketSpaces.size(); ++i) { std::shared_ptr<api::RequestBucketInfoReply> reply = getFakeBucketReply(lib::ClusterState("distributor:1 .0.s:i storage:1"), - *((RequestBucketInfoCommand*)_sender.commands[i].get()), + *((RequestBucketInfoCommand*)_sender.command(i).get()), 0, 10); reply->setResult(api::ReturnCode::NOT_CONNECTED); @@ -710,11 +710,11 @@ TEST_F(BucketDBUpdaterTest, testFailedRequestBucketInfo) { // Should be resent. ASSERT_EQ(getRequestBucketInfoStrings(messageCount(2)), _sender.getCommands()); - ASSERT_EQ(size_t(0), _senderDown.commands.size()); + ASSERT_EQ(size_t(0), _senderDown.commands().size()); for (uint32_t i = 0; i < _bucketSpaces.size(); ++i) { ASSERT_NO_FATAL_FAILURE(fakeBucketReply(lib::ClusterState("distributor:1 .0.s:i storage:1"), - *_sender.commands[_bucketSpaces.size() + i], 10)); + *_sender.command(_bucketSpaces.size() + i), 10)); } for (int i=0; i<10; i++) { @@ -727,19 +727,19 @@ TEST_F(BucketDBUpdaterTest, testFailedRequestBucketInfo) { EXPECT_EQ(std::string("Set system state"), _senderDown.getCommands()); } -TEST_F(BucketDBUpdaterTest, testDownWhileInit) { +TEST_F(BucketDBUpdaterTest, down_while_init) { ASSERT_NO_FATAL_FAILURE(setStorageNodes(3)); ASSERT_NO_FATAL_FAILURE(fakeBucketReply(lib::ClusterState("distributor:1 storage:3"), - *_sender.commands[0], 5)); + *_sender.command(0), 5)); setSystemState(lib::ClusterState("distributor:1 storage:3 .1.s:d")); ASSERT_NO_FATAL_FAILURE(fakeBucketReply(lib::ClusterState("distributor:1 storage:3"), - *_sender.commands[2], 5)); + *_sender.command(2), 5)); ASSERT_NO_FATAL_FAILURE(fakeBucketReply(lib::ClusterState("distributor:1 storage:3"), - *_sender.commands[1], 5)); + *_sender.command(1), 5)); } bool @@ -790,7 +790,7 @@ BucketDBUpdaterTest::expandNodeVec(const std::vector<uint16_t> &nodes) return res; } -TEST_F(BucketDBUpdaterTest, testNodeDown) { +TEST_F(BucketDBUpdaterTest, node_down) { ASSERT_NO_FATAL_FAILURE(setStorageNodes(3)); enableDistributorClusterState("distributor:1 storage:3"); @@ -805,7 +805,7 @@ TEST_F(BucketDBUpdaterTest, testNodeDown) { EXPECT_FALSE(bucketExistsThatHasNode(100, 1)); } -TEST_F(BucketDBUpdaterTest, testStorageNodeInMaintenanceClearsBucketsForNode) { +TEST_F(BucketDBUpdaterTest, storage_node_in_maintenance_clears_buckets_for_node) { ASSERT_NO_FATAL_FAILURE(setStorageNodes(3)); enableDistributorClusterState("distributor:1 storage:3"); @@ -820,7 +820,7 @@ TEST_F(BucketDBUpdaterTest, testStorageNodeInMaintenanceClearsBucketsForNode) { EXPECT_FALSE(bucketExistsThatHasNode(100, 1)); } -TEST_F(BucketDBUpdaterTest, testNodeDownCopiesGetInSync) { +TEST_F(BucketDBUpdaterTest, node_down_copies_get_in_sync) { ASSERT_NO_FATAL_FAILURE(setStorageNodes(3)); lib::ClusterState systemState("distributor:1 storage:3"); @@ -837,35 +837,35 @@ TEST_F(BucketDBUpdaterTest, testNodeDownCopiesGetInSync) { dumpBucket(bid)); } -TEST_F(BucketDBUpdaterTest, testInitializingWhileRecheck) { +TEST_F(BucketDBUpdaterTest, initializing_while_recheck) { lib::ClusterState systemState("distributor:1 storage:2 .0.s:i .0.i:0.1"); setSystemState(systemState); - ASSERT_EQ(messageCount(2), _sender.commands.size()); - ASSERT_EQ(size_t(0), _senderDown.commands.size()); + ASSERT_EQ(messageCount(2), _sender.commands().size()); + ASSERT_EQ(size_t(0), _senderDown.commands().size()); getBucketDBUpdater().recheckBucketInfo(1, makeDocumentBucket(document::BucketId(16, 3))); for (uint32_t i = 0; i < messageCount(2); ++i) { - ASSERT_NO_FATAL_FAILURE(fakeBucketReply(systemState, *_sender.commands[i], 100)); + ASSERT_NO_FATAL_FAILURE(fakeBucketReply(systemState, *_sender.command(i), 100)); } // Now we can pass on system state. - ASSERT_EQ(size_t(1), _senderDown.commands.size()); - EXPECT_EQ(MessageType::SETSYSTEMSTATE, _senderDown.commands[0]->getType()); + ASSERT_EQ(size_t(1), _senderDown.commands().size()); + EXPECT_EQ(MessageType::SETSYSTEMSTATE, _senderDown.command(0)->getType()); } -TEST_F(BucketDBUpdaterTest, testBitChange) { +TEST_F(BucketDBUpdaterTest, bit_change) { std::vector<document::BucketId> bucketlist; { setSystemState(lib::ClusterState("bits:14 storage:1 distributor:2")); - ASSERT_EQ(_bucketSpaces.size(), _sender.commands.size()); + ASSERT_EQ(_bucketSpaces.size(), _sender.commands().size()); for (uint32_t bsi = 0; bsi < _bucketSpaces.size(); ++bsi) { - ASSERT_EQ(_sender.commands[bsi]->getType(), MessageType::REQUESTBUCKETINFO); - const auto &req = dynamic_cast<const RequestBucketInfoCommand &>(*_sender.commands[bsi]); + ASSERT_EQ(_sender.command(bsi)->getType(), MessageType::REQUESTBUCKETINFO); + const auto &req = dynamic_cast<const RequestBucketInfoCommand &>(*_sender.command(bsi)); auto sreply = std::make_shared<RequestBucketInfoReply>(req); sreply->setAddress(storageAddress(0)); auto& vec = sreply->getBucketInfo(); @@ -904,11 +904,11 @@ TEST_F(BucketDBUpdaterTest, testBitChange) { _sender.clear(); setSystemState(lib::ClusterState("bits:16 storage:1 distributor:2")); - ASSERT_EQ(_bucketSpaces.size(), _sender.commands.size()); + ASSERT_EQ(_bucketSpaces.size(), _sender.commands().size()); for (uint32_t bsi = 0; bsi < _bucketSpaces.size(); ++bsi) { - ASSERT_EQ(_sender.commands[bsi]->getType(), MessageType::REQUESTBUCKETINFO); - const auto &req = dynamic_cast<const RequestBucketInfoCommand &>(*_sender.commands[bsi]); + ASSERT_EQ(_sender.command(bsi)->getType(), MessageType::REQUESTBUCKETINFO); + const auto &req = dynamic_cast<const RequestBucketInfoCommand &>(*_sender.command(bsi)); auto sreply = std::make_shared<RequestBucketInfoReply>(req); sreply->setAddress(storageAddress(0)); sreply->setResult(api::ReturnCode::OK); @@ -954,22 +954,22 @@ TEST_F(BucketDBUpdaterTest, testBitChange) { } }; -TEST_F(BucketDBUpdaterTest, testRecheckNodeWithFailure) { +TEST_F(BucketDBUpdaterTest, recheck_node_with_failure) { ASSERT_NO_FATAL_FAILURE(initializeNodesAndBuckets(3, 5)); _sender.clear(); getBucketDBUpdater().recheckBucketInfo(1, makeDocumentBucket(document::BucketId(16, 3))); - ASSERT_EQ(size_t(1), _sender.commands.size()); + ASSERT_EQ(size_t(1), _sender.commands().size()); uint16_t index = 0; { - auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.commands[0]); + auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.command(0)); ASSERT_EQ(size_t(1), rbi.getBuckets().size()); EXPECT_EQ(document::BucketId(16, 3), rbi.getBuckets()[0]); auto reply = std::make_shared<api::RequestBucketInfoReply>(rbi); - const api::StorageMessageAddress *address = _sender.commands[0]->getAddress(); + const api::StorageMessageAddress *address = _sender.command(0)->getAddress(); index = address->getIndex(); reply->setResult(api::ReturnCode::NOT_CONNECTED); getBucketDBUpdater().onRequestBucketInfoReply(reply); @@ -978,14 +978,14 @@ TEST_F(BucketDBUpdaterTest, testRecheckNodeWithFailure) { getBucketDBUpdater().resendDelayedMessages(); } - ASSERT_EQ(size_t(2), _sender.commands.size()); + ASSERT_EQ(size_t(2), _sender.commands().size()); setSystemState( lib::ClusterState(vespalib::make_string("distributor:1 storage:3 .%d.s:d", index))); // Recheck bucket. { - auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.commands[1]); + auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.command(1)); ASSERT_EQ(size_t(1), rbi.getBuckets().size()); EXPECT_EQ(document::BucketId(16, 3), rbi.getBuckets()[0]); auto reply = std::make_shared<api::RequestBucketInfoReply>(rbi); @@ -994,19 +994,19 @@ TEST_F(BucketDBUpdaterTest, testRecheckNodeWithFailure) { } // Should not retry since node is down. - EXPECT_EQ(size_t(2), _sender.commands.size()); + EXPECT_EQ(size_t(2), _sender.commands().size()); } -TEST_F(BucketDBUpdaterTest, testRecheckNode) { +TEST_F(BucketDBUpdaterTest, recheck_node) { ASSERT_NO_FATAL_FAILURE(initializeNodesAndBuckets(3, 5)); _sender.clear(); getBucketDBUpdater().recheckBucketInfo(1, makeDocumentBucket(document::BucketId(16, 3))); - ASSERT_EQ(size_t(1), _sender.commands.size()); + ASSERT_EQ(size_t(1), _sender.commands().size()); - auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.commands[0]); + auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.command(0)); ASSERT_EQ(size_t(1), rbi.getBuckets().size()); EXPECT_EQ(document::BucketId(16, 3), rbi.getBuckets()[0]); @@ -1035,11 +1035,11 @@ TEST_F(BucketDBUpdaterTest, testRecheckNode) { EXPECT_EQ(api::BucketInfo(20,10,12, 50, 60, true, true), copy->getBucketInfo()); } -TEST_F(BucketDBUpdaterTest, testNotifyBucketChange) { +TEST_F(BucketDBUpdaterTest, notify_bucket_change) { enableDistributorClusterState("distributor:1 storage:1"); addNodesToBucketDB(document::BucketId(16, 1), "0=1234"); - _sender.replies.clear(); + _sender.replies().clear(); { api::BucketInfo info(1, 2, 3, 4, 5, true, true); @@ -1058,11 +1058,11 @@ TEST_F(BucketDBUpdaterTest, testNotifyBucketChange) { } // Must receive reply - ASSERT_EQ(size_t(2), _sender.replies.size()); + ASSERT_EQ(size_t(2), _sender.replies().size()); for (int i = 0; i < 2; ++i) { ASSERT_EQ(MessageType::NOTIFYBUCKETCHANGE_REPLY, - _sender.replies[i]->getType()); + _sender.reply(i)->getType()); } // No database update until request bucket info replies have been received. @@ -1072,14 +1072,14 @@ TEST_F(BucketDBUpdaterTest, testNotifyBucketChange) { dumpBucket(document::BucketId(16, 1))); EXPECT_EQ(std::string("NONEXISTING"), dumpBucket(document::BucketId(16, 2))); - ASSERT_EQ(size_t(2), _sender.commands.size()); + ASSERT_EQ(size_t(2), _sender.commands().size()); std::vector<api::BucketInfo> infos; infos.push_back(api::BucketInfo(4567, 200, 2000, 400, 4000, true, true)); infos.push_back(api::BucketInfo(8999, 300, 3000, 500, 5000, false, false)); for (int i = 0; i < 2; ++i) { - auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.commands[i]); + auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.command(i)); ASSERT_EQ(size_t(1), rbi.getBuckets().size()); EXPECT_EQ(document::BucketId(16, i + 1), rbi.getBuckets()[0]); @@ -1098,12 +1098,12 @@ TEST_F(BucketDBUpdaterTest, testNotifyBucketChange) { dumpBucket(document::BucketId(16, 2))); } -TEST_F(BucketDBUpdaterTest, testNotifyBucketChangeFromNodeDown) { +TEST_F(BucketDBUpdaterTest, notify_bucket_change_from_node_down) { enableDistributorClusterState("distributor:1 storage:2"); addNodesToBucketDB(document::BucketId(16, 1), "1=1234"); - _sender.replies.clear(); + _sender.replies().clear(); { api::BucketInfo info(8999, 300, 3000, 500, 5000, false, false); @@ -1120,14 +1120,14 @@ TEST_F(BucketDBUpdaterTest, testNotifyBucketChangeFromNodeDown) { "node(idx=1,crc=0x4d2,docs=1234/1234,bytes=1234/1234,trusted=false,active=false,ready=false)"), dumpBucket(document::BucketId(16, 1))); - ASSERT_EQ(size_t(1), _sender.replies.size()); - ASSERT_EQ(MessageType::NOTIFYBUCKETCHANGE_REPLY, _sender.replies[0]->getType()); + ASSERT_EQ(size_t(1), _sender.replies().size()); + ASSERT_EQ(MessageType::NOTIFYBUCKETCHANGE_REPLY, _sender.reply(0)->getType()); // Currently, this pending operation will be auto-flushed when the cluster state // changes so the behavior is still correct. Keep this test around to prevent // regressions here. - ASSERT_EQ(size_t(1), _sender.commands.size()); - auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.commands[0]); + ASSERT_EQ(size_t(1), _sender.commands().size()); + auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.command(0)); ASSERT_EQ(size_t(1), rbi.getBuckets().size()); EXPECT_EQ(document::BucketId(16, 1), rbi.getBuckets()[0]); @@ -1152,9 +1152,9 @@ TEST_F(BucketDBUpdaterTest, testNotifyBucketChangeFromNodeDown) { * distributor in the pending state but not by the current state would be * discarded when attempted inserted into the bucket database. */ -TEST_F(BucketDBUpdaterTest, testNotifyChangeWithPendingStateQueuesBucketInfoRequests) { +TEST_F(BucketDBUpdaterTest, notify_change_with_pending_state_queues_bucket_info_requests) { setSystemState(lib::ClusterState("distributor:1 storage:1")); - ASSERT_EQ(_bucketSpaces.size(), _sender.commands.size()); + ASSERT_EQ(_bucketSpaces.size(), _sender.commands().size()); { api::BucketInfo info(8999, 300, 3000, 500, 5000, false, false); @@ -1164,15 +1164,15 @@ TEST_F(BucketDBUpdaterTest, testNotifyChangeWithPendingStateQueuesBucketInfoRequ getBucketDBUpdater().onNotifyBucketChange(cmd); } - ASSERT_EQ(_bucketSpaces.size(), _sender.commands.size()); + ASSERT_EQ(_bucketSpaces.size(), _sender.commands().size()); ASSERT_NO_FATAL_FAILURE(completeBucketInfoGathering(lib::ClusterState("distributor:1 storage:1"), _bucketSpaces.size(), 10)); - ASSERT_EQ(_bucketSpaces.size() + 1, _sender.commands.size()); + ASSERT_EQ(_bucketSpaces.size() + 1, _sender.commands().size()); { - auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.commands[_bucketSpaces.size()]); + auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.command(_bucketSpaces.size())); ASSERT_EQ(size_t(1), rbi.getBuckets().size()); EXPECT_EQ(document::BucketId(16, 1), rbi.getBuckets()[0]); } @@ -1184,14 +1184,14 @@ TEST_F(BucketDBUpdaterTest, testNotifyChangeWithPendingStateQueuesBucketInfoRequ uint32_t expectedMsgs = _bucketSpaces.size(), dummyBucketsToReturn = 1; ASSERT_NO_FATAL_FAILURE(setAndEnableClusterState(state, expectedMsgs, dummyBucketsToReturn)); } - ASSERT_EQ(_bucketSpaces.size(), _sender.commands.size()); + ASSERT_EQ(_bucketSpaces.size(), _sender.commands().size()); { - auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.commands[0]); + auto& rbi = dynamic_cast<RequestBucketInfoCommand&>(*_sender.command(0)); EXPECT_EQ(size_t(0), rbi.getBuckets().size()); } } -TEST_F(BucketDBUpdaterTest, testMergeReply) { +TEST_F(BucketDBUpdaterTest, merge_reply) { enableDistributorClusterState("distributor:1 storage:3"); addNodesToBucketDB(document::BucketId(16, 1234), @@ -1209,10 +1209,10 @@ TEST_F(BucketDBUpdaterTest, testMergeReply) { _sender.clear(); getBucketDBUpdater().onMergeBucketReply(reply); - ASSERT_EQ(size_t(3), _sender.commands.size()); + ASSERT_EQ(size_t(3), _sender.commands().size()); for (uint32_t i = 0; i < 3; i++) { - auto req = std::dynamic_pointer_cast<api::RequestBucketInfoCommand>(_sender.commands[i]); + auto req = std::dynamic_pointer_cast<api::RequestBucketInfoCommand>(_sender.command(i)); ASSERT_TRUE(req.get() != nullptr); ASSERT_EQ(size_t(1), req->getBuckets().size()); @@ -1233,7 +1233,7 @@ TEST_F(BucketDBUpdaterTest, testMergeReply) { dumpBucket(document::BucketId(16, 1234))); }; -TEST_F(BucketDBUpdaterTest, testMergeReplyNodeDown) { +TEST_F(BucketDBUpdaterTest, merge_reply_node_down) { enableDistributorClusterState("distributor:1 storage:3"); std::vector<api::MergeBucketCommand::Node> nodes; @@ -1252,10 +1252,10 @@ TEST_F(BucketDBUpdaterTest, testMergeReplyNodeDown) { _sender.clear(); getBucketDBUpdater().onMergeBucketReply(reply); - ASSERT_EQ(size_t(2), _sender.commands.size()); + ASSERT_EQ(size_t(2), _sender.commands().size()); for (uint32_t i = 0; i < 2; i++) { - auto req = std::dynamic_pointer_cast<api::RequestBucketInfoCommand>(_sender.commands[i]); + auto req = std::dynamic_pointer_cast<api::RequestBucketInfoCommand>(_sender.command(i)); ASSERT_TRUE(req.get() != nullptr); ASSERT_EQ(size_t(1), req->getBuckets().size()); @@ -1275,7 +1275,7 @@ TEST_F(BucketDBUpdaterTest, testMergeReplyNodeDown) { dumpBucket(document::BucketId(16, 1234))); }; -TEST_F(BucketDBUpdaterTest, testMergeReplyNodeDownAfterRequestSent) { +TEST_F(BucketDBUpdaterTest, merge_reply_node_down_after_request_sent) { enableDistributorClusterState("distributor:1 storage:3"); std::vector<api::MergeBucketCommand::Node> nodes; @@ -1292,12 +1292,12 @@ TEST_F(BucketDBUpdaterTest, testMergeReplyNodeDownAfterRequestSent) { _sender.clear(); getBucketDBUpdater().onMergeBucketReply(reply); - ASSERT_EQ(size_t(3), _sender.commands.size()); + ASSERT_EQ(size_t(3), _sender.commands().size()); setSystemState(lib::ClusterState("distributor:1 storage:2")); for (uint32_t i = 0; i < 3; i++) { - auto req = std::dynamic_pointer_cast<api::RequestBucketInfoCommand>(_sender.commands[i]); + auto req = std::dynamic_pointer_cast<api::RequestBucketInfoCommand>(_sender.command(i)); ASSERT_TRUE(req.get() != nullptr); ASSERT_EQ(size_t(1), req->getBuckets().size()); @@ -1318,7 +1318,7 @@ TEST_F(BucketDBUpdaterTest, testMergeReplyNodeDownAfterRequestSent) { }; -TEST_F(BucketDBUpdaterTest, testFlush) { +TEST_F(BucketDBUpdaterTest, flush) { enableDistributorClusterState("distributor:1 storage:3"); _sender.clear(); @@ -1336,12 +1336,12 @@ TEST_F(BucketDBUpdaterTest, testFlush) { _sender.clear(); getBucketDBUpdater().onMergeBucketReply(reply); - ASSERT_EQ(size_t(3), _sender.commands.size()); - ASSERT_EQ(size_t(0), _senderDown.replies.size()); + ASSERT_EQ(size_t(3), _sender.commands().size()); + ASSERT_EQ(size_t(0), _senderDown.replies().size()); getBucketDBUpdater().flush(); // Flushing should drop all merge bucket replies - EXPECT_EQ(size_t(0), _senderDown.commands.size()); + EXPECT_EQ(size_t(0), _senderDown.commands().size()); } std::string @@ -1355,8 +1355,8 @@ BucketDBUpdaterTest::getSentNodes( sortSentMessagesByIndex(fixture->sender); std::ostringstream ost; - for (uint32_t i = 0; i < fixture->sender.commands.size(); i++) { - auto& req = dynamic_cast<RequestBucketInfoCommand&>(*fixture->sender.commands[i]); + for (uint32_t i = 0; i < fixture->sender.commands().size(); i++) { + auto& req = dynamic_cast<RequestBucketInfoCommand&>(*fixture->sender.command(i)); if (i > 0) { ost << ","; @@ -1372,7 +1372,7 @@ std::string BucketDBUpdaterTest::getSentNodesDistributionChanged( const std::string& oldClusterState) { - MessageSenderStub sender; + DistributorMessageSenderStub sender; framework::defaultimplementation::FakeClock clock; ClusterInformation::CSP clusterInfo(createClusterInfo(oldClusterState)); @@ -1383,8 +1383,8 @@ BucketDBUpdaterTest::getSentNodesDistributionChanged( sortSentMessagesByIndex(sender); std::ostringstream ost; - for (uint32_t i = 0; i < sender.commands.size(); i++) { - auto& req = dynamic_cast<RequestBucketInfoCommand&>(*sender.commands[i]); + for (uint32_t i = 0; i < sender.commands().size(); i++) { + auto& req = dynamic_cast<RequestBucketInfoCommand&>(*sender.command(i)); if (i > 0) { ost << ","; @@ -1396,7 +1396,7 @@ BucketDBUpdaterTest::getSentNodesDistributionChanged( return ost.str(); } -TEST_F(BucketDBUpdaterTest, testPendingClusterStateSendMessages) { +TEST_F(BucketDBUpdaterTest, pending_cluster_state_send_messages) { EXPECT_EQ(getNodeList({0, 1, 2}), getSentNodes("cluster:d", "distributor:1 storage:3")); @@ -1501,8 +1501,8 @@ TEST_F(BucketDBUpdaterTest, testPendingClusterStateSendMessages) { "distributor:3 storage:3 .1.s:m")); }; -TEST_F(BucketDBUpdaterTest, testPendingClusterStateReceive) { - MessageSenderStub sender; +TEST_F(BucketDBUpdaterTest, pending_cluster_state_receive) { + DistributorMessageSenderStub sender; auto cmd(std::make_shared<api::SetSystemStateCommand>( lib::ClusterState("distributor:1 storage:3"))); @@ -1515,13 +1515,13 @@ TEST_F(BucketDBUpdaterTest, testPendingClusterStateReceive) { clock, clusterInfo, sender, getBucketSpaceRepo(), cmd, outdatedNodesMap, api::Timestamp(1))); - ASSERT_EQ(messageCount(3), sender.commands.size()); + ASSERT_EQ(messageCount(3), sender.commands().size()); sortSentMessagesByIndex(sender); std::ostringstream ost; - for (uint32_t i = 0; i < sender.commands.size(); i++) { - auto* req = dynamic_cast<RequestBucketInfoCommand*>(sender.commands[i].get()); + for (uint32_t i = 0; i < sender.commands().size(); i++) { + auto* req = dynamic_cast<RequestBucketInfoCommand*>(sender.command(i).get()); ASSERT_TRUE(req != nullptr); auto rep = std::make_shared<RequestBucketInfoReply>(*req); @@ -1532,14 +1532,14 @@ TEST_F(BucketDBUpdaterTest, testPendingClusterStateReceive) { api::BucketInfo(i, i, i, i, i))); ASSERT_TRUE(state->onRequestBucketInfoReply(rep)); - ASSERT_EQ((i == (sender.commands.size() - 1)), state->done()); + ASSERT_EQ((i == (sender.commands().size() - 1)), state->done()); } auto& pendingTransition = state->getPendingBucketSpaceDbTransition(makeBucketSpace()); EXPECT_EQ(3, (int)pendingTransition.results().size()); } -TEST_F(BucketDBUpdaterTest, testPendingClusterStateWithGroupDown) { +TEST_F(BucketDBUpdaterTest, pending_cluster_state_with_group_down) { std::string config(getDistConfig6Nodes4Groups()); config += "distributor_auto_ownership_transfer_on_whole_group_down true\n"; setDistribution(config); @@ -1558,7 +1558,7 @@ TEST_F(BucketDBUpdaterTest, testPendingClusterStateWithGroupDown) { "distributor:6 .2.s:d storage:6")); } -TEST_F(BucketDBUpdaterTest, testPendingClusterStateWithGroupDownAndNoHandover) { +TEST_F(BucketDBUpdaterTest, pending_cluster_state_with_group_down_and_no_handover) { std::string config(getDistConfig6Nodes4Groups()); config += "distributor_auto_ownership_transfer_on_whole_group_down false\n"; setDistribution(config); @@ -1654,7 +1654,7 @@ BucketDBUpdaterTest::mergeBucketLists( framework::defaultimplementation::FakeClock clock; framework::MilliSecTimer timer(clock); - MessageSenderStub sender; + DistributorMessageSenderStub sender; OutdatedNodesMap outdatedNodesMap; { @@ -1711,7 +1711,7 @@ BucketDBUpdaterTest::mergeBucketLists(const std::string& existingData, includeBucketInfo); } -TEST_F(BucketDBUpdaterTest, testPendingClusterStateMerge) { +TEST_F(BucketDBUpdaterTest, pending_cluster_state_merge) { // Simple initializing case - ask all nodes for info EXPECT_EQ( // Result is on the form: [bucket w/o count bits]:[node indexes]|.. @@ -1781,7 +1781,7 @@ TEST_F(BucketDBUpdaterTest, testPendingClusterStateMerge) { mergeBucketLists("", "0:5/0/0/0|1:5/2/3/4", true)); } -TEST_F(BucketDBUpdaterTest, testPendingClusterStateMergeReplicaChanged) { +TEST_F(BucketDBUpdaterTest, pending_cluster_state_merge_replica_changed) { // Node went from initializing to up and non-invalid bucket changed. EXPECT_EQ( std::string("2:0/2/3/4/t|3:0/2/4/6/t|"), @@ -1793,7 +1793,7 @@ TEST_F(BucketDBUpdaterTest, testPendingClusterStateMergeReplicaChanged) { true)); } -TEST_F(BucketDBUpdaterTest, testNoDbResurrectionForBucketNotOwnedInCurrentState) { +TEST_F(BucketDBUpdaterTest, no_db_resurrection_for_bucket_not_owned_in_current_state) { document::BucketId bucket(16, 3); lib::ClusterState stateBefore("distributor:1 storage:1"); { @@ -1804,10 +1804,10 @@ TEST_F(BucketDBUpdaterTest, testNoDbResurrectionForBucketNotOwnedInCurrentState) getBucketDBUpdater().recheckBucketInfo(0, makeDocumentBucket(bucket)); - ASSERT_EQ(size_t(1), _sender.commands.size()); + ASSERT_EQ(size_t(1), _sender.commands().size()); std::shared_ptr<api::RequestBucketInfoCommand> rbi( std::dynamic_pointer_cast<RequestBucketInfoCommand>( - _sender.commands[0])); + _sender.command(0))); lib::ClusterState stateAfter("distributor:3 storage:3"); @@ -1823,7 +1823,7 @@ TEST_F(BucketDBUpdaterTest, testNoDbResurrectionForBucketNotOwnedInCurrentState) EXPECT_EQ(std::string("NONEXISTING"), dumpBucket(bucket)); } -TEST_F(BucketDBUpdaterTest, testNoDbResurrectionForBucketNotOwnedInPendingState) { +TEST_F(BucketDBUpdaterTest, no_db_resurrection_for_bucket_not_owned_in_pending_state) { document::BucketId bucket(16, 3); lib::ClusterState stateBefore("distributor:1 storage:1"); { @@ -1834,10 +1834,10 @@ TEST_F(BucketDBUpdaterTest, testNoDbResurrectionForBucketNotOwnedInPendingState) getBucketDBUpdater().recheckBucketInfo(0, makeDocumentBucket(bucket)); - ASSERT_EQ(size_t(1), _sender.commands.size()); + ASSERT_EQ(size_t(1), _sender.commands().size()); std::shared_ptr<api::RequestBucketInfoCommand> rbi( std::dynamic_pointer_cast<RequestBucketInfoCommand>( - _sender.commands[0])); + _sender.command(0))); lib::ClusterState stateAfter("distributor:3 storage:3"); // Set, but _don't_ enable cluster state. We want it to be pending. @@ -1859,7 +1859,7 @@ TEST_F(BucketDBUpdaterTest, testNoDbResurrectionForBucketNotOwnedInPendingState) * will with a high likelihood end up not getting the complete view of the buckets in * the cluster. */ -TEST_F(BucketDBUpdaterTest, testClusterStateAlwaysSendsFullFetchWhenDistributionChangePending) { +TEST_F(BucketDBUpdaterTest, cluster_state_always_sends_full_fetch_when_distribution_change_pending) { lib::ClusterState stateBefore("distributor:6 storage:6"); { uint32_t expectedMsgs = messageCount(6), dummyBucketsToReturn = 1; @@ -1870,19 +1870,19 @@ TEST_F(BucketDBUpdaterTest, testClusterStateAlwaysSendsFullFetchWhenDistribution setDistribution(distConfig); sortSentMessagesByIndex(_sender); - ASSERT_EQ(messageCount(6), _sender.commands.size()); + ASSERT_EQ(messageCount(6), _sender.commands().size()); // Suddenly, a wild cluster state change appears! Even though this state // does not in itself imply any bucket changes, it will still overwrite the // pending cluster state and thus its state of pending bucket info requests. setSystemState(lib::ClusterState("distributor:6 .2.t:12345 storage:6")); - ASSERT_EQ(messageCount(12), _sender.commands.size()); + ASSERT_EQ(messageCount(12), _sender.commands().size()); // Send replies for first messageCount(6) (outdated requests). int numBuckets = 10; for (uint32_t i = 0; i < messageCount(6); ++i) { ASSERT_NO_FATAL_FAILURE(fakeBucketReply(lib::ClusterState("distributor:6 storage:6"), - *_sender.commands[i], numBuckets)); + *_sender.command(i), numBuckets)); } // No change from these. ASSERT_NO_FATAL_FAILURE(assertCorrectBuckets(1, "distributor:6 storage:6")); @@ -1890,7 +1890,7 @@ TEST_F(BucketDBUpdaterTest, testClusterStateAlwaysSendsFullFetchWhenDistribution // Send for current pending. for (uint32_t i = 0; i < messageCount(6); ++i) { ASSERT_NO_FATAL_FAILURE(fakeBucketReply(lib::ClusterState("distributor:6 .2.t:12345 storage:6"), - *_sender.commands[i + messageCount(6)], + *_sender.command(i + messageCount(6)), numBuckets)); } ASSERT_NO_FATAL_FAILURE(assertCorrectBuckets(numBuckets, "distributor:6 storage:6")); @@ -1898,10 +1898,10 @@ TEST_F(BucketDBUpdaterTest, testClusterStateAlwaysSendsFullFetchWhenDistribution // No more pending global fetch; this should be a no-op state. setSystemState(lib::ClusterState("distributor:6 .3.t:12345 storage:6")); - EXPECT_EQ(size_t(0), _sender.commands.size()); + EXPECT_EQ(size_t(0), _sender.commands().size()); } -TEST_F(BucketDBUpdaterTest, testChangedDistributionConfigTriggersRecoveryMode) { +TEST_F(BucketDBUpdaterTest, changed_distribution_config_triggers_recovery_mode) { ASSERT_NO_FATAL_FAILURE(setAndEnableClusterState(lib::ClusterState("distributor:6 storage:6"), messageCount(6), 20)); _sender.clear(); EXPECT_TRUE(_distributor->isInRecoveryMode()); @@ -1914,11 +1914,11 @@ TEST_F(BucketDBUpdaterTest, testChangedDistributionConfigTriggersRecoveryMode) { // No replies received yet, still no recovery mode. EXPECT_FALSE(_distributor->isInRecoveryMode()); - ASSERT_EQ(messageCount(6), _sender.commands.size()); + ASSERT_EQ(messageCount(6), _sender.commands().size()); uint32_t numBuckets = 10; for (uint32_t i = 0; i < messageCount(6); ++i) { ASSERT_NO_FATAL_FAILURE(fakeBucketReply(lib::ClusterState("distributor:6 storage:6"), - *_sender.commands[i], numBuckets)); + *_sender.command(i), numBuckets)); } // Pending cluster state (i.e. distribution) has been enabled, which should @@ -1970,7 +1970,7 @@ TEST_F(BucketDBUpdaterTest, changed_distribution_config_does_not_elide_bucket_db })); } -TEST_F(BucketDBUpdaterTest, testNewlyAddedBucketsHaveCurrentTimeAsGcTimestamp) { +TEST_F(BucketDBUpdaterTest, newly_added_buckets_have_current_time_as_gc_timestamp) { getClock().setAbsoluteTimeInSeconds(101234); lib::ClusterState stateBefore("distributor:1 storage:1"); { @@ -1985,7 +1985,7 @@ TEST_F(BucketDBUpdaterTest, testNewlyAddedBucketsHaveCurrentTimeAsGcTimestamp) { EXPECT_EQ(uint32_t(101234), e->getLastGarbageCollectionTime()); } -TEST_F(BucketDBUpdaterTest, testNewerMutationsNotOverwrittenByEarlierBucketFetch) { +TEST_F(BucketDBUpdaterTest, newer_mutations_not_overwritten_by_earlier_bucket_fetch) { { lib::ClusterState stateBefore("distributor:1 storage:1 .0.s:i"); uint32_t expectedMsgs = _bucketSpaces.size(), dummyBucketsToReturn = 0; @@ -1998,7 +1998,7 @@ TEST_F(BucketDBUpdaterTest, testNewerMutationsNotOverwrittenByEarlierBucketFetch getClock().setAbsoluteTimeInSeconds(1000); lib::ClusterState state("distributor:1 storage:1"); setSystemState(state); - ASSERT_EQ(_bucketSpaces.size(), _sender.commands.size()); + ASSERT_EQ(_bucketSpaces.size(), _sender.commands().size()); // Before replying with the bucket info, simulate the arrival of a mutation // reply that alters the state of the bucket with information that will be @@ -2023,7 +2023,7 @@ TEST_F(BucketDBUpdaterTest, testNewerMutationsNotOverwrittenByEarlierBucketFetch // correctness, as this should contain the same bucket info as that // contained in the full bucket reply and the DB update is thus idempotent. for (uint32_t i = 0; i < _bucketSpaces.size(); ++i) { - ASSERT_NO_FATAL_FAILURE(fakeBucketReply(state, *_sender.commands[i], bucketsReturned)); + ASSERT_NO_FATAL_FAILURE(fakeBucketReply(state, *_sender.command(i), bucketsReturned)); } BucketDatabase::Entry e(getBucket(bucket)); @@ -2035,8 +2035,8 @@ std::vector<uint16_t> BucketDBUpdaterTest::getSendSet() const { std::vector<uint16_t> nodes; - std::transform(_sender.commands.begin(), - _sender.commands.end(), + std::transform(_sender.commands().begin(), + _sender.commands().end(), std::back_inserter(nodes), [](auto& cmd) { @@ -2080,7 +2080,7 @@ using nodeVec = std::vector<uint16_t>; * database modifications caused by intermediate states will not be * accounted for (basically the ABA problem in a distributed setting). */ -TEST_F(BucketDBUpdaterTest, preemptedDistrChangeCarriesNodeSetOverToNextStateFetch) { +TEST_F(BucketDBUpdaterTest, preempted_distributor_change_carries_node_set_over_to_next_state_fetch) { EXPECT_EQ( expandNodeVec({0, 1, 2, 3, 4, 5}), getSentNodesWithPreemption("version:1 distributor:6 storage:6", @@ -2089,7 +2089,7 @@ TEST_F(BucketDBUpdaterTest, preemptedDistrChangeCarriesNodeSetOverToNextStateFet "version:3 distributor:6 storage:6")); } -TEST_F(BucketDBUpdaterTest, preemptedStorChangeCarriesNodeSetOverToNextStateFetch) { +TEST_F(BucketDBUpdaterTest, preempted_storage_change_carries_node_set_over_to_next_state_fetch) { EXPECT_EQ( expandNodeVec({2, 3}), getSentNodesWithPreemption( @@ -2099,7 +2099,7 @@ TEST_F(BucketDBUpdaterTest, preemptedStorChangeCarriesNodeSetOverToNextStateFetc "version:3 distributor:6 storage:6")); } -TEST_F(BucketDBUpdaterTest, preemptedStorageNodeDownMustBeReFetched) { +TEST_F(BucketDBUpdaterTest, preempted_storage_node_down_must_be_re_fetched) { EXPECT_EQ( expandNodeVec({2}), getSentNodesWithPreemption( @@ -2109,7 +2109,7 @@ TEST_F(BucketDBUpdaterTest, preemptedStorageNodeDownMustBeReFetched) { "version:3 distributor:6 storage:6")); } -TEST_F(BucketDBUpdaterTest, doNotSendToPreemptedNodeNowInDownState) { +TEST_F(BucketDBUpdaterTest, do_not_send_to_preempted_node_now_in_down_state) { EXPECT_EQ( nodeVec{}, getSentNodesWithPreemption( @@ -2131,7 +2131,7 @@ TEST_F(BucketDBUpdaterTest, doNotSendToPreemptedNodeNotPartOfNewState) { "version:3 distributor:6 storage:6")); } -TEST_F(BucketDBUpdaterTest, outdatedNodeSetClearedAfterSuccessfulStateCompletion) { +TEST_F(BucketDBUpdaterTest, outdated_node_set_cleared_after_successful_state_completion) { lib::ClusterState stateBefore( "version:1 distributor:6 storage:6 .1.t:1234"); uint32_t expectedMsgs = messageCount(6), dummyBucketsToReturn = 10; @@ -2142,7 +2142,7 @@ TEST_F(BucketDBUpdaterTest, outdatedNodeSetClearedAfterSuccessfulStateCompletion // (completed) cluster state has been set. lib::ClusterState stateAfter("version:3 distributor:6 storage:6"); setSystemState(stateAfter); - EXPECT_EQ(size_t(0), _sender.commands.size()); + EXPECT_EQ(size_t(0), _sender.commands().size()); } // XXX test currently disabled since distribution config currently isn't used @@ -2151,7 +2151,7 @@ TEST_F(BucketDBUpdaterTest, outdatedNodeSetClearedAfterSuccessfulStateCompletion // distribution config will follow very shortly after the config has been // applied to the node. The new cluster state will then send out requests to // the correct node set. -TEST_F(BucketDBUpdaterTest, DISABLED_clusterConfigDownsizeOnlySendsToAvailableNodes) { +TEST_F(BucketDBUpdaterTest, DISABLED_cluster_config_downsize_only_sends_to_available_nodes) { uint32_t expectedMsgs = 6, dummyBucketsToReturn = 20; ASSERT_NO_FATAL_FAILURE(setAndEnableClusterState(lib::ClusterState("distributor:6 storage:6"), expectedMsgs, dummyBucketsToReturn)); @@ -2166,7 +2166,7 @@ TEST_F(BucketDBUpdaterTest, DISABLED_clusterConfigDownsizeOnlySendsToAvailableNo EXPECT_EQ((nodeVec{0, 1, 2}), getSendSet()); } -TEST_F(BucketDBUpdaterTest, changedDiskSetTriggersReFetch) { +TEST_F(BucketDBUpdaterTest, changed_disk_set_triggers_re_fetch) { // Same number of online disks, but the set of disks has changed. EXPECT_EQ( getNodeList({1}), @@ -2182,7 +2182,7 @@ TEST_F(BucketDBUpdaterTest, changedDiskSetTriggersReFetch) { * * See VESPA-790 for details. */ -TEST_F(BucketDBUpdaterTest, nodeMissingFromConfigIsTreatedAsNeedingOwnershipTransfer) { +TEST_F(BucketDBUpdaterTest, node_missing_from_config_is_treated_as_needing_ownership_transfer) { uint32_t expectedMsgs = messageCount(3), dummyBucketsToReturn = 1; ASSERT_NO_FATAL_FAILURE(setAndEnableClusterState(lib::ClusterState("distributor:3 storage:3"), expectedMsgs, dummyBucketsToReturn)); @@ -2354,10 +2354,10 @@ TEST_F(BucketDBUpdaterTest, global_distribution_hash_falls_back_to_legacy_format const vespalib::string legacy_hash = "(0d3|3|*(0;0;1;2)(1;3;4;5))"; setSystemState(lib::ClusterState("distributor:6 storage:6")); - ASSERT_EQ(messageCount(6), _sender.commands.size()); + ASSERT_EQ(messageCount(6), _sender.commands().size()); api::RequestBucketInfoCommand* global_req = nullptr; - for (auto& cmd : _sender.commands) { + for (auto& cmd : _sender.commands()) { auto& req_cmd = dynamic_cast<api::RequestBucketInfoCommand&>(*cmd); if (req_cmd.getBucketSpace() == document::FixedBucketSpaces::global_space()) { global_req = &req_cmd; @@ -2375,8 +2375,8 @@ TEST_F(BucketDBUpdaterTest, global_distribution_hash_falls_back_to_legacy_format getBucketDBUpdater().resendDelayedMessages(); // Should now be a resent request with legacy distribution hash - ASSERT_EQ(messageCount(6) + 1, _sender.commands.size()); - auto& legacy_req = dynamic_cast<api::RequestBucketInfoCommand&>(*_sender.commands.back()); + ASSERT_EQ(messageCount(6) + 1, _sender.commands().size()); + auto& legacy_req = dynamic_cast<api::RequestBucketInfoCommand&>(*_sender.commands().back()); ASSERT_EQ(legacy_hash, legacy_req.getDistributionHash()); // Now if we reject it _again_ we should cycle back to the current hash @@ -2388,8 +2388,8 @@ TEST_F(BucketDBUpdaterTest, global_distribution_hash_falls_back_to_legacy_format getClock().addSecondsToTime(10); getBucketDBUpdater().resendDelayedMessages(); - ASSERT_EQ(messageCount(6) + 2, _sender.commands.size()); - auto& new_current_req = dynamic_cast<api::RequestBucketInfoCommand&>(*_sender.commands.back()); + ASSERT_EQ(messageCount(6) + 2, _sender.commands().size()); + auto& new_current_req = dynamic_cast<api::RequestBucketInfoCommand&>(*_sender.commands().back()); ASSERT_EQ(current_hash, new_current_req.getDistributionHash()); } @@ -2420,7 +2420,7 @@ TEST_F(BucketDBUpdaterTest, non_owned_buckets_moved_to_read_only_db_on_ownership lib::ClusterState initial_state("distributor:1 storage:4"); // All buckets owned by us by definition set_cluster_state_bundle(lib::ClusterStateBundle(initial_state, {}, false)); // Skip activation step for simplicity - ASSERT_EQ(messageCount(4), _sender.commands.size()); + ASSERT_EQ(messageCount(4), _sender.commands().size()); constexpr uint32_t n_buckets = 10; ASSERT_NO_FATAL_FAILURE(completeBucketInfoGathering(initial_state, messageCount(4), n_buckets)); _sender.clear(); @@ -2473,7 +2473,7 @@ TEST_F(BucketDBUpdaterTest, non_owned_buckets_purged_when_read_only_support_is_c lib::ClusterState initial_state("distributor:1 storage:4"); // All buckets owned by us by definition set_cluster_state_bundle(lib::ClusterStateBundle(initial_state, {}, false)); // Skip activation step for simplicity - ASSERT_EQ(messageCount(4), _sender.commands.size()); + ASSERT_EQ(messageCount(4), _sender.commands().size()); constexpr uint32_t n_buckets = 10; ASSERT_NO_FATAL_FAILURE(completeBucketInfoGathering(initial_state, messageCount(4), n_buckets)); _sender.clear(); @@ -2500,14 +2500,14 @@ void BucketDBUpdaterTest::trigger_completed_but_not_yet_activated_transition( getConfig().setAllowStaleReadsDuringClusterStateTransitions(true); lib::ClusterState initial_state(initial_state_str); setSystemState(initial_state); - ASSERT_EQ(messageCount(initial_expected_msgs), _sender.commands.size()); + ASSERT_EQ(messageCount(initial_expected_msgs), _sender.commands().size()); ASSERT_NO_FATAL_FAILURE(completeBucketInfoGathering( initial_state, messageCount(initial_expected_msgs), initial_buckets)); _sender.clear(); lib::ClusterState pending_state(pending_state_str); // Ownership change set_cluster_state_bundle(lib::ClusterStateBundle(pending_state, {}, true)); - ASSERT_EQ(messageCount(pending_expected_msgs), _sender.commands.size()); + ASSERT_EQ(messageCount(pending_expected_msgs), _sender.commands().size()); ASSERT_NO_FATAL_FAILURE(completeBucketInfoGathering( pending_state, messageCount(pending_expected_msgs), pending_buckets)); _sender.clear(); @@ -2581,7 +2581,7 @@ TEST_F(BucketDBUpdaterTest, activate_cluster_state_request_without_pending_trans // Note: state manager is not modelled in this test, so we just check that the message handler returns // false (meaning "didn't take message ownership") and there's no auto-generated reply. EXPECT_FALSE(activate_cluster_state_version(3)); - EXPECT_EQ(size_t(0), _sender.replies.size()); + EXPECT_EQ(size_t(0), _sender.replies().size()); } TEST_F(BucketDBUpdaterTest, DISABLED_benchmark_bulk_loading_into_empty_db) { @@ -2597,10 +2597,10 @@ TEST_F(BucketDBUpdaterTest, DISABLED_benchmark_bulk_loading_into_empty_db) { constexpr uint32_t sub_buckets = 14; constexpr uint32_t n_buckets = superbuckets * sub_buckets; - ASSERT_EQ(_bucketSpaces.size(), _sender.commands.size()); + ASSERT_EQ(_bucketSpaces.size(), _sender.commands().size()); for (uint32_t bsi = 0; bsi < _bucketSpaces.size(); ++bsi) { - ASSERT_EQ(_sender.commands[bsi]->getType(), MessageType::REQUESTBUCKETINFO); - const auto& req = dynamic_cast<const RequestBucketInfoCommand&>(*_sender.commands[bsi]); + ASSERT_EQ(_sender.command(bsi)->getType(), MessageType::REQUESTBUCKETINFO); + const auto& req = dynamic_cast<const RequestBucketInfoCommand&>(*_sender.command(bsi)); auto sreply = std::make_shared<RequestBucketInfoReply>(req); sreply->setAddress(storageAddress(0)); @@ -2643,10 +2643,10 @@ uint32_t BucketDBUpdaterTest::populate_bucket_db_via_request_bucket_info_for_ben constexpr uint32_t sub_buckets = 14; constexpr uint32_t n_buckets = superbuckets * sub_buckets; - assert(_bucketSpaces.size() == _sender.commands.size()); + assert(_bucketSpaces.size() == _sender.commands().size()); for (uint32_t bsi = 0; bsi < _bucketSpaces.size(); ++bsi) { - assert(_sender.commands[bsi]->getType() == MessageType::REQUESTBUCKETINFO); - const auto& req = dynamic_cast<const RequestBucketInfoCommand&>(*_sender.commands[bsi]); + assert(_sender.command(bsi)->getType() == MessageType::REQUESTBUCKETINFO); + const auto& req = dynamic_cast<const RequestBucketInfoCommand&>(*_sender.command(bsi)); auto sreply = std::make_shared<RequestBucketInfoReply>(req); sreply->setAddress(storageAddress(0)); diff --git a/storage/src/tests/distributor/bucketgctimecalculatortest.cpp b/storage/src/tests/distributor/bucketgctimecalculatortest.cpp index 2d2c2e48e1a..d9d5c498735 100644 --- a/storage/src/tests/distributor/bucketgctimecalculatortest.cpp +++ b/storage/src/tests/distributor/bucketgctimecalculatortest.cpp @@ -1,11 +1,12 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <chrono> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/storage/distributor/bucketgctimecalculator.h> +#include <vespa/vespalib/gtest/gtest.h> -namespace storage { -namespace distributor { +using namespace ::testing; + +namespace storage::distributor { struct MockBucketIdHasher : public BucketGcTimeCalculator::BucketIdHasher { @@ -16,25 +17,9 @@ struct MockBucketIdHasher : public BucketGcTimeCalculator::BucketIdHasher } }; -struct BucketGcTimeCalculatorTest : public CppUnit::TestFixture -{ - void noGcIfAlreadyCheckedAfterStartPoint(); - void gcIfNotRunInCurrentPeriodAndCheckPeriodPassed(); - void noGcIfNotRunInCurrentPeriodAndCheckPeriodNotPassed(); - void noGcIfCheckIntervalIsZero(); - void identityHasherReturnsBucketId(); - +struct BucketGcTimeCalculatorTest : Test { BucketGcTimeCalculatorTest(); - CPPUNIT_TEST_SUITE(BucketGcTimeCalculatorTest); - CPPUNIT_TEST(noGcIfAlreadyCheckedAfterStartPoint); - CPPUNIT_TEST(gcIfNotRunInCurrentPeriodAndCheckPeriodPassed); - CPPUNIT_TEST(noGcIfNotRunInCurrentPeriodAndCheckPeriodNotPassed); - CPPUNIT_TEST(noGcIfCheckIntervalIsZero); - CPPUNIT_TEST(identityHasherReturnsBucketId); - CPPUNIT_TEST_SUITE_END(); - -private: // Ease of reading aliases using CurrentTime = std::chrono::seconds; using LastRunAt = std::chrono::seconds; @@ -53,61 +38,47 @@ BucketGcTimeCalculatorTest::BucketGcTimeCalculatorTest() hasher.nextGeneratedHash = 500; } -CPPUNIT_TEST_SUITE_REGISTRATION(BucketGcTimeCalculatorTest); - -void -BucketGcTimeCalculatorTest::noGcIfAlreadyCheckedAfterStartPoint() -{ +TEST_F(BucketGcTimeCalculatorTest, no_gc_if_already_checked_after_start_point) { // Note: LastRun(0) is considered to be within the current period. - CPPUNIT_ASSERT(!calc.shouldGc(b, CurrentTime(0), LastRunAt(0))); - CPPUNIT_ASSERT(!calc.shouldGc(b, CurrentTime(499), LastRunAt(0))); - CPPUNIT_ASSERT(!calc.shouldGc(b, CurrentTime(999), LastRunAt(500))); + EXPECT_FALSE(calc.shouldGc(b, CurrentTime(0), LastRunAt(0))); + EXPECT_FALSE(calc.shouldGc(b, CurrentTime(499), LastRunAt(0))); + EXPECT_FALSE(calc.shouldGc(b, CurrentTime(999), LastRunAt(500))); - CPPUNIT_ASSERT(!calc.shouldGc(b, CurrentTime(1000), LastRunAt(1000))); - CPPUNIT_ASSERT(!calc.shouldGc(b, CurrentTime(1234), LastRunAt(1100))); - CPPUNIT_ASSERT(!calc.shouldGc(b, CurrentTime(1600), LastRunAt(1500))); + EXPECT_FALSE(calc.shouldGc(b, CurrentTime(1000), LastRunAt(1000))); + EXPECT_FALSE(calc.shouldGc(b, CurrentTime(1234), LastRunAt(1100))); + EXPECT_FALSE(calc.shouldGc(b, CurrentTime(1600), LastRunAt(1500))); } -void -BucketGcTimeCalculatorTest::gcIfNotRunInCurrentPeriodAndCheckPeriodPassed() -{ - CPPUNIT_ASSERT(calc.shouldGc(b, CurrentTime(500), LastRunAt(0))); - CPPUNIT_ASSERT(calc.shouldGc(b, CurrentTime(1600), LastRunAt(500))); +TEST_F(BucketGcTimeCalculatorTest, gc_if_not_run_in_current_period_and_check_period_passed) { + EXPECT_TRUE(calc.shouldGc(b, CurrentTime(500), LastRunAt(0))); + EXPECT_TRUE(calc.shouldGc(b, CurrentTime(1600), LastRunAt(500))); // Note: this may look wrong, but is correct since GC should have been // scheduled _after_ 1499 so this is most likely the case where a bucket // has been added to the database at this point in time. Not treating // this as a valid GC scenario would mean newly added buckets would have to // wait until the next period to be considered. If the period is long and // the system is unstable (causing many bucket handoffs), we'd risk not - // being able to scheduled many buckets at all. - CPPUNIT_ASSERT(calc.shouldGc(b, CurrentTime(1600), LastRunAt(1499))); + // being able to schedule many buckets at all. + EXPECT_TRUE(calc.shouldGc(b, CurrentTime(1600), LastRunAt(1499))); - CPPUNIT_ASSERT(calc.shouldGc(b, CurrentTime(2000), LastRunAt(500))); - CPPUNIT_ASSERT(calc.shouldGc(b, CurrentTime(2600), LastRunAt(1500))); + EXPECT_TRUE(calc.shouldGc(b, CurrentTime(2000), LastRunAt(500))); + EXPECT_TRUE(calc.shouldGc(b, CurrentTime(2600), LastRunAt(1500))); } -void -BucketGcTimeCalculatorTest::noGcIfNotRunInCurrentPeriodAndCheckPeriodNotPassed() -{ - CPPUNIT_ASSERT(!calc.shouldGc(b, CurrentTime(1000), LastRunAt(500))); +TEST_F(BucketGcTimeCalculatorTest, no_gc_if_not_run_in_current_period_and_check_period_not_passed) { + EXPECT_FALSE(calc.shouldGc(b, CurrentTime(1000), LastRunAt(500))); } -void -BucketGcTimeCalculatorTest::noGcIfCheckIntervalIsZero() -{ +TEST_F(BucketGcTimeCalculatorTest, no_gc_if_check_interval_is_zero) { BucketGcTimeCalculator calc2(hasher, std::chrono::seconds(0)); - CPPUNIT_ASSERT(!calc2.shouldGc(b, CurrentTime(5000), LastRunAt(0))); + EXPECT_FALSE(calc2.shouldGc(b, CurrentTime(5000), LastRunAt(0))); } -void -BucketGcTimeCalculatorTest::identityHasherReturnsBucketId() -{ +TEST_F(BucketGcTimeCalculatorTest, identity_hasher_returns_bucket_id) { BucketGcTimeCalculator::BucketIdIdentityHasher hasher2; document::BucketId bucket(36, 1234); - CPPUNIT_ASSERT_EQUAL(bucket.getId(), static_cast<uint64_t>(hasher2.hash(bucket))); + EXPECT_EQ(bucket.getId(), static_cast<uint64_t>(hasher2.hash(bucket))); } -} // distributor -} // storage - +} // storage::distributor diff --git a/storage/src/tests/distributor/bucketstateoperationtest.cpp b/storage/src/tests/distributor/bucketstateoperationtest.cpp index 216a051be15..c62d0a62ed3 100644 --- a/storage/src/tests/distributor/bucketstateoperationtest.cpp +++ b/storage/src/tests/distributor/bucketstateoperationtest.cpp @@ -1,64 +1,38 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <cppunit/extensions/HelperMacros.h> #include <tests/distributor/distributortestutil.h> #include <vespa/storage/distributor/operations/idealstate/setbucketstateoperation.h> #include <vespa/storage/distributor/distributor.h> #include <vespa/document/test/make_document_bucket.h> +#include <vespa/vespalib/gtest/gtest.h> using document::test::makeDocumentBucket; +using namespace ::testing; -namespace storage { - -namespace distributor { - -class BucketStateOperationTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ - CPPUNIT_TEST_SUITE(BucketStateOperationTest); - CPPUNIT_TEST(testActiveStateSupportedInBucketDb); - CPPUNIT_TEST(testActivateSingleNode); - CPPUNIT_TEST(testActivateAndDeactivateNodes); - CPPUNIT_TEST(testDoNotDeactivateIfActivateFails); - CPPUNIT_TEST(testBucketDbNotUpdatedOnFailure); - CPPUNIT_TEST_SUITE_END(); - -private: - void testActiveStateSupportedInBucketDb(); - void testActivateSingleNode(); - void testActivateAndDeactivateNodes(); - void testDoNotDeactivateIfActivateFails(); - void testBucketDbNotUpdatedOnFailure(); - -public: - void setUp() override { +namespace storage::distributor { + +struct BucketStateOperationTest : Test, DistributorTestUtil { + void SetUp() override { createLinks(); } - void tearDown() override { + void TearDown() override { close(); } }; -CPPUNIT_TEST_SUITE_REGISTRATION(BucketStateOperationTest); - -void -BucketStateOperationTest::testActiveStateSupportedInBucketDb() -{ +TEST_F(BucketStateOperationTest, active_state_supported_in_bucket_db) { document::BucketId bid(16, 1); insertBucketInfo(bid, 0, 0xabc, 10, 1100, true, true); BucketDatabase::Entry entry = getBucket(bid); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT(entry->getNode(0)->active()); - CPPUNIT_ASSERT_EQUAL( - std::string("node(idx=0,crc=0xabc,docs=10/10,bytes=1100/1100," - "trusted=true,active=true,ready=false)"), - entry->getNode(0)->toString()); + ASSERT_TRUE(entry.valid()); + EXPECT_TRUE(entry->getNode(0)->active()); + EXPECT_EQ("node(idx=0,crc=0xabc,docs=10/10,bytes=1100/1100," + "trusted=true,active=true,ready=false)", + entry->getNode(0)->toString()); } -void -BucketStateOperationTest::testActivateSingleNode() -{ +TEST_F(BucketStateOperationTest, activate_single_node) { document::BucketId bid(16, 1); insertBucketInfo(bid, 0, 0xabc, 10, 1100, true, false); @@ -70,35 +44,31 @@ BucketStateOperationTest::testActivateSingleNode() op.setIdealStateManager(&getIdealStateManager()); op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL((size_t)1, _sender.commands.size()); + ASSERT_EQ(1, _sender.commands().size()); - std::shared_ptr<api::StorageCommand> msg = _sender.commands[0]; - CPPUNIT_ASSERT(msg->getType() == api::MessageType::SETBUCKETSTATE); - CPPUNIT_ASSERT_EQUAL( - api::StorageMessageAddress( - "storage", lib::NodeType::STORAGE, 0).toString(), - msg->getAddress()->toString()); + std::shared_ptr<api::StorageCommand> msg = _sender.command(0); + ASSERT_EQ(msg->getType(), api::MessageType::SETBUCKETSTATE); + EXPECT_EQ(api::StorageMessageAddress( + "storage", lib::NodeType::STORAGE, 0).toString(), + msg->getAddress()->toString()); - const api::SetBucketStateCommand& cmd( - dynamic_cast<const api::SetBucketStateCommand&>(*msg)); - CPPUNIT_ASSERT_EQUAL(bid, cmd.getBucketId()); - CPPUNIT_ASSERT_EQUAL(api::SetBucketStateCommand::ACTIVE, cmd.getState()); + auto& cmd = dynamic_cast<const api::SetBucketStateCommand&>(*msg); + EXPECT_EQ(bid, cmd.getBucketId()); + EXPECT_EQ(api::SetBucketStateCommand::ACTIVE, cmd.getState()); std::shared_ptr<api::StorageReply> reply(msg->makeReply().release()); op.receive(_sender, reply); BucketDatabase::Entry entry = getBucket(bid); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT(entry->getNodeRef(0).active()); + ASSERT_TRUE(entry.valid()); + EXPECT_TRUE(entry->getNodeRef(0).active()); - CPPUNIT_ASSERT(op.ok()); + EXPECT_TRUE(op.ok()); // TODO: check that it's done } -void -BucketStateOperationTest::testActivateAndDeactivateNodes() -{ +TEST_F(BucketStateOperationTest, activate_and_deactivate_nodes) { document::BucketId bid(16, 1); insertBucketInfo(bid, 0, 0xabc, 10, 1100, false, true); insertBucketInfo(bid, 1, 0xdef, 15, 1500, false, false); @@ -111,59 +81,51 @@ BucketStateOperationTest::testActivateAndDeactivateNodes() op.setIdealStateManager(&getIdealStateManager()); op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL((size_t)1, _sender.commands.size()); + ASSERT_EQ(1, _sender.commands().size()); { - std::shared_ptr<api::StorageCommand> msg = _sender.commands[0]; - CPPUNIT_ASSERT(msg->getType() == api::MessageType::SETBUCKETSTATE); - CPPUNIT_ASSERT_EQUAL( - api::StorageMessageAddress( - "storage", lib::NodeType::STORAGE, 1).toString(), - msg->getAddress()->toString()); - - const api::SetBucketStateCommand& cmd( - dynamic_cast<const api::SetBucketStateCommand&>(*msg)); - CPPUNIT_ASSERT_EQUAL(bid, cmd.getBucketId()); - CPPUNIT_ASSERT_EQUAL(api::SetBucketStateCommand::ACTIVE, cmd.getState()); + std::shared_ptr<api::StorageCommand> msg = _sender.command(0); + ASSERT_EQ(msg->getType(), api::MessageType::SETBUCKETSTATE); + EXPECT_EQ(api::StorageMessageAddress( + "storage", lib::NodeType::STORAGE, 1).toString(), + msg->getAddress()->toString()); + + auto& cmd = dynamic_cast<const api::SetBucketStateCommand&>(*msg); + EXPECT_EQ(bid, cmd.getBucketId()); + EXPECT_EQ(api::SetBucketStateCommand::ACTIVE, cmd.getState()); std::shared_ptr<api::StorageReply> reply(msg->makeReply().release()); op.receive(_sender, reply); } - CPPUNIT_ASSERT_EQUAL((size_t)2, _sender.commands.size()); + ASSERT_EQ(2, _sender.commands().size()); { - std::shared_ptr<api::StorageCommand> msg = _sender.commands[1]; - CPPUNIT_ASSERT(msg->getType() == api::MessageType::SETBUCKETSTATE); - CPPUNIT_ASSERT_EQUAL( - api::StorageMessageAddress( - "storage", lib::NodeType::STORAGE, 0).toString(), - msg->getAddress()->toString()); - - const api::SetBucketStateCommand& cmd( - dynamic_cast<const api::SetBucketStateCommand&>(*msg)); - CPPUNIT_ASSERT_EQUAL(bid, cmd.getBucketId()); - CPPUNIT_ASSERT_EQUAL(api::SetBucketStateCommand::INACTIVE, cmd.getState()); + std::shared_ptr<api::StorageCommand> msg = _sender.command(1); + ASSERT_EQ(msg->getType(), api::MessageType::SETBUCKETSTATE); + EXPECT_EQ(api::StorageMessageAddress( + "storage", lib::NodeType::STORAGE, 0).toString(), + msg->getAddress()->toString()); + + auto& cmd = dynamic_cast<const api::SetBucketStateCommand&>(*msg); + EXPECT_EQ(bid, cmd.getBucketId()); + EXPECT_EQ(api::SetBucketStateCommand::INACTIVE, cmd.getState()); std::shared_ptr<api::StorageReply> reply(msg->makeReply().release()); op.receive(_sender, reply); } BucketDatabase::Entry entry = getBucket(bid); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT_EQUAL( - std::string("node(idx=0,crc=0xabc,docs=10/10,bytes=1100/1100," - "trusted=true,active=false,ready=false)"), - entry->getNodeRef(0).toString()); - CPPUNIT_ASSERT_EQUAL( - std::string("node(idx=1,crc=0xdef,docs=15/15,bytes=1500/1500," - "trusted=false,active=true,ready=false)"), - entry->getNodeRef(1).toString()); - - CPPUNIT_ASSERT(op.ok()); + ASSERT_TRUE(entry.valid()); + EXPECT_EQ("node(idx=0,crc=0xabc,docs=10/10,bytes=1100/1100," + "trusted=true,active=false,ready=false)", + entry->getNodeRef(0).toString()); + EXPECT_EQ("node(idx=1,crc=0xdef,docs=15/15,bytes=1500/1500," + "trusted=false,active=true,ready=false)", + entry->getNodeRef(1).toString()); + + EXPECT_TRUE(op.ok()); } -void -BucketStateOperationTest::testDoNotDeactivateIfActivateFails() -{ +TEST_F(BucketStateOperationTest, do_not_deactivate_if_activate_fails) { document::BucketId bid(16, 1); insertBucketInfo(bid, 0, 0xabc, 10, 1100, false, true); insertBucketInfo(bid, 1, 0xdef, 15, 1500, false, false); @@ -176,44 +138,38 @@ BucketStateOperationTest::testDoNotDeactivateIfActivateFails() op.setIdealStateManager(&getIdealStateManager()); op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL((size_t)1, _sender.commands.size()); + ASSERT_EQ(1, _sender.commands().size()); { - std::shared_ptr<api::StorageCommand> msg = _sender.commands[0]; - CPPUNIT_ASSERT(msg->getType() == api::MessageType::SETBUCKETSTATE); - CPPUNIT_ASSERT_EQUAL( - api::StorageMessageAddress( - "storage", lib::NodeType::STORAGE, 1).toString(), - msg->getAddress()->toString()); - - const api::SetBucketStateCommand& cmd( - dynamic_cast<const api::SetBucketStateCommand&>(*msg)); - CPPUNIT_ASSERT_EQUAL(bid, cmd.getBucketId()); - CPPUNIT_ASSERT_EQUAL(api::SetBucketStateCommand::ACTIVE, cmd.getState()); + std::shared_ptr<api::StorageCommand> msg = _sender.command(0); + ASSERT_EQ(msg->getType(), api::MessageType::SETBUCKETSTATE); + EXPECT_EQ(api::StorageMessageAddress( + "storage", lib::NodeType::STORAGE, 1).toString(), + msg->getAddress()->toString()); + + auto& cmd = dynamic_cast<const api::SetBucketStateCommand&>(*msg); + EXPECT_EQ(bid, cmd.getBucketId()); + EXPECT_EQ(api::SetBucketStateCommand::ACTIVE, cmd.getState()); std::shared_ptr<api::StorageReply> reply(msg->makeReply().release()); reply->setResult(api::ReturnCode(api::ReturnCode::ABORTED, "aaarg!")); op.receive(_sender, reply); } - CPPUNIT_ASSERT_EQUAL((size_t)1, _sender.commands.size()); + ASSERT_EQ(1, _sender.commands().size()); BucketDatabase::Entry entry = getBucket(bid); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT_EQUAL( - std::string("node(idx=0,crc=0xabc,docs=10/10,bytes=1100/1100," - "trusted=true,active=true,ready=false)"), - entry->getNodeRef(0).toString()); - CPPUNIT_ASSERT_EQUAL( - std::string("node(idx=1,crc=0xdef,docs=15/15,bytes=1500/1500," - "trusted=false,active=false,ready=false)"), - entry->getNodeRef(1).toString()); - - CPPUNIT_ASSERT(!op.ok()); + ASSERT_TRUE(entry.valid()); + EXPECT_EQ("node(idx=0,crc=0xabc,docs=10/10,bytes=1100/1100," + "trusted=true,active=true,ready=false)", + entry->getNodeRef(0).toString()); + EXPECT_EQ("node(idx=1,crc=0xdef,docs=15/15,bytes=1500/1500," + "trusted=false,active=false,ready=false)", + entry->getNodeRef(1).toString()); + + EXPECT_FALSE(op.ok()); } -void -BucketStateOperationTest::testBucketDbNotUpdatedOnFailure() -{ +TEST_F(BucketStateOperationTest, bucket_db_not_updated_on_failure) { document::BucketId bid(16, 1); insertBucketInfo(bid, 0, 0xabc, 10, 1100, true, false); @@ -225,27 +181,24 @@ BucketStateOperationTest::testBucketDbNotUpdatedOnFailure() op.setIdealStateManager(&getIdealStateManager()); op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL((size_t)1, _sender.commands.size()); + ASSERT_EQ(1, _sender.commands().size()); - std::shared_ptr<api::StorageCommand> msg = _sender.commands[0]; - CPPUNIT_ASSERT(msg->getType() == api::MessageType::SETBUCKETSTATE); - CPPUNIT_ASSERT_EQUAL( - api::StorageMessageAddress( - "storage", lib::NodeType::STORAGE, 0).toString(), - msg->getAddress()->toString()); + std::shared_ptr<api::StorageCommand> msg = _sender.command(0); + ASSERT_EQ(msg->getType(), api::MessageType::SETBUCKETSTATE); + EXPECT_EQ(api::StorageMessageAddress( + "storage", lib::NodeType::STORAGE, 0).toString(), + msg->getAddress()->toString()); std::shared_ptr<api::StorageReply> reply(msg->makeReply().release()); reply->setResult(api::ReturnCode(api::ReturnCode::ABORTED, "aaarg!")); op.receive(_sender, reply); BucketDatabase::Entry entry = getBucket(bid); - CPPUNIT_ASSERT(entry.valid()); + ASSERT_TRUE(entry.valid()); // Should not be updated - CPPUNIT_ASSERT(!entry->getNodeRef(0).active()); + EXPECT_FALSE(entry->getNodeRef(0).active()); - CPPUNIT_ASSERT(!op.ok()); + EXPECT_FALSE(op.ok()); } -} // namespace distributor - -} // namespace storage +} // namespace storage::distributor diff --git a/storage/src/tests/distributor/distributor_host_info_reporter_test.cpp b/storage/src/tests/distributor/distributor_host_info_reporter_test.cpp index c2e8367fa30..e1010285dba 100644 --- a/storage/src/tests/distributor/distributor_host_info_reporter_test.cpp +++ b/storage/src/tests/distributor/distributor_host_info_reporter_test.cpp @@ -1,14 +1,13 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> +#include <vespa/storage/distributor/bucket_spaces_stats_provider.h> #include <vespa/storage/distributor/distributor_host_info_reporter.h> #include <vespa/storage/distributor/min_replica_provider.h> +#include <tests/common/hostreporter/util.h> #include <vespa/vespalib/data/slime/slime.h> #include <vespa/vespalib/io/fileutil.h> -#include <vespa/vespalib/testkit/test_kit.h> -#include <tests/common/hostreporter/util.h> #include <vespa/vespalib/stllike/asciistream.h> -#include <vespa/storage/distributor/bucket_spaces_stats_provider.h> +#include <vespa/vespalib/gtest/gtest.h> namespace storage::distributor { @@ -16,17 +15,9 @@ using PerNodeBucketSpacesStats = BucketSpacesStatsProvider::PerNodeBucketSpacesS using End = vespalib::JsonStream::End; using File = vespalib::File; using Object = vespalib::JsonStream::Object; +using namespace ::testing; -class DistributorHostInfoReporterTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(DistributorHostInfoReporterTest); - CPPUNIT_TEST(min_replica_stats_are_reported); - CPPUNIT_TEST(generate_example_json); - CPPUNIT_TEST(no_report_generated_if_disabled); - CPPUNIT_TEST(bucket_spaces_stats_are_reported); - CPPUNIT_TEST_SUITE_END(); - - void min_replica_stats_are_reported(); +struct DistributorHostInfoReporterTest : Test { void verifyBucketSpaceStats(const vespalib::Slime& root, uint16_t nodeIndex, const vespalib::string& bucketSpaceName, @@ -35,13 +26,8 @@ class DistributorHostInfoReporterTest : public CppUnit::TestFixture void verifyBucketSpaceStats(const vespalib::Slime& root, uint16_t nodeIndex, const vespalib::string& bucketSpaceName); - void generate_example_json(); - void no_report_generated_if_disabled(); - void bucket_spaces_stats_are_reported(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(DistributorHostInfoReporterTest); - using ms = std::chrono::milliseconds; namespace { @@ -107,8 +93,8 @@ DistributorHostInfoReporterTest::verifyBucketSpaceStats(const vespalib::Slime& r { const auto &stats = getBucketSpaceStats(root, nodeIndex, bucketSpaceName); const auto &buckets = stats["buckets"]; - CPPUNIT_ASSERT_EQUAL(bucketsTotal, static_cast<size_t>(buckets["total"].asLong())); - CPPUNIT_ASSERT_EQUAL(bucketsPending, static_cast<size_t>(buckets["pending"].asLong())); + EXPECT_EQ(bucketsTotal, static_cast<size_t>(buckets["total"].asLong())); + EXPECT_EQ(bucketsPending, static_cast<size_t>(buckets["pending"].asLong())); } void @@ -117,7 +103,7 @@ DistributorHostInfoReporterTest::verifyBucketSpaceStats(const vespalib::Slime& r const vespalib::string& bucketSpaceName) { const auto &stats = getBucketSpaceStats(root, nodeIndex, bucketSpaceName); - CPPUNIT_ASSERT(!stats["buckets"].valid()); + EXPECT_FALSE(stats["buckets"].valid()); } struct Fixture { @@ -129,12 +115,10 @@ struct Fixture { bucketSpacesStatsProvider(), reporter(minReplicaProvider, bucketSpacesStatsProvider) {} - ~Fixture() {} + ~Fixture() = default; }; -void -DistributorHostInfoReporterTest::min_replica_stats_are_reported() -{ +TEST_F(DistributorHostInfoReporterTest, min_replica_stats_are_reported) { Fixture f; std::unordered_map<uint16_t, uint32_t> minReplica; @@ -145,13 +129,11 @@ DistributorHostInfoReporterTest::min_replica_stats_are_reported() vespalib::Slime root; util::reporterToSlime(f.reporter, root); - CPPUNIT_ASSERT_EQUAL(2, getMinReplica(root, 0)); - CPPUNIT_ASSERT_EQUAL(9, getMinReplica(root, 5)); + EXPECT_EQ(2, getMinReplica(root, 0)); + EXPECT_EQ(9, getMinReplica(root, 5)); } -void -DistributorHostInfoReporterTest::generate_example_json() -{ +TEST_F(DistributorHostInfoReporterTest, generate_example_json) { Fixture f; std::unordered_map<uint16_t, uint32_t> minReplica; @@ -175,7 +157,7 @@ DistributorHostInfoReporterTest::generate_example_json() std::string jsonString = json.str(); - std::string path = TEST_PATH("../../../protocols/getnodestate/distributor.json"); + std::string path = "../../../../protocols/getnodestate/distributor.json"; std::string goldenString = File::readAll(path); vespalib::Memory goldenMemory(goldenString); @@ -186,12 +168,10 @@ DistributorHostInfoReporterTest::generate_example_json() vespalib::Slime jsonSlime; vespalib::slime::JsonFormat::decode(jsonMemory, jsonSlime); - CPPUNIT_ASSERT_EQUAL(goldenSlime, jsonSlime); + EXPECT_EQ(goldenSlime, jsonSlime); } -void -DistributorHostInfoReporterTest::no_report_generated_if_disabled() -{ +TEST_F(DistributorHostInfoReporterTest, no_report_generated_if_disabled) { Fixture f; f.reporter.enableReporting(false); @@ -202,12 +182,10 @@ DistributorHostInfoReporterTest::no_report_generated_if_disabled() vespalib::Slime root; util::reporterToSlime(f.reporter, root); - CPPUNIT_ASSERT_EQUAL(size_t(0), root.get().children()); + EXPECT_EQ(0, root.get().children()); } -void -DistributorHostInfoReporterTest::bucket_spaces_stats_are_reported() -{ +TEST_F(DistributorHostInfoReporterTest, bucket_spaces_stats_are_reported) { Fixture f; PerNodeBucketSpacesStats stats; stats[1]["default"] = BucketSpaceStats(11, 3); @@ -226,9 +204,9 @@ DistributorHostInfoReporterTest::bucket_spaces_stats_are_reported() verifyBucketSpaceStats(root, 3, "default", 19, 11); try { verifyBucketSpaceStats(root, 3, "global"); - CPPUNIT_ASSERT(false); - } catch (const std::runtime_error &ex) { - CPPUNIT_ASSERT("No bucket space found with name global" == vespalib::string(ex.what())); + FAIL() << "No exception thrown"; + } catch (const std::runtime_error& ex) { + EXPECT_EQ("No bucket space found with name global", vespalib::string(ex.what())); } } diff --git a/storage/src/tests/distributor/distributor_message_sender_stub.cpp b/storage/src/tests/distributor/distributor_message_sender_stub.cpp new file mode 100644 index 00000000000..df894f1bb2c --- /dev/null +++ b/storage/src/tests/distributor/distributor_message_sender_stub.cpp @@ -0,0 +1,20 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "distributor_message_sender_stub.h" +#include <vespa/storageapi/messageapi/storagecommand.h> +#include <vespa/storageapi/messageapi/storagereply.h> +#include <string> +#include <sstream> +#include <stdexcept> + +namespace storage { + +DistributorMessageSenderStub::DistributorMessageSenderStub() + : _stub_impl(), + _cluster_name("storage"), + _pending_message_tracker(nullptr) +{} + +DistributorMessageSenderStub::~DistributorMessageSenderStub() = default; + +} diff --git a/storage/src/tests/distributor/distributor_message_sender_stub.h b/storage/src/tests/distributor/distributor_message_sender_stub.h new file mode 100644 index 00000000000..7ebd4dee1ae --- /dev/null +++ b/storage/src/tests/distributor/distributor_message_sender_stub.h @@ -0,0 +1,98 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/storage/distributor/distributormessagesender.h> +#include <tests/common/message_sender_stub.h> +#include <cassert> + +namespace storage { + +class DistributorMessageSenderStub : public distributor::DistributorMessageSender { + MessageSenderStub _stub_impl; + std::string _cluster_name; + distributor::PendingMessageTracker* _pending_message_tracker; +public: + + DistributorMessageSenderStub(); + ~DistributorMessageSenderStub() override; + + std::vector<std::shared_ptr<api::StorageCommand>>& commands() noexcept { + return _stub_impl.commands; + } + std::vector<std::shared_ptr<api::StorageReply>>& replies() noexcept { + return _stub_impl.replies; + } + const std::vector<std::shared_ptr<api::StorageCommand>>& commands() const noexcept { + return _stub_impl.commands; + } + const std::vector<std::shared_ptr<api::StorageReply>>& replies() const noexcept { + return _stub_impl.replies; + }; + + const std::shared_ptr<api::StorageCommand>& command(size_t idx) noexcept { + assert(idx < commands().size()); + return commands()[idx]; + } + + const std::shared_ptr<api::StorageReply>& reply(size_t idx) noexcept { + assert(idx < replies().size()); + return replies()[idx]; + } + + void clear() { + _stub_impl.clear(); + } + + void sendCommand(const std::shared_ptr<api::StorageCommand>& cmd) override { + _stub_impl.sendCommand(cmd); + } + + void sendReply(const std::shared_ptr<api::StorageReply>& reply) override { + _stub_impl.sendReply(reply); + } + + std::string getLastCommand(bool verbose = true) const { + return _stub_impl.getLastCommand(verbose); + } + + std::string getCommands(bool includeAddress = false, + bool verbose = false, + uint32_t fromIndex = 0) const { + return _stub_impl.getCommands(includeAddress, verbose, fromIndex); + } + + std::string getLastReply(bool verbose = true) const { + return _stub_impl.getLastReply(verbose); + } + + std::string getReplies(bool includeAddress = false, + bool verbose = false) const { + return _stub_impl.getReplies(includeAddress, verbose); + } + + std::string dumpMessage(const api::StorageMessage& msg, + bool includeAddress, + bool verbose) const { + return _stub_impl.dumpMessage(msg, includeAddress, verbose); + } + + int getDistributorIndex() const override { + return 0; + } + + const std::string& getClusterName() const override { + return _cluster_name; + } + + const distributor::PendingMessageTracker& getPendingMessageTracker() const override { + assert(_pending_message_tracker); + return *_pending_message_tracker; + } + + void setPendingMessageTracker(distributor::PendingMessageTracker& tracker) { + _pending_message_tracker = &tracker; + } +}; + +} diff --git a/storage/src/tests/distributor/distributortest.cpp b/storage/src/tests/distributor/distributortest.cpp index c519ef0713b..2710ed67717 100644 --- a/storage/src/tests/distributor/distributortest.cpp +++ b/storage/src/tests/distributor/distributortest.cpp @@ -1,6 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/storage/distributor/idealstatemetricsset.h> #include <vespa/storageapi/message/persistence.h> #include <vespa/storageapi/message/bucketsplitting.h> @@ -15,6 +14,8 @@ #include <tests/common/dummystoragelink.h> #include <vespa/storage/distributor/distributor.h> #include <vespa/vespalib/text/stringtokenizer.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> using document::test::makeDocumentBucket; using document::test::makeBucketSpace; @@ -22,87 +23,13 @@ using document::FixedBucketSpaces; using document::BucketSpace; using document::Bucket; using document::BucketId; +using namespace ::testing; -namespace storage { +namespace storage::distributor { -namespace distributor { +struct DistributorTest : Test, DistributorTestUtil { + DistributorTest(); -class Distributor_Test : public CppUnit::TestFixture, - public DistributorTestUtil -{ - CPPUNIT_TEST_SUITE(Distributor_Test); - CPPUNIT_TEST(testOperationGeneration); - CPPUNIT_TEST(testOperationsGeneratedAndStartedWithoutDuplicates); - CPPUNIT_TEST(testRecoveryModeOnClusterStateChange); - CPPUNIT_TEST(testOperationsAreThrottled); - CPPUNIT_TEST_IGNORED(testRecoveryModeEntryResetsScanner); - CPPUNIT_TEST_IGNORED(testReprioritizeBucketOnMaintenanceReply); - CPPUNIT_TEST(testHandleUnknownMaintenanceReply); - CPPUNIT_TEST(testContainsTimeStatement); - CPPUNIT_TEST(testUpdateBucketDatabase); - CPPUNIT_TEST(testTickProcessesStatusRequests); - CPPUNIT_TEST(testMetricUpdateHookUpdatesPendingMaintenanceMetrics); - CPPUNIT_TEST(testPriorityConfigIsPropagatedToDistributorConfiguration); - CPPUNIT_TEST(testNoDbResurrectionForBucketNotOwnedInPendingState); - CPPUNIT_TEST(testAddedDbBucketsWithoutGcTimestampImplicitlyGetCurrentTime); - CPPUNIT_TEST(mergeStatsAreAccumulatedDuringDatabaseIteration); - CPPUNIT_TEST(statsGeneratedForPreemptedOperations); - CPPUNIT_TEST(hostInfoReporterConfigIsPropagatedToReporter); - CPPUNIT_TEST(replicaCountingModeIsConfiguredToTrustedByDefault); - CPPUNIT_TEST(replicaCountingModeConfigIsPropagatedToMetricUpdater); - CPPUNIT_TEST(bucketActivationIsEnabledByDefault); - CPPUNIT_TEST(bucketActivationConfigIsPropagatedToDistributorConfiguration); - CPPUNIT_TEST(max_clock_skew_config_is_propagated_to_distributor_config); - CPPUNIT_TEST(configured_safe_time_point_rejection_works_end_to_end); - CPPUNIT_TEST(sequencing_config_is_propagated_to_distributor_config); - CPPUNIT_TEST(merge_busy_inhibit_duration_config_is_propagated_to_distributor_config); - CPPUNIT_TEST(merge_busy_inhibit_duration_is_propagated_to_pending_message_tracker); - CPPUNIT_TEST(external_client_requests_are_handled_individually_in_priority_order); - CPPUNIT_TEST(internal_messages_are_started_in_fifo_order_batch); - CPPUNIT_TEST(closing_aborts_priority_queued_client_requests); - CPPUNIT_TEST(entering_recovery_mode_resets_bucket_space_stats); - CPPUNIT_TEST(leaving_recovery_mode_immediately_sends_getnodestate_replies); - CPPUNIT_TEST(pending_to_no_pending_default_merges_edge_immediately_sends_getnodestate_replies); - CPPUNIT_TEST(pending_to_no_pending_global_merges_edge_immediately_sends_getnodestate_replies); - CPPUNIT_TEST_SUITE_END(); - -public: - Distributor_Test(); - -protected: - void testOperationGeneration(); - void testOperationsGeneratedAndStartedWithoutDuplicates(); - void testRecoveryModeOnClusterStateChange(); - void testOperationsAreThrottled(); - void testRecoveryModeEntryResetsScanner(); - void testReprioritizeBucketOnMaintenanceReply(); - void testHandleUnknownMaintenanceReply(); - void testContainsTimeStatement(); - void testUpdateBucketDatabase(); - void testTickProcessesStatusRequests(); - void testMetricUpdateHookUpdatesPendingMaintenanceMetrics(); - void testPriorityConfigIsPropagatedToDistributorConfiguration(); - void testNoDbResurrectionForBucketNotOwnedInPendingState(); - void testAddedDbBucketsWithoutGcTimestampImplicitlyGetCurrentTime(); - void mergeStatsAreAccumulatedDuringDatabaseIteration(); - void statsGeneratedForPreemptedOperations(); - void hostInfoReporterConfigIsPropagatedToReporter(); - void replicaCountingModeIsConfiguredToTrustedByDefault(); - void replicaCountingModeConfigIsPropagatedToMetricUpdater(); - void bucketActivationIsEnabledByDefault(); - void bucketActivationConfigIsPropagatedToDistributorConfiguration(); - void max_clock_skew_config_is_propagated_to_distributor_config(); - void configured_safe_time_point_rejection_works_end_to_end(); - void sequencing_config_is_propagated_to_distributor_config(); - void merge_busy_inhibit_duration_config_is_propagated_to_distributor_config(); - void merge_busy_inhibit_duration_is_propagated_to_pending_message_tracker(); - void external_client_requests_are_handled_individually_in_priority_order(); - void internal_messages_are_started_in_fifo_order_batch(); - void closing_aborts_priority_queued_client_requests(); - void entering_recovery_mode_resets_bucket_space_stats(); - void leaving_recovery_mode_immediately_sends_getnodestate_replies(); - void pending_to_no_pending_default_merges_edge_immediately_sends_getnodestate_replies(); - void pending_to_no_pending_global_merges_edge_immediately_sends_getnodestate_replies(); // TODO handle edge case for window between getnodestate reply already // sent and new request not yet received @@ -110,17 +37,15 @@ protected: const BucketSpacesStatsProvider::PerNodeBucketSpacesStats &stats); std::vector<document::BucketSpace> _bucketSpaces; -public: - void setUp() override { + void SetUp() override { createLinks(); _bucketSpaces = getBucketSpaces(); }; - void tearDown() override { + void TearDown() override { close(); } -private: // Simple type aliases to make interfacing with certain utility functions // easier. Note that this is only for readability and does not provide any // added type safety. @@ -139,10 +64,9 @@ private: .getMinimumReplicaCountingMode(); } - std::string testOp(api::StorageMessage* msg) + std::string testOp(std::shared_ptr<api::StorageMessage> msg) { - api::StorageMessage::SP msgPtr(msg); - _distributor->handleMessage(msgPtr); + _distributor->handleMessage(msg); std::string tmp = _sender.getCommands(); _sender.clear(); @@ -211,6 +135,38 @@ private: return _node->getNodeStateUpdater().explicit_node_state_reply_send_invocations(); } + StatusReporterDelegate& distributor_status_delegate() { + return _distributor->_distributorStatusDelegate; + } + + framework::TickingThreadPool& distributor_thread_pool() { + return _distributor->_threadPool; + } + + const std::vector<std::shared_ptr<Distributor::Status>>& distributor_status_todos() { + return _distributor->_statusToDo; + } + + Distributor::MetricUpdateHook distributor_metric_update_hook() { + return _distributor->_metricUpdateHook; + } + + SimpleMaintenanceScanner::PendingMaintenanceStats& distributor_maintenance_stats() { + return _distributor->_maintenanceStats; + } + + BucketSpacesStatsProvider::PerNodeBucketSpacesStats distributor_bucket_spaces_stats() { + return _distributor->getBucketSpacesStats(); + } + + DistributorHostInfoReporter& distributor_host_info_reporter() { + return _distributor->_hostInfoReporter; + } + + bool distributor_handle_message(const std::shared_ptr<api::StorageMessage>& msg) { + return _distributor->handleMessage(msg); + } + void configureMaxClusterClockSkew(int seconds); void sendDownClusterStateCommand(); void replyToSingleRequestBucketInfoCommandWith1Bucket(); @@ -222,39 +178,32 @@ private: void do_test_pending_merge_getnodestate_reply_edge(BucketSpace space); }; -CPPUNIT_TEST_SUITE_REGISTRATION(Distributor_Test); - -Distributor_Test::Distributor_Test() - : CppUnit::TestFixture(), - DistributorTestUtil(), - _bucketSpaces() +DistributorTest::DistributorTest() + : Test(), + DistributorTestUtil(), + _bucketSpaces() { } -void -Distributor_Test::testOperationGeneration() -{ +TEST_F(DistributorTest, operation_generation) { setupDistributor(Redundancy(1), NodeCount(1), "storage:1 distributor:1"); document::BucketId bid; addNodesToBucketDB(document::BucketId(16, 1), "0=1/1/1/t"); - CPPUNIT_ASSERT_EQUAL(std::string("Remove"), - testOp(new api::RemoveCommand( - makeDocumentBucket(bid), - document::DocumentId("userdoc:m:1:foo"), - api::Timestamp(1234)))); + EXPECT_EQ("Remove", testOp(std::make_shared<api::RemoveCommand>( + makeDocumentBucket(bid), + document::DocumentId("userdoc:m:1:foo"), + api::Timestamp(1234)))); - api::CreateVisitorCommand* cmd = new api::CreateVisitorCommand(makeBucketSpace(), "foo", "bar", ""); + auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "foo", "bar", ""); cmd->addBucketToBeVisited(document::BucketId(16, 1)); cmd->addBucketToBeVisited(document::BucketId()); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create"), testOp(cmd)); + EXPECT_EQ("Visitor Create", testOp(cmd)); } -void -Distributor_Test::testOperationsGeneratedAndStartedWithoutDuplicates() -{ +TEST_F(DistributorTest, operations_generated_and_started_without_duplicates) { setupDistributor(Redundancy(1), NodeCount(1), "storage:1 distributor:1"); for (uint32_t i = 0; i < 6; ++i) { @@ -263,36 +212,32 @@ Distributor_Test::testOperationsGeneratedAndStartedWithoutDuplicates() tickDistributorNTimes(20); - CPPUNIT_ASSERT(!tick()); + ASSERT_FALSE(tick()); - CPPUNIT_ASSERT_EQUAL(6, (int)_sender.commands.size()); + ASSERT_EQ(6, _sender.commands().size()); } -void -Distributor_Test::testRecoveryModeOnClusterStateChange() -{ +TEST_F(DistributorTest, recovery_mode_on_cluster_state_change) { setupDistributor(Redundancy(1), NodeCount(2), "storage:1 .0.s:d distributor:1"); enableDistributorClusterState("storage:1 distributor:1"); - CPPUNIT_ASSERT(_distributor->isInRecoveryMode()); + EXPECT_TRUE(_distributor->isInRecoveryMode()); for (uint32_t i = 0; i < 3; ++i) { addNodesToBucketDB(document::BucketId(16, i), "0=1"); } for (int i = 0; i < 3; ++i) { tick(); - CPPUNIT_ASSERT(_distributor->isInRecoveryMode()); + EXPECT_TRUE(_distributor->isInRecoveryMode()); } tick(); - CPPUNIT_ASSERT(!_distributor->isInRecoveryMode()); + EXPECT_FALSE(_distributor->isInRecoveryMode()); enableDistributorClusterState("storage:2 distributor:1"); - CPPUNIT_ASSERT(_distributor->isInRecoveryMode()); + EXPECT_TRUE(_distributor->isInRecoveryMode()); } -void -Distributor_Test::testOperationsAreThrottled() -{ +TEST_F(DistributorTest, operations_are_throttled) { setupDistributor(Redundancy(1), NodeCount(1), "storage:1 distributor:1"); getConfig().setMinPendingMaintenanceOps(1); getConfig().setMaxPendingMaintenanceOps(1); @@ -301,32 +246,16 @@ Distributor_Test::testOperationsAreThrottled() addNodesToBucketDB(document::BucketId(16, i), "0=1"); } tickDistributorNTimes(20); - CPPUNIT_ASSERT_EQUAL(1, (int)_sender.commands.size()); + ASSERT_EQ(1, _sender.commands().size()); } -void -Distributor_Test::testRecoveryModeEntryResetsScanner() -{ - CPPUNIT_FAIL("TODO: refactor so this can be mocked and tested easily"); -} - -void -Distributor_Test::testReprioritizeBucketOnMaintenanceReply() -{ - CPPUNIT_FAIL("TODO: refactor so this can be mocked and tested easily"); -} - -void -Distributor_Test::testHandleUnknownMaintenanceReply() -{ +TEST_F(DistributorTest, handle_unknown_maintenance_reply) { setupDistributor(Redundancy(1), NodeCount(1), "storage:1 distributor:1"); { - api::SplitBucketCommand::SP cmd( - new api::SplitBucketCommand(makeDocumentBucket(document::BucketId(16, 1234)))); - api::SplitBucketReply::SP reply(new api::SplitBucketReply(*cmd)); - - CPPUNIT_ASSERT(_distributor->handleReply(reply)); + auto cmd = std::make_shared<api::SplitBucketCommand>(makeDocumentBucket(document::BucketId(16, 1234))); + auto reply = std::make_shared<api::SplitBucketReply>(*cmd); + ASSERT_TRUE(_distributor->handleReply(reply)); } { @@ -335,94 +264,74 @@ Distributor_Test::testHandleUnknownMaintenanceReply() auto cmd = std::make_shared<api::RemoveLocationCommand>( "false", makeDocumentBucket(document::BucketId(30, 1234))); auto reply = std::shared_ptr<api::StorageReply>(cmd->makeReply()); - CPPUNIT_ASSERT(_distributor->handleReply(reply)); + ASSERT_TRUE(_distributor->handleReply(reply)); } } -void -Distributor_Test::testContainsTimeStatement() -{ +TEST_F(DistributorTest, contains_time_statement) { setupDistributor(Redundancy(1), NodeCount(1), "storage:1 distributor:1"); - CPPUNIT_ASSERT_EQUAL(false, getConfig().containsTimeStatement("")); - CPPUNIT_ASSERT_EQUAL(false, getConfig().containsTimeStatement("testdoctype1")); - CPPUNIT_ASSERT_EQUAL(false, getConfig().containsTimeStatement("testdoctype1.headerfield > 42")); - CPPUNIT_ASSERT_EQUAL(true, getConfig().containsTimeStatement("testdoctype1.headerfield > now()")); - CPPUNIT_ASSERT_EQUAL(true, getConfig().containsTimeStatement("testdoctype1.headerfield > now() - 3600")); - CPPUNIT_ASSERT_EQUAL(true, getConfig().containsTimeStatement("testdoctype1.headerfield == now() - 3600")); + EXPECT_FALSE(getConfig().containsTimeStatement("")); + EXPECT_FALSE(getConfig().containsTimeStatement("testdoctype1")); + EXPECT_FALSE(getConfig().containsTimeStatement("testdoctype1.headerfield > 42")); + EXPECT_TRUE(getConfig().containsTimeStatement("testdoctype1.headerfield > now()")); + EXPECT_TRUE(getConfig().containsTimeStatement("testdoctype1.headerfield > now() - 3600")); + EXPECT_TRUE(getConfig().containsTimeStatement("testdoctype1.headerfield == now() - 3600")); } -void -Distributor_Test::testUpdateBucketDatabase() -{ +TEST_F(DistributorTest, update_bucket_database) { enableDistributorClusterState("distributor:1 storage:3"); - CPPUNIT_ASSERT_EQUAL( - std::string("BucketId(0x4000000000000001) : " - "node(idx=0,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false), " - "node(idx=1,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false)" - ), - updateBucketDB("0:456,1:456,2:789", "2:r")); - - CPPUNIT_ASSERT_EQUAL( - std::string("BucketId(0x4000000000000001) : " - "node(idx=0,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false), " - "node(idx=2,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false), " - "node(idx=1,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false)" - ), - updateBucketDB("0:456,1:456", "2:456")); - - CPPUNIT_ASSERT_EQUAL( - std::string("BucketId(0x4000000000000001) : " - "node(idx=0,crc=0x315,docs=394/394,bytes=197/197,trusted=false,active=false,ready=false), " - "node(idx=2,crc=0x14d,docs=166/166,bytes=83/83,trusted=false,active=false,ready=false), " - "node(idx=1,crc=0x34a,docs=421/421,bytes=210/210,trusted=false,active=false,ready=false)" - ), - updateBucketDB("0:456:t,1:456:t,2:123", "0:789,1:842,2:333")); - - CPPUNIT_ASSERT_EQUAL( - std::string("BucketId(0x4000000000000001) : " - "node(idx=0,crc=0x315,docs=394/394,bytes=197/197,trusted=true,active=false,ready=false), " - "node(idx=2,crc=0x14d,docs=166/166,bytes=83/83,trusted=false,active=false,ready=false), " - "node(idx=1,crc=0x315,docs=394/394,bytes=197/197,trusted=true,active=false,ready=false)" - ), - updateBucketDB("0:456:t,1:456:t,2:123", "0:789,1:789,2:333")); - - CPPUNIT_ASSERT_EQUAL( - std::string("BucketId(0x4000000000000001) : " - "node(idx=2,crc=0x14d,docs=166/166,bytes=83/83,trusted=true,active=false,ready=false)"), - updateBucketDB("0:456:t,1:456:t", "0:r,1:r,2:333")); + EXPECT_EQ("BucketId(0x4000000000000001) : " + "node(idx=0,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false), " + "node(idx=1,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false)", + updateBucketDB("0:456,1:456,2:789", "2:r")); + + EXPECT_EQ("BucketId(0x4000000000000001) : " + "node(idx=0,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false), " + "node(idx=2,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false), " + "node(idx=1,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false)", + updateBucketDB("0:456,1:456", "2:456")); + + EXPECT_EQ("BucketId(0x4000000000000001) : " + "node(idx=0,crc=0x315,docs=394/394,bytes=197/197,trusted=false,active=false,ready=false), " + "node(idx=2,crc=0x14d,docs=166/166,bytes=83/83,trusted=false,active=false,ready=false), " + "node(idx=1,crc=0x34a,docs=421/421,bytes=210/210,trusted=false,active=false,ready=false)", + updateBucketDB("0:456:t,1:456:t,2:123", "0:789,1:842,2:333")); + + EXPECT_EQ("BucketId(0x4000000000000001) : " + "node(idx=0,crc=0x315,docs=394/394,bytes=197/197,trusted=true,active=false,ready=false), " + "node(idx=2,crc=0x14d,docs=166/166,bytes=83/83,trusted=false,active=false,ready=false), " + "node(idx=1,crc=0x315,docs=394/394,bytes=197/197,trusted=true,active=false,ready=false)", + updateBucketDB("0:456:t,1:456:t,2:123", "0:789,1:789,2:333")); + + EXPECT_EQ("BucketId(0x4000000000000001) : " + "node(idx=2,crc=0x14d,docs=166/166,bytes=83/83,trusted=true,active=false,ready=false)", + updateBucketDB("0:456:t,1:456:t", "0:r,1:r,2:333")); // Copies are in sync so should still be trusted even if explicitly reset. - CPPUNIT_ASSERT_EQUAL( - std::string("BucketId(0x4000000000000001) : " - "node(idx=0,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false), " - "node(idx=2,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false), " - "node(idx=1,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false)" - ), - updateBucketDB("0:456,1:456", "2:456", ResetTrusted(true))); + EXPECT_EQ("BucketId(0x4000000000000001) : " + "node(idx=0,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false), " + "node(idx=2,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false), " + "node(idx=1,crc=0x1c8,docs=228/228,bytes=114/114,trusted=true,active=false,ready=false)", + updateBucketDB("0:456,1:456", "2:456", ResetTrusted(true))); // When resetting, first inserted copy should not end up as implicitly trusted. - CPPUNIT_ASSERT_EQUAL( - std::string("BucketId(0x4000000000000001) : " - "node(idx=0,crc=0x1c8,docs=228/228,bytes=114/114,trusted=false,active=false,ready=false), " - "node(idx=2,crc=0x14d,docs=166/166,bytes=83/83,trusted=false,active=false,ready=false)" - ), - updateBucketDB("0:456", - "2:333", - ResetTrusted(true))); + EXPECT_EQ("BucketId(0x4000000000000001) : " + "node(idx=0,crc=0x1c8,docs=228/228,bytes=114/114,trusted=false,active=false,ready=false), " + "node(idx=2,crc=0x14d,docs=166/166,bytes=83/83,trusted=false,active=false,ready=false)", + updateBucketDB("0:456", "2:333", ResetTrusted(true))); } namespace { using namespace framework::defaultimplementation; -class StatusRequestThread : public framework::Runnable -{ +class StatusRequestThread : public framework::Runnable { StatusReporterDelegate& _reporter; std::string _result; public: - StatusRequestThread(StatusReporterDelegate& reporter) + explicit StatusRequestThread(StatusReporterDelegate& reporter) : _reporter(reporter) {} void run(framework::ThreadHandle&) override { @@ -439,16 +348,14 @@ public: } -void -Distributor_Test::testTickProcessesStatusRequests() -{ +TEST_F(DistributorTest, tick_processes_status_requests) { setupDistributor(Redundancy(1), NodeCount(1), "storage:1 distributor:1"); addNodesToBucketDB(document::BucketId(16, 1), "0=1/1/1/t"); // Must go via delegate since reportStatus is now just a rendering // function and not a request enqueuer (see Distributor::handleStatusRequest). - StatusRequestThread thread(_distributor->_distributorStatusDelegate); + StatusRequestThread thread(distributor_status_delegate()); FakeClock clock; ThreadPoolImpl pool(clock); @@ -461,20 +368,20 @@ Distributor_Test::testTickProcessesStatusRequests() while (true) { FastOS_Thread::Sleep(1); framework::TickingLockGuard guard( - _distributor->_threadPool.freezeCriticalTicks()); - if (!_distributor->_statusToDo.empty()) break; + distributor_thread_pool().freezeCriticalTicks()); + if (!distributor_status_todos().empty()) { + break; + } } - CPPUNIT_ASSERT(tick()); + ASSERT_TRUE(tick()); - tp->interruptAndJoin(0); + tp->interruptAndJoin(nullptr); - CPPUNIT_ASSERT_CONTAIN("BucketId(0x4000000000000001)", thread.getResult()); + EXPECT_THAT(thread.getResult(), HasSubstr("BucketId(0x4000000000000001)")); } -void -Distributor_Test::testMetricUpdateHookUpdatesPendingMaintenanceMetrics() -{ +TEST_F(DistributorTest, metric_update_hook_updates_pending_maintenance_metrics) { setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1"); // To ensure we count all operations, not just those fitting within the // pending window. @@ -494,53 +401,33 @@ Distributor_Test::testMetricUpdateHookUpdatesPendingMaintenanceMetrics() // By this point, no hook has been called so the metrics have not been // set. - typedef MaintenanceOperation MO; + using MO = MaintenanceOperation; { const IdealStateMetricSet& metrics(getIdealStateManager().getMetrics()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), - metrics.operations[MO::MERGE_BUCKET] - ->pending.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), metrics.operations[MO::SPLIT_BUCKET] - ->pending.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), - metrics.operations[MO::SET_BUCKET_STATE] - ->pending.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), metrics.operations[MO::DELETE_BUCKET] - ->pending.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), metrics.operations[MO::JOIN_BUCKET] - ->pending.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), - metrics.operations[MO::GARBAGE_COLLECTION] - ->pending.getLast()); + EXPECT_EQ(0, metrics.operations[MO::MERGE_BUCKET]->pending.getLast()); + EXPECT_EQ(0, metrics.operations[MO::SPLIT_BUCKET]->pending.getLast()); + EXPECT_EQ(0, metrics.operations[MO::SET_BUCKET_STATE]->pending.getLast()); + EXPECT_EQ(0, metrics.operations[MO::DELETE_BUCKET]->pending.getLast()); + EXPECT_EQ(0, metrics.operations[MO::JOIN_BUCKET]->pending.getLast()); + EXPECT_EQ(0, metrics.operations[MO::GARBAGE_COLLECTION]->pending.getLast()); } // Force trigger update hook vespalib::Monitor l; - _distributor->_metricUpdateHook.updateMetrics(vespalib::MonitorGuard(l)); + distributor_metric_update_hook().updateMetrics(vespalib::MonitorGuard(l)); // Metrics should now be updated to the last complete working state { const IdealStateMetricSet& metrics(getIdealStateManager().getMetrics()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), - metrics.operations[MO::MERGE_BUCKET] - ->pending.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), metrics.operations[MO::SPLIT_BUCKET] - ->pending.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), - metrics.operations[MO::SET_BUCKET_STATE] - ->pending.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), metrics.operations[MO::DELETE_BUCKET] - ->pending.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), metrics.operations[MO::JOIN_BUCKET] - ->pending.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), - metrics.operations[MO::GARBAGE_COLLECTION] - ->pending.getLast()); + EXPECT_EQ(1, metrics.operations[MO::MERGE_BUCKET]->pending.getLast()); + EXPECT_EQ(1, metrics.operations[MO::SPLIT_BUCKET]->pending.getLast()); + EXPECT_EQ(1, metrics.operations[MO::SET_BUCKET_STATE]->pending.getLast()); + EXPECT_EQ(0, metrics.operations[MO::DELETE_BUCKET]->pending.getLast()); + EXPECT_EQ(0, metrics.operations[MO::JOIN_BUCKET]->pending.getLast()); + EXPECT_EQ(0, metrics.operations[MO::GARBAGE_COLLECTION]->pending.getLast()); } } -void -Distributor_Test::testPriorityConfigIsPropagatedToDistributorConfiguration() -{ +TEST_F(DistributorTest, priority_config_is_propagated_to_distributor_configuration) { using namespace vespa::config::content::core; setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1"); @@ -560,24 +447,21 @@ Distributor_Test::testPriorityConfigIsPropagatedToDistributorConfiguration() getConfig().configure(builder); - const DistributorConfiguration::MaintenancePriorities& mp( - getConfig().getMaintenancePriorities()); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(mp.mergeMoveToIdealNode)); - CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(mp.mergeOutOfSyncCopies)); - CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(mp.mergeTooFewCopies)); - CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(mp.activateNoExistingActive)); - CPPUNIT_ASSERT_EQUAL(5, static_cast<int>(mp.activateWithExistingActive)); - CPPUNIT_ASSERT_EQUAL(6, static_cast<int>(mp.deleteBucketCopy)); - CPPUNIT_ASSERT_EQUAL(7, static_cast<int>(mp.joinBuckets)); - CPPUNIT_ASSERT_EQUAL(8, static_cast<int>(mp.splitDistributionBits)); - CPPUNIT_ASSERT_EQUAL(9, static_cast<int>(mp.splitLargeBucket)); - CPPUNIT_ASSERT_EQUAL(10, static_cast<int>(mp.splitInconsistentBucket)); - CPPUNIT_ASSERT_EQUAL(11, static_cast<int>(mp.garbageCollection)); -} - -void -Distributor_Test::testNoDbResurrectionForBucketNotOwnedInPendingState() -{ + const auto& mp = getConfig().getMaintenancePriorities(); + EXPECT_EQ(1, static_cast<int>(mp.mergeMoveToIdealNode)); + EXPECT_EQ(2, static_cast<int>(mp.mergeOutOfSyncCopies)); + EXPECT_EQ(3, static_cast<int>(mp.mergeTooFewCopies)); + EXPECT_EQ(4, static_cast<int>(mp.activateNoExistingActive)); + EXPECT_EQ(5, static_cast<int>(mp.activateWithExistingActive)); + EXPECT_EQ(6, static_cast<int>(mp.deleteBucketCopy)); + EXPECT_EQ(7, static_cast<int>(mp.joinBuckets)); + EXPECT_EQ(8, static_cast<int>(mp.splitDistributionBits)); + EXPECT_EQ(9, static_cast<int>(mp.splitLargeBucket)); + EXPECT_EQ(10, static_cast<int>(mp.splitInconsistentBucket)); + EXPECT_EQ(11, static_cast<int>(mp.garbageCollection)); +} + +TEST_F(DistributorTest, no_db_resurrection_for_bucket_not_owned_in_pending_state) { setupDistributor(Redundancy(1), NodeCount(10), "storage:2 distributor:2"); lib::ClusterState newState("storage:10 distributor:10"); auto stateCmd = std::make_shared<api::SetSystemStateCommand>(newState); @@ -587,24 +471,20 @@ Distributor_Test::testNoDbResurrectionForBucketNotOwnedInPendingState() getBucketDBUpdater().onSetSystemState(stateCmd); document::BucketId nonOwnedBucket(16, 3); - CPPUNIT_ASSERT(!getBucketDBUpdater() - .checkOwnershipInPendingState(makeDocumentBucket(nonOwnedBucket)).isOwned()); - CPPUNIT_ASSERT(!getBucketDBUpdater().getDistributorComponent() - .checkOwnershipInPendingAndCurrentState(makeDocumentBucket(nonOwnedBucket)) - .isOwned()); + EXPECT_FALSE(getBucketDBUpdater().checkOwnershipInPendingState(makeDocumentBucket(nonOwnedBucket)).isOwned()); + EXPECT_FALSE(getBucketDBUpdater().getDistributorComponent() + .checkOwnershipInPendingAndCurrentState(makeDocumentBucket(nonOwnedBucket)) + .isOwned()); std::vector<BucketCopy> copies; copies.emplace_back(1234, 0, api::BucketInfo(0x567, 1, 2)); getExternalOperationHandler().updateBucketDatabase(makeDocumentBucket(nonOwnedBucket), copies, DatabaseUpdate::CREATE_IF_NONEXISTING); - CPPUNIT_ASSERT_EQUAL(std::string("NONEXISTING"), - dumpBucket(nonOwnedBucket)); + EXPECT_EQ("NONEXISTING", dumpBucket(nonOwnedBucket)); } -void -Distributor_Test::testAddedDbBucketsWithoutGcTimestampImplicitlyGetCurrentTime() -{ +TEST_F(DistributorTest, added_db_buckets_without_gc_timestamp_implicitly_get_current_time) { setupDistributor(Redundancy(1), NodeCount(10), "storage:2 distributor:2"); getClock().setAbsoluteTimeInSeconds(101234); document::BucketId bucket(16, 7654); @@ -614,13 +494,10 @@ Distributor_Test::testAddedDbBucketsWithoutGcTimestampImplicitlyGetCurrentTime() getExternalOperationHandler().updateBucketDatabase(makeDocumentBucket(bucket), copies, DatabaseUpdate::CREATE_IF_NONEXISTING); BucketDatabase::Entry e(getBucket(bucket)); - CPPUNIT_ASSERT_EQUAL(uint32_t(101234), e->getLastGarbageCollectionTime()); + EXPECT_EQ(101234, e->getLastGarbageCollectionTime()); } - -void -Distributor_Test::mergeStatsAreAccumulatedDuringDatabaseIteration() -{ +TEST_F(DistributorTest, merge_stats_are_accumulated_during_database_iteration) { setupDistributor(Redundancy(2), NodeCount(3), "storage:3 distributor:1"); // Copies out of sync. Not possible for distributor to _reliably_ tell // which direction(s) data will flow, so for simplicity assume that we @@ -642,46 +519,47 @@ Distributor_Test::mergeStatsAreAccumulatedDuringDatabaseIteration() // added to existing. tickDistributorNTimes(50); - const auto& stats(_distributor->_maintenanceStats); + const auto& stats = distributor_maintenance_stats(); { NodeMaintenanceStats wanted; wanted.syncing = 1; wanted.copyingOut = 2; wanted.total = 3; - CPPUNIT_ASSERT_EQUAL(wanted, stats.perNodeStats.forNode(0, makeBucketSpace())); + EXPECT_EQ(wanted, stats.perNodeStats.forNode(0, makeBucketSpace())); } { NodeMaintenanceStats wanted; wanted.movingOut = 1; wanted.total = 1; - CPPUNIT_ASSERT_EQUAL(wanted, stats.perNodeStats.forNode(1, makeBucketSpace())); + EXPECT_EQ(wanted, stats.perNodeStats.forNode(1, makeBucketSpace())); } { NodeMaintenanceStats wanted; wanted.syncing = 1; wanted.copyingIn = 2; wanted.total = 1; - CPPUNIT_ASSERT_EQUAL(wanted, stats.perNodeStats.forNode(2, makeBucketSpace())); + EXPECT_EQ(wanted, stats.perNodeStats.forNode(2, makeBucketSpace())); } - auto bucketStats = _distributor->getBucketSpacesStats(); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), bucketStats.size()); + auto bucketStats = distributor_bucket_spaces_stats(); + ASSERT_EQ(3, bucketStats.size()); assertBucketSpaceStats(1, 3, 0, "default", bucketStats); assertBucketSpaceStats(0, 1, 1, "default", bucketStats); assertBucketSpaceStats(3, 1, 2, "default", bucketStats); } void -Distributor_Test::assertBucketSpaceStats(size_t expBucketPending, size_t expBucketTotal, uint16_t node, const vespalib::string &bucketSpace, - const BucketSpacesStatsProvider::PerNodeBucketSpacesStats &stats) +DistributorTest::assertBucketSpaceStats(size_t expBucketPending, size_t expBucketTotal, uint16_t node, + const vespalib::string& bucketSpace, + const BucketSpacesStatsProvider::PerNodeBucketSpacesStats& stats) { auto nodeItr = stats.find(node); - CPPUNIT_ASSERT(nodeItr != stats.end()); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), nodeItr->second.size()); + ASSERT_TRUE(nodeItr != stats.end()); + ASSERT_EQ(1, nodeItr->second.size()); auto bucketSpaceItr = nodeItr->second.find(bucketSpace); - CPPUNIT_ASSERT(bucketSpaceItr != nodeItr->second.end()); - CPPUNIT_ASSERT(bucketSpaceItr->second.valid()); - CPPUNIT_ASSERT_EQUAL(expBucketTotal, bucketSpaceItr->second.bucketsTotal()); - CPPUNIT_ASSERT_EQUAL(expBucketPending, bucketSpaceItr->second.bucketsPending()); + ASSERT_TRUE(bucketSpaceItr != nodeItr->second.end()); + ASSERT_TRUE(bucketSpaceItr->second.valid()); + ASSERT_EQ(expBucketTotal, bucketSpaceItr->second.bucketsTotal()); + ASSERT_EQ(expBucketPending, bucketSpaceItr->second.bucketsPending()); } /** @@ -690,9 +568,7 @@ Distributor_Test::assertBucketSpaceStats(size_t expBucketPending, size_t expBuck * their state checkers at all, we won't get any statistics from any other * operations for the bucket. */ -void -Distributor_Test::statsGeneratedForPreemptedOperations() -{ +TEST_F(DistributorTest, stats_generated_for_preempted_operations) { setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1"); // For this test it suffices to have a single bucket with multiple aspects // wrong about it. In this case, let a bucket be both out of sync _and_ @@ -701,63 +577,53 @@ Distributor_Test::statsGeneratedForPreemptedOperations() // by activation, we'll see no merge stats at all. addNodesToBucketDB(document::BucketId(16, 1), "0=1/1/1,1=2/2/2"); tickDistributorNTimes(50); - const auto& stats(_distributor->_maintenanceStats); + const auto& stats = distributor_maintenance_stats(); { NodeMaintenanceStats wanted; wanted.syncing = 1; wanted.total = 1; - CPPUNIT_ASSERT_EQUAL(wanted, stats.perNodeStats.forNode(0, makeBucketSpace())); + EXPECT_EQ(wanted, stats.perNodeStats.forNode(0, makeBucketSpace())); } { NodeMaintenanceStats wanted; wanted.syncing = 1; wanted.total = 1; - CPPUNIT_ASSERT_EQUAL(wanted, stats.perNodeStats.forNode(1, makeBucketSpace())); + EXPECT_EQ(wanted, stats.perNodeStats.forNode(1, makeBucketSpace())); } } -void -Distributor_Test::hostInfoReporterConfigIsPropagatedToReporter() -{ +TEST_F(DistributorTest, host_info_reporter_config_is_propagated_to_reporter) { setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1"); // Default is enabled=true. - CPPUNIT_ASSERT(_distributor->_hostInfoReporter.isReportingEnabled()); + EXPECT_TRUE(distributor_host_info_reporter().isReportingEnabled()); ConfigBuilder builder; builder.enableHostInfoReporting = false; configureDistributor(builder); - CPPUNIT_ASSERT(!_distributor->_hostInfoReporter.isReportingEnabled()); + EXPECT_FALSE(distributor_host_info_reporter().isReportingEnabled()); } -void -Distributor_Test::replicaCountingModeIsConfiguredToTrustedByDefault() -{ +TEST_F(DistributorTest, replica_counting_mode_is_configured_to_trusted_by_default) { setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1"); - CPPUNIT_ASSERT_EQUAL(ConfigBuilder::TRUSTED, currentReplicaCountingMode()); + EXPECT_EQ(ConfigBuilder::TRUSTED, currentReplicaCountingMode()); } -void -Distributor_Test::replicaCountingModeConfigIsPropagatedToMetricUpdater() -{ +TEST_F(DistributorTest, replica_counting_mode_config_is_propagated_to_metric_updater) { setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1"); ConfigBuilder builder; builder.minimumReplicaCountingMode = ConfigBuilder::ANY; configureDistributor(builder); - CPPUNIT_ASSERT_EQUAL(ConfigBuilder::ANY, currentReplicaCountingMode()); + EXPECT_EQ(ConfigBuilder::ANY, currentReplicaCountingMode()); } -void -Distributor_Test::bucketActivationIsEnabledByDefault() -{ +TEST_F(DistributorTest, bucket_activation_is_enabled_by_default) { setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1"); - CPPUNIT_ASSERT(getConfig().isBucketActivationDisabled() == false); + EXPECT_FALSE(getConfig().isBucketActivationDisabled()); } -void -Distributor_Test::bucketActivationConfigIsPropagatedToDistributorConfiguration() -{ +TEST_F(DistributorTest, bucket_activation_config_is_propagated_to_distributor_configuration) { using namespace vespa::config::content::core; setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1"); @@ -766,11 +632,11 @@ Distributor_Test::bucketActivationConfigIsPropagatedToDistributorConfiguration() builder.disableBucketActivation = true; getConfig().configure(builder); - CPPUNIT_ASSERT(getConfig().isBucketActivationDisabled()); + EXPECT_TRUE(getConfig().isBucketActivationDisabled()); } void -Distributor_Test::configureMaxClusterClockSkew(int seconds) { +DistributorTest::configureMaxClusterClockSkew(int seconds) { using namespace vespa::config::content::core; ConfigBuilder builder; @@ -779,12 +645,11 @@ Distributor_Test::configureMaxClusterClockSkew(int seconds) { _distributor->enableNextConfig(); } -void -Distributor_Test::max_clock_skew_config_is_propagated_to_distributor_config() { +TEST_F(DistributorTest, max_clock_skew_config_is_propagated_to_distributor_config) { setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1"); configureMaxClusterClockSkew(5); - CPPUNIT_ASSERT(getConfig().getMaxClusterClockSkew() == std::chrono::seconds(5)); + EXPECT_EQ(getConfig().getMaxClusterClockSkew(), std::chrono::seconds(5)); } namespace { @@ -798,19 +663,18 @@ auto makeDummyRemoveCommand() { } -void Distributor_Test::sendDownClusterStateCommand() { +void DistributorTest::sendDownClusterStateCommand() { lib::ClusterState newState("bits:1 storage:1 distributor:1"); auto stateCmd = std::make_shared<api::SetSystemStateCommand>(newState); _distributor->handleMessage(stateCmd); } -void Distributor_Test::replyToSingleRequestBucketInfoCommandWith1Bucket() { - CPPUNIT_ASSERT_EQUAL(_bucketSpaces.size(), _sender.commands.size()); - for (uint32_t i = 0; i < _sender.commands.size(); ++i) { - CPPUNIT_ASSERT_EQUAL(api::MessageType::REQUESTBUCKETINFO, - _sender.commands[i]->getType()); +void DistributorTest::replyToSingleRequestBucketInfoCommandWith1Bucket() { + ASSERT_EQ(_bucketSpaces.size(), _sender.commands().size()); + for (uint32_t i = 0; i < _sender.commands().size(); ++i) { + ASSERT_EQ(api::MessageType::REQUESTBUCKETINFO, _sender.command(i)->getType()); auto& bucketReq(static_cast<api::RequestBucketInfoCommand&> - (*_sender.commands[i])); + (*_sender.command(i))); auto bucketReply = bucketReq.makeReply(); if (bucketReq.getBucketSpace() == FixedBucketSpaces::default_space()) { // Make sure we have a bucket to route our remove op to, or we'd get @@ -822,52 +686,49 @@ void Distributor_Test::replyToSingleRequestBucketInfoCommandWith1Bucket() { } _distributor->handleMessage(std::move(bucketReply)); } - _sender.commands.clear(); + _sender.commands().clear(); } -void Distributor_Test::sendDownDummyRemoveCommand() { +void DistributorTest::sendDownDummyRemoveCommand() { _distributor->handleMessage(makeDummyRemoveCommand()); } -void Distributor_Test::assertSingleBouncedRemoveReplyPresent() { - CPPUNIT_ASSERT_EQUAL(size_t(1), _sender.replies.size()); // Rejected remove - CPPUNIT_ASSERT_EQUAL(api::MessageType::REMOVE_REPLY, - _sender.replies[0]->getType()); - auto& reply(static_cast<api::RemoveReply&>(*_sender.replies[0])); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::STALE_TIMESTAMP, - reply.getResult().getResult()); - _sender.replies.clear(); +void DistributorTest::assertSingleBouncedRemoveReplyPresent() { + ASSERT_EQ(1, _sender.replies().size()); // Rejected remove + ASSERT_EQ(api::MessageType::REMOVE_REPLY, _sender.reply(0)->getType()); + auto& reply(static_cast<api::RemoveReply&>(*_sender.reply(0))); + ASSERT_EQ(api::ReturnCode::STALE_TIMESTAMP, reply.getResult().getResult()); + _sender.replies().clear(); } -void Distributor_Test::assertNoMessageBounced() { - CPPUNIT_ASSERT_EQUAL(size_t(0), _sender.replies.size()); +void DistributorTest::assertNoMessageBounced() { + ASSERT_EQ(0, _sender.replies().size()); } // TODO refactor this to set proper highest timestamp as part of bucket info // reply once we have the "highest timestamp across all owned buckets" feature // in place. -void -Distributor_Test::configured_safe_time_point_rejection_works_end_to_end() { +TEST_F(DistributorTest, configured_safe_time_point_rejection_works_end_to_end) { setupDistributor(Redundancy(2), NodeCount(2), "bits:1 storage:1 distributor:2"); getClock().setAbsoluteTimeInSeconds(1000); configureMaxClusterClockSkew(10); sendDownClusterStateCommand(); - replyToSingleRequestBucketInfoCommandWith1Bucket(); + ASSERT_NO_FATAL_FAILURE(replyToSingleRequestBucketInfoCommandWith1Bucket()); // SetSystemStateCommand sent down chain at this point. sendDownDummyRemoveCommand(); - assertSingleBouncedRemoveReplyPresent(); + ASSERT_NO_FATAL_FAILURE(assertSingleBouncedRemoveReplyPresent()); // Increment time to first whole second of clock + 10 seconds of skew. // Should now not get any feed rejections. getClock().setAbsoluteTimeInSeconds(1011); sendDownDummyRemoveCommand(); - assertNoMessageBounced(); + ASSERT_NO_FATAL_FAILURE(assertNoMessageBounced()); } -void Distributor_Test::configure_mutation_sequencing(bool enabled) { +void DistributorTest::configure_mutation_sequencing(bool enabled) { using namespace vespa::config::content::core; ConfigBuilder builder; @@ -876,23 +737,23 @@ void Distributor_Test::configure_mutation_sequencing(bool enabled) { _distributor->enableNextConfig(); } -void Distributor_Test::sequencing_config_is_propagated_to_distributor_config() { +TEST_F(DistributorTest, sequencing_config_is_propagated_to_distributor_config) { setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1"); // Should be enabled by default - CPPUNIT_ASSERT(getConfig().getSequenceMutatingOperations()); + EXPECT_TRUE(getConfig().getSequenceMutatingOperations()); // Explicitly disabled. configure_mutation_sequencing(false); - CPPUNIT_ASSERT(!getConfig().getSequenceMutatingOperations()); + EXPECT_FALSE(getConfig().getSequenceMutatingOperations()); // Explicitly enabled. configure_mutation_sequencing(true); - CPPUNIT_ASSERT(getConfig().getSequenceMutatingOperations()); + EXPECT_TRUE(getConfig().getSequenceMutatingOperations()); } void -Distributor_Test::configure_merge_busy_inhibit_duration(int seconds) { +DistributorTest::configure_merge_busy_inhibit_duration(int seconds) { using namespace vespa::config::content::core; ConfigBuilder builder; @@ -901,39 +762,39 @@ Distributor_Test::configure_merge_busy_inhibit_duration(int seconds) { _distributor->enableNextConfig(); } -void Distributor_Test::merge_busy_inhibit_duration_config_is_propagated_to_distributor_config() { +TEST_F(DistributorTest, merge_busy_inhibit_duration_config_is_propagated_to_distributor_config) { setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1"); configure_merge_busy_inhibit_duration(7); - CPPUNIT_ASSERT(getConfig().getInhibitMergesOnBusyNodeDuration() == std::chrono::seconds(7)); + EXPECT_EQ(getConfig().getInhibitMergesOnBusyNodeDuration(), std::chrono::seconds(7)); } -void Distributor_Test::merge_busy_inhibit_duration_is_propagated_to_pending_message_tracker() { +TEST_F(DistributorTest, merge_busy_inhibit_duration_is_propagated_to_pending_message_tracker) { setupDistributor(Redundancy(2), NodeCount(2), "storage:1 distributor:1"); addNodesToBucketDB(document::BucketId(16, 1), "0=1/1/1/t"); configure_merge_busy_inhibit_duration(100); auto cmd = makeDummyRemoveCommand(); // Remove is for bucket 1 - _distributor->handleMessage(cmd); + distributor_handle_message(cmd); // Should send to content node 0 - CPPUNIT_ASSERT_EQUAL(size_t(1), _sender.commands.size()); - CPPUNIT_ASSERT_EQUAL(api::MessageType::REMOVE, _sender.commands[0]->getType()); - auto& fwd_cmd = dynamic_cast<api::RemoveCommand&>(*_sender.commands[0]); + ASSERT_EQ(1, _sender.commands().size()); + ASSERT_EQ(api::MessageType::REMOVE, _sender.command(0)->getType()); + auto& fwd_cmd = dynamic_cast<api::RemoveCommand&>(*_sender.command(0)); auto reply = fwd_cmd.makeReply(); reply->setResult(api::ReturnCode(api::ReturnCode::BUSY)); _distributor->handleReply(std::shared_ptr<api::StorageReply>(std::move(reply))); auto& node_info = _distributor->getPendingMessageTracker().getNodeInfo(); - CPPUNIT_ASSERT(node_info.isBusy(0)); + EXPECT_TRUE(node_info.isBusy(0)); getClock().addSecondsToTime(99); - CPPUNIT_ASSERT(node_info.isBusy(0)); + EXPECT_TRUE(node_info.isBusy(0)); getClock().addSecondsToTime(2); - CPPUNIT_ASSERT(!node_info.isBusy(0)); + EXPECT_FALSE(node_info.isBusy(0)); } -void Distributor_Test::external_client_requests_are_handled_individually_in_priority_order() { +TEST_F(DistributorTest, external_client_requests_are_handled_individually_in_priority_order) { setupDistributor(Redundancy(1), NodeCount(1), "storage:1 distributor:1"); addNodesToBucketDB(document::BucketId(16, 1), "0=1/1/1/t/a"); @@ -950,18 +811,18 @@ void Distributor_Test::external_client_requests_are_handled_individually_in_prio // For each tick, a priority-order client request is processed and sent off. for (size_t i = 1; i <= priorities.size(); ++i) { tickDistributorNTimes(1); - CPPUNIT_ASSERT_EQUAL(size_t(i), _sender.commands.size()); + ASSERT_EQ(i, _sender.commands().size()); } std::vector<int> expected({0, 10, 40, 50, 255}); std::vector<int> actual; - for (auto& msg : _sender.commands) { + for (auto& msg : _sender.commands()) { actual.emplace_back(static_cast<int>(msg->getPriority())); } - CPPUNIT_ASSERT_EQUAL(expected, actual); + EXPECT_THAT(actual, ContainerEq(expected)); } -void Distributor_Test::internal_messages_are_started_in_fifo_order_batch() { +TEST_F(DistributorTest, internal_messages_are_started_in_fifo_order_batch) { // To test internal request ordering, we use NotifyBucketChangeCommand // for the reason that it explicitly updates the bucket database for // each individual invocation. @@ -980,16 +841,16 @@ void Distributor_Test::internal_messages_are_started_in_fifo_order_batch() { // Doing a single tick should process all internal requests in one batch tickDistributorNTimes(1); - CPPUNIT_ASSERT_EQUAL(size_t(5), _sender.replies.size()); + ASSERT_EQ(5, _sender.replies().size()); // The bucket info for priority 1 (last FIFO-order change command received, but // highest priority) should be the end-state of the bucket database, _not_ that // of lowest priority 255. BucketDatabase::Entry e(getBucket(bucket)); - CPPUNIT_ASSERT_EQUAL(api::BucketInfo(1, 1, 1), e.getBucketInfo().getNode(0)->getBucketInfo()); + EXPECT_EQ(api::BucketInfo(1, 1, 1), e.getBucketInfo().getNode(0)->getBucketInfo()); } -void Distributor_Test::closing_aborts_priority_queued_client_requests() { +TEST_F(DistributorTest, closing_aborts_priority_queued_client_requests) { setupDistributor(Redundancy(1), NodeCount(1), "storage:1 distributor:1"); document::BucketId bucket(16, 1); addNodesToBucketDB(bucket, "0=1/1/1/t"); @@ -1003,10 +864,9 @@ void Distributor_Test::closing_aborts_priority_queued_client_requests() { tickDistributorNTimes(1); // Closing should trigger 1 abort via startet GetOperation and 9 aborts from pri queue _distributor->close(); - CPPUNIT_ASSERT_EQUAL(size_t(10), _sender.replies.size()); - for (auto& msg : _sender.replies) { - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::ABORTED, - dynamic_cast<api::StorageReply&>(*msg).getResult().getResult()); + ASSERT_EQ(10, _sender.replies().size()); + for (auto& msg : _sender.replies()) { + EXPECT_EQ(api::ReturnCode::ABORTED, dynamic_cast<api::StorageReply&>(*msg).getResult().getResult()); } } @@ -1016,19 +876,19 @@ void assert_invalid_stats_for_all_spaces( const BucketSpacesStatsProvider::PerNodeBucketSpacesStats& stats, uint16_t node_index) { auto stats_iter = stats.find(node_index); - CPPUNIT_ASSERT(stats_iter != stats.cend()); - CPPUNIT_ASSERT_EQUAL(size_t(2), stats_iter->second.size()); + ASSERT_TRUE(stats_iter != stats.cend()); + ASSERT_EQ(2, stats_iter->second.size()); auto space_iter = stats_iter->second.find(document::FixedBucketSpaces::default_space_name()); - CPPUNIT_ASSERT(space_iter != stats_iter->second.cend()); - CPPUNIT_ASSERT(!space_iter->second.valid()); + ASSERT_TRUE(space_iter != stats_iter->second.cend()); + ASSERT_FALSE(space_iter->second.valid()); space_iter = stats_iter->second.find(document::FixedBucketSpaces::global_space_name()); - CPPUNIT_ASSERT(space_iter != stats_iter->second.cend()); - CPPUNIT_ASSERT(!space_iter->second.valid()); + ASSERT_TRUE(space_iter != stats_iter->second.cend()); + ASSERT_FALSE(space_iter->second.valid()); } } -void Distributor_Test::entering_recovery_mode_resets_bucket_space_stats() { +TEST_F(DistributorTest, entering_recovery_mode_resets_bucket_space_stats) { // Set up a cluster state + DB contents which implies merge maintenance ops setupDistributor(Redundancy(2), NodeCount(2), "version:1 distributor:1 storage:2"); addNodesToBucketDB(document::BucketId(16, 1), "0=1/1/1/t/a"); @@ -1038,82 +898,80 @@ void Distributor_Test::entering_recovery_mode_resets_bucket_space_stats() { tickDistributorNTimes(5); // 1/3rds into second round through database enableDistributorClusterState("version:2 distributor:1 storage:3 .1.s:d"); - CPPUNIT_ASSERT(_distributor->isInRecoveryMode()); + EXPECT_TRUE(_distributor->isInRecoveryMode()); // Bucket space stats should now be invalid per space per node, pending stats // from state version 2. Exposing stats from version 1 risks reporting stale // information back to the cluster controller. - const auto stats = _distributor->getBucketSpacesStats(); - CPPUNIT_ASSERT_EQUAL(size_t(2), stats.size()); + const auto stats = distributor_bucket_spaces_stats(); + ASSERT_EQ(2, stats.size()); assert_invalid_stats_for_all_spaces(stats, 0); assert_invalid_stats_for_all_spaces(stats, 2); } -void Distributor_Test::leaving_recovery_mode_immediately_sends_getnodestate_replies() { +TEST_F(DistributorTest, leaving_recovery_mode_immediately_sends_getnodestate_replies) { setupDistributor(Redundancy(2), NodeCount(2), "version:1 distributor:1 storage:2"); // Should not send explicit replies during init stage - CPPUNIT_ASSERT_EQUAL(size_t(0), explicit_node_state_reply_send_invocations()); + ASSERT_EQ(0, explicit_node_state_reply_send_invocations()); // Add a couple of buckets so we have something to iterate over addNodesToBucketDB(document::BucketId(16, 1), "0=1/1/1/t/a"); addNodesToBucketDB(document::BucketId(16, 2), "0=1/1/1/t/a"); enableDistributorClusterState("version:2 distributor:1 storage:3 .1.s:d"); - CPPUNIT_ASSERT(_distributor->isInRecoveryMode()); - CPPUNIT_ASSERT_EQUAL(size_t(0), explicit_node_state_reply_send_invocations()); + EXPECT_TRUE(_distributor->isInRecoveryMode()); + EXPECT_EQ(0, explicit_node_state_reply_send_invocations()); tickDistributorNTimes(1); // DB round not yet complete - CPPUNIT_ASSERT_EQUAL(size_t(0), explicit_node_state_reply_send_invocations()); + EXPECT_EQ(0, explicit_node_state_reply_send_invocations()); tickDistributorNTimes(2); // DB round complete after 2nd bucket + "scan done" discovery tick - CPPUNIT_ASSERT_EQUAL(size_t(1), explicit_node_state_reply_send_invocations()); - CPPUNIT_ASSERT(!_distributor->isInRecoveryMode()); + EXPECT_EQ(1, explicit_node_state_reply_send_invocations()); + EXPECT_FALSE(_distributor->isInRecoveryMode()); // Now out of recovery mode, subsequent round completions should not send replies tickDistributorNTimes(10); - CPPUNIT_ASSERT_EQUAL(size_t(1), explicit_node_state_reply_send_invocations()); + EXPECT_EQ(1, explicit_node_state_reply_send_invocations()); } -void Distributor_Test::do_test_pending_merge_getnodestate_reply_edge(BucketSpace space) { +void DistributorTest::do_test_pending_merge_getnodestate_reply_edge(BucketSpace space) { setupDistributor(Redundancy(2), NodeCount(2), "version:1 distributor:1 storage:2"); - CPPUNIT_ASSERT(_distributor->isInRecoveryMode()); + EXPECT_TRUE(_distributor->isInRecoveryMode()); // 2 buckets with missing replicas triggering merge pending stats addNodesToBucketDB(Bucket(space, BucketId(16, 1)), "0=1/1/1/t/a"); addNodesToBucketDB(Bucket(space, BucketId(16, 2)), "0=1/1/1/t/a"); tickDistributorNTimes(3); - CPPUNIT_ASSERT(!_distributor->isInRecoveryMode()); + EXPECT_FALSE(_distributor->isInRecoveryMode()); const auto space_name = FixedBucketSpaces::to_string(space); assertBucketSpaceStats(2, 0, 1, space_name, _distributor->getBucketSpacesStats()); // First completed scan sends off merge stats et al to cluster controller - CPPUNIT_ASSERT_EQUAL(size_t(1), explicit_node_state_reply_send_invocations()); + EXPECT_EQ(1, explicit_node_state_reply_send_invocations()); // Edge not triggered when 1 bucket with missing replica left addNodesToBucketDB(Bucket(space, BucketId(16, 1)), "0=1/1/1/t/a,1=1/1/1/t"); tickDistributorNTimes(3); assertBucketSpaceStats(1, 1, 1, space_name, _distributor->getBucketSpacesStats()); - CPPUNIT_ASSERT_EQUAL(size_t(1), explicit_node_state_reply_send_invocations()); + EXPECT_EQ(1, explicit_node_state_reply_send_invocations()); // Edge triggered when no more buckets with requiring merge addNodesToBucketDB(Bucket(space, BucketId(16, 2)), "0=1/1/1/t/a,1=1/1/1/t"); tickDistributorNTimes(3); assertBucketSpaceStats(0, 2, 1, space_name, _distributor->getBucketSpacesStats()); - CPPUNIT_ASSERT_EQUAL(size_t(2), explicit_node_state_reply_send_invocations()); + EXPECT_EQ(2, explicit_node_state_reply_send_invocations()); // Should only send when edge happens, not in subsequent DB iterations tickDistributorNTimes(10); - CPPUNIT_ASSERT_EQUAL(size_t(2), explicit_node_state_reply_send_invocations()); + EXPECT_EQ(2, explicit_node_state_reply_send_invocations()); // Going back to merges pending should _not_ send a getnodestate reply (at least for now) addNodesToBucketDB(Bucket(space, BucketId(16, 1)), "0=1/1/1/t/a"); tickDistributorNTimes(3); assertBucketSpaceStats(1, 1, 1, space_name, _distributor->getBucketSpacesStats()); - CPPUNIT_ASSERT_EQUAL(size_t(2), explicit_node_state_reply_send_invocations()); + EXPECT_EQ(2, explicit_node_state_reply_send_invocations()); } -void Distributor_Test::pending_to_no_pending_default_merges_edge_immediately_sends_getnodestate_replies() { +TEST_F(DistributorTest, pending_to_no_pending_default_merges_edge_immediately_sends_getnodestate_replies) { do_test_pending_merge_getnodestate_reply_edge(FixedBucketSpaces::default_space()); } -void Distributor_Test::pending_to_no_pending_global_merges_edge_immediately_sends_getnodestate_replies() { +TEST_F(DistributorTest, pending_to_no_pending_global_merges_edge_immediately_sends_getnodestate_replies) { do_test_pending_merge_getnodestate_reply_edge(FixedBucketSpaces::global_space()); } } - -} diff --git a/storage/src/tests/distributor/distributortestutil.cpp b/storage/src/tests/distributor/distributortestutil.cpp index 3f7f2eac63a..91af37e0f30 100644 --- a/storage/src/tests/distributor/distributortestutil.cpp +++ b/storage/src/tests/distributor/distributortestutil.cpp @@ -295,11 +295,11 @@ DistributorTestUtil::sendReply(Operation& op, api::ReturnCode::Result result) { if (idx == -1) { - idx = _sender.commands.size() - 1; + idx = _sender.commands().size() - 1; } - assert(idx >= 0 && idx < static_cast<int>(_sender.commands.size())); + assert(idx >= 0 && idx < static_cast<int>(_sender.commands().size())); - std::shared_ptr<api::StorageCommand> cmd = _sender.commands[idx]; + std::shared_ptr<api::StorageCommand> cmd = _sender.command(idx); api::StorageReply::SP reply(cmd->makeReply().release()); reply->setResult(result); op.receive(_sender, reply); diff --git a/storage/src/tests/distributor/distributortestutil.h b/storage/src/tests/distributor/distributortestutil.h index 420111437d2..3dc71bcb433 100644 --- a/storage/src/tests/distributor/distributortestutil.h +++ b/storage/src/tests/distributor/distributortestutil.h @@ -1,7 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include "messagesenderstub.h" +#include "distributor_message_sender_stub.h" #include <tests/common/teststorageapp.h> #include <tests/common/testhelper.h> #include <tests/common/dummystoragelink.h> @@ -181,14 +181,14 @@ protected: std::unique_ptr<framework::TickingThreadPool> _threadPool; std::unique_ptr<Distributor> _distributor; std::unique_ptr<storage::DistributorComponent> _component; - MessageSenderStub _sender; - MessageSenderStub _senderDown; + DistributorMessageSenderStub _sender; + DistributorMessageSenderStub _senderDown; HostInfo _hostInfo; struct MessageSenderImpl : public ChainedMessageSender { - MessageSenderStub& _sender; - MessageSenderStub& _senderDown; - MessageSenderImpl(MessageSenderStub& up, MessageSenderStub& down) + DistributorMessageSenderStub& _sender; + DistributorMessageSenderStub& _senderDown; + MessageSenderImpl(DistributorMessageSenderStub& up, DistributorMessageSenderStub& down) : _sender(up), _senderDown(down) {} void sendUp(const std::shared_ptr<api::StorageMessage>& msg) override { diff --git a/storage/src/tests/distributor/externaloperationhandlertest.cpp b/storage/src/tests/distributor/externaloperationhandlertest.cpp index 40fe885dcb1..88e133cc010 100644 --- a/storage/src/tests/distributor/externaloperationhandlertest.cpp +++ b/storage/src/tests/distributor/externaloperationhandlertest.cpp @@ -9,43 +9,17 @@ #include <vespa/document/repo/documenttyperepo.h> #include <vespa/document/update/documentupdate.h> #include <vespa/document/test/make_document_bucket.h> +#include <vespa/vespalib/gtest/gtest.h> using document::test::makeDocumentBucket; +using document::DocumentId; +using namespace ::testing; namespace storage::distributor { -class ExternalOperationHandlerTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ +struct ExternalOperationHandlerTest : Test, DistributorTestUtil { document::TestDocMan _testDocMan; - CPPUNIT_TEST_SUITE(ExternalOperationHandlerTest); - CPPUNIT_TEST(testBucketSplitMask); - CPPUNIT_TEST(mutating_operation_wdr_bounced_on_wrong_current_distribution); - CPPUNIT_TEST(mutating_operation_busy_bounced_on_wrong_pending_distribution); - CPPUNIT_TEST(mutating_operation_busy_bounced_if_no_cluster_state_received_yet); - CPPUNIT_TEST(read_only_operation_wdr_bounced_on_wrong_current_distribution); - CPPUNIT_TEST(read_only_operation_busy_bounced_if_no_cluster_state_received_yet); - CPPUNIT_TEST(reject_put_if_not_past_safe_time_point); - CPPUNIT_TEST(reject_remove_if_not_past_safe_time_point); - CPPUNIT_TEST(reject_update_if_not_past_safe_time_point); - CPPUNIT_TEST(get_not_rejected_by_unsafe_time_point); - CPPUNIT_TEST(mutation_not_rejected_when_safe_point_reached); - CPPUNIT_TEST(reject_put_with_concurrent_mutation_to_same_id); - CPPUNIT_TEST(do_not_reject_put_operations_to_different_ids); - CPPUNIT_TEST(reject_remove_with_concurrent_mutation_to_same_id); - CPPUNIT_TEST(do_not_reject_remove_operations_to_different_ids); - CPPUNIT_TEST(reject_update_with_concurrent_mutation_to_same_id); - CPPUNIT_TEST(do_not_reject_update_operations_to_different_ids); - CPPUNIT_TEST(operation_destruction_allows_new_mutations_for_id); - CPPUNIT_TEST(concurrent_get_and_mutation_do_not_conflict); - CPPUNIT_TEST(sequencing_works_across_mutation_types); - CPPUNIT_TEST(sequencing_can_be_explicitly_config_disabled); - CPPUNIT_TEST(gets_are_started_with_mutable_db_outside_transition_period); - CPPUNIT_TEST(gets_are_started_with_read_only_db_during_transition_period); - CPPUNIT_TEST(gets_are_busy_bounced_during_transition_period_if_stale_reads_disabled); - CPPUNIT_TEST_SUITE_END(); - document::BucketId findNonOwnedUserBucketInState(vespalib::stringref state); document::BucketId findOwned1stNotOwned2ndInStates( vespalib::stringref state1, @@ -63,7 +37,8 @@ class ExternalOperationHandlerTest : public CppUnit::TestFixture, void verify_busy_bounced_due_to_no_active_state(std::shared_ptr<api::StorageCommand> cmd); - Operation::SP start_operation_verify_not_rejected(std::shared_ptr<api::StorageCommand> cmd); + void start_operation_verify_not_rejected(std::shared_ptr<api::StorageCommand> cmd, + Operation::SP& out_generated); void start_operation_verify_rejected(std::shared_ptr<api::StorageCommand> cmd); int64_t safe_time_not_reached_metric_count( @@ -93,32 +68,6 @@ class ExternalOperationHandlerTest : public CppUnit::TestFixture, // Returns an arbitrary bucket not owned in the pending state document::BucketId set_up_pending_cluster_state_transition(bool read_only_enabled); -protected: - void testBucketSplitMask(); - void mutating_operation_wdr_bounced_on_wrong_current_distribution(); - void mutating_operation_busy_bounced_on_wrong_pending_distribution(); - void mutating_operation_busy_bounced_if_no_cluster_state_received_yet(); - void read_only_operation_wdr_bounced_on_wrong_current_distribution(); - void read_only_operation_busy_bounced_if_no_cluster_state_received_yet(); - void reject_put_if_not_past_safe_time_point(); - void reject_remove_if_not_past_safe_time_point(); - void reject_update_if_not_past_safe_time_point(); - void get_not_rejected_by_unsafe_time_point(); - void mutation_not_rejected_when_safe_point_reached(); - void reject_put_with_concurrent_mutation_to_same_id(); - void do_not_reject_put_operations_to_different_ids(); - void reject_remove_with_concurrent_mutation_to_same_id(); - void do_not_reject_remove_operations_to_different_ids(); - void reject_update_with_concurrent_mutation_to_same_id(); - void do_not_reject_update_operations_to_different_ids(); - void operation_destruction_allows_new_mutations_for_id(); - void concurrent_get_and_mutation_do_not_conflict(); - void sequencing_works_across_mutation_types(); - void sequencing_can_be_explicitly_config_disabled(); - void gets_are_started_with_mutable_db_outside_transition_period(); - void gets_are_started_with_read_only_db_during_transition_period(); - void gets_are_busy_bounced_during_transition_period_if_stale_reads_disabled(); - void assert_rejection_due_to_unsafe_time( std::shared_ptr<api::StorageCommand> cmd); @@ -130,37 +79,30 @@ protected: std::shared_ptr<api::StorageCommand> cmd1, std::shared_ptr<api::StorageCommand> cmd2); -public: - void tearDown() override { + void TearDown() override { close(); } }; -CPPUNIT_TEST_SUITE_REGISTRATION(ExternalOperationHandlerTest); - -using document::DocumentId; - -void -ExternalOperationHandlerTest::testBucketSplitMask() -{ +TEST_F(ExternalOperationHandlerTest, bucket_split_mask) { { createLinks(); getDirConfig().getConfig("stor-distributormanager").set("minsplitcount", "16"); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0xffff), + EXPECT_EQ(document::BucketId(16, 0xffff), getExternalOperationHandler().getBucketId(document::DocumentId( vespalib::make_string("userdoc:ns:%d::", 0xffff)) ).stripUnused()); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0), + EXPECT_EQ(document::BucketId(16, 0), getExternalOperationHandler().getBucketId(document::DocumentId( vespalib::make_string("userdoc:ns:%d::", 0x10000)) ).stripUnused()); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0xffff), + EXPECT_EQ(document::BucketId(16, 0xffff), getExternalOperationHandler().getBucketId(document::DocumentId( vespalib::make_string("userdoc:ns:%d::", 0xffff)) ).stripUnused()); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0x100), + EXPECT_EQ(document::BucketId(16, 0x100), getExternalOperationHandler().getBucketId(document::DocumentId( vespalib::make_string("userdoc:ns:%d::", 0x100)) ).stripUnused()); @@ -169,11 +111,11 @@ ExternalOperationHandlerTest::testBucketSplitMask() { getDirConfig().getConfig("stor-distributormanager").set("minsplitcount", "20"); createLinks(); - CPPUNIT_ASSERT_EQUAL(document::BucketId(20, 0x11111), + EXPECT_EQ(document::BucketId(20, 0x11111), getExternalOperationHandler().getBucketId(document::DocumentId( vespalib::make_string("userdoc:ns:%d::", 0x111111)) ).stripUnused()); - CPPUNIT_ASSERT_EQUAL(document::BucketId(20, 0x22222), + EXPECT_EQ(document::BucketId(20, 0x22222), getExternalOperationHandler().getBucketId(document::DocumentId( vespalib::make_string("userdoc:ns:%d::", 0x222222)) ).stripUnused()); @@ -256,9 +198,7 @@ std::shared_ptr<api::RemoveCommand> ExternalOperationHandlerTest::makeRemoveComm return std::make_shared<api::RemoveCommand>(makeDocumentBucket(document::BucketId(0)), DocumentId(id), api::Timestamp(0)); } -void -ExternalOperationHandlerTest::mutating_operation_wdr_bounced_on_wrong_current_distribution() -{ +TEST_F(ExternalOperationHandlerTest, mutating_operation_wdr_bounced_on_wrong_current_distribution) { createLinks(); std::string state("version:1 distributor:2 storage:2"); setupDistributor(1, 2, state); @@ -267,18 +207,15 @@ ExternalOperationHandlerTest::mutating_operation_wdr_bounced_on_wrong_current_di auto cmd = makeUpdateCommandForUser(bucket.withoutCountBits()); Operation::SP genOp; - CPPUNIT_ASSERT(getExternalOperationHandler().handleMessage(cmd, genOp)); - CPPUNIT_ASSERT(!genOp.get()); - CPPUNIT_ASSERT_EQUAL(size_t(1), _sender.replies.size()); - CPPUNIT_ASSERT_EQUAL( - std::string("ReturnCode(WRONG_DISTRIBUTION, " - "version:1 distributor:2 storage:2)"), - _sender.replies[0]->getResult().toString()); + ASSERT_TRUE(getExternalOperationHandler().handleMessage(cmd, genOp)); + ASSERT_FALSE(genOp.get()); + ASSERT_EQ(1, _sender.replies().size()); + EXPECT_EQ("ReturnCode(WRONG_DISTRIBUTION, " + "version:1 distributor:2 storage:2)", + _sender.reply(0)->getResult().toString()); } -void -ExternalOperationHandlerTest::read_only_operation_wdr_bounced_on_wrong_current_distribution() -{ +TEST_F(ExternalOperationHandlerTest, read_only_operation_wdr_bounced_on_wrong_current_distribution) { createLinks(); std::string state("version:1 distributor:2 storage:2"); setupDistributor(1, 2, state); @@ -287,18 +224,15 @@ ExternalOperationHandlerTest::read_only_operation_wdr_bounced_on_wrong_current_d auto cmd = makeGetCommandForUser(bucket.withoutCountBits()); Operation::SP genOp; - CPPUNIT_ASSERT(getExternalOperationHandler().handleMessage(cmd, genOp)); - CPPUNIT_ASSERT(!genOp.get()); - CPPUNIT_ASSERT_EQUAL(size_t(1), _sender.replies.size()); - CPPUNIT_ASSERT_EQUAL( - std::string("ReturnCode(WRONG_DISTRIBUTION, " - "version:1 distributor:2 storage:2)"), - _sender.replies[0]->getResult().toString()); + ASSERT_TRUE(getExternalOperationHandler().handleMessage(cmd, genOp)); + ASSERT_FALSE(genOp.get()); + ASSERT_EQ(1, _sender.replies().size()); + EXPECT_EQ("ReturnCode(WRONG_DISTRIBUTION, " + "version:1 distributor:2 storage:2)", + _sender.reply(0)->getResult().toString()); } -void -ExternalOperationHandlerTest::mutating_operation_busy_bounced_on_wrong_pending_distribution() -{ +TEST_F(ExternalOperationHandlerTest, mutating_operation_busy_bounced_on_wrong_pending_distribution) { createLinks(); std::string current("version:10 distributor:2 storage:2"); std::string pending("version:11 distributor:3 storage:3"); @@ -313,12 +247,11 @@ ExternalOperationHandlerTest::mutating_operation_busy_bounced_on_wrong_pending_d auto cmd = makeUpdateCommandForUser(b.withoutCountBits()); Operation::SP genOp; - CPPUNIT_ASSERT(getExternalOperationHandler().handleMessage(cmd, genOp)); - CPPUNIT_ASSERT(!genOp.get()); - CPPUNIT_ASSERT_EQUAL(size_t(1), _sender.replies.size()); - CPPUNIT_ASSERT_EQUAL( - std::string("ReturnCode(BUSY, Currently pending cluster state transition from version 10 to 11)"), - _sender.replies[0]->getResult().toString()); + ASSERT_TRUE(getExternalOperationHandler().handleMessage(cmd, genOp)); + ASSERT_FALSE(genOp.get()); + ASSERT_EQ(1, _sender.replies().size()); + EXPECT_EQ("ReturnCode(BUSY, Currently pending cluster state transition from version 10 to 11)", + _sender.reply(0)->getResult().toString()); } void @@ -329,25 +262,20 @@ ExternalOperationHandlerTest::verify_busy_bounced_due_to_no_active_state(std::sh setupDistributor(1, 2, state); Operation::SP genOp; - CPPUNIT_ASSERT(getExternalOperationHandler().handleMessage(cmd, genOp)); - CPPUNIT_ASSERT(!genOp.get()); - CPPUNIT_ASSERT_EQUAL(size_t(1), _sender.replies.size()); - CPPUNIT_ASSERT_EQUAL( - std::string("ReturnCode(BUSY, No cluster state activated yet)"), - _sender.replies[0]->getResult().toString()); + ASSERT_TRUE(getExternalOperationHandler().handleMessage(cmd, genOp)); + ASSERT_FALSE(genOp.get()); + ASSERT_EQ(1, _sender.replies().size()); + EXPECT_EQ("ReturnCode(BUSY, No cluster state activated yet)", + _sender.reply(0)->getResult().toString()); } // TODO NOT_READY is a more appropriate return code for this case, but must ensure it's // handled gracefully and silently through the stack. BUSY is a safe bet until then. -void -ExternalOperationHandlerTest::mutating_operation_busy_bounced_if_no_cluster_state_received_yet() -{ +TEST_F(ExternalOperationHandlerTest, mutating_operation_busy_bounced_if_no_cluster_state_received_yet) { verify_busy_bounced_due_to_no_active_state(makeUpdateCommandForUser(12345)); } -void -ExternalOperationHandlerTest::read_only_operation_busy_bounced_if_no_cluster_state_received_yet() -{ +TEST_F(ExternalOperationHandlerTest, read_only_operation_busy_bounced_if_no_cluster_state_received_yet) { verify_busy_bounced_due_to_no_active_state(makeGetCommandForUser(12345)); } @@ -364,34 +292,30 @@ void ExternalOperationHandlerTest::assert_rejection_due_to_unsafe_time( Operation::SP generated; getExternalOperationHandler().handleMessage(cmd, generated); - CPPUNIT_ASSERT(generated.get() == nullptr); - CPPUNIT_ASSERT_EQUAL(size_t(1), _sender.replies.size()); - CPPUNIT_ASSERT_EQUAL( - std::string("ReturnCode(STALE_TIMESTAMP, " - "Operation received at time 9, which is before " - "bucket ownership transfer safe time of 10)"), - _sender.replies[0]->getResult().toString()); + ASSERT_EQ(generated.get(), nullptr); + ASSERT_EQ(1, _sender.replies().size()); + EXPECT_EQ("ReturnCode(STALE_TIMESTAMP, " + "Operation received at time 9, which is before " + "bucket ownership transfer safe time of 10)", + _sender.reply(0)->getResult().toString()); } -void ExternalOperationHandlerTest::reject_put_if_not_past_safe_time_point() { +TEST_F(ExternalOperationHandlerTest, reject_put_if_not_past_safe_time_point) { assert_rejection_due_to_unsafe_time(makePutCommand("foo", "id:foo:testdoctype1::bar")); - CPPUNIT_ASSERT_EQUAL(int64_t(1), safe_time_not_reached_metric_count( - getDistributor().getMetrics().puts)); + EXPECT_EQ(1, safe_time_not_reached_metric_count(getDistributor().getMetrics().puts)); } -void ExternalOperationHandlerTest::reject_remove_if_not_past_safe_time_point() { +TEST_F(ExternalOperationHandlerTest, reject_remove_if_not_past_safe_time_point) { assert_rejection_due_to_unsafe_time(makeRemoveCommand("id:foo:testdoctype1::bar")); - CPPUNIT_ASSERT_EQUAL(int64_t(1), safe_time_not_reached_metric_count( - getDistributor().getMetrics().removes)); + EXPECT_EQ(1, safe_time_not_reached_metric_count(getDistributor().getMetrics().removes)); } -void ExternalOperationHandlerTest::reject_update_if_not_past_safe_time_point() { +TEST_F(ExternalOperationHandlerTest, reject_update_if_not_past_safe_time_point) { assert_rejection_due_to_unsafe_time(makeUpdateCommand()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), safe_time_not_reached_metric_count( - getDistributor().getMetrics().updates)); + EXPECT_EQ(1, safe_time_not_reached_metric_count(getDistributor().getMetrics().updates)); } -void ExternalOperationHandlerTest::get_not_rejected_by_unsafe_time_point() { +TEST_F(ExternalOperationHandlerTest, get_not_rejected_by_unsafe_time_point) { createLinks(); setupDistributor(1, 2, "version:1 distributor:1 storage:1"); getClock().setAbsoluteTimeInSeconds(9); @@ -400,13 +324,12 @@ void ExternalOperationHandlerTest::get_not_rejected_by_unsafe_time_point() { Operation::SP generated; getExternalOperationHandler().handleMessage( makeGetCommandForUser(0), generated); - CPPUNIT_ASSERT(generated.get() != nullptr); - CPPUNIT_ASSERT_EQUAL(size_t(0), _sender.replies.size()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), safe_time_not_reached_metric_count( - getDistributor().getMetrics().gets)); + ASSERT_NE(generated.get(), nullptr); + ASSERT_EQ(0, _sender.replies().size()); + EXPECT_EQ(0, safe_time_not_reached_metric_count(getDistributor().getMetrics().gets)); } -void ExternalOperationHandlerTest::mutation_not_rejected_when_safe_point_reached() { +TEST_F(ExternalOperationHandlerTest, mutation_not_rejected_when_safe_point_reached) { createLinks(); setupDistributor(1, 2, "version:1 distributor:1 storage:1"); getClock().setAbsoluteTimeInSeconds(10); @@ -418,10 +341,9 @@ void ExternalOperationHandlerTest::mutation_not_rejected_when_safe_point_reached std::make_shared<api::RemoveCommand>( makeDocumentBucket(document::BucketId(0)), id, api::Timestamp(0)), generated); - CPPUNIT_ASSERT(generated.get() != nullptr); - CPPUNIT_ASSERT_EQUAL(size_t(0), _sender.replies.size()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), safe_time_not_reached_metric_count( - getDistributor().getMetrics().removes)); + ASSERT_NE(generated.get(), nullptr); + ASSERT_EQ(0, _sender.replies().size()); + EXPECT_EQ(0, safe_time_not_reached_metric_count(getDistributor().getMetrics().removes)); } void ExternalOperationHandlerTest::set_up_distributor_for_sequencing_test() { @@ -429,22 +351,24 @@ void ExternalOperationHandlerTest::set_up_distributor_for_sequencing_test() { setupDistributor(1, 2, "version:1 distributor:1 storage:1"); } -Operation::SP ExternalOperationHandlerTest::start_operation_verify_not_rejected( - std::shared_ptr<api::StorageCommand> cmd) { +void ExternalOperationHandlerTest::start_operation_verify_not_rejected( + std::shared_ptr<api::StorageCommand> cmd, + Operation::SP& out_generated) +{ Operation::SP generated; - _sender.replies.clear(); + _sender.replies().clear(); getExternalOperationHandler().handleMessage(cmd, generated); - CPPUNIT_ASSERT(generated.get() != nullptr); - CPPUNIT_ASSERT_EQUAL(size_t(0), _sender.replies.size()); - return generated; + ASSERT_NE(generated.get(), nullptr); + ASSERT_EQ(0, _sender.replies().size()); + out_generated = std::move(generated); } void ExternalOperationHandlerTest::start_operation_verify_rejected( std::shared_ptr<api::StorageCommand> cmd) { Operation::SP generated; - _sender.replies.clear(); + _sender.replies().clear(); getExternalOperationHandler().handleMessage(cmd, generated); - CPPUNIT_ASSERT(generated.get() == nullptr); - CPPUNIT_ASSERT_EQUAL(size_t(1), _sender.replies.size()); + ASSERT_EQ(generated.get(), nullptr); + ASSERT_EQ(1, _sender.replies().size()); } void ExternalOperationHandlerTest::assert_second_command_rejected_due_to_concurrent_mutation( @@ -454,15 +378,15 @@ void ExternalOperationHandlerTest::assert_second_command_rejected_due_to_concurr set_up_distributor_for_sequencing_test(); // Must hold ref to started operation, or sequencing handle will be released. - Operation::SP generated1 = start_operation_verify_not_rejected(std::move(cmd1)); - start_operation_verify_rejected(std::move(cmd2)); + Operation::SP generated1; + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected(std::move(cmd1), generated1)); + ASSERT_NO_FATAL_FAILURE(start_operation_verify_rejected(std::move(cmd2))); // TODO reconsider BUSY return code. Need something transient and non-noisy - CPPUNIT_ASSERT_EQUAL( - std::string(vespalib::make_string( + EXPECT_EQ(vespalib::make_string( "ReturnCode(BUSY, A mutating operation for document " - "'%s' is already in progress)", expected_id_in_message.c_str())), - _sender.replies[0]->getResult().toString()); + "'%s' is already in progress)", expected_id_in_message.c_str()), + _sender.reply(0)->getResult().toString()); } void ExternalOperationHandlerTest::assert_second_command_not_rejected_due_to_concurrent_mutation( @@ -470,89 +394,97 @@ void ExternalOperationHandlerTest::assert_second_command_not_rejected_due_to_con std::shared_ptr<api::StorageCommand> cmd2) { set_up_distributor_for_sequencing_test(); - Operation::SP generated1 = start_operation_verify_not_rejected(std::move(cmd1)); - start_operation_verify_not_rejected(std::move(cmd2)); + Operation::SP generated1; + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected(std::move(cmd1), generated1)); + Operation::SP generated2; + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected(std::move(cmd2), generated2)); } -void ExternalOperationHandlerTest::reject_put_with_concurrent_mutation_to_same_id() { - assert_second_command_rejected_due_to_concurrent_mutation( +TEST_F(ExternalOperationHandlerTest, reject_put_with_concurrent_mutation_to_same_id) { + ASSERT_NO_FATAL_FAILURE(assert_second_command_rejected_due_to_concurrent_mutation( makePutCommand("testdoctype1", _dummy_id), - makePutCommand("testdoctype1", _dummy_id), _dummy_id); - CPPUNIT_ASSERT_EQUAL(int64_t(1), concurrent_mutatations_metric_count(getDistributor().getMetrics().puts)); + makePutCommand("testdoctype1", _dummy_id), _dummy_id)); + EXPECT_EQ(1, concurrent_mutatations_metric_count(getDistributor().getMetrics().puts)); } -void ExternalOperationHandlerTest::do_not_reject_put_operations_to_different_ids() { - assert_second_command_not_rejected_due_to_concurrent_mutation( +TEST_F(ExternalOperationHandlerTest, do_not_reject_put_operations_to_different_ids) { + ASSERT_NO_FATAL_FAILURE(assert_second_command_not_rejected_due_to_concurrent_mutation( makePutCommand("testdoctype1", "id:foo:testdoctype1::baz"), - makePutCommand("testdoctype1", "id:foo:testdoctype1::foo")); - CPPUNIT_ASSERT_EQUAL(int64_t(0), concurrent_mutatations_metric_count(getDistributor().getMetrics().puts)); + makePutCommand("testdoctype1", "id:foo:testdoctype1::foo"))); + EXPECT_EQ(0, concurrent_mutatations_metric_count(getDistributor().getMetrics().puts)); } -void ExternalOperationHandlerTest::reject_remove_with_concurrent_mutation_to_same_id() { - assert_second_command_rejected_due_to_concurrent_mutation( - makeRemoveCommand(_dummy_id), makeRemoveCommand(_dummy_id), _dummy_id); - CPPUNIT_ASSERT_EQUAL(int64_t(1), concurrent_mutatations_metric_count(getDistributor().getMetrics().removes)); +TEST_F(ExternalOperationHandlerTest, reject_remove_with_concurrent_mutation_to_same_id) { + ASSERT_NO_FATAL_FAILURE(assert_second_command_rejected_due_to_concurrent_mutation( + makeRemoveCommand(_dummy_id), makeRemoveCommand(_dummy_id), _dummy_id)); + EXPECT_EQ(1, concurrent_mutatations_metric_count(getDistributor().getMetrics().removes)); } -void ExternalOperationHandlerTest::do_not_reject_remove_operations_to_different_ids() { - assert_second_command_not_rejected_due_to_concurrent_mutation( +TEST_F(ExternalOperationHandlerTest, do_not_reject_remove_operations_to_different_ids) { + ASSERT_NO_FATAL_FAILURE(assert_second_command_not_rejected_due_to_concurrent_mutation( makeRemoveCommand("id:foo:testdoctype1::baz"), - makeRemoveCommand("id:foo:testdoctype1::foo")); - CPPUNIT_ASSERT_EQUAL(int64_t(0), concurrent_mutatations_metric_count(getDistributor().getMetrics().removes)); + makeRemoveCommand("id:foo:testdoctype1::foo"))); + EXPECT_EQ(0, concurrent_mutatations_metric_count(getDistributor().getMetrics().removes)); } -void ExternalOperationHandlerTest::reject_update_with_concurrent_mutation_to_same_id() { - assert_second_command_rejected_due_to_concurrent_mutation( +TEST_F(ExternalOperationHandlerTest, reject_update_with_concurrent_mutation_to_same_id) { + ASSERT_NO_FATAL_FAILURE(assert_second_command_rejected_due_to_concurrent_mutation( makeUpdateCommand("testdoctype1", _dummy_id), - makeUpdateCommand("testdoctype1", _dummy_id), _dummy_id); - CPPUNIT_ASSERT_EQUAL(int64_t(1), concurrent_mutatations_metric_count(getDistributor().getMetrics().updates)); + makeUpdateCommand("testdoctype1", _dummy_id), _dummy_id)); + EXPECT_EQ(1, concurrent_mutatations_metric_count(getDistributor().getMetrics().updates)); } -void ExternalOperationHandlerTest::do_not_reject_update_operations_to_different_ids() { - assert_second_command_not_rejected_due_to_concurrent_mutation( +TEST_F(ExternalOperationHandlerTest, do_not_reject_update_operations_to_different_ids) { + ASSERT_NO_FATAL_FAILURE(assert_second_command_not_rejected_due_to_concurrent_mutation( makeUpdateCommand("testdoctype1", "id:foo:testdoctype1::baz"), - makeUpdateCommand("testdoctype1", "id:foo:testdoctype1::foo")); - CPPUNIT_ASSERT_EQUAL(int64_t(0), concurrent_mutatations_metric_count(getDistributor().getMetrics().updates)); + makeUpdateCommand("testdoctype1", "id:foo:testdoctype1::foo"))); + EXPECT_EQ(0, concurrent_mutatations_metric_count(getDistributor().getMetrics().updates)); } -void ExternalOperationHandlerTest::operation_destruction_allows_new_mutations_for_id() { +TEST_F(ExternalOperationHandlerTest, operation_destruction_allows_new_mutations_for_id) { set_up_distributor_for_sequencing_test(); - Operation::SP generated = start_operation_verify_not_rejected(makeRemoveCommand(_dummy_id)); + Operation::SP generated; + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected(makeRemoveCommand(_dummy_id), generated)); generated.reset(); // Implicitly release sequencing handle - start_operation_verify_not_rejected(makeRemoveCommand(_dummy_id)); + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected(makeRemoveCommand(_dummy_id), generated)); } -void ExternalOperationHandlerTest::concurrent_get_and_mutation_do_not_conflict() { +TEST_F(ExternalOperationHandlerTest, concurrent_get_and_mutation_do_not_conflict) { set_up_distributor_for_sequencing_test(); - Operation::SP generated1 = start_operation_verify_not_rejected(makeRemoveCommand(_dummy_id)); + Operation::SP generated1; + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected(makeRemoveCommand(_dummy_id), generated1)); - start_operation_verify_not_rejected(makeGetCommand(_dummy_id)); + Operation::SP generated2; + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected(makeGetCommand(_dummy_id), generated2)); } -void ExternalOperationHandlerTest::sequencing_works_across_mutation_types() { +TEST_F(ExternalOperationHandlerTest, sequencing_works_across_mutation_types) { set_up_distributor_for_sequencing_test(); - Operation::SP generated = start_operation_verify_not_rejected(makePutCommand("testdoctype1", _dummy_id)); - start_operation_verify_rejected(makeRemoveCommand(_dummy_id)); - start_operation_verify_rejected(makeUpdateCommand("testdoctype1", _dummy_id)); + Operation::SP generated; + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected(makePutCommand("testdoctype1", _dummy_id), generated)); + ASSERT_NO_FATAL_FAILURE(start_operation_verify_rejected(makeRemoveCommand(_dummy_id))); + ASSERT_NO_FATAL_FAILURE(start_operation_verify_rejected(makeUpdateCommand("testdoctype1", _dummy_id))); } -void ExternalOperationHandlerTest::sequencing_can_be_explicitly_config_disabled() { +TEST_F(ExternalOperationHandlerTest, sequencing_can_be_explicitly_config_disabled) { set_up_distributor_for_sequencing_test(); // Should be able to modify config after links have been created, i.e. this is a live config. getConfig().setSequenceMutatingOperations(false); - Operation::SP generated = start_operation_verify_not_rejected(makeRemoveCommand(_dummy_id)); + Operation::SP generated1; + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected(makeRemoveCommand(_dummy_id), generated1)); // Sequencing is disabled, so concurrent op is not rejected. - start_operation_verify_not_rejected(makeRemoveCommand(_dummy_id)); + Operation::SP generated2; + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected(makeRemoveCommand(_dummy_id), generated2)); } -void ExternalOperationHandlerTest::gets_are_started_with_mutable_db_outside_transition_period() { +TEST_F(ExternalOperationHandlerTest, gets_are_started_with_mutable_db_outside_transition_period) { createLinks(); std::string current = "version:1 distributor:1 storage:3"; setupDistributor(1, 3, current); @@ -560,10 +492,12 @@ void ExternalOperationHandlerTest::gets_are_started_with_mutable_db_outside_tran document::BucketId b(16, 1234); // Only 1 distributor (us), so doesn't matter - auto op = start_operation_verify_not_rejected(makeGetCommandForUser(b.withoutCountBits())); + Operation::SP op; + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected( + makeGetCommandForUser(b.withoutCountBits()), op)); auto& get_op = dynamic_cast<GetOperation&>(*op); const auto* expected_space = &getBucketSpaceRepo().get(document::FixedBucketSpaces::default_space()); - CPPUNIT_ASSERT_EQUAL(expected_space, &get_op.bucketSpace()); + EXPECT_EQ(expected_space, &get_op.bucketSpace()); } document::BucketId ExternalOperationHandlerTest::set_up_pending_cluster_state_transition(bool read_only_enabled) { @@ -579,22 +513,24 @@ document::BucketId ExternalOperationHandlerTest::set_up_pending_cluster_state_tr return findOwned1stNotOwned2ndInStates(current, pending); } -void ExternalOperationHandlerTest::gets_are_started_with_read_only_db_during_transition_period() { +TEST_F(ExternalOperationHandlerTest, gets_are_started_with_read_only_db_during_transition_period) { auto non_owned_bucket = set_up_pending_cluster_state_transition(true); - auto op = start_operation_verify_not_rejected(makeGetCommandForUser(non_owned_bucket.withoutCountBits())); + Operation::SP op; + ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected( + makeGetCommandForUser(non_owned_bucket.withoutCountBits()), op)); auto& get_op = dynamic_cast<GetOperation&>(*op); const auto* expected_space = &getReadOnlyBucketSpaceRepo().get(document::FixedBucketSpaces::default_space()); - CPPUNIT_ASSERT_EQUAL(expected_space, &get_op.bucketSpace()); + EXPECT_EQ(expected_space, &get_op.bucketSpace()); } -void ExternalOperationHandlerTest::gets_are_busy_bounced_during_transition_period_if_stale_reads_disabled() { +TEST_F(ExternalOperationHandlerTest, gets_are_busy_bounced_during_transition_period_if_stale_reads_disabled) { auto non_owned_bucket = set_up_pending_cluster_state_transition(false); - start_operation_verify_rejected(makeGetCommandForUser(non_owned_bucket.withoutCountBits())); - CPPUNIT_ASSERT_EQUAL( - std::string("ReturnCode(BUSY, Currently pending cluster state transition from version 123 to 321)"), - _sender.replies[0]->getResult().toString()); + ASSERT_NO_FATAL_FAILURE(start_operation_verify_rejected( + makeGetCommandForUser(non_owned_bucket.withoutCountBits()))); + EXPECT_EQ("ReturnCode(BUSY, Currently pending cluster state transition from version 123 to 321)", + _sender.reply(0)->getResult().toString()); } diff --git a/storage/src/tests/distributor/garbagecollectiontest.cpp b/storage/src/tests/distributor/garbagecollectiontest.cpp index e2a6bb84065..122a1452632 100644 --- a/storage/src/tests/distributor/garbagecollectiontest.cpp +++ b/storage/src/tests/distributor/garbagecollectiontest.cpp @@ -1,42 +1,29 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <cppunit/extensions/HelperMacros.h> #include <vespa/storageapi/message/removelocation.h> #include <vespa/storage/distributor/operations/idealstate/garbagecollectionoperation.h> #include <vespa/storage/distributor/idealstatemanager.h> #include <tests/distributor/distributortestutil.h> #include <vespa/storage/distributor/distributor.h> #include <vespa/document/test/make_document_bucket.h> +#include <vespa/vespalib/gtest/gtest.h> using document::test::makeDocumentBucket; +using namespace ::testing; -namespace storage { -namespace distributor { +namespace storage::distributor { -class GarbageCollectionOperationTest : public CppUnit::TestFixture, public DistributorTestUtil -{ - CPPUNIT_TEST_SUITE(GarbageCollectionOperationTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST_SUITE_END(); - -protected: - void testSimple(); - -public: - void setUp() override { +struct GarbageCollectionOperationTest : Test, DistributorTestUtil { + void SetUp() override { createLinks(); }; - void tearDown() override { + void TearDown() override { close(); } }; -CPPUNIT_TEST_SUITE_REGISTRATION(GarbageCollectionOperationTest); - -void -GarbageCollectionOperationTest::testSimple() -{ +TEST_F(GarbageCollectionOperationTest, simple) { enableDistributorClusterState("distributor:1 storage:2"); addNodesToBucketDB(document::BucketId(16, 1), "0=250/50/300,1=250/50/300"); getConfig().setGarbageCollection("music.date < 34", 3600); @@ -48,34 +35,30 @@ GarbageCollectionOperationTest::testSimple() op.setIdealStateManager(&getIdealStateManager()); op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL((size_t)2, _sender.commands.size()); + ASSERT_EQ(2, _sender.commands().size()); getClock().setAbsoluteTimeInSeconds(34); for (uint32_t i = 0; i < 2; ++i) { - std::shared_ptr<api::StorageCommand> msg = _sender.commands[i]; - CPPUNIT_ASSERT(msg->getType() == api::MessageType::REMOVELOCATION); + std::shared_ptr<api::StorageCommand> msg = _sender.command(i); + ASSERT_EQ(msg->getType(), api::MessageType::REMOVELOCATION); - api::RemoveLocationCommand* tmp = (api::RemoveLocationCommand*)msg.get(); - CPPUNIT_ASSERT_EQUAL(vespalib::string("music.date < 34"), - tmp->getDocumentSelection()); + auto& tmp = dynamic_cast<api::RemoveLocationCommand&>(*msg); + EXPECT_EQ("music.date < 34", tmp.getDocumentSelection()); - std::shared_ptr<api::StorageReply> reply(tmp->makeReply().release()); - api::RemoveLocationReply* sreply = (api::RemoveLocationReply*)reply.get(); - sreply->setBucketInfo(api::BucketInfo(666, 90, 500)); + std::shared_ptr<api::StorageReply> reply(tmp.makeReply()); + auto& sreply = dynamic_cast<api::RemoveLocationReply&>(*reply); + sreply.setBucketInfo(api::BucketInfo(666, 90, 500)); op.receive(_sender, reply); } BucketDatabase::Entry entry = getBucket(document::BucketId(16, 1)); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT_EQUAL(2, (int)entry->getNodeCount()); - CPPUNIT_ASSERT_EQUAL(34, (int)entry->getLastGarbageCollectionTime()); - CPPUNIT_ASSERT_EQUAL(api::BucketInfo(666, 90, 500), - entry->getNodeRef(0).getBucketInfo()); - CPPUNIT_ASSERT_EQUAL(api::BucketInfo(666, 90, 500), - entry->getNodeRef(1).getBucketInfo()); + ASSERT_TRUE(entry.valid()); + ASSERT_EQ(2, entry->getNodeCount()); + EXPECT_EQ(34, entry->getLastGarbageCollectionTime()); + EXPECT_EQ(api::BucketInfo(666, 90, 500), entry->getNodeRef(0).getBucketInfo()); + EXPECT_EQ(api::BucketInfo(666, 90, 500), entry->getNodeRef(1).getBucketInfo()); } -} // distributor -} // storage +} // storage::distributor diff --git a/storage/src/tests/distributor/getoperationtest.cpp b/storage/src/tests/distributor/getoperationtest.cpp index 064348539bf..4b67cf1963d 100644 --- a/storage/src/tests/distributor/getoperationtest.cpp +++ b/storage/src/tests/distributor/getoperationtest.cpp @@ -6,121 +6,101 @@ #include <vespa/storage/distributor/externaloperationhandler.h> #include <vespa/storage/distributor/distributor.h> #include <vespa/storage/distributor/distributormetricsset.h> +#include <vespa/storage/distributor/operations/external/getoperation.h> #include <tests/distributor/distributortestutil.h> #include <vespa/storageapi/message/persistence.h> #include <vespa/document/test/make_document_bucket.h> -#include <vespa/vespalib/testkit/testapp.h> #include <vespa/config/helper/configgetter.hpp> +#include <vespa/vespalib/gtest/gtest.h> #include <iomanip> -#include <vespa/storage/distributor/operations/external/getoperation.h> using std::shared_ptr; using config::ConfigGetter; using document::DocumenttypesConfig; using config::FileSpec; using document::test::makeDocumentBucket; +using namespace ::testing; namespace storage::distributor { -class GetOperationTest : public CppUnit::TestFixture, public DistributorTestUtil { - CPPUNIT_TEST_SUITE(GetOperationTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(testNotFound); - CPPUNIT_TEST(testResendOnStorageFailure); - CPPUNIT_TEST(testResendOnStorageFailureAllFail); - CPPUNIT_TEST(testSendToIdealCopyIfBucketInSync); - CPPUNIT_TEST(testReturnNotFoundWhenBucketNotInDb); - CPPUNIT_TEST(testAskAllNodesIfBucketIsInconsistent); - CPPUNIT_TEST(testSendToAllInvalidNodesWhenInconsistent); - CPPUNIT_TEST(testAskTrustedNodeIfBucketIsInconsistent); - CPPUNIT_TEST(testInconsistentSplit); // Test that we ask all nodes if a bucket is inconsistent. - CPPUNIT_TEST(testSendToAllInvalidCopies); - CPPUNIT_TEST(testMultiInconsistentBucket); - CPPUNIT_TEST(testMultiInconsistentBucketFail); - CPPUNIT_TEST(testMultiInconsistentBucketNotFound); - CPPUNIT_TEST(testMultiInconsistentBucketNotFoundDeleted); - CPPUNIT_TEST(testMultipleCopiesWithFailureOnLocalNode); - CPPUNIT_TEST(canGetDocumentsWhenAllReplicaNodesRetired); - CPPUNIT_TEST_SUITE_END(); +struct GetOperationTest : Test, DistributorTestUtil { std::shared_ptr<const document::DocumentTypeRepo> _repo; - -public: document::DocumentId docId; document::BucketId bucketId; std::unique_ptr<Operation> op; - void setUp() override { + GetOperationTest(); + ~GetOperationTest(); + + void SetUp() override { _repo.reset( new document::DocumentTypeRepo(*ConfigGetter<DocumenttypesConfig>:: getConfig("config-doctypes", - FileSpec(TEST_PATH("config-doctypes.cfg"))))); + FileSpec("../config-doctypes.cfg")))); createLinks(); docId = document::DocumentId(document::DocIdString("test", "uri")); bucketId = getExternalOperationHandler().getBucketId(docId); }; - void tearDown() override { + void TearDown() override { close(); op.reset(); } void sendGet() { - std::shared_ptr<api::GetCommand> msg( - new api::GetCommand(makeDocumentBucket(document::BucketId(0)), docId, "[all]")); - - op.reset(new GetOperation(getExternalOperationHandler(), - getDistributorBucketSpace(), - msg, - getDistributor().getMetrics(). - gets[msg->getLoadType()])); + auto msg = std::make_shared<api::GetCommand>(makeDocumentBucket(document::BucketId(0)), docId, "[all]"); + op = std::make_unique<GetOperation>( + getExternalOperationHandler(), getDistributorBucketSpace(), + msg, getDistributor().getMetrics(). gets[msg->getLoadType()]); op->start(_sender, framework::MilliSecTime(0)); } + static constexpr uint32_t LastCommand = UINT32_MAX; + void sendReply(uint32_t idx, api::ReturnCode::Result result, std::string authorVal, uint32_t timestamp) { - if (idx == (uint32_t)-1) { - idx = _sender.commands.size() - 1; + if (idx == LastCommand) { + idx = _sender.commands().size() - 1; } - std::shared_ptr<api::StorageCommand> msg2 = _sender.commands[idx]; - CPPUNIT_ASSERT_EQUAL(api::MessageType::GET, msg2->getType()); + std::shared_ptr<api::StorageCommand> msg2 = _sender.command(idx); + ASSERT_EQ(api::MessageType::GET, msg2->getType()); - api::GetCommand* tmp = static_cast<api::GetCommand*>(msg2.get()); + auto* tmp = static_cast<api::GetCommand*>(msg2.get()); document::Document::SP doc; - if (authorVal.length()) { + if (!authorVal.empty()) { const document::DocumentType* type(_repo->getDocumentType("text/html")); - doc = document::Document::SP( - new document::Document(*type, docId)); + doc = std::make_unique<document::Document>(*type, docId); doc->setValue(doc->getField("author"), document::StringFieldValue(authorVal)); } - api::GetReply* reply = new api::GetReply(*tmp, doc, timestamp); + auto reply = std::make_shared<api::GetReply>(*tmp, doc, timestamp); reply->setResult(result); - op->receive(_sender, std::shared_ptr<api::StorageReply>(reply)); + op->receive(_sender, reply); } void replyWithFailure() { - sendReply(-1, api::ReturnCode::IO_FAILURE, "", 0); + sendReply(LastCommand, api::ReturnCode::IO_FAILURE, "", 0); } void replyWithNotFound() { - sendReply(-1, api::ReturnCode::OK, "", 0); + sendReply(LastCommand, api::ReturnCode::OK, "", 0); } void replyWithDocument() { - sendReply(-1, api::ReturnCode::OK, "foo", 100); + sendReply(LastCommand, api::ReturnCode::OK, "foo", 100); } std::string getLastReplyAuthor() { - api::StorageMessage& msg = *_sender.replies[_sender.replies.size() - 1]; + api::StorageMessage& msg = *_sender.replies().back(); if (msg.getType() == api::MessageType::GET_REPLY) { document::Document::SP doc( @@ -137,147 +117,104 @@ public: void setClusterState(const std::string& clusterState) { enableDistributorClusterState(clusterState); } - - void testSimple(); - void testReturnNotFoundWhenBucketNotInDb(); - void testNotFound(); - void testResendOnStorageFailure(); - void testResendOnStorageFailureAllFail(); - void testSendToIdealCopyIfBucketInSync(); - void testAskAllNodesIfBucketIsInconsistent(); - void testSendToAllInvalidNodesWhenInconsistent(); - void testAskTrustedNodeIfBucketIsInconsistent(); - void testInconsistentSplit(); - void testMultiInconsistentBucket(); - void testMultiInconsistentBucketFail(); - void testMultiInconsistentBucketNotFound(); - void testMultiInconsistentBucketNotFoundDeleted(); - void testSendToAllInvalidCopies(); - void testMultipleCopiesWithFailureOnLocalNode(); - void canGetDocumentsWhenAllReplicaNodesRetired(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(GetOperationTest); +GetOperationTest::GetOperationTest() = default; +GetOperationTest::~GetOperationTest() = default; -void -GetOperationTest::testSimple() -{ +TEST_F(GetOperationTest, simple) { setClusterState("distributor:1 storage:2"); addNodesToBucketDB(bucketId, "0=4,1=4"); sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 0", _sender.getCommands(true)); - replyWithDocument(); + ASSERT_NO_FATAL_FAILURE(replyWithDocument()); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 100) ReturnCode(NONE)"), - _sender.getLastReply()); + EXPECT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 100) ReturnCode(NONE)", + _sender.getLastReply()); } -void -GetOperationTest::testAskTrustedNodeIfBucketIsInconsistent() -{ +TEST_F(GetOperationTest, ask_trusted_node_if_bucket_is_inconsistent) { setClusterState("distributor:1 storage:4"); addNodesToBucketDB(bucketId, "0=100/3/10,1=200/4/12/t"); sendGet(); - CPPUNIT_ASSERT_EQUAL(std::string("Get => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 1", _sender.getCommands(true)); - replyWithDocument(); + ASSERT_NO_FATAL_FAILURE(replyWithDocument()); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 100) ReturnCode(NONE)"), - _sender.getLastReply()); + EXPECT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 100) ReturnCode(NONE)", + _sender.getLastReply()); } -void -GetOperationTest::testAskAllNodesIfBucketIsInconsistent() -{ +TEST_F(GetOperationTest, ask_all_nodes_if_bucket_is_inconsistent) { setClusterState("distributor:1 storage:4"); addNodesToBucketDB(bucketId, "0=100/3/10,1=200/4/12"); sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 0,Get => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 1", _sender.getCommands(true)); - sendReply(0, api::ReturnCode::OK, "newauthor", 2); - sendReply(1, api::ReturnCode::OK, "oldauthor", 1); + ASSERT_NO_FATAL_FAILURE(sendReply(0, api::ReturnCode::OK, "newauthor", 2)); + ASSERT_NO_FATAL_FAILURE(sendReply(1, api::ReturnCode::OK, "oldauthor", 1)); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 2) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 2) ReturnCode(NONE)", + _sender.getLastReply()); - CPPUNIT_ASSERT_EQUAL(std::string("newauthor"), getLastReplyAuthor()); + EXPECT_EQ("newauthor", getLastReplyAuthor()); } - -void -GetOperationTest::testSendToAllInvalidCopies() -{ +TEST_F(GetOperationTest, send_to_all_invalid_copies) { setClusterState("distributor:1 storage:4"); addNodesToBucketDB(bucketId, "2=0/0/1,3=0/0/1"); sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 2,Get => 3"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 2,Get => 3", _sender.getCommands(true)); - sendReply(0, api::ReturnCode::OK, "newauthor", 2); - sendReply(1, api::ReturnCode::OK, "oldauthor", 1); + ASSERT_NO_FATAL_FAILURE(sendReply(0, api::ReturnCode::OK, "newauthor", 2)); + ASSERT_NO_FATAL_FAILURE(sendReply(1, api::ReturnCode::OK, "oldauthor", 1)); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 2) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 2) ReturnCode(NONE)", + _sender.getLastReply()); - CPPUNIT_ASSERT_EQUAL(std::string("newauthor"), getLastReplyAuthor()); + EXPECT_EQ("newauthor", getLastReplyAuthor()); } -void -GetOperationTest::testSendToAllInvalidNodesWhenInconsistent() -{ +TEST_F(GetOperationTest, send_to_all_invalid_nodes_when_inconsistent) { setClusterState("distributor:1 storage:4"); addNodesToBucketDB(bucketId, "0=100,1=200,2=0/0/1,3=0/0/1"); sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 2,Get => 3,Get => 0,Get => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 2,Get => 3,Get => 0,Get => 1", + _sender.getCommands(true)); - sendReply(0, api::ReturnCode::OK, "newauthor", 2); - sendReply(1, api::ReturnCode::OK, "oldauthor", 1); - sendReply(2, api::ReturnCode::OK, "oldauthor", 1); - sendReply(3, api::ReturnCode::OK, "oldauthor", 1); + ASSERT_NO_FATAL_FAILURE(sendReply(0, api::ReturnCode::OK, "newauthor", 2)); + ASSERT_NO_FATAL_FAILURE(sendReply(1, api::ReturnCode::OK, "oldauthor", 1)); + ASSERT_NO_FATAL_FAILURE(sendReply(2, api::ReturnCode::OK, "oldauthor", 1)); + ASSERT_NO_FATAL_FAILURE(sendReply(3, api::ReturnCode::OK, "oldauthor", 1)); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 2) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 2) ReturnCode(NONE)", + _sender.getLastReply()); - CPPUNIT_ASSERT_EQUAL(std::string("newauthor"), getLastReplyAuthor()); + EXPECT_EQ("newauthor", getLastReplyAuthor()); } -void -GetOperationTest::testInconsistentSplit() -{ +TEST_F(GetOperationTest, inconsistent_split) { setClusterState("distributor:1 storage:4"); addNodesToBucketDB(document::BucketId(16, 0x2a52), "0=100"); @@ -285,162 +222,126 @@ GetOperationTest::testInconsistentSplit() sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 0,Get => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 1", _sender.getCommands(true)); - sendReply(0, api::ReturnCode::OK, "newauthor", 2); - sendReply(1, api::ReturnCode::OK, "oldauthor", 1); + ASSERT_NO_FATAL_FAILURE(sendReply(0, api::ReturnCode::OK, "newauthor", 2)); + ASSERT_NO_FATAL_FAILURE(sendReply(1, api::ReturnCode::OK, "oldauthor", 1)); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 2) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 2) ReturnCode(NONE)", + _sender.getLastReply()); - CPPUNIT_ASSERT_EQUAL(std::string("newauthor"), getLastReplyAuthor()); + EXPECT_EQ("newauthor", getLastReplyAuthor()); } - -void -GetOperationTest::testMultiInconsistentBucketNotFound() -{ +TEST_F(GetOperationTest, multi_inconsistent_bucket_not_found) { setClusterState("distributor:1 storage:4"); addNodesToBucketDB(bucketId, "0=100,2=100,1=200,3=200"); sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 0,Get => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 1", _sender.getCommands(true)); - sendReply(0, api::ReturnCode::OK, "newauthor", 2); - sendReply(1, api::ReturnCode::OK, "", 0); + ASSERT_NO_FATAL_FAILURE(sendReply(0, api::ReturnCode::OK, "newauthor", 2)); + ASSERT_NO_FATAL_FAILURE(sendReply(1, api::ReturnCode::OK, "", 0)); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 2) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 2) ReturnCode(NONE)", + _sender.getLastReply()); } -void -GetOperationTest::testMultiInconsistentBucketNotFoundDeleted() -{ +TEST_F(GetOperationTest, multi_inconsistent_bucket_not_found_deleted) { setClusterState("distributor:1 storage:4"); addNodesToBucketDB(bucketId, "0=100,2=100,1=200,3=200"); sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 0,Get => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 1", _sender.getCommands(true)); - sendReply(0, api::ReturnCode::OK, "newauthor", 2); + ASSERT_NO_FATAL_FAILURE(sendReply(0, api::ReturnCode::OK, "newauthor", 2)); // This signifies that the latest change was that the document was deleted // at timestamp 3. - sendReply(1, api::ReturnCode::OK, "", 3); + ASSERT_NO_FATAL_FAILURE(sendReply(1, api::ReturnCode::OK, "", 3)); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 3) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 3) ReturnCode(NONE)", + _sender.getLastReply()); } -void -GetOperationTest::testMultiInconsistentBucket() -{ +TEST_F(GetOperationTest, multi_inconsistent_bucket) { setClusterState("distributor:1 storage:4"); addNodesToBucketDB(bucketId, "0=100,2=100,1=200,3=200"); sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 0,Get => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 1", _sender.getCommands(true)); - sendReply(0, api::ReturnCode::OK, "newauthor", 2); - sendReply(1, api::ReturnCode::OK, "oldauthor", 1); + ASSERT_NO_FATAL_FAILURE(sendReply(0, api::ReturnCode::OK, "newauthor", 2)); + ASSERT_NO_FATAL_FAILURE(sendReply(1, api::ReturnCode::OK, "oldauthor", 1)); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 2) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 2) ReturnCode(NONE)", + _sender.getLastReply()); - CPPUNIT_ASSERT_EQUAL(std::string("newauthor"), getLastReplyAuthor()); + EXPECT_EQ("newauthor", getLastReplyAuthor()); } -void -GetOperationTest::testMultiInconsistentBucketFail() -{ +TEST_F(GetOperationTest, multi_inconsistent_bucket_fail) { setClusterState("distributor:1 storage:4"); addNodesToBucketDB(bucketId, "0=100,2=100,1=200,3=200"); sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 0,Get => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 1", _sender.getCommands(true)); - sendReply(0, api::ReturnCode::OK, "newauthor", 1); - sendReply(1, api::ReturnCode::DISK_FAILURE, "", 0); + ASSERT_NO_FATAL_FAILURE(sendReply(0, api::ReturnCode::OK, "newauthor", 1)); + ASSERT_NO_FATAL_FAILURE(sendReply(1, api::ReturnCode::DISK_FAILURE, "", 0)); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000002a52), doc:test:uri) => 3"), - _sender.getLastCommand()); + ASSERT_EQ("Get(BucketId(0x4000000000002a52), doc:test:uri) => 3", + _sender.getLastCommand()); - replyWithDocument(); + ASSERT_NO_FATAL_FAILURE(replyWithDocument()); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 100) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 100) ReturnCode(NONE)", + _sender.getLastReply()); } - -void -GetOperationTest::testReturnNotFoundWhenBucketNotInDb() -{ +TEST_F(GetOperationTest, return_not_found_when_bucket_not_in_db) { setClusterState("distributor:1 storage:1"); sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 0) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 0) ReturnCode(NONE)", + _sender.getLastReply()); } -void -GetOperationTest::testNotFound() -{ +TEST_F(GetOperationTest, not_found) { setClusterState("distributor:1 storage:1"); addNodesToBucketDB(bucketId, "0=100"); sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000002a52), doc:test:uri) => 0"), - _sender.getLastCommand()); + ASSERT_EQ("Get(BucketId(0x4000000000002a52), doc:test:uri) => 0", + _sender.getLastCommand()); - replyWithNotFound(); + ASSERT_NO_FATAL_FAILURE(replyWithNotFound()); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 0) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 0) ReturnCode(NONE)", + _sender.getLastReply()); - CPPUNIT_ASSERT_EQUAL(1, (int)(getDistributor(). - getMetrics().gets[documentapi::LoadType::DEFAULT]. - failures.notfound.getValue())); + EXPECT_EQ(1, getDistributor().getMetrics().gets[documentapi::LoadType::DEFAULT]. + failures.notfound.getValue()); } -void -GetOperationTest::testResendOnStorageFailure() -{ +TEST_F(GetOperationTest, resend_on_storage_failure) { setClusterState("distributor:1 storage:3"); // Add two nodes that are not trusted. GET should retry each one of them @@ -449,27 +350,22 @@ GetOperationTest::testResendOnStorageFailure() sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000002a52), doc:test:uri) => 1"), - _sender.getLastCommand()); + ASSERT_EQ("Get(BucketId(0x4000000000002a52), doc:test:uri) => 1", + _sender.getLastCommand()); - replyWithFailure(); + ASSERT_NO_FATAL_FAILURE(replyWithFailure()); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000002a52), doc:test:uri) => 2"), - _sender.getLastCommand()); + ASSERT_EQ("Get(BucketId(0x4000000000002a52), doc:test:uri) => 2", + _sender.getLastCommand()); - replyWithDocument(); + ASSERT_NO_FATAL_FAILURE(replyWithDocument()); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 100) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 100) ReturnCode(NONE)", + _sender.getLastReply()); } -void -GetOperationTest::testResendOnStorageFailureAllFail() -{ +TEST_F(GetOperationTest, resend_on_storage_failure_all_fail) { setClusterState("distributor:1 storage:3"); // Add two nodes that are not trusted. GET should retry each one of them @@ -478,27 +374,22 @@ GetOperationTest::testResendOnStorageFailureAllFail() sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000002a52), doc:test:uri) => 1"), - _sender.getLastCommand()); + ASSERT_EQ("Get(BucketId(0x4000000000002a52), doc:test:uri) => 1", + _sender.getLastCommand()); - replyWithFailure(); + ASSERT_NO_FATAL_FAILURE(replyWithFailure()); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000002a52), doc:test:uri) => 2"), - _sender.getLastCommand()); + ASSERT_EQ("Get(BucketId(0x4000000000002a52), doc:test:uri) => 2", + _sender.getLastCommand()); - replyWithFailure(); + ASSERT_NO_FATAL_FAILURE(replyWithFailure()); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 0) ReturnCode(IO_FAILURE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 0) ReturnCode(IO_FAILURE)", + _sender.getLastReply()); } -void -GetOperationTest::testSendToIdealCopyIfBucketInSync() -{ +TEST_F(GetOperationTest, send_to_ideal_copy_if_bucket_in_sync) { setClusterState("distributor:1 storage:4"); addNodesToBucketDB(bucketId, "1=100,2=100,3=100"); @@ -506,21 +397,17 @@ GetOperationTest::testSendToIdealCopyIfBucketInSync() sendGet(); // Should always send to node 1 (follow bucket db order) - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000002a52), doc:test:uri) => 1"), - _sender.getLastCommand()); + ASSERT_EQ("Get(BucketId(0x4000000000002a52), doc:test:uri) => 1", + _sender.getLastCommand()); - replyWithDocument(); + ASSERT_NO_FATAL_FAILURE(replyWithDocument()); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 100) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 100) ReturnCode(NONE)", + _sender.getLastReply()); } -void -GetOperationTest::testMultipleCopiesWithFailureOnLocalNode() -{ +TEST_F(GetOperationTest, multiple_copies_with_failure_on_local_node) { setClusterState("distributor:1 storage:4"); // Node 0 is local copy to distributor 0 and will be preferred when @@ -529,39 +416,30 @@ GetOperationTest::testMultipleCopiesWithFailureOnLocalNode() sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 0", _sender.getCommands(true)); // Fail local node; no reply must be sent yet since we've got more nodes // to try. - sendReply(0, api::ReturnCode::TIMEOUT, "", 0); + ASSERT_NO_FATAL_FAILURE(sendReply(0, api::ReturnCode::TIMEOUT, "", 0)); // Retry with remaining copy on node 2. - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 0,Get => 2"), - _sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 2", _sender.getCommands(true)); - sendReply(1, api::ReturnCode::OK, "newestauthor", 3); + ASSERT_NO_FATAL_FAILURE(sendReply(1, api::ReturnCode::OK, "newestauthor", 3)); - CPPUNIT_ASSERT_EQUAL( - std::string("GetReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 3) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("GetReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 3) ReturnCode(NONE)", + _sender.getLastReply()); - CPPUNIT_ASSERT_EQUAL(std::string("newestauthor"), getLastReplyAuthor()); + EXPECT_EQ("newestauthor", getLastReplyAuthor()); } -void -GetOperationTest::canGetDocumentsWhenAllReplicaNodesRetired() -{ +TEST_F(GetOperationTest, can_get_documents_when_all_replica_nodes_retired) { setClusterState("distributor:1 storage:2 .0.s:r .1.s:r"); addNodesToBucketDB(bucketId, "0=4,1=4"); sendGet(); - CPPUNIT_ASSERT_EQUAL( - std::string("Get => 0"), - _sender.getCommands(true)); + EXPECT_EQ("Get => 0", _sender.getCommands(true)); } } diff --git a/storage/src/tests/distributor/idealstatemanagertest.cpp b/storage/src/tests/distributor/idealstatemanagertest.cpp index 7401e083900..fc26a8c9cce 100644 --- a/storage/src/tests/distributor/idealstatemanagertest.cpp +++ b/storage/src/tests/distributor/idealstatemanagertest.cpp @@ -1,5 +1,4 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> #include <tests/common/dummystoragelink.h> #include <vespa/storageapi/message/persistence.h> #include <vespa/storage/distributor/bucketdbupdater.h> @@ -12,81 +11,68 @@ #include <vespa/document/bucket/fixed_bucket_spaces.h> #include <vespa/document/test/make_document_bucket.h> #include <vespa/document/test/make_bucket_space.h> +#include <vespa/vespalib/gtest/gtest.h> using document::test::makeDocumentBucket; using document::test::makeBucketSpace; using document::FixedBucketSpaces; +using namespace ::testing; -namespace storage { -namespace distributor { +namespace storage::distributor { -class IdealStateManagerTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ -public: +struct IdealStateManagerTest : Test, DistributorTestUtil { IdealStateManagerTest() - : CppUnit::TestFixture(), - DistributorTestUtil(), - _bucketSpaces() + : Test(), + DistributorTestUtil(), + _bucketSpaces() {} - void setUp() override { + void SetUp() override { createLinks(); _bucketSpaces = getBucketSpaces(); }; - void tearDown() override { + void TearDown() override { close(); } - void testSibling(); - void testClearActiveOnNodeDown(); - void testRecheckWhenActive(); - void testRecheckWhenPending(); - void testOpsGenerationBusy(); - void testStatusPage(); - void testDisabledStateChecker(); - void testBlockIdealStateOpsOnFullRequestBucketInfo(); - void testBlockCheckForAllOperationsToSpecificBucket(); - void setSystemState(const lib::ClusterState& systemState) { _distributor->enableClusterStateBundle(lib::ClusterStateBundle(systemState)); } - CPPUNIT_TEST_SUITE(IdealStateManagerTest); - CPPUNIT_TEST(testSibling); - CPPUNIT_TEST(testClearActiveOnNodeDown); - CPPUNIT_TEST(testRecheckWhenActive); - CPPUNIT_TEST(testStatusPage); - CPPUNIT_TEST(testDisabledStateChecker); - CPPUNIT_TEST(testBlockIdealStateOpsOnFullRequestBucketInfo); - CPPUNIT_TEST(testBlockCheckForAllOperationsToSpecificBucket); - CPPUNIT_TEST_SUITE_END(); -private: + bool checkBlock(const IdealStateOperation& op, + const document::Bucket& bucket, + const PendingMessageTracker& tracker) const + { + return op.checkBlock(bucket, tracker); + } + + bool checkBlockForAllNodes(const IdealStateOperation& op, + const document::Bucket& bucket, + const PendingMessageTracker& tracker) const + { + return op.checkBlockForAllNodes(bucket, tracker); + } + std::vector<document::BucketSpace> _bucketSpaces; std::string makeBucketStatusString(const std::string &defaultSpaceBucketStatus); }; -CPPUNIT_TEST_SUITE_REGISTRATION(IdealStateManagerTest); - -void -IdealStateManagerTest::testSibling() -{ - CPPUNIT_ASSERT_EQUAL(document::BucketId(1,1), - getIdealStateManager().getDistributorComponent() - .getSibling(document::BucketId(1, 0))); - CPPUNIT_ASSERT_EQUAL(document::BucketId(1,0), - getIdealStateManager().getDistributorComponent() - .getSibling(document::BucketId(1, 1))); - CPPUNIT_ASSERT_EQUAL(document::BucketId(2,3), - getIdealStateManager().getDistributorComponent() - .getSibling(document::BucketId(2, 1))); - CPPUNIT_ASSERT_EQUAL(document::BucketId(2,1), - getIdealStateManager().getDistributorComponent() - .getSibling(document::BucketId(2, 3))); +TEST_F(IdealStateManagerTest, sibling) { + EXPECT_EQ(document::BucketId(1,1), + getIdealStateManager().getDistributorComponent() + .getSibling(document::BucketId(1, 0))); + EXPECT_EQ(document::BucketId(1,0), + getIdealStateManager().getDistributorComponent() + .getSibling(document::BucketId(1, 1))); + EXPECT_EQ(document::BucketId(2,3), + getIdealStateManager().getDistributorComponent() + .getSibling(document::BucketId(2, 1))); + EXPECT_EQ(document::BucketId(2,1), + getIdealStateManager().getDistributorComponent() + .getSibling(document::BucketId(2, 3))); } -void -IdealStateManagerTest::testStatusPage() { +TEST_F(IdealStateManagerTest, status_page) { close(); getDirConfig().getConfig("stor-distributormanager").set("splitsize", "100"); getDirConfig().getConfig("stor-distributormanager").set("splitcount", "1000000"); @@ -101,15 +87,14 @@ IdealStateManagerTest::testStatusPage() { std::ostringstream ost; getIdealStateManager().getBucketStatus(ost); - CPPUNIT_ASSERT_EQUAL(makeBucketStatusString("BucketId(0x4000000000000002) : [node(idx=0,crc=0xff,docs=10/10,bytes=10/10,trusted=true,active=true,ready=false)]<br>\n" + EXPECT_EQ(makeBucketStatusString("BucketId(0x4000000000000002) : [node(idx=0,crc=0xff,docs=10/10,bytes=10/10,trusted=true,active=true,ready=false)]<br>\n" "<b>BucketId(0x4000000000000005):</b> <i> : split: [Splitting bucket because its maximum size (200 b, 100 docs, 100 meta, 200 b total) is " "higher than the configured limit of (100, 1000000)]</i> [node(idx=0,crc=0xff,docs=100/100,bytes=200/200,trusted=true," "active=true,ready=false)]<br>\n"), - ost.str()); + ost.str()); } -void -IdealStateManagerTest::testDisabledStateChecker() { +TEST_F(IdealStateManagerTest, disabled_state_checker) { setupDistributor(1, 1, "distributor:1 storage:1"); getConfig().setSplitSize(100); @@ -122,7 +107,7 @@ IdealStateManagerTest::testDisabledStateChecker() { std::ostringstream ost; getIdealStateManager().getBucketStatus(ost); - CPPUNIT_ASSERT_EQUAL(makeBucketStatusString( + EXPECT_EQ(makeBucketStatusString( "BucketId(0x4000000000000002) : [node(idx=0,crc=0xff,docs=10/10,bytes=10/10,trusted=true,active=true,ready=false)]<br>\n" "<b>BucketId(0x4000000000000005):</b> <i> : split: [Splitting bucket because its maximum size (200 b, 100 docs, 100 meta, 200 b total) is " "higher than the configured limit of (100, 1000000)]</i> [node(idx=0,crc=0xff,docs=100/100,bytes=200/200,trusted=true," @@ -130,14 +115,11 @@ IdealStateManagerTest::testDisabledStateChecker() { ost.str()); tick(); - CPPUNIT_ASSERT_EQUAL(std::string(""), - _distributor->getActiveIdealStateOperations()); + EXPECT_EQ("", _distributor->getActiveIdealStateOperations()); } -void -IdealStateManagerTest::testClearActiveOnNodeDown() -{ +TEST_F(IdealStateManagerTest, clear_active_on_node_down) { setSystemState(lib::ClusterState("distributor:1 storage:3")); for (int i = 1; i < 4; i++) { insertBucketInfo(document::BucketId(16, i), 0, 0xff, 100, 200); @@ -152,24 +134,19 @@ IdealStateManagerTest::testClearActiveOnNodeDown() tick(); } - CPPUNIT_ASSERT_EQUAL( - std::string("setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)) (pri 100)\n" - "setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000002)) (pri 100)\n" - "setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000003)) (pri 100)\n"), - _distributor->getActiveIdealStateOperations()); + EXPECT_EQ("setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)) (pri 100)\n" + "setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000002)) (pri 100)\n" + "setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000003)) (pri 100)\n", + _distributor->getActiveIdealStateOperations()); setSystemState(lib::ClusterState("distributor:1 storage:3 .0.s:d")); - CPPUNIT_ASSERT_EQUAL(std::string(""), - _distributor->getActiveIdealStateOperations()); - CPPUNIT_ASSERT_EQUAL(uint32_t(0), - _distributor->getPendingMessageTracker() - .getNodeInfo().getPendingCount(0)); + EXPECT_EQ("", _distributor->getActiveIdealStateOperations()); + EXPECT_EQ(0, _distributor->getPendingMessageTracker() + .getNodeInfo().getPendingCount(0)); } -void -IdealStateManagerTest::testRecheckWhenActive() -{ +TEST_F(IdealStateManagerTest, recheck_when_active) { for (uint32_t j = 0; j < 3; j++) { insertBucketInfo(document::BucketId(16, 1), j, 0xff - j, 100, 200); } @@ -178,26 +155,21 @@ IdealStateManagerTest::testRecheckWhenActive() tick(); - CPPUNIT_ASSERT_EQUAL( - std::string("setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)) (pri 100)\n"), - _distributor->getActiveIdealStateOperations()); + EXPECT_EQ("setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)) (pri 100)\n", + _distributor->getActiveIdealStateOperations()); tick(); - CPPUNIT_ASSERT_EQUAL( - std::string("setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)) (pri 100)\n"), - _distributor->getActiveIdealStateOperations()); + EXPECT_EQ("setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)) (pri 100)\n", + _distributor->getActiveIdealStateOperations()); tick(); - CPPUNIT_ASSERT_EQUAL( - std::string("setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)) (pri 100)\n"), - _distributor->getActiveIdealStateOperations()); + EXPECT_EQ("setbucketstate to [0] Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)) (pri 100)\n", + _distributor->getActiveIdealStateOperations()); } -void -IdealStateManagerTest::testBlockIdealStateOpsOnFullRequestBucketInfo() -{ +TEST_F(IdealStateManagerTest, block_ideal_state_ops_on_full_request_bucket_info) { setupDistributor(2, 10, "distributor:1 storage:2"); framework::defaultimplementation::FakeClock clock; @@ -209,45 +181,39 @@ IdealStateManagerTest::testBlockIdealStateOpsOnFullRequestBucketInfo() // RequestBucketInfoCommand does not have a specific bucketid since it's // sent to the entire node. It will then use a null bucketid. { - std::shared_ptr<api::RequestBucketInfoCommand> msg( - new api::RequestBucketInfoCommand(makeBucketSpace(), buckets)); - msg->setAddress( - api::StorageMessageAddress("storage", lib::NodeType::STORAGE, 4)); + auto msg = std::make_shared<api::RequestBucketInfoCommand>(makeBucketSpace(), buckets); + msg->setAddress(api::StorageMessageAddress("storage", lib::NodeType::STORAGE, 4)); tracker.insert(msg); } { RemoveBucketOperation op("storage", BucketAndNodes(makeDocumentBucket(bid), toVector<uint16_t>(3, 4))); - CPPUNIT_ASSERT(op.isBlocked(tracker)); + EXPECT_TRUE(op.isBlocked(tracker)); } { // Don't trigger on requests to other nodes. RemoveBucketOperation op("storage", BucketAndNodes(makeDocumentBucket(bid), toVector<uint16_t>(3, 5))); - CPPUNIT_ASSERT(!op.isBlocked(tracker)); + EXPECT_FALSE(op.isBlocked(tracker)); } // Don't block on null-bucket messages that aren't RequestBucketInfo. { - std::shared_ptr<api::CreateVisitorCommand> msg( - new api::CreateVisitorCommand(makeBucketSpace(), "foo", "bar", "baz")); - msg->setAddress( - api::StorageMessageAddress("storage", lib::NodeType::STORAGE, 7)); + auto msg = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "foo", "bar", "baz"); + msg->setAddress(api::StorageMessageAddress("storage", lib::NodeType::STORAGE, 7)); tracker.insert(msg); } { RemoveBucketOperation op("storage", BucketAndNodes(makeDocumentBucket(bid), toVector<uint16_t>(7))); - CPPUNIT_ASSERT(!op.isBlocked(tracker)); + EXPECT_FALSE(op.isBlocked(tracker)); } } -void -IdealStateManagerTest::testBlockCheckForAllOperationsToSpecificBucket() -{ +TEST_F(IdealStateManagerTest, block_check_for_all_operations_to_specific_bucket) { setupDistributor(2, 10, "distributor:1 storage:2"); framework::defaultimplementation::FakeClock clock; PendingMessageTracker tracker(_node->getComponentRegister()); @@ -263,9 +229,9 @@ IdealStateManagerTest::testBlockCheckForAllOperationsToSpecificBucket() RemoveBucketOperation op("storage", BucketAndNodes(makeDocumentBucket(bid), toVector<uint16_t>(7))); // Not blocked for exact node match. - CPPUNIT_ASSERT(!op.checkBlock(makeDocumentBucket(bid), tracker)); + EXPECT_FALSE(checkBlock(op, makeDocumentBucket(bid), tracker)); // But blocked for bucket match! - CPPUNIT_ASSERT(op.checkBlockForAllNodes(makeDocumentBucket(bid), tracker)); + EXPECT_TRUE(checkBlockForAllNodes(op, makeDocumentBucket(bid), tracker)); } } @@ -282,6 +248,4 @@ IdealStateManagerTest::makeBucketStatusString(const std::string &defaultSpaceBuc return ost.str(); } -} // distributor -} // storage - +} // storage::distributor diff --git a/storage/src/tests/distributor/joinbuckettest.cpp b/storage/src/tests/distributor/joinbuckettest.cpp index 42ba0c0c0b9..a918a29c609 100644 --- a/storage/src/tests/distributor/joinbuckettest.cpp +++ b/storage/src/tests/distributor/joinbuckettest.cpp @@ -1,47 +1,33 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <cppunit/extensions/HelperMacros.h> #include <vespa/storageapi/message/bucketsplitting.h> #include <vespa/storage/distributor/operations/idealstate/joinoperation.h> #include <vespa/storage/distributor/distributor.h> #include <tests/distributor/distributortestutil.h> #include <vespa/document/test/make_document_bucket.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> using document::test::makeDocumentBucket; +using namespace ::testing; -namespace storage { -namespace distributor { - -class JoinOperationTest : public CppUnit::TestFixture, public DistributorTestUtil -{ - CPPUNIT_TEST_SUITE(JoinOperationTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(sendSparseJoinsToNodesWithoutBothSourceBuckets); - CPPUNIT_TEST_SUITE_END(); +namespace storage::distributor { +struct JoinOperationTest : Test, DistributorTestUtil { void checkSourceBucketsAndSendReply( JoinOperation& op, size_t msgIndex, const std::vector<document::BucketId>& wantedIds); -protected: - void testSimple(); - void sendSparseJoinsToNodesWithoutBothSourceBuckets(); - -public: - void setUp() override { + void SetUp() override { createLinks(); }; - void tearDown() override { + void TearDown() override { close(); } }; -CPPUNIT_TEST_SUITE_REGISTRATION(JoinOperationTest); - -void -JoinOperationTest::testSimple() -{ +TEST_F(JoinOperationTest, simple) { getConfig().setJoinCount(100); getConfig().setJoinSize(1000); @@ -61,14 +47,13 @@ JoinOperationTest::testSimple() checkSourceBucketsAndSendReply(op, 0, {{33, 1}, {33, 0x100000001}}); - CPPUNIT_ASSERT(!getBucket(document::BucketId(33, 0x100000001)).valid()); - CPPUNIT_ASSERT(!getBucket(document::BucketId(33, 1)).valid()); + EXPECT_FALSE(getBucket(document::BucketId(33, 0x100000001)).valid()); + EXPECT_FALSE(getBucket(document::BucketId(33, 1)).valid()); BucketDatabase::Entry entry = getBucket(document::BucketId(32, 0)); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT_EQUAL((uint16_t)0, entry->getNodeRef(0).getNode()); - CPPUNIT_ASSERT_EQUAL(api::BucketInfo(666, 90, 500), - entry->getNodeRef(0).getBucketInfo()); + ASSERT_TRUE(entry.valid()); + EXPECT_EQ(0, entry->getNodeRef(0).getNode()); + EXPECT_EQ(api::BucketInfo(666, 90, 500), entry->getNodeRef(0).getBucketInfo()); } void @@ -77,18 +62,16 @@ JoinOperationTest::checkSourceBucketsAndSendReply( size_t msgIndex, const std::vector<document::BucketId>& wantedIds) { - CPPUNIT_ASSERT(_sender.commands.size() > msgIndex); + ASSERT_GT(_sender.commands().size(), msgIndex); - std::shared_ptr<api::StorageCommand> msg(_sender.commands[msgIndex]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::JOINBUCKETS, msg->getType()); + std::shared_ptr<api::StorageCommand> msg(_sender.command(msgIndex)); + ASSERT_EQ(api::MessageType::JOINBUCKETS, msg->getType()); - api::JoinBucketsCommand& joinCmd( - dynamic_cast<api::JoinBucketsCommand&>(*msg)); - CPPUNIT_ASSERT_EQUAL(wantedIds, joinCmd.getSourceBuckets()); + auto& joinCmd = dynamic_cast<api::JoinBucketsCommand&>(*msg); + EXPECT_THAT(joinCmd.getSourceBuckets(), ContainerEq(wantedIds)); std::shared_ptr<api::StorageReply> reply(joinCmd.makeReply()); - api::JoinBucketsReply& sreply( - dynamic_cast<api::JoinBucketsReply&>(*reply)); + auto& sreply = dynamic_cast<api::JoinBucketsReply&>(*reply); sreply.setBucketInfo(api::BucketInfo(666, 90, 500)); op.receive(_sender, reply); @@ -99,9 +82,7 @@ JoinOperationTest::checkSourceBucketsAndSendReply( * bucket id used as both source buckets) for those nodes having only one of * the buckets. */ -void -JoinOperationTest::sendSparseJoinsToNodesWithoutBothSourceBuckets() -{ +TEST_F(JoinOperationTest, send_sparse_joins_to_nodes_without_both_source_buckets) { getConfig().setJoinCount(100); getConfig().setJoinSize(1000); @@ -119,10 +100,8 @@ JoinOperationTest::sendSparseJoinsToNodesWithoutBothSourceBuckets() op.setIdealStateManager(&getIdealStateManager()); op.start(_sender, framework::MilliSecTime(0)); - checkSourceBucketsAndSendReply(op, 0, {{33, 1}, {33, 0x100000001}}); - checkSourceBucketsAndSendReply(op, 1, {{33, 1}, {33, 1}}); -} - + ASSERT_NO_FATAL_FAILURE(checkSourceBucketsAndSendReply(op, 0, {{33, 1}, {33, 0x100000001}})); + ASSERT_NO_FATAL_FAILURE(checkSourceBucketsAndSendReply(op, 1, {{33, 1}, {33, 1}})); } } diff --git a/storage/src/tests/distributor/maintenancemocks.h b/storage/src/tests/distributor/maintenancemocks.h index 2be74ca1a8b..c88e477e90e 100644 --- a/storage/src/tests/distributor/maintenancemocks.h +++ b/storage/src/tests/distributor/maintenancemocks.h @@ -11,8 +11,7 @@ using document::test::makeBucketSpace; -namespace storage { -namespace distributor { +namespace storage::distributor { class MockMaintenancePriorityGenerator : public MaintenancePriorityGenerator @@ -116,5 +115,3 @@ public: }; } -} - diff --git a/storage/src/tests/distributor/maintenanceschedulertest.cpp b/storage/src/tests/distributor/maintenanceschedulertest.cpp index db0347617f0..53408bbf6b6 100644 --- a/storage/src/tests/distributor/maintenanceschedulertest.cpp +++ b/storage/src/tests/distributor/maintenanceschedulertest.cpp @@ -1,110 +1,78 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> -#include <string> -#include <sstream> -#include <memory> +#include <vespa/document/test/make_document_bucket.h> #include <vespa/storage/distributor/maintenance/simplebucketprioritydatabase.h> #include <vespa/storage/distributor/maintenance/maintenancescheduler.h> #include <vespa/storage/bucketdb/mapbucketdatabase.h> #include <tests/distributor/maintenancemocks.h> -#include <vespa/document/test/make_document_bucket.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <memory> +#include <string> +#include <sstream> using document::test::makeDocumentBucket; +using namespace ::testing; -namespace storage { - -namespace distributor { +namespace storage::distributor { using document::BucketId; -typedef MaintenancePriority Priority; -typedef MaintenanceScheduler::WaitTimeMs WaitTimeMs; - -class MaintenanceSchedulerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(MaintenanceSchedulerTest); - CPPUNIT_TEST(testPriorityClearedAfterScheduled); - CPPUNIT_TEST(testOperationIsScheduled); - CPPUNIT_TEST(testNoOperationsToSchedule); - CPPUNIT_TEST(testSuppressLowPrioritiesInEmergencyMode); - CPPUNIT_TEST(testPriorityNotClearedIfOperationNotStarted); - CPPUNIT_TEST_SUITE_END(); +using Priority = MaintenancePriority; +using WaitTimeMs = MaintenanceScheduler::WaitTimeMs; +struct MaintenanceSchedulerTest : Test { std::unique_ptr<SimpleBucketPriorityDatabase> _priorityDb; std::unique_ptr<MockMaintenanceOperationGenerator> _operationGenerator; std::unique_ptr<MockOperationStarter> _operationStarter; std::unique_ptr<MaintenanceScheduler> _scheduler; - void addBucketToDb(int bucketNum); -public: - void testPriorityClearedAfterScheduled(); - void testOperationIsScheduled(); - void testNoOperationsToSchedule(); - void testSuppressLowPrioritiesInEmergencyMode(); - void testPriorityNotClearedIfOperationNotStarted(); - - void setUp() override; + void SetUp() override; }; -CPPUNIT_TEST_SUITE_REGISTRATION(MaintenanceSchedulerTest); - void -MaintenanceSchedulerTest::setUp() +MaintenanceSchedulerTest::SetUp() { - _priorityDb.reset(new SimpleBucketPriorityDatabase()); - _operationGenerator.reset(new MockMaintenanceOperationGenerator()); - _operationStarter.reset(new MockOperationStarter()); - _scheduler.reset(new MaintenanceScheduler(*_operationGenerator, - *_priorityDb, - *_operationStarter)); + _priorityDb = std::make_unique<SimpleBucketPriorityDatabase>(); + _operationGenerator = std::make_unique<MockMaintenanceOperationGenerator>(); + _operationStarter = std::make_unique<MockOperationStarter>(); + _scheduler = std::make_unique<MaintenanceScheduler>(*_operationGenerator, *_priorityDb, *_operationStarter); } -void -MaintenanceSchedulerTest::testPriorityClearedAfterScheduled() -{ +TEST_F(MaintenanceSchedulerTest, priority_cleared_after_scheduled) { _priorityDb->setPriority(PrioritizedBucket(makeDocumentBucket(BucketId(16, 1)), Priority::VERY_HIGH)); _scheduler->tick(MaintenanceScheduler::NORMAL_SCHEDULING_MODE); - CPPUNIT_ASSERT_EQUAL(std::string(), _priorityDb->toString()); + EXPECT_EQ("", _priorityDb->toString()); } -void -MaintenanceSchedulerTest::testOperationIsScheduled() -{ +TEST_F(MaintenanceSchedulerTest, operation_is_scheduled) { _priorityDb->setPriority(PrioritizedBucket(makeDocumentBucket(BucketId(16, 1)), Priority::MEDIUM)); _scheduler->tick(MaintenanceScheduler::NORMAL_SCHEDULING_MODE); - CPPUNIT_ASSERT_EQUAL(std::string("Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri 100\n"), - _operationStarter->toString()); + EXPECT_EQ("Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri 100\n", + _operationStarter->toString()); } -void -MaintenanceSchedulerTest::testNoOperationsToSchedule() -{ +TEST_F(MaintenanceSchedulerTest, no_operations_toschedule) { WaitTimeMs waitMs(_scheduler->tick(MaintenanceScheduler::NORMAL_SCHEDULING_MODE)); - CPPUNIT_ASSERT_EQUAL(WaitTimeMs(1), waitMs); - CPPUNIT_ASSERT_EQUAL(std::string(), _operationStarter->toString()); + EXPECT_EQ(WaitTimeMs(1), waitMs); + EXPECT_EQ("", _operationStarter->toString()); } -void -MaintenanceSchedulerTest::testSuppressLowPrioritiesInEmergencyMode() -{ +TEST_F(MaintenanceSchedulerTest, suppress_low_priorities_in_emergency_mode) { _priorityDb->setPriority(PrioritizedBucket(makeDocumentBucket(BucketId(16, 1)), Priority::HIGH)); _priorityDb->setPriority(PrioritizedBucket(makeDocumentBucket(BucketId(16, 2)), Priority::VERY_HIGH)); - CPPUNIT_ASSERT_EQUAL(WaitTimeMs(0), _scheduler->tick(MaintenanceScheduler::RECOVERY_SCHEDULING_MODE)); - CPPUNIT_ASSERT_EQUAL(WaitTimeMs(1), _scheduler->tick(MaintenanceScheduler::RECOVERY_SCHEDULING_MODE)); - CPPUNIT_ASSERT_EQUAL(std::string("Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000002)), pri 0\n"), - _operationStarter->toString()); - CPPUNIT_ASSERT_EQUAL(std::string("PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri HIGH)\n"), - _priorityDb->toString()); + EXPECT_EQ(WaitTimeMs(0), _scheduler->tick(MaintenanceScheduler::RECOVERY_SCHEDULING_MODE)); + EXPECT_EQ(WaitTimeMs(1), _scheduler->tick(MaintenanceScheduler::RECOVERY_SCHEDULING_MODE)); + EXPECT_EQ("Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000002)), pri 0\n", + _operationStarter->toString()); + EXPECT_EQ("PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri HIGH)\n", + _priorityDb->toString()); } -void -MaintenanceSchedulerTest::testPriorityNotClearedIfOperationNotStarted() -{ +TEST_F(MaintenanceSchedulerTest, priority_not_cleared_if_operation_not_started) { _priorityDb->setPriority(PrioritizedBucket(makeDocumentBucket(BucketId(16, 1)), Priority::HIGH)); _operationStarter->setShouldStartOperations(false); WaitTimeMs waitMs(_scheduler->tick(MaintenanceScheduler::NORMAL_SCHEDULING_MODE)); - CPPUNIT_ASSERT_EQUAL(WaitTimeMs(1), waitMs); - CPPUNIT_ASSERT_EQUAL(std::string("PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri HIGH)\n"), - _priorityDb->toString()); + EXPECT_EQ(WaitTimeMs(1), waitMs); + EXPECT_EQ("PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri HIGH)\n", + _priorityDb->toString()); } } -} diff --git a/storage/src/tests/distributor/mergelimitertest.cpp b/storage/src/tests/distributor/mergelimitertest.cpp index 0b40424594b..b06630ea592 100644 --- a/storage/src/tests/distributor/mergelimitertest.cpp +++ b/storage/src/tests/distributor/mergelimitertest.cpp @@ -1,94 +1,65 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/storage/distributor/operations/idealstate/mergelimiter.h> -#include <vespa/vdstestlib/cppunit/macros.h> +#include <vespa/vespalib/gtest/gtest.h> + +using namespace ::testing; namespace storage::distributor { -struct MergeLimiterTest : public CppUnit::TestFixture -{ - void testKeepsAllBelowLimit(); - void testLessThanMaxUntrusted(); - void testMoreThanMaxUntrusted(); - void testAllUntrustedLessThanMaxVariants(); - void testAllUntrustedMoreThanMaxVariants(); - void testSourceOnlyLast(); - void limited_set_cannot_be_just_source_only(); - void non_source_only_replica_chosen_from_in_sync_group(); - void non_source_only_replicas_preferred_when_replicas_not_in_sync(); - void at_least_one_non_source_only_replica_chosen_when_all_trusted(); - void missing_replica_distinct_from_empty_replica(); - - CPPUNIT_TEST_SUITE(MergeLimiterTest); - CPPUNIT_TEST(testKeepsAllBelowLimit); - CPPUNIT_TEST(testLessThanMaxUntrusted); - CPPUNIT_TEST(testMoreThanMaxUntrusted); - CPPUNIT_TEST(testAllUntrustedLessThanMaxVariants); - CPPUNIT_TEST(testAllUntrustedMoreThanMaxVariants); - CPPUNIT_TEST(testSourceOnlyLast); - CPPUNIT_TEST(limited_set_cannot_be_just_source_only); - CPPUNIT_TEST(non_source_only_replica_chosen_from_in_sync_group); - CPPUNIT_TEST(non_source_only_replicas_preferred_when_replicas_not_in_sync); - CPPUNIT_TEST(at_least_one_non_source_only_replica_chosen_when_all_trusted); - CPPUNIT_TEST(missing_replica_distinct_from_empty_replica); - CPPUNIT_TEST_SUITE_END(); -}; +namespace { -CPPUNIT_TEST_SUITE_REGISTRATION(MergeLimiterTest); +using BucketCopyPtr = std::unique_ptr<BucketCopy>; +std::vector<BucketCopyPtr> _bucketDatabase; -namespace { - using BucketCopyPtr = std::unique_ptr<BucketCopy>; - std::vector<BucketCopyPtr> _bucketDatabase; - - struct NodeFactory { - std::vector<MergeMetaData> _nodes; - - NodeFactory& add(int index, int crc) { - _bucketDatabase.push_back(BucketCopyPtr( - new BucketCopy(0, index, api::BucketInfo(crc, 5, 10)))); - _nodes.push_back(MergeMetaData(index, *_bucketDatabase.back())); - return *this; - } - NodeFactory& addTrusted(int index, int crc) { - add(index, crc); - _bucketDatabase.back()->setTrusted(true); - return *this; - } - NodeFactory& addMissing(int index) { - add(index, 0x1); // "Magic" checksum value implying invalid/recently created replica - return *this; - } - NodeFactory& addEmpty(int index) { - add(index, 0x0); - return *this; - } - NodeFactory& setSourceOnly() { - _nodes.back()._sourceOnly = true; - return *this; - } - - operator const MergeLimiter::NodeArray&() const { return _nodes; } - }; - - #define ASSERT_LIMIT(maxNodes, nodes, result) \ - { \ - MergeLimiter limiter(maxNodes); \ - auto nodesCopy = nodes; \ - limiter.limitMergeToMaxNodes(nodesCopy); \ - std::ostringstream actual; \ - for (uint32_t i = 0; i < nodesCopy.size(); ++i) { \ - if (i != 0) actual << ","; \ - actual << nodesCopy[i]._nodeIndex; \ - if (nodesCopy[i]._sourceOnly) actual << 's'; \ - } \ - CPPUNIT_ASSERT_EQUAL(std::string(result), actual.str()); \ +struct NodeFactory { + std::vector<MergeMetaData> _nodes; + + NodeFactory& add(int index, int crc) { + _bucketDatabase.emplace_back( + std::make_unique<BucketCopy>(0, index, api::BucketInfo(crc, 5, 10))); + _nodes.emplace_back(MergeMetaData(index, *_bucketDatabase.back())); + return *this; + } + NodeFactory& addTrusted(int index, int crc) { + add(index, crc); + _bucketDatabase.back()->setTrusted(true); + return *this; + } + NodeFactory& addMissing(int index) { + add(index, 0x1); // "Magic" checksum value implying invalid/recently created replica + return *this; } + NodeFactory& addEmpty(int index) { + add(index, 0x0); + return *this; + } + NodeFactory& setSourceOnly() { + _nodes.back()._sourceOnly = true; + return *this; + } + + operator const MergeLimiter::NodeArray&() const { return _nodes; } +}; + +#define ASSERT_LIMIT(maxNodes, nodes, result) \ +{ \ + MergeLimiter limiter(maxNodes); \ + auto nodesCopy = nodes; \ + limiter.limitMergeToMaxNodes(nodesCopy); \ + std::ostringstream actual; \ + for (uint32_t i = 0; i < nodesCopy.size(); ++i) { \ + if (i != 0) actual << ","; \ + actual << nodesCopy[i]._nodeIndex; \ + if (nodesCopy[i]._sourceOnly) actual << 's'; \ + } \ + ASSERT_EQ(result, actual.str()); \ +} + } // If there is <= max nodes, then none should be removed. -void -MergeLimiterTest::testKeepsAllBelowLimit() -{ +TEST(MergeLimiterTest, keeps_all_below_limit) { MergeLimiter::NodeArray nodes(NodeFactory() .addTrusted(3, 0x4) .addTrusted(5, 0x4) @@ -100,9 +71,7 @@ MergeLimiterTest::testKeepsAllBelowLimit() } // If less than max nodes is untrusted, merge all untrusted copies with a // trusted one. (Optionally with extra trusted copies if there is space) -void -MergeLimiterTest::testLessThanMaxUntrusted() -{ +TEST(MergeLimiterTest, less_than_max_untrusted) { MergeLimiter::NodeArray nodes(NodeFactory() .addTrusted(3, 0x4) .addTrusted(5, 0x4) @@ -113,9 +82,7 @@ MergeLimiterTest::testLessThanMaxUntrusted() } // With more than max untrusted, just merge one trusted with as many untrusted // that fits. -void -MergeLimiterTest::testMoreThanMaxUntrusted() -{ +TEST(MergeLimiterTest, more_than_max_untrusted) { MergeLimiter::NodeArray nodes(NodeFactory() .addTrusted(3, 0x4) .addTrusted(5, 0x4) @@ -129,9 +96,7 @@ MergeLimiterTest::testMoreThanMaxUntrusted() // With nothing trusted. If there is <= max different variants (checksums), // merge one of each variant. After this merge, all these nodes can be set // trusted. (Except for any source only ones) -void -MergeLimiterTest::testAllUntrustedLessThanMaxVariants() -{ +TEST(MergeLimiterTest, all_untrusted_less_than_max_variants) { MergeLimiter::NodeArray nodes(NodeFactory() .add(3, 0x4) .add(5, 0x4) @@ -144,9 +109,7 @@ MergeLimiterTest::testAllUntrustedLessThanMaxVariants() } // With nothing trusted and more than max variants, we just have to merge one // of each variant until we end up with less than max variants. -void -MergeLimiterTest::testAllUntrustedMoreThanMaxVariants() -{ +TEST(MergeLimiterTest, all_untrusted_more_than_max_variants) { MergeLimiter::NodeArray nodes(NodeFactory() .add(3, 0x4) .add(5, 0x5) @@ -160,9 +123,7 @@ MergeLimiterTest::testAllUntrustedMoreThanMaxVariants() // With more than max untrusted, just merge one trusted with as many untrusted // that fits. -void -MergeLimiterTest::testSourceOnlyLast() -{ +TEST(MergeLimiterTest, source_only_last) { MergeLimiter::NodeArray nodes(NodeFactory() .addTrusted(3, 0x4) .addTrusted(5, 0x4).setSourceOnly() @@ -174,7 +135,7 @@ MergeLimiterTest::testSourceOnlyLast() ASSERT_LIMIT(4, nodes, "9,3,5s,2s"); } -void MergeLimiterTest::limited_set_cannot_be_just_source_only() { +TEST(MergeLimiterTest, limited_set_cannot_be_just_source_only) { MergeLimiter::NodeArray nodes(NodeFactory() .addTrusted(9, 0x6) .addTrusted(2, 0x6) @@ -184,7 +145,7 @@ void MergeLimiterTest::limited_set_cannot_be_just_source_only() { ASSERT_LIMIT(3, nodes, "2,13s,1s"); } -void MergeLimiterTest::non_source_only_replica_chosen_from_in_sync_group() { +TEST(MergeLimiterTest, non_source_only_replica_chosen_from_in_sync_group) { // nodes 9, 2, 13 are all in sync. Merge limiter will currently by default // pop the _last_ node of an in-sync replica "group" when outputting a limited // set. Unless we special-case source-only replicas here, we'd end up with an @@ -198,7 +159,7 @@ void MergeLimiterTest::non_source_only_replica_chosen_from_in_sync_group() { ASSERT_LIMIT(3, nodes, "2,13s,1s"); } -void MergeLimiterTest::non_source_only_replicas_preferred_when_replicas_not_in_sync() { +TEST(MergeLimiterTest, non_source_only_replicas_preferred_when_replicas_not_in_sync) { MergeLimiter::NodeArray nodes(NodeFactory() .add(9, 0x4) .add(2, 0x5) @@ -208,7 +169,7 @@ void MergeLimiterTest::non_source_only_replicas_preferred_when_replicas_not_in_s ASSERT_LIMIT(3, nodes, "9,2,13s"); } -void MergeLimiterTest::at_least_one_non_source_only_replica_chosen_when_all_trusted() { +TEST(MergeLimiterTest, at_least_one_non_source_only_replica_chosen_when_all_trusted) { MergeLimiter::NodeArray nodes(NodeFactory() .addTrusted(9, 0x6) .addTrusted(2, 0x6) @@ -218,7 +179,7 @@ void MergeLimiterTest::at_least_one_non_source_only_replica_chosen_when_all_trus ASSERT_LIMIT(3, nodes, "2,13s,1s"); } -void MergeLimiterTest::missing_replica_distinct_from_empty_replica() { +TEST(MergeLimiterTest, missing_replica_distinct_from_empty_replica) { MergeLimiter::NodeArray nodes(NodeFactory() .addEmpty(3) .addEmpty(5) diff --git a/storage/src/tests/distributor/mergeoperationtest.cpp b/storage/src/tests/distributor/mergeoperationtest.cpp index 672c1d06124..75faddbe667 100644 --- a/storage/src/tests/distributor/mergeoperationtest.cpp +++ b/storage/src/tests/distributor/mergeoperationtest.cpp @@ -1,70 +1,35 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <boost/lexical_cast.hpp> -#include <cppunit/extensions/HelperMacros.h> -#include <iomanip> +#include <vespa/document/test/make_document_bucket.h> #include <tests/common/dummystoragelink.h> #include <vespa/storage/distributor/idealstatemanager.h> #include <vespa/storageapi/message/persistence.h> #include <vespa/storage/distributor/operations/idealstate/mergeoperation.h> #include <vespa/storage/distributor/bucketdbupdater.h> -#include <tests/distributor/distributortestutil.h> -#include <vespa/document/test/make_document_bucket.h> #include <vespa/storage/distributor/distributor.h> +#include <tests/distributor/distributortestutil.h> #include <vespa/vespalib/text/stringtokenizer.h> +#include <vespa/vespalib/gtest/gtest.h> -using std::shared_ptr; using document::test::makeDocumentBucket; +using namespace ::testing; -namespace storage { -namespace distributor { - -class MergeOperationTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ - CPPUNIT_TEST_SUITE(MergeOperationTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(testFailIfSourceOnlyCopiesChanged); - CPPUNIT_TEST(testGenerateNodeList); - CPPUNIT_TEST(doNotRemoveCopiesWithPendingMessages); - CPPUNIT_TEST(allow_deleting_active_source_only_replica); - CPPUNIT_TEST(testMarkRedundantTrustedCopiesAsSourceOnly); - CPPUNIT_TEST(onlyMarkRedundantRetiredReplicasAsSourceOnly); - CPPUNIT_TEST(mark_post_merge_redundant_replicas_source_only); - CPPUNIT_TEST(merge_operation_is_blocked_by_any_busy_target_node); - CPPUNIT_TEST(missing_replica_is_included_in_limited_node_list); - CPPUNIT_TEST_SUITE_END(); +namespace storage::distributor { +struct MergeOperationTest : Test, DistributorTestUtil { std::unique_ptr<PendingMessageTracker> _pendingTracker; -protected: - void testSimple(); - void testFailIfSourceOnlyCopiesChanged(); - void testGenerateNodeList(); - void doNotRemoveCopiesWithPendingMessages(); - void allow_deleting_active_source_only_replica(); - void testMarkRedundantTrustedCopiesAsSourceOnly(); - void onlyMarkRedundantRetiredReplicasAsSourceOnly(); - void mark_post_merge_redundant_replicas_source_only(); - void merge_operation_is_blocked_by_any_busy_target_node(); - void missing_replica_is_included_in_limited_node_list(); - -public: - void setUp() override { + void SetUp() override { createLinks(); - _pendingTracker.reset(new PendingMessageTracker(getComponentRegister())); + _pendingTracker = std::make_unique<PendingMessageTracker>(getComponentRegister()); _sender.setPendingMessageTracker(*_pendingTracker); } - void tearDown() override { + void TearDown() override { close(); } }; -CPPUNIT_TEST_SUITE_REGISTRATION(MergeOperationTest); - -void -MergeOperationTest::testSimple() -{ +TEST_F(MergeOperationTest, simple) { getClock().setAbsoluteTimeInSeconds(10); addNodesToBucketDB(document::BucketId(16, 1), @@ -79,25 +44,20 @@ MergeOperationTest::testSimple() op.setIdealStateManager(&getIdealStateManager()); op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string( - "MergeBucketCommand(BucketId(0x4000000000000001), to time 10000000, " - "cluster state version: 0, nodes: [0, 2, 1 (source only)], chain: [], " - "reasons to start: ) => 0"), - _sender.getLastCommand(true)); + ASSERT_EQ("MergeBucketCommand(BucketId(0x4000000000000001), to time 10000000, " + "cluster state version: 0, nodes: [0, 2, 1 (source only)], chain: [], " + "reasons to start: ) => 0", + _sender.getLastCommand(true)); sendReply(op); - CPPUNIT_ASSERT_EQUAL( - std::string("DeleteBucketCommand(BucketId(0x4000000000000001)) " - "Reasons to start: => 1"), - _sender.getLastCommand(true)); + ASSERT_EQ("DeleteBucketCommand(BucketId(0x4000000000000001)) " + "Reasons to start: => 1", + _sender.getLastCommand(true)); } -void -MergeOperationTest::testFailIfSourceOnlyCopiesChanged() -{ +TEST_F(MergeOperationTest, fail_if_source_only_copies_changed) { getClock().setAbsoluteTimeInSeconds(10); addNodesToBucketDB(document::BucketId(16, 1), @@ -116,11 +76,10 @@ MergeOperationTest::testFailIfSourceOnlyCopiesChanged() "cluster state version: 0, nodes: [0, 2, 1 (source only)], chain: [], " "reasons to start: ) => 0"); - CPPUNIT_ASSERT_EQUAL(merge, _sender.getLastCommand(true)); + ASSERT_EQ(merge, _sender.getLastCommand(true)); { - const api::MergeBucketCommand& cmd( - dynamic_cast<api::MergeBucketCommand&>(*_sender.commands[0])); - CPPUNIT_ASSERT_EQUAL(uint16_t(0), cmd.getSourceIndex()); + auto& cmd = dynamic_cast<api::MergeBucketCommand&>(*_sender.command(0)); + EXPECT_EQ(0, cmd.getSourceIndex()); } // Source-only copy changed during merge @@ -130,8 +89,8 @@ MergeOperationTest::testFailIfSourceOnlyCopiesChanged() "2=10/1/1/t"); sendReply(op); // Should not be a remove here! - CPPUNIT_ASSERT_EQUAL(merge, _sender.getLastCommand(true)); - CPPUNIT_ASSERT(!op.ok()); + ASSERT_EQ(merge, _sender.getLastCommand(true)); + EXPECT_FALSE(op.ok()); } namespace { @@ -176,130 +135,96 @@ std::string getNodeList(std::string state, uint32_t redundancy, std::string exis } } -void -MergeOperationTest::testGenerateNodeList() -{ +TEST_F(MergeOperationTest, generate_node_list) { // If this fails, the distribution has changed and the rest of the test will // likely fail - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9,2,1,4"), - getNodeList("storage:10", 10, "0,1,2,3,4,5,6,7,8,9")); + ASSERT_EQ("3,5,7,6,8,0,9,2,1,4", + getNodeList("storage:10", 10, "0,1,2,3,4,5,6,7,8,9")); // Nodes that are initializing should be treated as up - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7s,6s"), - getNodeList("storage:10 .3.s:i .5.s:i", 2, "7,6,3,5")); // Ideal: 3,5 + EXPECT_EQ("3,5,7s,6s", + getNodeList("storage:10 .3.s:i .5.s:i", 2, "7,6,3,5")); // Ideal: 3,5 // Order is given by ideal state algorithm, not order of storagenodes in bucket db - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7"), - getNodeList("storage:10", 3, "3,7,5")); + EXPECT_EQ("3,5,7", + getNodeList("storage:10", 3, "3,7,5")); // Node not in ideal state will be used if not enough nodes in ideal state - CPPUNIT_ASSERT_EQUAL( - std::string("3,7,6"), - getNodeList("storage:10", 3, "3,7,6")); + EXPECT_EQ("3,7,6", + getNodeList("storage:10", 3, "3,7,6")); // Nodes not in ideal state will be included as source only after redundancy // is reached - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,8s"), - getNodeList("storage:10", 3, "3,5,7,8")); + EXPECT_EQ("3,5,7,8s", + getNodeList("storage:10", 3, "3,5,7,8")); // Need at least redundancy copies that are not source only - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,8,9s"), - getNodeList("storage:10", 3, "3,5,8,9")); + EXPECT_EQ("3,5,8,9s", + getNodeList("storage:10", 3, "3,5,8,9")); // Order is given by storagenodes in bucket db // when no nodes are in ideal state - CPPUNIT_ASSERT_EQUAL( - std::string("4,1,2"), - getNodeList("storage:10", 3, "4,1,2")); - - CPPUNIT_ASSERT_EQUAL( - std::string("3,0s,1s,2s,4s,5s,6s,7s,8s,9s"), - getNodeList("storage:10", 1, "0,1,2,3,4,5,6,7,8,9")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,0s,1s,2s,4s,6s,7s,8s,9s"), - getNodeList("storage:10", 2, "0,1,2,3,4,5,6,7,8,9")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,0s,1s,2s,4s,6s,8s,9s"), - getNodeList("storage:10", 3, "0,1,2,3,4,5,6,7,8,9")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,0s,1s,2s,4s,8s,9s"), - getNodeList("storage:10", 4, "0,1,2,3,4,5,6,7,8,9")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0s,1s,2s,4s,9s"), - getNodeList("storage:10", 5, "0,1,2,3,4,5,6,7,8,9")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,1s,2s,4s,9s"), - getNodeList("storage:10", 6, "0,1,2,3,4,5,6,7,8,9")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9,1s,2s,4s"), - getNodeList("storage:10", 7, "0,1,2,3,4,5,6,7,8,9")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9,2,1s,4s"), - getNodeList("storage:10", 8, "0,1,2,3,4,5,6,7,8,9")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9,2,1,4s"), - getNodeList("storage:10", 9, "0,1,2,3,4,5,6,7,8,9")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9,2,1,4"), - getNodeList("storage:10", 10, "0,1,2,3,4,5,6,7,8,9")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,9s,8s,7s,6s,5s,4s,2s,1s,0s"), - getNodeList("storage:10", 1, "9,8,7,6,5,4,3,2,1,0")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,9s,8s,7s,6s,4s,2s,1s,0s"), - getNodeList("storage:10", 2, "9,8,7,6,5,4,3,2,1,0")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,9s,8s,6s,4s,2s,1s,0s"), - getNodeList("storage:10", 3, "9,8,7,6,5,4,3,2,1,0")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,9s,8s,4s,2s,1s,0s"), - getNodeList("storage:10", 4, "9,8,7,6,5,4,3,2,1,0")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,9s,4s,2s,1s,0s"), - getNodeList("storage:10", 5, "9,8,7,6,5,4,3,2,1,0")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9s,4s,2s,1s"), - getNodeList("storage:10", 6, "9,8,7,6,5,4,3,2,1,0")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9,4s,2s,1s"), - getNodeList("storage:10", 7, "9,8,7,6,5,4,3,2,1,0")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9,2,4s,1s"), - getNodeList("storage:10", 8, "9,8,7,6,5,4,3,2,1,0")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9,2,1,4s"), - getNodeList("storage:10", 9, "9,8,7,6,5,4,3,2,1,0")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9,2,1,4"), - getNodeList("storage:10", 10, "9,8,7,6,5,4,3,2,1,0")); + EXPECT_EQ("4,1,2", + getNodeList("storage:10", 3, "4,1,2")); + + EXPECT_EQ("3,0s,1s,2s,4s,5s,6s,7s,8s,9s", + getNodeList("storage:10", 1, "0,1,2,3,4,5,6,7,8,9")); + EXPECT_EQ("3,5,0s,1s,2s,4s,6s,7s,8s,9s", + getNodeList("storage:10", 2, "0,1,2,3,4,5,6,7,8,9")); + EXPECT_EQ("3,5,7,0s,1s,2s,4s,6s,8s,9s", + getNodeList("storage:10", 3, "0,1,2,3,4,5,6,7,8,9")); + EXPECT_EQ("3,5,7,6,0s,1s,2s,4s,8s,9s", + getNodeList("storage:10", 4, "0,1,2,3,4,5,6,7,8,9")); + EXPECT_EQ("3,5,7,6,8,0s,1s,2s,4s,9s", + getNodeList("storage:10", 5, "0,1,2,3,4,5,6,7,8,9")); + EXPECT_EQ("3,5,7,6,8,0,1s,2s,4s,9s", + getNodeList("storage:10", 6, "0,1,2,3,4,5,6,7,8,9")); + EXPECT_EQ("3,5,7,6,8,0,9,1s,2s,4s", + getNodeList("storage:10", 7, "0,1,2,3,4,5,6,7,8,9")); + EXPECT_EQ("3,5,7,6,8,0,9,2,1s,4s", + getNodeList("storage:10", 8, "0,1,2,3,4,5,6,7,8,9")); + EXPECT_EQ("3,5,7,6,8,0,9,2,1,4s", + getNodeList("storage:10", 9, "0,1,2,3,4,5,6,7,8,9")); + EXPECT_EQ("3,5,7,6,8,0,9,2,1,4", + getNodeList("storage:10", 10, "0,1,2,3,4,5,6,7,8,9")); + EXPECT_EQ("3,9s,8s,7s,6s,5s,4s,2s,1s,0s", + getNodeList("storage:10", 1, "9,8,7,6,5,4,3,2,1,0")); + EXPECT_EQ("3,5,9s,8s,7s,6s,4s,2s,1s,0s", + getNodeList("storage:10", 2, "9,8,7,6,5,4,3,2,1,0")); + EXPECT_EQ("3,5,7,9s,8s,6s,4s,2s,1s,0s", + getNodeList("storage:10", 3, "9,8,7,6,5,4,3,2,1,0")); + EXPECT_EQ("3,5,7,6,9s,8s,4s,2s,1s,0s", + getNodeList("storage:10", 4, "9,8,7,6,5,4,3,2,1,0")); + EXPECT_EQ("3,5,7,6,8,9s,4s,2s,1s,0s", + getNodeList("storage:10", 5, "9,8,7,6,5,4,3,2,1,0")); + EXPECT_EQ("3,5,7,6,8,0,9s,4s,2s,1s", + getNodeList("storage:10", 6, "9,8,7,6,5,4,3,2,1,0")); + EXPECT_EQ("3,5,7,6,8,0,9,4s,2s,1s", + getNodeList("storage:10", 7, "9,8,7,6,5,4,3,2,1,0")); + EXPECT_EQ("3,5,7,6,8,0,9,2,4s,1s", + getNodeList("storage:10", 8, "9,8,7,6,5,4,3,2,1,0")); + EXPECT_EQ("3,5,7,6,8,0,9,2,1,4s", + getNodeList("storage:10", 9, "9,8,7,6,5,4,3,2,1,0")); + EXPECT_EQ("3,5,7,6,8,0,9,2,1,4", + getNodeList("storage:10", 10, "9,8,7,6,5,4,3,2,1,0")); // Trusted copies can be source-only if they are in the non-ideal node set. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9,1s,2s,4s"), - getNodeList("storage:10", 7, "0,1t,2t,3,4,5,6,7,8,9")); + EXPECT_EQ("3,5,7,6,8,0,9,1s,2s,4s", + getNodeList("storage:10", 7, "0,1t,2t,3,4,5,6,7,8,9")); - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6,8,0,9,1s,2s,4s"), - getNodeList("storage:10", 7, "0,1,2t,3,4,5,6,7,8,9")); + EXPECT_EQ("3,5,7,6,8,0,9,1s,2s,4s", + getNodeList("storage:10", 7, "0,1,2t,3,4,5,6,7,8,9")); // Retired nodes are not in ideal state // Ideal: 5,7 - CPPUNIT_ASSERT_EQUAL( - std::string("0,2,3s"), - getNodeList("storage:10 .3.s:r", 2, "0,2,3")); + EXPECT_EQ("0,2,3s", + getNodeList("storage:10 .3.s:r", 2, "0,2,3")); // Ideal: 5,7,6 - CPPUNIT_ASSERT_EQUAL( - std::string("0,2,3"), - getNodeList("storage:10 .3.s:r", 3, "0,2,3")); + EXPECT_EQ("0,2,3", + getNodeList("storage:10 .3.s:r", 3, "0,2,3")); } -void -MergeOperationTest::doNotRemoveCopiesWithPendingMessages() { +TEST_F(MergeOperationTest, do_not_remove_copies_with_pending_messages) { document::BucketId bucket(16, 1); getClock().setAbsoluteTimeInSeconds(10); @@ -318,20 +243,20 @@ MergeOperationTest::doNotRemoveCopiesWithPendingMessages() { "cluster state version: 0, nodes: [0, 2, 1 (source only)], chain: [], " "reasons to start: ) => 0"); - CPPUNIT_ASSERT_EQUAL(merge, _sender.getLastCommand(true)); + ASSERT_EQ(merge, _sender.getLastCommand(true)); // Suddenly a wild operation appears to the source only copy! // Removes are blocked by all and any operation types, so can just choose // at will. - api::StorageMessage::SP msg( - new api::SetBucketStateCommand(makeDocumentBucket(bucket), api::SetBucketStateCommand::ACTIVE)); + auto msg = std::make_shared<api::SetBucketStateCommand>( + makeDocumentBucket(bucket), api::SetBucketStateCommand::ACTIVE); msg->setAddress(api::StorageMessageAddress("storage", lib::NodeType::STORAGE, 1)); _pendingTracker->insert(msg); sendReply(op); // Should not be a remove here! - CPPUNIT_ASSERT_EQUAL(merge, _sender.getLastCommand(true)); - CPPUNIT_ASSERT(!op.ok()); + ASSERT_EQ(merge, _sender.getLastCommand(true)); + EXPECT_FALSE(op.ok()); } /* @@ -359,9 +284,7 @@ MergeOperationTest::doNotRemoveCopiesWithPendingMessages() { * should be an uncommon edge case and it's arguably better than to never * activate the ideal replicas at all. */ -void -MergeOperationTest::allow_deleting_active_source_only_replica() -{ +TEST_F(MergeOperationTest, allow_deleting_active_source_only_replica) { getClock().setAbsoluteTimeInSeconds(10); addNodesToBucketDB(document::BucketId(16, 1), @@ -379,111 +302,92 @@ MergeOperationTest::allow_deleting_active_source_only_replica() "MergeBucketCommand(BucketId(0x4000000000000001), to time " "10000000, cluster state version: 0, nodes: [0, 2, 1 " "(source only)], chain: [], reasons to start: ) => 0"); - CPPUNIT_ASSERT_EQUAL(merge, _sender.getLastCommand(true)); + ASSERT_EQ(merge, _sender.getLastCommand(true)); sendReply(op); - CPPUNIT_ASSERT_EQUAL( - std::string("DeleteBucketCommand(BucketId(0x4000000000000001)) " - "Reasons to start: => 1"), - _sender.getLastCommand(true)); + ASSERT_EQ("DeleteBucketCommand(BucketId(0x4000000000000001)) " + "Reasons to start: => 1", + _sender.getLastCommand(true)); } -void -MergeOperationTest::testMarkRedundantTrustedCopiesAsSourceOnly() -{ +TEST_F(MergeOperationTest, MarkRedundantTrustedCopiesAsSourceOnly) { // This test uses the same distribution as testGenerateNodeList(), i.e. // an ideal state sequence of [3, 5, 7, 6, 8, 0, 9, 2, 1, 4] // 3 redundancy, 5 trusted -> 2 trusted source only. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6s,8s"), - getNodeList("storage:10", 3, "3t,5t,7t,6t,8t")); + EXPECT_EQ("3,5,7,6s,8s", + getNodeList("storage:10", 3, "3t,5t,7t,6t,8t")); // 3 redundancy, 4 trusted -> 1 trusted source only. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6s,8s"), - getNodeList("storage:10", 3, "3t,5t,7t,6t,8")); + EXPECT_EQ("3,5,7,6s,8s", + getNodeList("storage:10", 3, "3t,5t,7t,6t,8")); // 3 redundancy, 3 trusted -> 0 trusted source only, 2 non-trusted sources. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6s,8s"), - getNodeList("storage:10", 3, "3t,5t,7t,6,8")); + EXPECT_EQ("3,5,7,6s,8s", + getNodeList("storage:10", 3, "3t,5t,7t,6,8")); // Trusted-ness should not be taken into account when marking nodes as source-only. // 2 out of 3 ideal replicas trusted. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6s,8s"), - getNodeList("storage:10", 3, "3t,5t,7,6t,8t")); + EXPECT_EQ("3,5,7,6s,8s", + getNodeList("storage:10", 3, "3t,5t,7,6t,8t")); // 1 out of 3 ideal replicas trusted. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6s,8s"), - getNodeList("storage:10", 3, "3t,5,7,6t,8t")); + EXPECT_EQ("3,5,7,6s,8s", + getNodeList("storage:10", 3, "3t,5,7,6t,8t")); // 0 out of 3 ideal replicas trusted. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6s,8s"), - getNodeList("storage:10", 3, "3,5,7,6t,8t")); + EXPECT_EQ("3,5,7,6s,8s", + getNodeList("storage:10", 3, "3,5,7,6t,8t")); // #redundancy of trusted, but none are ideal. Non-ideal trusted may be // marked as source only. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6s,8s,0s,9s"), - getNodeList("storage:10", 3, "3,5,7,6,8t,0t,9t")); + EXPECT_EQ("3,5,7,6s,8s,0s,9s", + getNodeList("storage:10", 3, "3,5,7,6,8t,0t,9t")); // Allow for removing excess trusted, non-ideal copies. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6s,8s,0s,9s"), - getNodeList("storage:10", 3, "3,5,7,6t,8t,0t,9t")); + EXPECT_EQ("3,5,7,6s,8s,0s,9s", + getNodeList("storage:10", 3, "3,5,7,6t,8t,0t,9t")); } -void -MergeOperationTest::onlyMarkRedundantRetiredReplicasAsSourceOnly() -{ +TEST_F(MergeOperationTest, only_mark_redundant_retired_replicas_as_source_only) { // No nodes in ideal state and all nodes are retired. With redundancy of 2 // we can only mark the last replica in the DB as source-only. Retired // nodes are meant as source-only due to being migrated away from, but // source-only nodes will have their replica removed after a successful // merge, which we cannot allow to happen here. - CPPUNIT_ASSERT_EQUAL( - std::string("1,0,2s"), - getNodeList("storage:3 .0.s:r .1.s:r .2.s:r", 2, "1,0,2")); + EXPECT_EQ("1,0,2s", + getNodeList("storage:3 .0.s:r .1.s:r .2.s:r", 2, "1,0,2")); } -void MergeOperationTest::mark_post_merge_redundant_replicas_source_only() { +TEST_F(MergeOperationTest, mark_post_merge_redundant_replicas_source_only) { // Ideal state sequence is [3, 5, 7, 6, 8, 0, 9, 2, 1, 4] // Retired node 7 is not part of the #redundancy ideal state and should be moved // to node 6. Once the merge is done we'll end up with too many replicas unless // we allow marking the to-be-moved replica as source only. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,6,7s"), - getNodeList("storage:10 .7.s:r", 3, "3t,5t,7t,6")); + EXPECT_EQ("3,5,6,7s", + getNodeList("storage:10 .7.s:r", 3, "3t,5t,7t,6")); // Should be allowed to mark as source only even if retired replica is the // only trusted replica at the time the merge starts. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,6,7s"), - getNodeList("storage:10 .7.s:r", 3, "3,5,7t,6")); + EXPECT_EQ("3,5,6,7s", + getNodeList("storage:10 .7.s:r", 3, "3,5,7t,6")); // This extends to multiple retired nodes. - CPPUNIT_ASSERT_EQUAL( - std::string("3,6,8,5s,7s"), - getNodeList("storage:10 .5.s:r .7.s:r", 3, "3t,5t,7t,6,8")); + EXPECT_EQ("3,6,8,5s,7s", + getNodeList("storage:10 .5.s:r .7.s:r", 3, "3t,5t,7t,6,8")); // If number of post-merge ideal nodes is lower than desired redundancy, don't // mark any as source only. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6"), - getNodeList("storage:10", 5, "3,5,7,6")); + EXPECT_EQ("3,5,7,6", + getNodeList("storage:10", 5, "3,5,7,6")); // Same applies to when post-merge ideal nodes is _equal_ to desired redundancy. - CPPUNIT_ASSERT_EQUAL( - std::string("3,5,7,6"), - getNodeList("storage:10", 4, "3,5,7,6")); + EXPECT_EQ("3,5,7,6", + getNodeList("storage:10", 4, "3,5,7,6")); } -void MergeOperationTest::merge_operation_is_blocked_by_any_busy_target_node() { +TEST_F(MergeOperationTest, merge_operation_is_blocked_by_any_busy_target_node) { getClock().setAbsoluteTimeInSeconds(10); addNodesToBucketDB(document::BucketId(16, 1), "0=10/1/1/t,1=20/1/1,2=10/1/1/t"); enableDistributorClusterState("distributor:1 storage:3"); @@ -492,21 +396,21 @@ void MergeOperationTest::merge_operation_is_blocked_by_any_busy_target_node() { // Should not block on nodes _not_ included in operation node set _pendingTracker->getNodeInfo().setBusy(3, std::chrono::seconds(10)); - CPPUNIT_ASSERT(!op.isBlocked(*_pendingTracker)); + EXPECT_FALSE(op.isBlocked(*_pendingTracker)); // Node 1 is included in operation node set and should cause a block _pendingTracker->getNodeInfo().setBusy(0, std::chrono::seconds(10)); - CPPUNIT_ASSERT(op.isBlocked(*_pendingTracker)); + EXPECT_TRUE(op.isBlocked(*_pendingTracker)); getClock().addSecondsToTime(11); - CPPUNIT_ASSERT(!op.isBlocked(*_pendingTracker)); // No longer busy + EXPECT_FALSE(op.isBlocked(*_pendingTracker)); // No longer busy // Should block on other operation nodes than the first listed as well _pendingTracker->getNodeInfo().setBusy(1, std::chrono::seconds(10)); - CPPUNIT_ASSERT(op.isBlocked(*_pendingTracker)); + EXPECT_TRUE(op.isBlocked(*_pendingTracker)); } -void MergeOperationTest::missing_replica_is_included_in_limited_node_list() { +TEST_F(MergeOperationTest, missing_replica_is_included_in_limited_node_list) { setupDistributor(Redundancy(4), NodeCount(4), "distributor:1 storage:4"); getClock().setAbsoluteTimeInSeconds(10); addNodesToBucketDB(document::BucketId(16, 1), "1=0/0/0/t,2=0/0/0/t,3=0/0/0/t"); @@ -516,12 +420,10 @@ void MergeOperationTest::missing_replica_is_included_in_limited_node_list() { op.start(_sender, framework::MilliSecTime(0)); // Must include missing node 0 and not just 2 existing replicas - CPPUNIT_ASSERT_EQUAL( - std::string("MergeBucketCommand(BucketId(0x4000000000000001), to time 10000000, " - "cluster state version: 0, nodes: [0, 1], chain: [], " - "reasons to start: ) => 0"), - _sender.getLastCommand(true)); + EXPECT_EQ("MergeBucketCommand(BucketId(0x4000000000000001), to time 10000000, " + "cluster state version: 0, nodes: [0, 1], chain: [], " + "reasons to start: ) => 0", + _sender.getLastCommand(true)); } -} // distributor -} // storage +} // storage::distributor diff --git a/storage/src/tests/distributor/messagesenderstub.h b/storage/src/tests/distributor/messagesenderstub.h deleted file mode 100644 index 1b526813ef7..00000000000 --- a/storage/src/tests/distributor/messagesenderstub.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#pragma once - -#include <vespa/storage/distributor/distributormessagesender.h> -#include <cassert> -#include <vector> -#include <string> - -namespace storage { - -struct MessageSenderStub : distributor::DistributorMessageSender -{ - std::vector<std::shared_ptr<api::StorageCommand> > commands; - std::vector<std::shared_ptr<api::StorageReply> > replies; - - MessageSenderStub(); - ~MessageSenderStub(); - - void clear() { - commands.clear(); - replies.clear(); - } - - void sendCommand(const std::shared_ptr<api::StorageCommand>& cmd) override { - commands.push_back(cmd); - } - - void sendReply(const std::shared_ptr<api::StorageReply>& reply) override { - replies.push_back(reply); - } - - std::string getLastCommand(bool verbose = true) const; - - std::string getCommands(bool includeAddress = false, - bool verbose = false, - uint32_t fromIndex = 0) const; - - std::string getLastReply(bool verbose = true) const; - - std::string getReplies(bool includeAddress = false, - bool verbose = false) const; - - std::string dumpMessage(const api::StorageMessage& msg, - bool includeAddress, - bool verbose) const; - - int getDistributorIndex() const override { - return 0; - } - - const std::string& getClusterName() const override { - return _clusterName; - } - - const distributor::PendingMessageTracker& getPendingMessageTracker() const override { - assert(_pendingMessageTracker); - return *_pendingMessageTracker; - } - - void setPendingMessageTracker(distributor::PendingMessageTracker& tracker) { - _pendingMessageTracker = &tracker; - } -private: - std::string _clusterName; - distributor::PendingMessageTracker* _pendingMessageTracker; -}; - -} diff --git a/storage/src/tests/distributor/nodeinfotest.cpp b/storage/src/tests/distributor/nodeinfotest.cpp index 0363f25831a..d729c686fa3 100644 --- a/storage/src/tests/distributor/nodeinfotest.cpp +++ b/storage/src/tests/distributor/nodeinfotest.cpp @@ -1,46 +1,17 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> -#include <iomanip> -#include <iostream> -#include <memory> -#include <vespa/storageapi/message/persistence.h> -#include <vespa/storageframework/defaultimplementation/clock/fakeclock.h> -#include <vespa/storage/distributor/bucketdbupdater.h> -#include <vespa/storageapi/message/bucket.h> -#include <vespa/storageapi/message/state.h> -#include <vespa/document/fieldvalue/document.h> -#include <vespa/vdslib/state/random.h> -#include <vespa/storageapi/message/bucket.h> -#include <vespa/storage/distributor/pendingclusterstate.h> -#include <vespa/vespalib/text/stringtokenizer.h> #include <vespa/storage/distributor/nodeinfo.h> +#include <vespa/storageframework/defaultimplementation/clock/fakeclock.h> +#include <vespa/vespalib/gtest/gtest.h> -#include <iostream> -#include <fstream> -#include <string> - -namespace storage { -namespace distributor { - -class NodeInfoTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(NodeInfoTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST_SUITE_END(); -public: - void testSimple(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(NodeInfoTest); +namespace storage::distributor { -void -NodeInfoTest::testSimple() -{ +TEST(NodeInfoTest, simple) { framework::defaultimplementation::FakeClock clock; NodeInfo info(clock); - CPPUNIT_ASSERT_EQUAL(0, (int)info.getPendingCount(3)); - CPPUNIT_ASSERT_EQUAL(0, (int)info.getPendingCount(9)); + EXPECT_EQ(0, info.getPendingCount(3)); + EXPECT_EQ(0, info.getPendingCount(9)); info.incPending(3); info.incPending(3); @@ -52,10 +23,10 @@ NodeInfoTest::testSimple() info.incPending(4); info.decPending(3); - CPPUNIT_ASSERT_EQUAL(2, (int)info.getPendingCount(3)); - CPPUNIT_ASSERT_EQUAL(1, (int)info.getPendingCount(4)); - CPPUNIT_ASSERT_EQUAL(1, (int)info.getPendingCount(7)); - CPPUNIT_ASSERT_EQUAL(0, (int)info.getPendingCount(5)); + EXPECT_EQ(2, info.getPendingCount(3)); + EXPECT_EQ(1, info.getPendingCount(4)); + EXPECT_EQ(1, info.getPendingCount(7)); + EXPECT_EQ(0, info.getPendingCount(5)); info.setBusy(5, std::chrono::seconds(60)); clock.addSecondsToTime(10); @@ -63,19 +34,17 @@ NodeInfoTest::testSimple() clock.addSecondsToTime(20); info.setBusy(42, std::chrono::seconds(60)); - CPPUNIT_ASSERT_EQUAL(true, info.isBusy(5)); - CPPUNIT_ASSERT_EQUAL(true, info.isBusy(1)); - CPPUNIT_ASSERT_EQUAL(true, info.isBusy(42)); - CPPUNIT_ASSERT_EQUAL(false, info.isBusy(7)); + EXPECT_TRUE(info.isBusy(5)); + EXPECT_TRUE(info.isBusy(1)); + EXPECT_TRUE(info.isBusy(42)); + EXPECT_FALSE(info.isBusy(7)); clock.addSecondsToTime(42); - CPPUNIT_ASSERT_EQUAL(false, info.isBusy(5)); - CPPUNIT_ASSERT_EQUAL(false, info.isBusy(1)); - CPPUNIT_ASSERT_EQUAL(true, info.isBusy(42)); - CPPUNIT_ASSERT_EQUAL(false, info.isBusy(7)); - -} + EXPECT_FALSE(info.isBusy(5)); + EXPECT_FALSE(info.isBusy(1)); + EXPECT_TRUE(info.isBusy(42)); + EXPECT_FALSE(info.isBusy(7)); } diff --git a/storage/src/tests/distributor/nodemaintenancestatstrackertest.cpp b/storage/src/tests/distributor/nodemaintenancestatstrackertest.cpp index ae0d0bc4478..58593799fc4 100644 --- a/storage/src/tests/distributor/nodemaintenancestatstrackertest.cpp +++ b/storage/src/tests/distributor/nodemaintenancestatstrackertest.cpp @@ -1,100 +1,77 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/document/test/make_bucket_space.h> -#include <vespa/storage/distributor/maintenance/node_maintenance_stats_tracker.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/document/bucket/fixed_bucket_spaces.h> +#include <vespa/storage/distributor/maintenance/node_maintenance_stats_tracker.h> +#include <vespa/vespalib/gtest/gtest.h> namespace storage::distributor { using document::test::makeBucketSpace; using document::BucketSpace; +using namespace ::testing; -class NodeMaintenanceStatsTrackerTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(NodeMaintenanceStatsTrackerTest); - CPPUNIT_TEST(emptyStatsInstancesAreEqual); - CPPUNIT_TEST(statsFieldsAffectEqualityComparison); - CPPUNIT_TEST(requestingNonExistingNodeGivesEmptyStats); - CPPUNIT_TEST(statsAreTrackedPerNode); - CPPUNIT_TEST(statsAreTrackedPerBucketSpace); - CPPUNIT_TEST_SUITE_END(); - - void emptyStatsInstancesAreEqual(); - void statsFieldsAffectEqualityComparison(); - void requestingNonExistingNodeGivesEmptyStats(); - void statsAreTrackedPerNode(); - void statsAreTrackedPerBucketSpace(); +struct NodeMaintenanceStatsTrackerTest : Test { void assertEmptyBucketStats(BucketSpace bucketSpace, const NodeMaintenanceStatsTracker& tracker); void assertBucketStats(uint64_t expMovingOut, uint64_t expSyncing, uint64_t expCopyingIn, uint64_t expCopyingOut, uint64_t expTotal, BucketSpace bucketSpace, const NodeMaintenanceStatsTracker& tracker); }; -CPPUNIT_TEST_SUITE_REGISTRATION(NodeMaintenanceStatsTrackerTest); - -void -NodeMaintenanceStatsTrackerTest::emptyStatsInstancesAreEqual() -{ +TEST_F(NodeMaintenanceStatsTrackerTest, empty_stats_instances_are_equal) { NodeMaintenanceStats a; NodeMaintenanceStats b; - CPPUNIT_ASSERT_EQUAL(a, b); + EXPECT_EQ(a, b); } -void -NodeMaintenanceStatsTrackerTest::statsFieldsAffectEqualityComparison() -{ +TEST_F(NodeMaintenanceStatsTrackerTest, stats_fields_affect_equality_comparison) { NodeMaintenanceStats a; NodeMaintenanceStats b; a.movingOut = 1; - CPPUNIT_ASSERT(!(a == b)); + EXPECT_NE(a, b); b.movingOut = 1; - CPPUNIT_ASSERT(a == b); + EXPECT_EQ(a, b); a.syncing = 1; - CPPUNIT_ASSERT(!(a == b)); + EXPECT_NE(a, b); b.syncing = 1; - CPPUNIT_ASSERT(a == b); + EXPECT_EQ(a, b); a.copyingIn = 1; - CPPUNIT_ASSERT(!(a == b)); + EXPECT_NE(a, b); b.copyingIn = 1; - CPPUNIT_ASSERT(a == b); + EXPECT_EQ(a, b); a.copyingOut = 1; - CPPUNIT_ASSERT(!(a == b)); + EXPECT_NE(a, b); b.copyingOut = 1; - CPPUNIT_ASSERT(a == b); + EXPECT_EQ(a, b); } -void -NodeMaintenanceStatsTrackerTest::requestingNonExistingNodeGivesEmptyStats() -{ +TEST_F(NodeMaintenanceStatsTrackerTest, requesting_non_existing_node_gives_empty_stats) { NodeMaintenanceStatsTracker tracker; NodeMaintenanceStats wanted; - CPPUNIT_ASSERT_EQUAL(wanted, tracker.forNode(0, makeBucketSpace())); + EXPECT_EQ(wanted, tracker.forNode(0, makeBucketSpace())); } -void -NodeMaintenanceStatsTrackerTest::statsAreTrackedPerNode() -{ +TEST_F(NodeMaintenanceStatsTrackerTest, stats_are_tracked_per_node){ NodeMaintenanceStatsTracker tracker; NodeMaintenanceStats wanted; BucketSpace space(1); tracker.incMovingOut(0, space); wanted.movingOut = 1; - CPPUNIT_ASSERT_EQUAL(wanted, tracker.forNode(0, space)); + EXPECT_EQ(wanted, tracker.forNode(0, space)); wanted.movingOut = 0; - CPPUNIT_ASSERT_EQUAL(wanted, tracker.forNode(1, space)); + EXPECT_EQ(wanted, tracker.forNode(1, space)); tracker.incMovingOut(0, space); wanted.movingOut = 2; - CPPUNIT_ASSERT_EQUAL(wanted, tracker.forNode(0, space)); + EXPECT_EQ(wanted, tracker.forNode(0, space)); tracker.incMovingOut(1, space); wanted.movingOut = 1; - CPPUNIT_ASSERT_EQUAL(wanted, tracker.forNode(1, space)); + EXPECT_EQ(wanted, tracker.forNode(1, space)); tracker.incSyncing(1, space); tracker.incCopyingIn(1, space); @@ -102,12 +79,10 @@ NodeMaintenanceStatsTrackerTest::statsAreTrackedPerNode() wanted.syncing = 1; wanted.copyingIn = 1; wanted.copyingOut = 1; - CPPUNIT_ASSERT_EQUAL(wanted, tracker.forNode(1, space)); + EXPECT_EQ(wanted, tracker.forNode(1, space)); } -void -NodeMaintenanceStatsTrackerTest::statsAreTrackedPerBucketSpace() -{ +TEST_F(NodeMaintenanceStatsTrackerTest, statsAreTrackedPerBucketSpace) { NodeMaintenanceStatsTracker tracker; BucketSpace fooSpace(3); BucketSpace barSpace(5); @@ -143,7 +118,7 @@ NodeMaintenanceStatsTrackerTest::assertEmptyBucketStats(BucketSpace bucketSpace, const NodeMaintenanceStatsTracker& tracker) { NodeMaintenanceStats expStats; - CPPUNIT_ASSERT_EQUAL(expStats, tracker.forNode(0, bucketSpace)); + EXPECT_EQ(expStats, tracker.forNode(0, bucketSpace)); } void @@ -156,7 +131,7 @@ NodeMaintenanceStatsTrackerTest::assertBucketStats(uint64_t expMovingOut, const NodeMaintenanceStatsTracker& tracker) { NodeMaintenanceStats expStats(expMovingOut, expSyncing, expCopyingIn, expCopyingOut, expTotal); - CPPUNIT_ASSERT_EQUAL(expStats, tracker.forNode(0, bucketSpace)); + EXPECT_EQ(expStats, tracker.forNode(0, bucketSpace)); } } diff --git a/storage/src/tests/distributor/operation_sequencer_test.cpp b/storage/src/tests/distributor/operation_sequencer_test.cpp index af9112aaeec..b3674ee2126 100644 --- a/storage/src/tests/distributor/operation_sequencer_test.cpp +++ b/storage/src/tests/distributor/operation_sequencer_test.cpp @@ -1,62 +1,46 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> -#include <vespa/storage/distributor/operation_sequencer.h> #include <vespa/document/base/documentid.h> +#include <vespa/storage/distributor/operation_sequencer.h> +#include <vespa/vespalib/gtest/gtest.h> namespace storage::distributor { using document::DocumentId; -class OperationSequencerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(OperationSequencerTest); - CPPUNIT_TEST(can_get_sequencing_handle_for_id_without_existing_handle); - CPPUNIT_TEST(can_get_sequencing_handle_for_different_ids); - CPPUNIT_TEST(cannot_get_sequencing_handle_for_id_with_existing_handle); - CPPUNIT_TEST(releasing_handle_allows_for_getting_new_handles_for_id); - CPPUNIT_TEST_SUITE_END(); - - void can_get_sequencing_handle_for_id_without_existing_handle(); - void can_get_sequencing_handle_for_different_ids(); - void cannot_get_sequencing_handle_for_id_with_existing_handle(); - void releasing_handle_allows_for_getting_new_handles_for_id(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(OperationSequencerTest); - -void OperationSequencerTest::can_get_sequencing_handle_for_id_without_existing_handle() { +TEST(OperationSequencerTest, can_get_sequencing_handle_for_id_without_existing_handle) { OperationSequencer sequencer; auto handle = sequencer.try_acquire(DocumentId("id:foo:test::abcd")); - CPPUNIT_ASSERT(handle.valid()); + EXPECT_TRUE(handle.valid()); } -void OperationSequencerTest::cannot_get_sequencing_handle_for_id_with_existing_handle() { +TEST(OperationSequencerTest, cannot_get_sequencing_handle_for_id_with_existing_handle) { OperationSequencer sequencer; auto first_handle = sequencer.try_acquire(DocumentId("id:foo:test::abcd")); auto second_handle = sequencer.try_acquire(DocumentId("id:foo:test::abcd")); - CPPUNIT_ASSERT(! second_handle.valid()); + EXPECT_FALSE(second_handle.valid()); } -void OperationSequencerTest::can_get_sequencing_handle_for_different_ids() { +TEST(OperationSequencerTest, can_get_sequencing_handle_for_different_ids) { OperationSequencer sequencer; auto first_handle = sequencer.try_acquire(DocumentId("id:foo:test::abcd")); auto second_handle = sequencer.try_acquire(DocumentId("id:foo:test::efgh")); - CPPUNIT_ASSERT(first_handle.valid()); - CPPUNIT_ASSERT(second_handle.valid()); + EXPECT_TRUE(first_handle.valid()); + EXPECT_TRUE(second_handle.valid()); } -void OperationSequencerTest::releasing_handle_allows_for_getting_new_handles_for_id() { +TEST(OperationSequencerTest, releasing_handle_allows_for_getting_new_handles_for_id) { OperationSequencer sequencer; auto first_handle = sequencer.try_acquire(DocumentId("id:foo:test::abcd")); // Explicit release first_handle.release(); { auto second_handle = sequencer.try_acquire(DocumentId("id:foo:test::abcd")); - CPPUNIT_ASSERT(second_handle.valid()); + EXPECT_TRUE(second_handle.valid()); // Implicit release by scope exit } auto third_handle = sequencer.try_acquire(DocumentId("id:foo:test::abcd")); - CPPUNIT_ASSERT(third_handle.valid()); + EXPECT_TRUE(third_handle.valid()); } } // storage::distributor diff --git a/storage/src/tests/distributor/operationtargetresolvertest.cpp b/storage/src/tests/distributor/operationtargetresolvertest.cpp index 17dbf007c63..da0206cf0a4 100644 --- a/storage/src/tests/distributor/operationtargetresolvertest.cpp +++ b/storage/src/tests/distributor/operationtargetresolvertest.cpp @@ -9,139 +9,104 @@ #include <vespa/storageapi/message/persistence.h> #include <tests/distributor/distributortestutil.h> #include <vespa/vdslib/distribution/idealnodecalculatorimpl.h> -#include <vespa/vespalib/testkit/testapp.h> #include <vespa/storage/distributor/distributor_bucket_space_repo.h> #include <vespa/storage/distributor/distributor_bucket_space.h> #include <vespa/storage/distributor/operationtargetresolverimpl.h> #include <vespa/storage/distributor/externaloperationhandler.h> #include <vespa/config/helper/configgetter.hpp> +#include <vespa/vespalib/gtest/gtest.h> using document::BucketId; using document::test::makeBucketSpace; using document::test::makeDocumentBucket; +using namespace ::testing; -namespace storage { -namespace distributor { - -struct OperationTargetResolverTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ +namespace storage::distributor { +struct OperationTargetResolverTest : Test, DistributorTestUtil { std::shared_ptr<const document::DocumentTypeRepo> _repo; const document::DocumentType* _html_type; std::unique_ptr<Operation> op; - void testSimple(); - void testMultipleNodes(); - void testChooseIdealStateWhenManyCopies(); - void testChooseHighestSplitBucket(); - void testChooseHighestSplitBucketPerNode(); - void testChooseHighestSplitBucketWithTrusted(); - void testInconsistentBucketsAreNotExplicitlyCreated(); - void testNoTrustedOrIdealStateCopyAvailable(); - void testCreateMissingCopies(); - void testNoExistingCopies(); - void testCountMaintenanceNodesAsDown(); - void testResolvingDoesNotMutateDatabase(); - void testTrustedOverIdealState(); - BucketInstanceList getInstances(const BucketId& bid, bool stripToRedundancy); - void setUp() override { + void SetUp() override { _repo.reset(new document::DocumentTypeRepo( *config::ConfigGetter<document::DocumenttypesConfig>::getConfig( "config-doctypes", - config::FileSpec(TEST_PATH("config-doctypes.cfg"))))); + config::FileSpec("../config-doctypes.cfg")))); _html_type = _repo->getDocumentType("text/html"); createLinks(); }; - void tearDown() override { + void TearDown() override { close(); } - - CPPUNIT_TEST_SUITE(OperationTargetResolverTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(testMultipleNodes); - CPPUNIT_TEST(testChooseIdealStateWhenManyCopies); - CPPUNIT_TEST(testChooseHighestSplitBucket); - CPPUNIT_TEST(testChooseHighestSplitBucketPerNode); - CPPUNIT_TEST(testChooseHighestSplitBucketWithTrusted); - CPPUNIT_TEST(testNoTrustedOrIdealStateCopyAvailable); - CPPUNIT_TEST(testInconsistentBucketsAreNotExplicitlyCreated); - CPPUNIT_TEST(testCreateMissingCopies); - CPPUNIT_TEST(testNoExistingCopies); - CPPUNIT_TEST(testCountMaintenanceNodesAsDown); - CPPUNIT_TEST(testResolvingDoesNotMutateDatabase); - CPPUNIT_TEST(testTrustedOverIdealState); - CPPUNIT_TEST_SUITE_END(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(OperationTargetResolverTest); namespace { - // Create assertion that makes it easy to write tests, and report correct - // line for problem at command line -#define ASSERT_THAT(id) \ - { \ - struct MyAsserter : public Asserter { \ - void assertEqualMsg(std::string t1, OperationTargetList t2, \ - OperationTargetList t3) override { \ - CPPUNIT_ASSERT_EQUAL_MSG(t1, t2, t3); \ - } \ - }; \ - _asserters.push_back(new MyAsserter); \ - } \ - TestTargets::createTest(id, *this, *_asserters.back()) - - struct Asserter { - virtual ~Asserter() {} - virtual void assertEqualMsg(std::string t1, - OperationTargetList t2, - OperationTargetList t3) = 0; - }; - std::vector<Asserter*> _asserters; - struct TestTargets { - const BucketId& _id; - OperationTargetList _expected; - OperationTargetResolverTest& _test; - Asserter& _asserter; - - TestTargets(const BucketId& id, - OperationTargetResolverTest& test, - Asserter& asserter) - : _id(id), _test(test), _asserter(asserter) {} - - ~TestTargets() { - BucketInstanceList result(_test.getInstances(_id, true)); - BucketInstanceList all(_test.getInstances(_id, false)); - _asserter.assertEqualMsg( - all.toString(), _expected, result.createTargets(makeBucketSpace())); - delete _asserters.back(); - _asserters.pop_back(); - } - - TestTargets& sendsTo(const BucketId& id, uint16_t node) { - _expected.push_back(OperationTarget( - makeDocumentBucket(id), lib::Node(lib::NodeType::STORAGE, node), false)); - return *this; - } - TestTargets& createsAt(const BucketId& id, uint16_t node) { - _expected.push_back(OperationTarget( - makeDocumentBucket(id), lib::Node(lib::NodeType::STORAGE, node), true)); - return *this; - } - - static TestTargets createTest(const BucketId& id, - OperationTargetResolverTest& test, - Asserter& asserter) - { - return TestTargets(id, test, asserter); - } - }; +// Create assertion that makes it easy to write tests, and report correct +// line for problem at command line +#define MY_ASSERT_THAT(id) \ +{ \ + struct MyAsserter : public Asserter { \ + void assertEqualMsg(std::string t1, OperationTargetList t2, \ + OperationTargetList t3) override { \ + ASSERT_EQ(t2, t3) << t1; \ + } \ + }; \ + _asserters.push_back(new MyAsserter); \ +} \ +TestTargets::createTest(id, *this, *_asserters.back()) + +struct Asserter { + virtual ~Asserter() {} + virtual void assertEqualMsg(std::string t1, + OperationTargetList t2, + OperationTargetList t3) = 0; +}; +std::vector<Asserter*> _asserters; +struct TestTargets { + const BucketId& _id; + OperationTargetList _expected; + OperationTargetResolverTest& _test; + Asserter& _asserter; + + TestTargets(const BucketId& id, + OperationTargetResolverTest& test, + Asserter& asserter) + : _id(id), _test(test), _asserter(asserter) {} + + ~TestTargets() { + BucketInstanceList result(_test.getInstances(_id, true)); + BucketInstanceList all(_test.getInstances(_id, false)); + _asserter.assertEqualMsg( + all.toString(), _expected, result.createTargets(makeBucketSpace())); + delete _asserters.back(); + _asserters.pop_back(); + } + + TestTargets& sendsTo(const BucketId& id, uint16_t node) { + _expected.push_back(OperationTarget( + makeDocumentBucket(id), lib::Node(lib::NodeType::STORAGE, node), false)); + return *this; + } + TestTargets& createsAt(const BucketId& id, uint16_t node) { + _expected.push_back(OperationTarget( + makeDocumentBucket(id), lib::Node(lib::NodeType::STORAGE, node), true)); + return *this; + } + static TestTargets createTest(const BucketId& id, + OperationTargetResolverTest& test, + Asserter& asserter) + { + return TestTargets(id, test, asserter); + } +}; } // anonymous @@ -168,19 +133,15 @@ OperationTargetResolverTest::getInstances(const BucketId& id, /* * Test basic case with no inconsistencies */ -void -OperationTargetResolverTest::testSimple() -{ +TEST_F(OperationTargetResolverTest, simple) { setupDistributor(2, 2, "storage:2 distributor:1"); addNodesToBucketDB(BucketId(16, 0), "0=0,1=0"); - - ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(16, 0), 1) - .sendsTo(BucketId(16, 0), 0); + + MY_ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(16, 0), 1) + .sendsTo(BucketId(16, 0), 0); } -void -OperationTargetResolverTest::testMultipleNodes() -{ +TEST_F(OperationTargetResolverTest, multiple_nodes) { setupDistributor(1, 2, "storage:2 distributor:1"); auto &bucketSpaceRepo(getExternalOperationHandler().getBucketSpaceRepo()); @@ -194,66 +155,54 @@ OperationTargetResolverTest::testMultipleNodes() lib::IdealNodeList idealNodes( idealNodeCalc.getIdealStorageNodes(BucketId(16, i))); uint16_t expectedNode = idealNodes[0].getIndex(); - ASSERT_THAT(BucketId(32, i)).sendsTo(BucketId(16, i), expectedNode); + MY_ASSERT_THAT(BucketId(32, i)).sendsTo(BucketId(16, i), expectedNode); } } -void -OperationTargetResolverTest::testChooseIdealStateWhenManyCopies() -{ +TEST_F(OperationTargetResolverTest, choose_ideal_state_when_many_copies) { setupDistributor(2, 4, "storage:4 distributor:1"); addNodesToBucketDB(BucketId(16, 0), "0=0,1=0,2=0,3=0"); // ideal nodes: 1, 3 - ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(16, 0), 1) - .sendsTo(BucketId(16, 0), 3); + MY_ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(16, 0), 1) + .sendsTo(BucketId(16, 0), 3); } -void -OperationTargetResolverTest::testTrustedOverIdealState() -{ +TEST_F(OperationTargetResolverTest, trusted_over_ideal_state) { setupDistributor(2, 4, "storage:4 distributor:1"); addNodesToBucketDB(BucketId(16, 0), "0=0/0/0/t,1=0,2=0/0/0/t,3=0"); - // ideal nodes: 1, 3 - ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(16, 0), 0) - .sendsTo(BucketId(16, 0), 2); + // ideal nodes: 1, 3 + MY_ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(16, 0), 0) + .sendsTo(BucketId(16, 0), 2); } -void -OperationTargetResolverTest::testChooseHighestSplitBucket() -{ +TEST_F(OperationTargetResolverTest, choose_highest_split_bucket) { setupDistributor(2, 2, "storage:2 distributor:1"); // 0, 1 are both in ideal state for both buckets. addNodesToBucketDB(BucketId(16, 0), "0=0,1=0"); addNodesToBucketDB(BucketId(17, 0), "0=0,1=0"); - ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(17, 0), 1) - .sendsTo(BucketId(17, 0), 0); + MY_ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(17, 0), 1) + .sendsTo(BucketId(17, 0), 0); } -void -OperationTargetResolverTest::testChooseHighestSplitBucketPerNode() -{ +TEST_F(OperationTargetResolverTest, choose_highest_split_bucket_per_node) { setupDistributor(2, 2, "storage:2 distributor:1"); addNodesToBucketDB(BucketId(16, 0), "1=0"); addNodesToBucketDB(BucketId(17, 0), "0=0"); - ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(17, 0), 0) - .sendsTo(BucketId(16, 0), 1); + MY_ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(17, 0), 0) + .sendsTo(BucketId(16, 0), 1); } -void -OperationTargetResolverTest::testChooseHighestSplitBucketWithTrusted() -{ +TEST_F(OperationTargetResolverTest, choose_highest_split_bucket_with_trusted) { setupDistributor(2, 2, "storage:2 distributor:1"); // Unfinished split scenario: split done on 0, not on 1. // Copy on 1 is only remaining for (16, 0), so always trusted. addNodesToBucketDB(BucketId(16, 0), "1=1/2/3/t"); addNodesToBucketDB(BucketId(17, 0), "0=2/3/4/t"); addNodesToBucketDB(BucketId(17, 1ULL << 16), "0=3/4/5/t"); - ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(17, 0), 0) - .sendsTo(BucketId(16, 0), 1); + MY_ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(17, 0), 0) + .sendsTo(BucketId(16, 0), 1); } -void -OperationTargetResolverTest::testInconsistentBucketsAreNotExplicitlyCreated() -{ +TEST_F(OperationTargetResolverTest, inconsistent_buckets_are_not_explicitly_created) { setupDistributor(2, 2, "bits:8 storage:2 distributor:1"); addNodesToBucketDB(BucketId(15, 0), "1=9/9/9/t"); addNodesToBucketDB(BucketId(16, 1 << 15), "0=9/9/9/t"); @@ -263,62 +212,50 @@ OperationTargetResolverTest::testInconsistentBucketsAreNotExplicitlyCreated() // the inconsistent (15, 0) bucket since it already exists and will be // split out very soon anyway. This is predominantly to avoid making things // even worse than they are and to avoid the edge case in bug 7296087. - ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(15, 0), 1) - .createsAt(BucketId(16, 0), 0); + MY_ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(15, 0), 1) + .createsAt(BucketId(16, 0), 0); } -void -OperationTargetResolverTest::testNoTrustedOrIdealStateCopyAvailable() -{ +TEST_F(OperationTargetResolverTest, no_trusted_or_ideal_state_copy_available) { setupDistributor(2, 4, "storage:4 distributor:1"); addNodesToBucketDB(BucketId(16, 0), "0=0,2=0"); addNodesToBucketDB(BucketId(18, 0), "0=0"); // ideal nodes: 1, 3 - ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(18, 0), 0) - .sendsTo(BucketId(16, 0), 2); + MY_ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(18, 0), 0) + .sendsTo(BucketId(16, 0), 2); } -void -OperationTargetResolverTest::testCreateMissingCopies() -{ +TEST_F(OperationTargetResolverTest, create_missing_copies) { setupDistributor(4, 10, "storage:10 distributor:1"); addNodesToBucketDB(BucketId(16, 0), "6=0"); addNodesToBucketDB(BucketId(18, 0), "4=0"); // ideal nodes: 6, 8, 7, 1 - ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(18, 0), 4) - .sendsTo(BucketId(16, 0), 6) - .createsAt(BucketId(18, 0), 8) - .createsAt(BucketId(18, 0), 7); + MY_ASSERT_THAT(BucketId(32, 0)).sendsTo(BucketId(18, 0), 4) + .sendsTo(BucketId(16, 0), 6) + .createsAt(BucketId(18, 0), 8) + .createsAt(BucketId(18, 0), 7); } -void -OperationTargetResolverTest::testNoExistingCopies() -{ +TEST_F(OperationTargetResolverTest, no_existing_copies) { setupDistributor(2, 5, "storage:5 distributor:1"); - ASSERT_THAT(BucketId(32, 0)).createsAt(BucketId(16, 0), 1) - .createsAt(BucketId(16, 0), 3); + MY_ASSERT_THAT(BucketId(32, 0)).createsAt(BucketId(16, 0), 1) + .createsAt(BucketId(16, 0), 3); } -void -OperationTargetResolverTest::testCountMaintenanceNodesAsDown() -{ +TEST_F(OperationTargetResolverTest, count_maintenance_nodes_as_down) { setupDistributor(2, 5, "storage:5 .1.s:m distributor:1"); - ASSERT_THAT(BucketId(32, 0)).createsAt(BucketId(16, 0), 3) - .createsAt(BucketId(16, 0), 2); + MY_ASSERT_THAT(BucketId(32, 0)).createsAt(BucketId(16, 0), 3) + .createsAt(BucketId(16, 0), 2); } -void -OperationTargetResolverTest::testResolvingDoesNotMutateDatabase() -{ +TEST_F(OperationTargetResolverTest, resolving_does_not_mutate_database) { setupDistributor(2, 5, "storage:5 distributor:1"); - ASSERT_THAT(BucketId(32, 0)).createsAt(BucketId(16, 0), 1) - .createsAt(BucketId(16, 0), 3); + MY_ASSERT_THAT(BucketId(32, 0)).createsAt(BucketId(16, 0), 1) + .createsAt(BucketId(16, 0), 3); - CPPUNIT_ASSERT_EQUAL(std::string("NONEXISTING"), - dumpBucket(BucketId(0x4000000000000000))); + EXPECT_EQ("NONEXISTING", dumpBucket(BucketId(0x4000000000000000))); } -} // distributor -} // storage +} // storage::distributor diff --git a/storage/src/tests/distributor/ownership_transfer_safe_time_point_calculator_test.cpp b/storage/src/tests/distributor/ownership_transfer_safe_time_point_calculator_test.cpp index 6a3cd1a5537..c47cb862c73 100644 --- a/storage/src/tests/distributor/ownership_transfer_safe_time_point_calculator_test.cpp +++ b/storage/src/tests/distributor/ownership_transfer_safe_time_point_calculator_test.cpp @@ -1,7 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/storage/distributor/ownership_transfer_safe_time_point_calculator.h> -#include <vespa/vdstestlib/cppunit/macros.h> +#include <vespa/vespalib/gtest/gtest.h> template <typename Clock, typename Duration> std::ostream& operator<<(std::ostream& os, @@ -12,21 +12,7 @@ std::ostream& operator<<(std::ostream& os, return os; } -namespace storage { -namespace distributor { - -struct OwnershipTransferSafeTimePointCalculatorTest : CppUnit::TestFixture { - void generated_safe_time_point_rounds_up_to_nearest_second(); - void zero_clock_skew_returns_epoch(); - - CPPUNIT_TEST_SUITE(OwnershipTransferSafeTimePointCalculatorTest); - CPPUNIT_TEST(generated_safe_time_point_rounds_up_to_nearest_second); - CPPUNIT_TEST(zero_clock_skew_returns_epoch); - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(OwnershipTransferSafeTimePointCalculatorTest); - +namespace storage::distributor { using CalcType = OwnershipTransferSafeTimePointCalculator; using Clock = CalcType::Clock; @@ -34,23 +20,16 @@ using TimePoint = CalcType::TimePoint; using namespace std::literals::chrono_literals; -void OwnershipTransferSafeTimePointCalculatorTest::generated_safe_time_point_rounds_up_to_nearest_second() { - CPPUNIT_ASSERT_EQUAL(TimePoint(6s), - CalcType(1s).safeTimePoint(TimePoint(4001ms))); - CPPUNIT_ASSERT_EQUAL(TimePoint(6s), - CalcType(1s).safeTimePoint(TimePoint(4999ms))); - CPPUNIT_ASSERT_EQUAL(TimePoint(6s), - CalcType(1s).safeTimePoint(TimePoint(4000ms))); - CPPUNIT_ASSERT_EQUAL(TimePoint(7s), - CalcType(2s).safeTimePoint(TimePoint(4001ms))); - CPPUNIT_ASSERT_EQUAL(TimePoint(7s), - CalcType(2s).safeTimePoint(TimePoint(4999ms))); +TEST(OwnershipTransferSafeTimePointCalculatorTest, generated_safe_time_point_rounds_up_to_nearest_second) { + EXPECT_EQ(TimePoint(6s), CalcType(1s).safeTimePoint(TimePoint(4001ms))); + EXPECT_EQ(TimePoint(6s), CalcType(1s).safeTimePoint(TimePoint(4999ms))); + EXPECT_EQ(TimePoint(6s), CalcType(1s).safeTimePoint(TimePoint(4000ms))); + EXPECT_EQ(TimePoint(7s), CalcType(2s).safeTimePoint(TimePoint(4001ms))); + EXPECT_EQ(TimePoint(7s), CalcType(2s).safeTimePoint(TimePoint(4999ms))); } -void OwnershipTransferSafeTimePointCalculatorTest::zero_clock_skew_returns_epoch() { - CPPUNIT_ASSERT_EQUAL(TimePoint(0s), - CalcType(0s).safeTimePoint(TimePoint(4001ms))); +TEST(OwnershipTransferSafeTimePointCalculatorTest, zero_clock_skew_returns_epoch) { + EXPECT_EQ(TimePoint(0s), CalcType(0s).safeTimePoint(TimePoint(4001ms))); } } -} diff --git a/storage/src/tests/distributor/pendingmessagetrackertest.cpp b/storage/src/tests/distributor/pendingmessagetrackertest.cpp index 1ded89dc6d3..f79b809de65 100644 --- a/storage/src/tests/distributor/pendingmessagetrackertest.cpp +++ b/storage/src/tests/distributor/pendingmessagetrackertest.cpp @@ -8,38 +8,17 @@ #include <vespa/storageframework/defaultimplementation/clock/fakeclock.h> #include <tests/common/dummystoragelink.h> #include <vespa/document/test/make_document_bucket.h> -#include <vespa/vdslib/state/random.h> -#include <vespa/vdstestlib/cppunit/macros.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> using document::test::makeDocumentBucket; +using namespace ::testing; namespace storage::distributor { using namespace std::chrono_literals; -class PendingMessageTrackerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(PendingMessageTrackerTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(testMultipleMessages); - CPPUNIT_TEST(testStartPage); - CPPUNIT_TEST(testGetPendingMessageTypes); - CPPUNIT_TEST(testHasPendingMessage); - CPPUNIT_TEST(testGetAllMessagesForSingleBucket); - CPPUNIT_TEST(busy_reply_marks_node_as_busy); - CPPUNIT_TEST(busy_node_duration_can_be_adjusted); - CPPUNIT_TEST_SUITE_END(); - -public: - void testSimple(); - void testMultipleMessages(); - void testStartPage(); - void testGetPendingMessageTypes(); - void testHasPendingMessage(); - void testGetAllMessagesForSingleBucket(); - void busy_reply_marks_node_as_busy(); - void busy_node_duration_can_be_adjusted(); - -private: +struct PendingMessageTrackerTest : Test { void insertMessages(PendingMessageTracker& tracker); }; @@ -98,30 +77,6 @@ public: _tracker->reply(*putReply); } - std::shared_ptr<api::RemoveCommand> sendRemove( - const RequestBuilder& builder) - { - assignMockedTime(builder.atTime()); - auto remove = createRemoveToNode(builder.toNode()); - _tracker->insert(remove); - return remove; - } - - void sendRemoveReply(api::RemoveCommand& removeCmd, - const RequestBuilder& builder) - { - assignMockedTime(builder.atTime()); - auto removeReply = removeCmd.makeReply(); - _tracker->reply(*removeReply); - } - - void sendPutAndReplyWithLatency(uint16_t node, - std::chrono::milliseconds latency) - { - auto put = sendPut(RequestBuilder().atTime(1000ms).toNode(node)); - sendPutReply(*put, RequestBuilder().atTime(1000ms + latency)); - } - PendingMessageTracker& tracker() { return *_tracker; } auto& clock() { return _clock; } @@ -145,10 +100,10 @@ private: std::shared_ptr<api::PutCommand> createPutToNode(uint16_t node) const { document::BucketId bucket(16, 1234); - std::shared_ptr<api::PutCommand> cmd( - new api::PutCommand(makeDocumentBucket(bucket), - createDummyDocumentForBucket(bucket), - api::Timestamp(123456))); + auto cmd = std::make_shared<api::PutCommand>( + makeDocumentBucket(bucket), + createDummyDocumentForBucket(bucket), + api::Timestamp(123456)); cmd->setAddress(makeStorageAddress(node)); return cmd; } @@ -157,11 +112,10 @@ private: uint16_t node) const { document::BucketId bucket(16, 1234); - std::shared_ptr<api::RemoveCommand> cmd( - new api::RemoveCommand(makeDocumentBucket(bucket), - document::DocumentId( - createDummyIdString(bucket)), - api::Timestamp(123456))); + auto cmd = std::make_shared<api::RemoveCommand>( + makeDocumentBucket(bucket), + document::DocumentId(createDummyIdString(bucket)), + api::Timestamp(123456)); cmd->setAddress(makeStorageAddress(node)); return cmd; } @@ -183,15 +137,11 @@ Fixture::Fixture() // flip out and die on an explicit nullptr check. _tracker = std::make_unique<PendingMessageTracker>(_compReg); } -Fixture::~Fixture() {} +Fixture::~Fixture() = default; -} - -CPPUNIT_TEST_SUITE_REGISTRATION(PendingMessageTrackerTest); +} // anonymous namespace -void -PendingMessageTrackerTest::testSimple() -{ +TEST_F(PendingMessageTrackerTest, simple) { StorageComponentRegisterImpl compReg; framework::defaultimplementation::FakeClock clock; compReg.setClock(clock); @@ -208,14 +158,12 @@ PendingMessageTrackerTest::testSimple() std::ostringstream ost; tracker.reportStatus(ost, framework::HttpUrlPath("/pendingmessages?order=bucket")); - CPPUNIT_ASSERT_CONTAIN( - std::string( - "<b>Bucket(BucketSpace(0x0000000000000001), BucketId(0x40000000000004d2))</b>\n" - "<ul>\n" - "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> " - "Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" - "</ul>\n"), - ost.str()); + EXPECT_THAT(ost.str(), HasSubstr( + "<b>Bucket(BucketSpace(0x0000000000000001), BucketId(0x40000000000004d2))</b>\n" + "<ul>\n" + "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> " + "Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" + "</ul>\n")); } api::RemoveReply reply(*remove); @@ -225,7 +173,7 @@ PendingMessageTrackerTest::testSimple() std::ostringstream ost; tracker.reportStatus(ost, framework::HttpUrlPath("/pendingmessages?order=bucket")); - CPPUNIT_ASSERT_MSG(ost.str(), ost.str().find("doc:") == std::string::npos); + EXPECT_THAT(ost.str(), Not(HasSubstr("doc:"))); } } @@ -251,9 +199,7 @@ PendingMessageTrackerTest::insertMessages(PendingMessageTracker& tracker) } } -void -PendingMessageTrackerTest::testStartPage() -{ +TEST_F(PendingMessageTrackerTest, start_page) { StorageComponentRegisterImpl compReg; framework::defaultimplementation::FakeClock clock; compReg.setClock(clock); @@ -263,21 +209,16 @@ PendingMessageTrackerTest::testStartPage() std::ostringstream ost; tracker.reportStatus(ost, framework::HttpUrlPath("/pendingmessages")); - CPPUNIT_ASSERT_CONTAIN( - std::string( - "<h1>Pending messages to storage nodes</h1>\n" - "View:\n" - "<ul>\n" - "<li><a href=\"?order=bucket\">Group by bucket</a></li>" - "<li><a href=\"?order=node\">Group by node</a></li>"), - ost.str()); - + EXPECT_THAT(ost.str(), HasSubstr( + "<h1>Pending messages to storage nodes</h1>\n" + "View:\n" + "<ul>\n" + "<li><a href=\"?order=bucket\">Group by bucket</a></li>" + "<li><a href=\"?order=node\">Group by node</a></li>")); } } -void -PendingMessageTrackerTest::testMultipleMessages() -{ +TEST_F(PendingMessageTrackerTest, multiple_messages) { StorageComponentRegisterImpl compReg; framework::defaultimplementation::FakeClock clock; compReg.setClock(clock); @@ -290,45 +231,41 @@ PendingMessageTrackerTest::testMultipleMessages() std::ostringstream ost; tracker.reportStatus(ost, framework::HttpUrlPath("/pendingmessages?order=bucket")); - CPPUNIT_ASSERT_CONTAIN( - std::string( - "<b>Bucket(BucketSpace(0x0000000000000001), BucketId(0x40000000000004d2))</b>\n" - "<ul>\n" - "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" - "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" - "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" - "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" - "</ul>\n" - "<b>Bucket(BucketSpace(0x0000000000000001), BucketId(0x40000000000011d7))</b>\n" - "<ul>\n" - "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" - "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" - "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" - "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" - "</ul>\n" - ), - ost.str()); + EXPECT_THAT(ost.str(), HasSubstr( + "<b>Bucket(BucketSpace(0x0000000000000001), BucketId(0x40000000000004d2))</b>\n" + "<ul>\n" + "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" + "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" + "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" + "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" + "</ul>\n" + "<b>Bucket(BucketSpace(0x0000000000000001), BucketId(0x40000000000011d7))</b>\n" + "<ul>\n" + "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" + "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" + "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" + "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" + "</ul>\n")); } { std::ostringstream ost; tracker.reportStatus(ost, framework::HttpUrlPath("/pendingmessages?order=node")); - CPPUNIT_ASSERT_CONTAIN(std::string( - "<b>Node 0 (pending count: 4)</b>\n" - "<ul>\n" - "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" - "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" - "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" - "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" - "</ul>\n" - "<b>Node 1 (pending count: 4)</b>\n" - "<ul>\n" - "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" - "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" - "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" - "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" - "</ul>\n" - ), ost.str()); + EXPECT_THAT(ost.str(), HasSubstr( + "<b>Node 0 (pending count: 4)</b>\n" + "<ul>\n" + "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" + "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" + "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" + "<li><i>Node 0</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" + "</ul>\n" + "<b>Node 1 (pending count: 4)</b>\n" + "<ul>\n" + "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" + "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000004d2), priority=127)</li>\n" + "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" + "<li><i>Node 1</i>: <b>1970-01-01 00:00:01</b> Remove(BucketId(0x40000000000011d7), priority=127)</li>\n" + "</ul>\n")); } } @@ -376,9 +313,7 @@ public: } -void -PendingMessageTrackerTest::testGetPendingMessageTypes() -{ +TEST_F(PendingMessageTrackerTest, get_pending_message_types) { StorageComponentRegisterImpl compReg; framework::defaultimplementation::FakeClock clock; compReg.setClock(clock); @@ -394,25 +329,23 @@ PendingMessageTrackerTest::testGetPendingMessageTypes() { TestChecker checker; tracker.checkPendingMessages(0, makeDocumentBucket(bid), checker); - CPPUNIT_ASSERT_EQUAL(127, (int)checker.pri); + EXPECT_EQ(127, static_cast<int>(checker.pri)); } { TestChecker checker; tracker.checkPendingMessages(0, makeDocumentBucket(document::BucketId(16, 1235)), checker); - CPPUNIT_ASSERT_EQUAL(255, (int)checker.pri); + EXPECT_EQ(255, static_cast<int>(checker.pri)); } { TestChecker checker; tracker.checkPendingMessages(1, makeDocumentBucket(bid), checker); - CPPUNIT_ASSERT_EQUAL(255, (int)checker.pri); + EXPECT_EQ(255, static_cast<int>(checker.pri)); } } -void -PendingMessageTrackerTest::testHasPendingMessage() -{ +TEST_F(PendingMessageTrackerTest, has_pending_message) { StorageComponentRegisterImpl compReg; framework::defaultimplementation::FakeClock clock; compReg.setClock(clock); @@ -420,7 +353,7 @@ PendingMessageTrackerTest::testHasPendingMessage() PendingMessageTracker tracker(compReg); document::BucketId bid(16, 1234); - CPPUNIT_ASSERT(!tracker.hasPendingMessage(1, makeDocumentBucket(bid), api::MessageType::REMOVE_ID)); + EXPECT_FALSE(tracker.hasPendingMessage(1, makeDocumentBucket(bid), api::MessageType::REMOVE_ID)); { auto remove = std::make_shared<api::RemoveCommand>(makeDocumentBucket(bid), @@ -429,11 +362,11 @@ PendingMessageTrackerTest::testHasPendingMessage() tracker.insert(remove); } - CPPUNIT_ASSERT(tracker.hasPendingMessage(1, makeDocumentBucket(bid), api::MessageType::REMOVE_ID)); - CPPUNIT_ASSERT(!tracker.hasPendingMessage(0, makeDocumentBucket(bid), api::MessageType::REMOVE_ID)); - CPPUNIT_ASSERT(!tracker.hasPendingMessage(2, makeDocumentBucket(bid), api::MessageType::REMOVE_ID)); - CPPUNIT_ASSERT(!tracker.hasPendingMessage(1, makeDocumentBucket(document::BucketId(16, 1233)), api::MessageType::REMOVE_ID)); - CPPUNIT_ASSERT(!tracker.hasPendingMessage(1, makeDocumentBucket(bid), api::MessageType::DELETEBUCKET_ID)); + EXPECT_TRUE(tracker.hasPendingMessage(1, makeDocumentBucket(bid), api::MessageType::REMOVE_ID)); + EXPECT_FALSE(tracker.hasPendingMessage(0, makeDocumentBucket(bid), api::MessageType::REMOVE_ID)); + EXPECT_FALSE(tracker.hasPendingMessage(2, makeDocumentBucket(bid), api::MessageType::REMOVE_ID)); + EXPECT_FALSE(tracker.hasPendingMessage(1, makeDocumentBucket(document::BucketId(16, 1233)), api::MessageType::REMOVE_ID)); + EXPECT_FALSE(tracker.hasPendingMessage(1, makeDocumentBucket(bid), api::MessageType::DELETEBUCKET_ID)); } namespace { @@ -455,9 +388,7 @@ public: } // anon ns -void -PendingMessageTrackerTest::testGetAllMessagesForSingleBucket() -{ +TEST_F(PendingMessageTrackerTest, get_all_messages_for_single_bucket) { StorageComponentRegisterImpl compReg; framework::defaultimplementation::FakeClock clock; compReg.setClock(clock); @@ -469,16 +400,16 @@ PendingMessageTrackerTest::testGetAllMessagesForSingleBucket() { OperationEnumerator enumerator; tracker.checkPendingMessages(makeDocumentBucket(document::BucketId(16, 1234)), enumerator); - CPPUNIT_ASSERT_EQUAL(std::string("Remove -> 0\n" - "Remove -> 0\n" - "Remove -> 1\n" - "Remove -> 1\n"), - enumerator.str()); + EXPECT_EQ("Remove -> 0\n" + "Remove -> 0\n" + "Remove -> 1\n" + "Remove -> 1\n", + enumerator.str()); } { OperationEnumerator enumerator; tracker.checkPendingMessages(makeDocumentBucket(document::BucketId(16, 9876)), enumerator); - CPPUNIT_ASSERT_EQUAL(std::string(""), enumerator.str()); + EXPECT_EQ("", enumerator.str()); } } @@ -486,23 +417,23 @@ PendingMessageTrackerTest::testGetAllMessagesForSingleBucket() // but have the same actual semantics as busy merges (i.e. "queue is full", not "node // is too busy to accept new requests in general"). -void PendingMessageTrackerTest::busy_reply_marks_node_as_busy() { +TEST_F(PendingMessageTrackerTest, busy_reply_marks_node_as_busy) { Fixture f; auto cmd = f.sendPut(RequestBuilder().toNode(0)); - CPPUNIT_ASSERT(!f.tracker().getNodeInfo().isBusy(0)); + EXPECT_FALSE(f.tracker().getNodeInfo().isBusy(0)); f.sendPutReply(*cmd, RequestBuilder(), api::ReturnCode(api::ReturnCode::BUSY)); - CPPUNIT_ASSERT(f.tracker().getNodeInfo().isBusy(0)); - CPPUNIT_ASSERT(!f.tracker().getNodeInfo().isBusy(1)); + EXPECT_TRUE(f.tracker().getNodeInfo().isBusy(0)); + EXPECT_FALSE(f.tracker().getNodeInfo().isBusy(1)); } -void PendingMessageTrackerTest::busy_node_duration_can_be_adjusted() { +TEST_F(PendingMessageTrackerTest, busy_node_duration_can_be_adjusted) { Fixture f; auto cmd = f.sendPut(RequestBuilder().toNode(0)); f.tracker().setNodeBusyDuration(std::chrono::seconds(10)); f.sendPutReply(*cmd, RequestBuilder(), api::ReturnCode(api::ReturnCode::BUSY)); - CPPUNIT_ASSERT(f.tracker().getNodeInfo().isBusy(0)); + EXPECT_TRUE(f.tracker().getNodeInfo().isBusy(0)); f.clock().addSecondsToTime(11); - CPPUNIT_ASSERT(!f.tracker().getNodeInfo().isBusy(0)); + EXPECT_FALSE(f.tracker().getNodeInfo().isBusy(0)); } } diff --git a/storage/src/tests/distributor/persistence_metrics_set_test.cpp b/storage/src/tests/distributor/persistence_metrics_set_test.cpp index 22e187bf4c0..3210a59a567 100644 --- a/storage/src/tests/distributor/persistence_metrics_set_test.cpp +++ b/storage/src/tests/distributor/persistence_metrics_set_test.cpp @@ -2,71 +2,52 @@ #include <vespa/storage/distributor/distributormetricsset.h> #include <vespa/storageapi/messageapi/returncode.h> -#include <vespa/vdstestlib/cppunit/macros.h> +#include <vespa/vespalib/gtest/gtest.h> -namespace storage { -namespace distributor { +using namespace ::testing; -struct PersistenceMetricsSetTest : CppUnit::TestFixture { - void successful_return_codes_are_counted_as_ok(); - void wrong_distribution_failure_is_counted(); - void timeout_failure_is_counted(); - // Note for these tests: busy, connection failures et al are sets of - // failure codes and not just a single code. We only test certain members - // of these sets here. See api::ReturnCode implementation for an exhaustive - // list. - void busy_failure_is_counted(); - void connection_failure_is_counted(); - void inconsistent_bucket_is_counted(); - void non_special_cased_failure_codes_are_catchall_counted(); - - CPPUNIT_TEST_SUITE(PersistenceMetricsSetTest); - CPPUNIT_TEST(successful_return_codes_are_counted_as_ok); - CPPUNIT_TEST(wrong_distribution_failure_is_counted); - CPPUNIT_TEST(timeout_failure_is_counted); - CPPUNIT_TEST(busy_failure_is_counted); - CPPUNIT_TEST(connection_failure_is_counted); - CPPUNIT_TEST(inconsistent_bucket_is_counted); - CPPUNIT_TEST(non_special_cased_failure_codes_are_catchall_counted); - CPPUNIT_TEST_SUITE_END(); +namespace storage::distributor { +struct PersistenceMetricsSetTest : Test { void assert_failure_is_counted(PersistenceOperationMetricSet& metrics, api::ReturnCode::Result failure_code, const metrics::LongCountMetric& checked) { metrics.updateFromResult(api::ReturnCode(failure_code)); - CPPUNIT_ASSERT_EQUAL(int64_t(1), checked.getLongValue("count")); - CPPUNIT_ASSERT_EQUAL(int64_t(0), metrics.ok.getLongValue("count")); + EXPECT_EQ(1, checked.getLongValue("count")); + EXPECT_EQ(0, metrics.ok.getLongValue("count")); } }; -CPPUNIT_TEST_SUITE_REGISTRATION(PersistenceMetricsSetTest); - -void PersistenceMetricsSetTest::successful_return_codes_are_counted_as_ok() { +TEST_F(PersistenceMetricsSetTest, successful_return_codes_are_counted_as_ok) { PersistenceOperationMetricSet metrics("foo"); metrics.updateFromResult(api::ReturnCode()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), metrics.ok.getLongValue("count")); + EXPECT_EQ(1, metrics.ok.getLongValue("count")); } -void PersistenceMetricsSetTest::wrong_distribution_failure_is_counted() { +TEST_F(PersistenceMetricsSetTest, wrong_distribution_failure_is_counted) { PersistenceOperationMetricSet metrics("foo"); assert_failure_is_counted(metrics, api::ReturnCode::WRONG_DISTRIBUTION, metrics.failures.wrongdistributor); } -void PersistenceMetricsSetTest::timeout_failure_is_counted() { +TEST_F(PersistenceMetricsSetTest, timeout_failure_is_counted) { PersistenceOperationMetricSet metrics("foo"); assert_failure_is_counted(metrics, api::ReturnCode::TIMEOUT, metrics.failures.timeout); } -void PersistenceMetricsSetTest::busy_failure_is_counted() { +// Note for these tests: busy, connection failures et al are sets of +// failure codes and not just a single code. We only test certain members +// of these sets here. See api::ReturnCode implementation for an exhaustive +// list. +TEST_F(PersistenceMetricsSetTest, busy_failure_is_counted) { PersistenceOperationMetricSet metrics("foo"); assert_failure_is_counted(metrics, api::ReturnCode::BUSY, metrics.failures.busy); } -void PersistenceMetricsSetTest::connection_failure_is_counted() { +TEST_F(PersistenceMetricsSetTest, connection_failure_is_counted) { PersistenceOperationMetricSet metrics("foo"); // This is dirty enum value coercion, but this is how "parent protocol" // error codes are handled already. @@ -76,17 +57,16 @@ void PersistenceMetricsSetTest::connection_failure_is_counted() { metrics.failures.notconnected); } -void PersistenceMetricsSetTest::inconsistent_bucket_is_counted() { +TEST_F(PersistenceMetricsSetTest, inconsistent_bucket_is_counted) { PersistenceOperationMetricSet metrics("foo"); assert_failure_is_counted(metrics, api::ReturnCode::BUCKET_NOT_FOUND, metrics.failures.inconsistent_bucket); } -void PersistenceMetricsSetTest::non_special_cased_failure_codes_are_catchall_counted() { +TEST_F(PersistenceMetricsSetTest, non_special_cased_failure_codes_are_catchall_counted) { PersistenceOperationMetricSet metrics("foo"); assert_failure_is_counted(metrics, api::ReturnCode::REJECTED, metrics.failures.storagefailure); } } -} diff --git a/storage/src/tests/distributor/putoperationtest.cpp b/storage/src/tests/distributor/putoperationtest.cpp index 881ccb560b4..d56ca69d52f 100644 --- a/storage/src/tests/distributor/putoperationtest.cpp +++ b/storage/src/tests/distributor/putoperationtest.cpp @@ -9,10 +9,8 @@ #include <tests/distributor/distributortestutil.h> #include <tests/common/dummystoragelink.h> #include <vespa/document/test/make_document_bucket.h> -#include <vespa/vdstestlib/cppunit/macros.h> -#include <vespa/vespalib/gtest/gtest.h> #include <vespa/vespalib/text/stringtokenizer.h> -#include <iomanip> +#include <vespa/vespalib/gtest/gtest.h> using std::shared_ptr; using config::ConfigGetter; @@ -57,15 +55,15 @@ public: = api::ReturnCode::OK, api::BucketInfo info = api::BucketInfo(1,2,3,4,5)) { - ASSERT_FALSE(_sender.commands.empty()); + ASSERT_FALSE(_sender.commands().empty()); if (idx == -1) { - idx = _sender.commands.size() - 1; - } else if (static_cast<size_t>(idx) >= _sender.commands.size()) { + idx = _sender.commands().size() - 1; + } else if (static_cast<size_t>(idx) >= _sender.commands().size()) { throw std::logic_error("Specified message index is greater " "than number of received messages"); } - std::shared_ptr<api::StorageCommand> msg = _sender.commands[idx]; + std::shared_ptr<api::StorageCommand> msg = _sender.command(idx); api::StorageReply::SP reply(msg->makeReply().release()); dynamic_cast<api::BucketInfoReply*>(reply.get())->setBucketInfo(info); reply->setResult(result); @@ -99,16 +97,12 @@ PutOperationTest::~PutOperationTest() = default; document::BucketId PutOperationTest::createAndSendSampleDocument(uint32_t timeout) { - Document::SP - doc(new Document(doc_type(), DocumentId(DocIdString("test", "test")))); + auto doc = std::make_shared<Document>(doc_type(), DocumentId(DocIdString("test", "test"))); document::BucketId id = getExternalOperationHandler().getBucketId(doc->getId()); addIdealNodes(id); - std::shared_ptr<api::PutCommand> msg( - new api::PutCommand(makeDocumentBucket(document::BucketId(0)), - doc, - 0)); + auto msg = std::make_shared<api::PutCommand>(makeDocumentBucket(document::BucketId(0)), doc, 0); msg->setTimestamp(100); msg->setPriority(128); msg->setTimeout(timeout); @@ -118,10 +112,10 @@ PutOperationTest::createAndSendSampleDocument(uint32_t timeout) { namespace { -typedef int Redundancy; -typedef int NodeCount; -typedef uint32_t ReturnAfter; -typedef bool RequirePrimaryWritten; +using Redundancy = int; +using NodeCount = int; +using ReturnAfter = uint32_t; +using RequirePrimaryWritten = bool; } @@ -306,7 +300,7 @@ TEST_F(PutOperationTest, multiple_copies_early_return_primary_required_not_done) sendReply(4); sendReply(5); - ASSERT_EQ(0, _sender.replies.size()); + ASSERT_EQ(0, _sender.replies().size()); } TEST_F(PutOperationTest, do_not_revert_on_failure_after_early_return) { @@ -395,9 +389,9 @@ TEST_F(PutOperationTest, do_not_send_CreateBucket_if_already_pending) { // Manually shove sent messages into pending message tracker, since // this isn't done automatically. - for (size_t i = 0; i < _sender.commands.size(); ++i) { + for (size_t i = 0; i < _sender.commands().size(); ++i) { getExternalOperationHandler().getDistributor().getPendingMessageTracker() - .insert(_sender.commands[i]); + .insert(_sender.command(i)); } sendPut(createPut(doc)); @@ -420,17 +414,14 @@ TEST_F(PutOperationTest, no_storage_nodes) { TEST_F(PutOperationTest, update_correct_bucket_on_remapped_put) { setupDistributor(2, 2, "storage:2 distributor:1"); - Document::SP doc(new Document(doc_type(), DocumentId( - UserDocIdString("userdoc:test:13:uri")))); - + auto doc = std::make_shared<Document>(doc_type(), DocumentId(UserDocIdString("userdoc:test:13:uri"))); addNodesToBucketDB(document::BucketId(16,13), "0=0,1=0"); - sendPut(createPut(doc)); ASSERT_EQ("Put => 0,Put => 1", _sender.getCommands(true)); { - std::shared_ptr<api::StorageCommand> msg2 = _sender.commands[0]; + std::shared_ptr<api::StorageCommand> msg2 = _sender.command(0); std::shared_ptr<api::StorageReply> reply(msg2->makeReply().release()); PutReply* sreply = (PutReply*)reply.get(); sreply->remapBucketId(document::BucketId(17, 13)); @@ -610,7 +601,7 @@ void PutOperationTest::do_test_creation_with_bucket_activation_disabled(bool dis sendPut(createPut(doc)); ASSERT_EQ("Create bucket => 0,Put => 0", _sender.getCommands(true)); - auto cmd = _sender.commands[0]; + auto cmd = _sender.command(0); auto createCmd = std::dynamic_pointer_cast<api::CreateBucketCommand>(cmd); ASSERT_TRUE(createCmd.get() != nullptr); // There's only 1 content node, so if activation were not disabled, it diff --git a/storage/src/tests/distributor/removebucketoperationtest.cpp b/storage/src/tests/distributor/removebucketoperationtest.cpp index f11c29bc55c..e2bf867ad11 100644 --- a/storage/src/tests/distributor/removebucketoperationtest.cpp +++ b/storage/src/tests/distributor/removebucketoperationtest.cpp @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <cppunit/extensions/HelperMacros.h> + #include <tests/common/dummystoragelink.h> #include <vespa/storageapi/message/persistence.h> #include <vespa/storageapi/message/bucket.h> @@ -8,41 +8,24 @@ #include <vespa/storage/distributor/distributor.h> #include <tests/distributor/distributortestutil.h> #include <vespa/document/test/make_document_bucket.h> +#include <vespa/vespalib/gtest/gtest.h> using document::test::makeDocumentBucket; +using namespace ::testing; + +namespace storage::distributor { -namespace storage { -namespace distributor { - -class RemoveBucketOperationTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ - CPPUNIT_TEST_SUITE(RemoveBucketOperationTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(testBucketInfoMismatchFailure); - CPPUNIT_TEST(testFailWithInvalidBucketInfo); - CPPUNIT_TEST_SUITE_END(); - -protected: - void testSimple(); - void testBucketInfoMismatchFailure(); - void testFailWithInvalidBucketInfo(); - -public: - void setUp() override { +struct RemoveBucketOperationTest : Test, DistributorTestUtil { + void SetUp() override { createLinks(); }; - void tearDown() override { + void TearDown() override { close(); } }; -CPPUNIT_TEST_SUITE_REGISTRATION(RemoveBucketOperationTest); - -void -RemoveBucketOperationTest::testSimple() -{ +TEST_F(RemoveBucketOperationTest, simple) { addNodesToBucketDB(document::BucketId(16, 1), "0=10/100/1/t," "1=10/100/1/t," @@ -57,18 +40,16 @@ RemoveBucketOperationTest::testSimple() op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Delete bucket => 1," - "Delete bucket => 2"), - _sender.getCommands(true)); + ASSERT_EQ("Delete bucket => 1," + "Delete bucket => 2", + _sender.getCommands(true)); sendReply(op, 0); sendReply(op, 1); - CPPUNIT_ASSERT_EQUAL( - std::string( - "BucketId(0x4000000000000001) : " - "node(idx=0,crc=0xa,docs=100/100,bytes=1/1,trusted=true,active=false,ready=false)"), - dumpBucket(document::BucketId(16, 1))); + ASSERT_EQ("BucketId(0x4000000000000001) : " + "node(idx=0,crc=0xa,docs=100/100,bytes=1/1,trusted=true,active=false,ready=false)", + dumpBucket(document::BucketId(16, 1))); } /** @@ -76,14 +57,11 @@ RemoveBucketOperationTest::testSimple() * back actual bucket info reinserts that bucket info into the distributor * bucket database. */ -void -RemoveBucketOperationTest::testBucketInfoMismatchFailure() -{ +TEST_F(RemoveBucketOperationTest, bucket_info_mismatch_failure) { addNodesToBucketDB(document::BucketId(16, 1), "1=0/0/0/t"); - getComponentRegisterImpl().setDistribution(std::shared_ptr<lib::Distribution>( - new lib::Distribution( - lib::Distribution::getDefaultDistributionConfig(1, 10)))); + getComponentRegisterImpl().setDistribution( + std::make_shared<lib::Distribution>(lib::Distribution::getDefaultDistributionConfig(1, 10))); enableDistributorClusterState("distributor:1 storage:2"); @@ -93,11 +71,10 @@ RemoveBucketOperationTest::testBucketInfoMismatchFailure() op.setIdealStateManager(&getIdealStateManager()); op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Delete bucket => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Delete bucket => 1", _sender.getCommands(true)); + ASSERT_EQ(1, _sender.commands().size()); - CPPUNIT_ASSERT_EQUAL((size_t) 1, _sender.commands.size()); - std::shared_ptr<api::StorageCommand> msg2 = _sender.commands[0]; + std::shared_ptr<api::StorageCommand> msg2 = _sender.command(0); std::shared_ptr<api::StorageReply> reply(msg2->makeReply().release()); dynamic_cast<api::DeleteBucketReply&>(*reply).setBucketInfo( api::BucketInfo(10, 100, 1)); @@ -105,11 +82,9 @@ RemoveBucketOperationTest::testBucketInfoMismatchFailure() op.receive(_sender, reply); // RemoveBucketOperation should reinsert bucketinfo into database - CPPUNIT_ASSERT_EQUAL( - std::string( - "BucketId(0x4000000000000001) : " - "node(idx=1,crc=0xa,docs=100/100,bytes=1/1,trusted=true,active=false,ready=false)"), - dumpBucket(document::BucketId(16, 1))); + ASSERT_EQ("BucketId(0x4000000000000001) : " + "node(idx=1,crc=0xa,docs=100/100,bytes=1/1,trusted=true,active=false,ready=false)", + dumpBucket(document::BucketId(16, 1))); } /** @@ -117,14 +92,11 @@ RemoveBucketOperationTest::testBucketInfoMismatchFailure() * not include valid BucketInfo in its reply does not reinsert the bucket * into the distributor. */ -void -RemoveBucketOperationTest::testFailWithInvalidBucketInfo() -{ +TEST_F(RemoveBucketOperationTest, fail_with_invalid_bucket_info) { addNodesToBucketDB(document::BucketId(16, 1), "1=0/0/0/t"); - getComponentRegisterImpl().setDistribution(std::shared_ptr<lib::Distribution>( - new lib::Distribution( - lib::Distribution::getDefaultDistributionConfig(1, 10)))); + getComponentRegisterImpl().setDistribution( + std::make_shared<lib::Distribution>(lib::Distribution::getDefaultDistributionConfig(1, 10))); enableDistributorClusterState("distributor:1 storage:2"); @@ -134,18 +106,15 @@ RemoveBucketOperationTest::testFailWithInvalidBucketInfo() op.setIdealStateManager(&getIdealStateManager()); op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Delete bucket => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Delete bucket => 1", _sender.getCommands(true)); + ASSERT_EQ(1, _sender.commands().size()); - CPPUNIT_ASSERT_EQUAL((size_t) 1, _sender.commands.size()); - std::shared_ptr<api::StorageCommand> msg2 = _sender.commands[0]; + std::shared_ptr<api::StorageCommand> msg2 = _sender.command(0); std::shared_ptr<api::StorageReply> reply(msg2->makeReply().release()); reply->setResult(api::ReturnCode::ABORTED); op.receive(_sender, reply); - CPPUNIT_ASSERT_EQUAL(std::string("NONEXISTING"), - dumpBucket(document::BucketId(16, 1))); + EXPECT_EQ("NONEXISTING", dumpBucket(document::BucketId(16, 1))); } -} // distributor -} // storage +} // storage::distributor diff --git a/storage/src/tests/distributor/removelocationtest.cpp b/storage/src/tests/distributor/removelocationtest.cpp index 5a6013c6fc4..74daba3d098 100644 --- a/storage/src/tests/distributor/removelocationtest.cpp +++ b/storage/src/tests/distributor/removelocationtest.cpp @@ -1,59 +1,43 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <cppunit/extensions/HelperMacros.h> -#include <iomanip> -#include <tests/common/dummystoragelink.h> #include <vespa/storageapi/message/removelocation.h> #include <vespa/storage/distributor/operations/external/removelocationoperation.h> #include <tests/distributor/distributortestutil.h> #include <vespa/document/test/make_document_bucket.h> #include <vespa/storage/distributor/distributor.h> +#include <vespa/vespalib/gtest/gtest.h> using document::test::makeDocumentBucket; +using namespace ::testing; -namespace storage { -namespace distributor { +namespace storage::distributor { -class RemoveLocationOperationTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ - CPPUNIT_TEST_SUITE(RemoveLocationOperationTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST_SUITE_END(); - -protected: - void testSimple(); - -public: +struct RemoveLocationOperationTest : Test, DistributorTestUtil { std::unique_ptr<RemoveLocationOperation> op; - void setUp() override { + void SetUp() override { createLinks(); }; - void tearDown() override { + void TearDown() override { close(); } void sendRemoveLocation(const std::string& selection) { - std::shared_ptr<api::RemoveLocationCommand> msg( - new api::RemoveLocationCommand(selection, makeDocumentBucket(document::BucketId(0)))); + auto msg = std::make_shared<api::RemoveLocationCommand>(selection, makeDocumentBucket(document::BucketId(0))); - op.reset(new RemoveLocationOperation(getExternalOperationHandler(), - getDistributorBucketSpace(), - msg, - getDistributor().getMetrics(). - removelocations[msg->getLoadType()])); + op = std::make_unique<RemoveLocationOperation>( + getExternalOperationHandler(), + getDistributorBucketSpace(), + msg, + getDistributor().getMetrics(). + removelocations[msg->getLoadType()]); op->start(_sender, framework::MilliSecTime(0)); } }; -CPPUNIT_TEST_SUITE_REGISTRATION(RemoveLocationOperationTest); - -void -RemoveLocationOperationTest::testSimple() -{ +TEST_F(RemoveLocationOperationTest, simple) { enableDistributorClusterState("distributor:1 storage:3"); addNodesToBucketDB(document::BucketId(34, 0x000001234), "0=1,1=1"); @@ -63,25 +47,22 @@ RemoveLocationOperationTest::testSimple() sendRemoveLocation("id.user=4660"); - CPPUNIT_ASSERT_EQUAL( - std::string("Remove selection(id.user=4660): BucketInfoCommand() => 0," - "Remove selection(id.user=4660): BucketInfoCommand() => 1," - "Remove selection(id.user=4660): BucketInfoCommand() => 0," - "Remove selection(id.user=4660): BucketInfoCommand() => 2," - "Remove selection(id.user=4660): BucketInfoCommand() => 0," - "Remove selection(id.user=4660): BucketInfoCommand() => 2," - "Remove selection(id.user=4660): BucketInfoCommand() => 1," - "Remove selection(id.user=4660): BucketInfoCommand() => 2"), - _sender.getCommands(true, true)); + ASSERT_EQ("Remove selection(id.user=4660): BucketInfoCommand() => 0," + "Remove selection(id.user=4660): BucketInfoCommand() => 1," + "Remove selection(id.user=4660): BucketInfoCommand() => 0," + "Remove selection(id.user=4660): BucketInfoCommand() => 2," + "Remove selection(id.user=4660): BucketInfoCommand() => 0," + "Remove selection(id.user=4660): BucketInfoCommand() => 2," + "Remove selection(id.user=4660): BucketInfoCommand() => 1," + "Remove selection(id.user=4660): BucketInfoCommand() => 2", + _sender.getCommands(true, true)); for (uint32_t i = 0; i < 8; ++i) { sendReply(*op, i); } - CPPUNIT_ASSERT_EQUAL( - std::string("BucketInfoReply(BucketInfo(invalid)) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("BucketInfoReply(BucketInfo(invalid)) ReturnCode(NONE)", + _sender.getLastReply()); } -} // distributor -} // storage +} // storage::distributor diff --git a/storage/src/tests/distributor/removeoperationtest.cpp b/storage/src/tests/distributor/removeoperationtest.cpp index 24c40f50894..bae2395bfa7 100644 --- a/storage/src/tests/distributor/removeoperationtest.cpp +++ b/storage/src/tests/distributor/removeoperationtest.cpp @@ -1,6 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <cppunit/extensions/HelperMacros.h> #include <iomanip> #include <tests/common/dummystoragelink.h> #include <vespa/storage/distributor/distributor.h> @@ -8,40 +7,19 @@ #include <tests/distributor/distributortestutil.h> #include <vespa/document/test/make_document_bucket.h> #include <vespa/storage/distributor/operations/external/removeoperation.h> +#include <vespa/vespalib/gtest/gtest.h> using document::test::makeDocumentBucket; +using namespace ::testing; -namespace storage { -namespace distributor { - -class RemoveOperationTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ - CPPUNIT_TEST_SUITE(RemoveOperationTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(testNotFound); - CPPUNIT_TEST(testStorageFailure); - CPPUNIT_TEST(testNotInDB); - CPPUNIT_TEST(testMultipleCopies); - CPPUNIT_TEST(canSendRemoveWhenAllReplicaNodesRetired); - CPPUNIT_TEST_SUITE_END(); - -protected: - void testSimple(); - void testNotFound(); - void testStorageFailure(); - void testNoReply(); - void testNotInDB(); - void testMultipleCopies(); - void testRevert(); - void canSendRemoveWhenAllReplicaNodesRetired(); - -public: +namespace storage::distributor { + +struct RemoveOperationTest : Test, DistributorTestUtil { document::DocumentId docId; document::BucketId bucketId; std::unique_ptr<RemoveOperation> op; - void setUp() override { + void SetUp() override { createLinks(); docId = document::DocumentId(document::DocIdString("test", "uri")); @@ -49,19 +27,19 @@ public: enableDistributorClusterState("distributor:1 storage:4"); }; - void tearDown() override { + void TearDown() override { close(); } void sendRemove(document::DocumentId dId) { - std::shared_ptr<api::RemoveCommand> msg( - new api::RemoveCommand(makeDocumentBucket(document::BucketId(0)), dId, 100)); + auto msg = std::make_shared<api::RemoveCommand>(makeDocumentBucket(document::BucketId(0)), dId, 100); - op.reset(new RemoveOperation(getExternalOperationHandler(), - getDistributorBucketSpace(), - msg, - getDistributor().getMetrics(). - removes[msg->getLoadType()])); + op = std::make_unique<RemoveOperation>( + getExternalOperationHandler(), + getDistributorBucketSpace(), + msg, + getDistributor().getMetrics(). + removes[msg->getLoadType()]); op->start(_sender, framework::MilliSecTime(0)); } @@ -71,13 +49,13 @@ public: uint64_t oldTimestamp) { if (index == (uint32_t)-1) { - index = _sender.commands.size() - 1; + index = _sender.commands().size() - 1; } - std::shared_ptr<api::StorageMessage> msg2 = _sender.commands[index]; - api::RemoveCommand* removec = dynamic_cast<api::RemoveCommand*>(msg2.get()); + std::shared_ptr<api::StorageMessage> msg2 = _sender.command(index); + auto* removec = dynamic_cast<api::RemoveCommand*>(msg2.get()); std::unique_ptr<api::StorageReply> reply(removec->makeReply()); - api::RemoveReply* removeR = static_cast<api::RemoveReply*>(reply.get()); + auto* removeR = static_cast<api::RemoveReply*>(reply.get()); removeR->setOldTimestamp(oldTimestamp); callback.onReceive(_sender, std::shared_ptr<api::StorageReply>(reply.release())); @@ -88,116 +66,92 @@ public: } }; -CPPUNIT_TEST_SUITE_REGISTRATION(RemoveOperationTest); - -void -RemoveOperationTest::testSimple() -{ +TEST_F(RemoveOperationTest, simple) { addNodesToBucketDB(bucketId, "1=0"); sendRemove(); - CPPUNIT_ASSERT_EQUAL( - std::string("Remove(BucketId(0x4000000000002a52), doc:test:uri, " - "timestamp 100) => 1"), + ASSERT_EQ("Remove(BucketId(0x4000000000002a52), doc:test:uri, " + "timestamp 100) => 1", _sender.getLastCommand()); replyToMessage(*op, -1, 34); - CPPUNIT_ASSERT_EQUAL( - std::string("RemoveReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 100, removed doc from 34) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("RemoveReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 100, removed doc from 34) ReturnCode(NONE)", + _sender.getLastReply()); } -void -RemoveOperationTest::testNotFound() -{ +TEST_F(RemoveOperationTest, not_found) { addNodesToBucketDB(bucketId, "1=0"); sendRemove(); - CPPUNIT_ASSERT_EQUAL( - std::string("Remove(BucketId(0x4000000000002a52), doc:test:uri, " - "timestamp 100) => 1"), - _sender.getLastCommand()); + ASSERT_EQ("Remove(BucketId(0x4000000000002a52), doc:test:uri, " + "timestamp 100) => 1", + _sender.getLastCommand()); replyToMessage(*op, -1, 0); - CPPUNIT_ASSERT_EQUAL( - std::string("RemoveReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 100, not found) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("RemoveReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 100, not found) ReturnCode(NONE)", + _sender.getLastReply()); } -void -RemoveOperationTest::testStorageFailure() -{ +TEST_F(RemoveOperationTest, storage_failure) { addNodesToBucketDB(bucketId, "1=0"); sendRemove(); - CPPUNIT_ASSERT_EQUAL( - std::string("Remove(BucketId(0x4000000000002a52), doc:test:uri, " - "timestamp 100) => 1"), - _sender.getLastCommand()); + ASSERT_EQ("Remove(BucketId(0x4000000000002a52), doc:test:uri, " + "timestamp 100) => 1", + _sender.getLastCommand()); sendReply(*op, -1, api::ReturnCode::INTERNAL_FAILURE); - CPPUNIT_ASSERT_EQUAL( - std::string("RemoveReply(BucketId(0x0000000000000000), doc:test:uri, " - "timestamp 100, not found) ReturnCode(INTERNAL_FAILURE)"), - _sender.getLastReply()); + ASSERT_EQ("RemoveReply(BucketId(0x0000000000000000), doc:test:uri, " + "timestamp 100, not found) ReturnCode(INTERNAL_FAILURE)", + _sender.getLastReply()); } -void -RemoveOperationTest::testNotInDB() -{ +TEST_F(RemoveOperationTest, not_in_db) { sendRemove(); - CPPUNIT_ASSERT_EQUAL(std::string("RemoveReply(BucketId(0x0000000000000000), " - "doc:test:uri, timestamp 100, not found) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("RemoveReply(BucketId(0x0000000000000000), " + "doc:test:uri, timestamp 100, not found) ReturnCode(NONE)", + _sender.getLastReply()); } -void -RemoveOperationTest::testMultipleCopies() -{ +TEST_F(RemoveOperationTest, multiple_copies) { addNodesToBucketDB(bucketId, "1=0, 2=0, 3=0"); sendRemove(); - CPPUNIT_ASSERT_EQUAL( - std::string("Remove(BucketId(0x4000000000002a52), doc:test:uri, " - "timestamp 100) => 1," - "Remove(BucketId(0x4000000000002a52), doc:test:uri, " - "timestamp 100) => 2," - "Remove(BucketId(0x4000000000002a52), doc:test:uri, " - "timestamp 100) => 3"), - _sender.getCommands(true, true)); + ASSERT_EQ("Remove(BucketId(0x4000000000002a52), doc:test:uri, " + "timestamp 100) => 1," + "Remove(BucketId(0x4000000000002a52), doc:test:uri, " + "timestamp 100) => 2," + "Remove(BucketId(0x4000000000002a52), doc:test:uri, " + "timestamp 100) => 3", + _sender.getCommands(true, true)); replyToMessage(*op, 0, 34); replyToMessage(*op, 1, 34); replyToMessage(*op, 2, 75); - CPPUNIT_ASSERT_EQUAL( - std::string("RemoveReply(BucketId(0x0000000000000000), " - "doc:test:uri, timestamp 100, removed doc from 75) ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("RemoveReply(BucketId(0x0000000000000000), " + "doc:test:uri, timestamp 100, removed doc from 75) ReturnCode(NONE)", + _sender.getLastReply()); } -void -RemoveOperationTest::canSendRemoveWhenAllReplicaNodesRetired() -{ +TEST_F(RemoveOperationTest, can_send_remove_when_all_replica_nodes_retired) { enableDistributorClusterState("distributor:1 storage:1 .0.s:r"); addNodesToBucketDB(bucketId, "0=123"); sendRemove(); - CPPUNIT_ASSERT_EQUAL( - std::string("Remove(BucketId(0x4000000000002a52), doc:test:uri, " - "timestamp 100) => 0"), - _sender.getLastCommand()); + ASSERT_EQ("Remove(BucketId(0x4000000000002a52), doc:test:uri, " + "timestamp 100) => 0", + _sender.getLastCommand()); } -} // distributor -} // storage +} // storage::distributor diff --git a/storage/src/tests/distributor/simplebucketprioritydatabasetest.cpp b/storage/src/tests/distributor/simplebucketprioritydatabasetest.cpp index f12917b0936..21ef2fa18bd 100644 --- a/storage/src/tests/distributor/simplebucketprioritydatabasetest.cpp +++ b/storage/src/tests/distributor/simplebucketprioritydatabasetest.cpp @@ -1,69 +1,38 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> -#include <string> -#include <vespa/storage/distributor/maintenance/simplebucketprioritydatabase.h> #include <vespa/document/test/make_document_bucket.h> +#include <vespa/storage/distributor/maintenance/simplebucketprioritydatabase.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <string> using document::test::makeDocumentBucket; -namespace storage { - -namespace distributor { +namespace storage::distributor { using document::BucketId; -typedef MaintenancePriority Priority; - -class SimpleBucketPriorityDatabaseTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(SimpleBucketPriorityDatabaseTest); - CPPUNIT_TEST(testIteratorRangeIsEqualOnEmptyDatabase); - CPPUNIT_TEST(testCanGetPrioritizedBucket); - CPPUNIT_TEST(testIterateOverMultiplePriorities); - CPPUNIT_TEST(testMultipleSetPriorityForOneBucket); - CPPUNIT_TEST(testIterateOverMultipleBucketsWithMultiplePriorities); - CPPUNIT_TEST(testNoMaintenanceNeededClearsBucketFromDatabase); - CPPUNIT_TEST_SUITE_END(); - - typedef SimpleBucketPriorityDatabase::const_iterator const_iterator; - -public: - void testIteratorRangeIsEqualOnEmptyDatabase(); - void testCanGetPrioritizedBucket(); - void testIterateOverMultiplePriorities(); - void testMultipleSetPriorityForOneBucket(); - void testIterateOverMultipleBucketsWithMultiplePriorities(); - void testNoMaintenanceNeededClearsBucketFromDatabase(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(SimpleBucketPriorityDatabaseTest); - -void -SimpleBucketPriorityDatabaseTest::testIteratorRangeIsEqualOnEmptyDatabase() -{ +using Priority = MaintenancePriority; + +TEST(SimpleBucketPriorityDatabaseTest, iterator_range_is_equal_on_empty_database) { SimpleBucketPriorityDatabase queue; - const_iterator begin(queue.begin()); - const_iterator end(queue.end()); + auto begin = queue.begin(); + auto end = queue.end(); - CPPUNIT_ASSERT(begin == end); - CPPUNIT_ASSERT(begin == begin); - CPPUNIT_ASSERT(end == end); + EXPECT_TRUE(begin == end); + EXPECT_TRUE(begin == begin); + EXPECT_TRUE(end == end); } -void -SimpleBucketPriorityDatabaseTest::testCanGetPrioritizedBucket() -{ +TEST(SimpleBucketPriorityDatabaseTest, can_get_prioritized_bucket) { SimpleBucketPriorityDatabase queue; PrioritizedBucket lowPriBucket(makeDocumentBucket(BucketId(16, 1234)), Priority::VERY_LOW); queue.setPriority(lowPriBucket); PrioritizedBucket highest(*queue.begin()); - CPPUNIT_ASSERT_EQUAL(lowPriBucket, highest); + EXPECT_EQ(lowPriBucket, highest); } -void -SimpleBucketPriorityDatabaseTest::testIterateOverMultiplePriorities() -{ +TEST(SimpleBucketPriorityDatabaseTest, iterate_over_multiple_priorities) { SimpleBucketPriorityDatabase queue; PrioritizedBucket lowPriBucket(makeDocumentBucket(BucketId(16, 1234)), Priority::LOW); @@ -71,18 +40,16 @@ SimpleBucketPriorityDatabaseTest::testIterateOverMultiplePriorities() queue.setPriority(lowPriBucket); queue.setPriority(highPriBucket); - const_iterator iter(queue.begin()); - CPPUNIT_ASSERT_EQUAL(highPriBucket, *iter); + auto iter = queue.begin(); + ASSERT_EQ(highPriBucket, *iter); ++iter; - CPPUNIT_ASSERT(iter != queue.end()); - CPPUNIT_ASSERT_EQUAL(lowPriBucket, *iter); + ASSERT_TRUE(iter != queue.end()); + ASSERT_EQ(lowPriBucket, *iter); ++iter; - CPPUNIT_ASSERT(iter == queue.end()); + ASSERT_TRUE(iter == queue.end()); } -void -SimpleBucketPriorityDatabaseTest::testMultipleSetPriorityForOneBucket() -{ +TEST(SimpleBucketPriorityDatabaseTest, multiple_set_priority_for_one_bucket) { SimpleBucketPriorityDatabase queue; PrioritizedBucket lowPriBucket(makeDocumentBucket(BucketId(16, 1234)), Priority::LOW); @@ -91,15 +58,13 @@ SimpleBucketPriorityDatabaseTest::testMultipleSetPriorityForOneBucket() queue.setPriority(lowPriBucket); queue.setPriority(highPriBucket); - const_iterator iter(queue.begin()); - CPPUNIT_ASSERT_EQUAL(highPriBucket, *iter); + auto iter = queue.begin(); + ASSERT_EQ(highPriBucket, *iter); ++iter; - CPPUNIT_ASSERT(iter == queue.end()); + ASSERT_TRUE(iter == queue.end()); } -void -SimpleBucketPriorityDatabaseTest::testNoMaintenanceNeededClearsBucketFromDatabase() -{ +TEST(SimpleBucketPriorityDatabaseTest, no_maintenance_needed_clears_bucket_from_database) { SimpleBucketPriorityDatabase queue; PrioritizedBucket highPriBucket(makeDocumentBucket(BucketId(16, 1234)), Priority::HIGH); @@ -108,13 +73,11 @@ SimpleBucketPriorityDatabaseTest::testNoMaintenanceNeededClearsBucketFromDatabas queue.setPriority(highPriBucket); queue.setPriority(noPriBucket); - const_iterator iter(queue.begin()); - CPPUNIT_ASSERT(iter == queue.end()); + auto iter = queue.begin(); + ASSERT_TRUE(iter == queue.end()); } -void -SimpleBucketPriorityDatabaseTest::testIterateOverMultipleBucketsWithMultiplePriorities() -{ +TEST(SimpleBucketPriorityDatabaseTest, iterate_over_multiple_buckets_with_multiple_priorities) { SimpleBucketPriorityDatabase queue; PrioritizedBucket lowPriBucket1(makeDocumentBucket(BucketId(16, 1)), Priority::LOW); @@ -129,17 +92,15 @@ SimpleBucketPriorityDatabaseTest::testIterateOverMultipleBucketsWithMultiplePrio queue.setPriority(highPriBucket2); queue.setPriority(lowPriBucket1); - const_iterator iter(queue.begin()); + auto iter = queue.begin(); PrioritizedBucket lastBucket(makeDocumentBucket(BucketId()), Priority::PRIORITY_LIMIT); for (int i = 0; i < 5; ++i) { - CPPUNIT_ASSERT(iter != queue.end()); - CPPUNIT_ASSERT(!iter->moreImportantThan(lastBucket)); + ASSERT_TRUE(iter != queue.end()); + ASSERT_FALSE(iter->moreImportantThan(lastBucket)); lastBucket = *iter; ++iter; } - CPPUNIT_ASSERT(iter == queue.end()); + ASSERT_TRUE(iter == queue.end()); } } -} - diff --git a/storage/src/tests/distributor/simplemaintenancescannertest.cpp b/storage/src/tests/distributor/simplemaintenancescannertest.cpp index ac4a5bbfb91..b21a10c319e 100644 --- a/storage/src/tests/distributor/simplemaintenancescannertest.cpp +++ b/storage/src/tests/distributor/simplemaintenancescannertest.cpp @@ -6,29 +6,19 @@ #include <vespa/storage/distributor/distributor_bucket_space_repo.h> #include <vespa/storage/distributor/maintenance/simplebucketprioritydatabase.h> #include <vespa/storage/distributor/maintenance/simplemaintenancescanner.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/vespalib/text/stringtokenizer.h> +#include <vespa/vespalib/gtest/gtest.h> namespace storage::distributor { using document::BucketId; using document::test::makeBucketSpace; -typedef MaintenancePriority Priority; - -class SimpleMaintenanceScannerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(SimpleMaintenanceScannerTest); - CPPUNIT_TEST(testPrioritizeSingleBucket); - CPPUNIT_TEST(testPrioritizeSingleBucketAltBucketSpace); - CPPUNIT_TEST(testPrioritizeMultipleBuckets); - CPPUNIT_TEST(testPendingMaintenanceOperationStatistics); - CPPUNIT_TEST(perNodeMaintenanceStatsAreTracked); - CPPUNIT_TEST(testReset); - CPPUNIT_TEST_SUITE_END(); +using Priority = MaintenancePriority; +using namespace ::testing; +struct SimpleMaintenanceScannerTest : Test { using PendingStats = SimpleMaintenanceScanner::PendingMaintenanceStats; - std::string dumpPriorityDbToString(const BucketPriorityDatabase&) const; - std::unique_ptr<MockMaintenancePriorityGenerator> _priorityGenerator; std::unique_ptr<DistributorBucketSpaceRepo> _bucketSpaceRepo; std::unique_ptr<SimpleBucketPriorityDatabase> _priorityDb; @@ -36,38 +26,26 @@ class SimpleMaintenanceScannerTest : public CppUnit::TestFixture { void addBucketToDb(document::BucketSpace bucketSpace, int bucketNum); void addBucketToDb(int bucketNum); - bool scanEntireDatabase(int expected); + std::string stringifyGlobalPendingStats(const PendingStats& stats) const; - std::string stringifyGlobalPendingStats(const PendingStats&) const; - -public: - void testPrioritizeSingleBucket(); - void testPrioritizeSingleBucketAltBucketSpace(); - void testPrioritizeMultipleBuckets(); - void testPendingMaintenanceOperationStatistics(); - void perNodeMaintenanceStatsAreTracked(); - void testReset(); - - void setUp() override; + void SetUp() override; }; -CPPUNIT_TEST_SUITE_REGISTRATION(SimpleMaintenanceScannerTest); - void -SimpleMaintenanceScannerTest::setUp() +SimpleMaintenanceScannerTest::SetUp() { - _priorityGenerator.reset(new MockMaintenancePriorityGenerator()); + _priorityGenerator = std::make_unique<MockMaintenancePriorityGenerator>(); _bucketSpaceRepo = std::make_unique<DistributorBucketSpaceRepo>(); - _priorityDb.reset(new SimpleBucketPriorityDatabase()); - _scanner.reset(new SimpleMaintenanceScanner(*_priorityDb, *_priorityGenerator, *_bucketSpaceRepo)); + _priorityDb = std::make_unique<SimpleBucketPriorityDatabase>(); + _scanner = std::make_unique<SimpleMaintenanceScanner>(*_priorityDb, *_priorityGenerator, *_bucketSpaceRepo); } void SimpleMaintenanceScannerTest::addBucketToDb(document::BucketSpace bucketSpace, int bucketNum) { BucketDatabase::Entry entry(BucketId(16, bucketNum), BucketInfo()); - auto &bucketDb(_bucketSpaceRepo->get(bucketSpace).getBucketDatabase()); + auto& bucketDb(_bucketSpaceRepo->get(bucketSpace).getBucketDatabase()); bucketDb.update(entry); } @@ -86,24 +64,20 @@ SimpleMaintenanceScannerTest::stringifyGlobalPendingStats( return ss.str(); } -void -SimpleMaintenanceScannerTest::testPrioritizeSingleBucket() -{ +TEST_F(SimpleMaintenanceScannerTest, prioritize_single_bucket) { addBucketToDb(1); std::string expected("PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri VERY_HIGH)\n"); auto scanResult = _scanner->scanNext(); - CPPUNIT_ASSERT(!scanResult.isDone()); - CPPUNIT_ASSERT_EQUAL(makeBucketSpace().getId(), scanResult.getBucketSpace().getId()); - CPPUNIT_ASSERT_EQUAL(expected, _priorityDb->toString()); + ASSERT_FALSE(scanResult.isDone()); + EXPECT_EQ(makeBucketSpace().getId(), scanResult.getBucketSpace().getId()); + EXPECT_EQ(expected, _priorityDb->toString()); - CPPUNIT_ASSERT(_scanner->scanNext().isDone()); - CPPUNIT_ASSERT_EQUAL(expected, _priorityDb->toString()); + ASSERT_TRUE(_scanner->scanNext().isDone()); + EXPECT_EQ(expected, _priorityDb->toString()); } -void -SimpleMaintenanceScannerTest::testPrioritizeSingleBucketAltBucketSpace() -{ +TEST_F(SimpleMaintenanceScannerTest, prioritize_single_bucket_alt_bucket_space) { document::BucketSpace bucketSpace(4); _bucketSpaceRepo->add(bucketSpace, std::make_unique<DistributorBucketSpace>()); _scanner->reset(); @@ -111,31 +85,31 @@ SimpleMaintenanceScannerTest::testPrioritizeSingleBucketAltBucketSpace() std::string expected("PrioritizedBucket(Bucket(BucketSpace(0x0000000000000004), BucketId(0x4000000000000001)), pri VERY_HIGH)\n"); auto scanResult = _scanner->scanNext(); - CPPUNIT_ASSERT(!scanResult.isDone()); - CPPUNIT_ASSERT_EQUAL(bucketSpace.getId(), scanResult.getBucketSpace().getId()); - CPPUNIT_ASSERT_EQUAL(expected, _priorityDb->toString()); + ASSERT_FALSE(scanResult.isDone()); + EXPECT_EQ(bucketSpace.getId(), scanResult.getBucketSpace().getId()); + EXPECT_EQ(expected, _priorityDb->toString()); - CPPUNIT_ASSERT(_scanner->scanNext().isDone()); - CPPUNIT_ASSERT_EQUAL(expected, _priorityDb->toString()); + ASSERT_TRUE(_scanner->scanNext().isDone()); + EXPECT_EQ(expected, _priorityDb->toString()); } namespace { - std::string sortLines(const std::string& source) { - vespalib::StringTokenizer st(source,"\n",""); - std::vector<std::string> lines; - std::copy(st.begin(), st.end(), std::back_inserter(lines)); - std::sort(lines.begin(), lines.end()); - std::ostringstream ost; - for (auto& line : lines) { - ost << line << "\n"; - } - return ost.str(); + +std::string sortLines(const std::string& source) { + vespalib::StringTokenizer st(source,"\n",""); + std::vector<std::string> lines; + std::copy(st.begin(), st.end(), std::back_inserter(lines)); + std::sort(lines.begin(), lines.end()); + std::ostringstream ost; + for (auto& line : lines) { + ost << line << "\n"; } + return ost.str(); } -void -SimpleMaintenanceScannerTest::testPrioritizeMultipleBuckets() -{ +} + +TEST_F(SimpleMaintenanceScannerTest, prioritize_multiple_buckets) { addBucketToDb(1); addBucketToDb(2); addBucketToDb(3); @@ -143,9 +117,9 @@ SimpleMaintenanceScannerTest::testPrioritizeMultipleBuckets() "PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000002)), pri VERY_HIGH)\n" "PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000003)), pri VERY_HIGH)\n"); - CPPUNIT_ASSERT(scanEntireDatabase(3)); - CPPUNIT_ASSERT_EQUAL(sortLines(expected), - sortLines(_priorityDb->toString())); + ASSERT_TRUE(scanEntireDatabase(3)); + EXPECT_EQ(sortLines(expected), + sortLines(_priorityDb->toString())); } bool @@ -159,33 +133,29 @@ SimpleMaintenanceScannerTest::scanEntireDatabase(int expected) return _scanner->scanNext().isDone(); } -void -SimpleMaintenanceScannerTest::testReset() -{ +TEST_F(SimpleMaintenanceScannerTest, reset) { addBucketToDb(1); addBucketToDb(3); - CPPUNIT_ASSERT(scanEntireDatabase(2)); + ASSERT_TRUE(scanEntireDatabase(2)); std::string expected("PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri VERY_HIGH)\n" "PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000003)), pri VERY_HIGH)\n"); - CPPUNIT_ASSERT_EQUAL(expected, _priorityDb->toString()); + EXPECT_EQ(expected, _priorityDb->toString()); addBucketToDb(2); - CPPUNIT_ASSERT(scanEntireDatabase(0)); - CPPUNIT_ASSERT_EQUAL(expected, _priorityDb->toString()); + ASSERT_TRUE(scanEntireDatabase(0)); + EXPECT_EQ(expected, _priorityDb->toString()); _scanner->reset(); - CPPUNIT_ASSERT(scanEntireDatabase(3)); + ASSERT_TRUE(scanEntireDatabase(3)); expected = "PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri VERY_HIGH)\n" "PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000002)), pri VERY_HIGH)\n" "PrioritizedBucket(Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000003)), pri VERY_HIGH)\n"; - CPPUNIT_ASSERT_EQUAL(sortLines(expected), sortLines(_priorityDb->toString())); + EXPECT_EQ(sortLines(expected), sortLines(_priorityDb->toString())); } -void -SimpleMaintenanceScannerTest::testPendingMaintenanceOperationStatistics() -{ +TEST_F(SimpleMaintenanceScannerTest, pending_maintenance_operation_statistics) { addBucketToDb(1); addBucketToDb(3); @@ -194,10 +164,10 @@ SimpleMaintenanceScannerTest::testPendingMaintenanceOperationStatistics() "set bucket state: 0, garbage collection: 0"); { auto stats(_scanner->getPendingMaintenanceStats()); - CPPUNIT_ASSERT_EQUAL(expectedEmpty, stringifyGlobalPendingStats(stats)); + EXPECT_EQ(expectedEmpty, stringifyGlobalPendingStats(stats)); } - CPPUNIT_ASSERT(scanEntireDatabase(2)); + ASSERT_TRUE(scanEntireDatabase(2)); // All mock operations generated have the merge type. { @@ -205,39 +175,37 @@ SimpleMaintenanceScannerTest::testPendingMaintenanceOperationStatistics() std::string expected("delete bucket: 0, merge bucket: 2, " "split bucket: 0, join bucket: 0, " "set bucket state: 0, garbage collection: 0"); - CPPUNIT_ASSERT_EQUAL(expected, stringifyGlobalPendingStats(stats)); + EXPECT_EQ(expected, stringifyGlobalPendingStats(stats)); } _scanner->reset(); { auto stats(_scanner->getPendingMaintenanceStats()); - CPPUNIT_ASSERT_EQUAL(expectedEmpty, stringifyGlobalPendingStats(stats)); + EXPECT_EQ(expectedEmpty, stringifyGlobalPendingStats(stats)); } } -void -SimpleMaintenanceScannerTest::perNodeMaintenanceStatsAreTracked() -{ +TEST_F(SimpleMaintenanceScannerTest, per_node_maintenance_stats_are_tracked) { addBucketToDb(1); addBucketToDb(3); { auto stats(_scanner->getPendingMaintenanceStats()); NodeMaintenanceStats emptyStats; - CPPUNIT_ASSERT_EQUAL(emptyStats, stats.perNodeStats.forNode(0, makeBucketSpace())); + EXPECT_EQ(emptyStats, stats.perNodeStats.forNode(0, makeBucketSpace())); } - CPPUNIT_ASSERT(scanEntireDatabase(2)); + ASSERT_TRUE(scanEntireDatabase(2)); // Mock is currently hardwired to increment movingOut for node 1 and // copyingIn for node 2 per bucket iterated (we've got 2). auto stats(_scanner->getPendingMaintenanceStats()); { NodeMaintenanceStats wantedNode1Stats; wantedNode1Stats.movingOut = 2; - CPPUNIT_ASSERT_EQUAL(wantedNode1Stats, stats.perNodeStats.forNode(1, makeBucketSpace())); + EXPECT_EQ(wantedNode1Stats, stats.perNodeStats.forNode(1, makeBucketSpace())); } { NodeMaintenanceStats wantedNode2Stats; wantedNode2Stats.copyingIn = 2; - CPPUNIT_ASSERT_EQUAL(wantedNode2Stats, stats.perNodeStats.forNode(2, makeBucketSpace())); + EXPECT_EQ(wantedNode2Stats, stats.perNodeStats.forNode(2, makeBucketSpace())); } } diff --git a/storage/src/tests/distributor/splitbuckettest.cpp b/storage/src/tests/distributor/splitbuckettest.cpp index aead043e120..d88b02b332e 100644 --- a/storage/src/tests/distributor/splitbuckettest.cpp +++ b/storage/src/tests/distributor/splitbuckettest.cpp @@ -1,6 +1,4 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <cppunit/extensions/HelperMacros.h> -#include <iomanip> #include <tests/common/dummystoragelink.h> #include <vespa/storageapi/message/bucketsplitting.h> #include <vespa/storage/distributor/operations/idealstate/splitoperation.h> @@ -10,53 +8,34 @@ #include <tests/distributor/distributortestutil.h> #include <vespa/document/test/make_document_bucket.h> #include <vespa/storage/distributor/distributor.h> +#include <vespa/vespalib/gtest/gtest.h> -using std::shared_ptr; -using namespace document; using document::test::makeDocumentBucket; +using namespace document; +using namespace ::testing; -namespace storage { - -namespace distributor { - -class SplitOperationTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ - CPPUNIT_TEST_SUITE(SplitOperationTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(testMultiNodeFailure); - CPPUNIT_TEST(testCopyTrustedStatusNotCarriedOverAfterSplit); - CPPUNIT_TEST(testOperationBlockedByPendingJoin); - CPPUNIT_TEST_SUITE_END(); +namespace storage::distributor { +struct SplitOperationTest : Test, DistributorTestUtil { uint32_t splitByteSize; uint32_t tooLargeBucketSize; uint32_t splitCount; uint32_t maxSplitBits; -protected: - void testSimple(); - void testMultiNodeFailure(); - void testCopyTrustedStatusNotCarriedOverAfterSplit(); - void testOperationBlockedByPendingJoin(); - -public: SplitOperationTest(); - void setUp() override { + void SetUp() override { createLinks(); getConfig().setSplitCount(splitCount); getConfig().setSplitSize(splitByteSize); } - void tearDown() override { + void TearDown() override { close(); } }; -CPPUNIT_TEST_SUITE_REGISTRATION(SplitOperationTest); - SplitOperationTest::SplitOperationTest() : splitByteSize(10*1024*1024), tooLargeBucketSize(splitByteSize * 1.1), @@ -65,9 +44,7 @@ SplitOperationTest::SplitOperationTest() { } -void -SplitOperationTest::testSimple() -{ +TEST_F(SplitOperationTest, simple) { enableDistributorClusterState("distributor:1 storage:1"); insertBucketInfo(document::BucketId(16, 1), 0, 0xabc, 1000, @@ -84,60 +61,51 @@ SplitOperationTest::testSimple() op.start(_sender, framework::MilliSecTime(0)); { - CPPUNIT_ASSERT_EQUAL(size_t(1), _sender.commands.size()); + ASSERT_EQ(1, _sender.commands().size()); - std::shared_ptr<api::StorageCommand> msg = _sender.commands[0]; - CPPUNIT_ASSERT(msg->getType() == api::MessageType::SPLITBUCKET); - CPPUNIT_ASSERT_EQUAL( - api::StorageMessageAddress("storage", lib::NodeType::STORAGE, 0) - .toString(), - msg->getAddress()->toString()); + std::shared_ptr<api::StorageCommand> msg = _sender.command(0); + ASSERT_EQ(msg->getType(), api::MessageType::SPLITBUCKET); + EXPECT_EQ(api::StorageMessageAddress("storage", lib::NodeType::STORAGE, 0).toString(), + msg->getAddress()->toString()); std::shared_ptr<api::StorageReply> reply(msg->makeReply().release()); - api::SplitBucketReply* sreply( - static_cast<api::SplitBucketReply*>(reply.get())); + auto* sreply = static_cast<api::SplitBucketReply*>(reply.get()); - sreply->getSplitInfo().push_back(api::SplitBucketReply::Entry( - document::BucketId(17, 1), - api::BucketInfo(100, 600, 5000000))); + sreply->getSplitInfo().emplace_back(document::BucketId(17, 1), + api::BucketInfo(100, 600, 5000000)); - sreply->getSplitInfo().push_back(api::SplitBucketReply::Entry( - document::BucketId(17, 0x10001), - api::BucketInfo(110, 400, 6000000))); + sreply->getSplitInfo().emplace_back(document::BucketId(17, 0x10001), + api::BucketInfo(110, 400, 6000000)); op.receive(_sender, reply); } - CPPUNIT_ASSERT(!getBucket(document::BucketId(16, 1)).valid()); + ASSERT_FALSE(getBucket(document::BucketId(16, 1)).valid()); { BucketDatabase::Entry entry = getBucket(document::BucketId(17, 1)); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT_EQUAL((uint16_t)0, entry->getNodeRef(0).getNode()); - CPPUNIT_ASSERT_EQUAL((uint32_t)100, entry->getNodeRef(0).getChecksum()); - CPPUNIT_ASSERT_EQUAL((uint32_t)5000000, - entry->getNodeRef(0).getTotalDocumentSize()); - CPPUNIT_ASSERT_EQUAL((uint32_t)600, - entry->getNodeRef(0).getDocumentCount()); + ASSERT_TRUE(entry.valid()); + ASSERT_EQ(1, entry->getNodeCount()); + EXPECT_EQ(0, entry->getNodeRef(0).getNode()); + EXPECT_EQ(100, entry->getNodeRef(0).getChecksum()); + EXPECT_EQ(5000000, entry->getNodeRef(0).getTotalDocumentSize()); + EXPECT_EQ(600, entry->getNodeRef(0).getDocumentCount()); } { BucketDatabase::Entry entry(getBucket(document::BucketId(17, 0x10001))); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT_EQUAL((uint16_t)0, entry->getNodeRef(0).getNode()); - CPPUNIT_ASSERT_EQUAL((uint32_t)110, entry->getNodeRef(0).getChecksum()); - CPPUNIT_ASSERT_EQUAL((uint32_t)6000000, - entry->getNodeRef(0).getTotalDocumentSize()); - CPPUNIT_ASSERT_EQUAL((uint32_t)400, - entry->getNodeRef(0).getDocumentCount()); + ASSERT_TRUE(entry.valid()); + ASSERT_EQ(1, entry->getNodeCount()); + EXPECT_EQ(0, entry->getNodeRef(0).getNode()); + EXPECT_EQ(110, entry->getNodeRef(0).getChecksum()); + EXPECT_EQ(6000000, entry->getNodeRef(0).getTotalDocumentSize()); + EXPECT_EQ(400, entry->getNodeRef(0).getDocumentCount()); } } -void -SplitOperationTest::testMultiNodeFailure() -{ +TEST_F(SplitOperationTest, multi_node_failure) { { BucketDatabase::Entry entry(document::BucketId(16, 1)); @@ -151,7 +119,6 @@ SplitOperationTest::testMultiNodeFailure() enableDistributorClusterState("distributor:1 storage:2"); - SplitOperation op("storage", BucketAndNodes(makeDocumentBucket(document::BucketId(16, 1)), toVector<uint16_t>(0,1)), @@ -163,28 +130,22 @@ SplitOperationTest::testMultiNodeFailure() op.start(_sender, framework::MilliSecTime(0)); { - CPPUNIT_ASSERT_EQUAL((size_t)2, _sender.commands.size()); + ASSERT_EQ(2, _sender.commands().size()); { - std::shared_ptr<api::StorageCommand> msg = _sender.commands[0]; - CPPUNIT_ASSERT(msg->getType() == api::MessageType::SPLITBUCKET); - CPPUNIT_ASSERT_EQUAL( - api::StorageMessageAddress("storage", - lib::NodeType::STORAGE, 0).toString(), - msg->getAddress()->toString()); - - api::SplitBucketReply* sreply( - static_cast<api::SplitBucketReply*>( - msg->makeReply().release())); + std::shared_ptr<api::StorageCommand> msg = _sender.command(0); + ASSERT_EQ(msg->getType(), api::MessageType::SPLITBUCKET); + EXPECT_EQ(api::StorageMessageAddress("storage", lib::NodeType::STORAGE, 0).toString(), + msg->getAddress()->toString()); + + auto* sreply = static_cast<api::SplitBucketReply*>(msg->makeReply().release()); sreply->setResult(api::ReturnCode::OK); - sreply->getSplitInfo().push_back(api::SplitBucketReply::Entry( - document::BucketId(17, 1), - api::BucketInfo(100, 600, 5000000))); + sreply->getSplitInfo().emplace_back(document::BucketId(17, 1), + api::BucketInfo(100, 600, 5000000)); - sreply->getSplitInfo().push_back(api::SplitBucketReply::Entry( - document::BucketId(17, 0x10001), - api::BucketInfo(110, 400, 6000000))); + sreply->getSplitInfo().emplace_back(document::BucketId(17, 0x10001), + api::BucketInfo(110, 400, 6000000)); op.receive(_sender, std::shared_ptr<api::StorageReply>(sreply)); } @@ -195,49 +156,41 @@ SplitOperationTest::testMultiNodeFailure() { BucketDatabase::Entry entry = getBucket(document::BucketId(16, 1)); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT_EQUAL((uint32_t)1, entry->getNodeCount()); + ASSERT_TRUE(entry.valid()); + ASSERT_EQ(1, entry->getNodeCount()); - CPPUNIT_ASSERT_EQUAL((uint16_t)1, entry->getNodeRef(0).getNode()); - CPPUNIT_ASSERT_EQUAL((uint32_t)250, entry->getNodeRef(0).getChecksum()); - CPPUNIT_ASSERT_EQUAL(tooLargeBucketSize, - entry->getNodeRef(0).getTotalDocumentSize()); - CPPUNIT_ASSERT_EQUAL((uint32_t)1000, - entry->getNodeRef(0).getDocumentCount()); + EXPECT_EQ(1, entry->getNodeRef(0).getNode()); + EXPECT_EQ(250, entry->getNodeRef(0).getChecksum()); + EXPECT_EQ(tooLargeBucketSize, entry->getNodeRef(0).getTotalDocumentSize()); + EXPECT_EQ(1000, entry->getNodeRef(0).getDocumentCount()); } { BucketDatabase::Entry entry = getBucket(document::BucketId(17, 1)); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT_EQUAL((uint32_t)1, entry->getNodeCount()); + ASSERT_TRUE(entry.valid()); + ASSERT_EQ(1, entry->getNodeCount()); - CPPUNIT_ASSERT_EQUAL((uint16_t)0, entry->getNodeRef(0).getNode()); - CPPUNIT_ASSERT_EQUAL((uint32_t)100, entry->getNodeRef(0).getChecksum()); - CPPUNIT_ASSERT_EQUAL((uint32_t)5000000, - entry->getNodeRef(0).getTotalDocumentSize()); - CPPUNIT_ASSERT_EQUAL((uint32_t)600, - entry->getNodeRef(0).getDocumentCount()); + EXPECT_EQ(0, entry->getNodeRef(0).getNode()); + EXPECT_EQ(100, entry->getNodeRef(0).getChecksum()); + EXPECT_EQ(5000000, entry->getNodeRef(0).getTotalDocumentSize()); + EXPECT_EQ(600, entry->getNodeRef(0).getDocumentCount()); } { BucketDatabase::Entry entry(getBucket(document::BucketId(17, 0x10001))); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT_EQUAL((uint32_t)1, entry->getNodeCount()); + ASSERT_TRUE(entry.valid()); + ASSERT_EQ(1, entry->getNodeCount()); - CPPUNIT_ASSERT_EQUAL((uint16_t)0, entry->getNodeRef(0).getNode()); - CPPUNIT_ASSERT_EQUAL((uint32_t)110, entry->getNodeRef(0).getChecksum()); - CPPUNIT_ASSERT_EQUAL((uint32_t)6000000, - entry->getNodeRef(0).getTotalDocumentSize()); - CPPUNIT_ASSERT_EQUAL((uint32_t)400, - entry->getNodeRef(0).getDocumentCount()); + EXPECT_EQ(0, entry->getNodeRef(0).getNode()); + EXPECT_EQ(110, entry->getNodeRef(0).getChecksum()); + EXPECT_EQ(6000000, entry->getNodeRef(0).getTotalDocumentSize()); + EXPECT_EQ(400, entry->getNodeRef(0).getDocumentCount()); } } -void -SplitOperationTest::testCopyTrustedStatusNotCarriedOverAfterSplit() -{ +TEST_F(SplitOperationTest, copy_trusted_status_not_carried_over_after_split) { enableDistributorClusterState("distributor:1 storage:2"); document::BucketId sourceBucket(16, 1); @@ -260,48 +213,43 @@ SplitOperationTest::testCopyTrustedStatusNotCarriedOverAfterSplit() op.setIdealStateManager(&getIdealStateManager()); op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(size_t(3), _sender.commands.size()); + ASSERT_EQ(3, _sender.commands().size()); std::vector<document::BucketId> childBuckets; - childBuckets.push_back(document::BucketId(17, 1)); - childBuckets.push_back(document::BucketId(17, 0x10001)); + childBuckets.emplace_back(17, 1); + childBuckets.emplace_back(17, 0x10001); // Note: only 2 out of 3 requests replied to! for (int i = 0; i < 2; ++i) { - std::shared_ptr<api::StorageCommand> msg = _sender.commands[i]; - CPPUNIT_ASSERT(msg->getType() == api::MessageType::SPLITBUCKET); + std::shared_ptr<api::StorageCommand> msg = _sender.command(i); + ASSERT_EQ(msg->getType(), api::MessageType::SPLITBUCKET); std::shared_ptr<api::StorageReply> reply(msg->makeReply().release()); - api::SplitBucketReply* sreply( - static_cast<api::SplitBucketReply*>(reply.get())); + auto* sreply = static_cast<api::SplitBucketReply*>(reply.get()); // Make sure copies differ so they cannot become implicitly trusted. - sreply->getSplitInfo().push_back(api::SplitBucketReply::Entry( - childBuckets[0], - api::BucketInfo(100 + i, 600, 5000000))); - sreply->getSplitInfo().push_back(api::SplitBucketReply::Entry( - childBuckets[1], - api::BucketInfo(110 + i, 400, 6000000))); + sreply->getSplitInfo().emplace_back(childBuckets[0], + api::BucketInfo(100 + i, 600, 5000000)); + sreply->getSplitInfo().emplace_back(childBuckets[1], + api::BucketInfo(110 + i, 400, 6000000)); op.receive(_sender, reply); } - CPPUNIT_ASSERT(getBucket(sourceBucket).valid()); // Still alive + ASSERT_TRUE(getBucket(sourceBucket).valid()); // Still alive for (uint32_t i = 0; i < 2; ++i) { BucketDatabase::Entry entry(getBucket(childBuckets[i])); - CPPUNIT_ASSERT(entry.valid()); - CPPUNIT_ASSERT_EQUAL(size_t(2), entry->getNodes().size()); + ASSERT_TRUE(entry.valid()); + ASSERT_EQ(2, entry->getNodes().size()); for (uint16_t j = 0; j < 2; ++j) { - CPPUNIT_ASSERT(!entry->getNodeRef(i).trusted()); + EXPECT_FALSE(entry->getNodeRef(i).trusted()); } } } -void -SplitOperationTest::testOperationBlockedByPendingJoin() -{ +TEST_F(SplitOperationTest, operation_blocked_by_pending_join) { StorageComponentRegisterImpl compReg; framework::defaultimplementation::FakeClock clock; compReg.setClock(clock); @@ -321,7 +269,7 @@ SplitOperationTest::testOperationBlockedByPendingJoin() tracker.insert(joinCmd); - insertBucketInfo(joinTarget, 0, 0xabc, 1000, 1234, 250); + insertBucketInfo(joinTarget, 0, 0xabc, 1000, 1234, true); SplitOperation op("storage", BucketAndNodes(makeDocumentBucket(joinTarget), toVector<uint16_t>(0)), @@ -329,19 +277,18 @@ SplitOperationTest::testOperationBlockedByPendingJoin() splitCount, splitByteSize); - CPPUNIT_ASSERT(op.isBlocked(tracker)); + EXPECT_TRUE(op.isBlocked(tracker)); // Now, pretend there's a join for another node in the same bucket. This // will happen when a join is partially completed. tracker.clearMessagesForNode(0); - CPPUNIT_ASSERT(!op.isBlocked(tracker)); + EXPECT_FALSE(op.isBlocked(tracker)); joinCmd->setAddress( api::StorageMessageAddress("storage", lib::NodeType::STORAGE, 1)); tracker.insert(joinCmd); - CPPUNIT_ASSERT(op.isBlocked(tracker)); + EXPECT_TRUE(op.isBlocked(tracker)); } -} // distributor -} // storage +} // storage::distributor diff --git a/storage/src/tests/distributor/statecheckerstest.cpp b/storage/src/tests/distributor/statecheckerstest.cpp index 53de8ded38c..eb0902f6dd2 100644 --- a/storage/src/tests/distributor/statecheckerstest.cpp +++ b/storage/src/tests/distributor/statecheckerstest.cpp @@ -11,23 +11,23 @@ #include <vespa/storage/distributor/statecheckers.h> #include <vespa/storageapi/message/persistence.h> #include <vespa/storageapi/message/stat.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> -using namespace std::literals::string_literals; using document::test::makeBucketSpace; using document::test::makeDocumentBucket; +using namespace ::testing; namespace storage::distributor { -struct StateCheckersTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ - StateCheckersTest() {} +struct StateCheckersTest : Test, DistributorTestUtil { + StateCheckersTest() = default; - void setUp() override { + void SetUp() override { createLinks(); } - void tearDown() override { + void TearDown() override { close(); } @@ -44,50 +44,6 @@ struct StateCheckersTest : public CppUnit::TestFixture, bool shouldCheck() const { return _msgType != UINT32_MAX; } }; - void testSplit(); - void testInconsistentSplit(); - void splitCanBeScheduledWhenReplicasOnRetiredNodes(); - void testSynchronizeAndMove(); - void testDoNotMergeInconsistentlySplitBuckets(); - void doNotMoveReplicasWithinRetiredNodes(); - void testDeleteExtraCopies(); - void testDoNotDeleteActiveExtraCopies(); - void testConsistentCopiesOnRetiredNodesMayBeDeleted(); - void redundantCopyDeletedEvenWhenAllNodesRetired(); - void testJoin(); - void testDoNotJoinBelowClusterStateBitCount(); - void testAllowInconsistentJoinInDifferingSiblingIdealState(); - void testDoNotAllowInconsistentJoinWhenNotInIdealState(); - void testDoNotAllowInconsistentJoinWhenConfigDisabled(); - void testNoJoinWhenInvalidCopyExists(); - void testNoJoinOnDifferentNodes(); - void testNoJoinWhenCopyCountAboveRedundancyLevelsForLeftSibling(); - void testNoJoinWhenCopyCountAboveRedundancyLevelsForRightSibling(); - void testNoJoinWhenCopyCountAboveRedundancyLevelsForBothSiblings(); - void joinCanBeScheduledWhenReplicasOnRetiredNodes(); - void testBucketState(); - void testDoNotActivateNonReadyCopiesWhenIdealNodeInMaintenance(); - void testDoNotChangeActiveStateForInconsistentlySplitBuckets(); - void testNoActiveChangeForNonIdealCopiesWhenOtherwiseIdentical(); - void testBucketStatePerGroup(); - void allowActivationOfRetiredNodes(); - void inhibitBucketActivationIfDisabledInConfig(); - void inhibitBucketDeactivationIfDisabledInConfig(); - void retiredNodesOutOfSyncAreMerged(); - void testGarbageCollection(); - void gc_ops_are_prioritized_with_low_priority_category(); - void gcInhibitedWhenIdealNodeInMaintenance(); - void testNoRemoveWhenIdealNodeInMaintenance(); - void testStepwiseJoinForSmallBucketsWithoutSiblings(); - void testNoStepwiseJoinWhenDisabledThroughConfig(); - void testNoStepwiseJoinWhenSingleSiblingTooLarge(); - void testStepwiseJoinMaySkipMultipleBitsWhenConsistent(); - void testStepwiseJoinDoesNotSkipBeyondLevelWithSibling(); - void contextPopulatesIdealStateContainers(); - void statsUpdatedWhenMergingDueToMove(); - void statsUpdatedWhenMergingDueToMissingCopy(); - void statsUpdatedWhenMergingDueToOutOfSyncCopies(); - void enableClusterState(const lib::ClusterState& systemState) { _distributor->enableClusterStateBundle(lib::ClusterStateBundle(systemState)); } @@ -95,16 +51,16 @@ struct StateCheckersTest : public CppUnit::TestFixture, void insertJoinableBuckets(); void assertCurrentIdealState(const document::BucketId& bucket, - const std::vector<uint16_t> expected) + const std::vector<uint16_t>& expected) { - auto &distributorBucketSpace(getIdealStateManager().getBucketSpaceRepo().get(makeBucketSpace())); + auto& distributorBucketSpace(getIdealStateManager().getBucketSpaceRepo().get(makeBucketSpace())); std::vector<uint16_t> idealNodes( distributorBucketSpace .getDistribution().getIdealStorageNodes( distributorBucketSpace.getClusterState(), bucket, "ui")); - CPPUNIT_ASSERT_EQUAL(expected, idealNodes); + ASSERT_EQ(expected, idealNodes); } void enableInconsistentJoinInConfig(bool enabled); @@ -259,7 +215,7 @@ struct StateCheckersTest : public CppUnit::TestFixture, checker, c, false, *params._blockerMessage, params._includeMessagePriority, params._includeSchedulingPriority); - CPPUNIT_ASSERT_EQUAL(params._expect, result); + ASSERT_EQ(params._expect, result); } std::string testSynchronizeAndMove( @@ -281,59 +237,10 @@ struct StateCheckersTest : public CppUnit::TestFixture, bool includePriority = false); std::string testBucketStatePerGroup(const std::string& bucketInfo, bool includePriority = false); - - CPPUNIT_TEST_SUITE(StateCheckersTest); - CPPUNIT_TEST(testSplit); - CPPUNIT_TEST(testInconsistentSplit); - CPPUNIT_TEST(splitCanBeScheduledWhenReplicasOnRetiredNodes); - CPPUNIT_TEST(testSynchronizeAndMove); - CPPUNIT_TEST(testDoNotMergeInconsistentlySplitBuckets); - CPPUNIT_TEST(doNotMoveReplicasWithinRetiredNodes); - CPPUNIT_TEST(retiredNodesOutOfSyncAreMerged); - CPPUNIT_TEST(testDoNotChangeActiveStateForInconsistentlySplitBuckets); - CPPUNIT_TEST(testDeleteExtraCopies); - CPPUNIT_TEST(testDoNotDeleteActiveExtraCopies); - CPPUNIT_TEST(testConsistentCopiesOnRetiredNodesMayBeDeleted); - CPPUNIT_TEST(redundantCopyDeletedEvenWhenAllNodesRetired); - CPPUNIT_TEST(testJoin); - CPPUNIT_TEST(testDoNotJoinBelowClusterStateBitCount); - CPPUNIT_TEST(testAllowInconsistentJoinInDifferingSiblingIdealState); - CPPUNIT_TEST(testDoNotAllowInconsistentJoinWhenNotInIdealState); - CPPUNIT_TEST(testDoNotAllowInconsistentJoinWhenConfigDisabled); - CPPUNIT_TEST(testNoJoinWhenInvalidCopyExists); - CPPUNIT_TEST(testNoJoinOnDifferentNodes); - CPPUNIT_TEST(testNoJoinWhenCopyCountAboveRedundancyLevelsForLeftSibling); - CPPUNIT_TEST(testNoJoinWhenCopyCountAboveRedundancyLevelsForRightSibling); - CPPUNIT_TEST(testNoJoinWhenCopyCountAboveRedundancyLevelsForBothSiblings); - CPPUNIT_TEST(joinCanBeScheduledWhenReplicasOnRetiredNodes); - CPPUNIT_TEST(testBucketState); - CPPUNIT_TEST(testDoNotActivateNonReadyCopiesWhenIdealNodeInMaintenance); - CPPUNIT_TEST(testNoActiveChangeForNonIdealCopiesWhenOtherwiseIdentical); - CPPUNIT_TEST(testBucketStatePerGroup); - CPPUNIT_TEST(allowActivationOfRetiredNodes); - CPPUNIT_TEST(inhibitBucketActivationIfDisabledInConfig); - CPPUNIT_TEST(inhibitBucketDeactivationIfDisabledInConfig); - CPPUNIT_TEST(testGarbageCollection); - CPPUNIT_TEST(gc_ops_are_prioritized_with_low_priority_category); - CPPUNIT_TEST(gcInhibitedWhenIdealNodeInMaintenance); - CPPUNIT_TEST(testNoRemoveWhenIdealNodeInMaintenance); - CPPUNIT_TEST(testStepwiseJoinForSmallBucketsWithoutSiblings); - CPPUNIT_TEST(testNoStepwiseJoinWhenDisabledThroughConfig); - CPPUNIT_TEST(testNoStepwiseJoinWhenSingleSiblingTooLarge); - CPPUNIT_TEST(testStepwiseJoinMaySkipMultipleBitsWhenConsistent); - CPPUNIT_TEST(testStepwiseJoinDoesNotSkipBeyondLevelWithSibling); - CPPUNIT_TEST(contextPopulatesIdealStateContainers); - CPPUNIT_TEST(statsUpdatedWhenMergingDueToMove); - CPPUNIT_TEST(statsUpdatedWhenMergingDueToMissingCopy); - CPPUNIT_TEST(statsUpdatedWhenMergingDueToOutOfSyncCopies); - CPPUNIT_TEST_SUITE_END(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(StateCheckersTest); - - -StateCheckersTest::CheckerParams::CheckerParams() {} -StateCheckersTest::CheckerParams::~CheckerParams() {} +StateCheckersTest::CheckerParams::CheckerParams() = default; +StateCheckersTest::CheckerParams::~CheckerParams() = default; const StateCheckersTest::PendingMessage @@ -359,95 +266,76 @@ std::string StateCheckersTest::testSplit(uint32_t splitCount, return testStateChecker(checker, c, false, blocker, includePriority); } +TEST_F(StateCheckersTest, split) { + setupDistributor(3, 10, "distributor:1 storage:2"); + EXPECT_EQ("[Splitting bucket because its maximum size (2000 b, 10 docs, 10 meta, 2000 b total) " + "is higher than the configured limit of (1000, 4294967295)]", + testSplit((uint32_t)-1, 1000, 16, "0=100/10/2000")); -void -StateCheckersTest::testSplit() -{ - setupDistributor(3, 10, "distributor:1 storage:2"); + EXPECT_EQ("[Splitting bucket because its maximum size (1000 b, " + "200 docs, 200 meta, 1000 b total) " + "is higher than the configured limit of (10000, 100)] " + "(pri 175)", + testSplit(100, 10000, 16, "0=100/200/1000", PendingMessage(), true)); + + EXPECT_EQ("NO OPERATIONS GENERATED", + testSplit(1000, 1000, 16, "0=100/200/200")); + + EXPECT_EQ("NO OPERATIONS GENERATED", + testSplit(1000, 1000, 16, "0=100/200/200/2000/2000")); + + EXPECT_EQ("[Splitting bucket because the current system size requires " + "a higher minimum split bit]", + testSplit((uint32_t)-1, (uint32_t)-1, 24, "0=100/200/1000")); + + EXPECT_EQ("[Splitting bucket because its maximum size (1000 b, 1000 docs, 1000 meta, 1000 b total) " + "is higher than the configured limit of (10000, 100)]", + testSplit(100, 10000, 16, "0=100/10/10,1=100/1000/1000")); - CPPUNIT_ASSERT_EQUAL( - std::string("[Splitting bucket because its maximum size (2000 b, 10 docs, 10 meta, 2000 b total) " - "is higher than the configured limit of (1000, 4294967295)]"), - testSplit((uint32_t)-1, 1000, 16, "0=100/10/2000")); - - CPPUNIT_ASSERT_EQUAL( - std::string("[Splitting bucket because its maximum size (1000 b, " - "200 docs, 200 meta, 1000 b total) " - "is higher than the configured limit of (10000, 100)] " - "(pri 175)"), - testSplit(100, 10000, 16, "0=100/200/1000", PendingMessage(), true)); - - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testSplit(1000, 1000, 16, "0=100/200/200")); - - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testSplit(1000, 1000, 16, "0=100/200/200/2000/2000")); - - CPPUNIT_ASSERT_EQUAL( - std::string("[Splitting bucket because the current system size requires " - "a higher minimum split bit]"), - testSplit((uint32_t)-1, (uint32_t)-1, 24, "0=100/200/1000")); - - CPPUNIT_ASSERT_EQUAL( - std::string("[Splitting bucket because its maximum size (1000 b, 1000 docs, 1000 meta, 1000 b total) " - "is higher than the configured limit of (10000, 100)]"), - testSplit(100, 10000, 16, "0=100/10/10,1=100/1000/1000")); - - CPPUNIT_ASSERT_EQUAL( - std::string("[Splitting bucket because its maximum size (1000 b, 1000 docs, 1000 meta, 1000 b total) " - "is higher than the configured limit of (10000, 100)]"), - testSplit(100, 10000, 16, "0=1/0/0,1=100/1000/1000")); - - CPPUNIT_ASSERT_EQUAL( - std::string("[Splitting bucket because its maximum size (1000 b, 1000 docs, 1000 meta, 1000 b total) " - "is higher than the configured limit of (10000, 100)]"), - testSplit(100, 10000, 16, "0=0/0/1,1=100/1000/1000")); - - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testSplit(1000, 1000, 16, "0=100/1/200000")); - - CPPUNIT_ASSERT_EQUAL( - std::string("BLOCKED"), - testSplit(100, 10000, 16, "0=0/0/1,1=100/1000/1000", - PendingMessage(api::MessageType::SPLITBUCKET_ID, 0))); - - // Split on too high meta - CPPUNIT_ASSERT_EQUAL( - std::string("[Splitting bucket because its maximum size (1000 b, 100 docs, 2100 meta, 15000000 b total) " - "is higher than the configured limit of (10000000, 1000)]"), - testSplit(1000, 10000000, 16, "0=14/100/1000/2100/15000000")); - // Split on too high file size - CPPUNIT_ASSERT_EQUAL( - std::string("[Splitting bucket because its maximum size (1000 b, 100 docs, 1500 meta, 21000000 b total) " - "is higher than the configured limit of (10000000, 1000)]"), - testSplit(1000, 10000000, 16, "0=14/100/1000/1500/21000000")); + EXPECT_EQ("[Splitting bucket because its maximum size (1000 b, 1000 docs, 1000 meta, 1000 b total) " + "is higher than the configured limit of (10000, 100)]", + testSplit(100, 10000, 16, "0=1/0/0,1=100/1000/1000")); + + EXPECT_EQ("[Splitting bucket because its maximum size (1000 b, 1000 docs, 1000 meta, 1000 b total) " + "is higher than the configured limit of (10000, 100)]", + testSplit(100, 10000, 16, "0=0/0/1,1=100/1000/1000")); + + EXPECT_EQ("NO OPERATIONS GENERATED", + testSplit(1000, 1000, 16, "0=100/1/200000")); + + EXPECT_EQ("BLOCKED", + testSplit(100, 10000, 16, "0=0/0/1,1=100/1000/1000", + PendingMessage(api::MessageType::SPLITBUCKET_ID, 0))); + + // Split on too high meta + EXPECT_EQ("[Splitting bucket because its maximum size (1000 b, 100 docs, 2100 meta, 15000000 b total) " + "is higher than the configured limit of (10000000, 1000)]", + testSplit(1000, 10000000, 16, "0=14/100/1000/2100/15000000")); + // Split on too high file size + EXPECT_EQ("[Splitting bucket because its maximum size (1000 b, 100 docs, 1500 meta, 21000000 b total) " + "is higher than the configured limit of (10000000, 1000)]", + testSplit(1000, 10000000, 16, "0=14/100/1000/1500/21000000")); // Don't block higher priority splits than what's already pending. - CPPUNIT_ASSERT_EQUAL( - std::string("[Splitting bucket because its maximum size (1000 b, 1000 docs, 1000 meta, 1000 b total) " - "is higher than the configured limit of (10000, 100)]"), - testSplit(100, 10000, 16, "0=100/10/10,1=100/1000/1000", - PendingMessage(api::MessageType::SPLITBUCKET_ID, 255))); + EXPECT_EQ("[Splitting bucket because its maximum size (1000 b, 1000 docs, 1000 meta, 1000 b total) " + "is higher than the configured limit of (10000, 100)]", + testSplit(100, 10000, 16, "0=100/10/10,1=100/1000/1000", + PendingMessage(api::MessageType::SPLITBUCKET_ID, 255))); // But must block equal priority splits that are already pending, or // we'll end up spamming the nodes with splits! // NOTE: assuming split priority of 175. - CPPUNIT_ASSERT_EQUAL( - std::string("BLOCKED"), - testSplit(100, 10000, 16, "0=0/0/1,1=100/1000/1000", - PendingMessage(api::MessageType::SPLITBUCKET_ID, 175))); + EXPECT_EQ("BLOCKED", + testSplit(100, 10000, 16, "0=0/0/1,1=100/1000/1000", + PendingMessage(api::MessageType::SPLITBUCKET_ID, 175))); // Don't split if we're already joining, since there's a window of time // where the bucket will appear to be inconsistently split when the join // is not finished on all the nodes. - CPPUNIT_ASSERT_EQUAL( - std::string("BLOCKED"), - testSplit(100, 10000, 16, "0=0/0/1,1=100/1000/1000", - PendingMessage(api::MessageType::JOINBUCKETS_ID, 175))); + EXPECT_EQ("BLOCKED", + testSplit(100, 10000, 16, "0=0/0/1,1=100/1000/1000", + PendingMessage(api::MessageType::JOINBUCKETS_ID, 175))); } std::string @@ -461,53 +349,43 @@ StateCheckersTest::testInconsistentSplit(const document::BucketId& bid, PendingMessage(), includePriority); } -void -StateCheckersTest::testInconsistentSplit() -{ +TEST_F(StateCheckersTest, inconsistent_split) { setupDistributor(3, 10, "distributor:1 storage:2"); insertBucketInfo(document::BucketId(16, 1), 1, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testInconsistentSplit(document::BucketId(16, 1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testInconsistentSplit(document::BucketId(16, 1))); insertBucketInfo(document::BucketId(17, 1), 1, 0x1, 1, 1); insertBucketInfo(document::BucketId(16, 1), 1, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL( - std::string("BucketId(0x4000000000000001): [Bucket is inconsistently " - "split (list includes 0x4000000000000001, 0x4400000000000001) " - "Splitting it to improve the problem (max used bits 17)]"), - testInconsistentSplit(document::BucketId(16, 1))); + EXPECT_EQ("BucketId(0x4000000000000001): [Bucket is inconsistently " + "split (list includes 0x4000000000000001, 0x4400000000000001) " + "Splitting it to improve the problem (max used bits 17)]", + testInconsistentSplit(document::BucketId(16, 1))); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testInconsistentSplit(document::BucketId(17, 1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testInconsistentSplit(document::BucketId(17, 1))); insertBucketInfo(document::BucketId(17, 1), 0, 0x0, 0, 0); insertBucketInfo(document::BucketId(16, 1), 1, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL( - std::string("BucketId(0x4000000000000001): [Bucket is inconsistently " - "split (list includes 0x4000000000000001, 0x4400000000000001) " - "Splitting it to improve the problem (max used bits " - "17)] (pri 110)"), - testInconsistentSplit(document::BucketId(16, 1), true)); - - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testInconsistentSplit(document::BucketId(17, 1))); + EXPECT_EQ("BucketId(0x4000000000000001): [Bucket is inconsistently " + "split (list includes 0x4000000000000001, 0x4400000000000001) " + "Splitting it to improve the problem (max used bits " + "17)] (pri 110)", + testInconsistentSplit(document::BucketId(16, 1), true)); + + EXPECT_EQ("NO OPERATIONS GENERATED", + testInconsistentSplit(document::BucketId(17, 1))); } -void -StateCheckersTest::splitCanBeScheduledWhenReplicasOnRetiredNodes() -{ +TEST_F(StateCheckersTest, split_can_be_scheduled_when_replicas_on_retired_nodes) { setupDistributor(Redundancy(2), NodeCount(2), "distributor:1 storage:2, .0.s:r .1.s:r"); - CPPUNIT_ASSERT_EQUAL( - "[Splitting bucket because its maximum size (2000 b, 10 docs, " - "10 meta, 2000 b total) is higher than the configured limit of " - "(1000, 4294967295)]"s, - testSplit(UINT32_MAX, 1000, 16, "0=100/10/2000")); + EXPECT_EQ("[Splitting bucket because its maximum size (2000 b, 10 docs, " + "10 meta, 2000 b total) is higher than the configured limit of " + "(1000, 4294967295)]", + testSplit(UINT32_MAX, 1000, 16, "0=100/10/2000")); } std::string @@ -535,55 +413,50 @@ StateCheckersTest::insertJoinableBuckets() insertBucketInfo(document::BucketId(33, 0x100000001), 1, 0x1, 1, 1); } -void -StateCheckersTest::testJoin() -{ +TEST_F(StateCheckersTest, join) { setupDistributor(3, 10, "distributor:1 storage:2"); insertJoinableBuckets(); - CPPUNIT_ASSERT_EQUAL(std::string( - "BucketId(0x8000000000000001): " - "[Joining buckets BucketId(0x8400000000000001) and " - "BucketId(0x8400000100000001) because their size " - "(2 bytes, 2 docs) is less than the configured limit " - "of (100, 10)"), - testJoin(10, 100, 16, document::BucketId(33, 1))); + EXPECT_EQ("BucketId(0x8000000000000001): " + "[Joining buckets BucketId(0x8400000000000001) and " + "BucketId(0x8400000100000001) because their size " + "(2 bytes, 2 docs) is less than the configured limit " + "of (100, 10)", + testJoin(10, 100, 16, document::BucketId(33, 1))); insertJoinableBuckets(); // Join size is 0, so only look at document count - CPPUNIT_ASSERT_EQUAL(std::string( - "BucketId(0x8000000000000001): " - "[Joining buckets BucketId(0x8400000000000001) and " - "BucketId(0x8400000100000001) because their size " - "(2 bytes, 2 docs) is less than the configured limit " - "of (0, 3) (pri 155)"), - testJoin(3, 0, 16, document::BucketId(33, 1), PendingMessage(), true)); + EXPECT_EQ("BucketId(0x8000000000000001): " + "[Joining buckets BucketId(0x8400000000000001) and " + "BucketId(0x8400000100000001) because their size " + "(2 bytes, 2 docs) is less than the configured limit " + "of (0, 3) (pri 155)", + testJoin(3, 0, 16, document::BucketId(33, 1), PendingMessage(), true)); insertJoinableBuckets(); // Should not generate joins for both pairs, just the primary - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 16, document::BucketId(33, 0x100000001))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 16, document::BucketId(33, 0x100000001))); insertJoinableBuckets(); // Should not generate join if min split bits is higher - CPPUNIT_ASSERT_EQUAL(std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 33, document::BucketId(33, 1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 33, document::BucketId(33, 1))); insertJoinableBuckets(); // Meta data too big, no join insertBucketInfo(document::BucketId(33, 1), 1, api::BucketInfo(0x1, 1, 1, 1000, 1000)); - CPPUNIT_ASSERT_EQUAL(std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 16, document::BucketId(33, 1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 16, document::BucketId(33, 1))); insertJoinableBuckets(); // Bucket recently created insertBucketInfo(document::BucketId(33, 1), 1, api::BucketInfo(0x1, 0, 0, 0, 0)); - CPPUNIT_ASSERT_EQUAL(std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 16, document::BucketId(33, 1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 16, document::BucketId(33, 1))); } @@ -594,19 +467,16 @@ StateCheckersTest::testJoin() * the safest is to never violate this and to effectively make distribution * bit increases a one-way street. */ -void -StateCheckersTest::testDoNotJoinBelowClusterStateBitCount() -{ +TEST_F(StateCheckersTest, do_not_join_below_cluster_state_bit_count) { setupDistributor(2, 2, "bits:16 distributor:1 storage:2"); // Insert sibling buckets at 16 bits that are small enough to be joined // unless there is special logic for dealing with distribution bits. insertBucketInfo(document::BucketId(16, 1), 1, 0x1, 1, 1); insertBucketInfo(document::BucketId(16, (1 << 15) | 1), 1, 0x1, 1, 1); using ConfiguredMinSplitBits = uint32_t; - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testJoin(100, 100, ConfiguredMinSplitBits(8), - document::BucketId(16, 1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(100, 100, ConfiguredMinSplitBits(8), + document::BucketId(16, 1))); } void @@ -617,9 +487,7 @@ StateCheckersTest::enableInconsistentJoinInConfig(bool enabled) getConfig().configure(config); } -void -StateCheckersTest::testAllowInconsistentJoinInDifferingSiblingIdealState() -{ +TEST_F(StateCheckersTest, allow_inconsistent_join_in_differing_sibling_ideal_state) { // Normally, bucket siblings have an ideal state on the same node in order // to enable joining these back together. However, the ideal disks assigned // may differ and it's sufficient for a sibling bucket's ideal disk to be @@ -645,18 +513,15 @@ StateCheckersTest::testAllowInconsistentJoinInDifferingSiblingIdealState() enableInconsistentJoinInConfig(true); - CPPUNIT_ASSERT_EQUAL(std::string( - "BucketId(0x8000000000000001): " - "[Joining buckets BucketId(0x8400000000000001) and " - "BucketId(0x8400000100000001) because their size " - "(6 bytes, 4 docs) is less than the configured limit " - "of (100, 10)"), - testJoin(10, 100, 16, sibling1)); + EXPECT_EQ("BucketId(0x8000000000000001): " + "[Joining buckets BucketId(0x8400000000000001) and " + "BucketId(0x8400000100000001) because their size " + "(6 bytes, 4 docs) is less than the configured limit " + "of (100, 10)", + testJoin(10, 100, 16, sibling1)); } -void -StateCheckersTest::testDoNotAllowInconsistentJoinWhenNotInIdealState() -{ +TEST_F(StateCheckersTest, do_not_allow_inconsistent_join_when_not_in_ideal_state) { setupDistributor(2, 4, "distributor:1 storage:4 .0.d:20 .0.d.14.s:d .2.d:20 .3.d:20"); document::BucketId sibling1(33, 0x000000001); document::BucketId sibling2(33, 0x100000001); @@ -671,13 +536,11 @@ StateCheckersTest::testDoNotAllowInconsistentJoinWhenNotInIdealState() enableInconsistentJoinInConfig(true); - CPPUNIT_ASSERT_EQUAL(std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 16, sibling1)); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 16, sibling1)); } -void -StateCheckersTest::testDoNotAllowInconsistentJoinWhenConfigDisabled() -{ +TEST_F(StateCheckersTest, do_not_allow_inconsistent_join_when_config_disabled) { setupDistributor(2, 3, "distributor:1 storage:3 .0.d:20 .0.d.14.s:d .2.d:20"); document::BucketId sibling1(33, 0x000000001); // ideal disk 14 on node 0 document::BucketId sibling2(33, 0x100000001); // ideal disk 1 on node 0 @@ -694,74 +557,60 @@ StateCheckersTest::testDoNotAllowInconsistentJoinWhenConfigDisabled() enableInconsistentJoinInConfig(false); - CPPUNIT_ASSERT_EQUAL(std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 16, sibling1)); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 16, sibling1)); } -void -StateCheckersTest::testNoJoinWhenInvalidCopyExists() -{ +TEST_F(StateCheckersTest, no_join_when_invalid_copy_exists) { setupDistributor(3, 10, "distributor:1 storage:3"); insertBucketInfo(document::BucketId(33, 0x100000001), 1, 0x1, 1, 1); // No join when there exists an invalid copy insertBucketInfo(document::BucketId(33, 1), 1, api::BucketInfo()); - CPPUNIT_ASSERT_EQUAL(std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 16, document::BucketId(33, 1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 16, document::BucketId(33, 1))); } -void -StateCheckersTest::testNoJoinOnDifferentNodes() -{ +TEST_F(StateCheckersTest, no_join_on_different_nodes) { setupDistributor(3, 10, "distributor:1 storage:2"); insertBucketInfo(document::BucketId(33, 0x000000001), 0, 0x1, 1, 1); insertBucketInfo(document::BucketId(33, 0x100000001), 1, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 16, document::BucketId(33, 0x1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 16, document::BucketId(33, 0x1))); } -void -StateCheckersTest::testNoJoinWhenCopyCountAboveRedundancyLevelsForLeftSibling() -{ +TEST_F(StateCheckersTest, no_join_when_copy_count_above_redundancy_levels_for_left_sibling) { setupDistributor(3, 10, "distributor:1 storage:2"); setRedundancy(1); insertBucketInfo(document::BucketId(33, 0x000000001), 0, 0x1, 1, 1); insertBucketInfo(document::BucketId(33, 0x000000001), 1, 0x1, 1, 1); insertBucketInfo(document::BucketId(33, 0x100000001), 0, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 16, document::BucketId(33, 0x1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 16, document::BucketId(33, 0x1))); } -void -StateCheckersTest::testNoJoinWhenCopyCountAboveRedundancyLevelsForRightSibling() -{ +TEST_F(StateCheckersTest, no_join_when_copy_count_above_redundancy_levels_for_right_sibling) { setupDistributor(3, 10, "distributor:1 storage:2"); setRedundancy(1); insertBucketInfo(document::BucketId(33, 0x000000001), 1, 0x1, 1, 1); insertBucketInfo(document::BucketId(33, 0x100000001), 0, 0x1, 1, 1); insertBucketInfo(document::BucketId(33, 0x100000001), 1, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 16, document::BucketId(33, 0x1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 16, document::BucketId(33, 0x1))); } -void -StateCheckersTest::testNoJoinWhenCopyCountAboveRedundancyLevelsForBothSiblings() -{ +TEST_F(StateCheckersTest, no_join_when_copy_count_above_redundancy_levels_for_both_siblings) { setupDistributor(3, 10, "distributor:1 storage:2"); setRedundancy(1); insertBucketInfo(document::BucketId(33, 0x000000001), 0, 0x1, 1, 1); insertBucketInfo(document::BucketId(33, 0x000000001), 1, 0x1, 1, 1); insertBucketInfo(document::BucketId(33, 0x100000001), 0, 0x1, 1, 1); insertBucketInfo(document::BucketId(33, 0x100000001), 1, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 16, document::BucketId(33, 0x1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 16, document::BucketId(33, 0x1))); } std::string @@ -784,9 +633,7 @@ StateCheckersTest::testSynchronizeAndMove(const std::string& bucketInfo, return testStateChecker(checker, c, false, blocker, includePriority); } -void -StateCheckersTest::testSynchronizeAndMove() -{ +TEST_F(StateCheckersTest, synchronize_and_move) { // Plus if it was more obvious which nodes were in ideal state for various // cluster states. (One possibility to override ideal state function for // test) @@ -903,30 +750,24 @@ StateCheckersTest::testSynchronizeAndMove() .clusterState("distributor:1 storage:4")); } -void -StateCheckersTest::testDoNotMergeInconsistentlySplitBuckets() -{ +TEST_F(StateCheckersTest, do_not_merge_inconsistently_split_buckets) { // No merge generated if buckets are inconsistently split. // This matches the case where a bucket has been split into 2 on one // node and is not yet split on another; we should never try to merge // either two of the split leaf buckets back onto the first node! // Running state checker on a leaf: addNodesToBucketDB(document::BucketId(16, 0), "0=2"); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testSynchronizeAndMove("1=1", // 17 bits - "distributor:1 storage:4")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testSynchronizeAndMove("1=1", // 17 bits + "distributor:1 storage:4")); // Running state checker on an inner node bucket: addNodesToBucketDB(document::BucketId(18, 0), "0=2"); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testSynchronizeAndMove("0=1", // 17 bits - "distributor:1 storage:4")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testSynchronizeAndMove("0=1", // 17 bits + "distributor:1 storage:4")); } -void -StateCheckersTest::doNotMoveReplicasWithinRetiredNodes() -{ +TEST_F(StateCheckersTest, do_not_move_replicas_within_retired_nodes) { // Nodes 1 and 3 would be in ideal state if the nodes were not retired. // Here, all nodes are retired and we should thus not do any sort of // moving. @@ -938,9 +779,7 @@ StateCheckersTest::doNotMoveReplicasWithinRetiredNodes() ".0.s:r .1.s:r .2.s:r .3.s:r")); } -void -StateCheckersTest::retiredNodesOutOfSyncAreMerged() -{ +TEST_F(StateCheckersTest, retired_nodes_out_of_sync_are_merged) { // Normally, we'd do a merge that'd move the bucket to new nodes, leaving // the out of sync retired nodes as source-only replicas. But here we // don't have that choice and thus try to do the most useful thing we can @@ -980,139 +819,106 @@ StateCheckersTest::testDeleteExtraCopies( } -void -StateCheckersTest::testDeleteExtraCopies() -{ +TEST_F(StateCheckersTest, delete_extra_copies) { setupDistributor(2, 100, "distributor:1 storage:4"); { - auto &distributorBucketSpace(getIdealStateManager().getBucketSpaceRepo().get(makeBucketSpace())); + auto& distributorBucketSpace(getIdealStateManager().getBucketSpaceRepo().get(makeBucketSpace())); std::vector<uint16_t> idealNodes( distributorBucketSpace .getDistribution().getIdealStorageNodes( distributorBucketSpace.getClusterState(), document::BucketId(17, 0), "ui")); - std::vector<uint16_t> wanted; - wanted.push_back(1); - wanted.push_back(3); - CPPUNIT_ASSERT_EQUAL(wanted, idealNodes); + std::vector<uint16_t> wanted = {1, 3}; + ASSERT_EQ(wanted, idealNodes); } - CPPUNIT_ASSERT_EQUAL_MSG( - "Remove empty buckets", - std::string("[Removing all copies since bucket is empty:node(idx=0,crc=0x0," - "docs=0/0,bytes=0/0,trusted=false,active=false,ready=false)]" - " (pri 100)"), - testDeleteExtraCopies("0=0", 2, PendingMessage(), "", true)); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Remove extra trusted copy", - std::string("[Removing redundant in-sync copy from node 2]"), - testDeleteExtraCopies("3=3/3/3/t,1=3/3/3/t,2=3/3/3/t")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Redundant copies in sync can be removed without trusted being a " - "factor of consideration. Ideal state copy not removed.", - std::string("[Removing redundant in-sync copy from node 2]"), - testDeleteExtraCopies("3=3/3/3,1=3/3/3/t,2=3/3/3/t")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Need redundancy number of copies", - std::string("NO OPERATIONS GENERATED"), - testDeleteExtraCopies("0=3,1=3")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Do not remove extra copies without enough trusted copies", - std::string("NO OPERATIONS GENERATED"), - testDeleteExtraCopies("0=0/0/1,1=3,2=3")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Do not remove buckets that have meta entries", - std::string("NO OPERATIONS GENERATED"), - testDeleteExtraCopies("0=0/0/1,1=0/0/1")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Do not remove any recently created copies", - std::string("NO OPERATIONS GENERATED"), - testDeleteExtraCopies("0=1/0/0/t,1=1/0/0/t,2=1/0/0/t")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Do not remove untrusted copy that is out of sync", - std::string("NO OPERATIONS GENERATED"), - testDeleteExtraCopies("0=2/3/4,1=1/2/3/t,2=1/2/3/t")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Do not remove out of sync copies, even if we have more than #" - "redundancy trusted copies", - std::string("NO OPERATIONS GENERATED"), - testDeleteExtraCopies("0=2/3/4,1=1/2/3/t,2=1/2/3/t,3=1/2/3/t")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Don't remove unless we have enough trusted " - "copies to satisfy redundancy", - std::string("NO OPERATIONS GENERATED"), - testDeleteExtraCopies("0=2/3/4,1=1/2/3,2=2/3/4,3=1/2/3")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Only remove empty copies unless all other copies are in sync", - std::string("[Removing empty copy from node 4]"), - testDeleteExtraCopies("0=2/3/4,1=1/2/3,2=2/3/4,3=1/2/3,4=0/0/0")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Remove redundant empty copy", - std::string("[Removing empty copy from node 0]"), - testDeleteExtraCopies("1=2/3,3=1/2/3,0=0/0/0")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Remove empty bucket with multiple copies", - std::string( - "[Removing all copies since bucket is empty:" - "node(idx=0,crc=0x0,docs=0/0,bytes=0/0,trusted=false,active=false,ready=false), " - "node(idx=1,crc=0x0,docs=0/0,bytes=0/0,trusted=false,active=false,ready=false), " - "node(idx=2,crc=0x0,docs=0/0,bytes=0/0,trusted=false,active=false,ready=false)]"), - testDeleteExtraCopies("0=0/0/0,1=0/0/0,2=0/0/0")); - - CPPUNIT_ASSERT_EQUAL_MSG( - "Pending persistence operation blocks delete", - std::string("BLOCKED"), - testDeleteExtraCopies("0=0/0/0,1=1/2/3/t,2=1/2/3/t", - 2, - PendingMessage(api::MessageType::PUT_ID, 255))); + EXPECT_EQ("[Removing all copies since bucket is empty:node(idx=0,crc=0x0," + "docs=0/0,bytes=0/0,trusted=false,active=false,ready=false)]" + " (pri 100)", + testDeleteExtraCopies("0=0", 2, PendingMessage(), "", true)) << "Remove empty buckets"; + + EXPECT_EQ("[Removing redundant in-sync copy from node 2]", + testDeleteExtraCopies("3=3/3/3/t,1=3/3/3/t,2=3/3/3/t")) << "Remove extra trusted copy"; + + EXPECT_EQ("[Removing redundant in-sync copy from node 2]", + testDeleteExtraCopies("3=3/3/3,1=3/3/3/t,2=3/3/3/t")) + << "Redundant copies in sync can be removed without trusted being a " + "factor of consideration. Ideal state copy not removed."; + + EXPECT_EQ("NO OPERATIONS GENERATED", + testDeleteExtraCopies("0=3,1=3")) << "Need redundancy number of copies"; + + EXPECT_EQ("NO OPERATIONS GENERATED", + testDeleteExtraCopies("0=0/0/1,1=3,2=3")) + << "Do not remove extra copies without enough trusted copies"; + + EXPECT_EQ("NO OPERATIONS GENERATED", + testDeleteExtraCopies("0=0/0/1,1=0/0/1")) + << "Do not remove buckets that have meta entries"; + + EXPECT_EQ("NO OPERATIONS GENERATED", + testDeleteExtraCopies("0=1/0/0/t,1=1/0/0/t,2=1/0/0/t")) + << "Do not remove any recently created copies"; + + EXPECT_EQ("NO OPERATIONS GENERATED", + testDeleteExtraCopies("0=2/3/4,1=1/2/3/t,2=1/2/3/t")) + << "Do not remove untrusted copy that is out of sync"; + + EXPECT_EQ("NO OPERATIONS GENERATED", + testDeleteExtraCopies("0=2/3/4,1=1/2/3/t,2=1/2/3/t,3=1/2/3/t")) + << "Do not remove out of sync copies, even if we have more than #" + "redundancy trusted copies"; + + EXPECT_EQ("NO OPERATIONS GENERATED", + testDeleteExtraCopies("0=2/3/4,1=1/2/3,2=2/3/4,3=1/2/3")) + << "Don't remove unless we have enough trusted " + "copies to satisfy redundancy"; + + EXPECT_EQ("[Removing empty copy from node 4]", + testDeleteExtraCopies("0=2/3/4,1=1/2/3,2=2/3/4,3=1/2/3,4=0/0/0")) + << "Only remove empty copies unless all other copies are in sync"; + + EXPECT_EQ("[Removing empty copy from node 0]", + testDeleteExtraCopies("1=2/3,3=1/2/3,0=0/0/0")) << "Remove redundant empty copy"; + + EXPECT_EQ("[Removing all copies since bucket is empty:" + "node(idx=0,crc=0x0,docs=0/0,bytes=0/0,trusted=false,active=false,ready=false), " + "node(idx=1,crc=0x0,docs=0/0,bytes=0/0,trusted=false,active=false,ready=false), " + "node(idx=2,crc=0x0,docs=0/0,bytes=0/0,trusted=false,active=false,ready=false)]", + testDeleteExtraCopies("0=0/0/0,1=0/0/0,2=0/0/0")) << "Remove empty bucket with multiple copies"; + + EXPECT_EQ("BLOCKED", + testDeleteExtraCopies("0=0/0/0,1=1/2/3/t,2=1/2/3/t", + 2, + PendingMessage(api::MessageType::PUT_ID, 255))) + << "Pending persistence operation blocks delete"; } -void -StateCheckersTest::testDoNotDeleteActiveExtraCopies() -{ +TEST_F(StateCheckersTest, do_not_delete_active_extra_copies) { setupDistributor(2, 100, "distributor:1 storage:4"); - CPPUNIT_ASSERT_EQUAL_MSG( - "Do not delete redundant copy if it is marked active", - std::string("NO OPERATIONS GENERATED"), - testDeleteExtraCopies("3=3/3/3/t,1=3/3/3/t,2=3/3/3/t/a")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testDeleteExtraCopies("3=3/3/3/t,1=3/3/3/t,2=3/3/3/t/a")) + << "Do not delete redundant copy if it is marked active"; } -void -StateCheckersTest::testConsistentCopiesOnRetiredNodesMayBeDeleted() -{ +TEST_F(StateCheckersTest, consistent_copies_on_retired_nodes_may_be_deleted) { setupDistributor(2, 100, "distributor:1 storage:4 .1.s:r"); - CPPUNIT_ASSERT_EQUAL_MSG( - "Remove in-sync copy on node that is retired", - std::string("[Removing redundant in-sync copy from node 1]"), - testDeleteExtraCopies("3=3/3/3/t,1=3/3/3/t,2=3/3/3/t")); + EXPECT_EQ("[Removing redundant in-sync copy from node 1]", + testDeleteExtraCopies("3=3/3/3/t,1=3/3/3/t,2=3/3/3/t")) + << "Remove in-sync copy on node that is retired"; } -void -StateCheckersTest::redundantCopyDeletedEvenWhenAllNodesRetired() -{ +TEST_F(StateCheckersTest, redundant_copy_deleted_even_when_all_nodes_retired) { setupDistributor(2, 100, "distributor:1 storage:4 " ".0.s:r .1.s:r .2.s:r .3.s:r"); - CPPUNIT_ASSERT_EQUAL_MSG( - "Remove in-sync copy on node that is retired", - "[Removing redundant in-sync copy from node 2]"s, - testDeleteExtraCopies("3=3/3/3/t,1=3/3/3/t,2=3/3/3/t")); + EXPECT_EQ("[Removing redundant in-sync copy from node 2]", + testDeleteExtraCopies("3=3/3/3/t,1=3/3/3/t,2=3/3/3/t")) + << "Remove in-sync copy on node that is retired"; } std::string StateCheckersTest::testBucketState( @@ -1130,9 +936,7 @@ std::string StateCheckersTest::testBucketState( includePriority); } -void -StateCheckersTest::testBucketState() -{ +TEST_F(StateCheckersTest, bucket_state) { setupDistributor(2, 100, "distributor:1 storage:4"); { @@ -1144,105 +948,87 @@ StateCheckersTest::testBucketState() getConfig().setMaintenancePriorities(mp); } - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("")); // Node 1 is in ideal state - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 1 as active:" - " copy is ideal state priority 0] (pri 90)"), - testBucketState("1=2/3/4", 2, true)); + EXPECT_EQ("[Setting node 1 as active:" + " copy is ideal state priority 0] (pri 90)", + testBucketState("1=2/3/4", 2, true)); // Node 3 is in ideal state - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 3 as active:" - " copy is ideal state priority 1]"), - testBucketState("3=2/3/4")); + EXPECT_EQ("[Setting node 3 as active:" + " copy is ideal state priority 1]", + testBucketState("3=2/3/4")); // No trusted nodes, but node 1 is first in ideal state. // Also check bad case where more than 1 node is set as active just // to ensure we can get out of that situation if it should ever happen. // Nothing done with node 3 since is't not active and shouldn't be. - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 1 as active:" - " copy is ideal state priority 0]" - "[Setting node 0 as inactive]" - "[Setting node 2 as inactive] (pri 120)"), - testBucketState("0=3/4/5/u/a,1=3,2=4/5/6/u/a,3=3", 2, true)); + EXPECT_EQ("[Setting node 1 as active:" + " copy is ideal state priority 0]" + "[Setting node 0 as inactive]" + "[Setting node 2 as inactive] (pri 120)", + testBucketState("0=3/4/5/u/a,1=3,2=4/5/6/u/a,3=3", 2, true)); // Test setting active when only node available is not contained // within the resolved ideal state. - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 0 as active: first available copy]"), - testBucketState("0=2/3/4")); + EXPECT_EQ("[Setting node 0 as active: first available copy]", + testBucketState("0=2/3/4")); // A trusted ideal state copy should be set active rather than a non-trusted // ideal state copy - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 3 as active:" - " copy is trusted and ideal state priority 1]" - "[Setting node 1 as inactive]"), - testBucketState("1=2/3/4/u/a,3=5/6/7/t")); + EXPECT_EQ("[Setting node 3 as active:" + " copy is trusted and ideal state priority 1]" + "[Setting node 1 as inactive]", + testBucketState("1=2/3/4/u/a,3=5/6/7/t")); // None of the ideal state copies are trusted but a non-ideal copy is. // The trusted copy should be active. - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 2 as active: copy is trusted]"), - testBucketState("1=2/3/4,3=5/6/7/,2=8/9/10/t")); + EXPECT_EQ("[Setting node 2 as active: copy is trusted]", + testBucketState("1=2/3/4,3=5/6/7/,2=8/9/10/t")); // Make sure bucket db ordering does not matter - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 2 as active: copy is trusted]"), - testBucketState("2=8/9/10/t,1=2/3/4,3=5/6/7")); + EXPECT_EQ("[Setting node 2 as active: copy is trusted]", + testBucketState("2=8/9/10/t,1=2/3/4,3=5/6/7")); // If copy is already active, we shouldn't generate operations - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("1=2/3/4/t/a")); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("1=2/3/4,3=5/6/7/t/a")); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("2=8/9/10/t/a,1=2/3/4,3=5/6/7")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("1=2/3/4/t/a")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("1=2/3/4,3=5/6/7/t/a")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("2=8/9/10/t/a,1=2/3/4,3=5/6/7")); // If multiple buckets are active, deactive all but one - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 2 as inactive]" - "[Setting node 3 as inactive]"), - testBucketState("1=1/2/3/t/a,2=1/2/3/t/a,3=1/2/3/t/a")); + EXPECT_EQ("[Setting node 2 as inactive]" + "[Setting node 3 as inactive]", + testBucketState("1=1/2/3/t/a,2=1/2/3/t/a,3=1/2/3/t/a")); // Invalid buckets should not be included - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("1=0/0/1,3=0/0/1")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("1=0/0/1,3=0/0/1")); // Ready preferred over trusted & ideal state - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("2=8/9/10/t/i/u,1=2/3/4/u/a/r,3=5/6/7")); - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 2 as active: copy is ready]" - "[Setting node 1 as inactive]"), - testBucketState("2=8/9/10/u/i/r,1=2/3/4/u/a/u,3=5/6/7/u/i/u")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("2=8/9/10/t/i/u,1=2/3/4/u/a/r,3=5/6/7")); + EXPECT_EQ("[Setting node 2 as active: copy is ready]" + "[Setting node 1 as inactive]", + testBucketState("2=8/9/10/u/i/r,1=2/3/4/u/a/u,3=5/6/7/u/i/u")); // Prefer in ideal state if multiple copies ready - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 3 as active: copy is ready]" - "[Setting node 1 as inactive]"), - testBucketState("2=8/9/10/u/i/r,1=2/3/4/u/a/u,3=5/6/7/u/i/r")); + EXPECT_EQ("[Setting node 3 as active: copy is ready]" + "[Setting node 1 as inactive]", + testBucketState("2=8/9/10/u/i/r,1=2/3/4/u/a/u,3=5/6/7/u/i/r")); // Prefer ideal state if all ready but no trusted - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 1 as active: copy is ready]"), - testBucketState("2=8/9/10/u/i/r,1=2/3/4/u/i/r,3=5/6/7/u/i/r")); + EXPECT_EQ("[Setting node 1 as active: copy is ready]", + testBucketState("2=8/9/10/u/i/r,1=2/3/4/u/i/r,3=5/6/7/u/i/r")); // Prefer trusted over ideal state - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 2 as active: copy is ready and trusted]" - "[Setting node 1 as inactive]"), - testBucketState("2=8/9/10/t/i/r,1=2/3/4/u/a/r,3=5/6/7")); + EXPECT_EQ("[Setting node 2 as active: copy is ready and trusted]" + "[Setting node 1 as inactive]", + testBucketState("2=8/9/10/t/i/r,1=2/3/4/u/a/r,3=5/6/7")); } /** @@ -1251,38 +1037,30 @@ StateCheckersTest::testBucketState() * into maintenance violates that assumption. See bug 6833209 for context and * details. */ -void -StateCheckersTest::testDoNotActivateNonReadyCopiesWhenIdealNodeInMaintenance() -{ +TEST_F(StateCheckersTest, do_not_activate_non_ready_copies_when_ideal_node_in_maintenance) { setupDistributor(2, 100, "distributor:1 storage:4 .1.s:m"); // Ideal node 1 is in maintenance and no ready copy available. - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("2=8/9/10/t/i/u,3=5/6/7")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("2=8/9/10/t/i/u,3=5/6/7")); // But we should activate another copy iff there's another ready copy. - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 2 as active: copy is ready]"), - testBucketState("2=8/9/10/u/i/r,3=5/6/7/u/i/u")); + EXPECT_EQ("[Setting node 2 as active: copy is ready]", + testBucketState("2=8/9/10/u/i/r,3=5/6/7/u/i/u")); } /** * We really do not want to activate buckets when they are inconsistent. * See bug 6395693 for a set of reasons why. */ -void -StateCheckersTest::testDoNotChangeActiveStateForInconsistentlySplitBuckets() -{ +TEST_F(StateCheckersTest, do_not_change_active_state_for_inconsistently_split_buckets) { setupDistributor(2, 100, "distributor:1 storage:4"); // Running state checker on a leaf: addNodesToBucketDB(document::BucketId(16, 0), "0=2"); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("1=1")); // 17 bits + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("1=1")); // 17 bits // Running state checker on an inner node bucket: addNodesToBucketDB(document::BucketId(18, 0), "0=2"); - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testSynchronizeAndMove("0=1")); // 17 bits + EXPECT_EQ("NO OPERATIONS GENERATED", + testSynchronizeAndMove("0=1")); // 17 bits } /** @@ -1299,21 +1077,17 @@ StateCheckersTest::testDoNotChangeActiveStateForInconsistentlySplitBuckets() * * See bug 7278932. */ -void -StateCheckersTest::testNoActiveChangeForNonIdealCopiesWhenOtherwiseIdentical() -{ +TEST_F(StateCheckersTest, no_active_change_for_non_ideal_copies_when_otherwise_identical) { setupDistributor(2, 100, "distributor:1 storage:50"); // 1 is more ideal than 3 in this state, but since they're both not part // of the #redundancy ideal set, activation should not change hands. - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("1=2/3/4/t/i/r,3=2/3/4/t/a/r")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("1=2/3/4/t/i/r,3=2/3/4/t/a/r")); // Same applies if the copies aren't ready, since if a copy has been marked // as active it will already have started background indexing. No need in // undoing that if we don't have any better candidates going anyway. - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("1=2/3/4/t,3=2/3/4/t/a")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("1=2/3/4/t,3=2/3/4/t/a")); } std::string StateCheckersTest::testBucketStatePerGroup( @@ -1329,9 +1103,7 @@ std::string StateCheckersTest::testBucketStatePerGroup( includePriority); } -void -StateCheckersTest::testBucketStatePerGroup() -{ +TEST_F(StateCheckersTest, bucket_state_per_group) { setupDistributor(6, 20, "distributor:1 storage:12 .2.s:d .4.s:d .7.s:d"); vespa::config::content::StorDistributionConfigBuilder config; config.activePerLeafGroup = true; @@ -1358,7 +1130,7 @@ StateCheckersTest::testBucketStatePerGroup() config.group[3].nodes[0].index = 9; config.group[3].nodes[1].index = 10; config.group[3].nodes[2].index = 11; - lib::Distribution::SP distr(new lib::Distribution(config)); + auto distr = std::make_shared<lib::Distribution>(config); triggerDistributionChange(std::move(distr)); { @@ -1369,85 +1141,72 @@ StateCheckersTest::testBucketStatePerGroup() } // Node 1 and 8 is is ideal state - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 1 as active: " - "copy is trusted and ideal state priority 4]" - "[Setting node 6 as active: " - "copy is trusted and ideal state priority 0] (pri 90)"), - testBucketStatePerGroup("0=2/3/4/t, 1=2/3/4/t, 3=2/3/4/t, " - "5=2/3/4/t, 6=2/3/4/t, 8=2/3/4/t", true)); + EXPECT_EQ("[Setting node 1 as active: " + "copy is trusted and ideal state priority 4]" + "[Setting node 6 as active: " + "copy is trusted and ideal state priority 0] (pri 90)", + testBucketStatePerGroup("0=2/3/4/t, 1=2/3/4/t, 3=2/3/4/t, " + "5=2/3/4/t, 6=2/3/4/t, 8=2/3/4/t", true)); // Data differ between groups - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 1 as active: " - "copy is trusted and ideal state priority 4]" - "[Setting node 6 as active: " - "copy is ideal state priority 0] (pri 90)"), - testBucketStatePerGroup("0=2/3/4/t, 1=2/3/4/t, 3=2/3/4/t, " - "5=5/6/7, 6=5/6/7, 8=5/6/7", true)); + EXPECT_EQ("[Setting node 1 as active: " + "copy is trusted and ideal state priority 4]" + "[Setting node 6 as active: " + "copy is ideal state priority 0] (pri 90)", + testBucketStatePerGroup("0=2/3/4/t, 1=2/3/4/t, 3=2/3/4/t, " + "5=5/6/7, 6=5/6/7, 8=5/6/7", true)); // Disable too - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 0 as inactive]" - "[Setting node 3 as inactive]" - "[Setting node 5 as inactive]" - "[Setting node 8 as inactive] (pri 90)"), - testBucketStatePerGroup("0=2/3/4/t/a, 1=2/3/4/t/a, 3=2/3/4/t/a, " - "5=2/3/4/t/a, 6=2/3/4/t/a, 8=2/3/4/t/a", - true)); + EXPECT_EQ("[Setting node 0 as inactive]" + "[Setting node 3 as inactive]" + "[Setting node 5 as inactive]" + "[Setting node 8 as inactive] (pri 90)", + testBucketStatePerGroup("0=2/3/4/t/a, 1=2/3/4/t/a, 3=2/3/4/t/a, " + "5=2/3/4/t/a, 6=2/3/4/t/a, 8=2/3/4/t/a", + true)); // Node 1 and 8 is is ideal state - CPPUNIT_ASSERT_EQUAL( - std::string("[Setting node 1 as active: " - "copy is trusted and ideal state priority 4]" - "[Setting node 6 as active: " - "copy is trusted and ideal state priority 0]" - "[Setting node 9 as active: " - "copy is trusted and ideal state priority 2] (pri 90)"), - testBucketStatePerGroup("0=2/3/4/t, 1=2/3/4/t, 3=2/3/4/t, " - "5=2/3/4/t, 6=2/3/4/t, 8=2/3/4/t, " - "9=2/3/4/t, 10=2/3/4/t, 11=2/3/4/t", - true)); + EXPECT_EQ("[Setting node 1 as active: " + "copy is trusted and ideal state priority 4]" + "[Setting node 6 as active: " + "copy is trusted and ideal state priority 0]" + "[Setting node 9 as active: " + "copy is trusted and ideal state priority 2] (pri 90)", + testBucketStatePerGroup("0=2/3/4/t, 1=2/3/4/t, 3=2/3/4/t, " + "5=2/3/4/t, 6=2/3/4/t, 8=2/3/4/t, " + "9=2/3/4/t, 10=2/3/4/t, 11=2/3/4/t", + true)); } -void -StateCheckersTest::allowActivationOfRetiredNodes() -{ +TEST_F(StateCheckersTest, allow_activation_of_retired_nodes) { // All nodes in retired state implies that the ideal state is empty. But // we still want to be able to shuffle bucket activations around in order // to preserve coverage. setupDistributor(2, 2, "distributor:1 storage:2 .0.s:r .1.s:r"); - CPPUNIT_ASSERT_EQUAL( - "[Setting node 1 as active: copy is trusted]" - "[Setting node 0 as inactive]"s, - testBucketState("0=2/3/4/u/a,1=5/6/7/t")); + EXPECT_EQ("[Setting node 1 as active: copy is trusted]" + "[Setting node 0 as inactive]", + testBucketState("0=2/3/4/u/a,1=5/6/7/t")); } -void -StateCheckersTest::inhibitBucketActivationIfDisabledInConfig() -{ +TEST_F(StateCheckersTest, inhibit_bucket_activation_if_disabled_in_config) { setupDistributor(2, 4, "distributor:1 storage:4"); disableBucketActivationInConfig(true); // Node 1 is in ideal state and only replica and should be activated in // an indexed cluster context (but not here). - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("1=2/3/4", 2, true)); + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("1=2/3/4", 2, true)); } -void -StateCheckersTest::inhibitBucketDeactivationIfDisabledInConfig() -{ +TEST_F(StateCheckersTest, inhibit_bucket_deactivation_if_disabled_in_config) { setupDistributor(2, 4, "distributor:1 storage:4"); disableBucketActivationInConfig(true); // Multiple replicas which would have been deactivated. This test is mostly // for the sake of completion; a scenario where buckets are active while // having no indexed documents configured should not happen. - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testBucketState("1=1/2/3/t/a,2=1/2/3/t/a,3=1/2/3/t/a")); + EXPECT_EQ("NO OPERATIONS GENERATED", + testBucketState("1=1/2/3/t/a,2=1/2/3/t/a,3=1/2/3/t/a")); } std::string StateCheckersTest::testGarbageCollection( @@ -1473,60 +1232,48 @@ std::string StateCheckersTest::testGarbageCollection( includePriority, includeSchedulingPri); } -void -StateCheckersTest::testGarbageCollection() -{ +TEST_F(StateCheckersTest, garbage_collection) { // BucketId(17, 0) has id (and thus 'hash') 0x4400000000000000. With a // check interval modulo of 3600, this implies a start point of 848. - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testGarbageCollection(900, 3600 + 847, 3600)); + EXPECT_EQ("NO OPERATIONS GENERATED", + testGarbageCollection(900, 3600 + 847, 3600)); - CPPUNIT_ASSERT_EQUAL( - std::string("[Needs garbage collection: Last check at 900, current time 4448, " - "configured interval 3600]"), - testGarbageCollection(900, 3600 + 848, 3600)); + EXPECT_EQ("[Needs garbage collection: Last check at 900, current time 4448, " + "configured interval 3600]", + testGarbageCollection(900, 3600 + 848, 3600)); - CPPUNIT_ASSERT_EQUAL( - std::string("[Needs garbage collection: Last check at 3, current time 4000, " - "configured interval 3600]"), - testGarbageCollection(3, 4000, 3600)); + EXPECT_EQ("[Needs garbage collection: Last check at 3, current time 4000, " + "configured interval 3600]", + testGarbageCollection(3, 4000, 3600)); // GC start point 3648. - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testGarbageCollection(3, 3647, 8000)); + EXPECT_EQ("NO OPERATIONS GENERATED", + testGarbageCollection(3, 3647, 8000)); - CPPUNIT_ASSERT_EQUAL( - std::string("[Needs garbage collection: Last check at 3, current time 4000, " - "configured interval 3600]"), - testGarbageCollection(3, 4000, 3600)); + EXPECT_EQ("[Needs garbage collection: Last check at 3, current time 4000, " + "configured interval 3600]", + testGarbageCollection(3, 4000, 3600)); // GC explicitly disabled. - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testGarbageCollection(3, 4000, 0)); - - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testGarbageCollection(3, 3, 1)); - - CPPUNIT_ASSERT_EQUAL( - std::string("[Needs garbage collection: Last check at 3, current time 4000, " - "configured interval 300] (pri 200)"), - testGarbageCollection(3, 4000, 300, 1, true)); - - CPPUNIT_ASSERT_EQUAL( - std::string("NO OPERATIONS GENERATED"), - testGarbageCollection(3850, 4000, 300, 1)); + EXPECT_EQ("NO OPERATIONS GENERATED", + testGarbageCollection(3, 4000, 0)); + + EXPECT_EQ("NO OPERATIONS GENERATED", + testGarbageCollection(3, 3, 1)); + + EXPECT_EQ("[Needs garbage collection: Last check at 3, current time 4000, " + "configured interval 300] (pri 200)", + testGarbageCollection(3, 4000, 300, 1, true)); + + EXPECT_EQ("NO OPERATIONS GENERATED", + testGarbageCollection(3850, 4000, 300, 1)); } -void StateCheckersTest::gc_ops_are_prioritized_with_low_priority_category() { - CPPUNIT_ASSERT_EQUAL( - std::string("[Needs garbage collection: Last check at 3, current time 4000, " - "configured interval 300] (scheduling pri VERY_LOW)"), - testGarbageCollection(3, 4000, 300, 1, false, true)); +TEST_F(StateCheckersTest, gc_ops_are_prioritized_with_low_priority_category) { + EXPECT_EQ("[Needs garbage collection: Last check at 3, current time 4000, " + "configured interval 300] (scheduling pri VERY_LOW)", + testGarbageCollection(3, 4000, 300, 1, false, true)); } /** @@ -1535,9 +1282,7 @@ void StateCheckersTest::gc_ops_are_prioritized_with_low_priority_category() { * the replicas when the node out of maintenance. Consequently we should not * trigger GC for buckets when this is the case. */ -void -StateCheckersTest::gcInhibitedWhenIdealNodeInMaintenance() -{ +TEST_F(StateCheckersTest, gc_inhibited_when_ideal_node_in_maintenance) { // Redundancy is 3, so with only 3 nodes, node 1 is guaranteed to be part of // the ideal state of any bucket in the system. setupDistributor(3, 3, "distributor:1 storage:3 .1.s:m"); @@ -1560,7 +1305,7 @@ StateCheckersTest::gcInhibitedWhenIdealNodeInMaintenance() // overshot the GC check cycle. auto result = testStateChecker(checker, c, false, PendingMessage(), false); - CPPUNIT_ASSERT_EQUAL(std::string("NO OPERATIONS GENERATED"), result); + EXPECT_EQ("NO OPERATIONS GENERATED", result); } /* @@ -1569,17 +1314,14 @@ StateCheckersTest::gcInhibitedWhenIdealNodeInMaintenance() * (it's bad mojo to potentially delete something that would've been merged * had it not been for a node being in maintenance). */ -void -StateCheckersTest::testNoRemoveWhenIdealNodeInMaintenance() -{ - CPPUNIT_ASSERT_EQUAL_MSG( - "Do not remove when ideal node is in maintenance mode", - std::string("NO OPERATIONS GENERATED"), - testDeleteExtraCopies("0=10/100/1/true," - "1=10/100/1/true," - "2=10/100/1/true", - 2, PendingMessage(), - "distributor:1 storage:3 .1.s:m")); +TEST_F(StateCheckersTest, no_remove_when_ideal_node_in_maintenance) { + EXPECT_EQ("NO OPERATIONS GENERATED", + testDeleteExtraCopies("0=10/100/1/true," + "1=10/100/1/true," + "2=10/100/1/true", + 2, PendingMessage(), + "distributor:1 storage:3 .1.s:m")) + << "Do not remove when ideal node is in maintenance mode"; } /* @@ -1591,9 +1333,7 @@ StateCheckersTest::testNoRemoveWhenIdealNodeInMaintenance() * * See bug 6768991 for context. */ -void -StateCheckersTest::testStepwiseJoinForSmallBucketsWithoutSiblings() -{ +TEST_F(StateCheckersTest, stepwise_join_for_small_buckets_without_siblings) { setupDistributor(3, 10, "distributor:1 storage:2 bits:1"); vespa::config::content::core::StorDistributormanagerConfigBuilder config; config.enableJoinForSiblingLessBuckets = true; @@ -1602,31 +1342,27 @@ StateCheckersTest::testStepwiseJoinForSmallBucketsWithoutSiblings() // into bucket (2, 1). insertBucketInfo(document::BucketId(3, 1), 1, 0x1, 1, 1); insertBucketInfo(document::BucketId(3, 0x3), 1, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL(std::string( - "BucketId(0x0800000000000001): " - "[Joining buckets BucketId(0x0c00000000000001) and " - "BucketId(0x0c00000000000001) because their size " - "(1 bytes, 1 docs) is less than the configured limit " - "of (100, 10)"), - testJoin(10, 100, 2, document::BucketId(3, 1))); + EXPECT_EQ("BucketId(0x0800000000000001): " + "[Joining buckets BucketId(0x0c00000000000001) and " + "BucketId(0x0c00000000000001) because their size " + "(1 bytes, 1 docs) is less than the configured limit " + "of (100, 10)", + testJoin(10, 100, 2, document::BucketId(3, 1))); // Other bucket should be joined as well. Together the two join targets // will transform into a mighty sibling pair that can rule the galaxy // (and also be joined together afterwards)! insertBucketInfo(document::BucketId(3, 1), 1, 0x1, 1, 1); insertBucketInfo(document::BucketId(3, 0x3), 1, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL(std::string( - "BucketId(0x0800000000000003): " - "[Joining buckets BucketId(0x0c00000000000003) and " - "BucketId(0x0c00000000000003) because their size " - "(1 bytes, 1 docs) is less than the configured limit " - "of (100, 10)"), - testJoin(10, 100, 2, document::BucketId(3, 0x3))); + EXPECT_EQ("BucketId(0x0800000000000003): " + "[Joining buckets BucketId(0x0c00000000000003) and " + "BucketId(0x0c00000000000003) because their size " + "(1 bytes, 1 docs) is less than the configured limit " + "of (100, 10)", + testJoin(10, 100, 2, document::BucketId(3, 0x3))); } -void -StateCheckersTest::testNoStepwiseJoinWhenDisabledThroughConfig() -{ +TEST_F(StateCheckersTest, no_stepwise_join_when_disabled_through_config) { setupDistributor(3, 10, "distributor:1 storage:2 bits:1"); vespa::config::content::core::StorDistributormanagerConfigBuilder config; config.enableJoinForSiblingLessBuckets = false; @@ -1636,13 +1372,11 @@ StateCheckersTest::testNoStepwiseJoinWhenDisabledThroughConfig() // into bucket 1 if it had been config-enabled. insertBucketInfo(document::BucketId(3, 1), 1, 0x1, 1, 1); insertBucketInfo(document::BucketId(3, 0x3), 1, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL(std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 1, document::BucketId(3, 1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 1, document::BucketId(3, 1))); } -void -StateCheckersTest::testNoStepwiseJoinWhenSingleSiblingTooLarge() -{ +TEST_F(StateCheckersTest, no_stepwise_join_when_single_sibling_too_large) { setupDistributor(3, 10, "distributor:1 storage:2 bits:1"); vespa::config::content::core::StorDistributormanagerConfigBuilder config; config.enableJoinForSiblingLessBuckets = true; @@ -1651,13 +1385,11 @@ StateCheckersTest::testNoStepwiseJoinWhenSingleSiblingTooLarge() // Bucket is exactly at the boundary where it's too big. insertBucketInfo(document::BucketId(3, 1), 1, 0x1, 10, 100); insertBucketInfo(document::BucketId(3, 0x3), 1, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL(std::string("NO OPERATIONS GENERATED"), - testJoin(10, 100, 1, document::BucketId(3, 1))); + EXPECT_EQ("NO OPERATIONS GENERATED", + testJoin(10, 100, 1, document::BucketId(3, 1))); } -void -StateCheckersTest::testStepwiseJoinMaySkipMultipleBitsWhenConsistent() -{ +TEST_F(StateCheckersTest, stepwise_join_may_skip_multiple_bits_when_consistent) { setupDistributor(2, 10, "distributor:1 storage:2 bits:8"); vespa::config::content::core::StorDistributormanagerConfigBuilder config; config.enableJoinForSiblingLessBuckets = true; @@ -1666,18 +1398,15 @@ StateCheckersTest::testStepwiseJoinMaySkipMultipleBitsWhenConsistent() insertBucketInfo(document::BucketId(16, 1), 1, 0x1, 1, 1); // No buckets further up in the tree, can join up to the distribution bit // limit at 8. - CPPUNIT_ASSERT_EQUAL(std::string( - "BucketId(0x2000000000000001): " - "[Joining buckets BucketId(0x4000000000000001) and " - "BucketId(0x4000000000000001) because their size " - "(1 bytes, 1 docs) is less than the configured limit " - "of (100, 10)"), - testJoin(10, 100, 8, document::BucketId(16, 1))); + EXPECT_EQ("BucketId(0x2000000000000001): " + "[Joining buckets BucketId(0x4000000000000001) and " + "BucketId(0x4000000000000001) because their size " + "(1 bytes, 1 docs) is less than the configured limit " + "of (100, 10)", + testJoin(10, 100, 8, document::BucketId(16, 1))); } -void -StateCheckersTest::testStepwiseJoinDoesNotSkipBeyondLevelWithSibling() -{ +TEST_F(StateCheckersTest, stepwise_join_does_not_skip_beyond_level_with_sibling) { setupDistributor(2, 10, "distributor:1 storage:2 bits:8"); vespa::config::content::core::StorDistributormanagerConfigBuilder config; config.enableJoinForSiblingLessBuckets = true; @@ -1689,44 +1418,34 @@ StateCheckersTest::testStepwiseJoinDoesNotSkipBeyondLevelWithSibling() // the (16, 0) bucket cannot be moved further up than level 11 as it has a // sibling there (0x2c00000000000400 sibling of 0x2c00000000000000). insertBucketInfo(document::BucketId(11, 1 << 10), 1, 0x1, 1, 1); - CPPUNIT_ASSERT_EQUAL(std::string( - "BucketId(0x2c00000000000000): " - "[Joining buckets BucketId(0x4000000000000000) and " - "BucketId(0x4000000000000000) because their size " - "(1 bytes, 1 docs) is less than the configured limit " - "of (100, 10)"), - testJoin(10, 100, 8, document::BucketId(16, 0))); + EXPECT_EQ("BucketId(0x2c00000000000000): " + "[Joining buckets BucketId(0x4000000000000000) and " + "BucketId(0x4000000000000000) because their size " + "(1 bytes, 1 docs) is less than the configured limit " + "of (100, 10)", + testJoin(10, 100, 8, document::BucketId(16, 0))); } -void -StateCheckersTest::joinCanBeScheduledWhenReplicasOnRetiredNodes() -{ +TEST_F(StateCheckersTest, join_can_be_scheduled_when_replicas_on_retired_nodes) { setupDistributor(1, 1, "distributor:1 storage:1 .0.s.:r"); insertJoinableBuckets(); - CPPUNIT_ASSERT_EQUAL( - "BucketId(0x8000000000000001): " - "[Joining buckets BucketId(0x8400000000000001) and " - "BucketId(0x8400000100000001) because their size " - "(2 bytes, 2 docs) is less than the configured limit " - "of (100, 10)"s, - testJoin(10, 100, 16, document::BucketId(33, 1))); + EXPECT_EQ("BucketId(0x8000000000000001): " + "[Joining buckets BucketId(0x8400000000000001) and " + "BucketId(0x8400000100000001) because their size " + "(2 bytes, 2 docs) is less than the configured limit " + "of (100, 10)", + testJoin(10, 100, 16, document::BucketId(33, 1))); } -void -StateCheckersTest::contextPopulatesIdealStateContainers() -{ +TEST_F(StateCheckersTest, context_populates_ideal_state_containers) { // 1 and 3 are ideal nodes for bucket {17, 0} setupDistributor(2, 100, "distributor:1 storage:4"); NodeMaintenanceStatsTracker statsTracker; StateChecker::Context c(getExternalOperationHandler(), getDistributorBucketSpace(), statsTracker, makeDocumentBucket({17, 0})); - CPPUNIT_ASSERT_EQUAL((std::vector<uint16_t>{1, 3}), c.idealState); - CPPUNIT_ASSERT_EQUAL(size_t(2), c.unorderedIdealState.size()); - CPPUNIT_ASSERT(c.unorderedIdealState.find(1) - != c.unorderedIdealState.end()); - CPPUNIT_ASSERT(c.unorderedIdealState.find(3) - != c.unorderedIdealState.end()); + ASSERT_THAT(c.idealState, ElementsAre(1, 3)); + ASSERT_THAT(c.unorderedIdealState, UnorderedElementsAre(1, 3)); } namespace { @@ -1738,10 +1457,9 @@ class StateCheckerRunner NodeMaintenanceStatsTracker _statsTracker; std::string _result; public: - StateCheckerRunner(StateCheckersTest& fixture); + explicit StateCheckerRunner(StateCheckersTest& fixture); ~StateCheckerRunner(); - StateCheckerRunner& addToDb(const document::BucketId& bid, const std::string& bucketInfo) { @@ -1780,13 +1498,11 @@ StateCheckerRunner<Checker>::StateCheckerRunner(StateCheckersTest& fixture) : _fixture(fixture) {} template <typename Checker> -StateCheckerRunner<Checker>::~StateCheckerRunner() {} +StateCheckerRunner<Checker>::~StateCheckerRunner() = default; } // anon ns -void -StateCheckersTest::statsUpdatedWhenMergingDueToMove() -{ +TEST_F(StateCheckersTest, stats_updated_when_merging_due_to_move) { StateCheckerRunner<SynchronizeAndMoveStateChecker> runner(*this); // Ideal state for bucket {17,0} in given cluster state is [1, 3] runner.addToDb({17, 0}, "0=1,1=1,2=1") @@ -1796,7 +1512,7 @@ StateCheckersTest::statsUpdatedWhenMergingDueToMove() { NodeMaintenanceStats wanted; wanted.copyingOut = 1; - CPPUNIT_ASSERT_EQUAL(wanted, runner.stats().forNode(1, makeBucketSpace())); + EXPECT_EQ(wanted, runner.stats().forNode(1, makeBucketSpace())); } // Moving 1 bucket from nodes {0, 2} into 3. // Note that we do not at this point in time distinguish _which_ of these @@ -1804,19 +1520,17 @@ StateCheckersTest::statsUpdatedWhenMergingDueToMove() { NodeMaintenanceStats wanted; wanted.copyingIn = 1; - CPPUNIT_ASSERT_EQUAL(wanted, runner.stats().forNode(3, makeBucketSpace())); + EXPECT_EQ(wanted, runner.stats().forNode(3, makeBucketSpace())); } { NodeMaintenanceStats wanted; wanted.movingOut = 1; - CPPUNIT_ASSERT_EQUAL(wanted, runner.stats().forNode(0, makeBucketSpace())); - CPPUNIT_ASSERT_EQUAL(wanted, runner.stats().forNode(2, makeBucketSpace())); + EXPECT_EQ(wanted, runner.stats().forNode(0, makeBucketSpace())); + EXPECT_EQ(wanted, runner.stats().forNode(2, makeBucketSpace())); } } -void -StateCheckersTest::statsUpdatedWhenMergingDueToMissingCopy() -{ +TEST_F(StateCheckersTest, stats_updated_when_merging_due_to_missing_copy) { StateCheckerRunner<SynchronizeAndMoveStateChecker> runner(*this); // Ideal state for bucket {17,0} in given cluster state is [1, 3] runner.addToDb({17, 0}, "1=1") @@ -1826,18 +1540,16 @@ StateCheckersTest::statsUpdatedWhenMergingDueToMissingCopy() { NodeMaintenanceStats wanted; wanted.copyingIn = 1; - CPPUNIT_ASSERT_EQUAL(wanted, runner.stats().forNode(3, makeBucketSpace())); + EXPECT_EQ(wanted, runner.stats().forNode(3, makeBucketSpace())); } { NodeMaintenanceStats wanted; wanted.copyingOut = 1; - CPPUNIT_ASSERT_EQUAL(wanted, runner.stats().forNode(1, makeBucketSpace())); + EXPECT_EQ(wanted, runner.stats().forNode(1, makeBucketSpace())); } } -void -StateCheckersTest::statsUpdatedWhenMergingDueToOutOfSyncCopies() -{ +TEST_F(StateCheckersTest, stats_updated_when_merging_due_to_out_of_sync_copies) { StateCheckerRunner<SynchronizeAndMoveStateChecker> runner(*this); runner.addToDb({17, 0}, "1=1,3=2") .clusterState("distributor:1 storage:4") @@ -1845,8 +1557,8 @@ StateCheckersTest::statsUpdatedWhenMergingDueToOutOfSyncCopies() { NodeMaintenanceStats wanted; wanted.syncing = 1; - CPPUNIT_ASSERT_EQUAL(wanted, runner.stats().forNode(1, makeBucketSpace())); - CPPUNIT_ASSERT_EQUAL(wanted, runner.stats().forNode(3, makeBucketSpace())); + EXPECT_EQ(wanted, runner.stats().forNode(1, makeBucketSpace())); + EXPECT_EQ(wanted, runner.stats().forNode(3, makeBucketSpace())); } } diff --git a/storage/src/tests/distributor/statoperationtest.cpp b/storage/src/tests/distributor/statoperationtest.cpp index 19337a0d52a..53ea0ec5efa 100644 --- a/storage/src/tests/distributor/statoperationtest.cpp +++ b/storage/src/tests/distributor/statoperationtest.cpp @@ -2,82 +2,63 @@ #include <tests/common/dummystoragelink.h> #include <vespa/storageapi/message/stat.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <tests/distributor/distributortestutil.h> #include <vespa/document/test/make_document_bucket.h> #include <vespa/storage/distributor/operations/external/statbucketoperation.h> #include <vespa/storage/distributor/operations/external/statbucketlistoperation.h> #include <vespa/storage/distributor/distributor.h> #include <vespa/storage/distributor/distributor_bucket_space.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> using document::test::makeDocumentBucket; +using namespace ::testing; -namespace storage { -namespace distributor { +namespace storage::distributor { -struct StatOperationTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ - void setUp() override { +struct StatOperationTest : Test, DistributorTestUtil { + void SetUp() override { createLinks(); }; - void tearDown() override { + void TearDown() override { close(); } - - void testBucketInfo(); - void testBucketList(); - - CPPUNIT_TEST_SUITE(StatOperationTest); - CPPUNIT_TEST(testBucketInfo); - CPPUNIT_TEST(testBucketList); - CPPUNIT_TEST_SUITE_END(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(StatOperationTest); - -void -StatOperationTest::testBucketInfo() -{ +TEST_F(StatOperationTest, bucket_info) { enableDistributorClusterState("distributor:1 storage:2"); - addNodesToBucketDB(document::BucketId(16, 5), - "0=4/2/100,1=4/2/100"); + addNodesToBucketDB(document::BucketId(16, 5), "0=4/2/100,1=4/2/100"); StatBucketOperation op( getExternalOperationHandler(), getDistributorBucketSpace(), - std::shared_ptr<api::StatBucketCommand>( - new api::StatBucketCommand(makeDocumentBucket(document::BucketId(16, 5)), ""))); + std::make_shared<api::StatBucketCommand>( + makeDocumentBucket(document::BucketId(16, 5)), "")); op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Statbucket => 0,Statbucket => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Statbucket => 0,Statbucket => 1", _sender.getCommands(true)); { - api::StatBucketCommand* tmp( - static_cast<api::StatBucketCommand*>(_sender.commands[0].get())); - api::StatBucketReply* reply = new api::StatBucketReply(*tmp, "foo"); - op.receive(_sender, std::shared_ptr<api::StorageReply>(reply)); + auto* tmp = static_cast<api::StatBucketCommand*>(_sender.command(0).get()); + auto reply = std::make_shared<api::StatBucketReply>(*tmp, "foo"); + op.receive(_sender, reply); } { - api::StatBucketCommand* tmp( - static_cast<api::StatBucketCommand*>(_sender.commands[1].get())); - api::StatBucketReply* reply = new api::StatBucketReply(*tmp, "bar"); - op.receive(_sender, std::shared_ptr<api::StorageReply>(reply)); + auto* tmp = static_cast<api::StatBucketCommand*>(_sender.command(1).get()); + auto reply = std::make_shared<api::StatBucketReply>(*tmp, "bar"); + op.receive(_sender, reply); } - api::StatBucketReply* replyback( - static_cast<api::StatBucketReply*>(_sender.replies.back().get())); - CPPUNIT_ASSERT_CONTAIN("foo", replyback->getResults()); - CPPUNIT_ASSERT_CONTAIN("bar", replyback->getResults()); + auto* replyback = static_cast<api::StatBucketReply*>(_sender.replies().back().get()); + EXPECT_THAT(replyback->getResults(), HasSubstr("foo")); + EXPECT_THAT(replyback->getResults(), HasSubstr("bar")); } -void -StatOperationTest::testBucketList() { +TEST_F(StatOperationTest, bucket_list) { setupDistributor(2, 2, "distributor:1 storage:2"); getConfig().setSplitCount(10); @@ -88,8 +69,7 @@ StatOperationTest::testBucketList() { 0xff, 100, 200, true, (i == 1)); } - std::shared_ptr<api::GetBucketListCommand> msg( - new api::GetBucketListCommand(makeDocumentBucket(document::BucketId(16, 5)))); + auto msg = std::make_shared<api::GetBucketListCommand>(makeDocumentBucket(document::BucketId(16, 5))); StatBucketListOperation op( getDistributorBucketSpace().getBucketDatabase(), @@ -98,23 +78,18 @@ StatOperationTest::testBucketList() { msg); op.start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(1, (int)_sender.replies.size()); - - api::GetBucketListReply* repl( - dynamic_cast<api::GetBucketListReply*>(_sender.replies[0].get())); - - CPPUNIT_ASSERT_EQUAL(1, (int)repl->getBuckets().size()); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 5), - repl->getBuckets()[0]._bucket); - CPPUNIT_ASSERT_EQUAL( - vespalib::string( - "[distributor:0] split: " - "[Splitting bucket because its maximum size (200 b, 100 docs, 100 meta, 200 b total) " - "is higher than the configured limit of (100, 10)] " - "[node(idx=0,crc=0xff,docs=100/100,bytes=200/200,trusted=true,active=false,ready=false), " - "node(idx=1,crc=0xff,docs=100/100,bytes=200/200,trusted=true,active=true,ready=false)]"), - repl->getBuckets()[0]._bucketInformation); + ASSERT_EQ(1, _sender.replies().size()); + + auto& repl = dynamic_cast<api::GetBucketListReply&>(*_sender.reply(0)); + + ASSERT_EQ(1, repl.getBuckets().size()); + EXPECT_EQ(repl.getBuckets()[0]._bucket, document::BucketId(16, 5)); + EXPECT_EQ("[distributor:0] split: " + "[Splitting bucket because its maximum size (200 b, 100 docs, 100 meta, 200 b total) " + "is higher than the configured limit of (100, 10)] " + "[node(idx=0,crc=0xff,docs=100/100,bytes=200/200,trusted=true,active=false,ready=false), " + "node(idx=1,crc=0xff,docs=100/100,bytes=200/200,trusted=true,active=true,ready=false)]", + repl.getBuckets()[0]._bucketInformation); } -} // distributor -} // storage +} // storage::distributor diff --git a/storage/src/tests/distributor/statusreporterdelegatetest.cpp b/storage/src/tests/distributor/statusreporterdelegatetest.cpp index 99d576cad56..9e66f1920e2 100644 --- a/storage/src/tests/distributor/statusreporterdelegatetest.cpp +++ b/storage/src/tests/distributor/statusreporterdelegatetest.cpp @@ -1,30 +1,16 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> #include <tests/common/testhelper.h> #include <tests/distributor/distributortestutil.h> - #include <vespa/storage/distributor/statusreporterdelegate.h> +#include <vespa/vespalib/gtest/gtest.h> -namespace storage { -namespace distributor { - -class StatusReporterDelegateTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(StatusReporterDelegateTest); - CPPUNIT_TEST(testDelegateInvokesDelegatorOnStatusRequest); - CPPUNIT_TEST_SUITE_END(); - - void testDelegateInvokesDelegatorOnStatusRequest(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(StatusReporterDelegateTest); +namespace storage::distributor { namespace { -// We really ought to get GoogleMock as part of our testing suite... -class MockDelegator : public StatusDelegator -{ +// TODO replace with gmock impl +class MockDelegator : public StatusDelegator { mutable std::ostringstream _calls; bool handleStatusRequest(const DelegatedStatusRequest& request) const override { _calls << "Request(" << request.path << ")"; @@ -58,30 +44,22 @@ public: } -void -StatusReporterDelegateTest::testDelegateInvokesDelegatorOnStatusRequest() -{ +TEST(StatusReporterDelegateTest, delegate_invokes_delegator_on_status_request) { vdstestlib::DirConfig config(getStandardConfig(false)); TestDistributorApp app(config.getConfigId()); MockDelegator mockDelegator; MockStatusReporter reporter; - StatusReporterDelegate delegate(app.getComponentRegister(), - mockDelegator, - reporter); + StatusReporterDelegate delegate(app.getComponentRegister(), mockDelegator, reporter); framework::HttpUrlPath path("dummy"); - CPPUNIT_ASSERT_EQUAL(vespalib::string("foo/bar"), - delegate.getReportContentType(path)); + EXPECT_EQ("foo/bar", delegate.getReportContentType(path)); std::ostringstream ss; - CPPUNIT_ASSERT(delegate.reportStatus(ss, path)); + ASSERT_TRUE(delegate.reportStatus(ss, path)); - CPPUNIT_ASSERT_EQUAL(std::string("Request(dummy)"), - mockDelegator.getCalls()); - CPPUNIT_ASSERT_EQUAL(std::string("reportStatus with dummy"), - ss.str()); + EXPECT_EQ("Request(dummy)", mockDelegator.getCalls()); + EXPECT_EQ("reportStatus with dummy", ss.str()); } -} // distributor -} // storage +} // storage::distributor diff --git a/storage/src/tests/distributor/throttlingoperationstartertest.cpp b/storage/src/tests/distributor/throttlingoperationstartertest.cpp index c3290a8c0f6..2dc4561068b 100644 --- a/storage/src/tests/distributor/throttlingoperationstartertest.cpp +++ b/storage/src/tests/distributor/throttlingoperationstartertest.cpp @@ -1,27 +1,17 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> + #include <vespa/storage/distributor/throttlingoperationstarter.h> #include <tests/distributor/maintenancemocks.h> #include <vespa/document/test/make_document_bucket.h> +#include <vespa/vespalib/gtest/gtest.h> -using document::test::makeDocumentBucket; - -namespace storage { - -namespace distributor { +namespace storage::distributor { using document::BucketId; +using document::test::makeDocumentBucket; +using namespace ::testing; -class ThrottlingOperationStarterTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(ThrottlingOperationStarterTest); - CPPUNIT_TEST(testOperationNotThrottledWhenSlotAvailable); - CPPUNIT_TEST(testOperationStartingIsForwardedToImplementation); - CPPUNIT_TEST(testOperationThrottledWhenNoAvailableSlots); - CPPUNIT_TEST(testThrottlingWithMaxPendingRange); - CPPUNIT_TEST(testStartingOperationsFillsUpPendingWindow); - CPPUNIT_TEST(testFinishingOperationsAllowsMoreToStart); - CPPUNIT_TEST_SUITE_END(); - +struct ThrottlingOperationStarterTest : Test { std::shared_ptr<Operation> createMockOperation() { return std::shared_ptr<Operation>(new MockOperation(makeDocumentBucket(BucketId(16, 1)))); } @@ -29,113 +19,90 @@ class ThrottlingOperationStarterTest : public CppUnit::TestFixture { std::unique_ptr<MockOperationStarter> _starterImpl; std::unique_ptr<ThrottlingOperationStarter> _operationStarter; -public: - void testOperationNotThrottledWhenSlotAvailable(); - void testOperationStartingIsForwardedToImplementation(); - void testOperationThrottledWhenNoAvailableSlots(); - void testThrottlingWithMaxPendingRange(); - void testStartingOperationsFillsUpPendingWindow(); - void testFinishingOperationsAllowsMoreToStart(); - - void setUp() override; - void tearDown() override; + void SetUp() override; + void TearDown() override; }; -CPPUNIT_TEST_SUITE_REGISTRATION(ThrottlingOperationStarterTest); - void -ThrottlingOperationStarterTest::setUp() +ThrottlingOperationStarterTest::SetUp() { - _starterImpl.reset(new MockOperationStarter()); - _operationStarter.reset(new ThrottlingOperationStarter(*_starterImpl)); + _starterImpl = std::make_unique<MockOperationStarter>(); + _operationStarter = std::make_unique<ThrottlingOperationStarter>(*_starterImpl); } void -ThrottlingOperationStarterTest::tearDown() +ThrottlingOperationStarterTest::TearDown() { // Must clear before _operationStarter goes out of scope, or operation // destructors will try to call method on destroyed object. _starterImpl->getOperations().clear(); } -void -ThrottlingOperationStarterTest::testOperationNotThrottledWhenSlotAvailable() -{ - CPPUNIT_ASSERT(_operationStarter->start(createMockOperation(), - OperationStarter::Priority(0))); +TEST_F(ThrottlingOperationStarterTest, operation_not_throttled_when_slot_available) { + EXPECT_TRUE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(0))); } -void -ThrottlingOperationStarterTest::testOperationStartingIsForwardedToImplementation() -{ - CPPUNIT_ASSERT(_operationStarter->start(createMockOperation(), - OperationStarter::Priority(0))); - CPPUNIT_ASSERT_EQUAL(std::string("Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri 0\n"), - _starterImpl->toString()); +TEST_F(ThrottlingOperationStarterTest, operation_starting_is_forwarded_to_implementation) { + ASSERT_TRUE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(0))); + EXPECT_EQ("Bucket(BucketSpace(0x0000000000000001), BucketId(0x4000000000000001)), pri 0\n", + _starterImpl->toString()); } -void -ThrottlingOperationStarterTest::testOperationThrottledWhenNoAvailableSlots() -{ +TEST_F(ThrottlingOperationStarterTest, operation_throttled_when_no_available_slots) { _operationStarter->setMaxPendingRange(0, 0); - CPPUNIT_ASSERT(!_operationStarter->start(createMockOperation(), - OperationStarter::Priority(0))); + EXPECT_FALSE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(0))); } -void -ThrottlingOperationStarterTest::testThrottlingWithMaxPendingRange() -{ +TEST_F(ThrottlingOperationStarterTest, throttling_with_max_pending_range) { _operationStarter->setMaxPendingRange(0, 1); - CPPUNIT_ASSERT(!_operationStarter->canStart(0, OperationStarter::Priority(255))); - CPPUNIT_ASSERT(_operationStarter->canStart(0, OperationStarter::Priority(0))); + EXPECT_FALSE(_operationStarter->canStart(0, OperationStarter::Priority(255))); + EXPECT_TRUE(_operationStarter->canStart(0, OperationStarter::Priority(0))); _operationStarter->setMaxPendingRange(1, 1); - CPPUNIT_ASSERT(_operationStarter->canStart(0, OperationStarter::Priority(255))); - CPPUNIT_ASSERT(_operationStarter->canStart(0, OperationStarter::Priority(0))); + EXPECT_TRUE(_operationStarter->canStart(0, OperationStarter::Priority(255))); + EXPECT_TRUE(_operationStarter->canStart(0, OperationStarter::Priority(0))); _operationStarter->setMaxPendingRange(1, 3); - CPPUNIT_ASSERT(!_operationStarter->canStart(1, OperationStarter::Priority(255))); - CPPUNIT_ASSERT(_operationStarter->canStart(1, OperationStarter::Priority(100))); - CPPUNIT_ASSERT(_operationStarter->canStart(1, OperationStarter::Priority(0))); - CPPUNIT_ASSERT(_operationStarter->canStart(2, OperationStarter::Priority(0))); - CPPUNIT_ASSERT(!_operationStarter->canStart(3, OperationStarter::Priority(0))); - CPPUNIT_ASSERT(!_operationStarter->canStart(4, OperationStarter::Priority(0))); + EXPECT_FALSE(_operationStarter->canStart(1, OperationStarter::Priority(255))); + EXPECT_TRUE(_operationStarter->canStart(1, OperationStarter::Priority(100))); + EXPECT_TRUE(_operationStarter->canStart(1, OperationStarter::Priority(0))); + EXPECT_TRUE(_operationStarter->canStart(2, OperationStarter::Priority(0))); + EXPECT_FALSE(_operationStarter->canStart(3, OperationStarter::Priority(0))); + EXPECT_FALSE(_operationStarter->canStart(4, OperationStarter::Priority(0))); } -void -ThrottlingOperationStarterTest::testStartingOperationsFillsUpPendingWindow() -{ +TEST_F(ThrottlingOperationStarterTest, starting_operations_fills_up_pending_window) { _operationStarter->setMaxPendingRange(1, 3); - CPPUNIT_ASSERT(_operationStarter->start(createMockOperation(), - OperationStarter::Priority(255))); - CPPUNIT_ASSERT(!_operationStarter->start(createMockOperation(), - OperationStarter::Priority(255))); - CPPUNIT_ASSERT(_operationStarter->start(createMockOperation(), - OperationStarter::Priority(100))); - CPPUNIT_ASSERT(!_operationStarter->start(createMockOperation(), - OperationStarter::Priority(100))); - CPPUNIT_ASSERT(_operationStarter->start(createMockOperation(), - OperationStarter::Priority(0))); - CPPUNIT_ASSERT(!_operationStarter->start(createMockOperation(), - OperationStarter::Priority(0))); + EXPECT_TRUE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(255))); + EXPECT_FALSE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(255))); + EXPECT_TRUE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(100))); + EXPECT_FALSE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(100))); + EXPECT_TRUE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(0))); + EXPECT_FALSE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(0))); } -void -ThrottlingOperationStarterTest::testFinishingOperationsAllowsMoreToStart() -{ +TEST_F(ThrottlingOperationStarterTest, finishing_operations_allows_more_to_start) { _operationStarter->setMaxPendingRange(1, 1); - CPPUNIT_ASSERT(_operationStarter->start(createMockOperation(), - OperationStarter::Priority(255))); - CPPUNIT_ASSERT(!_operationStarter->start(createMockOperation(), - OperationStarter::Priority(255))); - CPPUNIT_ASSERT(!_starterImpl->getOperations().empty()); + EXPECT_TRUE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(255))); + EXPECT_FALSE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(255))); + EXPECT_FALSE(_starterImpl->getOperations().empty()); _starterImpl->getOperations().pop_back(); - CPPUNIT_ASSERT(_operationStarter->start(createMockOperation(), - OperationStarter::Priority(255))); - CPPUNIT_ASSERT(!_starterImpl->getOperations().empty()); + EXPECT_TRUE(_operationStarter->start(createMockOperation(), + OperationStarter::Priority(255))); + EXPECT_FALSE(_starterImpl->getOperations().empty()); } } -} diff --git a/storage/src/tests/distributor/twophaseupdateoperationtest.cpp b/storage/src/tests/distributor/twophaseupdateoperationtest.cpp index a8771ddc28a..edb5261fbfa 100644 --- a/storage/src/tests/distributor/twophaseupdateoperationtest.cpp +++ b/storage/src/tests/distributor/twophaseupdateoperationtest.cpp @@ -1,7 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/config/helper/configgetter.h> -#include <cppunit/extensions/HelperMacros.h> #include <vespa/document/config/config-documenttypes.h> #include <vespa/document/repo/documenttyperepo.h> #include <vespa/document/base/testdocrepo.h> @@ -14,13 +13,12 @@ #include <tests/distributor/distributortestutil.h> #include <vespa/document/test/make_document_bucket.h> #include <vespa/storage/distributor/distributor.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> -using document::test::makeDocumentBucket; - -namespace storage { -namespace distributor { +namespace storage::distributor { -using std::shared_ptr; +using document::test::makeDocumentBucket; using config::ConfigGetter; using document::DocumenttypesConfig; using namespace document; @@ -28,87 +26,22 @@ using namespace storage; using namespace storage::distributor; using namespace storage::api; using namespace storage::lib; +using namespace ::testing; -using namespace std::literals::string_literals; - -class TwoPhaseUpdateOperationTest : public CppUnit::TestFixture, - public DistributorTestUtil -{ - CPPUNIT_TEST_SUITE(TwoPhaseUpdateOperationTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(testNonExisting); - CPPUNIT_TEST(testUpdateFailed); - CPPUNIT_TEST(testFastPathInconsistentTimestamps); - CPPUNIT_TEST(testFastPathInconsistentTimestampsNotFound); - CPPUNIT_TEST(testFastPathInconsistentTimestampsUpdateError); - CPPUNIT_TEST(testFastPathInconsistentTimestampsGetError); - CPPUNIT_TEST(testFastPathInconsistentTimestampsPutError); - CPPUNIT_TEST(testFastPathInconsistentTimestampsPutNotStarted); - CPPUNIT_TEST(testFastPathInconsistentTimestampsInconsistentSplit); - CPPUNIT_TEST(testFastPathPropagatesMessageSettingsToUpdate); - CPPUNIT_TEST(testNofM); - CPPUNIT_TEST(testSafePathUpdatesNewestReceivedDocument); - CPPUNIT_TEST(testCreateIfNonExistentCreatesDocumentIfAllEmptyGets); - CPPUNIT_TEST(testUpdateFailsIfSafePathHasFailedPut); - CPPUNIT_TEST(testUpdateFailsIfSafePathGetsFail); - CPPUNIT_TEST(testUpdateFailsIfApplyThrowsException); - CPPUNIT_TEST(testNonExistingWithAutoCreate); - CPPUNIT_TEST(testSafePathFailsUpdateWhenMismatchingTimestampConstraint); - CPPUNIT_TEST(testSafePathUpdatePropagatesMessageSettingsToGetsAndPuts); - CPPUNIT_TEST(testSafePathPropagatesMbusTracesFromReplies); - CPPUNIT_TEST(testUpdateFailsIfOwnershipChangesBetweenGetAndPut); - CPPUNIT_TEST(testSafePathConditionMismatchFailsWithTasError); - CPPUNIT_TEST(testSafePathConditionMatchSendsPutsWithUpdatedDoc); - CPPUNIT_TEST(testSafePathConditionParseFailureFailsWithIllegalParamsError); - CPPUNIT_TEST(testSafePathConditonUnknownDocTypeFailsWithIllegalParamsError); - CPPUNIT_TEST(safe_path_condition_with_missing_doc_and_no_auto_create_fails_with_tas_error); - CPPUNIT_TEST(safe_path_condition_with_missing_doc_and_auto_create_sends_puts); - CPPUNIT_TEST(testFastPathCloseEdgeSendsCorrectReply); - CPPUNIT_TEST(testSafePathCloseEdgeSendsCorrectReply); - CPPUNIT_TEST_SUITE_END(); - +struct TwoPhaseUpdateOperationTest : Test, DistributorTestUtil { document::TestDocRepo _testRepo; std::shared_ptr<const DocumentTypeRepo> _repo; const DocumentType* _doc_type; -protected: - void testSimple(); - void testNonExisting(); - void testUpdateFailed(); - void testFastPathInconsistentTimestamps(); - void testFastPathInconsistentTimestampsNotFound(); - void testFastPathInconsistentTimestampsUpdateError(); - void testFastPathInconsistentTimestampsGetError(); - void testFastPathInconsistentTimestampsPutError(); - void testFastPathInconsistentTimestampsPutNotStarted(); - void testFastPathInconsistentTimestampsInconsistentSplit(); - void testFastPathPropagatesMessageSettingsToUpdate(); - void testNofM(); - void testSafePathUpdatesNewestReceivedDocument(); - void testCreateIfNonExistentCreatesDocumentIfAllEmptyGets(); - void testUpdateFailsIfSafePathHasFailedPut(); - void testUpdateFailsIfSafePathGetsFail(); - void testUpdateFailsIfApplyThrowsException(); - void testNonExistingWithAutoCreate(); - void testSafePathFailsUpdateWhenMismatchingTimestampConstraint(); - void testSafePathUpdatePropagatesMessageSettingsToGetsAndPuts(); - void testSafePathPropagatesMbusTracesFromReplies(); - void testUpdateFailsIfOwnershipChangesBetweenGetAndPut(); - void testSafePathConditionMismatchFailsWithTasError(); - void testSafePathConditionMatchSendsPutsWithUpdatedDoc(); - void testSafePathConditionParseFailureFailsWithIllegalParamsError(); - void testSafePathConditonUnknownDocTypeFailsWithIllegalParamsError(); - void safe_path_condition_with_missing_doc_and_no_auto_create_fails_with_tas_error(); - void safe_path_condition_with_missing_doc_and_auto_create_sends_puts(); - void testFastPathCloseEdgeSendsCorrectReply(); - void testSafePathCloseEdgeSendsCorrectReply(); + TwoPhaseUpdateOperationTest(); + ~TwoPhaseUpdateOperationTest(); void checkMessageSettingsPropagatedTo( const api::StorageCommand::SP& msg) const; - std::string getUpdatedValueFromLastPut(MessageSenderStub&); -public: - void setUp() override { + std::string getUpdatedValueFromLastPut(DistributorMessageSenderStub&); + + void SetUp() override { _repo = _testRepo.getTypeRepoSp(); _doc_type = _repo->getDocumentType("testdoctype1"); createLinks(); @@ -116,32 +49,32 @@ public: getClock().setAbsoluteTimeInSeconds(200); } - void tearDown() override { + void TearDown() override { close(); } void replyToMessage(Operation& callback, - MessageSenderStub& sender, + DistributorMessageSenderStub& sender, uint32_t index, uint64_t oldTimestamp, api::ReturnCode::Result result = api::ReturnCode::OK); void replyToPut( Operation& callback, - MessageSenderStub& sender, + DistributorMessageSenderStub& sender, uint32_t index, api::ReturnCode::Result result = api::ReturnCode::OK, const std::string& traceMsg = ""); void replyToCreateBucket( Operation& callback, - MessageSenderStub& sender, + DistributorMessageSenderStub& sender, uint32_t index, api::ReturnCode::Result result = api::ReturnCode::OK); void replyToGet( Operation& callback, - MessageSenderStub& sender, + DistributorMessageSenderStub& sender, uint32_t index, uint64_t oldTimestamp, bool haveDocument = true, @@ -191,21 +124,22 @@ public: const UpdateOptions& options = UpdateOptions()); void assertAbortedUpdateReplyWithContextPresent( - const MessageSenderStub& closeSender) const; + const DistributorMessageSenderStub& closeSender) const; }; -CPPUNIT_TEST_SUITE_REGISTRATION(TwoPhaseUpdateOperationTest); +TwoPhaseUpdateOperationTest::TwoPhaseUpdateOperationTest() = default; +TwoPhaseUpdateOperationTest::~TwoPhaseUpdateOperationTest() = default; void TwoPhaseUpdateOperationTest::replyToMessage( Operation& callback, - MessageSenderStub& sender, + DistributorMessageSenderStub& sender, uint32_t index, uint64_t oldTimestamp, api::ReturnCode::Result result) { - std::shared_ptr<api::StorageMessage> msg2 = sender.commands.at(index); + std::shared_ptr<api::StorageMessage> msg2 = sender.command(index); auto& updatec = dynamic_cast<UpdateCommand&>(*msg2); std::unique_ptr<api::StorageReply> reply(updatec.makeReply()); static_cast<api::UpdateReply*>(reply.get())->setOldTimestamp(oldTimestamp); @@ -218,12 +152,12 @@ TwoPhaseUpdateOperationTest::replyToMessage( void TwoPhaseUpdateOperationTest::replyToPut( Operation& callback, - MessageSenderStub& sender, + DistributorMessageSenderStub& sender, uint32_t index, api::ReturnCode::Result result, const std::string& traceMsg) { - std::shared_ptr<api::StorageMessage> msg2 = sender.commands.at(index); + std::shared_ptr<api::StorageMessage> msg2 = sender.command(index); auto& putc = dynamic_cast<PutCommand&>(*msg2); std::unique_ptr<api::StorageReply> reply(putc.makeReply()); reply->setResult(api::ReturnCode(result, "")); @@ -237,11 +171,11 @@ TwoPhaseUpdateOperationTest::replyToPut( void TwoPhaseUpdateOperationTest::replyToCreateBucket( Operation& callback, - MessageSenderStub& sender, + DistributorMessageSenderStub& sender, uint32_t index, api::ReturnCode::Result result) { - std::shared_ptr<api::StorageMessage> msg2 = sender.commands.at(index); + std::shared_ptr<api::StorageMessage> msg2 = sender.command(index); auto& putc = dynamic_cast<CreateBucketCommand&>(*msg2); std::unique_ptr<api::StorageReply> reply(putc.makeReply()); reply->setResult(api::ReturnCode(result, "")); @@ -252,14 +186,14 @@ TwoPhaseUpdateOperationTest::replyToCreateBucket( void TwoPhaseUpdateOperationTest::replyToGet( Operation& callback, - MessageSenderStub& sender, + DistributorMessageSenderStub& sender, uint32_t index, uint64_t oldTimestamp, bool haveDocument, api::ReturnCode::Result result, const std::string& traceMsg) { - auto& get = static_cast<const api::GetCommand&>(*sender.commands.at(index)); + auto& get = static_cast<const api::GetCommand&>(*sender.command(index)); std::shared_ptr<api::StorageReply> reply; if (haveDocument) { @@ -340,294 +274,239 @@ TwoPhaseUpdateOperationTest::sendUpdate(const std::string& bucketState, handler, getDistributorBucketSpace(), msg, getDistributor().getMetrics()); } - -void -TwoPhaseUpdateOperationTest::testSimple() -{ +TEST_F(TwoPhaseUpdateOperationTest, simple) { setupDistributor(1, 1, "storage:1 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("0=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Update => 0"), sender.getCommands(true)); + ASSERT_EQ("Update => 0", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 90); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 90) ReturnCode(NONE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 90) ReturnCode(NONE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testNonExisting() -{ +TEST_F(TwoPhaseUpdateOperationTest, non_existing) { setupDistributor(1, 1, "storage:1 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 0) ReturnCode(NONE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 0) ReturnCode(NONE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testUpdateFailed() -{ +TEST_F(TwoPhaseUpdateOperationTest, update_failed) { setupDistributor(1, 1, "storage:1 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("0=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("Update => 0"), - sender.getCommands(true)); + ASSERT_EQ("Update => 0", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 90, api::ReturnCode::INTERNAL_FAILURE); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 0) " - "ReturnCode(INTERNAL_FAILURE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 0) " + "ReturnCode(INTERNAL_FAILURE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testFastPathInconsistentTimestamps() -{ +TEST_F(TwoPhaseUpdateOperationTest, fast_path_inconsistent_timestamps) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("0=1/2/3,1=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("Update => 0,Update => 1"), - sender.getCommands(true)); + ASSERT_EQ("Update => 0,Update => 1", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 90); replyToMessage(*cb, sender, 1, 110); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000008b13), doc:test:test) => 1"), - sender.getLastCommand(true)); + ASSERT_EQ("Get(BucketId(0x4000000000008b13), doc:test:test) => 1", + sender.getLastCommand(true)); replyToGet(*cb, sender, 2, 110); - CPPUNIT_ASSERT_EQUAL( - std::string("Update => 0,Update => 1,Get => 1,Put => 1,Put => 0"), - sender.getCommands(true)); + ASSERT_EQ("Update => 0,Update => 1,Get => 1,Put => 1,Put => 0", + sender.getCommands(true)); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToPut(*cb, sender, 3); replyToPut(*cb, sender, 4); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 110 Was inconsistent " - "(best node 1)) ReturnCode(NONE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 110 Was inconsistent " + "(best node 1)) ReturnCode(NONE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testFastPathInconsistentTimestampsNotFound() -{ +TEST_F(TwoPhaseUpdateOperationTest, fast_path_inconsistent_timestamps_not_found) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("0=1/2/3,1=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("Update => 0,Update => 1"), - sender.getCommands(true)); + ASSERT_EQ("Update => 0,Update => 1", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 90); replyToMessage(*cb, sender, 1, 110); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000008b13), doc:test:test) => 1"), - sender.getLastCommand(true)); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_EQ("Get(BucketId(0x4000000000008b13), doc:test:test) => 1", + sender.getLastCommand(true)); + ASSERT_TRUE(sender.replies().empty()); replyToGet(*cb, sender, 2, 110, false); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 110 Was inconsistent " - "(best node 1)) ReturnCode(INTERNAL_FAILURE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 110 Was inconsistent " + "(best node 1)) ReturnCode(INTERNAL_FAILURE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testFastPathInconsistentTimestampsUpdateError() -{ +TEST_F(TwoPhaseUpdateOperationTest, fast_path_inconsistent_timestamps_update_error) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("0=1/2/3,1=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("Update => 0,Update => 1"), - sender.getCommands(true)); + ASSERT_EQ("Update => 0,Update => 1", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 90); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToMessage(*cb, sender, 1, 110, api::ReturnCode::IO_FAILURE); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 90) " - "ReturnCode(IO_FAILURE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 90) " + "ReturnCode(IO_FAILURE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testFastPathInconsistentTimestampsGetError() -{ +TEST_F(TwoPhaseUpdateOperationTest, fast_path_inconsistent_timestamps_get_error) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("0=1/2/3,1=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("Update => 0,Update => 1"), - sender.getCommands(true)); + ASSERT_EQ("Update => 0,Update => 1", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 90); replyToMessage(*cb, sender, 1, 110); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000008b13), doc:test:test) => 1"), - sender.getLastCommand(true)); + ASSERT_EQ("Get(BucketId(0x4000000000008b13), doc:test:test) => 1", + sender.getLastCommand(true)); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToGet(*cb, sender, 2, 110, false, api::ReturnCode::IO_FAILURE); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 110 Was inconsistent " - "(best node 1)) ReturnCode(IO_FAILURE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 110 Was inconsistent " + "(best node 1)) ReturnCode(IO_FAILURE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testFastPathInconsistentTimestampsPutError() -{ +TEST_F(TwoPhaseUpdateOperationTest, fast_path_inconsistent_timestamps_put_error) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("0=1/2/3,1=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("Update => 0,Update => 1"), - sender.getCommands(true)); + ASSERT_EQ("Update => 0,Update => 1", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 90); replyToMessage(*cb, sender, 1, 110); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000008b13), doc:test:test) => 1"), - sender.getLastCommand(true)); + ASSERT_EQ("Get(BucketId(0x4000000000008b13), doc:test:test) => 1", + sender.getLastCommand(true)); replyToGet(*cb, sender, 2, 110); - CPPUNIT_ASSERT_EQUAL( - std::string("Update => 0,Update => 1,Get => 1,Put => 1,Put => 0"), - sender.getCommands(true)); + ASSERT_EQ("Update => 0,Update => 1,Get => 1,Put => 1,Put => 0", + sender.getCommands(true)); replyToPut(*cb, sender, 3, api::ReturnCode::IO_FAILURE); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToPut(*cb, sender, 4); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 110 Was inconsistent " - "(best node 1)) ReturnCode(IO_FAILURE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 110 Was inconsistent " + "(best node 1)) ReturnCode(IO_FAILURE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testFastPathInconsistentTimestampsPutNotStarted() -{ +TEST_F(TwoPhaseUpdateOperationTest, fast_path_inconsistent_timestamps_put_not_started) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("0=1/2/3,1=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("Update => 0,Update => 1"), - sender.getCommands(true)); + ASSERT_EQ("Update => 0,Update => 1", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 90); replyToMessage(*cb, sender, 1, 110); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000008b13), doc:test:test) => 1"), - sender.getLastCommand(true)); - checkMessageSettingsPropagatedTo(sender.commands.back()); + ASSERT_EQ("Get(BucketId(0x4000000000008b13), doc:test:test) => 1", + sender.getLastCommand(true)); + checkMessageSettingsPropagatedTo(sender.commands().back()); enableDistributorClusterState("storage:0 distributor:1"); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToGet(*cb, sender, 2, 110); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 110 Was inconsistent " - "(best node 1)) ReturnCode(NOT_CONNECTED, " - "Can't store document: No storage nodes available)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 110 Was inconsistent " + "(best node 1)) ReturnCode(NOT_CONNECTED, " + "Can't store document: No storage nodes available)", + sender.getLastReply(true)); } - -void -TwoPhaseUpdateOperationTest::testFastPathInconsistentTimestampsInconsistentSplit() -{ +TEST_F(TwoPhaseUpdateOperationTest, fast_path_inconsistent_timestamps_inconsistent_split) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=1/2/3", UpdateOptions().makeInconsistentSplit(true))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); std::string wanted("Get(BucketId(0x4000000000008b13), doc:test:test) => 0," "Get(BucketId(0x4400000000008b13), doc:test:test) => 0"); std::string text = sender.getCommands(true, true); - CPPUNIT_ASSERT_EQUAL(wanted, text); + ASSERT_EQ(wanted, text); replyToGet(*cb, sender, 0, 90); replyToGet(*cb, sender, 1, 120); - CPPUNIT_ASSERT_EQUAL( - std::string( - "Put(BucketId(0x4400000000008b13), doc:test:test, " - "timestamp 200000000, size 52) => 1," - "Put(BucketId(0x4400000000008b13), doc:test:test, " - "timestamp 200000000, size 52) => 0"), - sender.getCommands(true, true, 2)); + ASSERT_EQ("Put(BucketId(0x4400000000008b13), doc:test:test, " + "timestamp 200000000, size 52) => 1," + "Put(BucketId(0x4400000000008b13), doc:test:test, " + "timestamp 200000000, size 52) => 0", + sender.getCommands(true, true, 2)); replyToPut(*cb, sender, 2); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToPut(*cb, sender, 3); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 120) " - "ReturnCode(NONE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 120) " + "ReturnCode(NONE)", + sender.getLastReply(true)); } void @@ -635,355 +514,301 @@ TwoPhaseUpdateOperationTest::checkMessageSettingsPropagatedTo( const api::StorageCommand::SP& msg) const { // Settings set in sendUpdate(). - CPPUNIT_ASSERT_EQUAL(uint32_t(6), msg->getTrace().getLevel()); - CPPUNIT_ASSERT_EQUAL(uint32_t(6789), msg->getTimeout()); - CPPUNIT_ASSERT_EQUAL(uint8_t(99), msg->getPriority()); + EXPECT_EQ(6, msg->getTrace().getLevel()); + EXPECT_EQ(6789, msg->getTimeout()); + EXPECT_EQ(99, msg->getPriority()); } -void -TwoPhaseUpdateOperationTest::testFastPathPropagatesMessageSettingsToUpdate() -{ +TEST_F(TwoPhaseUpdateOperationTest, fast_path_propagates_message_settings_to_update) { setupDistributor(1, 1, "storage:1 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("0=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Update => 0"), sender.getCommands(true)); + ASSERT_EQ("Update => 0", sender.getCommands(true)); - StorageCommand::SP msg(sender.commands.back()); + StorageCommand::SP msg(sender.commands().back()); checkMessageSettingsPropagatedTo(msg); } -void -TwoPhaseUpdateOperationTest::testNofM() -{ +TEST_F(TwoPhaseUpdateOperationTest, n_of_m) { setupDistributor(2, 2, "storage:2 distributor:1", 1); std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("0=1/2/3,1=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("Update => 0,Update => 1"), - sender.getCommands(true)); + ASSERT_EQ("Update => 0,Update => 1", sender.getCommands(true)); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToMessage(*cb, sender, 0, 90); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 90) ReturnCode(NONE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 90) ReturnCode(NONE)", + sender.getLastReply(true)); replyToMessage(*cb, sender, 1, 123); } std::string TwoPhaseUpdateOperationTest::getUpdatedValueFromLastPut( - MessageSenderStub& sender) + DistributorMessageSenderStub& sender) { - Document::SP doc(dynamic_cast<api::PutCommand&>(*sender.commands.back()) + Document::SP doc(dynamic_cast<api::PutCommand&>(*sender.commands().back()) .getDocument()); FieldValue::UP value(doc->getValue("headerval")); return value->toString(); } -void -TwoPhaseUpdateOperationTest::testSafePathUpdatesNewestReceivedDocument() -{ +TEST_F(TwoPhaseUpdateOperationTest, safe_path_updates_newest_received_document) { setupDistributor(3, 3, "storage:3 distributor:1"); // 0,1 in sync. 2 out of sync. std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=1/2/3,2=2/3/4")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("Get(BucketId(0x4000000000008b13), doc:test:test) => 0," - "Get(BucketId(0x4000000000008b13), doc:test:test) => 2"), - sender.getCommands(true, true)); + ASSERT_EQ("Get(BucketId(0x4000000000008b13), doc:test:test) => 0," + "Get(BucketId(0x4000000000008b13), doc:test:test) => 2", + sender.getCommands(true, true)); replyToGet(*cb, sender, 0, 50); replyToGet(*cb, sender, 1, 70); - CPPUNIT_ASSERT_EQUAL( - std::string( - "Put(BucketId(0x4000000000008b13), doc:test:test, " - "timestamp 200000000, size 52) => 1," - "Put(BucketId(0x4000000000008b13), doc:test:test, " - "timestamp 200000000, size 52) => 0," - "Put(BucketId(0x4000000000008b13), doc:test:test, " - "timestamp 200000000, size 52) => 2"), - sender.getCommands(true, true, 2)); + ASSERT_EQ("Put(BucketId(0x4000000000008b13), doc:test:test, " + "timestamp 200000000, size 52) => 1," + "Put(BucketId(0x4000000000008b13), doc:test:test, " + "timestamp 200000000, size 52) => 0," + "Put(BucketId(0x4000000000008b13), doc:test:test, " + "timestamp 200000000, size 52) => 2", + sender.getCommands(true, true, 2)); // Make sure Put contains an updated document (+10 arith. update on field // whose value equals gotten timestamp). In this case we want 70 -> 80. - CPPUNIT_ASSERT_EQUAL(std::string("80"), getUpdatedValueFromLastPut(sender)); + ASSERT_EQ("80", getUpdatedValueFromLastPut(sender)); replyToPut(*cb, sender, 2); replyToPut(*cb, sender, 3); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToPut(*cb, sender, 4); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 70) " - "ReturnCode(NONE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 70) " + "ReturnCode(NONE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testCreateIfNonExistentCreatesDocumentIfAllEmptyGets() -{ +TEST_F(TwoPhaseUpdateOperationTest, create_if_non_existent_creates_document_if_all_empty_gets) { setupDistributor(3, 3, "storage:3 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=1/2/3,2=2/3/4", UpdateOptions().createIfNonExistent(true))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Get => 0,Get => 2"), - sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 2", sender.getCommands(true)); replyToGet(*cb, sender, 0, 0, false); replyToGet(*cb, sender, 1, 0, false); // Since create-if-non-existent is set, distributor should create doc from // scratch. - CPPUNIT_ASSERT_EQUAL( - std::string( - "Put(BucketId(0x4000000000008b13), doc:test:test, " - "timestamp 200000000, size 52) => 1," - "Put(BucketId(0x4000000000008b13), doc:test:test, " - "timestamp 200000000, size 52) => 0," - "Put(BucketId(0x4000000000008b13), doc:test:test, " - "timestamp 200000000, size 52) => 2"), - sender.getCommands(true, true, 2)); - - CPPUNIT_ASSERT_EQUAL(std::string("10"), getUpdatedValueFromLastPut(sender)); + ASSERT_EQ("Put(BucketId(0x4000000000008b13), doc:test:test, " + "timestamp 200000000, size 52) => 1," + "Put(BucketId(0x4000000000008b13), doc:test:test, " + "timestamp 200000000, size 52) => 0," + "Put(BucketId(0x4000000000008b13), doc:test:test, " + "timestamp 200000000, size 52) => 2", + sender.getCommands(true, true, 2)); + + ASSERT_EQ("10", getUpdatedValueFromLastPut(sender)); replyToPut(*cb, sender, 2); replyToPut(*cb, sender, 3); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToPut(*cb, sender, 4); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 200000000) " - "ReturnCode(NONE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 200000000) " + "ReturnCode(NONE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testUpdateFailsIfSafePathHasFailedPut() -{ +TEST_F(TwoPhaseUpdateOperationTest, update_fails_if_safe_path_has_failed_put) { setupDistributor(3, 3, "storage:3 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=1/2/3,2=2/3/4", UpdateOptions().createIfNonExistent(true))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Get => 0,Get => 2"), - sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 2", sender.getCommands(true)); replyToGet(*cb, sender, 0, 0, false); replyToGet(*cb, sender, 1, 0, false); // Since create-if-non-existent is set, distributor should create doc from // scratch. - CPPUNIT_ASSERT_EQUAL(std::string("Put => 1,Put => 0,Put => 2"), - sender.getCommands(true, false, 2)); + ASSERT_EQ("Put => 1,Put => 0,Put => 2", sender.getCommands(true, false, 2)); replyToPut(*cb, sender, 2); replyToPut(*cb, sender, 3); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToPut(*cb, sender, 4, api::ReturnCode::IO_FAILURE); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 200000000) " - "ReturnCode(IO_FAILURE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 200000000) " + "ReturnCode(IO_FAILURE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testUpdateFailsIfSafePathGetsFail() -{ +TEST_F(TwoPhaseUpdateOperationTest, update_fails_if_safe_path_gets_fail) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=2/3/4", UpdateOptions().createIfNonExistent(true))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Get => 0,Get => 1"), - sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 1", sender.getCommands(true)); replyToGet(*cb, sender, 0, 0, false, api::ReturnCode::IO_FAILURE); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToGet(*cb, sender, 1, 0, false, api::ReturnCode::IO_FAILURE); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 0) " - "ReturnCode(IO_FAILURE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 0) " + "ReturnCode(IO_FAILURE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testUpdateFailsIfApplyThrowsException() -{ +TEST_F(TwoPhaseUpdateOperationTest, update_fails_if_apply_throws_exception) { setupDistributor(2, 2, "storage:2 distributor:1"); // Create update for wrong doctype which will fail the update. std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=2/3/4", UpdateOptions().withError())); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Get => 0,Get => 1"), - sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 1", sender.getCommands(true)); replyToGet(*cb, sender, 0, 50); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToGet(*cb, sender, 1, 70); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 70) " - "ReturnCode(INTERNAL_FAILURE, Can not apply a " - "\"testdoctype2\" document update to a " - "\"testdoctype1\" document.)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 70) " + "ReturnCode(INTERNAL_FAILURE, Can not apply a " + "\"testdoctype2\" document update to a " + "\"testdoctype1\" document.)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testNonExistingWithAutoCreate() -{ +TEST_F(TwoPhaseUpdateOperationTest, non_existing_with_auto_create) { setupDistributor(1, 1, "storage:1 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("", UpdateOptions().createIfNonExistent(true))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string( - "CreateBucketCommand(BucketId(0x4000000000008b13), active) " - "Reasons to start: => 0," - "Put(BucketId(0x4000000000008b13), doc:test:test, " - "timestamp 200000000, size 52) => 0"), - sender.getCommands(true, true)); + ASSERT_EQ("CreateBucketCommand(BucketId(0x4000000000008b13), active) " + "Reasons to start: => 0," + "Put(BucketId(0x4000000000008b13), doc:test:test, " + "timestamp 200000000, size 52) => 0", + sender.getCommands(true, true)); - CPPUNIT_ASSERT_EQUAL(std::string("10"), getUpdatedValueFromLastPut(sender)); + ASSERT_EQ("10", getUpdatedValueFromLastPut(sender)); replyToCreateBucket(*cb, sender, 0); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToPut(*cb, sender, 1); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 200000000) " - "ReturnCode(NONE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 200000000) " + "ReturnCode(NONE)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testSafePathFailsUpdateWhenMismatchingTimestampConstraint() -{ +TEST_F(TwoPhaseUpdateOperationTest, safe_path_fails_update_when_mismatching_timestamp_constraint) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=2/3/4", UpdateOptions().timestampToUpdate(1234))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Get => 0,Get => 1"), - sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 1", sender.getCommands(true)); replyToGet(*cb, sender, 0, 100); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToGet(*cb, sender, 1, 110); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 0) " - "ReturnCode(NONE, No document with requested " - "timestamp found)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 0) " + "ReturnCode(NONE, No document with requested " + "timestamp found)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testSafePathUpdatePropagatesMessageSettingsToGetsAndPuts() -{ +TEST_F(TwoPhaseUpdateOperationTest, safe_path_update_propagates_message_settings_to_gets_and_puts) { setupDistributor(3, 3, "storage:3 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=1/2/3,2=2/3/4")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Get => 0,Get => 2"), - sender.getCommands(true)); - checkMessageSettingsPropagatedTo(sender.commands.at(0)); - checkMessageSettingsPropagatedTo(sender.commands.at(1)); + ASSERT_EQ("Get => 0,Get => 2", sender.getCommands(true)); + checkMessageSettingsPropagatedTo(sender.command(0)); + checkMessageSettingsPropagatedTo(sender.command(1)); replyToGet(*cb, sender, 0, 50); replyToGet(*cb, sender, 1, 70); - CPPUNIT_ASSERT_EQUAL(std::string("Put => 1,Put => 0,Put => 2"), - sender.getCommands(true, false, 2)); - checkMessageSettingsPropagatedTo(sender.commands.at(2)); - checkMessageSettingsPropagatedTo(sender.commands.at(3)); - checkMessageSettingsPropagatedTo(sender.commands.at(4)); + ASSERT_EQ("Put => 1,Put => 0,Put => 2", sender.getCommands(true, false, 2)); + checkMessageSettingsPropagatedTo(sender.command(2)); + checkMessageSettingsPropagatedTo(sender.command(3)); + checkMessageSettingsPropagatedTo(sender.command(4)); replyToPut(*cb, sender, 2); replyToPut(*cb, sender, 3); replyToPut(*cb, sender, 4); } -void -TwoPhaseUpdateOperationTest::testSafePathPropagatesMbusTracesFromReplies() -{ +TEST_F(TwoPhaseUpdateOperationTest, safe_path_propagates_mbus_traces_from_replies) { setupDistributor(3, 3, "storage:3 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=1/2/3,2=2/3/4")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Get => 0,Get => 2"), - sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 2", sender.getCommands(true)); replyToGet(*cb, sender, 0, 50, true, api::ReturnCode::OK, "hello earthlings"); replyToGet(*cb, sender, 1, 70); - CPPUNIT_ASSERT_EQUAL(std::string("Put => 1,Put => 0,Put => 2"), - sender.getCommands(true, false, 2)); + ASSERT_EQ("Put => 1,Put => 0,Put => 2", sender.getCommands(true, false, 2)); replyToPut(*cb, sender, 2, api::ReturnCode::OK, "fooo"); replyToPut(*cb, sender, 3, api::ReturnCode::OK, "baaa"); - CPPUNIT_ASSERT(sender.replies.empty()); + ASSERT_TRUE(sender.replies().empty()); replyToPut(*cb, sender, 4); - CPPUNIT_ASSERT_EQUAL(std::string("Update Reply"), - sender.getLastReply(false)); - - std::string trace(sender.replies.back()->getTrace().toString()); - //std::cout << "\n\n" << trace << "\n\n"; - CPPUNIT_ASSERT(trace.find("hello earthlings") != std::string::npos); - CPPUNIT_ASSERT(trace.find("fooo") != std::string::npos); - CPPUNIT_ASSERT(trace.find("baaa") != std::string::npos); + ASSERT_EQ("Update Reply", sender.getLastReply(false)); + + std::string trace(sender.replies().back()->getTrace().toString()); + ASSERT_THAT(trace, HasSubstr("hello earthlings")); + ASSERT_THAT(trace, HasSubstr("fooo")); + ASSERT_THAT(trace, HasSubstr("baaa")); } -void -TwoPhaseUpdateOperationTest::testUpdateFailsIfOwnershipChangesBetweenGetAndPut() -{ +TEST_F(TwoPhaseUpdateOperationTest, update_fails_if_ownership_changes_between_get_and_put) { setupDistributor(2, 2, "storage:2 distributor:1"); // Update towards inconsistent bucket invokes safe path. std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=2/3/4")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Get => 0,Get => 1"), - sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 1", sender.getCommands(true)); // Alter cluster state so that distributor is now down (technically the // entire cluster is down in this state, but this should not matter). In @@ -998,194 +823,170 @@ TwoPhaseUpdateOperationTest::testUpdateFailsIfOwnershipChangesBetweenGetAndPut() // BUCKET_NOT_FOUND is a transient error code which should cause the client // to re-send the operation, presumably to the correct distributor the next // time. - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 70) " - "ReturnCode(BUCKET_NOT_FOUND, Distributor lost " - "ownership of bucket between executing the read " - "and write phases of a two-phase update operation)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 70) " + "ReturnCode(BUCKET_NOT_FOUND, Distributor lost " + "ownership of bucket between executing the read " + "and write phases of a two-phase update operation)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testSafePathConditionMismatchFailsWithTasError() -{ +TEST_F(TwoPhaseUpdateOperationTest, safe_path_condition_mismatch_fails_with_tas_error) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=2/3/4", UpdateOptions().condition( "testdoctype1.headerval==120"))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); // Newest doc has headerval==110, not 120. replyToGet(*cb, sender, 0, 100); replyToGet(*cb, sender, 1, 110); - CPPUNIT_ASSERT_EQUAL( - "UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 0) " - "ReturnCode(TEST_AND_SET_CONDITION_FAILED, " - "Condition did not match document)"s, - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 0) " + "ReturnCode(TEST_AND_SET_CONDITION_FAILED, " + "Condition did not match document)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testSafePathConditionMatchSendsPutsWithUpdatedDoc() -{ +TEST_F(TwoPhaseUpdateOperationTest, safe_path_condition_match_sends_puts_with_updated_doc) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=2/3/4", UpdateOptions().condition( "testdoctype1.headerval==110"))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); replyToGet(*cb, sender, 0, 100); replyToGet(*cb, sender, 1, 110); - CPPUNIT_ASSERT_EQUAL("Put => 1,Put => 0"s, - sender.getCommands(true, false, 2)); + ASSERT_EQ("Put => 1,Put => 0", sender.getCommands(true, false, 2)); } -void -TwoPhaseUpdateOperationTest::testSafePathConditionParseFailureFailsWithIllegalParamsError() -{ +TEST_F(TwoPhaseUpdateOperationTest, safe_path_condition_parse_failure_fails_with_illegal_params_error) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=2/3/4", UpdateOptions().condition( "testdoctype1.san==fran...cisco"))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); replyToGet(*cb, sender, 0, 100); replyToGet(*cb, sender, 1, 110); // NOTE: condition is currently not attempted parsed until Gets have been // replied to. This may change in the future. // XXX reliance on parser/exception error message is very fragile. - CPPUNIT_ASSERT_EQUAL( - "UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 0) " - "ReturnCode(ILLEGAL_PARAMETERS, " - "Failed to parse test and set condition: " - "syntax error, unexpected . at column 24 when " - "parsing selection 'testdoctype1.san==fran...cisco')"s, - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 0) " + "ReturnCode(ILLEGAL_PARAMETERS, " + "Failed to parse test and set condition: " + "syntax error, unexpected . at column 24 when " + "parsing selection 'testdoctype1.san==fran...cisco')", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::testSafePathConditonUnknownDocTypeFailsWithIllegalParamsError() -{ +TEST_F(TwoPhaseUpdateOperationTest, safe_path_condition_unknown_doc_type_fails_with_illegal_params_error) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=2/3/4", UpdateOptions().condition( "langbein.headerval=1234"))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); replyToGet(*cb, sender, 0, 100); replyToGet(*cb, sender, 1, 110); // NOTE: condition is currently not attempted parsed until Gets have been // replied to. This may change in the future. - CPPUNIT_ASSERT_EQUAL( - "UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 0) " - "ReturnCode(ILLEGAL_PARAMETERS, " - "Failed to parse test and set condition: " - "Document type 'langbein' not found at column 1 " - "when parsing selection 'langbein.headerval=1234')"s, - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 0) " + "ReturnCode(ILLEGAL_PARAMETERS, " + "Failed to parse test and set condition: " + "Document type 'langbein' not found at column 1 " + "when parsing selection 'langbein.headerval=1234')", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::safe_path_condition_with_missing_doc_and_no_auto_create_fails_with_tas_error() -{ +TEST_F(TwoPhaseUpdateOperationTest, safe_path_condition_with_missing_doc_and_no_auto_create_fails_with_tas_error) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=2/3/4", UpdateOptions().condition( "testdoctype1.headerval==120"))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); // Both Gets return nothing at all, nothing at all. replyToGet(*cb, sender, 0, 100, false); replyToGet(*cb, sender, 1, 110, false); - CPPUNIT_ASSERT_EQUAL( - "UpdateReply(doc:test:test, " - "BucketId(0x0000000000000000), " - "timestamp 0, timestamp of updated doc: 0) " - "ReturnCode(TEST_AND_SET_CONDITION_FAILED, " - "Document did not exist)"s, - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, " + "BucketId(0x0000000000000000), " + "timestamp 0, timestamp of updated doc: 0) " + "ReturnCode(TEST_AND_SET_CONDITION_FAILED, " + "Document did not exist)", + sender.getLastReply(true)); } -void -TwoPhaseUpdateOperationTest::safe_path_condition_with_missing_doc_and_auto_create_sends_puts() -{ +TEST_F(TwoPhaseUpdateOperationTest, safe_path_condition_with_missing_doc_and_auto_create_sends_puts) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=2/3/4", UpdateOptions() .condition("testdoctype1.headerval==120") .createIfNonExistent(true))); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); replyToGet(*cb, sender, 0, 100, false); replyToGet(*cb, sender, 1, 110, false); - CPPUNIT_ASSERT_EQUAL("Put => 1,Put => 0"s, sender.getCommands(true, false, 2)); + ASSERT_EQ("Put => 1,Put => 0", sender.getCommands(true, false, 2)); } void TwoPhaseUpdateOperationTest::assertAbortedUpdateReplyWithContextPresent( - const MessageSenderStub& closeSender) const + const DistributorMessageSenderStub& closeSender) const { - CPPUNIT_ASSERT_EQUAL(size_t(1), closeSender.replies.size()); - StorageReply::SP reply(closeSender.replies.back()); - CPPUNIT_ASSERT_EQUAL(api::MessageType::UPDATE_REPLY, reply->getType()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::ABORTED, - reply->getResult().getResult()); + ASSERT_EQ(1, closeSender.replies().size()); + StorageReply::SP reply(closeSender.replies().back()); + ASSERT_EQ(api::MessageType::UPDATE_REPLY, reply->getType()); + ASSERT_EQ(api::ReturnCode::ABORTED, reply->getResult().getResult()); auto context = reply->getTransportContext(); // Transfers ownership - CPPUNIT_ASSERT(context.get()); + ASSERT_TRUE(context.get()); } -void -TwoPhaseUpdateOperationTest::testFastPathCloseEdgeSendsCorrectReply() -{ +TEST_F(TwoPhaseUpdateOperationTest, fast_path_close_edge_sends_correct_reply) { setupDistributor(1, 1, "storage:1 distributor:1"); // Only 1 replica; consistent with itself by definition. std::shared_ptr<TwoPhaseUpdateOperation> cb(sendUpdate("0=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL("Update => 0"s, sender.getCommands(true)); + ASSERT_EQ("Update => 0", sender.getCommands(true)); // Close the operation. This should generate a single reply that is // bound to the original command. We can identify rogue replies by these // not having a transport context, as these are unique_ptrs that are // moved to the reply upon the first reply construction. Any subsequent or // erroneous replies will not have this context attached to themselves. - MessageSenderStub closeSender; + DistributorMessageSenderStub closeSender; cb->onClose(closeSender); assertAbortedUpdateReplyWithContextPresent(closeSender); } -void -TwoPhaseUpdateOperationTest::testSafePathCloseEdgeSendsCorrectReply() -{ +TEST_F(TwoPhaseUpdateOperationTest, safe_path_close_edge_sends_correct_reply) { setupDistributor(2, 2, "storage:2 distributor:1"); std::shared_ptr<TwoPhaseUpdateOperation> cb( sendUpdate("0=1/2/3,1=2/3/4")); // Inconsistent replicas. - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Get => 0,Get => 1"), - sender.getCommands(true)); + ASSERT_EQ("Get => 0,Get => 1", sender.getCommands(true)); // Closing the operation should now only return an ABORTED reply for // the UpdateCommand, _not_ from the nested, pending Get operation (which // will implicitly generate an ABORTED reply for the synthesized Get // command passed to it). - MessageSenderStub closeSender; + DistributorMessageSenderStub closeSender; cb->onClose(closeSender); assertAbortedUpdateReplyWithContextPresent(closeSender); @@ -1198,5 +999,4 @@ TwoPhaseUpdateOperationTest::testSafePathCloseEdgeSendsCorrectReply() // XXX: test case where update reply has been sent but callback still // has pending messages (e.g. n-of-m case). -} // distributor -} // storage +} // storage::distributor diff --git a/storage/src/tests/distributor/updateoperationtest.cpp b/storage/src/tests/distributor/updateoperationtest.cpp index 67cd4f5f233..7cf3ea0ad18 100644 --- a/storage/src/tests/distributor/updateoperationtest.cpp +++ b/storage/src/tests/distributor/updateoperationtest.cpp @@ -1,7 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <cppunit/extensions/HelperMacros.h> -#include <iomanip> #include <tests/common/dummystoragelink.h> #include <vespa/storageapi/message/persistence.h> #include <vespa/storageapi/message/state.h> @@ -11,56 +9,39 @@ #include <vespa/document/update/documentupdate.h> #include <vespa/document/test/make_document_bucket.h> #include <vespa/storage/distributor/operations/external/updateoperation.h> -#include <vespa/vespalib/testkit/test_kit.h> #include <vespa/storage/distributor/distributor.h> #include <vespa/config/helper/configgetter.hpp> +#include <vespa/vespalib/gtest/gtest.h> -using std::shared_ptr; using namespace document; using namespace storage; using namespace storage::distributor; using namespace storage::api; using namespace std; using namespace storage::lib; +using namespace ::testing; using config::ConfigGetter; using config::FileSpec; using vespalib::string; using document::test::makeDocumentBucket; -class UpdateOperation_Test : public CppUnit::TestFixture, - public DistributorTestUtil -{ - CPPUNIT_TEST_SUITE(UpdateOperation_Test); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(testNotFound); - CPPUNIT_TEST(testMultiNode); - CPPUNIT_TEST(testMultiNodeInconsistentTimestamp); - CPPUNIT_TEST_SUITE_END(); - +struct UpdateOperationTest : Test, DistributorTestUtil { std::shared_ptr<const DocumentTypeRepo> _repo; - const DocumentType *_html_type; - -protected: - void testSimple(); - void testNotFound(); - void testMultiNode(); - void testMultiNodeInconsistentTimestamp(); + const DocumentType* _html_type; -public: - void setUp() override { + void SetUp() override { _repo.reset( new DocumentTypeRepo(*ConfigGetter<DocumenttypesConfig>:: - getConfig("config-doctypes", - FileSpec(TEST_PATH("config-doctypes.cfg"))))); + getConfig("config-doctypes", FileSpec("../config-doctypes.cfg")))); _html_type = _repo->getDocumentType("text/html"); createLinks(); } - void tearDown() override { + void TearDown() override { close(); } - void replyToMessage(UpdateOperation& callback, MessageSenderStub& sender, uint32_t index, + void replyToMessage(UpdateOperation& callback, DistributorMessageSenderStub& sender, uint32_t index, uint64_t oldTimestamp, const api::BucketInfo& info = api::BucketInfo(2,4,6)); std::shared_ptr<UpdateOperation> @@ -69,133 +50,116 @@ public: document::BucketId _bId; }; -CPPUNIT_TEST_SUITE_REGISTRATION(UpdateOperation_Test); - std::shared_ptr<UpdateOperation> -UpdateOperation_Test::sendUpdate(const std::string& bucketState) +UpdateOperationTest::sendUpdate(const std::string& bucketState) { - document::DocumentUpdate::SP update( - new document::DocumentUpdate(*_repo, *_html_type, - document::DocumentId(document::DocIdString("test", "test")))); + auto update = std::make_shared<document::DocumentUpdate>( + *_repo, *_html_type, + document::DocumentId(document::DocIdString("test", "test"))); _bId = getExternalOperationHandler().getBucketId(update->getId()); addNodesToBucketDB(_bId, bucketState); - std::shared_ptr<api::UpdateCommand> msg( - new api::UpdateCommand(makeDocumentBucket(document::BucketId(0)), update, 100)); + auto msg = std::make_shared<api::UpdateCommand>(makeDocumentBucket(document::BucketId(0)), update, 100); ExternalOperationHandler& handler = getExternalOperationHandler(); - return std::shared_ptr<UpdateOperation>( - new UpdateOperation(handler, getDistributorBucketSpace(), msg, - getDistributor().getMetrics().updates[msg->getLoadType()])); + return std::make_shared<UpdateOperation>( + handler, getDistributorBucketSpace(), msg, + getDistributor().getMetrics().updates[msg->getLoadType()]); } void -UpdateOperation_Test::replyToMessage(UpdateOperation& callback, MessageSenderStub& sender, uint32_t index, +UpdateOperationTest::replyToMessage(UpdateOperation& callback, DistributorMessageSenderStub& sender, uint32_t index, uint64_t oldTimestamp, const api::BucketInfo& info) { - std::shared_ptr<api::StorageMessage> msg2 = sender.commands[index]; - UpdateCommand* updatec = dynamic_cast<UpdateCommand*>(msg2.get()); + std::shared_ptr<api::StorageMessage> msg2 = sender.command(index); + auto* updatec = dynamic_cast<UpdateCommand*>(msg2.get()); std::unique_ptr<api::StorageReply> reply(updatec->makeReply()); - UpdateReply* updateR = static_cast<api::UpdateReply*>(reply.get()); + auto* updateR = static_cast<api::UpdateReply*>(reply.get()); updateR->setOldTimestamp(oldTimestamp); updateR->setBucketInfo(info); callback.onReceive(sender, std::shared_ptr<StorageReply>(reply.release())); } -void -UpdateOperation_Test::testSimple() -{ +TEST_F(UpdateOperationTest, simple) { setupDistributor(1, 1, "storage:1 distributor:1"); std::shared_ptr<UpdateOperation> cb(sendUpdate("0=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Update => 0"), sender.getCommands(true)); + ASSERT_EQ("Update => 0", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 90); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 100, timestamp of updated doc: 90) ReturnCode(NONE)"), - sender.getLastReply(true)); + ASSERT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 100, timestamp of updated doc: 90) ReturnCode(NONE)", + sender.getLastReply(true)); auto& metrics = getDistributor().getMetrics().updates[documentapi::LoadType::DEFAULT]; - CPPUNIT_ASSERT_EQUAL(UINT64_C(0), metrics.diverging_timestamp_updates.getValue()); + EXPECT_EQ(0, metrics.diverging_timestamp_updates.getValue()); } -void -UpdateOperation_Test::testNotFound() -{ +TEST_F(UpdateOperationTest, not_found) { setupDistributor(1, 1, "storage:1 distributor:1"); std::shared_ptr<UpdateOperation> cb(sendUpdate("0=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Update => 0"), sender.getCommands(true)); + ASSERT_EQ("Update => 0", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 0); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 100, timestamp of updated doc: 0) ReturnCode(NONE)"), - sender.getLastReply(true)); + EXPECT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 100, timestamp of updated doc: 0) ReturnCode(NONE)", + sender.getLastReply(true)); } -void -UpdateOperation_Test::testMultiNode() -{ +TEST_F(UpdateOperationTest, multi_node) { setupDistributor(2, 2, "distributor:1 storage:2"); std::shared_ptr<UpdateOperation> cb(sendUpdate("0=1/2/3,1=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Update => 0,Update => 1"), sender.getCommands(true)); + ASSERT_EQ("Update => 0,Update => 1", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 120); replyToMessage(*cb, sender, 1, 120); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 100, timestamp of updated doc: 120) ReturnCode(NONE)"), - sender.getLastReply(true)); + ASSERT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 100, timestamp of updated doc: 120) ReturnCode(NONE)", + sender.getLastReply(true)); - CPPUNIT_ASSERT_EQUAL( - std::string( - _bId.toString() + " : " - "node(idx=1,crc=0x2,docs=4/4,bytes=6/6,trusted=true,active=false,ready=false), " - "node(idx=0,crc=0x2,docs=4/4,bytes=6/6,trusted=true,active=false,ready=false)"), - dumpBucket(_bId)); + ASSERT_EQ(_bId.toString() + " : " + "node(idx=1,crc=0x2,docs=4/4,bytes=6/6,trusted=true,active=false,ready=false), " + "node(idx=0,crc=0x2,docs=4/4,bytes=6/6,trusted=true,active=false,ready=false)", + dumpBucket(_bId)); auto& metrics = getDistributor().getMetrics().updates[documentapi::LoadType::DEFAULT]; - CPPUNIT_ASSERT_EQUAL(UINT64_C(0), metrics.diverging_timestamp_updates.getValue()); + EXPECT_EQ(0, metrics.diverging_timestamp_updates.getValue()); } -void -UpdateOperation_Test::testMultiNodeInconsistentTimestamp() -{ +TEST_F(UpdateOperationTest, multi_node_inconsistent_timestamp) { setupDistributor(2, 2, "distributor:1 storage:2"); std::shared_ptr<UpdateOperation> cb(sendUpdate("0=1/2/3,1=1/2/3")); - MessageSenderStub sender; + DistributorMessageSenderStub sender; cb->start(sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Update => 0,Update => 1"), sender.getCommands(true)); + ASSERT_EQ("Update => 0,Update => 1", sender.getCommands(true)); replyToMessage(*cb, sender, 0, 119); replyToMessage(*cb, sender, 1, 120); - CPPUNIT_ASSERT_EQUAL( - std::string("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " - "timestamp 100, timestamp of updated doc: 120 Was inconsistent " - "(best node 1)) ReturnCode(NONE)"), - sender.getLastReply(true)); + ASSERT_EQ("UpdateReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 100, timestamp of updated doc: 120 Was inconsistent " + "(best node 1)) ReturnCode(NONE)", + sender.getLastReply(true)); auto& metrics = getDistributor().getMetrics().updates[documentapi::LoadType::DEFAULT]; - CPPUNIT_ASSERT_EQUAL(UINT64_C(1), metrics.diverging_timestamp_updates.getValue()); + EXPECT_EQ(1, metrics.diverging_timestamp_updates.getValue()); } diff --git a/storage/src/tests/distributor/visitoroperationtest.cpp b/storage/src/tests/distributor/visitoroperationtest.cpp index af580480563..7819b0ed5dc 100644 --- a/storage/src/tests/distributor/visitoroperationtest.cpp +++ b/storage/src/tests/distributor/visitoroperationtest.cpp @@ -1,7 +1,4 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <iomanip> -#include <iostream> -#include <memory> #include <vespa/storageapi/message/bucket.h> #include <vespa/storageapi/message/bucketsplitting.h> #include <vespa/storageapi/message/datagram.h> @@ -13,127 +10,36 @@ #include <tests/distributor/distributortestutil.h> #include <vespa/storage/distributor/distributor.h> #include <tests/common/dummystoragelink.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/document/test/make_bucket_space.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> +#include <ostream> using namespace document; using namespace storage::api; using namespace storage::lib; -using namespace std::string_literals; +using namespace ::testing; using document::test::makeBucketSpace; namespace storage::distributor { -class VisitorOperationTest : public CppUnit::TestFixture, - public DistributorTestUtil { - CPPUNIT_TEST_SUITE(VisitorOperationTest); - CPPUNIT_TEST(testParameterForwarding); - CPPUNIT_TEST(testShutdown); - CPPUNIT_TEST(testNoBucket); - CPPUNIT_TEST(testOnlySuperBucketAndProgressAllowed); - CPPUNIT_TEST(testRetiredStorageNode); - CPPUNIT_TEST(testNoResendAfterTimeoutPassed); - CPPUNIT_TEST(testDistributorNotReady); - CPPUNIT_TEST(testInvalidOrderDocSelection); - CPPUNIT_TEST(testNonExistingBucket); - CPPUNIT_TEST(testUserSingleBucket); - CPPUNIT_TEST(testUserInconsistentlySplitBucket); - CPPUNIT_TEST(testBucketRemovedWhileVisitorPending); - CPPUNIT_TEST(testEmptyBucketsVisitedWhenVisitingRemoves); - CPPUNIT_TEST(testResendToOtherStorageNodeOnFailure); - CPPUNIT_TEST(testTimeoutOnlyAfterReplyFromAllStorageNodes); - CPPUNIT_TEST(testTimeoutDoesNotOverrideCriticalError); - CPPUNIT_TEST(testWrongDistribution); - CPPUNIT_TEST(testWrongDistributionInPendingState); - CPPUNIT_TEST(testVisitorAbortedIfNodeIsMarkedAsDown); - CPPUNIT_TEST(testBucketHighBitCount); - CPPUNIT_TEST(testBucketLowBitCount); - CPPUNIT_TEST(testParallelVisitorsToOneStorageNode); - CPPUNIT_TEST(testParallelVisitorsResendOnlyFailing); - CPPUNIT_TEST(testParallelVisitorsToOneStorageNodeOneSuperBucket); - CPPUNIT_TEST(testVisitWhenOneBucketCopyIsInvalid); - CPPUNIT_TEST(testVisitingWhenAllBucketsAreInvalid); - CPPUNIT_TEST(testInconsistencyHandling); - CPPUNIT_TEST(testVisitIdealNode); - CPPUNIT_TEST(testNoResendingOnCriticalFailure); - CPPUNIT_TEST(testFailureOnAllNodes); - CPPUNIT_TEST(testVisitOrder); - CPPUNIT_TEST(testVisitInChunks); - CPPUNIT_TEST(testVisitOrderSplitPastOrderBits); - CPPUNIT_TEST(testVisitOrderInconsistentlySplit); - CPPUNIT_TEST(testUserVisitorOrder); - CPPUNIT_TEST(testUserVisitorOrderSplitPastOrderBits); - CPPUNIT_TEST(testNoClientReplyBeforeAllStorageRepliesReceived); - CPPUNIT_TEST(testSkipFailedSubBucketsWhenVisitingInconsistent); - CPPUNIT_TEST(testQueueTimeoutIsFactorOfTotalTimeout); - CPPUNIT_TEST(metrics_are_updated_with_visitor_statistics_upon_replying); - CPPUNIT_TEST(statistical_metrics_not_updated_on_wrong_distribution); - CPPUNIT_TEST_SUITE_END(); - -protected: - void testParameterForwarding(); - void testShutdown(); - void testNoBucket(); - void testOnlySuperBucketAndProgressAllowed(); - void testRetiredStorageNode(); - void testNoResendAfterTimeoutPassed(); - void testDistributorNotReady(); - void testInvalidOrderDocSelection(); - void testNonExistingBucket(); - void testUserSingleBucket(); - void testUserInconsistentlySplitBucket(); - void testBucketRemovedWhileVisitorPending(); - void testEmptyBucketsVisitedWhenVisitingRemoves(); - void testResendToOtherStorageNodeOnFailure(); - void testTimeoutOnlyAfterReplyFromAllStorageNodes(); - void testTimeoutDoesNotOverrideCriticalError(); - void testAbortNonExisting(); - void testAbort(); - void testWrongDistribution(); - void testWrongDistributionInPendingState(); - void testVisitorAbortedIfNodeIsMarkedAsDown(); - void testBucketHighBitCount(); - void testBucketLowBitCount(); - void testParallelVisitorsToOneStorageNode(); - void testParallelVisitorsResendOnlyFailing(); - void testParallelVisitorsToOneStorageNodeOneSuperBucket(); - void testVisitWhenOneBucketCopyIsInvalid(); - void testVisitingWhenAllBucketsAreInvalid(); - void testInconsistencyHandling(); - void testVisitIdealNode(); - void testNoResendingOnCriticalFailure(); - void testFailureOnAllNodes(); - void testVisitOrder(); - void testVisitInChunks(); - void testVisitOrderSplitPastOrderBits(); - void testVisitOrderInconsistentlySplit(); - void testUserVisitorOrder(); - void testUserVisitorOrderSplitPastOrderBits(); - void testUserVisitorOrderInconsistentlySplit(); - void testNoClientReplyBeforeAllStorageRepliesReceived(); - void testSkipFailedSubBucketsWhenVisitingInconsistent(); - void testQueueTimeoutIsFactorOfTotalTimeout(); - void metrics_are_updated_with_visitor_statistics_upon_replying(); - void statistical_metrics_not_updated_on_wrong_distribution(); -public: +struct VisitorOperationTest : Test, DistributorTestUtil { VisitorOperationTest() : defaultConfig(100, 100) {} - void setUp() override { + void SetUp() override { createLinks(); nullId = document::BucketId(0, 0); - doneId = document::BucketId(INT_MAX); }; - void tearDown() override { + void TearDown() override { close(); } enum {MAX_PENDING = 2}; -private: + document::BucketId nullId; - document::BucketId doneId; VisitorOperation::Config defaultConfig; api::CreateVisitorCommand::SP @@ -149,8 +55,8 @@ private: document::OrderingSpecification::ASCENDING, const std::string& docSelection = "") { - api::CreateVisitorCommand::SP cmd( - new api::CreateVisitorCommand(makeBucketSpace(), libraryName, instanceId, docSelection)); + auto cmd = std::make_shared<api::CreateVisitorCommand>( + makeBucketSpace(), libraryName, instanceId, docSelection); cmd->setControlDestination("controldestination"); cmd->setDataDestination("datadestination"); cmd->setFieldSet("[header]"); @@ -176,13 +82,13 @@ private: std::string serializeVisitorCommand(int idx = -1) { if (idx == -1) { - idx = _sender.commands.size() - 1; + idx = _sender.commands().size() - 1; } std::ostringstream ost; - CreateVisitorCommand* cvc = dynamic_cast<CreateVisitorCommand*>( - _sender.commands[idx].get()); + auto* cvc = dynamic_cast<CreateVisitorCommand*>(_sender.command(idx).get()); + assert(cvc != nullptr); ost << *cvc << " Buckets: [ "; for (uint32_t i = 0; i < cvc->getBuckets().size(); ++i) { @@ -225,9 +131,8 @@ private: } const std::vector<BucketId>& getBucketsFromLastCommand() { - const CreateVisitorCommand& cvc( - dynamic_cast<const CreateVisitorCommand&>( - *_sender.commands[_sender.commands.size() - 1])); + const auto& cvc = dynamic_cast<const CreateVisitorCommand&>( + *_sender.commands().back()); return cvc.getBuckets(); } @@ -236,7 +141,7 @@ private: document::BucketId lastId, uint32_t maxBuckets); - std::string doOrderedVisitor(document::BucketId startBucket); + void doOrderedVisitor(document::BucketId startBucket, std::string& out); void doStandardVisitTest(const std::string& clusterState); @@ -246,11 +151,7 @@ private: void do_visitor_roundtrip_with_statistics(const api::ReturnCode& result); }; -CPPUNIT_TEST_SUITE_REGISTRATION(VisitorOperationTest); - -void -VisitorOperationTest::testParameterForwarding() -{ +TEST_F(VisitorOperationTest, parameter_forwarding) { doStandardVisitTest("distributor:1 storage:1"); } @@ -267,11 +168,8 @@ VisitorOperationTest::doStandardVisitTest(const std::string& clusterState) vespalib::string instanceId("testParameterForwarding"); vespalib::string libraryName("dumpvisitor"); vespalib::string docSelection(""); - api::CreateVisitorCommand::SP msg( - new api::CreateVisitorCommand(makeBucketSpace(), - libraryName, - instanceId, - docSelection)); + auto msg = std::make_shared<api::CreateVisitorCommand>( + makeBucketSpace(), libraryName, instanceId, docSelection); vespalib::string controlDestination("controldestination"); msg->setControlDestination(controlDestination); vespalib::string dataDestination("datadestination"); @@ -291,41 +189,37 @@ VisitorOperationTest::doStandardVisitTest(const std::string& clusterState) op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); // Receive create visitor command for storage and simulate reply - api::StorageMessage::SP rep0 = _sender.commands[0]; - CreateVisitorCommand* cvc = dynamic_cast<CreateVisitorCommand*>(rep0.get()); - CPPUNIT_ASSERT(cvc); - CPPUNIT_ASSERT_EQUAL(libraryName, cvc->getLibraryName()); - CPPUNIT_ASSERT_EQUAL(instanceId, cvc->getInstanceId().substr(0, instanceId.length())); - CPPUNIT_ASSERT_EQUAL(docSelection, cvc->getDocumentSelection()); - CPPUNIT_ASSERT_EQUAL(controlDestination, cvc->getControlDestination()); - CPPUNIT_ASSERT_EQUAL(dataDestination, cvc->getDataDestination()); - CPPUNIT_ASSERT_EQUAL((unsigned int) VisitorOperationTest::MAX_PENDING, cvc->getMaximumPendingReplyCount()); - CPPUNIT_ASSERT_EQUAL((unsigned int) 8, cvc->getMaxBucketsPerVisitor()); - CPPUNIT_ASSERT_EQUAL((size_t) 1, cvc->getBuckets().size()); - CPPUNIT_ASSERT_EQUAL((api::Timestamp) 10, cvc->getFromTime()); - CPPUNIT_ASSERT(cvc->getToTime() > 0); - CPPUNIT_ASSERT_EQUAL(vespalib::string("[header]"), cvc->getFieldSet()); - CPPUNIT_ASSERT_EQUAL((bool) 1, cvc->visitRemoves()); - CPPUNIT_ASSERT_EQUAL(uint32_t(1234), cvc->getTimeout()); - CPPUNIT_ASSERT_EQUAL(uint32_t(7), cvc->getTrace().getLevel()); + api::StorageMessage::SP rep0 = _sender.command(0); + auto* cvc = dynamic_cast<CreateVisitorCommand*>(rep0.get()); + ASSERT_TRUE(cvc != nullptr); + EXPECT_EQ(libraryName, cvc->getLibraryName()); + EXPECT_EQ(instanceId, cvc->getInstanceId().substr(0, instanceId.length())); + EXPECT_EQ(docSelection, cvc->getDocumentSelection()); + EXPECT_EQ(controlDestination, cvc->getControlDestination()); + EXPECT_EQ(dataDestination, cvc->getDataDestination()); + EXPECT_EQ(VisitorOperationTest::MAX_PENDING, cvc->getMaximumPendingReplyCount()); + EXPECT_EQ(8, cvc->getMaxBucketsPerVisitor()); + EXPECT_EQ(1, cvc->getBuckets().size()); + EXPECT_EQ(api::Timestamp(10), cvc->getFromTime()); + EXPECT_GT(cvc->getToTime(), 0); + EXPECT_EQ("[header]", cvc->getFieldSet()); + EXPECT_TRUE(cvc->visitRemoves()); + EXPECT_EQ(1234, cvc->getTimeout()); + EXPECT_EQ(7, cvc->getTrace().getLevel()); sendReply(*op); - CPPUNIT_ASSERT_EQUAL(std::string("CreateVisitorReply(" - "last=BucketId(0x000000007fffffff)) " - "ReturnCode(NONE)"), - _sender.getLastReply()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), defaultVisitorMetrics(). - ok.getLongValue("count")); + ASSERT_EQ("CreateVisitorReply(" + "last=BucketId(0x000000007fffffff)) " + "ReturnCode(NONE)", + _sender.getLastReply()); + EXPECT_EQ(1, defaultVisitorMetrics().ok.getLongValue("count")); } -void -VisitorOperationTest::testShutdown() -{ +TEST_F(VisitorOperationTest, shutdown) { enableDistributorClusterState("distributor:1 storage:1"); // Create bucket in bucketdb @@ -336,11 +230,8 @@ VisitorOperationTest::testShutdown() vespalib::string instanceId("testShutdown"); vespalib::string libraryName("dumpvisitor"); vespalib::string docSelection(""); - api::CreateVisitorCommand::SP msg( - new api::CreateVisitorCommand(makeBucketSpace(), - libraryName, - instanceId, - docSelection)); + auto msg = std::make_shared<api::CreateVisitorCommand>( + makeBucketSpace(), libraryName, instanceId, docSelection); msg->addBucketToBeVisited(id); msg->addBucketToBeVisited(nullId); @@ -348,36 +239,29 @@ VisitorOperationTest::testShutdown() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); op->onClose(_sender); // This will fail the visitor - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(ABORTED, Process is shutting down)"), - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(ABORTED, Process is shutting down)", + _sender.getLastReply()); } -void -VisitorOperationTest::testNoBucket() -{ +TEST_F(VisitorOperationTest, no_bucket) { enableDistributorClusterState("distributor:1 storage:1"); // Send create visitor - api::CreateVisitorCommand::SP msg(new api::CreateVisitorCommand( - makeBucketSpace(), "dumpvisitor", "instance", "")); + auto msg = std::make_shared<api::CreateVisitorCommand>( + makeBucketSpace(), "dumpvisitor", "instance", ""); - CPPUNIT_ASSERT_EQUAL(std::string( - "CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(ILLEGAL_PARAMETERS, No buckets in " - "CreateVisitorCommand for visitor 'instance')"), - runEmptyVisitor(msg)); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(ILLEGAL_PARAMETERS, No buckets in " + "CreateVisitorCommand for visitor 'instance')", + runEmptyVisitor(msg)); } -void -VisitorOperationTest::testOnlySuperBucketAndProgressAllowed() -{ +TEST_F(VisitorOperationTest, only_super_bucket_and_progress_allowed) { enableDistributorClusterState("distributor:1 storage:1"); // Send create visitor @@ -387,23 +271,18 @@ VisitorOperationTest::testOnlySuperBucketAndProgressAllowed() msg->addBucketToBeVisited(nullId); msg->addBucketToBeVisited(nullId); - CPPUNIT_ASSERT_EQUAL(std::string( - "CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(ILLEGAL_PARAMETERS, CreateVisitorCommand " - "does not contain 2 buckets for visitor " - "'instance')"), - runEmptyVisitor(msg)); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(ILLEGAL_PARAMETERS, CreateVisitorCommand " + "does not contain 2 buckets for visitor " + "'instance')", + runEmptyVisitor(msg)); } -void -VisitorOperationTest::testRetiredStorageNode() -{ +TEST_F(VisitorOperationTest, retired_storage_node) { doStandardVisitTest("distributor:1 storage:1 .0.s:r"); } -void -VisitorOperationTest::testNoResendAfterTimeoutPassed() -{ +TEST_F(VisitorOperationTest, no_resend_after_timeout_passed) { document::BucketId id(uint64_t(0x400000000000007b)); enableDistributorClusterState("distributor:1 storage:2"); @@ -414,78 +293,57 @@ VisitorOperationTest::testNoResendAfterTimeoutPassed() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); getClock().addMilliSecondsToTime(22); sendReply(*op, -1, api::ReturnCode::BUSY); - CPPUNIT_ASSERT_EQUAL( - std::string( - "CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(ABORTED, Timeout of 20 ms is running out)"), - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(ABORTED, Timeout of 20 ms is running out)", + _sender.getLastReply()); } -void -VisitorOperationTest::testDistributorNotReady() -{ +TEST_F(VisitorOperationTest, distributor_not_ready) { enableDistributorClusterState("distributor:0 storage:0"); document::BucketId id(uint64_t(0x400000000000007b)); - CPPUNIT_ASSERT_EQUAL( - std::string( - "CreateVisitorReply(last=BucketId(0x0000000000000000)) " + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " "ReturnCode(NODE_NOT_READY, No distributors available when " - "processing visitor 'notready')"), - runEmptyVisitor(createVisitorCommand("notready", id, nullId))); + "processing visitor 'notready')", + runEmptyVisitor(createVisitorCommand("notready", id, nullId))); } // Distributor only parses selection if in the order doc case (which is detected // by first checking if string contains "order" which it must to refer to // "id.order" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -void -VisitorOperationTest::testInvalidOrderDocSelection() -{ +TEST_F(VisitorOperationTest, invalid_order_doc_selection) { enableDistributorClusterState("distributor:1 storage:1"); document::BucketId id(0x400000000000007b); addNodesToBucketDB(id, "0=1/1/1/t"); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(ILLEGAL_PARAMETERS, Failed to parse document select " - "string 'id.order(10,3)=1 and dummy': Document type 'dummy' not " - "found at column 22 when parsing selection 'id.order(10,3)=1 and dummy')"), - runEmptyVisitor( - createVisitorCommand("invalidOrderDoc", - id, - nullId, - 8, - 500, - false, - false, - "dumpvisitor", - document::OrderingSpecification::ASCENDING, - "id.order(10,3)=1 and dummy"))); + auto res = runEmptyVisitor( + createVisitorCommand("invalidOrderDoc", id, nullId, 8, 500, + false, false, "dumpvisitor", + document::OrderingSpecification::ASCENDING, + "id.order(10,3)=1 and dummy")); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(ILLEGAL_PARAMETERS, Failed to parse document select " + "string 'id.order(10,3)=1 and dummy': Document type 'dummy' not " + "found at column 22 when parsing selection 'id.order(10,3)=1 and dummy')", + res); + } -void -VisitorOperationTest::testNonExistingBucket() -{ +TEST_F(VisitorOperationTest, non_existing_bucket) { document::BucketId id(uint64_t(0x400000000000007b)); enableDistributorClusterState("distributor:1 storage:1"); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " - "ReturnCode(NONE)"), - runEmptyVisitor( - createVisitorCommand("nonExistingBucket", - id, - nullId))); + auto res = runEmptyVisitor( + createVisitorCommand("nonExistingBucket", id, nullId)); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " + "ReturnCode(NONE)", res); } -void -VisitorOperationTest::testUserSingleBucket() -{ +TEST_F(VisitorOperationTest, user_single_bucket) { document::BucketId id(uint64_t(0x400000000000007b)); document::BucketId userid(uint64_t(0x800000000000007b)); enableDistributorClusterState("distributor:1 storage:1"); @@ -507,14 +365,11 @@ VisitorOperationTest::testUserSingleBucket() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL_MSG(_sender.getLastReply(), - std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)) << _sender.getLastReply(); sendReply(*op); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " - "ReturnCode(NONE)"), - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " + "ReturnCode(NONE)", + _sender.getLastReply()); } std::pair<std::string, std::string> @@ -546,9 +401,7 @@ VisitorOperationTest::runVisitor(document::BucketId id, return retVal; } -void -VisitorOperationTest::testUserInconsistentlySplitBucket() -{ +TEST_F(VisitorOperationTest, user_inconsistently_split_bucket) { enableDistributorClusterState("distributor:1 storage:1"); // Not containing (19, 0x40001) @@ -575,27 +428,23 @@ VisitorOperationTest::testUserInconsistentlySplitBucket() std::pair<std::string, std::string> val( runVisitor(id, nullId, 100)); - CPPUNIT_ASSERT_EQUAL(std::string( - "CreateVisitorCommand(dumpvisitor, true, 7 buckets) " - "Buckets: [ BucketId(0x4400000000000001) " - "BucketId(0x4800000000000001) " - "BucketId(0x4c00000000040001) " - "BucketId(0x5000000000040001) " - "BucketId(0x5400000000040001) " - "BucketId(0x5400000000140001) " - "BucketId(0x50000000000c0001) ]"), - val.first); - - CPPUNIT_ASSERT_EQUAL(std::string( - "CreateVisitorReply(last=BucketId(0x000000007fffffff)) " - "ReturnCode(NONE)"), - val.second); + EXPECT_EQ("CreateVisitorCommand(dumpvisitor, true, 7 buckets) " + "Buckets: [ BucketId(0x4400000000000001) " + "BucketId(0x4800000000000001) " + "BucketId(0x4c00000000040001) " + "BucketId(0x5000000000040001) " + "BucketId(0x5400000000040001) " + "BucketId(0x5400000000140001) " + "BucketId(0x50000000000c0001) ]", + val.first); + + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " + "ReturnCode(NONE)", + val.second); } } -void -VisitorOperationTest::testBucketRemovedWhileVisitorPending() -{ +TEST_F(VisitorOperationTest, bucket_removed_while_visitor_pending) { enableDistributorClusterState("distributor:1 storage:1"); // Create bucket in bucketdb @@ -608,24 +457,19 @@ VisitorOperationTest::testBucketRemovedWhileVisitorPending() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); removeFromBucketDB(id); sendReply(*op, -1, api::ReturnCode::NOT_CONNECTED); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(BUCKET_NOT_FOUND)"), - _sender.getLastReply()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), defaultVisitorMetrics().failures. - inconsistent_bucket.getLongValue("count")); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(BUCKET_NOT_FOUND)", + _sender.getLastReply()); + EXPECT_EQ(1, defaultVisitorMetrics().failures.inconsistent_bucket.getLongValue("count")); } -void -VisitorOperationTest::testEmptyBucketsVisitedWhenVisitingRemoves() -{ +TEST_F(VisitorOperationTest, empty_buckets_visited_when_visiting_removes) { enableDistributorClusterState("distributor:1 storage:1"); document::BucketId id(uint64_t(0x400000000000007b)); addNodesToBucketDB(id, "0=0/0/0/1/2/t"); @@ -642,13 +486,10 @@ VisitorOperationTest::testEmptyBucketsVisitedWhenVisitingRemoves() op->start(_sender, framework::MilliSecTime(0)); // Since visitRemoves is true, the empty bucket will be visited - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); } -void -VisitorOperationTest::testResendToOtherStorageNodeOnFailure() -{ +TEST_F(VisitorOperationTest, resend_to_other_storage_node_on_failure) { enableDistributorClusterState("distributor:1 storage:2"); document::BucketId id(uint64_t(0x400000000000007b)); @@ -659,23 +500,20 @@ VisitorOperationTest::testResendToOtherStorageNodeOnFailure() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); sendReply(*op, -1, api::ReturnCode::NOT_CONNECTED); - CPPUNIT_ASSERT_EQUAL(""s, _sender.getReplies()); + ASSERT_EQ("", _sender.getReplies()); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0,Visitor Create => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0,Visitor Create => 1", + _sender.getCommands(true)); } // Since MessageBus handles timeouts for us implicitly, we make the assumption // that we can safely wait for all replies to be received before sending a // client reply and that this won't cause things to hang for indeterminate // amounts of time. -void -VisitorOperationTest::testTimeoutOnlyAfterReplyFromAllStorageNodes() -{ +TEST_F(VisitorOperationTest, timeout_only_after_reply_from_all_storage_nodes) { enableDistributorClusterState("distributor:1 storage:2"); // Contained in (16, 0x1) @@ -690,33 +528,30 @@ VisitorOperationTest::testTimeoutOnlyAfterReplyFromAllStorageNodes() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL("Visitor Create => 0,Visitor Create => 1"s, - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0,Visitor Create => 1", + _sender.getCommands(true)); getClock().addMilliSecondsToTime(501); sendReply(*op, 0); - CPPUNIT_ASSERT_EQUAL(""s, _sender.getReplies()); // No reply yet. + ASSERT_EQ("", _sender.getReplies()); // No reply yet. sendReply(*op, 1, api::ReturnCode::BUSY); - CPPUNIT_ASSERT_EQUAL( - "CreateVisitorReply(last=BucketId(0x4400000000000001)) " - "ReturnCode(ABORTED, Timeout of 500 ms is running out)"s, - _sender.getLastReply()); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x4400000000000001)) " + "ReturnCode(ABORTED, Timeout of 500 ms is running out)", + _sender.getLastReply()); // XXX This is sub-optimal in the case that we time out but all storage // visitors return OK, as we'll then be failing an operation that // technically went fine. However, this is assumed to happen sufficiently // rarely (requires timing to be so that mbus timouts don't happen for // neither client -> distributor nor distributor -> storage for the - // operation to possibly could have been considered successful) that we + // operation to possibly have been considered successful) that we // don't bother to add complexity for handling it as a special case. } -void -VisitorOperationTest::testTimeoutDoesNotOverrideCriticalError() -{ +TEST_F(VisitorOperationTest, timeout_does_not_override_critical_error) { enableDistributorClusterState("distributor:1 storage:2"); addNodesToBucketDB(document::BucketId(17, 0x00001), "0=1/1/1/t"); addNodesToBucketDB(document::BucketId(17, 0x10001), "1=1/1/1/t"); @@ -729,41 +564,33 @@ VisitorOperationTest::testTimeoutDoesNotOverrideCriticalError() 500)); // ms timeout op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL("Visitor Create => 0,Visitor Create => 1"s, - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0,Visitor Create => 1", + _sender.getCommands(true)); getClock().addMilliSecondsToTime(501); // Technically has timed out at this point, but should still report the // critical failure. sendReply(*op, 0, api::ReturnCode::INTERNAL_FAILURE); - CPPUNIT_ASSERT_EQUAL(""s, _sender.getReplies()); + ASSERT_EQ("", _sender.getReplies()); sendReply(*op, 1, api::ReturnCode::BUSY); - CPPUNIT_ASSERT_EQUAL( - "CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(INTERNAL_FAILURE, [from content node 0] )"s, - _sender.getLastReply()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), defaultVisitorMetrics().failures. - storagefailure.getLongValue("count")); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(INTERNAL_FAILURE, [from content node 0] )", + _sender.getLastReply()); + EXPECT_EQ(1, defaultVisitorMetrics().failures.storagefailure.getLongValue("count")); } -void -VisitorOperationTest::testWrongDistribution() -{ +TEST_F(VisitorOperationTest, wrong_distribution) { setupDistributor(1, 100, "distributor:100 storage:2"); document::BucketId id(uint64_t(0x400000000000127b)); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(WRONG_DISTRIBUTION, distributor:100 storage:2)"), - runEmptyVisitor(createVisitorCommand("wrongdist", id, nullId))); - CPPUNIT_ASSERT_EQUAL(int64_t(1), defaultVisitorMetrics().failures. - wrongdistributor.getLongValue("count")); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(WRONG_DISTRIBUTION, distributor:100 storage:2)", + runEmptyVisitor(createVisitorCommand("wrongdist", id, nullId))); + EXPECT_EQ(1, defaultVisitorMetrics().failures.wrongdistributor.getLongValue("count")); } -void -VisitorOperationTest::testWrongDistributionInPendingState() -{ +TEST_F(VisitorOperationTest, wrong_distribution_in_pending_state) { // Force bucket to belong to this distributor in currently enabled state. setupDistributor(1, 100, "distributor:1 storage:2"); // Trigger pending cluster state. Note: increase in storage node count @@ -773,10 +600,9 @@ VisitorOperationTest::testWrongDistributionInPendingState() getBucketDBUpdater().onSetSystemState(stateCmd); document::BucketId id(uint64_t(0x400000000000127b)); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(WRONG_DISTRIBUTION, distributor:100 storage:3)"), - runEmptyVisitor(createVisitorCommand("wrongdistpending", id, nullId))); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(WRONG_DISTRIBUTION, distributor:100 storage:3)", + runEmptyVisitor(createVisitorCommand("wrongdistpending", id, nullId))); } // If the current node state changes, this alters the node's cluster state @@ -784,30 +610,24 @@ VisitorOperationTest::testWrongDistributionInPendingState() // we cannot answer with WRONG_DISTRIBUTION as the client expects to see a // higher version number. // See ticket 6353382 for details. -void -VisitorOperationTest::testVisitorAbortedIfNodeIsMarkedAsDown() -{ +TEST_F(VisitorOperationTest, visitor_aborted_if_node_is_marked_as_down) { setupDistributor(1, 10, "distributor:10 .0.s:s storage:10"); document::BucketId id(uint64_t(0x400000000000127b)); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(ABORTED, Distributor is shutting down)"), - runEmptyVisitor(createVisitorCommand("wrongdist", id, nullId))); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(ABORTED, Distributor is shutting down)", + runEmptyVisitor(createVisitorCommand("wrongdist", id, nullId))); } -void -VisitorOperationTest::testBucketHighBitCount() -{ +TEST_F(VisitorOperationTest, bucket_high_bit_count) { enableDistributorClusterState("distributor:1 storage:1 bits:16"); document::BucketId id(18, 0x0); addNodesToBucketDB(id, "0=1/1/1/t"); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(WRONG_DISTRIBUTION, distributor:1 storage:1)"), - runEmptyVisitor(createVisitorCommand("buckethigbit", id, nullId))); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(WRONG_DISTRIBUTION, distributor:1 storage:1)", + runEmptyVisitor(createVisitorCommand("buckethigbit", id, nullId))); auto op = createOpWithDefaultConfig( createVisitorCommand("buckethighbitcount", @@ -823,22 +643,18 @@ VisitorOperationTest::testBucketHighBitCount() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + EXPECT_EQ("Visitor Create => 0", _sender.getCommands(true)); } -void -VisitorOperationTest::testBucketLowBitCount() -{ +TEST_F(VisitorOperationTest, bucket_low_bit_count) { enableDistributorClusterState("distributor:1 storage:1 bits:16"); document::BucketId id(1, 0x0); addNodesToBucketDB(id, "0=1/1/1/t"); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(WRONG_DISTRIBUTION, distributor:1 storage:1)"), - runEmptyVisitor(createVisitorCommand("bucketlowbit", id, nullId))); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(WRONG_DISTRIBUTION, distributor:1 storage:1)", + runEmptyVisitor(createVisitorCommand("bucketlowbit", id, nullId))); auto op = createOpWithDefaultConfig( createVisitorCommand("buckethighbitcount", @@ -853,15 +669,12 @@ VisitorOperationTest::testBucketLowBitCount() "true")); op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(WRONG_DISTRIBUTION, distributor:1 storage:1)"), - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(WRONG_DISTRIBUTION, distributor:1 storage:1)", + _sender.getLastReply()); } -void -VisitorOperationTest::testParallelVisitorsToOneStorageNode() -{ +TEST_F(VisitorOperationTest, parallel_visitors_to_one_storage_node) { enableDistributorClusterState("distributor:1 storage:1"); // Create buckets in bucketdb @@ -878,47 +691,42 @@ VisitorOperationTest::testParallelVisitorsToOneStorageNode() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0,Visitor Create => 0," - "Visitor Create => 0,Visitor Create => 0"), - _sender.getCommands(true)); - - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorCommand(dumpvisitor, , 8 buckets) Buckets: [ " - "BucketId(0x5400000000000001) BucketId(0x5400000000040001) " - "BucketId(0x5400000000020001) BucketId(0x5400000000060001) " - "BucketId(0x5400000000010001) BucketId(0x5400000000050001) " - "BucketId(0x5400000000030001) BucketId(0x5400000000070001) ]"), - serializeVisitorCommand(0)); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorCommand(dumpvisitor, , 8 buckets) Buckets: [ " - "BucketId(0x5400000000100001) BucketId(0x5400000000140001) " - "BucketId(0x5400000000120001) BucketId(0x5400000000160001) " - "BucketId(0x5400000000110001) BucketId(0x5400000000150001) " - "BucketId(0x5400000000130001) BucketId(0x5400000000170001) ]"), - serializeVisitorCommand(1)); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorCommand(dumpvisitor, , 8 buckets) Buckets: [ " - "BucketId(0x5400000000080001) BucketId(0x54000000000c0001) " - "BucketId(0x54000000000a0001) BucketId(0x54000000000e0001) " - "BucketId(0x5400000000090001) BucketId(0x54000000000d0001) " - "BucketId(0x54000000000b0001) BucketId(0x54000000000f0001) ]"), - serializeVisitorCommand(2)); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorCommand(dumpvisitor, , 7 buckets) Buckets: [ " - "BucketId(0x5400000000180001) BucketId(0x54000000001c0001) " - "BucketId(0x54000000001a0001) BucketId(0x54000000001e0001) " - "BucketId(0x5400000000190001) BucketId(0x54000000001d0001) " - "BucketId(0x54000000001b0001) ]"), - serializeVisitorCommand(3)); + ASSERT_EQ("Visitor Create => 0,Visitor Create => 0," + "Visitor Create => 0,Visitor Create => 0", + _sender.getCommands(true)); + + ASSERT_EQ("CreateVisitorCommand(dumpvisitor, , 8 buckets) Buckets: [ " + "BucketId(0x5400000000000001) BucketId(0x5400000000040001) " + "BucketId(0x5400000000020001) BucketId(0x5400000000060001) " + "BucketId(0x5400000000010001) BucketId(0x5400000000050001) " + "BucketId(0x5400000000030001) BucketId(0x5400000000070001) ]", + serializeVisitorCommand(0)); + ASSERT_EQ("CreateVisitorCommand(dumpvisitor, , 8 buckets) Buckets: [ " + "BucketId(0x5400000000100001) BucketId(0x5400000000140001) " + "BucketId(0x5400000000120001) BucketId(0x5400000000160001) " + "BucketId(0x5400000000110001) BucketId(0x5400000000150001) " + "BucketId(0x5400000000130001) BucketId(0x5400000000170001) ]", + serializeVisitorCommand(1)); + ASSERT_EQ("CreateVisitorCommand(dumpvisitor, , 8 buckets) Buckets: [ " + "BucketId(0x5400000000080001) BucketId(0x54000000000c0001) " + "BucketId(0x54000000000a0001) BucketId(0x54000000000e0001) " + "BucketId(0x5400000000090001) BucketId(0x54000000000d0001) " + "BucketId(0x54000000000b0001) BucketId(0x54000000000f0001) ]", + serializeVisitorCommand(2)); + ASSERT_EQ("CreateVisitorCommand(dumpvisitor, , 7 buckets) Buckets: [ " + "BucketId(0x5400000000180001) BucketId(0x54000000001c0001) " + "BucketId(0x54000000001a0001) BucketId(0x54000000001e0001) " + "BucketId(0x5400000000190001) BucketId(0x54000000001d0001) " + "BucketId(0x54000000001b0001) ]", + serializeVisitorCommand(3)); for (uint32_t i = 0; i < 4; ++i) { sendReply(*op, i); } - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x54000000000f0001)) " - "ReturnCode(NONE)"), - _sender.getLastReply()); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x54000000000f0001)) " + "ReturnCode(NONE)", + _sender.getLastReply()); _sender.clear(); @@ -930,20 +738,16 @@ VisitorOperationTest::testParallelVisitorsToOneStorageNode() op2->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); sendReply(*op2); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " - "ReturnCode(NONE)"), - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " + "ReturnCode(NONE)", + _sender.getLastReply()); } -void -VisitorOperationTest::testParallelVisitorsResendOnlyFailing() -{ +TEST_F(VisitorOperationTest, parallel_visitors_resend_only_failing) { enableDistributorClusterState("distributor:1 storage:2"); // Create buckets in bucketdb @@ -962,32 +766,29 @@ VisitorOperationTest::testParallelVisitorsResendOnlyFailing() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0,Visitor Create => 0," - "Visitor Create => 0,Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0,Visitor Create => 0," + "Visitor Create => 0,Visitor Create => 0", + _sender.getCommands(true)); for (uint32_t i = 0; i < 2; ++i) { sendReply(*op, i, api::ReturnCode::NOT_CONNECTED); } - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0,Visitor Create => 0," - "Visitor Create => 0,Visitor Create => 0," - "Visitor Create => 1,Visitor Create => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0,Visitor Create => 0," + "Visitor Create => 0,Visitor Create => 0," + "Visitor Create => 1,Visitor Create => 1", + _sender.getCommands(true)); for (uint32_t i = 2; i < 6; ++i) { sendReply(*op, i); } - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x54000000000f0001)) " - "ReturnCode(NONE)"), - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x54000000000f0001)) " + "ReturnCode(NONE)", + _sender.getLastReply()); } -void -VisitorOperationTest::testParallelVisitorsToOneStorageNodeOneSuperBucket() -{ +TEST_F(VisitorOperationTest, parallel_visitors_to_one_storage_node_one_super_bucket) { enableDistributorClusterState("distributor:1 storage:1"); // Create buckets in bucketdb @@ -1004,74 +805,56 @@ VisitorOperationTest::testParallelVisitorsToOneStorageNodeOneSuperBucket() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorCommand(dumpvisitor, , 8 buckets) Buckets: [ " - "BucketId(0x8c000000e3362b6a) BucketId(0x8c000004e3362b6a) " - "BucketId(0x8c000002e3362b6a) BucketId(0x8c000006e3362b6a) " - "BucketId(0x8c000001e3362b6a) BucketId(0x8c000005e3362b6a) " - "BucketId(0x8c000003e3362b6a) BucketId(0x8c000007e3362b6a) ]"), - serializeVisitorCommand(0)); + ASSERT_EQ("CreateVisitorCommand(dumpvisitor, , 8 buckets) Buckets: [ " + "BucketId(0x8c000000e3362b6a) BucketId(0x8c000004e3362b6a) " + "BucketId(0x8c000002e3362b6a) BucketId(0x8c000006e3362b6a) " + "BucketId(0x8c000001e3362b6a) BucketId(0x8c000005e3362b6a) " + "BucketId(0x8c000003e3362b6a) BucketId(0x8c000007e3362b6a) ]", + serializeVisitorCommand(0)); sendReply(*op); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " - "ReturnCode(NONE)"), - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " + "ReturnCode(NONE)", + _sender.getLastReply()); } -void -VisitorOperationTest::testVisitWhenOneBucketCopyIsInvalid() -{ +TEST_F(VisitorOperationTest, visit_when_one_bucket_copy_is_invalid) { enableDistributorClusterState("distributor:1 storage:2"); document::BucketId id(16, 0); addNodesToBucketDB(id, "0=100,1=0/0/1"); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(BUCKET_NOT_FOUND)"), - runEmptyVisitor(createVisitorCommand("incompletehandling", - id, - nullId))); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(BUCKET_NOT_FOUND)", + runEmptyVisitor(createVisitorCommand("incompletehandling", id, nullId))); } -void -VisitorOperationTest::testVisitingWhenAllBucketsAreInvalid() -{ +TEST_F(VisitorOperationTest, visiting_when_all_buckets_are_invalid) { enableDistributorClusterState("distributor:1 storage:2"); document::BucketId id(16, 0); addNodesToBucketDB(id, "0=0/0/1,1=0/0/1"); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(BUCKET_NOT_FOUND)"), - runEmptyVisitor(createVisitorCommand("allincompletehandling", - id, - nullId))); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(BUCKET_NOT_FOUND)", + runEmptyVisitor(createVisitorCommand("allincompletehandling", id, nullId))); } -void -VisitorOperationTest::testInconsistencyHandling() -{ +TEST_F(VisitorOperationTest, inconsistency_handling) { enableDistributorClusterState("distributor:1 storage:2"); document::BucketId id(16, 0); addNodesToBucketDB(id, "0=1/1/1,1=2/2/2"); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(BUCKET_NOT_FOUND)"), - runEmptyVisitor(createVisitorCommand("testinconsistencyhandling", - id, - nullId))); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(BUCKET_NOT_FOUND)", + runEmptyVisitor(createVisitorCommand("testinconsistencyhandling", id, nullId))); _sender.clear(); auto op = createOpWithConfig( @@ -1080,20 +863,16 @@ VisitorOperationTest::testInconsistencyHandling() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 1", _sender.getCommands(true)); sendReply(*op); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " - "ReturnCode(NONE)"), - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " + "ReturnCode(NONE)", + _sender.getLastReply()); } -void -VisitorOperationTest::testVisitIdealNode() -{ +TEST_F(VisitorOperationTest, visit_ideal_node) { ClusterState state("distributor:1 storage:3"); _distributor->enableClusterStateBundle(lib::ClusterStateBundle(state)); @@ -1109,28 +888,23 @@ VisitorOperationTest::testVisitIdealNode() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorCommand(dumpvisitor, , 8 buckets) Buckets: [ " - "BucketId(0x5400000000000001) BucketId(0x5400000000100001) " - "BucketId(0x5400000000080001) BucketId(0x5400000000180001) " - "BucketId(0x5400000000040001) BucketId(0x5400000000140001) " - "BucketId(0x54000000000c0001) BucketId(0x54000000001c0001) ]"), - serializeVisitorCommand(0)); + ASSERT_EQ("CreateVisitorCommand(dumpvisitor, , 8 buckets) Buckets: [ " + "BucketId(0x5400000000000001) BucketId(0x5400000000100001) " + "BucketId(0x5400000000080001) BucketId(0x5400000000180001) " + "BucketId(0x5400000000040001) BucketId(0x5400000000140001) " + "BucketId(0x54000000000c0001) BucketId(0x54000000001c0001) ]", + serializeVisitorCommand(0)); sendReply(*op); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x54000000001c0001)) " - "ReturnCode(NONE)"), - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x54000000001c0001)) " + "ReturnCode(NONE)", + _sender.getLastReply()); } -void -VisitorOperationTest::testNoResendingOnCriticalFailure() -{ +TEST_F(VisitorOperationTest, no_resending_on_critical_failure) { enableDistributorClusterState("distributor:1 storage:3"); // Create buckets in bucketdb @@ -1145,20 +919,16 @@ VisitorOperationTest::testNoResendingOnCriticalFailure() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); sendReply(*op, -1, api::ReturnCode::ILLEGAL_PARAMETERS); - CPPUNIT_ASSERT_EQUAL( - "CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(ILLEGAL_PARAMETERS, [from content node 0] )"s, - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(ILLEGAL_PARAMETERS, [from content node 0] )", + _sender.getLastReply()); } -void -VisitorOperationTest::testFailureOnAllNodes() -{ +TEST_F(VisitorOperationTest, failure_on_all_nodes) { enableDistributorClusterState("distributor:1 storage:3"); // Create buckets in bucketdb @@ -1173,29 +943,23 @@ VisitorOperationTest::testFailureOnAllNodes() op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); sendReply(*op, -1, api::ReturnCode::NOT_CONNECTED); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0,Visitor Create => 1"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0,Visitor Create => 1", _sender.getCommands(true)); sendReply(*op, -1, api::ReturnCode::NOT_CONNECTED); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(BUCKET_NOT_FOUND)"), - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(BUCKET_NOT_FOUND)", + _sender.getLastReply()); // TODO it'd be much more accurate to increase the "notconnected" metric // here, but our metrics are currently based on the reply sent back to the // client, not the ones sent from the content nodes to the distributor. } - -void -VisitorOperationTest::testVisitOrder() -{ +TEST_F(VisitorOperationTest, visit_order) { std::vector<document::BucketId> buckets; document::BucketId id000(35, 0x0000004d2); @@ -1211,43 +975,28 @@ VisitorOperationTest::testVisitOrder() buckets.end(), VisitorOrder(document::OrderingSpecification( document::OrderingSpecification::ASCENDING, 0x0, 6, 2))); - - CPPUNIT_ASSERT_EQUAL(buckets[0], id000); - CPPUNIT_ASSERT_EQUAL(buckets[1], id001); - CPPUNIT_ASSERT_EQUAL(buckets[2], id01); - CPPUNIT_ASSERT_EQUAL(buckets[3], id1); + EXPECT_THAT(buckets, ElementsAre(id000, id001, id01, id1)); std::sort(buckets.begin(), buckets.end(), VisitorOrder(document::OrderingSpecification( document::OrderingSpecification::DESCENDING, 0xFF, 6, 2))); - CPPUNIT_ASSERT_EQUAL(buckets[0], id1); - CPPUNIT_ASSERT_EQUAL(buckets[1], id01); - CPPUNIT_ASSERT_EQUAL(buckets[2], id001); - CPPUNIT_ASSERT_EQUAL(buckets[3], id000); + EXPECT_THAT(buckets, ElementsAre(id1, id01, id001, id000)); std::sort(buckets.begin(), buckets.end(), VisitorOrder(document::OrderingSpecification( document::OrderingSpecification::ASCENDING, 0x14, 6, 2))); - CPPUNIT_ASSERT_EQUAL(buckets[0], id01); - CPPUNIT_ASSERT_EQUAL(buckets[1], id1); - CPPUNIT_ASSERT_EQUAL(buckets[2], id000); - CPPUNIT_ASSERT_EQUAL(buckets[3], id001); + EXPECT_THAT(buckets, ElementsAre(id01, id1, id000, id001)); std::sort(buckets.begin(), buckets.end(), VisitorOrder(document::OrderingSpecification( document::OrderingSpecification::DESCENDING, 0x14, 6, 2))); - CPPUNIT_ASSERT_EQUAL(buckets[0], id01); - CPPUNIT_ASSERT_EQUAL(buckets[1], id001); - CPPUNIT_ASSERT_EQUAL(buckets[2], id000); - CPPUNIT_ASSERT_EQUAL(buckets[3], id1); + EXPECT_THAT(buckets, ElementsAre(id01, id001, id000, id1)); } -void -VisitorOperationTest::testVisitInChunks() -{ +TEST_F(VisitorOperationTest, visit_in_chunks) { enableDistributorClusterState("distributor:1 storage:1"); for (int i = 0; i < 9; ++i) { @@ -1257,48 +1006,40 @@ VisitorOperationTest::testVisitInChunks() document::BucketId id(16, 0); std::pair<std::string, std::string> val(runVisitor(id, nullId, 3)); - CPPUNIT_ASSERT_EQUAL(std::string( - "CreateVisitorCommand(dumpvisitor, true, 3 buckets) " - "Buckets: [ BucketId(0x7800000000000000) " - "BucketId(0x7800000000080000) " - "BucketId(0x7800000000040000) ]"), - val.first); - - CPPUNIT_ASSERT_EQUAL(std::string( - "CreateVisitorReply(last=BucketId(0x7800000000040000)) " - "ReturnCode(NONE)"), - val.second); + EXPECT_EQ("CreateVisitorCommand(dumpvisitor, true, 3 buckets) " + "Buckets: [ BucketId(0x7800000000000000) " + "BucketId(0x7800000000080000) " + "BucketId(0x7800000000040000) ]", + val.first); + + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x7800000000040000)) " + "ReturnCode(NONE)", + val.second); val = runVisitor(id, document::BucketId(0x7800000000040000), 3); - CPPUNIT_ASSERT_EQUAL(std::string( - "CreateVisitorCommand(dumpvisitor, true, 3 buckets) " - "Buckets: [ BucketId(0x7800000000020000) " - "BucketId(0x7800000000060000) " - "BucketId(0x7800000000010000) ]"), - val.first); - - CPPUNIT_ASSERT_EQUAL(std::string( - "CreateVisitorReply(last=BucketId(0x7800000000010000)) " - "ReturnCode(NONE)"), - val.second); + EXPECT_EQ("CreateVisitorCommand(dumpvisitor, true, 3 buckets) " + "Buckets: [ BucketId(0x7800000000020000) " + "BucketId(0x7800000000060000) " + "BucketId(0x7800000000010000) ]", + val.first); + + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x7800000000010000)) " + "ReturnCode(NONE)", + val.second); val = runVisitor(id, document::BucketId(0x7800000000010000), 3); - CPPUNIT_ASSERT_EQUAL(std::string( - "CreateVisitorCommand(dumpvisitor, true, 3 buckets) " - "Buckets: [ BucketId(0x7800000000050000) " - "BucketId(0x7800000000030000) " - "BucketId(0x7800000000070000) ]"), - val.first); - - CPPUNIT_ASSERT_EQUAL(std::string( - "CreateVisitorReply(last=BucketId(0x000000007fffffff)) " - "ReturnCode(NONE)"), - val.second); + EXPECT_EQ("CreateVisitorCommand(dumpvisitor, true, 3 buckets) " + "Buckets: [ BucketId(0x7800000000050000) " + "BucketId(0x7800000000030000) " + "BucketId(0x7800000000070000) ]", + val.first); + + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " + "ReturnCode(NONE)", + val.second); } -void -VisitorOperationTest::testVisitOrderSplitPastOrderBits() -{ +TEST_F(VisitorOperationTest, visit_order_split_past_order_bits) { std::vector<document::BucketId> buckets; document::BucketId max(INT_MAX); @@ -1316,46 +1057,24 @@ VisitorOperationTest::testVisitOrderSplitPastOrderBits() document::BucketId null(0, 0); buckets.push_back(null); - std::sort(buckets.begin(), buckets.end(), VisitorOrder(document::OrderingSpecification(document::OrderingSpecification::ASCENDING, 0x0, 6, 2))); - CPPUNIT_ASSERT_EQUAL(buckets[0], null); - CPPUNIT_ASSERT_EQUAL(buckets[1], id0000); - CPPUNIT_ASSERT_EQUAL(buckets[2], id00000); - CPPUNIT_ASSERT_EQUAL(buckets[3], id00001); - CPPUNIT_ASSERT_EQUAL(buckets[4], id01); - CPPUNIT_ASSERT_EQUAL(buckets[5], id1); - CPPUNIT_ASSERT_EQUAL(buckets[6], max); - - std::sort(buckets.begin(), buckets.end(), VisitorOrder(document::OrderingSpecification(document::OrderingSpecification::DESCENDING, 0xFF, 6, 2))); - CPPUNIT_ASSERT_EQUAL(buckets[0], null); - CPPUNIT_ASSERT_EQUAL(buckets[1], id1); - CPPUNIT_ASSERT_EQUAL(buckets[2], id01); - CPPUNIT_ASSERT_EQUAL(buckets[3], id0000); - CPPUNIT_ASSERT_EQUAL(buckets[4], id00000); - CPPUNIT_ASSERT_EQUAL(buckets[5], id00001); - CPPUNIT_ASSERT_EQUAL(buckets[6], max); - - std::sort(buckets.begin(), buckets.end(), VisitorOrder(document::OrderingSpecification(document::OrderingSpecification::ASCENDING, 0x14, 6, 2))); - CPPUNIT_ASSERT_EQUAL(buckets[0], null); - CPPUNIT_ASSERT_EQUAL(buckets[1], id01); - CPPUNIT_ASSERT_EQUAL(buckets[2], id1); - CPPUNIT_ASSERT_EQUAL(buckets[3], id0000); - CPPUNIT_ASSERT_EQUAL(buckets[4], id00000); - CPPUNIT_ASSERT_EQUAL(buckets[5], id00001); - CPPUNIT_ASSERT_EQUAL(buckets[6], max); - - std::sort(buckets.begin(), buckets.end(), VisitorOrder(document::OrderingSpecification(document::OrderingSpecification::DESCENDING, 0x14, 6, 2))); - CPPUNIT_ASSERT_EQUAL(buckets[0], null); - CPPUNIT_ASSERT_EQUAL(buckets[1], id01); - CPPUNIT_ASSERT_EQUAL(buckets[2], id0000); - CPPUNIT_ASSERT_EQUAL(buckets[3], id00000); - CPPUNIT_ASSERT_EQUAL(buckets[4], id00001); - CPPUNIT_ASSERT_EQUAL(buckets[5], id1); - CPPUNIT_ASSERT_EQUAL(buckets[6], max); + std::sort(buckets.begin(), buckets.end(), VisitorOrder( + document::OrderingSpecification(document::OrderingSpecification::ASCENDING, 0x0, 6, 2))); + EXPECT_THAT(buckets, ElementsAre(null, id0000, id00000, id00001, id01, id1, max)); + + std::sort(buckets.begin(), buckets.end(), VisitorOrder( + document::OrderingSpecification(document::OrderingSpecification::DESCENDING, 0xFF, 6, 2))); + EXPECT_THAT(buckets, ElementsAre(null, id1, id01, id0000, id00000, id00001, max)); + + std::sort(buckets.begin(), buckets.end(), VisitorOrder( + document::OrderingSpecification(document::OrderingSpecification::ASCENDING, 0x14, 6, 2))); + EXPECT_THAT(buckets, ElementsAre(null, id01, id1, id0000, id00000, id00001, max)); + + std::sort(buckets.begin(), buckets.end(), VisitorOrder( + document::OrderingSpecification(document::OrderingSpecification::DESCENDING, 0x14, 6, 2))); + EXPECT_THAT(buckets, ElementsAre(null, id01, id0000, id00000, id00001, id1, max)); } -void -VisitorOperationTest::testVisitOrderInconsistentlySplit() -{ +TEST_F(VisitorOperationTest, visit_order_inconsistently_split) { std::vector<document::BucketId> buckets; document::BucketId max(INT_MAX); @@ -1373,45 +1092,25 @@ VisitorOperationTest::testVisitOrderInconsistentlySplit() document::BucketId null(0, 0); buckets.push_back(null); - std::sort(buckets.begin(), buckets.end(), VisitorOrder(document::OrderingSpecification(document::OrderingSpecification::ASCENDING, 0x0, 6, 2))); - CPPUNIT_ASSERT_EQUAL(buckets[0], null); - CPPUNIT_ASSERT_EQUAL(buckets[1], idsuper); - CPPUNIT_ASSERT_EQUAL(buckets[2], id000); - CPPUNIT_ASSERT_EQUAL(buckets[3], id001); - CPPUNIT_ASSERT_EQUAL(buckets[4], id01); - CPPUNIT_ASSERT_EQUAL(buckets[5], id1); - CPPUNIT_ASSERT_EQUAL(buckets[6], max); - - std::sort(buckets.begin(), buckets.end(), VisitorOrder(document::OrderingSpecification(document::OrderingSpecification::DESCENDING, 0xFF, 6, 2))); - CPPUNIT_ASSERT_EQUAL(buckets[0], null); - CPPUNIT_ASSERT_EQUAL(buckets[1], idsuper); - CPPUNIT_ASSERT_EQUAL(buckets[2], id1); - CPPUNIT_ASSERT_EQUAL(buckets[3], id01); - CPPUNIT_ASSERT_EQUAL(buckets[4], id001); - CPPUNIT_ASSERT_EQUAL(buckets[5], id000); - CPPUNIT_ASSERT_EQUAL(buckets[6], max); - - std::sort(buckets.begin(), buckets.end(), VisitorOrder(document::OrderingSpecification(document::OrderingSpecification::ASCENDING, 0x14, 6, 2))); - CPPUNIT_ASSERT_EQUAL(buckets[0], null); - CPPUNIT_ASSERT_EQUAL(buckets[1], idsuper); - CPPUNIT_ASSERT_EQUAL(buckets[2], id01); - CPPUNIT_ASSERT_EQUAL(buckets[3], id1); - CPPUNIT_ASSERT_EQUAL(buckets[4], id000); - CPPUNIT_ASSERT_EQUAL(buckets[5], id001); - CPPUNIT_ASSERT_EQUAL(buckets[6], max); - - std::sort(buckets.begin(), buckets.end(), VisitorOrder(document::OrderingSpecification(document::OrderingSpecification::DESCENDING, 0x14, 6, 2))); - CPPUNIT_ASSERT_EQUAL(buckets[0], null); - CPPUNIT_ASSERT_EQUAL(buckets[1], idsuper); - CPPUNIT_ASSERT_EQUAL(buckets[2], id01); - CPPUNIT_ASSERT_EQUAL(buckets[3], id001); - CPPUNIT_ASSERT_EQUAL(buckets[4], id000); - CPPUNIT_ASSERT_EQUAL(buckets[5], id1); - CPPUNIT_ASSERT_EQUAL(buckets[6], max); + std::sort(buckets.begin(), buckets.end(), VisitorOrder( + document::OrderingSpecification(document::OrderingSpecification::ASCENDING, 0x0, 6, 2))); + EXPECT_THAT(buckets, ElementsAre(null, idsuper, id000, id001, id01, id1, max)); + + std::sort(buckets.begin(), buckets.end(), VisitorOrder( + document::OrderingSpecification(document::OrderingSpecification::DESCENDING, 0xFF, 6, 2))); + EXPECT_THAT(buckets, ElementsAre(null, idsuper, id1, id01, id001, id000, max)); + + std::sort(buckets.begin(), buckets.end(), VisitorOrder( + document::OrderingSpecification(document::OrderingSpecification::ASCENDING, 0x14, 6, 2))); + EXPECT_THAT(buckets, ElementsAre(null, idsuper, id01, id1, id000, id001, max)); + + std::sort(buckets.begin(), buckets.end(), VisitorOrder( + document::OrderingSpecification(document::OrderingSpecification::DESCENDING, 0x14, 6, 2))); + EXPECT_THAT(buckets, ElementsAre(null, idsuper, id01, id001, id000, id1, max)); } -std::string -VisitorOperationTest::doOrderedVisitor(document::BucketId startBucket) +void +VisitorOperationTest::doOrderedVisitor(document::BucketId startBucket, std::string& out) { std::vector<document::BucketId> buckets; @@ -1434,13 +1133,12 @@ VisitorOperationTest::doOrderedVisitor(document::BucketId startBucket) op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); - for (uint32_t i = 0; i < _sender.commands.size(); ++i) { + for (uint32_t i = 0; i < _sender.commands().size(); ++i) { const api::CreateVisitorCommand cmd( static_cast<const api::CreateVisitorCommand&>( - *_sender.commands[i])); + *_sender.command(i))); for (uint32_t j = 0; j < cmd.getBuckets().size(); ++j) { buckets.push_back(cmd.getBuckets()[j]); @@ -1449,10 +1147,9 @@ VisitorOperationTest::doOrderedVisitor(document::BucketId startBucket) sendReply(*op); - CPPUNIT_ASSERT_EQUAL(1, (int)_sender.replies.size()); + ASSERT_EQ(1, _sender.replies().size()); - const api::CreateVisitorReply& reply( - static_cast<const api::CreateVisitorReply&>(*_sender.replies[0])); + auto& reply = dynamic_cast<const api::CreateVisitorReply&>(*_sender.reply(0)); if (reply.getLastBucket() == document::BucketId(0x000000007fffffff)) { break; @@ -1464,12 +1161,10 @@ VisitorOperationTest::doOrderedVisitor(document::BucketId startBucket) ost << buckets[i] << "\n"; } - return ost.str(); + out = ost.str(); } -void -VisitorOperationTest::testUserVisitorOrder() -{ +TEST_F(VisitorOperationTest, user_visitor_order) { enableDistributorClusterState("distributor:1 storage:1"); // Create buckets in bucketdb @@ -1489,16 +1184,16 @@ VisitorOperationTest::testUserVisitorOrder() document::BucketId id(16, 0x04d2); - CPPUNIT_ASSERT_EQUAL(std::string("BucketId(0x88000002000004d2)\n" - "BucketId(0x8c000004000004d2)\n" - "BucketId(0x8c000000000004d2)\n" - "BucketId(0x84000001000004d2)\n"), - doOrderedVisitor(id)); + std::string res; + ASSERT_NO_FATAL_FAILURE(doOrderedVisitor(id, res)); + EXPECT_EQ("BucketId(0x88000002000004d2)\n" + "BucketId(0x8c000004000004d2)\n" + "BucketId(0x8c000000000004d2)\n" + "BucketId(0x84000001000004d2)\n", + res); } -void -VisitorOperationTest::testUserVisitorOrderSplitPastOrderBits() -{ +TEST_F(VisitorOperationTest, user_visitor_order_split_past_order_bits) { enableDistributorClusterState("distributor:1 storage:1"); // Create buckets in bucketdb @@ -1519,12 +1214,14 @@ VisitorOperationTest::testUserVisitorOrderSplitPastOrderBits() document::BucketId id(16, 0x04d2); - CPPUNIT_ASSERT_EQUAL(std::string("BucketId(0x88000002000004d2)\n" - "BucketId(0x90000000000004d2)\n" - "BucketId(0x94000000000004d2)\n" - "BucketId(0x94000010000004d2)\n" - "BucketId(0x84000001000004d2)\n"), - doOrderedVisitor(id)); + std::string res; + ASSERT_NO_FATAL_FAILURE(doOrderedVisitor(id, res)); + EXPECT_EQ("BucketId(0x88000002000004d2)\n" + "BucketId(0x90000000000004d2)\n" + "BucketId(0x94000000000004d2)\n" + "BucketId(0x94000010000004d2)\n" + "BucketId(0x84000001000004d2)\n", + res); } std::unique_ptr<VisitorOperation> @@ -1533,8 +1230,7 @@ VisitorOperationTest::startOperationWith2StorageNodeVisitors(bool inconsistent) enableDistributorClusterState("distributor:1 storage:3"); addNodesToBucketDB(document::BucketId(17, 1), "0=1/1/1/t"); - addNodesToBucketDB(document::BucketId(17, 1 << 16 | 1), - "1=1/1/1/t"); + addNodesToBucketDB(document::BucketId(17, 1ULL << 16 | 1), "1=1/1/1/t"); document::BucketId id(16, 1); auto op = createOpWithDefaultConfig( @@ -1548,57 +1244,48 @@ VisitorOperationTest::startOperationWith2StorageNodeVisitors(bool inconsistent) op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL("Visitor Create => 0,Visitor Create => 1"s, - _sender.getCommands(true)); + assert(_sender.getCommands(true) == "Visitor Create => 0,Visitor Create => 1"); return op; } -void -VisitorOperationTest::testNoClientReplyBeforeAllStorageRepliesReceived() -{ +TEST_F(VisitorOperationTest, no_client_reply_before_all_storage_replies_received) { auto op = startOperationWith2StorageNodeVisitors(false); sendReply(*op, 0, api::ReturnCode::BUSY); // We don't want to see a reply here until the other node has replied. - CPPUNIT_ASSERT_EQUAL(""s, _sender.getReplies(true)); + ASSERT_EQ("", _sender.getReplies(true)); // OK reply from 1, but have to retry from client anyhow since one of // the sub buckets failed to be processed and we don't have inconsistent // visiting set in the client visitor command. sendReply(*op, 1); - CPPUNIT_ASSERT_EQUAL( - "CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(BUCKET_NOT_FOUND)"s, - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(BUCKET_NOT_FOUND)", + _sender.getLastReply()); // XXX we should consider wether we want BUSY to be returned instead. // Non-critical error codes are currently converted to a generic "not found" // code to let the client silently retry until the bucket has hopefully // become consistent/available. } -void -VisitorOperationTest::testSkipFailedSubBucketsWhenVisitingInconsistent() -{ +TEST_F(VisitorOperationTest, skip_failed_sub_buckets_when_visiting_inconsistent) { auto op = startOperationWith2StorageNodeVisitors(true); sendReply(*op, 0, api::ReturnCode::BUSY); - CPPUNIT_ASSERT_EQUAL(""s, _sender.getReplies(true)); + ASSERT_EQ("", _sender.getReplies(true)); // Subset of buckets could not be visited, but visit inconsistent flag is // set in the client visitor so we treat it as a success anyway. In this // case we've expanded the entire superbucket sub-tree so return with magic // number to signify this. sendReply(*op, 1); - CPPUNIT_ASSERT_EQUAL( - "CreateVisitorReply(last=BucketId(0x000000007fffffff)) " - "ReturnCode(NONE)"s, - _sender.getLastReply()); + EXPECT_EQ("CreateVisitorReply(last=BucketId(0x000000007fffffff)) " + "ReturnCode(NONE)", + _sender.getLastReply()); } // By default, queue timeout should be half of remaining visitor time. This // is a highly un-scientific heuristic, but seems rather more reasonable than // having it hard-coded to 2000 ms as was the case earlier. -void -VisitorOperationTest::testQueueTimeoutIsFactorOfTotalTimeout() -{ +TEST_F(VisitorOperationTest, queue_timeout_is_factor_of_total_timeout) { document::BucketId id(uint64_t(0x400000000000007b)); enableDistributorClusterState("distributor:1 storage:2"); addNodesToBucketDB(id, "0=1/1/1/t,1=1/1/1/t"); @@ -1607,11 +1294,10 @@ VisitorOperationTest::testQueueTimeoutIsFactorOfTotalTimeout() createVisitorCommand("foo", id, nullId, 8, 10000)); op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); - auto& cmd(dynamic_cast<CreateVisitorCommand&>(*_sender.commands[0])); - CPPUNIT_ASSERT_EQUAL(uint32_t(5000), cmd.getQueueTimeout()); + auto& cmd = dynamic_cast<CreateVisitorCommand&>(*_sender.command(0)); + EXPECT_EQ(5000, cmd.getQueueTimeout()); } void @@ -1626,49 +1312,43 @@ VisitorOperationTest::do_visitor_roundtrip_with_statistics( createVisitorCommand("metricstats", id, nullId)); op->start(_sender, framework::MilliSecTime(0)); - CPPUNIT_ASSERT_EQUAL(std::string("Visitor Create => 0"), - _sender.getCommands(true)); - auto& cmd(dynamic_cast<CreateVisitorCommand&>(*_sender.commands[0])); + ASSERT_EQ("Visitor Create => 0", _sender.getCommands(true)); + auto& cmd = dynamic_cast<CreateVisitorCommand&>(*_sender.command(0)); auto reply = cmd.makeReply(); vdslib::VisitorStatistics stats; stats.setBucketsVisited(50); stats.setDocumentsVisited(100); stats.setBytesVisited(2000); - static_cast<CreateVisitorReply&>(*reply).setVisitorStatistics(stats); + dynamic_cast<CreateVisitorReply&>(*reply).setVisitorStatistics(stats); reply->setResult(result); op->receive(_sender, api::StorageReply::SP(std::move(reply))); } -void -VisitorOperationTest::metrics_are_updated_with_visitor_statistics_upon_replying() -{ - do_visitor_roundtrip_with_statistics(api::ReturnCode(api::ReturnCode::OK)); +TEST_F(VisitorOperationTest, metrics_are_updated_with_visitor_statistics_upon_replying) { + ASSERT_NO_FATAL_FAILURE(do_visitor_roundtrip_with_statistics(api::ReturnCode(api::ReturnCode::OK))); - CPPUNIT_ASSERT_EQUAL(int64_t(50), defaultVisitorMetrics().buckets_per_visitor.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(100), defaultVisitorMetrics().docs_per_visitor.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(2000), defaultVisitorMetrics().bytes_per_visitor.getLast()); + EXPECT_EQ(50, defaultVisitorMetrics().buckets_per_visitor.getLast()); + EXPECT_EQ(100, defaultVisitorMetrics().docs_per_visitor.getLast()); + EXPECT_EQ(2000, defaultVisitorMetrics().bytes_per_visitor.getLast()); } -void -VisitorOperationTest::statistical_metrics_not_updated_on_wrong_distribution() -{ +TEST_F(VisitorOperationTest, statistical_metrics_not_updated_on_wrong_distribution) { setupDistributor(1, 100, "distributor:100 storage:2"); document::BucketId id(uint64_t(0x400000000000127b)); - CPPUNIT_ASSERT_EQUAL( - std::string("CreateVisitorReply(last=BucketId(0x0000000000000000)) " - "ReturnCode(WRONG_DISTRIBUTION, distributor:100 storage:2)"), - runEmptyVisitor(createVisitorCommand("wrongdist", id, nullId))); + ASSERT_EQ("CreateVisitorReply(last=BucketId(0x0000000000000000)) " + "ReturnCode(WRONG_DISTRIBUTION, distributor:100 storage:2)", + runEmptyVisitor(createVisitorCommand("wrongdist", id, nullId))); // Note that we're testing the number of _times_ the metric has been // updated, not the value with which it's been updated (which would be zero // even in the case we actually did update the statistical metrics). - CPPUNIT_ASSERT_EQUAL(int64_t(0), defaultVisitorMetrics().buckets_per_visitor.getCount()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), defaultVisitorMetrics().docs_per_visitor.getCount()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), defaultVisitorMetrics().bytes_per_visitor.getCount()); + EXPECT_EQ(0, defaultVisitorMetrics().buckets_per_visitor.getCount()); + EXPECT_EQ(0, defaultVisitorMetrics().docs_per_visitor.getCount()); + EXPECT_EQ(0, defaultVisitorMetrics().bytes_per_visitor.getCount()); // Fascinating that count is also a double... - CPPUNIT_ASSERT_EQUAL(0.0, defaultVisitorMetrics().latency.getCount()); + EXPECT_DOUBLE_EQ(0.0, defaultVisitorMetrics().latency.getCount()); } } diff --git a/storage/src/tests/persistence/CMakeLists.txt b/storage/src/tests/persistence/CMakeLists.txt index 76361e1d419..1e25f38fe2a 100644 --- a/storage/src/tests/persistence/CMakeLists.txt +++ b/storage/src/tests/persistence/CMakeLists.txt @@ -15,7 +15,6 @@ vespa_add_executable(storage_persistence_gtest_runner_app TEST gtest_runner.cpp DEPENDS storage - storage_testdistributor storage_testpersistence_common gtest ) diff --git a/storage/src/tests/persistence/bucketownershipnotifiertest.cpp b/storage/src/tests/persistence/bucketownershipnotifiertest.cpp index f4820f3ff13..47b1c43ca63 100644 --- a/storage/src/tests/persistence/bucketownershipnotifiertest.cpp +++ b/storage/src/tests/persistence/bucketownershipnotifiertest.cpp @@ -2,7 +2,7 @@ #include <vespa/document/test/make_document_bucket.h> #include <vespa/storage/persistence/bucketownershipnotifier.h> -#include <tests/distributor/messagesenderstub.h> +#include <tests/common/message_sender_stub.h> #include <tests/common/teststorageapp.h> #include <vespa/vespalib/gtest/gtest.h> diff --git a/storage/src/tests/persistence/common/filestortestfixture.h b/storage/src/tests/persistence/common/filestortestfixture.h index a8c32a409ec..85cec16a546 100644 --- a/storage/src/tests/persistence/common/filestortestfixture.h +++ b/storage/src/tests/persistence/common/filestortestfixture.h @@ -1,7 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/vdstestlib/cppunit/macros.h> #include <tests/common/testhelper.h> #include <vespa/persistence/spi/persistenceprovider.h> #include <vespa/storage/persistence/filestorage/filestormanager.h> diff --git a/storage/src/tests/persistence/mergehandlertest.cpp b/storage/src/tests/persistence/mergehandlertest.cpp index 0c291a179ae..8dedf3f18df 100644 --- a/storage/src/tests/persistence/mergehandlertest.cpp +++ b/storage/src/tests/persistence/mergehandlertest.cpp @@ -4,7 +4,7 @@ #include <vespa/storage/persistence/mergehandler.h> #include <tests/persistence/persistencetestutils.h> #include <tests/persistence/common/persistenceproviderwrapper.h> -#include <tests/distributor/messagesenderstub.h> +#include <tests/common/message_sender_stub.h> #include <vespa/document/test/make_document_bucket.h> #include <vespa/vespalib/objects/nbostream.h> #include <gmock/gmock.h> |