diff options
| -rw-r--r-- | cmds/statsd/Android.mk | 1 | ||||
| -rw-r--r-- | cmds/statsd/src/StatsLogProcessor.cpp | 4 | ||||
| -rw-r--r-- | cmds/statsd/src/StatsLogProcessor.h | 9 | ||||
| -rw-r--r-- | cmds/statsd/src/StatsService.cpp | 2 | ||||
| -rw-r--r-- | cmds/statsd/src/anomaly/AlarmTracker.cpp | 15 | ||||
| -rw-r--r-- | cmds/statsd/src/anomaly/AlarmTracker.h | 6 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/MetricsManager.cpp | 4 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/MetricsManager.h | 5 | ||||
| -rw-r--r-- | cmds/statsd/tests/e2e/Alarm_e2e_test.cpp | 92 | ||||
| -rw-r--r-- | cmds/statsd/tests/statsd_test_util.cpp | 4 |
10 files changed, 127 insertions, 15 deletions
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk index 1aef0c4c43c5..7723615245b7 100644 --- a/cmds/statsd/Android.mk +++ b/cmds/statsd/Android.mk @@ -202,6 +202,7 @@ LOCAL_SRC_FILES := \ tests/statsd_test_util.cpp \ tests/e2e/WakelockDuration_e2e_test.cpp \ tests/e2e/MetricConditionLink_e2e_test.cpp \ + tests/e2e/Alarm_e2e_test.cpp \ tests/e2e/Attribution_e2e_test.cpp \ tests/e2e/GaugeMetric_e2e_push_test.cpp \ tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp \ diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index c1ff27545401..13f2679e9b0e 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -85,7 +85,7 @@ StatsLogProcessor::~StatsLogProcessor() { } void StatsLogProcessor::onAnomalyAlarmFired( - const uint64_t timestampNs, + const uint64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) { std::lock_guard<std::mutex> lock(mMetricsMutex); for (const auto& itr : mMetricsManagers) { @@ -93,7 +93,7 @@ void StatsLogProcessor::onAnomalyAlarmFired( } } void StatsLogProcessor::onPeriodicAlarmFired( - const uint64_t timestampNs, + const uint64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) { std::lock_guard<std::mutex> lock(mMetricsMutex); diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h index a07a35587b11..387a9295055f 100644 --- a/cmds/statsd/src/StatsLogProcessor.h +++ b/cmds/statsd/src/StatsLogProcessor.h @@ -51,12 +51,12 @@ public: /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */ void onAnomalyAlarmFired( - const uint64_t timestampNs, + const uint64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet); /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */ void onPeriodicAlarmFired( - const uint64_t timestampNs, + const uint64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet); /* Flushes data to disk. Data on memory will be gone after written to disk. */ @@ -74,6 +74,10 @@ private: return mAnomalyAlarmMonitor; } + inline sp<AlarmMonitor> getPeriodicAlarmMonitor() const { + return mPeriodicAlarmMonitor; + } + mutable mutex mMetricsMutex; std::unordered_map<ConfigKey, sp<MetricsManager>> mMetricsManagers; @@ -147,6 +151,7 @@ private: FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket); FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets); FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period); + FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms); }; } // namespace statsd diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index 9f70c75d66e9..7b0d5d9ca884 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -698,7 +698,7 @@ Status StatsService::informAlarmForSubscriberTriggeringFired() { "Only system uid can call informAlarmForSubscriberTriggeringFired"); } - uint64_t currentTimeSec = time(nullptr); + uint64_t currentTimeSec = getElapsedRealtimeSec(); std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet = mPeriodicAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec)); if (alarmSet.size() > 0) { diff --git a/cmds/statsd/src/anomaly/AlarmTracker.cpp b/cmds/statsd/src/anomaly/AlarmTracker.cpp index eb283838afd7..249cb596d3c6 100644 --- a/cmds/statsd/src/anomaly/AlarmTracker.cpp +++ b/cmds/statsd/src/anomaly/AlarmTracker.cpp @@ -39,12 +39,14 @@ AlarmTracker::AlarmTracker(uint64_t startMillis, VLOG("AlarmTracker() called"); mAlarmSec = (startMillis + mAlarmConfig.offset_millis()) / MS_PER_SEC; mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)}; - mAlarmMonitor->add(mInternalAlarm); + if (mAlarmMonitor != nullptr) { + mAlarmMonitor->add(mInternalAlarm); + } } AlarmTracker::~AlarmTracker() { VLOG("~AlarmTracker() called"); - if (mInternalAlarm != nullptr) { + if (mInternalAlarm != nullptr && mAlarmMonitor != nullptr) { mAlarmMonitor->remove(mInternalAlarm); } } @@ -61,7 +63,8 @@ uint64_t AlarmTracker::findNextAlarmSec(uint64_t currentTimeSec) { void AlarmTracker::informAlarmsFired( const uint64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) { - if (firedAlarms.empty() || firedAlarms.find(mInternalAlarm) == firedAlarms.end()) { + if (firedAlarms.empty() || mInternalAlarm == nullptr || + firedAlarms.find(mInternalAlarm) == firedAlarms.end()) { return; } if (!mSubscriptions.empty()) { @@ -69,9 +72,11 @@ void AlarmTracker::informAlarmsFired( mSubscriptions); } firedAlarms.erase(mInternalAlarm); - mAlarmSec = findNextAlarmSec(timestampNs / NS_PER_SEC); + mAlarmSec = findNextAlarmSec((timestampNs-1) / NS_PER_SEC + 1); // round up mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)}; - mAlarmMonitor->add(mInternalAlarm); + if (mAlarmMonitor != nullptr) { + mAlarmMonitor->add(mInternalAlarm); + } } } // namespace statsd diff --git a/cmds/statsd/src/anomaly/AlarmTracker.h b/cmds/statsd/src/anomaly/AlarmTracker.h index d59dacaa1b69..13180a53ccbf 100644 --- a/cmds/statsd/src/anomaly/AlarmTracker.h +++ b/cmds/statsd/src/anomaly/AlarmTracker.h @@ -48,6 +48,11 @@ public: unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms); protected: + // For test only. Returns the alarm timestamp in seconds. Otherwise returns 0. + inline uint32_t getAlarmTimestampSec() const { + return mInternalAlarm == nullptr ? 0 : mInternalAlarm->timestampSec; + } + uint64_t findNextAlarmSec(uint64_t currentTimeMillis); // statsd_config.proto Alarm message that defines this tracker. @@ -69,6 +74,7 @@ protected: sp<const InternalAlarm> mInternalAlarm; FRIEND_TEST(AlarmTrackerTest, TestTriggerTimestamp); + FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms); }; } // namespace statsd diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index 1be082a692cc..00188e8da0fb 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -351,7 +351,7 @@ void MetricsManager::onLogEvent(const LogEvent& event) { } void MetricsManager::onAnomalyAlarmFired( - const uint64_t timestampNs, + const uint64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) { for (const auto& itr : mAllAnomalyTrackers) { itr->informAlarmsFired(timestampNs, alarmSet); @@ -359,7 +359,7 @@ void MetricsManager::onAnomalyAlarmFired( } void MetricsManager::onPeriodicAlarmFired( - const uint64_t timestampNs, + const uint64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) { for (const auto& itr : mAllPeriodicAlarmTrackers) { itr->informAlarmsFired(timestampNs, alarmSet); diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index 05ce84d7ea8f..da0cd4a29d3b 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -48,11 +48,11 @@ public: void onLogEvent(const LogEvent& event); void onAnomalyAlarmFired( - const uint64_t timestampNs, + const uint64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet); void onPeriodicAlarmFired( - const uint64_t timestampNs, + const uint64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet); void notifyAppUpgrade(const uint64_t& eventTimeNs, const string& apk, const int uid, @@ -184,6 +184,7 @@ private: FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets); FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period); + FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms); }; } // namespace statsd diff --git a/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp b/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp new file mode 100644 index 000000000000..73c4e7b859de --- /dev/null +++ b/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp @@ -0,0 +1,92 @@ +// 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 <gtest/gtest.h> + +#include "src/StatsLogProcessor.h" +#include "src/stats_log_util.h" +#include "tests/statsd_test_util.h" + +#include <vector> + +namespace android { +namespace os { +namespace statsd { + +#ifdef __ANDROID__ + +namespace { + +StatsdConfig CreateStatsdConfig() { + StatsdConfig config; + config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + + auto alarm = config.add_alarm(); + alarm->set_id(123456); + alarm->set_offset_millis(TimeUnitToBucketSizeInMillis(TEN_MINUTES)); + alarm->set_period_millis(TimeUnitToBucketSizeInMillis(ONE_HOUR)); + + alarm = config.add_alarm(); + alarm->set_id(654321); + alarm->set_offset_millis(TimeUnitToBucketSizeInMillis(FIVE_MINUTES)); + alarm->set_period_millis(TimeUnitToBucketSizeInMillis(THIRTY_MINUTES)); + return config; +} + +} // namespace + +TEST(AlarmE2eTest, TestMultipleAlarms) { + auto config = CreateStatsdConfig(); + int64_t bucketStartTimeNs = 10000000000; + + ConfigKey cfgKey; + auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey); + EXPECT_EQ(processor->mMetricsManagers.size(), 1u); + EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); + EXPECT_EQ(2u, processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers.size()); + + auto alarmTracker1 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[0]; + auto alarmTracker2 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[1]; + + int64_t alarmTimestampSec0 = bucketStartTimeNs / NS_PER_SEC + 10 * 60; + int64_t alarmTimestampSec1 = bucketStartTimeNs / NS_PER_SEC + 5 * 60; + EXPECT_EQ(alarmTimestampSec0, alarmTracker1->getAlarmTimestampSec()); + EXPECT_EQ(alarmTimestampSec1, alarmTracker2->getAlarmTimestampSec()); + + // Alarm fired. + const int64_t alarmFiredTimestampSec0 = alarmTimestampSec1 + 5; + auto alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan( + static_cast<uint32_t>(alarmFiredTimestampSec0)); + EXPECT_EQ(1u, alarmSet.size()); + processor->onPeriodicAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet); + EXPECT_EQ(alarmTimestampSec0, alarmTracker1->getAlarmTimestampSec()); + EXPECT_EQ(alarmTimestampSec1 + 30 * 60, alarmTracker2->getAlarmTimestampSec()); + + // Alarms fired very late. + const int64_t alarmFiredTimestampSec1 = alarmTimestampSec0 + 2 * 60 * 60 + 125; + alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan( + static_cast<uint32_t>(alarmFiredTimestampSec1)); + EXPECT_EQ(2u, alarmSet.size()); + processor->onPeriodicAlarmFired(alarmFiredTimestampSec1 * NS_PER_SEC, alarmSet); + EXPECT_EQ(alarmTimestampSec0 + 60 * 60 * 3, alarmTracker1->getAlarmTimestampSec()); + EXPECT_EQ(alarmTimestampSec1 + 30 * 60 * 5, alarmTracker2->getAlarmTimestampSec()); +} + +#else +GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp index 66215004db5f..d0840f050723 100644 --- a/cmds/statsd/tests/statsd_test_util.cpp +++ b/cmds/statsd/tests/statsd_test_util.cpp @@ -450,7 +450,9 @@ sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const Stat sp<AlarmMonitor> anomalyAlarmMonitor = new AlarmMonitor(1, [](const sp<IStatsCompanionService>&, int64_t){}, [](const sp<IStatsCompanionService>&){}); - sp<AlarmMonitor> periodicAlarmMonitor; + sp<AlarmMonitor> periodicAlarmMonitor = + new AlarmMonitor(1, [](const sp<IStatsCompanionService>&, int64_t){}, + [](const sp<IStatsCompanionService>&){}); sp<StatsLogProcessor> processor = new StatsLogProcessor( uidMap, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseSec, [](const ConfigKey&){}); processor->OnConfigUpdated(key, config); |