1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
// Copyright 2017 The Chromium Authors
// 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(const SwapMetricsDelegateCounter&) = delete;
SwapMetricsDelegateCounter& operator=(const SwapMetricsDelegateCounter&) =
delete;
~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_;
};
// The time delta between updates must non-zero for the delegate callbacks to be
// invoked.
constexpr base::TimeDelta kUpdateDelay = base::Milliseconds(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::Seconds(60), false);
auto result = driver->Start();
EXPECT_EQ(
SwapMetricsDriver::SwapMetricsUpdateResult::kSwapMetricsUpdateSuccess,
result);
}
TEST_F(TestSwapMetricsDriver, TimerStartFail) {
std::unique_ptr<SwapMetricsDriver> driver =
CreateDriver(base::Seconds(60), true);
auto result = driver->Start();
EXPECT_EQ(
SwapMetricsDriver::SwapMetricsUpdateResult::kSwapMetricsUpdateFailed,
result);
}
TEST_F(TestSwapMetricsDriver, UpdateMetricsFail) {
std::unique_ptr<SwapMetricsDriver> driver =
CreateDriver(base::Seconds(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
|