blob: c874d92a1b019b21ae2604b3cc695c550d16b4d7 [file] [log] [blame]
Yangster-mac20877162017-12-22 17:19:39 -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 <gtest/gtest.h>
16
17#include "src/StatsLogProcessor.h"
Yangster-macb8144812018-01-04 10:56:23 -080018#include "src/stats_log_util.h"
Yangster-mac20877162017-12-22 17:19:39 -080019#include "tests/statsd_test_util.h"
20
21#include <vector>
22
23namespace android {
24namespace os {
25namespace statsd {
26
27#ifdef __ANDROID__
Yangster-macb5bc7412018-01-06 23:17:45 -080028namespace {
Yangster-mac20877162017-12-22 17:19:39 -080029
30StatsdConfig CreateStatsdConfig() {
31 StatsdConfig config;
32 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
33 *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
34
35 *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
36 *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
37
38 *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
39 *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
40
41 auto appCrashMatcher = CreateProcessCrashAtomMatcher();
42 *config.add_atom_matcher() = appCrashMatcher;
43
44 auto screenIsOffPredicate = CreateScreenIsOffPredicate();
45
46 auto isSyncingPredicate = CreateIsSyncingPredicate();
Yangster-mac93694462018-01-22 20:49:31 -080047 auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
48 *syncDimension = CreateAttributionUidDimensions(
49 android::util::SYNC_STATE_CHANGED, {Position::FIRST});
50 syncDimension->add_child()->set_field(2 /* name field*/);
Yangster-mac20877162017-12-22 17:19:39 -080051
52 auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
53 *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
54 CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
55
56 *config.add_predicate() = screenIsOffPredicate;
57 *config.add_predicate() = isSyncingPredicate;
58 *config.add_predicate() = isInBackgroundPredicate;
59
60 auto combinationPredicate = config.add_predicate();
Yangster-mac94e197c2018-01-02 16:03:03 -080061 combinationPredicate->set_id(StringToId("combinationPredicate"));
Yangster-mac20877162017-12-22 17:19:39 -080062 combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
63 addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
64 addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
65 addPredicateToPredicateCombination(isInBackgroundPredicate, combinationPredicate);
66
67 auto countMetric = config.add_count_metric();
Yangster-mac94e197c2018-01-02 16:03:03 -080068 countMetric->set_id(StringToId("AppCrashes"));
69 countMetric->set_what(appCrashMatcher.id());
70 countMetric->set_condition(combinationPredicate->id());
Yangster-mac20877162017-12-22 17:19:39 -080071 // The metric is dimensioning by uid only.
Yangster-mac468ff042018-01-17 12:26:34 -080072 *countMetric->mutable_dimensions_in_what() =
Yangster-mac20877162017-12-22 17:19:39 -080073 CreateDimensions(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, {1});
yro59cc24d2018-02-13 20:17:32 -080074 countMetric->set_bucket(FIVE_MINUTES);
Yangster-mac20877162017-12-22 17:19:39 -080075
76 // Links between crash atom and condition of app is in syncing.
77 auto links = countMetric->add_links();
Yangster-mac94e197c2018-01-02 16:03:03 -080078 links->set_condition(isSyncingPredicate.id());
Yangster-mac2c6dc472018-01-18 16:17:43 -080079 auto dimensionWhat = links->mutable_fields_in_what();
Yangster-mac20877162017-12-22 17:19:39 -080080 dimensionWhat->set_field(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
81 dimensionWhat->add_child()->set_field(1); // uid field.
Yangster-mac93694462018-01-22 20:49:31 -080082 *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
83 android::util::SYNC_STATE_CHANGED, {Position::FIRST});
Yangster-mac20877162017-12-22 17:19:39 -080084
85 // Links between crash atom and condition of app is in background.
86 links = countMetric->add_links();
Yangster-mac94e197c2018-01-02 16:03:03 -080087 links->set_condition(isInBackgroundPredicate.id());
Yangster-mac2c6dc472018-01-18 16:17:43 -080088 dimensionWhat = links->mutable_fields_in_what();
Yangster-mac20877162017-12-22 17:19:39 -080089 dimensionWhat->set_field(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
90 dimensionWhat->add_child()->set_field(1); // uid field.
Yangster-mac93694462018-01-22 20:49:31 -080091 auto dimensionCondition = links->mutable_fields_in_condition();
Yangster-mac20877162017-12-22 17:19:39 -080092 dimensionCondition->set_field(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
93 dimensionCondition->add_child()->set_field(1); // uid field.
94 return config;
95}
Yangster-macb5bc7412018-01-06 23:17:45 -080096} // namespace
97
Yao Chen8a8d16c2018-02-08 14:50:40 -080098// If we want to test multiple dump data, we must do it in separate tests, because in the e2e tests,
99// we should use the real API which will clear the data after dump data is called.
100// TODO: better refactor the code so that the tests are not so verbose.
101TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) {
Yangster-mac20877162017-12-22 17:19:39 -0800102 auto config = CreateStatsdConfig();
103 uint64_t bucketStartTimeNs = 10000000000;
Yangster-macb8144812018-01-04 10:56:23 -0800104 uint64_t bucketSizeNs =
105 TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
Yangster-mac20877162017-12-22 17:19:39 -0800106
107 ConfigKey cfgKey;
108 auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
109 EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
110 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
111
112 int appUid = 123;
113 auto crashEvent1 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 1);
114 auto crashEvent2 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 201);
115 auto crashEvent3= CreateAppCrashEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 101);
116
117 auto crashEvent4 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 51);
118 auto crashEvent5 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 299);
119 auto crashEvent6 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 2001);
120
121 auto crashEvent7 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 16);
122 auto crashEvent8 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 249);
123
124 auto crashEvent9 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 351);
125 auto crashEvent10 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 2);
126
127 auto screenTurnedOnEvent =
Bookatz1a1b0462018-01-12 11:47:03 -0800128 CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
129 bucketStartTimeNs + 2);
Yangster-mac20877162017-12-22 17:19:39 -0800130 auto screenTurnedOffEvent =
Bookatz1a1b0462018-01-12 11:47:03 -0800131 CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
132 bucketStartTimeNs + 200);
Yangster-mac20877162017-12-22 17:19:39 -0800133 auto screenTurnedOnEvent2 =
Bookatz1a1b0462018-01-12 11:47:03 -0800134 CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
Yangster-mac20877162017-12-22 17:19:39 -0800135 bucketStartTimeNs + 2 * bucketSizeNs - 100);
136
Yao Chen9c1debe2018-02-19 14:39:19 -0800137 std::vector<AttributionNodeInternal> attributions = {
138 CreateAttribution(appUid, "App1"), CreateAttribution(appUid + 1, "GMSCoreModule1")};
Yangster-mac20877162017-12-22 17:19:39 -0800139 auto syncOnEvent1 =
Yangster-mac93694462018-01-22 20:49:31 -0800140 CreateSyncStartEvent(attributions, "ReadEmail", bucketStartTimeNs + 50);
Yangster-mac20877162017-12-22 17:19:39 -0800141 auto syncOffEvent1 =
Yangster-mac93694462018-01-22 20:49:31 -0800142 CreateSyncEndEvent(attributions, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 300);
Yangster-mac20877162017-12-22 17:19:39 -0800143 auto syncOnEvent2 =
Yangster-mac93694462018-01-22 20:49:31 -0800144 CreateSyncStartEvent(attributions, "ReadDoc", bucketStartTimeNs + bucketSizeNs + 2000);
Yangster-mac20877162017-12-22 17:19:39 -0800145
146 auto moveToBackgroundEvent1 =
147 CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 15);
148 auto moveToForegroundEvent1 =
149 CreateMoveToForegroundEvent(appUid, bucketStartTimeNs + bucketSizeNs + 250);
150
151 auto moveToBackgroundEvent2 =
152 CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + bucketSizeNs + 350);
153 auto moveToForegroundEvent2 =
154 CreateMoveToForegroundEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 1);
155
156 /*
157 bucket #1 bucket #2
158
159
160 | | | | | | | | | | (crashEvents)
161 |-------------------------------------|-----------------------------------|---------
162
163 | | (MoveToBkground)
164
165 | | (MoveToForeground)
166
167 | | (SyncIsOn)
168 | (SyncIsOff)
169 | | (ScreenIsOn)
170 | (ScreenIsOff)
171 */
172 std::vector<std::unique_ptr<LogEvent>> events;
173 events.push_back(std::move(crashEvent1));
174 events.push_back(std::move(crashEvent2));
175 events.push_back(std::move(crashEvent3));
176 events.push_back(std::move(crashEvent4));
177 events.push_back(std::move(crashEvent5));
178 events.push_back(std::move(crashEvent6));
179 events.push_back(std::move(crashEvent7));
180 events.push_back(std::move(crashEvent8));
181 events.push_back(std::move(crashEvent9));
182 events.push_back(std::move(crashEvent10));
183 events.push_back(std::move(screenTurnedOnEvent));
184 events.push_back(std::move(screenTurnedOffEvent));
185 events.push_back(std::move(screenTurnedOnEvent2));
186 events.push_back(std::move(syncOnEvent1));
187 events.push_back(std::move(syncOffEvent1));
188 events.push_back(std::move(syncOnEvent2));
189 events.push_back(std::move(moveToBackgroundEvent1));
190 events.push_back(std::move(moveToForegroundEvent1));
191 events.push_back(std::move(moveToBackgroundEvent2));
192 events.push_back(std::move(moveToForegroundEvent2));
193
194 sortLogEventsByTimestamp(&events);
195
196 for (const auto& event : events) {
Yangster-macd40053e2018-01-09 16:29:22 -0800197 processor->OnLogEvent(event.get());
Yangster-mac20877162017-12-22 17:19:39 -0800198 }
199 ConfigMetricsReportList reports;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800200 vector<uint8_t> buffer;
201 processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &buffer);
202 EXPECT_TRUE(buffer.size() > 0);
203 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
Yangster-mac20877162017-12-22 17:19:39 -0800204 EXPECT_EQ(reports.reports_size(), 1);
205 EXPECT_EQ(reports.reports(0).metrics_size(), 1);
206 EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
207 EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 1);
208 EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
209 auto data = reports.reports(0).metrics(0).count_metrics().data(0);
210 // Validate dimension value.
Yangster-mac468ff042018-01-17 12:26:34 -0800211 EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
212 EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
Yangster-mac20877162017-12-22 17:19:39 -0800213 // Uid field.
Yangster-mac468ff042018-01-17 12:26:34 -0800214 EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
215 EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800216}
Yangster-mac20877162017-12-22 17:19:39 -0800217
Yao Chen8a8d16c2018-02-08 14:50:40 -0800218TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2) {
219 auto config = CreateStatsdConfig();
220 uint64_t bucketStartTimeNs = 10000000000;
221 uint64_t bucketSizeNs =
222 TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
223
224 ConfigKey cfgKey;
225 auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
226 EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
227 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
228
229 int appUid = 123;
230 auto crashEvent1 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 1);
231 auto crashEvent2 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 201);
232 auto crashEvent3 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 101);
233
234 auto crashEvent4 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 51);
235 auto crashEvent5 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 299);
236 auto crashEvent6 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 2001);
237
238 auto crashEvent7 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 16);
239 auto crashEvent8 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 249);
240
241 auto crashEvent9 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 351);
242 auto crashEvent10 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 2);
243
244 auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
245 android::view::DisplayStateEnum::DISPLAY_STATE_ON, bucketStartTimeNs + 2);
246 auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
247 android::view::DisplayStateEnum::DISPLAY_STATE_OFF, bucketStartTimeNs + 200);
248 auto screenTurnedOnEvent2 =
249 CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
250 bucketStartTimeNs + 2 * bucketSizeNs - 100);
251
Yao Chen9c1debe2018-02-19 14:39:19 -0800252 std::vector<AttributionNodeInternal> attributions = {
253 CreateAttribution(appUid, "App1"), CreateAttribution(appUid + 1, "GMSCoreModule1")};
Yao Chen8a8d16c2018-02-08 14:50:40 -0800254 auto syncOnEvent1 = CreateSyncStartEvent(attributions, "ReadEmail", bucketStartTimeNs + 50);
255 auto syncOffEvent1 =
256 CreateSyncEndEvent(attributions, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 300);
257 auto syncOnEvent2 =
258 CreateSyncStartEvent(attributions, "ReadDoc", bucketStartTimeNs + bucketSizeNs + 2000);
259
260 auto moveToBackgroundEvent1 = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 15);
261 auto moveToForegroundEvent1 =
262 CreateMoveToForegroundEvent(appUid, bucketStartTimeNs + bucketSizeNs + 250);
263
264 auto moveToBackgroundEvent2 =
265 CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + bucketSizeNs + 350);
266 auto moveToForegroundEvent2 =
267 CreateMoveToForegroundEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 1);
268
269 /*
270 bucket #1 bucket #2
271
272
273 | | | | | | | | | | (crashEvents)
274 |-------------------------------------|-----------------------------------|---------
275
276 | | (MoveToBkground)
277
278 | | (MoveToForeground)
279
280 | | (SyncIsOn)
281 | (SyncIsOff)
282 | | (ScreenIsOn)
283 | (ScreenIsOff)
284 */
285 std::vector<std::unique_ptr<LogEvent>> events;
286 events.push_back(std::move(crashEvent1));
287 events.push_back(std::move(crashEvent2));
288 events.push_back(std::move(crashEvent3));
289 events.push_back(std::move(crashEvent4));
290 events.push_back(std::move(crashEvent5));
291 events.push_back(std::move(crashEvent6));
292 events.push_back(std::move(crashEvent7));
293 events.push_back(std::move(crashEvent8));
294 events.push_back(std::move(crashEvent9));
295 events.push_back(std::move(crashEvent10));
296 events.push_back(std::move(screenTurnedOnEvent));
297 events.push_back(std::move(screenTurnedOffEvent));
298 events.push_back(std::move(screenTurnedOnEvent2));
299 events.push_back(std::move(syncOnEvent1));
300 events.push_back(std::move(syncOffEvent1));
301 events.push_back(std::move(syncOnEvent2));
302 events.push_back(std::move(moveToBackgroundEvent1));
303 events.push_back(std::move(moveToForegroundEvent1));
304 events.push_back(std::move(moveToBackgroundEvent2));
305 events.push_back(std::move(moveToForegroundEvent2));
306
307 sortLogEventsByTimestamp(&events);
308
309 for (const auto& event : events) {
310 processor->OnLogEvent(event.get());
311 }
312 ConfigMetricsReportList reports;
313 vector<uint8_t> buffer;
314
315 processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer);
316 EXPECT_TRUE(buffer.size() > 0);
317 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
Yangster-mac20877162017-12-22 17:19:39 -0800318 EXPECT_EQ(reports.reports_size(), 1);
319 EXPECT_EQ(reports.reports(0).metrics_size(), 1);
320 EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
321 EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 2);
322 EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
323 EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(1).count(), 3);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800324 auto data = reports.reports(0).metrics(0).count_metrics().data(0);
Yangster-mac20877162017-12-22 17:19:39 -0800325 // Validate dimension value.
Yangster-mac468ff042018-01-17 12:26:34 -0800326 EXPECT_EQ(data.dimensions_in_what().field(),
Yangster-mac20877162017-12-22 17:19:39 -0800327 android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
Yangster-mac468ff042018-01-17 12:26:34 -0800328 EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
Yangster-mac20877162017-12-22 17:19:39 -0800329 // Uid field.
Yangster-mac468ff042018-01-17 12:26:34 -0800330 EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
331 EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
Yangster-mac20877162017-12-22 17:19:39 -0800332}
333
334#else
335GTEST_LOG_(INFO) << "This test does nothing.\n";
336#endif
337
338} // namespace statsd
339} // namespace os
yro59cc24d2018-02-13 20:17:32 -0800340} // namespace android