blob: f7058306275da00114cc2b993e7cbf20cdf2382d [file] [log] [blame]
// 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