// Copyright (C) 2017 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "StatsLogProcessor.h" #include "config/ConfigKey.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "guardrail/StatsdStats.h" #include "logd/LogEvent.h" #include "packages/UidMap.h" #include "statslog.h" #include #include #include using namespace android; using namespace testing; namespace android { namespace os { namespace statsd { #ifdef __ANDROID__ /** * Mock MetricsManager (ByteSize() is called). */ class MockMetricsManager : public MetricsManager { public: MockMetricsManager() : MetricsManager(ConfigKey(1, "key"), StatsdConfig()) { } MOCK_METHOD0(byteSize, size_t()); MOCK_METHOD0(onDumpReport, std::vector>>()); }; TEST(StatsLogProcessorTest, TestRateLimitByteSize) { sp m = new UidMap(); sp anomalyMonitor; // Construct the processor with a dummy sendBroadcast function that does nothing. StatsLogProcessor p(m, anomalyMonitor, [](const ConfigKey& key) {}); MockMetricsManager mockMetricsManager; ConfigKey key(100, "key"); // Expect only the first flush to trigger a check for byte size since the last two are // rate-limited. EXPECT_CALL(mockMetricsManager, byteSize()).Times(1); p.flushIfNecessary(99, key, mockMetricsManager); p.flushIfNecessary(100, key, mockMetricsManager); p.flushIfNecessary(101, key, mockMetricsManager); } TEST(StatsLogProcessorTest, TestRateLimitBroadcast) { sp m = new UidMap(); sp anomalyMonitor; int broadcastCount = 0; StatsLogProcessor p(m, anomalyMonitor, [&broadcastCount](const ConfigKey& key) { broadcastCount++; }); MockMetricsManager mockMetricsManager; ConfigKey key(100, "key"); EXPECT_CALL(mockMetricsManager, byteSize()) .Times(2) .WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * .95))); // Expect only one broadcast despite always returning a size that should trigger broadcast. p.flushIfNecessary(1, key, mockMetricsManager); EXPECT_EQ(1, broadcastCount); // This next call to flush should not trigger a broadcast. p.mLastByteSizeTimes.clear(); // Force another check for byte size. p.flushIfNecessary(2, key, mockMetricsManager); EXPECT_EQ(1, broadcastCount); } TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) { sp m = new UidMap(); sp anomalyMonitor; int broadcastCount = 0; StatsLogProcessor p(m, anomalyMonitor, [&broadcastCount](const ConfigKey& key) { broadcastCount++; }); MockMetricsManager mockMetricsManager; ConfigKey key(100, "key"); EXPECT_CALL(mockMetricsManager, byteSize()) .Times(1) .WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * 1.2))); EXPECT_CALL(mockMetricsManager, onDumpReport()).Times(1); // Expect to call the onDumpReport and skip the broadcast. p.flushIfNecessary(1, key, mockMetricsManager); EXPECT_EQ(0, broadcastCount); } #else GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } // namespace statsd } // namespace os } // namespace android