• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 
17 #include <vector>
18 
19 #include <base/at_exit.h>
20 #include <base/files/file_util.h>
21 #include <base/files/scoped_temp_dir.h>
22 #include <base/strings/string_number_conversions.h>
23 #include <brillo/flag_helper.h>
24 #include <gtest/gtest.h>
25 
26 #include "constants.h"
27 #include "metrics_collector.h"
28 #include "metrics/metrics_library_mock.h"
29 #include "persistent_integer_mock.h"
30 
31 using base::FilePath;
32 using base::TimeDelta;
33 using std::string;
34 using std::vector;
35 using ::testing::_;
36 using ::testing::AnyNumber;
37 using ::testing::AtLeast;
38 using ::testing::Return;
39 using ::testing::StrictMock;
40 using chromeos_metrics::PersistentIntegerMock;
41 
42 
43 class MetricsCollectorTest : public testing::Test {
44  protected:
SetUp()45   virtual void SetUp() {
46     brillo::FlagHelper::Init(0, nullptr, "");
47     EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
48 
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);
56   }
57 
58   // Adds a metrics library mock expectation that the specified metric
59   // will be generated.
ExpectSample(const std::string & name,int sample)60   void ExpectSample(const std::string& name, int sample) {
61     EXPECT_CALL(metrics_lib_, SendToUMA(name, sample, _, _, _))
62         .Times(1)
63         .WillOnce(Return(true))
64         .RetiresOnSaturation();
65   }
66 
67   // Creates or overwrites the file in |path| so that it contains the printable
68   // representation of |value|.
CreateUint64ValueFile(const base::FilePath & path,uint64_t value)69   void CreateUint64ValueFile(const base::FilePath& path, uint64_t value) {
70     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()));
74   }
75 
76   // The MetricsCollector under test.
77   MetricsCollector daemon_;
78 
79   // Temporary directory used for tests.
80   base::ScopedTempDir temp_dir_;
81 
82   // Mocks. They are strict mock so that all unexpected
83   // calls are marked as failures.
84   StrictMock<MetricsLibraryMock> metrics_lib_;
85 };
86 
TEST_F(MetricsCollectorTest,SendSample)87 TEST_F(MetricsCollectorTest, SendSample) {
88   ExpectSample("Dummy.Metric", 3);
89   daemon_.SendSample("Dummy.Metric", /* sample */ 3,
90                      /* min */ 1, /* max */ 100, /* buckets */ 50);
91 }
92 
TEST_F(MetricsCollectorTest,ProcessMeminfo)93 TEST_F(MetricsCollectorTest, ProcessMeminfo) {
94   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 
114   // All enum calls must report percents.
115   EXPECT_CALL(metrics_lib_, SendEnumToUMA(_, _, 100)).Times(AtLeast(1));
116   // 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).
120   EXPECT_CALL(metrics_lib_, SendToUMA(_, _, _, _, _))
121       .Times(AtLeast(1));
122   // Make sure we don't report fields not in the list.
123   EXPECT_CALL(metrics_lib_, SendToUMA("Platform.MeminfoMlocked", _, _, _, _))
124       .Times(0);
125   EXPECT_CALL(metrics_lib_, SendEnumToUMA("Platform.MeminfoMlocked", _, _))
126       .Times(0);
127   EXPECT_TRUE(daemon_.ProcessMeminfo(meminfo));
128 }
129 
TEST_F(MetricsCollectorTest,ProcessMeminfo2)130 TEST_F(MetricsCollectorTest, ProcessMeminfo2) {
131   string meminfo = "MemTotal:        2000000 kB\nMemFree:         1000000 kB\n";
132   // Not enough fields.
133   EXPECT_FALSE(daemon_.ProcessMeminfo(meminfo));
134 }
135 
TEST_F(MetricsCollectorTest,SendZramMetrics)136 TEST_F(MetricsCollectorTest, SendZramMetrics) {
137   EXPECT_TRUE(daemon_.testing_);
138 
139   // |compr_data_size| is the size in bytes of compressed data.
140   const uint64_t compr_data_size = 50 * 1000 * 1000;
141   // The constant '3' is a realistic but random choice.
142   // |orig_data_size| does not include zero pages.
143   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;
146 
147   CreateUint64ValueFile(
148       temp_dir_.path().Append(MetricsCollector::kComprDataSizeName),
149       compr_data_size);
150   CreateUint64ValueFile(
151       temp_dir_.path().Append(MetricsCollector::kOrigDataSizeName),
152       orig_data_size);
153   CreateUint64ValueFile(
154       temp_dir_.path().Append(MetricsCollector::kZeroPagesName), zero_pages);
155 
156   const uint64_t real_orig_size = orig_data_size + zero_pages * page_size;
157   const uint64_t zero_ratio_percent =
158       zero_pages * page_size * 100 / real_orig_size;
159   // Ratio samples are in percents.
160   const uint64_t actual_ratio_sample = real_orig_size * 100 / compr_data_size;
161 
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 
169   EXPECT_TRUE(daemon_.ReportZram(temp_dir_.path()));
170 }
171