diff options
author | Tor Brede Vekterli <vekterli@verizonmedia.com> | 2019-06-13 16:25:25 +0000 |
---|---|---|
committer | Tor Brede Vekterli <vekterli@verizonmedia.com> | 2019-06-14 10:42:18 +0000 |
commit | 71947d62ce117cd5803ca03c1e63e8e9db9e8a86 (patch) | |
tree | 98981c0b067e9eab9696bc29ffc8c5d0e7556d82 /storage | |
parent | 98187c9181c2acc140e8556a5a9cfd8b8bda1764 (diff) |
Convert storageserver and visiting tests from CppUnit to GTest
Diffstat (limited to 'storage')
21 files changed, 1587 insertions, 2422 deletions
diff --git a/storage/src/tests/CMakeLists.txt b/storage/src/tests/CMakeLists.txt index 53113ea0eb1..ae55c80c148 100644 --- a/storage/src/tests/CMakeLists.txt +++ b/storage/src/tests/CMakeLists.txt @@ -6,8 +6,6 @@ vespa_add_executable(storage_testrunner_app TEST SOURCES testrunner.cpp DEPENDS - storage_teststorageserver - storage_testvisiting storage_testcommon storage_testhostreporter storage_testdistributor diff --git a/storage/src/tests/common/testhelper.h b/storage/src/tests/common/testhelper.h index 5a42732ae43..1bcc53dfe12 100644 --- a/storage/src/tests/common/testhelper.h +++ b/storage/src/tests/common/testhelper.h @@ -19,17 +19,6 @@ CPPUNIT_ASSERT_EQUAL_MSG(msgost.str(), size_t(count), \ (dummylink).getNumReplies()); \ } -#define ASSERT_COMMAND_COUNT(count, dummylink) \ - { \ - std::ostringstream msgost; \ - if ((dummylink).getNumCommands() != count) { \ - for (uint32_t ijx=0; ijx<(dummylink).getNumCommands(); ++ijx) { \ - msgost << (dummylink).getCommand(ijx)->toString(true) << "\n"; \ - } \ - } \ - CPPUNIT_ASSERT_EQUAL_MSG(msgost.str(), size_t(count), \ - (dummylink).getNumCommands()); \ - } namespace storage { diff --git a/storage/src/tests/storageserver/CMakeLists.txt b/storage/src/tests/storageserver/CMakeLists.txt index aa1059e6d79..9b63f5054c0 100644 --- a/storage/src/tests/storageserver/CMakeLists.txt +++ b/storage/src/tests/storageserver/CMakeLists.txt @@ -1,6 +1,14 @@ # Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. vespa_add_library(storage_teststorageserver TEST SOURCES + testvisitormessagesession.cpp + DEPENDS + storage_storageserver + storage_testcommon +) + +vespa_add_executable(storage_storageserver_gtest_runner_app TEST + SOURCES bouncertest.cpp bucketintegritycheckertest.cpp changedbucketownershiphandlertest.cpp @@ -13,18 +21,11 @@ vespa_add_library(storage_teststorageserver TEST service_layer_error_listener_test.cpp statemanagertest.cpp statereportertest.cpp - testvisitormessagesession.cpp - DEPENDS - storage_storageserver - storage_testcommon -) - -vespa_add_executable(storage_storageserver_gtest_runner_app TEST - SOURCES gtest_runner.cpp DEPENDS storage_storageserver storage_testcommon + storage_teststorageserver gtest ) diff --git a/storage/src/tests/storageserver/bouncertest.cpp b/storage/src/tests/storageserver/bouncertest.cpp index 371c24accbc..35b752fedfd 100644 --- a/storage/src/tests/storageserver/bouncertest.cpp +++ b/storage/src/tests/storageserver/bouncertest.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 <vespa/storageapi/message/bucket.h> #include <vespa/storageapi/message/state.h> #include <vespa/storageapi/message/stat.h> @@ -13,12 +12,14 @@ #include <vespa/document/test/make_document_bucket.h> #include <vespa/storageapi/message/persistence.h> #include <vespa/config/common/exceptions.h> +#include <vespa/vespalib/gtest/gtest.h> using document::test::makeDocumentBucket; +using namespace ::testing; namespace storage { -struct BouncerTest : public CppUnit::TestFixture { +struct BouncerTest : public Test { std::unique_ptr<TestStorageApp> _node; std::unique_ptr<DummyStorageLink> _upper; Bouncer* _manager; @@ -26,41 +27,11 @@ struct BouncerTest : public CppUnit::TestFixture { BouncerTest(); - void setUp() override; - void tearDown() override; + void SetUp() override; + void TearDown() override; void setUpAsNode(const lib::NodeType& type); - void testFutureTimestamp(); - void testAllowNotifyBucketChangeEvenWhenDistributorDown(); - void rejectLowerPrioritizedFeedMessagesWhenConfigured(); - void doNotRejectHigherPrioritizedFeedMessagesThanConfigured(); - void rejectionThresholdIsExclusive(); - void onlyRejectFeedMessagesWhenConfigured(); - void rejectionIsDisabledByDefaultInConfig(); - void readOnlyOperationsAreNotRejected(); - void internalOperationsAreNotRejected(); - void outOfBoundsConfigValuesThrowException(); - void abort_request_when_derived_bucket_space_node_state_is_marked_down(); - void client_operations_are_allowed_through_on_cluster_state_down_distributor(); - void cluster_state_activation_commands_are_not_bounced(); - - CPPUNIT_TEST_SUITE(BouncerTest); - CPPUNIT_TEST(testFutureTimestamp); - CPPUNIT_TEST(testAllowNotifyBucketChangeEvenWhenDistributorDown); - CPPUNIT_TEST(rejectLowerPrioritizedFeedMessagesWhenConfigured); - CPPUNIT_TEST(doNotRejectHigherPrioritizedFeedMessagesThanConfigured); - CPPUNIT_TEST(rejectionThresholdIsExclusive); - CPPUNIT_TEST(onlyRejectFeedMessagesWhenConfigured); - CPPUNIT_TEST(rejectionIsDisabledByDefaultInConfig); - CPPUNIT_TEST(readOnlyOperationsAreNotRejected); - CPPUNIT_TEST(internalOperationsAreNotRejected); - CPPUNIT_TEST(outOfBoundsConfigValuesThrowException); - CPPUNIT_TEST(abort_request_when_derived_bucket_space_node_state_is_marked_down); - CPPUNIT_TEST(client_operations_are_allowed_through_on_cluster_state_down_distributor); - CPPUNIT_TEST(cluster_state_activation_commands_are_not_bounced); - CPPUNIT_TEST_SUITE_END(); - using Priority = api::StorageMessage::Priority; static constexpr int RejectionDisabledConfigValue = -1; @@ -77,13 +48,11 @@ struct BouncerTest : public CppUnit::TestFixture { api::Timestamp timestamp, document::BucketSpace bucketSpace); - void assertMessageBouncedWithRejection(); - void assertMessageBouncedWithAbort(); - void assertMessageNotBounced(); + void expectMessageBouncedWithRejection(); + void expectMessageBouncedWithAbort(); + void expectMessageNotBounced(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(BouncerTest); - BouncerTest::BouncerTest() : _node(), _upper(), @@ -109,12 +78,12 @@ void BouncerTest::setUpAsNode(const lib::NodeType& type) { } void -BouncerTest::setUp() { +BouncerTest::SetUp() { setUpAsNode(lib::NodeType::STORAGE); } void -BouncerTest::tearDown() { +BouncerTest::TearDown() { _manager = nullptr; _lower = nullptr; if (_upper) { @@ -149,30 +118,27 @@ BouncerTest::createDummyFeedMessage(api::Timestamp timestamp, return cmd; } -void -BouncerTest::testFutureTimestamp() -{ - CPPUNIT_ASSERT_EQUAL(uint64_t(0), _manager->metrics().clock_skew_aborts.getValue()); +TEST_F(BouncerTest, future_timestamp) { + EXPECT_EQ(0, _manager->metrics().clock_skew_aborts.getValue()); // Fail when future timestamps (more than 5 seconds) are received. { _upper->sendDown(createDummyFeedMessage(16 * 1000000)); - CPPUNIT_ASSERT_EQUAL(1, (int)_upper->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(0, (int)_upper->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::REJECTED, - static_cast<api::RemoveReply&>(*_upper->getReply(0)). - getResult().getResult()); + ASSERT_EQ(1, _upper->getNumReplies()); + EXPECT_EQ(0, _upper->getNumCommands()); + EXPECT_EQ(api::ReturnCode::REJECTED, + dynamic_cast<api::RemoveReply&>(*_upper->getReply(0)).getResult().getResult()); _upper->reset(); } - CPPUNIT_ASSERT_EQUAL(uint64_t(1), _manager->metrics().clock_skew_aborts.getValue()); + EXPECT_EQ(1, _manager->metrics().clock_skew_aborts.getValue()); // Verify that 1 second clock skew is OK { _upper->sendDown(createDummyFeedMessage(11 * 1000000)); - CPPUNIT_ASSERT_EQUAL(0, (int)_upper->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(1, (int)_lower->getNumCommands()); + EXPECT_EQ(0, _upper->getNumReplies()); + EXPECT_EQ(1, _lower->getNumCommands()); _lower->reset(); } @@ -180,15 +146,13 @@ BouncerTest::testFutureTimestamp() { _upper->sendDown(createDummyFeedMessage(5 * 1000000)); - CPPUNIT_ASSERT_EQUAL(1, (int)_lower->getNumCommands()); + EXPECT_EQ(1, _lower->getNumCommands()); } - CPPUNIT_ASSERT_EQUAL(uint64_t(1), _manager->metrics().clock_skew_aborts.getValue()); + EXPECT_EQ(1, _manager->metrics().clock_skew_aborts.getValue()); } -void -BouncerTest::testAllowNotifyBucketChangeEvenWhenDistributorDown() -{ +TEST_F(BouncerTest, allow_notify_bucket_change_even_when_distributor_down) { lib::NodeState state(lib::NodeType::DISTRIBUTOR, lib::State::DOWN); _node->getNodeStateUpdater().setReportedNodeState(state); // Trigger Bouncer state update @@ -202,39 +166,38 @@ BouncerTest::testAllowNotifyBucketChangeEvenWhenDistributorDown() auto cmd = std::make_shared<api::NotifyBucketChangeCommand>(makeDocumentBucket(bucket), info); _upper->sendDown(cmd); - CPPUNIT_ASSERT_EQUAL(size_t(0), _upper->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(size_t(1), _lower->getNumCommands()); + EXPECT_EQ(0, _upper->getNumReplies()); + EXPECT_EQ(1, _lower->getNumCommands()); } void -BouncerTest::assertMessageBouncedWithRejection() +BouncerTest::expectMessageBouncedWithRejection() { - CPPUNIT_ASSERT_EQUAL(size_t(1), _upper->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(size_t(0), _upper->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::REJECTED, - static_cast<api::RemoveReply&>(*_upper->getReply(0)). - getResult().getResult()); - CPPUNIT_ASSERT_EQUAL(size_t(0), _lower->getNumCommands()); + ASSERT_EQ(1, _upper->getNumReplies()); + EXPECT_EQ(0, _upper->getNumCommands()); + EXPECT_EQ(api::ReturnCode::REJECTED, + dynamic_cast<api::RemoveReply&>(*_upper->getReply(0)).getResult().getResult()); + EXPECT_EQ(size_t(0), _lower->getNumCommands()); } void -BouncerTest::assertMessageBouncedWithAbort() +BouncerTest::expectMessageBouncedWithAbort() { - CPPUNIT_ASSERT_EQUAL(size_t(1), _upper->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(size_t(0), _upper->getNumCommands()); + ASSERT_EQ(1, _upper->getNumReplies()); + EXPECT_EQ(0, _upper->getNumCommands()); auto& reply = dynamic_cast<api::StorageReply&>(*_upper->getReply(0)); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::ABORTED, - "We don't allow command of type MessageType(12, Remove) " - "when node is in state Down (on storage.2)"), - reply.getResult()); - CPPUNIT_ASSERT_EQUAL(size_t(0), _lower->getNumCommands()); + EXPECT_EQ(api::ReturnCode(api::ReturnCode::ABORTED, + "We don't allow command of type MessageType(12, Remove) " + "when node is in state Down (on storage.2)"), + reply.getResult()); + EXPECT_EQ(0, _lower->getNumCommands()); } void -BouncerTest::assertMessageNotBounced() +BouncerTest::expectMessageNotBounced() { - CPPUNIT_ASSERT_EQUAL(size_t(0), _upper->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(size_t(1), _lower->getNumCommands()); + EXPECT_EQ(size_t(0), _upper->getNumReplies()); + EXPECT_EQ(size_t(1), _lower->getNumCommands()); } void @@ -246,49 +209,37 @@ BouncerTest::configureRejectionThreshold(int newThreshold) _manager->configure(std::move(config)); } -void -BouncerTest::rejectLowerPrioritizedFeedMessagesWhenConfigured() -{ +TEST_F(BouncerTest, reject_lower_prioritized_feed_messages_when_configured) { configureRejectionThreshold(Priority(120)); _upper->sendDown(createDummyFeedMessage(11 * 1000000, Priority(121))); - assertMessageBouncedWithRejection(); + expectMessageBouncedWithRejection(); } -void -BouncerTest::doNotRejectHigherPrioritizedFeedMessagesThanConfigured() -{ +TEST_F(BouncerTest, do_not_reject_higher_prioritized_feed_messages_than_configured) { configureRejectionThreshold(Priority(120)); _upper->sendDown(createDummyFeedMessage(11 * 1000000, Priority(119))); - assertMessageNotBounced(); + expectMessageNotBounced(); } -void -BouncerTest::rejectionThresholdIsExclusive() -{ +TEST_F(BouncerTest, rejection_threshold_is_exclusive) { configureRejectionThreshold(Priority(120)); _upper->sendDown(createDummyFeedMessage(11 * 1000000, Priority(120))); - assertMessageNotBounced(); + expectMessageNotBounced(); } -void -BouncerTest::onlyRejectFeedMessagesWhenConfigured() -{ +TEST_F(BouncerTest, only_reject_feed_messages_when_configured) { configureRejectionThreshold(RejectionDisabledConfigValue); // A message with even the lowest priority should not be rejected. _upper->sendDown(createDummyFeedMessage(11 * 1000000, Priority(255))); - assertMessageNotBounced(); + expectMessageNotBounced(); } -void -BouncerTest::rejectionIsDisabledByDefaultInConfig() -{ +TEST_F(BouncerTest, rejection_is_disabled_by_default_in_config) { _upper->sendDown(createDummyFeedMessage(11 * 1000000, Priority(255))); - assertMessageNotBounced(); + expectMessageNotBounced(); } -void -BouncerTest::readOnlyOperationsAreNotRejected() -{ +TEST_F(BouncerTest, read_only_operations_are_not_rejected) { configureRejectionThreshold(Priority(1)); // StatBucket is an external operation, but it's not a mutating operation // and should therefore not be blocked. @@ -296,33 +247,22 @@ BouncerTest::readOnlyOperationsAreNotRejected() makeDocumentBucket(document::BucketId(16, 5)), ""); cmd->setPriority(Priority(2)); _upper->sendDown(cmd); - assertMessageNotBounced(); + expectMessageNotBounced(); } -void -BouncerTest::internalOperationsAreNotRejected() -{ +TEST_F(BouncerTest, internal_operations_are_not_rejected) { configureRejectionThreshold(Priority(1)); document::BucketId bucket(16, 1234); api::BucketInfo info(0x1, 0x2, 0x3); auto cmd = std::make_shared<api::NotifyBucketChangeCommand>(makeDocumentBucket(bucket), info); cmd->setPriority(Priority(2)); _upper->sendDown(cmd); - assertMessageNotBounced(); + expectMessageNotBounced(); } -void -BouncerTest::outOfBoundsConfigValuesThrowException() -{ - try { - configureRejectionThreshold(256); - CPPUNIT_FAIL("Upper bound violation not caught"); - } catch (config::InvalidConfigException &) {} - - try { - configureRejectionThreshold(-2); - CPPUNIT_FAIL("Lower bound violation not caught"); - } catch (config::InvalidConfigException &) {} +TEST_F(BouncerTest, out_of_bounds_config_values_throw_exception) { + EXPECT_THROW(configureRejectionThreshold(256), config::InvalidConfigException); + EXPECT_THROW(configureRejectionThreshold(-2), config::InvalidConfigException); } @@ -340,25 +280,23 @@ makeClusterStateBundle(const vespalib::string &baselineState, const std::map<doc } -void -BouncerTest::abort_request_when_derived_bucket_space_node_state_is_marked_down() -{ - CPPUNIT_ASSERT_EQUAL(uint64_t(0), _manager->metrics().unavailable_node_aborts.getValue()); +TEST_F(BouncerTest, abort_request_when_derived_bucket_space_node_state_is_marked_down) { + EXPECT_EQ(0, _manager->metrics().unavailable_node_aborts.getValue()); auto state = makeClusterStateBundle("distributor:3 storage:3", {{ document::FixedBucketSpaces::default_space(), "distributor:3 storage:3 .2.s:d" }}); _node->getNodeStateUpdater().setClusterStateBundle(state); _upper->sendDown(createDummyFeedMessage(11 * 1000000, document::FixedBucketSpaces::default_space())); - assertMessageBouncedWithAbort(); - CPPUNIT_ASSERT_EQUAL(uint64_t(1), _manager->metrics().unavailable_node_aborts.getValue()); + expectMessageBouncedWithAbort(); + EXPECT_EQ(1, _manager->metrics().unavailable_node_aborts.getValue()); _upper->reset(); _upper->sendDown(createDummyFeedMessage(11 * 1000000, document::FixedBucketSpaces::global_space())); - assertMessageNotBounced(); - CPPUNIT_ASSERT_EQUAL(uint64_t(1), _manager->metrics().unavailable_node_aborts.getValue()); + expectMessageNotBounced(); + EXPECT_EQ(1, _manager->metrics().unavailable_node_aborts.getValue()); } -void BouncerTest::client_operations_are_allowed_through_on_cluster_state_down_distributor() { - tearDown(); +TEST_F(BouncerTest, client_operations_are_allowed_through_on_cluster_state_down_distributor) { + TearDown(); setUpAsNode(lib::NodeType::DISTRIBUTOR); // Distributor states never vary across bucket spaces, so not necessary to test with @@ -366,12 +304,12 @@ void BouncerTest::client_operations_are_allowed_through_on_cluster_state_down_di auto state = makeClusterStateBundle("distributor:3 .2.s:d storage:3", {}); _node->getNodeStateUpdater().setClusterStateBundle(state); _upper->sendDown(createDummyFeedMessage(11 * 1000000, document::FixedBucketSpaces::default_space())); - assertMessageNotBounced(); - CPPUNIT_ASSERT_EQUAL(uint64_t(0), _manager->metrics().unavailable_node_aborts.getValue()); + expectMessageNotBounced(); + EXPECT_EQ(0, _manager->metrics().unavailable_node_aborts.getValue()); } -void BouncerTest::cluster_state_activation_commands_are_not_bounced() { - tearDown(); +TEST_F(BouncerTest, cluster_state_activation_commands_are_not_bounced) { + TearDown(); setUpAsNode(lib::NodeType::DISTRIBUTOR); auto state = makeClusterStateBundle("version:10 distributor:3 .2.s:d storage:3", {}); // Our index (2) is down @@ -379,7 +317,7 @@ void BouncerTest::cluster_state_activation_commands_are_not_bounced() { auto activate_cmd = std::make_shared<api::ActivateClusterStateVersionCommand>(11); _upper->sendDown(activate_cmd); - assertMessageNotBounced(); + expectMessageNotBounced(); } } // storage diff --git a/storage/src/tests/storageserver/bucketintegritycheckertest.cpp b/storage/src/tests/storageserver/bucketintegritycheckertest.cpp index a4a6cbae9cf..ae466f04734 100644 --- a/storage/src/tests/storageserver/bucketintegritycheckertest.cpp +++ b/storage/src/tests/storageserver/bucketintegritycheckertest.cpp @@ -1,8 +1,5 @@ // 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 <vespa/log/log.h> #include <vespa/storage/bucketdb/bucketmanager.h> #include <vespa/storage/persistence/filestorage/filestormanager.h> #include <vespa/storage/storageserver/bucketintegritychecker.h> @@ -11,43 +8,26 @@ #include <tests/common/dummystoragelink.h> #include <vespa/vespalib/io/fileutil.h> #include <tests/common/teststorageapp.h> +#include <vespa/vespalib/gtest/gtest.h> -LOG_SETUP(".test.bucketintegritychecker"); +using namespace ::testing; namespace storage { -struct BucketIntegrityCheckerTest : public CppUnit::TestFixture { +struct BucketIntegrityCheckerTest : public Test { std::unique_ptr<vdstestlib::DirConfig> _config; std::unique_ptr<TestServiceLayerApp> _node; int _timeout; // Timeout in seconds before aborting - void setUp() override { + void SetUp() override { _timeout = 60*2; - _config.reset(new vdstestlib::DirConfig(getStandardConfig(true))); - _node.reset(new TestServiceLayerApp(DiskCount(256), - NodeIndex(0), - _config->getConfigId())); + _config = std::make_unique<vdstestlib::DirConfig>(getStandardConfig(true)); + _node = std::make_unique<TestServiceLayerApp>( + DiskCount(256), NodeIndex(0), _config->getConfigId()); } - - void tearDown() override { - LOG(info, "Finished test"); - } - - void testConfig(); - void testBasicFunctionality(); - void testTiming(); - - CPPUNIT_TEST_SUITE(BucketIntegrityCheckerTest); - CPPUNIT_TEST(testConfig); - CPPUNIT_TEST(testBasicFunctionality); - CPPUNIT_TEST_SUITE_END(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(BucketIntegrityCheckerTest); - -void BucketIntegrityCheckerTest::testConfig() -{ - +TEST_F(BucketIntegrityCheckerTest, config) { // Verify that config is read correctly. Given config should not use // any default values. vdstestlib::DirConfig::Config& config( @@ -63,18 +43,18 @@ void BucketIntegrityCheckerTest::testConfig() _node->getComponentRegister()); checker.setMaxThreadWaitTime(framework::MilliSecTime(10)); SchedulingOptions& opt(checker.getSchedulingOptions()); - CPPUNIT_ASSERT_EQUAL(60u, opt._dailyCycleStart); - CPPUNIT_ASSERT_EQUAL(360u, opt._dailyCycleStop); - CPPUNIT_ASSERT_EQUAL(SchedulingOptions::CONTINUE, opt._dailyStates[0]); - CPPUNIT_ASSERT_EQUAL(SchedulingOptions::RUN_CHEAP, opt._dailyStates[1]); - CPPUNIT_ASSERT_EQUAL(SchedulingOptions::RUN_FULL, opt._dailyStates[2]); - CPPUNIT_ASSERT_EQUAL(SchedulingOptions::CONTINUE, opt._dailyStates[3]); - CPPUNIT_ASSERT_EQUAL(SchedulingOptions::DONT_RUN, opt._dailyStates[4]); - CPPUNIT_ASSERT_EQUAL(SchedulingOptions::RUN_CHEAP, opt._dailyStates[5]); - CPPUNIT_ASSERT_EQUAL(SchedulingOptions::CONTINUE, opt._dailyStates[6]); - CPPUNIT_ASSERT_EQUAL(2u, opt._maxPendingCount); - CPPUNIT_ASSERT_EQUAL(framework::SecondTime(7200), opt._minCycleTime); - CPPUNIT_ASSERT_EQUAL(framework::SecondTime(5), opt._requestDelay); + EXPECT_EQ(60u, opt._dailyCycleStart); + EXPECT_EQ(360u, opt._dailyCycleStop); + EXPECT_EQ(SchedulingOptions::CONTINUE, opt._dailyStates[0]); + EXPECT_EQ(SchedulingOptions::RUN_CHEAP, opt._dailyStates[1]); + EXPECT_EQ(SchedulingOptions::RUN_FULL, opt._dailyStates[2]); + EXPECT_EQ(SchedulingOptions::CONTINUE, opt._dailyStates[3]); + EXPECT_EQ(SchedulingOptions::DONT_RUN, opt._dailyStates[4]); + EXPECT_EQ(SchedulingOptions::RUN_CHEAP, opt._dailyStates[5]); + EXPECT_EQ(SchedulingOptions::CONTINUE, opt._dailyStates[6]); + EXPECT_EQ(2u, opt._maxPendingCount); + EXPECT_EQ(framework::SecondTime(7200), opt._minCycleTime); + EXPECT_EQ(framework::SecondTime(5), opt._requestDelay); } namespace { @@ -115,11 +95,11 @@ namespace { mytime.tm_min = 0; mytime.tm_sec = 0; time_t startTime = timegm(&mytime); - CPPUNIT_ASSERT(gmtime_r(&startTime, &mytime)); + assert(gmtime_r(&startTime, &mytime)); while (mytime.tm_wday != 0) { ++mytime.tm_mday; startTime = timegm(&mytime); - CPPUNIT_ASSERT(gmtime_r(&startTime, &mytime)); + assert(gmtime_r(&startTime, &mytime)); } // Add the wanted values to the start time time_t resultTime = startTime; @@ -166,8 +146,18 @@ namespace { } } -void BucketIntegrityCheckerTest::testBasicFunctionality() -{ +#define ASSERT_COMMAND_COUNT(count, dummylink) \ + { \ + std::ostringstream msgost; \ + if ((dummylink).getNumCommands() != count) { \ + for (uint32_t ijx=0; ijx<(dummylink).getNumCommands(); ++ijx) { \ + msgost << (dummylink).getCommand(ijx)->toString(true) << "\n"; \ + } \ + } \ + ASSERT_EQ(size_t(count), (dummylink).getNumCommands()) << msgost.str(); \ + } + +TEST_F(BucketIntegrityCheckerTest, basic_functionality) { _node->getClock().setAbsoluteTimeInSeconds(getDate("week1 sun 00:00:00")); addBucketsToDatabase(*_node, false); DummyStorageLink* dummyLink = 0; @@ -193,91 +183,70 @@ void BucketIntegrityCheckerTest::testBasicFunctionality() dummyLink->waitForMessages(4, _timeout); FastOS_Thread::Sleep(10); // Give 5th message chance to come ASSERT_COMMAND_COUNT(4, *dummyLink); - RepairBucketCommand *cmd1 = dynamic_cast<RepairBucketCommand*>( - dummyLink->getCommand(0).get()); - CPPUNIT_ASSERT_EQUAL(230, (int)cmd1->getPriority()); - CPPUNIT_ASSERT(cmd1); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0x234), - cmd1->getBucketId()); - RepairBucketCommand *cmd2 = dynamic_cast<RepairBucketCommand*>( - dummyLink->getCommand(1).get()); - CPPUNIT_ASSERT(cmd2); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0x456), - cmd2->getBucketId()); - RepairBucketCommand *cmd3 = dynamic_cast<RepairBucketCommand*>( - dummyLink->getCommand(2).get()); - CPPUNIT_ASSERT(cmd3); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0x567), - cmd3->getBucketId()); - RepairBucketCommand *cmd4 = dynamic_cast<RepairBucketCommand*>( - dummyLink->getCommand(3).get()); - CPPUNIT_ASSERT(cmd4); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0x987), - cmd4->getBucketId()); + auto* cmd1 = dynamic_cast<RepairBucketCommand*>(dummyLink->getCommand(0).get()); + EXPECT_EQ(230, cmd1->getPriority()); + ASSERT_TRUE(cmd1); + EXPECT_EQ(document::BucketId(16, 0x234), cmd1->getBucketId()); + auto* cmd2 = dynamic_cast<RepairBucketCommand*>(dummyLink->getCommand(1).get()); + ASSERT_TRUE(cmd2); + EXPECT_EQ(document::BucketId(16, 0x456), cmd2->getBucketId()); + auto* cmd3 = dynamic_cast<RepairBucketCommand*>(dummyLink->getCommand(2).get()); + ASSERT_TRUE(cmd3); + EXPECT_EQ(document::BucketId(16, 0x567), cmd3->getBucketId()); + auto* cmd4 = dynamic_cast<RepairBucketCommand*>(dummyLink->getCommand(3).get()); + ASSERT_TRUE(cmd4); + EXPECT_EQ(document::BucketId(16, 0x987), cmd4->getBucketId()); // Answering a message on disk with no more buckets does not trigger new - std::shared_ptr<RepairBucketReply> reply1( - new RepairBucketReply(*cmd3)); - CPPUNIT_ASSERT(checker.onUp(reply1)); + auto reply1 = std::make_shared<RepairBucketReply>(*cmd3); + ASSERT_TRUE(checker.onUp(reply1)); FastOS_Thread::Sleep(10); // Give next message chance to come ASSERT_COMMAND_COUNT(4, *dummyLink); // Answering a message on disk with more buckets trigger new repair - std::shared_ptr<RepairBucketReply> reply2( - new RepairBucketReply(*cmd2)); - CPPUNIT_ASSERT(checker.onUp(reply2)); + auto reply2 = std::make_shared<RepairBucketReply>(*cmd2); + ASSERT_TRUE(checker.onUp(reply2)); dummyLink->waitForMessages(5, _timeout); FastOS_Thread::Sleep(10); // Give 6th message chance to come ASSERT_COMMAND_COUNT(5, *dummyLink); - RepairBucketCommand *cmd5 = dynamic_cast<RepairBucketCommand*>( - dummyLink->getCommand(4).get()); - CPPUNIT_ASSERT(cmd5); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0x345), - cmd5->getBucketId()); + auto* cmd5 = dynamic_cast<RepairBucketCommand*>(dummyLink->getCommand(4).get()); + ASSERT_TRUE(cmd5); + EXPECT_EQ(document::BucketId(16, 0x345), cmd5->getBucketId()); // Fail a repair, causing it to be resent later, but first continue // with other bucket. - std::shared_ptr<RepairBucketReply> reply3( - new RepairBucketReply(*cmd1)); + auto reply3 = std::make_shared<RepairBucketReply>(*cmd1); reply3->setResult(api::ReturnCode(api::ReturnCode::IGNORED)); - CPPUNIT_ASSERT(checker.onUp(reply3)); + ASSERT_TRUE(checker.onUp(reply3)); dummyLink->waitForMessages(6, _timeout); FastOS_Thread::Sleep(10); // Give 7th message chance to come ASSERT_COMMAND_COUNT(6, *dummyLink); - RepairBucketCommand *cmd6 = dynamic_cast<RepairBucketCommand*>( - dummyLink->getCommand(5).get()); - CPPUNIT_ASSERT(cmd6); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0x123), - cmd6->getBucketId()); + auto* cmd6 = dynamic_cast<RepairBucketCommand*>(dummyLink->getCommand(5).get()); + ASSERT_TRUE(cmd6); + EXPECT_EQ(document::BucketId(16, 0x123), cmd6->getBucketId()); // Fail a repair with not found. That is an acceptable return code. // (No more requests as this was last for that disk) - std::shared_ptr<RepairBucketReply> reply4( - new RepairBucketReply(*cmd4)); + auto reply4 = std::make_shared<RepairBucketReply>(*cmd4); reply3->setResult(api::ReturnCode(api::ReturnCode::BUCKET_NOT_FOUND)); - CPPUNIT_ASSERT(checker.onUp(reply4)); + ASSERT_TRUE(checker.onUp(reply4)); FastOS_Thread::Sleep(10); // Give 7th message chance to come ASSERT_COMMAND_COUNT(6, *dummyLink); // Send a repair reply that actually have corrected the bucket. api::BucketInfo newInfo(0x3456, 4, 8192); - std::shared_ptr<RepairBucketReply> reply5( - new RepairBucketReply(*cmd5, newInfo)); + auto reply5 = std::make_shared<RepairBucketReply>(*cmd5, newInfo); reply5->setAltered(true); - CPPUNIT_ASSERT(checker.onUp(reply5)); + ASSERT_TRUE(checker.onUp(reply5)); // Finish run. New iteration should not start yet as min // cycle time has not passed - std::shared_ptr<RepairBucketReply> reply6( - new RepairBucketReply(*cmd6)); - CPPUNIT_ASSERT(checker.onUp(reply6)); + auto reply6 = std::make_shared<RepairBucketReply>(*cmd6); + ASSERT_TRUE(checker.onUp(reply6)); dummyLink->waitForMessages(7, _timeout); ASSERT_COMMAND_COUNT(7, *dummyLink); - RepairBucketCommand *cmd7 = dynamic_cast<RepairBucketCommand*>( - dummyLink->getCommand(6).get()); - CPPUNIT_ASSERT(cmd7); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0x234), - cmd7->getBucketId()); - std::shared_ptr<RepairBucketReply> reply7( - new RepairBucketReply(*cmd7)); - CPPUNIT_ASSERT(checker.onUp(reply7)); + auto* cmd7 = dynamic_cast<RepairBucketCommand*>(dummyLink->getCommand(6).get()); + ASSERT_TRUE(cmd7); + EXPECT_EQ(document::BucketId(16, 0x234), cmd7->getBucketId()); + auto reply7 = std::make_shared<RepairBucketReply>(*cmd7); + ASSERT_TRUE(checker.onUp(reply7)); FastOS_Thread::Sleep(10); // Give 8th message chance to come ASSERT_COMMAND_COUNT(7, *dummyLink); diff --git a/storage/src/tests/storageserver/changedbucketownershiphandlertest.cpp b/storage/src/tests/storageserver/changedbucketownershiphandlertest.cpp index 98ad8761736..2f091572ed2 100644 --- a/storage/src/tests/storageserver/changedbucketownershiphandlertest.cpp +++ b/storage/src/tests/storageserver/changedbucketownershiphandlertest.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/document/base/testdocman.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/storage/bucketdb/storbucketdb.h> #include <vespa/storage/persistence/messages.h> #include <vespa/storageapi/message/state.h> @@ -16,46 +15,20 @@ #include <vespa/document/update/documentupdate.h> #include <vespa/document/test/make_document_bucket.h> #include <vespa/storage/storageserver/changedbucketownershiphandler.h> +#include <vespa/vespalib/gtest/gtest.h> using document::test::makeDocumentBucket; +using namespace ::testing; namespace storage { -class ChangedBucketOwnershipHandlerTest : public CppUnit::TestFixture -{ +struct ChangedBucketOwnershipHandlerTest : Test { std::unique_ptr<TestServiceLayerApp> _app; std::unique_ptr<DummyStorageLink> _top; ChangedBucketOwnershipHandler* _handler; DummyStorageLink* _bottom; document::TestDocMan _testDocRepo; - CPPUNIT_TEST_SUITE(ChangedBucketOwnershipHandlerTest); - CPPUNIT_TEST(testEnumerateBucketsBelongingOnChangedNodes); - CPPUNIT_TEST(testNoPreExistingClusterState); - CPPUNIT_TEST(testNoAvailableDistributorsInCurrentState); - CPPUNIT_TEST(testNoAvailableDistributorsInCurrentAndNewState); - CPPUNIT_TEST(testDownEdgeToNoAvailableDistributors); - CPPUNIT_TEST(testOwnershipChangedOnDistributorUpEdge); - CPPUNIT_TEST(testDistributionConfigChangeUpdatesOwnership); - CPPUNIT_TEST(testAbortOpsWhenNoClusterStateSet); - CPPUNIT_TEST(testAbortOutdatedSplit); - CPPUNIT_TEST(testAbortOutdatedJoin); - CPPUNIT_TEST(testAbortOutdatedSetBucketState); - CPPUNIT_TEST(testAbortOutdatedCreateBucket); - CPPUNIT_TEST(testAbortOutdatedDeleteBucket); - CPPUNIT_TEST(testAbortOutdatedMergeBucket); - CPPUNIT_TEST(testAbortOutdatedRemoveLocation); - CPPUNIT_TEST(testIdealStateAbortsAreConfigurable); - CPPUNIT_TEST(testAbortOutdatedPutOperation); - CPPUNIT_TEST(testAbortOutdatedUpdateCommand); - CPPUNIT_TEST(testAbortOutdatedRemoveCommand); - CPPUNIT_TEST(testAbortOutdatedRevertCommand); - CPPUNIT_TEST(testIdealStateAbortUpdatesMetric); - CPPUNIT_TEST(testExternalLoadOpAbortUpdatesMetric); - CPPUNIT_TEST(testExternalLoadOpAbortsAreConfigurable); - CPPUNIT_TEST(testAbortCommandsWhenStorageNodeIsDown); - CPPUNIT_TEST_SUITE_END(); - // TODO test: down edge triggered on cluster state with cluster down? std::vector<document::BucketId> insertBuckets( @@ -89,10 +62,10 @@ class ChangedBucketOwnershipHandlerTest : public CppUnit::TestFixture void sendAndExpectAbortedCreateBucket(uint16_t fromDistributorIndex); template <typename MsgType, typename... MsgParams> - bool changeAbortsMessage(MsgParams&&... params); + void expectChangeAbortsMessage(bool expected, MsgParams&& ... params); template <typename MsgType, typename... MsgParams> - bool downAbortsMessage(MsgParams&&... params); + void expectDownAbortsMessage(bool expected, MsgParams&& ... params); lib::ClusterState getDefaultTestClusterState() const { return lib::ClusterState("distributor:4 storage:1"); @@ -101,36 +74,9 @@ class ChangedBucketOwnershipHandlerTest : public CppUnit::TestFixture lib::ClusterState getStorageDownTestClusterState() const { return lib::ClusterState("distributor:4 storage:1 .0.s:d"); } -public: - void testEnumerateBucketsBelongingOnChangedNodes(); - void testNoPreExistingClusterState(); - void testNoAvailableDistributorsInCurrentState(); - void testNoAvailableDistributorsInCurrentAndNewState(); - void testDownEdgeToNoAvailableDistributors(); - void testOwnershipChangedOnDistributorUpEdge(); - void testDistributionConfigChangeUpdatesOwnership(); - void testAbortOpsWhenNoClusterStateSet(); - void testAbortOutdatedSplit(); - void testAbortOutdatedJoin(); - void testAbortOutdatedSetBucketState(); - void testAbortOutdatedCreateBucket(); - void testAbortOutdatedDeleteBucket(); - void testAbortOutdatedMergeBucket(); - void testAbortOutdatedRemoveLocation(); - void testIdealStateAbortsAreConfigurable(); - void testAbortOutdatedPutOperation(); - void testAbortOutdatedUpdateCommand(); - void testAbortOutdatedRemoveCommand(); - void testAbortOutdatedRevertCommand(); - void testIdealStateAbortUpdatesMetric(); - void testExternalLoadOpAbortUpdatesMetric(); - void testExternalLoadOpAbortsAreConfigurable(); - void testAbortCommandsWhenStorageNodeIsDown(); - - void setUp() override; -}; -CPPUNIT_TEST_SUITE_REGISTRATION(ChangedBucketOwnershipHandlerTest); + void SetUp() override; +}; document::BucketId ChangedBucketOwnershipHandlerTest::nextOwnedBucket( @@ -171,7 +117,7 @@ ChangedBucketOwnershipHandlerTest::insertBuckets(uint32_t numBuckets, } void -ChangedBucketOwnershipHandlerTest::setUp() +ChangedBucketOwnershipHandlerTest::SetUp() { vdstestlib::DirConfig config(getStandardConfig(true)); @@ -185,8 +131,7 @@ ChangedBucketOwnershipHandlerTest::setUp() _top->open(); // Ensure we're not dependent on config schema default values. - std::unique_ptr<vespa::config::content::PersistenceConfigBuilder> pconfig( - new vespa::config::content::PersistenceConfigBuilder); + auto pconfig = std::make_unique<vespa::config::content::PersistenceConfigBuilder>(); pconfig->abortOutdatedMutatingIdealStateOps = true; pconfig->abortOutdatedMutatingExternalLoadOps = true; _handler->configure(std::move(pconfig)); @@ -253,9 +198,7 @@ ChangedBucketOwnershipHandlerTest::applyClusterState( _handler->reloadClusterState(); } -void -ChangedBucketOwnershipHandlerTest::testEnumerateBucketsBelongingOnChangedNodes() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, enumerate_buckets_belonging_on_changed_nodes) { lib::ClusterState stateBefore("distributor:4 storage:1"); applyDistribution(Redundancy(1), NodeCount(4)); applyClusterState(stateBefore); @@ -267,25 +210,21 @@ ChangedBucketOwnershipHandlerTest::testEnumerateBucketsBelongingOnChangedNodes() _top->sendDown(createStateCmd("distributor:4 .1.s:d .3.s:d storage:1")); // TODO: refactor into own function - CPPUNIT_ASSERT_EQUAL(size_t(2), _bottom->getNumCommands()); - AbortBucketOperationsCommand::SP cmd( - std::dynamic_pointer_cast<AbortBucketOperationsCommand>( - _bottom->getCommand(0))); - CPPUNIT_ASSERT(cmd.get() != 0); + ASSERT_EQ(2, _bottom->getNumCommands()); + auto cmd = std::dynamic_pointer_cast<AbortBucketOperationsCommand>(_bottom->getCommand(0)); + ASSERT_TRUE(cmd.get() != 0); - CPPUNIT_ASSERT(hasAbortedAllOf(cmd, node1Buckets)); - CPPUNIT_ASSERT(hasAbortedAllOf(cmd, node3Buckets)); - CPPUNIT_ASSERT(hasAbortedNoneOf(cmd, node0Buckets)); - CPPUNIT_ASSERT(hasAbortedNoneOf(cmd, node2Buckets)); + EXPECT_TRUE(hasAbortedAllOf(cmd, node1Buckets)); + EXPECT_TRUE(hasAbortedAllOf(cmd, node3Buckets)); + EXPECT_TRUE(hasAbortedNoneOf(cmd, node0Buckets)); + EXPECT_TRUE(hasAbortedNoneOf(cmd, node2Buckets)); // Handler must swallow abort replies _bottom->sendUp(api::StorageMessage::SP(cmd->makeReply().release())); - CPPUNIT_ASSERT_EQUAL(size_t(0), _top->getNumReplies()); + EXPECT_EQ(size_t(0), _top->getNumReplies()); } -void -ChangedBucketOwnershipHandlerTest::testNoPreExistingClusterState() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, no_pre_existing_cluster_state) { applyDistribution(Redundancy(1), NodeCount(4)); lib::ClusterState stateBefore("distributor:4 storage:1"); insertBuckets(2, 1, stateBefore); @@ -293,7 +232,7 @@ ChangedBucketOwnershipHandlerTest::testNoPreExistingClusterState() insertBuckets(2, 2, stateBefore); _top->sendDown(createStateCmd("distributor:4 .1.s:d .3.s:d storage:1")); - CPPUNIT_ASSERT(hasOnlySetSystemStateCmdQueued(*_bottom)); + EXPECT_TRUE(hasOnlySetSystemStateCmdQueued(*_bottom)); } /** @@ -301,9 +240,7 @@ ChangedBucketOwnershipHandlerTest::testNoPreExistingClusterState() * more distributors, we do not send any abort messages since this should * already have been done on the down-edge. */ -void -ChangedBucketOwnershipHandlerTest::testNoAvailableDistributorsInCurrentState() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, no_available_distributors_in_current_state) { applyDistribution(Redundancy(1), NodeCount(3)); lib::ClusterState insertedState("distributor:3 storage:1"); insertBuckets(2, 0, insertedState); @@ -313,12 +250,10 @@ ChangedBucketOwnershipHandlerTest::testNoAvailableDistributorsInCurrentState() _app->setClusterState(downState); _top->sendDown(createStateCmd("distributor:3 .1.s:d storage:1")); - CPPUNIT_ASSERT(hasOnlySetSystemStateCmdQueued(*_bottom)); + EXPECT_TRUE(hasOnlySetSystemStateCmdQueued(*_bottom)); } -void -ChangedBucketOwnershipHandlerTest::testNoAvailableDistributorsInCurrentAndNewState() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, no_available_distributors_in_current_and_new_state) { applyDistribution(Redundancy(1), NodeCount(3)); lib::ClusterState insertedState("distributor:3 storage:1"); insertBuckets(2, 0, insertedState); @@ -329,12 +264,10 @@ ChangedBucketOwnershipHandlerTest::testNoAvailableDistributorsInCurrentAndNewSta lib::ClusterState downState("distributor:3 .0.s:d .1.s:d .2.s:d storage:1"); _top->sendDown(createStateCmd(downState)); - CPPUNIT_ASSERT(hasOnlySetSystemStateCmdQueued(*_bottom)); + EXPECT_TRUE(hasOnlySetSystemStateCmdQueued(*_bottom)); } -void -ChangedBucketOwnershipHandlerTest::testDownEdgeToNoAvailableDistributors() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, down_edge_to_no_available_distributors) { lib::ClusterState insertedState("distributor:3 storage:1"); applyDistribution(Redundancy(1), NodeCount(3)); applyClusterState(insertedState); @@ -345,20 +278,16 @@ ChangedBucketOwnershipHandlerTest::testDownEdgeToNoAvailableDistributors() _top->sendDown(createStateCmd(downState)); // TODO: refactor into own function - CPPUNIT_ASSERT_EQUAL(size_t(2), _bottom->getNumCommands()); - AbortBucketOperationsCommand::SP cmd( - std::dynamic_pointer_cast<AbortBucketOperationsCommand>( - _bottom->getCommand(0))); - CPPUNIT_ASSERT(cmd.get() != 0); + ASSERT_EQ(2, _bottom->getNumCommands()); + auto cmd = std::dynamic_pointer_cast<AbortBucketOperationsCommand>(_bottom->getCommand(0)); + ASSERT_TRUE(cmd.get() != 0); - CPPUNIT_ASSERT(hasAbortedAllOf(cmd, node0Buckets)); - CPPUNIT_ASSERT(hasAbortedAllOf(cmd, node1Buckets)); - CPPUNIT_ASSERT(hasAbortedAllOf(cmd, node2Buckets)); + EXPECT_TRUE(hasAbortedAllOf(cmd, node0Buckets)); + EXPECT_TRUE(hasAbortedAllOf(cmd, node1Buckets)); + EXPECT_TRUE(hasAbortedAllOf(cmd, node2Buckets)); } -void -ChangedBucketOwnershipHandlerTest::testOwnershipChangedOnDistributorUpEdge() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, ownership_changed_on_distributor_up_edge) { lib::ClusterState stateBefore( "version:10 distributor:4 .1.s:d storage:4 .1.s:d"); lib::ClusterState stateAfter( @@ -373,19 +302,17 @@ ChangedBucketOwnershipHandlerTest::testOwnershipChangedOnDistributorUpEdge() _top->sendDown(createStateCmd(stateAfter)); // TODO: refactor into own function - CPPUNIT_ASSERT_EQUAL(size_t(2), _bottom->getNumCommands()); - AbortBucketOperationsCommand::SP cmd( - std::dynamic_pointer_cast<AbortBucketOperationsCommand>( - _bottom->getCommand(0))); - CPPUNIT_ASSERT(cmd.get() != 0); + ASSERT_EQ(2, _bottom->getNumCommands()); + auto cmd = std::dynamic_pointer_cast<AbortBucketOperationsCommand>(_bottom->getCommand(0)); + ASSERT_TRUE(cmd.get() != 0); - CPPUNIT_ASSERT(hasAbortedAllOf(cmd, node1Buckets)); - CPPUNIT_ASSERT(hasAbortedNoneOf(cmd, node0Buckets)); - CPPUNIT_ASSERT(hasAbortedNoneOf(cmd, node2Buckets)); + EXPECT_TRUE(hasAbortedAllOf(cmd, node1Buckets)); + EXPECT_TRUE(hasAbortedNoneOf(cmd, node0Buckets)); + EXPECT_TRUE(hasAbortedNoneOf(cmd, node2Buckets)); // Handler must swallow abort replies _bottom->sendUp(api::StorageMessage::SP(cmd->makeReply().release())); - CPPUNIT_ASSERT_EQUAL(size_t(0), _top->getNumReplies()); + EXPECT_EQ(0, _top->getNumReplies()); } void @@ -398,21 +325,16 @@ ChangedBucketOwnershipHandlerTest::sendAndExpectAbortedCreateBucket( _top->sendDown(msg); std::vector<api::StorageMessage::SP> replies(_top->getRepliesOnce()); - CPPUNIT_ASSERT_EQUAL(size_t(1), replies.size()); - api::StorageReply& reply(dynamic_cast<api::StorageReply&>(*replies[0])); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::ABORTED, - reply.getResult().getResult()); + ASSERT_EQ(1, replies.size()); + auto& reply(dynamic_cast<api::StorageReply&>(*replies[0])); + EXPECT_EQ(api::ReturnCode::ABORTED, reply.getResult().getResult()); } -void -ChangedBucketOwnershipHandlerTest::testAbortOpsWhenNoClusterStateSet() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, abort_ops_when_no_cluster_state_set) { sendAndExpectAbortedCreateBucket(1); } -void -ChangedBucketOwnershipHandlerTest::testDistributionConfigChangeUpdatesOwnership() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, distribution_config_change_updates_ownership) { lib::ClusterState insertedState("distributor:3 storage:1"); applyClusterState(insertedState); applyDistribution(Redundancy(1), NodeCount(3)); @@ -431,8 +353,8 @@ ChangedBucketOwnershipHandlerTest::testDistributionConfigChangeUpdatesOwnership( * owned by distributor 1 in this state to trigger an abort. */ template <typename MsgType, typename... MsgParams> -bool -ChangedBucketOwnershipHandlerTest::changeAbortsMessage(MsgParams&&... params) +void +ChangedBucketOwnershipHandlerTest::expectChangeAbortsMessage(bool expected, MsgParams&&... params) { auto msg = std::make_shared<MsgType>(std::forward<MsgParams>(params)...); msg->setSourceIndex(1); @@ -444,15 +366,14 @@ ChangedBucketOwnershipHandlerTest::changeAbortsMessage(MsgParams&&... params) std::vector<api::StorageMessage::SP> replies(_top->getRepliesOnce()); // Test is single-threaded, no need to do any waiting. if (replies.empty()) { - return false; + EXPECT_FALSE(expected); } else { - CPPUNIT_ASSERT_EQUAL(size_t(1), replies.size()); + ASSERT_EQ(replies.size(), 1); // Make sure the message was actually aborted and not bounced with // some other arbitrary failure code. - api::StorageReply& reply(dynamic_cast<api::StorageReply&>(*replies[0])); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::ABORTED, - reply.getResult().getResult()); - return true; + auto& reply(dynamic_cast<api::StorageReply&>(*replies[0])); + ASSERT_EQ(reply.getResult().getResult(), api::ReturnCode::ABORTED); + EXPECT_TRUE(expected); } } @@ -463,21 +384,21 @@ ChangedBucketOwnershipHandlerTest::changeAbortsMessage(MsgParams&&... params) * node is down. This means that any abortable message will trigger an abort. */ template <typename MsgType, typename... MsgParams> -bool -ChangedBucketOwnershipHandlerTest::downAbortsMessage(MsgParams&&... params) +void +ChangedBucketOwnershipHandlerTest::expectDownAbortsMessage(bool expected, MsgParams&&... params) { (void) _top->getRepliesOnce(); (void) _bottom->getCommandsOnce(); - CPPUNIT_ASSERT((!changeAbortsMessage<MsgType, MsgParams...>(std::forward<MsgParams>(params) ...))); + ASSERT_NO_FATAL_FAILURE((expectChangeAbortsMessage<MsgType, MsgParams...>(false, std::forward<MsgParams>(params)...))); _top->sendDown(createStateCmd(getStorageDownTestClusterState())); - CPPUNIT_ASSERT_EQUAL(size_t(3), _bottom->getNumCommands()); + ASSERT_EQ(_bottom->getNumCommands(), 3); auto setSystemStateCommand = std::dynamic_pointer_cast<api::SetSystemStateCommand>(_bottom->getCommand(2)); - CPPUNIT_ASSERT(setSystemStateCommand); + ASSERT_TRUE(setSystemStateCommand); auto abortBucketOperationsCommand = std::dynamic_pointer_cast<AbortBucketOperationsCommand>(_bottom->getCommand(1)); - CPPUNIT_ASSERT(abortBucketOperationsCommand); + ASSERT_TRUE(abortBucketOperationsCommand); auto testCommand = _bottom->getCommand(0); - CPPUNIT_ASSERT(testCommand); - return abortBucketOperationsCommand->shouldAbort(testCommand->getBucket()); + ASSERT_TRUE(testCommand); + EXPECT_EQ(expected, abortBucketOperationsCommand->shouldAbort(testCommand->getBucket())); } /** @@ -502,59 +423,37 @@ ChangedBucketOwnershipHandlerTest::getBucketToAllow() const return makeDocumentBucket(nextOwnedBucket(1, state, document::BucketId())); } -void -ChangedBucketOwnershipHandlerTest::testAbortOutdatedSplit() -{ - CPPUNIT_ASSERT(changeAbortsMessage<api::SplitBucketCommand>( - getBucketToAbort())); - CPPUNIT_ASSERT(!changeAbortsMessage<api::SplitBucketCommand>( - getBucketToAllow())); +TEST_F(ChangedBucketOwnershipHandlerTest, abort_outdated_split) { + expectChangeAbortsMessage<api::SplitBucketCommand>(true, getBucketToAbort()); + expectChangeAbortsMessage<api::SplitBucketCommand>(false, getBucketToAllow()); } -void -ChangedBucketOwnershipHandlerTest::testAbortOutdatedJoin() -{ - CPPUNIT_ASSERT(changeAbortsMessage<api::JoinBucketsCommand>( - getBucketToAbort())); - CPPUNIT_ASSERT(!changeAbortsMessage<api::JoinBucketsCommand>( - getBucketToAllow())); +TEST_F(ChangedBucketOwnershipHandlerTest, abort_outdated_join) { + expectChangeAbortsMessage<api::JoinBucketsCommand>(true, getBucketToAbort()); + expectChangeAbortsMessage<api::JoinBucketsCommand>(false, getBucketToAllow()); } -void -ChangedBucketOwnershipHandlerTest::testAbortOutdatedSetBucketState() -{ - CPPUNIT_ASSERT(changeAbortsMessage<api::SetBucketStateCommand>( - getBucketToAbort(), api::SetBucketStateCommand::ACTIVE)); - CPPUNIT_ASSERT(!changeAbortsMessage<api::SetBucketStateCommand>( - getBucketToAllow(), api::SetBucketStateCommand::ACTIVE)); +TEST_F(ChangedBucketOwnershipHandlerTest, abort_outdated_set_bucket_state) { + expectChangeAbortsMessage<api::SetBucketStateCommand>( + true, getBucketToAbort(), api::SetBucketStateCommand::ACTIVE); + expectChangeAbortsMessage<api::SetBucketStateCommand>( + false, getBucketToAllow(), api::SetBucketStateCommand::ACTIVE); } -void -ChangedBucketOwnershipHandlerTest::testAbortOutdatedCreateBucket() -{ - CPPUNIT_ASSERT(changeAbortsMessage<api::CreateBucketCommand>( - getBucketToAbort())); - CPPUNIT_ASSERT(!changeAbortsMessage<api::CreateBucketCommand>( - getBucketToAllow())); +TEST_F(ChangedBucketOwnershipHandlerTest, abort_outdated_create_bucket) { + expectChangeAbortsMessage<api::CreateBucketCommand>(true, getBucketToAbort()); + expectChangeAbortsMessage<api::CreateBucketCommand>(false, getBucketToAllow()); } -void -ChangedBucketOwnershipHandlerTest::testAbortOutdatedDeleteBucket() -{ - CPPUNIT_ASSERT(changeAbortsMessage<api::DeleteBucketCommand>( - getBucketToAbort())); - CPPUNIT_ASSERT(!changeAbortsMessage<api::DeleteBucketCommand>( - getBucketToAllow())); +TEST_F(ChangedBucketOwnershipHandlerTest, abort_outdated_delete_bucket) { + expectChangeAbortsMessage<api::DeleteBucketCommand>(true, getBucketToAbort()); + expectChangeAbortsMessage<api::DeleteBucketCommand>(false, getBucketToAllow()); } -void -ChangedBucketOwnershipHandlerTest::testAbortOutdatedMergeBucket() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, abort_outdated_merge_bucket) { std::vector<api::MergeBucketCommand::Node> nodes; - CPPUNIT_ASSERT(changeAbortsMessage<api::MergeBucketCommand>( - getBucketToAbort(), nodes, 0)); - CPPUNIT_ASSERT(!changeAbortsMessage<api::MergeBucketCommand>( - getBucketToAllow(), nodes, 0)); + expectChangeAbortsMessage<api::MergeBucketCommand>(true, getBucketToAbort(), nodes, 0); + expectChangeAbortsMessage<api::MergeBucketCommand>(false, getBucketToAllow(), nodes, 0); } /** @@ -562,114 +461,76 @@ ChangedBucketOwnershipHandlerTest::testAbortOutdatedMergeBucket() * used as the backing operation for GC we have to treat it as if it were an * ideal state operation class. */ -void -ChangedBucketOwnershipHandlerTest::testAbortOutdatedRemoveLocation() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, abort_outdated_remove_location) { std::vector<api::MergeBucketCommand::Node> nodes; - CPPUNIT_ASSERT(changeAbortsMessage<api::RemoveLocationCommand>( - "foo", getBucketToAbort())); - CPPUNIT_ASSERT(!changeAbortsMessage<api::RemoveLocationCommand>( - "foo", getBucketToAllow())); + expectChangeAbortsMessage<api::RemoveLocationCommand>(true, "foo", getBucketToAbort()); + expectChangeAbortsMessage<api::RemoveLocationCommand>(false, "foo", getBucketToAllow()); } -void -ChangedBucketOwnershipHandlerTest::testIdealStateAbortsAreConfigurable() -{ - std::unique_ptr<vespa::config::content::PersistenceConfigBuilder> config( - new vespa::config::content::PersistenceConfigBuilder); +TEST_F(ChangedBucketOwnershipHandlerTest, ideal_state_aborts_are_configurable) { + auto config = std::make_unique<vespa::config::content::PersistenceConfigBuilder>(); config->abortOutdatedMutatingIdealStateOps = false; _handler->configure(std::move(config)); // Should not abort operation, even when ownership has changed. - CPPUNIT_ASSERT(!changeAbortsMessage<api::CreateBucketCommand>( - getBucketToAbort())); + expectChangeAbortsMessage<api::CreateBucketCommand>(false, getBucketToAbort()); } -void -ChangedBucketOwnershipHandlerTest::testAbortOutdatedPutOperation() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, abort_outdated_put_operation) { document::Document::SP doc(_testDocRepo.createRandomDocumentAtLocation(1)); - CPPUNIT_ASSERT(changeAbortsMessage<api::PutCommand>( - getBucketToAbort(), doc, api::Timestamp(1234))); - CPPUNIT_ASSERT(!changeAbortsMessage<api::PutCommand>( - getBucketToAllow(), doc, api::Timestamp(1234))); + expectChangeAbortsMessage<api::PutCommand>(true, getBucketToAbort(), doc, api::Timestamp(1234)); + expectChangeAbortsMessage<api::PutCommand>(false, getBucketToAllow(), doc, api::Timestamp(1234)); } -void -ChangedBucketOwnershipHandlerTest::testAbortOutdatedUpdateCommand() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, abort_outdated_update_command) { const document::DocumentType* docType(_testDocRepo.getTypeRepo().getDocumentType("testdoctype1")); document::DocumentId docId("id:foo:testdoctype1::bar"); auto update(std::make_shared<document::DocumentUpdate>(_testDocRepo.getTypeRepo(), *docType, docId)); - CPPUNIT_ASSERT(changeAbortsMessage<api::UpdateCommand>(getBucketToAbort(), update, api::Timestamp(1234))); - CPPUNIT_ASSERT(!changeAbortsMessage<api::UpdateCommand>(getBucketToAllow(), update, api::Timestamp(1234))); + expectChangeAbortsMessage<api::UpdateCommand>(true, getBucketToAbort(), update, api::Timestamp(1234)); + expectChangeAbortsMessage<api::UpdateCommand>(false, getBucketToAllow(), update, api::Timestamp(1234)); } -void -ChangedBucketOwnershipHandlerTest::testAbortOutdatedRemoveCommand() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, abort_outdated_remove_command) { document::DocumentId docId("id:foo:testdoctype1::bar"); - CPPUNIT_ASSERT(changeAbortsMessage<api::RemoveCommand>(getBucketToAbort(), docId, api::Timestamp(1234))); - CPPUNIT_ASSERT(!changeAbortsMessage<api::RemoveCommand>(getBucketToAllow(), docId, api::Timestamp(1234))); + expectChangeAbortsMessage<api::RemoveCommand>(true, getBucketToAbort(), docId, api::Timestamp(1234)); + expectChangeAbortsMessage<api::RemoveCommand>(false, getBucketToAllow(), docId, api::Timestamp(1234)); } -void -ChangedBucketOwnershipHandlerTest::testAbortOutdatedRevertCommand() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, abort_outdated_revert_command) { std::vector<api::Timestamp> timestamps; - CPPUNIT_ASSERT(changeAbortsMessage<api::RevertCommand>( - getBucketToAbort(), timestamps)); - CPPUNIT_ASSERT(!changeAbortsMessage<api::RevertCommand>( - getBucketToAllow(), timestamps)); + expectChangeAbortsMessage<api::RevertCommand>(true, getBucketToAbort(), timestamps); + expectChangeAbortsMessage<api::RevertCommand>(false, getBucketToAllow(), timestamps); } -void -ChangedBucketOwnershipHandlerTest::testIdealStateAbortUpdatesMetric() -{ - CPPUNIT_ASSERT(changeAbortsMessage<api::SplitBucketCommand>( - getBucketToAbort())); - CPPUNIT_ASSERT_EQUAL( - uint64_t(1), - _handler->getMetrics().idealStateOpsAborted.getValue()); - CPPUNIT_ASSERT_EQUAL( - uint64_t(0), - _handler->getMetrics().externalLoadOpsAborted.getValue()); +TEST_F(ChangedBucketOwnershipHandlerTest, ideal_state_abort_updates_metric) { + expectChangeAbortsMessage<api::SplitBucketCommand>(true, getBucketToAbort()); + EXPECT_EQ(1, _handler->getMetrics().idealStateOpsAborted.getValue()); + EXPECT_EQ(0, _handler->getMetrics().externalLoadOpsAborted.getValue()); } -void -ChangedBucketOwnershipHandlerTest::testExternalLoadOpAbortUpdatesMetric() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, external_load_op_abort_updates_metric) { document::DocumentId docId("id:foo:testdoctype1::bar"); - CPPUNIT_ASSERT(changeAbortsMessage<api::RemoveCommand>( - getBucketToAbort(), docId, api::Timestamp(1234))); - CPPUNIT_ASSERT_EQUAL( - uint64_t(0), - _handler->getMetrics().idealStateOpsAborted.getValue()); - CPPUNIT_ASSERT_EQUAL( - uint64_t(1), - _handler->getMetrics().externalLoadOpsAborted.getValue()); + expectChangeAbortsMessage<api::RemoveCommand>( + true, getBucketToAbort(), docId, api::Timestamp(1234)); + EXPECT_EQ(0, _handler->getMetrics().idealStateOpsAborted.getValue()); + EXPECT_EQ(1, _handler->getMetrics().externalLoadOpsAborted.getValue()); } -void -ChangedBucketOwnershipHandlerTest::testExternalLoadOpAbortsAreConfigurable() -{ - std::unique_ptr<vespa::config::content::PersistenceConfigBuilder> config( - new vespa::config::content::PersistenceConfigBuilder); +TEST_F(ChangedBucketOwnershipHandlerTest, external_load_op_aborts_are_configurable) { + auto config = std::make_unique<vespa::config::content::PersistenceConfigBuilder>(); config->abortOutdatedMutatingExternalLoadOps = false; _handler->configure(std::move(config)); // Should not abort operation, even when ownership has changed. document::DocumentId docId("id:foo:testdoctype1::bar"); - CPPUNIT_ASSERT(!changeAbortsMessage<api::RemoveCommand>( - getBucketToAbort(), docId, api::Timestamp(1234))); + expectChangeAbortsMessage<api::RemoveCommand>( + false, getBucketToAbort(), docId, api::Timestamp(1234)); } -void -ChangedBucketOwnershipHandlerTest::testAbortCommandsWhenStorageNodeIsDown() -{ +TEST_F(ChangedBucketOwnershipHandlerTest, abort_commands_when_storage_node_is_down) { document::Document::SP doc(_testDocRepo.createRandomDocumentAtLocation(1)); - CPPUNIT_ASSERT(downAbortsMessage<api::PutCommand>( - getBucketToAllow(), doc, api::Timestamp(1234))); - CPPUNIT_ASSERT(downAbortsMessage<api::SetBucketStateCommand>( - getBucketToAllow(), api::SetBucketStateCommand::ACTIVE)); + expectDownAbortsMessage<api::PutCommand>( + true, getBucketToAllow(), doc, api::Timestamp(1234)); + expectDownAbortsMessage<api::SetBucketStateCommand>( + true, getBucketToAllow(), api::SetBucketStateCommand::ACTIVE); } } // storage diff --git a/storage/src/tests/storageserver/communicationmanagertest.cpp b/storage/src/tests/storageserver/communicationmanagertest.cpp index 6af2733f3b9..b970e56343e 100644 --- a/storage/src/tests/storageserver/communicationmanagertest.cpp +++ b/storage/src/tests/storageserver/communicationmanagertest.cpp @@ -12,24 +12,17 @@ #include <tests/common/testhelper.h> #include <vespa/document/test/make_document_bucket.h> #include <vespa/documentapi/messagebus/messages/getdocumentmessage.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/documentapi/messagebus/messages/removedocumentmessage.h> #include <vespa/documentapi/messagebus/messages/getdocumentreply.h> +#include <vespa/vespalib/gtest/gtest.h> using document::test::makeDocumentBucket; +using namespace ::testing; namespace storage { -struct CommunicationManagerTest : public CppUnit::TestFixture { - void testSimple(); - void testDistPendingLimitConfigsArePropagatedToMessageBus(); - void testStorPendingLimitConfigsArePropagatedToMessageBus(); - void testCommandsAreDequeuedInFifoOrder(); - void testRepliesAreDequeuedInFifoOrder(); - void bucket_space_config_can_be_updated_live(); - void unmapped_bucket_space_documentapi_request_returns_error_reply(); - void unmapped_bucket_space_for_get_documentapi_request_returns_error_reply(); +struct CommunicationManagerTest : Test { static constexpr uint32_t MESSAGE_WAIT_TIME_SEC = 60; @@ -45,23 +38,9 @@ struct CommunicationManagerTest : public CppUnit::TestFixture { cmd->setPriority(priority); return cmd; } - - CPPUNIT_TEST_SUITE(CommunicationManagerTest); - CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(testDistPendingLimitConfigsArePropagatedToMessageBus); - CPPUNIT_TEST(testStorPendingLimitConfigsArePropagatedToMessageBus); - CPPUNIT_TEST(testCommandsAreDequeuedInFifoOrder); - CPPUNIT_TEST(testRepliesAreDequeuedInFifoOrder); - CPPUNIT_TEST(bucket_space_config_can_be_updated_live); - CPPUNIT_TEST(unmapped_bucket_space_documentapi_request_returns_error_reply); - CPPUNIT_TEST(unmapped_bucket_space_for_get_documentapi_request_returns_error_reply); - CPPUNIT_TEST_SUITE_END(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(CommunicationManagerTest); - -void CommunicationManagerTest::testSimple() -{ +TEST_F(CommunicationManagerTest, simple) { mbus::Slobrok slobrok; vdstestlib::DirConfig distConfig(getStandardConfig(false)); vdstestlib::DirConfig storConfig(getStandardConfig(true)); @@ -70,8 +49,8 @@ void CommunicationManagerTest::testSimple() addSlobrokConfig(distConfig, slobrok); addSlobrokConfig(storConfig, slobrok); - // Set up a "distributor" and a "storage" node with communication - // managers and a dummy storage link below we can use for testing. + // Set up a "distributor" and a "storage" node with communication + // managers and a dummy storage link below we can use for testing. TestServiceLayerApp storNode(storConfig.getConfigId()); TestDistributorApp distNode(distConfig.getConfigId()); @@ -89,30 +68,22 @@ void CommunicationManagerTest::testSimple() FastOS_Thread::Sleep(1000); // Send a message through from distributor to storage - std::shared_ptr<api::StorageCommand> cmd( - new api::GetCommand( - makeDocumentBucket(document::BucketId(0)), document::DocumentId("doc::mydoc"), "[all]")); - cmd->setAddress(api::StorageMessageAddress( - "storage", lib::NodeType::STORAGE, 1)); + auto cmd = std::make_shared<api::GetCommand>( + makeDocumentBucket(document::BucketId(0)), document::DocumentId("doc::mydoc"), "[all]"); + cmd->setAddress(api::StorageMessageAddress("storage", lib::NodeType::STORAGE, 1)); distributorLink->sendUp(cmd); storageLink->waitForMessages(1, MESSAGE_WAIT_TIME_SEC); - CPPUNIT_ASSERT(storageLink->getNumCommands() > 0); - std::shared_ptr<api::StorageCommand> cmd2( - std::dynamic_pointer_cast<api::StorageCommand>( - storageLink->getCommand(0))); - CPPUNIT_ASSERT_EQUAL( - vespalib::string("doc::mydoc"), - static_cast<api::GetCommand&>(*cmd2).getDocumentId().toString()); - // Reply to the message + ASSERT_GT(storageLink->getNumCommands(), 0); + auto cmd2 = std::dynamic_pointer_cast<api::StorageCommand>(storageLink->getCommand(0)); + EXPECT_EQ("doc::mydoc", dynamic_cast<api::GetCommand&>(*cmd2).getDocumentId().toString()); + // Reply to the message std::shared_ptr<api::StorageReply> reply(cmd2->makeReply().release()); storageLink->sendUp(reply); storageLink->sendUp(reply); distributorLink->waitForMessages(1, MESSAGE_WAIT_TIME_SEC); - CPPUNIT_ASSERT(distributorLink->getNumCommands() > 0); - std::shared_ptr<api::GetReply> reply2( - std::dynamic_pointer_cast<api::GetReply>( - distributorLink->getCommand(0))); - CPPUNIT_ASSERT_EQUAL(false, reply2->wasFound()); + ASSERT_GT(distributorLink->getNumCommands(), 0); + auto reply2 = std::dynamic_pointer_cast<api::GetReply>(distributorLink->getCommand(0)); + EXPECT_FALSE(reply2->wasFound()); } void @@ -144,11 +115,11 @@ CommunicationManagerTest::doTestConfigPropagation(bool isContentNode) // Outer type is RPCMessageBus, which wraps regular MessageBus. auto& mbus = commMgr.getMessageBus().getMessageBus(); if (isContentNode) { - CPPUNIT_ASSERT_EQUAL(uint32_t(12345), mbus.getMaxPendingCount()); - CPPUNIT_ASSERT_EQUAL(uint32_t(555666), mbus.getMaxPendingSize()); + EXPECT_EQ(12345, mbus.getMaxPendingCount()); + EXPECT_EQ(555666, mbus.getMaxPendingSize()); } else { - CPPUNIT_ASSERT_EQUAL(uint32_t(6789), mbus.getMaxPendingCount()); - CPPUNIT_ASSERT_EQUAL(uint32_t(777888), mbus.getMaxPendingSize()); + EXPECT_EQ(6789, mbus.getMaxPendingCount()); + EXPECT_EQ(777888, mbus.getMaxPendingSize()); } // Test live reconfig of limits. @@ -160,27 +131,21 @@ CommunicationManagerTest::doTestConfigPropagation(bool isContentNode) commMgr.configure(std::move(liveCfg)); if (isContentNode) { - CPPUNIT_ASSERT_EQUAL(uint32_t(777777), mbus.getMaxPendingCount()); + EXPECT_EQ(777777, mbus.getMaxPendingCount()); } else { - CPPUNIT_ASSERT_EQUAL(uint32_t(999999), mbus.getMaxPendingCount()); + EXPECT_EQ(999999, mbus.getMaxPendingCount()); } } -void -CommunicationManagerTest::testDistPendingLimitConfigsArePropagatedToMessageBus() -{ +TEST_F(CommunicationManagerTest, dist_pending_limit_configs_are_propagated_to_message_bus) { doTestConfigPropagation(false); } -void -CommunicationManagerTest::testStorPendingLimitConfigsArePropagatedToMessageBus() -{ +TEST_F(CommunicationManagerTest, stor_pending_limit_configs_are_propagated_to_message_bus) { doTestConfigPropagation(true); } -void -CommunicationManagerTest::testCommandsAreDequeuedInFifoOrder() -{ +TEST_F(CommunicationManagerTest, commands_are_dequeued_in_fifo_order) { mbus::Slobrok slobrok; vdstestlib::DirConfig storConfig(getStandardConfig(true)); storConfig.getConfig("stor-server").set("node_index", "1"); @@ -207,15 +172,13 @@ CommunicationManagerTest::testCommandsAreDequeuedInFifoOrder() for (size_t i = 0; i < pris.size(); ++i) { // Casting is just to avoid getting mismatched values printed to the // output verbatim as chars. - CPPUNIT_ASSERT_EQUAL( + EXPECT_EQ( uint32_t(pris[i]), uint32_t(storageLink->getCommand(i)->getPriority())); } } -void -CommunicationManagerTest::testRepliesAreDequeuedInFifoOrder() -{ +TEST_F(CommunicationManagerTest, replies_are_dequeued_in_fifo_order) { mbus::Slobrok slobrok; vdstestlib::DirConfig storConfig(getStandardConfig(true)); storConfig.getConfig("stor-server").set("node_index", "1"); @@ -236,7 +199,7 @@ CommunicationManagerTest::testRepliesAreDequeuedInFifoOrder() // Want FIFO order for replies, not priority-sorted order. for (size_t i = 0; i < pris.size(); ++i) { - CPPUNIT_ASSERT_EQUAL( + EXPECT_EQ( uint32_t(pris[i]), uint32_t(storageLink->getCommand(i)->getPriority())); } @@ -303,7 +266,7 @@ BucketspacesConfigBuilder::Documenttype doc_type(vespalib::stringref name, vespa } -void CommunicationManagerTest::bucket_space_config_can_be_updated_live() { +TEST_F(CommunicationManagerTest, bucket_space_config_can_be_updated_live) { CommunicationManagerFixture f; BucketspacesConfigBuilder config; config.documenttype.emplace_back(doc_type("foo", "default")); @@ -315,10 +278,10 @@ void CommunicationManagerTest::bucket_space_config_can_be_updated_live() { f.bottom_link->waitForMessages(2, MESSAGE_WAIT_TIME_SEC); auto cmd1 = f.bottom_link->getCommand(0); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::global_space(), cmd1->getBucket().getBucketSpace()); + EXPECT_EQ(document::FixedBucketSpaces::global_space(), cmd1->getBucket().getBucketSpace()); auto cmd2 = f.bottom_link->getCommand(1); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::default_space(), cmd2->getBucket().getBucketSpace()); + EXPECT_EQ(document::FixedBucketSpaces::default_space(), cmd2->getBucket().getBucketSpace()); config.documenttype[1] = doc_type("bar", "default"); f.comm_mgr->updateBucketSpacesConfig(config); @@ -326,30 +289,30 @@ void CommunicationManagerTest::bucket_space_config_can_be_updated_live() { f.bottom_link->waitForMessages(3, MESSAGE_WAIT_TIME_SEC); auto cmd3 = f.bottom_link->getCommand(2); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::default_space(), cmd3->getBucket().getBucketSpace()); + EXPECT_EQ(document::FixedBucketSpaces::default_space(), cmd3->getBucket().getBucketSpace()); - CPPUNIT_ASSERT_EQUAL(uint64_t(0), f.comm_mgr->metrics().bucketSpaceMappingFailures.getValue()); + EXPECT_EQ(uint64_t(0), f.comm_mgr->metrics().bucketSpaceMappingFailures.getValue()); } -void CommunicationManagerTest::unmapped_bucket_space_documentapi_request_returns_error_reply() { +TEST_F(CommunicationManagerTest, unmapped_bucket_space_documentapi_request_returns_error_reply) { CommunicationManagerFixture f; BucketspacesConfigBuilder config; config.documenttype.emplace_back(doc_type("foo", "default")); f.comm_mgr->updateBucketSpacesConfig(config); - CPPUNIT_ASSERT_EQUAL(uint64_t(0), f.comm_mgr->metrics().bucketSpaceMappingFailures.getValue()); + EXPECT_EQ(uint64_t(0), f.comm_mgr->metrics().bucketSpaceMappingFailures.getValue()); f.comm_mgr->handleMessage(f.documentapi_remove_message_for_space("fluff")); - CPPUNIT_ASSERT_EQUAL(size_t(1), f.reply_handler.replies.size()); + ASSERT_EQ(1, f.reply_handler.replies.size()); auto& reply = *f.reply_handler.replies[0]; - CPPUNIT_ASSERT(reply.hasErrors()); - CPPUNIT_ASSERT_EQUAL(static_cast<uint32_t>(api::ReturnCode::REJECTED), reply.getError(0).getCode()); + ASSERT_TRUE(reply.hasErrors()); + EXPECT_EQ(static_cast<uint32_t>(api::ReturnCode::REJECTED), reply.getError(0).getCode()); - CPPUNIT_ASSERT_EQUAL(uint64_t(1), f.comm_mgr->metrics().bucketSpaceMappingFailures.getValue()); + EXPECT_EQ(uint64_t(1), f.comm_mgr->metrics().bucketSpaceMappingFailures.getValue()); } -void CommunicationManagerTest::unmapped_bucket_space_for_get_documentapi_request_returns_error_reply() { +TEST_F(CommunicationManagerTest, unmapped_bucket_space_for_get_documentapi_request_returns_error_reply) { CommunicationManagerFixture f; BucketspacesConfigBuilder config; @@ -357,11 +320,11 @@ void CommunicationManagerTest::unmapped_bucket_space_for_get_documentapi_request f.comm_mgr->updateBucketSpacesConfig(config); f.comm_mgr->handleMessage(f.documentapi_get_message_for_space("fluff")); - CPPUNIT_ASSERT_EQUAL(size_t(1), f.reply_handler.replies.size()); + ASSERT_EQ(1, f.reply_handler.replies.size()); auto& reply = *f.reply_handler.replies[0]; - CPPUNIT_ASSERT(reply.hasErrors()); - CPPUNIT_ASSERT_EQUAL(static_cast<uint32_t>(api::ReturnCode::REJECTED), reply.getError(0).getCode()); - CPPUNIT_ASSERT_EQUAL(uint64_t(1), f.comm_mgr->metrics().bucketSpaceMappingFailures.getValue()); + ASSERT_TRUE(reply.hasErrors()); + EXPECT_EQ(static_cast<uint32_t>(api::ReturnCode::REJECTED), reply.getError(0).getCode()); + EXPECT_EQ(uint64_t(1), f.comm_mgr->metrics().bucketSpaceMappingFailures.getValue()); } } // storage diff --git a/storage/src/tests/storageserver/configurable_bucket_resolver_test.cpp b/storage/src/tests/storageserver/configurable_bucket_resolver_test.cpp index c10db0a1acd..5797074f892 100644 --- a/storage/src/tests/storageserver/configurable_bucket_resolver_test.cpp +++ b/storage/src/tests/storageserver/configurable_bucket_resolver_test.cpp @@ -3,26 +3,14 @@ #include <vespa/storage/storageserver/configurable_bucket_resolver.h> #include <vespa/document/base/documentid.h> #include <vespa/document/bucket/fixed_bucket_spaces.h> -#include <cppunit/extensions/HelperMacros.h> +#include <vespa/vespalib/gtest/gtest.h> namespace storage { using document::DocumentId; +using namespace ::testing; -struct ConfigurableBucketResolverTest : CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(ConfigurableBucketResolverTest); - CPPUNIT_TEST(bucket_space_from_name_is_defined_for_default_space); - CPPUNIT_TEST(bucket_space_from_name_is_defined_for_global_space); - CPPUNIT_TEST(bucket_space_from_name_throws_exception_for_unknown_space); - CPPUNIT_TEST(name_from_bucket_space_is_defined_for_default_space); - CPPUNIT_TEST(name_from_bucket_space_is_defined_for_global_space); - CPPUNIT_TEST(name_from_bucket_space_throws_exception_for_unknown_space); - CPPUNIT_TEST(known_bucket_space_is_resolved_from_document_id); - CPPUNIT_TEST(unknown_bucket_space_in_id_throws_exception); - CPPUNIT_TEST(can_create_resolver_from_bucket_space_config); - CPPUNIT_TEST(legacy_document_id_without_document_type_maps_to_default_space); - CPPUNIT_TEST_SUITE_END(); - +struct ConfigurableBucketResolverTest : Test { using BucketSpaceMapping = ConfigurableBucketResolver::BucketSpaceMapping; BucketSpaceMapping create_simple_mapping() { @@ -38,74 +26,50 @@ struct ConfigurableBucketResolverTest : CppUnit::TestFixture { ConfigurableBucketResolver create_simple_resolver() { return ConfigurableBucketResolver(create_simple_mapping()); } - - void bucket_space_from_name_is_defined_for_default_space(); - void bucket_space_from_name_is_defined_for_global_space(); - void bucket_space_from_name_throws_exception_for_unknown_space(); - void name_from_bucket_space_is_defined_for_default_space(); - void name_from_bucket_space_is_defined_for_global_space(); - void name_from_bucket_space_throws_exception_for_unknown_space(); - void known_bucket_space_is_resolved_from_document_id(); - void unknown_bucket_space_in_id_throws_exception(); - void can_create_resolver_from_bucket_space_config(); - void legacy_document_id_without_document_type_maps_to_default_space(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(ConfigurableBucketResolverTest); - // TODO reduce overlap with FixedBucketSpacesTest -void ConfigurableBucketResolverTest::bucket_space_from_name_is_defined_for_default_space() { +TEST_F(ConfigurableBucketResolverTest, bucket_space_from_name_is_defined_for_default_space) { auto space = create_empty_resolver().bucketSpaceFromName("default"); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::default_space(), space); + EXPECT_EQ(document::FixedBucketSpaces::default_space(), space); } -void ConfigurableBucketResolverTest::bucket_space_from_name_is_defined_for_global_space() { +TEST_F(ConfigurableBucketResolverTest, bucket_space_from_name_is_defined_for_global_space) { auto space = create_empty_resolver().bucketSpaceFromName("global"); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::global_space(), space); + EXPECT_EQ(document::FixedBucketSpaces::global_space(), space); } -void ConfigurableBucketResolverTest::bucket_space_from_name_throws_exception_for_unknown_space() { - try { - create_empty_resolver().bucketSpaceFromName("bjarne"); - CPPUNIT_FAIL("Expected exception on unknown bucket space name"); - } catch (document::UnknownBucketSpaceException& e) { - } +TEST_F(ConfigurableBucketResolverTest, bucket_space_from_name_throws_exception_for_unknown_space) { + EXPECT_THROW(create_empty_resolver().bucketSpaceFromName("bjarne"), + document::UnknownBucketSpaceException); } -void ConfigurableBucketResolverTest::name_from_bucket_space_is_defined_for_default_space() { - CPPUNIT_ASSERT_EQUAL(vespalib::string("default"), - create_empty_resolver().nameFromBucketSpace(document::FixedBucketSpaces::default_space())); +TEST_F(ConfigurableBucketResolverTest, name_from_bucket_space_is_defined_for_default_space) { + EXPECT_EQ("default", create_empty_resolver().nameFromBucketSpace(document::FixedBucketSpaces::default_space())); } -void ConfigurableBucketResolverTest::name_from_bucket_space_is_defined_for_global_space() { - CPPUNIT_ASSERT_EQUAL(vespalib::string("global"), - create_empty_resolver().nameFromBucketSpace(document::FixedBucketSpaces::global_space())); +TEST_F(ConfigurableBucketResolverTest, name_from_bucket_space_is_defined_for_global_space) { + EXPECT_EQ("global", create_empty_resolver().nameFromBucketSpace(document::FixedBucketSpaces::global_space())); } -void ConfigurableBucketResolverTest::name_from_bucket_space_throws_exception_for_unknown_space() { - try { - create_empty_resolver().nameFromBucketSpace(document::BucketSpace(1234)); - CPPUNIT_FAIL("Expected exception on unknown bucket space value"); - } catch (document::UnknownBucketSpaceException& e) { - } +TEST_F(ConfigurableBucketResolverTest, name_from_bucket_space_throws_exception_for_unknown_space) { + EXPECT_THROW(create_empty_resolver().nameFromBucketSpace(document::BucketSpace(1234)), + document::UnknownBucketSpaceException); } -void ConfigurableBucketResolverTest::known_bucket_space_is_resolved_from_document_id() { +TEST_F(ConfigurableBucketResolverTest, known_bucket_space_is_resolved_from_document_id) { auto resolver = create_simple_resolver(); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::default_space(), - resolver.bucketFromId(DocumentId("id::foo::xyz")).getBucketSpace()); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::default_space(), - resolver.bucketFromId(DocumentId("id::bar::xyz")).getBucketSpace()); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::global_space(), - resolver.bucketFromId(DocumentId("id::baz::xyz")).getBucketSpace()); + EXPECT_EQ(document::FixedBucketSpaces::default_space(), + resolver.bucketFromId(DocumentId("id::foo::xyz")).getBucketSpace()); + EXPECT_EQ(document::FixedBucketSpaces::default_space(), + resolver.bucketFromId(DocumentId("id::bar::xyz")).getBucketSpace()); + EXPECT_EQ(document::FixedBucketSpaces::global_space(), + resolver.bucketFromId(DocumentId("id::baz::xyz")).getBucketSpace()); } -void ConfigurableBucketResolverTest::unknown_bucket_space_in_id_throws_exception() { - try { - create_simple_resolver().bucketFromId(DocumentId("id::bjarne::xyz")); - CPPUNIT_FAIL("Expected exception on unknown document type -> bucket space mapping"); - } catch (document::UnknownBucketSpaceException& e) { - } +TEST_F(ConfigurableBucketResolverTest, unknown_bucket_space_in_id_throws_exception) { + EXPECT_THROW(create_simple_resolver().bucketFromId(DocumentId("id::bjarne::xyz")), + document::UnknownBucketSpaceException); } using BucketSpacesConfigBuilder = vespa::config::content::core::BucketspacesConfigBuilder; @@ -121,24 +85,24 @@ BucketSpacesConfigBuilder::Documenttype make_doc_type(vespalib::stringref name, } -void ConfigurableBucketResolverTest::can_create_resolver_from_bucket_space_config() { +TEST_F(ConfigurableBucketResolverTest, can_create_resolver_from_bucket_space_config) { BucketSpacesConfigBuilder builder; builder.documenttype.emplace_back(make_doc_type("foo", "default")); builder.documenttype.emplace_back(make_doc_type("bar", "global")); builder.documenttype.emplace_back(make_doc_type("baz", "global")); auto resolver = ConfigurableBucketResolver::from_config(builder); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::default_space(), - resolver->bucketFromId(DocumentId("id::foo::xyz")).getBucketSpace()); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::global_space(), - resolver->bucketFromId(DocumentId("id::bar::xyz")).getBucketSpace()); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::global_space(), - resolver->bucketFromId(DocumentId("id::baz::xyz")).getBucketSpace()); + EXPECT_EQ(document::FixedBucketSpaces::default_space(), + resolver->bucketFromId(DocumentId("id::foo::xyz")).getBucketSpace()); + EXPECT_EQ(document::FixedBucketSpaces::global_space(), + resolver->bucketFromId(DocumentId("id::bar::xyz")).getBucketSpace()); + EXPECT_EQ(document::FixedBucketSpaces::global_space(), + resolver->bucketFromId(DocumentId("id::baz::xyz")).getBucketSpace()); } -void ConfigurableBucketResolverTest::legacy_document_id_without_document_type_maps_to_default_space() { +TEST_F(ConfigurableBucketResolverTest, legacy_document_id_without_document_type_maps_to_default_space) { auto resolver = create_simple_resolver(); - CPPUNIT_ASSERT_EQUAL(document::FixedBucketSpaces::default_space(), - resolver.bucketFromId(DocumentId("userdoc:baz:1234:baz")).getBucketSpace()); + EXPECT_EQ(document::FixedBucketSpaces::default_space(), + resolver.bucketFromId(DocumentId("userdoc:baz:1234:baz")).getBucketSpace()); } } diff --git a/storage/src/tests/storageserver/documentapiconvertertest.cpp b/storage/src/tests/storageserver/documentapiconvertertest.cpp index 7f8b1b8f34a..c879f7d2779 100644 --- a/storage/src/tests/storageserver/documentapiconvertertest.cpp +++ b/storage/src/tests/storageserver/documentapiconvertertest.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 <vespa/config/subscription/configuri.h> #include <vespa/document/base/testdocrepo.h> #include <vespa/document/bucket/bucketidfactory.h> @@ -17,7 +16,7 @@ #include <vespa/storageapi/message/persistence.h> #include <vespa/storageapi/message/removelocation.h> #include <vespa/storageapi/message/stat.h> -#include <vespa/vespalib/testkit/test_kit.h> +#include <vespa/vespalib/gtest/gtest.h> using document::Bucket; using document::BucketId; @@ -29,6 +28,7 @@ using document::DocumentId; using document::DocumentTypeRepo; using document::readDocumenttypesConfig; using document::test::makeDocumentBucket; +using namespace ::testing; namespace storage { @@ -58,8 +58,7 @@ struct MockBucketResolver : public BucketResolver { } }; -struct DocumentApiConverterTest : public CppUnit::TestFixture -{ +struct DocumentApiConverterTest : Test { std::shared_ptr<MockBucketResolver> _bucketResolver; std::unique_ptr<DocumentApiConverter> _converter; const std::shared_ptr<const DocumentTypeRepo> _repo; @@ -67,20 +66,19 @@ struct DocumentApiConverterTest : public CppUnit::TestFixture DocumentApiConverterTest() : _bucketResolver(std::make_shared<MockBucketResolver>()), - _repo(std::make_shared<DocumentTypeRepo>(readDocumenttypesConfig( - TEST_PATH("config-doctypes.cfg")))), + _repo(std::make_shared<DocumentTypeRepo>(readDocumenttypesConfig("../config-doctypes.cfg"))), _html_type(*_repo->getDocumentType("text/html")) { } - void setUp() override { - _converter.reset(new DocumentApiConverter("raw:", _bucketResolver)); + void SetUp() override { + _converter = std::make_unique<DocumentApiConverter>("raw:", _bucketResolver); }; template <typename DerivedT, typename BaseT> std::unique_ptr<DerivedT> dynamic_unique_ptr_cast(std::unique_ptr<BaseT> base) { auto derived = dynamic_cast<DerivedT*>(base.get()); - CPPUNIT_ASSERT(derived); + assert(derived); base.release(); return std::unique_ptr<DerivedT>(derived); } @@ -103,162 +101,119 @@ struct DocumentApiConverterTest : public CppUnit::TestFixture auto result = _converter->toDocumentAPI(cmd); return dynamic_unique_ptr_cast<T>(std::move(result)); } - - void testPut(); - void testForwardedPut(); - void testUpdate(); - void testRemove(); - void testGet(); - void testCreateVisitor(); - void testCreateVisitorHighTimeout(); - void testCreateVisitorReplyNotReady(); - void testCreateVisitorReplyLastBucket(); - void testDestroyVisitor(); - void testVisitorInfo(); - void testStatBucket(); - void testGetBucketList(); - void testRemoveLocation(); - void can_replace_bucket_resolver_after_construction(); - - CPPUNIT_TEST_SUITE(DocumentApiConverterTest); - CPPUNIT_TEST(testPut); - CPPUNIT_TEST(testForwardedPut); - CPPUNIT_TEST(testUpdate); - CPPUNIT_TEST(testRemove); - CPPUNIT_TEST(testGet); - CPPUNIT_TEST(testCreateVisitor); - CPPUNIT_TEST(testCreateVisitorHighTimeout); - CPPUNIT_TEST(testCreateVisitorReplyNotReady); - CPPUNIT_TEST(testCreateVisitorReplyLastBucket); - CPPUNIT_TEST(testDestroyVisitor); - CPPUNIT_TEST(testVisitorInfo); - CPPUNIT_TEST(testStatBucket); - CPPUNIT_TEST(testGetBucketList); - CPPUNIT_TEST(testRemoveLocation); - CPPUNIT_TEST(can_replace_bucket_resolver_after_construction); - CPPUNIT_TEST_SUITE_END(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(DocumentApiConverterTest); - -void DocumentApiConverterTest::testPut() -{ +TEST_F(DocumentApiConverterTest, put) { auto doc = std::make_shared<Document>(_html_type, defaultDocId); documentapi::PutDocumentMessage putmsg(doc); putmsg.setTimestamp(1234); auto cmd = toStorageAPI<api::PutCommand>(putmsg); - CPPUNIT_ASSERT_EQUAL(defaultBucket, cmd->getBucket()); - CPPUNIT_ASSERT(cmd->getDocument().get() == doc.get()); + EXPECT_EQ(defaultBucket, cmd->getBucket()); + ASSERT_EQ(cmd->getDocument().get(), doc.get()); std::unique_ptr<mbus::Reply> reply = putmsg.createReply(); - CPPUNIT_ASSERT(reply.get()); + ASSERT_TRUE(reply.get()); toStorageAPI<api::PutReply>(*reply, *cmd); auto mbusPut = toDocumentAPI<documentapi::PutDocumentMessage>(*cmd); - CPPUNIT_ASSERT(mbusPut->getDocumentSP().get() == doc.get()); - CPPUNIT_ASSERT(mbusPut->getTimestamp() == 1234); + ASSERT_EQ(mbusPut->getDocumentSP().get(), doc.get()); + EXPECT_EQ(mbusPut->getTimestamp(), 1234); } -void DocumentApiConverterTest::testForwardedPut() -{ +TEST_F(DocumentApiConverterTest, forwarded_put) { auto doc = std::make_shared<Document>(_html_type, DocumentId(DocIdString("test", "test"))); - documentapi::PutDocumentMessage* putmsg = new documentapi::PutDocumentMessage(doc); - std::unique_ptr<mbus::Reply> reply(((documentapi::DocumentMessage*)putmsg)->createReply()); - reply->setMessage(std::unique_ptr<mbus::Message>(putmsg)); + auto putmsg = std::make_unique<documentapi::PutDocumentMessage>(doc); + auto* putmsg_raw = putmsg.get(); + std::unique_ptr<mbus::Reply> reply(putmsg->createReply()); + reply->setMessage(std::unique_ptr<mbus::Message>(putmsg.release())); - auto cmd = toStorageAPI<api::PutCommand>(*putmsg); + auto cmd = toStorageAPI<api::PutCommand>(*putmsg_raw); cmd->setTimestamp(1234); auto rep = dynamic_unique_ptr_cast<api::PutReply>(cmd->makeReply()); _converter->transferReplyState(*rep, *reply); } -void DocumentApiConverterTest::testUpdate() -{ +TEST_F(DocumentApiConverterTest, update) { auto update = std::make_shared<document::DocumentUpdate>(*_repo, _html_type, defaultDocId); documentapi::UpdateDocumentMessage updateMsg(update); updateMsg.setOldTimestamp(1234); updateMsg.setNewTimestamp(5678); auto updateCmd = toStorageAPI<api::UpdateCommand>(updateMsg); - CPPUNIT_ASSERT_EQUAL(defaultBucket, updateCmd->getBucket()); - CPPUNIT_ASSERT_EQUAL(update.get(), updateCmd->getUpdate().get()); - CPPUNIT_ASSERT_EQUAL(api::Timestamp(1234), updateCmd->getOldTimestamp()); - CPPUNIT_ASSERT_EQUAL(api::Timestamp(5678), updateCmd->getTimestamp()); + EXPECT_EQ(defaultBucket, updateCmd->getBucket()); + ASSERT_EQ(update.get(), updateCmd->getUpdate().get()); + EXPECT_EQ(api::Timestamp(1234), updateCmd->getOldTimestamp()); + EXPECT_EQ(api::Timestamp(5678), updateCmd->getTimestamp()); auto mbusReply = updateMsg.createReply(); - CPPUNIT_ASSERT(mbusReply.get()); + ASSERT_TRUE(mbusReply.get()); toStorageAPI<api::UpdateReply>(*mbusReply, *updateCmd); auto mbusUpdate = toDocumentAPI<documentapi::UpdateDocumentMessage>(*updateCmd); - CPPUNIT_ASSERT((&mbusUpdate->getDocumentUpdate()) == update.get()); - CPPUNIT_ASSERT_EQUAL(api::Timestamp(1234), mbusUpdate->getOldTimestamp()); - CPPUNIT_ASSERT_EQUAL(api::Timestamp(5678), mbusUpdate->getNewTimestamp()); + ASSERT_EQ((&mbusUpdate->getDocumentUpdate()), update.get()); + EXPECT_EQ(api::Timestamp(1234), mbusUpdate->getOldTimestamp()); + EXPECT_EQ(api::Timestamp(5678), mbusUpdate->getNewTimestamp()); } -void DocumentApiConverterTest::testRemove() -{ +TEST_F(DocumentApiConverterTest, remove) { documentapi::RemoveDocumentMessage removemsg(defaultDocId); auto cmd = toStorageAPI<api::RemoveCommand>(removemsg); - CPPUNIT_ASSERT_EQUAL(defaultBucket, cmd->getBucket()); - CPPUNIT_ASSERT_EQUAL(defaultDocId, cmd->getDocumentId()); + EXPECT_EQ(defaultBucket, cmd->getBucket()); + EXPECT_EQ(defaultDocId, cmd->getDocumentId()); std::unique_ptr<mbus::Reply> reply = removemsg.createReply(); - CPPUNIT_ASSERT(reply.get()); + ASSERT_TRUE(reply.get()); toStorageAPI<api::RemoveReply>(*reply, *cmd); auto mbusRemove = toDocumentAPI<documentapi::RemoveDocumentMessage>(*cmd); - CPPUNIT_ASSERT_EQUAL(defaultDocId, mbusRemove->getDocumentId()); + EXPECT_EQ(defaultDocId, mbusRemove->getDocumentId()); } -void DocumentApiConverterTest::testGet() -{ +TEST_F(DocumentApiConverterTest, get) { documentapi::GetDocumentMessage getmsg(defaultDocId, "foo bar"); auto cmd = toStorageAPI<api::GetCommand>(getmsg); - CPPUNIT_ASSERT_EQUAL(defaultBucket, cmd->getBucket()); - CPPUNIT_ASSERT_EQUAL(defaultDocId, cmd->getDocumentId()); - CPPUNIT_ASSERT_EQUAL(vespalib::string("foo bar"), cmd->getFieldSet()); + EXPECT_EQ(defaultBucket, cmd->getBucket()); + EXPECT_EQ(defaultDocId, cmd->getDocumentId()); + EXPECT_EQ("foo bar", cmd->getFieldSet()); } -void DocumentApiConverterTest::testCreateVisitor() -{ +TEST_F(DocumentApiConverterTest, create_visitor) { documentapi::CreateVisitorMessage cv("mylib", "myinstance", "control-dest", "data-dest"); cv.setBucketSpace(defaultSpaceName); cv.setTimeRemaining(123456); auto cmd = toStorageAPI<api::CreateVisitorCommand>(cv); - CPPUNIT_ASSERT_EQUAL(defaultBucketSpace, cmd->getBucket().getBucketSpace()); - CPPUNIT_ASSERT_EQUAL(vespalib::string("mylib"), cmd->getLibraryName()); - CPPUNIT_ASSERT_EQUAL(vespalib::string("myinstance"), cmd->getInstanceId()); - CPPUNIT_ASSERT_EQUAL(vespalib::string("control-dest"), cmd->getControlDestination()); - CPPUNIT_ASSERT_EQUAL(vespalib::string("data-dest"), cmd->getDataDestination()); - CPPUNIT_ASSERT_EQUAL(123456u, cmd->getTimeout()); + EXPECT_EQ(defaultBucketSpace, cmd->getBucket().getBucketSpace()); + EXPECT_EQ("mylib", cmd->getLibraryName()); + EXPECT_EQ("myinstance", cmd->getInstanceId()); + EXPECT_EQ("control-dest", cmd->getControlDestination()); + EXPECT_EQ("data-dest", cmd->getDataDestination()); + EXPECT_EQ(123456u, cmd->getTimeout()); auto msg = toDocumentAPI<documentapi::CreateVisitorMessage>(*cmd); - CPPUNIT_ASSERT_EQUAL(defaultSpaceName, msg->getBucketSpace()); + EXPECT_EQ(defaultSpaceName, msg->getBucketSpace()); } -void DocumentApiConverterTest::testCreateVisitorHighTimeout() -{ +TEST_F(DocumentApiConverterTest, create_visitor_high_timeout) { documentapi::CreateVisitorMessage cv("mylib", "myinstance", "control-dest", "data-dest"); cv.setTimeRemaining((uint64_t)std::numeric_limits<uint32_t>::max() + 1); // Will be INT_MAX auto cmd = toStorageAPI<api::CreateVisitorCommand>(cv); - CPPUNIT_ASSERT_EQUAL(vespalib::string("mylib"), cmd->getLibraryName()); - CPPUNIT_ASSERT_EQUAL(vespalib::string("myinstance"), cmd->getInstanceId()); - CPPUNIT_ASSERT_EQUAL(vespalib::string("control-dest"), cmd->getControlDestination()); - CPPUNIT_ASSERT_EQUAL(vespalib::string("data-dest"), cmd->getDataDestination()); - CPPUNIT_ASSERT_EQUAL((uint32_t) std::numeric_limits<int32_t>::max(), cmd->getTimeout()); + EXPECT_EQ("mylib", cmd->getLibraryName()); + EXPECT_EQ("myinstance", cmd->getInstanceId()); + EXPECT_EQ("control-dest", cmd->getControlDestination()); + EXPECT_EQ("data-dest", cmd->getDataDestination()); + EXPECT_EQ(std::numeric_limits<int32_t>::max(), cmd->getTimeout()); } -void DocumentApiConverterTest::testCreateVisitorReplyNotReady() -{ +TEST_F(DocumentApiConverterTest, create_visitor_reply_not_ready) { documentapi::CreateVisitorMessage cv("mylib", "myinstance", "control-dest", "data-dest"); auto cmd = toStorageAPI<api::CreateVisitorCommand>(cv); @@ -267,14 +222,13 @@ void DocumentApiConverterTest::testCreateVisitorReplyNotReady() std::unique_ptr<documentapi::CreateVisitorReply> reply( dynamic_cast<documentapi::CreateVisitorReply*>(cv.createReply().release())); - CPPUNIT_ASSERT(reply.get()); + ASSERT_TRUE(reply.get()); _converter->transferReplyState(cvr, *reply); - CPPUNIT_ASSERT_EQUAL((uint32_t)documentapi::DocumentProtocol::ERROR_NODE_NOT_READY, reply->getError(0).getCode()); - CPPUNIT_ASSERT_EQUAL(document::BucketId(std::numeric_limits<int>::max()), reply->getLastBucket()); + EXPECT_EQ(documentapi::DocumentProtocol::ERROR_NODE_NOT_READY, reply->getError(0).getCode()); + EXPECT_EQ(document::BucketId(std::numeric_limits<int>::max()), reply->getLastBucket()); } -void DocumentApiConverterTest::testCreateVisitorReplyLastBucket() -{ +TEST_F(DocumentApiConverterTest, create_visitor_reply_last_bucket) { documentapi::CreateVisitorMessage cv("mylib", "myinstance", "control-dest", "data-dest"); auto cmd = toStorageAPI<api::CreateVisitorCommand>(cv); @@ -283,75 +237,66 @@ void DocumentApiConverterTest::testCreateVisitorReplyLastBucket() std::unique_ptr<documentapi::CreateVisitorReply> reply( dynamic_cast<documentapi::CreateVisitorReply*>(cv.createReply().release())); - CPPUNIT_ASSERT(reply.get()); + ASSERT_TRUE(reply.get()); _converter->transferReplyState(cvr, *reply); - CPPUNIT_ASSERT_EQUAL(document::BucketId(123), reply->getLastBucket()); + EXPECT_EQ(document::BucketId(123), reply->getLastBucket()); } -void DocumentApiConverterTest::testDestroyVisitor() -{ +TEST_F(DocumentApiConverterTest, destroy_visitor) { documentapi::DestroyVisitorMessage cv("myinstance"); auto cmd = toStorageAPI<api::DestroyVisitorCommand>(cv); - CPPUNIT_ASSERT_EQUAL(vespalib::string("myinstance"), cmd->getInstanceId()); + EXPECT_EQ("myinstance", cmd->getInstanceId()); } -void -DocumentApiConverterTest::testVisitorInfo() -{ +TEST_F(DocumentApiConverterTest, visitor_info) { api::VisitorInfoCommand vicmd; std::vector<api::VisitorInfoCommand::BucketTimestampPair> bucketsCompleted; - bucketsCompleted.push_back(api::VisitorInfoCommand::BucketTimestampPair(document::BucketId(16, 1), 0)); - bucketsCompleted.push_back(api::VisitorInfoCommand::BucketTimestampPair(document::BucketId(16, 2), 0)); - bucketsCompleted.push_back(api::VisitorInfoCommand::BucketTimestampPair(document::BucketId(16, 4), 0)); + bucketsCompleted.emplace_back(document::BucketId(16, 1), 0); + bucketsCompleted.emplace_back(document::BucketId(16, 2), 0); + bucketsCompleted.emplace_back(document::BucketId(16, 4), 0); vicmd.setBucketsCompleted(bucketsCompleted); auto mbusvi = toDocumentAPI<documentapi::VisitorInfoMessage>(vicmd); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 1), mbusvi->getFinishedBuckets()[0]); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 2), mbusvi->getFinishedBuckets()[1]); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 4), mbusvi->getFinishedBuckets()[2]); + EXPECT_EQ(document::BucketId(16, 1), mbusvi->getFinishedBuckets()[0]); + EXPECT_EQ(document::BucketId(16, 2), mbusvi->getFinishedBuckets()[1]); + EXPECT_EQ(document::BucketId(16, 4), mbusvi->getFinishedBuckets()[2]); std::unique_ptr<mbus::Reply> reply = mbusvi->createReply(); - CPPUNIT_ASSERT(reply.get()); + ASSERT_TRUE(reply.get()); toStorageAPI<api::VisitorInfoReply>(*reply, vicmd); } -void -DocumentApiConverterTest::testStatBucket() -{ +TEST_F(DocumentApiConverterTest, stat_bucket) { documentapi::StatBucketMessage msg(BucketId(123), ""); msg.setBucketSpace(defaultSpaceName); auto cmd = toStorageAPI<api::StatBucketCommand>(msg); - CPPUNIT_ASSERT_EQUAL(Bucket(defaultBucketSpace, BucketId(123)), cmd->getBucket()); + EXPECT_EQ(Bucket(defaultBucketSpace, BucketId(123)), cmd->getBucket()); auto mbusMsg = toDocumentAPI<documentapi::StatBucketMessage>(*cmd); - CPPUNIT_ASSERT_EQUAL(BucketId(123), mbusMsg->getBucketId()); - CPPUNIT_ASSERT_EQUAL(defaultSpaceName, mbusMsg->getBucketSpace()); + EXPECT_EQ(BucketId(123), mbusMsg->getBucketId()); + EXPECT_EQ(defaultSpaceName, mbusMsg->getBucketSpace()); } -void -DocumentApiConverterTest::testGetBucketList() -{ +TEST_F(DocumentApiConverterTest, get_bucket_list) { documentapi::GetBucketListMessage msg(BucketId(123)); msg.setBucketSpace(defaultSpaceName); auto cmd = toStorageAPI<api::GetBucketListCommand>(msg); - CPPUNIT_ASSERT_EQUAL(Bucket(defaultBucketSpace, BucketId(123)), cmd->getBucket()); + EXPECT_EQ(Bucket(defaultBucketSpace, BucketId(123)), cmd->getBucket()); } -void -DocumentApiConverterTest::testRemoveLocation() -{ +TEST_F(DocumentApiConverterTest, remove_location) { document::BucketIdFactory factory; document::select::Parser parser(*_repo, factory); documentapi::RemoveLocationMessage msg(factory, parser, "id.group == \"mygroup\""); msg.setBucketSpace(defaultSpaceName); auto cmd = toStorageAPI<api::RemoveLocationCommand>(msg); - CPPUNIT_ASSERT_EQUAL(defaultBucket, cmd->getBucket()); + EXPECT_EQ(defaultBucket, cmd->getBucket()); } namespace { @@ -367,16 +312,16 @@ struct ReplacementMockBucketResolver : public MockBucketResolver { } -void DocumentApiConverterTest::can_replace_bucket_resolver_after_construction() { +TEST_F(DocumentApiConverterTest, can_replace_bucket_resolver_after_construction) { documentapi::GetDocumentMessage get_msg(DocumentId("id::testdoctype1::baz"), "foo bar"); auto cmd = toStorageAPI<api::GetCommand>(get_msg); - CPPUNIT_ASSERT_EQUAL(BucketSpace(0), cmd->getBucket().getBucketSpace()); + EXPECT_EQ(BucketSpace(0), cmd->getBucket().getBucketSpace()); _converter->setBucketResolver(std::make_shared<ReplacementMockBucketResolver>()); cmd = toStorageAPI<api::GetCommand>(get_msg); - CPPUNIT_ASSERT_EQUAL(defaultBucketSpace, cmd->getBucket().getBucketSpace()); + EXPECT_EQ(defaultBucketSpace, cmd->getBucket().getBucketSpace()); } } diff --git a/storage/src/tests/storageserver/fnet_listener_test.cpp b/storage/src/tests/storageserver/fnet_listener_test.cpp index d40b230d725..b9f2ca74df3 100644 --- a/storage/src/tests/storageserver/fnet_listener_test.cpp +++ b/storage/src/tests/storageserver/fnet_listener_test.cpp @@ -8,43 +8,20 @@ #include <vespa/storageapi/message/state.h> #include <vespa/vdslib/state/clusterstate.h> #include <vespa/vespalib/stllike/asciistream.h> -#include <vespa/vdstestlib/cppunit/macros.h> -#include <vespa/vdstestlib/cppunit/dirconfig.h> +#include <vespa/vdstestlib/cppunit/dirconfig.hpp> #include <vespa/messagebus/testlib/slobrok.h> #include <tests/common/testhelper.h> +#include <vespa/vespalib/gtest/gtest.h> #include <vector> namespace storage { using document::FixedBucketSpaces; +using namespace ::testing; -class FNetListenerTest : public CppUnit::TestFixture { -public: - CPPUNIT_TEST_SUITE(FNetListenerTest); - CPPUNIT_TEST(baseline_set_distribution_states_rpc_enqueues_command_with_state_bundle); - CPPUNIT_TEST(set_distribution_states_rpc_with_derived_enqueues_command_with_state_bundle); - CPPUNIT_TEST(compressed_bundle_is_transparently_uncompressed); - CPPUNIT_TEST(set_distribution_rpc_is_immediately_failed_if_listener_is_closed); - CPPUNIT_TEST(overly_large_uncompressed_bundle_size_parameter_returns_rpc_error); - CPPUNIT_TEST(mismatching_uncompressed_bundle_size_parameter_returns_rpc_error); - CPPUNIT_TEST(true_deferred_activation_flag_can_be_roundtrip_encoded); - CPPUNIT_TEST(false_deferred_activation_flag_can_be_roundtrip_encoded); - CPPUNIT_TEST(activate_cluster_state_version_rpc_enqueues_command_with_version); - CPPUNIT_TEST_SUITE_END(); - - void baseline_set_distribution_states_rpc_enqueues_command_with_state_bundle(); - void set_distribution_states_rpc_with_derived_enqueues_command_with_state_bundle(); - void compressed_bundle_is_transparently_uncompressed(); - void set_distribution_rpc_is_immediately_failed_if_listener_is_closed(); - void overly_large_uncompressed_bundle_size_parameter_returns_rpc_error(); - void mismatching_uncompressed_bundle_size_parameter_returns_rpc_error(); - void true_deferred_activation_flag_can_be_roundtrip_encoded(); - void false_deferred_activation_flag_can_be_roundtrip_encoded(); - void activate_cluster_state_version_rpc_enqueues_command_with_version(); +struct FNetListenerTest : Test { }; -CPPUNIT_TEST_SUITE_REGISTRATION(FNetListenerTest); - namespace { struct MockOperationEnqueuer : MessageEnqueuer { @@ -113,11 +90,11 @@ struct SetStateFixture : FixtureBase { } void assert_enqueued_operation_has_bundle(const lib::ClusterStateBundle& expectedBundle) { - CPPUNIT_ASSERT(bound_request != nullptr); - CPPUNIT_ASSERT(request_is_detached); - CPPUNIT_ASSERT_EQUAL(size_t(1), enqueuer._enqueued.size()); + ASSERT_TRUE(bound_request != nullptr); + ASSERT_TRUE(request_is_detached); + ASSERT_EQ(1, enqueuer._enqueued.size()); auto& state_request = dynamic_cast<const api::SetSystemStateCommand&>(*enqueuer._enqueued[0]); - CPPUNIT_ASSERT_EQUAL(expectedBundle, state_request.getClusterStateBundle()); + ASSERT_EQ(expectedBundle, state_request.getClusterStateBundle()); } void assert_request_received_and_propagated(const lib::ClusterStateBundle& bundle) { @@ -128,9 +105,9 @@ struct SetStateFixture : FixtureBase { void assert_request_returns_error_response(RPCRequestWrapper::ErrorCode error_code) { fnet_listener->RPC_setDistributionStates(bound_request); - CPPUNIT_ASSERT(!request_is_detached); - CPPUNIT_ASSERT(bound_request->IsError()); - CPPUNIT_ASSERT_EQUAL(static_cast<uint32_t>(error_code), bound_request->GetErrorCode()); + ASSERT_FALSE(request_is_detached); + ASSERT_TRUE(bound_request->IsError()); + ASSERT_EQ(static_cast<uint32_t>(error_code), bound_request->GetErrorCode()); } lib::ClusterStateBundle dummy_baseline_bundle() const { @@ -157,14 +134,14 @@ vespalib::string make_compressable_state_string() { } // anon namespace -void FNetListenerTest::baseline_set_distribution_states_rpc_enqueues_command_with_state_bundle() { +TEST_F(FNetListenerTest, baseline_set_distribution_states_rpc_enqueues_command_with_state_bundle) { SetStateFixture f; auto baseline = f.dummy_baseline_bundle(); f.assert_request_received_and_propagated(baseline); } -void FNetListenerTest::set_distribution_states_rpc_with_derived_enqueues_command_with_state_bundle() { +TEST_F(FNetListenerTest, set_distribution_states_rpc_with_derived_enqueues_command_with_state_bundle) { SetStateFixture f; lib::ClusterStateBundle spaces_bundle( lib::ClusterState("version:123 distributor:3 storage:3"), @@ -174,47 +151,47 @@ void FNetListenerTest::set_distribution_states_rpc_with_derived_enqueues_command f.assert_request_received_and_propagated(spaces_bundle); } -void FNetListenerTest::compressed_bundle_is_transparently_uncompressed() { +TEST_F(FNetListenerTest, compressed_bundle_is_transparently_uncompressed) { SetStateFixture f; auto state_str = make_compressable_state_string(); lib::ClusterStateBundle compressable_bundle{lib::ClusterState(state_str)}; f.create_request(compressable_bundle); // First verify that the bundle is sent in compressed form - CPPUNIT_ASSERT(f.bound_request->GetParams()->GetValue(2)._data._len < state_str.size()); + ASSERT_LT(f.bound_request->GetParams()->GetValue(2)._data._len, state_str.size()); // Ensure we uncompress it to the original form f.fnet_listener->RPC_setDistributionStates(f.bound_request); f.assert_enqueued_operation_has_bundle(compressable_bundle); } -void FNetListenerTest::set_distribution_rpc_is_immediately_failed_if_listener_is_closed() { +TEST_F(FNetListenerTest, set_distribution_rpc_is_immediately_failed_if_listener_is_closed) { SetStateFixture f; f.create_request(f.dummy_baseline_bundle()); f.fnet_listener->close(); f.assert_request_returns_error_response(RPCRequestWrapper::ERR_NODE_SHUTTING_DOWN); } -void FNetListenerTest::overly_large_uncompressed_bundle_size_parameter_returns_rpc_error() { +TEST_F(FNetListenerTest, overly_large_uncompressed_bundle_size_parameter_returns_rpc_error) { SetStateFixture f; auto encoded_bundle = f.codec.encode(f.dummy_baseline_bundle()); f.bind_request_params(encoded_bundle, FNetListener::StateBundleMaxUncompressedSize + 1); f.assert_request_returns_error_response(RPCRequestWrapper::ERR_BAD_REQUEST); } -void FNetListenerTest::mismatching_uncompressed_bundle_size_parameter_returns_rpc_error() { +TEST_F(FNetListenerTest, mismatching_uncompressed_bundle_size_parameter_returns_rpc_error) { SetStateFixture f; auto encoded_bundle = f.codec.encode(f.dummy_baseline_bundle()); f.bind_request_params(encoded_bundle, encoded_bundle._buffer->getDataLen() + 100); f.assert_request_returns_error_response(RPCRequestWrapper::ERR_BAD_REQUEST); } -void FNetListenerTest::true_deferred_activation_flag_can_be_roundtrip_encoded() { +TEST_F(FNetListenerTest, true_deferred_activation_flag_can_be_roundtrip_encoded) { SetStateFixture f; f.assert_request_received_and_propagated(f.dummy_baseline_bundle_with_deferred_activation(true)); } -void FNetListenerTest::false_deferred_activation_flag_can_be_roundtrip_encoded() { +TEST_F(FNetListenerTest, false_deferred_activation_flag_can_be_roundtrip_encoded) { SetStateFixture f; f.assert_request_received_and_propagated(f.dummy_baseline_bundle_with_deferred_activation(false)); } @@ -238,11 +215,11 @@ struct ActivateStateFixture : FixtureBase { } void assert_enqueued_operation_has_activate_version(uint32_t version) { - CPPUNIT_ASSERT(bound_request != nullptr); - CPPUNIT_ASSERT(request_is_detached); - CPPUNIT_ASSERT_EQUAL(size_t(1), enqueuer._enqueued.size()); + ASSERT_TRUE(bound_request != nullptr); + ASSERT_TRUE(request_is_detached); + ASSERT_EQ(1, enqueuer._enqueued.size()); auto& state_request = dynamic_cast<const api::ActivateClusterStateVersionCommand&>(*enqueuer._enqueued[0]); - CPPUNIT_ASSERT_EQUAL(version, state_request.version()); + ASSERT_EQ(version, state_request.version()); } void assert_request_received_and_propagated(uint32_t activate_version) { @@ -252,7 +229,7 @@ struct ActivateStateFixture : FixtureBase { } }; -void FNetListenerTest::activate_cluster_state_version_rpc_enqueues_command_with_version() { +TEST_F(FNetListenerTest, activate_cluster_state_version_rpc_enqueues_command_with_version) { ActivateStateFixture f; f.assert_request_received_and_propagated(1234567); } diff --git a/storage/src/tests/storageserver/mergethrottlertest.cpp b/storage/src/tests/storageserver/mergethrottlertest.cpp index 5815bbd67c8..30ad9b58e9f 100644 --- a/storage/src/tests/storageserver/mergethrottlertest.cpp +++ b/storage/src/tests/storageserver/mergethrottlertest.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 <cppunit/extensions/HelperMacros.h> #include <vespa/vespalib/util/document_runnable.h> #include <vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.h> #include <tests/common/testhelper.h> @@ -12,6 +11,7 @@ #include <vespa/storageapi/message/bucket.h> #include <vespa/storageapi/message/state.h> #include <vespa/vespalib/util/exceptions.h> +#include <vespa/vespalib/gtest/gtest.h> #include <unordered_set> #include <memory> #include <iterator> @@ -23,6 +23,7 @@ using namespace document; using namespace storage::api; using document::test::makeDocumentBucket; +using namespace ::testing; namespace storage { @@ -100,16 +101,16 @@ struct MergeBuilder { bool source_only = (_source_only.find(node) != _source_only.end()); n.emplace_back(node, source_only); } - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(_bucket), n, _maxTimestamp, - _clusterStateVersion, _chain)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(_bucket), n, _maxTimestamp, + _clusterStateVersion, _chain); StorageMessageAddress address("storage", lib::NodeType::STORAGE, _nodes[0]); cmd->setAddress(address); return cmd; } }; -MergeBuilder::~MergeBuilder() {} +MergeBuilder::~MergeBuilder() = default; std::shared_ptr<api::SetSystemStateCommand> makeSystemStateCmd(const std::string& state) @@ -120,70 +121,9 @@ makeSystemStateCmd(const std::string& state) } // anon ns -class MergeThrottlerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(MergeThrottlerTest); - CPPUNIT_TEST(testMergesConfig); - CPPUNIT_TEST(testChain); - CPPUNIT_TEST(testWithSourceOnlyNode); - CPPUNIT_TEST(test42DistributorBehavior); - CPPUNIT_TEST(test42DistributorBehaviorDoesNotTakeOwnership); - CPPUNIT_TEST(testEndOfChainExecutionDoesNotTakeOwnership); - CPPUNIT_TEST(testResendHandling); - CPPUNIT_TEST(testPriorityQueuing); - CPPUNIT_TEST(testCommandInQueueDuplicateOfKnownMerge); - CPPUNIT_TEST(testInvalidReceiverNode); - CPPUNIT_TEST(testForwardQueuedMerge); - CPPUNIT_TEST(testExecuteQueuedMerge); - CPPUNIT_TEST(testFlush); - CPPUNIT_TEST(testUnseenMergeWithNodeInChain); - CPPUNIT_TEST(testMergeWithNewerClusterStateFlushesOutdatedQueued); - CPPUNIT_TEST(testUpdatedClusterStateFlushesOutdatedQueued); - CPPUNIT_TEST(test42MergesDoNotTriggerFlush); - CPPUNIT_TEST(testOutdatedClusterStateMergesAreRejectedOnArrival); - CPPUNIT_TEST(testUnknownMergeWithSelfInChain); - CPPUNIT_TEST(testBusyReturnedOnFullQueue); - CPPUNIT_TEST(testBrokenCycle); - CPPUNIT_TEST(testGetBucketDiffCommandNotInActiveSetIsRejected); - CPPUNIT_TEST(testApplyBucketDiffCommandNotInActiveSetIsRejected); - CPPUNIT_TEST(testNewClusterStateAbortsAllOutdatedActiveMerges); - CPPUNIT_TEST(backpressure_busy_bounces_merges_for_configured_duration); - CPPUNIT_TEST(source_only_merges_are_not_affected_by_backpressure); - CPPUNIT_TEST(backpressure_evicts_all_queued_merges); - CPPUNIT_TEST_SUITE_END(); -public: - void setUp() override; - void tearDown() override; - - void testMergesConfig(); - void testChain(); - void testWithSourceOnlyNode(); - void test42DistributorBehavior(); - void test42DistributorBehaviorDoesNotTakeOwnership(); - void testEndOfChainExecutionDoesNotTakeOwnership(); - void testResendHandling(); - void testPriorityQueuing(); - void testCommandInQueueDuplicateOfKnownMerge(); - void testInvalidReceiverNode(); - void testForwardQueuedMerge(); - void testExecuteQueuedMerge(); - void testFlush(); - void testUnseenMergeWithNodeInChain(); - void testMergeWithNewerClusterStateFlushesOutdatedQueued(); - void testUpdatedClusterStateFlushesOutdatedQueued(); - void test42MergesDoNotTriggerFlush(); - void testOutdatedClusterStateMergesAreRejectedOnArrival(); - void testUnknownMergeWithSelfInChain(); - void testBusyReturnedOnFullQueue(); - void testBrokenCycle(); - void testGetBucketDiffCommandNotInActiveSetIsRejected(); - void testApplyBucketDiffCommandNotInActiveSetIsRejected(); - void testNewClusterStateAbortsAllOutdatedActiveMerges(); - void backpressure_busy_bounces_merges_for_configured_duration(); - void source_only_merges_are_not_affected_by_backpressure(); - void backpressure_evicts_all_queued_merges(); -private: - static const int _storageNodeCount = 3; - static const int _messageWaitTime = 100; +struct MergeThrottlerTest : Test { + static constexpr int _storageNodeCount = 3; + static constexpr int _messageWaitTime = 100; // Using n storage node links and dummy servers std::vector<std::shared_ptr<DummyStorageLink> > _topLinks; @@ -191,6 +131,12 @@ private: std::vector<MergeThrottler*> _throttlers; std::vector<DummyStorageLink*> _bottomLinks; + MergeThrottlerTest(); + ~MergeThrottlerTest(); + + void SetUp() override; + void TearDown() override; + api::MergeBucketCommand::SP sendMerge(const MergeBuilder&); void sendAndExpectReply( @@ -201,13 +147,11 @@ private: void fill_throttler_queue_with_n_commands(uint16_t throttler_index, size_t queued_count); }; -const int MergeThrottlerTest::_storageNodeCount; -const int MergeThrottlerTest::_messageWaitTime; - -CPPUNIT_TEST_SUITE_REGISTRATION(MergeThrottlerTest); +MergeThrottlerTest::MergeThrottlerTest() = default; +MergeThrottlerTest::~MergeThrottlerTest() = default; void -MergeThrottlerTest::setUp() +MergeThrottlerTest::SetUp() { vdstestlib::DirConfig config(getStandardConfig(true)); @@ -234,7 +178,7 @@ MergeThrottlerTest::setUp() } void -MergeThrottlerTest::tearDown() +MergeThrottlerTest::TearDown() { for (std::size_t i = 0; i < _topLinks.size(); ++i) { if (_topLinks[i]->getState() == StorageLink::OPENED) { @@ -293,20 +237,16 @@ void waitUntilMergeQueueIs(MergeThrottler& throttler, std::size_t sz, int timeou // Extremely simple test that just checks that (min|max)_merges_per_node // under the stor-server config gets propagated to all the nodes -void -MergeThrottlerTest::testMergesConfig() -{ +TEST_F(MergeThrottlerTest, merges_config) { for (int i = 0; i < _storageNodeCount; ++i) { - CPPUNIT_ASSERT_EQUAL(uint32_t(25), _throttlers[i]->getThrottlePolicy().getMaxPendingCount()); - CPPUNIT_ASSERT_EQUAL(std::size_t(20), _throttlers[i]->getMaxQueueSize()); + EXPECT_EQ(25, _throttlers[i]->getThrottlePolicy().getMaxPendingCount()); + EXPECT_EQ(20, _throttlers[i]->getMaxQueueSize()); } } // Test that a distributor sending a merge to the lowest-index storage // node correctly invokes a merge forwarding chain and subsequent unwind. -void -MergeThrottlerTest::testChain() -{ +TEST_F(MergeThrottlerTest, chain) { uint16_t indices[_storageNodeCount]; for (int i = 0; i < _storageNodeCount; ++i) { indices[i] = i; @@ -342,31 +282,31 @@ MergeThrottlerTest::testChain() if (i == executorNode) { fwdToExec = fwd; } - CPPUNIT_ASSERT_EQUAL(uint16_t(i), _servers[i]->getIndex()); + ASSERT_EQ(i, _servers[i]->getIndex()); // No matter the node order, command is always sent to node 0 -> 1 -> 2 etc _topLinks[i]->sendDown(fwd); _topLinks[i]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); // Forwarded merge should not be sent down. Should not be necessary // to lock throttler here, since it should be sleeping like a champion - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _bottomLinks[i]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _topLinks[i]->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _throttlers[i]->getActiveMerges().size()); + ASSERT_EQ(0, _bottomLinks[i]->getNumCommands()); + ASSERT_EQ(1, _topLinks[i]->getNumReplies()); + ASSERT_EQ(1, _throttlers[i]->getActiveMerges().size()); fwd = _topLinks[i]->getAndRemoveMessage(MessageType::MERGEBUCKET); - CPPUNIT_ASSERT_EQUAL(uint16_t(i + 1), fwd->getAddress()->getIndex()); - CPPUNIT_ASSERT_EQUAL(distributorIndex, dynamic_cast<const StorageCommand&>(*fwd).getSourceIndex()); + ASSERT_EQ(i + 1, fwd->getAddress()->getIndex()); + ASSERT_EQ(distributorIndex, dynamic_cast<const StorageCommand&>(*fwd).getSourceIndex()); { std::vector<uint16_t> chain; for (int j = 0; j <= i; ++j) { chain.push_back(j); } - CPPUNIT_ASSERT(checkChain(fwd, chain.begin(), chain.end())); + EXPECT_TRUE(checkChain(fwd, chain.begin(), chain.end())); } // Ensure priority, cluster state version and timeout is correctly forwarded - CPPUNIT_ASSERT_EQUAL(7, static_cast<int>(fwd->getPriority())); - CPPUNIT_ASSERT_EQUAL(uint32_t(123), dynamic_cast<const MergeBucketCommand&>(*fwd).getClusterStateVersion()); - CPPUNIT_ASSERT_EQUAL(uint32_t(54321), dynamic_cast<const StorageCommand&>(*fwd).getTimeout()); + EXPECT_EQ(7, static_cast<int>(fwd->getPriority())); + EXPECT_EQ(123, dynamic_cast<const MergeBucketCommand&>(*fwd).getClusterStateVersion()); + EXPECT_EQ(54321, dynamic_cast<const StorageCommand&>(*fwd).getTimeout()); } _topLinks[lastNodeIdx]->sendDown(fwd); @@ -374,26 +314,25 @@ MergeThrottlerTest::testChain() // If node 2 is the first in the node list, it should immediately execute // the merge. Otherwise, a cycle with the first node should be formed. if (executorNode != lastNodeIdx) { - //std::cout << "cycle " << lastNodeIdx << " -> " << executorNode << "\n"; _topLinks[lastNodeIdx]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); // Forwarded merge should not be sent down - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _bottomLinks[lastNodeIdx]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _topLinks[lastNodeIdx]->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _throttlers[lastNodeIdx]->getActiveMerges().size()); + ASSERT_EQ(0, _bottomLinks[lastNodeIdx]->getNumCommands()); + ASSERT_EQ(1, _topLinks[lastNodeIdx]->getNumReplies()); + ASSERT_EQ(1, _throttlers[lastNodeIdx]->getActiveMerges().size()); fwd = _topLinks[lastNodeIdx]->getAndRemoveMessage(MessageType::MERGEBUCKET); - CPPUNIT_ASSERT_EQUAL(uint16_t(executorNode), fwd->getAddress()->getIndex()); - CPPUNIT_ASSERT_EQUAL(distributorIndex, dynamic_cast<const StorageCommand&>(*fwd).getSourceIndex()); + ASSERT_EQ(executorNode, fwd->getAddress()->getIndex()); + ASSERT_EQ(distributorIndex, dynamic_cast<const StorageCommand&>(*fwd).getSourceIndex()); { std::vector<uint16_t> chain; for (int j = 0; j < _storageNodeCount; ++j) { chain.push_back(j); } - CPPUNIT_ASSERT(checkChain(fwd, chain.begin(), chain.end())); + EXPECT_TRUE(checkChain(fwd, chain.begin(), chain.end())); } - CPPUNIT_ASSERT_EQUAL(7, static_cast<int>(fwd->getPriority())); - CPPUNIT_ASSERT_EQUAL(uint32_t(123), dynamic_cast<const MergeBucketCommand&>(*fwd).getClusterStateVersion()); - CPPUNIT_ASSERT_EQUAL(uint32_t(54321), dynamic_cast<const StorageCommand&>(*fwd).getTimeout()); + EXPECT_EQ(7, static_cast<int>(fwd->getPriority())); + EXPECT_EQ(123, dynamic_cast<const MergeBucketCommand&>(*fwd).getClusterStateVersion()); + EXPECT_EQ(54321, dynamic_cast<const StorageCommand&>(*fwd).getTimeout()); _topLinks[executorNode]->sendDown(fwd); } @@ -401,29 +340,28 @@ MergeThrottlerTest::testChain() _bottomLinks[executorNode]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); // Forwarded merge has now been sent down to persistence layer - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _bottomLinks[executorNode]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _topLinks[executorNode]->getNumReplies()); // No reply sent yet - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _throttlers[executorNode]->getActiveMerges().size()); // no re-registering merge + ASSERT_EQ(1, _bottomLinks[executorNode]->getNumCommands()); + ASSERT_EQ(0, _topLinks[executorNode]->getNumReplies()); // No reply sent yet + ASSERT_EQ(1, _throttlers[executorNode]->getActiveMerges().size()); // no re-registering merge if (executorNode != lastNodeIdx) { // The MergeBucketCommand that is kept in the executor node should // be the one from the node it initially got it from, NOT the one // from the last node, since the chain has looped - CPPUNIT_ASSERT(_throttlers[executorNode]->getActiveMerges().find(bucket) - != _throttlers[executorNode]->getActiveMerges().end()); - CPPUNIT_ASSERT_EQUAL(static_cast<StorageMessage*>(fwdToExec.get()), - _throttlers[executorNode]->getActiveMerges().find(bucket)->second.getMergeCmd().get()); + ASSERT_TRUE(_throttlers[executorNode]->getActiveMerges().find(bucket) + != _throttlers[executorNode]->getActiveMerges().end()); + ASSERT_EQ(static_cast<StorageMessage*>(fwdToExec.get()), + _throttlers[executorNode]->getActiveMerges().find(bucket)->second.getMergeCmd().get()); } // Send reply up from persistence layer to simulate a completed // merge operation. Chain should now unwind properly fwd = _bottomLinks[executorNode]->getAndRemoveMessage(MessageType::MERGEBUCKET); - CPPUNIT_ASSERT_EQUAL(7, static_cast<int>(fwd->getPriority())); - CPPUNIT_ASSERT_EQUAL(uint32_t(123), dynamic_cast<const MergeBucketCommand&>(*fwd).getClusterStateVersion()); - CPPUNIT_ASSERT_EQUAL(uint32_t(54321), dynamic_cast<const StorageCommand&>(*fwd).getTimeout()); + EXPECT_EQ(7, static_cast<int>(fwd->getPriority())); + EXPECT_EQ(123, dynamic_cast<const MergeBucketCommand&>(*fwd).getClusterStateVersion()); + EXPECT_EQ(54321, dynamic_cast<const StorageCommand&>(*fwd).getTimeout()); - std::shared_ptr<MergeBucketReply> reply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*fwd))); + auto reply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*fwd)); reply->setResult(ReturnCode(ReturnCode::OK, "Great success! :D-|-<")); _bottomLinks[executorNode]->sendUp(reply); @@ -431,45 +369,41 @@ MergeThrottlerTest::testChain() if (executorNode != lastNodeIdx) { // Merge should not be removed yet from executor, since it's pending an unwind - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _throttlers[executorNode]->getActiveMerges().size()); - CPPUNIT_ASSERT_EQUAL(static_cast<StorageMessage*>(fwdToExec.get()), - _throttlers[executorNode]->getActiveMerges().find(bucket)->second.getMergeCmd().get()); + ASSERT_EQ(1, _throttlers[executorNode]->getActiveMerges().size()); + ASSERT_EQ(static_cast<StorageMessage*>(fwdToExec.get()), + _throttlers[executorNode]->getActiveMerges().find(bucket)->second.getMergeCmd().get()); } // MergeBucketReply waiting to be sent back to node 2. NOTE: we don't have any // transport context stuff set up here to perform the reply mapping, so we // have to emulate it - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _topLinks[executorNode]->getNumReplies()); + ASSERT_EQ(1, _topLinks[executorNode]->getNumReplies()); - StorageMessage::SP unwind = _topLinks[executorNode]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL(uint16_t(executorNode), unwind->getAddress()->getIndex()); + auto unwind = _topLinks[executorNode]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); + ASSERT_EQ(executorNode, unwind->getAddress()->getIndex()); // eg: 0 -> 2 -> 1 -> 0. Or: 2 -> 1 -> 0 if no cycle for (int i = (executorNode != lastNodeIdx ? _storageNodeCount - 1 : _storageNodeCount - 2); i >= 0; --i) { _topLinks[i]->sendDown(unwind); _topLinks[i]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _bottomLinks[i]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _topLinks[i]->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _throttlers[i]->getActiveMerges().size()); + ASSERT_EQ(0, _bottomLinks[i]->getNumCommands()); + ASSERT_EQ(1, _topLinks[i]->getNumReplies()); + ASSERT_EQ(0, _throttlers[i]->getActiveMerges().size()); unwind = _topLinks[i]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL(uint16_t(i), unwind->getAddress()->getIndex()); + ASSERT_EQ(uint16_t(i), unwind->getAddress()->getIndex()); } const MergeBucketReply& mbr = dynamic_cast<const MergeBucketReply&>(*unwind); - CPPUNIT_ASSERT_EQUAL(ReturnCode::OK, mbr.getResult().getResult()); - CPPUNIT_ASSERT_EQUAL(vespalib::string("Great success! :D-|-<"), mbr.getResult().getMessage()); - CPPUNIT_ASSERT_EQUAL(bucket, mbr.getBucket()); + EXPECT_EQ(ReturnCode::OK, mbr.getResult().getResult()); + EXPECT_EQ(vespalib::string("Great success! :D-|-<"), mbr.getResult().getMessage()); + EXPECT_EQ(bucket, mbr.getBucket()); } while (std::next_permutation(indices, indices + _storageNodeCount)); - - //std::cout << "\n" << *_topLinks[0] << "\n"; } -void -MergeThrottlerTest::testWithSourceOnlyNode() -{ +TEST_F(MergeThrottlerTest, with_source_only_node) { BucketId bid(14, 0x1337); StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); @@ -478,39 +412,37 @@ MergeThrottlerTest::testWithSourceOnlyNode() nodes.push_back(0); nodes.push_back(2); nodes.push_back(MergeBucketCommand::Node(1, true)); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(bid), nodes, UINT_MAX, 123)); + auto cmd = std::make_shared<MergeBucketCommand>(makeDocumentBucket(bid), nodes, UINT_MAX, 123); cmd->setAddress(address); _topLinks[0]->sendDown(cmd); _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); StorageMessage::SP fwd = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); - CPPUNIT_ASSERT_EQUAL(uint16_t(1), fwd->getAddress()->getIndex()); + ASSERT_EQ(1, fwd->getAddress()->getIndex()); _topLinks[1]->sendDown(fwd); _topLinks[1]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); fwd = _topLinks[1]->getAndRemoveMessage(MessageType::MERGEBUCKET); - CPPUNIT_ASSERT_EQUAL(uint16_t(2), fwd->getAddress()->getIndex()); + ASSERT_EQ(2, fwd->getAddress()->getIndex()); _topLinks[2]->sendDown(fwd); _topLinks[2]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); fwd = _topLinks[2]->getAndRemoveMessage(MessageType::MERGEBUCKET); - CPPUNIT_ASSERT_EQUAL(uint16_t(0), fwd->getAddress()->getIndex()); + ASSERT_EQ(0, fwd->getAddress()->getIndex()); _topLinks[0]->sendDown(fwd); _bottomLinks[0]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); _bottomLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); - std::shared_ptr<MergeBucketReply> reply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*fwd))); + auto reply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*fwd)); reply->setResult(ReturnCode(ReturnCode::OK, "Great success! :D-|-<")); _bottomLinks[0]->sendUp(reply); _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); fwd = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL(uint16_t(0), fwd->getAddress()->getIndex()); + ASSERT_EQ(0, fwd->getAddress()->getIndex()); // Assume everything's fine from here on out } @@ -519,17 +451,15 @@ MergeThrottlerTest::testWithSourceOnlyNode() // index, so we must detect such situations and execute the merge // immediately rather than attempt to chain it. Test that this // is done correctly. -void -MergeThrottlerTest::test42DistributorBehavior() -{ +// TODO remove functionality and test +TEST_F(MergeThrottlerTest, legacy_42_distributor_behavior) { BucketId bid(32, 0xfeef00); std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(bid), nodes, 1234)); + auto cmd = std::make_shared<MergeBucketCommand>(makeDocumentBucket(bid), nodes, 1234); // Send to node 1, which is not the lowest index StorageMessageAddress address("storage", lib::NodeType::STORAGE, 1); @@ -539,40 +469,37 @@ MergeThrottlerTest::test42DistributorBehavior() _bottomLinks[1]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); // Should now have been sent to persistence layer - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _bottomLinks[1]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _topLinks[1]->getNumReplies()); // No reply sent yet - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _throttlers[1]->getActiveMerges().size()); + ASSERT_EQ(1, _bottomLinks[1]->getNumCommands()); + ASSERT_EQ(0, _topLinks[1]->getNumReplies()); // No reply sent yet + ASSERT_EQ(1, _throttlers[1]->getActiveMerges().size()); // Send reply up from persistence layer to simulate a completed // merge operation. Merge should be removed from state. _bottomLinks[1]->getAndRemoveMessage(MessageType::MERGEBUCKET); - std::shared_ptr<MergeBucketReply> reply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*cmd))); + auto reply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*cmd)); reply->setResult(ReturnCode(ReturnCode::OK, "Tonight we dine on turtle soup!")); _bottomLinks[1]->sendUp(reply); _topLinks[1]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _bottomLinks[1]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _topLinks[1]->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _throttlers[1]->getActiveMerges().size()); + ASSERT_EQ(0, _bottomLinks[1]->getNumCommands()); + ASSERT_EQ(1, _topLinks[1]->getNumReplies()); + ASSERT_EQ(0, _throttlers[1]->getActiveMerges().size()); - CPPUNIT_ASSERT_EQUAL(uint64_t(1), _throttlers[1]->getMetrics().local.ok.getValue()); + EXPECT_EQ(uint64_t(1), _throttlers[1]->getMetrics().local.ok.getValue()); } // Test that we don't take ownership of the merge command when we're // just passing it through to the persistence layer when receiving // a merge command that presumably comes form a 4.2 distributor -void -MergeThrottlerTest::test42DistributorBehaviorDoesNotTakeOwnership() -{ +// TODO remove functionality and test +TEST_F(MergeThrottlerTest, legacy_42_distributor_behavior_does_not_take_ownership) { BucketId bid(32, 0xfeef00); std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(bid), nodes, 1234)); + auto cmd = std::make_shared<MergeBucketCommand>(makeDocumentBucket(bid), nodes, 1234); // Send to node 1, which is not the lowest index StorageMessageAddress address("storage", lib::NodeType::STORAGE, 1); @@ -582,9 +509,9 @@ MergeThrottlerTest::test42DistributorBehaviorDoesNotTakeOwnership() _bottomLinks[1]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); // Should now have been sent to persistence layer - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _bottomLinks[1]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _topLinks[1]->getNumReplies()); // No reply sent yet - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _throttlers[1]->getActiveMerges().size()); + ASSERT_EQ(1, _bottomLinks[1]->getNumCommands()); + ASSERT_EQ(0, _topLinks[1]->getNumReplies()); // No reply sent yet + ASSERT_EQ(1, _throttlers[1]->getActiveMerges().size()); _bottomLinks[1]->getAndRemoveMessage(MessageType::MERGEBUCKET); @@ -597,29 +524,26 @@ MergeThrottlerTest::test42DistributorBehaviorDoesNotTakeOwnership() // for the merge command, as it is not owned by the throttler _throttlers[1]->onFlush(true); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _bottomLinks[1]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _topLinks[1]->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _throttlers[1]->getActiveMerges().size()); + ASSERT_EQ(0, _bottomLinks[1]->getNumCommands()); + ASSERT_EQ(0, _topLinks[1]->getNumReplies()); + ASSERT_EQ(0, _throttlers[1]->getActiveMerges().size()); // Send a belated reply from persistence up just to ensure the // throttler doesn't throw a fit if it receives an unknown merge - std::shared_ptr<MergeBucketReply> reply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*cmd))); + auto reply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*cmd)); reply->setResult(ReturnCode(ReturnCode::OK, "Tonight we dine on turtle soup!")); _bottomLinks[1]->sendUp(reply); _topLinks[1]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _bottomLinks[1]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _topLinks[1]->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _throttlers[1]->getActiveMerges().size()); + ASSERT_EQ(0, _bottomLinks[1]->getNumCommands()); + ASSERT_EQ(1, _topLinks[1]->getNumReplies()); + ASSERT_EQ(0, _throttlers[1]->getActiveMerges().size()); } // Test that we don't take ownership of the merge command when we're // just passing it through to the persistence layer when we're at the // the end of the chain and also the designated executor -void -MergeThrottlerTest::testEndOfChainExecutionDoesNotTakeOwnership() -{ +TEST_F(MergeThrottlerTest, end_of_chain_execution_does_not_take_ownership) { BucketId bid(32, 0xfeef00); std::vector<MergeBucketCommand::Node> nodes; @@ -629,8 +553,7 @@ MergeThrottlerTest::testEndOfChainExecutionDoesNotTakeOwnership() std::vector<uint16_t> chain; chain.push_back(0); chain.push_back(1); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(bid), nodes, 1234, 1, chain)); + auto cmd = std::make_shared<MergeBucketCommand>(makeDocumentBucket(bid), nodes, 1234, 1, chain); // Send to last node, which is not the lowest index StorageMessageAddress address("storage", lib::NodeType::STORAGE, 3); @@ -640,9 +563,9 @@ MergeThrottlerTest::testEndOfChainExecutionDoesNotTakeOwnership() _bottomLinks[2]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); // Should now have been sent to persistence layer - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _bottomLinks[2]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _topLinks[2]->getNumReplies()); // No reply sent yet - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _throttlers[2]->getActiveMerges().size()); + ASSERT_EQ(1, _bottomLinks[2]->getNumCommands()); + ASSERT_EQ(0, _topLinks[2]->getNumReplies()); // No reply sent yet + ASSERT_EQ(1, _throttlers[2]->getActiveMerges().size()); _bottomLinks[2]->getAndRemoveMessage(MessageType::MERGEBUCKET); @@ -655,37 +578,33 @@ MergeThrottlerTest::testEndOfChainExecutionDoesNotTakeOwnership() // for the merge command, as it is not owned by the throttler _throttlers[2]->onFlush(true); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _bottomLinks[2]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _topLinks[2]->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _throttlers[2]->getActiveMerges().size()); + ASSERT_EQ(0, _bottomLinks[2]->getNumCommands()); + ASSERT_EQ(0, _topLinks[2]->getNumReplies()); + ASSERT_EQ(0, _throttlers[2]->getActiveMerges().size()); // Send a belated reply from persistence up just to ensure the // throttler doesn't throw a fit if it receives an unknown merge - std::shared_ptr<MergeBucketReply> reply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*cmd))); + auto reply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*cmd)); reply->setResult(ReturnCode(ReturnCode::OK, "Tonight we dine on turtle soup!")); _bottomLinks[2]->sendUp(reply); _topLinks[2]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _bottomLinks[2]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _topLinks[2]->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _throttlers[2]->getActiveMerges().size()); + ASSERT_EQ(0, _bottomLinks[2]->getNumCommands()); + ASSERT_EQ(1, _topLinks[2]->getNumReplies()); + ASSERT_EQ(0, _throttlers[2]->getActiveMerges().size()); } // Test that nodes resending a merge command won't lead to duplicate // state registration/forwarding or erasing the already present state // information. -void -MergeThrottlerTest::testResendHandling() -{ +TEST_F(MergeThrottlerTest, resend_handling) { BucketId bid(32, 0xbadbed); std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(bid), nodes, 1234)); + auto cmd = std::make_shared<MergeBucketCommand>(makeDocumentBucket(bid), nodes, 1234); StorageMessageAddress address("storage", lib::NodeType::STORAGE, 1); @@ -702,9 +621,8 @@ MergeThrottlerTest::testResendHandling() // Reply should be BUSY StorageMessage::SP reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - static_cast<MergeBucketReply&>(*reply).getResult().getResult(), - ReturnCode::BUSY); + EXPECT_EQ(static_cast<MergeBucketReply&>(*reply).getResult().getResult(), + ReturnCode::BUSY); _topLinks[1]->sendDown(fwd); _topLinks[1]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); @@ -717,9 +635,8 @@ MergeThrottlerTest::testResendHandling() // Reply should be BUSY reply = _topLinks[2]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - static_cast<MergeBucketReply&>(*reply).getResult().getResult(), - ReturnCode::BUSY); + EXPECT_EQ(static_cast<MergeBucketReply&>(*reply).getResult().getResult(), + ReturnCode::BUSY); fwd = _topLinks[2]->getAndRemoveMessage(MessageType::MERGEBUCKET); @@ -729,24 +646,21 @@ MergeThrottlerTest::testResendHandling() _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - static_cast<MergeBucketReply&>(*reply).getResult().getResult(), - ReturnCode::BUSY); + EXPECT_EQ(static_cast<MergeBucketReply&>(*reply).getResult().getResult(), + ReturnCode::BUSY); } -void -MergeThrottlerTest::testPriorityQueuing() -{ +TEST_F(MergeThrottlerTest, priority_queuing) { // Fill up all active merges std::size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - CPPUNIT_ASSERT(maxPending >= 4u); + ASSERT_GE(maxPending, 4u); for (std::size_t i = 0; i < maxPending; ++i) { - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234); cmd->setPriority(100); _topLinks[0]->sendDown(cmd); } @@ -771,15 +685,14 @@ MergeThrottlerTest::testPriorityQueuing() for (std::size_t i = 0; i < maxPending - 4; ++i) { _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); } - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _topLinks[0]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(4), _topLinks[0]->getNumReplies()); + ASSERT_EQ(0, _topLinks[0]->getNumCommands()); + ASSERT_EQ(4, _topLinks[0]->getNumReplies()); // Now when we start replying to merges, queued merges should be // processed in priority order for (int i = 0; i < 4; ++i) { StorageMessage::SP replyTo = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); - std::shared_ptr<MergeBucketReply> reply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*replyTo))); + auto reply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*replyTo)); reply->setResult(ReturnCode(ReturnCode::OK, "whee")); _topLinks[0]->sendDown(reply); } @@ -789,26 +702,24 @@ MergeThrottlerTest::testPriorityQueuing() for (int i = 0; i < 4; ++i) { StorageMessage::SP cmd = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); - CPPUNIT_ASSERT_EQUAL(uint8_t(sortedPris[i]), cmd->getPriority()); + EXPECT_EQ(uint8_t(sortedPris[i]), cmd->getPriority()); } } // Test that we can detect and reject merges that due to resending // and potential priority queue sneaking etc may end up with duplicates // in the queue for a merge that is already known. -void -MergeThrottlerTest::testCommandInQueueDuplicateOfKnownMerge() -{ +TEST_F(MergeThrottlerTest, command_in_queue_duplicate_of_known_merge) { // Fill up all active merges and 1 queued one - std::size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); - CPPUNIT_ASSERT(maxPending < 100); + size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); + ASSERT_LT(maxPending, 100); for (std::size_t i = 0; i < maxPending + 1; ++i) { std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(2 + i); nodes.push_back(5 + i); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234); cmd->setPriority(100 - i); _topLinks[0]->sendDown(cmd); } @@ -823,8 +734,8 @@ MergeThrottlerTest::testCommandInQueueDuplicateOfKnownMerge() nodes.push_back(0); nodes.push_back(12); nodes.push_back(123); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf000feee)), nodes, 1234)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf000feee)), nodes, 1234); _topLinks[0]->sendDown(cmd); } { @@ -832,22 +743,21 @@ MergeThrottlerTest::testCommandInQueueDuplicateOfKnownMerge() nodes.push_back(0); nodes.push_back(124); // Different node set doesn't matter nodes.push_back(14); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf000feee)), nodes, 1234)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf000feee)), nodes, 1234); _topLinks[0]->sendDown(cmd); } waitUntilMergeQueueIs(*_throttlers[0], 3, _messageWaitTime); - StorageMessage::SP fwd = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); + auto fwd = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); // Remove and success-reply for 2 merges. This will give enough room // for the 2 first queued merges to be processed, the last one having a // duplicate in the queue. for (int i = 0; i < 2; ++i) { StorageMessage::SP fwd2 = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); - std::shared_ptr<MergeBucketReply> reply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*fwd2))); + auto reply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*fwd2)); reply->setResult(ReturnCode(ReturnCode::OK, "")); _topLinks[0]->sendDown(reply); } @@ -859,8 +769,7 @@ MergeThrottlerTest::testCommandInQueueDuplicateOfKnownMerge() _topLinks[0]->getRepliesOnce(); // Send a success-reply for fwd, allowing the duplicate from the queue // to have its moment to shine only to then be struck down mercilessly - std::shared_ptr<MergeBucketReply> reply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*fwd))); + auto reply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*fwd)); reply->setResult(ReturnCode(ReturnCode::OK, "")); _topLinks[0]->sendDown(reply); @@ -868,62 +777,55 @@ MergeThrottlerTest::testCommandInQueueDuplicateOfKnownMerge() waitUntilMergeQueueIs(*_throttlers[0], 0, _messageWaitTime); // First reply is the successful merge reply - StorageMessage::SP reply2 = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - static_cast<MergeBucketReply&>(*reply2).getResult().getResult(), - ReturnCode::OK); + auto reply2 = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); + EXPECT_EQ(static_cast<MergeBucketReply&>(*reply2).getResult().getResult(), + ReturnCode::OK); // Second reply should be the BUSY-rejected duplicate - StorageMessage::SP reply1 = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - static_cast<MergeBucketReply&>(*reply1).getResult().getResult(), - ReturnCode::BUSY); - CPPUNIT_ASSERT(static_cast<MergeBucketReply&>(*reply1).getResult() - .getMessage().find("out of date;") != std::string::npos); + auto reply1 = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); + EXPECT_EQ(static_cast<MergeBucketReply&>(*reply1).getResult().getResult(), + ReturnCode::BUSY); + EXPECT_TRUE(static_cast<MergeBucketReply&>(*reply1).getResult() + .getMessage().find("out of date;") != std::string::npos); } // Test that sending a merge command to a node not in the set of // to-be-merged nodes is handled gracefully. // This is not a scenario that should ever actually happen, but for // the sake of robustness, include it anyway. -void -MergeThrottlerTest::testInvalidReceiverNode() -{ +TEST_F(MergeThrottlerTest, invalid_receiver_node) { std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(1); nodes.push_back(5); nodes.push_back(9); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf00baaaa)), nodes, 1234)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf00baaaa)), nodes, 1234); // Send to node with index 0 _topLinks[0]->sendDown(cmd); _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); - StorageMessage::SP reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - static_cast<MergeBucketReply&>(*reply).getResult().getResult(), - ReturnCode::REJECTED); - CPPUNIT_ASSERT(static_cast<MergeBucketReply&>(*reply).getResult() - .getMessage().find("which is not in its forwarding chain") != std::string::npos); + auto reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); + EXPECT_EQ(static_cast<MergeBucketReply&>(*reply).getResult().getResult(), + ReturnCode::REJECTED); + EXPECT_TRUE(static_cast<MergeBucketReply&>(*reply).getResult() + .getMessage().find("which is not in its forwarding chain") != std::string::npos); } // Test that the throttling policy kicks in after a certain number of // merges are forwarded and that the rest are queued in a prioritized // order. -void -MergeThrottlerTest::testForwardQueuedMerge() -{ +TEST_F(MergeThrottlerTest, forward_queued_merge) { // Fill up all active merges and then 3 queued ones - std::size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); - CPPUNIT_ASSERT(maxPending < 100); + size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); + ASSERT_LT(maxPending, 100); for (std::size_t i = 0; i < maxPending + 3; ++i) { std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(2 + i); nodes.push_back(5 + i); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234); cmd->setPriority(100 - i); _topLinks[0]->sendDown(cmd); } @@ -933,70 +835,61 @@ MergeThrottlerTest::testForwardQueuedMerge() waitUntilMergeQueueIs(*_throttlers[0], 3, _messageWaitTime); // Merge queue state should not be touched by worker thread now - StorageMessage::SP nextMerge = _throttlers[0]->getMergeQueue().begin()->_msg; + auto nextMerge = _throttlers[0]->getMergeQueue().begin()->_msg; - StorageMessage::SP fwd = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); + auto fwd = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); // Remove all the rest of the active merges while (!_topLinks[0]->getReplies().empty()) { _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); } - std::shared_ptr<MergeBucketReply> reply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*fwd))); + auto reply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*fwd)); reply->setResult(ReturnCode(ReturnCode::OK, "Celebrate good times come on")); _topLinks[0]->sendDown(reply); _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); // Success rewind reply // Remove reply bound for distributor - StorageMessage::SP distReply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - static_cast<MergeBucketReply&>(*distReply).getResult().getResult(), - ReturnCode::OK); + auto distReply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); + EXPECT_EQ(static_cast<MergeBucketReply&>(*distReply).getResult().getResult(), + ReturnCode::OK); waitUntilMergeQueueIs(*_throttlers[0], 2, _messageWaitTime); _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _topLinks[0]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(1), _topLinks[0]->getNumReplies()); + ASSERT_EQ(0, _topLinks[0]->getNumCommands()); + ASSERT_EQ(1, _topLinks[0]->getNumReplies()); // First queued merge should now have been registered and forwarded fwd = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); - CPPUNIT_ASSERT_EQUAL( - static_cast<const MergeBucketCommand&>(*fwd).getBucketId(), - static_cast<const MergeBucketCommand&>(*nextMerge).getBucketId()); + ASSERT_EQ(static_cast<const MergeBucketCommand&>(*fwd).getBucketId(), + static_cast<const MergeBucketCommand&>(*nextMerge).getBucketId()); - CPPUNIT_ASSERT( - static_cast<const MergeBucketCommand&>(*fwd).getNodes() - == static_cast<const MergeBucketCommand&>(*nextMerge).getNodes()); + ASSERT_TRUE(static_cast<const MergeBucketCommand&>(*fwd).getNodes() + == static_cast<const MergeBucketCommand&>(*nextMerge).getNodes()); // Ensure forwarded merge has a higher priority than the next queued one - CPPUNIT_ASSERT(fwd->getPriority() < _throttlers[0]->getMergeQueue().begin()->_msg->getPriority()); - - CPPUNIT_ASSERT_EQUAL(uint64_t(1), _throttlers[0]->getMetrics().chaining.ok.getValue()); + EXPECT_LT(fwd->getPriority(), _throttlers[0]->getMergeQueue().begin()->_msg->getPriority()); - /*framework::HttpUrlPath path("?xml"); - _forwarders[0]->reportStatus(std::cerr, path);*/ + EXPECT_EQ(uint64_t(1), _throttlers[0]->getMetrics().chaining.ok.getValue()); } -void -MergeThrottlerTest::testExecuteQueuedMerge() -{ +TEST_F(MergeThrottlerTest, execute_queued_merge) { MergeThrottler& throttler(*_throttlers[1]); DummyStorageLink& topLink(*_topLinks[1]); DummyStorageLink& bottomLink(*_bottomLinks[1]); // Fill up all active merges and then 3 queued ones - std::size_t maxPending = throttler.getThrottlePolicy().getMaxPendingCount(); - CPPUNIT_ASSERT(maxPending < 100); + size_t maxPending = throttler.getThrottlePolicy().getMaxPendingCount(); + ASSERT_LT(maxPending, 100); for (std::size_t i = 0; i < maxPending + 3; ++i) { std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(1); nodes.push_back(5 + i); nodes.push_back(7 + i); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234, 1)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234, 1); cmd->setPriority(250 - i + 5); topLink.sendDown(cmd); } @@ -1013,8 +906,8 @@ MergeThrottlerTest::testExecuteQueuedMerge() nodes.push_back(0); std::vector<uint16_t> chain; chain.push_back(0); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0x1337)), nodes, 1234, 1, chain)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0x1337)), nodes, 1234, 1, chain); cmd->setPriority(0); topLink.sendDown(cmd); } @@ -1022,19 +915,12 @@ MergeThrottlerTest::testExecuteQueuedMerge() waitUntilMergeQueueIs(throttler, 4, _messageWaitTime); // Merge queue state should not be touched by worker thread now - StorageMessage::SP nextMerge(throttler.getMergeQueue().begin()->_msg); - /*StorageMessage::SP nextMerge; - { - vespalib::LockGuard lock(_throttlers[0]->getStateLock()); - // Dirty: have to check internal state - nextMerge = _throttlers[0]->getMergeQueue().begin()->_msg; - }*/ + auto nextMerge = throttler.getMergeQueue().begin()->_msg; - CPPUNIT_ASSERT_EQUAL( - BucketId(32, 0x1337), - dynamic_cast<const MergeBucketCommand&>(*nextMerge).getBucketId()); + ASSERT_EQ(BucketId(32, 0x1337), + dynamic_cast<const MergeBucketCommand&>(*nextMerge).getBucketId()); - StorageMessage::SP fwd(topLink.getAndRemoveMessage(MessageType::MERGEBUCKET)); + auto fwd = topLink.getAndRemoveMessage(MessageType::MERGEBUCKET); // Remove all the rest of the active merges while (!topLink.getReplies().empty()) { @@ -1042,50 +928,44 @@ MergeThrottlerTest::testExecuteQueuedMerge() } // Free up a merge slot - std::shared_ptr<MergeBucketReply> reply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*fwd))); + auto reply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*fwd)); reply->setResult(ReturnCode(ReturnCode::OK, "Celebrate good times come on")); topLink.sendDown(reply); topLink.waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); // Remove chain reply - StorageMessage::SP distReply(topLink.getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY)); - CPPUNIT_ASSERT_EQUAL( - static_cast<MergeBucketReply&>(*distReply).getResult().getResult(), - ReturnCode::OK); + auto distReply = topLink.getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); + ASSERT_EQ(static_cast<MergeBucketReply&>(*distReply).getResult().getResult(), + ReturnCode::OK); waitUntilMergeQueueIs(throttler, 3, _messageWaitTime); bottomLink.waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), topLink.getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), topLink.getNumReplies()); - CPPUNIT_ASSERT_EQUAL(std::size_t(1), bottomLink.getNumCommands()); + ASSERT_EQ(0, topLink.getNumCommands()); + ASSERT_EQ(0, topLink.getNumReplies()); + ASSERT_EQ(1, bottomLink.getNumCommands()); // First queued merge should now have been registered and sent down - StorageMessage::SP cmd(bottomLink.getAndRemoveMessage(MessageType::MERGEBUCKET)); + auto cmd = bottomLink.getAndRemoveMessage(MessageType::MERGEBUCKET); - CPPUNIT_ASSERT_EQUAL( - static_cast<const MergeBucketCommand&>(*cmd).getBucketId(), - static_cast<const MergeBucketCommand&>(*nextMerge).getBucketId()); + ASSERT_EQ(static_cast<const MergeBucketCommand&>(*cmd).getBucketId(), + static_cast<const MergeBucketCommand&>(*nextMerge).getBucketId()); - CPPUNIT_ASSERT( - static_cast<const MergeBucketCommand&>(*cmd).getNodes() - == static_cast<const MergeBucketCommand&>(*nextMerge).getNodes()); + ASSERT_TRUE(static_cast<const MergeBucketCommand&>(*cmd).getNodes() + == static_cast<const MergeBucketCommand&>(*nextMerge).getNodes()); } -void -MergeThrottlerTest::testFlush() -{ +TEST_F(MergeThrottlerTest, flush) { // Fill up all active merges and then 3 queued ones std::size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); - CPPUNIT_ASSERT(maxPending < 100); + ASSERT_LT(maxPending, 100); for (std::size_t i = 0; i < maxPending + 3; ++i) { std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234, 1)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234, 1); _topLinks[0]->sendDown(cmd); } @@ -1095,7 +975,7 @@ MergeThrottlerTest::testFlush() // Remove all forwarded commands uint32_t removed = _topLinks[0]->getRepliesOnce().size(); - CPPUNIT_ASSERT(removed >= 5); + ASSERT_GE(removed, 5); // Flush the storage link, triggering an abort of all commands // no matter what their current state is. @@ -1105,9 +985,8 @@ MergeThrottlerTest::testFlush() while (!_topLinks[0]->getReplies().empty()) { StorageMessage::SP reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - ReturnCode::ABORTED, - static_cast<const MergeBucketReply&>(*reply).getResult().getResult()); + ASSERT_EQ(ReturnCode::ABORTED, + static_cast<const MergeBucketReply&>(*reply).getResult().getResult()); } // NOTE: merges that have been immediately executed (i.e. not cycled) // on the node should _not_ be replied to, since they're not owned @@ -1119,9 +998,7 @@ MergeThrottlerTest::testFlush() // it knows nothing about when it comes back up. If this is not handled // properly, it will attempt to forward this node again with a bogus // index. This should be implicitly handled by checking for a full node -void -MergeThrottlerTest::testUnseenMergeWithNodeInChain() -{ +TEST_F(MergeThrottlerTest, unseen_merge_with_node_in_chain) { std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(5); @@ -1130,8 +1007,8 @@ MergeThrottlerTest::testUnseenMergeWithNodeInChain() chain.push_back(0); chain.push_back(5); chain.push_back(9); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xdeadbeef)), nodes, 1234, 1, chain)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xdeadbeef)), nodes, 1234, 1, chain); StorageMessageAddress address("storage", lib::NodeType::STORAGE, 9); @@ -1141,21 +1018,19 @@ MergeThrottlerTest::testUnseenMergeWithNodeInChain() // First, test that we get rejected when processing merge immediately // Should get a rejection in return _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); - StorageMessage::SP reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - ReturnCode::REJECTED, - dynamic_cast<const MergeBucketReply&>(*reply).getResult().getResult()); + auto reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); + ASSERT_EQ(ReturnCode::REJECTED, + dynamic_cast<const MergeBucketReply&>(*reply).getResult().getResult()); // Second, test that we get rejected before queueing up. This is to // avoid a hypothetical deadlock scenario. // Fill up all active merges { - std::size_t maxPending( - _throttlers[0]->getThrottlePolicy().getMaxPendingCount()); - for (std::size_t i = 0; i < maxPending; ++i) { - std::shared_ptr<MergeBucketCommand> fillCmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234)); + size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); + for (size_t i = 0; i < maxPending; ++i) { + auto fillCmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234); _topLinks[0]->sendDown(fillCmd); } } @@ -1164,26 +1039,23 @@ MergeThrottlerTest::testUnseenMergeWithNodeInChain() _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - ReturnCode::REJECTED, - dynamic_cast<const MergeBucketReply&>(*reply).getResult().getResult()); + ASSERT_EQ(ReturnCode::REJECTED, + dynamic_cast<const MergeBucketReply&>(*reply).getResult().getResult()); } -void -MergeThrottlerTest::testMergeWithNewerClusterStateFlushesOutdatedQueued() -{ +TEST_F(MergeThrottlerTest, merge_with_newer_cluster_state_flushes_outdated_queued){ // Fill up all active merges and then 3 queued ones with the same // system state - std::size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); - CPPUNIT_ASSERT(maxPending < 100); + size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); + ASSERT_LT(maxPending, 100); std::vector<api::StorageMessage::Id> ids; for (std::size_t i = 0; i < maxPending + 3; ++i) { std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234, 1)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234, 1); ids.push_back(cmd->getMsgId()); _topLinks[0]->sendDown(cmd); } @@ -1198,8 +1070,8 @@ MergeThrottlerTest::testMergeWithNewerClusterStateFlushesOutdatedQueued() nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0x12345678)), nodes, 1234, 2)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0x12345678)), nodes, 1234, 2); ids.push_back(cmd->getMsgId()); _topLinks[0]->sendDown(cmd); } @@ -1211,30 +1083,27 @@ MergeThrottlerTest::testMergeWithNewerClusterStateFlushesOutdatedQueued() for (int i = 0; i < 3; ++i) { StorageMessage::SP reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - static_cast<MergeBucketReply&>(*reply).getResult().getResult(), - ReturnCode::WRONG_DISTRIBUTION); - CPPUNIT_ASSERT_EQUAL(1u, static_cast<MergeBucketReply&>(*reply).getClusterStateVersion()); - CPPUNIT_ASSERT_EQUAL(ids[maxPending + i], reply->getMsgId()); + ASSERT_EQ(static_cast<MergeBucketReply&>(*reply).getResult().getResult(), + ReturnCode::WRONG_DISTRIBUTION); + ASSERT_EQ(1u, static_cast<MergeBucketReply&>(*reply).getClusterStateVersion()); + ASSERT_EQ(ids[maxPending + i], reply->getMsgId()); } - CPPUNIT_ASSERT_EQUAL(uint64_t(3), _throttlers[0]->getMetrics().chaining.failures.wrongdistribution.getValue()); + EXPECT_EQ(uint64_t(3), _throttlers[0]->getMetrics().chaining.failures.wrongdistribution.getValue()); } -void -MergeThrottlerTest::testUpdatedClusterStateFlushesOutdatedQueued() -{ +TEST_F(MergeThrottlerTest, updated_cluster_state_flushes_outdated_queued) { // State is version 1. Send down several merges with state version 2. - std::size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); - CPPUNIT_ASSERT(maxPending < 100); + size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); + ASSERT_LT(maxPending, 100); std::vector<api::StorageMessage::Id> ids; for (std::size_t i = 0; i < maxPending + 3; ++i) { std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234, 2)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234, 2); ids.push_back(cmd->getMsgId()); _topLinks[0]->sendDown(cmd); } @@ -1245,8 +1114,8 @@ MergeThrottlerTest::testUpdatedClusterStateFlushesOutdatedQueued() // Send down new system state (also set it explicitly) _servers[0]->setClusterState(lib::ClusterState("distributor:100 storage:100 version:3")); - std::shared_ptr<api::SetSystemStateCommand> stateCmd( - new api::SetSystemStateCommand(lib::ClusterState("distributor:100 storage:100 version:3"))); + auto stateCmd = std::make_shared<api::SetSystemStateCommand>( + lib::ClusterState("distributor:100 storage:100 version:3")); _topLinks[0]->sendDown(stateCmd); // Queue should now be flushed with all being replied to with WRONG_DISTRIBUTION @@ -1255,29 +1124,27 @@ MergeThrottlerTest::testUpdatedClusterStateFlushesOutdatedQueued() for (int i = 0; i < 3; ++i) { StorageMessage::SP reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - static_cast<MergeBucketReply&>(*reply).getResult().getResult(), - ReturnCode::WRONG_DISTRIBUTION); - CPPUNIT_ASSERT_EQUAL(2u, static_cast<MergeBucketReply&>(*reply).getClusterStateVersion()); - CPPUNIT_ASSERT_EQUAL(ids[maxPending + i], reply->getMsgId()); + ASSERT_EQ(static_cast<MergeBucketReply&>(*reply).getResult().getResult(), + ReturnCode::WRONG_DISTRIBUTION); + ASSERT_EQ(2u, static_cast<MergeBucketReply&>(*reply).getClusterStateVersion()); + ASSERT_EQ(ids[maxPending + i], reply->getMsgId()); } - CPPUNIT_ASSERT_EQUAL(uint64_t(3), _throttlers[0]->getMetrics().chaining.failures.wrongdistribution.getValue()); + EXPECT_EQ(uint64_t(3), _throttlers[0]->getMetrics().chaining.failures.wrongdistribution.getValue()); } -void -MergeThrottlerTest::test42MergesDoNotTriggerFlush() -{ +// TODO remove functionality and test +TEST_F(MergeThrottlerTest, legacy_42_merges_do_not_trigger_flush) { // Fill up all active merges and then 1 queued one - std::size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); - CPPUNIT_ASSERT(maxPending < 100); + size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); + ASSERT_LT(maxPending, 100); for (std::size_t i = 0; i < maxPending + 1; ++i) { std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234, 1)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf00baa00 + i)), nodes, 1234, 1); _topLinks[0]->sendDown(cmd); } @@ -1285,7 +1152,7 @@ MergeThrottlerTest::test42MergesDoNotTriggerFlush() _topLinks[0]->waitForMessages(maxPending, _messageWaitTime); waitUntilMergeQueueIs(*_throttlers[0], 1, _messageWaitTime); - StorageMessage::SP fwd = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); + auto fwd = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); // Remove all the rest of the active merges while (!_topLinks[0]->getReplies().empty()) { @@ -1299,24 +1166,22 @@ MergeThrottlerTest::test42MergesDoNotTriggerFlush() nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xbaaadbed)), nodes, 1234, 0)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xbaaadbed)), nodes, 1234, 0); _topLinks[0]->sendDown(cmd); } waitUntilMergeQueueIs(*_throttlers[0], 2, _messageWaitTime); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _topLinks[0]->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _topLinks[0]->getNumReplies()); + ASSERT_EQ(0, _topLinks[0]->getNumCommands()); + ASSERT_EQ(0, _topLinks[0]->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(uint64_t(0), _throttlers[0]->getMetrics().local.failures.wrongdistribution.getValue()); + EXPECT_EQ(uint64_t(0), _throttlers[0]->getMetrics().local.failures.wrongdistribution.getValue()); } // Test that a merge that arrive with a state version that is less than // that of the node is rejected immediately -void -MergeThrottlerTest::testOutdatedClusterStateMergesAreRejectedOnArrival() -{ +TEST_F(MergeThrottlerTest, outdated_cluster_state_merges_are_rejected_on_arrival) { _servers[0]->setClusterState(lib::ClusterState("distributor:100 storage:100 version:10")); // Send down a merge with a cluster state version of 9, which should @@ -1326,28 +1191,25 @@ MergeThrottlerTest::testOutdatedClusterStateMergesAreRejectedOnArrival() nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xfeef00)), nodes, 1234, 9)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xfeef00)), nodes, 1234, 9); _topLinks[0]->sendDown(cmd); } _topLinks[0]->waitForMessages(1, _messageWaitTime); - StorageMessage::SP reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - static_cast<MergeBucketReply&>(*reply).getResult().getResult(), - ReturnCode::WRONG_DISTRIBUTION); + auto reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); + EXPECT_EQ(static_cast<MergeBucketReply&>(*reply).getResult().getResult(), + ReturnCode::WRONG_DISTRIBUTION); - CPPUNIT_ASSERT_EQUAL(uint64_t(1), _throttlers[0]->getMetrics().chaining.failures.wrongdistribution.getValue()); + EXPECT_EQ(uint64_t(1), _throttlers[0]->getMetrics().chaining.failures.wrongdistribution.getValue()); } // Test erroneous case where node receives merge where the merge does // not exist in the state, but it exists in the chain without the chain // being full. This is something that shouldn't happen, but must still // not crash the node -void -MergeThrottlerTest::testUnknownMergeWithSelfInChain() -{ +TEST_F(MergeThrottlerTest, unknown_merge_with_self_in_chain) { BucketId bid(32, 0xbadbed); std::vector<MergeBucketCommand::Node> nodes; @@ -1356,8 +1218,7 @@ MergeThrottlerTest::testUnknownMergeWithSelfInChain() nodes.push_back(2); std::vector<uint16_t> chain; chain.push_back(0); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(bid), nodes, 1234, 1, chain)); + auto cmd = std::make_shared<MergeBucketCommand>(makeDocumentBucket(bid), nodes, 1234, 1, chain); StorageMessageAddress address("storage", lib::NodeType::STORAGE, 1); @@ -1365,26 +1226,23 @@ MergeThrottlerTest::testUnknownMergeWithSelfInChain() _topLinks[0]->sendDown(cmd); _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); - StorageMessage::SP reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); + auto reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - ReturnCode::REJECTED, - static_cast<MergeBucketReply&>(*reply).getResult().getResult()); + EXPECT_EQ(ReturnCode::REJECTED, + static_cast<MergeBucketReply&>(*reply).getResult().getResult()); } -void -MergeThrottlerTest::testBusyReturnedOnFullQueue() -{ - std::size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); - std::size_t maxQueue = _throttlers[0]->getMaxQueueSize(); - CPPUNIT_ASSERT(maxPending < 100); +TEST_F(MergeThrottlerTest, busy_returned_on_full_queue) { + size_t maxPending = _throttlers[0]->getThrottlePolicy().getMaxPendingCount(); + size_t maxQueue = _throttlers[0]->getMaxQueueSize(); + ASSERT_LT(maxPending, 100); for (std::size_t i = 0; i < maxPending + maxQueue; ++i) { std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf00000 + i)), nodes, 1234, 1)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf00000 + i)), nodes, 1234, 1); _topLinks[0]->sendDown(cmd); } @@ -1400,32 +1258,24 @@ MergeThrottlerTest::testBusyReturnedOnFullQueue() nodes.push_back(0); nodes.push_back(1); nodes.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xf000baaa)), nodes, 1234, 1)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xf000baaa)), nodes, 1234, 1); _topLinks[0]->sendDown(cmd); } _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); - StorageMessage::SP reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); + auto reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL( - BucketId(32, 0xf000baaa), - static_cast<MergeBucketReply&>(*reply).getBucketId()); + EXPECT_EQ(BucketId(32, 0xf000baaa), + static_cast<MergeBucketReply&>(*reply).getBucketId()); - CPPUNIT_ASSERT_EQUAL( - ReturnCode::BUSY, - static_cast<MergeBucketReply&>(*reply).getResult().getResult()); + EXPECT_EQ(ReturnCode::BUSY, + static_cast<MergeBucketReply&>(*reply).getResult().getResult()); - CPPUNIT_ASSERT_EQUAL(uint64_t(0), - _throttlers[0]->getMetrics().chaining - .failures.busy.getValue()); - CPPUNIT_ASSERT_EQUAL(uint64_t(1), - _throttlers[0]->getMetrics().local - .failures.busy.getValue()); + EXPECT_EQ(0, _throttlers[0]->getMetrics().chaining.failures.busy.getValue()); + EXPECT_EQ(1, _throttlers[0]->getMetrics().local.failures.busy.getValue()); } -void -MergeThrottlerTest::testBrokenCycle() -{ +TEST_F(MergeThrottlerTest, broken_cycle) { std::vector<MergeBucketCommand::Node> nodes; nodes.push_back(1); nodes.push_back(0); @@ -1433,14 +1283,14 @@ MergeThrottlerTest::testBrokenCycle() { std::vector<uint16_t> chain; chain.push_back(0); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xfeef00)), nodes, 1234, 1, chain)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xfeef00)), nodes, 1234, 1, chain); _topLinks[1]->sendDown(cmd); } _topLinks[1]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); - StorageMessage::SP fwd = _topLinks[1]->getAndRemoveMessage(MessageType::MERGEBUCKET); - CPPUNIT_ASSERT_EQUAL(uint16_t(2), fwd->getAddress()->getIndex()); + auto fwd = _topLinks[1]->getAndRemoveMessage(MessageType::MERGEBUCKET); + ASSERT_EQ(2, fwd->getAddress()->getIndex()); // Send cycled merge which will be executed { @@ -1448,23 +1298,21 @@ MergeThrottlerTest::testBrokenCycle() chain.push_back(0); chain.push_back(1); chain.push_back(2); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xfeef00)), nodes, 1234, 1, chain)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xfeef00)), nodes, 1234, 1, chain); _topLinks[1]->sendDown(cmd); } _bottomLinks[1]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); - StorageMessage::SP cycled = _bottomLinks[1]->getAndRemoveMessage(MessageType::MERGEBUCKET); + auto cycled = _bottomLinks[1]->getAndRemoveMessage(MessageType::MERGEBUCKET); // Now, node 2 goes down, auto sending back a failed merge - std::shared_ptr<MergeBucketReply> nodeDownReply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*fwd))); + auto nodeDownReply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*fwd)); nodeDownReply->setResult(ReturnCode(ReturnCode::NOT_CONNECTED, "Node went sightseeing")); _topLinks[1]->sendDown(nodeDownReply); // Merge reply also arrives from persistence - std::shared_ptr<MergeBucketReply> persistenceReply( - new MergeBucketReply(dynamic_cast<const MergeBucketCommand&>(*cycled))); + auto persistenceReply = std::make_shared<MergeBucketReply>(dynamic_cast<const MergeBucketCommand&>(*cycled)); persistenceReply->setResult(ReturnCode(ReturnCode::ABORTED, "Oh dear")); _bottomLinks[1]->sendUp(persistenceReply); @@ -1474,8 +1322,8 @@ MergeThrottlerTest::testBrokenCycle() // Unwind reply shares the result of the persistence reply for (int i = 0; i < 2; ++i) { StorageMessage::SP reply = _topLinks[1]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(ReturnCode::ABORTED, "Oh dear"), - static_cast<MergeBucketReply&>(*reply).getResult()); + ASSERT_EQ(api::ReturnCode(ReturnCode::ABORTED, "Oh dear"), + static_cast<MergeBucketReply&>(*reply).getResult()); } // Make sure it has been removed from the internal state so we can @@ -1483,14 +1331,14 @@ MergeThrottlerTest::testBrokenCycle() { std::vector<uint16_t> chain; chain.push_back(0); - std::shared_ptr<MergeBucketCommand> cmd( - new MergeBucketCommand(makeDocumentBucket(BucketId(32, 0xfeef00)), nodes, 1234, 1, chain)); + auto cmd = std::make_shared<MergeBucketCommand>( + makeDocumentBucket(BucketId(32, 0xfeef00)), nodes, 1234, 1, chain); _topLinks[1]->sendDown(cmd); } _topLinks[1]->waitForMessage(MessageType::MERGEBUCKET, 5); fwd = _topLinks[1]->getAndRemoveMessage(MessageType::MERGEBUCKET); - CPPUNIT_ASSERT_EQUAL(uint16_t(2), fwd->getAddress()->getIndex()); + ASSERT_EQ(2, fwd->getAddress()->getIndex()); } void @@ -1501,39 +1349,33 @@ MergeThrottlerTest::sendAndExpectReply( { _topLinks[0]->sendDown(msg); _topLinks[0]->waitForMessage(expectedReplyType, _messageWaitTime); - StorageMessage::SP reply(_topLinks[0]->getAndRemoveMessage( - expectedReplyType)); + auto reply = _topLinks[0]->getAndRemoveMessage(expectedReplyType); auto& storageReply = dynamic_cast<api::StorageReply&>(*reply); - CPPUNIT_ASSERT_EQUAL(expectedResultCode, - storageReply.getResult().getResult()); + ASSERT_EQ(expectedResultCode, storageReply.getResult().getResult()); } -void -MergeThrottlerTest::testGetBucketDiffCommandNotInActiveSetIsRejected() -{ +TEST_F(MergeThrottlerTest, get_bucket_diff_command_not_in_active_set_is_rejected) { document::BucketId bucket(16, 1234); std::vector<api::GetBucketDiffCommand::Node> nodes; - std::shared_ptr<api::GetBucketDiffCommand> getDiffCmd( - new api::GetBucketDiffCommand(makeDocumentBucket(bucket), nodes, api::Timestamp(1234))); + auto getDiffCmd = std::make_shared<api::GetBucketDiffCommand>( + makeDocumentBucket(bucket), nodes, api::Timestamp(1234)); - sendAndExpectReply(getDiffCmd, - api::MessageType::GETBUCKETDIFF_REPLY, - api::ReturnCode::ABORTED); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _bottomLinks[0]->getNumCommands()); + ASSERT_NO_FATAL_FAILURE(sendAndExpectReply(getDiffCmd, + api::MessageType::GETBUCKETDIFF_REPLY, + api::ReturnCode::ABORTED)); + ASSERT_EQ(0, _bottomLinks[0]->getNumCommands()); } -void -MergeThrottlerTest::testApplyBucketDiffCommandNotInActiveSetIsRejected() -{ +TEST_F(MergeThrottlerTest, apply_bucket_diff_command_not_in_active_set_is_rejected) { document::BucketId bucket(16, 1234); std::vector<api::GetBucketDiffCommand::Node> nodes; - std::shared_ptr<api::ApplyBucketDiffCommand> applyDiffCmd( - new api::ApplyBucketDiffCommand(makeDocumentBucket(bucket), nodes, api::Timestamp(1234))); + auto applyDiffCmd = std::make_shared<api::ApplyBucketDiffCommand>( + makeDocumentBucket(bucket), nodes, api::Timestamp(1234)); - sendAndExpectReply(applyDiffCmd, - api::MessageType::APPLYBUCKETDIFF_REPLY, - api::ReturnCode::ABORTED); - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _bottomLinks[0]->getNumCommands()); + ASSERT_NO_FATAL_FAILURE(sendAndExpectReply(applyDiffCmd, + api::MessageType::APPLYBUCKETDIFF_REPLY, + api::ReturnCode::ABORTED)); + ASSERT_EQ(0, _bottomLinks[0]->getNumCommands()); } api::MergeBucketCommand::SP @@ -1544,51 +1386,47 @@ MergeThrottlerTest::sendMerge(const MergeBuilder& builder) return cmd; } -void -MergeThrottlerTest::testNewClusterStateAbortsAllOutdatedActiveMerges() -{ +TEST_F(MergeThrottlerTest, new_cluster_state_aborts_all_outdated_active_merges) { document::BucketId bucket(16, 6789); _throttlers[0]->getThrottlePolicy().setMaxPendingCount(1); // Merge will be forwarded (i.e. active). sendMerge(MergeBuilder(bucket).clusterStateVersion(10)); _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); - StorageMessage::SP fwd(_topLinks[0]->getAndRemoveMessage( - MessageType::MERGEBUCKET)); + auto fwd = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET); - _topLinks[0]->sendDown(makeSystemStateCmd( - "version:11 distributor:100 storage:100")); + _topLinks[0]->sendDown(makeSystemStateCmd("version:11 distributor:100 storage:100")); // Cannot send reply until we're unwinding - CPPUNIT_ASSERT_EQUAL(std::size_t(0), _topLinks[0]->getNumReplies()); + ASSERT_EQ(0, _topLinks[0]->getNumReplies()); // Trying to diff the bucket should now fail { - std::shared_ptr<api::GetBucketDiffCommand> getDiffCmd( - new api::GetBucketDiffCommand(makeDocumentBucket(bucket), {}, api::Timestamp(123))); + auto getDiffCmd = std::make_shared<api::GetBucketDiffCommand>( + makeDocumentBucket(bucket), std::vector<api::GetBucketDiffCommand::Node>(), api::Timestamp(123)); - sendAndExpectReply(getDiffCmd, - api::MessageType::GETBUCKETDIFF_REPLY, - api::ReturnCode::ABORTED); + ASSERT_NO_FATAL_FAILURE(sendAndExpectReply(getDiffCmd, + api::MessageType::GETBUCKETDIFF_REPLY, + api::ReturnCode::ABORTED)); } } -void MergeThrottlerTest::backpressure_busy_bounces_merges_for_configured_duration() { +TEST_F(MergeThrottlerTest, backpressure_busy_bounces_merges_for_configured_duration) { _servers[0]->getClock().setAbsoluteTimeInSeconds(1000); - CPPUNIT_ASSERT(!_throttlers[0]->backpressure_mode_active()); + EXPECT_FALSE(_throttlers[0]->backpressure_mode_active()); _throttlers[0]->apply_timed_backpressure(); - CPPUNIT_ASSERT(_throttlers[0]->backpressure_mode_active()); + EXPECT_TRUE(_throttlers[0]->backpressure_mode_active()); document::BucketId bucket(16, 6789); - CPPUNIT_ASSERT_EQUAL(uint64_t(0), _throttlers[0]->getMetrics().bounced_due_to_back_pressure.getValue()); - CPPUNIT_ASSERT_EQUAL(uint64_t(0), _throttlers[0]->getMetrics().local.failures.busy.getValue()); + EXPECT_EQ(0, _throttlers[0]->getMetrics().bounced_due_to_back_pressure.getValue()); + EXPECT_EQ(uint64_t(0), _throttlers[0]->getMetrics().local.failures.busy.getValue()); - sendAndExpectReply(MergeBuilder(bucket).create(), - api::MessageType::MERGEBUCKET_REPLY, - api::ReturnCode::BUSY); + ASSERT_NO_FATAL_FAILURE(sendAndExpectReply(MergeBuilder(bucket).create(), + api::MessageType::MERGEBUCKET_REPLY, + api::ReturnCode::BUSY)); - CPPUNIT_ASSERT_EQUAL(uint64_t(1), _throttlers[0]->getMetrics().bounced_due_to_back_pressure.getValue()); - CPPUNIT_ASSERT_EQUAL(uint64_t(1), _throttlers[0]->getMetrics().local.failures.busy.getValue()); + EXPECT_EQ(1, _throttlers[0]->getMetrics().bounced_due_to_back_pressure.getValue()); + EXPECT_EQ(1, _throttlers[0]->getMetrics().local.failures.busy.getValue()); _servers[0]->getClock().addSecondsToTime(15); // Test-config has duration set to 15 seconds // Backpressure has now been lifted. New merges should be forwarded @@ -1596,11 +1434,11 @@ void MergeThrottlerTest::backpressure_busy_bounces_merges_for_configured_duratio sendMerge(MergeBuilder(bucket)); _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); - CPPUNIT_ASSERT(!_throttlers[0]->backpressure_mode_active()); - CPPUNIT_ASSERT_EQUAL(uint64_t(1), _throttlers[0]->getMetrics().bounced_due_to_back_pressure.getValue()); + EXPECT_FALSE(_throttlers[0]->backpressure_mode_active()); + EXPECT_EQ(1, _throttlers[0]->getMetrics().bounced_due_to_back_pressure.getValue()); } -void MergeThrottlerTest::source_only_merges_are_not_affected_by_backpressure() { +TEST_F(MergeThrottlerTest, source_only_merges_are_not_affected_by_backpressure) { _servers[2]->getClock().setAbsoluteTimeInSeconds(1000); _throttlers[2]->apply_timed_backpressure(); document::BucketId bucket(16, 6789); @@ -1608,12 +1446,12 @@ void MergeThrottlerTest::source_only_merges_are_not_affected_by_backpressure() { _topLinks[2]->sendDown(MergeBuilder(bucket).chain(0, 1).source_only(2).create()); _topLinks[2]->waitForMessage(MessageType::MERGEBUCKET, _messageWaitTime); - CPPUNIT_ASSERT_EQUAL(uint64_t(0), _throttlers[0]->getMetrics().bounced_due_to_back_pressure.getValue()); + EXPECT_EQ(0, _throttlers[0]->getMetrics().bounced_due_to_back_pressure.getValue()); } void MergeThrottlerTest::fill_throttler_queue_with_n_commands(uint16_t throttler_index, size_t queued_count) { - std::size_t max_pending = _throttlers[throttler_index]->getThrottlePolicy().getMaxPendingCount(); - for (std::size_t i = 0; i < max_pending + queued_count; ++i) { + size_t max_pending = _throttlers[throttler_index]->getThrottlePolicy().getMaxPendingCount(); + for (size_t i = 0; i < max_pending + queued_count; ++i) { _topLinks[throttler_index]->sendDown(MergeBuilder(document::BucketId(16, i)).create()); } @@ -1622,7 +1460,7 @@ void MergeThrottlerTest::fill_throttler_queue_with_n_commands(uint16_t throttler waitUntilMergeQueueIs(*_throttlers[throttler_index], queued_count, _messageWaitTime); } -void MergeThrottlerTest::backpressure_evicts_all_queued_merges() { +TEST_F(MergeThrottlerTest, backpressure_evicts_all_queued_merges) { _servers[0]->getClock().setAbsoluteTimeInSeconds(1000); fill_throttler_queue_with_n_commands(0, 1); @@ -1631,7 +1469,7 @@ void MergeThrottlerTest::backpressure_evicts_all_queued_merges() { _topLinks[0]->waitForMessage(MessageType::MERGEBUCKET_REPLY, _messageWaitTime); auto reply = _topLinks[0]->getAndRemoveMessage(MessageType::MERGEBUCKET_REPLY); - CPPUNIT_ASSERT_EQUAL(ReturnCode::BUSY, dynamic_cast<const MergeBucketReply&>(*reply).getResult().getResult()); + EXPECT_EQ(ReturnCode::BUSY, dynamic_cast<const MergeBucketReply&>(*reply).getResult().getResult()); } // TODO test message queue aborting (use rendezvous functionality--make guard) diff --git a/storage/src/tests/storageserver/priorityconvertertest.cpp b/storage/src/tests/storageserver/priorityconvertertest.cpp index 54f451ebdb2..af0b35e0869 100644 --- a/storage/src/tests/storageserver/priorityconvertertest.cpp +++ b/storage/src/tests/storageserver/priorityconvertertest.cpp @@ -3,101 +3,71 @@ #include <vespa/documentapi/documentapi.h> #include <vespa/storage/storageserver/priorityconverter.h> #include <tests/common/testhelper.h> +#include <vespa/vespalib/gtest/gtest.h> + +using namespace ::testing; namespace storage { -struct PriorityConverterTest : public CppUnit::TestFixture -{ +struct PriorityConverterTest : Test { std::unique_ptr<PriorityConverter> _converter; - void setUp() override { + void SetUp() override { vdstestlib::DirConfig config(getStandardConfig(true)); - _converter.reset(new PriorityConverter(config.getConfigId())); + _converter = std::make_unique<PriorityConverter>(config.getConfigId()); }; - - void testNormalUsage(); - void testLowestPriorityIsReturnedForUnknownCode(); - - CPPUNIT_TEST_SUITE(PriorityConverterTest); - CPPUNIT_TEST(testNormalUsage); - CPPUNIT_TEST(testLowestPriorityIsReturnedForUnknownCode); - CPPUNIT_TEST_SUITE_END(); }; -CPPUNIT_TEST_SUITE_REGISTRATION(PriorityConverterTest); - -void PriorityConverterTest::testNormalUsage() -{ - for (int p=0; p<16; ++p) { - CPPUNIT_ASSERT_EQUAL( - (uint8_t)(50+p*10), +TEST_F(PriorityConverterTest, normal_usage) { + for (int p = 0; p < 16; ++p) { + EXPECT_EQ( + (50 + p * 10), _converter->toStoragePriority( static_cast<documentapi::Priority::Value>(p))); } - for (int i=0; i<256; ++i) { + for (int i = 0; i < 256; ++i) { uint8_t p = i; if (p <= 50) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_HIGHEST, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_HIGHEST, _converter->toDocumentPriority(p)); } else if (p <= 60) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_VERY_HIGH, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_VERY_HIGH, _converter->toDocumentPriority(p)); } else if (p <= 70) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_HIGH_1, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_HIGH_1, _converter->toDocumentPriority(p)); } else if (p <= 80) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_HIGH_2, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_HIGH_2, _converter->toDocumentPriority(p)); } else if (p <= 90) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_HIGH_3, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_HIGH_3, _converter->toDocumentPriority(p)); } else if (p <= 100) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_NORMAL_1, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_NORMAL_1, _converter->toDocumentPriority(p)); } else if (p <= 110) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_NORMAL_2, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_NORMAL_2, _converter->toDocumentPriority(p)); } else if (p <= 120) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_NORMAL_3, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_NORMAL_3, _converter->toDocumentPriority(p)); } else if (p <= 130) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_NORMAL_4, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_NORMAL_4, _converter->toDocumentPriority(p)); } else if (p <= 140) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_NORMAL_5, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_NORMAL_5, _converter->toDocumentPriority(p)); } else if (p <= 150) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_NORMAL_6, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_NORMAL_6, _converter->toDocumentPriority(p)); } else if (p <= 160) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_LOW_1, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_LOW_1, _converter->toDocumentPriority(p)); } else if (p <= 170) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_LOW_2, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_LOW_2, _converter->toDocumentPriority(p)); } else if (p <= 180) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_LOW_3, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_LOW_3, _converter->toDocumentPriority(p)); } else if (p <= 190) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_VERY_LOW, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_VERY_LOW, _converter->toDocumentPriority(p)); } else if (p <= 200) { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_LOWEST, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_LOWEST, _converter->toDocumentPriority(p)); } else { - CPPUNIT_ASSERT_EQUAL(documentapi::Priority::PRI_LOWEST, - _converter->toDocumentPriority(p)); + EXPECT_EQ(documentapi::Priority::PRI_LOWEST, _converter->toDocumentPriority(p)); } } } - -void -PriorityConverterTest::testLowestPriorityIsReturnedForUnknownCode() -{ - CPPUNIT_ASSERT_EQUAL(255, - static_cast<int>(_converter->toStoragePriority( - static_cast<documentapi::Priority::Value>(123)))); +TEST_F(PriorityConverterTest, lowest_priority_is_returned_for_unknown_code) { + EXPECT_EQ(255, static_cast<int>(_converter->toStoragePriority( + static_cast<documentapi::Priority::Value>(123)))); } } diff --git a/storage/src/tests/storageserver/service_layer_error_listener_test.cpp b/storage/src/tests/storageserver/service_layer_error_listener_test.cpp index b726a24b6b6..dc5324c00e3 100644 --- a/storage/src/tests/storageserver/service_layer_error_listener_test.cpp +++ b/storage/src/tests/storageserver/service_layer_error_listener_test.cpp @@ -3,30 +3,22 @@ #include <vespa/storage/storageserver/service_layer_error_listener.h> #include <vespa/storage/storageserver/mergethrottler.h> #include <vespa/storageframework/defaultimplementation/component/componentregisterimpl.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/vdstestlib/cppunit/dirconfig.h> #include <tests/common/testhelper.h> #include <tests/common/teststorageapp.h> +#include <vespa/vespalib/gtest/gtest.h> -namespace storage { +using namespace ::testing; -class ServiceLayerErrorListenerTest : public CppUnit::TestFixture { -public: - CPPUNIT_TEST_SUITE(ServiceLayerErrorListenerTest); - CPPUNIT_TEST(shutdown_invoked_on_fatal_error); - CPPUNIT_TEST(merge_throttle_backpressure_invoked_on_resource_exhaustion_error); - CPPUNIT_TEST_SUITE_END(); +namespace storage { - void shutdown_invoked_on_fatal_error(); - void merge_throttle_backpressure_invoked_on_resource_exhaustion_error(); +struct ServiceLayerErrorListenerTest : Test { }; -CPPUNIT_TEST_SUITE_REGISTRATION(ServiceLayerErrorListenerTest); - namespace { class TestShutdownListener - : public framework::defaultimplementation::ShutdownListener + : public framework::defaultimplementation::ShutdownListener { public: TestShutdownListener() : _reason() {} @@ -52,31 +44,31 @@ struct Fixture { ~Fixture(); }; -Fixture::~Fixture() {} +Fixture::~Fixture() = default; } -void ServiceLayerErrorListenerTest::shutdown_invoked_on_fatal_error() { +TEST_F(ServiceLayerErrorListenerTest, shutdown_invoked_on_fatal_error) { Fixture f; f.app.getComponentRegister().registerShutdownListener(f.shutdown_listener); - CPPUNIT_ASSERT(!f.shutdown_listener.shutdown_requested()); + EXPECT_FALSE(f.shutdown_listener.shutdown_requested()); f.error_listener.on_fatal_error("eject! eject!"); - CPPUNIT_ASSERT(f.shutdown_listener.shutdown_requested()); - CPPUNIT_ASSERT_EQUAL(vespalib::string("eject! eject!"), f.shutdown_listener.reason()); + EXPECT_TRUE(f.shutdown_listener.shutdown_requested()); + EXPECT_EQ("eject! eject!", f.shutdown_listener.reason()); // Should only be invoked once f.error_listener.on_fatal_error("here be dragons"); - CPPUNIT_ASSERT_EQUAL(vespalib::string("eject! eject!"), f.shutdown_listener.reason()); + EXPECT_EQ("eject! eject!", f.shutdown_listener.reason()); } -void ServiceLayerErrorListenerTest::merge_throttle_backpressure_invoked_on_resource_exhaustion_error() { +TEST_F(ServiceLayerErrorListenerTest, merge_throttle_backpressure_invoked_on_resource_exhaustion_error) { Fixture f; - CPPUNIT_ASSERT(!f.merge_throttler.backpressure_mode_active()); + EXPECT_FALSE(f.merge_throttler.backpressure_mode_active()); f.error_listener.on_resource_exhaustion_error("buy more RAM!"); - CPPUNIT_ASSERT(f.merge_throttler.backpressure_mode_active()); + EXPECT_TRUE(f.merge_throttler.backpressure_mode_active()); } } diff --git a/storage/src/tests/storageserver/statemanagertest.cpp b/storage/src/tests/storageserver/statemanagertest.cpp index cdf990fa28f..c2074c53dd7 100644 --- a/storage/src/tests/storageserver/statemanagertest.cpp +++ b/storage/src/tests/storageserver/statemanagertest.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 <vespa/metrics/metricmanager.h> #include <vespa/storageapi/message/bucket.h> #include <vespa/storageapi/message/state.h> @@ -11,15 +10,17 @@ #include <tests/common/testhelper.h> #include <tests/common/dummystoragelink.h> #include <vespa/vespalib/data/slime/slime.h> +#include <vespa/vespalib/gtest/gtest.h> using storage::lib::NodeState; using storage::lib::NodeType; using storage::lib::State; using storage::lib::ClusterState; +using namespace ::testing; namespace storage { -struct StateManagerTest : public CppUnit::TestFixture { +struct StateManagerTest : Test { std::unique_ptr<TestServiceLayerApp> _node; std::unique_ptr<DummyStorageLink> _upper; std::unique_ptr<metrics::MetricManager> _metricManager; @@ -28,26 +29,8 @@ struct StateManagerTest : public CppUnit::TestFixture { StateManagerTest(); - void setUp() override; - void tearDown() override; - - void testSystemState(); - void testReportedNodeState(); - void current_cluster_state_version_is_included_in_host_info_json(); - void can_explicitly_send_get_node_state_reply(); - void explicit_node_state_replying_without_pending_request_immediately_replies_on_next_request(); - void immediate_node_state_replying_is_tracked_per_controller(); - void activation_command_is_bounced_with_current_cluster_state_version(); - - CPPUNIT_TEST_SUITE(StateManagerTest); - CPPUNIT_TEST(testSystemState); - CPPUNIT_TEST(testReportedNodeState); - CPPUNIT_TEST(current_cluster_state_version_is_included_in_host_info_json); - CPPUNIT_TEST(can_explicitly_send_get_node_state_reply); - CPPUNIT_TEST(explicit_node_state_replying_without_pending_request_immediately_replies_on_next_request); - CPPUNIT_TEST(immediate_node_state_replying_is_tracked_per_controller); - CPPUNIT_TEST(activation_command_is_bounced_with_current_cluster_state_version); - CPPUNIT_TEST_SUITE_END(); + void SetUp() override; + void TearDown() override; void force_current_cluster_state_version(uint32_t version); void mark_reported_node_state_up(); @@ -55,52 +38,49 @@ struct StateManagerTest : public CppUnit::TestFixture { void assert_ok_get_node_state_reply_sent_and_clear(); void clear_sent_replies(); void mark_reply_observed_from_n_controllers(uint16_t n); -}; -CPPUNIT_TEST_SUITE_REGISTRATION(StateManagerTest); + std::string get_node_info() const { + return _manager->getNodeInfo(); + } +}; StateManagerTest::StateManagerTest() : _node(), _upper(), - _manager(0), - _lower(0) + _manager(nullptr), + _lower(nullptr) { } void -StateManagerTest::setUp() { - try{ - vdstestlib::DirConfig config(getStandardConfig(true)); - _node.reset(new TestServiceLayerApp(DiskCount(1), NodeIndex(2))); - // Clock will increase 1 sec per call. - _node->getClock().setAbsoluteTimeInSeconds(1); - _metricManager.reset(new metrics::MetricManager); - _upper.reset(new DummyStorageLink()); - _manager = new StateManager(_node->getComponentRegister(), - *_metricManager, - std::unique_ptr<HostInfo>(new HostInfo)); - _lower = new DummyStorageLink(); - _upper->push_back(StorageLink::UP(_manager)); - _upper->push_back(StorageLink::UP(_lower)); - _upper->open(); - } catch (std::exception& e) { - std::cerr << "Failed to static initialize objects: " << e.what() - << "\n"; - } +StateManagerTest::SetUp() { + vdstestlib::DirConfig config(getStandardConfig(true)); + _node = std::make_unique<TestServiceLayerApp>(DiskCount(1), NodeIndex(2)); + // Clock will increase 1 sec per call. + _node->getClock().setAbsoluteTimeInSeconds(1); + _metricManager = std::make_unique<metrics::MetricManager>(); + _upper = std::make_unique<DummyStorageLink>(); + _manager = new StateManager(_node->getComponentRegister(), + *_metricManager, + std::make_unique<HostInfo>()); + _lower = new DummyStorageLink(); + _upper->push_back(StorageLink::UP(_manager)); + _upper->push_back(StorageLink::UP(_lower)); + _upper->open(); } void -StateManagerTest::tearDown() { - CPPUNIT_ASSERT_EQUAL(size_t(0), _lower->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(size_t(0), _lower->getNumCommands()); - CPPUNIT_ASSERT_EQUAL(size_t(0), _upper->getNumReplies()); - CPPUNIT_ASSERT_EQUAL(size_t(0), _upper->getNumCommands()); - _manager = 0; - _lower = 0; +StateManagerTest::TearDown() { + assert(_lower->getNumReplies() == 0); + assert(_lower->getNumCommands() == 0); + assert(_upper->getNumReplies() == 0); + assert(_upper->getNumCommands() == 0); + _manager = nullptr; + _lower = nullptr; _upper->close(); _upper->flush(); - _upper.reset(0); - _node.reset(0); + _upper.reset(); + _node.reset(); _metricManager.reset(); } @@ -112,107 +92,96 @@ void StateManagerTest::force_current_cluster_state_version(uint32_t version) { #define GET_ONLY_OK_REPLY(varname) \ { \ - CPPUNIT_ASSERT_EQUAL(size_t(1), _upper->getNumReplies()); \ - CPPUNIT_ASSERT(_upper->getReply(0)->getType().isReply()); \ + ASSERT_EQ(size_t(1), _upper->getNumReplies()); \ + ASSERT_TRUE(_upper->getReply(0)->getType().isReply()); \ varname = std::dynamic_pointer_cast<api::StorageReply>( \ _upper->getReply(0)); \ - CPPUNIT_ASSERT(varname != 0); \ + ASSERT_TRUE(varname.get() != nullptr); \ _upper->reset(); \ - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::OK), \ - varname->getResult()); \ + ASSERT_EQ(api::ReturnCode(api::ReturnCode::OK), \ + varname->getResult()); \ } -void -StateManagerTest::testSystemState() -{ +TEST_F(StateManagerTest, cluster_state) { std::shared_ptr<api::StorageReply> reply; - // Verify initial state on startup - ClusterState::CSP currentState = _manager->getClusterStateBundle()->getBaselineClusterState(); - CPPUNIT_ASSERT_EQUAL(std::string("cluster:d"), - currentState->toString(false)); + // Verify initial state on startup + auto currentState = _manager->getClusterStateBundle()->getBaselineClusterState(); + EXPECT_EQ("cluster:d", currentState->toString(false)); - NodeState::CSP currentNodeState = _manager->getCurrentNodeState(); - CPPUNIT_ASSERT_EQUAL(std::string("s:d"), currentNodeState->toString(false)); + auto currentNodeState = _manager->getCurrentNodeState(); + EXPECT_EQ("s:d", currentNodeState->toString(false)); ClusterState sendState("storage:4 .2.s:m"); - std::shared_ptr<api::SetSystemStateCommand> cmd( - new api::SetSystemStateCommand(sendState)); + auto cmd = std::make_shared<api::SetSystemStateCommand>(sendState); _upper->sendDown(cmd); GET_ONLY_OK_REPLY(reply); currentState = _manager->getClusterStateBundle()->getBaselineClusterState(); - CPPUNIT_ASSERT_EQUAL(sendState, *currentState); + EXPECT_EQ(sendState, *currentState); currentNodeState = _manager->getCurrentNodeState(); - CPPUNIT_ASSERT_EQUAL(std::string("s:m"), currentNodeState->toString(false)); + EXPECT_EQ("s:m", currentNodeState->toString(false)); } namespace { - struct MyStateListener : public StateListener { - const NodeStateUpdater& updater; - lib::NodeState current; - std::ostringstream ost; - - MyStateListener(const NodeStateUpdater& upd) - : updater(upd), current(*updater.getReportedNodeState()) {} - ~MyStateListener() { } - - void handleNewState() override { - ost << current << " -> "; - current = *updater.getReportedNodeState(); - ost << current << "\n"; - } - }; +struct MyStateListener : public StateListener { + const NodeStateUpdater& updater; + lib::NodeState current; + std::ostringstream ost; + + MyStateListener(const NodeStateUpdater& upd) + : updater(upd), current(*updater.getReportedNodeState()) {} + ~MyStateListener() override = default; + + void handleNewState() override { + ost << current << " -> "; + current = *updater.getReportedNodeState(); + ost << current << "\n"; + } +}; } -void -StateManagerTest::testReportedNodeState() -{ +TEST_F(StateManagerTest, reported_node_state) { std::shared_ptr<api::StorageReply> reply; - // Add a state listener to check that we get events. + // Add a state listener to check that we get events. MyStateListener stateListener(*_manager); _manager->addStateListener(stateListener); - // Test that initial state is initializing - NodeState::CSP nodeState = _manager->getReportedNodeState(); - CPPUNIT_ASSERT_EQUAL(std::string("s:i b:58 i:0 t:1"), nodeState->toString(false)); - // Test that it works to update the state + // Test that initial state is initializing + auto nodeState = _manager->getReportedNodeState(); + EXPECT_EQ("s:i b:58 i:0 t:1", nodeState->toString(false)); + // Test that it works to update the state { - NodeStateUpdater::Lock::SP lock(_manager->grabStateChangeLock()); + auto lock = _manager->grabStateChangeLock(); NodeState ns(*_manager->getReportedNodeState()); ns.setState(State::UP); _manager->setReportedNodeState(ns); } - // And that we get the change both through state interface + // And that we get the change both through state interface nodeState = _manager->getReportedNodeState(); - CPPUNIT_ASSERT_EQUAL(std::string("s:u b:58 t:1"), - nodeState->toString(false)); - // And get node state command (no expected state) - std::shared_ptr<api::GetNodeStateCommand> cmd( - new api::GetNodeStateCommand(lib::NodeState::UP())); + EXPECT_EQ("s:u b:58 t:1", nodeState->toString(false)); + // And get node state command (no expected state) + auto cmd = std::make_shared<api::GetNodeStateCommand>(lib::NodeState::UP()); _upper->sendDown(cmd); GET_ONLY_OK_REPLY(reply); - CPPUNIT_ASSERT_EQUAL(api::MessageType::GETNODESTATE_REPLY, - reply->getType()); - nodeState.reset(new NodeState( - dynamic_cast<api::GetNodeStateReply&>(*reply).getNodeState())); - CPPUNIT_ASSERT_EQUAL(std::string("s:u b:58 t:1"), - nodeState->toString(false)); - // We should also get it with wrong expected state - cmd.reset(new api::GetNodeStateCommand(lib::NodeState::UP(new NodeState(NodeType::STORAGE, State::INITIALIZING)))); + ASSERT_EQ(api::MessageType::GETNODESTATE_REPLY, reply->getType()); + nodeState = std::make_shared<NodeState>( + dynamic_cast<api::GetNodeStateReply&>(*reply).getNodeState()); + EXPECT_EQ("s:u b:58 t:1", nodeState->toString(false)); + // We should also get it with wrong expected state + cmd = std::make_shared<api::GetNodeStateCommand>( + std::make_unique<NodeState>(NodeType::STORAGE, State::INITIALIZING)); _upper->sendDown(cmd); GET_ONLY_OK_REPLY(reply); - CPPUNIT_ASSERT_EQUAL(api::MessageType::GETNODESTATE_REPLY, - reply->getType()); - nodeState.reset(new NodeState( - dynamic_cast<api::GetNodeStateReply&>(*reply).getNodeState())); - CPPUNIT_ASSERT_EQUAL(std::string("s:u b:58 t:1"), - nodeState->toString(false)); - // With correct wanted state we should not get response right away - cmd.reset(new api::GetNodeStateCommand( - lib::NodeState::UP(new NodeState("s:u b:58 t:1", &NodeType::STORAGE)))); + ASSERT_EQ(api::MessageType::GETNODESTATE_REPLY, reply->getType()); + nodeState = std::make_unique<NodeState>( + dynamic_cast<api::GetNodeStateReply&>(*reply).getNodeState()); + EXPECT_EQ("s:u b:58 t:1", nodeState->toString(false)); + // With correct wanted state we should not get response right away + cmd = std::make_shared<api::GetNodeStateCommand>( + std::make_unique<lib::NodeState>("s:u b:58 t:1", &NodeType::STORAGE)); _upper->sendDown(cmd); - CPPUNIT_ASSERT_EQUAL(size_t(0), _upper->getNumReplies()); - // But when we update state, we get the reply + ASSERT_EQ(size_t(0), _upper->getNumReplies()); + // But when we update state, we get the reply { NodeStateUpdater::Lock::SP lock(_manager->grabStateChangeLock()); NodeState ns(*_manager->getReportedNodeState()); @@ -222,16 +191,14 @@ StateManagerTest::testReportedNodeState() } GET_ONLY_OK_REPLY(reply); - CPPUNIT_ASSERT_EQUAL(api::MessageType::GETNODESTATE_REPLY, - reply->getType()); - nodeState.reset(new NodeState( - dynamic_cast<api::GetNodeStateReply&>(*reply).getNodeState())); - CPPUNIT_ASSERT_EQUAL(std::string("s:s b:58 t:1 m:Stopping\\x20node"), - nodeState->toString(false)); - - // Removing state listener, it stops getting updates + ASSERT_EQ(api::MessageType::GETNODESTATE_REPLY, reply->getType()); + nodeState = std::make_unique<NodeState>( + dynamic_cast<api::GetNodeStateReply&>(*reply).getNodeState()); + EXPECT_EQ("s:s b:58 t:1 m:Stopping\\x20node", nodeState->toString(false)); + + // Removing state listener, it stops getting updates _manager->removeStateListener(stateListener); - // Do another update which listener should not get.. + // Do another update which listener should not get.. { NodeStateUpdater::Lock::SP lock(_manager->grabStateChangeLock()); NodeState ns(*_manager->getReportedNodeState()); @@ -241,35 +208,34 @@ StateManagerTest::testReportedNodeState() std::string expectedEvents = "s:i b:58 i:0 t:1 -> s:u b:58 t:1\n" "s:u b:58 t:1 -> s:s b:58 t:1 m:Stopping\\x20node\n"; - CPPUNIT_ASSERT_EQUAL(expectedEvents, stateListener.ost.str()); + EXPECT_EQ(expectedEvents, stateListener.ost.str()); } -void StateManagerTest::current_cluster_state_version_is_included_in_host_info_json() { +TEST_F(StateManagerTest, current_cluster_state_version_is_included_in_host_info_json) { force_current_cluster_state_version(123); - std::string nodeInfoString(_manager->getNodeInfo()); + std::string nodeInfoString = get_node_info(); vespalib::Memory goldenMemory(nodeInfoString); vespalib::Slime nodeInfo; vespalib::slime::JsonFormat::decode(nodeInfoString, nodeInfo); - vespalib::slime::Symbol lookupSymbol = - nodeInfo.lookup("cluster-state-version"); + vespalib::slime::Symbol lookupSymbol = nodeInfo.lookup("cluster-state-version"); if (lookupSymbol.undefined()) { - CPPUNIT_FAIL("No cluster-state-version was found in the node info"); + FAIL() << "No cluster-state-version was found in the node info"; } auto& cursor = nodeInfo.get(); auto& clusterStateVersionCursor = cursor["cluster-state-version"]; if (!clusterStateVersionCursor.valid()) { - CPPUNIT_FAIL("No cluster-state-version was found in the node info"); + FAIL() << "No cluster-state-version was found in the node info"; } if (clusterStateVersionCursor.type().getId() != vespalib::slime::LONG::ID) { - CPPUNIT_FAIL("No cluster-state-version was found in the node info"); + FAIL() << "No cluster-state-version was found in the node info"; } int version = clusterStateVersionCursor.asLong(); - CPPUNIT_ASSERT_EQUAL(123, version); + EXPECT_EQ(123, version); } void StateManagerTest::mark_reported_node_state_up() { @@ -286,10 +252,10 @@ void StateManagerTest::send_down_get_node_state_request(uint16_t controller_inde } void StateManagerTest::assert_ok_get_node_state_reply_sent_and_clear() { - CPPUNIT_ASSERT_EQUAL(size_t(1), _upper->getNumReplies()); + ASSERT_EQ(1, _upper->getNumReplies()); std::shared_ptr<api::StorageReply> reply; GET_ONLY_OK_REPLY(reply); // Implicitly clears messages from _upper - CPPUNIT_ASSERT_EQUAL(api::MessageType::GETNODESTATE_REPLY, reply->getType()); + ASSERT_EQ(api::MessageType::GETNODESTATE_REPLY, reply->getType()); } void StateManagerTest::clear_sent_replies() { @@ -299,11 +265,11 @@ void StateManagerTest::clear_sent_replies() { void StateManagerTest::mark_reply_observed_from_n_controllers(uint16_t n) { for (uint16_t i = 0; i < n; ++i) { send_down_get_node_state_request(i); - assert_ok_get_node_state_reply_sent_and_clear(); + ASSERT_NO_FATAL_FAILURE(assert_ok_get_node_state_reply_sent_and_clear()); } } -void StateManagerTest::can_explicitly_send_get_node_state_reply() { +TEST_F(StateManagerTest, can_explicitly_send_get_node_state_reply) { mark_reported_node_state_up(); // Must "pre-trigger" that a controller has already received a GetNodeState // reply, or an immediate reply will be sent by default when the first request @@ -311,13 +277,13 @@ void StateManagerTest::can_explicitly_send_get_node_state_reply() { mark_reply_observed_from_n_controllers(1); send_down_get_node_state_request(0); - CPPUNIT_ASSERT_EQUAL(size_t(0), _upper->getNumReplies()); + ASSERT_EQ(0, _upper->getNumReplies()); _manager->immediately_send_get_node_state_replies(); - assert_ok_get_node_state_reply_sent_and_clear(); + ASSERT_NO_FATAL_FAILURE(assert_ok_get_node_state_reply_sent_and_clear()); } -void StateManagerTest::explicit_node_state_replying_without_pending_request_immediately_replies_on_next_request() { +TEST_F(StateManagerTest, explicit_node_state_replying_without_pending_request_immediately_replies_on_next_request) { mark_reported_node_state_up(); mark_reply_observed_from_n_controllers(1); @@ -325,13 +291,13 @@ void StateManagerTest::explicit_node_state_replying_without_pending_request_imme _manager->immediately_send_get_node_state_replies(); send_down_get_node_state_request(0); - assert_ok_get_node_state_reply_sent_and_clear(); + ASSERT_NO_FATAL_FAILURE(assert_ok_get_node_state_reply_sent_and_clear()); // Sending a new request should now _not_ immediately receive a reply send_down_get_node_state_request(0); - CPPUNIT_ASSERT_EQUAL(size_t(0), _upper->getNumReplies()); + ASSERT_EQ(0, _upper->getNumReplies()); } -void StateManagerTest::immediate_node_state_replying_is_tracked_per_controller() { +TEST_F(StateManagerTest, immediate_node_state_replying_is_tracked_per_controller) { mark_reported_node_state_up(); mark_reply_observed_from_n_controllers(3); @@ -340,17 +306,17 @@ void StateManagerTest::immediate_node_state_replying_is_tracked_per_controller() send_down_get_node_state_request(0); send_down_get_node_state_request(1); send_down_get_node_state_request(2); - CPPUNIT_ASSERT_EQUAL(size_t(3), _upper->getNumReplies()); + ASSERT_EQ(3, _upper->getNumReplies()); clear_sent_replies(); // Sending a new request should now _not_ immediately receive a reply send_down_get_node_state_request(0); send_down_get_node_state_request(1); send_down_get_node_state_request(2); - CPPUNIT_ASSERT_EQUAL(size_t(0), _upper->getNumReplies()); + ASSERT_EQ(0, _upper->getNumReplies()); } -void StateManagerTest::activation_command_is_bounced_with_current_cluster_state_version() { +TEST_F(StateManagerTest, activation_command_is_bounced_with_current_cluster_state_version) { force_current_cluster_state_version(12345); auto cmd = std::make_shared<api::ActivateClusterStateVersionCommand>(12340); @@ -358,13 +324,13 @@ void StateManagerTest::activation_command_is_bounced_with_current_cluster_state_ cmd->setSourceIndex(0); _upper->sendDown(cmd); - CPPUNIT_ASSERT_EQUAL(size_t(1), _upper->getNumReplies()); + ASSERT_EQ(1, _upper->getNumReplies()); std::shared_ptr<api::StorageReply> reply; GET_ONLY_OK_REPLY(reply); // Implicitly clears messages from _upper - CPPUNIT_ASSERT_EQUAL(api::MessageType::ACTIVATE_CLUSTER_STATE_VERSION_REPLY, reply->getType()); + ASSERT_EQ(api::MessageType::ACTIVATE_CLUSTER_STATE_VERSION_REPLY, reply->getType()); auto& activate_reply = dynamic_cast<api::ActivateClusterStateVersionReply&>(*reply); - CPPUNIT_ASSERT_EQUAL(uint32_t(12340), activate_reply.activateVersion()); - CPPUNIT_ASSERT_EQUAL(uint32_t(12345), activate_reply.actualVersion()); + EXPECT_EQ(12340, activate_reply.activateVersion()); + EXPECT_EQ(12345, activate_reply.actualVersion()); } } // storage diff --git a/storage/src/tests/storageserver/statereportertest.cpp b/storage/src/tests/storageserver/statereportertest.cpp index d0cdf41823b..c84f9311c52 100644 --- a/storage/src/tests/storageserver/statereportertest.cpp +++ b/storage/src/tests/storageserver/statereportertest.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 <vespa/storageframework/defaultimplementation/clock/fakeclock.h> #include <vespa/storage/persistence/filestorage/filestormanager.h> #include <vespa/storage/storageserver/applicationgenerationfetcher.h> @@ -11,10 +10,13 @@ #include <tests/common/dummystoragelink.h> #include <vespa/config/common/exceptions.h> #include <vespa/vespalib/data/slime/slime.h> +#include <vespa/vespalib/gtest/gtest.h> #include <vespa/log/log.h> LOG_SETUP(".test.statereporter"); +using namespace ::testing; + namespace storage { class DummyApplicationGenerationFether : public ApplicationGenerationFetcher { @@ -23,7 +25,7 @@ public: std::string getComponentName() const override { return "component"; } }; -struct StateReporterTest : public CppUnit::TestFixture { +struct StateReporterTest : Test { FastOS_ThreadPool _threadPool; framework::defaultimplementation::FakeClock* _clock; std::unique_ptr<TestServiceLayerApp> _node; @@ -37,87 +39,72 @@ struct StateReporterTest : public CppUnit::TestFixture { StateReporterTest(); - void setUp() override; - void tearDown() override; + void SetUp() override; + void TearDown() override; void runLoad(uint32_t count = 1); +}; - void testReportConfigGeneration(); - void testReportHealth(); - void testReportMetrics(); +namespace { - CPPUNIT_TEST_SUITE(StateReporterTest); - CPPUNIT_TEST(testReportConfigGeneration); - CPPUNIT_TEST(testReportHealth); - CPPUNIT_TEST(testReportMetrics); - CPPUNIT_TEST_SUITE_END(); +struct MetricClock : public metrics::MetricManager::Timer +{ + framework::Clock& _clock; + explicit MetricClock(framework::Clock& c) : _clock(c) {} + time_t getTime() const override { return _clock.getTimeInSeconds().getTime(); } + time_t getTimeInMilliSecs() const override { return _clock.getTimeInMillis().getTime(); } }; -CPPUNIT_TEST_SUITE_REGISTRATION(StateReporterTest); - -namespace { - struct MetricClock : public metrics::MetricManager::Timer - { - framework::Clock& _clock; - MetricClock(framework::Clock& c) : _clock(c) {} - time_t getTime() const override { return _clock.getTimeInSeconds().getTime(); } - time_t getTimeInMilliSecs() const override { return _clock.getTimeInMillis().getTime(); } - }; } StateReporterTest::StateReporterTest() : _threadPool(256*1024), - _clock(0), + _clock(nullptr), _top(), _stateReporter() { } -void StateReporterTest::setUp() { - _config.reset(new vdstestlib::DirConfig(getStandardConfig(true, "statereportertest"))); +void StateReporterTest::SetUp() { + _config = std::make_unique<vdstestlib::DirConfig>(getStandardConfig(true, "statereportertest")); assert(system(("rm -rf " + getRootFolder(*_config)).c_str()) == 0); - try { - _node.reset(new TestServiceLayerApp(DiskCount(4), NodeIndex(0), - _config->getConfigId())); - _node->setupDummyPersistence(); - _clock = &_node->getClock(); - _clock->setAbsoluteTimeInSeconds(1000000); - _top.reset(new DummyStorageLink); - } catch (config::InvalidConfigException& e) { - fprintf(stderr, "%s\n", e.what()); - } - _metricManager.reset(new metrics::MetricManager( - std::unique_ptr<metrics::MetricManager::Timer>( - new MetricClock(*_clock)))); + + _node = std::make_unique<TestServiceLayerApp>(DiskCount(4), NodeIndex(0), _config->getConfigId()); + _node->setupDummyPersistence(); + _clock = &_node->getClock(); + _clock->setAbsoluteTimeInSeconds(1000000); + _top = std::make_unique<DummyStorageLink>(); + + _metricManager = std::make_unique<metrics::MetricManager>(std::make_unique<MetricClock>(*_clock)); _topSet.reset(new metrics::MetricSet("vds", {}, "")); { metrics::MetricLockGuard guard(_metricManager->getMetricLock()); _metricManager->registerMetric(guard, *_topSet); } - _stateReporter.reset(new StateReporter( + _stateReporter = std::make_unique<StateReporter>( _node->getComponentRegister(), *_metricManager, _generationFetcher, - "status")); + "status"); uint16_t diskCount = _node->getPartitions().size(); documentapi::LoadTypeSet::SP loadTypes(_node->getLoadTypes()); - _filestorMetrics.reset(new FileStorMetrics(_node->getLoadTypes()->getMetricLoadTypes())); + _filestorMetrics = std::make_shared<FileStorMetrics>(_node->getLoadTypes()->getMetricLoadTypes()); _filestorMetrics->initDiskMetrics(diskCount, loadTypes->getMetricLoadTypes(), 1, 1); _topSet->registerMetric(*_filestorMetrics); _metricManager->init(_config->getConfigId(), _node->getThreadPool()); } -void StateReporterTest::tearDown() { +void StateReporterTest::TearDown() { _metricManager->stop(); - _stateReporter.reset(0); - _topSet.reset(0); - _metricManager.reset(0); - _top.reset(0); - _node.reset(0); - _config.reset(0); + _stateReporter.reset(); + _topSet.reset(); + _metricManager.reset(); + _top.reset(); + _node.reset(); + _config.reset(); _filestorMetrics.reset(); } @@ -129,17 +116,15 @@ vespalib::Slime slime; \ vespalib::SimpleBuffer buffer; \ JsonFormat::encode(slime, buffer, false); \ if (parsed == 0) { \ - std::ostringstream error; \ - error << "Failed to parse JSON: '\n" \ - << jsonData << "'\n:" << buffer.get().make_string() << "\n"; \ - CPPUNIT_ASSERT_EQUAL_MSG(error.str(), jsonData.size(), parsed); \ + ASSERT_EQ(jsonData.size(), parsed) << "Failed to parse JSON: '\n" \ + << jsonData << "':" << buffer.get().make_string(); \ } \ } #define ASSERT_GENERATION(jsonData, component, generation) \ { \ PARSE_JSON(jsonData); \ - CPPUNIT_ASSERT_EQUAL( \ + ASSERT_EQ( \ generation, \ slime.get()["config"][component]["generation"].asDouble()); \ } @@ -147,10 +132,10 @@ vespalib::Slime slime; \ #define ASSERT_NODE_STATUS(jsonData, code, message) \ { \ PARSE_JSON(jsonData); \ - CPPUNIT_ASSERT_EQUAL( \ + ASSERT_EQ( \ vespalib::string(code), \ slime.get()["status"]["code"].asString().make_string()); \ - CPPUNIT_ASSERT_EQUAL( \ + ASSERT_EQ( \ vespalib::string(message), \ slime.get()["status"]["message"].asString().make_string()); \ } @@ -161,7 +146,6 @@ vespalib::Slime slime; \ double getCount = -1; \ double putCount = -1; \ size_t metricCount = slime.get()["metrics"]["values"].children(); \ - /*std::cerr << "\nmetric count=" << metricCount << "\n";*/ \ for (size_t j=0; j<metricCount; j++) { \ const vespalib::string name = slime.get()["metrics"]["values"][j]["name"] \ .asString().make_string(); \ @@ -177,22 +161,21 @@ vespalib::Slime slime; \ .asDouble(); \ } \ } \ - CPPUNIT_ASSERT_EQUAL(expGetCount, getCount); \ - CPPUNIT_ASSERT_EQUAL(expPutCount, putCount); \ - CPPUNIT_ASSERT(metricCount > 100); \ + ASSERT_EQ(expGetCount, getCount); \ + ASSERT_EQ(expPutCount, putCount); \ + ASSERT_GT(metricCount, 100); \ } -void StateReporterTest::testReportConfigGeneration() { +TEST_F(StateReporterTest, report_config_generation) { std::ostringstream ost; framework::HttpUrlPath path("/state/v1/config"); _stateReporter->reportStatus(ost, path); std::string jsonData = ost.str(); - //std::cerr << "\nConfig: " << jsonData << "\n"; ASSERT_GENERATION(jsonData, "component", 1.0); } -void StateReporterTest::testReportHealth() { +TEST_F(StateReporterTest, report_health) { const int stateCount = 7; const lib::NodeState nodeStates[stateCount] = { lib::NodeState(lib::NodeType::STORAGE, lib::State::UNKNOWN), @@ -228,23 +211,22 @@ void StateReporterTest::testReportHealth() { std::ostringstream ost; _stateReporter->reportStatus(ost, path); std::string jsonData = ost.str(); - //std::cerr << "\nHealth " << i << ":" << jsonData << "\n"; ASSERT_NODE_STATUS(jsonData, codes[i], messages[i]); } } -void StateReporterTest::testReportMetrics() { +TEST_F(StateReporterTest, report_metrics) { FileStorDiskMetrics& disk0(*_filestorMetrics->disks[0]); FileStorThreadMetrics& thread0(*disk0.threads[0]); - LOG(info, "Adding to get metric"); + LOG(debug, "Adding to get metric"); using documentapi::LoadType; thread0.get[LoadType::DEFAULT].count.inc(1); - LOG(info, "Waiting for 5 minute snapshot to be taken"); + LOG(debug, "Waiting for 5 minute snapshot to be taken"); // Wait until active metrics have been added to 5 min snapshot and reset - for (uint32_t i=0; i<6; ++i) { + for (uint32_t i = 0; i < 6; ++i) { _clock->addSecondsToTime(60); _metricManager->timeChangedNotification(); while ( @@ -254,7 +236,7 @@ void StateReporterTest::testReportMetrics() { FastOS_Thread::Sleep(1); } } - LOG(info, "5 minute snapshot should have been taken. Adding put count"); + LOG(debug, "5 minute snapshot should have been taken. Adding put count"); thread0.put[LoadType::DEFAULT].count.inc(1); @@ -264,12 +246,11 @@ void StateReporterTest::testReportMetrics() { "/state/v1/metrics?consumer=status" }; - for (int i=0; i<pathCount; i++) { + for (int i = 0; i < pathCount; i++) { framework::HttpUrlPath path(paths[i]); std::ostringstream ost; _stateReporter->reportStatus(ost, path); std::string jsonData = ost.str(); - //std::cerr << "\nMetrics:" << jsonData << "\n"; ASSERT_METRIC_GET_PUT(jsonData, 1.0, 0.0); } } diff --git a/storage/src/tests/visiting/CMakeLists.txt b/storage/src/tests/visiting/CMakeLists.txt index 438086fddd3..c1b19960cea 100644 --- a/storage/src/tests/visiting/CMakeLists.txt +++ b/storage/src/tests/visiting/CMakeLists.txt @@ -1,19 +1,11 @@ # Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -# TODO: Remove test library when all tests have been migrated to gtest. -vespa_add_library(storage_testvisiting TEST +vespa_add_executable(storage_visiting_gtest_runner_app TEST SOURCES commandqueuetest.cpp memory_bounded_trace_test.cpp visitormanagertest.cpp visitortest.cpp - DEPENDS - storage - storage_teststorageserver -) - -vespa_add_executable(storage_visiting_gtest_runner_app TEST - SOURCES gtest_runner.cpp DEPENDS storage diff --git a/storage/src/tests/visiting/commandqueuetest.cpp b/storage/src/tests/visiting/commandqueuetest.cpp index e335df353f6..c152e4c5191 100644 --- a/storage/src/tests/visiting/commandqueuetest.cpp +++ b/storage/src/tests/visiting/commandqueuetest.cpp @@ -3,62 +3,44 @@ #include <vespa/storageframework/defaultimplementation/clock/fakeclock.h> #include <vespa/storage/visiting/commandqueue.h> #include <vespa/storageapi/message/visitor.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/vespalib/stllike/asciistream.h> #include <vespa/document/test/make_bucket_space.h> - +#include <vespa/vespalib/gtest/gtest.h> using vespalib::string; using document::test::makeBucketSpace; +using namespace ::testing; namespace storage { -struct CommandQueueTest : public CppUnit::TestFixture -{ - void testFIFO(); - void testFIFOWithPriorities(); - void testReleaseOldest(); - void testReleaseLowestPriority(); - void testDeleteIterator(); - - CPPUNIT_TEST_SUITE(CommandQueueTest); - CPPUNIT_TEST(testFIFO); - CPPUNIT_TEST(testFIFOWithPriorities); - CPPUNIT_TEST(testReleaseOldest); - CPPUNIT_TEST(testReleaseLowestPriority); - CPPUNIT_TEST(testDeleteIterator); - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(CommandQueueTest); - namespace { - std::shared_ptr<api::CreateVisitorCommand> getCommand( - vespalib::stringref name, int timeout, - uint8_t priority = 0) - { - vespalib::asciistream ost; - ost << name << " t=" << timeout << " p=" << static_cast<unsigned int>(priority); - // Piggyback name in document selection - std::shared_ptr<api::CreateVisitorCommand> cmd( - new api::CreateVisitorCommand(makeBucketSpace(), "", "", ost.str())); - cmd->setQueueTimeout(timeout); - cmd->setPriority(priority); - return cmd; - } - const vespalib::string & - getCommandString(const std::shared_ptr<api::CreateVisitorCommand>& cmd) - { - return cmd->getDocumentSelection(); - } +std::shared_ptr<api::CreateVisitorCommand> getCommand( + vespalib::stringref name, int timeout, + uint8_t priority = 0) +{ + vespalib::asciistream ost; + ost << name << " t=" << timeout << " p=" << static_cast<unsigned int>(priority); + // Piggyback name in document selection + std::shared_ptr<api::CreateVisitorCommand> cmd( + new api::CreateVisitorCommand(makeBucketSpace(), "", "", ost.str())); + cmd->setQueueTimeout(timeout); + cmd->setPriority(priority); + return cmd; +} +const vespalib::string & +getCommandString(const std::shared_ptr<api::CreateVisitorCommand>& cmd) +{ + return cmd->getDocumentSelection(); } -void CommandQueueTest::testFIFO() { +} + +TEST(CommandQueueTest, fifo) { framework::defaultimplementation::FakeClock clock; CommandQueue<api::CreateVisitorCommand> queue(clock); - CPPUNIT_ASSERT(queue.empty()); + ASSERT_TRUE(queue.empty()); // Use all default priorities, meaning what comes out should be in the same order // as what went in queue.add(getCommand("first", 1)); @@ -69,64 +51,66 @@ void CommandQueueTest::testFIFO() { queue.add(getCommand("sixth", 14)); queue.add(getCommand("seventh", 7)); - CPPUNIT_ASSERT(!queue.empty()); - std::vector<std::shared_ptr<api::CreateVisitorCommand> > commands; + ASSERT_FALSE(queue.empty()); + std::vector<std::shared_ptr<api::CreateVisitorCommand>> commands; for (;;) { std::shared_ptr<api::CreateVisitorCommand> cmd( queue.releaseNextCommand().first); if (cmd.get() == 0) break; commands.push_back(cmd); } - CPPUNIT_ASSERT_EQUAL(size_t(7), commands.size()); - CPPUNIT_ASSERT_EQUAL(string("first t=1 p=0"), getCommandString(commands[0])); - CPPUNIT_ASSERT_EQUAL(string("second t=10 p=0"), getCommandString(commands[1])); - CPPUNIT_ASSERT_EQUAL(string("third t=5 p=0"), getCommandString(commands[2])); - CPPUNIT_ASSERT_EQUAL(string("fourth t=0 p=0"), getCommandString(commands[3])); - CPPUNIT_ASSERT_EQUAL(string("fifth t=3 p=0"), getCommandString(commands[4])); - CPPUNIT_ASSERT_EQUAL(string("sixth t=14 p=0"), getCommandString(commands[5])); - CPPUNIT_ASSERT_EQUAL(string("seventh t=7 p=0"), getCommandString(commands[6])); + ASSERT_EQ(7, commands.size()); + EXPECT_EQ("first t=1 p=0", getCommandString(commands[0])); + EXPECT_EQ("second t=10 p=0", getCommandString(commands[1])); + EXPECT_EQ("third t=5 p=0", getCommandString(commands[2])); + EXPECT_EQ("fourth t=0 p=0", getCommandString(commands[3])); + EXPECT_EQ("fifth t=3 p=0", getCommandString(commands[4])); + EXPECT_EQ("sixth t=14 p=0", getCommandString(commands[5])); + EXPECT_EQ("seventh t=7 p=0", getCommandString(commands[6])); } -void CommandQueueTest::testFIFOWithPriorities() { +TEST(CommandQueueTest, fifo_with_priorities) { framework::defaultimplementation::FakeClock clock; CommandQueue<api::CreateVisitorCommand> queue(clock); - CPPUNIT_ASSERT(queue.empty()); + ASSERT_TRUE(queue.empty()); queue.add(getCommand("first", 1, 10)); - CPPUNIT_ASSERT_EQUAL(string("first t=1 p=10"), getCommandString(queue.peekLowestPriorityCommand())); + EXPECT_EQ("first t=1 p=10", getCommandString(queue.peekLowestPriorityCommand())); queue.add(getCommand("second", 10, 22)); queue.add(getCommand("third", 5, 9)); - CPPUNIT_ASSERT_EQUAL(string("second t=10 p=22"), getCommandString(queue.peekLowestPriorityCommand())); + EXPECT_EQ("second t=10 p=22", getCommandString(queue.peekLowestPriorityCommand())); queue.add(getCommand("fourth", 0, 22)); queue.add(getCommand("fifth", 3, 22)); - CPPUNIT_ASSERT_EQUAL(string("fifth t=3 p=22"), getCommandString(queue.peekLowestPriorityCommand())); + EXPECT_EQ("fifth t=3 p=22", getCommandString(queue.peekLowestPriorityCommand())); queue.add(getCommand("sixth", 14, 50)); queue.add(getCommand("seventh", 7, 0)); - CPPUNIT_ASSERT_EQUAL(string("sixth t=14 p=50"), getCommandString(queue.peekLowestPriorityCommand())); + EXPECT_EQ("sixth t=14 p=50", getCommandString(queue.peekLowestPriorityCommand())); - CPPUNIT_ASSERT(!queue.empty()); - std::vector<std::shared_ptr<api::CreateVisitorCommand> > commands; + ASSERT_FALSE(queue.empty()); + std::vector<std::shared_ptr<api::CreateVisitorCommand>> commands; for (;;) { std::shared_ptr<api::CreateVisitorCommand> cmdPeek(queue.peekNextCommand()); std::shared_ptr<api::CreateVisitorCommand> cmd(queue.releaseNextCommand().first); - if (cmd.get() == 0 || cmdPeek != cmd) break; + if (cmd.get() == 0 || cmdPeek != cmd) { + break; + } commands.push_back(cmd); } - CPPUNIT_ASSERT_EQUAL(size_t(7), commands.size()); - CPPUNIT_ASSERT_EQUAL(string("seventh t=7 p=0"), getCommandString(commands[0])); - CPPUNIT_ASSERT_EQUAL(string("third t=5 p=9"), getCommandString(commands[1])); - CPPUNIT_ASSERT_EQUAL(string("first t=1 p=10"), getCommandString(commands[2])); - CPPUNIT_ASSERT_EQUAL(string("second t=10 p=22"), getCommandString(commands[3])); - CPPUNIT_ASSERT_EQUAL(string("fourth t=0 p=22"), getCommandString(commands[4])); - CPPUNIT_ASSERT_EQUAL(string("fifth t=3 p=22"), getCommandString(commands[5])); - CPPUNIT_ASSERT_EQUAL(string("sixth t=14 p=50"), getCommandString(commands[6])); + ASSERT_EQ(7, commands.size()); + EXPECT_EQ("seventh t=7 p=0", getCommandString(commands[0])); + EXPECT_EQ("third t=5 p=9", getCommandString(commands[1])); + EXPECT_EQ("first t=1 p=10", getCommandString(commands[2])); + EXPECT_EQ("second t=10 p=22", getCommandString(commands[3])); + EXPECT_EQ("fourth t=0 p=22", getCommandString(commands[4])); + EXPECT_EQ("fifth t=3 p=22", getCommandString(commands[5])); + EXPECT_EQ("sixth t=14 p=50", getCommandString(commands[6])); } -void CommandQueueTest::testReleaseOldest() { +TEST(CommandQueueTest, release_oldest) { framework::defaultimplementation::FakeClock clock(framework::defaultimplementation::FakeClock::FAKE_ABSOLUTE); CommandQueue<api::CreateVisitorCommand> queue(clock); - CPPUNIT_ASSERT(queue.empty()); + ASSERT_TRUE(queue.empty()); queue.add(getCommand("first", 10)); queue.add(getCommand("second", 100)); queue.add(getCommand("third", 1000)); @@ -134,32 +118,31 @@ void CommandQueueTest::testReleaseOldest() { queue.add(getCommand("fifth", 3000)); queue.add(getCommand("sixth", 400)); queue.add(getCommand("seventh", 700)); - CPPUNIT_ASSERT_EQUAL(7u, queue.size()); + ASSERT_EQ(7u, queue.size()); - typedef CommandQueue<api::CreateVisitorCommand>::CommandEntry CommandEntry; + using CommandEntry = CommandQueue<api::CreateVisitorCommand>::CommandEntry; std::list<CommandEntry> timedOut(queue.releaseTimedOut()); - CPPUNIT_ASSERT(timedOut.empty()); + ASSERT_TRUE(timedOut.empty()); clock.addMilliSecondsToTime(400 * 1000); timedOut = queue.releaseTimedOut(); - CPPUNIT_ASSERT_EQUAL(size_t(4), timedOut.size()); + ASSERT_EQ(4, timedOut.size()); std::ostringstream ost; for (std::list<CommandEntry>::const_iterator it = timedOut.begin(); it != timedOut.end(); ++it) { ost << getCommandString(it->_command) << "\n"; } - CPPUNIT_ASSERT_EQUAL(std::string( - "fourth t=5 p=0\n" - "first t=10 p=0\n" - "second t=100 p=0\n" - "sixth t=400 p=0\n"), ost.str()); - CPPUNIT_ASSERT_EQUAL(3u, queue.size()); + EXPECT_EQ("fourth t=5 p=0\n" + "first t=10 p=0\n" + "second t=100 p=0\n" + "sixth t=400 p=0\n", ost.str()); + EXPECT_EQ(3u, queue.size()); } -void CommandQueueTest::testReleaseLowestPriority() { +TEST(CommandQueueTest, release_lowest_priority) { framework::defaultimplementation::FakeClock clock; CommandQueue<api::CreateVisitorCommand> queue(clock); - CPPUNIT_ASSERT(queue.empty()); + ASSERT_TRUE(queue.empty()); queue.add(getCommand("first", 1, 10)); queue.add(getCommand("second", 10, 22)); @@ -168,30 +151,32 @@ void CommandQueueTest::testReleaseLowestPriority() { queue.add(getCommand("fifth", 3, 22)); queue.add(getCommand("sixth", 14, 50)); queue.add(getCommand("seventh", 7, 0)); - CPPUNIT_ASSERT_EQUAL(7u, queue.size()); + ASSERT_EQ(7u, queue.size()); - std::vector<std::shared_ptr<api::CreateVisitorCommand> > commands; + std::vector<std::shared_ptr<api::CreateVisitorCommand>> commands; for (;;) { std::shared_ptr<api::CreateVisitorCommand> cmdPeek(queue.peekLowestPriorityCommand()); std::pair<std::shared_ptr<api::CreateVisitorCommand>, uint64_t> cmd( queue.releaseLowestPriorityCommand()); - if (cmd.first.get() == 0 || cmdPeek != cmd.first) break; + if (cmd.first.get() == 0 || cmdPeek != cmd.first) { + break; + } commands.push_back(cmd.first); } - CPPUNIT_ASSERT_EQUAL(size_t(7), commands.size()); - CPPUNIT_ASSERT_EQUAL(string("sixth t=14 p=50"), getCommandString(commands[0])); - CPPUNIT_ASSERT_EQUAL(string("fifth t=3 p=22"), getCommandString(commands[1])); - CPPUNIT_ASSERT_EQUAL(string("fourth t=0 p=22"), getCommandString(commands[2])); - CPPUNIT_ASSERT_EQUAL(string("second t=10 p=22"), getCommandString(commands[3])); - CPPUNIT_ASSERT_EQUAL(string("first t=1 p=10"), getCommandString(commands[4])); - CPPUNIT_ASSERT_EQUAL(string("third t=5 p=9"), getCommandString(commands[5])); - CPPUNIT_ASSERT_EQUAL(string("seventh t=7 p=0"), getCommandString(commands[6])); + ASSERT_EQ(7, commands.size()); + EXPECT_EQ("sixth t=14 p=50", getCommandString(commands[0])); + EXPECT_EQ("fifth t=3 p=22", getCommandString(commands[1])); + EXPECT_EQ("fourth t=0 p=22", getCommandString(commands[2])); + EXPECT_EQ("second t=10 p=22", getCommandString(commands[3])); + EXPECT_EQ("first t=1 p=10", getCommandString(commands[4])); + EXPECT_EQ("third t=5 p=9", getCommandString(commands[5])); + EXPECT_EQ("seventh t=7 p=0", getCommandString(commands[6])); } -void CommandQueueTest::testDeleteIterator() { +TEST(CommandQueueTest, delete_iterator) { framework::defaultimplementation::FakeClock clock; CommandQueue<api::CreateVisitorCommand> queue(clock); - CPPUNIT_ASSERT(queue.empty()); + ASSERT_TRUE(queue.empty()); queue.add(getCommand("first", 10)); queue.add(getCommand("second", 100)); queue.add(getCommand("third", 1000)); @@ -199,28 +184,30 @@ void CommandQueueTest::testDeleteIterator() { queue.add(getCommand("fifth", 3000)); queue.add(getCommand("sixth", 400)); queue.add(getCommand("seventh", 700)); - CPPUNIT_ASSERT_EQUAL(7u, queue.size()); + ASSERT_EQ(7u, queue.size()); CommandQueue<api::CreateVisitorCommand>::iterator it = queue.begin(); ++it; ++it; queue.erase(it); - CPPUNIT_ASSERT_EQUAL(6u, queue.size()); + ASSERT_EQ(6u, queue.size()); - std::vector<std::shared_ptr<api::CreateVisitorCommand> > cmds; + std::vector<std::shared_ptr<api::CreateVisitorCommand>> cmds; for (;;) { std::shared_ptr<api::CreateVisitorCommand> cmd( std::dynamic_pointer_cast<api::CreateVisitorCommand>( queue.releaseNextCommand().first)); - if (cmd.get() == 0) break; + if (cmd.get() == 0) { + break; + } cmds.push_back(cmd); } - CPPUNIT_ASSERT_EQUAL(size_t(6), cmds.size()); - CPPUNIT_ASSERT_EQUAL(string("first t=10 p=0"), getCommandString(cmds[0])); - CPPUNIT_ASSERT_EQUAL(string("second t=100 p=0"), getCommandString(cmds[1])); - CPPUNIT_ASSERT_EQUAL(string("fourth t=5 p=0"), getCommandString(cmds[2])); - CPPUNIT_ASSERT_EQUAL(string("fifth t=3000 p=0"), getCommandString(cmds[3])); - CPPUNIT_ASSERT_EQUAL(string("sixth t=400 p=0"), getCommandString(cmds[4])); - CPPUNIT_ASSERT_EQUAL(string("seventh t=700 p=0"), getCommandString(cmds[5])); + ASSERT_EQ(6, cmds.size()); + EXPECT_EQ("first t=10 p=0", getCommandString(cmds[0])); + EXPECT_EQ("second t=100 p=0", getCommandString(cmds[1])); + EXPECT_EQ("fourth t=5 p=0", getCommandString(cmds[2])); + EXPECT_EQ("fifth t=3000 p=0", getCommandString(cmds[3])); + EXPECT_EQ("sixth t=400 p=0", getCommandString(cmds[4])); + EXPECT_EQ("seventh t=700 p=0", getCommandString(cmds[5])); } } diff --git a/storage/src/tests/visiting/memory_bounded_trace_test.cpp b/storage/src/tests/visiting/memory_bounded_trace_test.cpp index 5d7dda16ced..0cfd3dad4c3 100644 --- a/storage/src/tests/visiting/memory_bounded_trace_test.cpp +++ b/storage/src/tests/visiting/memory_bounded_trace_test.cpp @@ -1,73 +1,43 @@ // 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/visiting/memory_bounded_trace.h> +#include <vespa/vespalib/gtest/gtest.h> -namespace storage { - -class MemoryBoundedTraceTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(MemoryBoundedTraceTest); - CPPUNIT_TEST(noMemoryReportedUsedWhenEmpty); - CPPUNIT_TEST(memoryUsedIsStringLengthForLeafNode); - CPPUNIT_TEST(memoryUsedIsAccumulatedRecursivelyForNonLeafNodes); - CPPUNIT_TEST(traceNodesCanBeMovedAndImplicitlyCleared); - CPPUNIT_TEST(movedTraceTreeIsMarkedAsStrict); - CPPUNIT_TEST(canNotAddMoreNodesWhenMemoryUsedExceedsUpperBound); - CPPUNIT_TEST(movedTreeIncludesStatsNodeWhenNodesOmitted); - CPPUNIT_TEST_SUITE_END(); - -public: - void noMemoryReportedUsedWhenEmpty(); - void memoryUsedIsStringLengthForLeafNode(); - void memoryUsedIsAccumulatedRecursivelyForNonLeafNodes(); - void traceNodesCanBeMovedAndImplicitlyCleared(); - void movedTraceTreeIsMarkedAsStrict(); - void canNotAddMoreNodesWhenMemoryUsedExceedsUpperBound(); - void movedTreeIncludesStatsNodeWhenNodesOmitted(); -}; +using namespace ::testing; -CPPUNIT_TEST_SUITE_REGISTRATION(MemoryBoundedTraceTest); +namespace storage { -void -MemoryBoundedTraceTest::noMemoryReportedUsedWhenEmpty() -{ +TEST(MemoryBoundedTraceTest, no_memory_reported_used_when_empty) { MemoryBoundedTrace trace(100); - CPPUNIT_ASSERT_EQUAL(size_t(0), trace.getApproxMemoryUsed()); + EXPECT_EQ(0, trace.getApproxMemoryUsed()); } -void -MemoryBoundedTraceTest::memoryUsedIsStringLengthForLeafNode() -{ +TEST(MemoryBoundedTraceTest, memory_used_is_string_length_for_leaf_node) { MemoryBoundedTrace trace(100); - CPPUNIT_ASSERT(trace.add(mbus::TraceNode("hello world", 0))); - CPPUNIT_ASSERT_EQUAL(size_t(11), trace.getApproxMemoryUsed()); + EXPECT_TRUE(trace.add(mbus::TraceNode("hello world", 0))); + EXPECT_EQ(11, trace.getApproxMemoryUsed()); } -void -MemoryBoundedTraceTest::memoryUsedIsAccumulatedRecursivelyForNonLeafNodes() -{ +TEST(MemoryBoundedTraceTest, memory_used_is_accumulated_recursively_for_non_leaf_nodes) { MemoryBoundedTrace trace(100); mbus::TraceNode innerNode; innerNode.addChild("hello world"); innerNode.addChild("goodbye moon"); - CPPUNIT_ASSERT(trace.add(innerNode)); - CPPUNIT_ASSERT_EQUAL(size_t(23), trace.getApproxMemoryUsed()); + EXPECT_TRUE(trace.add(innerNode)); + EXPECT_EQ(23, trace.getApproxMemoryUsed()); } -void -MemoryBoundedTraceTest::traceNodesCanBeMovedAndImplicitlyCleared() -{ +TEST(MemoryBoundedTraceTest, trace_nodes_can_be_moved_and_implicitly_cleared) { MemoryBoundedTrace trace(100); - CPPUNIT_ASSERT(trace.add(mbus::TraceNode("hello world", 0))); + EXPECT_TRUE(trace.add(mbus::TraceNode("hello world", 0))); mbus::TraceNode target; trace.moveTraceTo(target); - CPPUNIT_ASSERT_EQUAL(uint32_t(1), target.getNumChildren()); - CPPUNIT_ASSERT_EQUAL(size_t(0), trace.getApproxMemoryUsed()); + EXPECT_EQ(1, target.getNumChildren()); + EXPECT_EQ(0, trace.getApproxMemoryUsed()); mbus::TraceNode emptinessCheck; trace.moveTraceTo(emptinessCheck); - CPPUNIT_ASSERT_EQUAL(uint32_t(0), emptinessCheck.getNumChildren()); + EXPECT_EQ(0, emptinessCheck.getNumChildren()); } /** @@ -77,54 +47,46 @@ MemoryBoundedTraceTest::traceNodesCanBeMovedAndImplicitlyCleared() * best of my knowledge, since the internal backing data structure is an * ordered vector anyhow. */ -void -MemoryBoundedTraceTest::movedTraceTreeIsMarkedAsStrict() -{ +TEST(MemoryBoundedTraceTest, moved_trace_tree_is_marked_as_strict) { MemoryBoundedTrace trace(100); - CPPUNIT_ASSERT(trace.add(mbus::TraceNode("hello world", 0))); + EXPECT_TRUE(trace.add(mbus::TraceNode("hello world", 0))); mbus::TraceNode target; trace.moveTraceTo(target); - CPPUNIT_ASSERT_EQUAL(uint32_t(1), target.getNumChildren()); - CPPUNIT_ASSERT(target.getChild(0).isStrict()); + EXPECT_EQ(1, target.getNumChildren()); + EXPECT_TRUE(target.getChild(0).isStrict()); } -void -MemoryBoundedTraceTest::canNotAddMoreNodesWhenMemoryUsedExceedsUpperBound() -{ +TEST(MemoryBoundedTraceTest, can_not_add_more_nodes_when_memory_used_exceeds_upper_bound) { // Note: we allow one complete node tree to exceed the bounds, but as soon // as the bound is exceeded no further nodes can be added. MemoryBoundedTrace trace(10); - CPPUNIT_ASSERT(trace.add(mbus::TraceNode("hello world", 0))); - CPPUNIT_ASSERT_EQUAL(size_t(11), trace.getApproxMemoryUsed()); + EXPECT_TRUE(trace.add(mbus::TraceNode("hello world", 0))); + EXPECT_EQ(11, trace.getApproxMemoryUsed()); - CPPUNIT_ASSERT(!trace.add(mbus::TraceNode("the quick red fox runs across " - "the freeway", 0))); - CPPUNIT_ASSERT_EQUAL(size_t(11), trace.getApproxMemoryUsed()); + EXPECT_FALSE(trace.add(mbus::TraceNode("the quick red fox runs across " + "the freeway", 0))); + EXPECT_EQ(11, trace.getApproxMemoryUsed()); mbus::TraceNode target; trace.moveTraceTo(target); // Twice nested node (root -> added trace tree -> leaf with txt). - CPPUNIT_ASSERT_EQUAL(uint32_t(1), target.getNumChildren()); - CPPUNIT_ASSERT(target.getChild(0).getNumChildren() >= 1); - CPPUNIT_ASSERT_EQUAL(vespalib::string("hello world"), - target.getChild(0).getChild(0).getNote()); + EXPECT_EQ(1, target.getNumChildren()); + EXPECT_GE(target.getChild(0).getNumChildren(), 1); + EXPECT_EQ("hello world", target.getChild(0).getChild(0).getNote()); } -void -MemoryBoundedTraceTest::movedTreeIncludesStatsNodeWhenNodesOmitted() -{ +TEST(MemoryBoundedTraceTest, moved_tree_includes_stats_node_when_nodes_omitted) { MemoryBoundedTrace trace(5); - CPPUNIT_ASSERT(trace.add(mbus::TraceNode("abcdef", 0))); - CPPUNIT_ASSERT(!trace.add(mbus::TraceNode("ghijkjlmn", 0))); + EXPECT_TRUE(trace.add(mbus::TraceNode("abcdef", 0))); + EXPECT_FALSE(trace.add(mbus::TraceNode("ghijkjlmn", 0))); mbus::TraceNode target; trace.moveTraceTo(target); - CPPUNIT_ASSERT_EQUAL(uint32_t(1), target.getNumChildren()); - CPPUNIT_ASSERT_EQUAL(uint32_t(2), target.getChild(0).getNumChildren()); + EXPECT_EQ(1, target.getNumChildren()); + EXPECT_EQ(2, target.getChild(0).getNumChildren()); vespalib::string expected("Trace too large; omitted 1 subsequent trace " "trees containing a total of 9 bytes"); - CPPUNIT_ASSERT_EQUAL(expected, target.getChild(0).getChild(1).getNote()); + EXPECT_EQ(expected, target.getChild(0).getChild(1).getNote()); } } // storage - diff --git a/storage/src/tests/visiting/visitormanagertest.cpp b/storage/src/tests/visiting/visitormanagertest.cpp index b9d4f24072d..1f2782de456 100644 --- a/storage/src/tests/visiting/visitormanagertest.cpp +++ b/storage/src/tests/visiting/visitormanagertest.cpp @@ -19,6 +19,8 @@ #include <vespa/documentapi/messagebus/messages/removedocumentmessage.h> #include <vespa/documentapi/messagebus/messages/visitor.h> #include <vespa/config/common/exceptions.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> #include <optional> #include <thread> #include <chrono> @@ -27,37 +29,17 @@ using document::test::makeDocumentBucket; using document::test::makeBucketSpace; using documentapi::Priority; using namespace std::chrono_literals; +using namespace ::testing; namespace storage { namespace { - typedef std::vector<api::StorageMessage::SP> msg_ptr_vector; -} -class VisitorManagerTest : public CppUnit::TestFixture -{ -private: - CPPUNIT_TEST_SUITE(VisitorManagerTest); - CPPUNIT_TEST(testNormalUsage); - CPPUNIT_TEST(testResending); - CPPUNIT_TEST(testVisitEmptyBucket); - CPPUNIT_TEST(testMultiBucketVisit); - CPPUNIT_TEST(testNoBuckets); - CPPUNIT_TEST(testVisitPutsAndRemoves); - CPPUNIT_TEST(testVisitWithTimeframeAndSelection); - CPPUNIT_TEST(testVisitWithTimeframeAndBogusSelection); - CPPUNIT_TEST(testVisitorCallbacks); - CPPUNIT_TEST(testVisitorCleanup); - CPPUNIT_TEST(testAbortOnFailedVisitorInfo); - CPPUNIT_TEST(testAbortOnFieldPathError); - CPPUNIT_TEST(testVisitorQueueTimeout); - CPPUNIT_TEST(testVisitorProcessingTimeout); - CPPUNIT_TEST(testPrioritizedVisitorQueing); - CPPUNIT_TEST(testPrioritizedMaxConcurrentVisitors); - CPPUNIT_TEST(testVisitorQueingZeroQueueSize); - CPPUNIT_TEST(testHitCounter); - CPPUNIT_TEST(testStatusPage); - CPPUNIT_TEST_SUITE_END(); +using msg_ptr_vector = std::vector<api::StorageMessage::SP>; + +} +struct VisitorManagerTest : Test { +protected: static uint32_t docCount; std::vector<document::Document::SP > _documents; std::unique_ptr<TestVisitorMessageSessionFactory> _messageSessionFactory; @@ -65,18 +47,19 @@ private: std::unique_ptr<DummyStorageLink> _top; VisitorManager* _manager; -public: VisitorManagerTest() : _node() {} + ~VisitorManagerTest(); - // Not using setUp since can't throw exception out of it. + // Not using setUp since can't throw exception out of it. void initializeTest(); void addSomeRemoves(bool removeAll = false); - void tearDown() override; + void TearDown() override; TestVisitorMessageSession& getSession(uint32_t n); - uint64_t verifyCreateVisitorReply( + void verifyCreateVisitorReply( api::ReturnCode::Result expectedResult, int checkStatsDocsVisited = -1, - int checkStatsBytesVisited = -1); + int checkStatsBytesVisited = -1, + uint64_t* message_id_out = nullptr); void getMessagesAndReply( int expectedCount, TestVisitorMessageSession& session, @@ -86,31 +69,11 @@ public: std::optional<Priority::Value> priority = documentapi::Priority::PRI_NORMAL_4); uint32_t getMatchingDocuments(std::vector<document::Document::SP >& docs); void finishAndWaitForVisitorSessionCompletion(uint32_t sessionIndex); - - void testNormalUsage(); - void testResending(); - void testVisitEmptyBucket(); - void testMultiBucketVisit(); - void testNoBuckets(); - void testVisitPutsAndRemoves(); - void testVisitWithTimeframeAndSelection(); - void testVisitWithTimeframeAndBogusSelection(); - void testVisitorCallbacks(); - void testVisitorCleanup(); - void testAbortOnFailedVisitorInfo(); - void testAbortOnFieldPathError(); - void testVisitorQueueTimeout(); - void testVisitorProcessingTimeout(); - void testPrioritizedVisitorQueing(); - void testPrioritizedMaxConcurrentVisitors(); - void testVisitorQueingZeroQueueSize(); - void testHitCounter(); - void testStatusPage(); }; -uint32_t VisitorManagerTest::docCount = 10; +VisitorManagerTest::~VisitorManagerTest() = default; -CPPUNIT_TEST_SUITE_REGISTRATION(VisitorManagerTest); +uint32_t VisitorManagerTest::docCount = 10; void VisitorManagerTest::initializeTest() @@ -118,28 +81,25 @@ VisitorManagerTest::initializeTest() vdstestlib::DirConfig config(getStandardConfig(true)); config.getConfig("stor-visitor").set("visitorthreads", "1"); - try { - _messageSessionFactory.reset( - new TestVisitorMessageSessionFactory(config.getConfigId())); - _node.reset( - new TestServiceLayerApp(config.getConfigId())); - _node->setupDummyPersistence(); - _node->getStateUpdater().setClusterState( - lib::ClusterState::CSP( - new lib::ClusterState("storage:1 distributor:1"))); - _top.reset(new DummyStorageLink()); - _top->push_back(std::unique_ptr<StorageLink>(_manager - = new VisitorManager( - config.getConfigId(), _node->getComponentRegister(), - *_messageSessionFactory))); - _top->push_back(std::unique_ptr<StorageLink>(new FileStorManager( - config.getConfigId(), _node->getPartitions(), _node->getPersistenceProvider(), _node->getComponentRegister()))); - _manager->setTimeBetweenTicks(10); - _top->open(); - } catch (config::InvalidConfigException& e) { - fprintf(stderr, "%s\n", e.what()); - } - // Adding some documents so database isn't empty + _messageSessionFactory.reset( + new TestVisitorMessageSessionFactory(config.getConfigId())); + _node.reset( + new TestServiceLayerApp(config.getConfigId())); + _node->setupDummyPersistence(); + _node->getStateUpdater().setClusterState( + lib::ClusterState::CSP( + new lib::ClusterState("storage:1 distributor:1"))); + _top.reset(new DummyStorageLink()); + _top->push_back(std::unique_ptr<StorageLink>(_manager + = new VisitorManager( + config.getConfigId(), _node->getComponentRegister(), + *_messageSessionFactory))); + _top->push_back(std::unique_ptr<StorageLink>(new FileStorManager( + config.getConfigId(), _node->getPartitions(), _node->getPersistenceProvider(), _node->getComponentRegister()))); + _manager->setTimeBetweenTicks(10); + _top->open(); + + // Adding some documents so database isn't empty api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); std::string content( "To be, or not to be: that is the question:\n" @@ -212,13 +172,10 @@ VisitorManagerTest::initializeTest() _top->sendDown(cmd); _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL((size_t) 1, replies.size()); - std::shared_ptr<api::PutReply> reply( - std::dynamic_pointer_cast<api::PutReply>( - replies[0])); - CPPUNIT_ASSERT(reply.get()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::OK), - reply->getResult()); + ASSERT_EQ(1, replies.size()); + auto reply = std::dynamic_pointer_cast<api::PutReply>(replies[0]); + ASSERT_TRUE(reply.get()); + ASSERT_EQ(api::ReturnCode(api::ReturnCode::OK), reply->getResult()); } } @@ -236,15 +193,15 @@ VisitorManagerTest::addSomeRemoves(bool removeAll) _top->sendDown(cmd); _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(size_t(1), replies.size()); + ASSERT_EQ(1, replies.size()); auto reply = std::dynamic_pointer_cast<api::RemoveReply>(replies[0]); - CPPUNIT_ASSERT(reply.get()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::OK), reply->getResult()); + ASSERT_TRUE(reply.get()); + ASSERT_EQ(api::ReturnCode(api::ReturnCode::OK), reply->getResult()); } } void -VisitorManagerTest::tearDown() +VisitorManagerTest::TearDown() { if (_top) { assert(_top->getNumReplies() == 0); @@ -277,7 +234,7 @@ VisitorManagerTest::getSession(uint32_t n) } std::this_thread::sleep_for(10ms); } - throw std::logic_error("unreachable"); + abort(); } void @@ -296,8 +253,7 @@ VisitorManagerTest::getMessagesAndReply( vespalib::MonitorGuard guard(session.getMonitor()); if (priority) { - CPPUNIT_ASSERT_EQUAL(*priority, - session.sentMessages[i]->getPriority()); + ASSERT_EQ(*priority, session.sentMessages[i]->getPriority()); } switch (session.sentMessages[i]->getType()) { @@ -327,34 +283,37 @@ VisitorManagerTest::getMessagesAndReply( } } -uint64_t +void VisitorManagerTest::verifyCreateVisitorReply( api::ReturnCode::Result expectedResult, int checkStatsDocsVisited, - int checkStatsBytesVisited) + int checkStatsBytesVisited, + uint64_t* message_id_out) { _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(1, (int)replies.size()); + ASSERT_EQ(1, replies.size()); std::shared_ptr<api::StorageMessage> msg(replies[0]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); - CPPUNIT_ASSERT(reply.get()); - CPPUNIT_ASSERT_EQUAL(expectedResult, reply->getResult().getResult()); + ASSERT_TRUE(reply.get()); + ASSERT_EQ(expectedResult, reply->getResult().getResult()); if (checkStatsDocsVisited >= 0) { - CPPUNIT_ASSERT_EQUAL(checkStatsDocsVisited, - int(reply->getVisitorStatistics().getDocumentsVisited())); + ASSERT_EQ(checkStatsDocsVisited, + reply->getVisitorStatistics().getDocumentsVisited()); } if (checkStatsBytesVisited >= 0) { - CPPUNIT_ASSERT_EQUAL(checkStatsBytesVisited, - int(reply->getVisitorStatistics().getBytesVisited())); + ASSERT_EQ(checkStatsBytesVisited, + reply->getVisitorStatistics().getBytesVisited()); } - return reply->getMsgId(); + if (message_id_out) { + *message_id_out = reply->getMsgId(); + } } uint32_t @@ -364,7 +323,6 @@ VisitorManagerTest::getMatchingDocuments(std::vector<document::Document::SP >& d for (uint32_t j=0; j<_documents.size(); ++j) { if (docs[i]->getId() == _documents[j]->getId() && *docs[i] == *_documents[j]) - { equalCount++; } @@ -374,9 +332,7 @@ VisitorManagerTest::getMatchingDocuments(std::vector<document::Document::SP >& d return equalCount; } -void -VisitorManagerTest::testHitCounter() -{ +TEST_F(VisitorManagerTest, hit_counter) { document::OrderingSpecification spec(document::OrderingSpecification::ASCENDING, 42, 7, 2); Visitor::HitCounter hitCounter(&spec); @@ -386,10 +342,10 @@ VisitorManagerTest::testHitCounter() hitCounter.addHit(document::DocumentId("orderdoc(7,2):mail:1234:10:foo"), 450); hitCounter.addHit(document::DocumentId("orderdoc(7,2):mail:1234:21:foo"), 450); - CPPUNIT_ASSERT_EQUAL(3, (int)hitCounter.getFirstPassHits()); - CPPUNIT_ASSERT_EQUAL(1350, (int)hitCounter.getFirstPassBytes()); - CPPUNIT_ASSERT_EQUAL(2, (int)hitCounter.getSecondPassHits()); - CPPUNIT_ASSERT_EQUAL(900, (int)hitCounter.getSecondPassBytes()); + EXPECT_EQ(3, hitCounter.getFirstPassHits()); + EXPECT_EQ(1350, hitCounter.getFirstPassBytes()); + EXPECT_EQ(2, hitCounter.getSecondPassHits()); + EXPECT_EQ(900, hitCounter.getSecondPassBytes()); } namespace { @@ -405,10 +361,8 @@ int getTotalSerializedSize(const std::vector<document::Document::SP>& docs) } -void -VisitorManagerTest::testNormalUsage() -{ - initializeTest(); +TEST_F(VisitorManagerTest, normal_usage) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); cmd->addBucketToBeVisited(document::BucketId(16, 3)); @@ -422,18 +376,17 @@ VisitorManagerTest::testNormalUsage() getMessagesAndReply(1, getSession(0), docs, docIds); // All data has been replied to, expecting to get a create visitor reply - verifyCreateVisitorReply(api::ReturnCode::OK, - int(docs.size()), - getTotalSerializedSize(docs)); + ASSERT_NO_FATAL_FAILURE( + verifyCreateVisitorReply(api::ReturnCode::OK, + int(docs.size()), + getTotalSerializedSize(docs))); - CPPUNIT_ASSERT_EQUAL(1u, getMatchingDocuments(docs)); - CPPUNIT_ASSERT(!_manager->hasPendingMessageState()); + EXPECT_EQ(1u, getMatchingDocuments(docs)); + EXPECT_FALSE(_manager->hasPendingMessageState()); } -void -VisitorManagerTest::testResending() -{ - initializeTest(); +TEST_F(VisitorManagerTest, resending) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); cmd->addBucketToBeVisited(document::BucketId(16, 3)); @@ -453,8 +406,8 @@ VisitorManagerTest::testResending() mbus::Reply::UP reply = msg->createReply(); - CPPUNIT_ASSERT_EQUAL((uint32_t)documentapi::DocumentProtocol::MESSAGE_VISITORINFO, - session.sentMessages[1]->getType()); + ASSERT_EQ(documentapi::DocumentProtocol::MESSAGE_VISITORINFO, + session.sentMessages[1]->getType()); reply->swapState(*session.sentMessages[1]); reply->setMessage(mbus::Message::UP(session.sentMessages[1].release())); session.reply(std::move(reply)); @@ -475,13 +428,11 @@ VisitorManagerTest::testResending() } // All data has been replied to, expecting to get a create visitor reply - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); } -void -VisitorManagerTest::testVisitEmptyBucket() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visit_empty_bucket) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); addSomeRemoves(true); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); @@ -491,13 +442,11 @@ VisitorManagerTest::testVisitEmptyBucket() _top->sendDown(cmd); // All data has been replied to, expecting to get a create visitor reply - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); } -void -VisitorManagerTest::testMultiBucketVisit() -{ - initializeTest(); +TEST_F(VisitorManagerTest, multi_bucket_visit) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); for (uint32_t i=0; i<10; ++i) { @@ -506,43 +455,40 @@ VisitorManagerTest::testMultiBucketVisit() cmd->setAddress(address); cmd->setDataDestination("fooclient.0"); _top->sendDown(cmd); - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; // Should receive one multioperation message for each bucket getMessagesAndReply(10, getSession(0), docs, docIds); // All data has been replied to, expecting to get a create visitor reply - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); - CPPUNIT_ASSERT_EQUAL(docCount, getMatchingDocuments(docs)); + EXPECT_EQ(docCount, getMatchingDocuments(docs)); } -void -VisitorManagerTest::testNoBuckets() -{ - initializeTest(); +TEST_F(VisitorManagerTest, no_buckets) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); cmd->setAddress(address); _top->sendDown(cmd); - // Should get one reply; a CreateVisitorReply with error since no - // buckets where specified in the CreateVisitorCommand + // Should get one reply; a CreateVisitorReply with error since no + // buckets where specified in the CreateVisitorCommand _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL((size_t) 1, replies.size()); + ASSERT_EQ(1, replies.size()); auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(replies[0]); - // Verify that cast went ok => it was a CreateVisitorReply message - CPPUNIT_ASSERT(reply.get()); + // Verify that cast went ok => it was a CreateVisitorReply message + ASSERT_TRUE(reply.get()); api::ReturnCode ret(api::ReturnCode::ILLEGAL_PARAMETERS, "No buckets specified"); - CPPUNIT_ASSERT_EQUAL(ret, reply->getResult()); + EXPECT_EQ(ret, reply->getResult()); } -void VisitorManagerTest::testVisitPutsAndRemoves() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visit_puts_and_removes) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); addSomeRemoves(); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); @@ -552,25 +498,22 @@ void VisitorManagerTest::testVisitPutsAndRemoves() cmd->addBucketToBeVisited(document::BucketId(16, i)); } _top->sendDown(cmd); - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; getMessagesAndReply(10, getSession(0), docs, docIds); - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); - CPPUNIT_ASSERT_EQUAL( - docCount - (docCount + 3) / 4, - getMatchingDocuments(docs)); + EXPECT_EQ(docCount - (docCount + 3) / 4, + getMatchingDocuments(docs)); - CPPUNIT_ASSERT_EQUAL( - (size_t) (docCount + 3) / 4, - docIds.size()); + EXPECT_EQ((docCount + 3) / 4, + docIds.size()); } -void VisitorManagerTest::testVisitWithTimeframeAndSelection() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visit_with_timeframe_and_selection) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", "testdoctype1.headerval < 2"); cmd->setFromTime(3); @@ -580,14 +523,14 @@ void VisitorManagerTest::testVisitWithTimeframeAndSelection() } cmd->setAddress(address); _top->sendDown(cmd); - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; getMessagesAndReply(2, getSession(0), docs, docIds); - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); - CPPUNIT_ASSERT_EQUAL((size_t) 2, docs.size()); + ASSERT_EQ(2, docs.size()); std::set<std::string> expected; expected.insert("userdoc:test:4:http://www.ntnu.no/4.html"); expected.insert("userdoc:test:5:http://www.ntnu.no/5.html"); @@ -595,12 +538,11 @@ void VisitorManagerTest::testVisitWithTimeframeAndSelection() for (uint32_t i=0; i<docs.size(); ++i) { actual.insert(docs[i]->getId().toString()); } - CPPUNIT_ASSERT_EQUAL(expected, actual); + EXPECT_THAT(expected, ContainerEq(actual)); } -void VisitorManagerTest::testVisitWithTimeframeAndBogusSelection() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visit_with_timeframe_and_bogus_selection) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", "DocType(testdoctype1---///---) XXX BAD Field(headerval) < 2"); @@ -614,17 +556,33 @@ void VisitorManagerTest::testVisitWithTimeframeAndBogusSelection() _top->sendDown(cmd); _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL((size_t) 1, replies.size()); + ASSERT_EQ(1, replies.size()); auto* reply = dynamic_cast<api::StorageReply*>(replies.front().get()); - CPPUNIT_ASSERT(reply); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::ILLEGAL_PARAMETERS, reply->getResult().getResult()); + ASSERT_TRUE(reply); + EXPECT_EQ(api::ReturnCode::ILLEGAL_PARAMETERS, reply->getResult().getResult()); } -void -VisitorManagerTest::testVisitorCallbacks() -{ - initializeTest(); +#define ASSERT_SUBSTRING_COUNT(source, expectedCount, substring) \ + { \ + uint32_t count = 0; \ + std::ostringstream value; /* Let value be non-strings */ \ + value << source; \ + std::string s(value.str()); \ + std::string::size_type pos = s.find(substring); \ + while (pos != std::string::npos) { \ + ++count; \ + pos = s.find(substring, pos+1); \ + } \ + if (count != (uint32_t) expectedCount) { \ + FAIL() << "Value of '" << s << "' contained " << count \ + << " instances of substring '" << substring << "', not " \ + << expectedCount << " as expected."; \ + } \ + } + +TEST_F(VisitorManagerTest, visitor_callbacks) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); std::ostringstream replydata; api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "TestVisitor", "testvis", ""); @@ -642,10 +600,10 @@ VisitorManagerTest::testVisitorCallbacks() { vespalib::MonitorGuard guard(session.getMonitor()); - CPPUNIT_ASSERT_EQUAL((uint32_t)documentapi::DocumentProtocol::MESSAGE_MAPVISITOR, session.sentMessages[i]->getType()); + ASSERT_EQ(documentapi::DocumentProtocol::MESSAGE_MAPVISITOR, session.sentMessages[i]->getType()); auto* mapvisitormsg = dynamic_cast<documentapi::MapVisitorMessage*>(session.sentMessages[i].get()); - CPPUNIT_ASSERT(mapvisitormsg != nullptr); + ASSERT_TRUE(mapvisitormsg != nullptr); replydata << mapvisitormsg->getData().get("msg"); @@ -657,18 +615,16 @@ VisitorManagerTest::testVisitorCallbacks() } // All data has been replied to, expecting to get a create visitor reply - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); - CPPUNIT_ASSERT_SUBSTRING_COUNT(replydata.str(), 1, "Starting visitor"); - CPPUNIT_ASSERT_SUBSTRING_COUNT(replydata.str(), 2, "Handling block of 1 documents"); - CPPUNIT_ASSERT_SUBSTRING_COUNT(replydata.str(), 2, "completedBucket"); - CPPUNIT_ASSERT_SUBSTRING_COUNT(replydata.str(), 1, "completedVisiting"); + ASSERT_SUBSTRING_COUNT(replydata.str(), 1, "Starting visitor"); + ASSERT_SUBSTRING_COUNT(replydata.str(), 2, "Handling block of 1 documents"); + ASSERT_SUBSTRING_COUNT(replydata.str(), 2, "completedBucket"); + ASSERT_SUBSTRING_COUNT(replydata.str(), 1, "completedVisiting"); } -void -VisitorManagerTest::testVisitorCleanup() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visitor_cleanup) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); // Start a bunch of invalid visitors @@ -699,16 +655,16 @@ VisitorManagerTest::testVisitorCleanup() const int expected_total = 16; _top->waitForMessages(expected_total, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(size_t(expected_total), replies.size()); + ASSERT_EQ(expected_total, replies.size()); int failures = 0; int busy = 0; for (uint32_t i=0; i< expected_total; ++i) { std::shared_ptr<api::StorageMessage> msg(replies[i]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); - CPPUNIT_ASSERT(reply.get()); + ASSERT_TRUE(reply.get()); if (i < 10) { if (api::ReturnCode::ILLEGAL_PARAMETERS == reply->getResult().getResult()) { @@ -723,20 +679,20 @@ VisitorManagerTest::testVisitorCleanup() } } - CPPUNIT_ASSERT_EQUAL(10, failures); - CPPUNIT_ASSERT_EQUAL(expected_total - 10, busy); + ASSERT_EQ(10, failures); + ASSERT_EQ(expected_total - 10, busy); } // 4 pending // Finish a visitor - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; getMessagesAndReply(1, getSession(0), docs, docIds); // Should get a reply for the visitor. - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); // 3 pending @@ -744,7 +700,7 @@ VisitorManagerTest::testVisitorCleanup() getMessagesAndReply(1, getSession(1), docs, docIds, api::ReturnCode::INTERNAL_FAILURE); // Should get a reply for the visitor. - verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE)); // Wait until there are 2 pending. Visitor threads might not have completed // cleanup of existing visitors yet. @@ -766,15 +722,15 @@ VisitorManagerTest::testVisitorCleanup() // Should now get 8 busy. _top->waitForMessages(8, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(size_t(8), replies.size()); + ASSERT_EQ(8, replies.size()); for (uint32_t i=0; i< replies.size(); ++i) { std::shared_ptr<api::StorageMessage> msg(replies[i]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); - CPPUNIT_ASSERT(reply.get()); + ASSERT_TRUE(reply.get()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::BUSY, reply->getResult().getResult()); + ASSERT_EQ(api::ReturnCode::BUSY, reply->getResult().getResult()); } for (uint32_t i = 0; i < 4; ++i) { @@ -783,10 +739,8 @@ VisitorManagerTest::testVisitorCleanup() } } -void -VisitorManagerTest::testAbortOnFailedVisitorInfo() -{ - initializeTest(); +TEST_F(VisitorManagerTest, abort_on_failed_visitor_info) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); { @@ -797,7 +751,7 @@ VisitorManagerTest::testAbortOnFailedVisitorInfo() _top->sendDown(cmd); } - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; TestVisitorMessageSession& session = getSession(0); @@ -810,18 +764,16 @@ VisitorManagerTest::testAbortOnFailedVisitorInfo() mbus::Reply::UP reply = cmd->createReply(); - CPPUNIT_ASSERT_EQUAL(uint32_t(documentapi::DocumentProtocol::MESSAGE_VISITORINFO), session.sentMessages[1]->getType()); + ASSERT_EQ(documentapi::DocumentProtocol::MESSAGE_VISITORINFO, session.sentMessages[1]->getType()); reply->swapState(*session.sentMessages[1]); reply->setMessage(mbus::Message::UP(session.sentMessages[1].release())); reply->addError(mbus::Error(api::ReturnCode::NOT_CONNECTED, "Me no ready")); session.reply(std::move(reply)); } - verifyCreateVisitorReply(api::ReturnCode::NOT_CONNECTED); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::NOT_CONNECTED)); } -void -VisitorManagerTest::testAbortOnFieldPathError() -{ +TEST_F(VisitorManagerTest, abort_on_field_path_error) { initializeTest(); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); @@ -833,13 +785,11 @@ VisitorManagerTest::testAbortOnFieldPathError() cmd->setQueueTimeout(0); _top->sendDown(cmd); - verifyCreateVisitorReply(api::ReturnCode::ILLEGAL_PARAMETERS); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::ILLEGAL_PARAMETERS)); } -void -VisitorManagerTest::testVisitorQueueTimeout() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visitor_queue_timeout) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); _manager->enforceQueueUsage(); @@ -861,16 +811,14 @@ VisitorManagerTest::testVisitorQueueTimeout() const msg_ptr_vector replies = _top->getRepliesOnce(); std::shared_ptr<api::StorageMessage> msg(replies[0]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::BUSY, "Visitor timed out in visitor queue"), - reply->getResult()); + ASSERT_EQ(api::ReturnCode(api::ReturnCode::BUSY, "Visitor timed out in visitor queue"), + reply->getResult()); } -void -VisitorManagerTest::testVisitorProcessingTimeout() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visitor_processing_timeout) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); @@ -886,32 +834,32 @@ VisitorManagerTest::testVisitorProcessingTimeout() _node->getClock().addSecondsToTime(1000); - verifyCreateVisitorReply(api::ReturnCode::ABORTED); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::ABORTED)); } namespace { - uint32_t nextVisitor = 0; - api::StorageMessage::Id - sendCreateVisitor(uint32_t timeout, DummyStorageLink& top, uint8_t priority = 127) { - std::ostringstream ost; - ost << "testvis" << ++nextVisitor; - api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); - auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", ost.str(), ""); - cmd->addBucketToBeVisited(document::BucketId(16, 3)); - cmd->setAddress(address); - cmd->setQueueTimeout(timeout); - cmd->setPriority(priority); - top.sendDown(cmd); - return cmd->getMsgId(); - } +uint32_t nextVisitor = 0; + +api::StorageMessage::Id +sendCreateVisitor(uint32_t timeout, DummyStorageLink& top, uint8_t priority = 127) { + std::ostringstream ost; + ost << "testvis" << ++nextVisitor; + api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); + auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", ost.str(), ""); + cmd->addBucketToBeVisited(document::BucketId(16, 3)); + cmd->setAddress(address); + cmd->setQueueTimeout(timeout); + cmd->setPriority(priority); + top.sendDown(cmd); + return cmd->getMsgId(); } -void -VisitorManagerTest::testPrioritizedVisitorQueing() -{ +} + +TEST_F(VisitorManagerTest, prioritized_visitor_queing) { framework::HttpUrlPath path("?verbose=true&allvisitors=true"); - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); _manager->setMaxConcurrentVisitors(4); _manager->setMaxVisitorQueueSize(4); @@ -933,27 +881,31 @@ VisitorManagerTest::testPrioritizedVisitorQueing() // Send a lower pri visitor that will be busy-returned immediately ids[8] = sendCreateVisitor(1000, *_top, 130); - CPPUNIT_ASSERT_EQUAL(ids[8], verifyCreateVisitorReply(api::ReturnCode::BUSY)); + uint64_t message_id = 0; + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY, -1, -1, &message_id)); + ASSERT_EQ(ids[8], message_id); // Send a higher pri visitor that will take the place of pri 100 visitor ids[9] = sendCreateVisitor(1000, *_top, 60); - CPPUNIT_ASSERT_EQUAL(ids[4], verifyCreateVisitorReply(api::ReturnCode::BUSY)); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY, -1, -1, &message_id)); + ASSERT_EQ(ids[4], message_id); // Finish the first visitor - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; getMessagesAndReply(1, getSession(0), docs, docIds, api::ReturnCode::OK, Priority::PRI_HIGHEST); - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK, -1, -1, &message_id)); // We should now start the highest priority visitor. getMessagesAndReply(1, getSession(4), docs, docIds, api::ReturnCode::OK, Priority::PRI_VERY_HIGH); - CPPUNIT_ASSERT_EQUAL(ids[9], verifyCreateVisitorReply(api::ReturnCode::OK)); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK, -1, -1, &message_id)); + ASSERT_EQ(ids[9], message_id); // 3 pending, 3 in queue. Clean them up std::vector<uint32_t> pending_sessions = {1, 2, 3, 5, 6, 7}; for (auto session : pending_sessions) { - finishAndWaitForVisitorSessionCompletion(session); + ASSERT_NO_FATAL_FAILURE(finishAndWaitForVisitorSessionCompletion(session)); } } @@ -961,13 +913,12 @@ void VisitorManagerTest::finishAndWaitForVisitorSessionCompletion(uint32_t sessi std::vector<document::Document::SP > docs; std::vector<document::DocumentId> docIds; getMessagesAndReply(1, getSession(sessionIndex), docs, docIds, api::ReturnCode::OK, std::optional<Priority::Value>()); - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); } -void -VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { +TEST_F(VisitorManagerTest, prioritized_max_concurrent_visitors) { framework::HttpUrlPath path("?verbose=true&allvisitors=true"); - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessage::Id ids[17] = { 0 }; @@ -997,12 +948,15 @@ VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { // Should punch pri203 msg out of the queue -> busy ids[11] = sendCreateVisitor(1000, *_top, 197); - CPPUNIT_ASSERT_EQUAL(ids[4], verifyCreateVisitorReply(api::ReturnCode::BUSY)); + uint64_t message_id = 0; + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY, -1, -1, &message_id)); + ASSERT_EQ(ids[4], message_id); // No concurrency slots left for this message -> busy ids[12] = sendCreateVisitor(1000, *_top, 204); - CPPUNIT_ASSERT_EQUAL(ids[12], verifyCreateVisitorReply(api::ReturnCode::BUSY)); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY, -1, -1, &message_id)); + ASSERT_EQ(ids[12], message_id); // Gets a concurrent slot ids[13] = sendCreateVisitor(1000, *_top, 80); @@ -1010,7 +964,8 @@ VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { // Kicks pri 202 out of the queue -> busy ids[14] = sendCreateVisitor(1000, *_top, 79); - CPPUNIT_ASSERT_EQUAL(ids[5], verifyCreateVisitorReply(api::ReturnCode::BUSY)); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY, -1, -1, &message_id)); + ASSERT_EQ(ids[5], message_id); // Gets a concurrent slot ids[15] = sendCreateVisitor(1000, *_top, 63); @@ -1018,7 +973,7 @@ VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { // Very Important Visitor(tm) gets a concurrent slot ids[16] = sendCreateVisitor(1000, *_top, 0); - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; std::set<uint64_t> finishedVisitors; @@ -1034,19 +989,19 @@ VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { } else if (i == 6) { priority = documentapi::Priority::PRI_HIGH_1; // ids 15 } - getMessagesAndReply(1, getSession(i), docs, docIds, api::ReturnCode::OK, - priority); - finishedVisitors.insert(verifyCreateVisitorReply(api::ReturnCode::OK)); + getMessagesAndReply(1, getSession(i), docs, docIds, api::ReturnCode::OK, priority); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK, -1, -1, &message_id)); + finishedVisitors.insert(message_id); } for (int i = 0; i < 4; i++) { - CPPUNIT_ASSERT(finishedVisitors.find(ids[i]) != finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[i]), finishedVisitors.end()); } - CPPUNIT_ASSERT(finishedVisitors.find(ids[10]) != finishedVisitors.end()); - CPPUNIT_ASSERT(finishedVisitors.find(ids[13]) != finishedVisitors.end()); - CPPUNIT_ASSERT(finishedVisitors.find(ids[15]) != finishedVisitors.end()); - CPPUNIT_ASSERT(finishedVisitors.find(ids[16]) != finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[10]), finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[13]), finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[15]), finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[16]), finishedVisitors.end()); finishedVisitors.clear(); @@ -1058,22 +1013,22 @@ VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { } getMessagesAndReply(1, getSession(i), docs, docIds, api::ReturnCode::OK, priority); - uint64_t msgId = verifyCreateVisitorReply(api::ReturnCode::OK); + uint64_t msgId = 0; + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK, -1, -1, &msgId)); finishedVisitors.insert(msgId); } for (int i = 6; i < 10; i++) { - CPPUNIT_ASSERT(finishedVisitors.find(ids[i]) != finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[i]), finishedVisitors.end()); } - CPPUNIT_ASSERT(finishedVisitors.find(ids[11]) != finishedVisitors.end()); - CPPUNIT_ASSERT(finishedVisitors.find(ids[14]) != finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[11]), finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[14]), finishedVisitors.end()); } -void -VisitorManagerTest::testVisitorQueingZeroQueueSize() { +TEST_F(VisitorManagerTest, visitor_queing_zero_queue_size) { framework::HttpUrlPath path("?verbose=true&allvisitors=true"); - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); _manager->setMaxConcurrentVisitors(4); _manager->setMaxVisitorQueueSize(0); @@ -1085,17 +1040,16 @@ VisitorManagerTest::testVisitorQueingZeroQueueSize() { // Queue size is zero, all visitors will be busy-returned for (uint32_t i = 0; i < 5; ++i) { sendCreateVisitor(1000, *_top, 100 - i); - verifyCreateVisitorReply(api::ReturnCode::BUSY); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY)); } for (uint32_t session = 0; session < 4; ++session) { finishAndWaitForVisitorSessionCompletion(session); } } -void -VisitorManagerTest::testStatusPage() { +TEST_F(VisitorManagerTest, status_page) { framework::HttpUrlPath path("?verbose=true&allvisitors=true"); - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); _manager->setMaxConcurrentVisitors(1, 1); _manager->setMaxVisitorQueueSize(6); @@ -1112,13 +1066,13 @@ VisitorManagerTest::testStatusPage() { static_cast<framework::HtmlStatusReporter&>(*_manager).reportHtmlStatus(ss, path); std::string str(ss.str()); - CPPUNIT_ASSERT(str.find("Currently running visitors") != std::string::npos); + EXPECT_THAT(str, HasSubstr("Currently running visitors")); // Should be propagated to visitor thread - CPPUNIT_ASSERT(str.find("Running 1 visitors") != std::string::npos); // 1 active - CPPUNIT_ASSERT(str.find("waiting visitors 1") != std::string::npos); // 1 queued - CPPUNIT_ASSERT(str.find("Visitor thread 0") != std::string::npos); - CPPUNIT_ASSERT(str.find("Disconnected visitor timeout") != std::string::npos); // verbose per thread - CPPUNIT_ASSERT(str.find("Message #1 <b>putdocumentmessage</b>") != std::string::npos); // 1 active + EXPECT_THAT(str, HasSubstr("Running 1 visitors")); // 1 active + EXPECT_THAT(str, HasSubstr("waiting visitors 1")); // 1 queued + EXPECT_THAT(str, HasSubstr("Visitor thread 0")); + EXPECT_THAT(str, HasSubstr("Disconnected visitor timeout")); // verbose per thread + EXPECT_THAT(str, HasSubstr("Message #1 <b>putdocumentmessage</b>")); // 1 active for (uint32_t session = 0; session < 2 ; ++session){ finishAndWaitForVisitorSessionCompletion(session); diff --git a/storage/src/tests/visiting/visitortest.cpp b/storage/src/tests/visiting/visitortest.cpp index 24b04c8d33a..3d37bbe434b 100644 --- a/storage/src/tests/visiting/visitortest.cpp +++ b/storage/src/tests/visiting/visitortest.cpp @@ -18,11 +18,13 @@ #include <vespa/documentapi/messagebus/messages/visitor.h> #include <vespa/vespalib/io/fileutil.h> #include <vespa/config/common/exceptions.h> +#include <vespa/vespalib/gtest/gtest.h> #include <thread> #include <sys/stat.h> using namespace std::chrono_literals; using document::test::makeBucketSpace; +using namespace ::testing; namespace storage { @@ -30,8 +32,7 @@ namespace { using msg_ptr_vector = std::vector<api::StorageMessage::SP>; -struct TestParams -{ +struct TestParams { TestParams& maxVisitorMemoryUsage(uint32_t bytes) { _maxVisitorMemoryUsage = bytes; return *this; @@ -52,26 +53,7 @@ struct TestParams } -class VisitorTest : public CppUnit::TestFixture -{ -private: - CPPUNIT_TEST_SUITE(VisitorTest); - CPPUNIT_TEST(testNormalUsage); - CPPUNIT_TEST(testFailedCreateIterator); - CPPUNIT_TEST(testFailedGetIter); - CPPUNIT_TEST(testDocumentAPIClientError); - CPPUNIT_TEST(testNoDocumentAPIResendingForFailedVisitor); - CPPUNIT_TEST(testIteratorCreatedForFailedVisitor); - CPPUNIT_TEST(testFailedDocumentAPISend); - CPPUNIT_TEST(testNoVisitorNotificationForTransientFailures); - CPPUNIT_TEST(testNotificationSentIfTransientErrorRetriedManyTimes); - CPPUNIT_TEST(testNoMbusTracingIfTraceLevelIsZero); - CPPUNIT_TEST(testReplyContainsTraceIfTraceLevelAboveZero); - CPPUNIT_TEST(testNoMoreIteratorsSentWhileMemoryUsedAboveLimit); - CPPUNIT_TEST(testDumpVisitorInvokesStrongReadConsistencyIteration); - CPPUNIT_TEST(testTestVisitorInvokesWeakReadConsistencyIteration); - CPPUNIT_TEST_SUITE_END(); - +struct VisitorTest : Test { static uint32_t docCount; std::vector<document::Document::SP > _documents; std::unique_ptr<TestVisitorMessageSessionFactory> _messageSessionFactory; @@ -80,26 +62,8 @@ private: DummyStorageLink* _bottom; VisitorManager* _manager; -public: VisitorTest() : _node() {} - void testNormalUsage(); - void testFailedCreateIterator(); - void testFailedGetIter(); - void testDocumentAPIClientError(); - void testNoDocumentAPIResendingForFailedVisitor(); - void testIteratorCreatedForFailedVisitor(); - void testFailedDocumentAPISend(); - void testNoVisitorNotificationForTransientFailures(); - void testNotificationSentIfTransientErrorRetriedManyTimes(); - void testNoMbusTracingIfTraceLevelIsZero(); - void testReplyContainsTraceIfTraceLevelAboveZero(); - void testNoMoreIteratorsSentWhileMemoryUsedAboveLimit(); - void testDumpVisitorInvokesStrongReadConsistencyIteration(); - void testTestVisitorInvokesWeakReadConsistencyIteration(); - // TODO: - void testVisitMultipleBuckets() {} - // Not using setUp since can't throw exception out of it. void initializeTest(const TestParams& params = TestParams()); @@ -118,13 +82,14 @@ public: std::shared_ptr<api::CreateVisitorCommand> makeCreateVisitor( const VisitorOptions& options = VisitorOptions()); - void tearDown() override; + void TearDown() override; bool waitUntilNoActiveVisitors(); TestVisitorMessageSession& getSession(uint32_t n); - uint64_t verifyCreateVisitorReply( + void verifyCreateVisitorReply( api::ReturnCode::Result expectedResult, int checkStatsDocsVisited = -1, - int checkStatsBytesVisited = -1); + int checkStatsBytesVisited = -1, + uint64_t* message_id_out = nullptr); void getMessagesAndReply( int expectedCount, TestVisitorMessageSession& session, @@ -134,18 +99,17 @@ public: api::ReturnCode::Result returnCode = api::ReturnCode::OK); uint32_t getMatchingDocuments(std::vector<document::Document::SP >& docs); -private: +protected: void doTestVisitorInstanceHasConsistencyLevel( vespalib::stringref visitorType, spi::ReadConsistency expectedConsistency); template <typename T> - std::vector<std::shared_ptr<T> > - fetchMultipleCommands(DummyStorageLink& link, size_t count); + void fetchMultipleCommands(DummyStorageLink& link, size_t count, + std::vector<std::shared_ptr<T>>& commands_out); template <typename T> - std::shared_ptr<T> - fetchSingleCommand(DummyStorageLink& link); + void fetchSingleCommand(DummyStorageLink& link, std::shared_ptr<T>& msg_out); void sendGetIterReply(GetIterCommand& cmd, const api::ReturnCode& result = @@ -153,8 +117,9 @@ private: uint32_t maxDocuments = 0, bool overrideCompleted = false); void sendCreateIteratorReply(uint64_t iteratorId = 1234); - std::shared_ptr<api::CreateVisitorReply> doCompleteVisitingSession( - const std::shared_ptr<api::CreateVisitorCommand>& cmd); + void doCompleteVisitingSession( + const std::shared_ptr<api::CreateVisitorCommand>& cmd, + std::shared_ptr<api::CreateVisitorReply>& reply_out); void sendInitialCreateVisitorAndGetIterRound(); @@ -171,8 +136,6 @@ private: uint32_t VisitorTest::docCount = 10; -CPPUNIT_TEST_SUITE_REGISTRATION(VisitorTest); - void VisitorTest::initializeTest(const TestParams& params) { @@ -192,26 +155,23 @@ VisitorTest::initializeTest(const TestParams& params) vespalib::mkdir(vespalib::make_string("%s/disks/d0", rootFolder.c_str()), true); vespalib::mkdir(vespalib::make_string("%s/disks/d1", rootFolder.c_str()), true); - try { - _messageSessionFactory.reset( - new TestVisitorMessageSessionFactory(config.getConfigId())); - if (params._autoReplyError.getCode() != mbus::ErrorCode::NONE) { - _messageSessionFactory->_autoReplyError = params._autoReplyError; - _messageSessionFactory->_createAutoReplyVisitorSessions = true; - } - _node.reset(new TestServiceLayerApp(config.getConfigId())); - _top.reset(new DummyStorageLink()); - _top->push_back(std::unique_ptr<StorageLink>(_manager - = new VisitorManager( - config.getConfigId(), - _node->getComponentRegister(), *_messageSessionFactory))); - _bottom = new DummyStorageLink(); - _top->push_back(std::unique_ptr<StorageLink>(_bottom)); - _manager->setTimeBetweenTicks(10); - _top->open(); - } catch (config::InvalidConfigException& e) { - fprintf(stderr, "%s\n", e.what()); + _messageSessionFactory.reset( + new TestVisitorMessageSessionFactory(config.getConfigId())); + if (params._autoReplyError.getCode() != mbus::ErrorCode::NONE) { + _messageSessionFactory->_autoReplyError = params._autoReplyError; + _messageSessionFactory->_createAutoReplyVisitorSessions = true; } + _node.reset(new TestServiceLayerApp(config.getConfigId())); + _top.reset(new DummyStorageLink()); + _top->push_back(std::unique_ptr<StorageLink>(_manager + = new VisitorManager( + config.getConfigId(), + _node->getComponentRegister(), *_messageSessionFactory))); + _bottom = new DummyStorageLink(); + _top->push_back(std::unique_ptr<StorageLink>(_bottom)); + _manager->setTimeBetweenTicks(10); + _top->open(); + std::string content( "To be, or not to be: that is the question:\n" "Whether 'tis nobler in the mind to suffer\n" @@ -263,16 +223,16 @@ VisitorTest::initializeTest(const TestParams& params) } void -VisitorTest::tearDown() +VisitorTest::TearDown() { - if (_top.get() != 0) { + if (_top) { _top->close(); _top->flush(); - _top.reset(0); + _top.reset(); } - _node.reset(0); - _messageSessionFactory.reset(0); - _manager = 0; + _node.reset(); + _messageSessionFactory.reset(); + _manager = nullptr; } bool @@ -310,7 +270,7 @@ VisitorTest::getSession(uint32_t n) } std::this_thread::sleep_for(10ms); } - throw std::logic_error("unreachable"); + abort(); } void @@ -327,10 +287,10 @@ VisitorTest::getMessagesAndReply( mbus::Reply::UP reply; { vespalib::MonitorGuard guard(session.getMonitor()); - CPPUNIT_ASSERT(!session.sentMessages.empty()); + ASSERT_FALSE(session.sentMessages.empty()); std::unique_ptr<documentapi::DocumentMessage> msg(std::move(session.sentMessages.front())); session.sentMessages.pop_front(); - CPPUNIT_ASSERT(msg->getPriority() < 16); + ASSERT_LT(msg->getPriority(), 16); switch (msg->getType()) { case documentapi::DocumentProtocol::MESSAGE_PUTDOCUMENT: @@ -361,35 +321,37 @@ VisitorTest::getMessagesAndReply( } } -uint64_t +void VisitorTest::verifyCreateVisitorReply( api::ReturnCode::Result expectedResult, int checkStatsDocsVisited, - int checkStatsBytesVisited) + int checkStatsBytesVisited, + uint64_t* message_id_out) { _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(1, (int)replies.size()); + ASSERT_EQ(1, replies.size()); std::shared_ptr<api::StorageMessage> msg(replies[0]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); - std::shared_ptr<api::CreateVisitorReply> reply( - std::dynamic_pointer_cast<api::CreateVisitorReply>(msg)); - CPPUNIT_ASSERT(reply.get()); - CPPUNIT_ASSERT_EQUAL(expectedResult, reply->getResult().getResult()); + auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); + ASSERT_TRUE(reply.get()); + ASSERT_EQ(expectedResult, reply->getResult().getResult()); if (checkStatsDocsVisited >= 0) { - CPPUNIT_ASSERT_EQUAL(checkStatsDocsVisited, - int(reply->getVisitorStatistics().getDocumentsVisited())); + ASSERT_EQ(checkStatsDocsVisited, + reply->getVisitorStatistics().getDocumentsVisited()); } if (checkStatsBytesVisited >= 0) { - CPPUNIT_ASSERT_EQUAL(checkStatsBytesVisited, - int(reply->getVisitorStatistics().getBytesVisited())); + ASSERT_EQ(checkStatsBytesVisited, + reply->getVisitorStatistics().getBytesVisited()); } - return reply->getMsgId(); + if (message_id_out) { + *message_id_out = reply->getMsgId(); + } } uint32_t @@ -423,12 +385,11 @@ VisitorTest::sendGetIterReply(GetIterCommand& cmd, assert(maxDocuments < _documents.size()); size_t documentCount = maxDocuments != 0 ? maxDocuments : _documents.size(); for (size_t i = 0; i < documentCount; ++i) { - reply->getEntries().push_back( - spi::DocEntry::UP( - new spi::DocEntry( + reply->getEntries().emplace_back( + std::make_unique<spi::DocEntry>( spi::Timestamp(1000 + i), spi::NONE, - document::Document::UP(_documents[i]->clone())))); + document::Document::UP(_documents[i]->clone()))); } if (documentCount == _documents.size() || overrideCompleted) { reply->setCompleted(); @@ -437,12 +398,13 @@ VisitorTest::sendGetIterReply(GetIterCommand& cmd, } template <typename T> -std::vector<std::shared_ptr<T> > -VisitorTest::fetchMultipleCommands(DummyStorageLink& link, size_t count) +void +VisitorTest::fetchMultipleCommands(DummyStorageLink& link, size_t count, + std::vector<std::shared_ptr<T>>& commands_out) { link.waitForMessages(count, 60); std::vector<api::StorageMessage::SP> msgs(link.getCommandsOnce()); - std::vector<std::shared_ptr<T> > fetched; + std::vector<std::shared_ptr<T>> fetched; if (msgs.size() != count) { std::ostringstream oss; oss << "Expected " @@ -453,38 +415,38 @@ VisitorTest::fetchMultipleCommands(DummyStorageLink& link, size_t count) for (size_t i = 0; i < msgs.size(); ++i) { oss << i << ": " << *msgs[i] << "\n"; } - CPPUNIT_FAIL(oss.str()); + FAIL() << oss.str(); } for (size_t i = 0; i < count; ++i) { - std::shared_ptr<T> ret(std::dynamic_pointer_cast<T>(msgs[i])); + auto ret = std::dynamic_pointer_cast<T>(msgs[i]); if (!ret) { std::ostringstream oss; oss << "Expected message of type " << typeid(T).name() << ", but got " << msgs[0]->toString(); - CPPUNIT_FAIL(oss.str()); + FAIL() << oss.str(); } fetched.push_back(ret); } - return fetched; + commands_out = std::move(fetched); } template <typename T> -std::shared_ptr<T> -VisitorTest::fetchSingleCommand(DummyStorageLink& link) +void +VisitorTest::fetchSingleCommand(DummyStorageLink& link, std::shared_ptr<T>& msg_out) { - std::vector<std::shared_ptr<T> > ret( - fetchMultipleCommands<T>(link, 1)); - return ret[0]; + std::vector<std::shared_ptr<T>> ret; + ASSERT_NO_FATAL_FAILURE(fetchMultipleCommands<T>(link, 1, ret)); + msg_out = std::move(ret[0]); } std::shared_ptr<api::CreateVisitorCommand> VisitorTest::makeCreateVisitor(const VisitorOptions& options) { api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); - std::shared_ptr<api::CreateVisitorCommand> cmd( - new api::CreateVisitorCommand(makeBucketSpace(), options.visitorType, "testvis", "")); + auto cmd = std::make_shared<api::CreateVisitorCommand>( + makeBucketSpace(), options.visitorType, "testvis", ""); cmd->addBucketToBeVisited(document::BucketId(16, 3)); cmd->setAddress(address); cmd->setMaximumPendingReplyCount(UINT32_MAX); @@ -496,35 +458,29 @@ VisitorTest::makeCreateVisitor(const VisitorOptions& options) void VisitorTest::sendCreateIteratorReply(uint64_t iteratorId) { - CreateIteratorCommand::SP createCmd( - fetchSingleCommand<CreateIteratorCommand>(*_bottom)); + CreateIteratorCommand::SP createCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<CreateIteratorCommand>(*_bottom, createCmd)); spi::IteratorId id(iteratorId); - api::StorageReply::SP reply( - new CreateIteratorReply(*createCmd, id)); + auto reply = std::make_shared<CreateIteratorReply>(*createCmd, id); _bottom->sendUp(reply); } -void -VisitorTest::testNormalUsage() -{ - initializeTest(); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); +TEST_F(VisitorTest, normal_usage) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); + auto cmd = makeCreateVisitor(); _top->sendDown(cmd); - CreateIteratorCommand::SP createCmd( - fetchSingleCommand<CreateIteratorCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(static_cast<int>(DefaultPriority), - static_cast<int>(createCmd->getPriority())); // Inherit pri + CreateIteratorCommand::SP createCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<CreateIteratorCommand>(*_bottom, createCmd)); + ASSERT_EQ(static_cast<int>(DefaultPriority), + static_cast<int>(createCmd->getPriority())); // Inherit pri spi::IteratorId id(1234); - api::StorageReply::SP reply( - new CreateIteratorReply(*createCmd, id)); + auto reply = std::make_shared<CreateIteratorReply>(*createCmd, id); _bottom->sendUp(reply); - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd); @@ -532,76 +488,64 @@ VisitorTest::testNormalUsage() std::vector<document::DocumentId> docIds; std::vector<std::string> infoMessages; getMessagesAndReply(_documents.size(), getSession(0), docs, docIds, infoMessages); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); - CPPUNIT_ASSERT_EQUAL(size_t(0), docIds.size()); + ASSERT_EQ(0, infoMessages.size()); + ASSERT_EQ(0, docIds.size()); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply(api::ReturnCode::OK); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); - CPPUNIT_ASSERT_EQUAL(INT64_C(0), getFailedVisitorDestinationReplyCount()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); + ASSERT_EQ(0, getFailedVisitorDestinationReplyCount()); } -void -VisitorTest::testFailedCreateIterator() -{ - initializeTest(); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); +TEST_F(VisitorTest, failed_create_iterator) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); + auto cmd = makeCreateVisitor(); cmd->addBucketToBeVisited(document::BucketId(16, 4)); _top->sendDown(cmd); - CreateIteratorCommand::SP createCmd( - fetchSingleCommand<CreateIteratorCommand>(*_bottom)); + CreateIteratorCommand::SP createCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<CreateIteratorCommand>(*_bottom, createCmd)); spi::IteratorId id(0); - api::StorageReply::SP reply( - new CreateIteratorReply(*createCmd, id)); + auto reply = std::make_shared<CreateIteratorReply>(*createCmd, id); reply->setResult(api::ReturnCode(api::ReturnCode::INTERNAL_FAILURE)); _bottom->sendUp(reply); - verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE, 0, 0); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE, 0, 0)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } -void -VisitorTest::testFailedGetIter() -{ - initializeTest(); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); +TEST_F(VisitorTest, failed_get_iter) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); + auto cmd = makeCreateVisitor(); _top->sendDown(cmd); sendCreateIteratorReply(); - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::BUCKET_NOT_FOUND)); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply(api::ReturnCode::BUCKET_NOT_FOUND, 0, 0); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUCKET_NOT_FOUND, 0, 0)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } -void -VisitorTest::testDocumentAPIClientError() -{ +TEST_F(VisitorTest, document_api_client_error) { initializeTest(); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); + auto cmd = makeCreateVisitor(); _top->sendDown(cmd); sendCreateIteratorReply(); { - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 1); } @@ -612,40 +556,36 @@ VisitorTest::testDocumentAPIClientError() getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::INTERNAL_FAILURE); // INTERNAL_FAILURE is critical, so no visitor info sent - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); std::this_thread::sleep_for(100ms); { - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd); } - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } -void -VisitorTest::testNoDocumentAPIResendingForFailedVisitor() -{ - initializeTest(); +TEST_F(VisitorTest, no_document_api_resending_for_failed_visitor) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); std::shared_ptr<api::CreateVisitorCommand> cmd( makeCreateVisitor()); _top->sendDown(cmd); sendCreateIteratorReply(); { - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 2, true); } @@ -658,50 +598,44 @@ VisitorTest::testNoDocumentAPIResendingForFailedVisitor() // should cause the entire visitor to fail. getMessagesAndReply(3, getSession(0), docs, docIds, infoMessages, api::ReturnCode::NOT_CONNECTED); - CPPUNIT_ASSERT_EQUAL(size_t(1), infoMessages.size()); - CPPUNIT_ASSERT_EQUAL( - std::string("[From content node 0] NOT_CONNECTED: Generic error"), - infoMessages[0]); + ASSERT_EQ(1, infoMessages.size()); + EXPECT_EQ("[From content node 0] NOT_CONNECTED: Generic error", + infoMessages[0]); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply(api::ReturnCode::NOT_CONNECTED); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); - CPPUNIT_ASSERT_EQUAL(INT64_C(3), getFailedVisitorDestinationReplyCount()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::NOT_CONNECTED)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); + ASSERT_EQ(3, getFailedVisitorDestinationReplyCount()); } -void -VisitorTest::testIteratorCreatedForFailedVisitor() -{ +TEST_F(VisitorTest, iterator_created_for_failed_visitor) { initializeTest(TestParams().parallelBuckets(2)); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); + auto cmd = makeCreateVisitor(); cmd->addBucketToBeVisited(document::BucketId(16, 4)); _top->sendDown(cmd); - std::vector<CreateIteratorCommand::SP> createCmds( - fetchMultipleCommands<CreateIteratorCommand>(*_bottom, 2)); + std::vector<CreateIteratorCommand::SP> createCmds; + ASSERT_NO_FATAL_FAILURE(fetchMultipleCommands<CreateIteratorCommand>(*_bottom, 2, createCmds)); { spi::IteratorId id(0); - api::StorageReply::SP reply( - new CreateIteratorReply(*createCmds[0], id)); + auto reply = std::make_shared<CreateIteratorReply>(*createCmds[0], id); reply->setResult(api::ReturnCode(api::ReturnCode::INTERNAL_FAILURE)); _bottom->sendUp(reply); } { spi::IteratorId id(1234); - api::StorageReply::SP reply( - new CreateIteratorReply(*createCmds[1], id)); + auto reply = std::make_shared<CreateIteratorReply>(*createCmds[1], id); _bottom->sendUp(reply); } // Want to immediately receive destroyiterator for newly created // iterator, since we cannot use it anyway when the visitor has failed. - DestroyIteratorCommand::SP destroyCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyCmd)); - verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE, 0, 0); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE, 0, 0)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } /** @@ -710,62 +644,55 @@ VisitorTest::testIteratorCreatedForFailedVisitor() * and the visitor terminates cleanly without counting the failed message * as pending. */ -void -VisitorTest::testFailedDocumentAPISend() -{ - initializeTest(TestParams().autoReplyError( +TEST_F(VisitorTest, failed_document_api_send) { + ASSERT_NO_FATAL_FAILURE(initializeTest(TestParams().autoReplyError( mbus::Error(mbus::ErrorCode::HANDSHAKE_FAILED, - "abandon ship!"))); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); + "abandon ship!")))); + auto cmd = makeCreateVisitor(); cmd->addBucketToBeVisited(document::BucketId(16, 4)); _top->sendDown(cmd); sendCreateIteratorReply(); - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 2, true); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply( + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply( static_cast<api::ReturnCode::Result>( mbus::ErrorCode::HANDSHAKE_FAILED), 0, - 0); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + 0)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); // We currently don't count failures to send in this metric; send failures // indicate a message bus problem and already log a warning when they happen - CPPUNIT_ASSERT_EQUAL(INT64_C(0), getFailedVisitorDestinationReplyCount()); + ASSERT_EQ(0, getFailedVisitorDestinationReplyCount()); } void VisitorTest::sendInitialCreateVisitorAndGetIterRound() { - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); + auto cmd = makeCreateVisitor(); _top->sendDown(cmd); sendCreateIteratorReply(); { - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 1, true); } } -void -VisitorTest::testNoVisitorNotificationForTransientFailures() -{ - initializeTest(); - sendInitialCreateVisitorAndGetIterRound(); +TEST_F(VisitorTest, no_visitor_notification_for_transient_failures) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); + ASSERT_NO_FATAL_FAILURE(sendInitialCreateVisitorAndGetIterRound()); std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; @@ -776,41 +703,40 @@ VisitorTest::testNoVisitorNotificationForTransientFailures() // Should not get info message for BUCKET_DELETED, but resend of Put. getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::BUCKET_DELETED); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); // Should not get info message for BUCKET_NOT_FOUND, but resend of Put. getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::BUCKET_NOT_FOUND); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); // MessageBus error codes guaranteed to fit in return code result. // Should not get info message for SESSION_BUSY, but resend of Put. getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, static_cast<api::ReturnCode::Result>( mbus::ErrorCode::SESSION_BUSY)); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); // WRONG_DISTRIBUTION should not be reported, as it will happen all the // time when initiating remote migrations et al. getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::WRONG_DISTRIBUTION); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); // Complete message successfully to finish the visitor. getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::OK); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); - fetchSingleCommand<DestroyIteratorCommand>(*_bottom); + DestroyIteratorCommand::SP cmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, cmd)); - verifyCreateVisitorReply(api::ReturnCode::OK); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } -void -VisitorTest::testNotificationSentIfTransientErrorRetriedManyTimes() -{ +TEST_F(VisitorTest, notification_sent_if_transient_error_retried_many_times) { constexpr size_t retries( Visitor::TRANSIENT_ERROR_RETRIES_BEFORE_NOTIFY); - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); sendInitialCreateVisitorAndGetIterRound(); std::vector<document::Document::SP> docs; @@ -822,31 +748,33 @@ VisitorTest::testNotificationSentIfTransientErrorRetriedManyTimes() for (size_t attempt = 0; attempt < retries; ++attempt) { getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::WRONG_DISTRIBUTION); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); } // Should now have a client notification along for the ride. // This has to be ACKed as OK or the visitor will fail. getMessagesAndReply(2, getSession(0), docs, docIds, infoMessages, api::ReturnCode::OK); - CPPUNIT_ASSERT_EQUAL(size_t(1), infoMessages.size()); + ASSERT_EQ(1, infoMessages.size()); // TODO(vekterli) ideally we'd want to test that this happens only once // per message, but this seems frustratingly complex to do currently. - fetchSingleCommand<DestroyIteratorCommand>(*_bottom); + DestroyIteratorCommand::SP cmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, cmd)); - verifyCreateVisitorReply(api::ReturnCode::OK); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } -std::shared_ptr<api::CreateVisitorReply> +void VisitorTest::doCompleteVisitingSession( - const std::shared_ptr<api::CreateVisitorCommand>& cmd) + const std::shared_ptr<api::CreateVisitorCommand>& cmd, + std::shared_ptr<api::CreateVisitorReply>& reply_out) { initializeTest(); _top->sendDown(cmd); sendCreateIteratorReply(); - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 1, @@ -857,50 +785,44 @@ VisitorTest::doCompleteVisitingSession( std::vector<std::string> infoMessages; getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(size_t(1), replies.size()); + ASSERT_EQ(1, replies.size()); std::shared_ptr<api::StorageMessage> msg(replies[0]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, - msg->getType()); - return std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + reply_out = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); } -void -VisitorTest::testNoMbusTracingIfTraceLevelIsZero() -{ +TEST_F(VisitorTest, no_mbus_tracing_if_trace_level_is_zero) { std::shared_ptr<api::CreateVisitorCommand> cmd(makeCreateVisitor()); cmd->getTrace().setLevel(0); - auto reply = doCompleteVisitingSession(cmd); - CPPUNIT_ASSERT(reply->getTrace().getRoot().isEmpty()); + std::shared_ptr<api::CreateVisitorReply> reply; + ASSERT_NO_FATAL_FAILURE(doCompleteVisitingSession(cmd, reply)); + EXPECT_TRUE(reply->getTrace().getRoot().isEmpty()); } -void -VisitorTest::testReplyContainsTraceIfTraceLevelAboveZero() -{ +TEST_F(VisitorTest, reply_contains_trace_if_trace_level_above_zero) { std::shared_ptr<api::CreateVisitorCommand> cmd(makeCreateVisitor()); cmd->getTrace().setLevel(1); - auto reply = doCompleteVisitingSession(cmd); - CPPUNIT_ASSERT(!reply->getTrace().getRoot().isEmpty()); + std::shared_ptr<api::CreateVisitorReply> reply; + ASSERT_NO_FATAL_FAILURE(doCompleteVisitingSession(cmd, reply)); + EXPECT_FALSE(reply->getTrace().getRoot().isEmpty()); } -void -VisitorTest::testNoMoreIteratorsSentWhileMemoryUsedAboveLimit() -{ +TEST_F(VisitorTest, no_more_iterators_sent_while_memory_used_above_limit) { initializeTest(TestParams().maxVisitorMemoryUsage(1) .parallelBuckets(1)); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); + auto cmd = makeCreateVisitor(); _top->sendDown(cmd); sendCreateIteratorReply(); - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 1); @@ -914,7 +836,7 @@ VisitorTest::testNoMoreIteratorsSentWhileMemoryUsedAboveLimit() // kind of explicit barrier with which we can synchronize the test and the // running visitor thread. std::this_thread::sleep_for(100ms); - CPPUNIT_ASSERT_EQUAL(size_t(0), _bottom->getNumCommands()); + ASSERT_EQ(0, _bottom->getNumCommands()); std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; @@ -922,7 +844,7 @@ VisitorTest::testNoMoreIteratorsSentWhileMemoryUsedAboveLimit() getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages); // 2nd round of GetIter now allowed. Send reply indicating completion. - getIterCmd = fetchSingleCommand<GetIterCommand>(*_bottom); + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 1, @@ -930,11 +852,11 @@ VisitorTest::testNoMoreIteratorsSentWhileMemoryUsedAboveLimit() getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply(api::ReturnCode::OK); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } void @@ -942,19 +864,17 @@ VisitorTest::doTestVisitorInstanceHasConsistencyLevel( vespalib::stringref visitorType, spi::ReadConsistency expectedConsistency) { - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); std::shared_ptr<api::CreateVisitorCommand> cmd( makeCreateVisitor(VisitorOptions().withVisitorType(visitorType))); _top->sendDown(cmd); - auto createCmd = fetchSingleCommand<CreateIteratorCommand>(*_bottom); - CPPUNIT_ASSERT_EQUAL(expectedConsistency, - createCmd->getReadConsistency()); + CreateIteratorCommand::SP createCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<CreateIteratorCommand>(*_bottom, createCmd)); + ASSERT_EQ(expectedConsistency, createCmd->getReadConsistency()); } -void -VisitorTest::testDumpVisitorInvokesStrongReadConsistencyIteration() -{ +TEST_F(VisitorTest, dump_visitor_invokes_strong_read_consistency_iteration) { doTestVisitorInstanceHasConsistencyLevel( "dumpvisitor", spi::ReadConsistency::STRONG); } @@ -965,9 +885,7 @@ VisitorTest::testDumpVisitorInvokesStrongReadConsistencyIteration() // any external client use cases. Our primary concern is to test that each // visitor subclass might report its own read consistency requirement and that // this is carried along to the CreateIteratorCommand. -void -VisitorTest::testTestVisitorInvokesWeakReadConsistencyIteration() -{ +TEST_F(VisitorTest, test_visitor_invokes_weak_read_consistency_iteration) { doTestVisitorInstanceHasConsistencyLevel( "testvisitor", spi::ReadConsistency::WEAK); } diff --git a/storage/src/vespa/storage/visiting/testvisitor.cpp b/storage/src/vespa/storage/visiting/testvisitor.cpp index a2e7116babd..9c1e04ecbbd 100644 --- a/storage/src/vespa/storage/visiting/testvisitor.cpp +++ b/storage/src/vespa/storage/visiting/testvisitor.cpp @@ -21,7 +21,7 @@ TestVisitor::TestVisitor(StorageComponent& c, ost << "\n " << it->first << " = " << it->second.c_str(); } _params = ost.str(); - LOG(info, "Created TestVisitor: %s", _params.c_str()); + LOG(debug, "Created TestVisitor: %s", _params.c_str()); } void @@ -33,7 +33,7 @@ TestVisitor::startingVisitor(const std::vector<document::BucketId>& buckets) for (uint32_t i=0, n=buckets.size(); i<n; ++i) { ost << " " << buckets[i] << "\n"; } - LOG(info, "%s", ost.str().c_str()); + LOG(debug, "%s", ost.str().c_str()); report(ost.str()); } @@ -44,7 +44,7 @@ TestVisitor::handleDocuments(const document::BucketId& /*bucketId*/, { std::ostringstream ost; ost << "Handling block of " << entries.size() << " documents.\n"; - LOG(info, "%s", ost.str().c_str()); + LOG(debug, "%s", ost.str().c_str()); report(ost.str()); } @@ -52,19 +52,19 @@ void TestVisitor::completedBucket(const document::BucketId& bucket, HitCounter&) { std::ostringstream ost; ost << "completedBucket(" << bucket.getId() << ")\n"; - LOG(info, "%s", ost.str().c_str()); + LOG(debug, "%s", ost.str().c_str()); report(ost.str()); } void TestVisitor::completedVisiting(HitCounter&) { - LOG(info, "completedVisiting()"); + LOG(debug, "completedVisiting()"); report("completedVisiting()\n"); } void TestVisitor::abortedVisiting() { - LOG(info, "abortedVisiting()"); + LOG(debug, "abortedVisiting()"); report("abortedVisiting()\n"); } |