1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/metrics/psi_memory_parser.h"
6
7 #include <memory>
8
9 #include "base/files/file_util.h"
10 #include "base/metrics/statistics_recorder.h"
11 #include "base/test/metrics/histogram_tester.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace metrics {
15
16 namespace {
17
18 // Just as the kernel outputs.
19 const char kFileContents1[] =
20 "some avg10=23.10 avg60=5.06 avg300=15.10 total=417963\n"
21 "full avg10=9.00 avg60=19.20 avg300=3.23 total=205933\n";
22
23 // Number of decimals not consistent, slightly malformed - but acceptable.
24 const char kFileContents2[] =
25 "some avg10=24 avg60=5.06 avg300=15.10 total=417963\n"
26 "full avg10=9.2 avg60=19.20 avg300=3.23 total=205933\n";
27
28 } // namespace
29
30 class PSIMemoryParserTest : public testing::Test {
31 public:
32 PSIMemoryParserTest() = default;
33 ~PSIMemoryParserTest() override = default;
34
Init(uint32_t period)35 void Init(uint32_t period) {
36 cit_ = std::make_unique<PSIMemoryParser>(period);
37 }
38
GetPeriod()39 uint32_t GetPeriod() { return cit_->GetPeriod(); }
Histograms()40 base::HistogramTester& Histograms() { return histogram_tester_; }
Cit()41 std::unique_ptr<PSIMemoryParser>& Cit() { return cit_; }
GetMetricPrefix()42 const std::string& GetMetricPrefix() { return cit_->metric_prefix_; }
43
KillCit()44 void KillCit() { cit_.reset(); }
45
46 private:
47 std::unique_ptr<PSIMemoryParser> cit_;
48 base::HistogramTester histogram_tester_;
49 };
50
TEST_F(PSIMemoryParserTest,CustomInterval)51 TEST_F(PSIMemoryParserTest, CustomInterval) {
52 Init(60u);
53
54 EXPECT_EQ(60u, GetPeriod());
55 }
56
TEST_F(PSIMemoryParserTest,InvalidInterval)57 TEST_F(PSIMemoryParserTest, InvalidInterval) {
58 Init(15u);
59
60 EXPECT_EQ(10u, GetPeriod());
61 }
62
TEST_F(PSIMemoryParserTest,InternalsA)63 TEST_F(PSIMemoryParserTest, InternalsA) {
64 Init(10u);
65
66 std::string testContent1 = "prefix" + GetMetricPrefix() + "9.37 suffix";
67 EXPECT_EQ(10u, GetPeriod());
68
69 size_t s = 0;
70 size_t e = 0;
71
72 EXPECT_EQ(false, internal::FindMiddleString(testContent1, 0, "nothere",
73 "suffix", &s, &e));
74
75 EXPECT_EQ(false, internal::FindMiddleString(testContent1, 0, "prefix",
76 "notthere", &s, &e));
77
78 EXPECT_EQ(true, internal::FindMiddleString(testContent1, 0, "prefix",
79 "suffix", &s, &e));
80 EXPECT_EQ(6u, s);
81 EXPECT_EQ(17u, e);
82
83 EXPECT_EQ(937, Cit()->GetMetricValue(testContent1, s, e));
84
85 std::string testContent2 = "extra " + testContent1;
86 EXPECT_EQ(true, internal::FindMiddleString(testContent2, 0, "prefix",
87 "suffix", &s, &e));
88 EXPECT_EQ(12u, s);
89 EXPECT_EQ(23u, e);
90
91 EXPECT_EQ(937, Cit()->GetMetricValue(testContent2, s, e));
92 }
93
TEST_F(PSIMemoryParserTest,InternalsB)94 TEST_F(PSIMemoryParserTest, InternalsB) {
95 Init(300);
96
97 int msome;
98 int mfull;
99 ParsePSIMemStatus stat;
100
101 stat = Cit()->ParseMetrics(kFileContents1, &msome, &mfull);
102
103 EXPECT_EQ(ParsePSIMemStatus::kSuccess, stat);
104 EXPECT_EQ(1510, msome);
105 EXPECT_EQ(323, mfull);
106 }
107
TEST_F(PSIMemoryParserTest,InternalsC)108 TEST_F(PSIMemoryParserTest, InternalsC) {
109 Init(60);
110
111 int msome;
112 int mfull;
113 ParsePSIMemStatus stat;
114
115 stat = Cit()->ParseMetrics(kFileContents1, &msome, &mfull);
116
117 EXPECT_EQ(ParsePSIMemStatus::kSuccess, stat);
118 EXPECT_EQ(506, msome);
119 EXPECT_EQ(1920, mfull);
120 }
121
TEST_F(PSIMemoryParserTest,InternalsD)122 TEST_F(PSIMemoryParserTest, InternalsD) {
123 Init(10);
124
125 int msome;
126 int mfull;
127 ParsePSIMemStatus stat;
128
129 stat = Cit()->ParseMetrics(kFileContents1, &msome, &mfull);
130
131 EXPECT_EQ(ParsePSIMemStatus::kSuccess, stat);
132 EXPECT_EQ(2310, msome);
133 EXPECT_EQ(900, mfull);
134 }
135
TEST_F(PSIMemoryParserTest,InternalsE)136 TEST_F(PSIMemoryParserTest, InternalsE) {
137 Init(10);
138
139 int msome;
140 int mfull;
141 ParsePSIMemStatus stat;
142
143 stat = Cit()->ParseMetrics(kFileContents2, &msome, &mfull);
144
145 EXPECT_EQ(ParsePSIMemStatus::kSuccess, stat);
146 EXPECT_EQ(2400, msome);
147 EXPECT_EQ(920, mfull);
148 }
149
TEST_F(PSIMemoryParserTest,ParseResultCounter)150 TEST_F(PSIMemoryParserTest, ParseResultCounter) {
151 Init(10);
152
153 Cit()->LogParseStatus(ParsePSIMemStatus::kSuccess);
154 Cit()->LogParseStatus(ParsePSIMemStatus::kInvalidMetricFormat);
155 Cit()->LogParseStatus(ParsePSIMemStatus::kInvalidMetricFormat);
156
157 Histograms().ExpectBucketCount("ChromeOS.CWP.ParsePSIMemory",
158 ParsePSIMemStatus::kSuccess, 1);
159 Histograms().ExpectBucketCount("ChromeOS.CWP.ParsePSIMemory",
160 ParsePSIMemStatus::kInvalidMetricFormat, 2);
161 }
162
163 } // namespace metrics
164