diff options
Diffstat (limited to 'storage/src/tests/bucketdb')
-rw-r--r-- | storage/src/tests/bucketdb/CMakeLists.txt | 12 | ||||
-rw-r--r-- | storage/src/tests/bucketdb/bucketinfotest.cpp | 150 | ||||
-rw-r--r-- | storage/src/tests/bucketdb/bucketmanagertest.cpp | 506 | ||||
-rw-r--r-- | storage/src/tests/bucketdb/initializertest.cpp | 502 | ||||
-rw-r--r-- | storage/src/tests/bucketdb/judyarraytest.cpp | 236 | ||||
-rw-r--r-- | storage/src/tests/bucketdb/judymultimaptest.cpp | 118 | ||||
-rw-r--r-- | storage/src/tests/bucketdb/lockablemaptest.cpp | 817 |
7 files changed, 621 insertions, 1720 deletions
diff --git a/storage/src/tests/bucketdb/CMakeLists.txt b/storage/src/tests/bucketdb/CMakeLists.txt index 714faf34de5..2468e587aff 100644 --- a/storage/src/tests/bucketdb/CMakeLists.txt +++ b/storage/src/tests/bucketdb/CMakeLists.txt @@ -1,10 +1,10 @@ # 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_testbucketdb TEST +vespa_add_executable(storage_bucketdb_gtest_runner_app TEST SOURCES bucketinfotest.cpp bucketmanagertest.cpp + gtest_runner.cpp initializertest.cpp judyarraytest.cpp judymultimaptest.cpp @@ -12,14 +12,6 @@ vespa_add_library(storage_testbucketdb TEST DEPENDS storage storage_testcommon -) - -vespa_add_executable(storage_bucketdb_gtest_runner_app TEST - SOURCES - gtest_runner.cpp - DEPENDS - storage - storage_testcommon gtest ) diff --git a/storage/src/tests/bucketdb/bucketinfotest.cpp b/storage/src/tests/bucketdb/bucketinfotest.cpp index 0298c50866c..fe922b5d6bd 100644 --- a/storage/src/tests/bucketdb/bucketinfotest.cpp +++ b/storage/src/tests/bucketdb/bucketinfotest.cpp @@ -1,47 +1,13 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> -#include <boost/assign.hpp> -#include <boost/random.hpp> -#include <cppunit/extensions/HelperMacros.h> -#include <map> -#include <vector> #include <vespa/vespalib/text/stringtokenizer.h> #include <vespa/storage/bucketdb/bucketinfo.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <vector> + +using namespace ::testing; -namespace storage { - -namespace distributor { - -struct BucketInfoTest : public CppUnit::TestFixture { - void testBucketInfoEntriesWithNewestTimestampsAreKept(); - void testOrder(); - void testHasInvalidCopy(); - void testAddNodeSetsTrustedWhenConsistent(); - void testTrustedResetWhenCopiesBecomeInconsistent(); - void testTrustedResetWhenTrustedCopiesGoOutOfSync(); - void testTrustedNotResetWhenNonTrustedCopiesStillOutOfSync(); - void add_nodes_can_immediately_update_trusted_flag(); - void add_nodes_can_defer_update_of_trusted_flag(); - void remove_node_can_immediately_update_trusted_flag(); - void remove_node_can_defer_update_of_trusted_flag(); - - CPPUNIT_TEST_SUITE(BucketInfoTest); - CPPUNIT_TEST(testBucketInfoEntriesWithNewestTimestampsAreKept); - CPPUNIT_TEST(testOrder); - CPPUNIT_TEST(testHasInvalidCopy); - CPPUNIT_TEST(testAddNodeSetsTrustedWhenConsistent); - CPPUNIT_TEST_IGNORED(testTrustedResetWhenCopiesBecomeInconsistent); - CPPUNIT_TEST(testTrustedResetWhenTrustedCopiesGoOutOfSync); - CPPUNIT_TEST(testTrustedNotResetWhenNonTrustedCopiesStillOutOfSync); - CPPUNIT_TEST(add_nodes_can_immediately_update_trusted_flag); - CPPUNIT_TEST(add_nodes_can_defer_update_of_trusted_flag); - CPPUNIT_TEST(remove_node_can_immediately_update_trusted_flag); - CPPUNIT_TEST(remove_node_can_defer_update_of_trusted_flag); - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(BucketInfoTest); +namespace storage::distributor { BucketInfo getBucketInfo(std::string nodeList, std::string order) { @@ -83,68 +49,55 @@ nodeList(const BucketInfo& info) { // in the meantime from having their updates lost when we perform a batch // insert. This also applies for when we postpone db updates in persistence // message tracker until we've received a reply from all copies. -void -BucketInfoTest::testBucketInfoEntriesWithNewestTimestampsAreKept() -{ +TEST(BucketInfoTest, bucket_info_entries_with_newest_timestamps_are_kept) { BucketInfo bi; std::vector<uint16_t> idealState; idealState.push_back(0); bi.addNode(BucketCopy(5, 0, api::BucketInfo(1,1,1)), idealState); - CPPUNIT_ASSERT_EQUAL(api::BucketInfo(1,1,1), - bi.getNode(0)->getBucketInfo()); + EXPECT_EQ(api::BucketInfo(1,1,1), bi.getNode(0)->getBucketInfo()); bi.addNode(BucketCopy(5, 0, api::BucketInfo(2,2,2)), idealState); - CPPUNIT_ASSERT_EQUAL(api::BucketInfo(1,1,1), - bi.getNode(0)->getBucketInfo()); + EXPECT_EQ(api::BucketInfo(1,1,1), bi.getNode(0)->getBucketInfo()); bi.addNode(BucketCopy(4, 0, api::BucketInfo(3,3,3)), idealState); - CPPUNIT_ASSERT_EQUAL(api::BucketInfo(1,1,1), - bi.getNode(0)->getBucketInfo()); + EXPECT_EQ(api::BucketInfo(1,1,1), bi.getNode(0)->getBucketInfo()); bi.addNode(BucketCopy(7, 0, api::BucketInfo(4,4,4)), idealState); - CPPUNIT_ASSERT_EQUAL(api::BucketInfo(4,4,4), - bi.getNode(0)->getBucketInfo()); + EXPECT_EQ(api::BucketInfo(4,4,4), bi.getNode(0)->getBucketInfo()); bi.addNode(BucketCopy(2, 1, api::BucketInfo(4,4,4)), idealState); - CPPUNIT_ASSERT_EQUAL(api::BucketInfo(4,4,4), - bi.getNode(1)->getBucketInfo()); + EXPECT_EQ(api::BucketInfo(4,4,4), bi.getNode(1)->getBucketInfo()); } -void -BucketInfoTest::testOrder() { - - CPPUNIT_ASSERT_EQUAL(std::string("2,0,1"), nodeList(getBucketInfo("0,1,2", "2,0,1"))); - CPPUNIT_ASSERT_EQUAL(std::string("2,0,1"), nodeList(getBucketInfo("1,0,2", "2,0,1"))); - CPPUNIT_ASSERT_EQUAL(std::string("1,0,2"), nodeList(getBucketInfo("1,2,0", "1"))); - CPPUNIT_ASSERT_EQUAL(std::string("2,1,0,3,4"), nodeList(getBucketInfo("0,1,2,3,4", "2,1"))); +TEST(BucketInfoTest, node_ordering_is_preserved) { + EXPECT_EQ("2,0,1", nodeList(getBucketInfo("0,1,2", "2,0,1"))); + EXPECT_EQ("2,0,1", nodeList(getBucketInfo("1,0,2", "2,0,1"))); + EXPECT_EQ("1,0,2", nodeList(getBucketInfo("1,2,0", "1"))); + EXPECT_EQ("2,1,0,3,4", nodeList(getBucketInfo("0,1,2,3,4", "2,1"))); } -void -BucketInfoTest::testHasInvalidCopy() -{ +TEST(BucketInfoTest, can_query_for_replica_with_invalid_info) { std::vector<uint16_t> order; BucketInfo info; info.addNode(BucketCopy(0, 0, api::BucketInfo(10, 100, 1000)), order); info.addNode(BucketCopy(0, 1, api::BucketInfo(10, 100, 1000)), order); - CPPUNIT_ASSERT(!info.hasInvalidCopy()); + EXPECT_FALSE(info.hasInvalidCopy()); info.addNode(BucketCopy(0, 2, api::BucketInfo()), order); - CPPUNIT_ASSERT(info.hasInvalidCopy()); + EXPECT_TRUE(info.hasInvalidCopy()); } -void -BucketInfoTest::testAddNodeSetsTrustedWhenConsistent() -{ +TEST(BucketInfoTest, add_node_sets_trusted_when_consistent) { std::vector<uint16_t> order; { BucketInfo info; info.addNode(BucketCopy(0, 0, api::BucketInfo(0x1, 2, 144)).setTrusted(), order); info.addNode(BucketCopy(0, 1, api::BucketInfo(0x1, 2, 144)), order); - CPPUNIT_ASSERT(info.getNode(1)->trusted()); + EXPECT_TRUE(info.getNode(1)->trusted()); } { @@ -155,91 +108,78 @@ BucketInfoTest::testAddNodeSetsTrustedWhenConsistent() BucketCopy copy(1, 1, api::BucketInfo(0x1, 1, 2)); info.updateNode(copy); - CPPUNIT_ASSERT(info.getNode(1)->trusted()); - CPPUNIT_ASSERT(!info.getNode(2)->trusted()); + EXPECT_TRUE(info.getNode(1)->trusted()); + EXPECT_FALSE(info.getNode(2)->trusted()); } } -void -BucketInfoTest::testTrustedResetWhenCopiesBecomeInconsistent() -{ - CPPUNIT_FAIL("TODO: test this!"); -} - -void -BucketInfoTest::testTrustedResetWhenTrustedCopiesGoOutOfSync() -{ +TEST(BucketInfoTest, testTrustedResetWhenTrustedCopiesGoOutOfSync) { std::vector<uint16_t> order; BucketInfo info; info.addNode(BucketCopy(0, 0, api::BucketInfo(10, 100, 1000)).setTrusted(), order); info.addNode(BucketCopy(0, 1, api::BucketInfo(10, 100, 1000)), order); - CPPUNIT_ASSERT(info.getNode(0)->trusted()); - CPPUNIT_ASSERT(info.getNode(1)->trusted()); + EXPECT_TRUE(info.getNode(0)->trusted()); + EXPECT_TRUE(info.getNode(1)->trusted()); info.updateNode(BucketCopy(0, 1, api::BucketInfo(20, 200, 2000)).setTrusted()); - CPPUNIT_ASSERT(!info.getNode(0)->trusted()); - CPPUNIT_ASSERT(!info.getNode(1)->trusted()); + EXPECT_FALSE(info.getNode(0)->trusted()); + EXPECT_FALSE(info.getNode(1)->trusted()); } -void -BucketInfoTest::testTrustedNotResetWhenNonTrustedCopiesStillOutOfSync() -{ +TEST(BucketInfoTest, trusted_not_reset_when_non_trusted_copies_still_out_of_sync) { std::vector<uint16_t> order; BucketInfo info; info.addNode(BucketCopy(0, 0, api::BucketInfo(10, 100, 1000)).setTrusted(), order); info.addNode(BucketCopy(0, 1, api::BucketInfo(20, 200, 2000)), order); info.addNode(BucketCopy(0, 2, api::BucketInfo(30, 300, 3000)), order); - CPPUNIT_ASSERT(info.getNode(0)->trusted()); - CPPUNIT_ASSERT(!info.getNode(1)->trusted()); - CPPUNIT_ASSERT(!info.getNode(2)->trusted()); + EXPECT_TRUE(info.getNode(0)->trusted()); + EXPECT_FALSE(info.getNode(1)->trusted()); + EXPECT_FALSE(info.getNode(2)->trusted()); info.updateNode(BucketCopy(0, 1, api::BucketInfo(21, 201, 2001))); - CPPUNIT_ASSERT(info.getNode(0)->trusted()); - CPPUNIT_ASSERT(!info.getNode(1)->trusted()); - CPPUNIT_ASSERT(!info.getNode(2)->trusted()); + EXPECT_TRUE(info.getNode(0)->trusted()); + EXPECT_FALSE(info.getNode(1)->trusted()); + EXPECT_FALSE(info.getNode(2)->trusted()); } -void BucketInfoTest::add_nodes_can_immediately_update_trusted_flag() { +TEST(BucketInfoTest, add_nodes_can_immediately_update_trusted_flag) { BucketInfo info; std::vector<uint16_t> order; info.addNodes({BucketCopy(0, 0, api::BucketInfo(10, 100, 1000))}, order, TrustedUpdate::UPDATE); // Only one replica, so implicitly trusted iff trusted flag update is invoked. - CPPUNIT_ASSERT(info.getNode(0)->trusted()); + EXPECT_TRUE(info.getNode(0)->trusted()); } -void BucketInfoTest::add_nodes_can_defer_update_of_trusted_flag() { +TEST(BucketInfoTest, add_nodes_can_defer_update_of_trusted_flag) { BucketInfo info; std::vector<uint16_t> order; info.addNodes({BucketCopy(0, 0, api::BucketInfo(10, 100, 1000))}, order, TrustedUpdate::DEFER); - CPPUNIT_ASSERT(!info.getNode(0)->trusted()); + EXPECT_FALSE(info.getNode(0)->trusted()); } -void BucketInfoTest::remove_node_can_immediately_update_trusted_flag() { +TEST(BucketInfoTest, remove_node_can_immediately_update_trusted_flag) { BucketInfo info; std::vector<uint16_t> order; info.addNodes({BucketCopy(0, 0, api::BucketInfo(10, 100, 1000)), BucketCopy(0, 1, api::BucketInfo(20, 200, 2000))}, order, TrustedUpdate::UPDATE); - CPPUNIT_ASSERT(!info.getNode(0)->trusted()); + EXPECT_FALSE(info.getNode(0)->trusted()); info.removeNode(1, TrustedUpdate::UPDATE); // Only one replica remaining after remove, so implicitly trusted iff trusted flag update is invoked. - CPPUNIT_ASSERT(info.getNode(0)->trusted()); + EXPECT_TRUE(info.getNode(0)->trusted()); } -void BucketInfoTest::remove_node_can_defer_update_of_trusted_flag() { +TEST(BucketInfoTest, remove_node_can_defer_update_of_trusted_flag) { BucketInfo info; std::vector<uint16_t> order; info.addNodes({BucketCopy(0, 0, api::BucketInfo(10, 100, 1000)), BucketCopy(0, 1, api::BucketInfo(20, 200, 2000))}, order, TrustedUpdate::UPDATE); info.removeNode(1, TrustedUpdate::DEFER); - CPPUNIT_ASSERT(!info.getNode(0)->trusted()); -} - + EXPECT_FALSE(info.getNode(0)->trusted()); } -} // storage - +} // storage::distributor diff --git a/storage/src/tests/bucketdb/bucketmanagertest.cpp b/storage/src/tests/bucketdb/bucketmanagertest.cpp index 09fe310e97e..1f72347b7ed 100644 --- a/storage/src/tests/bucketdb/bucketmanagertest.cpp +++ b/storage/src/tests/bucketdb/bucketmanagertest.cpp @@ -1,12 +1,13 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/config/helper/configgetter.h> -#include <cppunit/extensions/HelperMacros.h> +#include <vespa/config/helper/configgetter.hpp> #include <vespa/document/config/config-documenttypes.h> #include <vespa/document/datatype/documenttype.h> #include <vespa/document/fieldvalue/document.h> #include <vespa/document/update/documentupdate.h> #include <vespa/document/repo/documenttyperepo.h> +#include <vespa/document/test/make_document_bucket.h> +#include <vespa/document/test/make_bucket_space.h> #include <vespa/storage/bucketdb/bucketmanager.h> #include <vespa/storage/common/global_bucket_space_distribution_converter.h> #include <vespa/storage/persistence/filestorage/filestormanager.h> @@ -16,13 +17,10 @@ #include <tests/common/teststorageapp.h> #include <tests/common/dummystoragelink.h> #include <tests/common/testhelper.h> -#include <vespa/document/test/make_document_bucket.h> -#include <vespa/document/test/make_bucket_space.h> #include <vespa/vdslib/state/random.h> #include <vespa/vespalib/io/fileutil.h> -#include <vespa/vespalib/testkit/testapp.h> #include <vespa/vespalib/util/stringfmt.h> -#include <vespa/config/helper/configgetter.hpp> +#include <vespa/vespalib/gtest/gtest.h> #include <future> #include <vespa/log/log.h> @@ -35,6 +33,7 @@ using document::DocumentType; using document::DocumentTypeRepo; using document::test::makeDocumentBucket; using document::test::makeBucketSpace; +using namespace ::testing; namespace storage { @@ -57,41 +56,8 @@ std::ostream& operator<<(std::ostream& out, const TestBucketInfo& info) { class ConcurrentOperationFixture; struct TestParams; -struct BucketManagerTest : public CppUnit::TestFixture { +struct BucketManagerTest : public Test { public: - CPPUNIT_TEST_SUITE(BucketManagerTest); - CPPUNIT_TEST(testRequestBucketInfoWithList); - CPPUNIT_TEST(testDistributionBitGenerationEmpty); - CPPUNIT_TEST(testDistributionBitChangeOnCreateBucket); - CPPUNIT_TEST(testMinUsedBitsFromComponentIsHonored); - CPPUNIT_TEST(testRemoveLastModifiedOK); - CPPUNIT_TEST(testRemoveLastModifiedFailed); - CPPUNIT_TEST(testSwallowNotifyBucketChangeReply); - CPPUNIT_TEST(testMetricsGeneration); - CPPUNIT_TEST(metrics_are_tracked_per_bucket_space); - CPPUNIT_TEST(testSplitReplyOrderedAfterBucketReply); - CPPUNIT_TEST(testJoinReplyOrderedAfterBucketReply); - CPPUNIT_TEST(testDeleteReplyOrderedAfterBucketReply); - CPPUNIT_TEST(testOnlyEnqueueWhenProcessingRequest); - CPPUNIT_TEST(testOrderRepliesAfterBucketSpecificRequest); - CPPUNIT_TEST(testQueuedRepliesOnlyDispatchedWhenAllProcessingDone); - CPPUNIT_TEST(testMutationRepliesForSplitBucketAreEnqueued); - CPPUNIT_TEST(testMutationRepliesForDeletedBucketAreEnqueued); - CPPUNIT_TEST(testMutationRepliesForJoinedBucketAreEnqueued); - CPPUNIT_TEST(testConflictingPutRepliesAreEnqueued); - CPPUNIT_TEST(testConflictingUpdateRepliesAreEnqueued); - CPPUNIT_TEST(testRemappedMutationIsCheckedAgainstOriginalBucket); - CPPUNIT_TEST(testBucketConflictSetIsClearedBetweenBlockingRequests); - CPPUNIT_TEST(testConflictSetOnlyClearedAfterAllBucketRequestsDone); - CPPUNIT_TEST(testRejectRequestWithMismatchingDistributionHash); - CPPUNIT_TEST(testDbNotIteratedWhenAllRequestsRejected); - CPPUNIT_TEST(fall_back_to_legacy_global_distribution_hash_on_mismatch); - - // FIXME(vekterli): test is not deterministic and enjoys failing - // sporadically when running under Valgrind. See bug 5932891. - CPPUNIT_TEST_IGNORED(testRequestBucketInfoWithState); - CPPUNIT_TEST_SUITE_END(); - std::unique_ptr<TestServiceLayerApp> _node; std::unique_ptr<DummyStorageLink> _top; BucketManager *_manager; @@ -101,12 +67,13 @@ public: uint32_t _emptyBuckets; document::Document::SP _document; + ~BucketManagerTest(); + void setupTestEnvironment(bool fakePersistenceLayer = true, bool noDelete = false); void addBucketsToDB(uint32_t count); bool wasBlockedDueToLastModified(api::StorageMessage* msg, uint64_t lastModified); - bool wasBlockedDueToLastModified(api::StorageMessage::SP msg); void insertSingleBucket(const document::BucketId& bucket, const api::BucketInfo& info); void waitUntilRequestsAreProcessing(size_t nRequests = 1); @@ -127,53 +94,30 @@ public: void assertRequestWithBadHashIsRejected( ConcurrentOperationFixture& fixture); +protected: + void update_min_used_bits() { + _manager->updateMinUsedBits(); + } + void trigger_metric_manager_update() { + vespalib::Monitor l; + _manager->updateMetrics(BucketManager::MetricLockGuard(l)); + } - void testRequestBucketInfoWithState(); - void testRequestBucketInfoWithList(); - void testDistributionBitGenerationEmpty(); - void testDistributionBitChangeOnCreateBucket(); - void testMinUsedBitsFromComponentIsHonored(); - - void testRemoveLastModifiedOK(); - void testRemoveLastModifiedFailed(); - - void testSwallowNotifyBucketChangeReply(); - void testMetricsGeneration(); - void metrics_are_tracked_per_bucket_space(); - void testSplitReplyOrderedAfterBucketReply(); - void testJoinReplyOrderedAfterBucketReply(); - void testDeleteReplyOrderedAfterBucketReply(); - void testOnlyEnqueueWhenProcessingRequest(); - void testOrderRepliesAfterBucketSpecificRequest(); - void testQueuedRepliesOnlyDispatchedWhenAllProcessingDone(); - void testMutationRepliesForSplitBucketAreEnqueued(); - void testMutationRepliesForDeletedBucketAreEnqueued(); - void testMutationRepliesForJoinedBucketAreEnqueued(); - void testConflictingPutRepliesAreEnqueued(); - void testConflictingUpdateRepliesAreEnqueued(); - void testRemappedMutationIsCheckedAgainstOriginalBucket(); - void testBucketConflictSetIsClearedBetweenBlockingRequests(); - void testConflictSetOnlyClearedAfterAllBucketRequestsDone(); - void testRejectRequestWithMismatchingDistributionHash(); - void testDbNotIteratedWhenAllRequestsRejected(); - void fall_back_to_legacy_global_distribution_hash_on_mismatch(); + const BucketManagerMetrics& bucket_manager_metrics() const { + return *_manager->_metrics; + } public: - static constexpr uint32_t DIR_SPREAD = 3; static constexpr uint32_t MESSAGE_WAIT_TIME = 60*2; - - void setUp() override { + void SetUp() override { _emptyBuckets = 0; } - void tearDown() override { - } - friend class ConcurrentOperationFixture; }; -CPPUNIT_TEST_SUITE_REGISTRATION(BucketManagerTest); +BucketManagerTest::~BucketManagerTest() = default; #define ASSERT_DUMMYLINK_REPLY_COUNT(link, count) \ if (link->getNumReplies() != count) { \ @@ -183,7 +127,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION(BucketManagerTest); for (uint32_t i=0; i<link->getNumReplies(); ++i) { \ ost << link->getReply(i)->getType() << "\n"; \ } \ - CPPUNIT_FAIL(ost.str()); \ + FAIL() << ost.str(); \ } std::string getMkDirDisk(const std::string & rootFolder, int disk) { @@ -203,34 +147,34 @@ void BucketManagerTest::setupTestEnvironment(bool fakePersistenceLayer, assert(system(getMkDirDisk(rootFolder, 0).c_str()) == 0); assert(system(getMkDirDisk(rootFolder, 1).c_str()) == 0); - std::shared_ptr<const DocumentTypeRepo> repo(new DocumentTypeRepo( + auto repo = std::make_shared<const DocumentTypeRepo>( *ConfigGetter<DocumenttypesConfig>::getConfig( - "config-doctypes", FileSpec(TEST_PATH("config-doctypes.cfg"))))); - _top.reset(new DummyStorageLink); - _node.reset(new TestServiceLayerApp( - DiskCount(2), NodeIndex(0), config.getConfigId())); + "config-doctypes", FileSpec("../config-doctypes.cfg"))); + _top = std::make_unique<DummyStorageLink>(); + _node = std::make_unique<TestServiceLayerApp>( + DiskCount(2), NodeIndex(0), config.getConfigId()); _node->setTypeRepo(repo); _node->setupDummyPersistence(); - // Set up the 3 links - StorageLink::UP manager(new BucketManager("", _node->getComponentRegister())); - _manager = (BucketManager*) manager.get(); + // Set up the 3 links + auto manager = std::make_unique<BucketManager>("", _node->getComponentRegister()); + _manager = manager.get(); _top->push_back(std::move(manager)); if (fakePersistenceLayer) { - StorageLink::UP bottom(new DummyStorageLink); - _bottom = (DummyStorageLink*) bottom.get(); + auto bottom = std::make_unique<DummyStorageLink>(); + _bottom = bottom.get(); _top->push_back(std::move(bottom)); } else { - StorageLink::UP bottom(new FileStorManager( + auto bottom = std::make_unique<FileStorManager>( config.getConfigId(), _node->getPartitions(), - _node->getPersistenceProvider(), _node->getComponentRegister())); - _filestorManager = (FileStorManager*) bottom.get(); + _node->getPersistenceProvider(), _node->getComponentRegister()); + _filestorManager = bottom.get(); _top->push_back(std::move(bottom)); } - // Generate a doc to use for testing.. + // Generate a doc to use for testing.. const DocumentType &type(*_node->getTypeRepo() ->getDocumentType("text/html")); - _document.reset(new document::Document(type, document::DocumentId( - document::DocIdString("test", "ntnu")))); + _document = std::make_shared<document::Document>( + type, document::DocumentId(document::DocIdString("test", "ntnu"))); } void BucketManagerTest::addBucketsToDB(uint32_t count) @@ -241,7 +185,7 @@ void BucketManagerTest::addBucketsToDB(uint32_t count) while (_bucketInfo.size() < count) { document::BucketId id(16, randomizer.nextUint32()); id = id.stripUnused(); - if (_bucketInfo.size() == 0) { + if (_bucketInfo.empty()) { id = _node->getBucketIdFactory().getBucketId( _document->getId()).stripUnused(); } @@ -261,15 +205,13 @@ void BucketManagerTest::addBucketsToDB(uint32_t count) info.count = 0; info.crc = 0; ++_emptyBuckets; - for (std::map<document::BucketId, TestBucketInfo>::iterator it - = _bucketInfo.begin(); it != _bucketInfo.end(); ++it) - { + for (const auto& bi : _bucketInfo) { bucketdb::StorageBucketInfo entry; - entry.disk = it->second.partition; - entry.setBucketInfo(api::BucketInfo(it->second.crc, - it->second.count, - it->second.size)); - _node->getStorageBucketDatabase().insert(it->first, entry, "foo"); + entry.disk = bi.second.partition; + entry.setBucketInfo(api::BucketInfo(bi.second.crc, + bi.second.count, + bi.second.size)); + _node->getStorageBucketDatabase().insert(bi.first, entry, "foo"); } } @@ -293,27 +235,25 @@ BucketManagerTest::wasBlockedDueToLastModified(api::StorageMessage* msg, _top->sendDown(api::StorageMessage::SP(msg)); if (_top->getNumReplies() == 1) { - CPPUNIT_ASSERT_EQUAL(0, (int)_bottom->getNumCommands()); - CPPUNIT_ASSERT(!static_cast<api::StorageReply&>( - *_top->getReply(0)).getResult().success()); + assert(_bottom->getNumCommands() == 0); + assert(!dynamic_cast<api::StorageReply&>(*_top->getReply(0)).getResult().success()); return true; } else { - CPPUNIT_ASSERT_EQUAL(0, (int)_top->getNumReplies()); + assert(_top->getNumReplies() == 0); // Check that bucket database now has the operation's timestamp as last modified. { StorBucketDatabase::WrappedEntry entry( _node->getStorageBucketDatabase().get(id, "foo")); - CPPUNIT_ASSERT_EQUAL(lastModified, entry->info.getLastModified()); + assert(entry->info.getLastModified() == lastModified); } return false; } } -void BucketManagerTest::testRemoveLastModifiedOK() -{ - CPPUNIT_ASSERT(!wasBlockedDueToLastModified( +TEST_F(BucketManagerTest, remove_last_modified_ok) { + EXPECT_FALSE(wasBlockedDueToLastModified( new api::RemoveCommand(makeDocumentBucket(document::BucketId(16, 1)), document::DocumentId("userdoc:m:1:foo"), api::Timestamp(1235)), @@ -321,45 +261,37 @@ void BucketManagerTest::testRemoveLastModifiedOK() } -void BucketManagerTest::testRemoveLastModifiedFailed() -{ - CPPUNIT_ASSERT(wasBlockedDueToLastModified( +TEST_F(BucketManagerTest, remove_last_modified_failed) { + EXPECT_TRUE(wasBlockedDueToLastModified( new api::RemoveCommand(makeDocumentBucket(document::BucketId(16, 1)), document::DocumentId("userdoc:m:1:foo"), api::Timestamp(1233)), 1233)); } -void BucketManagerTest::testDistributionBitGenerationEmpty() -{ - TestName("BucketManagerTest::testDistributionBitGenerationEmpty()"); +TEST_F(BucketManagerTest, distribution_bit_generation_empty) { setupTestEnvironment(); _manager->doneInit(); - vespalib::Monitor l; - _manager->updateMetrics(BucketManager::MetricLockGuard(l)); - CPPUNIT_ASSERT_EQUAL(58u, _node->getStateUpdater().getReportedNodeState()->getMinUsedBits()); + trigger_metric_manager_update(); + EXPECT_EQ(58u, _node->getStateUpdater().getReportedNodeState()->getMinUsedBits()); } -void BucketManagerTest::testDistributionBitChangeOnCreateBucket() -{ - TestName("BucketManagerTest::testDistributionBitChangeOnCreateBucket()"); +TEST_F(BucketManagerTest, distribution_bit_change_on_create_bucket){ setupTestEnvironment(); addBucketsToDB(30); _top->open(); _node->getDoneInitializeHandler().notifyDoneInitializing(); _manager->doneInit(); - _manager->updateMinUsedBits(); - CPPUNIT_ASSERT_EQUAL(16u, _node->getStateUpdater().getReportedNodeState()->getMinUsedBits()); + update_min_used_bits(); + EXPECT_EQ(16u, _node->getStateUpdater().getReportedNodeState()->getMinUsedBits()); std::shared_ptr<api::CreateBucketCommand> cmd( new api::CreateBucketCommand(makeDocumentBucket(document::BucketId(4, 5678)))); _top->sendDown(cmd); - CPPUNIT_ASSERT_EQUAL(4u, _node->getStateUpdater().getReportedNodeState()->getMinUsedBits()); + EXPECT_EQ(4u, _node->getStateUpdater().getReportedNodeState()->getMinUsedBits()); } -void BucketManagerTest::testMinUsedBitsFromComponentIsHonored() -{ - TestName("BucketManagerTest::testMinUsedBitsFromComponentIsHonored()"); +TEST_F(BucketManagerTest, Min_Used_Bits_From_Component_Is_Honored) { setupTestEnvironment(); // Let these differ in order to test state update behavior. _node->getComponentRegister().getMinUsedBitsTracker().setMinUsedBits(10); @@ -377,40 +309,21 @@ void BucketManagerTest::testMinUsedBitsFromComponentIsHonored() std::shared_ptr<api::CreateBucketCommand> cmd( new api::CreateBucketCommand(makeDocumentBucket(document::BucketId(12, 5678)))); _top->sendDown(cmd); - CPPUNIT_ASSERT_EQUAL(13u, _node->getStateUpdater().getReportedNodeState()->getMinUsedBits()); + EXPECT_EQ(13u, _node->getStateUpdater().getReportedNodeState()->getMinUsedBits()); } -void BucketManagerTest::testRequestBucketInfoWithState() -{ - TestName("BucketManagerTest::testRequestBucketInfoWithState()"); - // Test prior to building bucket cache +// FIXME: non-deterministic test +TEST_F(BucketManagerTest, IGNORED_request_bucket_info_with_state) { + // Test prior to building bucket cache setupTestEnvironment(); addBucketsToDB(30); - /* Currently this is just queued up - { - std::shared_ptr<api::RequestBucketInfoCommand> cmd( - new api::RequestBucketInfoCommand( - 0, lib::ClusterState("distributor:3 .2.s:d storage:1"))); - _top->sendDown(cmd); - _top->waitForMessages(1, 5); - CPPUNIT_ASSERT_EQUAL((size_t) 1, _top->getNumReplies()); - std::shared_ptr<api::RequestBucketInfoReply> reply( - std::dynamic_pointer_cast<api::RequestBucketInfoReply>( - _top->getReply(0))); - _top->reset(); - CPPUNIT_ASSERT(reply.get()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::NOT_READY), - reply->getResult()); - } */ + std::vector<lib::ClusterState> states; - states.push_back(lib::ClusterState("version:0")); - states.push_back(lib::ClusterState("version:1 distributor:1 storage:1")); - states.push_back(lib::ClusterState( - "version:2 distributor:3 .1.s:i .2.s:d storage:4")); - states.push_back(lib::ClusterState( - "version:3 distributor:3 .1.s:i .2.s:d storage:4 .3.s:d")); - states.push_back(lib::ClusterState( - "version:4 distributor:3 .1.s:i .2.s:d storage:4")); + states.emplace_back("version:0"); + states.emplace_back("version:1 distributor:1 storage:1"); + states.emplace_back("version:2 distributor:3 .1.s:i .2.s:d storage:4"); + states.emplace_back("version:3 distributor:3 .1.s:i .2.s:d storage:4 .3.s:d"); + states.emplace_back("version:4 distributor:3 .1.s:i .2.s:d storage:4"); _node->setClusterState(states.back()); for (uint32_t i=0; i<states.size(); ++i) { @@ -419,11 +332,11 @@ void BucketManagerTest::testRequestBucketInfoWithState() _manager->onDown(cmd); } - // Send a request bucket info command that will be outdated and failed. + // Send a request bucket info command that will be outdated and failed. std::shared_ptr<api::RequestBucketInfoCommand> cmd1( new api::RequestBucketInfoCommand(makeBucketSpace(), 0, states[1])); - // Send two request bucket info commands that will be processed together - // when the bucket manager is idle, as states are equivalent + // Send two request bucket info commands that will be processed together + // when the bucket manager is idle, as states are equivalent std::shared_ptr<api::RequestBucketInfoCommand> cmd2( new api::RequestBucketInfoCommand(makeBucketSpace(), 0, states[2])); std::shared_ptr<api::RequestBucketInfoCommand> cmd3( @@ -457,104 +370,29 @@ void BucketManagerTest::testRequestBucketInfoWithState() std::shared_ptr<api::RequestBucketInfoReply> reply3( replies[cmd3->getMsgId()]); _top->reset(); - CPPUNIT_ASSERT(reply1.get()); - CPPUNIT_ASSERT(reply2.get()); - CPPUNIT_ASSERT(reply3.get()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::REJECTED, + ASSERT_TRUE(reply1.get()); + ASSERT_TRUE(reply2.get()); + ASSERT_TRUE(reply3.get()); + EXPECT_EQ(api::ReturnCode(api::ReturnCode::REJECTED, "Ignoring bucket info request for cluster state version 1 as " "versions from version 2 differs from this state."), reply1->getResult()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::REJECTED, + EXPECT_EQ(api::ReturnCode(api::ReturnCode::REJECTED, "There is already a newer bucket info request for " "this node from distributor 0"), reply2->getResult()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::OK), + EXPECT_EQ(api::ReturnCode(api::ReturnCode::OK), reply3->getResult()); api::RequestBucketInfoReply::Entry entry; - CPPUNIT_ASSERT_EQUAL((size_t) 18, reply3->getBucketInfo().size()); + ASSERT_EQ(18u, reply3->getBucketInfo().size()); entry = api::RequestBucketInfoReply::Entry( document::BucketId(16, 0xe8c8), api::BucketInfo(0x79d04f78, 11153, 1851385240u)); - CPPUNIT_ASSERT_EQUAL(entry, reply3->getBucketInfo()[0]); + EXPECT_EQ(entry, reply3->getBucketInfo()[0]); } } -namespace { - struct PopenWrapper { - FILE* _file; - std::vector<char> _buffer; - uint32_t _index; - uint32_t _size; - bool _eof; - - PopenWrapper(const std::string& cmd) - : _buffer(65536, '\0'), _index(0), _size(0), _eof(false) - { - _file = popen(cmd.c_str(), "r"); - if (_file == 0) { - throw vespalib::Exception("Failed to run '" + cmd - + "' in popen: " + strerror(errno), VESPA_STRLOC); - } - } - - const char* getNextLine() { - if (_eof && _size == 0) return 0; - // Check if we have a newline waiting - char* newline = strchr(&_buffer[_index], '\n'); - // If not try to get one - if (_eof) { - newline = &_buffer[_index + _size]; - } else if (newline == 0) { - // If we index is passed half the buffer, reposition - if (_index > _buffer.size() / 2) { - memcpy(&_buffer[0], &_buffer[_index], _size); - _index = 0; - } - // Verify we have space to write to - if (_index + _size >= _buffer.size()) { - throw vespalib::Exception("No newline could be find in " - "half the buffer size. Wrapper not designed to " - "handle that long lines (1)", VESPA_STRLOC); - } - // Fill up buffer - size_t bytesRead = fread(&_buffer[_index + _size], - 1, _buffer.size() - _index - _size - 1, - _file); - if (bytesRead == 0) { - if (!feof(_file)) { - throw vespalib::Exception("Failed to run fgets: " - + std::string(strerror(errno)), VESPA_STRLOC); - } else { - _eof = true; - } - } else { - _size += bytesRead; - } - newline = strchr(&_buffer[_index], '\n'); - if (newline == 0) { - if (_eof) { - if (_size == 0) return 0; - } else { - throw vespalib::Exception("No newline could be find in " - "half the buffer size. Wrapper not designed to " - "handle that long lines (2)", VESPA_STRLOC); - } - } - } - *newline = '\0'; - ++newline; - const char* line = &_buffer[_index]; - uint32_t strlen = (newline - line); - _index += strlen; - _size -= strlen; - return line; - } - }; -} - -void BucketManagerTest::testRequestBucketInfoWithList() -{ - TestName("BucketManagerTest::testRequestBucketInfoWithList()"); +TEST_F(BucketManagerTest, request_bucket_info_with_list) { setupTestEnvironment(); addBucketsToDB(30); _top->open(); @@ -562,39 +400,26 @@ void BucketManagerTest::testRequestBucketInfoWithList() _top->doneInit(); { std::vector<document::BucketId> bids; - bids.push_back(document::BucketId(16, 0xe8c8)); + bids.emplace_back(16, 0xe8c8); - std::shared_ptr<api::RequestBucketInfoCommand> cmd( - new api::RequestBucketInfoCommand(makeBucketSpace(), bids)); + auto cmd = std::make_shared<api::RequestBucketInfoCommand>(makeBucketSpace(), bids); _top->sendDown(cmd); _top->waitForMessages(1, 5); ASSERT_DUMMYLINK_REPLY_COUNT(_top, 1); - std::shared_ptr<api::RequestBucketInfoReply> reply( - std::dynamic_pointer_cast<api::RequestBucketInfoReply>( - _top->getReply(0))); + auto reply = std::dynamic_pointer_cast<api::RequestBucketInfoReply>(_top->getReply(0)); _top->reset(); - CPPUNIT_ASSERT(reply.get()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::OK), - reply->getResult()); - if (reply->getBucketInfo().size() > 1) { - std::cerr << "Too many replies found\n"; - for (uint32_t i=0; i<reply->getBucketInfo().size(); ++i) { - std::cerr << reply->getBucketInfo()[i] << "\n"; - } - } - CPPUNIT_ASSERT_EQUAL((size_t) 1, reply->getBucketInfo().size()); + ASSERT_TRUE(reply.get()); + EXPECT_EQ(api::ReturnCode(api::ReturnCode::OK), reply->getResult()); + ASSERT_EQ(1u, reply->getBucketInfo().size()); api::RequestBucketInfoReply::Entry entry( document::BucketId(16, 0xe8c8), api::BucketInfo(0x79d04f78, 11153, 1851385240u)); - CPPUNIT_ASSERT_EQUAL(entry, reply->getBucketInfo()[0]); + EXPECT_EQ(entry, reply->getBucketInfo()[0]); } } -void -BucketManagerTest::testSwallowNotifyBucketChangeReply() -{ - TestName("BucketManagerTest::testSwallowNotifyBucketChangeReply()"); +TEST_F(BucketManagerTest, swallow_notify_bucket_change_reply) { setupTestEnvironment(); addBucketsToDB(30); _top->open(); @@ -603,17 +428,14 @@ BucketManagerTest::testSwallowNotifyBucketChangeReply() api::NotifyBucketChangeCommand cmd(makeDocumentBucket(document::BucketId(1, 16)), api::BucketInfo()); - std::shared_ptr<api::NotifyBucketChangeReply> reply( - new api::NotifyBucketChangeReply(cmd)); + auto reply = std::make_shared<api::NotifyBucketChangeReply>(cmd); _top->sendDown(reply); // Should not leave the bucket manager. - CPPUNIT_ASSERT_EQUAL(0, (int)_bottom->getNumCommands()); + EXPECT_EQ(0u, _bottom->getNumCommands()); } -void -BucketManagerTest::testMetricsGeneration() -{ +TEST_F(BucketManagerTest, metrics_generation) { setupTestEnvironment(); _top->open(); // Add 3 buckets; 2 ready, 1 active. 300 docs total, 600 bytes total. @@ -633,19 +455,18 @@ BucketManagerTest::testMetricsGeneration() } _node->getDoneInitializeHandler().notifyDoneInitializing(); _top->doneInit(); - vespalib::Monitor l; - _manager->updateMetrics(BucketManager::MetricLockGuard(l)); - - CPPUNIT_ASSERT_EQUAL(size_t(2), _manager->_metrics->disks.size()); - const DataStoredMetrics& m(*_manager->_metrics->disks[0]); - CPPUNIT_ASSERT_EQUAL(int64_t(3), m.buckets.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(300), m.docs.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(600), m.bytes.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), m.active.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(2), m.ready.getLast()); + trigger_metric_manager_update(); + + ASSERT_EQ(2u, bucket_manager_metrics().disks.size()); + const DataStoredMetrics& m(*bucket_manager_metrics().disks[0]); + EXPECT_EQ(3, m.buckets.getLast()); + EXPECT_EQ(300, m.docs.getLast()); + EXPECT_EQ(600, m.bytes.getLast()); + EXPECT_EQ(1, m.active.getLast()); + EXPECT_EQ(2, m.ready.getLast()); } -void BucketManagerTest::metrics_are_tracked_per_bucket_space() { +TEST_F(BucketManagerTest, metrics_are_tracked_per_bucket_space) { setupTestEnvironment(); _top->open(); auto& repo = _node->getComponentRegister().getBucketSpaceRepo(); @@ -669,25 +490,24 @@ void BucketManagerTest::metrics_are_tracked_per_bucket_space() { } _node->getDoneInitializeHandler().notifyDoneInitializing(); _top->doneInit(); - vespalib::Monitor l; - _manager->updateMetrics(BucketManager::MetricLockGuard(l)); + trigger_metric_manager_update(); - auto& spaces = _manager->_metrics->bucket_spaces; + auto& spaces = bucket_manager_metrics().bucket_spaces; auto default_m = spaces.find(document::FixedBucketSpaces::default_space()); - CPPUNIT_ASSERT(default_m != spaces.end()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), default_m->second->buckets_total.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(100), default_m->second->docs.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(200), default_m->second->bytes.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), default_m->second->active_buckets.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), default_m->second->ready_buckets.getLast()); + ASSERT_TRUE(default_m != spaces.end()); + EXPECT_EQ(1, default_m->second->buckets_total.getLast()); + EXPECT_EQ(100, default_m->second->docs.getLast()); + EXPECT_EQ(200, default_m->second->bytes.getLast()); + EXPECT_EQ(0, default_m->second->active_buckets.getLast()); + EXPECT_EQ(1, default_m->second->ready_buckets.getLast()); auto global_m = spaces.find(document::FixedBucketSpaces::global_space()); - CPPUNIT_ASSERT(global_m != spaces.end()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), global_m->second->buckets_total.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(150), global_m->second->docs.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(300), global_m->second->bytes.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(1), global_m->second->active_buckets.getLast()); - CPPUNIT_ASSERT_EQUAL(int64_t(0), global_m->second->ready_buckets.getLast()); + ASSERT_TRUE(global_m != spaces.end()); + EXPECT_EQ(1, global_m->second->buckets_total.getLast()); + EXPECT_EQ(150, global_m->second->docs.getLast()); + EXPECT_EQ(300, global_m->second->bytes.getLast()); + EXPECT_EQ(1, global_m->second->active_buckets.getLast()); + EXPECT_EQ(0, global_m->second->ready_buckets.getLast()); } void @@ -725,7 +545,7 @@ struct WithBuckets { class ConcurrentOperationFixture { public: - ConcurrentOperationFixture(BucketManagerTest& self) + explicit ConcurrentOperationFixture(BucketManagerTest& self) : _self(self), _state("distributor:1 storage:1") { @@ -835,21 +655,20 @@ public: { const size_t nTotal = nBucketReplies + 1; auto replies = awaitAndGetReplies(nTotal); - CPPUNIT_ASSERT_EQUAL(nTotal, replies.size()); + ASSERT_EQ(nTotal, replies.size()); for (size_t i = 0; i < nBucketReplies; ++i) { - CPPUNIT_ASSERT_EQUAL(api::MessageType::REQUESTBUCKETINFO_REPLY, - replies[i]->getType()); + ASSERT_EQ(api::MessageType::REQUESTBUCKETINFO_REPLY, replies[i]->getType()); } - CPPUNIT_ASSERT_EQUAL(msgType, replies[nBucketReplies]->getType()); + ASSERT_EQ(msgType, replies[nBucketReplies]->getType()); } void assertReplyOrdering( const std::vector<const api::MessageType*>& replyTypes) { auto replies = awaitAndGetReplies(replyTypes.size()); - CPPUNIT_ASSERT_EQUAL(replyTypes.size(), replies.size()); + ASSERT_EQ(replyTypes.size(), replies.size()); for (size_t i = 0; i < replyTypes.size(); ++i) { - CPPUNIT_ASSERT_EQUAL(*replyTypes[i], replies[i]->getType()); + ASSERT_EQ(*replyTypes[i], replies[i]->getType()); } } @@ -901,9 +720,7 @@ private: lib::ClusterState _state; }; -void -BucketManagerTest::testSplitReplyOrderedAfterBucketReply() -{ +TEST_F(BucketManagerTest, split_reply_ordered_after_bucket_reply) { ConcurrentOperationFixture fixture(*this); document::BucketId bucketA(17, 0); document::BucketId bucketB(17, 1); @@ -924,9 +741,7 @@ BucketManagerTest::testSplitReplyOrderedAfterBucketReply() 1, api::MessageType::SPLITBUCKET_REPLY); } -void -BucketManagerTest::testJoinReplyOrderedAfterBucketReply() -{ +TEST_F(BucketManagerTest, join_reply_ordered_after_bucket_reply) { ConcurrentOperationFixture fixture(*this); document::BucketId bucketA(17, 0); document::BucketId bucketB(17, 1 << 16); @@ -949,9 +764,7 @@ BucketManagerTest::testJoinReplyOrderedAfterBucketReply() // Technically, deletes being ordered after bucket info replies won't help // correctness since buckets are removed from the distributor DB upon _sending_ // the delete and not receiving it. -void -BucketManagerTest::testDeleteReplyOrderedAfterBucketReply() -{ +TEST_F(BucketManagerTest, delete_reply_ordered_after_bucket_reply) { ConcurrentOperationFixture fixture(*this); document::BucketId bucketA(17, 0); document::BucketId bucketB(17, 1); @@ -970,9 +783,7 @@ BucketManagerTest::testDeleteReplyOrderedAfterBucketReply() 1, api::MessageType::DELETEBUCKET_REPLY); } -void -BucketManagerTest::testOnlyEnqueueWhenProcessingRequest() -{ +TEST_F(BucketManagerTest, only_enqueue_when_processing_request) { ConcurrentOperationFixture fixture(*this); document::BucketId bucketA(17, 0); fixture.setUp(WithBuckets() @@ -990,9 +801,7 @@ BucketManagerTest::testOnlyEnqueueWhenProcessingRequest() // differently than full bucket info fetches and are not delegated to the // worker thread. We still require that any split/joins etc are ordered after // this reply if their reply is sent up concurrently. -void -BucketManagerTest::testOrderRepliesAfterBucketSpecificRequest() -{ +TEST_F(BucketManagerTest, order_replies_after_bucket_specific_request) { ConcurrentOperationFixture fixture(*this); document::BucketId bucketA(17, 0); fixture.setUp(WithBuckets() @@ -1025,14 +834,12 @@ BucketManagerTest::testOrderRepliesAfterBucketSpecificRequest() 1, api::MessageType::SPLITBUCKET_REPLY); } -// Test is similar to testOrderRepliesAfterBucketSpecificRequest, but has +// Test is similar to order_replies_after_bucket_specific_request, but has // two concurrent bucket info request processing instances going on; one in // the worker thread and one in the message chain itself. Since we only have // one queue, we must wait with dispatching replies until _all_ processing // has ceased. -void -BucketManagerTest::testQueuedRepliesOnlyDispatchedWhenAllProcessingDone() -{ +TEST_F(BucketManagerTest, queued_replies_only_dispatched_when_all_processing_done) { ConcurrentOperationFixture fixture(*this); document::BucketId bucketA(17, 0); fixture.setUp(WithBuckets() @@ -1085,9 +892,9 @@ struct TestParams { BUILDER_PARAM(std::vector<const api::MessageType*>, expectedOrdering); }; -TestParams::TestParams() { } +TestParams::TestParams() = default; TestParams::TestParams(const TestParams &) = default; -TestParams::~TestParams() {} +TestParams::~TestParams() = default; void BucketManagerTest::doTestMutationOrdering( @@ -1140,9 +947,7 @@ BucketManagerTest::doTestConflictingReplyIsEnqueued( doTestMutationOrdering(fixture, params); } -void -BucketManagerTest::testMutationRepliesForSplitBucketAreEnqueued() -{ +TEST_F(BucketManagerTest, mutation_replies_for_split_bucket_are_enqueued) { document::BucketId bucket(17, 0); doTestConflictingReplyIsEnqueued( bucket, @@ -1150,9 +955,7 @@ BucketManagerTest::testMutationRepliesForSplitBucketAreEnqueued() api::MessageType::SPLITBUCKET_REPLY); } -void -BucketManagerTest::testMutationRepliesForDeletedBucketAreEnqueued() -{ +TEST_F(BucketManagerTest, mutation_replies_for_deleted_bucket_are_enqueued) { document::BucketId bucket(17, 0); doTestConflictingReplyIsEnqueued( bucket, @@ -1160,9 +963,7 @@ BucketManagerTest::testMutationRepliesForDeletedBucketAreEnqueued() api::MessageType::DELETEBUCKET_REPLY); } -void -BucketManagerTest::testMutationRepliesForJoinedBucketAreEnqueued() -{ +TEST_F(BucketManagerTest, mutation_replies_for_joined_bucket_are_enqueued) { ConcurrentOperationFixture fixture(*this); document::BucketId bucketA(17, 0); document::BucketId bucketB(17, 1 << 16); @@ -1183,9 +984,7 @@ BucketManagerTest::testMutationRepliesForJoinedBucketAreEnqueued() doTestMutationOrdering(fixture, params); } -void -BucketManagerTest::testConflictingPutRepliesAreEnqueued() -{ +TEST_F(BucketManagerTest, conflicting_put_replies_are_enqueued) { ConcurrentOperationFixture fixture(*this); document::BucketId bucket(17, 0); @@ -1200,9 +999,7 @@ BucketManagerTest::testConflictingPutRepliesAreEnqueued() doTestMutationOrdering(fixture, params); } -void -BucketManagerTest::testConflictingUpdateRepliesAreEnqueued() -{ +TEST_F(BucketManagerTest, conflicting_update_replies_are_enqueued) { ConcurrentOperationFixture fixture(*this); document::BucketId bucket(17, 0); @@ -1223,9 +1020,7 @@ BucketManagerTest::testConflictingUpdateRepliesAreEnqueued() * resulting from the operation. We have to make sure remapped operations are * enqueued as well. */ -void -BucketManagerTest::testRemappedMutationIsCheckedAgainstOriginalBucket() -{ +TEST_F(BucketManagerTest, remapped_mutation_is_checked_against_original_bucket) { ConcurrentOperationFixture fixture(*this); document::BucketId bucket(17, 0); document::BucketId remappedToBucket(18, 0); @@ -1263,9 +1058,7 @@ BucketManagerTest::scheduleBucketInfoRequestWithConcurrentOps( guard.unlock(); } -void -BucketManagerTest::testBucketConflictSetIsClearedBetweenBlockingRequests() -{ +TEST_F(BucketManagerTest, bucket_conflict_set_is_cleared_between_blocking_requests) { ConcurrentOperationFixture fixture(*this); document::BucketId firstConflictBucket(17, 0); document::BucketId secondConflictBucket(18, 0); @@ -1308,9 +1101,7 @@ BucketManagerTest::sendSingleBucketInfoRequest(const document::BucketId& id) _top->sendDown(infoCmd); } -void -BucketManagerTest::testConflictSetOnlyClearedAfterAllBucketRequestsDone() -{ +TEST_F(BucketManagerTest, conflict_set_only_cleared_after_all_bucket_requests_done) { ConcurrentOperationFixture fixture(*this); document::BucketId bucketA(16, 0); document::BucketId bucketB(16, 1); @@ -1371,22 +1162,17 @@ BucketManagerTest::assertRequestWithBadHashIsRejected( _top->sendDown(infoCmd); auto replies = fixture.awaitAndGetReplies(1); auto& reply = dynamic_cast<api::RequestBucketInfoReply&>(*replies[0]); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::REJECTED, - reply.getResult().getResult()); + ASSERT_EQ(api::ReturnCode::REJECTED, reply.getResult().getResult()); } -void -BucketManagerTest::testRejectRequestWithMismatchingDistributionHash() -{ +TEST_F(BucketManagerTest, reject_request_with_mismatching_distribution_hash) { ConcurrentOperationFixture fixture(*this); document::BucketId bucket(17, 0); fixture.setUp(WithBuckets().add(bucket, api::BucketInfo(50, 100, 200))); assertRequestWithBadHashIsRejected(fixture); } -void -BucketManagerTest::testDbNotIteratedWhenAllRequestsRejected() -{ +TEST_F(BucketManagerTest, db_not_iterated_when_all_requests_rejected) { ConcurrentOperationFixture fixture(*this); document::BucketId bucket(17, 0); fixture.setUp(WithBuckets().add(bucket, api::BucketInfo(50, 100, 200))); @@ -1405,7 +1191,7 @@ BucketManagerTest::testDbNotIteratedWhenAllRequestsRejected() } // TODO remove on Vespa 8 - this is a workaround for https://github.com/vespa-engine/vespa/issues/8475 -void BucketManagerTest::fall_back_to_legacy_global_distribution_hash_on_mismatch() { +TEST_F(BucketManagerTest, fall_back_to_legacy_global_distribution_hash_on_mismatch) { ConcurrentOperationFixture f(*this); f.set_grouped_distribution_configs(); @@ -1416,7 +1202,7 @@ void BucketManagerTest::fall_back_to_legacy_global_distribution_hash_on_mismatch _top->sendDown(infoCmd); auto replies = f.awaitAndGetReplies(1); auto& reply = dynamic_cast<api::RequestBucketInfoReply&>(*replies[0]); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::OK, reply.getResult().getResult()); // _not_ REJECTED + EXPECT_EQ(api::ReturnCode::OK, reply.getResult().getResult()); // _not_ REJECTED } } // storage diff --git a/storage/src/tests/bucketdb/initializertest.cpp b/storage/src/tests/bucketdb/initializertest.cpp index 2141dbf4b53..57bb3a865d5 100644 --- a/storage/src/tests/bucketdb/initializertest.cpp +++ b/storage/src/tests/bucketdb/initializertest.cpp @@ -2,33 +2,31 @@ /** * Tests storage initialization without depending on persistence layer. */ -#include <vespa/storage/bucketdb/storagebucketdbinitializer.h> - #include <vespa/document/base/testdocman.h> - +#include <vespa/document/bucket/fixed_bucket_spaces.h> +#include <vespa/storage/bucketdb/lockablemap.hpp> +#include <vespa/storage/bucketdb/storagebucketdbinitializer.h> #include <vespa/storage/persistence/filestorage/filestormanager.h> #include <vespa/storageapi/message/bucket.h> #include <vespa/storageapi/message/persistence.h> #include <vespa/storageapi/message/state.h> #include <tests/common/teststorageapp.h> #include <tests/common/dummystoragelink.h> -#include <tests/common/testhelper.h> -#include <vespa/vdstestlib/cppunit/dirconfig.h> -#include <vespa/vdstestlib/cppunit/macros.h> -#include <vespa/storage/bucketdb/lockablemap.hpp> -#include <vespa/vdstestlib/cppunit/dirconfig.hpp> -#include <vespa/document/bucket/fixed_bucket_spaces.h> +#include <tests/common/testhelper.h> // TODO decouple from CppUnit +#include <vespa/vdstestlib/cppunit/dirconfig.hpp> // TODO decouple from CppUnit +#include <vespa/vespalib/gtest/gtest.h> #include <vespa/log/log.h> LOG_SETUP(".test.bucketdb.initializing"); using document::FixedBucketSpaces; +using namespace ::testing; namespace storage { typedef uint16_t PartitionId; -struct InitializerTest : public CppUnit::TestFixture { +struct InitializerTest : public Test { class InitParams { vdstestlib::DirConfig config; @@ -59,14 +57,8 @@ struct InitializerTest : public CppUnit::TestFixture { bucketWrongDisk(false), bucketMultipleDisks(false), failingListRequest(false), - failingInfoRequest(false) {} - - void setAllFailures() { - bucketWrongDisk = true; - bucketMultipleDisks = true; - failingListRequest = true; - failingInfoRequest = true; - } + failingInfoRequest(false) + {} vdstestlib::DirConfig& getConfig() { if (!configFinalized) { @@ -83,104 +75,44 @@ struct InitializerTest : public CppUnit::TestFixture { document::TestDocMan _docMan; - void testInitialization(InitParams& params); + void do_test_initialization(InitParams& params); +}; - /** - * Test that the status page can be shown during init without a deadlock - * or crash or anything. Don't validate much output, it might change. - */ - void testStatusPage(); +TEST_F(InitializerTest, init_with_empty_node) { + InitParams params; + params.docsPerDisk = 0; + do_test_initialization(params); +} - /** Test initializing with an empty node. */ - void testInitEmptyNode() { - InitParams params; - params.docsPerDisk = 0; - testInitialization(params); - } - /** Test initializing with some data on single disk. */ - void testInitSingleDisk() { - InitParams params; - params.diskCount = DiskCount(1); - testInitialization(params); - } - /** Test initializing with multiple disks. */ - void testInitMultiDisk() { - InitParams params; - testInitialization(params); - } - /** Test initializing with one of the disks being bad. */ - void testInitFailingMiddleDisk() { - InitParams params; - params.disksDown.insert(1); - testInitialization(params); - } - /** Test initializing with last disk being bad. */ - void testInitFailingLastDisk() { - InitParams params; - params.disksDown.insert(params.diskCount - 1); - testInitialization(params); - } - /** Test initializing with bucket on wrong disk. */ - void testInitBucketOnWrongDisk() { - InitParams params; - params.bucketWrongDisk = true; - params.bucketBitsUsed = 58; - testInitialization(params); - } - /** Test initializing with bucket on multiple disks. */ - void testInitBucketOnMultipleDisks() { - InitParams params; - params.bucketMultipleDisks = true; - params.bucketBitsUsed = 58; - testInitialization(params); - } - /** Test initializing with failing list request. */ - void testInitFailingListRequest() { - InitParams params; - params.failingListRequest = true; - testInitialization(params); - } - void testInitFailingInfoRequest() { - InitParams params; - params.failingInfoRequest = true; - testInitialization(params); - } - /** Test initializing with everything being wrong at once. */ - void testAllFailures() { - InitParams params; - params.docsPerDisk = 100; - params.diskCount = DiskCount(10); - params.disksDown.insert(0); - params.disksDown.insert(2); - params.disksDown.insert(3); - params.disksDown.insert(9); - params.setAllFailures(); - testInitialization(params); - } - void testCommandBlockingDuringInit(); - - void testBucketProgressCalculator(); - - void testBucketsInitializedByLoad(); - - CPPUNIT_TEST_SUITE(InitializerTest); - CPPUNIT_TEST(testInitEmptyNode); - CPPUNIT_TEST(testInitSingleDisk); - CPPUNIT_TEST(testInitMultiDisk); - CPPUNIT_TEST(testInitFailingMiddleDisk); - CPPUNIT_TEST(testInitFailingLastDisk); - CPPUNIT_TEST(testInitBucketOnWrongDisk); - //CPPUNIT_TEST(testInitBucketOnMultipleDisks); - //CPPUNIT_TEST(testStatusPage); - //CPPUNIT_TEST(testCommandBlockingDuringInit); - //CPPUNIT_TEST(testAllFailures); - CPPUNIT_TEST(testBucketProgressCalculator); - CPPUNIT_TEST(testBucketsInitializedByLoad); - CPPUNIT_TEST_SUITE_END(); +TEST_F(InitializerTest, init_with_data_on_single_disk) { + InitParams params; + params.diskCount = DiskCount(1); + do_test_initialization(params); +} -}; +TEST_F(InitializerTest, init_with_multiple_disks) { + InitParams params; + do_test_initialization(params); +} + +TEST_F(InitializerTest, init_with_bad_non_last_disk) { + InitParams params; + params.disksDown.insert(1); + do_test_initialization(params); +} + +TEST_F(InitializerTest, init_with_bad_last_disk) { + InitParams params; + params.disksDown.insert(params.diskCount - 1); + do_test_initialization(params); +} -CPPUNIT_TEST_SUITE_REGISTRATION(InitializerTest); +TEST_F(InitializerTest, init_with_bucket_on_wrong_disk) { + InitParams params; + params.bucketWrongDisk = true; + params.bucketBitsUsed = 58; + do_test_initialization(params); +} namespace { // Data kept on buckets we're using in test. @@ -202,7 +134,7 @@ struct BucketData { return copy; } }; -// Data reciding on one disk +// Data residing on one disk typedef std::map<document::BucketId, BucketData> DiskData; struct BucketInfoLogger { std::map<PartitionId, DiskData>& map; @@ -215,11 +147,8 @@ struct BucketInfoLogger { { document::BucketId bucket( document::BucketId::keyToBucketId(revBucket)); - CPPUNIT_ASSERT(bucket.getRawId() != 0); - CPPUNIT_ASSERT_MSG( - "Found invalid bucket in database: " + bucket.toString() - + " " + entry.getBucketInfo().toString(), - entry.getBucketInfo().valid()); + assert(bucket.getRawId() != 0); + assert(entry.getBucketInfo().valid()); DiskData& ddata(map[entry.disk]); BucketData& bdata(ddata[bucket]); bdata.info = entry.getBucketInfo(); @@ -277,10 +206,10 @@ buildBucketInfo(const document::TestDocMan& docMan, while (params.disksDown.find(partition) != params.disksDown.end()) { partition = (partition + 1) % params.diskCount;; } - LOG(info, "Putting bucket %s on wrong disk %u instead of %u", + LOG(debug, "Putting bucket %s on wrong disk %u instead of %u", bid.toString().c_str(), partition, correctPart); } - LOG(info, "Putting bucket %s on disk %u", + LOG(debug, "Putting bucket %s on disk %u", bid.toString().c_str(), partition); BucketData& data(result[partition][bid]); data.info.setDocumentCount(data.info.getDocumentCount() + 1); @@ -299,84 +228,65 @@ void verifyEqual(std::map<PartitionId, DiskData>& org, while (part1 != org.end() && part2 != existing.end()) { if (part1->first < part2->first) { if (!part1->second.empty()) { - std::ostringstream ost; - ost << "No data in partition " << part1->first << " found."; - CPPUNIT_FAIL(ost.str()); + FAIL() << "No data in partition " << part1->first << " found."; } ++part1; } else if (part1->first > part2->first) { if (!part2->second.empty()) { - std::ostringstream ost; - ost << "Found data in partition " << part2->first - << " which should not exist."; - CPPUNIT_FAIL(ost.str()); + FAIL() << "Found data in partition " << part2->first + << " which should not exist."; } ++part2; } else { - DiskData::const_iterator bucket1(part1->second.begin()); - DiskData::const_iterator bucket2(part2->second.begin()); + auto bucket1 = part1->second.begin(); + auto bucket2 = part2->second.begin(); while (bucket1 != part1->second.end() && bucket2 != part2->second.end()) { if (bucket1->first < bucket2->first) { - std::ostringstream ost; - ost << "No data in partition " << part1->first - << " for bucket " << bucket1->first << " found."; - CPPUNIT_FAIL(ost.str()); + FAIL() << "No data in partition " << part1->first + << " for bucket " << bucket1->first << " found."; } else if (bucket1->first.getId() > bucket2->first.getId()) { - std::ostringstream ost; - ost << "Found data in partition " << part2->first - << " for bucket " << bucket2->first - << " which should not exist."; - CPPUNIT_FAIL(ost.str()); + FAIL() << "Found data in partition " << part2->first + << " for bucket " << bucket2->first + << " which should not exist."; } else if (!(bucket1->second.info == bucket2->second.info)) { - std::ostringstream ost; - ost << "Bucket " << bucket1->first << " on partition " - << part1->first << " has bucket info " - << bucket2->second.info << " and not " - << bucket1->second.info << " as expected."; - CPPUNIT_FAIL(ost.str()); + FAIL() << "Bucket " << bucket1->first << " on partition " + << part1->first << " has bucket info " + << bucket2->second.info << " and not " + << bucket1->second.info << " as expected."; } ++bucket1; ++bucket2; ++equalCount; } if (bucket1 != part1->second.end()) { - std::ostringstream ost; - ost << "No data in partition " << part1->first - << " for bucket " << bucket1->first << " found."; - CPPUNIT_FAIL(ost.str()); + FAIL() << "No data in partition " << part1->first + << " for bucket " << bucket1->first << " found."; } if (bucket2 != part2->second.end()) { - std::ostringstream ost; - ost << "Found data in partition " << part2->first - << " for bucket " << bucket2->first - << " which should not exist."; - CPPUNIT_FAIL(ost.str()); + FAIL() << "Found data in partition " << part2->first + << " for bucket " << bucket2->first + << " which should not exist."; } ++part1; ++part2; } } if (part1 != org.end() && !part1->second.empty()) { - std::ostringstream ost; - ost << "No data in partition " << part1->first << " found."; - CPPUNIT_FAIL(ost.str()); + FAIL() << "No data in partition " << part1->first << " found."; } if (part2 != existing.end() && !part2->second.empty()) { - std::ostringstream ost; - ost << "Found data in partition " << part2->first - << " which should not exist."; - CPPUNIT_FAIL(ost.str()); + FAIL() << "Found data in partition " << part2->first + << " which should not exist."; } - //std::cerr << "\n " << equalCount << " buckets were matched. "; } struct MessageCallback { public: - virtual ~MessageCallback() {} + virtual ~MessageCallback() = default; virtual void onMessage(const api::StorageMessage&) = 0; }; @@ -413,7 +323,7 @@ struct FakePersistenceLayer : public StorageLink { << "it there."; fatal(ost.str()); } else { - DiskData::const_iterator it2(it->second.find(bucket)); + auto it2 = it->second.find(bucket); if (it2 == it->second.end()) { std::ostringstream ost; ost << "Have no data for " << bucket << " on disk " << partition @@ -433,10 +343,9 @@ struct FakePersistenceLayer : public StorageLink { messageCallback->onMessage(*msg); } if (msg->getType() == api::MessageType::INTERNAL) { - api::InternalCommand& cmd( - dynamic_cast<api::InternalCommand&>(*msg)); + auto& cmd = dynamic_cast<api::InternalCommand&>(*msg); if (cmd.getType() == ReadBucketList::ID) { - ReadBucketList& rbl(dynamic_cast<ReadBucketList&>(cmd)); + auto& rbl = dynamic_cast<ReadBucketList&>(cmd); ReadBucketListReply::SP reply(new ReadBucketListReply(rbl)); std::map<PartitionId, DiskData>::const_iterator it( data.find(rbl.getPartition())); @@ -448,10 +357,8 @@ struct FakePersistenceLayer : public StorageLink { fatal(ost.str()); } else { if (cmd.getBucket().getBucketSpace() == FixedBucketSpaces::default_space()) { - for (DiskData::const_iterator it2 = it->second.begin(); - it2 != it->second.end(); ++it2) - { - reply->getBuckets().push_back(it2->first); + for (const auto& bd : it->second) { + reply->getBuckets().push_back(bd.first); } } } @@ -461,7 +368,7 @@ struct FakePersistenceLayer : public StorageLink { } sendUp(reply); } else if (cmd.getType() == ReadBucketInfo::ID) { - ReadBucketInfo& rbi(dynamic_cast<ReadBucketInfo&>(cmd)); + auto& rbi = dynamic_cast<ReadBucketInfo&>(cmd); ReadBucketInfoReply::SP reply(new ReadBucketInfoReply(rbi)); StorBucketDatabase::WrappedEntry entry( bucketDatabase.get(rbi.getBucketId(), "fakelayer")); @@ -483,8 +390,7 @@ struct FakePersistenceLayer : public StorageLink { } sendUp(reply); } else if (cmd.getType() == InternalBucketJoinCommand::ID) { - InternalBucketJoinCommand& ibj( - dynamic_cast<InternalBucketJoinCommand&>(cmd)); + auto& ibj = dynamic_cast<InternalBucketJoinCommand&>(cmd); InternalBucketJoinReply::SP reply( new InternalBucketJoinReply(ibj)); StorBucketDatabase::WrappedEntry entry( @@ -521,20 +427,14 @@ struct FakePersistenceLayer : public StorageLink { } // end of anonymous namespace -#define CPPUNIT_ASSERT_METRIC_SET(x) \ - CPPUNIT_ASSERT(initializer->getMetrics().x.getValue() > 0); - void -InitializerTest::testInitialization(InitParams& params) +InitializerTest::do_test_initialization(InitParams& params) { std::map<PartitionId, DiskData> data(buildBucketInfo(_docMan, params)); spi::PartitionStateList partitions(params.diskCount); - for (std::set<uint32_t>::const_iterator it = params.disksDown.begin(); - it != params.disksDown.end(); ++it) - { - partitions[*it] = spi::PartitionState( - spi::PartitionState::DOWN, "Set down in test"); + for (const auto& p : params.disksDown) { + partitions[p] = spi::PartitionState(spi::PartitionState::DOWN, "Set down in test"); } TestServiceLayerApp node(params.diskCount, params.nodeIndex, params.getConfig().getConfigId()); @@ -549,233 +449,32 @@ InitializerTest::testInitialization(InitParams& params) top.push_back(StorageLink::UP(bottom = new FakePersistenceLayer( data, node.getStorageBucketDatabase()))); - LOG(info, "STARTING INITIALIZATION"); + LOG(debug, "STARTING INITIALIZATION"); top.open(); - /* - FileChanger updater(config, nodeIndex, params, orgBucketDatabase); - if (params.bucketWrongDisk) updater.moveBucketWrongDisk(); - if (params.bucketMultipleDisks) updater.copyBucketWrongDisk(); - if (params.failingListRequest) { - updater.removeDirPermission(6, 'r'); - updater.removeBucketsFromDBAtPath(6); - } - if (params.failingInfoRequest) { - updater.removeFilePermission(); - orgBucketDatabase.erase(updater.getBucket(8)); - } - */ - node.waitUntilInitialized(initializer); std::map<PartitionId, DiskData> initedBucketDatabase( createMapFromBucketDatabase(node.getStorageBucketDatabase())); verifyEqual(data, initedBucketDatabase); - /* - if (params.bucketWrongDisk) { - CPPUNIT_ASSERT_METRIC_SET(_wrongDisk); - } - if (params.bucketMultipleDisks) { - CPPUNIT_ASSERT_METRIC_SET(_joinedCount); - } - */ -} - -/* -namespace { - enum State { LISTING, INFO, DONE }; - void verifyStatusContent(StorageBucketDBInitializer& initializer, - State state) - { - std::ostringstream ost; - initializer.reportStatus(ost, framework::HttpUrlPath("")); - std::string status = ost.str(); - - if (state == LISTING) { - CPPUNIT_ASSERT_CONTAIN("List phase completed: false", status); - CPPUNIT_ASSERT_CONTAIN("Initialization completed: false", status); - } else if (state == INFO) { - CPPUNIT_ASSERT_CONTAIN("List phase completed: true", status); - CPPUNIT_ASSERT_CONTAIN("Initialization completed: false", status); - } else if (state == DONE) { - CPPUNIT_ASSERT_CONTAIN("List phase completed: true", status); - CPPUNIT_ASSERT_CONTAIN("Initialization completed: true", status); - } - } -} - -void -InitializerTest::testStatusPage() -{ - // Set up surrounding system to create a single bucket for us to - // do init on. - vdstestlib::DirConfig config(getStandardConfig(true)); - uint16_t nodeIndex( - config.getConfig("stor-server").getValue("node_index", 0)); - InitParams params; - params.docsPerDisk = 1; - params.diskCount = 1; - std::map<document::BucketId, api::BucketInfo> orgBucketDatabase( - buildBucketInfo(_docMan, config, nodeIndex, 1, 1, params.disksDown)); - FileChanger updater(config, nodeIndex, params, orgBucketDatabase); - - // Set up the initializer. - DummyStorageServer server(config.getConfigId()); - DummyStorageLink top; - DummyStorageLink *bottom; - StorageBucketDBInitializer* initializer; - top.push_back(StorageLink::UP(initializer = new StorageBucketDBInitializer( - config.getConfigId(), server))); - top.push_back(StorageLink::UP(bottom = new DummyStorageLink)); - - // Grab bucket database lock for bucket to init to lock the initializer - // in the init stage - StorBucketDatabase::WrappedEntry entry( - server.getStorageBucketDatabase().get( - updater.getBucket(0), "testCommandBlocking", - StorBucketDatabase::LOCK_IF_NONEXISTING_AND_NOT_CREATING)); - // Start the initializer - top.open(); - bottom->waitForMessages(1, 30); - verifyStatusContent(*initializer, LISTING); - // Attempt to send put. Should be blocked - // Attempt to send request bucket info. Should be blocked. - // Attempt to send getNodeState. Should not be blocked. - - // Unlock bucket in bucket database so listing step can complete. - // Await read info request being sent down. - entry.unlock(); - bottom->waitForMessages(1, 30); - verifyStatusContent(*initializer, INFO); - - ReadBucketInfo& cmd(dynamic_cast<ReadBucketInfo&>(*bottom->getCommand(0))); - ReadBucketInfoReply::SP reply(new ReadBucketInfoReply(cmd)); - bottom->sendUp(reply); - - node.waitUntilInitialized(initializer); - verifyStatusContent(*initializer, DONE); - } -#define ASSERT_BLOCKED(top, bottom, blocks) \ - if (blocks) { \ - top.waitForMessages(1, 30); \ - CPPUNIT_ASSERT_EQUAL(size_t(1), top.getReplies().size()); \ - CPPUNIT_ASSERT_EQUAL(size_t(0), bottom.getCommands().size()); \ - api::StorageReply& reply(dynamic_cast<api::StorageReply&>( \ - *top.getReply(0))); \ - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::ABORTED, \ - reply.getResult().getResult()); \ - top.reset(); \ - } else { \ - bottom.waitForMessages(1, 30); \ - CPPUNIT_ASSERT_EQUAL(size_t(0), top.getReplies().size()); \ - CPPUNIT_ASSERT_EQUAL(size_t(1), bottom.getCommands().size()); \ - api::StorageCommand& command(dynamic_cast<api::StorageCommand&>( \ - *bottom.getCommand(0))); \ - (void) command; \ - bottom.reset(); \ - } - -namespace { - void verifyBlockingOn(DummyStorageLink& top, - DummyStorageLink& bottom, - bool blockEnabled) - { - // Attempt to send get. Should be blocked if block enabled - { - api::GetCommand::SP cmd(new api::GetCommand( - document::BucketId(16, 4), - document::DocumentId("userdoc:ns:4:test"), true)); - top.sendDown(cmd); - ASSERT_BLOCKED(top, bottom, blockEnabled); - } - // Attempt to send request bucket info. Should be blocked if enabled. - { - api::RequestBucketInfoCommand::SP cmd( - new api::RequestBucketInfoCommand( - 0, lib::ClusterState(""))); - top.sendDown(cmd); - ASSERT_BLOCKED(top, bottom, blockEnabled); - } - // Attempt to send getNodeState. Should not be blocked. - { - api::GetNodeStateCommand::SP cmd(new api::GetNodeStateCommand( - lib::NodeState::UP(0))); - top.sendDown(cmd); - ASSERT_BLOCKED(top, bottom, false); - } - } -} - -void -InitializerTest::testCommandBlockingDuringInit() -{ - // Set up surrounding system to create a single bucket for us to - // do init on. - vdstestlib::DirConfig config(getStandardConfig(true)); - uint16_t nodeIndex( - config.getConfig("stor-server").getValue("node_index", 0)); - InitParams params; - params.docsPerDisk = 1; - params.diskCount = 1; - std::map<document::BucketId, api::BucketInfo> orgBucketDatabase( - buildBucketInfo(_docMan, config, nodeIndex, 1, 1, params.disksDown)); - FileChanger updater(config, nodeIndex, params, orgBucketDatabase); - - // Set up the initializer. - DummyStorageServer server(config.getConfigId()); - DummyStorageLink top; - DummyStorageLink *bottom; - StorageBucketDBInitializer* initializer; - top.push_back(StorageLink::UP(initializer = new StorageBucketDBInitializer( - config.getConfigId(), server))); - top.push_back(StorageLink::UP(bottom = new DummyStorageLink)); - - // Grab bucket database lock for bucket to init to lock the initializer - // in the init stage - StorBucketDatabase::WrappedEntry entry( - server.getStorageBucketDatabase().get( - updater.getBucket(0), "testCommandBlocking", - StorBucketDatabase::LOCK_IF_NONEXISTING_AND_NOT_CREATING)); - // Start the initializer - top.open(); - verifyBlockingOn(top, *bottom, true); - // Attempt to send put. Should be blocked - // Attempt to send request bucket info. Should be blocked. - // Attempt to send getNodeState. Should not be blocked. - - // Unlock bucket in bucket database so listing step can complete. - // Await read info request being sent down. - entry.unlock(); - bottom->waitForMessages(1, 30); - dynamic_cast<ReadBucketInfo&>(*bottom->getCommand(0)); - CPPUNIT_ASSERT(!server.isInitialized()); - bottom->reset(); - - // Retry - Should now not block - verifyBlockingOn(top, *bottom, false); -} -*/ - -void -InitializerTest::testBucketProgressCalculator() -{ +TEST_F(InitializerTest, bucket_progress_calculator) { using document::BucketId; StorageBucketDBInitializer::BucketProgressCalculator calc; // We consider the given bucket as not being completed, so progress // will be _up to_, not _including_ the bucket. This means we can never // reach 1.0, so progress completion must be handled by other logic! - CPPUNIT_ASSERT_EQUAL(0.0, calc.calculateProgress(BucketId(1, 0))); - CPPUNIT_ASSERT_EQUAL(0.0, calc.calculateProgress(BucketId(32, 0))); + EXPECT_DOUBLE_EQ(0.0, calc.calculateProgress(BucketId(1, 0))); + EXPECT_DOUBLE_EQ(0.0, calc.calculateProgress(BucketId(32, 0))); - CPPUNIT_ASSERT_EQUAL(0.5, calc.calculateProgress(BucketId(1, 1))); + EXPECT_DOUBLE_EQ(0.5, calc.calculateProgress(BucketId(1, 1))); - CPPUNIT_ASSERT_EQUAL(0.25, calc.calculateProgress(BucketId(2, 2))); - CPPUNIT_ASSERT_EQUAL(0.5, calc.calculateProgress(BucketId(2, 1))); - CPPUNIT_ASSERT_EQUAL(0.75, calc.calculateProgress(BucketId(2, 3))); + EXPECT_DOUBLE_EQ(0.25, calc.calculateProgress(BucketId(2, 2))); + EXPECT_DOUBLE_EQ(0.5, calc.calculateProgress(BucketId(2, 1))); + EXPECT_DOUBLE_EQ(0.75, calc.calculateProgress(BucketId(2, 3))); - CPPUNIT_ASSERT_EQUAL(0.875, calc.calculateProgress(BucketId(3, 7))); + EXPECT_DOUBLE_EQ(0.875, calc.calculateProgress(BucketId(3, 7))); } struct DatabaseInsertCallback : MessageCallback @@ -809,7 +508,6 @@ struct DatabaseInsertCallback : MessageCallback _app.getStateUpdater().getReportedNodeState()); double progress(reportedState->getInitProgress().getValue()); LOG(debug, "reported progress is now %g", progress); - // CppUnit exceptions are swallowed... if (progress >= 1.0) { _errors << "progress exceeded 1.0: " << progress << "\n"; } @@ -835,8 +533,7 @@ struct DatabaseInsertCallback : MessageCallback } if (msg.getType() == api::MessageType::INTERNAL) { - const api::InternalCommand& cmd( - dynamic_cast<const api::InternalCommand&>(msg)); + auto& cmd = dynamic_cast<const api::InternalCommand&>(msg); if (cmd.getType() == ReadBucketInfo::ID) { if (cmd.getPriority() != _expectedReadBucketPriority) { _errors << "expected ReadBucketInfo priority of " @@ -871,9 +568,7 @@ struct DatabaseInsertCallback : MessageCallback } }; -void -InitializerTest::testBucketsInitializedByLoad() -{ +TEST_F(InitializerTest, buckets_initialized_by_load) { InitParams params; params.docsPerDisk = 100; params.diskCount = DiskCount(1); @@ -911,8 +606,8 @@ InitializerTest::testBucketsInitializedByLoad() // has been set. top.close(); - CPPUNIT_ASSERT(callback._invoked); - CPPUNIT_ASSERT_EQUAL(std::string(), callback._errors.str()); + ASSERT_TRUE(callback._invoked); + EXPECT_EQ(std::string(), callback._errors.str()); std::map<PartitionId, DiskData> initedBucketDatabase( createMapFromBucketDatabase(node.getStorageBucketDatabase())); @@ -922,11 +617,10 @@ InitializerTest::testBucketsInitializedByLoad() node.getStateUpdater().getReportedNodeState()); double progress(reportedState->getInitProgress().getValue()); - CPPUNIT_ASSERT(progress >= 1.0); - CPPUNIT_ASSERT(progress < 1.0001); + EXPECT_GE(progress, 1.0); + EXPECT_LT(progress, 1.0001); - CPPUNIT_ASSERT_EQUAL(params.bucketBitsUsed, - reportedState->getMinUsedBits()); + EXPECT_EQ(params.bucketBitsUsed, reportedState->getMinUsedBits()); } } // storage diff --git a/storage/src/tests/bucketdb/judyarraytest.cpp b/storage/src/tests/bucketdb/judyarraytest.cpp index 07992450fbf..94d61107fcf 100644 --- a/storage/src/tests/bucketdb/judyarraytest.cpp +++ b/storage/src/tests/bucketdb/judyarraytest.cpp @@ -1,36 +1,20 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/storage/bucketdb/judyarray.h> -#include <vespa/vdstestlib/cppunit/macros.h> -#include <boost/assign.hpp> #include <boost/random.hpp> -#include <cppunit/extensions/HelperMacros.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> #include <map> #include <vector> -namespace storage { - -struct JudyArrayTest : public CppUnit::TestFixture { - void testIterating(); - void testDualArrayFunctions(); - void testComparing(); - void testSize(); - void testStress(); +using namespace ::testing; - CPPUNIT_TEST_SUITE(JudyArrayTest); - CPPUNIT_TEST(testIterating); - CPPUNIT_TEST(testDualArrayFunctions); - CPPUNIT_TEST(testSize); - CPPUNIT_TEST(testStress); - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(JudyArrayTest); +namespace storage { namespace { - std::vector<std::pair<JudyArray::key_type, JudyArray::data_type> > + std::vector<std::pair<JudyArray::key_type, JudyArray::data_type>> getJudyArrayContents(const JudyArray& array) { - std::vector<std::pair<JudyArray::key_type, JudyArray::data_type> > vals; + std::vector<std::pair<JudyArray::key_type, JudyArray::data_type>> vals; for (JudyArray::const_iterator it = array.begin(); it != array.end(); ++it) { @@ -40,168 +24,129 @@ namespace { } } -void -JudyArrayTest::testIterating() -{ +TEST(JudyArrayTest, iterating) { JudyArray array; - // Test that things are sane for empty document - CPPUNIT_ASSERT_EQUAL(array.begin(), array.end()); - // Add some values - using namespace boost::assign; - std::vector<std::pair<JudyArray::key_type, JudyArray::data_type> > values - = map_list_of(3,2)(5,12)(15,8)(13,10)(7,6)(9,4); + // Test that things are sane for empty document + ASSERT_EQ(array.begin(), array.end()); + // Add some values + std::vector<std::pair<JudyArray::key_type, JudyArray::data_type>> values({ + {3, 2}, {5, 12}, {15, 8}, {13, 10}, {7, 6}, {9, 4} + }); for (uint32_t i=0; i<values.size(); ++i) { array.insert(values[i].first, values[i].second); } - // Create expected result + // Create expected result std::sort(values.begin(), values.end()); - // Test that we can iterate through const iterator - std::vector<std::pair<JudyArray::key_type, JudyArray::data_type> > - foundVals = getJudyArrayContents(array); - CPPUNIT_ASSERT_EQUAL(values, foundVals); + // Test that we can iterate through const iterator + auto foundVals = getJudyArrayContents(array); + ASSERT_EQ(values, foundVals); { // Test that we can alter through non-const iterator JudyArray::iterator it = array.begin(); ++it; ++it; it.setValue(20); - CPPUNIT_ASSERT_EQUAL((JudyArray::key_type) 7, it.key()); - CPPUNIT_ASSERT_EQUAL((JudyArray::data_type) 20, array[7]); + ASSERT_EQ((JudyArray::key_type) 7, it.key()); + ASSERT_EQ((JudyArray::data_type) 20, array[7]); it.remove(); - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 5, - getJudyArrayContents(array).size()); - CPPUNIT_ASSERT_EQUAL(array.end(), array.find(7)); + ASSERT_EQ((JudyArray::size_type) 5, getJudyArrayContents(array).size()); + ASSERT_EQ(array.end(), array.find(7)); values.erase(values.begin() + 2); - CPPUNIT_ASSERT_EQUAL(values, getJudyArrayContents(array)); - // And that we can continue iterating after removing. + ASSERT_EQ(values, getJudyArrayContents(array)); + // And that we can continue iterating after removing. ++it; - CPPUNIT_ASSERT_EQUAL((JudyArray::key_type) 9, it.key()); - CPPUNIT_ASSERT_EQUAL((JudyArray::data_type) 4, array[9]); + ASSERT_EQ((JudyArray::key_type) 9, it.key()); + ASSERT_EQ((JudyArray::data_type) 4, array[9]); } { // Test printing of iterators JudyArray::ConstIterator cit = array.begin(); - CPPUNIT_ASSERT_MATCH_REGEX( - "^ConstIterator\\(Key: 3, Valp: 0x[0-9a-f]{1,16}, Val: 2\\)$", - cit.toString()); + EXPECT_THAT(cit.toString(), MatchesRegex("^ConstIterator\\(Key: 3, Valp: 0x[0-9a-f]{1,16}, Val: 2\\)$")); JudyArray::Iterator it = array.end(); - CPPUNIT_ASSERT_MATCH_REGEX( - "^Iterator\\(Key: 0, Valp: 0\\)$", - it.toString()); + EXPECT_THAT(it.toString(), MatchesRegex("^Iterator\\(Key: 0, Valp: 0\\)$")); } } -void -JudyArrayTest::testDualArrayFunctions() -{ +TEST(JudyArrayTest, dual_array_functions) { JudyArray array1; JudyArray array2; - // Add values to array1 - using namespace boost::assign; - std::vector<std::pair<JudyArray::key_type, JudyArray::data_type> > values1 - = map_list_of(3,2)(5,12)(15,8)(13,10)(7,6)(9,4); + // Add values to array1 + std::vector<std::pair<JudyArray::key_type, JudyArray::data_type>> values1({ + {3, 2}, {5, 12}, {15, 8}, {13, 10}, {7, 6}, {9, 4} + }); for (uint32_t i=0; i<values1.size(); ++i) { array1.insert(values1[i].first, values1[i].second); } - // Add values to array2 - std::vector<std::pair<JudyArray::key_type, JudyArray::data_type> > values2 - = map_list_of(4,5)(9,40); + // Add values to array2 + std::vector<std::pair<JudyArray::key_type, JudyArray::data_type>> values2({ + {4, 5}, {9, 40} + }); for (uint32_t i=0; i<values2.size(); ++i) { array2.insert(values2[i].first, values2[i].second); } - // Create expected result + // Create expected result std::sort(values1.begin(), values1.end()); std::sort(values2.begin(), values2.end()); - CPPUNIT_ASSERT_EQUAL(values1, getJudyArrayContents(array1)); - CPPUNIT_ASSERT_EQUAL(values2, getJudyArrayContents(array2)); - CPPUNIT_ASSERT(array2 < array1); - CPPUNIT_ASSERT(array1 != array2); + EXPECT_EQ(values1, getJudyArrayContents(array1)); + EXPECT_EQ(values2, getJudyArrayContents(array2)); + EXPECT_LT(array2, array1); + EXPECT_NE(array1, array2); array1.swap(array2); - CPPUNIT_ASSERT_EQUAL(values1, getJudyArrayContents(array2)); - CPPUNIT_ASSERT_EQUAL(values2, getJudyArrayContents(array1)); - CPPUNIT_ASSERT(array1 < array2); - CPPUNIT_ASSERT(array1 != array2); + EXPECT_EQ(values1, getJudyArrayContents(array2)); + EXPECT_EQ(values2, getJudyArrayContents(array1)); + EXPECT_LT(array1, array2); + EXPECT_NE(array1, array2); - // Test some operators + // Test some operators JudyArray array3; for (uint32_t i=0; i<values1.size(); ++i) { array3.insert(values1[i].first, values1[i].second); } - CPPUNIT_ASSERT(array1 != array3); - CPPUNIT_ASSERT_EQUAL(array2, array3); - CPPUNIT_ASSERT(!(array2 < array3)); + EXPECT_NE(array1, array3); + EXPECT_EQ(array2, array3); + EXPECT_FALSE(array2 < array3); } -void -JudyArrayTest::testSize() -{ +TEST(JudyArrayTest, size) { JudyArray array; - CPPUNIT_ASSERT_EQUAL(array.begin(), array.end()); - CPPUNIT_ASSERT(array.empty()); - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 0, array.size()); - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 0, array.getMemoryUsage()); + EXPECT_EQ(array.begin(), array.end()); + EXPECT_TRUE(array.empty()); + EXPECT_EQ((JudyArray::size_type) 0, array.size()); + EXPECT_EQ((JudyArray::size_type) 0, array.getMemoryUsage()); - // Test each method one can insert stuff into array + // Test each method one can insert stuff into array array.insert(4, 3); - CPPUNIT_ASSERT_EQUAL(getJudyArrayContents(array).size(), array.size()); + EXPECT_EQ(getJudyArrayContents(array).size(), array.size()); array.insert(4, 7); - CPPUNIT_ASSERT_EQUAL(getJudyArrayContents(array).size(), array.size()); - if (sizeof(JudyArray::size_type) == 4) { - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 12, array.getMemoryUsage()); - } else if (sizeof(JudyArray::size_type) == 8) { - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 24, array.getMemoryUsage()); - } else CPPUNIT_FAIL("Unknown size of type"); + EXPECT_EQ(getJudyArrayContents(array).size(), array.size()); + EXPECT_EQ((JudyArray::size_type) 24, array.getMemoryUsage()); array[6] = 8; - CPPUNIT_ASSERT_EQUAL(getJudyArrayContents(array).size(), array.size()); + EXPECT_EQ(getJudyArrayContents(array).size(), array.size()); array[6] = 10; - CPPUNIT_ASSERT_EQUAL(getJudyArrayContents(array).size(), array.size()); - if (sizeof(JudyArray::size_type) == 4) { - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 20, array.getMemoryUsage()); - } else if (sizeof(JudyArray::size_type) == 8) { - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 40, array.getMemoryUsage()); - } else CPPUNIT_FAIL("Unknown size of type"); + EXPECT_EQ(getJudyArrayContents(array).size(), array.size()); + EXPECT_EQ((JudyArray::size_type) 40, array.getMemoryUsage()); bool preExisted; array.find(8, true, preExisted); - CPPUNIT_ASSERT_EQUAL(false, preExisted); - CPPUNIT_ASSERT_EQUAL(getJudyArrayContents(array).size(), array.size()); + EXPECT_EQ(false, preExisted); + EXPECT_EQ(getJudyArrayContents(array).size(), array.size()); array.find(8, true, preExisted); - CPPUNIT_ASSERT_EQUAL(true, preExisted); - CPPUNIT_ASSERT_EQUAL(getJudyArrayContents(array).size(), array.size()); - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 3, array.size()); - if (sizeof(JudyArray::size_type) == 4) { - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 28, array.getMemoryUsage()); - } else if (sizeof(JudyArray::size_type) == 8) { - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 56, array.getMemoryUsage()); - } else CPPUNIT_FAIL("Unknown size of type"); + EXPECT_EQ(true, preExisted); + EXPECT_EQ(getJudyArrayContents(array).size(), array.size()); + EXPECT_EQ((JudyArray::size_type) 3, array.size()); + EXPECT_EQ((JudyArray::size_type) 56, array.getMemoryUsage()); - // Test each method one can remove stuff in array with + // Test each method one can remove stuff in array with array.erase(8); - CPPUNIT_ASSERT_EQUAL(getJudyArrayContents(array).size(), array.size()); + EXPECT_EQ(getJudyArrayContents(array).size(), array.size()); array.erase(8); - CPPUNIT_ASSERT_EQUAL(getJudyArrayContents(array).size(), array.size()); - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 2, array.size()); - if (sizeof(JudyArray::size_type) == 4) { - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 20, array.getMemoryUsage()); - } else if (sizeof(JudyArray::size_type) == 8) { - CPPUNIT_ASSERT_EQUAL((JudyArray::size_type) 40, array.getMemoryUsage()); - } else CPPUNIT_FAIL("Unknown size of type"); -} - -namespace { - template<typename T> - std::string toString(const T& m) { - std::cerr << "#"; - std::ostringstream ost; - ost << m; - return ost.str(); - } + EXPECT_EQ(getJudyArrayContents(array).size(), array.size()); + EXPECT_EQ((JudyArray::size_type) 2, array.size()); + EXPECT_EQ((JudyArray::size_type) 40, array.getMemoryUsage()); } -void -JudyArrayTest::testStress() -{ +TEST(JudyArrayTest, stress) { // Do a lot of random stuff to both judy array and std::map. Ensure equal // behaviour @@ -219,9 +164,6 @@ JudyArrayTest::testStress() JudyArray::key_type value(rnd()); judyArray.insert(key, value); stdMap[key] = value; - //std::pair<StdMap::iterator, bool> result - // = stdMap.insert(std::make_pair(key, value)); - //if (!result.second) result.first->second = value; } else if (optype < 50) { // operator[] JudyArray::key_type key(rnd() % 500); JudyArray::key_type value(rnd()); @@ -229,42 +171,30 @@ JudyArrayTest::testStress() stdMap[key] = value; } else if (optype < 70) { // erase() JudyArray::key_type key(rnd() % 500); - CPPUNIT_ASSERT_EQUAL_MSG( - toString(judyArray) + toString(stdMap), - stdMap.erase(key), judyArray.erase(key)); + EXPECT_EQ(stdMap.erase(key), judyArray.erase(key)); } else if (optype < 75) { // size() - CPPUNIT_ASSERT_EQUAL_MSG( - toString(judyArray) + toString(stdMap), - stdMap.size(), judyArray.size()); + EXPECT_EQ(stdMap.size(), judyArray.size()); } else if (optype < 78) { // empty() - CPPUNIT_ASSERT_EQUAL_MSG( - toString(judyArray) + toString(stdMap), - stdMap.empty(), judyArray.empty()); + EXPECT_EQ(stdMap.empty(), judyArray.empty()); } else { // find() JudyArray::key_type key(rnd() % 500); - JudyArray::iterator it = judyArray.find(key); - StdMap::iterator it2 = stdMap.find(key); - CPPUNIT_ASSERT_EQUAL_MSG( - toString(judyArray) + toString(stdMap), - it2 == stdMap.end(), it == judyArray.end()); + auto it = judyArray.find(key); + auto it2 = stdMap.find(key); + EXPECT_EQ(it2 == stdMap.end(), it == judyArray.end()); if (it != judyArray.end()) { - CPPUNIT_ASSERT_EQUAL_MSG( - toString(judyArray) + toString(stdMap), - it.key(), it2->first); - CPPUNIT_ASSERT_EQUAL_MSG( - toString(judyArray) + toString(stdMap), - it.value(), it2->second); + EXPECT_EQ(it.key(), it2->first); + EXPECT_EQ(it.value(), it2->second); } } } - // Ensure judy array contents is equal to std::map's at this point + // Ensure judy array contents is equal to std::map's at this point StdMap tmpMap; for (JudyArray::const_iterator it = judyArray.begin(); it != judyArray.end(); ++it) { tmpMap[it.key()] = it.value(); } - CPPUNIT_ASSERT_EQUAL(stdMap, tmpMap); + EXPECT_EQ(stdMap, tmpMap); } } diff --git a/storage/src/tests/bucketdb/judymultimaptest.cpp b/storage/src/tests/bucketdb/judymultimaptest.cpp index 43b83b16dec..254dbb78b18 100644 --- a/storage/src/tests/bucketdb/judymultimaptest.cpp +++ b/storage/src/tests/bucketdb/judymultimaptest.cpp @@ -2,31 +2,15 @@ #include <vespa/storage/bucketdb/judymultimap.h> #include <vespa/storage/bucketdb/judymultimap.hpp> -#include <vespa/vdstestlib/cppunit/macros.h> -#include <boost/assign.hpp> -#include <boost/random.hpp> -#include <cppunit/extensions/HelperMacros.h> +#include <vespa/vespalib/gtest/gtest.h> #include <map> #include <ostream> #include <vector> -#include <vespa/log/log.h> -LOG_SETUP(".judy_multi_map_test"); +using namespace ::testing; namespace storage { -struct JudyMultiMapTest : public CppUnit::TestFixture { - void testSimpleUsage(); - void testIterator(); - - CPPUNIT_TEST_SUITE(JudyMultiMapTest); - CPPUNIT_TEST(testSimpleUsage); - CPPUNIT_TEST(testIterator); - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(JudyMultiMapTest); - namespace { struct B; struct C; @@ -84,48 +68,44 @@ namespace { } } -void -JudyMultiMapTest::testSimpleUsage() { +TEST(JudyMultiMapTest, simple_usage) { typedef JudyMultiMap<C, B, A> MultiMap; MultiMap multiMap; - // Do some insertions + // Do some insertions bool preExisted; - CPPUNIT_ASSERT(multiMap.empty()); + EXPECT_TRUE(multiMap.empty()); multiMap.insert(16, A(1, 2, 3), preExisted); - CPPUNIT_ASSERT_EQUAL(false, preExisted); + EXPECT_EQ(false, preExisted); multiMap.insert(11, A(4, 6, 0), preExisted); - CPPUNIT_ASSERT_EQUAL(false, preExisted); + EXPECT_EQ(false, preExisted); multiMap.insert(14, A(42, 0, 0), preExisted); - CPPUNIT_ASSERT_EQUAL(false, preExisted); - CPPUNIT_ASSERT_EQUAL_MSG(multiMap.toString(), - (MultiMap::size_type) 3, multiMap.size()); + EXPECT_EQ(false, preExisted); + EXPECT_EQ((MultiMap::size_type) 3, multiMap.size()) << multiMap.toString(); multiMap.insert(11, A(4, 7, 0), preExisted); - CPPUNIT_ASSERT_EQUAL(true, preExisted); - CPPUNIT_ASSERT_EQUAL((MultiMap::size_type) 3, multiMap.size()); - CPPUNIT_ASSERT(!multiMap.empty()); - - // Access some elements - CPPUNIT_ASSERT_EQUAL(A(4, 7, 0), multiMap[11]); - CPPUNIT_ASSERT_EQUAL(A(1, 2, 3), multiMap[16]); - CPPUNIT_ASSERT_EQUAL(A(42,0, 0), multiMap[14]); - - // Do removes - CPPUNIT_ASSERT(multiMap.erase(12) == 0); - CPPUNIT_ASSERT_EQUAL((MultiMap::size_type) 3, multiMap.size()); - - CPPUNIT_ASSERT(multiMap.erase(14) == 1); - CPPUNIT_ASSERT_EQUAL((MultiMap::size_type) 2, multiMap.size()); - - CPPUNIT_ASSERT(multiMap.erase(11) == 1); - CPPUNIT_ASSERT(multiMap.erase(16) == 1); - CPPUNIT_ASSERT_EQUAL((MultiMap::size_type) 0, multiMap.size()); - CPPUNIT_ASSERT(multiMap.empty()); + EXPECT_EQ(true, preExisted); + EXPECT_EQ((MultiMap::size_type) 3, multiMap.size()); + EXPECT_FALSE(multiMap.empty()); + + // Access some elements + EXPECT_EQ(A(4, 7, 0), multiMap[11]); + EXPECT_EQ(A(1, 2, 3), multiMap[16]); + EXPECT_EQ(A(42,0, 0), multiMap[14]); + + // Do removes + EXPECT_EQ(multiMap.erase(12), 0); + EXPECT_EQ((MultiMap::size_type) 3, multiMap.size()); + + EXPECT_EQ(multiMap.erase(14), 1); + EXPECT_EQ((MultiMap::size_type) 2, multiMap.size()); + + EXPECT_EQ(multiMap.erase(11), 1); + EXPECT_EQ(multiMap.erase(16), 1); + EXPECT_EQ((MultiMap::size_type) 0, multiMap.size()); + EXPECT_TRUE(multiMap.empty()); } -void -JudyMultiMapTest::testIterator() -{ +TEST(JudyMultiMapTest, iterator) { typedef JudyMultiMap<C, B, A> MultiMap; MultiMap multiMap; bool preExisted; @@ -135,37 +115,37 @@ JudyMultiMapTest::testIterator() multiMap.insert(14, A(42, 0, 0), preExisted); MultiMap::Iterator iter = multiMap.begin(); - CPPUNIT_ASSERT_EQUAL((uint64_t)11, (uint64_t)iter.key()); - CPPUNIT_ASSERT_EQUAL(A(4, 6, 0), iter.value()); + EXPECT_EQ((uint64_t)11, (uint64_t)iter.key()); + EXPECT_EQ(A(4, 6, 0), iter.value()); ++iter; - CPPUNIT_ASSERT_EQUAL((uint64_t)14, (uint64_t)iter.key()); - CPPUNIT_ASSERT_EQUAL(A(42, 0, 0), iter.value()); + EXPECT_EQ((uint64_t)14, (uint64_t)iter.key()); + EXPECT_EQ(A(42, 0, 0), iter.value()); ++iter; - CPPUNIT_ASSERT_EQUAL((uint64_t)16, (uint64_t)iter.key()); - CPPUNIT_ASSERT_EQUAL(A(1, 2, 3), iter.value()); + EXPECT_EQ((uint64_t)16, (uint64_t)iter.key()); + EXPECT_EQ(A(1, 2, 3), iter.value()); --iter; - CPPUNIT_ASSERT_EQUAL((uint64_t)14, (uint64_t)iter.key()); - CPPUNIT_ASSERT_EQUAL(A(42, 0, 0), iter.value()); + EXPECT_EQ((uint64_t)14, (uint64_t)iter.key()); + EXPECT_EQ(A(42, 0, 0), iter.value()); ++iter; - CPPUNIT_ASSERT_EQUAL((uint64_t)16, (uint64_t)iter.key()); - CPPUNIT_ASSERT_EQUAL(A(1, 2, 3), iter.value()); + EXPECT_EQ((uint64_t)16, (uint64_t)iter.key()); + EXPECT_EQ(A(1, 2, 3), iter.value()); --iter; --iter; - CPPUNIT_ASSERT_EQUAL((uint64_t)11,(uint64_t) iter.key()); - CPPUNIT_ASSERT_EQUAL(A(4, 6, 0), iter.value()); + EXPECT_EQ((uint64_t)11,(uint64_t) iter.key()); + EXPECT_EQ(A(4, 6, 0), iter.value()); ++iter; ++iter; ++iter; - CPPUNIT_ASSERT_EQUAL(multiMap.end(), iter); + EXPECT_EQ(multiMap.end(), iter); --iter; - CPPUNIT_ASSERT_EQUAL((uint64_t)16, (uint64_t)iter.key()); - CPPUNIT_ASSERT_EQUAL(A(1, 2, 3), iter.value()); + EXPECT_EQ((uint64_t)16, (uint64_t)iter.key()); + EXPECT_EQ(A(1, 2, 3), iter.value()); --iter; - CPPUNIT_ASSERT_EQUAL((uint64_t)14, (uint64_t)iter.key()); - CPPUNIT_ASSERT_EQUAL(A(42, 0, 0), iter.value()); + EXPECT_EQ((uint64_t)14, (uint64_t)iter.key()); + EXPECT_EQ(A(42, 0, 0), iter.value()); --iter; - CPPUNIT_ASSERT_EQUAL((uint64_t)11,(uint64_t) iter.key()); - CPPUNIT_ASSERT_EQUAL(A(4, 6, 0), iter.value()); + EXPECT_EQ((uint64_t)11,(uint64_t) iter.key()); + EXPECT_EQ(A(4, 6, 0), iter.value()); } } // storage diff --git a/storage/src/tests/bucketdb/lockablemaptest.cpp b/storage/src/tests/bucketdb/lockablemaptest.cpp index 10f806f2e97..a55e258129c 100644 --- a/storage/src/tests/bucketdb/lockablemaptest.cpp +++ b/storage/src/tests/bucketdb/lockablemaptest.cpp @@ -4,84 +4,17 @@ #include <vespa/storage/bucketdb/judymultimap.h> #include <vespa/storage/bucketdb/judymultimap.hpp> #include <vespa/storage/bucketdb/lockablemap.hpp> -#include <vespa/vdstestlib/cppunit/macros.h> -#include <cppunit/extensions/HelperMacros.h> +#include <vespa/vespalib/gtest/gtest.h> #include <boost/operators.hpp> #include <vespa/log/log.h> LOG_SETUP(".lockable_map_test"); -namespace storage { +// FIXME these old tests may have the least obvious semantics and worst naming in the entire storage module + +using namespace ::testing; -struct LockableMapTest : public CppUnit::TestFixture { - void testSimpleUsage(); - void testComparison(); - void testIterating(); - void testChunkedIterationIsTransparentAcrossChunkSizes(); - void testCanAbortDuringChunkedIteration(); - void testThreadSafetyStress(); - void testFindBuckets(); - void testFindBuckets2(); - void testFindBuckets3(); - void testFindBuckets4(); - void testFindBuckets5(); - void testFindBucketsSimple(); - void testFindNoBuckets(); - void testFindAll(); - void testFindAll2(); - void testFindAllUnusedBitIsSet(); - void testFindAllInconsistentlySplit(); - void testFindAllInconsistentlySplit2(); - void testFindAllInconsistentlySplit3(); - void testFindAllInconsistentlySplit4(); - void testFindAllInconsistentlySplit5(); - void testFindAllInconsistentlySplit6(); - void testFindAllInconsistentBelow16Bits(); - void testCreate(); - void testCreate2(); - void testCreate3(); - void testCreate4(); - void testCreate5(); - void testCreate6(); - void testCreateEmpty(); - void testIsConsistent(); - - CPPUNIT_TEST_SUITE(LockableMapTest); - CPPUNIT_TEST(testSimpleUsage); - CPPUNIT_TEST(testComparison); - CPPUNIT_TEST(testIterating); - CPPUNIT_TEST(testChunkedIterationIsTransparentAcrossChunkSizes); - CPPUNIT_TEST(testCanAbortDuringChunkedIteration); - CPPUNIT_TEST(testThreadSafetyStress); - CPPUNIT_TEST(testFindBuckets); - CPPUNIT_TEST(testFindBuckets2); - CPPUNIT_TEST(testFindBuckets3); - CPPUNIT_TEST(testFindBuckets4); - CPPUNIT_TEST(testFindBuckets5); - CPPUNIT_TEST(testFindBucketsSimple); - CPPUNIT_TEST(testFindNoBuckets); - CPPUNIT_TEST(testFindAll); - CPPUNIT_TEST(testFindAll2); - CPPUNIT_TEST(testFindAllUnusedBitIsSet); - CPPUNIT_TEST(testFindAllInconsistentlySplit); - CPPUNIT_TEST(testFindAllInconsistentlySplit2); - CPPUNIT_TEST(testFindAllInconsistentlySplit3); - CPPUNIT_TEST(testFindAllInconsistentlySplit4); - CPPUNIT_TEST(testFindAllInconsistentlySplit5); - CPPUNIT_TEST(testFindAllInconsistentlySplit6); - CPPUNIT_TEST(testFindAllInconsistentBelow16Bits); - CPPUNIT_TEST(testCreate); - CPPUNIT_TEST(testCreate2); - CPPUNIT_TEST(testCreate3); - CPPUNIT_TEST(testCreate4); - CPPUNIT_TEST(testCreate5); - CPPUNIT_TEST(testCreate6); - CPPUNIT_TEST(testCreateEmpty); - CPPUNIT_TEST(testIsConsistent); - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(LockableMapTest); +namespace storage { namespace { struct A : public boost::operators<A> { @@ -112,84 +45,81 @@ namespace { typedef LockableMap<JudyMultiMap<A> > Map; } -void -LockableMapTest::testSimpleUsage() { - // Tests insert, erase, size, empty, operator[] +TEST(LockableMapTest, simple_usage) { + // Tests insert, erase, size, empty, operator[] Map map; - // Do some insertions - CPPUNIT_ASSERT(map.empty()); + // Do some insertions + EXPECT_TRUE(map.empty()); bool preExisted; map.insert(16, A(1, 2, 3), "foo", preExisted); - CPPUNIT_ASSERT_EQUAL(false, preExisted); + EXPECT_EQ(false, preExisted); map.insert(11, A(4, 6, 0), "foo", preExisted); - CPPUNIT_ASSERT_EQUAL(false, preExisted); + EXPECT_EQ(false, preExisted); map.insert(14, A(42, 0, 0), "foo", preExisted); - CPPUNIT_ASSERT_EQUAL(false, preExisted); - CPPUNIT_ASSERT_EQUAL_MSG(map.toString(), - (Map::size_type) 3, map.size()); + EXPECT_EQ(false, preExisted); + EXPECT_EQ((Map::size_type) 3, map.size()) << map.toString(); map.insert(11, A(4, 7, 0), "foo", preExisted); - CPPUNIT_ASSERT_EQUAL(true, preExisted); - CPPUNIT_ASSERT_EQUAL((Map::size_type) 3, map.size()); - CPPUNIT_ASSERT(!map.empty()); - - // Access some elements - CPPUNIT_ASSERT_EQUAL(A(4, 7, 0), *map.get(11, "foo")); - CPPUNIT_ASSERT_EQUAL(A(1, 2, 3), *map.get(16, "foo")); - CPPUNIT_ASSERT_EQUAL(A(42,0, 0), *map.get(14, "foo")); - - // Do removes - CPPUNIT_ASSERT(map.erase(12, "foo") == 0); - CPPUNIT_ASSERT_EQUAL((Map::size_type) 3, map.size()); - - CPPUNIT_ASSERT(map.erase(14, "foo") == 1); - CPPUNIT_ASSERT_EQUAL((Map::size_type) 2, map.size()); - - CPPUNIT_ASSERT(map.erase(11, "foo") == 1); - CPPUNIT_ASSERT(map.erase(16, "foo") == 1); - CPPUNIT_ASSERT_EQUAL((Map::size_type) 0, map.size()); - CPPUNIT_ASSERT(map.empty()); + EXPECT_EQ(true, preExisted); + EXPECT_EQ((Map::size_type) 3, map.size()); + EXPECT_FALSE(map.empty()); + + // Access some elements + EXPECT_EQ(A(4, 7, 0), *map.get(11, "foo")); + EXPECT_EQ(A(1, 2, 3), *map.get(16, "foo")); + EXPECT_EQ(A(42,0, 0), *map.get(14, "foo")); + + // Do removes + EXPECT_EQ(map.erase(12, "foo"), 0); + EXPECT_EQ((Map::size_type) 3, map.size()); + + EXPECT_EQ(map.erase(14, "foo"), 1); + EXPECT_EQ((Map::size_type) 2, map.size()); + + EXPECT_EQ(map.erase(11, "foo"), 1); + EXPECT_EQ(map.erase(16, "foo"), 1); + EXPECT_EQ((Map::size_type) 0, map.size()); + EXPECT_TRUE(map.empty()); } -void -LockableMapTest::testComparison() { +TEST(LockableMapTest, comparison) { Map map1; Map map2; bool preExisted; - // Check empty state is correct - CPPUNIT_ASSERT_EQUAL(map1, map2); - CPPUNIT_ASSERT(!(map1 < map2)); - CPPUNIT_ASSERT(!(map1 != map2)); + // Check empty state is correct + EXPECT_EQ(map1, map2); + EXPECT_FALSE(map1 < map2); + EXPECT_FALSE(map1 != map2); - // Check that different lengths are oki + // Check that different lengths are ok map1.insert(4, A(1, 2, 3), "foo", preExisted); - CPPUNIT_ASSERT(!(map1 == map2)); - CPPUNIT_ASSERT(!(map1 < map2)); - CPPUNIT_ASSERT(map2 < map1); - CPPUNIT_ASSERT(map1 != map2); + EXPECT_FALSE(map1 == map2); + EXPECT_FALSE(map1 < map2); + EXPECT_LT(map2, map1); + EXPECT_NE(map1, map2); - // Check that equal elements are oki + // Check that equal elements are ok map2.insert(4, A(1, 2, 3), "foo", preExisted); - CPPUNIT_ASSERT_EQUAL(map1, map2); - CPPUNIT_ASSERT(!(map1 < map2)); - CPPUNIT_ASSERT(!(map1 != map2)); + EXPECT_EQ(map1, map2); + EXPECT_FALSE(map1 < map2); + EXPECT_FALSE(map1 != map2); - // Check that non-equal values are oki + // Check that non-equal values are ok map1.insert(6, A(1, 2, 6), "foo", preExisted); map2.insert(6, A(1, 2, 3), "foo", preExisted); - CPPUNIT_ASSERT(!(map1 == map2)); - CPPUNIT_ASSERT(!(map1 < map2)); - CPPUNIT_ASSERT(map2 < map1); - CPPUNIT_ASSERT(map1 != map2); + EXPECT_FALSE(map1 == map2); + EXPECT_FALSE(map1 < map2); + EXPECT_LT(map2, map1); + EXPECT_NE(map1, map2); - // Check that non-equal keys are oki + // Check that non-equal keys are ok map1.erase(6, "foo"); map1.insert(7, A(1, 2, 3), "foo", preExisted); - CPPUNIT_ASSERT(!(map1 == map2)); - CPPUNIT_ASSERT(!(map1 < map2)); - CPPUNIT_ASSERT(map2 < map1); - CPPUNIT_ASSERT(map1 != map2); + EXPECT_FALSE(map1 == map2); + EXPECT_FALSE(map1 < map2); + EXPECT_LT(map2, map1); + EXPECT_NE(map1, map2); } namespace { @@ -225,7 +155,9 @@ namespace { std::string toString() { std::ostringstream ost; - for (uint32_t i=0; i<log.size(); ++i) ost << log[i] << "\n"; + for (uint32_t i=0; i<log.size(); ++i) { + ost << log[i] << "\n"; + } return ost.str(); } }; @@ -234,10 +166,9 @@ namespace { EntryProcessor::EntryProcessor() : count(0), log(), behaviour() {} EntryProcessor::EntryProcessor(const std::vector<Map::Decision>& decisions) : count(0), log(), behaviour(decisions) {} -EntryProcessor::~EntryProcessor() {} +EntryProcessor::~EntryProcessor() = default; -void -LockableMapTest::testIterating() { +TEST(LockableMapTest, iterating) { Map map; bool preExisted; map.insert(16, A(1, 2, 3), "foo", preExisted); @@ -247,13 +178,13 @@ LockableMapTest::testIterating() { { NonConstProcessor ncproc; map.each(ncproc, "foo"); // Locking both for each element - CPPUNIT_ASSERT_EQUAL(A(4, 7, 0), *map.get(11, "foo")); - CPPUNIT_ASSERT_EQUAL(A(42,1, 0), *map.get(14, "foo")); - CPPUNIT_ASSERT_EQUAL(A(1, 3, 3), *map.get(16, "foo")); + EXPECT_EQ(A(4, 7, 0), *map.get(11, "foo")); + EXPECT_EQ(A(42,1, 0), *map.get(14, "foo")); + EXPECT_EQ(A(1, 3, 3), *map.get(16, "foo")); map.all(ncproc, "foo"); // And for all - CPPUNIT_ASSERT_EQUAL(A(4, 8, 0), *map.get(11, "foo")); - CPPUNIT_ASSERT_EQUAL(A(42,2, 0), *map.get(14, "foo")); - CPPUNIT_ASSERT_EQUAL(A(1, 4, 3), *map.get(16, "foo")); + EXPECT_EQ(A(4, 8, 0), *map.get(11, "foo")); + EXPECT_EQ(A(42,2, 0), *map.get(14, "foo")); + EXPECT_EQ(A(1, 4, 3), *map.get(16, "foo")); } // Test that we can use const functors directly.. map.each(EntryProcessor(), "foo"); @@ -265,12 +196,12 @@ LockableMapTest::testIterating() { std::string expected("11 - A(4, 8, 0)\n" "14 - A(42, 2, 0)\n" "16 - A(1, 4, 3)\n"); - CPPUNIT_ASSERT_EQUAL(expected, proc.toString()); + EXPECT_EQ(expected, proc.toString()); EntryProcessor proc2; map.each(proc2, "foo", 12, 15); expected = "14 - A(42, 2, 0)\n"; - CPPUNIT_ASSERT_EQUAL(expected, proc2.toString()); + EXPECT_EQ(expected, proc2.toString()); } // Test that we can abort iterating { @@ -281,7 +212,7 @@ LockableMapTest::testIterating() { map.each(proc, "foo"); std::string expected("11 - A(4, 8, 0)\n" "14 - A(42, 2, 0)\n"); - CPPUNIT_ASSERT_EQUAL(expected, proc.toString()); + EXPECT_EQ(expected, proc.toString()); } // Test that we can remove during iteration { @@ -293,19 +224,16 @@ LockableMapTest::testIterating() { std::string expected("11 - A(4, 8, 0)\n" "14 - A(42, 2, 0)\n" "16 - A(1, 4, 3)\n"); - CPPUNIT_ASSERT_EQUAL(expected, proc.toString()); - CPPUNIT_ASSERT_EQUAL_MSG(map.toString(), - (Map::size_type) 2, map.size()); - CPPUNIT_ASSERT_EQUAL(A(4, 8, 0), *map.get(11, "foo")); - CPPUNIT_ASSERT_EQUAL(A(1, 4, 3), *map.get(16, "foo")); + EXPECT_EQ(expected, proc.toString()); + EXPECT_EQ((Map::size_type) 2, map.size()) << map.toString(); + EXPECT_EQ(A(4, 8, 0), *map.get(11, "foo")); + EXPECT_EQ(A(1, 4, 3), *map.get(16, "foo")); Map::WrappedEntry entry = map.get(14, "foo"); - CPPUNIT_ASSERT(!entry.exist()); + EXPECT_FALSE(entry.exist()); } } -void -LockableMapTest::testChunkedIterationIsTransparentAcrossChunkSizes() -{ +TEST(LockableMapTest, chunked_iteration_is_transparent_across_chunk_sizes) { Map map; bool preExisted; map.insert(16, A(1, 2, 3), "foo", preExisted); @@ -314,19 +242,17 @@ LockableMapTest::testChunkedIterationIsTransparentAcrossChunkSizes() NonConstProcessor ncproc; // Increments 2nd value in all entries. // chunkedAll with chunk size of 1 map.chunkedAll(ncproc, "foo", 1); - CPPUNIT_ASSERT_EQUAL(A(4, 7, 0), *map.get(11, "foo")); - CPPUNIT_ASSERT_EQUAL(A(42, 1, 0), *map.get(14, "foo")); - CPPUNIT_ASSERT_EQUAL(A(1, 3, 3), *map.get(16, "foo")); + EXPECT_EQ(A(4, 7, 0), *map.get(11, "foo")); + EXPECT_EQ(A(42, 1, 0), *map.get(14, "foo")); + EXPECT_EQ(A(1, 3, 3), *map.get(16, "foo")); // chunkedAll with chunk size larger than db size map.chunkedAll(ncproc, "foo", 100); - CPPUNIT_ASSERT_EQUAL(A(4, 8, 0), *map.get(11, "foo")); - CPPUNIT_ASSERT_EQUAL(A(42, 2, 0), *map.get(14, "foo")); - CPPUNIT_ASSERT_EQUAL(A(1, 4, 3), *map.get(16, "foo")); + EXPECT_EQ(A(4, 8, 0), *map.get(11, "foo")); + EXPECT_EQ(A(42, 2, 0), *map.get(14, "foo")); + EXPECT_EQ(A(1, 4, 3), *map.get(16, "foo")); } -void -LockableMapTest::testCanAbortDuringChunkedIteration() -{ +TEST(LockableMapTest, can_abort_during_chunked_iteration) { Map map; bool preExisted; map.insert(16, A(1, 2, 3), "foo", preExisted); @@ -340,243 +266,10 @@ LockableMapTest::testCanAbortDuringChunkedIteration() map.chunkedAll(proc, "foo", 100); std::string expected("11 - A(4, 6, 0)\n" "14 - A(42, 0, 0)\n"); - CPPUNIT_ASSERT_EQUAL(expected, proc.toString()); + EXPECT_EQ(expected, proc.toString()); } -namespace { - struct LoadGiver : public document::Runnable { - typedef std::shared_ptr<LoadGiver> SP; - Map& _map; - uint32_t _counter; - - LoadGiver(Map& map) : _map(map), _counter(0) {} - ~LoadGiver() __attribute__((noinline)); - }; - - LoadGiver::~LoadGiver() { } - - struct InsertEraseLoadGiver : public LoadGiver { - InsertEraseLoadGiver(Map& map) : LoadGiver(map) {} - - void run() override { - // Screws up order of buckets by xor'ing with 12345. - // Only operate on last 32k super buckets. - while (running()) { - uint32_t bucket = ((_counter ^ 12345) % 0x8000) + 0x8000; - if (bucket % 7 < 3) { - bool preExisted; - _map.insert(bucket, A(bucket, 0, _counter), "foo", - preExisted); - } - if (bucket % 5 < 2) { - _map.erase(bucket, "foo"); - } - ++_counter; - } - } - }; - - struct GetLoadGiver : public LoadGiver { - GetLoadGiver(Map& map) : LoadGiver(map) {} - - void run() override { - // It's legal to keep entries as long as you only request higher - // buckets. So, to test this, keep entries until you request one - // that is smaller than those stored. - std::vector<std::pair<uint32_t, Map::WrappedEntry> > stored; - while (running()) { - uint32_t bucket = (_counter ^ 52721) % 0x10000; - if (!stored.empty() && stored.back().first > bucket) { - stored.clear(); - } - stored.push_back(std::pair<uint32_t, Map::WrappedEntry>( - bucket, _map.get(bucket, "foo", _counter % 3 == 0))); - ++_counter; - } - } - }; - - struct AllLoadGiver : public LoadGiver { - AllLoadGiver(Map& map) : LoadGiver(map) {} - - void run() override { - while (running()) { - _map.all(*this, "foo"); - ++_counter; - } - } - - Map::Decision operator()(int key, A& a) { - //std::cerr << (void*) this << " - " << key << "\n"; - (void) key; - ++a._val2; - return Map::CONTINUE; - } - }; - - struct EachLoadGiver : public LoadGiver { - EachLoadGiver(Map& map) : LoadGiver(map) {} - - void run() override { - while (running()) { - _map.each(*this, "foo"); - ++_counter; - } - } - - Map::Decision operator()(int key, A& a) { - //std::cerr << (void*) this << " - " << key << "\n"; - (void) key; - ++a._val2; - return Map::CONTINUE; - } - }; - - struct RandomRangeLoadGiver : public LoadGiver { - RandomRangeLoadGiver(Map& map) : LoadGiver(map) {} - - void run() override { - while (running()) { - uint32_t min = (_counter ^ 23426) % 0x10000; - uint32_t max = (_counter ^ 40612) % 0x10000; - if (min > max) { - uint32_t tmp = min; - min = max; - max = tmp; - } - if (_counter % 7 < 5) { - _map.each(*this, "foo", min, max); - } else { - _map.all(*this, "foo", min, max); - } - ++_counter; - } - } - - Map::Decision operator()(int key, A& a) { - //std::cerr << "."; - (void) key; - ++a._val2; - return Map::CONTINUE; - } - }; - - struct GetNextLoadGiver : public LoadGiver { - GetNextLoadGiver(Map& map) : LoadGiver(map) {} - - void run() override { - while (running()) { - uint32_t bucket = (_counter ^ 60417) % 0xffff; - if (_counter % 7 < 5) { - _map.each(*this, "foo", bucket + 1, 0xffff); - } else { - _map.all(*this, "foo", bucket + 1, 0xffff); - } - ++_counter; - } - } - - Map::Decision operator()(int key, A& a) { - //std::cerr << "."; - (void) key; - ++a._val2; - return Map::ABORT; - } - }; -} - -void -LockableMapTest::testThreadSafetyStress() { - uint32_t duration = 2 * 1000; - std::cerr << "\nRunning LockableMap threadsafety test for " - << (duration / 1000) << " seconds.\n"; - // Set up multiple threads going through the bucket database at the same - // time. Ensuring all works and there are no deadlocks. - - // Initial database of 32k elements which should always be present. - // Next 32k elements may exist (loadgivers may erase and create them, "foo") - Map map; - for (uint32_t i=0; i<65536; ++i) { - bool preExisted; - map.insert(i, A(i, 0, i ^ 12345), "foo", preExisted); - } - std::vector<LoadGiver::SP> loadgivers; - for (uint32_t i=0; i<8; ++i) { - loadgivers.push_back(LoadGiver::SP(new InsertEraseLoadGiver(map))); - } - for (uint32_t i=0; i<2; ++i) { - loadgivers.push_back(LoadGiver::SP(new GetLoadGiver(map))); - } - for (uint32_t i=0; i<2; ++i) { - loadgivers.push_back(LoadGiver::SP(new AllLoadGiver(map))); - } - for (uint32_t i=0; i<2; ++i) { - loadgivers.push_back(LoadGiver::SP(new EachLoadGiver(map))); - } - for (uint32_t i=0; i<2; ++i) { - loadgivers.push_back(LoadGiver::SP(new RandomRangeLoadGiver(map))); - } - for (uint32_t i=0; i<2; ++i) { - loadgivers.push_back(LoadGiver::SP(new GetNextLoadGiver(map))); - } - - FastOS_ThreadPool pool(128 * 1024); - for (uint32_t i=0; i<loadgivers.size(); ++i) { - CPPUNIT_ASSERT(loadgivers[i]->start(pool)); - } - FastOS_Thread::Sleep(duration); - std::cerr << "Closing down test\n"; - for (uint32_t i=0; i<loadgivers.size(); ++i) { - CPPUNIT_ASSERT(loadgivers[i]->stop()); - } -// FastOS_Thread::Sleep(duration); -// std::cerr << "Didn't manage to shut down\n"; -// map._lockedKeys.print(std::cerr, true, ""); - - for (uint32_t i=0; i<loadgivers.size(); ++i) { - CPPUNIT_ASSERT(loadgivers[i]->join()); - } - std::cerr << "Loadgiver counts:"; - for (uint32_t i=0; i<loadgivers.size(); ++i) { - std::cerr << " " << loadgivers[i]->_counter; - } - std::cerr << "\nTest completed\n"; -} - -#if 0 -namespace { -struct Hex { - document::BucketId::Type val; - - Hex(document::BucketId::Type v) : val(v) {} - bool operator==(const Hex& h) const { return val == h.val; } -}; - -std::ostream& operator<<(std::ostream& out, const Hex& h) { - out << std::hex << h.val << std::dec; - return out; -} - -void -printBucket(const std::string s, const document::BucketId& b) { - std::cerr << s << "bucket=" << b << ", reversed=" << b.stripUnused().toKey() << ", hex=" << Hex(b.stripUnused().toKey()) << "\n"; -} - -void -printBuckets(const std::map<document::BucketId, Map::WrappedEntry>& results) { - for (std::map<document::BucketId, Map::WrappedEntry>::const_iterator iter = results.begin(); - iter != results.end(); - iter++) { - printBucket("Returned ", iter->first); - } -} - -} -#endif - -void -LockableMapTest::testFindBucketsSimple() { -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_buckets_simple) { Map map; document::BucketId id1(17, 0x0ffff); @@ -594,17 +287,13 @@ LockableMapTest::testFindBucketsSimple() { map.insert(id3.toKey(), A(3,4,5), "foo", preExisted); document::BucketId id(22, 0xfffff); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getContained(id, "foo"); + auto results = map.getContained(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)1, results.size()); - CPPUNIT_ASSERT_EQUAL(A(3,4,5), *results[id3]); -#endif + EXPECT_EQ(1, results.size()); + EXPECT_EQ(A(3,4,5), *results[id3]); } -void -LockableMapTest::testFindBuckets() { -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_buckets) { Map map; document::BucketId id1(16, 0x0ffff); @@ -619,20 +308,16 @@ LockableMapTest::testFindBuckets() { map.insert(id4.stripUnused().toKey(), A(4,5,6), "foo", preExisted); document::BucketId id(22, 0xfffff); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getContained(id, "foo"); + auto results = map.getContained(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)3, results.size()); + EXPECT_EQ(3, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); - CPPUNIT_ASSERT_EQUAL(A(4,5,6), *results[id4.stripUnused()]); - CPPUNIT_ASSERT_EQUAL(A(3,4,5), *results[id3.stripUnused()]); -#endif + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); + EXPECT_EQ(A(4,5,6), *results[id4.stripUnused()]); + EXPECT_EQ(A(3,4,5), *results[id3.stripUnused()]); } -void -LockableMapTest::testFindBuckets2() { // ticket 3121525 -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_buckets_2) { // ticket 3121525 Map map; document::BucketId id1(16, 0x0ffff); @@ -647,20 +332,16 @@ LockableMapTest::testFindBuckets2() { // ticket 3121525 map.insert(id4.stripUnused().toKey(), A(4,5,6), "foo", preExisted); document::BucketId id(22, 0x1ffff); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getContained(id, "foo"); + auto results = map.getContained(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)3, results.size()); + EXPECT_EQ(3, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); - CPPUNIT_ASSERT_EQUAL(A(4,5,6), *results[id4.stripUnused()]); - CPPUNIT_ASSERT_EQUAL(A(3,4,5), *results[id3.stripUnused()]); -#endif + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); + EXPECT_EQ(A(4,5,6), *results[id4.stripUnused()]); + EXPECT_EQ(A(3,4,5), *results[id3.stripUnused()]); } -void -LockableMapTest::testFindBuckets3() { // ticket 3121525 -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_buckets_3) { // ticket 3121525 Map map; document::BucketId id1(16, 0x0ffff); @@ -671,18 +352,14 @@ LockableMapTest::testFindBuckets3() { // ticket 3121525 map.insert(id2.stripUnused().toKey(), A(2,3,4), "foo", preExisted); document::BucketId id(22, 0x1ffff); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getContained(id, "foo"); + auto results = map.getContained(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)1, results.size()); + EXPECT_EQ(1, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); -#endif + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); } -void -LockableMapTest::testFindBuckets4() { // ticket 3121525 -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_buckets_4) { // ticket 3121525 Map map; document::BucketId id1(16, 0x0ffff); @@ -695,18 +372,14 @@ LockableMapTest::testFindBuckets4() { // ticket 3121525 map.insert(id3.stripUnused().toKey(), A(3,4,5), "foo", preExisted); document::BucketId id(18, 0x1ffff); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getContained(id, "foo"); + auto results = map.getContained(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)1, results.size()); + EXPECT_EQ(1, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); -#endif + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); } -void -LockableMapTest::testFindBuckets5() { // ticket 3121525 -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_buckets_5) { // ticket 3121525 Map map; document::BucketId id1(16, 0x0ffff); @@ -719,31 +392,23 @@ LockableMapTest::testFindBuckets5() { // ticket 3121525 map.insert(id3.stripUnused().toKey(), A(3,4,5), "foo", preExisted); document::BucketId id(18, 0x1ffff); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getContained(id, "foo"); + auto results = map.getContained(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)1, results.size()); + EXPECT_EQ(1, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); -#endif + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); } -void -LockableMapTest::testFindNoBuckets() { -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_no_buckets) { Map map; document::BucketId id(16, 0x0ffff); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getAll(id, "foo"); + auto results = map.getAll(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)0, results.size()); -#endif + EXPECT_EQ(0, results.size()); } -void -LockableMapTest::testFindAll() { -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_all) { Map map; document::BucketId id1(16, 0x0aaaa); // contains id2-id7 @@ -766,45 +431,26 @@ LockableMapTest::testFindAll() { map.insert(id7.stripUnused().toKey(), A(7,8,9), "foo", preExisted); map.insert(id8.stripUnused().toKey(), A(8,9,10), "foo", preExisted); map.insert(id9.stripUnused().toKey(), A(9,10,11), "foo", preExisted); - //printBucket("Inserted ", id1); - //printBucket("Inserted ", id2); - //printBucket("Inserted ", id3); - //printBucket("Inserted ", id4); - //printBucket("Inserted ", id5); - //printBucket("Inserted ", id6); - //printBucket("Inserted ", id7); - //printBucket("Inserted ", id8); - //printBucket("Inserted ", id9); document::BucketId id(17, 0x1aaaa); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getAll(id, "foo"); - - //std::cerr << "Done: getAll() for bucket " << id << "\n"; - //printBuckets(results); + auto results = map.getAll(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)4, results.size()); + EXPECT_EQ(4, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); // super bucket - CPPUNIT_ASSERT_EQUAL(A(5,6,7), *results[id5.stripUnused()]); // most specific match (exact match) - CPPUNIT_ASSERT_EQUAL(A(6,7,8), *results[id6.stripUnused()]); // sub bucket - CPPUNIT_ASSERT_EQUAL(A(7,8,9), *results[id7.stripUnused()]); // sub bucket + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); // super bucket + EXPECT_EQ(A(5,6,7), *results[id5.stripUnused()]); // most specific match (exact match) + EXPECT_EQ(A(6,7,8), *results[id6.stripUnused()]); // sub bucket + EXPECT_EQ(A(7,8,9), *results[id7.stripUnused()]); // sub bucket id = document::BucketId(16, 0xffff); results = map.getAll(id, "foo"); - //std::cerr << "Done: getAll() for bucket " << id << "\n"; - //printBuckets(results); + EXPECT_EQ(1, results.size()); - CPPUNIT_ASSERT_EQUAL((size_t)1, results.size()); - - CPPUNIT_ASSERT_EQUAL(A(9,10,11), *results[id9.stripUnused()]); // sub bucket -#endif + EXPECT_EQ(A(9,10,11), *results[id9.stripUnused()]); // sub bucket } -void -LockableMapTest::testFindAll2() { // Ticket 3121525 -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_all_2) { // Ticket 3121525 Map map; document::BucketId id1(17, 0x00001); @@ -815,19 +461,15 @@ LockableMapTest::testFindAll2() { // Ticket 3121525 map.insert(id2.stripUnused().toKey(), A(2,3,4), "foo", preExisted); document::BucketId id(16, 0x00001); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getAll(id, "foo"); + auto results = map.getAll(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)2, results.size()); + EXPECT_EQ(2, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); // sub bucket - CPPUNIT_ASSERT_EQUAL(A(2,3,4), *results[id2.stripUnused()]); // sub bucket -#endif + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); // sub bucket + EXPECT_EQ(A(2,3,4), *results[id2.stripUnused()]); // sub bucket } -void -LockableMapTest::testFindAllUnusedBitIsSet() { // ticket 2938896 -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_all_unused_bit_is_set) { // ticket 2938896 Map map; document::BucketId id1(24, 0x000dc7089); @@ -843,19 +485,15 @@ LockableMapTest::testFindAllUnusedBitIsSet() { // ticket 2938896 document::BucketId id(33, 0x1053c7089); id.setUsedBits(32); // Bit 33 is set, but unused - std::map<document::BucketId, Map::WrappedEntry> results = - map.getAll(id, "foo"); + auto results = map.getAll(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)2, results.size()); + EXPECT_EQ(2, results.size()); - CPPUNIT_ASSERT_EQUAL(A(2,3,4), *results[id2.stripUnused()]); // sub bucket - CPPUNIT_ASSERT_EQUAL(A(3,4,5), *results[id3.stripUnused()]); // sub bucket -#endif + EXPECT_EQ(A(2,3,4), *results[id2.stripUnused()]); // sub bucket + EXPECT_EQ(A(3,4,5), *results[id3.stripUnused()]); // sub bucket } -void -LockableMapTest::testFindAllInconsistentlySplit() { // Ticket 2938896 -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_all_inconsistently_split) { // Ticket 2938896 Map map; document::BucketId id1(16, 0x00001); // contains id2-id3 @@ -868,20 +506,16 @@ LockableMapTest::testFindAllInconsistentlySplit() { // Ticket 2938896 map.insert(id3.stripUnused().toKey(), A(3,4,5), "foo", preExisted); document::BucketId id(16, 0x00001); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getAll(id, "foo"); + auto results = map.getAll(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)3, results.size()); + EXPECT_EQ(3, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); // most specific match (exact match) - CPPUNIT_ASSERT_EQUAL(A(2,3,4), *results[id2.stripUnused()]); // sub bucket - CPPUNIT_ASSERT_EQUAL(A(3,4,5), *results[id3.stripUnused()]); // sub bucket -#endif + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); // most specific match (exact match) + EXPECT_EQ(A(2,3,4), *results[id2.stripUnused()]); // sub bucket + EXPECT_EQ(A(3,4,5), *results[id3.stripUnused()]); // sub bucket } -void -LockableMapTest::testFindAllInconsistentlySplit2() { // ticket 3121525 -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_all_inconsistently_split_2) { // ticket 3121525 Map map; document::BucketId id1(17, 0x10000); @@ -896,19 +530,15 @@ LockableMapTest::testFindAllInconsistentlySplit2() { // ticket 3121525 map.insert(id4.stripUnused().toKey(), A(4,5,6), "foo", preExisted); document::BucketId id(32, 0x027228034); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getAll(id, "foo"); + auto results = map.getAll(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)2, results.size()); + EXPECT_EQ(2, results.size()); - CPPUNIT_ASSERT_EQUAL(A(2,3,4), *results[id2.stripUnused()]); // super bucket - CPPUNIT_ASSERT_EQUAL(A(3,4,5), *results[id3.stripUnused()]); // most specific match (super bucket) -#endif + EXPECT_EQ(A(2,3,4), *results[id2.stripUnused()]); // super bucket + EXPECT_EQ(A(3,4,5), *results[id3.stripUnused()]); // most specific match (super bucket) } -void -LockableMapTest::testFindAllInconsistentlySplit3() { // ticket 3121525 -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_all_inconsistently_split_3) { // ticket 3121525 Map map; document::BucketId id1(16, 0x0ffff); // contains id2 @@ -919,18 +549,14 @@ LockableMapTest::testFindAllInconsistentlySplit3() { // ticket 3121525 map.insert(id2.stripUnused().toKey(), A(2,3,4), "foo", preExisted); document::BucketId id(22, 0x1ffff); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getAll(id, "foo"); + auto results = map.getAll(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)1, results.size()); + EXPECT_EQ(1, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); // super bucket -#endif + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); // super bucket } -void -LockableMapTest::testFindAllInconsistentlySplit4() { // ticket 3121525 -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_all_inconsistently_split_4) { // ticket 3121525 Map map; document::BucketId id1(16, 0x0ffff); // contains id2-id3 @@ -943,19 +569,15 @@ LockableMapTest::testFindAllInconsistentlySplit4() { // ticket 3121525 map.insert(id3.stripUnused().toKey(), A(3,4,5), "foo", preExisted); document::BucketId id(18, 0x1ffff); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getAll(id, "foo"); + auto results = map.getAll(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)2, results.size()); + EXPECT_EQ(2, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); // super bucket - CPPUNIT_ASSERT_EQUAL(A(3,4,5), *results[id3.stripUnused()]); // sub bucket -#endif + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); // super bucket + EXPECT_EQ(A(3,4,5), *results[id3.stripUnused()]); // sub bucket } -void -LockableMapTest::testFindAllInconsistentlySplit5() { // ticket 3121525 -#if __WORDSIZE == 64 +TEST(LockableMapTest, find_all_inconsistently_split_5) { // ticket 3121525 Map map; document::BucketId id1(16, 0x0ffff); // contains id2-id3 @@ -968,18 +590,15 @@ LockableMapTest::testFindAllInconsistentlySplit5() { // ticket 3121525 map.insert(id3.stripUnused().toKey(), A(3,4,5), "foo", preExisted); document::BucketId id(18, 0x1ffff); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getAll(id, "foo"); + auto results = map.getAll(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)2, results.size()); + EXPECT_EQ(2, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); // super bucket - CPPUNIT_ASSERT_EQUAL(A(3,4,5), *results[id3.stripUnused()]); // sub bucket -#endif + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); // super bucket + EXPECT_EQ(A(3,4,5), *results[id3.stripUnused()]); // sub bucket } -void -LockableMapTest::testFindAllInconsistentlySplit6() { +TEST(LockableMapTest, find_all_inconsistently_split_6) { Map map; document::BucketId id1(16, 0x0ffff); // contains id2-id3 @@ -992,18 +611,15 @@ LockableMapTest::testFindAllInconsistentlySplit6() { map.insert(id3.stripUnused().toKey(), A(3,4,5), "foo", preExisted); document::BucketId id(18, 0x3ffff); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getAll(id, "foo"); + auto results = map.getAll(id, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)2, results.size()); + EXPECT_EQ(2, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); // super bucket - CPPUNIT_ASSERT_EQUAL(A(3,4,5), *results[id3.stripUnused()]); // sub bucket + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); // super bucket + EXPECT_EQ(A(3,4,5), *results[id3.stripUnused()]); // sub bucket } -void -LockableMapTest::testFindAllInconsistentBelow16Bits() -{ +TEST(LockableMapTest, find_all_inconsistent_below_16_bits) { Map map; document::BucketId id1(1, 0x1); // contains id2-id3 @@ -1017,50 +633,40 @@ LockableMapTest::testFindAllInconsistentBelow16Bits() document::BucketId id(3, 0x5); - std::map<document::BucketId, Map::WrappedEntry> results = - map.getAll(id, "foo"); + auto results = map.getAll(id, "foo"); - CPPUNIT_ASSERT_EQUAL(size_t(2), results.size()); + EXPECT_EQ(2, results.size()); - CPPUNIT_ASSERT_EQUAL(A(1,2,3), *results[id1.stripUnused()]); // super bucket - CPPUNIT_ASSERT_EQUAL(A(3,4,5), *results[id3.stripUnused()]); // sub bucket + EXPECT_EQ(A(1,2,3), *results[id1.stripUnused()]); // super bucket + EXPECT_EQ(A(3,4,5), *results[id3.stripUnused()]); // sub bucket } -void -LockableMapTest::testCreate() { -#if __WORDSIZE == 64 +TEST(LockableMapTest, create) { Map map; { document::BucketId id1(58, 0x43d6c878000004d2ull); - std::map<document::BucketId, Map::WrappedEntry> entries( - map.getContained(id1, "foo")); + auto entries = map.getContained(id1, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)0, entries.size()); + EXPECT_EQ(0, entries.size()); Map::WrappedEntry entry = map.createAppropriateBucket(36, "", id1); - CPPUNIT_ASSERT_EQUAL(document::BucketId(36,0x8000004d2ull), - entry.getBucketId()); + EXPECT_EQ(document::BucketId(36,0x8000004d2ull), entry.getBucketId()); } { document::BucketId id1(58, 0x423bf1e0000004d2ull); - std::map<document::BucketId, Map::WrappedEntry> entries( - map.getContained(id1, "foo")); - CPPUNIT_ASSERT_EQUAL((size_t)0, entries.size()); + auto entries = map.getContained(id1, "foo"); + EXPECT_EQ(0, entries.size()); Map::WrappedEntry entry = map.createAppropriateBucket(36, "", id1); - CPPUNIT_ASSERT_EQUAL(document::BucketId(36,0x0000004d2ull), - entry.getBucketId()); + EXPECT_EQ(document::BucketId(36,0x0000004d2ull), entry.getBucketId()); } - CPPUNIT_ASSERT_EQUAL((size_t)2, map.size()); -#endif + EXPECT_EQ(2, map.size()); } -void -LockableMapTest::testCreate2() { -#if __WORDSIZE == 64 +TEST(LockableMapTest, create_2) { Map map; { document::BucketId id1(58, 0xeaf77782000004d2); @@ -1069,24 +675,19 @@ LockableMapTest::testCreate2() { } { document::BucketId id1(58, 0x00000000000004d2); - std::map<document::BucketId, Map::WrappedEntry> entries( - map.getContained(id1, "foo")); + auto entries = map.getContained(id1, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)0, entries.size()); + EXPECT_EQ(0, entries.size()); Map::WrappedEntry entry = map.createAppropriateBucket(16, "", id1); - CPPUNIT_ASSERT_EQUAL(document::BucketId(34, 0x0000004d2ull), - entry.getBucketId()); + EXPECT_EQ(document::BucketId(34, 0x0000004d2ull), entry.getBucketId()); } - CPPUNIT_ASSERT_EQUAL((size_t)2, map.size()); -#endif + EXPECT_EQ(2, map.size()); } -void -LockableMapTest::testCreate3() { -#if __WORDSIZE == 64 +TEST(LockableMapTest, create_3) { Map map; { document::BucketId id1(58, 0xeaf77780000004d2); @@ -1100,21 +701,16 @@ LockableMapTest::testCreate3() { } { document::BucketId id1(58, 0x00000000000004d2); - std::map<document::BucketId, Map::WrappedEntry> entries( - map.getContained(id1, "foo")); + auto entries = map.getContained(id1, "foo"); - CPPUNIT_ASSERT_EQUAL((size_t)0, entries.size()); + EXPECT_EQ(0, entries.size()); Map::WrappedEntry entry = map.createAppropriateBucket(16, "", id1); - CPPUNIT_ASSERT_EQUAL(document::BucketId(40, 0x0000004d2ull), - entry.getBucketId()); + EXPECT_EQ(document::BucketId(40, 0x0000004d2ull), entry.getBucketId()); } -#endif } -void -LockableMapTest::testCreate4() { -#if __WORDSIZE == 64 +TEST(LockableMapTest, create_4) { Map map; { document::BucketId id1(16, 0x00000000000004d1); @@ -1130,15 +726,11 @@ LockableMapTest::testCreate4() { document::BucketId id1(58, 0x00000000010004d2); Map::WrappedEntry entry = map.createAppropriateBucket(16, "", id1); - CPPUNIT_ASSERT_EQUAL(document::BucketId(25, 0x0010004d2ull), - entry.getBucketId()); + EXPECT_EQ(document::BucketId(25, 0x0010004d2ull), entry.getBucketId()); } -#endif } -void -LockableMapTest::testCreate6() { -#if __WORDSIZE == 64 +TEST(LockableMapTest, create_5) { Map map; { document::BucketId id1(0x8c000000000004d2); @@ -1165,16 +757,11 @@ LockableMapTest::testCreate6() { { document::BucketId id1(0xe9944a44000004d2); Map::WrappedEntry entry = map.createAppropriateBucket(16, "", id1); - CPPUNIT_ASSERT_EQUAL(document::BucketId(0x90000004000004d2), - entry.getBucketId()); + EXPECT_EQ(document::BucketId(0x90000004000004d2), entry.getBucketId()); } -#endif } - -void -LockableMapTest::testCreate5() { -#if __WORDSIZE == 64 +TEST(LockableMapTest, create_6) { Map map; { document::BucketId id1(58, 0xeaf77780000004d2); @@ -1190,28 +777,20 @@ LockableMapTest::testCreate5() { { document::BucketId id1(58, 0x00000000010004d2); Map::WrappedEntry entry = map.createAppropriateBucket(16, "", id1); - CPPUNIT_ASSERT_EQUAL(document::BucketId(25, 0x0010004d2ull), - entry.getBucketId()); + EXPECT_EQ(document::BucketId(25, 0x0010004d2ull), entry.getBucketId()); } -#endif } -void -LockableMapTest::testCreateEmpty() { -#if __WORDSIZE == 64 +TEST(LockableMapTest, create_empty) { Map map; { document::BucketId id1(58, 0x00000000010004d2); Map::WrappedEntry entry = map.createAppropriateBucket(16, "", id1); - CPPUNIT_ASSERT_EQUAL(document::BucketId(16, 0x0000004d2ull), - entry.getBucketId()); + EXPECT_EQ(document::BucketId(16, 0x0000004d2ull), entry.getBucketId()); } -#endif } -void -LockableMapTest::testIsConsistent() -{ +TEST(LockableMapTest, is_consistent) { Map map; document::BucketId id1(16, 0x00001); // contains id2-id3 document::BucketId id2(17, 0x00001); @@ -1221,13 +800,13 @@ LockableMapTest::testIsConsistent() { Map::WrappedEntry entry( map.get(id1.stripUnused().toKey(), "foo", true)); - CPPUNIT_ASSERT(map.isConsistent(entry)); + EXPECT_TRUE(map.isConsistent(entry)); } map.insert(id2.stripUnused().toKey(), A(1,2,3), "foo", preExisted); { Map::WrappedEntry entry( map.get(id1.stripUnused().toKey(), "foo", true)); - CPPUNIT_ASSERT(!map.isConsistent(entry)); + EXPECT_FALSE(map.isConsistent(entry)); } } |