diff options
author | Tor Brede Vekterli <vekterli@yahooinc.com> | 2023-04-20 11:53:36 +0000 |
---|---|---|
committer | Tor Brede Vekterli <vekterli@yahooinc.com> | 2023-04-20 12:04:12 +0000 |
commit | 53dc081d48be4f5850f4b609e6a031c014ae6425 (patch) | |
tree | e32eb4e17709beef33acdccbb2b912b8a15aa365 | |
parent | b78746c2f8cac3e87b79ca362acb57c0a5d9f4df (diff) |
Add NewestReplica equality tests and gmock matcher for distinct elements in a range
Add a new `matchers` directory in vespalib which can be used as a repository for
generic, reusable GMock matchers.
Move distributor tests from using an explicit gtest runner to using `GTest::gmock_main`
which serves the same purpose. Need to depend on a gmock target (not just gtest) to
be able to link with stuff required for matchers.
4 files changed, 61 insertions, 10 deletions
diff --git a/storage/src/tests/distributor/CMakeLists.txt b/storage/src/tests/distributor/CMakeLists.txt index c59b56eb68f..11bbf2c241a 100644 --- a/storage/src/tests/distributor/CMakeLists.txt +++ b/storage/src/tests/distributor/CMakeLists.txt @@ -19,7 +19,6 @@ vespa_add_executable(storage_distributor_gtest_runner_app TEST externaloperationhandlertest.cpp garbagecollectiontest.cpp getoperationtest.cpp - gtest_runner.cpp idealstatemanagertest.cpp joinbuckettest.cpp maintenancemocks.cpp @@ -27,6 +26,7 @@ vespa_add_executable(storage_distributor_gtest_runner_app TEST mergelimitertest.cpp mergeoperationtest.cpp multi_thread_stripe_access_guard_test.cpp + newest_replica_test.cpp node_supported_features_repo_test.cpp nodeinfotest.cpp nodemaintenancestatstrackertest.cpp @@ -57,7 +57,7 @@ vespa_add_executable(storage_distributor_gtest_runner_app TEST storage_testcommon storage_testhostreporter storage - GTest::GTest + GTest::gmock_main ) vespa_add_test( diff --git a/storage/src/tests/distributor/gtest_runner.cpp b/storage/src/tests/distributor/gtest_runner.cpp deleted file mode 100644 index 7c20f681093..00000000000 --- a/storage/src/tests/distributor/gtest_runner.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include <vespa/vespalib/gtest/gtest.h> - -#include <vespa/log/log.h> -LOG_SETUP("storage_distributor_gtest_runner"); - -GTEST_MAIN_RUN_ALL_TESTS() diff --git a/storage/src/tests/distributor/newest_replica_test.cpp b/storage/src/tests/distributor/newest_replica_test.cpp new file mode 100644 index 00000000000..9267c6e37a2 --- /dev/null +++ b/storage/src/tests/distributor/newest_replica_test.cpp @@ -0,0 +1,24 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/storage/distributor/operations/external/newest_replica.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <vespa/vespalib/gtest/matchers/elements_are_distinct.h> + +using namespace ::testing; +using storage::api::Timestamp; +using document::BucketId; + +namespace storage::distributor { + +TEST(NewestReplicaTest, equality_predicate_considers_all_fields) { + std::vector elems = { + NewestReplica::of(Timestamp(1000), BucketId(16, 1), 0, false, false), + NewestReplica::of(Timestamp(1001), BucketId(16, 1), 0, false, false), + NewestReplica::of(Timestamp(1000), BucketId(16, 2), 0, false, false), + NewestReplica::of(Timestamp(1000), BucketId(16, 1), 1, false, false), + NewestReplica::of(Timestamp(1000), BucketId(16, 1), 0, true, false), + NewestReplica::of(Timestamp(1000), BucketId(16, 1), 0, false, true) + }; + EXPECT_THAT(elems, ElementsAreDistinct()); +} + +} diff --git a/vespalib/src/vespa/vespalib/gtest/matchers/elements_are_distinct.h b/vespalib/src/vespa/vespalib/gtest/matchers/elements_are_distinct.h new file mode 100644 index 00000000000..374dafbf893 --- /dev/null +++ b/vespalib/src/vespa/vespalib/gtest/matchers/elements_are_distinct.h @@ -0,0 +1,35 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <gtest/gtest.h> +#include <gmock/gmock.h> +#include <ranges> + +/** + * Checks that all elements of a forward iterable range are distinct, i.e. the following must hold: + * - for any single element `foo`, foo == foo is true + * - for any two separate elements `foo` and `bar`, foo == bar is false + */ +MATCHER(ElementsAreDistinct, "") { + const auto& range = arg; + static_assert(std::ranges::forward_range<decltype(range)>); + const auto end = std::ranges::cend(range); + // Explicitly count element positions instead of comparing iterators to avoid depending + // on iterators being comparable with each other. + size_t i = 0; + for (auto lhs = std::ranges::cbegin(range); lhs != end; ++lhs, ++i) { + size_t j = 0; + for (auto rhs = std::ranges::cbegin(range); rhs != end; ++rhs, ++j) { + if (i != j) { + if (*lhs == *rhs) { + *result_listener << "Expected elements to be distinct, but element at position " + << i << " (" << *lhs << ") is equal to element at position " + << j << " (" << *rhs << ")"; + return false; + } + } else if (!(*lhs == *rhs)) { + *result_listener << "Element at position " << i << " (" << *lhs << ") does not equal itself"; + return false; + } + } + } + return true; +} |