blob: e99e40286a6a7efe193022ac62f7c2b21cbaff2b [file] [log] [blame]
Yao Chenb3561512017-11-21 18:07:17 -08001// Copyright (C) 2017 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "src/guardrail/StatsdStats.h"
Yao Chen69f1baf2017-11-27 17:25:36 -080016#include "statslog.h"
Yangster-mac94e197c2018-01-02 16:03:03 -080017#include "tests/statsd_test_util.h"
Yao Chenb3561512017-11-21 18:07:17 -080018
19#include <gtest/gtest.h>
Yao Chen69f1baf2017-11-27 17:25:36 -080020#include <vector>
Yao Chenb3561512017-11-21 18:07:17 -080021
22#ifdef __ANDROID__
23
24namespace android {
25namespace os {
26namespace statsd {
27
Yao Chen69f1baf2017-11-27 17:25:36 -080028using std::vector;
29
30TEST(StatsdStatsTest, TestValidConfigAdd) {
31 StatsdStats stats;
Yangster-mac94e197c2018-01-02 16:03:03 -080032 ConfigKey key(0, 12345);
Yao Chen69f1baf2017-11-27 17:25:36 -080033 const int metricsCount = 10;
34 const int conditionsCount = 20;
35 const int matchersCount = 30;
36 const int alertsCount = 10;
David Chenfaa1af52018-03-30 15:14:04 -070037 stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
Yao Chen69f1baf2017-11-27 17:25:36 -080038 true /*valid config*/);
39 vector<uint8_t> output;
40 stats.dumpStats(&output, false /*reset stats*/);
41
42 StatsdStatsReport report;
43 bool good = report.ParseFromArray(&output[0], output.size());
44 EXPECT_TRUE(good);
45 EXPECT_EQ(1, report.config_stats_size());
46 const auto& configReport = report.config_stats(0);
47 EXPECT_EQ(0, configReport.uid());
Yangster-mac94e197c2018-01-02 16:03:03 -080048 EXPECT_EQ(12345, configReport.id());
Yao Chen69f1baf2017-11-27 17:25:36 -080049 EXPECT_EQ(metricsCount, configReport.metric_count());
50 EXPECT_EQ(conditionsCount, configReport.condition_count());
51 EXPECT_EQ(matchersCount, configReport.matcher_count());
52 EXPECT_EQ(alertsCount, configReport.alert_count());
53 EXPECT_EQ(true, configReport.is_valid());
54 EXPECT_FALSE(configReport.has_deletion_time_sec());
55}
56
57TEST(StatsdStatsTest, TestInvalidConfigAdd) {
58 StatsdStats stats;
Yangster-mac94e197c2018-01-02 16:03:03 -080059 ConfigKey key(0, 12345);
Yao Chen69f1baf2017-11-27 17:25:36 -080060 const int metricsCount = 10;
61 const int conditionsCount = 20;
62 const int matchersCount = 30;
63 const int alertsCount = 10;
David Chenfaa1af52018-03-30 15:14:04 -070064 stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
Yao Chen69f1baf2017-11-27 17:25:36 -080065 false /*bad config*/);
66 vector<uint8_t> output;
67 stats.dumpStats(&output, false);
68
69 StatsdStatsReport report;
70 bool good = report.ParseFromArray(&output[0], output.size());
71 EXPECT_TRUE(good);
72 EXPECT_EQ(1, report.config_stats_size());
73 const auto& configReport = report.config_stats(0);
74 // The invalid config should be put into icebox with a deletion time.
75 EXPECT_TRUE(configReport.has_deletion_time_sec());
Yao Chenb3561512017-11-21 18:07:17 -080076}
77
78TEST(StatsdStatsTest, TestConfigRemove) {
Yao Chen69f1baf2017-11-27 17:25:36 -080079 StatsdStats stats;
Yangster-mac94e197c2018-01-02 16:03:03 -080080 ConfigKey key(0, 12345);
Yao Chen69f1baf2017-11-27 17:25:36 -080081 const int metricsCount = 10;
82 const int conditionsCount = 20;
83 const int matchersCount = 30;
84 const int alertsCount = 10;
David Chenfaa1af52018-03-30 15:14:04 -070085 stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
86 true);
Yao Chen69f1baf2017-11-27 17:25:36 -080087 vector<uint8_t> output;
88 stats.dumpStats(&output, false);
89 StatsdStatsReport report;
90 bool good = report.ParseFromArray(&output[0], output.size());
91 EXPECT_TRUE(good);
92 EXPECT_EQ(1, report.config_stats_size());
93 const auto& configReport = report.config_stats(0);
94 EXPECT_FALSE(configReport.has_deletion_time_sec());
95
96 stats.noteConfigRemoved(key);
97 stats.dumpStats(&output, false);
98 good = report.ParseFromArray(&output[0], output.size());
99 EXPECT_TRUE(good);
100 EXPECT_EQ(1, report.config_stats_size());
101 const auto& configReport2 = report.config_stats(0);
102 EXPECT_TRUE(configReport2.has_deletion_time_sec());
Yao Chenb3561512017-11-21 18:07:17 -0800103}
104
Yao Chen69f1baf2017-11-27 17:25:36 -0800105TEST(StatsdStatsTest, TestSubStats) {
106 StatsdStats stats;
Yangster-mac94e197c2018-01-02 16:03:03 -0800107 ConfigKey key(0, 12345);
David Chenfaa1af52018-03-30 15:14:04 -0700108 stats.noteConfigReceived(key, 2, 3, 4, 5, {std::make_pair(123, 456)}, true);
Yao Chenb3561512017-11-21 18:07:17 -0800109
Yangster-mac94e197c2018-01-02 16:03:03 -0800110 stats.noteMatcherMatched(key, StringToId("matcher1"));
111 stats.noteMatcherMatched(key, StringToId("matcher1"));
112 stats.noteMatcherMatched(key, StringToId("matcher2"));
Yao Chen69f1baf2017-11-27 17:25:36 -0800113
Yangster-mac94e197c2018-01-02 16:03:03 -0800114 stats.noteConditionDimensionSize(key, StringToId("condition1"), 250);
115 stats.noteConditionDimensionSize(key, StringToId("condition1"), 240);
Yao Chen69f1baf2017-11-27 17:25:36 -0800116
Yangster-mac94e197c2018-01-02 16:03:03 -0800117 stats.noteMetricDimensionSize(key, StringToId("metric1"), 201);
118 stats.noteMetricDimensionSize(key, StringToId("metric1"), 202);
Yao Chen69f1baf2017-11-27 17:25:36 -0800119
Yangster-mac94e197c2018-01-02 16:03:03 -0800120 stats.noteAnomalyDeclared(key, StringToId("alert1"));
121 stats.noteAnomalyDeclared(key, StringToId("alert1"));
122 stats.noteAnomalyDeclared(key, StringToId("alert2"));
Bookatz8f2f3d82017-12-07 13:53:21 -0800123
Yao Chen69f1baf2017-11-27 17:25:36 -0800124 // broadcast-> 2
125 stats.noteBroadcastSent(key);
126 stats.noteBroadcastSent(key);
127
128 // data drop -> 1
129 stats.noteDataDropped(key);
130
131 // dump report -> 3
Yangster-mace68f3a52018-04-04 00:01:43 -0700132 stats.noteMetricsReportSent(key, 0);
133 stats.noteMetricsReportSent(key, 0);
134 stats.noteMetricsReportSent(key, 0);
Yao Chen69f1baf2017-11-27 17:25:36 -0800135
136 vector<uint8_t> output;
137 stats.dumpStats(&output, true); // Dump and reset stats
138 StatsdStatsReport report;
139 bool good = report.ParseFromArray(&output[0], output.size());
140 EXPECT_TRUE(good);
141 EXPECT_EQ(1, report.config_stats_size());
142 const auto& configReport = report.config_stats(0);
143 EXPECT_EQ(2, configReport.broadcast_sent_time_sec_size());
144 EXPECT_EQ(1, configReport.data_drop_time_sec_size());
145 EXPECT_EQ(3, configReport.dump_report_time_sec_size());
Yangster-mace68f3a52018-04-04 00:01:43 -0700146 EXPECT_EQ(3, configReport.dump_report_data_size_size());
David Chenfaa1af52018-03-30 15:14:04 -0700147 EXPECT_EQ(1, configReport.annotation_size());
148 EXPECT_EQ(123, configReport.annotation(0).field_int64());
149 EXPECT_EQ(456, configReport.annotation(0).field_int32());
Yao Chen69f1baf2017-11-27 17:25:36 -0800150
151 EXPECT_EQ(2, configReport.matcher_stats_size());
Yao Chen69f1baf2017-11-27 17:25:36 -0800152 // matcher1 is the first in the list
Yangster-mac94e197c2018-01-02 16:03:03 -0800153 if (configReport.matcher_stats(0).id() == StringToId("matcher1")) {
Yao Chen69f1baf2017-11-27 17:25:36 -0800154 EXPECT_EQ(2, configReport.matcher_stats(0).matched_times());
155 EXPECT_EQ(1, configReport.matcher_stats(1).matched_times());
Yangster-mac94e197c2018-01-02 16:03:03 -0800156 EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(1).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800157 } else {
158 // matcher1 is the second in the list.
159 EXPECT_EQ(1, configReport.matcher_stats(0).matched_times());
Yangster-mac94e197c2018-01-02 16:03:03 -0800160 EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800161
162 EXPECT_EQ(2, configReport.matcher_stats(1).matched_times());
Yangster-mac94e197c2018-01-02 16:03:03 -0800163 EXPECT_EQ(StringToId("matcher1"), configReport.matcher_stats(1).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800164 }
165
Bookatz8f2f3d82017-12-07 13:53:21 -0800166 EXPECT_EQ(2, configReport.alert_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800167 bool alert1first = configReport.alert_stats(0).id() == StringToId("alert1");
168 EXPECT_EQ(StringToId("alert1"), configReport.alert_stats(alert1first ? 0 : 1).id());
Bookatze1d143a2017-12-13 15:21:57 -0800169 EXPECT_EQ(2, configReport.alert_stats(alert1first ? 0 : 1).alerted_times());
Yangster-mac94e197c2018-01-02 16:03:03 -0800170 EXPECT_EQ(StringToId("alert2"), configReport.alert_stats(alert1first ? 1 : 0).id());
Bookatze1d143a2017-12-13 15:21:57 -0800171 EXPECT_EQ(1, configReport.alert_stats(alert1first ? 1 : 0).alerted_times());
Bookatz8f2f3d82017-12-07 13:53:21 -0800172
Yao Chen69f1baf2017-11-27 17:25:36 -0800173 EXPECT_EQ(1, configReport.condition_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800174 EXPECT_EQ(StringToId("condition1"), configReport.condition_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800175 EXPECT_EQ(250, configReport.condition_stats(0).max_tuple_counts());
176
177 EXPECT_EQ(1, configReport.metric_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800178 EXPECT_EQ(StringToId("metric1"), configReport.metric_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800179 EXPECT_EQ(202, configReport.metric_stats(0).max_tuple_counts());
180
181 // after resetting the stats, some new events come
Yangster-mac94e197c2018-01-02 16:03:03 -0800182 stats.noteMatcherMatched(key, StringToId("matcher99"));
183 stats.noteConditionDimensionSize(key, StringToId("condition99"), 300);
184 stats.noteMetricDimensionSize(key, StringToId("metric99tion99"), 270);
185 stats.noteAnomalyDeclared(key, StringToId("alert99"));
Yao Chen69f1baf2017-11-27 17:25:36 -0800186
187 // now the config stats should only contain the stats about the new event.
188 stats.dumpStats(&output, false);
189 good = report.ParseFromArray(&output[0], output.size());
190 EXPECT_TRUE(good);
191 EXPECT_EQ(1, report.config_stats_size());
192 const auto& configReport2 = report.config_stats(0);
193 EXPECT_EQ(1, configReport2.matcher_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800194 EXPECT_EQ(StringToId("matcher99"), configReport2.matcher_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800195 EXPECT_EQ(1, configReport2.matcher_stats(0).matched_times());
196
197 EXPECT_EQ(1, configReport2.condition_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800198 EXPECT_EQ(StringToId("condition99"), configReport2.condition_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800199 EXPECT_EQ(300, configReport2.condition_stats(0).max_tuple_counts());
200
201 EXPECT_EQ(1, configReport2.metric_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800202 EXPECT_EQ(StringToId("metric99tion99"), configReport2.metric_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800203 EXPECT_EQ(270, configReport2.metric_stats(0).max_tuple_counts());
Bookatz8f2f3d82017-12-07 13:53:21 -0800204
205 EXPECT_EQ(1, configReport2.alert_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800206 EXPECT_EQ(StringToId("alert99"), configReport2.alert_stats(0).id());
Bookatze1d143a2017-12-13 15:21:57 -0800207 EXPECT_EQ(1, configReport2.alert_stats(0).alerted_times());
Yao Chenb3561512017-11-21 18:07:17 -0800208}
209
210TEST(StatsdStatsTest, TestAtomLog) {
Yao Chen69f1baf2017-11-27 17:25:36 -0800211 StatsdStats stats;
212 time_t now = time(nullptr);
213 // old event, we get it from the stats buffer. should be ignored.
214 stats.noteAtomLogged(android::util::SENSOR_STATE_CHANGED, 1000);
215
216 stats.noteAtomLogged(android::util::SENSOR_STATE_CHANGED, now + 1);
217 stats.noteAtomLogged(android::util::SENSOR_STATE_CHANGED, now + 2);
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800218 stats.noteAtomLogged(android::util::APP_CRASH_OCCURRED, now + 3);
Yao Chen69f1baf2017-11-27 17:25:36 -0800219 // pulled event, should ignore
Chenjie Yu31d14d72017-12-12 17:54:33 -0800220 stats.noteAtomLogged(android::util::WIFI_BYTES_TRANSFER, now + 4);
Yao Chen69f1baf2017-11-27 17:25:36 -0800221
222 vector<uint8_t> output;
223 stats.dumpStats(&output, false);
224 StatsdStatsReport report;
225 bool good = report.ParseFromArray(&output[0], output.size());
226 EXPECT_TRUE(good);
227
228 EXPECT_EQ(2, report.atom_stats_size());
229 bool sensorAtomGood = false;
230 bool dropboxAtomGood = false;
231
232 for (const auto& atomStats : report.atom_stats()) {
Yangster-mac330af582018-02-08 15:24:38 -0800233 if (atomStats.tag() == android::util::SENSOR_STATE_CHANGED && atomStats.count() == 3) {
Yao Chen69f1baf2017-11-27 17:25:36 -0800234 sensorAtomGood = true;
235 }
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800236 if (atomStats.tag() == android::util::APP_CRASH_OCCURRED && atomStats.count() == 1) {
Yao Chen69f1baf2017-11-27 17:25:36 -0800237 dropboxAtomGood = true;
238 }
239 }
240
241 EXPECT_TRUE(dropboxAtomGood);
242 EXPECT_TRUE(sensorAtomGood);
Yao Chenb3561512017-11-21 18:07:17 -0800243}
244
Bookatz1d0136d2017-12-01 11:13:32 -0800245
246TEST(StatsdStatsTest, TestAnomalyMonitor) {
247 StatsdStats stats;
248 stats.noteRegisteredAnomalyAlarmChanged();
249 stats.noteRegisteredAnomalyAlarmChanged();
250
251 vector<uint8_t> output;
252 stats.dumpStats(&output, false);
253 StatsdStatsReport report;
254 bool good = report.ParseFromArray(&output[0], output.size());
255 EXPECT_TRUE(good);
256
257 EXPECT_EQ(2, report.anomaly_alarm_stats().alarms_registered());
258}
259
Yao Chen0fac5b12017-11-28 16:07:02 -0800260TEST(StatsdStatsTest, TestTimestampThreshold) {
261 StatsdStats stats;
262 vector<int32_t> timestamps;
263 for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
264 timestamps.push_back(i);
265 }
Yangster-mac94e197c2018-01-02 16:03:03 -0800266 ConfigKey key(0, 12345);
David Chenfaa1af52018-03-30 15:14:04 -0700267 stats.noteConfigReceived(key, 2, 3, 4, 5, {}, true);
Yao Chen0fac5b12017-11-28 16:07:02 -0800268
269 for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
270 stats.noteDataDropped(key, timestamps[i]);
271 stats.noteBroadcastSent(key, timestamps[i]);
Yangster-mace68f3a52018-04-04 00:01:43 -0700272 stats.noteMetricsReportSent(key, 0, timestamps[i]);
Yao Chen0fac5b12017-11-28 16:07:02 -0800273 }
274
275 int32_t newTimestamp = 10000;
276
277 // now it should trigger removing oldest timestamp
278 stats.noteDataDropped(key, 10000);
279 stats.noteBroadcastSent(key, 10000);
Yangster-mace68f3a52018-04-04 00:01:43 -0700280 stats.noteMetricsReportSent(key, 0, 10000);
Yao Chen0fac5b12017-11-28 16:07:02 -0800281
282 EXPECT_TRUE(stats.mConfigStats.find(key) != stats.mConfigStats.end());
283 const auto& configStats = stats.mConfigStats[key];
284
Yao Chen20e9e622018-02-28 11:18:51 -0800285 size_t maxCount = StatsdStats::kMaxTimestampCount;
286 EXPECT_EQ(maxCount, configStats->broadcast_sent_time_sec.size());
287 EXPECT_EQ(maxCount, configStats->data_drop_time_sec.size());
Yangster-mace68f3a52018-04-04 00:01:43 -0700288 EXPECT_EQ(maxCount, configStats->dump_report_stats.size());
Yao Chen0fac5b12017-11-28 16:07:02 -0800289
290 // the oldest timestamp is the second timestamp in history
Yao Chen20e9e622018-02-28 11:18:51 -0800291 EXPECT_EQ(1, configStats->broadcast_sent_time_sec.front());
292 EXPECT_EQ(1, configStats->broadcast_sent_time_sec.front());
293 EXPECT_EQ(1, configStats->broadcast_sent_time_sec.front());
Yao Chen0fac5b12017-11-28 16:07:02 -0800294
295 // the last timestamp is the newest timestamp.
Yao Chen20e9e622018-02-28 11:18:51 -0800296 EXPECT_EQ(newTimestamp, configStats->broadcast_sent_time_sec.back());
297 EXPECT_EQ(newTimestamp, configStats->data_drop_time_sec.back());
Yangster-mace68f3a52018-04-04 00:01:43 -0700298 EXPECT_EQ(newTimestamp, configStats->dump_report_stats.back().first);
Yao Chen0fac5b12017-11-28 16:07:02 -0800299}
300
Yao Chenb3561512017-11-21 18:07:17 -0800301} // namespace statsd
302} // namespace os
303} // namespace android
304#else
305GTEST_LOG_(INFO) << "This test does nothing.\n";
306#endif