235 lines
9.2 KiB
C++
235 lines
9.2 KiB
C++
// Copyright 2022 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
#include "base/allocator/dispatcher/configuration.h"
|
|
#include "base/allocator/dispatcher/initializer.h"
|
|
#include "base/allocator/dispatcher/testing/observer_mock.h"
|
|
#include "base/allocator/dispatcher/testing/tools.h"
|
|
|
|
#include <functional>
|
|
#include <map>
|
|
#include <tuple>
|
|
|
|
namespace base::allocator::dispatcher {
|
|
namespace testing {
|
|
|
|
// A mock Dispatcher for testing. Since Initializer and Dispatcher rely on
|
|
// templating, we can't employ GoogleMocks for mocking. The mock dispatcher
|
|
// records the number of invocations of Initialize for a given tuple of
|
|
// observers.
|
|
struct Dispatcher {
|
|
Dispatcher() = default;
|
|
|
|
~Dispatcher() {
|
|
for (const auto& reset_data : reseter_) {
|
|
reset_data.second();
|
|
}
|
|
}
|
|
|
|
template <typename... Observers>
|
|
void Initialize(const std::tuple<Observers*...>& observers) {
|
|
++total_number_of_inits_;
|
|
++(GetInitCounterForObservers(observers));
|
|
}
|
|
|
|
size_t GetTotalInitCounter() const { return total_number_of_inits_; }
|
|
|
|
template <typename... Observers>
|
|
size_t& GetInitCounterForObservers(
|
|
const std::tuple<Observers*...>& observers) {
|
|
static std::map<std::tuple<Observers*...>, size_t>
|
|
observer_init_counter_map;
|
|
reseter_[&observer_init_counter_map] = []() {
|
|
observer_init_counter_map.clear();
|
|
};
|
|
return observer_init_counter_map[observers];
|
|
}
|
|
|
|
size_t total_number_of_inits_ = 0;
|
|
std::map<void*, std::function<void()>> reseter_;
|
|
};
|
|
} // namespace testing
|
|
|
|
using testing::ObserverMock;
|
|
|
|
struct BaseAllocatorDispatcherInitializerTest : public ::testing::Test {};
|
|
|
|
TEST_F(BaseAllocatorDispatcherInitializerTest, VerifyEmptyInitializer) {
|
|
const auto initializer = CreateInitializer();
|
|
|
|
EXPECT_EQ(initializer.GetOptionalObservers(), std::make_tuple());
|
|
EXPECT_EQ(initializer.GetMandatoryObservers(), std::make_tuple());
|
|
}
|
|
|
|
TEST_F(BaseAllocatorDispatcherInitializerTest, VerifySettingOptionalObservers) {
|
|
ObserverMock<int> optional_observer_1;
|
|
ObserverMock<float> optional_observer_2;
|
|
ObserverMock<size_t> optional_observer_3;
|
|
|
|
auto initializer_1 = CreateInitializer().SetOptionalObservers(
|
|
&optional_observer_1, &optional_observer_2);
|
|
EXPECT_EQ(initializer_1.GetOptionalObservers(),
|
|
std::make_tuple(&optional_observer_1, &optional_observer_2));
|
|
EXPECT_EQ(initializer_1.GetMandatoryObservers(), std::make_tuple());
|
|
|
|
auto initializer_2 = initializer_1.SetOptionalObservers(&optional_observer_3);
|
|
EXPECT_EQ(initializer_2.GetOptionalObservers(),
|
|
std::make_tuple(&optional_observer_3));
|
|
EXPECT_EQ(initializer_2.GetMandatoryObservers(), std::make_tuple());
|
|
|
|
auto initializer_3 = initializer_2.SetOptionalObservers();
|
|
EXPECT_EQ(initializer_3.GetOptionalObservers(), std::make_tuple());
|
|
EXPECT_EQ(initializer_3.GetMandatoryObservers(), std::make_tuple());
|
|
}
|
|
|
|
TEST_F(BaseAllocatorDispatcherInitializerTest, VerifyAddingOptionalObservers) {
|
|
ObserverMock<int> optional_observer_1;
|
|
ObserverMock<float> optional_observer_2;
|
|
ObserverMock<size_t> optional_observer_3;
|
|
|
|
auto initializer_1 = CreateInitializer().AddOptionalObservers(
|
|
&optional_observer_1, &optional_observer_2);
|
|
EXPECT_EQ(initializer_1.GetOptionalObservers(),
|
|
std::make_tuple(&optional_observer_1, &optional_observer_2));
|
|
EXPECT_EQ(initializer_1.GetMandatoryObservers(), std::make_tuple());
|
|
|
|
auto initializer_2 = initializer_1.AddOptionalObservers(&optional_observer_3);
|
|
EXPECT_EQ(initializer_2.GetOptionalObservers(),
|
|
std::make_tuple(&optional_observer_1, &optional_observer_2,
|
|
&optional_observer_3));
|
|
EXPECT_EQ(initializer_2.GetMandatoryObservers(), std::make_tuple());
|
|
|
|
auto initializer_3 = initializer_2.AddOptionalObservers();
|
|
EXPECT_EQ(initializer_3.GetOptionalObservers(),
|
|
std::make_tuple(&optional_observer_1, &optional_observer_2,
|
|
&optional_observer_3));
|
|
EXPECT_EQ(initializer_3.GetMandatoryObservers(), std::make_tuple());
|
|
|
|
auto initializer_4 = initializer_3.SetOptionalObservers();
|
|
EXPECT_EQ(initializer_4.GetOptionalObservers(), std::make_tuple());
|
|
EXPECT_EQ(initializer_4.GetMandatoryObservers(), std::make_tuple());
|
|
}
|
|
|
|
TEST_F(BaseAllocatorDispatcherInitializerTest,
|
|
VerifySettingMandatoryObservers) {
|
|
ObserverMock<int> mandatory_observer_1;
|
|
ObserverMock<float> mandatory_observer_2;
|
|
ObserverMock<size_t> mandatory_observer_3;
|
|
|
|
auto initializer_1 = CreateInitializer().SetMandatoryObservers(
|
|
&mandatory_observer_1, &mandatory_observer_2);
|
|
EXPECT_EQ(initializer_1.GetMandatoryObservers(),
|
|
std::make_tuple(&mandatory_observer_1, &mandatory_observer_2));
|
|
EXPECT_EQ(initializer_1.GetOptionalObservers(), std::make_tuple());
|
|
|
|
auto initializer_2 =
|
|
initializer_1.SetMandatoryObservers(&mandatory_observer_3);
|
|
EXPECT_EQ(initializer_2.GetMandatoryObservers(),
|
|
std::make_tuple(&mandatory_observer_3));
|
|
EXPECT_EQ(initializer_2.GetOptionalObservers(), std::make_tuple());
|
|
|
|
auto initializer_3 = initializer_2.SetMandatoryObservers();
|
|
EXPECT_EQ(initializer_3.GetMandatoryObservers(), std::make_tuple());
|
|
EXPECT_EQ(initializer_3.GetOptionalObservers(), std::make_tuple());
|
|
}
|
|
|
|
TEST_F(BaseAllocatorDispatcherInitializerTest, VerifyAddingMandatoryObservers) {
|
|
ObserverMock<int> mandatory_observer_1;
|
|
ObserverMock<float> mandatory_observer_2;
|
|
ObserverMock<size_t> mandatory_observer_3;
|
|
|
|
auto initializer_1 = CreateInitializer().AddMandatoryObservers(
|
|
&mandatory_observer_1, &mandatory_observer_2);
|
|
EXPECT_EQ(initializer_1.GetMandatoryObservers(),
|
|
std::make_tuple(&mandatory_observer_1, &mandatory_observer_2));
|
|
EXPECT_EQ(initializer_1.GetOptionalObservers(), std::make_tuple());
|
|
|
|
auto initializer_2 =
|
|
initializer_1.AddMandatoryObservers(&mandatory_observer_3);
|
|
EXPECT_EQ(initializer_2.GetMandatoryObservers(),
|
|
std::make_tuple(&mandatory_observer_1, &mandatory_observer_2,
|
|
&mandatory_observer_3));
|
|
EXPECT_EQ(initializer_2.GetOptionalObservers(), std::make_tuple());
|
|
|
|
auto initializer_3 = initializer_2.AddMandatoryObservers();
|
|
EXPECT_EQ(initializer_3.GetMandatoryObservers(),
|
|
std::make_tuple(&mandatory_observer_1, &mandatory_observer_2,
|
|
&mandatory_observer_3));
|
|
EXPECT_EQ(initializer_3.GetOptionalObservers(), std::make_tuple());
|
|
|
|
auto initializer_4 = initializer_3.SetMandatoryObservers();
|
|
EXPECT_EQ(initializer_4.GetMandatoryObservers(), std::make_tuple());
|
|
EXPECT_EQ(initializer_4.GetOptionalObservers(), std::make_tuple());
|
|
}
|
|
|
|
TEST_F(BaseAllocatorDispatcherInitializerTest, VerifyBasicInitialization) {
|
|
ObserverMock<int> optional_observer_1;
|
|
ObserverMock<float> optional_observer_2;
|
|
ObserverMock<size_t> mandatory_observer_1;
|
|
ObserverMock<double> mandatory_observer_2;
|
|
|
|
testing::Dispatcher test_dispatcher;
|
|
|
|
CreateInitializer()
|
|
.SetMandatoryObservers(&mandatory_observer_1, &mandatory_observer_2)
|
|
.SetOptionalObservers(&optional_observer_1, &optional_observer_2)
|
|
.DoInitialize(test_dispatcher);
|
|
|
|
const auto observer_ptrs =
|
|
std::make_tuple(&mandatory_observer_1, &mandatory_observer_2,
|
|
&optional_observer_1, &optional_observer_2);
|
|
|
|
EXPECT_EQ(1ul, test_dispatcher.GetInitCounterForObservers(observer_ptrs));
|
|
}
|
|
|
|
TEST_F(BaseAllocatorDispatcherInitializerTest,
|
|
VerifyInitializationWithMandatoryNullObservers) {
|
|
ObserverMock<int> optional_observer_1;
|
|
ObserverMock<float> optional_observer_2;
|
|
ObserverMock<size_t> mandatory_observer;
|
|
ObserverMock<double>* mandatory_null_observer = nullptr;
|
|
|
|
testing::Dispatcher test_dispatcher;
|
|
|
|
CreateInitializer()
|
|
.SetMandatoryObservers(&mandatory_observer, mandatory_null_observer)
|
|
.SetOptionalObservers(&optional_observer_1, &optional_observer_2)
|
|
.DoInitialize(test_dispatcher);
|
|
|
|
// For mandatory observers being null we expect them to be passed straight
|
|
// down to the dispatcher, which will then perform a check of ALL observers.
|
|
const auto valid_observer_ptrs =
|
|
std::make_tuple(&mandatory_observer, mandatory_null_observer,
|
|
&optional_observer_1, &optional_observer_2);
|
|
|
|
EXPECT_EQ(1ul, test_dispatcher.GetTotalInitCounter());
|
|
EXPECT_EQ(1ul,
|
|
test_dispatcher.GetInitCounterForObservers(valid_observer_ptrs));
|
|
}
|
|
|
|
TEST_F(BaseAllocatorDispatcherInitializerTest,
|
|
VerifyInitializationWithOptionalNullObservers) {
|
|
ObserverMock<int> optional_observer;
|
|
ObserverMock<float>* optional_null_observer = nullptr;
|
|
ObserverMock<size_t> mandatory_observer_1;
|
|
ObserverMock<double> mandatory_observer_2;
|
|
|
|
testing::Dispatcher test_dispatcher;
|
|
|
|
CreateInitializer()
|
|
.SetMandatoryObservers(&mandatory_observer_1, &mandatory_observer_2)
|
|
.SetOptionalObservers(&optional_observer, optional_null_observer)
|
|
.DoInitialize(test_dispatcher);
|
|
|
|
const auto valid_observer_ptrs = std::make_tuple(
|
|
&mandatory_observer_1, &mandatory_observer_2, &optional_observer);
|
|
|
|
EXPECT_EQ(1ul, test_dispatcher.GetTotalInitCounter());
|
|
EXPECT_EQ(1ul,
|
|
test_dispatcher.GetInitCounterForObservers(valid_observer_ptrs));
|
|
}
|
|
|
|
} // namespace base::allocator::dispatcher
|