| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/memory/swap_metrics_driver_impl.h" |
| |
| #include <memory> |
| |
| #include "base/memory/ptr_util.h" |
| #include "base/test/task_environment.h" |
| #include "base/threading/platform_thread.h" |
| #include "base/time/time.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace content { |
| |
| namespace { |
| |
| // A SwapMetricsDriver that mocks what a platform-dependent driver does, but |
| // with control over when it fails so we can test error conditions. |
| class MockSwapMetricsDriver : public SwapMetricsDriverImpl { |
| public: |
| MockSwapMetricsDriver(std::unique_ptr<Delegate> delegate, |
| const base::TimeDelta update_interval, |
| const bool fail_on_update) |
| : SwapMetricsDriverImpl(std::move(delegate), update_interval), |
| fail_on_update_(fail_on_update) {} |
| |
| ~MockSwapMetricsDriver() override = default; |
| |
| protected: |
| SwapMetricsDriver::SwapMetricsUpdateResult UpdateMetricsInternal( |
| base::TimeDelta interval) override { |
| if (fail_on_update_) |
| return SwapMetricsDriver::SwapMetricsUpdateResult:: |
| kSwapMetricsUpdateFailed; |
| |
| if (interval.is_zero()) |
| return SwapMetricsDriver::SwapMetricsUpdateResult:: |
| kSwapMetricsUpdateSuccess; |
| |
| delegate_->OnSwapInCount(0, interval); |
| delegate_->OnSwapOutCount(0, interval); |
| delegate_->OnDecompressedPageCount(0, interval); |
| delegate_->OnCompressedPageCount(0, interval); |
| |
| return SwapMetricsDriver::SwapMetricsUpdateResult:: |
| kSwapMetricsUpdateSuccess; |
| } |
| |
| private: |
| bool fail_on_update_; |
| }; |
| |
| // A SwapMetricsDriver::Delegate that counts the number of updates for each |
| // metric. |
| class SwapMetricsDelegateCounter : public SwapMetricsDriver::Delegate { |
| public: |
| SwapMetricsDelegateCounter() |
| : num_swap_in_updates_(0), |
| num_swap_out_updates_(0), |
| num_decompressed_updates_(0), |
| num_compressed_updates_(0), |
| num_updates_failed_(0) {} |
| |
| ~SwapMetricsDelegateCounter() override = default; |
| |
| void OnSwapInCount(uint64_t count, base::TimeDelta interval) override { |
| ++num_swap_in_updates_; |
| } |
| |
| void OnSwapOutCount(uint64_t count, base::TimeDelta interval) override { |
| ++num_swap_out_updates_; |
| } |
| |
| void OnDecompressedPageCount(uint64_t count, |
| base::TimeDelta interval) override { |
| ++num_decompressed_updates_; |
| } |
| |
| void OnCompressedPageCount(uint64_t count, |
| base::TimeDelta interval) override { |
| ++num_compressed_updates_; |
| } |
| |
| void OnUpdateMetricsFailed() override { ++num_updates_failed_; } |
| |
| size_t num_swap_in_updates() const { return num_swap_in_updates_; } |
| size_t num_swap_out_updates() const { return num_swap_out_updates_; } |
| size_t num_decompressed_updates() const { return num_decompressed_updates_; } |
| size_t num_compressed_updates() const { return num_compressed_updates_; } |
| size_t num_updates_failed() const { return num_updates_failed_; } |
| |
| private: |
| size_t num_swap_in_updates_; |
| size_t num_swap_out_updates_; |
| size_t num_decompressed_updates_; |
| size_t num_compressed_updates_; |
| size_t num_updates_failed_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SwapMetricsDelegateCounter); |
| }; |
| |
| // The time delta between updates must non-zero for the delegate callbacks to be |
| // invoked. |
| constexpr base::TimeDelta kUpdateDelay = base::TimeDelta::FromMilliseconds(50); |
| |
| } // namespace |
| |
| class TestSwapMetricsDriver : public testing::Test { |
| public: |
| static std::unique_ptr<SwapMetricsDriver> CreateDriver( |
| const base::TimeDelta update_interval, |
| bool fail_on_update) { |
| SwapMetricsDelegateCounter* delegate = new SwapMetricsDelegateCounter(); |
| return base::WrapUnique<SwapMetricsDriver>(new MockSwapMetricsDriver( |
| base::WrapUnique<SwapMetricsDriver::Delegate>(delegate), |
| update_interval, fail_on_update)); |
| } |
| |
| protected: |
| base::test::TaskEnvironment task_environment_; |
| }; |
| |
| TEST_F(TestSwapMetricsDriver, ExpectedMetricCounts) { |
| std::unique_ptr<SwapMetricsDriver> driver = |
| CreateDriver(base::TimeDelta(), false); |
| |
| auto result = driver->InitializeMetrics(); |
| EXPECT_EQ( |
| SwapMetricsDriver::SwapMetricsUpdateResult::kSwapMetricsUpdateSuccess, |
| result); |
| |
| base::PlatformThread::Sleep(kUpdateDelay); |
| result = driver->UpdateMetrics(); |
| EXPECT_EQ( |
| SwapMetricsDriver::SwapMetricsUpdateResult::kSwapMetricsUpdateSuccess, |
| result); |
| |
| base::PlatformThread::Sleep(kUpdateDelay); |
| result = driver->UpdateMetrics(); |
| EXPECT_EQ( |
| SwapMetricsDriver::SwapMetricsUpdateResult::kSwapMetricsUpdateSuccess, |
| result); |
| |
| auto* delegate = static_cast<SwapMetricsDelegateCounter*>( |
| static_cast<SwapMetricsDriverImpl*>(driver.get())->delegate_.get()); |
| |
| EXPECT_EQ(2UL, delegate->num_swap_in_updates()); |
| EXPECT_EQ(2UL, delegate->num_swap_out_updates()); |
| EXPECT_EQ(2UL, delegate->num_decompressed_updates()); |
| EXPECT_EQ(2UL, delegate->num_compressed_updates()); |
| } |
| |
| TEST_F(TestSwapMetricsDriver, TimerStartSuccess) { |
| std::unique_ptr<SwapMetricsDriver> driver = |
| CreateDriver(base::TimeDelta::FromSeconds(60), false); |
| auto result = driver->Start(); |
| EXPECT_EQ( |
| SwapMetricsDriver::SwapMetricsUpdateResult::kSwapMetricsUpdateSuccess, |
| result); |
| } |
| |
| TEST_F(TestSwapMetricsDriver, TimerStartFail) { |
| std::unique_ptr<SwapMetricsDriver> driver = |
| CreateDriver(base::TimeDelta::FromSeconds(60), true); |
| auto result = driver->Start(); |
| EXPECT_EQ( |
| SwapMetricsDriver::SwapMetricsUpdateResult::kSwapMetricsUpdateFailed, |
| result); |
| } |
| |
| TEST_F(TestSwapMetricsDriver, UpdateMetricsFail) { |
| std::unique_ptr<SwapMetricsDriver> driver = |
| CreateDriver(base::TimeDelta::FromSeconds(60), true); |
| auto result = driver->InitializeMetrics(); |
| EXPECT_EQ( |
| SwapMetricsDriver::SwapMetricsUpdateResult::kSwapMetricsUpdateFailed, |
| result); |
| result = driver->InitializeMetrics(); |
| EXPECT_EQ( |
| SwapMetricsDriver::SwapMetricsUpdateResult::kSwapMetricsUpdateFailed, |
| result); |
| auto* delegate = static_cast<SwapMetricsDelegateCounter*>( |
| static_cast<SwapMetricsDriverImpl*>(driver.get())->delegate_.get()); |
| EXPECT_EQ(2UL, delegate->num_updates_failed()); |
| } |
| |
| } // namespace content |