1 // 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" 18 #include "src/stats_log_util.h" 19 #include "tests/statsd_test_util.h" 20 21 #include <vector> 22 23 namespace android { 24 namespace os { 25 namespace statsd { 26 27 #ifdef __ANDROID__ 28 29 namespace { 30 31 const int64_t metricId = 123456; 32 33 StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type, 34 bool useCondition = true) { 35 StatsdConfig config; 36 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. 37 auto atomMatcher = CreateSimpleAtomMatcher("TestMatcher", android::util::SUBSYSTEM_SLEEP_STATE); 38 *config.add_atom_matcher() = atomMatcher; 39 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher(); 40 *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher(); 41 42 auto screenIsOffPredicate = CreateScreenIsOffPredicate(); 43 *config.add_predicate() = screenIsOffPredicate; 44 45 auto gaugeMetric = config.add_gauge_metric(); 46 gaugeMetric->set_id(metricId); 47 gaugeMetric->set_what(atomMatcher.id()); 48 if (useCondition) { 49 gaugeMetric->set_condition(screenIsOffPredicate.id()); 50 } 51 gaugeMetric->set_sampling_type(sampling_type); 52 gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true); 53 *gaugeMetric->mutable_dimensions_in_what() = 54 CreateDimensions(android::util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */}); 55 gaugeMetric->set_bucket(FIVE_MINUTES); 56 gaugeMetric->set_max_pull_delay_sec(INT_MAX); 57 config.set_hash_strings_in_metric_report(false); 58 59 return config; 60 } 61 62 } // namespace 63 64 TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) { 65 auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE); 66 int64_t baseTimeNs = getElapsedRealtimeNs(); 67 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs; 68 int64_t bucketSizeNs = 69 TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; 70 71 ConfigKey cfgKey; 72 auto processor = CreateStatsLogProcessor( 73 baseTimeNs, configAddedTimeNs, config, cfgKey); 74 EXPECT_EQ(processor->mMetricsManagers.size(), 1u); 75 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); 76 processor->mPullerManager->ForceClearPullerCache(); 77 78 int startBucketNum = processor->mMetricsManagers.begin()->second-> 79 mAllMetricProducers[0]->getCurrentBucketNum(); 80 EXPECT_GT(startBucketNum, (int64_t)0); 81 82 // When creating the config, the gauge metric producer should register the alarm at the 83 // end of the current bucket. 84 EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size()); 85 EXPECT_EQ(bucketSizeNs, 86 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs); 87 int64_t& nextPullTimeNs = 88 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs; 89 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs); 90 91 auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, 92 configAddedTimeNs + 55); 93 processor->OnLogEvent(screenOffEvent.get()); 94 95 // Pulling alarm arrives on time and reset the sequential pulling alarm. 96 processor->informPullAlarmFired(nextPullTimeNs + 1); 97 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs); 98 99 auto screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, 100 configAddedTimeNs + bucketSizeNs + 10); 101 processor->OnLogEvent(screenOnEvent.get()); 102 103 screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, 104 configAddedTimeNs + bucketSizeNs + 100); 105 processor->OnLogEvent(screenOffEvent.get()); 106 107 processor->informPullAlarmFired(nextPullTimeNs + 1); 108 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, 109 nextPullTimeNs); 110 111 processor->informPullAlarmFired(nextPullTimeNs + 1); 112 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs); 113 114 screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, 115 configAddedTimeNs + 3 * bucketSizeNs + 2); 116 processor->OnLogEvent(screenOnEvent.get()); 117 118 processor->informPullAlarmFired(nextPullTimeNs + 3); 119 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs); 120 121 screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, 122 configAddedTimeNs + 5 * bucketSizeNs + 1); 123 processor->OnLogEvent(screenOffEvent.get()); 124 125 processor->informPullAlarmFired(nextPullTimeNs + 2); 126 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, nextPullTimeNs); 127 128 processor->informPullAlarmFired(nextPullTimeNs + 2); 129 130 ConfigMetricsReportList reports; 131 vector<uint8_t> buffer; 132 processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true, 133 ADB_DUMP, FAST, &buffer); 134 EXPECT_TRUE(buffer.size() > 0); 135 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); 136 backfillDimensionPath(&reports); 137 backfillStringInReport(&reports); 138 backfillStartEndTimestamp(&reports); 139 EXPECT_EQ(1, reports.reports_size()); 140 EXPECT_EQ(1, reports.reports(0).metrics_size()); 141 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics; 142 sortMetricDataByDimensionsValue( 143 reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics); 144 EXPECT_GT((int)gaugeMetrics.data_size(), 1); 145 146 auto data = gaugeMetrics.data(0); 147 EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field()); 148 EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size()); 149 EXPECT_EQ(1 /* subsystem name field */, 150 data.dimensions_in_what().value_tuple().dimensions_value(0).field()); 151 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty()); 152 EXPECT_EQ(6, data.bucket_info_size()); 153 154 EXPECT_EQ(1, data.bucket_info(0).atom_size()); 155 EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size()); 156 EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0)); 157 EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size()); 158 EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos()); 159 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos()); 160 EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty()); 161 EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0); 162 163 EXPECT_EQ(1, data.bucket_info(1).atom_size()); 164 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, 165 data.bucket_info(1).elapsed_timestamp_nanos(0)); 166 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0)); 167 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos()); 168 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos()); 169 EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty()); 170 EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0); 171 172 EXPECT_EQ(1, data.bucket_info(2).atom_size()); 173 EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size()); 174 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, 175 data.bucket_info(2).elapsed_timestamp_nanos(0)); 176 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos()); 177 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos()); 178 EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty()); 179 EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0); 180 181 EXPECT_EQ(1, data.bucket_info(3).atom_size()); 182 EXPECT_EQ(1, data.bucket_info(3).elapsed_timestamp_nanos_size()); 183 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 1, 184 data.bucket_info(3).elapsed_timestamp_nanos(0)); 185 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos()); 186 EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos()); 187 EXPECT_TRUE(data.bucket_info(3).atom(0).subsystem_sleep_state().subsystem_name().empty()); 188 EXPECT_GT(data.bucket_info(3).atom(0).subsystem_sleep_state().time_millis(), 0); 189 190 EXPECT_EQ(1, data.bucket_info(4).atom_size()); 191 EXPECT_EQ(1, data.bucket_info(4).elapsed_timestamp_nanos_size()); 192 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, 193 data.bucket_info(4).elapsed_timestamp_nanos(0)); 194 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos()); 195 EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos()); 196 EXPECT_TRUE(data.bucket_info(4).atom(0).subsystem_sleep_state().subsystem_name().empty()); 197 EXPECT_GT(data.bucket_info(4).atom(0).subsystem_sleep_state().time_millis(), 0); 198 199 EXPECT_EQ(1, data.bucket_info(5).atom_size()); 200 EXPECT_EQ(1, data.bucket_info(5).elapsed_timestamp_nanos_size()); 201 EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs + 2, 202 data.bucket_info(5).elapsed_timestamp_nanos(0)); 203 EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(5).start_bucket_elapsed_nanos()); 204 EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(5).end_bucket_elapsed_nanos()); 205 EXPECT_TRUE(data.bucket_info(5).atom(0).subsystem_sleep_state().subsystem_name().empty()); 206 EXPECT_GT(data.bucket_info(5).atom(0).subsystem_sleep_state().time_millis(), 0); 207 } 208 209 TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) { 210 auto config = CreateStatsdConfig(GaugeMetric::CONDITION_CHANGE_TO_TRUE); 211 int64_t baseTimeNs = getElapsedRealtimeNs(); 212 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs; 213 int64_t bucketSizeNs = 214 TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; 215 216 ConfigKey cfgKey; 217 auto processor = CreateStatsLogProcessor( 218 baseTimeNs, configAddedTimeNs, config, cfgKey); 219 EXPECT_EQ(processor->mMetricsManagers.size(), 1u); 220 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); 221 processor->mPullerManager->ForceClearPullerCache(); 222 223 int startBucketNum = processor->mMetricsManagers.begin()->second-> 224 mAllMetricProducers[0]->getCurrentBucketNum(); 225 EXPECT_GT(startBucketNum, (int64_t)0); 226 227 auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, 228 configAddedTimeNs + 55); 229 processor->OnLogEvent(screenOffEvent.get()); 230 231 auto screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, 232 configAddedTimeNs + bucketSizeNs + 10); 233 processor->OnLogEvent(screenOnEvent.get()); 234 235 screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, 236 configAddedTimeNs + bucketSizeNs + 100); 237 processor->OnLogEvent(screenOffEvent.get()); 238 239 screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, 240 configAddedTimeNs + 3 * bucketSizeNs + 2); 241 processor->OnLogEvent(screenOnEvent.get()); 242 243 screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, 244 configAddedTimeNs + 5 * bucketSizeNs + 1); 245 processor->OnLogEvent(screenOffEvent.get()); 246 screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, 247 configAddedTimeNs + 5 * bucketSizeNs + 3); 248 processor->OnLogEvent(screenOnEvent.get()); 249 screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, 250 configAddedTimeNs + 5 * bucketSizeNs + 10); 251 processor->OnLogEvent(screenOffEvent.get()); 252 253 ConfigMetricsReportList reports; 254 vector<uint8_t> buffer; 255 processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, true, 256 ADB_DUMP, FAST, &buffer); 257 EXPECT_TRUE(buffer.size() > 0); 258 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); 259 backfillDimensionPath(&reports); 260 backfillStringInReport(&reports); 261 backfillStartEndTimestamp(&reports); 262 EXPECT_EQ(1, reports.reports_size()); 263 EXPECT_EQ(1, reports.reports(0).metrics_size()); 264 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics; 265 sortMetricDataByDimensionsValue( 266 reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics); 267 EXPECT_GT((int)gaugeMetrics.data_size(), 1); 268 269 auto data = gaugeMetrics.data(0); 270 EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field()); 271 EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size()); 272 EXPECT_EQ(1 /* subsystem name field */, 273 data.dimensions_in_what().value_tuple().dimensions_value(0).field()); 274 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty()); 275 EXPECT_EQ(3, data.bucket_info_size()); 276 277 EXPECT_EQ(1, data.bucket_info(0).atom_size()); 278 EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size()); 279 EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0)); 280 EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size()); 281 EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos()); 282 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos()); 283 EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty()); 284 EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0); 285 286 EXPECT_EQ(1, data.bucket_info(1).atom_size()); 287 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 100, 288 data.bucket_info(1).elapsed_timestamp_nanos(0)); 289 EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0)); 290 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos()); 291 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos()); 292 EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty()); 293 EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0); 294 295 EXPECT_EQ(2, data.bucket_info(2).atom_size()); 296 EXPECT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size()); 297 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, 298 data.bucket_info(2).elapsed_timestamp_nanos(0)); 299 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 10, 300 data.bucket_info(2).elapsed_timestamp_nanos(1)); 301 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos()); 302 EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos()); 303 EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty()); 304 EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0); 305 EXPECT_TRUE(data.bucket_info(2).atom(1).subsystem_sleep_state().subsystem_name().empty()); 306 EXPECT_GT(data.bucket_info(2).atom(1).subsystem_sleep_state().time_millis(), 0); 307 } 308 309 310 TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) { 311 auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE); 312 int64_t baseTimeNs = getElapsedRealtimeNs(); 313 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs; 314 int64_t bucketSizeNs = 315 TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; 316 317 ConfigKey cfgKey; 318 auto processor = CreateStatsLogProcessor( 319 baseTimeNs, configAddedTimeNs, config, cfgKey); 320 EXPECT_EQ(processor->mMetricsManagers.size(), 1u); 321 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); 322 processor->mPullerManager->ForceClearPullerCache(); 323 324 int startBucketNum = processor->mMetricsManagers.begin()->second-> 325 mAllMetricProducers[0]->getCurrentBucketNum(); 326 EXPECT_GT(startBucketNum, (int64_t)0); 327 328 // When creating the config, the gauge metric producer should register the alarm at the 329 // end of the current bucket. 330 EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size()); 331 EXPECT_EQ(bucketSizeNs, 332 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs); 333 int64_t& nextPullTimeNs = 334 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs; 335 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs); 336 337 auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, 338 configAddedTimeNs + 55); 339 processor->OnLogEvent(screenOffEvent.get()); 340 341 auto screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, 342 configAddedTimeNs + bucketSizeNs + 10); 343 processor->OnLogEvent(screenOnEvent.get()); 344 345 // Pulling alarm arrives one bucket size late. 346 processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs); 347 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs); 348 349 screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, 350 configAddedTimeNs + 3 * bucketSizeNs + 11); 351 processor->OnLogEvent(screenOffEvent.get()); 352 353 // Pulling alarm arrives more than one bucket size late. 354 processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs + 12); 355 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs); 356 357 ConfigMetricsReportList reports; 358 vector<uint8_t> buffer; 359 processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true, 360 ADB_DUMP, FAST, &buffer); 361 EXPECT_TRUE(buffer.size() > 0); 362 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); 363 backfillDimensionPath(&reports); 364 backfillStringInReport(&reports); 365 backfillStartEndTimestamp(&reports); 366 EXPECT_EQ(1, reports.reports_size()); 367 EXPECT_EQ(1, reports.reports(0).metrics_size()); 368 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics; 369 sortMetricDataByDimensionsValue( 370 reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics); 371 EXPECT_GT((int)gaugeMetrics.data_size(), 1); 372 373 auto data = gaugeMetrics.data(0); 374 EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field()); 375 EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size()); 376 EXPECT_EQ(1 /* subsystem name field */, 377 data.dimensions_in_what().value_tuple().dimensions_value(0).field()); 378 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty()); 379 EXPECT_EQ(3, data.bucket_info_size()); 380 381 EXPECT_EQ(1, data.bucket_info(0).atom_size()); 382 EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size()); 383 EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0)); 384 EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos()); 385 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos()); 386 EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty()); 387 EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0); 388 389 EXPECT_EQ(1, data.bucket_info(1).atom_size()); 390 EXPECT_EQ(configAddedTimeNs + 3 * bucketSizeNs + 11, 391 data.bucket_info(1).elapsed_timestamp_nanos(0)); 392 EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0)); 393 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos()); 394 EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos()); 395 EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty()); 396 EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0); 397 398 EXPECT_EQ(1, data.bucket_info(2).atom_size()); 399 EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size()); 400 EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs + 12, 401 data.bucket_info(2).elapsed_timestamp_nanos(0)); 402 EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos()); 403 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos()); 404 EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty()); 405 EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0); 406 } 407 408 TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation) { 409 auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false); 410 411 int64_t baseTimeNs = getElapsedRealtimeNs(); 412 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs; 413 int64_t bucketSizeNs = 414 TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; 415 416 auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher(); 417 *config.add_atom_matcher() = batterySaverStartMatcher; 418 const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets. 419 auto metric_activation = config.add_metric_activation(); 420 metric_activation->set_metric_id(metricId); 421 metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY); 422 auto event_activation = metric_activation->add_event_activation(); 423 event_activation->set_atom_matcher_id(batterySaverStartMatcher.id()); 424 event_activation->set_ttl_seconds(ttlNs / 1000000000); 425 426 ConfigKey cfgKey; 427 auto processor = CreateStatsLogProcessor( 428 baseTimeNs, configAddedTimeNs, config, cfgKey); 429 EXPECT_EQ(processor->mMetricsManagers.size(), 1u); 430 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); 431 processor->mPullerManager->ForceClearPullerCache(); 432 433 int startBucketNum = processor->mMetricsManagers.begin()->second-> 434 mAllMetricProducers[0]->getCurrentBucketNum(); 435 EXPECT_GT(startBucketNum, (int64_t)0); 436 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive()); 437 438 // When creating the config, the gauge metric producer should register the alarm at the 439 // end of the current bucket. 440 EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size()); 441 EXPECT_EQ(bucketSizeNs, 442 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs); 443 int64_t& nextPullTimeNs = 444 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs; 445 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs); 446 447 // Pulling alarm arrives on time and reset the sequential pulling alarm. 448 // Event should not be kept. 449 processor->informPullAlarmFired(nextPullTimeNs + 1); // 15 mins + 1 ns. 450 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs); 451 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive()); 452 453 // Activate the metric. A pull occurs upon activation. 454 const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis. 455 auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs); 456 processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms. 457 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive()); 458 459 // This event should be kept. 2 total. 460 processor->informPullAlarmFired(nextPullTimeNs + 1); // 20 mins + 1 ns. 461 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, 462 nextPullTimeNs); 463 464 // This event should be kept. 3 total. 465 processor->informPullAlarmFired(nextPullTimeNs + 2); // 25 mins + 2 ns. 466 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs); 467 468 // Create random event to deactivate metric. 469 auto deactivationEvent = CreateScreenBrightnessChangedEvent(50, activationNs + ttlNs + 1); 470 processor->OnLogEvent(deactivationEvent.get()); 471 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive()); 472 473 // Event should not be kept. 3 total. 474 processor->informPullAlarmFired(nextPullTimeNs + 3); 475 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs); 476 477 processor->informPullAlarmFired(nextPullTimeNs + 2); 478 479 ConfigMetricsReportList reports; 480 vector<uint8_t> buffer; 481 processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true, 482 ADB_DUMP, FAST, &buffer); 483 EXPECT_TRUE(buffer.size() > 0); 484 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); 485 backfillDimensionPath(&reports); 486 backfillStringInReport(&reports); 487 backfillStartEndTimestamp(&reports); 488 EXPECT_EQ(1, reports.reports_size()); 489 EXPECT_EQ(1, reports.reports(0).metrics_size()); 490 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics; 491 sortMetricDataByDimensionsValue( 492 reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics); 493 EXPECT_GT((int)gaugeMetrics.data_size(), 0); 494 495 auto data = gaugeMetrics.data(0); 496 EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field()); 497 EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size()); 498 EXPECT_EQ(1 /* subsystem name field */, 499 data.dimensions_in_what().value_tuple().dimensions_value(0).field()); 500 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty()); 501 EXPECT_EQ(3, data.bucket_info_size()); 502 503 auto bucketInfo = data.bucket_info(0); 504 EXPECT_EQ(1, bucketInfo.atom_size()); 505 EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size()); 506 EXPECT_EQ(activationNs, bucketInfo.elapsed_timestamp_nanos(0)); 507 EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size()); 508 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos()); 509 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos()); 510 EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty()); 511 EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0); 512 513 bucketInfo = data.bucket_info(1); 514 EXPECT_EQ(1, bucketInfo.atom_size()); 515 EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size()); 516 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, bucketInfo.elapsed_timestamp_nanos(0)); 517 EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size()); 518 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos()); 519 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos()); 520 EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty()); 521 EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0); 522 523 bucketInfo = data.bucket_info(2); 524 EXPECT_EQ(1, bucketInfo.atom_size()); 525 EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size()); 526 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, bucketInfo.elapsed_timestamp_nanos(0)); 527 EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size()); 528 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)), 529 bucketInfo.start_bucket_elapsed_nanos()); 530 EXPECT_EQ(MillisToNano(NanoToMillis(activationNs + ttlNs + 1)), 531 bucketInfo.end_bucket_elapsed_nanos()); 532 EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty()); 533 EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0); 534 } 535 536 TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition) { 537 auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false); 538 539 int64_t baseTimeNs = getElapsedRealtimeNs(); 540 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs; 541 int64_t bucketSizeNs = 542 TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; 543 544 ConfigKey cfgKey; 545 auto processor = CreateStatsLogProcessor( 546 baseTimeNs, configAddedTimeNs, config, cfgKey); 547 EXPECT_EQ(processor->mMetricsManagers.size(), 1u); 548 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); 549 processor->mPullerManager->ForceClearPullerCache(); 550 551 int startBucketNum = processor->mMetricsManagers.begin()->second-> 552 mAllMetricProducers[0]->getCurrentBucketNum(); 553 EXPECT_GT(startBucketNum, (int64_t)0); 554 555 // When creating the config, the gauge metric producer should register the alarm at the 556 // end of the current bucket. 557 EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size()); 558 EXPECT_EQ(bucketSizeNs, 559 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs); 560 int64_t& nextPullTimeNs = 561 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs; 562 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs); 563 564 // Pulling alarm arrives on time and reset the sequential pulling alarm. 565 processor->informPullAlarmFired(nextPullTimeNs + 1); 566 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs); 567 568 processor->informPullAlarmFired(nextPullTimeNs + 4); 569 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, 570 nextPullTimeNs); 571 572 ConfigMetricsReportList reports; 573 vector<uint8_t> buffer; 574 processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true, 575 ADB_DUMP, FAST, &buffer); 576 EXPECT_TRUE(buffer.size() > 0); 577 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); 578 backfillDimensionPath(&reports); 579 backfillStringInReport(&reports); 580 backfillStartEndTimestamp(&reports); 581 EXPECT_EQ(1, reports.reports_size()); 582 EXPECT_EQ(1, reports.reports(0).metrics_size()); 583 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics; 584 sortMetricDataByDimensionsValue( 585 reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics); 586 EXPECT_GT((int)gaugeMetrics.data_size(), 0); 587 588 auto data = gaugeMetrics.data(0); 589 EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field()); 590 EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size()); 591 EXPECT_EQ(1 /* subsystem name field */, 592 data.dimensions_in_what().value_tuple().dimensions_value(0).field()); 593 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty()); 594 EXPECT_EQ(3, data.bucket_info_size()); 595 596 EXPECT_EQ(1, data.bucket_info(0).atom_size()); 597 EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size()); 598 EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).elapsed_timestamp_nanos(0)); 599 EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size()); 600 EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos()); 601 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos()); 602 EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty()); 603 EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0); 604 605 EXPECT_EQ(1, data.bucket_info(1).atom_size()); 606 EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size()); 607 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0)); 608 EXPECT_EQ(0, data.bucket_info(1).wall_clock_timestamp_nanos_size()); 609 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos()); 610 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos()); 611 EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty()); 612 EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0); 613 614 EXPECT_EQ(1, data.bucket_info(2).atom_size()); 615 EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size()); 616 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 4, data.bucket_info(2).elapsed_timestamp_nanos(0)); 617 EXPECT_EQ(0, data.bucket_info(2).wall_clock_timestamp_nanos_size()); 618 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos()); 619 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos()); 620 EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty()); 621 EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0); 622 } 623 624 #else 625 GTEST_LOG_(INFO) << "This test does nothing.\n"; 626 #endif 627 628 } // namespace statsd 629 } // namespace os 630 } // namespace android 631