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: 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. 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|. 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 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 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 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 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