summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.cpp19
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/duration_helper/DurationTracker.h10
-rw-r--r--cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp12
-rw-r--r--cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h7
-rw-r--r--cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp16
-rw-r--r--cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h7
-rw-r--r--cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp9
-rw-r--r--cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp99
-rw-r--r--cmds/statsd/tests/metrics/OringDurationTracker_test.cpp127
10 files changed, 157 insertions, 151 deletions
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 66e8c6103ae8..0fac11836caa 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -111,16 +111,16 @@ void DurationMetricProducer::startNewProtoOutputStreamLocked(long long startTime
}
unique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker(
- const HashableDimensionKey& eventKey, vector<DurationBucket>& bucket) const {
+ const HashableDimensionKey& eventKey) const {
switch (mMetric.aggregation_type()) {
case DurationMetric_AggregationType_SUM:
return make_unique<OringDurationTracker>(
mConfigKey, mMetric.name(), eventKey, mWizard, mConditionTrackerIndex, mNested,
- mCurrentBucketStartTimeNs, mBucketSizeNs, mAnomalyTrackers, bucket);
+ mCurrentBucketStartTimeNs, mBucketSizeNs, mAnomalyTrackers);
case DurationMetric_AggregationType_MAX_SPARSE:
return make_unique<MaxDurationTracker>(
mConfigKey, mMetric.name(), eventKey, mWizard, mConditionTrackerIndex, mNested,
- mCurrentBucketStartTimeNs, mBucketSizeNs, mAnomalyTrackers, bucket);
+ mCurrentBucketStartTimeNs, mBucketSizeNs, mAnomalyTrackers);
}
}
@@ -168,13 +168,6 @@ std::unique_ptr<std::vector<uint8_t>> DurationMetricProducer::onDumpReportLocked
continue;
}
- // If there is no duration bucket info for this key, don't include it in the report.
- // For example, duration started, but condition is never turned to true.
- // TODO: Only add the key to the map when we add duration buckets info for it.
- if (pair.second.size() == 0) {
- continue;
- }
-
long long wrapperToken =
mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
@@ -217,7 +210,7 @@ std::unique_ptr<std::vector<uint8_t>> DurationMetricProducer::onDumpReportLocked
(long long)mCurrentBucketStartTimeNs);
std::unique_ptr<std::vector<uint8_t>> buffer = serializeProtoLocked();
startNewProtoOutputStreamLocked(endTime);
- // TODO: Properly clear the old buckets.
+ mPastBuckets.clear();
return buffer;
}
@@ -227,7 +220,7 @@ void DurationMetricProducer::flushIfNeededLocked(const uint64_t& eventTime) {
}
VLOG("flushing...........");
for (auto it = mCurrentSlicedDuration.begin(); it != mCurrentSlicedDuration.end();) {
- if (it->second->flushIfNeeded(eventTime)) {
+ if (it->second->flushIfNeeded(eventTime, &mPastBuckets)) {
VLOG("erase bucket for key %s", it->first.c_str());
it = mCurrentSlicedDuration.erase(it);
} else {
@@ -279,7 +272,7 @@ void DurationMetricProducer::onMatchedLogEventInternalLocked(
if (hitGuardRailLocked(eventKey)) {
return;
}
- mCurrentSlicedDuration[eventKey] = createDurationTracker(eventKey, mPastBuckets[eventKey]);
+ mCurrentSlicedDuration[eventKey] = createDurationTracker(eventKey);
}
auto it = mCurrentSlicedDuration.find(eventKey);
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 8e32d148e221..8ba241ea5497 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -104,7 +104,7 @@ private:
// Helper function to create a duration tracker given the metric aggregation type.
std::unique_ptr<DurationTracker> createDurationTracker(
- const HashableDimensionKey& eventKey, std::vector<DurationBucket>& bucket) const;
+ const HashableDimensionKey& eventKey) const;
// Util function to check whether the specified dimension hits the guardrail.
bool hitGuardRailLocked(const HashableDimensionKey& newKey);
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
index 834f7f5b0b86..3c714b3923e8 100644
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
@@ -63,8 +63,7 @@ public:
DurationTracker(const ConfigKey& key, const string& name, const HashableDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
uint64_t currentBucketStartNs, uint64_t bucketSizeNs,
- const std::vector<sp<AnomalyTracker>>& anomalyTrackers,
- std::vector<DurationBucket>& bucket)
+ const std::vector<sp<AnomalyTracker>>& anomalyTrackers)
: mConfigKey(key),
mName(name),
mEventKey(eventKey),
@@ -73,7 +72,6 @@ public:
mBucketSizeNs(bucketSizeNs),
mNested(nesting),
mCurrentBucketStartTimeNs(currentBucketStartNs),
- mBucket(bucket),
mDuration(0),
mCurrentBucketNum(0),
mAnomalyTrackers(anomalyTrackers){};
@@ -91,7 +89,9 @@ public:
// Flush stale buckets if needed, and return true if the tracker has no on-going duration
// events, so that the owner can safely remove the tracker.
- virtual bool flushIfNeeded(uint64_t timestampNs) = 0;
+ virtual bool flushIfNeeded(
+ uint64_t timestampNs,
+ std::unordered_map<HashableDimensionKey, std::vector<DurationBucket>>* output) = 0;
// Predict the anomaly timestamp given the current status.
virtual int64_t predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
@@ -159,8 +159,6 @@ protected:
uint64_t mCurrentBucketStartTimeNs;
- std::vector<DurationBucket>& mBucket; // where to write output
-
int64_t mDuration; // current recorded duration result
uint64_t mCurrentBucketNum;
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
index 4b346dd25050..08c91351c49e 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
@@ -28,10 +28,9 @@ MaxDurationTracker::MaxDurationTracker(const ConfigKey& key, const string& name,
const HashableDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
uint64_t currentBucketStartNs, uint64_t bucketSizeNs,
- const std::vector<sp<AnomalyTracker>>& anomalyTrackers,
- std::vector<DurationBucket>& bucket)
+ const std::vector<sp<AnomalyTracker>>& anomalyTrackers)
: DurationTracker(key, name, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs,
- bucketSizeNs, anomalyTrackers, bucket) {
+ bucketSizeNs, anomalyTrackers) {
}
bool MaxDurationTracker::hitGuardRail(const HashableDimensionKey& newKey) {
@@ -145,7 +144,8 @@ void MaxDurationTracker::noteStopAll(const uint64_t eventTime) {
}
}
-bool MaxDurationTracker::flushIfNeeded(uint64_t eventTime) {
+bool MaxDurationTracker::flushIfNeeded(
+ uint64_t eventTime, unordered_map<HashableDimensionKey, vector<DurationBucket>>* output) {
if (mCurrentBucketStartTimeNs + mBucketSizeNs > eventTime) {
return false;
}
@@ -202,7 +202,7 @@ bool MaxDurationTracker::flushIfNeeded(uint64_t eventTime) {
if (mDuration != 0) {
info.mDuration = mDuration;
- mBucket.push_back(info);
+ (*output)[mEventKey].push_back(info);
addPastBucketToAnomalyTrackers(info.mDuration, info.mBucketNum);
VLOG(" final duration for last bucket: %lld", (long long)mDuration);
}
@@ -215,7 +215,7 @@ bool MaxDurationTracker::flushIfNeeded(uint64_t eventTime) {
info.mBucketEndNs = endTime + mBucketSizeNs * i;
info.mBucketNum = mCurrentBucketNum + i;
info.mDuration = mBucketSizeNs;
- mBucket.push_back(info);
+ (*output)[mEventKey].push_back(info);
addPastBucketToAnomalyTrackers(info.mDuration, info.mBucketNum);
VLOG(" filling gap bucket with duration %lld", (long long)mBucketSizeNs);
}
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
index e0d1466c6fc4..10eddb8bee6e 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
@@ -32,15 +32,16 @@ public:
const HashableDimensionKey& eventKey, sp<ConditionWizard> wizard,
int conditionIndex, bool nesting, uint64_t currentBucketStartNs,
uint64_t bucketSizeNs,
- const std::vector<sp<AnomalyTracker>>& anomalyTrackers,
- std::vector<DurationBucket>& bucket);
+ const std::vector<sp<AnomalyTracker>>& anomalyTrackers);
void noteStart(const HashableDimensionKey& key, bool condition, const uint64_t eventTime,
const ConditionKey& conditionKey) override;
void noteStop(const HashableDimensionKey& key, const uint64_t eventTime,
const bool stopAll) override;
void noteStopAll(const uint64_t eventTime) override;
- bool flushIfNeeded(uint64_t timestampNs) override;
+ bool flushIfNeeded(
+ uint64_t timestampNs,
+ std::unordered_map<HashableDimensionKey, std::vector<DurationBucket>>* output) override;
void onSlicedConditionMayChange(const uint64_t timestamp) override;
void onConditionChanged(bool condition, const uint64_t timestamp) override;
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
index abdfbc06d7a7..8122744b32b5 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
@@ -29,10 +29,9 @@ OringDurationTracker::OringDurationTracker(const ConfigKey& key, const string& n
sp<ConditionWizard> wizard, int conditionIndex,
bool nesting, uint64_t currentBucketStartNs,
uint64_t bucketSizeNs,
- const std::vector<sp<AnomalyTracker>>& anomalyTrackers,
- std::vector<DurationBucket>& bucket)
+ const std::vector<sp<AnomalyTracker>>& anomalyTrackers)
: DurationTracker(key, name, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs,
- bucketSizeNs, anomalyTrackers, bucket),
+ bucketSizeNs, anomalyTrackers),
mStarted(),
mPaused() {
mLastStartTime = 0;
@@ -128,7 +127,8 @@ void OringDurationTracker::noteStopAll(const uint64_t timestamp) {
mConditionKeyMap.clear();
}
-bool OringDurationTracker::flushIfNeeded(uint64_t eventTime) {
+bool OringDurationTracker::flushIfNeeded(
+ uint64_t eventTime, unordered_map<HashableDimensionKey, vector<DurationBucket>>* output) {
if (eventTime < mCurrentBucketStartTimeNs + mBucketSizeNs) {
return false;
}
@@ -145,7 +145,7 @@ bool OringDurationTracker::flushIfNeeded(uint64_t eventTime) {
}
if (mDuration > 0) {
current_info.mDuration = mDuration;
- mBucket.push_back(current_info);
+ (*output)[mEventKey].push_back(current_info);
addPastBucketToAnomalyTrackers(current_info.mDuration, current_info.mBucketNum);
VLOG(" duration: %lld", (long long)current_info.mDuration);
}
@@ -157,9 +157,9 @@ bool OringDurationTracker::flushIfNeeded(uint64_t eventTime) {
info.mBucketEndNs = info.mBucketStartNs + mBucketSizeNs;
info.mBucketNum = mCurrentBucketNum + i;
info.mDuration = mBucketSizeNs;
- mBucket.push_back(info);
- addPastBucketToAnomalyTrackers(info.mDuration, info.mBucketNum);
- VLOG(" add filling bucket with duration %lld", (long long)info.mDuration);
+ (*output)[mEventKey].push_back(info);
+ addPastBucketToAnomalyTrackers(info.mDuration, info.mBucketNum);
+ VLOG(" add filling bucket with duration %lld", (long long)info.mDuration);
}
}
mCurrentBucketStartTimeNs += numBucketsForward * mBucketSizeNs;
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
index a8404a961dd2..b7d3cba7055e 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
@@ -31,8 +31,7 @@ public:
const HashableDimensionKey& eventKey, sp<ConditionWizard> wizard,
int conditionIndex, bool nesting, uint64_t currentBucketStartNs,
uint64_t bucketSizeNs,
- const std::vector<sp<AnomalyTracker>>& anomalyTrackers,
- std::vector<DurationBucket>& bucket);
+ const std::vector<sp<AnomalyTracker>>& anomalyTrackers);
void noteStart(const HashableDimensionKey& key, bool condition, const uint64_t eventTime,
const ConditionKey& conditionKey) override;
@@ -43,7 +42,9 @@ public:
void onSlicedConditionMayChange(const uint64_t timestamp) override;
void onConditionChanged(bool condition, const uint64_t timestamp) override;
- bool flushIfNeeded(uint64_t timestampNs) override;
+ bool flushIfNeeded(
+ uint64_t timestampNs,
+ std::unordered_map<HashableDimensionKey, std::vector<DurationBucket>>* output) override;
int64_t predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
const uint64_t currentTimestamp) const override;
diff --git a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
index 3f2b7cdd22ee..3158c2757263 100644
--- a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
@@ -89,7 +89,7 @@ TEST(DurationMetricTrackerTest, TestNonSlicedCondition) {
LogEvent event4(tagId, bucketStartTimeNs + bucketSizeNs + 3);
DurationMetricProducer durationProducer(
- kConfigKey, metric, 0 /*no condition*/, 1 /* start index */, 2 /* stop index */,
+ kConfigKey, metric, 0 /* condition index */, 1 /* start index */, 2 /* stop index */,
3 /* stop_all index */, false /*nesting*/, wizard, {}, bucketStartTimeNs);
EXPECT_FALSE(durationProducer.mCondition);
EXPECT_FALSE(durationProducer.isConditionSliced());
@@ -97,12 +97,7 @@ TEST(DurationMetricTrackerTest, TestNonSlicedCondition) {
durationProducer.onMatchedLogEvent(1 /* start index*/, event1, false /* scheduledPull */);
durationProducer.onMatchedLogEvent(2 /* stop index*/, event2, false /* scheduledPull */);
durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
- EXPECT_EQ(1UL, durationProducer.mPastBuckets.size());
- EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_DIMENSION_KEY) !=
- durationProducer.mPastBuckets.end());
- const auto& buckets1 = durationProducer.mPastBuckets[DEFAULT_DIMENSION_KEY];
- EXPECT_EQ(0UL, buckets1.size());
-
+ EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
durationProducer.onMatchedLogEvent(1 /* start index*/, event3, false /* scheduledPull */);
durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
index 5d47437c486c..1adcc1146c42 100644
--- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
@@ -37,18 +37,19 @@ namespace os {
namespace statsd {
const ConfigKey kConfigKey(0, "test");
+const string eventKey = "event";
TEST(MaxDurationTrackerTest, TestSimpleMaxDuration) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
ConditionKey key1;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- MaxDurationTracker tracker(kConfigKey, "metric", "event", wizard, -1, false, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ MaxDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, -1, false, bucketStartTimeNs,
+ bucketSizeNs, {});
tracker.noteStart("1", true, bucketStartTimeNs, key1);
// Event starts again. This would not change anything as it already starts.
@@ -60,50 +61,53 @@ TEST(MaxDurationTrackerTest, TestSimpleMaxDuration) {
tracker.noteStart("2", true, bucketStartTimeNs + 20, key1);
tracker.noteStop("2", bucketStartTimeNs + 40, false /*stop all*/);
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1);
- EXPECT_EQ(1u, buckets.size());
- EXPECT_EQ(20ULL, buckets[0].mDuration);
+ tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(1u, buckets[eventKey].size());
+ EXPECT_EQ(20ULL, buckets[eventKey][0].mDuration);
}
TEST(MaxDurationTrackerTest, TestStopAll) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
ConditionKey key1;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- MaxDurationTracker tracker(kConfigKey, "metric", "event", wizard, -1, false, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ MaxDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, -1, false, bucketStartTimeNs,
+ bucketSizeNs, {});
tracker.noteStart("1", true, bucketStartTimeNs + 1, key1);
// Another event starts in this bucket.
tracker.noteStart("2", true, bucketStartTimeNs + 20, key1);
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 40);
+ tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 40, &buckets);
tracker.noteStopAll(bucketStartTimeNs + bucketSizeNs + 40);
EXPECT_TRUE(tracker.mInfos.empty());
- EXPECT_EQ(1u, buckets.size());
- EXPECT_EQ(bucketSizeNs - 1, buckets[0].mDuration);
- tracker.flushIfNeeded(bucketStartTimeNs + 3 * bucketSizeNs + 40);
- EXPECT_EQ(2u, buckets.size());
- EXPECT_EQ(bucketSizeNs - 1, buckets[0].mDuration);
- EXPECT_EQ(40ULL, buckets[1].mDuration);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(1u, buckets[eventKey].size());
+ EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
+
+ tracker.flushIfNeeded(bucketStartTimeNs + 3 * bucketSizeNs + 40, &buckets);
+ EXPECT_EQ(2u, buckets[eventKey].size());
+ EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
+ EXPECT_EQ(40ULL, buckets[eventKey][1].mDuration);
}
TEST(MaxDurationTrackerTest, TestCrossBucketBoundary) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
ConditionKey key1;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- MaxDurationTracker tracker(kConfigKey, "metric", "event", wizard, -1, false, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ MaxDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, -1, false, bucketStartTimeNs,
+ bucketSizeNs, {});
// The event starts.
tracker.noteStart("", true, bucketStartTimeNs + 1, key1);
@@ -112,25 +116,26 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary) {
tracker.noteStart("", true, bucketStartTimeNs + bucketSizeNs + 1, key1);
// The event stops at early 4th bucket.
- tracker.flushIfNeeded(bucketStartTimeNs + (3 * bucketSizeNs) + 20);
+ tracker.flushIfNeeded(bucketStartTimeNs + (3 * bucketSizeNs) + 20, &buckets);
tracker.noteStop("", bucketStartTimeNs + (3 * bucketSizeNs) + 20, false /*stop all*/);
- EXPECT_EQ(3u, buckets.size());
- EXPECT_EQ((unsigned long long)(bucketSizeNs - 1), buckets[0].mDuration);
- EXPECT_EQ((unsigned long long)bucketSizeNs, buckets[1].mDuration);
- EXPECT_EQ((unsigned long long)bucketSizeNs, buckets[2].mDuration);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(3u, buckets[eventKey].size());
+ EXPECT_EQ((unsigned long long)(bucketSizeNs - 1), buckets[eventKey][0].mDuration);
+ EXPECT_EQ((unsigned long long)bucketSizeNs, buckets[eventKey][1].mDuration);
+ EXPECT_EQ((unsigned long long)bucketSizeNs, buckets[eventKey][2].mDuration);
}
TEST(MaxDurationTrackerTest, TestCrossBucketBoundary_nested) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
ConditionKey key1;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- MaxDurationTracker tracker(kConfigKey, "metric", "event", wizard, -1, true, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ MaxDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, -1, true, bucketStartTimeNs,
+ bucketSizeNs, {});
// 2 starts
tracker.noteStart("", true, bucketStartTimeNs + 1, key1);
@@ -138,20 +143,21 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary_nested) {
// one stop
tracker.noteStop("", bucketStartTimeNs + 20, false /*stop all*/);
- tracker.flushIfNeeded(bucketStartTimeNs + (2 * bucketSizeNs) + 1);
+ tracker.flushIfNeeded(bucketStartTimeNs + (2 * bucketSizeNs) + 1, &buckets);
- EXPECT_EQ(2u, buckets.size());
- EXPECT_EQ(bucketSizeNs - 1, buckets[0].mDuration);
- EXPECT_EQ(bucketSizeNs, buckets[1].mDuration);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(2u, buckets[eventKey].size());
+ EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
+ EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
// real stop now.
tracker.noteStop("", bucketStartTimeNs + (2 * bucketSizeNs) + 5, false);
- tracker.flushIfNeeded(bucketStartTimeNs + (3 * bucketSizeNs) + 1);
+ tracker.flushIfNeeded(bucketStartTimeNs + (3 * bucketSizeNs) + 1, &buckets);
- EXPECT_EQ(3u, buckets.size());
- EXPECT_EQ(bucketSizeNs - 1, buckets[0].mDuration);
- EXPECT_EQ(bucketSizeNs, buckets[1].mDuration);
- EXPECT_EQ(5ULL, buckets[2].mDuration);
+ EXPECT_EQ(3u, buckets[eventKey].size());
+ EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
+ EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
+ EXPECT_EQ(5ULL, buckets[eventKey][2].mDuration);
}
TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) {
@@ -163,15 +169,15 @@ TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) {
EXPECT_CALL(*wizard, query(_, key1)) // #4
.WillOnce(Return(ConditionState::kFalse));
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t eventStartTimeNs = bucketStartTimeNs + 1;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
int64_t durationTimeNs = 2 * 1000;
- MaxDurationTracker tracker(kConfigKey, "metric", "event", wizard, 1, false, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ MaxDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, false, bucketStartTimeNs,
+ bucketSizeNs, {});
EXPECT_TRUE(tracker.mAnomalyTrackers.empty());
tracker.noteStart("2:maps", true, eventStartTimeNs, key1);
@@ -180,9 +186,10 @@ TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) {
tracker.noteStop("2:maps", eventStartTimeNs + durationTimeNs, false);
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1);
- EXPECT_EQ(1u, buckets.size());
- EXPECT_EQ(5ULL, buckets[0].mDuration);
+ tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(1u, buckets[eventKey].size());
+ EXPECT_EQ(5ULL, buckets[eventKey][0].mDuration);
}
TEST(MaxDurationTrackerTest, TestAnomalyDetection) {
@@ -193,7 +200,7 @@ TEST(MaxDurationTrackerTest, TestAnomalyDetection) {
alert.set_number_of_buckets(2);
alert.set_refractory_period_secs(1);
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey key1;
key1["APP_BACKGROUND"] = "1:maps|";
@@ -202,8 +209,8 @@ TEST(MaxDurationTrackerTest, TestAnomalyDetection) {
uint64_t bucketSizeNs = 30 * NS_PER_SEC;
sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert);
- MaxDurationTracker tracker(kConfigKey, "metric", "event", wizard, -1, true, bucketStartTimeNs,
- bucketSizeNs, {anomalyTracker}, buckets);
+ MaxDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, -1, true, bucketStartTimeNs,
+ bucketSizeNs, {anomalyTracker});
tracker.noteStart("1", true, eventStartTimeNs, key1);
tracker.noteStop("1", eventStartTimeNs + 10, false);
@@ -211,7 +218,7 @@ TEST(MaxDurationTrackerTest, TestAnomalyDetection) {
EXPECT_EQ(10LL, tracker.mDuration);
tracker.noteStart("2", true, eventStartTimeNs + 20, key1);
- tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 3 * NS_PER_SEC);
+ tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 3 * NS_PER_SEC, &buckets);
tracker.noteStop("2", eventStartTimeNs + 2 * bucketSizeNs + 3 * NS_PER_SEC, false);
EXPECT_EQ((long long)(4 * NS_PER_SEC + 1LL), tracker.mDuration);
EXPECT_EQ(anomalyTracker->mLastAlarmTimestampNs,
diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
index 6913c8161345..fa7b9a734524 100644
--- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
@@ -35,6 +35,7 @@ namespace os {
namespace statsd {
const ConfigKey kConfigKey(0, "test");
+const string eventKey = "event";
TEST(OringDurationTrackerTest, TestDurationOverlap) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
@@ -42,15 +43,15 @@ TEST(OringDurationTrackerTest, TestDurationOverlap) {
ConditionKey key1;
key1["APP_BACKGROUND"] = "1:maps|";
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t eventStartTimeNs = bucketStartTimeNs + 1;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
uint64_t durationTimeNs = 2 * 1000;
- OringDurationTracker tracker(kConfigKey, "metric", "event", wizard, 1, false, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, false,
+ bucketStartTimeNs, bucketSizeNs, {});
tracker.noteStart("2:maps", true, eventStartTimeNs, key1);
EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
@@ -58,9 +59,11 @@ TEST(OringDurationTrackerTest, TestDurationOverlap) {
EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
tracker.noteStop("2:maps", eventStartTimeNs + durationTimeNs, false);
- tracker.flushIfNeeded(eventStartTimeNs + bucketSizeNs + 1);
- EXPECT_EQ(1u, buckets.size());
- EXPECT_EQ(durationTimeNs, buckets[0].mDuration);
+ tracker.flushIfNeeded(eventStartTimeNs + bucketSizeNs + 1, &buckets);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+
+ EXPECT_EQ(1u, buckets[eventKey].size());
+ EXPECT_EQ(durationTimeNs, buckets[eventKey][0].mDuration);
}
TEST(OringDurationTrackerTest, TestDurationNested) {
@@ -69,14 +72,14 @@ TEST(OringDurationTrackerTest, TestDurationNested) {
ConditionKey key1;
key1["APP_BACKGROUND"] = "1:maps|";
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t eventStartTimeNs = bucketStartTimeNs + 1;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- OringDurationTracker tracker(kConfigKey, "metric", "event", wizard, 1, true, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, true, bucketStartTimeNs,
+ bucketSizeNs, {});
tracker.noteStart("2:maps", true, eventStartTimeNs, key1);
tracker.noteStart("2:maps", true, eventStartTimeNs + 10, key1); // overlapping wl
@@ -84,9 +87,10 @@ TEST(OringDurationTrackerTest, TestDurationNested) {
tracker.noteStop("2:maps", eventStartTimeNs + 2000, false);
tracker.noteStop("2:maps", eventStartTimeNs + 2003, false);
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1);
- EXPECT_EQ(1u, buckets.size());
- EXPECT_EQ(2003ULL, buckets[0].mDuration);
+ tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(1u, buckets[eventKey].size());
+ EXPECT_EQ(2003ULL, buckets[eventKey][0].mDuration);
}
TEST(OringDurationTrackerTest, TestStopAll) {
@@ -95,23 +99,24 @@ TEST(OringDurationTrackerTest, TestStopAll) {
ConditionKey key1;
key1["APP_BACKGROUND"] = "1:maps|";
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t eventStartTimeNs = bucketStartTimeNs + 1;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- OringDurationTracker tracker(kConfigKey, "metric", "event", wizard, 1, true, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, true, bucketStartTimeNs,
+ bucketSizeNs, {});
tracker.noteStart("2:maps", true, eventStartTimeNs, key1);
tracker.noteStart("3:maps", true, eventStartTimeNs + 10, key1); // overlapping wl
tracker.noteStopAll(eventStartTimeNs + 2003);
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1);
- EXPECT_EQ(1u, buckets.size());
- EXPECT_EQ(2003ULL, buckets[0].mDuration);
+ tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(1u, buckets[eventKey].size());
+ EXPECT_EQ(2003ULL, buckets[eventKey][0].mDuration);
}
TEST(OringDurationTrackerTest, TestCrossBucketBoundary) {
@@ -120,32 +125,33 @@ TEST(OringDurationTrackerTest, TestCrossBucketBoundary) {
ConditionKey key1;
key1["APP_BACKGROUND"] = "1:maps|";
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t eventStartTimeNs = bucketStartTimeNs + 1;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
uint64_t durationTimeNs = 2 * 1000;
- OringDurationTracker tracker(kConfigKey, "metric", "event", wizard, 1, true, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, true, bucketStartTimeNs,
+ bucketSizeNs, {});
tracker.noteStart("2:maps", true, eventStartTimeNs, key1);
EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
- tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs);
+ tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs, &buckets);
tracker.noteStart("2:maps", true, eventStartTimeNs + 2 * bucketSizeNs, key1);
EXPECT_EQ((long long)(bucketStartTimeNs + 2 * bucketSizeNs), tracker.mLastStartTime);
- EXPECT_EQ(2u, buckets.size());
- EXPECT_EQ(bucketSizeNs - 1, buckets[0].mDuration);
- EXPECT_EQ(bucketSizeNs, buckets[1].mDuration);
+ EXPECT_EQ(2u, buckets[eventKey].size());
+ EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
+ EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
tracker.noteStop("2:maps", eventStartTimeNs + 2 * bucketSizeNs + 10, false);
tracker.noteStop("2:maps", eventStartTimeNs + 2 * bucketSizeNs + 12, false);
- tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 12);
- EXPECT_EQ(2u, buckets.size());
- EXPECT_EQ(bucketSizeNs - 1, buckets[0].mDuration);
- EXPECT_EQ(bucketSizeNs, buckets[1].mDuration);
+ tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 12, &buckets);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(2u, buckets[eventKey].size());
+ EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
+ EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
}
TEST(OringDurationTrackerTest, TestDurationConditionChange) {
@@ -157,15 +163,15 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange) {
EXPECT_CALL(*wizard, query(_, key1)) // #4
.WillOnce(Return(ConditionState::kFalse));
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t eventStartTimeNs = bucketStartTimeNs + 1;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
uint64_t durationTimeNs = 2 * 1000;
- OringDurationTracker tracker(kConfigKey, "metric", "event", wizard, 1, false, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, false,
+ bucketStartTimeNs, bucketSizeNs, {});
tracker.noteStart("2:maps", true, eventStartTimeNs, key1);
@@ -173,9 +179,10 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange) {
tracker.noteStop("2:maps", eventStartTimeNs + durationTimeNs, false);
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1);
- EXPECT_EQ(1u, buckets.size());
- EXPECT_EQ(5ULL, buckets[0].mDuration);
+ tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(1u, buckets[eventKey].size());
+ EXPECT_EQ(5ULL, buckets[eventKey][0].mDuration);
}
TEST(OringDurationTrackerTest, TestDurationConditionChange2) {
@@ -189,15 +196,15 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange2) {
.WillOnce(Return(ConditionState::kFalse))
.WillOnce(Return(ConditionState::kTrue));
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t eventStartTimeNs = bucketStartTimeNs + 1;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
uint64_t durationTimeNs = 2 * 1000;
- OringDurationTracker tracker(kConfigKey, "metric", "event", wizard, 1, false, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, false,
+ bucketStartTimeNs, bucketSizeNs, {});
tracker.noteStart("2:maps", true, eventStartTimeNs, key1);
// condition to false; record duration 5n
@@ -207,9 +214,10 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange2) {
// 2nd duration: 1000ns
tracker.noteStop("2:maps", eventStartTimeNs + durationTimeNs, false);
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1);
- EXPECT_EQ(1u, buckets.size());
- EXPECT_EQ(1005ULL, buckets[0].mDuration);
+ tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(1u, buckets[eventKey].size());
+ EXPECT_EQ(1005ULL, buckets[eventKey][0].mDuration);
}
TEST(OringDurationTrackerTest, TestDurationConditionChangeNested) {
@@ -221,14 +229,14 @@ TEST(OringDurationTrackerTest, TestDurationConditionChangeNested) {
EXPECT_CALL(*wizard, query(_, key1)) // #4
.WillOnce(Return(ConditionState::kFalse));
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
uint64_t bucketStartTimeNs = 10000000000;
uint64_t eventStartTimeNs = bucketStartTimeNs + 1;
uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- OringDurationTracker tracker(kConfigKey, "metric", "event", wizard, 1, true, bucketStartTimeNs,
- bucketSizeNs, {}, buckets);
+ OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, true, bucketStartTimeNs,
+ bucketSizeNs, {});
tracker.noteStart("2:maps", true, eventStartTimeNs, key1);
tracker.noteStart("2:maps", true, eventStartTimeNs + 2, key1);
@@ -239,9 +247,10 @@ TEST(OringDurationTrackerTest, TestDurationConditionChangeNested) {
tracker.noteStop("2:maps", eventStartTimeNs + 2003, false);
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1);
- EXPECT_EQ(1u, buckets.size());
- EXPECT_EQ(15ULL, buckets[0].mDuration);
+ tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(1u, buckets[eventKey].size());
+ EXPECT_EQ(15ULL, buckets[eventKey][0].mDuration);
}
TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) {
@@ -252,7 +261,7 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) {
alert.set_number_of_buckets(2);
alert.set_refractory_period_secs(1);
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey key1;
key1["APP_BACKGROUND"] = "1:maps|";
@@ -261,8 +270,8 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) {
uint64_t bucketSizeNs = 30 * NS_PER_SEC;
sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert);
- OringDurationTracker tracker(kConfigKey, "metric", "event", wizard, 1, true, bucketStartTimeNs,
- bucketSizeNs, {anomalyTracker}, buckets);
+ OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, true, bucketStartTimeNs,
+ bucketSizeNs, {anomalyTracker});
// Nothing in the past bucket.
tracker.noteStart("", true, eventStartTimeNs, key1);
@@ -270,7 +279,7 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) {
tracker.predictAnomalyTimestampNs(*anomalyTracker, eventStartTimeNs));
tracker.noteStop("", eventStartTimeNs + 3, false);
- EXPECT_EQ(0u, buckets.size());
+ EXPECT_EQ(0u, buckets[eventKey].size());
uint64_t event1StartTimeNs = eventStartTimeNs + 10;
tracker.noteStart("1", true, event1StartTimeNs, key1);
@@ -279,11 +288,13 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) {
tracker.predictAnomalyTimestampNs(*anomalyTracker, event1StartTimeNs));
uint64_t event1StopTimeNs = eventStartTimeNs + bucketSizeNs + 10;
- tracker.flushIfNeeded(event1StopTimeNs);
+ tracker.flushIfNeeded(event1StopTimeNs, &buckets);
tracker.noteStop("1", event1StopTimeNs, false);
- EXPECT_EQ(1u, buckets.size());
+
+ EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
+ EXPECT_EQ(1u, buckets[eventKey].size());
EXPECT_EQ(3ULL + bucketStartTimeNs + bucketSizeNs - eventStartTimeNs - 10,
- buckets[0].mDuration);
+ buckets[eventKey][0].mDuration);
const int64_t bucket0Duration = 3ULL + bucketStartTimeNs + bucketSizeNs - eventStartTimeNs - 10;
const int64_t bucket1Duration = eventStartTimeNs + 10 - bucketStartTimeNs;
@@ -312,7 +323,7 @@ TEST(OringDurationTrackerTest, TestAnomalyDetection) {
alert.set_number_of_buckets(2);
alert.set_refractory_period_secs(1);
- vector<DurationBucket> buckets;
+ unordered_map<HashableDimensionKey, vector<DurationBucket>> buckets;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey key1;
key1["APP_BACKGROUND"] = "1:maps|";
@@ -321,8 +332,8 @@ TEST(OringDurationTrackerTest, TestAnomalyDetection) {
uint64_t bucketSizeNs = 30 * NS_PER_SEC;
sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert);
- OringDurationTracker tracker(kConfigKey, "metric", "event", wizard, 1, true /*nesting*/,
- bucketStartTimeNs, bucketSizeNs, {anomalyTracker}, buckets);
+ OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, true /*nesting*/,
+ bucketStartTimeNs, bucketSizeNs, {anomalyTracker});
tracker.noteStart("", true, eventStartTimeNs, key1);
tracker.noteStop("", eventStartTimeNs + 10, false);
@@ -336,7 +347,7 @@ TEST(OringDurationTrackerTest, TestAnomalyDetection) {
EXPECT_EQ(1u, anomalyTracker->mAlarms.size());
EXPECT_EQ((long long)(51ULL * NS_PER_SEC),
(long long)(anomalyTracker->mAlarms.begin()->second->timestampSec * NS_PER_SEC));
- tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 25);
+ tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 25, &buckets);
tracker.noteStop("", eventStartTimeNs + 2 * bucketSizeNs + 25, false);
EXPECT_EQ(anomalyTracker->getSumOverPastBuckets("event"), (long long)(bucketSizeNs));
EXPECT_EQ((long long)(eventStartTimeNs + 2 * bucketSizeNs + 25),