blob: 7bdb66870ea86c453f8264f8ac45f6dfbbf6585e [file] [log] [blame]
Honglin Yu1cd25072019-07-09 11:54:14 +10001// Copyright 2019 The Chromium OS Authors. All rights reserved.
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 <limits>
6#include <string>
7
8#include <gmock/gmock.h>
9#include <gtest/gtest.h>
10#include <base/strings/string_number_conversions.h>
11#include <base/strings/stringprintf.h>
12#include <base/files/scoped_temp_dir.h>
13#include <base/files/file_util.h>
14#include <brillo/file_utils.h>
15
16#include "ml/test_utils.h"
17#include "ml/util.h"
18
19namespace ml {
20namespace {
21
22// Represents a temp status file valid for the lifetime of this object.
23// The constructor creates a temp file named "status" in a temp folder and
Andrew Moylan79b34a42020-07-08 11:13:11 +100024// writes `content` to that file.
Honglin Yu1cd25072019-07-09 11:54:14 +100025// Use GetPath() to obtain the path fo the temporary file.
26class ScopedTempStatusFile {
27 public:
28 explicit ScopedTempStatusFile(const std::string& content) {
29 CHECK(dir_.CreateUniqueTempDir());
30 file_path_ = dir_.GetPath().Append("status");
31 CHECK(brillo::WriteStringToFile(file_path_, content));
32 }
33 base::FilePath GetPath() { return file_path_; }
34
35 private:
36 base::ScopedTempDir dir_;
37 base::FilePath file_path_;
38
39 DISALLOW_COPY_AND_ASSIGN(ScopedTempStatusFile);
40};
41
42// Status file does not exist.
43TEST(GetProcessMemoryUsageTest, InvalidFile) {
44 ScopedTempStatusFile status_file("");
45 MemoryUsage memory_usage;
46 EXPECT_FALSE(GetProcessMemoryUsageFromFile(
47 &memory_usage, status_file.GetPath().Append("nonexistfile")));
48}
49
50TEST(GetProcessMemoryUsageTest, EmptyFile) {
51 ScopedTempStatusFile status_file("");
52 MemoryUsage memory_usage;
53 EXPECT_FALSE(
54 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
55}
56
57TEST(GetProcessMemoryUsageTest, MissingVmSwap) {
58 ScopedTempStatusFile status_file("VmRSS: 3235 kB");
59 MemoryUsage memory_usage;
60 EXPECT_FALSE(
61 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
62}
63
64TEST(GetProcessMemoryUsageTest, MissingVmRSS) {
65 ScopedTempStatusFile status_file("VmSwap: 34213 kB");
66 MemoryUsage memory_usage;
67 EXPECT_FALSE(
68 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
69}
70
71TEST(GetProcessMemoryUsageTest, MissingBothValues) {
72 ScopedTempStatusFile status_file("VmRSS: kB \n VmSwap: kB\n");
73 MemoryUsage memory_usage;
74 EXPECT_FALSE(
75 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
76}
77
78TEST(GetProcessMemoryUsageTest, MissingVmRSSValue) {
79 ScopedTempStatusFile status_file("VmRSS: kB \n VmSwap: 421532 kB\n");
80 MemoryUsage memory_usage;
81 EXPECT_FALSE(
82 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
83}
84
85TEST(GetProcessMemoryUsageTest, MissingVmSwapValue) {
86 ScopedTempStatusFile status_file("VmRSS: 32432 kB \n VmSwap: kB\n");
87 MemoryUsage memory_usage;
88 EXPECT_FALSE(
89 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
90}
91
92TEST(GetProcessMemoryUsageTest, InvalidVmSwapValueNan) {
93 ScopedTempStatusFile status_file(
94 "VmRSS: 767234322 kB \n VmSwap: nan kB\n");
95 MemoryUsage memory_usage;
96 EXPECT_FALSE(
97 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
98}
99
100TEST(GetProcessMemoryUsageTest, InvalidVmRSSValueNan) {
101 ScopedTempStatusFile status_file("VmRSS: nan kB \n VmSwap: 4214 kB\n");
102 MemoryUsage memory_usage;
103 EXPECT_FALSE(
104 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
105}
106
107TEST(GetProcessMemoryUsageTest, Duplicate) {
108 ScopedTempStatusFile status_file(
109 "VmRSS: 432 kB \n VmSwap: 421532 kB\n"
110 "VmRSS: 432 kB \n VmSwap: 421532 kB\n");
111 MemoryUsage memory_usage;
112 EXPECT_FALSE(
113 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
114}
115
116TEST(GetProcessMemoryUsageTest, ValidInputNonZeroValue) {
117 ScopedTempStatusFile status_file("VmRSS: 432 kB \n VmSwap: 421532 kB\n");
118 MemoryUsage memory_usage;
119 EXPECT_TRUE(
120 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
121 EXPECT_EQ(memory_usage.VmRSSKb, 432);
122 EXPECT_EQ(memory_usage.VmSwapKb, 421532);
123}
124
125TEST(GetProcessMemoryUsageTest, ValidInputZeroValue) {
126 ScopedTempStatusFile status_file("VmRSS: 0 kB \n VmSwap: 0 kB\n");
127 MemoryUsage memory_usage;
128 EXPECT_TRUE(
129 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
130 EXPECT_EQ(memory_usage.VmRSSKb, 0);
131 EXPECT_EQ(memory_usage.VmSwapKb, 0);
132}
133
134TEST(GetProcessMemoryUsageTest, ValidInputZeroLead) {
135 ScopedTempStatusFile status_file(
136 "VmRSS: 0242 kB \n VmSwap: 03523 kB\n");
137 MemoryUsage memory_usage;
138 EXPECT_TRUE(
139 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
140 EXPECT_EQ(memory_usage.VmRSSKb, 242);
141 EXPECT_EQ(memory_usage.VmSwapKb, 3523);
142}
143
144// Checks the maximum value of size_t. It may fail if treated as int32.
145TEST(GetProcessMemoryUsageTest, ValidInputMaxSizeT) {
146 constexpr size_t kSizeTMax = std::numeric_limits<size_t>::max();
147
148 ScopedTempStatusFile status_file(base::StringPrintf(
149 "VmRSS: %zu kB\nVmSwap: %zu kB\n", kSizeTMax, kSizeTMax));
150 MemoryUsage memory_usage;
151 EXPECT_TRUE(
152 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
153 EXPECT_EQ(memory_usage.VmRSSKb, kSizeTMax);
154 EXPECT_EQ(memory_usage.VmSwapKb, kSizeTMax);
155}
156
157TEST(GetProcessMemoryUsageTest, OrderChanged) {
158 ScopedTempStatusFile status_file(
159 "VmSwap: 34 kB\nVmRSS: 123 kB\n");
160 MemoryUsage memory_usage;
161 EXPECT_TRUE(
162 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
163 EXPECT_EQ(memory_usage.VmRSSKb, 123);
164 EXPECT_EQ(memory_usage.VmSwapKb, 34);
165}
166
167TEST(GetProcessMemoryUsageTest, MissingNonMemoryValue) {
168 ScopedTempStatusFile status_file(
169 "VmSize: \nVmSwap: 34 kB\nVmRSS: 123 kB\n");
170 MemoryUsage memory_usage;
171 EXPECT_TRUE(
172 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
173 EXPECT_EQ(memory_usage.VmRSSKb, 123);
174 EXPECT_EQ(memory_usage.VmSwapKb, 34);
175}
176
177TEST(GetProcessMemoryUsageTest, RealisticProcStatus) {
178 ScopedTempStatusFile status_file(
179 "Name: cat\n"
180 "Umask: 0022\n"
181 "State: R (running)\n"
182 "Tgid: 21255\n"
183 "Ngid: 0\n"
184 "Pid: 21255\n"
185 "PPid: 7\n"
186 "TracerPid: 0\n"
187 "Uid: 694971 694971 694971 694971\n"
188 "Gid: 89939 89939 89939 89939\n"
189 "FDSize: 256\n"
190 "Groups: 4 11 18 19 20 27 250 89939\n"
191 "NStgid: 21255\n"
192 "NSpid: 21255\n"
193 "NSpgid: 21255\n"
194 "NSsid: 0\n"
195 "VmPeak: 6048 kB\n"
196 "VmSize: 6048 kB\n"
197 "VmLck: 0 kB\n"
198 "VmPin: 0 kB\n"
199 "VmHWM: 732 kB\n"
200 "VmRSS: 732 kB\n"
201 "RssAnon: 68 kB\n"
202 "RssFile: 664 kB\n"
203 "RssShmem: 0 kB\n"
204 "VmData: 312 kB\n"
205 "VmStk: 136 kB\n"
206 "VmExe: 40 kB\n"
207 "VmLib: 1872 kB\n"
208 "VmPTE: 52 kB\n"
209 "VmSwap: 321 kB\n"
210 "HugetlbPages: 0 kB\n"
211 "CoreDumping: 0\n"
212 "Threads: 1\n"
213 "SigQ: 0/767737\n"
214 "SigPnd: 0000000000000000\n"
215 "ShdPnd: 0000000000000000\n"
216 "SigBlk: 0000000000000000\n"
217 "SigIgn: 0000000001001000\n"
218 "SigCgt: 0000000000000000\n"
219 "CapInh: 0000000000000000\n"
220 "CapPrm: 0000000000000000\n"
221 "CapEff: 0000000000000000\n"
222 "CapBnd: 0000003fffffffff\n"
223 "CapAmb: 0000000000000000\n"
224 "NoNewPrivs: 0\n"
225 "Seccomp: 0\n"
226 "Speculation_Store_Bypass: thread vulnerable\n"
227 "Cpus_allowed: ff,ffffffff,ffffffff\n"
228 "Cpus_allowed_list: 0-71\n"
229 "Mems_allowed: 00000000,00000003\n"
230 "Mems_allowed_list: 0-1\n"
231 "voluntary_ctxt_switches: 0\n"
232 "nonvoluntary_ctxt_switches: 1\n");
233 MemoryUsage memory_usage;
234 EXPECT_TRUE(
235 GetProcessMemoryUsageFromFile(&memory_usage, status_file.GetPath()));
236 EXPECT_EQ(memory_usage.VmRSSKb, 732);
237 EXPECT_EQ(memory_usage.VmSwapKb, 321);
238}
239
240} // namespace
241} // namespace ml