summaryrefslogtreecommitdiff
path: root/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp')
-rw-r--r--cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp664
1 files changed, 357 insertions, 307 deletions
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index b9553a8fded8..5997bedcdf2d 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -12,19 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "src/matchers/SimpleLogMatchingTracker.h"
#include "src/metrics/GaugeMetricProducer.h"
-#include "src/stats_log_util.h"
-#include "logd/LogEvent.h"
-#include "metrics_test_helper.h"
-#include "tests/statsd_test_util.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <math.h>
#include <stdio.h>
+
#include <vector>
+#include "logd/LogEvent.h"
+#include "metrics_test_helper.h"
+#include "src/matchers/SimpleLogMatchingTracker.h"
+#include "src/metrics/MetricProducer.h"
+#include "src/stats_log_util.h"
+#include "stats_event.h"
+#include "tests/statsd_test_util.h"
+
using namespace testing;
using android::sp;
using std::set;
@@ -38,6 +42,8 @@ namespace android {
namespace os {
namespace statsd {
+namespace {
+
const ConfigKey kConfigKey(0, 12345);
const int tagId = 1;
const int64_t metricId = 123;
@@ -48,7 +54,30 @@ const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000L
const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
-const int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
+const int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
+
+shared_ptr<LogEvent> makeLogEvent(int32_t atomId, int64_t timestampNs, int32_t value1, string str1,
+ int32_t value2) {
+ AStatsEvent* statsEvent = AStatsEvent_obtain();
+ AStatsEvent_setAtomId(statsEvent, atomId);
+ AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
+
+ AStatsEvent_writeInt32(statsEvent, value1);
+ AStatsEvent_writeString(statsEvent, str1.c_str());
+ AStatsEvent_writeInt32(statsEvent, value2);
+
+ shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
+ parseStatsEventToLogEvent(statsEvent, logEvent.get());
+ return logEvent;
+}
+} // anonymous namespace
+
+// Setup for parameterized tests.
+class GaugeMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
+
+INSTANTIATE_TEST_SUITE_P(GaugeMetricProducerTest_PartialBucket,
+ GaugeMetricProducerTest_PartialBucket,
+ testing::Values(APP_UPGRADE, BOOT_COMPLETE));
/*
* Tests that the first bucket works correctly
@@ -75,13 +104,11 @@ TEST(GaugeMetricProducerTest, TestFirstBucket) {
// statsd started long ago.
// The metric starts in the middle of the bucket
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- logEventMatcherIndex, eventMatcherWizard,
- -1, -1, tagId, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2,
- pullerManager);
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+ wizard, logEventMatcherIndex, eventMatcherWizard, -1, -1,
+ tagId, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
gaugeProducer.prepareFirstBucket();
-
EXPECT_EQ(600500000000, gaugeProducer.mCurrentBucketStartTimeNs);
EXPECT_EQ(10, gaugeProducer.mCurrentBucketNum);
EXPECT_EQ(660000000005, gaugeProducer.getCurrentBucketEndTimeNs());
@@ -103,60 +130,49 @@ TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) {
UidMap uidMap;
SimpleAtomMatcher atomMatcher;
atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _))
- .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
+ EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
- event->write(3);
- event->write("some value");
- event->write(11);
- event->init();
- data->push_back(event);
+ data->push_back(makeLogEvent(tagId, eventTimeNs + 10, 3, "some value", 11));
return true;
}));
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- logEventMatcherIndex, eventMatcherWizard,
- tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
-
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+ wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
+ tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
gaugeProducer.prepareFirstBucket();
vector<shared_ptr<LogEvent>> allData;
allData.clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
- event->write(10);
- event->write("some value");
- event->write(11);
- event->init();
- allData.push_back(event);
+ allData.push_back(makeLogEvent(tagId, bucket2StartTimeNs + 1, 10, "some value", 11));
gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
EXPECT_EQ(INT, it->mValue.getType());
EXPECT_EQ(10, it->mValue.int_value);
it++;
EXPECT_EQ(11, it->mValue.int_value);
- EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(3, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms
- .front().mFields->begin()->mValue.int_value);
+ ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+ EXPECT_EQ(3, gaugeProducer.mPastBuckets.begin()
+ ->second.back()
+ .mGaugeAtoms.front()
+ .mFields->begin()
+ ->mValue.int_value);
allData.clear();
- std::shared_ptr<LogEvent> event2 = std::make_shared<LogEvent>(tagId, bucket3StartTimeNs + 10);
- event2->write(24);
- event2->write("some value");
- event2->write(25);
- event2->init();
- allData.push_back(event2);
+ allData.push_back(makeLogEvent(tagId, bucket3StartTimeNs + 10, 24, "some value", 25));
gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
EXPECT_EQ(INT, it->mValue.getType());
EXPECT_EQ(24, it->mValue.int_value);
@@ -164,8 +180,8 @@ TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) {
EXPECT_EQ(INT, it->mValue.getType());
EXPECT_EQ(25, it->mValue.int_value);
// One dimension.
- EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
+ ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+ ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
EXPECT_EQ(INT, it->mValue.getType());
EXPECT_EQ(10L, it->mValue.int_value);
@@ -174,10 +190,10 @@ TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) {
EXPECT_EQ(11L, it->mValue.int_value);
gaugeProducer.flushIfNeededLocked(bucket4StartTimeNs);
- EXPECT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
+ ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
// One dimension.
- EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(3UL, gaugeProducer.mPastBuckets.begin()->second.size());
+ ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+ ASSERT_EQ(3UL, gaugeProducer.mPastBuckets.begin()->second.size());
it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
EXPECT_EQ(INT, it->mValue.getType());
EXPECT_EQ(24L, it->mValue.int_value);
@@ -186,7 +202,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) {
EXPECT_EQ(25L, it->mValue.int_value);
}
-TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade) {
+TEST_P(GaugeMetricProducerTest_PartialBucket, TestPushedEvents) {
sp<AlarmMonitor> alarmMonitor;
GaugeMetric metric;
metric.set_id(metricId);
@@ -204,11 +220,12 @@ TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade) {
UidMap uidMap;
SimpleAtomMatcher atomMatcher;
atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- logEventMatcherIndex, eventMatcherWizard,
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+ wizard, logEventMatcherIndex, eventMatcherWizard,
-1 /* -1 means no pulling */, -1, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
gaugeProducer.prepareFirstBucket();
@@ -216,58 +233,64 @@ TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade) {
sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
EXPECT_TRUE(anomalyTracker != nullptr);
- shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
- event1->write(1);
- event1->write(10);
- event1->init();
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
EXPECT_EQ(1UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY));
- gaugeProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
+ switch (GetParam()) {
+ case APP_UPGRADE:
+ gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
+ break;
+ case BOOT_COMPLETE:
+ gaugeProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
+ break;
+ }
EXPECT_EQ(0UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY));
- EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ EXPECT_EQ(bucketStartTimeNs,
+ gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
+ EXPECT_EQ(partialBucketSplitTimeNs,
+ gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(eventUpgradeTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
// Partial buckets are not sent to anomaly tracker.
EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
// Create an event in the same partial bucket.
- shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 59 * NS_PER_SEC);
- event2->write(1);
- event2->write(10);
- event2->init();
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 1, 10);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ((int64_t)eventUpgradeTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
+ ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ EXPECT_EQ(bucketStartTimeNs,
+ gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
+ EXPECT_EQ(partialBucketSplitTimeNs,
+ gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
+ EXPECT_EQ((int64_t)partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
// Partial buckets are not sent to anomaly tracker.
EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
// Next event should trigger creation of new bucket and send previous full bucket to anomaly
// tracker.
- shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 65 * NS_PER_SEC);
- event3->write(1);
- event3->write(10);
- event3->init();
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
+ LogEvent event3(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event3, tagId, bucketStartTimeNs + 65 * NS_PER_SEC, 1, 10);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
EXPECT_EQ(1L, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ ASSERT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
EXPECT_EQ((int64_t)bucketStartTimeNs + bucketSizeNs, gaugeProducer.mCurrentBucketStartTimeNs);
EXPECT_EQ(1, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
// Next event should trigger creation of new bucket.
- shared_ptr<LogEvent> event4 =
- make_shared<LogEvent>(tagId, bucketStartTimeNs + 125 * NS_PER_SEC);
- event4->write(1);
- event4->write(10);
- event4->init();
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
+ LogEvent event4(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event4, tagId, bucketStartTimeNs + 125 * NS_PER_SEC, 1, 10);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
EXPECT_EQ(2L, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(3UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ ASSERT_EQ(3UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
}
-TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) {
+TEST_P(GaugeMetricProducerTest_PartialBucket, TestPulled) {
GaugeMetric metric;
metric.set_id(metricId);
metric.set_bucket(ONE_MINUTE);
@@ -284,59 +307,59 @@ TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) {
sp<EventMatcherWizard> eventMatcherWizard =
new EventMatcherWizard({new SimpleLogMatchingTracker(
atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
.WillOnce(Return(false))
- .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
+ EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, eventUpgradeTimeNs);
- event->write("some value");
- event->write(2);
- event->init();
- data->push_back(event);
+ data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 2));
return true;
}));
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
- bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+ wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
+ tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
gaugeProducer.prepareFirstBucket();
vector<shared_ptr<LogEvent>> allData;
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
- event->write("some value");
- event->write(1);
- event->init();
- allData.push_back(event);
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
->mValue.int_value);
- gaugeProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
- EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ switch (GetParam()) {
+ case APP_UPGRADE:
+ gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
+ break;
+ case BOOT_COMPLETE:
+ gaugeProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
+ break;
+ }
+ ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ EXPECT_EQ(bucketStartTimeNs,
+ gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
+ EXPECT_EQ(partialBucketSplitTimeNs,
+ gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ((int64_t)eventUpgradeTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ EXPECT_EQ(partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(2, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
->mValue.int_value);
allData.clear();
- event = make_shared<LogEvent>(tagId, bucketStartTimeNs + bucketSizeNs + 1);
- event->write("some value");
- event->write(3);
- event->init();
- allData.push_back(event);
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + bucketSizeNs + 1, 3));
gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ ASSERT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(3, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
@@ -358,38 +381,35 @@ TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
UidMap uidMap;
SimpleAtomMatcher atomMatcher;
atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false));
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- logEventMatcherIndex, eventMatcherWizard,
- tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ .WillOnce(Return(false));
+
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+ wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
+ tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
gaugeProducer.prepareFirstBucket();
vector<shared_ptr<LogEvent>> allData;
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
- event->write("some value");
- event->write(1);
- event->init();
- allData.push_back(event);
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
->mValue.int_value);
- gaugeProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
- EXPECT_EQ(0UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
+ ASSERT_EQ(0UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
EXPECT_EQ(bucketStartTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
@@ -411,51 +431,48 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) {
UidMap uidMap;
SimpleAtomMatcher atomMatcher;
atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
+ int64_t conditionChangeNs = bucketStartTimeNs + 8;
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _))
- .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, conditionChangeNs, _, _))
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
- event->write("some value");
- event->write(100);
- event->init();
- data->push_back(event);
+ data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs + 10, 100));
return true;
}));
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard,
- logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
- bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
+ {ConditionState::kUnknown}, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, -1, tagId, bucketStartTimeNs,
+ bucketStartTimeNs, pullerManager);
gaugeProducer.prepareFirstBucket();
- gaugeProducer.onConditionChanged(true, bucketStartTimeNs + 8);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ gaugeProducer.onConditionChanged(true, conditionChangeNs);
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(100, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
->mValue.int_value);
- EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
+ ASSERT_EQ(0UL, gaugeProducer.mPastBuckets.size());
vector<shared_ptr<LogEvent>> allData;
allData.clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
- event->write("some value");
- event->write(110);
- event->init();
- allData.push_back(event);
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(110, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
->mValue.int_value);
- EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+ ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
EXPECT_EQ(100, gaugeProducer.mPastBuckets.begin()
->second.back()
.mGaugeAtoms.front()
@@ -464,8 +481,8 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) {
gaugeProducer.onConditionChanged(false, bucket2StartTimeNs + 10);
gaugeProducer.flushIfNeededLocked(bucket3StartTimeNs + 10);
- EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
+ ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+ ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
EXPECT_EQ(110L, gaugeProducer.mPastBuckets.begin()
->second.back()
.mGaugeAtoms.front()
@@ -485,75 +502,61 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) {
dim->set_field(tagId);
dim->add_child()->set_field(1);
- dim = metric.mutable_dimensions_in_condition();
- dim->set_field(conditionTag);
- dim->add_child()->set_field(1);
-
UidMap uidMap;
SimpleAtomMatcher atomMatcher;
atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*wizard, query(_, _, _, _, _, _))
+ EXPECT_CALL(*wizard, query(_, _, _))
.WillRepeatedly(
Invoke([](const int conditionIndex, const ConditionKey& conditionParameters,
- const vector<Matcher>& dimensionFields, const bool isSubsetDim,
- const bool isPartialLink,
- std::unordered_set<HashableDimensionKey>* dimensionKeySet) {
- dimensionKeySet->clear();
+ const bool isPartialLink) {
int pos[] = {1, 0, 0};
Field f(conditionTag, pos, 0);
HashableDimensionKey key;
key.mutableValues()->emplace_back(f, Value((int32_t)1000000));
- dimensionKeySet->insert(key);
return ConditionState::kTrue;
}));
+ int64_t sliceConditionChangeNs = bucketStartTimeNs + 8;
+
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _))
- .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, sliceConditionChangeNs, _, _))
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
- event->write(1000);
- event->write(100);
- event->init();
- data->push_back(event);
+ data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs + 10, 1000, 100));
return true;
}));
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard,
- logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
- bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
+ {ConditionState::kUnknown}, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, -1, tagId, bucketStartTimeNs,
+ bucketStartTimeNs, pullerManager);
gaugeProducer.prepareFirstBucket();
- gaugeProducer.onSlicedConditionMayChange(true, bucketStartTimeNs + 8);
+ gaugeProducer.onSlicedConditionMayChange(true, sliceConditionChangeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
const auto& key = gaugeProducer.mCurrentSlicedBucket->begin()->first;
- EXPECT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size());
+ ASSERT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size());
EXPECT_EQ(1000, key.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(1UL, key.getDimensionKeyInCondition().getValues().size());
- EXPECT_EQ(1000000, key.getDimensionKeyInCondition().getValues()[0].mValue.int_value);
-
- EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
+ ASSERT_EQ(0UL, gaugeProducer.mPastBuckets.size());
vector<shared_ptr<LogEvent>> allData;
allData.clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
- event->write(1000);
- event->write(110);
- event->init();
- allData.push_back(event);
+ allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1000, 110));
gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
}
TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
@@ -561,9 +564,10 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false));
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ .WillOnce(Return(false));
GaugeMetric metric;
metric.set_id(metricId);
@@ -576,13 +580,13 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
UidMap uidMap;
SimpleAtomMatcher atomMatcher;
atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- logEventMatcherIndex, eventMatcherWizard,
- tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+ wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
+ tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
gaugeProducer.prepareFirstBucket();
Alert alert;
@@ -595,13 +599,11 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
int tagId = 1;
- std::shared_ptr<LogEvent> event1 = std::make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
- event1->write("some value");
- event1->write(13);
- event1->init();
-
- gaugeProducer.onDataPulled({event1}, /** succeed */ true, bucketStartTimeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 13));
+ gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(13L, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
@@ -609,13 +611,12 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
std::shared_ptr<LogEvent> event2 =
- std::make_shared<LogEvent>(tagId, bucketStartTimeNs + bucketSizeNs + 20);
- event2->write("some value");
- event2->write(15);
- event2->init();
+ CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + bucketSizeNs + 20, 15);
- gaugeProducer.onDataPulled({event2}, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ allData.clear();
+ allData.push_back(event2);
+ gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(15L, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
@@ -623,14 +624,11 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC) + refPeriodSec);
- std::shared_ptr<LogEvent> event3 =
- std::make_shared<LogEvent>(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 10);
- event3->write("some value");
- event3->write(26);
- event3->init();
-
- gaugeProducer.onDataPulled({event3}, /** succeed */ true, bucket2StartTimeNs + 2 * bucketSizeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ allData.clear();
+ allData.push_back(
+ CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 10, 26));
+ gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 2 * bucketSizeNs);
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(26L, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
.mFields->begin()
@@ -638,13 +636,11 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
- // The event4 does not have the gauge field. Thus the current bucket value is 0.
- std::shared_ptr<LogEvent> event4 =
- std::make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10);
- event4->write("some value");
- event4->init();
- gaugeProducer.onDataPulled({event4}, /** succeed */ true, bucketStartTimeNs + 3 * bucketSizeNs);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ // This event does not have the gauge field. Thus the current bucket value is 0.
+ allData.clear();
+ allData.push_back(CreateNoValuesLogEvent(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10));
+ gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 3 * bucketSizeNs);
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_TRUE(gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->empty());
}
@@ -664,51 +660,49 @@ TEST(GaugeMetricProducerTest, TestPullOnTrigger) {
UidMap uidMap;
SimpleAtomMatcher atomMatcher;
atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, _))
- .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
+ EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
- event->write(4);
- event->init();
- data->push_back(event);
+ data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 4));
return true;
}))
- .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
+ EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
- event->write(5);
- event->init();
- data->push_back(event);
+ data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 5));
return true;
}))
.WillOnce(Return(true));
int triggerId = 5;
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- logEventMatcherIndex, eventMatcherWizard,
- tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+ wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
+ triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
pullerManager);
gaugeProducer.prepareFirstBucket();
- vector<shared_ptr<LogEvent>> allData;
+ ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
- LogEvent trigger(triggerId, bucketStartTimeNs + 10);
- trigger.init();
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- trigger.setElapsedTimestampNs(bucketStartTimeNs + 20);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
- EXPECT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- trigger.setElapsedTimestampNs(bucket2StartTimeNs + 1);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
-
- EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.size());
+ LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
+ CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 10);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
+ triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 20);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
+ ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
+ triggerEvent.setElapsedTimestampNs(bucket2StartTimeNs + 1);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
+
+ ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+ ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.size());
EXPECT_EQ(4, gaugeProducer.mPastBuckets.begin()
->second.back()
.mGaugeAtoms[0]
@@ -738,75 +732,131 @@ TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput) {
UidMap uidMap;
SimpleAtomMatcher atomMatcher;
atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, _))
- .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
+ EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3);
- event->write(3);
- event->write(4);
- event->init();
- data->push_back(event);
+ data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 3, 4));
return true;
}))
- .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
+ EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
- event->write(4);
- event->write(5);
- event->init();
- data->push_back(event);
+ data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 5));
return true;
}))
- .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
+ EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
- event->write(4);
- event->write(6);
- event->init();
- data->push_back(event);
+ data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 6));
return true;
}))
.WillOnce(Return(true));
int triggerId = 5;
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- logEventMatcherIndex, eventMatcherWizard,
- tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+ wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
+ triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
pullerManager);
gaugeProducer.prepareFirstBucket();
- vector<shared_ptr<LogEvent>> allData;
-
- LogEvent trigger(triggerId, bucketStartTimeNs + 3);
- trigger.init();
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- trigger.setElapsedTimestampNs(bucketStartTimeNs + 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
- EXPECT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- trigger.setElapsedTimestampNs(bucketStartTimeNs + 20);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
- EXPECT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- trigger.setElapsedTimestampNs(bucket2StartTimeNs + 1);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
-
- EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.size());
+ LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
+ CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 3);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 10);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
+ ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->size());
+ ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
+ triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 20);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
+ ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
+ triggerEvent.setElapsedTimestampNs(bucket2StartTimeNs + 1);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
+
+ ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.size());
auto bucketIt = gaugeProducer.mPastBuckets.begin();
- EXPECT_EQ(1UL, bucketIt->second.back().mGaugeAtoms.size());
+ ASSERT_EQ(1UL, bucketIt->second.back().mGaugeAtoms.size());
EXPECT_EQ(3, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
EXPECT_EQ(4, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
bucketIt++;
- EXPECT_EQ(2UL, bucketIt->second.back().mGaugeAtoms.size());
+ ASSERT_EQ(2UL, bucketIt->second.back().mGaugeAtoms.size());
EXPECT_EQ(4, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
EXPECT_EQ(5, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
EXPECT_EQ(6, bucketIt->second.back().mGaugeAtoms[1].mFields->begin()->mValue.int_value);
}
+/*
+ * Test that BUCKET_TOO_SMALL dump reason is logged when a flushed bucket size
+ * is smaller than the "min_bucket_size_nanos" specified in the metric config.
+ */
+TEST(GaugeMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
+ GaugeMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(FIVE_MINUTES);
+ metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
+ metric.set_min_bucket_size_nanos(10000000000); // 10 seconds
+
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 3, _, _))
+ // Bucket start.
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 10));
+ return true;
+ }));
+
+ int triggerId = 5;
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+ wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
+ triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
+ gaugeProducer.prepareFirstBucket();
+
+ LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
+ CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 3);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
+
+ // Check dump report.
+ ProtoOutputStream output;
+ std::set<string> strSet;
+ gaugeProducer.onDumpReport(bucketStartTimeNs + 9000000, true /* include recent buckets */, true,
+ FAST /* dump_latency */, &strSet, &output);
+
+ StatsLogReport report = outputStreamToProto(&output);
+ EXPECT_TRUE(report.has_gauge_metrics());
+ ASSERT_EQ(0, report.gauge_metrics().data_size());
+ ASSERT_EQ(1, report.gauge_metrics().skipped_size());
+
+ EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
+ report.gauge_metrics().skipped(0).start_bucket_elapsed_millis());
+ EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000),
+ report.gauge_metrics().skipped(0).end_bucket_elapsed_millis());
+ ASSERT_EQ(1, report.gauge_metrics().skipped(0).drop_event_size());
+
+ auto dropEvent = report.gauge_metrics().skipped(0).drop_event(0);
+ EXPECT_EQ(BucketDropReason::BUCKET_TOO_SMALL, dropEvent.drop_reason());
+ EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000), dropEvent.drop_time_millis());
+}
+
} // namespace statsd
} // namespace os
} // namespace android