blob: 8dda529b40f73e65a0f87ce118f304afe391e2ad [file] [log] [blame]
Bertrand SIMONNET52e5b992015-08-10 15:18:00 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Darin Petkov2ccef012010-05-05 16:06:37 -070016
Daniel Eratb9b05e62010-11-09 12:18:51 -080017#include <vector>
18
Luigi Semenzato859b3f02014-02-05 15:33:19 -080019#include <base/at_exit.h>
Ben Chan51bf92a2014-09-05 08:21:06 -070020#include <base/files/file_util.h>
Bertrand SIMONNET12531862015-08-31 11:11:57 -070021#include <base/files/scoped_temp_dir.h>
Luigi Semenzato96360192014-06-04 10:53:35 -070022#include <base/strings/string_number_conversions.h>
Alex Vakulenko74dc6242015-10-13 09:23:34 -070023#include <brillo/flag_helper.h>
Darin Petkovf1e85e42010-06-10 15:59:53 -070024#include <gtest/gtest.h>
25
Bertrand SIMONNET12531862015-08-31 11:11:57 -070026#include "constants.h"
Bertrand SIMONNET608e4282015-11-12 17:52:17 -080027#include "metrics_collector.h"
Samuel Tan28a78b72015-09-23 14:39:35 -070028#include "metrics/metrics_library_mock.h"
Bertrand SIMONNET4b915ae2015-07-28 15:38:14 -070029#include "persistent_integer_mock.h"
Darin Petkov2ccef012010-05-05 16:06:37 -070030
Ben Chan2e6543d2014-02-05 23:26:25 -080031using base::FilePath;
Daniel Eratc83975a2014-04-04 08:53:44 -070032using base::TimeDelta;
Daniel Eratb9b05e62010-11-09 12:18:51 -080033using std::string;
34using std::vector;
Darin Petkovf1e85e42010-06-10 15:59:53 -070035using ::testing::_;
Steve Funge86591e2014-12-01 13:38:21 -080036using ::testing::AnyNumber;
Daniel Eratc83975a2014-04-04 08:53:44 -070037using ::testing::AtLeast;
Darin Petkovfc91b422010-05-12 13:05:45 -070038using ::testing::Return;
39using ::testing::StrictMock;
Luigi Semenzato2fd51cc2014-02-26 11:53:16 -080040using chromeos_metrics::PersistentIntegerMock;
Darin Petkovfc91b422010-05-12 13:05:45 -070041
Luigi Semenzato5bd764f2011-10-14 12:03:35 -070042
Bertrand SIMONNET608e4282015-11-12 17:52:17 -080043class MetricsCollectorTest : public testing::Test {
Darin Petkov2ccef012010-05-05 16:06:37 -070044 protected:
45 virtual void SetUp() {
Alex Vakulenko74dc6242015-10-13 09:23:34 -070046 brillo::FlagHelper::Init(0, nullptr, "");
Bertrand SIMONNET12531862015-08-31 11:11:57 -070047 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
Bertrand SIMONNET9d3a4ae2015-11-25 13:49:12 -080048
49 base::FilePath private_dir = temp_dir_.path().Append("private");
50 base::FilePath shared_dir = temp_dir_.path().Append("shared");
51
52 EXPECT_TRUE(base::CreateDirectory(private_dir));
53 EXPECT_TRUE(base::CreateDirectory(shared_dir));
54
55 daemon_.Init(true, &metrics_lib_, "", private_dir, shared_dir);
Darin Petkov2ccef012010-05-05 16:06:37 -070056 }
57
Darin Petkovfc91b422010-05-12 13:05:45 -070058 // Adds a metrics library mock expectation that the specified metric
59 // will be generated.
Daniel Eratc83975a2014-04-04 08:53:44 -070060 void ExpectSample(const std::string& name, int sample) {
61 EXPECT_CALL(metrics_lib_, SendToUMA(name, sample, _, _, _))
Darin Petkovfc91b422010-05-12 13:05:45 -070062 .Times(1)
63 .WillOnce(Return(true))
64 .RetiresOnSaturation();
Darin Petkov2ccef012010-05-05 16:06:37 -070065 }
66
Luigi Semenzato96360192014-06-04 10:53:35 -070067 // Creates or overwrites the file in |path| so that it contains the printable
68 // representation of |value|.
Ben Chanf05ab402014-08-07 00:54:59 -070069 void CreateUint64ValueFile(const base::FilePath& path, uint64_t value) {
Luigi Semenzato96360192014-06-04 10:53:35 -070070 std::string value_string = base::Uint64ToString(value);
71 ASSERT_EQ(value_string.length(),
72 base::WriteFile(path, value_string.c_str(),
73 value_string.length()));
Luigi Semenzatofb3a8212013-05-07 16:55:00 -070074 }
75
Bertrand SIMONNET608e4282015-11-12 17:52:17 -080076 // The MetricsCollector under test.
77 MetricsCollector daemon_;
Darin Petkov2ccef012010-05-05 16:06:37 -070078
Bertrand SIMONNET12531862015-08-31 11:11:57 -070079 // Temporary directory used for tests.
80 base::ScopedTempDir temp_dir_;
81
Luigi Semenzato2fd51cc2014-02-26 11:53:16 -080082 // Mocks. They are strict mock so that all unexpected
83 // calls are marked as failures.
Darin Petkovfc91b422010-05-12 13:05:45 -070084 StrictMock<MetricsLibraryMock> metrics_lib_;
Darin Petkov2ccef012010-05-05 16:06:37 -070085};
86
Bertrand SIMONNET608e4282015-11-12 17:52:17 -080087TEST_F(MetricsCollectorTest, SendSample) {
Daniel Eratc83975a2014-04-04 08:53:44 -070088 ExpectSample("Dummy.Metric", 3);
Luigi Semenzato2fd51cc2014-02-26 11:53:16 -080089 daemon_.SendSample("Dummy.Metric", /* sample */ 3,
Darin Petkov11b8eb32010-05-18 11:00:59 -070090 /* min */ 1, /* max */ 100, /* buckets */ 50);
91}
92
Bertrand SIMONNET608e4282015-11-12 17:52:17 -080093TEST_F(MetricsCollectorTest, ProcessMeminfo) {
Bertrand SIMONNETe6cfd642014-07-09 16:35:23 -070094 string meminfo =
95 "MemTotal: 2000000 kB\nMemFree: 500000 kB\n"
96 "Buffers: 1000000 kB\nCached: 213652 kB\n"
97 "SwapCached: 0 kB\nActive: 133400 kB\n"
98 "Inactive: 183396 kB\nActive(anon): 92984 kB\n"
99 "Inactive(anon): 58860 kB\nActive(file): 40416 kB\n"
100 "Inactive(file): 124536 kB\nUnevictable: 0 kB\n"
101 "Mlocked: 0 kB\nSwapTotal: 0 kB\n"
102 "SwapFree: 0 kB\nDirty: 40 kB\n"
103 "Writeback: 0 kB\nAnonPages: 92652 kB\n"
104 "Mapped: 59716 kB\nShmem: 59196 kB\n"
105 "Slab: 16656 kB\nSReclaimable: 6132 kB\n"
106 "SUnreclaim: 10524 kB\nKernelStack: 1648 kB\n"
107 "PageTables: 2780 kB\nNFS_Unstable: 0 kB\n"
108 "Bounce: 0 kB\nWritebackTmp: 0 kB\n"
109 "CommitLimit: 970656 kB\nCommitted_AS: 1260528 kB\n"
110 "VmallocTotal: 122880 kB\nVmallocUsed: 12144 kB\n"
111 "VmallocChunk: 103824 kB\nDirectMap4k: 9636 kB\n"
112 "DirectMap2M: 1955840 kB\n";
113
Luigi Semenzato8accd332011-05-17 16:37:18 -0700114 // All enum calls must report percents.
Bertrand SIMONNETe6cfd642014-07-09 16:35:23 -0700115 EXPECT_CALL(metrics_lib_, SendEnumToUMA(_, _, 100)).Times(AtLeast(1));
Luigi Semenzato8accd332011-05-17 16:37:18 -0700116 // Check that MemFree is correctly computed at 25%.
117 EXPECT_CALL(metrics_lib_, SendEnumToUMA("Platform.MeminfoMemFree", 25, 100))
118 .Times(AtLeast(1));
119 // Check that we call SendToUma at least once (log histogram).
Luigi Semenzato29c7ef92011-04-12 14:12:35 -0700120 EXPECT_CALL(metrics_lib_, SendToUMA(_, _, _, _, _))
121 .Times(AtLeast(1));
Luigi Semenzato8accd332011-05-17 16:37:18 -0700122 // Make sure we don't report fields not in the list.
123 EXPECT_CALL(metrics_lib_, SendToUMA("Platform.MeminfoMlocked", _, _, _, _))
Luigi Semenzato29c7ef92011-04-12 14:12:35 -0700124 .Times(0);
Luigi Semenzato8accd332011-05-17 16:37:18 -0700125 EXPECT_CALL(metrics_lib_, SendEnumToUMA("Platform.MeminfoMlocked", _, _))
Luigi Semenzato29c7ef92011-04-12 14:12:35 -0700126 .Times(0);
127 EXPECT_TRUE(daemon_.ProcessMeminfo(meminfo));
128}
129
Bertrand SIMONNET608e4282015-11-12 17:52:17 -0800130TEST_F(MetricsCollectorTest, ProcessMeminfo2) {
Bertrand SIMONNETe6cfd642014-07-09 16:35:23 -0700131 string meminfo = "MemTotal: 2000000 kB\nMemFree: 1000000 kB\n";
Luigi Semenzatofb3a8212013-05-07 16:55:00 -0700132 // Not enough fields.
Luigi Semenzato29c7ef92011-04-12 14:12:35 -0700133 EXPECT_FALSE(daemon_.ProcessMeminfo(meminfo));
134}
135
Bertrand SIMONNET608e4282015-11-12 17:52:17 -0800136TEST_F(MetricsCollectorTest, SendZramMetrics) {
Luigi Semenzato96360192014-06-04 10:53:35 -0700137 EXPECT_TRUE(daemon_.testing_);
138
139 // |compr_data_size| is the size in bytes of compressed data.
Ben Chanf05ab402014-08-07 00:54:59 -0700140 const uint64_t compr_data_size = 50 * 1000 * 1000;
Luigi Semenzato96360192014-06-04 10:53:35 -0700141 // The constant '3' is a realistic but random choice.
142 // |orig_data_size| does not include zero pages.
Ben Chanf05ab402014-08-07 00:54:59 -0700143 const uint64_t orig_data_size = compr_data_size * 3;
144 const uint64_t page_size = 4096;
145 const uint64_t zero_pages = 10 * 1000 * 1000 / page_size;
Luigi Semenzato96360192014-06-04 10:53:35 -0700146
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700147 CreateUint64ValueFile(
Bertrand SIMONNET608e4282015-11-12 17:52:17 -0800148 temp_dir_.path().Append(MetricsCollector::kComprDataSizeName),
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700149 compr_data_size);
150 CreateUint64ValueFile(
Bertrand SIMONNET608e4282015-11-12 17:52:17 -0800151 temp_dir_.path().Append(MetricsCollector::kOrigDataSizeName),
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700152 orig_data_size);
153 CreateUint64ValueFile(
Bertrand SIMONNET608e4282015-11-12 17:52:17 -0800154 temp_dir_.path().Append(MetricsCollector::kZeroPagesName), zero_pages);
Luigi Semenzato96360192014-06-04 10:53:35 -0700155
Ben Chanf05ab402014-08-07 00:54:59 -0700156 const uint64_t real_orig_size = orig_data_size + zero_pages * page_size;
157 const uint64_t zero_ratio_percent =
Luigi Semenzato96360192014-06-04 10:53:35 -0700158 zero_pages * page_size * 100 / real_orig_size;
159 // Ratio samples are in percents.
Ben Chanf05ab402014-08-07 00:54:59 -0700160 const uint64_t actual_ratio_sample = real_orig_size * 100 / compr_data_size;
Luigi Semenzato96360192014-06-04 10:53:35 -0700161
162 EXPECT_CALL(metrics_lib_, SendToUMA(_, compr_data_size >> 20, _, _, _));
163 EXPECT_CALL(metrics_lib_,
164 SendToUMA(_, (real_orig_size - compr_data_size) >> 20, _, _, _));
165 EXPECT_CALL(metrics_lib_, SendToUMA(_, actual_ratio_sample, _, _, _));
166 EXPECT_CALL(metrics_lib_, SendToUMA(_, zero_pages, _, _, _));
167 EXPECT_CALL(metrics_lib_, SendToUMA(_, zero_ratio_percent, _, _, _));
168
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700169 EXPECT_TRUE(daemon_.ReportZram(temp_dir_.path()));
Darin Petkov2ccef012010-05-05 16:06:37 -0700170}