diff options
Diffstat (limited to 'storage/src/tests/visiting')
-rw-r--r-- | storage/src/tests/visiting/CMakeLists.txt | 10 | ||||
-rw-r--r-- | storage/src/tests/visiting/commandqueuetest.cpp | 199 | ||||
-rw-r--r-- | storage/src/tests/visiting/memory_bounded_trace_test.cpp | 108 | ||||
-rw-r--r-- | storage/src/tests/visiting/visitormanagertest.cpp | 508 | ||||
-rw-r--r-- | storage/src/tests/visiting/visitortest.cpp | 518 |
5 files changed, 578 insertions, 765 deletions
diff --git a/storage/src/tests/visiting/CMakeLists.txt b/storage/src/tests/visiting/CMakeLists.txt index 438086fddd3..c1b19960cea 100644 --- a/storage/src/tests/visiting/CMakeLists.txt +++ b/storage/src/tests/visiting/CMakeLists.txt @@ -1,19 +1,11 @@ # Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -# TODO: Remove test library when all tests have been migrated to gtest. -vespa_add_library(storage_testvisiting TEST +vespa_add_executable(storage_visiting_gtest_runner_app TEST SOURCES commandqueuetest.cpp memory_bounded_trace_test.cpp visitormanagertest.cpp visitortest.cpp - DEPENDS - storage - storage_teststorageserver -) - -vespa_add_executable(storage_visiting_gtest_runner_app TEST - SOURCES gtest_runner.cpp DEPENDS storage diff --git a/storage/src/tests/visiting/commandqueuetest.cpp b/storage/src/tests/visiting/commandqueuetest.cpp index e335df353f6..c152e4c5191 100644 --- a/storage/src/tests/visiting/commandqueuetest.cpp +++ b/storage/src/tests/visiting/commandqueuetest.cpp @@ -3,62 +3,44 @@ #include <vespa/storageframework/defaultimplementation/clock/fakeclock.h> #include <vespa/storage/visiting/commandqueue.h> #include <vespa/storageapi/message/visitor.h> -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/vespalib/stllike/asciistream.h> #include <vespa/document/test/make_bucket_space.h> - +#include <vespa/vespalib/gtest/gtest.h> using vespalib::string; using document::test::makeBucketSpace; +using namespace ::testing; namespace storage { -struct CommandQueueTest : public CppUnit::TestFixture -{ - void testFIFO(); - void testFIFOWithPriorities(); - void testReleaseOldest(); - void testReleaseLowestPriority(); - void testDeleteIterator(); - - CPPUNIT_TEST_SUITE(CommandQueueTest); - CPPUNIT_TEST(testFIFO); - CPPUNIT_TEST(testFIFOWithPriorities); - CPPUNIT_TEST(testReleaseOldest); - CPPUNIT_TEST(testReleaseLowestPriority); - CPPUNIT_TEST(testDeleteIterator); - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(CommandQueueTest); - namespace { - std::shared_ptr<api::CreateVisitorCommand> getCommand( - vespalib::stringref name, int timeout, - uint8_t priority = 0) - { - vespalib::asciistream ost; - ost << name << " t=" << timeout << " p=" << static_cast<unsigned int>(priority); - // Piggyback name in document selection - std::shared_ptr<api::CreateVisitorCommand> cmd( - new api::CreateVisitorCommand(makeBucketSpace(), "", "", ost.str())); - cmd->setQueueTimeout(timeout); - cmd->setPriority(priority); - return cmd; - } - const vespalib::string & - getCommandString(const std::shared_ptr<api::CreateVisitorCommand>& cmd) - { - return cmd->getDocumentSelection(); - } +std::shared_ptr<api::CreateVisitorCommand> getCommand( + vespalib::stringref name, int timeout, + uint8_t priority = 0) +{ + vespalib::asciistream ost; + ost << name << " t=" << timeout << " p=" << static_cast<unsigned int>(priority); + // Piggyback name in document selection + std::shared_ptr<api::CreateVisitorCommand> cmd( + new api::CreateVisitorCommand(makeBucketSpace(), "", "", ost.str())); + cmd->setQueueTimeout(timeout); + cmd->setPriority(priority); + return cmd; +} +const vespalib::string & +getCommandString(const std::shared_ptr<api::CreateVisitorCommand>& cmd) +{ + return cmd->getDocumentSelection(); } -void CommandQueueTest::testFIFO() { +} + +TEST(CommandQueueTest, fifo) { framework::defaultimplementation::FakeClock clock; CommandQueue<api::CreateVisitorCommand> queue(clock); - CPPUNIT_ASSERT(queue.empty()); + ASSERT_TRUE(queue.empty()); // Use all default priorities, meaning what comes out should be in the same order // as what went in queue.add(getCommand("first", 1)); @@ -69,64 +51,66 @@ void CommandQueueTest::testFIFO() { queue.add(getCommand("sixth", 14)); queue.add(getCommand("seventh", 7)); - CPPUNIT_ASSERT(!queue.empty()); - std::vector<std::shared_ptr<api::CreateVisitorCommand> > commands; + ASSERT_FALSE(queue.empty()); + std::vector<std::shared_ptr<api::CreateVisitorCommand>> commands; for (;;) { std::shared_ptr<api::CreateVisitorCommand> cmd( queue.releaseNextCommand().first); if (cmd.get() == 0) break; commands.push_back(cmd); } - CPPUNIT_ASSERT_EQUAL(size_t(7), commands.size()); - CPPUNIT_ASSERT_EQUAL(string("first t=1 p=0"), getCommandString(commands[0])); - CPPUNIT_ASSERT_EQUAL(string("second t=10 p=0"), getCommandString(commands[1])); - CPPUNIT_ASSERT_EQUAL(string("third t=5 p=0"), getCommandString(commands[2])); - CPPUNIT_ASSERT_EQUAL(string("fourth t=0 p=0"), getCommandString(commands[3])); - CPPUNIT_ASSERT_EQUAL(string("fifth t=3 p=0"), getCommandString(commands[4])); - CPPUNIT_ASSERT_EQUAL(string("sixth t=14 p=0"), getCommandString(commands[5])); - CPPUNIT_ASSERT_EQUAL(string("seventh t=7 p=0"), getCommandString(commands[6])); + ASSERT_EQ(7, commands.size()); + EXPECT_EQ("first t=1 p=0", getCommandString(commands[0])); + EXPECT_EQ("second t=10 p=0", getCommandString(commands[1])); + EXPECT_EQ("third t=5 p=0", getCommandString(commands[2])); + EXPECT_EQ("fourth t=0 p=0", getCommandString(commands[3])); + EXPECT_EQ("fifth t=3 p=0", getCommandString(commands[4])); + EXPECT_EQ("sixth t=14 p=0", getCommandString(commands[5])); + EXPECT_EQ("seventh t=7 p=0", getCommandString(commands[6])); } -void CommandQueueTest::testFIFOWithPriorities() { +TEST(CommandQueueTest, fifo_with_priorities) { framework::defaultimplementation::FakeClock clock; CommandQueue<api::CreateVisitorCommand> queue(clock); - CPPUNIT_ASSERT(queue.empty()); + ASSERT_TRUE(queue.empty()); queue.add(getCommand("first", 1, 10)); - CPPUNIT_ASSERT_EQUAL(string("first t=1 p=10"), getCommandString(queue.peekLowestPriorityCommand())); + EXPECT_EQ("first t=1 p=10", getCommandString(queue.peekLowestPriorityCommand())); queue.add(getCommand("second", 10, 22)); queue.add(getCommand("third", 5, 9)); - CPPUNIT_ASSERT_EQUAL(string("second t=10 p=22"), getCommandString(queue.peekLowestPriorityCommand())); + EXPECT_EQ("second t=10 p=22", getCommandString(queue.peekLowestPriorityCommand())); queue.add(getCommand("fourth", 0, 22)); queue.add(getCommand("fifth", 3, 22)); - CPPUNIT_ASSERT_EQUAL(string("fifth t=3 p=22"), getCommandString(queue.peekLowestPriorityCommand())); + EXPECT_EQ("fifth t=3 p=22", getCommandString(queue.peekLowestPriorityCommand())); queue.add(getCommand("sixth", 14, 50)); queue.add(getCommand("seventh", 7, 0)); - CPPUNIT_ASSERT_EQUAL(string("sixth t=14 p=50"), getCommandString(queue.peekLowestPriorityCommand())); + EXPECT_EQ("sixth t=14 p=50", getCommandString(queue.peekLowestPriorityCommand())); - CPPUNIT_ASSERT(!queue.empty()); - std::vector<std::shared_ptr<api::CreateVisitorCommand> > commands; + ASSERT_FALSE(queue.empty()); + std::vector<std::shared_ptr<api::CreateVisitorCommand>> commands; for (;;) { std::shared_ptr<api::CreateVisitorCommand> cmdPeek(queue.peekNextCommand()); std::shared_ptr<api::CreateVisitorCommand> cmd(queue.releaseNextCommand().first); - if (cmd.get() == 0 || cmdPeek != cmd) break; + if (cmd.get() == 0 || cmdPeek != cmd) { + break; + } commands.push_back(cmd); } - CPPUNIT_ASSERT_EQUAL(size_t(7), commands.size()); - CPPUNIT_ASSERT_EQUAL(string("seventh t=7 p=0"), getCommandString(commands[0])); - CPPUNIT_ASSERT_EQUAL(string("third t=5 p=9"), getCommandString(commands[1])); - CPPUNIT_ASSERT_EQUAL(string("first t=1 p=10"), getCommandString(commands[2])); - CPPUNIT_ASSERT_EQUAL(string("second t=10 p=22"), getCommandString(commands[3])); - CPPUNIT_ASSERT_EQUAL(string("fourth t=0 p=22"), getCommandString(commands[4])); - CPPUNIT_ASSERT_EQUAL(string("fifth t=3 p=22"), getCommandString(commands[5])); - CPPUNIT_ASSERT_EQUAL(string("sixth t=14 p=50"), getCommandString(commands[6])); + ASSERT_EQ(7, commands.size()); + EXPECT_EQ("seventh t=7 p=0", getCommandString(commands[0])); + EXPECT_EQ("third t=5 p=9", getCommandString(commands[1])); + EXPECT_EQ("first t=1 p=10", getCommandString(commands[2])); + EXPECT_EQ("second t=10 p=22", getCommandString(commands[3])); + EXPECT_EQ("fourth t=0 p=22", getCommandString(commands[4])); + EXPECT_EQ("fifth t=3 p=22", getCommandString(commands[5])); + EXPECT_EQ("sixth t=14 p=50", getCommandString(commands[6])); } -void CommandQueueTest::testReleaseOldest() { +TEST(CommandQueueTest, release_oldest) { framework::defaultimplementation::FakeClock clock(framework::defaultimplementation::FakeClock::FAKE_ABSOLUTE); CommandQueue<api::CreateVisitorCommand> queue(clock); - CPPUNIT_ASSERT(queue.empty()); + ASSERT_TRUE(queue.empty()); queue.add(getCommand("first", 10)); queue.add(getCommand("second", 100)); queue.add(getCommand("third", 1000)); @@ -134,32 +118,31 @@ void CommandQueueTest::testReleaseOldest() { queue.add(getCommand("fifth", 3000)); queue.add(getCommand("sixth", 400)); queue.add(getCommand("seventh", 700)); - CPPUNIT_ASSERT_EQUAL(7u, queue.size()); + ASSERT_EQ(7u, queue.size()); - typedef CommandQueue<api::CreateVisitorCommand>::CommandEntry CommandEntry; + using CommandEntry = CommandQueue<api::CreateVisitorCommand>::CommandEntry; std::list<CommandEntry> timedOut(queue.releaseTimedOut()); - CPPUNIT_ASSERT(timedOut.empty()); + ASSERT_TRUE(timedOut.empty()); clock.addMilliSecondsToTime(400 * 1000); timedOut = queue.releaseTimedOut(); - CPPUNIT_ASSERT_EQUAL(size_t(4), timedOut.size()); + ASSERT_EQ(4, timedOut.size()); std::ostringstream ost; for (std::list<CommandEntry>::const_iterator it = timedOut.begin(); it != timedOut.end(); ++it) { ost << getCommandString(it->_command) << "\n"; } - CPPUNIT_ASSERT_EQUAL(std::string( - "fourth t=5 p=0\n" - "first t=10 p=0\n" - "second t=100 p=0\n" - "sixth t=400 p=0\n"), ost.str()); - CPPUNIT_ASSERT_EQUAL(3u, queue.size()); + EXPECT_EQ("fourth t=5 p=0\n" + "first t=10 p=0\n" + "second t=100 p=0\n" + "sixth t=400 p=0\n", ost.str()); + EXPECT_EQ(3u, queue.size()); } -void CommandQueueTest::testReleaseLowestPriority() { +TEST(CommandQueueTest, release_lowest_priority) { framework::defaultimplementation::FakeClock clock; CommandQueue<api::CreateVisitorCommand> queue(clock); - CPPUNIT_ASSERT(queue.empty()); + ASSERT_TRUE(queue.empty()); queue.add(getCommand("first", 1, 10)); queue.add(getCommand("second", 10, 22)); @@ -168,30 +151,32 @@ void CommandQueueTest::testReleaseLowestPriority() { queue.add(getCommand("fifth", 3, 22)); queue.add(getCommand("sixth", 14, 50)); queue.add(getCommand("seventh", 7, 0)); - CPPUNIT_ASSERT_EQUAL(7u, queue.size()); + ASSERT_EQ(7u, queue.size()); - std::vector<std::shared_ptr<api::CreateVisitorCommand> > commands; + std::vector<std::shared_ptr<api::CreateVisitorCommand>> commands; for (;;) { std::shared_ptr<api::CreateVisitorCommand> cmdPeek(queue.peekLowestPriorityCommand()); std::pair<std::shared_ptr<api::CreateVisitorCommand>, uint64_t> cmd( queue.releaseLowestPriorityCommand()); - if (cmd.first.get() == 0 || cmdPeek != cmd.first) break; + if (cmd.first.get() == 0 || cmdPeek != cmd.first) { + break; + } commands.push_back(cmd.first); } - CPPUNIT_ASSERT_EQUAL(size_t(7), commands.size()); - CPPUNIT_ASSERT_EQUAL(string("sixth t=14 p=50"), getCommandString(commands[0])); - CPPUNIT_ASSERT_EQUAL(string("fifth t=3 p=22"), getCommandString(commands[1])); - CPPUNIT_ASSERT_EQUAL(string("fourth t=0 p=22"), getCommandString(commands[2])); - CPPUNIT_ASSERT_EQUAL(string("second t=10 p=22"), getCommandString(commands[3])); - CPPUNIT_ASSERT_EQUAL(string("first t=1 p=10"), getCommandString(commands[4])); - CPPUNIT_ASSERT_EQUAL(string("third t=5 p=9"), getCommandString(commands[5])); - CPPUNIT_ASSERT_EQUAL(string("seventh t=7 p=0"), getCommandString(commands[6])); + ASSERT_EQ(7, commands.size()); + EXPECT_EQ("sixth t=14 p=50", getCommandString(commands[0])); + EXPECT_EQ("fifth t=3 p=22", getCommandString(commands[1])); + EXPECT_EQ("fourth t=0 p=22", getCommandString(commands[2])); + EXPECT_EQ("second t=10 p=22", getCommandString(commands[3])); + EXPECT_EQ("first t=1 p=10", getCommandString(commands[4])); + EXPECT_EQ("third t=5 p=9", getCommandString(commands[5])); + EXPECT_EQ("seventh t=7 p=0", getCommandString(commands[6])); } -void CommandQueueTest::testDeleteIterator() { +TEST(CommandQueueTest, delete_iterator) { framework::defaultimplementation::FakeClock clock; CommandQueue<api::CreateVisitorCommand> queue(clock); - CPPUNIT_ASSERT(queue.empty()); + ASSERT_TRUE(queue.empty()); queue.add(getCommand("first", 10)); queue.add(getCommand("second", 100)); queue.add(getCommand("third", 1000)); @@ -199,28 +184,30 @@ void CommandQueueTest::testDeleteIterator() { queue.add(getCommand("fifth", 3000)); queue.add(getCommand("sixth", 400)); queue.add(getCommand("seventh", 700)); - CPPUNIT_ASSERT_EQUAL(7u, queue.size()); + ASSERT_EQ(7u, queue.size()); CommandQueue<api::CreateVisitorCommand>::iterator it = queue.begin(); ++it; ++it; queue.erase(it); - CPPUNIT_ASSERT_EQUAL(6u, queue.size()); + ASSERT_EQ(6u, queue.size()); - std::vector<std::shared_ptr<api::CreateVisitorCommand> > cmds; + std::vector<std::shared_ptr<api::CreateVisitorCommand>> cmds; for (;;) { std::shared_ptr<api::CreateVisitorCommand> cmd( std::dynamic_pointer_cast<api::CreateVisitorCommand>( queue.releaseNextCommand().first)); - if (cmd.get() == 0) break; + if (cmd.get() == 0) { + break; + } cmds.push_back(cmd); } - CPPUNIT_ASSERT_EQUAL(size_t(6), cmds.size()); - CPPUNIT_ASSERT_EQUAL(string("first t=10 p=0"), getCommandString(cmds[0])); - CPPUNIT_ASSERT_EQUAL(string("second t=100 p=0"), getCommandString(cmds[1])); - CPPUNIT_ASSERT_EQUAL(string("fourth t=5 p=0"), getCommandString(cmds[2])); - CPPUNIT_ASSERT_EQUAL(string("fifth t=3000 p=0"), getCommandString(cmds[3])); - CPPUNIT_ASSERT_EQUAL(string("sixth t=400 p=0"), getCommandString(cmds[4])); - CPPUNIT_ASSERT_EQUAL(string("seventh t=700 p=0"), getCommandString(cmds[5])); + ASSERT_EQ(6, cmds.size()); + EXPECT_EQ("first t=10 p=0", getCommandString(cmds[0])); + EXPECT_EQ("second t=100 p=0", getCommandString(cmds[1])); + EXPECT_EQ("fourth t=5 p=0", getCommandString(cmds[2])); + EXPECT_EQ("fifth t=3000 p=0", getCommandString(cmds[3])); + EXPECT_EQ("sixth t=400 p=0", getCommandString(cmds[4])); + EXPECT_EQ("seventh t=700 p=0", getCommandString(cmds[5])); } } diff --git a/storage/src/tests/visiting/memory_bounded_trace_test.cpp b/storage/src/tests/visiting/memory_bounded_trace_test.cpp index 5d7dda16ced..0cfd3dad4c3 100644 --- a/storage/src/tests/visiting/memory_bounded_trace_test.cpp +++ b/storage/src/tests/visiting/memory_bounded_trace_test.cpp @@ -1,73 +1,43 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/storage/visiting/memory_bounded_trace.h> +#include <vespa/vespalib/gtest/gtest.h> -namespace storage { - -class MemoryBoundedTraceTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(MemoryBoundedTraceTest); - CPPUNIT_TEST(noMemoryReportedUsedWhenEmpty); - CPPUNIT_TEST(memoryUsedIsStringLengthForLeafNode); - CPPUNIT_TEST(memoryUsedIsAccumulatedRecursivelyForNonLeafNodes); - CPPUNIT_TEST(traceNodesCanBeMovedAndImplicitlyCleared); - CPPUNIT_TEST(movedTraceTreeIsMarkedAsStrict); - CPPUNIT_TEST(canNotAddMoreNodesWhenMemoryUsedExceedsUpperBound); - CPPUNIT_TEST(movedTreeIncludesStatsNodeWhenNodesOmitted); - CPPUNIT_TEST_SUITE_END(); - -public: - void noMemoryReportedUsedWhenEmpty(); - void memoryUsedIsStringLengthForLeafNode(); - void memoryUsedIsAccumulatedRecursivelyForNonLeafNodes(); - void traceNodesCanBeMovedAndImplicitlyCleared(); - void movedTraceTreeIsMarkedAsStrict(); - void canNotAddMoreNodesWhenMemoryUsedExceedsUpperBound(); - void movedTreeIncludesStatsNodeWhenNodesOmitted(); -}; +using namespace ::testing; -CPPUNIT_TEST_SUITE_REGISTRATION(MemoryBoundedTraceTest); +namespace storage { -void -MemoryBoundedTraceTest::noMemoryReportedUsedWhenEmpty() -{ +TEST(MemoryBoundedTraceTest, no_memory_reported_used_when_empty) { MemoryBoundedTrace trace(100); - CPPUNIT_ASSERT_EQUAL(size_t(0), trace.getApproxMemoryUsed()); + EXPECT_EQ(0, trace.getApproxMemoryUsed()); } -void -MemoryBoundedTraceTest::memoryUsedIsStringLengthForLeafNode() -{ +TEST(MemoryBoundedTraceTest, memory_used_is_string_length_for_leaf_node) { MemoryBoundedTrace trace(100); - CPPUNIT_ASSERT(trace.add(mbus::TraceNode("hello world", 0))); - CPPUNIT_ASSERT_EQUAL(size_t(11), trace.getApproxMemoryUsed()); + EXPECT_TRUE(trace.add(mbus::TraceNode("hello world", 0))); + EXPECT_EQ(11, trace.getApproxMemoryUsed()); } -void -MemoryBoundedTraceTest::memoryUsedIsAccumulatedRecursivelyForNonLeafNodes() -{ +TEST(MemoryBoundedTraceTest, memory_used_is_accumulated_recursively_for_non_leaf_nodes) { MemoryBoundedTrace trace(100); mbus::TraceNode innerNode; innerNode.addChild("hello world"); innerNode.addChild("goodbye moon"); - CPPUNIT_ASSERT(trace.add(innerNode)); - CPPUNIT_ASSERT_EQUAL(size_t(23), trace.getApproxMemoryUsed()); + EXPECT_TRUE(trace.add(innerNode)); + EXPECT_EQ(23, trace.getApproxMemoryUsed()); } -void -MemoryBoundedTraceTest::traceNodesCanBeMovedAndImplicitlyCleared() -{ +TEST(MemoryBoundedTraceTest, trace_nodes_can_be_moved_and_implicitly_cleared) { MemoryBoundedTrace trace(100); - CPPUNIT_ASSERT(trace.add(mbus::TraceNode("hello world", 0))); + EXPECT_TRUE(trace.add(mbus::TraceNode("hello world", 0))); mbus::TraceNode target; trace.moveTraceTo(target); - CPPUNIT_ASSERT_EQUAL(uint32_t(1), target.getNumChildren()); - CPPUNIT_ASSERT_EQUAL(size_t(0), trace.getApproxMemoryUsed()); + EXPECT_EQ(1, target.getNumChildren()); + EXPECT_EQ(0, trace.getApproxMemoryUsed()); mbus::TraceNode emptinessCheck; trace.moveTraceTo(emptinessCheck); - CPPUNIT_ASSERT_EQUAL(uint32_t(0), emptinessCheck.getNumChildren()); + EXPECT_EQ(0, emptinessCheck.getNumChildren()); } /** @@ -77,54 +47,46 @@ MemoryBoundedTraceTest::traceNodesCanBeMovedAndImplicitlyCleared() * best of my knowledge, since the internal backing data structure is an * ordered vector anyhow. */ -void -MemoryBoundedTraceTest::movedTraceTreeIsMarkedAsStrict() -{ +TEST(MemoryBoundedTraceTest, moved_trace_tree_is_marked_as_strict) { MemoryBoundedTrace trace(100); - CPPUNIT_ASSERT(trace.add(mbus::TraceNode("hello world", 0))); + EXPECT_TRUE(trace.add(mbus::TraceNode("hello world", 0))); mbus::TraceNode target; trace.moveTraceTo(target); - CPPUNIT_ASSERT_EQUAL(uint32_t(1), target.getNumChildren()); - CPPUNIT_ASSERT(target.getChild(0).isStrict()); + EXPECT_EQ(1, target.getNumChildren()); + EXPECT_TRUE(target.getChild(0).isStrict()); } -void -MemoryBoundedTraceTest::canNotAddMoreNodesWhenMemoryUsedExceedsUpperBound() -{ +TEST(MemoryBoundedTraceTest, can_not_add_more_nodes_when_memory_used_exceeds_upper_bound) { // Note: we allow one complete node tree to exceed the bounds, but as soon // as the bound is exceeded no further nodes can be added. MemoryBoundedTrace trace(10); - CPPUNIT_ASSERT(trace.add(mbus::TraceNode("hello world", 0))); - CPPUNIT_ASSERT_EQUAL(size_t(11), trace.getApproxMemoryUsed()); + EXPECT_TRUE(trace.add(mbus::TraceNode("hello world", 0))); + EXPECT_EQ(11, trace.getApproxMemoryUsed()); - CPPUNIT_ASSERT(!trace.add(mbus::TraceNode("the quick red fox runs across " - "the freeway", 0))); - CPPUNIT_ASSERT_EQUAL(size_t(11), trace.getApproxMemoryUsed()); + EXPECT_FALSE(trace.add(mbus::TraceNode("the quick red fox runs across " + "the freeway", 0))); + EXPECT_EQ(11, trace.getApproxMemoryUsed()); mbus::TraceNode target; trace.moveTraceTo(target); // Twice nested node (root -> added trace tree -> leaf with txt). - CPPUNIT_ASSERT_EQUAL(uint32_t(1), target.getNumChildren()); - CPPUNIT_ASSERT(target.getChild(0).getNumChildren() >= 1); - CPPUNIT_ASSERT_EQUAL(vespalib::string("hello world"), - target.getChild(0).getChild(0).getNote()); + EXPECT_EQ(1, target.getNumChildren()); + EXPECT_GE(target.getChild(0).getNumChildren(), 1); + EXPECT_EQ("hello world", target.getChild(0).getChild(0).getNote()); } -void -MemoryBoundedTraceTest::movedTreeIncludesStatsNodeWhenNodesOmitted() -{ +TEST(MemoryBoundedTraceTest, moved_tree_includes_stats_node_when_nodes_omitted) { MemoryBoundedTrace trace(5); - CPPUNIT_ASSERT(trace.add(mbus::TraceNode("abcdef", 0))); - CPPUNIT_ASSERT(!trace.add(mbus::TraceNode("ghijkjlmn", 0))); + EXPECT_TRUE(trace.add(mbus::TraceNode("abcdef", 0))); + EXPECT_FALSE(trace.add(mbus::TraceNode("ghijkjlmn", 0))); mbus::TraceNode target; trace.moveTraceTo(target); - CPPUNIT_ASSERT_EQUAL(uint32_t(1), target.getNumChildren()); - CPPUNIT_ASSERT_EQUAL(uint32_t(2), target.getChild(0).getNumChildren()); + EXPECT_EQ(1, target.getNumChildren()); + EXPECT_EQ(2, target.getChild(0).getNumChildren()); vespalib::string expected("Trace too large; omitted 1 subsequent trace " "trees containing a total of 9 bytes"); - CPPUNIT_ASSERT_EQUAL(expected, target.getChild(0).getChild(1).getNote()); + EXPECT_EQ(expected, target.getChild(0).getChild(1).getNote()); } } // storage - diff --git a/storage/src/tests/visiting/visitormanagertest.cpp b/storage/src/tests/visiting/visitormanagertest.cpp index b9d4f24072d..1f2782de456 100644 --- a/storage/src/tests/visiting/visitormanagertest.cpp +++ b/storage/src/tests/visiting/visitormanagertest.cpp @@ -19,6 +19,8 @@ #include <vespa/documentapi/messagebus/messages/removedocumentmessage.h> #include <vespa/documentapi/messagebus/messages/visitor.h> #include <vespa/config/common/exceptions.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <gmock/gmock.h> #include <optional> #include <thread> #include <chrono> @@ -27,37 +29,17 @@ using document::test::makeDocumentBucket; using document::test::makeBucketSpace; using documentapi::Priority; using namespace std::chrono_literals; +using namespace ::testing; namespace storage { namespace { - typedef std::vector<api::StorageMessage::SP> msg_ptr_vector; -} -class VisitorManagerTest : public CppUnit::TestFixture -{ -private: - CPPUNIT_TEST_SUITE(VisitorManagerTest); - CPPUNIT_TEST(testNormalUsage); - CPPUNIT_TEST(testResending); - CPPUNIT_TEST(testVisitEmptyBucket); - CPPUNIT_TEST(testMultiBucketVisit); - CPPUNIT_TEST(testNoBuckets); - CPPUNIT_TEST(testVisitPutsAndRemoves); - CPPUNIT_TEST(testVisitWithTimeframeAndSelection); - CPPUNIT_TEST(testVisitWithTimeframeAndBogusSelection); - CPPUNIT_TEST(testVisitorCallbacks); - CPPUNIT_TEST(testVisitorCleanup); - CPPUNIT_TEST(testAbortOnFailedVisitorInfo); - CPPUNIT_TEST(testAbortOnFieldPathError); - CPPUNIT_TEST(testVisitorQueueTimeout); - CPPUNIT_TEST(testVisitorProcessingTimeout); - CPPUNIT_TEST(testPrioritizedVisitorQueing); - CPPUNIT_TEST(testPrioritizedMaxConcurrentVisitors); - CPPUNIT_TEST(testVisitorQueingZeroQueueSize); - CPPUNIT_TEST(testHitCounter); - CPPUNIT_TEST(testStatusPage); - CPPUNIT_TEST_SUITE_END(); +using msg_ptr_vector = std::vector<api::StorageMessage::SP>; + +} +struct VisitorManagerTest : Test { +protected: static uint32_t docCount; std::vector<document::Document::SP > _documents; std::unique_ptr<TestVisitorMessageSessionFactory> _messageSessionFactory; @@ -65,18 +47,19 @@ private: std::unique_ptr<DummyStorageLink> _top; VisitorManager* _manager; -public: VisitorManagerTest() : _node() {} + ~VisitorManagerTest(); - // Not using setUp since can't throw exception out of it. + // Not using setUp since can't throw exception out of it. void initializeTest(); void addSomeRemoves(bool removeAll = false); - void tearDown() override; + void TearDown() override; TestVisitorMessageSession& getSession(uint32_t n); - uint64_t verifyCreateVisitorReply( + void verifyCreateVisitorReply( api::ReturnCode::Result expectedResult, int checkStatsDocsVisited = -1, - int checkStatsBytesVisited = -1); + int checkStatsBytesVisited = -1, + uint64_t* message_id_out = nullptr); void getMessagesAndReply( int expectedCount, TestVisitorMessageSession& session, @@ -86,31 +69,11 @@ public: std::optional<Priority::Value> priority = documentapi::Priority::PRI_NORMAL_4); uint32_t getMatchingDocuments(std::vector<document::Document::SP >& docs); void finishAndWaitForVisitorSessionCompletion(uint32_t sessionIndex); - - void testNormalUsage(); - void testResending(); - void testVisitEmptyBucket(); - void testMultiBucketVisit(); - void testNoBuckets(); - void testVisitPutsAndRemoves(); - void testVisitWithTimeframeAndSelection(); - void testVisitWithTimeframeAndBogusSelection(); - void testVisitorCallbacks(); - void testVisitorCleanup(); - void testAbortOnFailedVisitorInfo(); - void testAbortOnFieldPathError(); - void testVisitorQueueTimeout(); - void testVisitorProcessingTimeout(); - void testPrioritizedVisitorQueing(); - void testPrioritizedMaxConcurrentVisitors(); - void testVisitorQueingZeroQueueSize(); - void testHitCounter(); - void testStatusPage(); }; -uint32_t VisitorManagerTest::docCount = 10; +VisitorManagerTest::~VisitorManagerTest() = default; -CPPUNIT_TEST_SUITE_REGISTRATION(VisitorManagerTest); +uint32_t VisitorManagerTest::docCount = 10; void VisitorManagerTest::initializeTest() @@ -118,28 +81,25 @@ VisitorManagerTest::initializeTest() vdstestlib::DirConfig config(getStandardConfig(true)); config.getConfig("stor-visitor").set("visitorthreads", "1"); - try { - _messageSessionFactory.reset( - new TestVisitorMessageSessionFactory(config.getConfigId())); - _node.reset( - new TestServiceLayerApp(config.getConfigId())); - _node->setupDummyPersistence(); - _node->getStateUpdater().setClusterState( - lib::ClusterState::CSP( - new lib::ClusterState("storage:1 distributor:1"))); - _top.reset(new DummyStorageLink()); - _top->push_back(std::unique_ptr<StorageLink>(_manager - = new VisitorManager( - config.getConfigId(), _node->getComponentRegister(), - *_messageSessionFactory))); - _top->push_back(std::unique_ptr<StorageLink>(new FileStorManager( - config.getConfigId(), _node->getPartitions(), _node->getPersistenceProvider(), _node->getComponentRegister()))); - _manager->setTimeBetweenTicks(10); - _top->open(); - } catch (config::InvalidConfigException& e) { - fprintf(stderr, "%s\n", e.what()); - } - // Adding some documents so database isn't empty + _messageSessionFactory.reset( + new TestVisitorMessageSessionFactory(config.getConfigId())); + _node.reset( + new TestServiceLayerApp(config.getConfigId())); + _node->setupDummyPersistence(); + _node->getStateUpdater().setClusterState( + lib::ClusterState::CSP( + new lib::ClusterState("storage:1 distributor:1"))); + _top.reset(new DummyStorageLink()); + _top->push_back(std::unique_ptr<StorageLink>(_manager + = new VisitorManager( + config.getConfigId(), _node->getComponentRegister(), + *_messageSessionFactory))); + _top->push_back(std::unique_ptr<StorageLink>(new FileStorManager( + config.getConfigId(), _node->getPartitions(), _node->getPersistenceProvider(), _node->getComponentRegister()))); + _manager->setTimeBetweenTicks(10); + _top->open(); + + // Adding some documents so database isn't empty api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); std::string content( "To be, or not to be: that is the question:\n" @@ -212,13 +172,10 @@ VisitorManagerTest::initializeTest() _top->sendDown(cmd); _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL((size_t) 1, replies.size()); - std::shared_ptr<api::PutReply> reply( - std::dynamic_pointer_cast<api::PutReply>( - replies[0])); - CPPUNIT_ASSERT(reply.get()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::OK), - reply->getResult()); + ASSERT_EQ(1, replies.size()); + auto reply = std::dynamic_pointer_cast<api::PutReply>(replies[0]); + ASSERT_TRUE(reply.get()); + ASSERT_EQ(api::ReturnCode(api::ReturnCode::OK), reply->getResult()); } } @@ -236,15 +193,15 @@ VisitorManagerTest::addSomeRemoves(bool removeAll) _top->sendDown(cmd); _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(size_t(1), replies.size()); + ASSERT_EQ(1, replies.size()); auto reply = std::dynamic_pointer_cast<api::RemoveReply>(replies[0]); - CPPUNIT_ASSERT(reply.get()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::OK), reply->getResult()); + ASSERT_TRUE(reply.get()); + ASSERT_EQ(api::ReturnCode(api::ReturnCode::OK), reply->getResult()); } } void -VisitorManagerTest::tearDown() +VisitorManagerTest::TearDown() { if (_top) { assert(_top->getNumReplies() == 0); @@ -277,7 +234,7 @@ VisitorManagerTest::getSession(uint32_t n) } std::this_thread::sleep_for(10ms); } - throw std::logic_error("unreachable"); + abort(); } void @@ -296,8 +253,7 @@ VisitorManagerTest::getMessagesAndReply( vespalib::MonitorGuard guard(session.getMonitor()); if (priority) { - CPPUNIT_ASSERT_EQUAL(*priority, - session.sentMessages[i]->getPriority()); + ASSERT_EQ(*priority, session.sentMessages[i]->getPriority()); } switch (session.sentMessages[i]->getType()) { @@ -327,34 +283,37 @@ VisitorManagerTest::getMessagesAndReply( } } -uint64_t +void VisitorManagerTest::verifyCreateVisitorReply( api::ReturnCode::Result expectedResult, int checkStatsDocsVisited, - int checkStatsBytesVisited) + int checkStatsBytesVisited, + uint64_t* message_id_out) { _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(1, (int)replies.size()); + ASSERT_EQ(1, replies.size()); std::shared_ptr<api::StorageMessage> msg(replies[0]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); - CPPUNIT_ASSERT(reply.get()); - CPPUNIT_ASSERT_EQUAL(expectedResult, reply->getResult().getResult()); + ASSERT_TRUE(reply.get()); + ASSERT_EQ(expectedResult, reply->getResult().getResult()); if (checkStatsDocsVisited >= 0) { - CPPUNIT_ASSERT_EQUAL(checkStatsDocsVisited, - int(reply->getVisitorStatistics().getDocumentsVisited())); + ASSERT_EQ(checkStatsDocsVisited, + reply->getVisitorStatistics().getDocumentsVisited()); } if (checkStatsBytesVisited >= 0) { - CPPUNIT_ASSERT_EQUAL(checkStatsBytesVisited, - int(reply->getVisitorStatistics().getBytesVisited())); + ASSERT_EQ(checkStatsBytesVisited, + reply->getVisitorStatistics().getBytesVisited()); } - return reply->getMsgId(); + if (message_id_out) { + *message_id_out = reply->getMsgId(); + } } uint32_t @@ -364,7 +323,6 @@ VisitorManagerTest::getMatchingDocuments(std::vector<document::Document::SP >& d for (uint32_t j=0; j<_documents.size(); ++j) { if (docs[i]->getId() == _documents[j]->getId() && *docs[i] == *_documents[j]) - { equalCount++; } @@ -374,9 +332,7 @@ VisitorManagerTest::getMatchingDocuments(std::vector<document::Document::SP >& d return equalCount; } -void -VisitorManagerTest::testHitCounter() -{ +TEST_F(VisitorManagerTest, hit_counter) { document::OrderingSpecification spec(document::OrderingSpecification::ASCENDING, 42, 7, 2); Visitor::HitCounter hitCounter(&spec); @@ -386,10 +342,10 @@ VisitorManagerTest::testHitCounter() hitCounter.addHit(document::DocumentId("orderdoc(7,2):mail:1234:10:foo"), 450); hitCounter.addHit(document::DocumentId("orderdoc(7,2):mail:1234:21:foo"), 450); - CPPUNIT_ASSERT_EQUAL(3, (int)hitCounter.getFirstPassHits()); - CPPUNIT_ASSERT_EQUAL(1350, (int)hitCounter.getFirstPassBytes()); - CPPUNIT_ASSERT_EQUAL(2, (int)hitCounter.getSecondPassHits()); - CPPUNIT_ASSERT_EQUAL(900, (int)hitCounter.getSecondPassBytes()); + EXPECT_EQ(3, hitCounter.getFirstPassHits()); + EXPECT_EQ(1350, hitCounter.getFirstPassBytes()); + EXPECT_EQ(2, hitCounter.getSecondPassHits()); + EXPECT_EQ(900, hitCounter.getSecondPassBytes()); } namespace { @@ -405,10 +361,8 @@ int getTotalSerializedSize(const std::vector<document::Document::SP>& docs) } -void -VisitorManagerTest::testNormalUsage() -{ - initializeTest(); +TEST_F(VisitorManagerTest, normal_usage) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); cmd->addBucketToBeVisited(document::BucketId(16, 3)); @@ -422,18 +376,17 @@ VisitorManagerTest::testNormalUsage() getMessagesAndReply(1, getSession(0), docs, docIds); // All data has been replied to, expecting to get a create visitor reply - verifyCreateVisitorReply(api::ReturnCode::OK, - int(docs.size()), - getTotalSerializedSize(docs)); + ASSERT_NO_FATAL_FAILURE( + verifyCreateVisitorReply(api::ReturnCode::OK, + int(docs.size()), + getTotalSerializedSize(docs))); - CPPUNIT_ASSERT_EQUAL(1u, getMatchingDocuments(docs)); - CPPUNIT_ASSERT(!_manager->hasPendingMessageState()); + EXPECT_EQ(1u, getMatchingDocuments(docs)); + EXPECT_FALSE(_manager->hasPendingMessageState()); } -void -VisitorManagerTest::testResending() -{ - initializeTest(); +TEST_F(VisitorManagerTest, resending) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); cmd->addBucketToBeVisited(document::BucketId(16, 3)); @@ -453,8 +406,8 @@ VisitorManagerTest::testResending() mbus::Reply::UP reply = msg->createReply(); - CPPUNIT_ASSERT_EQUAL((uint32_t)documentapi::DocumentProtocol::MESSAGE_VISITORINFO, - session.sentMessages[1]->getType()); + ASSERT_EQ(documentapi::DocumentProtocol::MESSAGE_VISITORINFO, + session.sentMessages[1]->getType()); reply->swapState(*session.sentMessages[1]); reply->setMessage(mbus::Message::UP(session.sentMessages[1].release())); session.reply(std::move(reply)); @@ -475,13 +428,11 @@ VisitorManagerTest::testResending() } // All data has been replied to, expecting to get a create visitor reply - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); } -void -VisitorManagerTest::testVisitEmptyBucket() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visit_empty_bucket) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); addSomeRemoves(true); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); @@ -491,13 +442,11 @@ VisitorManagerTest::testVisitEmptyBucket() _top->sendDown(cmd); // All data has been replied to, expecting to get a create visitor reply - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); } -void -VisitorManagerTest::testMultiBucketVisit() -{ - initializeTest(); +TEST_F(VisitorManagerTest, multi_bucket_visit) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); for (uint32_t i=0; i<10; ++i) { @@ -506,43 +455,40 @@ VisitorManagerTest::testMultiBucketVisit() cmd->setAddress(address); cmd->setDataDestination("fooclient.0"); _top->sendDown(cmd); - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; // Should receive one multioperation message for each bucket getMessagesAndReply(10, getSession(0), docs, docIds); // All data has been replied to, expecting to get a create visitor reply - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); - CPPUNIT_ASSERT_EQUAL(docCount, getMatchingDocuments(docs)); + EXPECT_EQ(docCount, getMatchingDocuments(docs)); } -void -VisitorManagerTest::testNoBuckets() -{ - initializeTest(); +TEST_F(VisitorManagerTest, no_buckets) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); cmd->setAddress(address); _top->sendDown(cmd); - // Should get one reply; a CreateVisitorReply with error since no - // buckets where specified in the CreateVisitorCommand + // Should get one reply; a CreateVisitorReply with error since no + // buckets where specified in the CreateVisitorCommand _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL((size_t) 1, replies.size()); + ASSERT_EQ(1, replies.size()); auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(replies[0]); - // Verify that cast went ok => it was a CreateVisitorReply message - CPPUNIT_ASSERT(reply.get()); + // Verify that cast went ok => it was a CreateVisitorReply message + ASSERT_TRUE(reply.get()); api::ReturnCode ret(api::ReturnCode::ILLEGAL_PARAMETERS, "No buckets specified"); - CPPUNIT_ASSERT_EQUAL(ret, reply->getResult()); + EXPECT_EQ(ret, reply->getResult()); } -void VisitorManagerTest::testVisitPutsAndRemoves() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visit_puts_and_removes) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); addSomeRemoves(); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); @@ -552,25 +498,22 @@ void VisitorManagerTest::testVisitPutsAndRemoves() cmd->addBucketToBeVisited(document::BucketId(16, i)); } _top->sendDown(cmd); - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; getMessagesAndReply(10, getSession(0), docs, docIds); - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); - CPPUNIT_ASSERT_EQUAL( - docCount - (docCount + 3) / 4, - getMatchingDocuments(docs)); + EXPECT_EQ(docCount - (docCount + 3) / 4, + getMatchingDocuments(docs)); - CPPUNIT_ASSERT_EQUAL( - (size_t) (docCount + 3) / 4, - docIds.size()); + EXPECT_EQ((docCount + 3) / 4, + docIds.size()); } -void VisitorManagerTest::testVisitWithTimeframeAndSelection() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visit_with_timeframe_and_selection) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", "testdoctype1.headerval < 2"); cmd->setFromTime(3); @@ -580,14 +523,14 @@ void VisitorManagerTest::testVisitWithTimeframeAndSelection() } cmd->setAddress(address); _top->sendDown(cmd); - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; getMessagesAndReply(2, getSession(0), docs, docIds); - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); - CPPUNIT_ASSERT_EQUAL((size_t) 2, docs.size()); + ASSERT_EQ(2, docs.size()); std::set<std::string> expected; expected.insert("userdoc:test:4:http://www.ntnu.no/4.html"); expected.insert("userdoc:test:5:http://www.ntnu.no/5.html"); @@ -595,12 +538,11 @@ void VisitorManagerTest::testVisitWithTimeframeAndSelection() for (uint32_t i=0; i<docs.size(); ++i) { actual.insert(docs[i]->getId().toString()); } - CPPUNIT_ASSERT_EQUAL(expected, actual); + EXPECT_THAT(expected, ContainerEq(actual)); } -void VisitorManagerTest::testVisitWithTimeframeAndBogusSelection() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visit_with_timeframe_and_bogus_selection) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", "DocType(testdoctype1---///---) XXX BAD Field(headerval) < 2"); @@ -614,17 +556,33 @@ void VisitorManagerTest::testVisitWithTimeframeAndBogusSelection() _top->sendDown(cmd); _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL((size_t) 1, replies.size()); + ASSERT_EQ(1, replies.size()); auto* reply = dynamic_cast<api::StorageReply*>(replies.front().get()); - CPPUNIT_ASSERT(reply); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::ILLEGAL_PARAMETERS, reply->getResult().getResult()); + ASSERT_TRUE(reply); + EXPECT_EQ(api::ReturnCode::ILLEGAL_PARAMETERS, reply->getResult().getResult()); } -void -VisitorManagerTest::testVisitorCallbacks() -{ - initializeTest(); +#define ASSERT_SUBSTRING_COUNT(source, expectedCount, substring) \ + { \ + uint32_t count = 0; \ + std::ostringstream value; /* Let value be non-strings */ \ + value << source; \ + std::string s(value.str()); \ + std::string::size_type pos = s.find(substring); \ + while (pos != std::string::npos) { \ + ++count; \ + pos = s.find(substring, pos+1); \ + } \ + if (count != (uint32_t) expectedCount) { \ + FAIL() << "Value of '" << s << "' contained " << count \ + << " instances of substring '" << substring << "', not " \ + << expectedCount << " as expected."; \ + } \ + } + +TEST_F(VisitorManagerTest, visitor_callbacks) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); std::ostringstream replydata; api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "TestVisitor", "testvis", ""); @@ -642,10 +600,10 @@ VisitorManagerTest::testVisitorCallbacks() { vespalib::MonitorGuard guard(session.getMonitor()); - CPPUNIT_ASSERT_EQUAL((uint32_t)documentapi::DocumentProtocol::MESSAGE_MAPVISITOR, session.sentMessages[i]->getType()); + ASSERT_EQ(documentapi::DocumentProtocol::MESSAGE_MAPVISITOR, session.sentMessages[i]->getType()); auto* mapvisitormsg = dynamic_cast<documentapi::MapVisitorMessage*>(session.sentMessages[i].get()); - CPPUNIT_ASSERT(mapvisitormsg != nullptr); + ASSERT_TRUE(mapvisitormsg != nullptr); replydata << mapvisitormsg->getData().get("msg"); @@ -657,18 +615,16 @@ VisitorManagerTest::testVisitorCallbacks() } // All data has been replied to, expecting to get a create visitor reply - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); - CPPUNIT_ASSERT_SUBSTRING_COUNT(replydata.str(), 1, "Starting visitor"); - CPPUNIT_ASSERT_SUBSTRING_COUNT(replydata.str(), 2, "Handling block of 1 documents"); - CPPUNIT_ASSERT_SUBSTRING_COUNT(replydata.str(), 2, "completedBucket"); - CPPUNIT_ASSERT_SUBSTRING_COUNT(replydata.str(), 1, "completedVisiting"); + ASSERT_SUBSTRING_COUNT(replydata.str(), 1, "Starting visitor"); + ASSERT_SUBSTRING_COUNT(replydata.str(), 2, "Handling block of 1 documents"); + ASSERT_SUBSTRING_COUNT(replydata.str(), 2, "completedBucket"); + ASSERT_SUBSTRING_COUNT(replydata.str(), 1, "completedVisiting"); } -void -VisitorManagerTest::testVisitorCleanup() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visitor_cleanup) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); // Start a bunch of invalid visitors @@ -699,16 +655,16 @@ VisitorManagerTest::testVisitorCleanup() const int expected_total = 16; _top->waitForMessages(expected_total, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(size_t(expected_total), replies.size()); + ASSERT_EQ(expected_total, replies.size()); int failures = 0; int busy = 0; for (uint32_t i=0; i< expected_total; ++i) { std::shared_ptr<api::StorageMessage> msg(replies[i]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); - CPPUNIT_ASSERT(reply.get()); + ASSERT_TRUE(reply.get()); if (i < 10) { if (api::ReturnCode::ILLEGAL_PARAMETERS == reply->getResult().getResult()) { @@ -723,20 +679,20 @@ VisitorManagerTest::testVisitorCleanup() } } - CPPUNIT_ASSERT_EQUAL(10, failures); - CPPUNIT_ASSERT_EQUAL(expected_total - 10, busy); + ASSERT_EQ(10, failures); + ASSERT_EQ(expected_total - 10, busy); } // 4 pending // Finish a visitor - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; getMessagesAndReply(1, getSession(0), docs, docIds); // Should get a reply for the visitor. - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); // 3 pending @@ -744,7 +700,7 @@ VisitorManagerTest::testVisitorCleanup() getMessagesAndReply(1, getSession(1), docs, docIds, api::ReturnCode::INTERNAL_FAILURE); // Should get a reply for the visitor. - verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE)); // Wait until there are 2 pending. Visitor threads might not have completed // cleanup of existing visitors yet. @@ -766,15 +722,15 @@ VisitorManagerTest::testVisitorCleanup() // Should now get 8 busy. _top->waitForMessages(8, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(size_t(8), replies.size()); + ASSERT_EQ(8, replies.size()); for (uint32_t i=0; i< replies.size(); ++i) { std::shared_ptr<api::StorageMessage> msg(replies[i]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); - CPPUNIT_ASSERT(reply.get()); + ASSERT_TRUE(reply.get()); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode::BUSY, reply->getResult().getResult()); + ASSERT_EQ(api::ReturnCode::BUSY, reply->getResult().getResult()); } for (uint32_t i = 0; i < 4; ++i) { @@ -783,10 +739,8 @@ VisitorManagerTest::testVisitorCleanup() } } -void -VisitorManagerTest::testAbortOnFailedVisitorInfo() -{ - initializeTest(); +TEST_F(VisitorManagerTest, abort_on_failed_visitor_info) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); { @@ -797,7 +751,7 @@ VisitorManagerTest::testAbortOnFailedVisitorInfo() _top->sendDown(cmd); } - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; TestVisitorMessageSession& session = getSession(0); @@ -810,18 +764,16 @@ VisitorManagerTest::testAbortOnFailedVisitorInfo() mbus::Reply::UP reply = cmd->createReply(); - CPPUNIT_ASSERT_EQUAL(uint32_t(documentapi::DocumentProtocol::MESSAGE_VISITORINFO), session.sentMessages[1]->getType()); + ASSERT_EQ(documentapi::DocumentProtocol::MESSAGE_VISITORINFO, session.sentMessages[1]->getType()); reply->swapState(*session.sentMessages[1]); reply->setMessage(mbus::Message::UP(session.sentMessages[1].release())); reply->addError(mbus::Error(api::ReturnCode::NOT_CONNECTED, "Me no ready")); session.reply(std::move(reply)); } - verifyCreateVisitorReply(api::ReturnCode::NOT_CONNECTED); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::NOT_CONNECTED)); } -void -VisitorManagerTest::testAbortOnFieldPathError() -{ +TEST_F(VisitorManagerTest, abort_on_field_path_error) { initializeTest(); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); @@ -833,13 +785,11 @@ VisitorManagerTest::testAbortOnFieldPathError() cmd->setQueueTimeout(0); _top->sendDown(cmd); - verifyCreateVisitorReply(api::ReturnCode::ILLEGAL_PARAMETERS); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::ILLEGAL_PARAMETERS)); } -void -VisitorManagerTest::testVisitorQueueTimeout() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visitor_queue_timeout) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); _manager->enforceQueueUsage(); @@ -861,16 +811,14 @@ VisitorManagerTest::testVisitorQueueTimeout() const msg_ptr_vector replies = _top->getRepliesOnce(); std::shared_ptr<api::StorageMessage> msg(replies[0]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); - CPPUNIT_ASSERT_EQUAL(api::ReturnCode(api::ReturnCode::BUSY, "Visitor timed out in visitor queue"), - reply->getResult()); + ASSERT_EQ(api::ReturnCode(api::ReturnCode::BUSY, "Visitor timed out in visitor queue"), + reply->getResult()); } -void -VisitorManagerTest::testVisitorProcessingTimeout() -{ - initializeTest(); +TEST_F(VisitorManagerTest, visitor_processing_timeout) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", "testvis", ""); @@ -886,32 +834,32 @@ VisitorManagerTest::testVisitorProcessingTimeout() _node->getClock().addSecondsToTime(1000); - verifyCreateVisitorReply(api::ReturnCode::ABORTED); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::ABORTED)); } namespace { - uint32_t nextVisitor = 0; - api::StorageMessage::Id - sendCreateVisitor(uint32_t timeout, DummyStorageLink& top, uint8_t priority = 127) { - std::ostringstream ost; - ost << "testvis" << ++nextVisitor; - api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); - auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", ost.str(), ""); - cmd->addBucketToBeVisited(document::BucketId(16, 3)); - cmd->setAddress(address); - cmd->setQueueTimeout(timeout); - cmd->setPriority(priority); - top.sendDown(cmd); - return cmd->getMsgId(); - } +uint32_t nextVisitor = 0; + +api::StorageMessage::Id +sendCreateVisitor(uint32_t timeout, DummyStorageLink& top, uint8_t priority = 127) { + std::ostringstream ost; + ost << "testvis" << ++nextVisitor; + api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); + auto cmd = std::make_shared<api::CreateVisitorCommand>(makeBucketSpace(), "DumpVisitor", ost.str(), ""); + cmd->addBucketToBeVisited(document::BucketId(16, 3)); + cmd->setAddress(address); + cmd->setQueueTimeout(timeout); + cmd->setPriority(priority); + top.sendDown(cmd); + return cmd->getMsgId(); } -void -VisitorManagerTest::testPrioritizedVisitorQueing() -{ +} + +TEST_F(VisitorManagerTest, prioritized_visitor_queing) { framework::HttpUrlPath path("?verbose=true&allvisitors=true"); - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); _manager->setMaxConcurrentVisitors(4); _manager->setMaxVisitorQueueSize(4); @@ -933,27 +881,31 @@ VisitorManagerTest::testPrioritizedVisitorQueing() // Send a lower pri visitor that will be busy-returned immediately ids[8] = sendCreateVisitor(1000, *_top, 130); - CPPUNIT_ASSERT_EQUAL(ids[8], verifyCreateVisitorReply(api::ReturnCode::BUSY)); + uint64_t message_id = 0; + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY, -1, -1, &message_id)); + ASSERT_EQ(ids[8], message_id); // Send a higher pri visitor that will take the place of pri 100 visitor ids[9] = sendCreateVisitor(1000, *_top, 60); - CPPUNIT_ASSERT_EQUAL(ids[4], verifyCreateVisitorReply(api::ReturnCode::BUSY)); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY, -1, -1, &message_id)); + ASSERT_EQ(ids[4], message_id); // Finish the first visitor - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; getMessagesAndReply(1, getSession(0), docs, docIds, api::ReturnCode::OK, Priority::PRI_HIGHEST); - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK, -1, -1, &message_id)); // We should now start the highest priority visitor. getMessagesAndReply(1, getSession(4), docs, docIds, api::ReturnCode::OK, Priority::PRI_VERY_HIGH); - CPPUNIT_ASSERT_EQUAL(ids[9], verifyCreateVisitorReply(api::ReturnCode::OK)); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK, -1, -1, &message_id)); + ASSERT_EQ(ids[9], message_id); // 3 pending, 3 in queue. Clean them up std::vector<uint32_t> pending_sessions = {1, 2, 3, 5, 6, 7}; for (auto session : pending_sessions) { - finishAndWaitForVisitorSessionCompletion(session); + ASSERT_NO_FATAL_FAILURE(finishAndWaitForVisitorSessionCompletion(session)); } } @@ -961,13 +913,12 @@ void VisitorManagerTest::finishAndWaitForVisitorSessionCompletion(uint32_t sessi std::vector<document::Document::SP > docs; std::vector<document::DocumentId> docIds; getMessagesAndReply(1, getSession(sessionIndex), docs, docIds, api::ReturnCode::OK, std::optional<Priority::Value>()); - verifyCreateVisitorReply(api::ReturnCode::OK); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); } -void -VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { +TEST_F(VisitorManagerTest, prioritized_max_concurrent_visitors) { framework::HttpUrlPath path("?verbose=true&allvisitors=true"); - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); api::StorageMessage::Id ids[17] = { 0 }; @@ -997,12 +948,15 @@ VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { // Should punch pri203 msg out of the queue -> busy ids[11] = sendCreateVisitor(1000, *_top, 197); - CPPUNIT_ASSERT_EQUAL(ids[4], verifyCreateVisitorReply(api::ReturnCode::BUSY)); + uint64_t message_id = 0; + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY, -1, -1, &message_id)); + ASSERT_EQ(ids[4], message_id); // No concurrency slots left for this message -> busy ids[12] = sendCreateVisitor(1000, *_top, 204); - CPPUNIT_ASSERT_EQUAL(ids[12], verifyCreateVisitorReply(api::ReturnCode::BUSY)); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY, -1, -1, &message_id)); + ASSERT_EQ(ids[12], message_id); // Gets a concurrent slot ids[13] = sendCreateVisitor(1000, *_top, 80); @@ -1010,7 +964,8 @@ VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { // Kicks pri 202 out of the queue -> busy ids[14] = sendCreateVisitor(1000, *_top, 79); - CPPUNIT_ASSERT_EQUAL(ids[5], verifyCreateVisitorReply(api::ReturnCode::BUSY)); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY, -1, -1, &message_id)); + ASSERT_EQ(ids[5], message_id); // Gets a concurrent slot ids[15] = sendCreateVisitor(1000, *_top, 63); @@ -1018,7 +973,7 @@ VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { // Very Important Visitor(tm) gets a concurrent slot ids[16] = sendCreateVisitor(1000, *_top, 0); - std::vector<document::Document::SP > docs; + std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; std::set<uint64_t> finishedVisitors; @@ -1034,19 +989,19 @@ VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { } else if (i == 6) { priority = documentapi::Priority::PRI_HIGH_1; // ids 15 } - getMessagesAndReply(1, getSession(i), docs, docIds, api::ReturnCode::OK, - priority); - finishedVisitors.insert(verifyCreateVisitorReply(api::ReturnCode::OK)); + getMessagesAndReply(1, getSession(i), docs, docIds, api::ReturnCode::OK, priority); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK, -1, -1, &message_id)); + finishedVisitors.insert(message_id); } for (int i = 0; i < 4; i++) { - CPPUNIT_ASSERT(finishedVisitors.find(ids[i]) != finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[i]), finishedVisitors.end()); } - CPPUNIT_ASSERT(finishedVisitors.find(ids[10]) != finishedVisitors.end()); - CPPUNIT_ASSERT(finishedVisitors.find(ids[13]) != finishedVisitors.end()); - CPPUNIT_ASSERT(finishedVisitors.find(ids[15]) != finishedVisitors.end()); - CPPUNIT_ASSERT(finishedVisitors.find(ids[16]) != finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[10]), finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[13]), finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[15]), finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[16]), finishedVisitors.end()); finishedVisitors.clear(); @@ -1058,22 +1013,22 @@ VisitorManagerTest::testPrioritizedMaxConcurrentVisitors() { } getMessagesAndReply(1, getSession(i), docs, docIds, api::ReturnCode::OK, priority); - uint64_t msgId = verifyCreateVisitorReply(api::ReturnCode::OK); + uint64_t msgId = 0; + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK, -1, -1, &msgId)); finishedVisitors.insert(msgId); } for (int i = 6; i < 10; i++) { - CPPUNIT_ASSERT(finishedVisitors.find(ids[i]) != finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[i]), finishedVisitors.end()); } - CPPUNIT_ASSERT(finishedVisitors.find(ids[11]) != finishedVisitors.end()); - CPPUNIT_ASSERT(finishedVisitors.find(ids[14]) != finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[11]), finishedVisitors.end()); + ASSERT_NE(finishedVisitors.find(ids[14]), finishedVisitors.end()); } -void -VisitorManagerTest::testVisitorQueingZeroQueueSize() { +TEST_F(VisitorManagerTest, visitor_queing_zero_queue_size) { framework::HttpUrlPath path("?verbose=true&allvisitors=true"); - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); _manager->setMaxConcurrentVisitors(4); _manager->setMaxVisitorQueueSize(0); @@ -1085,17 +1040,16 @@ VisitorManagerTest::testVisitorQueingZeroQueueSize() { // Queue size is zero, all visitors will be busy-returned for (uint32_t i = 0; i < 5; ++i) { sendCreateVisitor(1000, *_top, 100 - i); - verifyCreateVisitorReply(api::ReturnCode::BUSY); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUSY)); } for (uint32_t session = 0; session < 4; ++session) { finishAndWaitForVisitorSessionCompletion(session); } } -void -VisitorManagerTest::testStatusPage() { +TEST_F(VisitorManagerTest, status_page) { framework::HttpUrlPath path("?verbose=true&allvisitors=true"); - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); _manager->setMaxConcurrentVisitors(1, 1); _manager->setMaxVisitorQueueSize(6); @@ -1112,13 +1066,13 @@ VisitorManagerTest::testStatusPage() { static_cast<framework::HtmlStatusReporter&>(*_manager).reportHtmlStatus(ss, path); std::string str(ss.str()); - CPPUNIT_ASSERT(str.find("Currently running visitors") != std::string::npos); + EXPECT_THAT(str, HasSubstr("Currently running visitors")); // Should be propagated to visitor thread - CPPUNIT_ASSERT(str.find("Running 1 visitors") != std::string::npos); // 1 active - CPPUNIT_ASSERT(str.find("waiting visitors 1") != std::string::npos); // 1 queued - CPPUNIT_ASSERT(str.find("Visitor thread 0") != std::string::npos); - CPPUNIT_ASSERT(str.find("Disconnected visitor timeout") != std::string::npos); // verbose per thread - CPPUNIT_ASSERT(str.find("Message #1 <b>putdocumentmessage</b>") != std::string::npos); // 1 active + EXPECT_THAT(str, HasSubstr("Running 1 visitors")); // 1 active + EXPECT_THAT(str, HasSubstr("waiting visitors 1")); // 1 queued + EXPECT_THAT(str, HasSubstr("Visitor thread 0")); + EXPECT_THAT(str, HasSubstr("Disconnected visitor timeout")); // verbose per thread + EXPECT_THAT(str, HasSubstr("Message #1 <b>putdocumentmessage</b>")); // 1 active for (uint32_t session = 0; session < 2 ; ++session){ finishAndWaitForVisitorSessionCompletion(session); diff --git a/storage/src/tests/visiting/visitortest.cpp b/storage/src/tests/visiting/visitortest.cpp index 24b04c8d33a..3d37bbe434b 100644 --- a/storage/src/tests/visiting/visitortest.cpp +++ b/storage/src/tests/visiting/visitortest.cpp @@ -18,11 +18,13 @@ #include <vespa/documentapi/messagebus/messages/visitor.h> #include <vespa/vespalib/io/fileutil.h> #include <vespa/config/common/exceptions.h> +#include <vespa/vespalib/gtest/gtest.h> #include <thread> #include <sys/stat.h> using namespace std::chrono_literals; using document::test::makeBucketSpace; +using namespace ::testing; namespace storage { @@ -30,8 +32,7 @@ namespace { using msg_ptr_vector = std::vector<api::StorageMessage::SP>; -struct TestParams -{ +struct TestParams { TestParams& maxVisitorMemoryUsage(uint32_t bytes) { _maxVisitorMemoryUsage = bytes; return *this; @@ -52,26 +53,7 @@ struct TestParams } -class VisitorTest : public CppUnit::TestFixture -{ -private: - CPPUNIT_TEST_SUITE(VisitorTest); - CPPUNIT_TEST(testNormalUsage); - CPPUNIT_TEST(testFailedCreateIterator); - CPPUNIT_TEST(testFailedGetIter); - CPPUNIT_TEST(testDocumentAPIClientError); - CPPUNIT_TEST(testNoDocumentAPIResendingForFailedVisitor); - CPPUNIT_TEST(testIteratorCreatedForFailedVisitor); - CPPUNIT_TEST(testFailedDocumentAPISend); - CPPUNIT_TEST(testNoVisitorNotificationForTransientFailures); - CPPUNIT_TEST(testNotificationSentIfTransientErrorRetriedManyTimes); - CPPUNIT_TEST(testNoMbusTracingIfTraceLevelIsZero); - CPPUNIT_TEST(testReplyContainsTraceIfTraceLevelAboveZero); - CPPUNIT_TEST(testNoMoreIteratorsSentWhileMemoryUsedAboveLimit); - CPPUNIT_TEST(testDumpVisitorInvokesStrongReadConsistencyIteration); - CPPUNIT_TEST(testTestVisitorInvokesWeakReadConsistencyIteration); - CPPUNIT_TEST_SUITE_END(); - +struct VisitorTest : Test { static uint32_t docCount; std::vector<document::Document::SP > _documents; std::unique_ptr<TestVisitorMessageSessionFactory> _messageSessionFactory; @@ -80,26 +62,8 @@ private: DummyStorageLink* _bottom; VisitorManager* _manager; -public: VisitorTest() : _node() {} - void testNormalUsage(); - void testFailedCreateIterator(); - void testFailedGetIter(); - void testDocumentAPIClientError(); - void testNoDocumentAPIResendingForFailedVisitor(); - void testIteratorCreatedForFailedVisitor(); - void testFailedDocumentAPISend(); - void testNoVisitorNotificationForTransientFailures(); - void testNotificationSentIfTransientErrorRetriedManyTimes(); - void testNoMbusTracingIfTraceLevelIsZero(); - void testReplyContainsTraceIfTraceLevelAboveZero(); - void testNoMoreIteratorsSentWhileMemoryUsedAboveLimit(); - void testDumpVisitorInvokesStrongReadConsistencyIteration(); - void testTestVisitorInvokesWeakReadConsistencyIteration(); - // TODO: - void testVisitMultipleBuckets() {} - // Not using setUp since can't throw exception out of it. void initializeTest(const TestParams& params = TestParams()); @@ -118,13 +82,14 @@ public: std::shared_ptr<api::CreateVisitorCommand> makeCreateVisitor( const VisitorOptions& options = VisitorOptions()); - void tearDown() override; + void TearDown() override; bool waitUntilNoActiveVisitors(); TestVisitorMessageSession& getSession(uint32_t n); - uint64_t verifyCreateVisitorReply( + void verifyCreateVisitorReply( api::ReturnCode::Result expectedResult, int checkStatsDocsVisited = -1, - int checkStatsBytesVisited = -1); + int checkStatsBytesVisited = -1, + uint64_t* message_id_out = nullptr); void getMessagesAndReply( int expectedCount, TestVisitorMessageSession& session, @@ -134,18 +99,17 @@ public: api::ReturnCode::Result returnCode = api::ReturnCode::OK); uint32_t getMatchingDocuments(std::vector<document::Document::SP >& docs); -private: +protected: void doTestVisitorInstanceHasConsistencyLevel( vespalib::stringref visitorType, spi::ReadConsistency expectedConsistency); template <typename T> - std::vector<std::shared_ptr<T> > - fetchMultipleCommands(DummyStorageLink& link, size_t count); + void fetchMultipleCommands(DummyStorageLink& link, size_t count, + std::vector<std::shared_ptr<T>>& commands_out); template <typename T> - std::shared_ptr<T> - fetchSingleCommand(DummyStorageLink& link); + void fetchSingleCommand(DummyStorageLink& link, std::shared_ptr<T>& msg_out); void sendGetIterReply(GetIterCommand& cmd, const api::ReturnCode& result = @@ -153,8 +117,9 @@ private: uint32_t maxDocuments = 0, bool overrideCompleted = false); void sendCreateIteratorReply(uint64_t iteratorId = 1234); - std::shared_ptr<api::CreateVisitorReply> doCompleteVisitingSession( - const std::shared_ptr<api::CreateVisitorCommand>& cmd); + void doCompleteVisitingSession( + const std::shared_ptr<api::CreateVisitorCommand>& cmd, + std::shared_ptr<api::CreateVisitorReply>& reply_out); void sendInitialCreateVisitorAndGetIterRound(); @@ -171,8 +136,6 @@ private: uint32_t VisitorTest::docCount = 10; -CPPUNIT_TEST_SUITE_REGISTRATION(VisitorTest); - void VisitorTest::initializeTest(const TestParams& params) { @@ -192,26 +155,23 @@ VisitorTest::initializeTest(const TestParams& params) vespalib::mkdir(vespalib::make_string("%s/disks/d0", rootFolder.c_str()), true); vespalib::mkdir(vespalib::make_string("%s/disks/d1", rootFolder.c_str()), true); - try { - _messageSessionFactory.reset( - new TestVisitorMessageSessionFactory(config.getConfigId())); - if (params._autoReplyError.getCode() != mbus::ErrorCode::NONE) { - _messageSessionFactory->_autoReplyError = params._autoReplyError; - _messageSessionFactory->_createAutoReplyVisitorSessions = true; - } - _node.reset(new TestServiceLayerApp(config.getConfigId())); - _top.reset(new DummyStorageLink()); - _top->push_back(std::unique_ptr<StorageLink>(_manager - = new VisitorManager( - config.getConfigId(), - _node->getComponentRegister(), *_messageSessionFactory))); - _bottom = new DummyStorageLink(); - _top->push_back(std::unique_ptr<StorageLink>(_bottom)); - _manager->setTimeBetweenTicks(10); - _top->open(); - } catch (config::InvalidConfigException& e) { - fprintf(stderr, "%s\n", e.what()); + _messageSessionFactory.reset( + new TestVisitorMessageSessionFactory(config.getConfigId())); + if (params._autoReplyError.getCode() != mbus::ErrorCode::NONE) { + _messageSessionFactory->_autoReplyError = params._autoReplyError; + _messageSessionFactory->_createAutoReplyVisitorSessions = true; } + _node.reset(new TestServiceLayerApp(config.getConfigId())); + _top.reset(new DummyStorageLink()); + _top->push_back(std::unique_ptr<StorageLink>(_manager + = new VisitorManager( + config.getConfigId(), + _node->getComponentRegister(), *_messageSessionFactory))); + _bottom = new DummyStorageLink(); + _top->push_back(std::unique_ptr<StorageLink>(_bottom)); + _manager->setTimeBetweenTicks(10); + _top->open(); + std::string content( "To be, or not to be: that is the question:\n" "Whether 'tis nobler in the mind to suffer\n" @@ -263,16 +223,16 @@ VisitorTest::initializeTest(const TestParams& params) } void -VisitorTest::tearDown() +VisitorTest::TearDown() { - if (_top.get() != 0) { + if (_top) { _top->close(); _top->flush(); - _top.reset(0); + _top.reset(); } - _node.reset(0); - _messageSessionFactory.reset(0); - _manager = 0; + _node.reset(); + _messageSessionFactory.reset(); + _manager = nullptr; } bool @@ -310,7 +270,7 @@ VisitorTest::getSession(uint32_t n) } std::this_thread::sleep_for(10ms); } - throw std::logic_error("unreachable"); + abort(); } void @@ -327,10 +287,10 @@ VisitorTest::getMessagesAndReply( mbus::Reply::UP reply; { vespalib::MonitorGuard guard(session.getMonitor()); - CPPUNIT_ASSERT(!session.sentMessages.empty()); + ASSERT_FALSE(session.sentMessages.empty()); std::unique_ptr<documentapi::DocumentMessage> msg(std::move(session.sentMessages.front())); session.sentMessages.pop_front(); - CPPUNIT_ASSERT(msg->getPriority() < 16); + ASSERT_LT(msg->getPriority(), 16); switch (msg->getType()) { case documentapi::DocumentProtocol::MESSAGE_PUTDOCUMENT: @@ -361,35 +321,37 @@ VisitorTest::getMessagesAndReply( } } -uint64_t +void VisitorTest::verifyCreateVisitorReply( api::ReturnCode::Result expectedResult, int checkStatsDocsVisited, - int checkStatsBytesVisited) + int checkStatsBytesVisited, + uint64_t* message_id_out) { _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(1, (int)replies.size()); + ASSERT_EQ(1, replies.size()); std::shared_ptr<api::StorageMessage> msg(replies[0]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); - std::shared_ptr<api::CreateVisitorReply> reply( - std::dynamic_pointer_cast<api::CreateVisitorReply>(msg)); - CPPUNIT_ASSERT(reply.get()); - CPPUNIT_ASSERT_EQUAL(expectedResult, reply->getResult().getResult()); + auto reply = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); + ASSERT_TRUE(reply.get()); + ASSERT_EQ(expectedResult, reply->getResult().getResult()); if (checkStatsDocsVisited >= 0) { - CPPUNIT_ASSERT_EQUAL(checkStatsDocsVisited, - int(reply->getVisitorStatistics().getDocumentsVisited())); + ASSERT_EQ(checkStatsDocsVisited, + reply->getVisitorStatistics().getDocumentsVisited()); } if (checkStatsBytesVisited >= 0) { - CPPUNIT_ASSERT_EQUAL(checkStatsBytesVisited, - int(reply->getVisitorStatistics().getBytesVisited())); + ASSERT_EQ(checkStatsBytesVisited, + reply->getVisitorStatistics().getBytesVisited()); } - return reply->getMsgId(); + if (message_id_out) { + *message_id_out = reply->getMsgId(); + } } uint32_t @@ -423,12 +385,11 @@ VisitorTest::sendGetIterReply(GetIterCommand& cmd, assert(maxDocuments < _documents.size()); size_t documentCount = maxDocuments != 0 ? maxDocuments : _documents.size(); for (size_t i = 0; i < documentCount; ++i) { - reply->getEntries().push_back( - spi::DocEntry::UP( - new spi::DocEntry( + reply->getEntries().emplace_back( + std::make_unique<spi::DocEntry>( spi::Timestamp(1000 + i), spi::NONE, - document::Document::UP(_documents[i]->clone())))); + document::Document::UP(_documents[i]->clone()))); } if (documentCount == _documents.size() || overrideCompleted) { reply->setCompleted(); @@ -437,12 +398,13 @@ VisitorTest::sendGetIterReply(GetIterCommand& cmd, } template <typename T> -std::vector<std::shared_ptr<T> > -VisitorTest::fetchMultipleCommands(DummyStorageLink& link, size_t count) +void +VisitorTest::fetchMultipleCommands(DummyStorageLink& link, size_t count, + std::vector<std::shared_ptr<T>>& commands_out) { link.waitForMessages(count, 60); std::vector<api::StorageMessage::SP> msgs(link.getCommandsOnce()); - std::vector<std::shared_ptr<T> > fetched; + std::vector<std::shared_ptr<T>> fetched; if (msgs.size() != count) { std::ostringstream oss; oss << "Expected " @@ -453,38 +415,38 @@ VisitorTest::fetchMultipleCommands(DummyStorageLink& link, size_t count) for (size_t i = 0; i < msgs.size(); ++i) { oss << i << ": " << *msgs[i] << "\n"; } - CPPUNIT_FAIL(oss.str()); + FAIL() << oss.str(); } for (size_t i = 0; i < count; ++i) { - std::shared_ptr<T> ret(std::dynamic_pointer_cast<T>(msgs[i])); + auto ret = std::dynamic_pointer_cast<T>(msgs[i]); if (!ret) { std::ostringstream oss; oss << "Expected message of type " << typeid(T).name() << ", but got " << msgs[0]->toString(); - CPPUNIT_FAIL(oss.str()); + FAIL() << oss.str(); } fetched.push_back(ret); } - return fetched; + commands_out = std::move(fetched); } template <typename T> -std::shared_ptr<T> -VisitorTest::fetchSingleCommand(DummyStorageLink& link) +void +VisitorTest::fetchSingleCommand(DummyStorageLink& link, std::shared_ptr<T>& msg_out) { - std::vector<std::shared_ptr<T> > ret( - fetchMultipleCommands<T>(link, 1)); - return ret[0]; + std::vector<std::shared_ptr<T>> ret; + ASSERT_NO_FATAL_FAILURE(fetchMultipleCommands<T>(link, 1, ret)); + msg_out = std::move(ret[0]); } std::shared_ptr<api::CreateVisitorCommand> VisitorTest::makeCreateVisitor(const VisitorOptions& options) { api::StorageMessageAddress address("storage", lib::NodeType::STORAGE, 0); - std::shared_ptr<api::CreateVisitorCommand> cmd( - new api::CreateVisitorCommand(makeBucketSpace(), options.visitorType, "testvis", "")); + auto cmd = std::make_shared<api::CreateVisitorCommand>( + makeBucketSpace(), options.visitorType, "testvis", ""); cmd->addBucketToBeVisited(document::BucketId(16, 3)); cmd->setAddress(address); cmd->setMaximumPendingReplyCount(UINT32_MAX); @@ -496,35 +458,29 @@ VisitorTest::makeCreateVisitor(const VisitorOptions& options) void VisitorTest::sendCreateIteratorReply(uint64_t iteratorId) { - CreateIteratorCommand::SP createCmd( - fetchSingleCommand<CreateIteratorCommand>(*_bottom)); + CreateIteratorCommand::SP createCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<CreateIteratorCommand>(*_bottom, createCmd)); spi::IteratorId id(iteratorId); - api::StorageReply::SP reply( - new CreateIteratorReply(*createCmd, id)); + auto reply = std::make_shared<CreateIteratorReply>(*createCmd, id); _bottom->sendUp(reply); } -void -VisitorTest::testNormalUsage() -{ - initializeTest(); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); +TEST_F(VisitorTest, normal_usage) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); + auto cmd = makeCreateVisitor(); _top->sendDown(cmd); - CreateIteratorCommand::SP createCmd( - fetchSingleCommand<CreateIteratorCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(static_cast<int>(DefaultPriority), - static_cast<int>(createCmd->getPriority())); // Inherit pri + CreateIteratorCommand::SP createCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<CreateIteratorCommand>(*_bottom, createCmd)); + ASSERT_EQ(static_cast<int>(DefaultPriority), + static_cast<int>(createCmd->getPriority())); // Inherit pri spi::IteratorId id(1234); - api::StorageReply::SP reply( - new CreateIteratorReply(*createCmd, id)); + auto reply = std::make_shared<CreateIteratorReply>(*createCmd, id); _bottom->sendUp(reply); - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd); @@ -532,76 +488,64 @@ VisitorTest::testNormalUsage() std::vector<document::DocumentId> docIds; std::vector<std::string> infoMessages; getMessagesAndReply(_documents.size(), getSession(0), docs, docIds, infoMessages); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); - CPPUNIT_ASSERT_EQUAL(size_t(0), docIds.size()); + ASSERT_EQ(0, infoMessages.size()); + ASSERT_EQ(0, docIds.size()); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply(api::ReturnCode::OK); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); - CPPUNIT_ASSERT_EQUAL(INT64_C(0), getFailedVisitorDestinationReplyCount()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); + ASSERT_EQ(0, getFailedVisitorDestinationReplyCount()); } -void -VisitorTest::testFailedCreateIterator() -{ - initializeTest(); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); +TEST_F(VisitorTest, failed_create_iterator) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); + auto cmd = makeCreateVisitor(); cmd->addBucketToBeVisited(document::BucketId(16, 4)); _top->sendDown(cmd); - CreateIteratorCommand::SP createCmd( - fetchSingleCommand<CreateIteratorCommand>(*_bottom)); + CreateIteratorCommand::SP createCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<CreateIteratorCommand>(*_bottom, createCmd)); spi::IteratorId id(0); - api::StorageReply::SP reply( - new CreateIteratorReply(*createCmd, id)); + auto reply = std::make_shared<CreateIteratorReply>(*createCmd, id); reply->setResult(api::ReturnCode(api::ReturnCode::INTERNAL_FAILURE)); _bottom->sendUp(reply); - verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE, 0, 0); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE, 0, 0)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } -void -VisitorTest::testFailedGetIter() -{ - initializeTest(); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); +TEST_F(VisitorTest, failed_get_iter) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); + auto cmd = makeCreateVisitor(); _top->sendDown(cmd); sendCreateIteratorReply(); - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::BUCKET_NOT_FOUND)); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply(api::ReturnCode::BUCKET_NOT_FOUND, 0, 0); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::BUCKET_NOT_FOUND, 0, 0)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } -void -VisitorTest::testDocumentAPIClientError() -{ +TEST_F(VisitorTest, document_api_client_error) { initializeTest(); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); + auto cmd = makeCreateVisitor(); _top->sendDown(cmd); sendCreateIteratorReply(); { - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 1); } @@ -612,40 +556,36 @@ VisitorTest::testDocumentAPIClientError() getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::INTERNAL_FAILURE); // INTERNAL_FAILURE is critical, so no visitor info sent - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); std::this_thread::sleep_for(100ms); { - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd); } - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } -void -VisitorTest::testNoDocumentAPIResendingForFailedVisitor() -{ - initializeTest(); +TEST_F(VisitorTest, no_document_api_resending_for_failed_visitor) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); std::shared_ptr<api::CreateVisitorCommand> cmd( makeCreateVisitor()); _top->sendDown(cmd); sendCreateIteratorReply(); { - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 2, true); } @@ -658,50 +598,44 @@ VisitorTest::testNoDocumentAPIResendingForFailedVisitor() // should cause the entire visitor to fail. getMessagesAndReply(3, getSession(0), docs, docIds, infoMessages, api::ReturnCode::NOT_CONNECTED); - CPPUNIT_ASSERT_EQUAL(size_t(1), infoMessages.size()); - CPPUNIT_ASSERT_EQUAL( - std::string("[From content node 0] NOT_CONNECTED: Generic error"), - infoMessages[0]); + ASSERT_EQ(1, infoMessages.size()); + EXPECT_EQ("[From content node 0] NOT_CONNECTED: Generic error", + infoMessages[0]); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply(api::ReturnCode::NOT_CONNECTED); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); - CPPUNIT_ASSERT_EQUAL(INT64_C(3), getFailedVisitorDestinationReplyCount()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::NOT_CONNECTED)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); + ASSERT_EQ(3, getFailedVisitorDestinationReplyCount()); } -void -VisitorTest::testIteratorCreatedForFailedVisitor() -{ +TEST_F(VisitorTest, iterator_created_for_failed_visitor) { initializeTest(TestParams().parallelBuckets(2)); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); + auto cmd = makeCreateVisitor(); cmd->addBucketToBeVisited(document::BucketId(16, 4)); _top->sendDown(cmd); - std::vector<CreateIteratorCommand::SP> createCmds( - fetchMultipleCommands<CreateIteratorCommand>(*_bottom, 2)); + std::vector<CreateIteratorCommand::SP> createCmds; + ASSERT_NO_FATAL_FAILURE(fetchMultipleCommands<CreateIteratorCommand>(*_bottom, 2, createCmds)); { spi::IteratorId id(0); - api::StorageReply::SP reply( - new CreateIteratorReply(*createCmds[0], id)); + auto reply = std::make_shared<CreateIteratorReply>(*createCmds[0], id); reply->setResult(api::ReturnCode(api::ReturnCode::INTERNAL_FAILURE)); _bottom->sendUp(reply); } { spi::IteratorId id(1234); - api::StorageReply::SP reply( - new CreateIteratorReply(*createCmds[1], id)); + auto reply = std::make_shared<CreateIteratorReply>(*createCmds[1], id); _bottom->sendUp(reply); } // Want to immediately receive destroyiterator for newly created // iterator, since we cannot use it anyway when the visitor has failed. - DestroyIteratorCommand::SP destroyCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyCmd)); - verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE, 0, 0); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::INTERNAL_FAILURE, 0, 0)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } /** @@ -710,62 +644,55 @@ VisitorTest::testIteratorCreatedForFailedVisitor() * and the visitor terminates cleanly without counting the failed message * as pending. */ -void -VisitorTest::testFailedDocumentAPISend() -{ - initializeTest(TestParams().autoReplyError( +TEST_F(VisitorTest, failed_document_api_send) { + ASSERT_NO_FATAL_FAILURE(initializeTest(TestParams().autoReplyError( mbus::Error(mbus::ErrorCode::HANDSHAKE_FAILED, - "abandon ship!"))); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); + "abandon ship!")))); + auto cmd = makeCreateVisitor(); cmd->addBucketToBeVisited(document::BucketId(16, 4)); _top->sendDown(cmd); sendCreateIteratorReply(); - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); - CPPUNIT_ASSERT_EQUAL(spi::IteratorId(1234), - getIterCmd->getIteratorId()); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); + ASSERT_EQ(spi::IteratorId(1234), getIterCmd->getIteratorId()); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 2, true); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply( + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply( static_cast<api::ReturnCode::Result>( mbus::ErrorCode::HANDSHAKE_FAILED), 0, - 0); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + 0)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); // We currently don't count failures to send in this metric; send failures // indicate a message bus problem and already log a warning when they happen - CPPUNIT_ASSERT_EQUAL(INT64_C(0), getFailedVisitorDestinationReplyCount()); + ASSERT_EQ(0, getFailedVisitorDestinationReplyCount()); } void VisitorTest::sendInitialCreateVisitorAndGetIterRound() { - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); + auto cmd = makeCreateVisitor(); _top->sendDown(cmd); sendCreateIteratorReply(); { - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 1, true); } } -void -VisitorTest::testNoVisitorNotificationForTransientFailures() -{ - initializeTest(); - sendInitialCreateVisitorAndGetIterRound(); +TEST_F(VisitorTest, no_visitor_notification_for_transient_failures) { + ASSERT_NO_FATAL_FAILURE(initializeTest()); + ASSERT_NO_FATAL_FAILURE(sendInitialCreateVisitorAndGetIterRound()); std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; @@ -776,41 +703,40 @@ VisitorTest::testNoVisitorNotificationForTransientFailures() // Should not get info message for BUCKET_DELETED, but resend of Put. getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::BUCKET_DELETED); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); // Should not get info message for BUCKET_NOT_FOUND, but resend of Put. getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::BUCKET_NOT_FOUND); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); // MessageBus error codes guaranteed to fit in return code result. // Should not get info message for SESSION_BUSY, but resend of Put. getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, static_cast<api::ReturnCode::Result>( mbus::ErrorCode::SESSION_BUSY)); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); // WRONG_DISTRIBUTION should not be reported, as it will happen all the // time when initiating remote migrations et al. getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::WRONG_DISTRIBUTION); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); // Complete message successfully to finish the visitor. getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::OK); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); - fetchSingleCommand<DestroyIteratorCommand>(*_bottom); + DestroyIteratorCommand::SP cmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, cmd)); - verifyCreateVisitorReply(api::ReturnCode::OK); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } -void -VisitorTest::testNotificationSentIfTransientErrorRetriedManyTimes() -{ +TEST_F(VisitorTest, notification_sent_if_transient_error_retried_many_times) { constexpr size_t retries( Visitor::TRANSIENT_ERROR_RETRIES_BEFORE_NOTIFY); - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); sendInitialCreateVisitorAndGetIterRound(); std::vector<document::Document::SP> docs; @@ -822,31 +748,33 @@ VisitorTest::testNotificationSentIfTransientErrorRetriedManyTimes() for (size_t attempt = 0; attempt < retries; ++attempt) { getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages, api::ReturnCode::WRONG_DISTRIBUTION); - CPPUNIT_ASSERT_EQUAL(size_t(0), infoMessages.size()); + ASSERT_EQ(0, infoMessages.size()); } // Should now have a client notification along for the ride. // This has to be ACKed as OK or the visitor will fail. getMessagesAndReply(2, getSession(0), docs, docIds, infoMessages, api::ReturnCode::OK); - CPPUNIT_ASSERT_EQUAL(size_t(1), infoMessages.size()); + ASSERT_EQ(1, infoMessages.size()); // TODO(vekterli) ideally we'd want to test that this happens only once // per message, but this seems frustratingly complex to do currently. - fetchSingleCommand<DestroyIteratorCommand>(*_bottom); + DestroyIteratorCommand::SP cmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, cmd)); - verifyCreateVisitorReply(api::ReturnCode::OK); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } -std::shared_ptr<api::CreateVisitorReply> +void VisitorTest::doCompleteVisitingSession( - const std::shared_ptr<api::CreateVisitorCommand>& cmd) + const std::shared_ptr<api::CreateVisitorCommand>& cmd, + std::shared_ptr<api::CreateVisitorReply>& reply_out) { initializeTest(); _top->sendDown(cmd); sendCreateIteratorReply(); - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 1, @@ -857,50 +785,44 @@ VisitorTest::doCompleteVisitingSession( std::vector<std::string> infoMessages; getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); _top->waitForMessages(1, 60); const msg_ptr_vector replies = _top->getRepliesOnce(); - CPPUNIT_ASSERT_EQUAL(size_t(1), replies.size()); + ASSERT_EQ(1, replies.size()); std::shared_ptr<api::StorageMessage> msg(replies[0]); - CPPUNIT_ASSERT_EQUAL(api::MessageType::VISITOR_CREATE_REPLY, - msg->getType()); - return std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); + ASSERT_EQ(api::MessageType::VISITOR_CREATE_REPLY, msg->getType()); + reply_out = std::dynamic_pointer_cast<api::CreateVisitorReply>(msg); } -void -VisitorTest::testNoMbusTracingIfTraceLevelIsZero() -{ +TEST_F(VisitorTest, no_mbus_tracing_if_trace_level_is_zero) { std::shared_ptr<api::CreateVisitorCommand> cmd(makeCreateVisitor()); cmd->getTrace().setLevel(0); - auto reply = doCompleteVisitingSession(cmd); - CPPUNIT_ASSERT(reply->getTrace().getRoot().isEmpty()); + std::shared_ptr<api::CreateVisitorReply> reply; + ASSERT_NO_FATAL_FAILURE(doCompleteVisitingSession(cmd, reply)); + EXPECT_TRUE(reply->getTrace().getRoot().isEmpty()); } -void -VisitorTest::testReplyContainsTraceIfTraceLevelAboveZero() -{ +TEST_F(VisitorTest, reply_contains_trace_if_trace_level_above_zero) { std::shared_ptr<api::CreateVisitorCommand> cmd(makeCreateVisitor()); cmd->getTrace().setLevel(1); - auto reply = doCompleteVisitingSession(cmd); - CPPUNIT_ASSERT(!reply->getTrace().getRoot().isEmpty()); + std::shared_ptr<api::CreateVisitorReply> reply; + ASSERT_NO_FATAL_FAILURE(doCompleteVisitingSession(cmd, reply)); + EXPECT_FALSE(reply->getTrace().getRoot().isEmpty()); } -void -VisitorTest::testNoMoreIteratorsSentWhileMemoryUsedAboveLimit() -{ +TEST_F(VisitorTest, no_more_iterators_sent_while_memory_used_above_limit) { initializeTest(TestParams().maxVisitorMemoryUsage(1) .parallelBuckets(1)); - std::shared_ptr<api::CreateVisitorCommand> cmd( - makeCreateVisitor()); + auto cmd = makeCreateVisitor(); _top->sendDown(cmd); sendCreateIteratorReply(); - GetIterCommand::SP getIterCmd( - fetchSingleCommand<GetIterCommand>(*_bottom)); + GetIterCommand::SP getIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 1); @@ -914,7 +836,7 @@ VisitorTest::testNoMoreIteratorsSentWhileMemoryUsedAboveLimit() // kind of explicit barrier with which we can synchronize the test and the // running visitor thread. std::this_thread::sleep_for(100ms); - CPPUNIT_ASSERT_EQUAL(size_t(0), _bottom->getNumCommands()); + ASSERT_EQ(0, _bottom->getNumCommands()); std::vector<document::Document::SP> docs; std::vector<document::DocumentId> docIds; @@ -922,7 +844,7 @@ VisitorTest::testNoMoreIteratorsSentWhileMemoryUsedAboveLimit() getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages); // 2nd round of GetIter now allowed. Send reply indicating completion. - getIterCmd = fetchSingleCommand<GetIterCommand>(*_bottom); + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<GetIterCommand>(*_bottom, getIterCmd)); sendGetIterReply(*getIterCmd, api::ReturnCode(api::ReturnCode::OK), 1, @@ -930,11 +852,11 @@ VisitorTest::testNoMoreIteratorsSentWhileMemoryUsedAboveLimit() getMessagesAndReply(1, getSession(0), docs, docIds, infoMessages); - DestroyIteratorCommand::SP destroyIterCmd( - fetchSingleCommand<DestroyIteratorCommand>(*_bottom)); + DestroyIteratorCommand::SP destroyIterCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<DestroyIteratorCommand>(*_bottom, destroyIterCmd)); - verifyCreateVisitorReply(api::ReturnCode::OK); - CPPUNIT_ASSERT(waitUntilNoActiveVisitors()); + ASSERT_NO_FATAL_FAILURE(verifyCreateVisitorReply(api::ReturnCode::OK)); + ASSERT_TRUE(waitUntilNoActiveVisitors()); } void @@ -942,19 +864,17 @@ VisitorTest::doTestVisitorInstanceHasConsistencyLevel( vespalib::stringref visitorType, spi::ReadConsistency expectedConsistency) { - initializeTest(); + ASSERT_NO_FATAL_FAILURE(initializeTest()); std::shared_ptr<api::CreateVisitorCommand> cmd( makeCreateVisitor(VisitorOptions().withVisitorType(visitorType))); _top->sendDown(cmd); - auto createCmd = fetchSingleCommand<CreateIteratorCommand>(*_bottom); - CPPUNIT_ASSERT_EQUAL(expectedConsistency, - createCmd->getReadConsistency()); + CreateIteratorCommand::SP createCmd; + ASSERT_NO_FATAL_FAILURE(fetchSingleCommand<CreateIteratorCommand>(*_bottom, createCmd)); + ASSERT_EQ(expectedConsistency, createCmd->getReadConsistency()); } -void -VisitorTest::testDumpVisitorInvokesStrongReadConsistencyIteration() -{ +TEST_F(VisitorTest, dump_visitor_invokes_strong_read_consistency_iteration) { doTestVisitorInstanceHasConsistencyLevel( "dumpvisitor", spi::ReadConsistency::STRONG); } @@ -965,9 +885,7 @@ VisitorTest::testDumpVisitorInvokesStrongReadConsistencyIteration() // any external client use cases. Our primary concern is to test that each // visitor subclass might report its own read consistency requirement and that // this is carried along to the CreateIteratorCommand. -void -VisitorTest::testTestVisitorInvokesWeakReadConsistencyIteration() -{ +TEST_F(VisitorTest, test_visitor_invokes_weak_read_consistency_iteration) { doTestVisitorInstanceHasConsistencyLevel( "testvisitor", spi::ReadConsistency::WEAK); } |