David Chen | d9269e2 | 2017-12-05 13:43:51 -0800 | [diff] [blame] | 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/statsd_config.pb.h" |
| 18 | #include "guardrail/StatsdStats.h" |
| 19 | #include "logd/LogEvent.h" |
| 20 | #include "packages/UidMap.h" |
| 21 | #include "statslog.h" |
| 22 | |
| 23 | #include <gmock/gmock.h> |
| 24 | #include <gtest/gtest.h> |
| 25 | |
| 26 | #include <stdio.h> |
| 27 | |
| 28 | using namespace android; |
| 29 | using namespace testing; |
| 30 | |
| 31 | namespace android { |
| 32 | namespace os { |
| 33 | namespace statsd { |
| 34 | |
Yao Chen | 288c600 | 2017-12-12 13:43:18 -0800 | [diff] [blame] | 35 | using android::util::ProtoOutputStream; |
| 36 | |
David Chen | d9269e2 | 2017-12-05 13:43:51 -0800 | [diff] [blame] | 37 | #ifdef __ANDROID__ |
| 38 | |
| 39 | /** |
| 40 | * Mock MetricsManager (ByteSize() is called). |
| 41 | */ |
| 42 | class MockMetricsManager : public MetricsManager { |
| 43 | public: |
Yao Chen | d10f7b1 | 2017-12-18 12:53:50 -0800 | [diff] [blame] | 44 | MockMetricsManager() : MetricsManager(ConfigKey(1, "key"), StatsdConfig(), 1000, new UidMap()) { |
David Chen | d9269e2 | 2017-12-05 13:43:51 -0800 | [diff] [blame] | 45 | } |
| 46 | |
| 47 | MOCK_METHOD0(byteSize, size_t()); |
Yao Chen | 288c600 | 2017-12-12 13:43:18 -0800 | [diff] [blame] | 48 | MOCK_METHOD1(onDumpReport, void(ProtoOutputStream* output)); |
David Chen | d9269e2 | 2017-12-05 13:43:51 -0800 | [diff] [blame] | 49 | }; |
| 50 | |
| 51 | TEST(StatsLogProcessorTest, TestRateLimitByteSize) { |
| 52 | sp<UidMap> m = new UidMap(); |
| 53 | sp<AnomalyMonitor> anomalyMonitor; |
| 54 | // Construct the processor with a dummy sendBroadcast function that does nothing. |
Yangster-mac | 2087716 | 2017-12-22 17:19:39 -0800 | [diff] [blame] | 55 | StatsLogProcessor p(m, anomalyMonitor, 0, [](const ConfigKey& key) {}); |
David Chen | d9269e2 | 2017-12-05 13:43:51 -0800 | [diff] [blame] | 56 | |
| 57 | MockMetricsManager mockMetricsManager; |
| 58 | |
| 59 | ConfigKey key(100, "key"); |
| 60 | // Expect only the first flush to trigger a check for byte size since the last two are |
| 61 | // rate-limited. |
| 62 | EXPECT_CALL(mockMetricsManager, byteSize()).Times(1); |
| 63 | p.flushIfNecessary(99, key, mockMetricsManager); |
| 64 | p.flushIfNecessary(100, key, mockMetricsManager); |
| 65 | p.flushIfNecessary(101, key, mockMetricsManager); |
| 66 | } |
| 67 | |
| 68 | TEST(StatsLogProcessorTest, TestRateLimitBroadcast) { |
| 69 | sp<UidMap> m = new UidMap(); |
| 70 | sp<AnomalyMonitor> anomalyMonitor; |
| 71 | int broadcastCount = 0; |
Yangster-mac | 2087716 | 2017-12-22 17:19:39 -0800 | [diff] [blame] | 72 | StatsLogProcessor p(m, anomalyMonitor, 0, |
David Chen | d9269e2 | 2017-12-05 13:43:51 -0800 | [diff] [blame] | 73 | [&broadcastCount](const ConfigKey& key) { broadcastCount++; }); |
| 74 | |
| 75 | MockMetricsManager mockMetricsManager; |
| 76 | |
| 77 | ConfigKey key(100, "key"); |
| 78 | EXPECT_CALL(mockMetricsManager, byteSize()) |
| 79 | .Times(2) |
| 80 | .WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * .95))); |
| 81 | |
| 82 | // Expect only one broadcast despite always returning a size that should trigger broadcast. |
| 83 | p.flushIfNecessary(1, key, mockMetricsManager); |
| 84 | EXPECT_EQ(1, broadcastCount); |
| 85 | |
| 86 | // This next call to flush should not trigger a broadcast. |
| 87 | p.mLastByteSizeTimes.clear(); // Force another check for byte size. |
| 88 | p.flushIfNecessary(2, key, mockMetricsManager); |
| 89 | EXPECT_EQ(1, broadcastCount); |
| 90 | } |
| 91 | |
| 92 | TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) { |
| 93 | sp<UidMap> m = new UidMap(); |
| 94 | sp<AnomalyMonitor> anomalyMonitor; |
| 95 | int broadcastCount = 0; |
Yangster-mac | 2087716 | 2017-12-22 17:19:39 -0800 | [diff] [blame] | 96 | StatsLogProcessor p(m, anomalyMonitor, 0, |
David Chen | d9269e2 | 2017-12-05 13:43:51 -0800 | [diff] [blame] | 97 | [&broadcastCount](const ConfigKey& key) { broadcastCount++; }); |
| 98 | |
| 99 | MockMetricsManager mockMetricsManager; |
| 100 | |
| 101 | ConfigKey key(100, "key"); |
| 102 | EXPECT_CALL(mockMetricsManager, byteSize()) |
| 103 | .Times(1) |
| 104 | .WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * 1.2))); |
| 105 | |
Yao Chen | 288c600 | 2017-12-12 13:43:18 -0800 | [diff] [blame] | 106 | EXPECT_CALL(mockMetricsManager, onDumpReport(_)).Times(1); |
David Chen | d9269e2 | 2017-12-05 13:43:51 -0800 | [diff] [blame] | 107 | |
| 108 | // Expect to call the onDumpReport and skip the broadcast. |
| 109 | p.flushIfNecessary(1, key, mockMetricsManager); |
| 110 | EXPECT_EQ(0, broadcastCount); |
| 111 | } |
| 112 | |
| 113 | #else |
| 114 | GTEST_LOG_(INFO) << "This test does nothing.\n"; |
| 115 | #endif |
| 116 | |
| 117 | } // namespace statsd |
| 118 | } // namespace os |
Yao Chen | 288c600 | 2017-12-12 13:43:18 -0800 | [diff] [blame] | 119 | } // namespace android |