blob: 9557205df7cc693139c7249a8f12cdaf262aa565 [file] [log] [blame]
// Copyright 2015 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 "components/memory_pressure/memory_pressure_stats_collector.h"
#include "base/test/histogram_tester.h"
#include "base/test/simple_test_tick_clock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace memory_pressure {
namespace {
// Histogram names.
const char kPressureLevel[] = "Memory.PressureLevel";
const char kPressureLevelChange[] = "Memory.PressureLevelChange";
} // namespace
// Test version of the stats collector with a few extra accessors.
class TestMemoryPressureStatsCollector : public MemoryPressureStatsCollector {
public:
TestMemoryPressureStatsCollector(base::TickClock* tick_clock)
: MemoryPressureStatsCollector(tick_clock) {}
// Accessors.
base::TimeDelta unreported_cumulative_time(int i) const {
return unreported_cumulative_time_[i];
}
MemoryPressureLevel last_pressure_level() const {
return last_pressure_level_;
}
base::TimeTicks last_update_time() const { return last_update_time_; }
};
// Test fixture.
class MemoryPressureStatsCollectorTest : public testing::Test {
public:
MemoryPressureStatsCollectorTest() : collector_(&tick_clock_) {}
void Tick(int ms) {
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(ms));
}
// Validates expectations on the amount of accumulated (and unreported)
// time (milliseconds) per pressure level.
void ExpectAccumulated(int none_ms, int moderate_ms, int critical_ms) {
EXPECT_EQ(base::TimeDelta::FromMilliseconds(none_ms),
collector_.unreported_cumulative_time(0)); // None.
EXPECT_EQ(base::TimeDelta::FromMilliseconds(moderate_ms),
collector_.unreported_cumulative_time(1)); // Moderate.
EXPECT_EQ(base::TimeDelta::FromMilliseconds(critical_ms),
collector_.unreported_cumulative_time(2)); // Critical.
}
// Validates expectations on the amount of reported time (seconds) per
// pressure level.
void ExpectReported(int none_s, int moderate_s, int critical_s) {
int total_s = none_s + moderate_s + critical_s;
// If the histogram should be empty then simply confirm that it doesn't
// yet exist.
if (total_s == 0) {
EXPECT_TRUE(histograms_.GetTotalCountsForPrefix(kPressureLevel).empty());
return;
}
histograms_.ExpectBucketCount(kPressureLevel, 0, none_s); // None.
histograms_.ExpectBucketCount(kPressureLevel, 1, moderate_s); // Moderate.
histograms_.ExpectBucketCount(kPressureLevel, 2, critical_s); // Critical.
histograms_.ExpectTotalCount(kPressureLevel, total_s);
}
base::SimpleTestTickClock tick_clock_;
TestMemoryPressureStatsCollector collector_;
base::HistogramTester histograms_;
};
TEST_F(MemoryPressureStatsCollectorTest, EndToEnd) {
// Upon construction no statistics should yet have been reported.
ExpectAccumulated(0, 0, 0);
ExpectReported(0, 0, 0);
histograms_.ExpectTotalCount(kPressureLevelChange, 0);
// A first call should not invoke any reporting functions, but it should
// modify member variables.
Tick(500);
collector_.UpdateStatistics(
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE);
EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
collector_.last_pressure_level());
EXPECT_EQ(tick_clock_.NowTicks(), collector_.last_update_time());
ExpectAccumulated(0, 0, 0);
ExpectReported(0, 0, 0);
histograms_.ExpectTotalCount(kPressureLevelChange, 0);
// A subsequent call with the same pressure level should increment the
// cumulative time but not make a report, as less than one second of time
// has been accumulated.
Tick(500);
collector_.UpdateStatistics(
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE);
EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
collector_.last_pressure_level());
EXPECT_EQ(tick_clock_.NowTicks(), collector_.last_update_time());
ExpectAccumulated(500, 0, 0);
ExpectReported(0, 0, 0);
histograms_.ExpectTotalCount(kPressureLevelChange, 0);
// Yet another call and this time a report should be made, as one second
// of time has been accumulated. 500ms should remain unreported.
Tick(1000);
collector_.UpdateStatistics(
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE);
EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
collector_.last_pressure_level());
EXPECT_EQ(tick_clock_.NowTicks(), collector_.last_update_time());
ExpectAccumulated(500, 0, 0);
ExpectReported(1, 0, 0);
histograms_.ExpectTotalCount(kPressureLevelChange, 0);
// A subsequent call with a different pressure level should increment the
// cumulative time and make several reports.
Tick(2250);
collector_.UpdateStatistics(
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
collector_.last_pressure_level());
EXPECT_EQ(tick_clock_.NowTicks(), collector_.last_update_time());
ExpectAccumulated(500, 250, 0);
ExpectReported(1, 2, 0);
histograms_.ExpectBucketCount(
kPressureLevelChange, UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_MODERATE,
1);
histograms_.ExpectTotalCount(kPressureLevelChange, 1);
}
} // namespace memory_pressure