summaryrefslogtreecommitdiff
path: root/src/mongo/client
diff options
context:
space:
mode:
authorBilly Donahue <billy.donahue@mongodb.com>2020-10-23 05:00:11 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-10-24 03:38:42 +0000
commitd7da6ab29e45b3ab22652e12bb524d966511ebf8 (patch)
treef4902f66a43a090dfc735592f1d4afe552f4d96e /src/mongo/client
parent2792042b5a81b2f4969243187e5fd9b41325c85f (diff)
downloadmongo-d7da6ab29e45b3ab22652e12bb524d966511ebf8.tar.gz
SERVER-51814 adaptForAssert: fix sdam/ ASSERT streaming
Diffstat (limited to 'src/mongo/client')
-rw-r--r--src/mongo/client/sdam/sdam_test_base.h170
-rw-r--r--src/mongo/client/sdam/server_description_test.cpp7
-rw-r--r--src/mongo/client/sdam/server_selector_test.cpp3
-rw-r--r--src/mongo/client/sdam/topology_description_test.cpp22
-rw-r--r--src/mongo/client/sdam/topology_manager_test.cpp2
-rw-r--r--src/mongo/client/sdam/topology_state_machine_test.cpp19
6 files changed, 139 insertions, 84 deletions
diff --git a/src/mongo/client/sdam/sdam_test_base.h b/src/mongo/client/sdam/sdam_test_base.h
index 3532e0588b7..eb2ecebfcdc 100644
--- a/src/mongo/client/sdam/sdam_test_base.h
+++ b/src/mongo/client/sdam/sdam_test_base.h
@@ -28,6 +28,8 @@
*/
#pragma once
+#include <array>
+#include <iterator>
#include <map>
#include <ostream>
#include <set>
@@ -37,82 +39,142 @@
#include "mongo/client/sdam/sdam_datatypes.h"
#include "mongo/client/sdam/server_description.h"
-
+#include "mongo/unittest/unittest.h"
/**
* The following facilitates writing tests in the Server Discovery And Monitoring (sdam) namespace.
*/
-namespace mongo {
+namespace mongo::sdam {
+
+namespace test_stream_extension {
+
+template <typename T>
+struct IsStdVector : std::false_type {};
+template <typename... Ts>
+struct IsStdVector<std::vector<Ts...>> : std::true_type {};
+
+template <typename T>
+struct IsStdSet : std::false_type {};
+template <typename... Ts>
+struct IsStdSet<std::set<Ts...>> : std::true_type {};
+
+template <typename T>
+struct IsStdMap : std::false_type {};
+template <typename... Ts>
+struct IsStdMap<std::map<Ts...>> : std::true_type {};
+
template <typename T>
-std::ostream& operator<<(std::ostream& os, const std::vector<T>& s) {
- os << "[";
- size_t i = 0;
- for (const auto& item : s) {
- os << item;
- if (i != s.size() - 1)
+struct IsStdPair : std::false_type {};
+template <typename... Ts>
+struct IsStdPair<std::pair<Ts...>> : std::true_type {};
+
+template <typename T>
+struct IsBoostOptional : std::false_type {};
+template <typename... Ts>
+struct IsBoostOptional<boost::optional<Ts...>> : std::true_type {};
+
+template <typename T>
+std::ostream& stream(std::ostream& os, const T& v);
+
+template <typename Seq>
+std::ostream& streamSequence(std::ostream& os, std::array<StringData, 2> braces, const Seq& seq) {
+ bool sep = false;
+ os << braces[0];
+ for (const auto& item : seq) {
+ if (sep)
os << ", ";
+ sep = true;
+ stream(os, item);
}
- os << "]";
+ os << braces[1];
return os;
}
template <typename T>
-std::ostream& operator<<(std::ostream& os, const std::set<T>& s) {
- os << "{";
- size_t i = 0;
- for (const auto& item : s) {
- os << item;
- if (i != s.size() - 1)
- os << ", ";
+struct Extension {
+ const T& operator*() const {
+ return v;
}
- os << "}";
- return os;
-}
-template <typename K, typename V>
-std::ostream& operator<<(std::ostream& os, const std::map<K, V>& m) {
- os << "{";
- size_t i = 0;
- for (const auto& item : m) {
- os << item.first << ": " << item.second;
- if (i != m.size() - 1)
- os << ", ";
+ template <typename U>
+ friend bool operator==(const Extension& a, const Extension<U>& b) {
+ return *a == *b;
+ }
+ template <typename U>
+ friend bool operator!=(const Extension& a, const Extension<U>& b) {
+ return *a != *b;
+ }
+ template <typename U>
+ friend bool operator<(const Extension& a, const Extension<U>& b) {
+ return *a < *b;
+ }
+ template <typename U>
+ friend bool operator>(const Extension& a, const Extension<U>& b) {
+ return *a > *b;
+ }
+ template <typename U>
+ friend bool operator<=(const Extension& a, const Extension<U>& b) {
+ return *a <= *b;
+ }
+ template <typename U>
+ friend bool operator>=(const Extension& a, const Extension<U>& b) {
+ return *a >= *b;
+ }
+
+ friend std::ostream& operator<<(std::ostream& os, const Extension& ext) {
+ return stream(os, *ext);
+ }
+
+ const T& v;
+};
+
+template <typename T>
+std::ostream& stream(std::ostream& os, const T& v) {
+ if constexpr (IsStdVector<T>{}) {
+ return streamSequence(os, {"[", "]"}, v);
+ } else if constexpr (IsStdSet<T>{}) {
+ return streamSequence(os, {"{", "}"}, v);
+ } else if constexpr (IsStdMap<T>{}) {
+ return streamSequence(os, {"{", "}"}, v);
+ } else if constexpr (IsStdPair<T>{}) {
+ stream(os, v.first);
+ os << ": ";
+ stream(os, v.second);
+ return os;
+ } else if constexpr (IsBoostOptional<T>{}) {
+ if (!v)
+ return os << boost::optional<Extension<T>>{};
+ return os << boost::optional<Extension<T>>{Extension<T>{*v}};
+ } else {
+ return os << v;
}
- os << "}";
- return os;
}
-template std::ostream& operator<<(std::ostream& os,
- const std::vector<mongo::sdam::ServerDescriptionPtr>& v);
-template std::ostream& operator<<(std::ostream& os, const std::set<std::string>& s);
-template std::ostream& operator<<(std::ostream& os, const std::map<std::string, std::string>& m);
-}; // namespace mongo
+} // namespace test_stream_extension
-// We include this here because the ASSERT_EQUALS needs to have the operator<< defined
-// beforehand for the types used in the tests.
-#include "mongo/unittest/unittest.h"
-namespace mongo {
-namespace sdam {
-using mongo::operator<<;
+/**
+ * Facade for use in ASSERTions. Presents pass-through relational ops and custom streaming
+ * behavior around arbitrary object `v`.
+ */
+template <typename T>
+auto adaptForAssert(const T& v) {
+ return test_stream_extension::Extension<T>{v};
+}
-class SdamTestFixture : public mongo::unittest::Test {
+class SdamTestFixture : public unittest::Test {
protected:
- template <typename T, typename U>
- std::vector<U> map(std::vector<T> source, std::function<U(const T&)> f) {
+ template <typename T, typename F, typename U = std::invoke_result_t<F, T>>
+ std::vector<U> map(const std::vector<T>& source, const F& f) {
std::vector<U> result;
- std::transform(source.begin(),
- source.end(),
- std::back_inserter(result),
- [f](const auto& item) { return f(item); });
+ std::transform(source.begin(), source.end(), std::back_inserter(result), f);
return result;
}
- template <typename T, typename U>
- std::set<U> mapSet(std::vector<T> source, std::function<U(const T&)> f) {
- auto v = map<T, U>(source, f);
- std::set<U> result(v.begin(), v.end());
- return result;
+ template <typename T, typename F, typename U = std::invoke_result_t<F, T>>
+ std::set<U> mapSet(const std::vector<T>& source, const F& f) {
+ auto v = map(source, f);
+ return std::set<U>(v.begin(), v.end());
}
};
-} // namespace sdam
-} // namespace mongo
+
+} // namespace mongo::sdam
diff --git a/src/mongo/client/sdam/server_description_test.cpp b/src/mongo/client/sdam/server_description_test.cpp
index c6dc8053e11..eac743ed6f5 100644
--- a/src/mongo/client/sdam/server_description_test.cpp
+++ b/src/mongo/client/sdam/server_description_test.cpp
@@ -39,6 +39,7 @@
#include "mongo/db/repl/optime.h"
#include "mongo/platform/random.h"
#include "mongo/unittest/unittest.h"
+#include "mongo/util/str.h"
#include "mongo/util/system_clock_source.h"
namespace mongo::sdam {
@@ -212,8 +213,7 @@ class ServerDescriptionTestFixture : public SdamTestFixture {
protected:
// returns a set containing the elements in the given bson array with lowercase values.
std::set<std::string> toHostSet(std::vector<BSONElement> bsonArray) {
- return mapSet<BSONElement, std::string>(
- bsonArray, [](const BSONElement& e) { return boost::to_lower_copy(e.String()); });
+ return mapSet(bsonArray, [](const BSONElement& e) { return str::toLower(e.String()); });
}
std::map<std::string, std::string> toStringMap(BSONObj bsonObj) {
@@ -466,7 +466,8 @@ TEST_F(ServerDescriptionTestFixture, ShouldStoreTags) {
auto response = HelloOutcome(
HostAndPort("foo:1234"), kBsonTags, duration_cast<HelloRTT>(mongo::Milliseconds(40)));
auto description = ServerDescription(clockSource, response);
- ASSERT_EQUALS(toStringMap(kBsonTags["tags"].Obj()), description.getTags());
+ ASSERT_EQUALS(adaptForAssert(toStringMap(kBsonTags["tags"].Obj())),
+ adaptForAssert(description.getTags()));
}
TEST_F(ServerDescriptionTestFixture, ShouldStoreSetVersionAndName) {
diff --git a/src/mongo/client/sdam/server_selector_test.cpp b/src/mongo/client/sdam/server_selector_test.cpp
index 5e8ed5f2837..0c0688f03fe 100644
--- a/src/mongo/client/sdam/server_selector_test.cpp
+++ b/src/mongo/client/sdam/server_selector_test.cpp
@@ -180,7 +180,8 @@ TEST_F(ServerSelectorTestFixture, ShouldThrowOnWireError) {
TEST_F(ServerSelectorTestFixture, ShouldReturnNoneIfTopologyUnknown) {
auto topologyDescription = std::make_shared<TopologyDescription>(sdamConfiguration);
ASSERT_EQ(TopologyType::kUnknown, topologyDescription->getType());
- ASSERT_EQ(boost::none, selector.selectServers(topologyDescription, ReadPreferenceSetting()));
+ ASSERT_EQ(adaptForAssert(boost::none),
+ adaptForAssert(selector.selectServers(topologyDescription, ReadPreferenceSetting())));
}
TEST_F(ServerSelectorTestFixture, ShouldBeAbleToSelectWithMaxStalenessFromClonedTopology) {
diff --git a/src/mongo/client/sdam/topology_description_test.cpp b/src/mongo/client/sdam/topology_description_test.cpp
index 6e93291b255..537f70e9e20 100644
--- a/src/mongo/client/sdam/topology_description_test.cpp
+++ b/src/mongo/client/sdam/topology_description_test.cpp
@@ -41,15 +41,12 @@
#include "mongo/unittest/death_test.h"
namespace mongo {
-template std::ostream& operator<<(std::ostream& os, const std::vector<HostAndPort>& s);
bool operator==(const TopologyVersion& a, const TopologyVersion& b) {
return a.getProcessId() == b.getProcessId() && a.getCounter() == b.getCounter();
}
namespace sdam {
-using mongo::operator<<;
-
class TopologyDescriptionTestFixture : public SdamTestFixture {
protected:
@@ -106,7 +103,7 @@ TEST_F(TopologyDescriptionTestFixture, ShouldHaveCorrectDefaultValues) {
//
// auto expectedAddresses = kTwoServersNormalCase;
//
-// auto serverAddresses = map<ServerDescriptionPtr, HostAndPort>(
+// auto serverAddresses = map(
// topologyDescription.getServers(),
// [](const ServerDescriptionPtr& description) { return description->getAddress(); });
//
@@ -118,10 +115,9 @@ TEST_F(TopologyDescriptionTestFixture, ShouldAllowTypeSingleWithASingleSeed) {
ASSERT(TopologyType::kSingle == topologyDescription.getType());
- auto servers = map<ServerDescriptionPtr, HostAndPort>(
- topologyDescription.getServers(),
- [](const ServerDescriptionPtr& desc) { return desc->getAddress(); });
- ASSERT_EQUALS(kOneServer, servers);
+ auto servers =
+ map(topologyDescription.getServers(), [](const auto& desc) { return desc->getAddress(); });
+ ASSERT_EQUALS(adaptForAssert(kOneServer), adaptForAssert(servers));
}
TEST_F(TopologyDescriptionTestFixture, DoesNotAllowMultipleSeedsWithSingle) {
@@ -244,7 +240,7 @@ TEST_F(TopologyDescriptionTestFixture, ShouldSetLogicalSessionTimeoutToMinOfAllS
const auto logicalSessionTimeouts = std::vector{300, 100, 200};
auto timeoutIt = logicalSessionTimeouts.begin();
- const auto serverDescriptionsWithTimeouts = map<ServerDescriptionPtr, ServerDescriptionPtr>(
+ const auto serverDescriptionsWithTimeouts = map(
topologyDescription->getServers(), [&timeoutIt](const ServerDescriptionPtr& description) {
auto newInstanceBuilder = ServerDescriptionBuilder()
.withType(ServerType::kRSSecondary)
@@ -274,8 +270,8 @@ TEST_F(TopologyDescriptionTestFixture,
const auto logicalSessionTimeouts = std::vector{300, 100, 200};
auto timeoutIt = logicalSessionTimeouts.begin();
- const auto serverDescriptionsWithTimeouts = map<ServerDescriptionPtr, ServerDescriptionPtr>(
- topologyDescription->getServers(), [&](const ServerDescriptionPtr& description) {
+ const auto serverDescriptionsWithTimeouts =
+ map(topologyDescription->getServers(), [&](const ServerDescriptionPtr& description) {
auto timeoutValue = (timeoutIt == logicalSessionTimeouts.begin())
? boost::none
: boost::make_optional(*timeoutIt);
@@ -341,5 +337,5 @@ TEST_F(TopologyDescriptionTestFixture, ShouldNotUpdateTopologyVersionOnError) {
auto topologyVersion = topologyDescription->getServers()[1]->getTopologyVersion();
ASSERT(topologyVersion == boost::none);
}
-}; // namespace sdam
-}; // namespace mongo
+} // namespace sdam
+} // namespace mongo
diff --git a/src/mongo/client/sdam/topology_manager_test.cpp b/src/mongo/client/sdam/topology_manager_test.cpp
index ba1eadaa89f..7b27038d256 100644
--- a/src/mongo/client/sdam/topology_manager_test.cpp
+++ b/src/mongo/client/sdam/topology_manager_test.cpp
@@ -35,10 +35,8 @@
#include "mongo/util/system_clock_source.h"
namespace mongo {
-template std::ostream& operator<<(std::ostream& os, const std::vector<HostAndPort>& s);
namespace sdam {
-using mongo::operator<<;
class TopologyManagerTestFixture : public SdamTestFixture {
protected:
diff --git a/src/mongo/client/sdam/topology_state_machine_test.cpp b/src/mongo/client/sdam/topology_state_machine_test.cpp
index 821d476aade..52a8d52754b 100644
--- a/src/mongo/client/sdam/topology_state_machine_test.cpp
+++ b/src/mongo/client/sdam/topology_state_machine_test.cpp
@@ -184,14 +184,12 @@ TEST_F(TopologyStateMachineTestFixture,
.instance();
ASSERT_EQUALS(static_cast<size_t>(2), topologyDescription->getServers().size());
- auto serversBefore = map<ServerDescriptionPtr, HostAndPort>(topologyDescription->getServers(),
- getServerDescriptionAddress);
+ auto serversBefore = map(topologyDescription->getServers(), getServerDescriptionAddress);
stateMachine.onServerDescription(*topologyDescription, serverDescription);
- auto serversAfter = map<ServerDescriptionPtr, HostAndPort>(topologyDescription->getServers(),
- getServerDescriptionAddress);
- ASSERT_EQUALS(serversBefore, serversAfter);
+ auto serversAfter = map(topologyDescription->getServers(), getServerDescriptionAddress);
+ ASSERT_EQUALS(adaptForAssert(serversBefore), adaptForAssert(serversAfter));
}
TEST_F(TopologyStateMachineTestFixture,
@@ -259,15 +257,14 @@ TEST_F(TopologyStateMachineTestFixture,
ASSERT_EQUALS(topologyDescription->getType(), TopologyType::kReplicaSetWithPrimary);
ASSERT_EQUALS(static_cast<size_t>(2), topologyDescription->getServers().size());
- auto serversBefore = map<ServerDescriptionPtr, HostAndPort>(topologyDescription->getServers(),
- getServerDescriptionAddress);
+ auto serversBefore = map(topologyDescription->getServers(), getServerDescriptionAddress);
stateMachine.onServerDescription(*topologyDescription, serverDescription);
- ASSERT_EQUALS(topologyDescription->getType(), TopologyType::kReplicaSetWithPrimary);
+ ASSERT_EQUALS(adaptForAssert(topologyDescription->getType()),
+ adaptForAssert(TopologyType::kReplicaSetWithPrimary));
- auto serversAfter = map<ServerDescriptionPtr, HostAndPort>(topologyDescription->getServers(),
- getServerDescriptionAddress);
- ASSERT_EQUALS(serversBefore, serversAfter);
+ auto serversAfter = map(topologyDescription->getServers(), getServerDescriptionAddress);
+ ASSERT_EQUALS(adaptForAssert(serversBefore), adaptForAssert(serversAfter));
}
TEST_F(TopologyStateMachineTestFixture,