1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vector>
#include <base/at_exit.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/flag_helper.h>
#include <gtest/gtest.h>
#include "constants.h"
#include "metrics_collector.h"
#include "metrics/metrics_library_mock.h"
#include "persistent_integer_mock.h"
using base::FilePath;
using base::TimeDelta;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::Return;
using ::testing::StrictMock;
using chromeos_metrics::PersistentIntegerMock;
class MetricsCollectorTest : public testing::Test {
protected:
virtual void SetUp() {
brillo::FlagHelper::Init(0, nullptr, "");
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
base::FilePath private_dir = temp_dir_.path().Append("private");
base::FilePath shared_dir = temp_dir_.path().Append("shared");
EXPECT_TRUE(base::CreateDirectory(private_dir));
EXPECT_TRUE(base::CreateDirectory(shared_dir));
daemon_.Init(true, &metrics_lib_, "", private_dir, shared_dir);
}
// Adds a metrics library mock expectation that the specified metric
// will be generated.
void ExpectSample(const std::string& name, int sample) {
EXPECT_CALL(metrics_lib_, SendToUMA(name, sample, _, _, _))
.Times(1)
.WillOnce(Return(true))
.RetiresOnSaturation();
}
// Creates or overwrites the file in |path| so that it contains the printable
// representation of |value|.
void CreateUint64ValueFile(const base::FilePath& path, uint64_t value) {
std::string value_string = base::Uint64ToString(value);
ASSERT_EQ(value_string.length(),
base::WriteFile(path, value_string.c_str(),
value_string.length()));
}
// The MetricsCollector under test.
MetricsCollector daemon_;
// Temporary directory used for tests.
base::ScopedTempDir temp_dir_;
// Mocks. They are strict mock so that all unexpected
// calls are marked as failures.
StrictMock<MetricsLibraryMock> metrics_lib_;
};
TEST_F(MetricsCollectorTest, SendSample) {
ExpectSample("Dummy.Metric", 3);
daemon_.SendSample("Dummy.Metric", /* sample */ 3,
/* min */ 1, /* max */ 100, /* buckets */ 50);
}
TEST_F(MetricsCollectorTest, ProcessMeminfo) {
string meminfo =
"MemTotal: 2000000 kB\nMemFree: 500000 kB\n"
"Buffers: 1000000 kB\nCached: 213652 kB\n"
"SwapCached: 0 kB\nActive: 133400 kB\n"
"Inactive: 183396 kB\nActive(anon): 92984 kB\n"
"Inactive(anon): 58860 kB\nActive(file): 40416 kB\n"
"Inactive(file): 124536 kB\nUnevictable: 0 kB\n"
"Mlocked: 0 kB\nSwapTotal: 0 kB\n"
"SwapFree: 0 kB\nDirty: 40 kB\n"
"Writeback: 0 kB\nAnonPages: 92652 kB\n"
"Mapped: 59716 kB\nShmem: 59196 kB\n"
"Slab: 16656 kB\nSReclaimable: 6132 kB\n"
"SUnreclaim: 10524 kB\nKernelStack: 1648 kB\n"
"PageTables: 2780 kB\nNFS_Unstable: 0 kB\n"
"Bounce: 0 kB\nWritebackTmp: 0 kB\n"
"CommitLimit: 970656 kB\nCommitted_AS: 1260528 kB\n"
"VmallocTotal: 122880 kB\nVmallocUsed: 12144 kB\n"
"VmallocChunk: 103824 kB\nDirectMap4k: 9636 kB\n"
"DirectMap2M: 1955840 kB\n";
// All enum calls must report percents.
EXPECT_CALL(metrics_lib_, SendEnumToUMA(_, _, 100)).Times(AtLeast(1));
// Check that MemFree is correctly computed at 25%.
EXPECT_CALL(metrics_lib_, SendEnumToUMA("Platform.MeminfoMemFree", 25, 100))
.Times(AtLeast(1));
// Check that we call SendToUma at least once (log histogram).
EXPECT_CALL(metrics_lib_, SendToUMA(_, _, _, _, _))
.Times(AtLeast(1));
// Make sure we don't report fields not in the list.
EXPECT_CALL(metrics_lib_, SendToUMA("Platform.MeminfoMlocked", _, _, _, _))
.Times(0);
EXPECT_CALL(metrics_lib_, SendEnumToUMA("Platform.MeminfoMlocked", _, _))
.Times(0);
EXPECT_TRUE(daemon_.ProcessMeminfo(meminfo));
}
TEST_F(MetricsCollectorTest, ProcessMeminfo2) {
string meminfo = "MemTotal: 2000000 kB\nMemFree: 1000000 kB\n";
// Not enough fields.
EXPECT_FALSE(daemon_.ProcessMeminfo(meminfo));
}
TEST_F(MetricsCollectorTest, SendZramMetrics) {
EXPECT_TRUE(daemon_.testing_);
// |compr_data_size| is the size in bytes of compressed data.
const uint64_t compr_data_size = 50 * 1000 * 1000;
// The constant '3' is a realistic but random choice.
// |orig_data_size| does not include zero pages.
const uint64_t orig_data_size = compr_data_size * 3;
const uint64_t page_size = 4096;
const uint64_t zero_pages = 10 * 1000 * 1000 / page_size;
CreateUint64ValueFile(
temp_dir_.path().Append(MetricsCollector::kComprDataSizeName),
compr_data_size);
CreateUint64ValueFile(
temp_dir_.path().Append(MetricsCollector::kOrigDataSizeName),
orig_data_size);
CreateUint64ValueFile(
temp_dir_.path().Append(MetricsCollector::kZeroPagesName), zero_pages);
const uint64_t real_orig_size = orig_data_size + zero_pages * page_size;
const uint64_t zero_ratio_percent =
zero_pages * page_size * 100 / real_orig_size;
// Ratio samples are in percents.
const uint64_t actual_ratio_sample = real_orig_size * 100 / compr_data_size;
EXPECT_CALL(metrics_lib_, SendToUMA(_, compr_data_size >> 20, _, _, _));
EXPECT_CALL(metrics_lib_,
SendToUMA(_, (real_orig_size - compr_data_size) >> 20, _, _, _));
EXPECT_CALL(metrics_lib_, SendToUMA(_, actual_ratio_sample, _, _, _));
EXPECT_CALL(metrics_lib_, SendToUMA(_, zero_pages, _, _, _));
EXPECT_CALL(metrics_lib_, SendToUMA(_, zero_ratio_percent, _, _, _));
EXPECT_TRUE(daemon_.ReportZram(temp_dir_.path()));
}
|