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 "StatsLogProcessor.h" 16 #include "config/ConfigKey.h" 17 #include "frameworks/base/cmds/statsd/src/stats_log.pb.h" 18 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" 19 #include "guardrail/StatsdStats.h" 20 #include "logd/LogEvent.h" 21 #include "packages/UidMap.h" 22 #include "statslog.h" 23 24 #include <gmock/gmock.h> 25 #include <gtest/gtest.h> 26 27 #include "tests/statsd_test_util.h" 28 29 #include <stdio.h> 30 31 using namespace android; 32 using namespace testing; 33 34 namespace android { 35 namespace os { 36 namespace statsd { 37 38 using android::util::ProtoOutputStream; 39 40 #ifdef __ANDROID__ 41 42 /** 43 * Mock MetricsManager (ByteSize() is called). 44 */ 45 class MockMetricsManager : public MetricsManager { 46 public: 47 MockMetricsManager() : MetricsManager( 48 ConfigKey(1, 12345), StatsdConfig(), 1000, 1000, 49 new UidMap(), 50 new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){}, 51 [](const sp<IStatsCompanionService>&){}), 52 new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){}, 53 [](const sp<IStatsCompanionService>&){})) { 54 } 55 56 MOCK_METHOD0(byteSize, size_t()); 57 58 MOCK_METHOD1(dropData, void(const int64_t dropTimeNs)); 59 }; 60 61 TEST(StatsLogProcessorTest, TestRateLimitByteSize) { 62 sp<UidMap> m = new UidMap(); 63 sp<AlarmMonitor> anomalyAlarmMonitor; 64 sp<AlarmMonitor> periodicAlarmMonitor; 65 // Construct the processor with a dummy sendBroadcast function that does nothing. 66 StatsLogProcessor p(m, anomalyAlarmMonitor, periodicAlarmMonitor, 0, 67 [](const ConfigKey& key) {return true;}); 68 69 MockMetricsManager mockMetricsManager; 70 71 ConfigKey key(100, 12345); 72 // Expect only the first flush to trigger a check for byte size since the last two are 73 // rate-limited. 74 EXPECT_CALL(mockMetricsManager, byteSize()).Times(1); 75 p.flushIfNecessaryLocked(99, key, mockMetricsManager); 76 p.flushIfNecessaryLocked(100, key, mockMetricsManager); 77 p.flushIfNecessaryLocked(101, key, mockMetricsManager); 78 } 79 80 TEST(StatsLogProcessorTest, TestRateLimitBroadcast) { 81 sp<UidMap> m = new UidMap(); 82 sp<AlarmMonitor> anomalyAlarmMonitor; 83 sp<AlarmMonitor> subscriberAlarmMonitor; 84 int broadcastCount = 0; 85 StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, 86 [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); 87 88 MockMetricsManager mockMetricsManager; 89 90 ConfigKey key(100, 12345); 91 EXPECT_CALL(mockMetricsManager, byteSize()) 92 .Times(1) 93 .WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * .95))); 94 95 // Expect only one broadcast despite always returning a size that should trigger broadcast. 96 p.flushIfNecessaryLocked(1, key, mockMetricsManager); 97 EXPECT_EQ(1, broadcastCount); 98 99 // b/73089712 100 // This next call to flush should not trigger a broadcast. 101 // p.mLastByteSizeTimes.clear(); // Force another check for byte size. 102 // p.flushIfNecessaryLocked(2, key, mockMetricsManager); 103 // EXPECT_EQ(1, broadcastCount); 104 } 105 106 TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) { 107 sp<UidMap> m = new UidMap(); 108 sp<AlarmMonitor> anomalyAlarmMonitor; 109 sp<AlarmMonitor> subscriberAlarmMonitor; 110 int broadcastCount = 0; 111 StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, 112 [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); 113 114 MockMetricsManager mockMetricsManager; 115 116 ConfigKey key(100, 12345); 117 EXPECT_CALL(mockMetricsManager, byteSize()) 118 .Times(1) 119 .WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * 1.2))); 120 121 EXPECT_CALL(mockMetricsManager, dropData(_)).Times(1); 122 123 // Expect to call the onDumpReport and skip the broadcast. 124 p.flushIfNecessaryLocked(1, key, mockMetricsManager); 125 EXPECT_EQ(0, broadcastCount); 126 } 127 128 StatsdConfig MakeConfig(bool includeMetric) { 129 StatsdConfig config; 130 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. 131 132 if (includeMetric) { 133 auto appCrashMatcher = CreateProcessCrashAtomMatcher(); 134 *config.add_atom_matcher() = appCrashMatcher; 135 auto countMetric = config.add_count_metric(); 136 countMetric->set_id(StringToId("AppCrashes")); 137 countMetric->set_what(appCrashMatcher.id()); 138 countMetric->set_bucket(FIVE_MINUTES); 139 } 140 return config; 141 } 142 143 TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) { 144 // Setup simple config key corresponding to empty config. 145 sp<UidMap> m = new UidMap(); 146 m->updateMap(1, {1, 2}, {1, 2}, {String16("p1"), String16("p2")}); 147 sp<AlarmMonitor> anomalyAlarmMonitor; 148 sp<AlarmMonitor> subscriberAlarmMonitor; 149 int broadcastCount = 0; 150 StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, 151 [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); 152 ConfigKey key(3, 4); 153 StatsdConfig config = MakeConfig(true); 154 p.OnConfigUpdated(0, key, config); 155 156 // Expect to get no metrics, but snapshot specified above in uidmap. 157 vector<uint8_t> bytes; 158 p.onDumpReport(key, 1, false, ADB_DUMP, &bytes); 159 160 ConfigMetricsReportList output; 161 output.ParseFromArray(bytes.data(), bytes.size()); 162 EXPECT_TRUE(output.reports_size() > 0); 163 auto uidmap = output.reports(0).uid_map(); 164 EXPECT_TRUE(uidmap.snapshots_size() > 0); 165 EXPECT_EQ(2, uidmap.snapshots(0).package_info_size()); 166 } 167 168 TEST(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) { 169 // Setup simple config key corresponding to empty config. 170 sp<UidMap> m = new UidMap(); 171 m->updateMap(1, {1, 2}, {1, 2}, {String16("p1"), String16("p2")}); 172 sp<AlarmMonitor> anomalyAlarmMonitor; 173 sp<AlarmMonitor> subscriberAlarmMonitor; 174 int broadcastCount = 0; 175 StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, 176 [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); 177 ConfigKey key(3, 4); 178 StatsdConfig config = MakeConfig(false); 179 p.OnConfigUpdated(0, key, config); 180 181 // Expect to get no metrics, but snapshot specified above in uidmap. 182 vector<uint8_t> bytes; 183 p.onDumpReport(key, 1, false, ADB_DUMP, &bytes); 184 185 ConfigMetricsReportList output; 186 output.ParseFromArray(bytes.data(), bytes.size()); 187 EXPECT_TRUE(output.reports_size() > 0); 188 EXPECT_FALSE(output.reports(0).has_uid_map()); 189 } 190 191 TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) { 192 // Setup simple config key corresponding to empty config. 193 sp<UidMap> m = new UidMap(); 194 sp<AlarmMonitor> anomalyAlarmMonitor; 195 sp<AlarmMonitor> subscriberAlarmMonitor; 196 int broadcastCount = 0; 197 StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, 198 [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); 199 ConfigKey key(3, 4); 200 StatsdConfig config; 201 auto annotation = config.add_annotation(); 202 annotation->set_field_int64(1); 203 annotation->set_field_int32(2); 204 config.add_allowed_log_source("AID_ROOT"); 205 p.OnConfigUpdated(1, key, config); 206 207 // Expect to get no metrics, but snapshot specified above in uidmap. 208 vector<uint8_t> bytes; 209 p.onDumpReport(key, 1, false, ADB_DUMP, &bytes); 210 211 ConfigMetricsReportList output; 212 output.ParseFromArray(bytes.data(), bytes.size()); 213 EXPECT_TRUE(output.reports_size() > 0); 214 auto report = output.reports(0); 215 EXPECT_EQ(1, report.annotation_size()); 216 EXPECT_EQ(1, report.annotation(0).field_int64()); 217 EXPECT_EQ(2, report.annotation(0).field_int32()); 218 } 219 220 TEST(StatsLogProcessorTest, TestOutOfOrderLogs) { 221 // Setup simple config key corresponding to empty config. 222 sp<UidMap> m = new UidMap(); 223 sp<AlarmMonitor> anomalyAlarmMonitor; 224 sp<AlarmMonitor> subscriberAlarmMonitor; 225 int broadcastCount = 0; 226 StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, 227 [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); 228 229 LogEvent event1(0, 1 /*logd timestamp*/, 1001 /*elapsedRealtime*/); 230 event1.init(); 231 232 LogEvent event2(0, 2, 1002); 233 event2.init(); 234 235 LogEvent event3(0, 3, 1005); 236 event3.init(); 237 238 LogEvent event4(0, 4, 1004); 239 event4.init(); 240 241 // <----- Reconnection happens 242 243 LogEvent event5(0, 5, 999); 244 event5.init(); 245 246 LogEvent event6(0, 6, 2000); 247 event6.init(); 248 249 // <----- Reconnection happens 250 251 LogEvent event7(0, 7, 3000); 252 event7.init(); 253 254 // first event ever 255 p.OnLogEvent(&event1, true); 256 EXPECT_EQ(1UL, p.mLogCount); 257 EXPECT_EQ(1001LL, p.mLargestTimestampSeen); 258 EXPECT_EQ(1001LL, p.mLastTimestampSeen); 259 260 p.OnLogEvent(&event2, false); 261 EXPECT_EQ(2UL, p.mLogCount); 262 EXPECT_EQ(1002LL, p.mLargestTimestampSeen); 263 EXPECT_EQ(1002LL, p.mLastTimestampSeen); 264 265 p.OnLogEvent(&event3, false); 266 EXPECT_EQ(3UL, p.mLogCount); 267 EXPECT_EQ(1005LL, p.mLargestTimestampSeen); 268 EXPECT_EQ(1005LL, p.mLastTimestampSeen); 269 270 p.OnLogEvent(&event4, false); 271 EXPECT_EQ(4UL, p.mLogCount); 272 EXPECT_EQ(1005LL, p.mLargestTimestampSeen); 273 EXPECT_EQ(1004LL, p.mLastTimestampSeen); 274 EXPECT_FALSE(p.mInReconnection); 275 276 // Reconnect happens, event1 out of buffer. Read event2 277 p.OnLogEvent(&event2, true); 278 EXPECT_EQ(4UL, p.mLogCount); 279 EXPECT_EQ(1005LL, p.mLargestTimestampSeen); 280 EXPECT_EQ(1004LL, p.mLastTimestampSeen); 281 EXPECT_TRUE(p.mInReconnection); 282 283 p.OnLogEvent(&event3, false); 284 EXPECT_EQ(4UL, p.mLogCount); 285 EXPECT_EQ(1005LL, p.mLargestTimestampSeen); 286 EXPECT_EQ(1004LL, p.mLastTimestampSeen); 287 EXPECT_TRUE(p.mInReconnection); 288 289 p.OnLogEvent(&event4, false); 290 EXPECT_EQ(4UL, p.mLogCount); 291 EXPECT_EQ(1005LL, p.mLargestTimestampSeen); 292 EXPECT_EQ(1004LL, p.mLastTimestampSeen); 293 EXPECT_FALSE(p.mInReconnection); 294 295 // Fresh event comes. 296 p.OnLogEvent(&event5, false); 297 EXPECT_EQ(5UL, p.mLogCount); 298 EXPECT_EQ(1005LL, p.mLargestTimestampSeen); 299 EXPECT_EQ(999LL, p.mLastTimestampSeen); 300 301 p.OnLogEvent(&event6, false); 302 EXPECT_EQ(6UL, p.mLogCount); 303 EXPECT_EQ(2000LL, p.mLargestTimestampSeen); 304 EXPECT_EQ(2000LL, p.mLastTimestampSeen); 305 306 // Reconnect happens, read from event4 307 p.OnLogEvent(&event4, true); 308 EXPECT_EQ(6UL, p.mLogCount); 309 EXPECT_EQ(2000LL, p.mLargestTimestampSeen); 310 EXPECT_EQ(2000LL, p.mLastTimestampSeen); 311 EXPECT_TRUE(p.mInReconnection); 312 313 p.OnLogEvent(&event5, false); 314 EXPECT_EQ(6UL, p.mLogCount); 315 EXPECT_EQ(2000LL, p.mLargestTimestampSeen); 316 EXPECT_EQ(2000LL, p.mLastTimestampSeen); 317 EXPECT_TRUE(p.mInReconnection); 318 319 // Before we get out of reconnection state, it reconnects again. 320 p.OnLogEvent(&event5, true); 321 EXPECT_EQ(6UL, p.mLogCount); 322 EXPECT_EQ(2000LL, p.mLargestTimestampSeen); 323 EXPECT_EQ(2000LL, p.mLastTimestampSeen); 324 EXPECT_TRUE(p.mInReconnection); 325 326 p.OnLogEvent(&event6, false); 327 EXPECT_EQ(6UL, p.mLogCount); 328 EXPECT_EQ(2000LL, p.mLargestTimestampSeen); 329 EXPECT_EQ(2000LL, p.mLastTimestampSeen); 330 EXPECT_FALSE(p.mInReconnection); 331 EXPECT_EQ(0, p.mLogLossCount); 332 333 // it reconnects again. All old events are gone. We lose CP. 334 p.OnLogEvent(&event7, true); 335 EXPECT_EQ(7UL, p.mLogCount); 336 EXPECT_EQ(3000LL, p.mLargestTimestampSeen); 337 EXPECT_EQ(3000LL, p.mLastTimestampSeen); 338 EXPECT_EQ(1, p.mLogLossCount); 339 EXPECT_FALSE(p.mInReconnection); 340 } 341 342 #else 343 GTEST_LOG_(INFO) << "This test does nothing.\n"; 344 #endif 345 346 } // namespace statsd 347 } // namespace os 348 } // namespace android 349