Merge "E2e test for periodic alarm." into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
46eef8d049
@@ -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 \
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
92
cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
Normal file
92
cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
Normal file
@@ -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
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user