blob: 139d014bcf6c3941e772fde6ad3c1590e789c2c3 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/memory_metrics.h"
#include <memory>
#include "ash/constants/ash_switches.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/metrics/statistics_recorder.h"
#include "base/test/metrics/histogram_tester.h"
#include "components/metrics/serialization/metric_sample.h"
#include "components/metrics/serialization/serialization_utils.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ash {
namespace {
// Just as the kernel outputs.
const char kFileContents1[] =
"some avg10=23.10 avg60=5.06 avg300=15.10 total=417963\n"
"full avg10=9.00 avg60=19.20 avg300=3.23 total=205933\n";
} // namespace
class MemoryMetricsTest : public testing::Test {
public:
MemoryMetricsTest() = default;
~MemoryMetricsTest() override = default;
void Init(uint32_t period) {
ASSERT_TRUE(dir_.CreateUniqueTempDir());
testfilename_ = dir_.GetPath().Append("testpsimem.txt");
cit_ = MemoryMetrics::CreateForTesting(period, testfilename_.value());
}
base::TimeDelta GetCollection() { return cit_->collection_interval_; }
const base::FilePath& GetTestFileName() { return testfilename_; }
base::HistogramTester& Histograms() { return histogram_tester_; }
scoped_refptr<MemoryMetrics> Cit() { return cit_; }
content::BrowserTaskEnvironment& task_environment() {
return task_environment_;
}
void KillCit() { cit_.reset(); }
private:
content::BrowserTaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
base::ScopedTempDir dir_;
scoped_refptr<MemoryMetrics> cit_;
base::FilePath testfilename_;
base::HistogramTester histogram_tester_;
};
// Tests basic collection of PSI metrics.
TEST_F(MemoryMetricsTest, SunnyDay1) {
Init(10);
ASSERT_TRUE(base::WriteFile(GetTestFileName(),
{kFileContents1, sizeof(kFileContents1)}));
Cit()->CollectEvents();
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Some",
2310 /*bucket*/, 1 /*count*/);
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Full",
900 /*bucket*/, 1 /*count*/);
}
// Tests basic collection of PSI metrics using the timer.
TEST_F(MemoryMetricsTest, TestWithTimer) {
Init(10);
ASSERT_TRUE(base::WriteFile(GetTestFileName(), kFileContents1));
// Repeating timer comes on.
Cit()->Start();
task_environment().FastForwardBy(base::Seconds(5));
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Some",
2310 /*bucket*/, 0 /*count*/);
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Full",
900 /*bucket*/, 0 /*count*/);
task_environment().FastForwardBy(base::Seconds(10));
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Some",
2310 /*bucket*/, 1 /*count*/);
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Full",
900 /*bucket*/, 1 /*count*/);
task_environment().FastForwardBy(base::Seconds(10));
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Some",
2310 /*bucket*/, 2 /*count*/);
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Full",
900 /*bucket*/, 2 /*count*/);
// No more.
Cit()->Stop();
KillCit();
task_environment().FastForwardBy(base::Seconds(50));
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Some",
2310 /*bucket*/, 2 /*count*/);
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Full",
900 /*bucket*/, 2 /*count*/);
}
// Tests timer cancellation.
TEST_F(MemoryMetricsTest, CancelBeforeFirstRun) {
Init(300);
EXPECT_TRUE(base::WriteFile(GetTestFileName(), kFileContents1));
// Repeating timer comes on - but we will cancel before first iteration.
Cit()->Start();
task_environment().FastForwardBy(base::Seconds(5));
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Some",
2310 /*bucket*/, 0 /*count*/);
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Full",
900 /*bucket*/, 0 /*count*/);
// No more.
Cit()->Stop();
KillCit();
task_environment().FastForwardBy(base::Seconds(50));
task_environment().FastForwardBy(base::Seconds(5));
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Some",
2310 /*bucket*/, 0 /*count*/);
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Full",
900 /*bucket*/, 0 /*count*/);
}
// Tests basic collection of PSI metrics with period=60.
TEST_F(MemoryMetricsTest, SunnyDay2) {
Init(60);
EXPECT_TRUE(base::WriteFile(GetTestFileName(), kFileContents1));
Cit()->CollectEvents();
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Some",
506 /*bucket*/, 1 /*count*/);
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Full",
1920 /*bucket*/, 1 /*count*/);
}
// Tests basic collection of PSI metrics with period=300.
TEST_F(MemoryMetricsTest, SunnyDay3) {
Init(300);
EXPECT_TRUE(base::WriteFile(GetTestFileName(), kFileContents1));
Cit()->CollectEvents();
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Some",
1510 /*bucket*/, 1 /*count*/);
Histograms().ExpectBucketCount("ChromeOS.CWP.PSIMemPressure.Full",
323 /*bucket*/, 1 /*count*/);
}
} // namespace ash