blob: 5cc10cd9840ce996029f2e7cef55365e7211b3e8 [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"
Jeffrey Huang3eb84d42020-03-17 10:31:22 -070016#include "statslog_statsdtest.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);
Muhammad Qureshidff78d62020-05-11 13:37:43 -070045 ASSERT_EQ(1, report.config_stats_size());
Yao Chen69f1baf2017-11-27 17:25:36 -080046 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);
Muhammad Qureshidff78d62020-05-11 13:37:43 -070072 ASSERT_EQ(1, report.config_stats_size());
Yao Chen69f1baf2017-11-27 17:25:36 -080073 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);
Muhammad Qureshidff78d62020-05-11 13:37:43 -070092 ASSERT_EQ(1, report.config_stats_size());
Yao Chen69f1baf2017-11-27 17:25:36 -080093 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);
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700100 ASSERT_EQ(1, report.config_stats_size());
Yao Chen69f1baf2017-11-27 17:25:36 -0800101 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
Chenjie Yuc3c30c02018-10-26 09:48:07 -0700129 stats.noteDataDropped(key, 123);
Yao Chen69f1baf2017-11-27 17:25:36 -0800130
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
Tej Singh6ede28b2019-01-29 17:06:54 -0800136 // activation_time_sec -> 2
137 stats.noteActiveStatusChanged(key, true);
138 stats.noteActiveStatusChanged(key, true);
139
140 // deactivation_time_sec -> 1
141 stats.noteActiveStatusChanged(key, false);
142
Yao Chen69f1baf2017-11-27 17:25:36 -0800143 vector<uint8_t> output;
144 stats.dumpStats(&output, true); // Dump and reset stats
145 StatsdStatsReport report;
146 bool good = report.ParseFromArray(&output[0], output.size());
147 EXPECT_TRUE(good);
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700148 ASSERT_EQ(1, report.config_stats_size());
Yao Chen69f1baf2017-11-27 17:25:36 -0800149 const auto& configReport = report.config_stats(0);
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700150 ASSERT_EQ(2, configReport.broadcast_sent_time_sec_size());
151 ASSERT_EQ(1, configReport.data_drop_time_sec_size());
152 ASSERT_EQ(1, configReport.data_drop_bytes_size());
Chenjie Yuc3c30c02018-10-26 09:48:07 -0700153 EXPECT_EQ(123, configReport.data_drop_bytes(0));
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700154 ASSERT_EQ(3, configReport.dump_report_time_sec_size());
155 ASSERT_EQ(3, configReport.dump_report_data_size_size());
156 ASSERT_EQ(2, configReport.activation_time_sec_size());
157 ASSERT_EQ(1, configReport.deactivation_time_sec_size());
158 ASSERT_EQ(1, configReport.annotation_size());
David Chenfaa1af52018-03-30 15:14:04 -0700159 EXPECT_EQ(123, configReport.annotation(0).field_int64());
160 EXPECT_EQ(456, configReport.annotation(0).field_int32());
Yao Chen69f1baf2017-11-27 17:25:36 -0800161
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700162 ASSERT_EQ(2, configReport.matcher_stats_size());
Yao Chen69f1baf2017-11-27 17:25:36 -0800163 // matcher1 is the first in the list
Yangster-mac94e197c2018-01-02 16:03:03 -0800164 if (configReport.matcher_stats(0).id() == StringToId("matcher1")) {
Yao Chen69f1baf2017-11-27 17:25:36 -0800165 EXPECT_EQ(2, configReport.matcher_stats(0).matched_times());
166 EXPECT_EQ(1, configReport.matcher_stats(1).matched_times());
Yangster-mac94e197c2018-01-02 16:03:03 -0800167 EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(1).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800168 } else {
169 // matcher1 is the second in the list.
170 EXPECT_EQ(1, configReport.matcher_stats(0).matched_times());
Yangster-mac94e197c2018-01-02 16:03:03 -0800171 EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800172
173 EXPECT_EQ(2, configReport.matcher_stats(1).matched_times());
Yangster-mac94e197c2018-01-02 16:03:03 -0800174 EXPECT_EQ(StringToId("matcher1"), configReport.matcher_stats(1).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800175 }
176
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700177 ASSERT_EQ(2, configReport.alert_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800178 bool alert1first = configReport.alert_stats(0).id() == StringToId("alert1");
179 EXPECT_EQ(StringToId("alert1"), configReport.alert_stats(alert1first ? 0 : 1).id());
Bookatze1d143a2017-12-13 15:21:57 -0800180 EXPECT_EQ(2, configReport.alert_stats(alert1first ? 0 : 1).alerted_times());
Yangster-mac94e197c2018-01-02 16:03:03 -0800181 EXPECT_EQ(StringToId("alert2"), configReport.alert_stats(alert1first ? 1 : 0).id());
Bookatze1d143a2017-12-13 15:21:57 -0800182 EXPECT_EQ(1, configReport.alert_stats(alert1first ? 1 : 0).alerted_times());
Bookatz8f2f3d82017-12-07 13:53:21 -0800183
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700184 ASSERT_EQ(1, configReport.condition_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800185 EXPECT_EQ(StringToId("condition1"), configReport.condition_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800186 EXPECT_EQ(250, configReport.condition_stats(0).max_tuple_counts());
187
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700188 ASSERT_EQ(1, configReport.metric_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800189 EXPECT_EQ(StringToId("metric1"), configReport.metric_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800190 EXPECT_EQ(202, configReport.metric_stats(0).max_tuple_counts());
191
192 // after resetting the stats, some new events come
Yangster-mac94e197c2018-01-02 16:03:03 -0800193 stats.noteMatcherMatched(key, StringToId("matcher99"));
194 stats.noteConditionDimensionSize(key, StringToId("condition99"), 300);
195 stats.noteMetricDimensionSize(key, StringToId("metric99tion99"), 270);
196 stats.noteAnomalyDeclared(key, StringToId("alert99"));
Yao Chen69f1baf2017-11-27 17:25:36 -0800197
198 // now the config stats should only contain the stats about the new event.
199 stats.dumpStats(&output, false);
200 good = report.ParseFromArray(&output[0], output.size());
201 EXPECT_TRUE(good);
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700202 ASSERT_EQ(1, report.config_stats_size());
Yao Chen69f1baf2017-11-27 17:25:36 -0800203 const auto& configReport2 = report.config_stats(0);
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700204 ASSERT_EQ(1, configReport2.matcher_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800205 EXPECT_EQ(StringToId("matcher99"), configReport2.matcher_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800206 EXPECT_EQ(1, configReport2.matcher_stats(0).matched_times());
207
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700208 ASSERT_EQ(1, configReport2.condition_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800209 EXPECT_EQ(StringToId("condition99"), configReport2.condition_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800210 EXPECT_EQ(300, configReport2.condition_stats(0).max_tuple_counts());
211
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700212 ASSERT_EQ(1, configReport2.metric_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800213 EXPECT_EQ(StringToId("metric99tion99"), configReport2.metric_stats(0).id());
Yao Chen69f1baf2017-11-27 17:25:36 -0800214 EXPECT_EQ(270, configReport2.metric_stats(0).max_tuple_counts());
Bookatz8f2f3d82017-12-07 13:53:21 -0800215
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700216 ASSERT_EQ(1, configReport2.alert_stats_size());
Yangster-mac94e197c2018-01-02 16:03:03 -0800217 EXPECT_EQ(StringToId("alert99"), configReport2.alert_stats(0).id());
Bookatze1d143a2017-12-13 15:21:57 -0800218 EXPECT_EQ(1, configReport2.alert_stats(0).alerted_times());
Yao Chenb3561512017-11-21 18:07:17 -0800219}
220
221TEST(StatsdStatsTest, TestAtomLog) {
Yao Chen69f1baf2017-11-27 17:25:36 -0800222 StatsdStats stats;
223 time_t now = time(nullptr);
224 // old event, we get it from the stats buffer. should be ignored.
Jeffrey Huang3eb84d42020-03-17 10:31:22 -0700225 stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, 1000);
Yao Chen69f1baf2017-11-27 17:25:36 -0800226
Jeffrey Huang3eb84d42020-03-17 10:31:22 -0700227 stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, now + 1);
228 stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, now + 2);
229 stats.noteAtomLogged(util::APP_CRASH_OCCURRED, now + 3);
Yao Chen69f1baf2017-11-27 17:25:36 -0800230
231 vector<uint8_t> output;
232 stats.dumpStats(&output, false);
233 StatsdStatsReport report;
234 bool good = report.ParseFromArray(&output[0], output.size());
235 EXPECT_TRUE(good);
236
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700237 ASSERT_EQ(2, report.atom_stats_size());
Yao Chen69f1baf2017-11-27 17:25:36 -0800238 bool sensorAtomGood = false;
239 bool dropboxAtomGood = false;
240
241 for (const auto& atomStats : report.atom_stats()) {
Jeffrey Huang3eb84d42020-03-17 10:31:22 -0700242 if (atomStats.tag() == util::SENSOR_STATE_CHANGED && atomStats.count() == 3) {
Yao Chen69f1baf2017-11-27 17:25:36 -0800243 sensorAtomGood = true;
244 }
Jeffrey Huang3eb84d42020-03-17 10:31:22 -0700245 if (atomStats.tag() == util::APP_CRASH_OCCURRED && atomStats.count() == 1) {
Yao Chen69f1baf2017-11-27 17:25:36 -0800246 dropboxAtomGood = true;
247 }
248 }
249
250 EXPECT_TRUE(dropboxAtomGood);
251 EXPECT_TRUE(sensorAtomGood);
Yao Chenb3561512017-11-21 18:07:17 -0800252}
253
Tej Singh35c7a572019-05-01 16:47:54 -0700254TEST(StatsdStatsTest, TestNonPlatformAtomLog) {
255 StatsdStats stats;
256 time_t now = time(nullptr);
Muhammad Qureshicdf291d2020-04-15 17:13:12 -0700257 int newAtom1 = StatsdStats::kMaxPushedAtomId + 1;
258 int newAtom2 = StatsdStats::kMaxPushedAtomId + 2;
Tej Singh35c7a572019-05-01 16:47:54 -0700259
260 stats.noteAtomLogged(newAtom1, now + 1);
261 stats.noteAtomLogged(newAtom1, now + 2);
262 stats.noteAtomLogged(newAtom2, now + 3);
263
264 vector<uint8_t> output;
265 stats.dumpStats(&output, false);
266 StatsdStatsReport report;
267 bool good = report.ParseFromArray(&output[0], output.size());
268 EXPECT_TRUE(good);
269
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700270 ASSERT_EQ(2, report.atom_stats_size());
Tej Singh35c7a572019-05-01 16:47:54 -0700271 bool newAtom1Good = false;
272 bool newAtom2Good = false;
273
274 for (const auto& atomStats : report.atom_stats()) {
275 if (atomStats.tag() == newAtom1 && atomStats.count() == 2) {
276 newAtom1Good = true;
277 }
278 if (atomStats.tag() == newAtom2 && atomStats.count() == 1) {
279 newAtom2Good = true;
280 }
281 }
282
283 EXPECT_TRUE(newAtom1Good);
284 EXPECT_TRUE(newAtom2Good);
285}
286
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700287TEST(StatsdStatsTest, TestPullAtomStats) {
288 StatsdStats stats;
289
Jeffrey Huang3eb84d42020-03-17 10:31:22 -0700290 stats.updateMinPullIntervalSec(util::DISK_SPACE, 3333L);
291 stats.updateMinPullIntervalSec(util::DISK_SPACE, 2222L);
292 stats.updateMinPullIntervalSec(util::DISK_SPACE, 4444L);
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700293
Jeffrey Huang3eb84d42020-03-17 10:31:22 -0700294 stats.notePull(util::DISK_SPACE);
295 stats.notePullTime(util::DISK_SPACE, 1111L);
296 stats.notePullDelay(util::DISK_SPACE, 1111L);
297 stats.notePull(util::DISK_SPACE);
298 stats.notePullTime(util::DISK_SPACE, 3333L);
299 stats.notePullDelay(util::DISK_SPACE, 3335L);
300 stats.notePull(util::DISK_SPACE);
301 stats.notePullFromCache(util::DISK_SPACE);
302 stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, true);
303 stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, false);
304 stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, true);
Tej Singh873e91a2020-04-28 00:33:11 -0700305 stats.notePullBinderCallFailed(util::DISK_SPACE);
306 stats.notePullUidProviderNotFound(util::DISK_SPACE);
307 stats.notePullerNotFound(util::DISK_SPACE);
308 stats.notePullerNotFound(util::DISK_SPACE);
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700309
310 vector<uint8_t> output;
311 stats.dumpStats(&output, false);
312 StatsdStatsReport report;
313 bool good = report.ParseFromArray(&output[0], output.size());
314 EXPECT_TRUE(good);
315
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700316 ASSERT_EQ(1, report.pulled_atom_stats_size());
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700317
Jeffrey Huang3eb84d42020-03-17 10:31:22 -0700318 EXPECT_EQ(util::DISK_SPACE, report.pulled_atom_stats(0).atom_id());
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700319 EXPECT_EQ(3, report.pulled_atom_stats(0).total_pull());
320 EXPECT_EQ(1, report.pulled_atom_stats(0).total_pull_from_cache());
321 EXPECT_EQ(2222L, report.pulled_atom_stats(0).min_pull_interval_sec());
322 EXPECT_EQ(2222L, report.pulled_atom_stats(0).average_pull_time_nanos());
323 EXPECT_EQ(3333L, report.pulled_atom_stats(0).max_pull_time_nanos());
324 EXPECT_EQ(2223L, report.pulled_atom_stats(0).average_pull_delay_nanos());
325 EXPECT_EQ(3335L, report.pulled_atom_stats(0).max_pull_delay_nanos());
Tej Singha0c89dd2019-01-25 16:39:18 -0800326 EXPECT_EQ(2L, report.pulled_atom_stats(0).registered_count());
327 EXPECT_EQ(1L, report.pulled_atom_stats(0).unregistered_count());
Tej Singh873e91a2020-04-28 00:33:11 -0700328 EXPECT_EQ(1L, report.pulled_atom_stats(0).binder_call_failed());
329 EXPECT_EQ(1L, report.pulled_atom_stats(0).failed_uid_provider_not_found());
330 EXPECT_EQ(2L, report.pulled_atom_stats(0).puller_not_found());
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700331}
Bookatz1d0136d2017-12-01 11:13:32 -0800332
Olivier Gaillarde3e969c2019-02-11 11:22:51 +0000333TEST(StatsdStatsTest, TestAtomMetricsStats) {
334 StatsdStats stats;
335 time_t now = time(nullptr);
336 // old event, we get it from the stats buffer. should be ignored.
337 stats.noteBucketDropped(1000L);
338
339 stats.noteBucketBoundaryDelayNs(1000L, -1L);
340 stats.noteBucketBoundaryDelayNs(1000L, -10L);
341 stats.noteBucketBoundaryDelayNs(1000L, 2L);
342
343 stats.noteBucketBoundaryDelayNs(1001L, 1L);
344
345 vector<uint8_t> output;
346 stats.dumpStats(&output, false);
347 StatsdStatsReport report;
348 bool good = report.ParseFromArray(&output[0], output.size());
349 EXPECT_TRUE(good);
350
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700351 ASSERT_EQ(2, report.atom_metric_stats().size());
Olivier Gaillarde3e969c2019-02-11 11:22:51 +0000352
353 auto atomStats = report.atom_metric_stats(0);
354 EXPECT_EQ(1000L, atomStats.metric_id());
355 EXPECT_EQ(1L, atomStats.bucket_dropped());
356 EXPECT_EQ(-10L, atomStats.min_bucket_boundary_delay_ns());
357 EXPECT_EQ(2L, atomStats.max_bucket_boundary_delay_ns());
358
359 auto atomStats2 = report.atom_metric_stats(1);
360 EXPECT_EQ(1001L, atomStats2.metric_id());
361 EXPECT_EQ(0L, atomStats2.bucket_dropped());
362 EXPECT_EQ(0L, atomStats2.min_bucket_boundary_delay_ns());
363 EXPECT_EQ(1L, atomStats2.max_bucket_boundary_delay_ns());
364}
365
Bookatz1d0136d2017-12-01 11:13:32 -0800366TEST(StatsdStatsTest, TestAnomalyMonitor) {
367 StatsdStats stats;
368 stats.noteRegisteredAnomalyAlarmChanged();
369 stats.noteRegisteredAnomalyAlarmChanged();
370
371 vector<uint8_t> output;
372 stats.dumpStats(&output, false);
373 StatsdStatsReport report;
374 bool good = report.ParseFromArray(&output[0], output.size());
375 EXPECT_TRUE(good);
376
377 EXPECT_EQ(2, report.anomaly_alarm_stats().alarms_registered());
378}
379
Yao Chen0fac5b12017-11-28 16:07:02 -0800380TEST(StatsdStatsTest, TestTimestampThreshold) {
381 StatsdStats stats;
382 vector<int32_t> timestamps;
383 for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
384 timestamps.push_back(i);
385 }
Yangster-mac94e197c2018-01-02 16:03:03 -0800386 ConfigKey key(0, 12345);
David Chenfaa1af52018-03-30 15:14:04 -0700387 stats.noteConfigReceived(key, 2, 3, 4, 5, {}, true);
Yao Chen0fac5b12017-11-28 16:07:02 -0800388
389 for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
390 stats.noteDataDropped(key, timestamps[i]);
391 stats.noteBroadcastSent(key, timestamps[i]);
Yangster-mace68f3a52018-04-04 00:01:43 -0700392 stats.noteMetricsReportSent(key, 0, timestamps[i]);
Tej Singh6ede28b2019-01-29 17:06:54 -0800393 stats.noteActiveStatusChanged(key, true, timestamps[i]);
394 stats.noteActiveStatusChanged(key, false, timestamps[i]);
Yao Chen0fac5b12017-11-28 16:07:02 -0800395 }
396
397 int32_t newTimestamp = 10000;
398
399 // now it should trigger removing oldest timestamp
Chenjie Yuc3c30c02018-10-26 09:48:07 -0700400 stats.noteDataDropped(key, 123, 10000);
Yao Chen0fac5b12017-11-28 16:07:02 -0800401 stats.noteBroadcastSent(key, 10000);
Yangster-mace68f3a52018-04-04 00:01:43 -0700402 stats.noteMetricsReportSent(key, 0, 10000);
Tej Singh6ede28b2019-01-29 17:06:54 -0800403 stats.noteActiveStatusChanged(key, true, 10000);
404 stats.noteActiveStatusChanged(key, false, 10000);
Yao Chen0fac5b12017-11-28 16:07:02 -0800405
406 EXPECT_TRUE(stats.mConfigStats.find(key) != stats.mConfigStats.end());
407 const auto& configStats = stats.mConfigStats[key];
408
Yao Chen20e9e622018-02-28 11:18:51 -0800409 size_t maxCount = StatsdStats::kMaxTimestampCount;
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700410 ASSERT_EQ(maxCount, configStats->broadcast_sent_time_sec.size());
411 ASSERT_EQ(maxCount, configStats->data_drop_time_sec.size());
412 ASSERT_EQ(maxCount, configStats->dump_report_stats.size());
413 ASSERT_EQ(maxCount, configStats->activation_time_sec.size());
414 ASSERT_EQ(maxCount, configStats->deactivation_time_sec.size());
Yao Chen0fac5b12017-11-28 16:07:02 -0800415
416 // the oldest timestamp is the second timestamp in history
Yao Chen20e9e622018-02-28 11:18:51 -0800417 EXPECT_EQ(1, configStats->broadcast_sent_time_sec.front());
Tej Singh6ede28b2019-01-29 17:06:54 -0800418 EXPECT_EQ(1, configStats->data_drop_bytes.front());
419 EXPECT_EQ(1, configStats->dump_report_stats.front().first);
420 EXPECT_EQ(1, configStats->activation_time_sec.front());
421 EXPECT_EQ(1, configStats->deactivation_time_sec.front());
Yao Chen0fac5b12017-11-28 16:07:02 -0800422
423 // the last timestamp is the newest timestamp.
Yao Chen20e9e622018-02-28 11:18:51 -0800424 EXPECT_EQ(newTimestamp, configStats->broadcast_sent_time_sec.back());
425 EXPECT_EQ(newTimestamp, configStats->data_drop_time_sec.back());
Chenjie Yuc3c30c02018-10-26 09:48:07 -0700426 EXPECT_EQ(123, configStats->data_drop_bytes.back());
Yangster-mace68f3a52018-04-04 00:01:43 -0700427 EXPECT_EQ(newTimestamp, configStats->dump_report_stats.back().first);
Tej Singh6ede28b2019-01-29 17:06:54 -0800428 EXPECT_EQ(newTimestamp, configStats->activation_time_sec.back());
429 EXPECT_EQ(newTimestamp, configStats->deactivation_time_sec.back());
Yao Chen0fac5b12017-11-28 16:07:02 -0800430}
431
Yangster-mac892f3d32018-05-02 14:16:48 -0700432TEST(StatsdStatsTest, TestSystemServerCrash) {
433 StatsdStats stats;
434 vector<int32_t> timestamps;
435 for (int i = 0; i < StatsdStats::kMaxSystemServerRestarts; i++) {
436 timestamps.push_back(i);
437 stats.noteSystemServerRestart(timestamps[i]);
438 }
439 vector<uint8_t> output;
440 stats.dumpStats(&output, false);
441 StatsdStatsReport report;
442 EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
443 const int maxCount = StatsdStats::kMaxSystemServerRestarts;
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700444 ASSERT_EQ(maxCount, (int)report.system_restart_sec_size());
Yangster-mac892f3d32018-05-02 14:16:48 -0700445
446 stats.noteSystemServerRestart(StatsdStats::kMaxSystemServerRestarts + 1);
447 output.clear();
448 stats.dumpStats(&output, false);
449 EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700450 ASSERT_EQ(maxCount, (int)report.system_restart_sec_size());
Yangster-mac892f3d32018-05-02 14:16:48 -0700451 EXPECT_EQ(StatsdStats::kMaxSystemServerRestarts + 1, report.system_restart_sec(maxCount - 1));
452}
453
Tej Singh16ca28f2019-06-24 11:58:23 -0700454TEST(StatsdStatsTest, TestActivationBroadcastGuardrailHit) {
455 StatsdStats stats;
456 int uid1 = 1;
457 int uid2 = 2;
458 stats.noteActivationBroadcastGuardrailHit(uid1, 10);
459 stats.noteActivationBroadcastGuardrailHit(uid1, 20);
460
461 // Test that we only keep 20 timestamps.
462 for (int i = 0; i < 100; i++) {
463 stats.noteActivationBroadcastGuardrailHit(uid2, i);
464 }
465
466 vector<uint8_t> output;
467 stats.dumpStats(&output, false);
468 StatsdStatsReport report;
469 EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
470
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700471 ASSERT_EQ(2, report.activation_guardrail_stats_size());
Tej Singh16ca28f2019-06-24 11:58:23 -0700472 bool uid1Good = false;
473 bool uid2Good = false;
474 for (const auto& guardrailTimes : report.activation_guardrail_stats()) {
475 if (uid1 == guardrailTimes.uid()) {
476 uid1Good = true;
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700477 ASSERT_EQ(2, guardrailTimes.guardrail_met_sec_size());
Tej Singh16ca28f2019-06-24 11:58:23 -0700478 EXPECT_EQ(10, guardrailTimes.guardrail_met_sec(0));
479 EXPECT_EQ(20, guardrailTimes.guardrail_met_sec(1));
480 } else if (uid2 == guardrailTimes.uid()) {
481 int maxCount = StatsdStats::kMaxTimestampCount;
482 uid2Good = true;
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700483 ASSERT_EQ(maxCount, guardrailTimes.guardrail_met_sec_size());
Tej Singh16ca28f2019-06-24 11:58:23 -0700484 for (int i = 0; i < maxCount; i++) {
485 EXPECT_EQ(100 - maxCount + i, guardrailTimes.guardrail_met_sec(i));
486 }
487 } else {
488 FAIL() << "Unexpected uid.";
489 }
490 }
491 EXPECT_TRUE(uid1Good);
492 EXPECT_TRUE(uid2Good);
493}
494
Ruchir Rastogi07f7adb2020-04-16 17:46:12 -0700495TEST(StatsdStatsTest, TestAtomErrorStats) {
496 StatsdStats stats;
497
498 int pushAtomTag = 100;
499 int pullAtomTag = 1000;
500 int numErrors = 10;
501
502 for (int i = 0; i < numErrors; i++) {
503 // We must call noteAtomLogged as well because only those pushed atoms
504 // that have been logged will have stats printed about them in the
505 // proto.
506 stats.noteAtomLogged(pushAtomTag, /*timeSec=*/0);
507 stats.noteAtomError(pushAtomTag, /*pull=*/false);
508
509 stats.noteAtomError(pullAtomTag, /*pull=*/true);
510 }
511
512 vector<uint8_t> output;
513 stats.dumpStats(&output, false);
514 StatsdStatsReport report;
515 EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
516
517 // Check error count = numErrors for push atom
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700518 ASSERT_EQ(1, report.atom_stats_size());
Ruchir Rastogi07f7adb2020-04-16 17:46:12 -0700519 const auto& pushedAtomStats = report.atom_stats(0);
520 EXPECT_EQ(pushAtomTag, pushedAtomStats.tag());
521 EXPECT_EQ(numErrors, pushedAtomStats.error_count());
522
523 // Check error count = numErrors for pull atom
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700524 ASSERT_EQ(1, report.pulled_atom_stats_size());
Ruchir Rastogi07f7adb2020-04-16 17:46:12 -0700525 const auto& pulledAtomStats = report.pulled_atom_stats(0);
526 EXPECT_EQ(pullAtomTag, pulledAtomStats.atom_id());
527 EXPECT_EQ(numErrors, pulledAtomStats.atom_error_count());
528}
529
Yao Chenb3561512017-11-21 18:07:17 -0800530} // namespace statsd
531} // namespace os
532} // namespace android
533#else
534GTEST_LOG_(INFO) << "This test does nothing.\n";
535#endif