Home | History | Annotate | Download | only in tests
      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