// 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 #include #include 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 void Initialize(const std::tuple& observers) { ++total_number_of_inits_; ++(GetInitCounterForObservers(observers)); } size_t GetTotalInitCounter() const { return total_number_of_inits_; } template size_t& GetInitCounterForObservers( const std::tuple& observers) { static std::map, 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> 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 optional_observer_1; ObserverMock optional_observer_2; ObserverMock 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 optional_observer_1; ObserverMock optional_observer_2; ObserverMock 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 mandatory_observer_1; ObserverMock mandatory_observer_2; ObserverMock 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 mandatory_observer_1; ObserverMock mandatory_observer_2; ObserverMock 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 optional_observer_1; ObserverMock optional_observer_2; ObserverMock mandatory_observer_1; ObserverMock 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 optional_observer_1; ObserverMock optional_observer_2; ObserverMock mandatory_observer; ObserverMock* 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 optional_observer; ObserverMock* optional_null_observer = nullptr; ObserverMock mandatory_observer_1; ObserverMock 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