Merge "(Part 1) Use new socket schema with statsd tests" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a8c6c8b1f6
@@ -328,4 +328,3 @@ void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::v
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
} // namespace android
|
||||
|
||||
|
||||
@@ -137,7 +137,9 @@ TEST(SimpleConditionTrackerTest, TestNonSlicedCondition) {
|
||||
simplePredicate, trackerNameIndexMap);
|
||||
EXPECT_FALSE(conditionTracker.isSliced());
|
||||
|
||||
LogEvent event(1 /*tagId*/, 0 /*timestamp*/);
|
||||
// This event is not accessed in this test besides dimensions which is why this is okay.
|
||||
// This is technically an invalid LogEvent because we do not call parseBuffer.
|
||||
LogEvent event(/*uid=*/0, /*pid=*/0);
|
||||
|
||||
vector<MatchingState> matcherState;
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
@@ -222,7 +224,9 @@ TEST(SimpleConditionTrackerTest, TestNonSlicedConditionNestCounting) {
|
||||
trackerNameIndexMap);
|
||||
EXPECT_FALSE(conditionTracker.isSliced());
|
||||
|
||||
LogEvent event(1 /*tagId*/, 0 /*timestamp*/);
|
||||
// This event is not accessed in this test besides dimensions which is why this is okay.
|
||||
// This is technically an invalid LogEvent because we do not call parseBuffer.
|
||||
LogEvent event(/*uid=*/0, /*pid=*/0);
|
||||
|
||||
// one matched start
|
||||
vector<MatchingState> matcherState;
|
||||
@@ -296,8 +300,8 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
|
||||
|
||||
std::vector<int> uids = {111, 222, 333};
|
||||
|
||||
LogEvent event(/*uid=*/-1, /*pid=*/-1);
|
||||
makeWakeLockEvent(&event, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/1);
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/1);
|
||||
|
||||
// one matched start
|
||||
vector<MatchingState> matcherState;
|
||||
@@ -308,7 +312,7 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
|
||||
vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
|
||||
vector<bool> changedCache(1, false);
|
||||
|
||||
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
|
||||
conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
|
||||
changedCache);
|
||||
|
||||
if (position == Position::FIRST || position == Position::LAST) {
|
||||
@@ -333,7 +337,7 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
|
||||
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
|
||||
|
||||
// another wake lock acquired by this uid
|
||||
LogEvent event2(/*uid=*/-1, /*pid=*/-1);
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids, "wl2", /*acquire=*/1);
|
||||
matcherState.clear();
|
||||
matcherState.push_back(MatchingState::kMatched);
|
||||
@@ -353,7 +357,7 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
|
||||
|
||||
|
||||
// wake lock 1 release
|
||||
LogEvent event3(/*uid=*/-1, /*pid=*/-1);
|
||||
LogEvent event3(/*uid=*/0, /*pid=*/0);
|
||||
makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/0);
|
||||
matcherState.clear();
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
@@ -372,7 +376,7 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
|
||||
EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
|
||||
EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
|
||||
|
||||
LogEvent event4(/*uid=*/-1, /*pid=*/-1);
|
||||
LogEvent event4(/*uid=*/0, /*pid=*/0);
|
||||
makeWakeLockEvent(&event4, /*atomId=*/1, /*timestamp=*/0, uids, "wl2", /*acquire=*/0);
|
||||
matcherState.clear();
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
@@ -399,246 +403,235 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
|
||||
|
||||
}
|
||||
|
||||
//TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) {
|
||||
// std::vector<sp<ConditionTracker>> allConditions;
|
||||
//
|
||||
// SimplePredicate simplePredicate = getWakeLockHeldCondition(
|
||||
// true /*nesting*/, true /*default to false*/, false /*slice output by uid*/,
|
||||
// Position::ANY /* position */);
|
||||
// string conditionName = "WL_HELD";
|
||||
//
|
||||
// unordered_map<int64_t, int> trackerNameIndexMap;
|
||||
// trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
|
||||
// trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
|
||||
// trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
|
||||
//
|
||||
// SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
|
||||
// 0 /*condition tracker index*/, simplePredicate,
|
||||
// trackerNameIndexMap);
|
||||
//
|
||||
// EXPECT_FALSE(conditionTracker.isSliced());
|
||||
//
|
||||
// std::vector<int> uid_list1 = {111, 1111, 11111};
|
||||
// string uid1_wl1 = "wl1_1";
|
||||
// std::vector<int> uid_list2 = {222, 2222, 22222};
|
||||
// string uid2_wl1 = "wl2_1";
|
||||
//
|
||||
// LogEvent event(1 /*tagId*/, 0 /*timestamp*/);
|
||||
// makeWakeLockEvent(&event, uid_list1, uid1_wl1, 1);
|
||||
//
|
||||
// // one matched start for uid1
|
||||
// vector<MatchingState> matcherState;
|
||||
// matcherState.push_back(MatchingState::kMatched);
|
||||
// matcherState.push_back(MatchingState::kNotMatched);
|
||||
// matcherState.push_back(MatchingState::kNotMatched);
|
||||
// vector<sp<ConditionTracker>> allPredicates;
|
||||
// vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
|
||||
// vector<bool> changedCache(1, false);
|
||||
//
|
||||
// conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
|
||||
// changedCache);
|
||||
//
|
||||
// EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
|
||||
// EXPECT_TRUE(changedCache[0]);
|
||||
//
|
||||
// // Now test query
|
||||
// ConditionKey queryKey;
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
//
|
||||
// conditionTracker.isConditionMet(queryKey, allPredicates,
|
||||
// true,
|
||||
// conditionCache);
|
||||
// EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
|
||||
//
|
||||
// // another wake lock acquired by this uid
|
||||
// LogEvent event2(1 /*tagId*/, 0 /*timestamp*/);
|
||||
// makeWakeLockEvent(&event2, uid_list2, uid2_wl1, 1);
|
||||
// matcherState.clear();
|
||||
// matcherState.push_back(MatchingState::kMatched);
|
||||
// matcherState.push_back(MatchingState::kNotMatched);
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// changedCache[0] = false;
|
||||
// conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
|
||||
// changedCache);
|
||||
// EXPECT_FALSE(changedCache[0]);
|
||||
//
|
||||
// // uid1 wake lock 1 release
|
||||
// LogEvent event3(1 /*tagId*/, 0 /*timestamp*/);
|
||||
// makeWakeLockEvent(&event3, uid_list1, uid1_wl1, 0); // now release it.
|
||||
// matcherState.clear();
|
||||
// matcherState.push_back(MatchingState::kNotMatched);
|
||||
// matcherState.push_back(MatchingState::kMatched);
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// changedCache[0] = false;
|
||||
// conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
|
||||
// changedCache);
|
||||
// // nothing changes, because uid2 is still holding wl.
|
||||
// EXPECT_FALSE(changedCache[0]);
|
||||
//
|
||||
// LogEvent event4(1 /*tagId*/, 0 /*timestamp*/);
|
||||
// makeWakeLockEvent(&event4, uid_list2, uid2_wl1, 0); // now release it.
|
||||
// matcherState.clear();
|
||||
// matcherState.push_back(MatchingState::kNotMatched);
|
||||
// matcherState.push_back(MatchingState::kMatched);
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// changedCache[0] = false;
|
||||
// conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
|
||||
// changedCache);
|
||||
// EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
|
||||
// EXPECT_TRUE(changedCache[0]);
|
||||
//
|
||||
// // query again
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// conditionTracker.isConditionMet(queryKey, allPredicates,
|
||||
// true,
|
||||
// conditionCache);
|
||||
// EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
|
||||
//}
|
||||
//
|
||||
//TEST(SimpleConditionTrackerTest, TestStopAll) {
|
||||
// std::vector<sp<ConditionTracker>> allConditions;
|
||||
// for (Position position :
|
||||
// { Position::FIRST, Position::LAST }) {
|
||||
// SimplePredicate simplePredicate = getWakeLockHeldCondition(
|
||||
// true /*nesting*/, true /*default to false*/, true /*output slice by uid*/,
|
||||
// position);
|
||||
// string conditionName = "WL_HELD_BY_UID3";
|
||||
//
|
||||
// unordered_map<int64_t, int> trackerNameIndexMap;
|
||||
// trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
|
||||
// trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
|
||||
// trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
|
||||
//
|
||||
// SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
|
||||
// 0 /*condition tracker index*/, simplePredicate,
|
||||
// trackerNameIndexMap);
|
||||
//
|
||||
// std::vector<int> uid_list1 = {111, 1111, 11111};
|
||||
// std::vector<int> uid_list2 = {222, 2222, 22222};
|
||||
//
|
||||
// LogEvent event(1 /*tagId*/, 0 /*timestamp*/);
|
||||
// makeWakeLockEvent(&event, uid_list1, "wl1", 1);
|
||||
//
|
||||
// // one matched start
|
||||
// vector<MatchingState> matcherState;
|
||||
// matcherState.push_back(MatchingState::kMatched);
|
||||
// matcherState.push_back(MatchingState::kNotMatched);
|
||||
// matcherState.push_back(MatchingState::kNotMatched);
|
||||
// vector<sp<ConditionTracker>> allPredicates;
|
||||
// vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
|
||||
// vector<bool> changedCache(1, false);
|
||||
//
|
||||
// conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
|
||||
// changedCache);
|
||||
// if (position == Position::FIRST ||
|
||||
// position == Position::LAST) {
|
||||
// EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
|
||||
// } else {
|
||||
// EXPECT_EQ(uid_list1.size(), conditionTracker.mSlicedConditionState.size());
|
||||
// }
|
||||
// EXPECT_TRUE(changedCache[0]);
|
||||
// {
|
||||
// if (position == Position::FIRST ||
|
||||
// position == Position::LAST) {
|
||||
// EXPECT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
|
||||
// EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
|
||||
// } else {
|
||||
// EXPECT_EQ(uid_list1.size(), conditionTracker.getChangedToTrueDimensions(allConditions)->size());
|
||||
// EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Now test query
|
||||
// const auto queryKey = getWakeLockQueryKey(position, uid_list1, conditionName);
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
//
|
||||
// conditionTracker.isConditionMet(queryKey, allPredicates,
|
||||
// false,
|
||||
// conditionCache);
|
||||
// EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
|
||||
//
|
||||
// // another wake lock acquired by uid2
|
||||
// LogEvent event2(1 /*tagId*/, 0 /*timestamp*/);
|
||||
// makeWakeLockEvent(&event2, uid_list2, "wl2", 1);
|
||||
// matcherState.clear();
|
||||
// matcherState.push_back(MatchingState::kMatched);
|
||||
// matcherState.push_back(MatchingState::kNotMatched);
|
||||
// matcherState.push_back(MatchingState::kNotMatched);
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// changedCache[0] = false;
|
||||
// conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
|
||||
// changedCache);
|
||||
// if (position == Position::FIRST ||
|
||||
// position == Position::LAST) {
|
||||
// EXPECT_EQ(2UL, conditionTracker.mSlicedConditionState.size());
|
||||
// } else {
|
||||
// EXPECT_EQ(uid_list1.size() + uid_list2.size(),
|
||||
// conditionTracker.mSlicedConditionState.size());
|
||||
// }
|
||||
// EXPECT_TRUE(changedCache[0]);
|
||||
// {
|
||||
// if (position == Position::FIRST ||
|
||||
// position == Position::LAST) {
|
||||
// EXPECT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
|
||||
// EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
|
||||
// } else {
|
||||
// EXPECT_EQ(uid_list2.size(), conditionTracker.getChangedToTrueDimensions(allConditions)->size());
|
||||
// EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// // TEST QUERY
|
||||
// const auto queryKey2 = getWakeLockQueryKey(position, uid_list2, conditionName);
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// conditionTracker.isConditionMet(queryKey, allPredicates,
|
||||
// false,
|
||||
// conditionCache);
|
||||
//
|
||||
// EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
|
||||
//
|
||||
//
|
||||
// // stop all event
|
||||
// LogEvent event3(2 /*tagId*/, 0 /*timestamp*/);
|
||||
// matcherState.clear();
|
||||
// matcherState.push_back(MatchingState::kNotMatched);
|
||||
// matcherState.push_back(MatchingState::kNotMatched);
|
||||
// matcherState.push_back(MatchingState::kMatched);
|
||||
//
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// changedCache[0] = false;
|
||||
// conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
|
||||
// changedCache);
|
||||
// EXPECT_TRUE(changedCache[0]);
|
||||
// EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
|
||||
// {
|
||||
// if (position == Position::FIRST || position == Position::LAST) {
|
||||
// EXPECT_EQ(2UL, conditionTracker.getChangedToFalseDimensions(allConditions)->size());
|
||||
// EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
|
||||
// } else {
|
||||
// EXPECT_EQ(uid_list1.size() + uid_list2.size(),
|
||||
// conditionTracker.getChangedToFalseDimensions(allConditions)->size());
|
||||
// EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // TEST QUERY
|
||||
// const auto queryKey3 = getWakeLockQueryKey(position, uid_list1, conditionName);
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// conditionTracker.isConditionMet(queryKey, allPredicates,
|
||||
// false,
|
||||
// conditionCache);
|
||||
// EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
|
||||
//
|
||||
// // TEST QUERY
|
||||
// const auto queryKey4 = getWakeLockQueryKey(position, uid_list2, conditionName);
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// conditionTracker.isConditionMet(queryKey, allPredicates,
|
||||
// false,
|
||||
// conditionCache);
|
||||
// EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
|
||||
// }
|
||||
//}
|
||||
TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) {
|
||||
std::vector<sp<ConditionTracker>> allConditions;
|
||||
|
||||
SimplePredicate simplePredicate =
|
||||
getWakeLockHeldCondition(true /*nesting*/, true /*default to false*/,
|
||||
false /*slice output by uid*/, Position::ANY /* position */);
|
||||
string conditionName = "WL_HELD";
|
||||
|
||||
unordered_map<int64_t, int> trackerNameIndexMap;
|
||||
trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
|
||||
trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
|
||||
trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
|
||||
|
||||
SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
|
||||
0 /*condition tracker index*/, simplePredicate,
|
||||
trackerNameIndexMap);
|
||||
|
||||
EXPECT_FALSE(conditionTracker.isSliced());
|
||||
|
||||
std::vector<int> uids1 = {111, 1111, 11111};
|
||||
string uid1_wl1 = "wl1_1";
|
||||
std::vector<int> uids2 = {222, 2222, 22222};
|
||||
string uid2_wl1 = "wl2_1";
|
||||
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids1, uid1_wl1, /*acquire=*/1);
|
||||
|
||||
// one matched start for uid1
|
||||
vector<MatchingState> matcherState;
|
||||
matcherState.push_back(MatchingState::kMatched);
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
vector<sp<ConditionTracker>> allPredicates;
|
||||
vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
|
||||
vector<bool> changedCache(1, false);
|
||||
|
||||
conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
|
||||
changedCache);
|
||||
|
||||
EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
|
||||
EXPECT_TRUE(changedCache[0]);
|
||||
|
||||
// Now test query
|
||||
ConditionKey queryKey;
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
|
||||
conditionTracker.isConditionMet(queryKey, allPredicates, true, conditionCache);
|
||||
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
|
||||
|
||||
// another wake lock acquired by this uid
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids2, uid2_wl1, /*acquire=*/1);
|
||||
|
||||
matcherState.clear();
|
||||
matcherState.push_back(MatchingState::kMatched);
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
changedCache[0] = false;
|
||||
conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
|
||||
changedCache);
|
||||
EXPECT_FALSE(changedCache[0]);
|
||||
|
||||
// uid1 wake lock 1 release
|
||||
LogEvent event3(/*uid=*/0, /*pid=*/0);
|
||||
makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids1, uid1_wl1,
|
||||
/*release=*/0); // now release it.
|
||||
|
||||
matcherState.clear();
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
matcherState.push_back(MatchingState::kMatched);
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
changedCache[0] = false;
|
||||
conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
|
||||
changedCache);
|
||||
// nothing changes, because uid2 is still holding wl.
|
||||
EXPECT_FALSE(changedCache[0]);
|
||||
|
||||
LogEvent event4(/*uid=*/0, /*pid=*/0);
|
||||
makeWakeLockEvent(&event4, /*atomId=*/1, /*timestamp=*/0, uids2, uid2_wl1,
|
||||
/*acquire=*/0); // now release it.
|
||||
matcherState.clear();
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
matcherState.push_back(MatchingState::kMatched);
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
changedCache[0] = false;
|
||||
conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
|
||||
changedCache);
|
||||
EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
|
||||
EXPECT_TRUE(changedCache[0]);
|
||||
|
||||
// query again
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
conditionTracker.isConditionMet(queryKey, allPredicates, true, conditionCache);
|
||||
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
|
||||
}
|
||||
|
||||
TEST(SimpleConditionTrackerTest, TestStopAll) {
|
||||
std::vector<sp<ConditionTracker>> allConditions;
|
||||
for (Position position : {Position::FIRST, Position::LAST}) {
|
||||
SimplePredicate simplePredicate =
|
||||
getWakeLockHeldCondition(true /*nesting*/, true /*default to false*/,
|
||||
true /*output slice by uid*/, position);
|
||||
string conditionName = "WL_HELD_BY_UID3";
|
||||
|
||||
unordered_map<int64_t, int> trackerNameIndexMap;
|
||||
trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
|
||||
trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
|
||||
trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
|
||||
|
||||
SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
|
||||
0 /*condition tracker index*/, simplePredicate,
|
||||
trackerNameIndexMap);
|
||||
|
||||
std::vector<int> uids1 = {111, 1111, 11111};
|
||||
std::vector<int> uids2 = {222, 2222, 22222};
|
||||
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids1, "wl1", /*acquire=*/1);
|
||||
|
||||
// one matched start
|
||||
vector<MatchingState> matcherState;
|
||||
matcherState.push_back(MatchingState::kMatched);
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
vector<sp<ConditionTracker>> allPredicates;
|
||||
vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
|
||||
vector<bool> changedCache(1, false);
|
||||
|
||||
conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
|
||||
changedCache);
|
||||
if (position == Position::FIRST || position == Position::LAST) {
|
||||
EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
|
||||
} else {
|
||||
EXPECT_EQ(uids1.size(), conditionTracker.mSlicedConditionState.size());
|
||||
}
|
||||
EXPECT_TRUE(changedCache[0]);
|
||||
{
|
||||
if (position == Position::FIRST || position == Position::LAST) {
|
||||
EXPECT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
|
||||
EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
|
||||
} else {
|
||||
EXPECT_EQ(uids1.size(),
|
||||
conditionTracker.getChangedToTrueDimensions(allConditions)->size());
|
||||
EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
|
||||
}
|
||||
}
|
||||
|
||||
// Now test query
|
||||
const auto queryKey = getWakeLockQueryKey(position, uids1, conditionName);
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
|
||||
conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
|
||||
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
|
||||
|
||||
// another wake lock acquired by uid2
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids2, "wl2", /*acquire=*/1);
|
||||
|
||||
matcherState.clear();
|
||||
matcherState.push_back(MatchingState::kMatched);
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
changedCache[0] = false;
|
||||
conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
|
||||
changedCache);
|
||||
if (position == Position::FIRST || position == Position::LAST) {
|
||||
EXPECT_EQ(2UL, conditionTracker.mSlicedConditionState.size());
|
||||
} else {
|
||||
EXPECT_EQ(uids1.size() + uids2.size(), conditionTracker.mSlicedConditionState.size());
|
||||
}
|
||||
EXPECT_TRUE(changedCache[0]);
|
||||
{
|
||||
if (position == Position::FIRST || position == Position::LAST) {
|
||||
EXPECT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
|
||||
EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
|
||||
} else {
|
||||
EXPECT_EQ(uids2.size(),
|
||||
conditionTracker.getChangedToTrueDimensions(allConditions)->size());
|
||||
EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
|
||||
}
|
||||
}
|
||||
|
||||
// TEST QUERY
|
||||
const auto queryKey2 = getWakeLockQueryKey(position, uids2, conditionName);
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
|
||||
|
||||
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
|
||||
|
||||
// stop all event
|
||||
LogEvent event3(/*uid=*/0, /*pid=*/0);
|
||||
makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids2, "wl2", /*acquire=*/1);
|
||||
|
||||
matcherState.clear();
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
matcherState.push_back(MatchingState::kNotMatched);
|
||||
matcherState.push_back(MatchingState::kMatched);
|
||||
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
changedCache[0] = false;
|
||||
conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
|
||||
changedCache);
|
||||
EXPECT_TRUE(changedCache[0]);
|
||||
EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
|
||||
{
|
||||
if (position == Position::FIRST || position == Position::LAST) {
|
||||
EXPECT_EQ(2UL, conditionTracker.getChangedToFalseDimensions(allConditions)->size());
|
||||
EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
|
||||
} else {
|
||||
EXPECT_EQ(uids1.size() + uids2.size(),
|
||||
conditionTracker.getChangedToFalseDimensions(allConditions)->size());
|
||||
EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
|
||||
}
|
||||
}
|
||||
|
||||
// TEST QUERY
|
||||
const auto queryKey3 = getWakeLockQueryKey(position, uids1, conditionName);
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
|
||||
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
|
||||
|
||||
// TEST QUERY
|
||||
const auto queryKey4 = getWakeLockQueryKey(position, uids2, conditionName);
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
|
||||
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
|
||||
@@ -53,185 +53,192 @@ StatsdConfig CreateStatsdConfig(int num_buckets, int threshold) {
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(b/149590301): Update these tests to use new socket schema.
|
||||
//TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket) {
|
||||
// const int num_buckets = 1;
|
||||
// const int threshold = 3;
|
||||
// auto config = CreateStatsdConfig(num_buckets, threshold);
|
||||
// const uint64_t alert_id = config.alert(0).id();
|
||||
// const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
|
||||
//
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
|
||||
//
|
||||
// sp<AnomalyTracker> anomalyTracker =
|
||||
// processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
|
||||
//
|
||||
// std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")};
|
||||
// std::vector<AttributionNodeInternal> attributions2 = {
|
||||
// CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1")};
|
||||
// std::vector<AttributionNodeInternal> attributions3 = {
|
||||
// CreateAttribution(111, "App1"), CreateAttribution(333, "App3")};
|
||||
// std::vector<AttributionNodeInternal> attributions4 = {
|
||||
// CreateAttribution(222, "GMSCoreModule1"), CreateAttribution(333, "App3")};
|
||||
// std::vector<AttributionNodeInternal> attributions5 = {
|
||||
// CreateAttribution(222, "GMSCoreModule1") };
|
||||
//
|
||||
// FieldValue fieldValue1(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
|
||||
// Value((int32_t)111));
|
||||
// HashableDimensionKey whatKey1({fieldValue1});
|
||||
// MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
|
||||
//
|
||||
// FieldValue fieldValue2(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
|
||||
// Value((int32_t)222));
|
||||
// HashableDimensionKey whatKey2({fieldValue2});
|
||||
// MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
|
||||
//
|
||||
// auto event = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 2);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions4, "wl2", bucketStartTimeNs + 2);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions2, "wl1", bucketStartTimeNs + 3);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions5, "wl2", bucketStartTimeNs + 3);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions3, "wl1", bucketStartTimeNs + 4);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions5, "wl2", bucketStartTimeNs + 4);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
//
|
||||
// // Fired alarm and refractory period end timestamp updated.
|
||||
// event = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 5);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(refractory_period_sec + bucketStartTimeNs / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 100);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(refractory_period_sec + bucketStartTimeNs / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + bucketSizeNs - 1);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs - 1) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + bucketSizeNs + 1);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs - 1) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions4, "wl2", bucketStartTimeNs + bucketSizeNs + 1);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions5, "wl2", bucketStartTimeNs + bucketSizeNs + 2);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions5, "wl2", bucketStartTimeNs + bucketSizeNs + 3);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions5, "wl2", bucketStartTimeNs + bucketSizeNs + 4);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 4) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
//}
|
||||
//
|
||||
//TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets) {
|
||||
// const int num_buckets = 3;
|
||||
// const int threshold = 3;
|
||||
// auto config = CreateStatsdConfig(num_buckets, threshold);
|
||||
// const uint64_t alert_id = config.alert(0).id();
|
||||
// const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
|
||||
//
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
|
||||
//
|
||||
// sp<AnomalyTracker> anomalyTracker =
|
||||
// processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
|
||||
//
|
||||
// std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")};
|
||||
// std::vector<AttributionNodeInternal> attributions2 = {
|
||||
// CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1")};
|
||||
// std::vector<AttributionNodeInternal> attributions3 = {
|
||||
// CreateAttribution(111, "App1"), CreateAttribution(333, "App3")};
|
||||
// std::vector<AttributionNodeInternal> attributions4 = {
|
||||
// CreateAttribution(222, "GMSCoreModule1"), CreateAttribution(333, "App3")};
|
||||
// std::vector<AttributionNodeInternal> attributions5 = {
|
||||
// CreateAttribution(222, "GMSCoreModule1") };
|
||||
//
|
||||
// FieldValue fieldValue1(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
|
||||
// Value((int32_t)111));
|
||||
// HashableDimensionKey whatKey1({fieldValue1});
|
||||
// MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
|
||||
//
|
||||
// FieldValue fieldValue2(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
|
||||
// Value((int32_t)222));
|
||||
// HashableDimensionKey whatKey2({fieldValue2});
|
||||
// MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
|
||||
//
|
||||
// auto event = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 2);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions2, "wl1", bucketStartTimeNs + 3);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// // Fired alarm and refractory period end timestamp updated.
|
||||
// event = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 4);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + bucketSizeNs + 1);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions2, "wl1", bucketStartTimeNs + bucketSizeNs + 2);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + 3 * bucketSizeNs + 1);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + 3 * bucketSizeNs + 2);
|
||||
// processor->OnLogEvent(event.get());
|
||||
// EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + 3 * bucketSizeNs + 2) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
//}
|
||||
TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket) {
|
||||
const int num_buckets = 1;
|
||||
const int threshold = 3;
|
||||
auto config = CreateStatsdConfig(num_buckets, threshold);
|
||||
const uint64_t alert_id = config.alert(0).id();
|
||||
const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
|
||||
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
|
||||
|
||||
sp<AnomalyTracker> anomalyTracker =
|
||||
processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
|
||||
|
||||
std::vector<int> attributionUids1 = {111};
|
||||
std::vector<string> attributionTags1 = {"App1"};
|
||||
std::vector<int> attributionUids2 = {111, 222};
|
||||
std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
|
||||
std::vector<int> attributionUids3 = {111, 333};
|
||||
std::vector<string> attributionTags3 = {"App1", "App3"};
|
||||
std::vector<int> attributionUids4 = {222, 333};
|
||||
std::vector<string> attributionTags4 = {"GMSCoreModule1", "App3"};
|
||||
std::vector<int> attributionUids5 = {222};
|
||||
std::vector<string> attributionTags5 = {"GMSCoreModule1"};
|
||||
|
||||
FieldValue fieldValue1(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
|
||||
Value((int32_t)111));
|
||||
HashableDimensionKey whatKey1({fieldValue1});
|
||||
MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
|
||||
|
||||
FieldValue fieldValue2(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
|
||||
Value((int32_t)222));
|
||||
HashableDimensionKey whatKey2({fieldValue2});
|
||||
MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
|
||||
|
||||
auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
|
||||
attributionTags1, "wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids4, attributionTags4,
|
||||
"wl2");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids2, attributionTags2,
|
||||
"wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids5, attributionTags5,
|
||||
"wl2");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids3, attributionTags3,
|
||||
"wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids5, attributionTags5,
|
||||
"wl2");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
|
||||
// Fired alarm and refractory period end timestamp updated.
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 5, attributionUids1, attributionTags1,
|
||||
"wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(refractory_period_sec + bucketStartTimeNs / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 100, attributionUids1, attributionTags1,
|
||||
"wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(refractory_period_sec + bucketStartTimeNs / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids1,
|
||||
attributionTags1, "wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs - 1) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids1,
|
||||
attributionTags1, "wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs - 1) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids4,
|
||||
attributionTags4, "wl2");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids5,
|
||||
attributionTags5, "wl2");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 3, attributionUids5,
|
||||
attributionTags5, "wl2");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 4, attributionUids5,
|
||||
attributionTags5, "wl2");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 4) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
}
|
||||
|
||||
TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets) {
|
||||
const int num_buckets = 3;
|
||||
const int threshold = 3;
|
||||
auto config = CreateStatsdConfig(num_buckets, threshold);
|
||||
const uint64_t alert_id = config.alert(0).id();
|
||||
const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
|
||||
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
|
||||
|
||||
sp<AnomalyTracker> anomalyTracker =
|
||||
processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
|
||||
|
||||
std::vector<int> attributionUids1 = {111};
|
||||
std::vector<string> attributionTags1 = {"App1"};
|
||||
std::vector<int> attributionUids2 = {111, 222};
|
||||
std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
|
||||
|
||||
FieldValue fieldValue1(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
|
||||
Value((int32_t)111));
|
||||
HashableDimensionKey whatKey1({fieldValue1});
|
||||
MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
|
||||
|
||||
auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
|
||||
attributionTags1, "wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids2, attributionTags2,
|
||||
"wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Fired alarm and refractory period end timestamp updated.
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids1, attributionTags1,
|
||||
"wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids1,
|
||||
attributionTags1, "wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids2,
|
||||
attributionTags2, "wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1, attributionUids2,
|
||||
attributionTags2, "wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 2, attributionUids2,
|
||||
attributionTags2, "wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + 3 * bucketSizeNs + 2) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
@@ -69,414 +69,432 @@ StatsdConfig CreateStatsdConfig(int num_buckets,
|
||||
return config;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
std::vector<int> attributionUids1 = {111, 222};
|
||||
std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1"};
|
||||
|
||||
std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
|
||||
CreateAttribution(222, "GMSCoreModule1")};
|
||||
std::vector<int> attributionUids2 = {111, 222};
|
||||
std::vector<string> attributionTags2 = {"App2", "GMSCoreModule1"};
|
||||
|
||||
std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(111, "App2"),
|
||||
CreateAttribution(222, "GMSCoreModule1")};
|
||||
std::vector<int> attributionUids3 = {222};
|
||||
std::vector<string> attributionTags3 = {"GMSCoreModule1"};
|
||||
|
||||
std::vector<AttributionNodeInternal> attributions3 = {CreateAttribution(222, "GMSCoreModule1")};
|
||||
|
||||
MetricDimensionKey dimensionKey(
|
||||
HashableDimensionKey({FieldValue(Field(android::util::WAKELOCK_STATE_CHANGED,
|
||||
(int32_t)0x02010101), Value((int32_t)111))}),
|
||||
DEFAULT_DIMENSION_KEY);
|
||||
MetricDimensionKey dimensionKey1(
|
||||
HashableDimensionKey({FieldValue(Field(android::util::WAKELOCK_STATE_CHANGED,
|
||||
(int32_t)0x02010101),
|
||||
Value((int32_t)111))}),
|
||||
DEFAULT_DIMENSION_KEY);
|
||||
|
||||
MetricDimensionKey dimensionKey2(
|
||||
HashableDimensionKey({FieldValue(Field(android::util::WAKELOCK_STATE_CHANGED,
|
||||
(int32_t)0x02010101), Value((int32_t)222))}),
|
||||
DEFAULT_DIMENSION_KEY);
|
||||
|
||||
// TODO(b/149590301): Update these tests to use new socket schema.
|
||||
//TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
|
||||
// const int num_buckets = 1;
|
||||
// const uint64_t threshold_ns = NS_PER_SEC;
|
||||
// auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, true);
|
||||
// const uint64_t alert_id = config.alert(0).id();
|
||||
// const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
|
||||
//
|
||||
// int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
|
||||
//
|
||||
// sp<AnomalyTracker> anomalyTracker =
|
||||
// processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
|
||||
//
|
||||
// auto screen_on_event = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_ON, bucketStartTimeNs + 1);
|
||||
// auto screen_off_event = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_OFF, bucketStartTimeNs + 10);
|
||||
// processor->OnLogEvent(screen_on_event.get());
|
||||
// processor->OnLogEvent(screen_off_event.get());
|
||||
//
|
||||
// // Acquire wakelock wl1.
|
||||
// auto acquire_event = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 11);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + 11 + threshold_ns) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Release wakelock wl1. No anomaly detected. Alarm cancelled at the "release" event.
|
||||
// auto release_event = CreateReleaseWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 101);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Acquire wakelock wl1 within bucket #0.
|
||||
// acquire_event = CreateAcquireWakelockEvent(attributions2, "wl1", bucketStartTimeNs + 110);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + 110 + threshold_ns - 90) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Release wakelock wl1. One anomaly detected.
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + NS_PER_SEC + 109);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Acquire wakelock wl1.
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + NS_PER_SEC + 112);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// // Wakelock has been hold longer than the threshold in bucket #0. The alarm is set at the
|
||||
// // end of the refractory period.
|
||||
// const int64_t alarmFiredTimestampSec0 = anomalyTracker->getAlarmTimestampSec(dimensionKey);
|
||||
// EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
|
||||
// (uint32_t)alarmFiredTimestampSec0);
|
||||
//
|
||||
// // Anomaly alarm fired.
|
||||
// auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
|
||||
// static_cast<uint32_t>(alarmFiredTimestampSec0));
|
||||
// EXPECT_EQ(1u, alarmSet.size());
|
||||
// processor->onAnomalyAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet);
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Release wakelock wl1.
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions1, "wl1", alarmFiredTimestampSec0 * NS_PER_SEC + NS_PER_SEC + 1);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// // Within refractory period. No more anomaly detected.
|
||||
// EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Acquire wakelock wl1.
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC - 11);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// const int64_t alarmFiredTimestampSec1 = anomalyTracker->getAlarmTimestampSec(dimensionKey);
|
||||
// EXPECT_EQ((bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC) / NS_PER_SEC,
|
||||
// (uint64_t)alarmFiredTimestampSec1);
|
||||
//
|
||||
// // Release wakelock wl1.
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(refractory_period_sec +
|
||||
// (bucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
|
||||
// static_cast<uint32_t>(alarmFiredTimestampSec1));
|
||||
// EXPECT_EQ(0u, alarmSet.size());
|
||||
//
|
||||
// // Acquire wakelock wl1 near the end of bucket #0.
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + bucketSizeNs - 2);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
//
|
||||
// // Release the event at early bucket #1.
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + bucketSizeNs + NS_PER_SEC - 1);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// // Anomaly detected when stopping the alarm. The refractory period does not change.
|
||||
// EXPECT_EQ(refractory_period_sec +
|
||||
// (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Condition changes to false.
|
||||
// screen_on_event = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_ON,
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs + 20);
|
||||
// processor->OnLogEvent(screen_on_event.get());
|
||||
// EXPECT_EQ(refractory_period_sec +
|
||||
// (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
//
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + 2 * bucketSizeNs + 30);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// // The condition is false. Do not start the alarm.
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(refractory_period_sec +
|
||||
// (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Condition turns true.
|
||||
// screen_off_event = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC);
|
||||
// processor->OnLogEvent(screen_off_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC + threshold_ns) / NS_PER_SEC,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
//
|
||||
// // Condition turns to false.
|
||||
// screen_on_event = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_ON,
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1);
|
||||
// processor->OnLogEvent(screen_on_event.get());
|
||||
// // Condition turns to false. Cancelled the alarm.
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// // Detected one anomaly.
|
||||
// EXPECT_EQ(refractory_period_sec +
|
||||
// (bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Condition turns to true again.
|
||||
// screen_off_event = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 2);
|
||||
// processor->OnLogEvent(screen_off_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 2 + 1,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
//
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(refractory_period_sec +
|
||||
// (bucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC) / NS_PER_SEC,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
//}
|
||||
//
|
||||
//TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets) {
|
||||
// const int num_buckets = 3;
|
||||
// const uint64_t threshold_ns = NS_PER_SEC;
|
||||
// auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, true);
|
||||
// const uint64_t alert_id = config.alert(0).id();
|
||||
// const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
|
||||
//
|
||||
// int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
|
||||
//
|
||||
// sp<AnomalyTracker> anomalyTracker =
|
||||
// processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
|
||||
//
|
||||
// auto screen_off_event = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_OFF, bucketStartTimeNs + 1);
|
||||
// processor->OnLogEvent(screen_off_event.get());
|
||||
//
|
||||
// // Acquire wakelock "wc1" in bucket #0.
|
||||
// auto acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + bucketSizeNs - NS_PER_SEC / 2 - 1);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Release wakelock "wc1" in bucket #0.
|
||||
// auto release_event = CreateReleaseWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + bucketSizeNs - 1);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Acquire wakelock "wc1" in bucket #1.
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + bucketSizeNs + 1);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + bucketSizeNs + 100);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Acquire wakelock "wc2" in bucket #2.
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions3, "wl2", bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey2));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
//
|
||||
// // Release wakelock "wc2" in bucket #2.
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions3, "wl2", bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
|
||||
// EXPECT_EQ(refractory_period_sec +
|
||||
// (bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC) / NS_PER_SEC,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
//
|
||||
// // Acquire wakelock "wc1" in bucket #2.
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 1,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Release wakelock "wc1" in bucket #2.
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + 2 * bucketSizeNs + 2.5 * NS_PER_SEC);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(refractory_period_sec +
|
||||
// (int64_t)(bucketStartTimeNs + 2 * bucketSizeNs + 2.5 * NS_PER_SEC) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions3, "wl2", bucketStartTimeNs + 6 * bucketSizeNs - NS_PER_SEC + 4);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 6 * bucketSizeNs - NS_PER_SEC + 5);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ((bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey2));
|
||||
//
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions3, "wl2", bucketStartTimeNs + 6 * bucketSizeNs + 2);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 6 * bucketSizeNs + 6);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
|
||||
// // The buckets are not messed up across dimensions. Only one dimension has anomaly triggered.
|
||||
// EXPECT_EQ(refractory_period_sec +
|
||||
// (int64_t)(bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 1,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//}
|
||||
//
|
||||
//TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period) {
|
||||
// const int num_buckets = 2;
|
||||
// const uint64_t threshold_ns = 3 * NS_PER_SEC;
|
||||
// auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, false);
|
||||
// int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// const uint64_t alert_id = config.alert(0).id();
|
||||
// const uint32_t refractory_period_sec = 3 * bucketSizeNs / NS_PER_SEC;
|
||||
// config.mutable_alert(0)->set_refractory_period_secs(refractory_period_sec);
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
|
||||
//
|
||||
// sp<AnomalyTracker> anomalyTracker =
|
||||
// processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
|
||||
//
|
||||
// auto screen_off_event = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_OFF, bucketStartTimeNs + 1);
|
||||
// processor->OnLogEvent(screen_off_event.get());
|
||||
//
|
||||
// // Acquire wakelock "wc1" in bucket #0.
|
||||
// auto acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + bucketSizeNs - 100);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Acquire the wakelock "wc1" again.
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + bucketSizeNs + 2 * NS_PER_SEC + 1);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// // The alarm does not change.
|
||||
// EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // Anomaly alarm fired late.
|
||||
// const int64_t firedAlarmTimestampNs = bucketStartTimeNs + 2 * bucketSizeNs - NS_PER_SEC;
|
||||
// auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
|
||||
// static_cast<uint32_t>(firedAlarmTimestampNs / NS_PER_SEC));
|
||||
// EXPECT_EQ(1u, alarmSet.size());
|
||||
// processor->onAnomalyAlarmFired(firedAlarmTimestampNs, alarmSet);
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 2 * bucketSizeNs - 100);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// auto release_event = CreateReleaseWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
// // Within the refractory period. No anomaly.
|
||||
// EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// // A new wakelock, but still within refractory period.
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 2 * bucketSizeNs + 10 * NS_PER_SEC);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
//
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 3 * bucketSizeNs - NS_PER_SEC);
|
||||
// // Still in the refractory period. No anomaly.
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
|
||||
// anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey));
|
||||
//
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 5);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
//
|
||||
// release_event = CreateReleaseWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 4);
|
||||
// processor->OnLogEvent(release_event.get());
|
||||
// EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
//
|
||||
// acquire_event = CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 3);
|
||||
// processor->OnLogEvent(acquire_event.get());
|
||||
// EXPECT_EQ((bucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC,
|
||||
// anomalyTracker->getAlarmTimestampSec(dimensionKey));
|
||||
//}
|
||||
} // namespace
|
||||
|
||||
TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
|
||||
const int num_buckets = 1;
|
||||
const uint64_t threshold_ns = NS_PER_SEC;
|
||||
auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, true);
|
||||
const uint64_t alert_id = config.alert(0).id();
|
||||
const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
|
||||
|
||||
int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
|
||||
int64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
|
||||
|
||||
sp<AnomalyTracker> anomalyTracker =
|
||||
processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
|
||||
|
||||
auto screen_on_event = CreateScreenStateChangedEvent(
|
||||
bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
auto screen_off_event = CreateScreenStateChangedEvent(
|
||||
bucketStartTimeNs + 10, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screen_on_event.get());
|
||||
processor->OnLogEvent(screen_off_event.get());
|
||||
|
||||
// Acquire wakelock wl1.
|
||||
auto acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 11, attributionUids1,
|
||||
attributionTags1, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + 11 + threshold_ns) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Release wakelock wl1. No anomaly detected. Alarm cancelled at the "release" event.
|
||||
auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 101, attributionUids1,
|
||||
attributionTags1, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Acquire wakelock wl1 within bucket #0.
|
||||
acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 110, attributionUids2,
|
||||
attributionTags2, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + 110 + threshold_ns - 90) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Release wakelock wl1. One anomaly detected.
|
||||
release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + NS_PER_SEC + 109,
|
||||
attributionUids2, attributionTags2, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Acquire wakelock wl1.
|
||||
acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + NS_PER_SEC + 112,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
// Wakelock has been hold longer than the threshold in bucket #0. The alarm is set at the
|
||||
// end of the refractory period.
|
||||
const int64_t alarmFiredTimestampSec0 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
|
||||
(uint32_t)alarmFiredTimestampSec0);
|
||||
|
||||
// Anomaly alarm fired.
|
||||
auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
|
||||
static_cast<uint32_t>(alarmFiredTimestampSec0));
|
||||
EXPECT_EQ(1u, alarmSet.size());
|
||||
processor->onAnomalyAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet);
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Release wakelock wl1.
|
||||
release_event =
|
||||
CreateReleaseWakelockEvent(alarmFiredTimestampSec0 * NS_PER_SEC + NS_PER_SEC + 1,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
// Within refractory period. No more anomaly detected.
|
||||
EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Acquire wakelock wl1.
|
||||
acquire_event =
|
||||
CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC - 11,
|
||||
attributionUids2, attributionTags2, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
const int64_t alarmFiredTimestampSec1 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
|
||||
EXPECT_EQ((bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC) / NS_PER_SEC,
|
||||
(uint64_t)alarmFiredTimestampSec1);
|
||||
|
||||
// Release wakelock wl1.
|
||||
release_event =
|
||||
CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10,
|
||||
attributionUids2, attributionTags2, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(refractory_period_sec +
|
||||
(bucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
|
||||
static_cast<uint32_t>(alarmFiredTimestampSec1));
|
||||
EXPECT_EQ(0u, alarmSet.size());
|
||||
|
||||
// Acquire wakelock wl1 near the end of bucket #0.
|
||||
acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 2,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
|
||||
// Release the event at early bucket #1.
|
||||
release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + NS_PER_SEC - 1,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
// Anomaly detected when stopping the alarm. The refractory period does not change.
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Condition changes to false.
|
||||
screen_on_event =
|
||||
CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 20,
|
||||
android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screen_on_event.get());
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
|
||||
acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 30,
|
||||
attributionUids2, attributionTags2, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
// The condition is false. Do not start the alarm.
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Condition turns true.
|
||||
screen_off_event =
|
||||
CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC,
|
||||
android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screen_off_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC + threshold_ns) / NS_PER_SEC,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
|
||||
// Condition turns to false.
|
||||
screen_on_event =
|
||||
CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1,
|
||||
android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screen_on_event.get());
|
||||
// Condition turns to false. Cancelled the alarm.
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
// Detected one anomaly.
|
||||
EXPECT_EQ(refractory_period_sec +
|
||||
(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Condition turns to true again.
|
||||
screen_off_event =
|
||||
CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 2,
|
||||
android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screen_off_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 2 + 1,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
|
||||
release_event =
|
||||
CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC,
|
||||
attributionUids2, attributionTags2, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(refractory_period_sec +
|
||||
(bucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC) / NS_PER_SEC,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
}
|
||||
|
||||
TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets) {
|
||||
const int num_buckets = 3;
|
||||
const uint64_t threshold_ns = NS_PER_SEC;
|
||||
auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, true);
|
||||
const uint64_t alert_id = config.alert(0).id();
|
||||
const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
|
||||
|
||||
int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
|
||||
int64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
|
||||
|
||||
sp<AnomalyTracker> anomalyTracker =
|
||||
processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
|
||||
|
||||
auto screen_off_event = CreateScreenStateChangedEvent(
|
||||
bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screen_off_event.get());
|
||||
|
||||
// Acquire wakelock "wc1" in bucket #0.
|
||||
auto acquire_event =
|
||||
CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - NS_PER_SEC / 2 - 1,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Release wakelock "wc1" in bucket #0.
|
||||
auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Acquire wakelock "wc1" in bucket #1.
|
||||
acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1,
|
||||
attributionUids2, attributionTags2, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + 100,
|
||||
attributionUids2, attributionTags2, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Acquire wakelock "wc2" in bucket #2.
|
||||
acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
|
||||
attributionUids3, attributionTags3, "wl2");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey2));
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
|
||||
// Release wakelock "wc2" in bucket #2.
|
||||
release_event =
|
||||
CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC,
|
||||
attributionUids3, attributionTags3, "wl2");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
|
||||
EXPECT_EQ(refractory_period_sec +
|
||||
(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC) / NS_PER_SEC,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
|
||||
|
||||
// Acquire wakelock "wc1" in bucket #2.
|
||||
acquire_event =
|
||||
CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC,
|
||||
attributionUids2, attributionTags2, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 1,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Release wakelock "wc1" in bucket #2.
|
||||
release_event =
|
||||
CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2.5 * NS_PER_SEC,
|
||||
attributionUids2, attributionTags2, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(refractory_period_sec +
|
||||
(int64_t)(bucketStartTimeNs + 2 * bucketSizeNs + 2.5 * NS_PER_SEC) /
|
||||
NS_PER_SEC +
|
||||
1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
acquire_event =
|
||||
CreateAcquireWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs - NS_PER_SEC + 4,
|
||||
attributionUids3, attributionTags3, "wl2");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
acquire_event =
|
||||
CreateAcquireWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs - NS_PER_SEC + 5,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ((bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 1,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey2));
|
||||
|
||||
release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs + 2,
|
||||
attributionUids3, attributionTags3, "wl2");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs + 6,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
|
||||
// The buckets are not messed up across dimensions. Only one dimension has anomaly triggered.
|
||||
EXPECT_EQ(refractory_period_sec + (int64_t)(bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC +
|
||||
1,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
}
|
||||
|
||||
TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period) {
|
||||
const int num_buckets = 2;
|
||||
const uint64_t threshold_ns = 3 * NS_PER_SEC;
|
||||
auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, false);
|
||||
int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
|
||||
int64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
|
||||
|
||||
const uint64_t alert_id = config.alert(0).id();
|
||||
const uint32_t refractory_period_sec = 3 * bucketSizeNs / NS_PER_SEC;
|
||||
config.mutable_alert(0)->set_refractory_period_secs(refractory_period_sec);
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
|
||||
|
||||
sp<AnomalyTracker> anomalyTracker =
|
||||
processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
|
||||
|
||||
auto screen_off_event = CreateScreenStateChangedEvent(
|
||||
bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screen_off_event.get());
|
||||
|
||||
// Acquire wakelock "wc1" in bucket #0.
|
||||
auto acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 100,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Acquire the wakelock "wc1" again.
|
||||
acquire_event =
|
||||
CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2 * NS_PER_SEC + 1,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
// The alarm does not change.
|
||||
EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// Anomaly alarm fired late.
|
||||
const int64_t firedAlarmTimestampNs = bucketStartTimeNs + 2 * bucketSizeNs - NS_PER_SEC;
|
||||
auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
|
||||
static_cast<uint32_t>(firedAlarmTimestampNs / NS_PER_SEC));
|
||||
EXPECT_EQ(1u, alarmSet.size());
|
||||
processor->onAnomalyAlarmFired(firedAlarmTimestampNs, alarmSet);
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
// Within the refractory period. No anomaly.
|
||||
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
// A new wakelock, but still within refractory period.
|
||||
acquire_event =
|
||||
CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 10 * NS_PER_SEC,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
|
||||
release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - NS_PER_SEC,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
// Still in the refractory period. No anomaly.
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
|
||||
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
|
||||
|
||||
acquire_event =
|
||||
CreateAcquireWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 5,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
|
||||
release_event =
|
||||
CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 4,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(release_event.get());
|
||||
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
|
||||
acquire_event =
|
||||
CreateAcquireWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 3,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
processor->OnLogEvent(acquire_event.get());
|
||||
EXPECT_EQ((bucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC,
|
||||
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
|
||||
}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
@@ -53,367 +53,318 @@ StatsdConfig CreateStatsdConfig(const Position position) {
|
||||
return config;
|
||||
}
|
||||
|
||||
// GMS core node is in the middle.
|
||||
std::vector<int> attributionUids1 = {111, 222, 333};
|
||||
std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1", "App3"};
|
||||
|
||||
// GMS core node is the last one.
|
||||
std::vector<int> attributionUids2 = {111, 333, 222};
|
||||
std::vector<string> attributionTags2 = {"App1", "App3", "GMSCoreModule1"};
|
||||
|
||||
// GMS core node is the first one.
|
||||
std::vector<int> attributionUids3 = {222, 333};
|
||||
std::vector<string> attributionTags3 = {"GMSCoreModule1", "App3"};
|
||||
|
||||
// Single GMS core node.
|
||||
std::vector<int> attributionUids4 = {222};
|
||||
std::vector<string> attributionTags4 = {"GMSCoreModule1"};
|
||||
|
||||
// GMS core has another uid.
|
||||
std::vector<int> attributionUids5 = {111, 444, 333};
|
||||
std::vector<string> attributionTags5 = {"App1", "GMSCoreModule2", "App3"};
|
||||
|
||||
// Multiple GMS core nodes.
|
||||
std::vector<int> attributionUids6 = {444, 222};
|
||||
std::vector<string> attributionTags6 = {"GMSCoreModule2", "GMSCoreModule1"};
|
||||
|
||||
// No GMS core nodes
|
||||
std::vector<int> attributionUids7 = {111, 333};
|
||||
std::vector<string> attributionTags7 = {"App1", "App3"};
|
||||
|
||||
std::vector<int> attributionUids8 = {111};
|
||||
std::vector<string> attributionTags8 = {"App1"};
|
||||
|
||||
// GMS core node with isolated uid.
|
||||
const int isolatedUid = 666;
|
||||
std::vector<int> attributionUids9 = {isolatedUid};
|
||||
std::vector<string> attributionTags9 = {"GMSCoreModule3"};
|
||||
|
||||
std::vector<int> attributionUids10 = {isolatedUid};
|
||||
std::vector<string> attributionTags10 = {"GMSCoreModule1"};
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(b/149590301): Update these tests to use new socket schema.
|
||||
//TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid) {
|
||||
// auto config = CreateStatsdConfig(Position::FIRST);
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
//
|
||||
// // Here it assumes that GMS core has two uids.
|
||||
// processor->getUidMap()->updateMap(
|
||||
// 1, {222, 444, 111, 333}, {1, 1, 2, 2},
|
||||
// {String16("v1"), String16("v1"), String16("v2"), String16("v2")},
|
||||
// {String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"),
|
||||
// String16("APP3")},
|
||||
// {String16(""), String16(""), String16(""), String16("")});
|
||||
//
|
||||
// // GMS core node is in the middle.
|
||||
// std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
|
||||
// CreateAttribution(222, "GMSCoreModule1"),
|
||||
// CreateAttribution(333, "App3")};
|
||||
//
|
||||
// // GMS core node is the last one.
|
||||
// std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(111, "App1"),
|
||||
// CreateAttribution(333, "App3"),
|
||||
// CreateAttribution(222, "GMSCoreModule1")};
|
||||
//
|
||||
// // GMS core node is the first one.
|
||||
// std::vector<AttributionNodeInternal> attributions3 = {CreateAttribution(222, "GMSCoreModule1"),
|
||||
// CreateAttribution(333, "App3")};
|
||||
//
|
||||
// // Single GMS core node.
|
||||
// std::vector<AttributionNodeInternal> attributions4 = {CreateAttribution(222, "GMSCoreModule1")};
|
||||
//
|
||||
// // GMS core has another uid.
|
||||
// std::vector<AttributionNodeInternal> attributions5 = {CreateAttribution(111, "App1"),
|
||||
// CreateAttribution(444, "GMSCoreModule2"),
|
||||
// CreateAttribution(333, "App3")};
|
||||
//
|
||||
// // Multiple GMS core nodes.
|
||||
// std::vector<AttributionNodeInternal> attributions6 = {CreateAttribution(444, "GMSCoreModule2"),
|
||||
// CreateAttribution(222, "GMSCoreModule1")};
|
||||
//
|
||||
// // No GMS core nodes.
|
||||
// std::vector<AttributionNodeInternal> attributions7 = {CreateAttribution(111, "App1"),
|
||||
// CreateAttribution(333, "App3")};
|
||||
// std::vector<AttributionNodeInternal> attributions8 = {CreateAttribution(111, "App1")};
|
||||
//
|
||||
// // GMS core node with isolated uid.
|
||||
// const int isolatedUid = 666;
|
||||
// std::vector<AttributionNodeInternal> attributions9 = {
|
||||
// CreateAttribution(isolatedUid, "GMSCoreModule3")};
|
||||
//
|
||||
// std::vector<std::unique_ptr<LogEvent>> events;
|
||||
// // Events 1~4 are in the 1st bucket.
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 2));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + 200));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions3, "wl1", bucketStartTimeNs + bucketSizeNs - 1));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions4, "wl1", bucketStartTimeNs + bucketSizeNs));
|
||||
//
|
||||
// // Events 5~8 are in the 3rd bucket.
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions5, "wl2", bucketStartTimeNs + 2 * bucketSizeNs + 1));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions6, "wl2", bucketStartTimeNs + 2 * bucketSizeNs + 100));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions7, "wl2", bucketStartTimeNs + 3 * bucketSizeNs - 2));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions8, "wl2", bucketStartTimeNs + 3 * bucketSizeNs));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions9, "wl2", bucketStartTimeNs + 3 * bucketSizeNs + 1));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions9, "wl2", bucketStartTimeNs + 3 * bucketSizeNs + 100));
|
||||
// events.push_back(CreateIsolatedUidChangedEvent(
|
||||
// isolatedUid, 222, true/* is_create*/, bucketStartTimeNs + 3 * bucketSizeNs - 1));
|
||||
// events.push_back(CreateIsolatedUidChangedEvent(
|
||||
// isolatedUid, 222, false/* is_create*/, bucketStartTimeNs + 3 * bucketSizeNs + 10));
|
||||
//
|
||||
// sortLogEventsByTimestamp(&events);
|
||||
//
|
||||
// for (const auto& event : events) {
|
||||
// processor->OnLogEvent(event.get());
|
||||
// }
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(reports.reports_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
//
|
||||
// StatsLogReport::CountMetricDataWrapper countMetrics;
|
||||
// sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
|
||||
// EXPECT_EQ(countMetrics.data_size(), 4);
|
||||
//
|
||||
// auto data = countMetrics.data(0);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), android::util::WAKELOCK_STATE_CHANGED, 111,
|
||||
// "App1");
|
||||
// EXPECT_EQ(data.bucket_info_size(), 2);
|
||||
// EXPECT_EQ(data.bucket_info(0).count(), 2);
|
||||
// EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
|
||||
// EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
|
||||
// EXPECT_EQ(data.bucket_info(1).count(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
|
||||
// EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
|
||||
//
|
||||
// data = countMetrics.data(1);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), android::util::WAKELOCK_STATE_CHANGED, 222,
|
||||
// "GMSCoreModule1");
|
||||
// EXPECT_EQ(data.bucket_info_size(), 2);
|
||||
// EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
|
||||
// EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
|
||||
// EXPECT_EQ(data.bucket_info(1).count(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
|
||||
// EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
|
||||
//
|
||||
// data = countMetrics.data(2);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), android::util::WAKELOCK_STATE_CHANGED, 222,
|
||||
// "GMSCoreModule3");
|
||||
// EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
|
||||
// EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 4 * bucketSizeNs);
|
||||
//
|
||||
// data = countMetrics.data(3);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), android::util::WAKELOCK_STATE_CHANGED, 444,
|
||||
// "GMSCoreModule2");
|
||||
// EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
|
||||
// EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
|
||||
//}
|
||||
//
|
||||
//TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain) {
|
||||
// auto config = CreateStatsdConfig(Position::ALL);
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
//
|
||||
// // Here it assumes that GMS core has two uids.
|
||||
// processor->getUidMap()->updateMap(
|
||||
// 1, {222, 444, 111, 333}, {1, 1, 2, 2},
|
||||
// {String16("v1"), String16("v1"), String16("v2"), String16("v2")},
|
||||
// {String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"),
|
||||
// String16("APP3")},
|
||||
// {String16(""), String16(""), String16(""), String16("")});
|
||||
//
|
||||
// // GMS core node is in the middle.
|
||||
// std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
|
||||
// CreateAttribution(222, "GMSCoreModule1"),
|
||||
// CreateAttribution(333, "App3")};
|
||||
//
|
||||
// // GMS core node is the last one.
|
||||
// std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(111, "App1"),
|
||||
// CreateAttribution(333, "App3"),
|
||||
// CreateAttribution(222, "GMSCoreModule1")};
|
||||
//
|
||||
// // GMS core node is the first one.
|
||||
// std::vector<AttributionNodeInternal> attributions3 = {CreateAttribution(222, "GMSCoreModule1"),
|
||||
// CreateAttribution(333, "App3")};
|
||||
//
|
||||
// // Single GMS core node.
|
||||
// std::vector<AttributionNodeInternal> attributions4 = {CreateAttribution(222, "GMSCoreModule1")};
|
||||
//
|
||||
// // GMS core has another uid.
|
||||
// std::vector<AttributionNodeInternal> attributions5 = {CreateAttribution(111, "App1"),
|
||||
// CreateAttribution(444, "GMSCoreModule2"),
|
||||
// CreateAttribution(333, "App3")};
|
||||
//
|
||||
// // Multiple GMS core nodes.
|
||||
// std::vector<AttributionNodeInternal> attributions6 = {CreateAttribution(444, "GMSCoreModule2"),
|
||||
// CreateAttribution(222, "GMSCoreModule1")};
|
||||
//
|
||||
// // No GMS core nodes.
|
||||
// std::vector<AttributionNodeInternal> attributions7 = {CreateAttribution(111, "App1"),
|
||||
// CreateAttribution(333, "App3")};
|
||||
// std::vector<AttributionNodeInternal> attributions8 = {CreateAttribution(111, "App1")};
|
||||
//
|
||||
// // GMS core node with isolated uid.
|
||||
// const int isolatedUid = 666;
|
||||
// std::vector<AttributionNodeInternal> attributions9 = {
|
||||
// CreateAttribution(isolatedUid, "GMSCoreModule1")};
|
||||
//
|
||||
// std::vector<std::unique_ptr<LogEvent>> events;
|
||||
// // Events 1~4 are in the 1st bucket.
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 2));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions2, "wl1", bucketStartTimeNs + 200));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions3, "wl1", bucketStartTimeNs + bucketSizeNs - 1));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions4, "wl1", bucketStartTimeNs + bucketSizeNs));
|
||||
//
|
||||
// // Events 5~8 are in the 3rd bucket.
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions5, "wl2", bucketStartTimeNs + 2 * bucketSizeNs + 1));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions6, "wl2", bucketStartTimeNs + 2 * bucketSizeNs + 100));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions7, "wl2", bucketStartTimeNs + 3 * bucketSizeNs - 2));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions8, "wl2", bucketStartTimeNs + 3 * bucketSizeNs));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions9, "wl2", bucketStartTimeNs + 3 * bucketSizeNs + 1));
|
||||
// events.push_back(CreateAcquireWakelockEvent(
|
||||
// attributions9, "wl2", bucketStartTimeNs + 3 * bucketSizeNs + 100));
|
||||
// events.push_back(CreateIsolatedUidChangedEvent(
|
||||
// isolatedUid, 222, true/* is_create*/, bucketStartTimeNs + 3 * bucketSizeNs - 1));
|
||||
// events.push_back(CreateIsolatedUidChangedEvent(
|
||||
// isolatedUid, 222, false/* is_create*/, bucketStartTimeNs + 3 * bucketSizeNs + 10));
|
||||
//
|
||||
// sortLogEventsByTimestamp(&events);
|
||||
//
|
||||
// for (const auto& event : events) {
|
||||
// processor->OnLogEvent(event.get());
|
||||
// }
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(reports.reports_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
//
|
||||
// StatsLogReport::CountMetricDataWrapper countMetrics;
|
||||
// sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
|
||||
// EXPECT_EQ(countMetrics.data_size(), 6);
|
||||
//
|
||||
// auto data = countMetrics.data(0);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), android::util::WAKELOCK_STATE_CHANGED, 222, "GMSCoreModule1");
|
||||
// EXPECT_EQ(2, data.bucket_info_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(0).count());
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
// data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
// data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, data.bucket_info(1).count());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
// data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 4 * bucketSizeNs,
|
||||
// data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
//
|
||||
// data = countMetrics.data(1);
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 222);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 222, "GMSCoreModule1");
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 333);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
|
||||
// EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
|
||||
// EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
|
||||
//
|
||||
// data = countMetrics.data(2);
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 444);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 444, "GMSCoreModule2");
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 222);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 222, "GMSCoreModule1");
|
||||
// EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
// data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
// data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
//
|
||||
// data = countMetrics.data(3);
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111, "App1");
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 222);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 222, "GMSCoreModule1");
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 333);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
|
||||
// EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
// EXPECT_EQ(bucketStartTimeNs,
|
||||
// data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
// data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
//
|
||||
// data = countMetrics.data(4);
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111, "App1");
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 333);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 222);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 222, "GMSCoreModule1");
|
||||
// EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
// EXPECT_EQ(bucketStartTimeNs,
|
||||
// data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
// data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
//
|
||||
// data = countMetrics.data(5);
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111, "App1");
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 444);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 444, "GMSCoreModule2");
|
||||
// ValidateUidDimension(
|
||||
// data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 333);
|
||||
// ValidateAttributionUidAndTagDimension(
|
||||
// data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
|
||||
// EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
// EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
// data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
// data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
//}
|
||||
TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid) {
|
||||
auto config = CreateStatsdConfig(Position::FIRST);
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
|
||||
// Here it assumes that GMS core has two uids.
|
||||
processor->getUidMap()->updateMap(
|
||||
1, {222, 444, 111, 333}, {1, 1, 2, 2},
|
||||
{String16("v1"), String16("v1"), String16("v2"), String16("v2")},
|
||||
{String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"),
|
||||
String16("APP3")},
|
||||
{String16(""), String16(""), String16(""), String16("")});
|
||||
|
||||
std::vector<std::unique_ptr<LogEvent>> events;
|
||||
// Events 1~4 are in the 1st bucket.
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
|
||||
attributionTags1, "wl1"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 200, attributionUids2,
|
||||
attributionTags2, "wl1"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
|
||||
attributionUids3, attributionTags3, "wl1"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs, attributionUids4,
|
||||
attributionTags4, "wl1"));
|
||||
|
||||
// Events 5~8 are in the 3rd bucket.
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
|
||||
attributionUids5, attributionTags5, "wl2"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
|
||||
attributionUids6, attributionTags6, "wl2"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - 2,
|
||||
attributionUids7, attributionTags7, "wl2"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
attributionUids8, attributionTags8, "wl2"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1,
|
||||
attributionUids9, attributionTags9, "wl2"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 100,
|
||||
attributionUids9, attributionTags9, "wl2"));
|
||||
events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs - 1, 222,
|
||||
isolatedUid, true /*is_create*/));
|
||||
events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs + 10, 222,
|
||||
isolatedUid, false /*is_create*/));
|
||||
|
||||
sortLogEventsByTimestamp(&events);
|
||||
|
||||
for (const auto& event : events) {
|
||||
processor->OnLogEvent(event.get());
|
||||
}
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true, ADB_DUMP,
|
||||
FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(reports.reports_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
|
||||
StatsLogReport::CountMetricDataWrapper countMetrics;
|
||||
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
|
||||
EXPECT_EQ(countMetrics.data_size(), 4);
|
||||
|
||||
auto data = countMetrics.data(0);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
|
||||
android::util::WAKELOCK_STATE_CHANGED, 111, "App1");
|
||||
EXPECT_EQ(data.bucket_info_size(), 2);
|
||||
EXPECT_EQ(data.bucket_info(0).count(), 2);
|
||||
EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
|
||||
EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
|
||||
EXPECT_EQ(data.bucket_info(1).count(), 1);
|
||||
EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
|
||||
bucketStartTimeNs + 2 * bucketSizeNs);
|
||||
EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
|
||||
|
||||
data = countMetrics.data(1);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
|
||||
android::util::WAKELOCK_STATE_CHANGED, 222,
|
||||
"GMSCoreModule1");
|
||||
EXPECT_EQ(data.bucket_info_size(), 2);
|
||||
EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
|
||||
EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
|
||||
EXPECT_EQ(data.bucket_info(1).count(), 1);
|
||||
EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
|
||||
EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
|
||||
|
||||
data = countMetrics.data(2);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
|
||||
android::util::WAKELOCK_STATE_CHANGED, 222,
|
||||
"GMSCoreModule3");
|
||||
EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
|
||||
bucketStartTimeNs + 3 * bucketSizeNs);
|
||||
EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 4 * bucketSizeNs);
|
||||
|
||||
data = countMetrics.data(3);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
|
||||
android::util::WAKELOCK_STATE_CHANGED, 444,
|
||||
"GMSCoreModule2");
|
||||
EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
|
||||
bucketStartTimeNs + 2 * bucketSizeNs);
|
||||
EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
|
||||
}
|
||||
|
||||
TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain) {
|
||||
auto config = CreateStatsdConfig(Position::ALL);
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
|
||||
// Here it assumes that GMS core has two uids.
|
||||
processor->getUidMap()->updateMap(
|
||||
1, {222, 444, 111, 333}, {1, 1, 2, 2},
|
||||
{String16("v1"), String16("v1"), String16("v2"), String16("v2")},
|
||||
{String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"),
|
||||
String16("APP3")},
|
||||
{String16(""), String16(""), String16(""), String16("")});
|
||||
|
||||
std::vector<std::unique_ptr<LogEvent>> events;
|
||||
// Events 1~4 are in the 1st bucket.
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
|
||||
attributionTags1, "wl1"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 200, attributionUids2,
|
||||
attributionTags2, "wl1"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
|
||||
attributionUids3, attributionTags3, "wl1"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs, attributionUids4,
|
||||
attributionTags4, "wl1"));
|
||||
|
||||
// Events 5~8 are in the 3rd bucket.
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
|
||||
attributionUids5, attributionTags5, "wl2"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
|
||||
attributionUids6, attributionTags6, "wl2"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - 2,
|
||||
attributionUids7, attributionTags7, "wl2"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
attributionUids8, attributionTags8, "wl2"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1,
|
||||
attributionUids10, attributionTags10, "wl2"));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 100,
|
||||
attributionUids10, attributionTags10, "wl2"));
|
||||
events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs - 1, 222,
|
||||
isolatedUid, true /*is_create*/));
|
||||
events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs + 10, 222,
|
||||
isolatedUid, false /*is_create*/));
|
||||
|
||||
sortLogEventsByTimestamp(&events);
|
||||
|
||||
for (const auto& event : events) {
|
||||
processor->OnLogEvent(event.get());
|
||||
}
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true, ADB_DUMP,
|
||||
FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(reports.reports_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
|
||||
StatsLogReport::CountMetricDataWrapper countMetrics;
|
||||
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
|
||||
EXPECT_EQ(countMetrics.data_size(), 6);
|
||||
|
||||
auto data = countMetrics.data(0);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
|
||||
android::util::WAKELOCK_STATE_CHANGED, 222,
|
||||
"GMSCoreModule1");
|
||||
EXPECT_EQ(2, data.bucket_info_size());
|
||||
EXPECT_EQ(1, data.bucket_info(0).count());
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, data.bucket_info(1).count());
|
||||
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
|
||||
data = countMetrics.data(1);
|
||||
ValidateUidDimension(data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 222);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 222,
|
||||
"GMSCoreModule1");
|
||||
ValidateUidDimension(data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 333);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
|
||||
EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
|
||||
EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
|
||||
|
||||
data = countMetrics.data(2);
|
||||
ValidateUidDimension(data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 444);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 444,
|
||||
"GMSCoreModule2");
|
||||
ValidateUidDimension(data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 222);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 222,
|
||||
"GMSCoreModule1");
|
||||
EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
|
||||
data = countMetrics.data(3);
|
||||
ValidateUidDimension(data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 111, "App1");
|
||||
ValidateUidDimension(data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 222);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 222,
|
||||
"GMSCoreModule1");
|
||||
ValidateUidDimension(data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 333);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
|
||||
EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
|
||||
data = countMetrics.data(4);
|
||||
ValidateUidDimension(data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 111, "App1");
|
||||
ValidateUidDimension(data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 333);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
|
||||
ValidateUidDimension(data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 222);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 222,
|
||||
"GMSCoreModule1");
|
||||
EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
|
||||
data = countMetrics.data(5);
|
||||
ValidateUidDimension(data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 111, "App1");
|
||||
ValidateUidDimension(data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 444);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 444,
|
||||
"GMSCoreModule2");
|
||||
ValidateUidDimension(data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 333);
|
||||
ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
|
||||
android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
|
||||
EXPECT_EQ(data.bucket_info_size(), 1);
|
||||
EXPECT_EQ(data.bucket_info(0).count(), 1);
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
@@ -56,54 +56,54 @@ StatsdConfig CreateStatsdConfig(int num_buckets, int threshold) {
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(ConfigTtlE2eTest, TestCountMetric) {
|
||||
// const int num_buckets = 1;
|
||||
// const int threshold = 3;
|
||||
// auto config = CreateStatsdConfig(num_buckets, threshold);
|
||||
// const uint64_t alert_id = config.alert(0).id();
|
||||
// const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
|
||||
//
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
//
|
||||
// std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")};
|
||||
//
|
||||
// FieldValue fieldValue1(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
|
||||
// Value((int32_t)111));
|
||||
// HashableDimensionKey whatKey1({fieldValue1});
|
||||
// MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
|
||||
//
|
||||
// FieldValue fieldValue2(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
|
||||
// Value((int32_t)222));
|
||||
// HashableDimensionKey whatKey2({fieldValue2});
|
||||
// MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
|
||||
//
|
||||
// auto event = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 2);
|
||||
// processor->OnLogEvent(event.get());
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(attributions1, "wl2", bucketStartTimeNs + bucketSizeNs + 2);
|
||||
// processor->OnLogEvent(event.get());
|
||||
//
|
||||
// event = CreateAcquireWakelockEvent(
|
||||
// attributions1, "wl1", bucketStartTimeNs + 25 * bucketSizeNs + 2);
|
||||
// processor->OnLogEvent(event.get());
|
||||
//
|
||||
// EXPECT_EQ((int64_t)(bucketStartTimeNs + 25 * bucketSizeNs + 2 + 2 * 3600 * NS_PER_SEC),
|
||||
// processor->mMetricsManagers.begin()->second->getTtlEndNs());
|
||||
//
|
||||
// // Clear the data stored on disk as a result of the ttl.
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 25 * bucketSizeNs + 3, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
//}
|
||||
TEST(ConfigTtlE2eTest, TestCountMetric) {
|
||||
const int num_buckets = 1;
|
||||
const int threshold = 3;
|
||||
auto config = CreateStatsdConfig(num_buckets, threshold);
|
||||
const uint64_t alert_id = config.alert(0).id();
|
||||
const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
|
||||
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
|
||||
std::vector<int> attributionUids1 = {111};
|
||||
std::vector<string> attributionTags1 = {"App1"};
|
||||
|
||||
FieldValue fieldValue1(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
|
||||
Value((int32_t)111));
|
||||
HashableDimensionKey whatKey1({fieldValue1});
|
||||
MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
|
||||
|
||||
FieldValue fieldValue2(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
|
||||
Value((int32_t)222));
|
||||
HashableDimensionKey whatKey2({fieldValue2});
|
||||
MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
|
||||
|
||||
auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
|
||||
attributionTags1, "wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids1,
|
||||
attributionTags1, "wl2");
|
||||
processor->OnLogEvent(event.get());
|
||||
|
||||
event = CreateAcquireWakelockEvent(bucketStartTimeNs + 25 * bucketSizeNs + 2, attributionUids1,
|
||||
attributionTags1, "wl1");
|
||||
processor->OnLogEvent(event.get());
|
||||
|
||||
EXPECT_EQ((int64_t)(bucketStartTimeNs + 25 * bucketSizeNs + 2 + 2 * 3600 * NS_PER_SEC),
|
||||
processor->mMetricsManagers.begin()->second->getTtlEndNs());
|
||||
|
||||
// Clear the data stored on disk as a result of the ttl.
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 25 * bucketSizeNs + 3, false, true,
|
||||
ADB_DUMP, FAST, &buffer);
|
||||
}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -65,482 +65,465 @@ StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type,
|
||||
|
||||
} // namespaces
|
||||
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) {
|
||||
// auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
|
||||
// int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
// int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
// SharedRefBase::make<FakeSubsystemSleepCallback>(),
|
||||
// ATOM_TAG);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// processor->mPullerManager->ForceClearPullerCache();
|
||||
//
|
||||
// int startBucketNum = processor->mMetricsManagers.begin()->second->
|
||||
// mAllMetricProducers[0]->getCurrentBucketNum();
|
||||
// EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
//
|
||||
// // When creating the config, the gauge metric producer should register the alarm at the
|
||||
// // end of the current bucket.
|
||||
// EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
// EXPECT_EQ(bucketSizeNs,
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
// int64_t& nextPullTimeNs =
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
|
||||
//
|
||||
// auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 55);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// // Pulling alarm arrives on time and reset the sequential pulling alarm.
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + 1);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
|
||||
//
|
||||
// auto screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
|
||||
// configAddedTimeNs + bucketSizeNs + 10);
|
||||
// processor->OnLogEvent(screenOnEvent.get());
|
||||
//
|
||||
// screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + bucketSizeNs + 100);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + 1);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs,
|
||||
// nextPullTimeNs);
|
||||
//
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + 1);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
|
||||
//
|
||||
// screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
|
||||
// configAddedTimeNs + 3 * bucketSizeNs + 2);
|
||||
// processor->OnLogEvent(screenOnEvent.get());
|
||||
//
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + 3);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
|
||||
//
|
||||
// screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 5 * bucketSizeNs + 1);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + 2);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, nextPullTimeNs);
|
||||
//
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + 2);
|
||||
//
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(1, reports.reports_size());
|
||||
// EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
// StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
|
||||
// sortMetricDataByDimensionsValue(
|
||||
// reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
|
||||
// EXPECT_GT((int)gaugeMetrics.data_size(), 1);
|
||||
//
|
||||
// auto data = gaugeMetrics.data(0);
|
||||
// EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
|
||||
// EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
// EXPECT_EQ(1 /* subsystem name field */,
|
||||
// data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
// EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
// EXPECT_EQ(6, data.bucket_info_size());
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(0).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(1).atom_size());
|
||||
// EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1,
|
||||
// data.bucket_info(1).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(2).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1,
|
||||
// data.bucket_info(2).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(3).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(3).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 1,
|
||||
// data.bucket_info(3).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(3).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(3).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(4).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(4).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1,
|
||||
// data.bucket_info(4).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(4).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(4).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(5).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(5).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs + 2,
|
||||
// data.bucket_info(5).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(5).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(5).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(5).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(5).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//}
|
||||
//
|
||||
//TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) {
|
||||
// auto config = CreateStatsdConfig(GaugeMetric::CONDITION_CHANGE_TO_TRUE);
|
||||
// int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
// int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
// SharedRefBase::make<FakeSubsystemSleepCallback>(),
|
||||
// ATOM_TAG);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// processor->mPullerManager->ForceClearPullerCache();
|
||||
//
|
||||
// int startBucketNum = processor->mMetricsManagers.begin()->second->
|
||||
// mAllMetricProducers[0]->getCurrentBucketNum();
|
||||
// EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
//
|
||||
// auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 55);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// auto screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
|
||||
// configAddedTimeNs + bucketSizeNs + 10);
|
||||
// processor->OnLogEvent(screenOnEvent.get());
|
||||
//
|
||||
// screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + bucketSizeNs + 100);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
|
||||
// configAddedTimeNs + 3 * bucketSizeNs + 2);
|
||||
// processor->OnLogEvent(screenOnEvent.get());
|
||||
//
|
||||
// screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 5 * bucketSizeNs + 1);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
// screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
|
||||
// configAddedTimeNs + 5 * bucketSizeNs + 3);
|
||||
// processor->OnLogEvent(screenOnEvent.get());
|
||||
// screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 5 * bucketSizeNs + 10);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(1, reports.reports_size());
|
||||
// EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
// StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
|
||||
// sortMetricDataByDimensionsValue(
|
||||
// reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
|
||||
// EXPECT_GT((int)gaugeMetrics.data_size(), 1);
|
||||
//
|
||||
// auto data = gaugeMetrics.data(0);
|
||||
// EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
|
||||
// EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
// EXPECT_EQ(1 /* subsystem name field */,
|
||||
// data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
// EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
// EXPECT_EQ(3, data.bucket_info_size());
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(0).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(1).atom_size());
|
||||
// EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 100,
|
||||
// data.bucket_info(1).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//
|
||||
// EXPECT_EQ(2, data.bucket_info(2).atom_size());
|
||||
// EXPECT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1,
|
||||
// data.bucket_info(2).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 10,
|
||||
// data.bucket_info(2).elapsed_timestamp_nanos(1));
|
||||
// EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
// EXPECT_TRUE(data.bucket_info(2).atom(1).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(2).atom(1).subsystem_sleep_state().time_millis(), 0);
|
||||
//}
|
||||
//
|
||||
//
|
||||
//TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) {
|
||||
// auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
|
||||
// int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
// int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
// SharedRefBase::make<FakeSubsystemSleepCallback>(),
|
||||
// ATOM_TAG);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// processor->mPullerManager->ForceClearPullerCache();
|
||||
//
|
||||
// int startBucketNum = processor->mMetricsManagers.begin()->second->
|
||||
// mAllMetricProducers[0]->getCurrentBucketNum();
|
||||
// EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
//
|
||||
// // When creating the config, the gauge metric producer should register the alarm at the
|
||||
// // end of the current bucket.
|
||||
// EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
// EXPECT_EQ(bucketSizeNs,
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
// int64_t& nextPullTimeNs =
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
|
||||
//
|
||||
// auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 55);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// auto screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
|
||||
// configAddedTimeNs + bucketSizeNs + 10);
|
||||
// processor->OnLogEvent(screenOnEvent.get());
|
||||
//
|
||||
// // Pulling alarm arrives one bucket size late.
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
|
||||
//
|
||||
// screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 3 * bucketSizeNs + 11);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// // Pulling alarm arrives more than one bucket size late.
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs + 12);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
|
||||
//
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(1, reports.reports_size());
|
||||
// EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
// StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
|
||||
// sortMetricDataByDimensionsValue(
|
||||
// reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
|
||||
// EXPECT_GT((int)gaugeMetrics.data_size(), 1);
|
||||
//
|
||||
// auto data = gaugeMetrics.data(0);
|
||||
// EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
|
||||
// EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
// EXPECT_EQ(1 /* subsystem name field */,
|
||||
// data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
// EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
// EXPECT_EQ(3, data.bucket_info_size());
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(0).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(1).atom_size());
|
||||
// EXPECT_EQ(configAddedTimeNs + 3 * bucketSizeNs + 11,
|
||||
// data.bucket_info(1).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(2).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs + 12,
|
||||
// data.bucket_info(2).elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//}
|
||||
//
|
||||
//TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation) {
|
||||
// auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
|
||||
//
|
||||
// int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
// int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
|
||||
// *config.add_atom_matcher() = batterySaverStartMatcher;
|
||||
// const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets.
|
||||
// auto metric_activation = config.add_metric_activation();
|
||||
// metric_activation->set_metric_id(metricId);
|
||||
// metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
|
||||
// auto event_activation = metric_activation->add_event_activation();
|
||||
// event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
|
||||
// event_activation->set_ttl_seconds(ttlNs / 1000000000);
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
// SharedRefBase::make<FakeSubsystemSleepCallback>(),
|
||||
// ATOM_TAG);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// processor->mPullerManager->ForceClearPullerCache();
|
||||
//
|
||||
// int startBucketNum = processor->mMetricsManagers.begin()->second->
|
||||
// mAllMetricProducers[0]->getCurrentBucketNum();
|
||||
// EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
// EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
//
|
||||
// // When creating the config, the gauge metric producer should register the alarm at the
|
||||
// // end of the current bucket.
|
||||
// EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
// EXPECT_EQ(bucketSizeNs,
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
// int64_t& nextPullTimeNs =
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
|
||||
//
|
||||
// // Pulling alarm arrives on time and reset the sequential pulling alarm.
|
||||
// // Event should not be kept.
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + 1); // 15 mins + 1 ns.
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
|
||||
// EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
//
|
||||
// // Activate the metric. A pull occurs upon activation.
|
||||
// const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
|
||||
// auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
|
||||
// processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
//
|
||||
// // This event should be kept. 2 total.
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + 1); // 20 mins + 1 ns.
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs,
|
||||
// nextPullTimeNs);
|
||||
//
|
||||
// // This event should be kept. 3 total.
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + 2); // 25 mins + 2 ns.
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
|
||||
//
|
||||
// // Create random event to deactivate metric.
|
||||
// auto deactivationEvent = CreateScreenBrightnessChangedEvent(50, activationNs + ttlNs + 1);
|
||||
// processor->OnLogEvent(deactivationEvent.get());
|
||||
// EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
//
|
||||
// // Event should not be kept. 3 total.
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + 3);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
|
||||
//
|
||||
// processor->informPullAlarmFired(nextPullTimeNs + 2);
|
||||
//
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(1, reports.reports_size());
|
||||
// EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
// StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
|
||||
// sortMetricDataByDimensionsValue(
|
||||
// reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
|
||||
// EXPECT_GT((int)gaugeMetrics.data_size(), 0);
|
||||
//
|
||||
// auto data = gaugeMetrics.data(0);
|
||||
// EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
|
||||
// EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
// EXPECT_EQ(1 /* subsystem name field */,
|
||||
// data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
// EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
// EXPECT_EQ(3, data.bucket_info_size());
|
||||
//
|
||||
// auto bucketInfo = data.bucket_info(0);
|
||||
// EXPECT_EQ(1, bucketInfo.atom_size());
|
||||
// EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(activationNs, bucketInfo.elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//
|
||||
// bucketInfo = data.bucket_info(1);
|
||||
// EXPECT_EQ(1, bucketInfo.atom_size());
|
||||
// EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, bucketInfo.elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//
|
||||
// bucketInfo = data.bucket_info(2);
|
||||
// EXPECT_EQ(1, bucketInfo.atom_size());
|
||||
// EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, bucketInfo.elapsed_timestamp_nanos(0));
|
||||
// EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
|
||||
// EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
|
||||
// bucketInfo.start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(MillisToNano(NanoToMillis(activationNs + ttlNs + 1)),
|
||||
// bucketInfo.end_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
// EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
//}
|
||||
TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) {
|
||||
auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
|
||||
int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor =
|
||||
CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
processor->mPullerManager->ForceClearPullerCache();
|
||||
|
||||
int startBucketNum = processor->mMetricsManagers.begin()
|
||||
->second->mAllMetricProducers[0]
|
||||
->getCurrentBucketNum();
|
||||
EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
|
||||
// When creating the config, the gauge metric producer should register the alarm at the
|
||||
// end of the current bucket.
|
||||
EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
EXPECT_EQ(bucketSizeNs,
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
int64_t& nextPullTimeNs =
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
auto screenOffEvent =
|
||||
CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
// Pulling alarm arrives on time and reset the sequential pulling alarm.
|
||||
processor->informPullAlarmFired(nextPullTimeNs + 1);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
|
||||
android::view::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screenOnEvent.get());
|
||||
|
||||
screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
|
||||
android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
processor->informPullAlarmFired(nextPullTimeNs + 1);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
processor->informPullAlarmFired(nextPullTimeNs + 1);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 2,
|
||||
android::view::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screenOnEvent.get());
|
||||
|
||||
processor->informPullAlarmFired(nextPullTimeNs + 3);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 1,
|
||||
android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
processor->informPullAlarmFired(nextPullTimeNs + 2);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
processor->informPullAlarmFired(nextPullTimeNs + 2);
|
||||
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
|
||||
ADB_DUMP, FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(1, reports.reports_size());
|
||||
EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
|
||||
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
|
||||
EXPECT_GT((int)gaugeMetrics.data_size(), 1);
|
||||
|
||||
auto data = gaugeMetrics.data(0);
|
||||
EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
|
||||
EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
EXPECT_EQ(1 /* subsystem name field */,
|
||||
data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
EXPECT_EQ(6, data.bucket_info_size());
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(0).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(1).atom_size());
|
||||
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(2).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(3).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(3).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 1, data.bucket_info(3).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(3).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(3).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(4).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(4).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(4).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(4).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(4).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(5).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(5).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs + 2, data.bucket_info(5).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(5).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(5).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(5).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(5).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
}
|
||||
|
||||
TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) {
|
||||
auto config = CreateStatsdConfig(GaugeMetric::CONDITION_CHANGE_TO_TRUE);
|
||||
int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor =
|
||||
CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
processor->mPullerManager->ForceClearPullerCache();
|
||||
|
||||
int startBucketNum = processor->mMetricsManagers.begin()
|
||||
->second->mAllMetricProducers[0]
|
||||
->getCurrentBucketNum();
|
||||
EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
|
||||
auto screenOffEvent =
|
||||
CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
|
||||
android::view::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screenOnEvent.get());
|
||||
|
||||
screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
|
||||
android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 2,
|
||||
android::view::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screenOnEvent.get());
|
||||
|
||||
screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 1,
|
||||
android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 3,
|
||||
android::view::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screenOnEvent.get());
|
||||
screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 10,
|
||||
android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, true,
|
||||
ADB_DUMP, FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(1, reports.reports_size());
|
||||
EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
|
||||
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
|
||||
EXPECT_GT((int)gaugeMetrics.data_size(), 1);
|
||||
|
||||
auto data = gaugeMetrics.data(0);
|
||||
EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
|
||||
EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
EXPECT_EQ(1 /* subsystem name field */,
|
||||
data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
EXPECT_EQ(3, data.bucket_info_size());
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(0).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(1).atom_size());
|
||||
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 100, data.bucket_info(1).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
|
||||
EXPECT_EQ(2, data.bucket_info(2).atom_size());
|
||||
EXPECT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 10, data.bucket_info(2).elapsed_timestamp_nanos(1));
|
||||
EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
EXPECT_TRUE(data.bucket_info(2).atom(1).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(2).atom(1).subsystem_sleep_state().time_millis(), 0);
|
||||
}
|
||||
|
||||
TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) {
|
||||
auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
|
||||
int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor =
|
||||
CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
processor->mPullerManager->ForceClearPullerCache();
|
||||
|
||||
int startBucketNum = processor->mMetricsManagers.begin()
|
||||
->second->mAllMetricProducers[0]
|
||||
->getCurrentBucketNum();
|
||||
EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
|
||||
// When creating the config, the gauge metric producer should register the alarm at the
|
||||
// end of the current bucket.
|
||||
EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
EXPECT_EQ(bucketSizeNs,
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
int64_t& nextPullTimeNs =
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
auto screenOffEvent =
|
||||
CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
|
||||
android::view::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screenOnEvent.get());
|
||||
|
||||
// Pulling alarm arrives one bucket size late.
|
||||
processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 11,
|
||||
android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
// Pulling alarm arrives more than one bucket size late.
|
||||
processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs + 12);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
|
||||
ADB_DUMP, FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(1, reports.reports_size());
|
||||
EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
|
||||
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
|
||||
EXPECT_GT((int)gaugeMetrics.data_size(), 1);
|
||||
|
||||
auto data = gaugeMetrics.data(0);
|
||||
EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
|
||||
EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
EXPECT_EQ(1 /* subsystem name field */,
|
||||
data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
EXPECT_EQ(3, data.bucket_info_size());
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(0).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(1).atom_size());
|
||||
EXPECT_EQ(configAddedTimeNs + 3 * bucketSizeNs + 11,
|
||||
data.bucket_info(1).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(2).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs + 12, data.bucket_info(2).elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
}
|
||||
|
||||
TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation) {
|
||||
auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
|
||||
|
||||
int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
|
||||
|
||||
auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
|
||||
*config.add_atom_matcher() = batterySaverStartMatcher;
|
||||
const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets.
|
||||
auto metric_activation = config.add_metric_activation();
|
||||
metric_activation->set_metric_id(metricId);
|
||||
metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
|
||||
auto event_activation = metric_activation->add_event_activation();
|
||||
event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
|
||||
event_activation->set_ttl_seconds(ttlNs / 1000000000);
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor =
|
||||
CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
processor->mPullerManager->ForceClearPullerCache();
|
||||
|
||||
int startBucketNum = processor->mMetricsManagers.begin()
|
||||
->second->mAllMetricProducers[0]
|
||||
->getCurrentBucketNum();
|
||||
EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
|
||||
// When creating the config, the gauge metric producer should register the alarm at the
|
||||
// end of the current bucket.
|
||||
EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
EXPECT_EQ(bucketSizeNs,
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
int64_t& nextPullTimeNs =
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
// Pulling alarm arrives on time and reset the sequential pulling alarm.
|
||||
// Event should not be kept.
|
||||
processor->informPullAlarmFired(nextPullTimeNs + 1); // 15 mins + 1 ns.
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
|
||||
EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
|
||||
// Activate the metric. A pull occurs upon activation.
|
||||
const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
|
||||
auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
|
||||
processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
|
||||
// This event should be kept. 2 total.
|
||||
processor->informPullAlarmFired(nextPullTimeNs + 1); // 20 mins + 1 ns.
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
// This event should be kept. 3 total.
|
||||
processor->informPullAlarmFired(nextPullTimeNs + 2); // 25 mins + 2 ns.
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
// Create random event to deactivate metric.
|
||||
auto deactivationEvent = CreateScreenBrightnessChangedEvent(activationNs + ttlNs + 1, 50);
|
||||
processor->OnLogEvent(deactivationEvent.get());
|
||||
EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
|
||||
// Event should not be kept. 3 total.
|
||||
processor->informPullAlarmFired(nextPullTimeNs + 3);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
|
||||
|
||||
processor->informPullAlarmFired(nextPullTimeNs + 2);
|
||||
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
|
||||
ADB_DUMP, FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(1, reports.reports_size());
|
||||
EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
|
||||
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
|
||||
EXPECT_GT((int)gaugeMetrics.data_size(), 0);
|
||||
|
||||
auto data = gaugeMetrics.data(0);
|
||||
EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
|
||||
EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
EXPECT_EQ(1 /* subsystem name field */,
|
||||
data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
EXPECT_EQ(3, data.bucket_info_size());
|
||||
|
||||
auto bucketInfo = data.bucket_info(0);
|
||||
EXPECT_EQ(1, bucketInfo.atom_size());
|
||||
EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(activationNs, bucketInfo.elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
|
||||
bucketInfo = data.bucket_info(1);
|
||||
EXPECT_EQ(1, bucketInfo.atom_size());
|
||||
EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, bucketInfo.elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
|
||||
bucketInfo = data.bucket_info(2);
|
||||
EXPECT_EQ(1, bucketInfo.atom_size());
|
||||
EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, bucketInfo.elapsed_timestamp_nanos(0));
|
||||
EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
|
||||
EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
|
||||
bucketInfo.start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(MillisToNano(NanoToMillis(activationNs + ttlNs + 1)),
|
||||
bucketInfo.end_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
|
||||
EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
|
||||
}
|
||||
|
||||
TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition) {
|
||||
auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
|
||||
|
||||
@@ -14,12 +14,13 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "src/StatsLogProcessor.h"
|
||||
#include "src/stats_log_util.h"
|
||||
#include "stats_event.h"
|
||||
#include "tests/statsd_test_util.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace android {
|
||||
namespace os {
|
||||
namespace statsd {
|
||||
@@ -68,221 +69,227 @@ StatsdConfig CreateStatsdConfigForPushedEvent(const GaugeMetric::SamplingType sa
|
||||
return config;
|
||||
}
|
||||
|
||||
// TODO(b/149590301): Update this helper to use new socket schema.
|
||||
//std::unique_ptr<LogEvent> CreateAppStartOccurredEvent(
|
||||
// const int uid, const string& pkg_name, AppStartOccurred::TransitionType type,
|
||||
// const string& activity_name, const string& calling_pkg_name, const bool is_instant_app,
|
||||
// int64_t activity_start_msec, uint64_t timestampNs) {
|
||||
// auto logEvent = std::make_unique<LogEvent>(
|
||||
// android::util::APP_START_OCCURRED, timestampNs);
|
||||
// logEvent->write(uid);
|
||||
// logEvent->write(pkg_name);
|
||||
// logEvent->write(type);
|
||||
// logEvent->write(activity_name);
|
||||
// logEvent->write(calling_pkg_name);
|
||||
// logEvent->write(is_instant_app);
|
||||
// logEvent->write(activity_start_msec);
|
||||
// logEvent->init();
|
||||
// return logEvent;
|
||||
//}
|
||||
std::unique_ptr<LogEvent> CreateAppStartOccurredEvent(
|
||||
uint64_t timestampNs, const int uid, const string& pkg_name,
|
||||
AppStartOccurred::TransitionType type, const string& activity_name,
|
||||
const string& calling_pkg_name, const bool is_instant_app, int64_t activity_start_msec) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::APP_START_OCCURRED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, uid);
|
||||
AStatsEvent_writeString(statsEvent, pkg_name.c_str());
|
||||
AStatsEvent_writeInt32(statsEvent, type);
|
||||
AStatsEvent_writeString(statsEvent, activity_name.c_str());
|
||||
AStatsEvent_writeString(statsEvent, calling_pkg_name.c_str());
|
||||
AStatsEvent_writeInt32(statsEvent, is_instant_app);
|
||||
AStatsEvent_writeInt32(statsEvent, activity_start_msec);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
|
||||
// for (const auto& sampling_type :
|
||||
// { GaugeMetric::FIRST_N_SAMPLES, GaugeMetric:: RANDOM_ONE_SAMPLE }) {
|
||||
// auto config = CreateStatsdConfigForPushedEvent(sampling_type);
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(
|
||||
// bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
//
|
||||
// int appUid1 = 123;
|
||||
// int appUid2 = 456;
|
||||
// std::vector<std::unique_ptr<LogEvent>> events;
|
||||
// events.push_back(CreateMoveToBackgroundEvent(appUid1, bucketStartTimeNs + 15));
|
||||
// events.push_back(CreateMoveToForegroundEvent(
|
||||
// appUid1, bucketStartTimeNs + bucketSizeNs + 250));
|
||||
// events.push_back(CreateMoveToBackgroundEvent(
|
||||
// appUid1, bucketStartTimeNs + bucketSizeNs + 350));
|
||||
// events.push_back(CreateMoveToForegroundEvent(
|
||||
// appUid1, bucketStartTimeNs + 2 * bucketSizeNs + 100));
|
||||
//
|
||||
//
|
||||
// events.push_back(CreateAppStartOccurredEvent(
|
||||
// appUid1, "app1", AppStartOccurred::WARM, "activity_name1", "calling_pkg_name1",
|
||||
// true /*is_instant_app*/, 101 /*activity_start_msec*/, bucketStartTimeNs + 10));
|
||||
// events.push_back(CreateAppStartOccurredEvent(
|
||||
// appUid1, "app1", AppStartOccurred::HOT, "activity_name2", "calling_pkg_name2",
|
||||
// true /*is_instant_app*/, 102 /*activity_start_msec*/, bucketStartTimeNs + 20));
|
||||
// events.push_back(CreateAppStartOccurredEvent(
|
||||
// appUid1, "app1", AppStartOccurred::COLD, "activity_name3", "calling_pkg_name3",
|
||||
// true /*is_instant_app*/, 103 /*activity_start_msec*/, bucketStartTimeNs + 30));
|
||||
// events.push_back(CreateAppStartOccurredEvent(
|
||||
// appUid1, "app1", AppStartOccurred::WARM, "activity_name4", "calling_pkg_name4",
|
||||
// true /*is_instant_app*/, 104 /*activity_start_msec*/,
|
||||
// bucketStartTimeNs + bucketSizeNs + 30));
|
||||
// events.push_back(CreateAppStartOccurredEvent(
|
||||
// appUid1, "app1", AppStartOccurred::COLD, "activity_name5", "calling_pkg_name5",
|
||||
// true /*is_instant_app*/, 105 /*activity_start_msec*/,
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs));
|
||||
// events.push_back(CreateAppStartOccurredEvent(
|
||||
// appUid1, "app1", AppStartOccurred::HOT, "activity_name6", "calling_pkg_name6",
|
||||
// false /*is_instant_app*/, 106 /*activity_start_msec*/,
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs + 10));
|
||||
//
|
||||
// events.push_back(CreateMoveToBackgroundEvent(
|
||||
// appUid2, bucketStartTimeNs + bucketSizeNs + 10));
|
||||
// events.push_back(CreateAppStartOccurredEvent(
|
||||
// appUid2, "app2", AppStartOccurred::COLD, "activity_name7", "calling_pkg_name7",
|
||||
// true /*is_instant_app*/, 201 /*activity_start_msec*/,
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs + 10));
|
||||
//
|
||||
// sortLogEventsByTimestamp(&events);
|
||||
//
|
||||
// for (const auto& event : events) {
|
||||
// processor->OnLogEvent(event.get());
|
||||
// }
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(1, reports.reports_size());
|
||||
// EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
// StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
|
||||
// sortMetricDataByDimensionsValue(
|
||||
// reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
|
||||
// EXPECT_EQ(2, gaugeMetrics.data_size());
|
||||
//
|
||||
// auto data = gaugeMetrics.data(0);
|
||||
// EXPECT_EQ(android::util::APP_START_OCCURRED, data.dimensions_in_what().field());
|
||||
// EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
// EXPECT_EQ(1 /* uid field */,
|
||||
// data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
// EXPECT_EQ(appUid1, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
|
||||
// EXPECT_EQ(3, data.bucket_info_size());
|
||||
// if (sampling_type == GaugeMetric::FIRST_N_SAMPLES) {
|
||||
// EXPECT_EQ(2, data.bucket_info(0).atom_size());
|
||||
// EXPECT_EQ(2, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
|
||||
// EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
// data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(AppStartOccurred::HOT,
|
||||
// data.bucket_info(0).atom(0).app_start_occurred().type());
|
||||
// EXPECT_EQ("activity_name2",
|
||||
// data.bucket_info(0).atom(0).app_start_occurred().activity_name());
|
||||
// EXPECT_EQ(102L,
|
||||
// data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
|
||||
// EXPECT_EQ(AppStartOccurred::COLD,
|
||||
// data.bucket_info(0).atom(1).app_start_occurred().type());
|
||||
// EXPECT_EQ("activity_name3",
|
||||
// data.bucket_info(0).atom(1).app_start_occurred().activity_name());
|
||||
// EXPECT_EQ(103L,
|
||||
// data.bucket_info(0).atom(1).app_start_occurred().activity_start_millis());
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(1).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
// data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
// data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(AppStartOccurred::WARM,
|
||||
// data.bucket_info(1).atom(0).app_start_occurred().type());
|
||||
// EXPECT_EQ("activity_name4",
|
||||
// data.bucket_info(1).atom(0).app_start_occurred().activity_name());
|
||||
// EXPECT_EQ(104L,
|
||||
// data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
|
||||
//
|
||||
// EXPECT_EQ(2, data.bucket_info(2).atom_size());
|
||||
// EXPECT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
// data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
// data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(AppStartOccurred::COLD,
|
||||
// data.bucket_info(2).atom(0).app_start_occurred().type());
|
||||
// EXPECT_EQ("activity_name5",
|
||||
// data.bucket_info(2).atom(0).app_start_occurred().activity_name());
|
||||
// EXPECT_EQ(105L,
|
||||
// data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
|
||||
// EXPECT_EQ(AppStartOccurred::HOT,
|
||||
// data.bucket_info(2).atom(1).app_start_occurred().type());
|
||||
// EXPECT_EQ("activity_name6",
|
||||
// data.bucket_info(2).atom(1).app_start_occurred().activity_name());
|
||||
// EXPECT_EQ(106L,
|
||||
// data.bucket_info(2).atom(1).app_start_occurred().activity_start_millis());
|
||||
// } else {
|
||||
// EXPECT_EQ(1, data.bucket_info(0).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
// data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(AppStartOccurred::HOT,
|
||||
// data.bucket_info(0).atom(0).app_start_occurred().type());
|
||||
// EXPECT_EQ("activity_name2",
|
||||
// data.bucket_info(0).atom(0).app_start_occurred().activity_name());
|
||||
// EXPECT_EQ(102L,
|
||||
// data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(1).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
// data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
// data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(AppStartOccurred::WARM,
|
||||
// data.bucket_info(1).atom(0).app_start_occurred().type());
|
||||
// EXPECT_EQ("activity_name4",
|
||||
// data.bucket_info(1).atom(0).app_start_occurred().activity_name());
|
||||
// EXPECT_EQ(104L,
|
||||
// data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
|
||||
//
|
||||
// EXPECT_EQ(1, data.bucket_info(2).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
// data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
// data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(AppStartOccurred::COLD,
|
||||
// data.bucket_info(2).atom(0).app_start_occurred().type());
|
||||
// EXPECT_EQ("activity_name5",
|
||||
// data.bucket_info(2).atom(0).app_start_occurred().activity_name());
|
||||
// EXPECT_EQ(105L,
|
||||
// data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
|
||||
// }
|
||||
//
|
||||
// data = gaugeMetrics.data(1);
|
||||
//
|
||||
// EXPECT_EQ(data.dimensions_in_what().field(), android::util::APP_START_OCCURRED);
|
||||
// EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
|
||||
// EXPECT_EQ(1 /* uid field */,
|
||||
// data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
// EXPECT_EQ(appUid2, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
|
||||
// EXPECT_EQ(1, data.bucket_info_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(0).atom_size());
|
||||
// EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
// data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
// data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(AppStartOccurred::COLD, data.bucket_info(0).atom(0).app_start_occurred().type());
|
||||
// EXPECT_EQ("activity_name7",
|
||||
// data.bucket_info(0).atom(0).app_start_occurred().activity_name());
|
||||
// EXPECT_EQ(201L, data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
|
||||
// }
|
||||
//}
|
||||
TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
|
||||
for (const auto& sampling_type :
|
||||
{GaugeMetric::FIRST_N_SAMPLES, GaugeMetric::RANDOM_ONE_SAMPLE}) {
|
||||
auto config = CreateStatsdConfigForPushedEvent(sampling_type);
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor =
|
||||
CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
|
||||
int appUid1 = 123;
|
||||
int appUid2 = 456;
|
||||
std::vector<std::unique_ptr<LogEvent>> events;
|
||||
events.push_back(CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid1));
|
||||
events.push_back(
|
||||
CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid1));
|
||||
events.push_back(
|
||||
CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid1));
|
||||
events.push_back(
|
||||
CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100, appUid1));
|
||||
|
||||
events.push_back(CreateAppStartOccurredEvent(
|
||||
bucketStartTimeNs + 10, appUid1, "app1", AppStartOccurred::WARM, "activity_name1",
|
||||
"calling_pkg_name1", true /*is_instant_app*/, 101 /*activity_start_msec*/));
|
||||
events.push_back(CreateAppStartOccurredEvent(
|
||||
bucketStartTimeNs + 20, appUid1, "app1", AppStartOccurred::HOT, "activity_name2",
|
||||
"calling_pkg_name2", true /*is_instant_app*/, 102 /*activity_start_msec*/));
|
||||
events.push_back(CreateAppStartOccurredEvent(
|
||||
bucketStartTimeNs + 30, appUid1, "app1", AppStartOccurred::COLD, "activity_name3",
|
||||
"calling_pkg_name3", true /*is_instant_app*/, 103 /*activity_start_msec*/));
|
||||
events.push_back(CreateAppStartOccurredEvent(
|
||||
bucketStartTimeNs + bucketSizeNs + 30, appUid1, "app1", AppStartOccurred::WARM,
|
||||
"activity_name4", "calling_pkg_name4", true /*is_instant_app*/,
|
||||
104 /*activity_start_msec*/));
|
||||
events.push_back(CreateAppStartOccurredEvent(
|
||||
bucketStartTimeNs + 2 * bucketSizeNs, appUid1, "app1", AppStartOccurred::COLD,
|
||||
"activity_name5", "calling_pkg_name5", true /*is_instant_app*/,
|
||||
105 /*activity_start_msec*/));
|
||||
events.push_back(CreateAppStartOccurredEvent(
|
||||
bucketStartTimeNs + 2 * bucketSizeNs + 10, appUid1, "app1", AppStartOccurred::HOT,
|
||||
"activity_name6", "calling_pkg_name6", false /*is_instant_app*/,
|
||||
106 /*activity_start_msec*/));
|
||||
|
||||
events.push_back(
|
||||
CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 10, appUid2));
|
||||
events.push_back(CreateAppStartOccurredEvent(
|
||||
bucketStartTimeNs + 2 * bucketSizeNs + 10, appUid2, "app2", AppStartOccurred::COLD,
|
||||
"activity_name7", "calling_pkg_name7", true /*is_instant_app*/,
|
||||
201 /*activity_start_msec*/));
|
||||
|
||||
sortLogEventsByTimestamp(&events);
|
||||
|
||||
for (const auto& event : events) {
|
||||
processor->OnLogEvent(event.get());
|
||||
}
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, false, true, ADB_DUMP,
|
||||
FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(1, reports.reports_size());
|
||||
EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
|
||||
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(),
|
||||
&gaugeMetrics);
|
||||
EXPECT_EQ(2, gaugeMetrics.data_size());
|
||||
|
||||
auto data = gaugeMetrics.data(0);
|
||||
EXPECT_EQ(android::util::APP_START_OCCURRED, data.dimensions_in_what().field());
|
||||
EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
EXPECT_EQ(1 /* uid field */,
|
||||
data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
EXPECT_EQ(appUid1, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
|
||||
EXPECT_EQ(3, data.bucket_info_size());
|
||||
if (sampling_type == GaugeMetric::FIRST_N_SAMPLES) {
|
||||
EXPECT_EQ(2, data.bucket_info(0).atom_size());
|
||||
EXPECT_EQ(2, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
|
||||
EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(AppStartOccurred::HOT,
|
||||
data.bucket_info(0).atom(0).app_start_occurred().type());
|
||||
EXPECT_EQ("activity_name2",
|
||||
data.bucket_info(0).atom(0).app_start_occurred().activity_name());
|
||||
EXPECT_EQ(102L,
|
||||
data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
|
||||
EXPECT_EQ(AppStartOccurred::COLD,
|
||||
data.bucket_info(0).atom(1).app_start_occurred().type());
|
||||
EXPECT_EQ("activity_name3",
|
||||
data.bucket_info(0).atom(1).app_start_occurred().activity_name());
|
||||
EXPECT_EQ(103L,
|
||||
data.bucket_info(0).atom(1).app_start_occurred().activity_start_millis());
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(1).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(AppStartOccurred::WARM,
|
||||
data.bucket_info(1).atom(0).app_start_occurred().type());
|
||||
EXPECT_EQ("activity_name4",
|
||||
data.bucket_info(1).atom(0).app_start_occurred().activity_name());
|
||||
EXPECT_EQ(104L,
|
||||
data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
|
||||
|
||||
EXPECT_EQ(2, data.bucket_info(2).atom_size());
|
||||
EXPECT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(AppStartOccurred::COLD,
|
||||
data.bucket_info(2).atom(0).app_start_occurred().type());
|
||||
EXPECT_EQ("activity_name5",
|
||||
data.bucket_info(2).atom(0).app_start_occurred().activity_name());
|
||||
EXPECT_EQ(105L,
|
||||
data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
|
||||
EXPECT_EQ(AppStartOccurred::HOT,
|
||||
data.bucket_info(2).atom(1).app_start_occurred().type());
|
||||
EXPECT_EQ("activity_name6",
|
||||
data.bucket_info(2).atom(1).app_start_occurred().activity_name());
|
||||
EXPECT_EQ(106L,
|
||||
data.bucket_info(2).atom(1).app_start_occurred().activity_start_millis());
|
||||
} else {
|
||||
EXPECT_EQ(1, data.bucket_info(0).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(AppStartOccurred::HOT,
|
||||
data.bucket_info(0).atom(0).app_start_occurred().type());
|
||||
EXPECT_EQ("activity_name2",
|
||||
data.bucket_info(0).atom(0).app_start_occurred().activity_name());
|
||||
EXPECT_EQ(102L,
|
||||
data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(1).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(AppStartOccurred::WARM,
|
||||
data.bucket_info(1).atom(0).app_start_occurred().type());
|
||||
EXPECT_EQ("activity_name4",
|
||||
data.bucket_info(1).atom(0).app_start_occurred().activity_name());
|
||||
EXPECT_EQ(104L,
|
||||
data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
|
||||
|
||||
EXPECT_EQ(1, data.bucket_info(2).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(AppStartOccurred::COLD,
|
||||
data.bucket_info(2).atom(0).app_start_occurred().type());
|
||||
EXPECT_EQ("activity_name5",
|
||||
data.bucket_info(2).atom(0).app_start_occurred().activity_name());
|
||||
EXPECT_EQ(105L,
|
||||
data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
|
||||
}
|
||||
|
||||
data = gaugeMetrics.data(1);
|
||||
|
||||
EXPECT_EQ(data.dimensions_in_what().field(), android::util::APP_START_OCCURRED);
|
||||
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
|
||||
EXPECT_EQ(1 /* uid field */,
|
||||
data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
EXPECT_EQ(appUid2, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
|
||||
EXPECT_EQ(1, data.bucket_info_size());
|
||||
EXPECT_EQ(1, data.bucket_info(0).atom_size());
|
||||
EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
|
||||
data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(AppStartOccurred::COLD, data.bucket_info(0).atom(0).app_start_occurred().type());
|
||||
EXPECT_EQ("activity_name7",
|
||||
data.bucket_info(0).atom(0).app_start_occurred().activity_name());
|
||||
EXPECT_EQ(201L, data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -97,250 +97,247 @@ StatsdConfig CreateStatsdConfig() {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// TODO(b/149590301): Update these tests to use new socket schema.
|
||||
//// If we want to test multiple dump data, we must do it in separate tests, because in the e2e tests,
|
||||
//// we should use the real API which will clear the data after dump data is called.
|
||||
//TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) {
|
||||
// auto config = CreateStatsdConfig();
|
||||
// uint64_t bucketStartTimeNs = 10000000000;
|
||||
// uint64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
//
|
||||
// int appUid = 123;
|
||||
// auto crashEvent1 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 1);
|
||||
// auto crashEvent2 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 201);
|
||||
// auto crashEvent3= CreateAppCrashEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 101);
|
||||
//
|
||||
// auto crashEvent4 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 51);
|
||||
// auto crashEvent5 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 299);
|
||||
// auto crashEvent6 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 2001);
|
||||
//
|
||||
// auto crashEvent7 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 16);
|
||||
// auto crashEvent8 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 249);
|
||||
//
|
||||
// auto crashEvent9 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 351);
|
||||
// auto crashEvent10 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 2);
|
||||
//
|
||||
// auto screenTurnedOnEvent =
|
||||
// CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
|
||||
// bucketStartTimeNs + 2);
|
||||
// auto screenTurnedOffEvent =
|
||||
// CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
|
||||
// bucketStartTimeNs + 200);
|
||||
// auto screenTurnedOnEvent2 =
|
||||
// CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs - 100);
|
||||
//
|
||||
// std::vector<AttributionNodeInternal> attributions = {
|
||||
// CreateAttribution(appUid, "App1"), CreateAttribution(appUid + 1, "GMSCoreModule1")};
|
||||
// auto syncOnEvent1 =
|
||||
// CreateSyncStartEvent(attributions, "ReadEmail", bucketStartTimeNs + 50);
|
||||
// auto syncOffEvent1 =
|
||||
// CreateSyncEndEvent(attributions, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 300);
|
||||
// auto syncOnEvent2 =
|
||||
// CreateSyncStartEvent(attributions, "ReadDoc", bucketStartTimeNs + bucketSizeNs + 2000);
|
||||
//
|
||||
// auto moveToBackgroundEvent1 =
|
||||
// CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 15);
|
||||
// auto moveToForegroundEvent1 =
|
||||
// CreateMoveToForegroundEvent(appUid, bucketStartTimeNs + bucketSizeNs + 250);
|
||||
//
|
||||
// auto moveToBackgroundEvent2 =
|
||||
// CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + bucketSizeNs + 350);
|
||||
// auto moveToForegroundEvent2 =
|
||||
// CreateMoveToForegroundEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 1);
|
||||
//
|
||||
// /*
|
||||
// bucket #1 bucket #2
|
||||
//
|
||||
//
|
||||
// | | | | | | | | | | (crashEvents)
|
||||
// |-------------------------------------|-----------------------------------|---------
|
||||
//
|
||||
// | | (MoveToBkground)
|
||||
//
|
||||
// | | (MoveToForeground)
|
||||
//
|
||||
// | | (SyncIsOn)
|
||||
// | (SyncIsOff)
|
||||
// | | (ScreenIsOn)
|
||||
// | (ScreenIsOff)
|
||||
// */
|
||||
// std::vector<std::unique_ptr<LogEvent>> events;
|
||||
// events.push_back(std::move(crashEvent1));
|
||||
// events.push_back(std::move(crashEvent2));
|
||||
// events.push_back(std::move(crashEvent3));
|
||||
// events.push_back(std::move(crashEvent4));
|
||||
// events.push_back(std::move(crashEvent5));
|
||||
// events.push_back(std::move(crashEvent6));
|
||||
// events.push_back(std::move(crashEvent7));
|
||||
// events.push_back(std::move(crashEvent8));
|
||||
// events.push_back(std::move(crashEvent9));
|
||||
// events.push_back(std::move(crashEvent10));
|
||||
// events.push_back(std::move(screenTurnedOnEvent));
|
||||
// events.push_back(std::move(screenTurnedOffEvent));
|
||||
// events.push_back(std::move(screenTurnedOnEvent2));
|
||||
// events.push_back(std::move(syncOnEvent1));
|
||||
// events.push_back(std::move(syncOffEvent1));
|
||||
// events.push_back(std::move(syncOnEvent2));
|
||||
// events.push_back(std::move(moveToBackgroundEvent1));
|
||||
// events.push_back(std::move(moveToForegroundEvent1));
|
||||
// events.push_back(std::move(moveToBackgroundEvent2));
|
||||
// events.push_back(std::move(moveToForegroundEvent2));
|
||||
//
|
||||
// sortLogEventsByTimestamp(&events);
|
||||
//
|
||||
// for (const auto& event : events) {
|
||||
// processor->OnLogEvent(event.get());
|
||||
// }
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(reports.reports_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
|
||||
// auto data = reports.reports(0).metrics(0).count_metrics().data(0);
|
||||
// // Validate dimension value.
|
||||
// EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
|
||||
// EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
|
||||
// // Uid field.
|
||||
// EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
|
||||
// EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
|
||||
//}
|
||||
//
|
||||
//TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2) {
|
||||
// auto config = CreateStatsdConfig();
|
||||
// uint64_t bucketStartTimeNs = 10000000000;
|
||||
// uint64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(
|
||||
// bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
//
|
||||
// int appUid = 123;
|
||||
// auto crashEvent1 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 1);
|
||||
// auto crashEvent2 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 201);
|
||||
// auto crashEvent3 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 101);
|
||||
//
|
||||
// auto crashEvent4 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 51);
|
||||
// auto crashEvent5 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 299);
|
||||
// auto crashEvent6 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 2001);
|
||||
//
|
||||
// auto crashEvent7 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 16);
|
||||
// auto crashEvent8 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 249);
|
||||
//
|
||||
// auto crashEvent9 = CreateAppCrashEvent(appUid, bucketStartTimeNs + bucketSizeNs + 351);
|
||||
// auto crashEvent10 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 2);
|
||||
//
|
||||
// auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_ON, bucketStartTimeNs + 2);
|
||||
// auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_OFF, bucketStartTimeNs + 200);
|
||||
// auto screenTurnedOnEvent2 =
|
||||
// CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs - 100);
|
||||
//
|
||||
// std::vector<AttributionNodeInternal> attributions = {
|
||||
// CreateAttribution(appUid, "App1"), CreateAttribution(appUid + 1, "GMSCoreModule1")};
|
||||
// auto syncOnEvent1 = CreateSyncStartEvent(attributions, "ReadEmail", bucketStartTimeNs + 50);
|
||||
// auto syncOffEvent1 =
|
||||
// CreateSyncEndEvent(attributions, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 300);
|
||||
// auto syncOnEvent2 =
|
||||
// CreateSyncStartEvent(attributions, "ReadDoc", bucketStartTimeNs + bucketSizeNs + 2000);
|
||||
//
|
||||
// auto moveToBackgroundEvent1 = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 15);
|
||||
// auto moveToForegroundEvent1 =
|
||||
// CreateMoveToForegroundEvent(appUid, bucketStartTimeNs + bucketSizeNs + 250);
|
||||
//
|
||||
// auto moveToBackgroundEvent2 =
|
||||
// CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + bucketSizeNs + 350);
|
||||
// auto moveToForegroundEvent2 =
|
||||
// CreateMoveToForegroundEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 1);
|
||||
//
|
||||
// /*
|
||||
// bucket #1 bucket #2
|
||||
//
|
||||
//
|
||||
// | | | | | | | | | | (crashEvents)
|
||||
// |-------------------------------------|-----------------------------------|---------
|
||||
//
|
||||
// | | (MoveToBkground)
|
||||
//
|
||||
// | | (MoveToForeground)
|
||||
//
|
||||
// | | (SyncIsOn)
|
||||
// | (SyncIsOff)
|
||||
// | | (ScreenIsOn)
|
||||
// | (ScreenIsOff)
|
||||
// */
|
||||
// std::vector<std::unique_ptr<LogEvent>> events;
|
||||
// events.push_back(std::move(crashEvent1));
|
||||
// events.push_back(std::move(crashEvent2));
|
||||
// events.push_back(std::move(crashEvent3));
|
||||
// events.push_back(std::move(crashEvent4));
|
||||
// events.push_back(std::move(crashEvent5));
|
||||
// events.push_back(std::move(crashEvent6));
|
||||
// events.push_back(std::move(crashEvent7));
|
||||
// events.push_back(std::move(crashEvent8));
|
||||
// events.push_back(std::move(crashEvent9));
|
||||
// events.push_back(std::move(crashEvent10));
|
||||
// events.push_back(std::move(screenTurnedOnEvent));
|
||||
// events.push_back(std::move(screenTurnedOffEvent));
|
||||
// events.push_back(std::move(screenTurnedOnEvent2));
|
||||
// events.push_back(std::move(syncOnEvent1));
|
||||
// events.push_back(std::move(syncOffEvent1));
|
||||
// events.push_back(std::move(syncOnEvent2));
|
||||
// events.push_back(std::move(moveToBackgroundEvent1));
|
||||
// events.push_back(std::move(moveToForegroundEvent1));
|
||||
// events.push_back(std::move(moveToBackgroundEvent2));
|
||||
// events.push_back(std::move(moveToForegroundEvent2));
|
||||
//
|
||||
// sortLogEventsByTimestamp(&events);
|
||||
//
|
||||
// for (const auto& event : events) {
|
||||
// processor->OnLogEvent(event.get());
|
||||
// }
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
//
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(reports.reports_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 2);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(1).count(), 3);
|
||||
// auto data = reports.reports(0).metrics(0).count_metrics().data(0);
|
||||
// // Validate dimension value.
|
||||
// EXPECT_EQ(data.dimensions_in_what().field(),
|
||||
// android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
|
||||
// EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
|
||||
// // Uid field.
|
||||
// EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
|
||||
// EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
|
||||
//}
|
||||
// If we want to test multiple dump data, we must do it in separate tests, because in the e2e tests,
|
||||
// we should use the real API which will clear the data after dump data is called.
|
||||
TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) {
|
||||
auto config = CreateStatsdConfig();
|
||||
uint64_t bucketStartTimeNs = 10000000000;
|
||||
uint64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
|
||||
int appUid = 123;
|
||||
auto crashEvent1 = CreateAppCrashEvent(bucketStartTimeNs + 1, appUid);
|
||||
auto crashEvent2 = CreateAppCrashEvent(bucketStartTimeNs + 201, appUid);
|
||||
auto crashEvent3 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 101, appUid);
|
||||
|
||||
auto crashEvent4 = CreateAppCrashEvent(bucketStartTimeNs + 51, appUid);
|
||||
auto crashEvent5 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 299, appUid);
|
||||
auto crashEvent6 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 2001, appUid);
|
||||
|
||||
auto crashEvent7 = CreateAppCrashEvent(bucketStartTimeNs + 16, appUid);
|
||||
auto crashEvent8 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 249, appUid);
|
||||
|
||||
auto crashEvent9 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 351, appUid);
|
||||
auto crashEvent10 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 2, appUid);
|
||||
|
||||
auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
|
||||
bucketStartTimeNs + 2, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
|
||||
bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
|
||||
auto screenTurnedOnEvent2 =
|
||||
CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
|
||||
android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
|
||||
std::vector<int> attributionUids = {appUid, appUid + 1};
|
||||
std::vector<string> attributionTags = {"App1", "GMSCoreModule1"};
|
||||
|
||||
auto syncOnEvent1 = CreateSyncStartEvent(bucketStartTimeNs + 50, attributionUids,
|
||||
attributionTags, "ReadEmail");
|
||||
auto syncOffEvent1 = CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 300, attributionUids,
|
||||
attributionTags, "ReadEmail");
|
||||
auto syncOnEvent2 = CreateSyncStartEvent(bucketStartTimeNs + bucketSizeNs + 2000,
|
||||
attributionUids, attributionTags, "ReadDoc");
|
||||
|
||||
auto moveToBackgroundEvent1 = CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid);
|
||||
auto moveToForegroundEvent1 =
|
||||
CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid);
|
||||
|
||||
auto moveToBackgroundEvent2 =
|
||||
CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid);
|
||||
auto moveToForegroundEvent2 =
|
||||
CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs - 1, appUid);
|
||||
|
||||
/*
|
||||
bucket #1 bucket #2
|
||||
|
||||
|
||||
| | | | | | | | | | (crashEvents)
|
||||
|-------------------------------------|-----------------------------------|---------
|
||||
|
||||
| | (MoveToBkground)
|
||||
|
||||
| | (MoveToForeground)
|
||||
|
||||
| | (SyncIsOn)
|
||||
| (SyncIsOff)
|
||||
| | (ScreenIsOn)
|
||||
| (ScreenIsOff)
|
||||
*/
|
||||
std::vector<std::unique_ptr<LogEvent>> events;
|
||||
events.push_back(std::move(crashEvent1));
|
||||
events.push_back(std::move(crashEvent2));
|
||||
events.push_back(std::move(crashEvent3));
|
||||
events.push_back(std::move(crashEvent4));
|
||||
events.push_back(std::move(crashEvent5));
|
||||
events.push_back(std::move(crashEvent6));
|
||||
events.push_back(std::move(crashEvent7));
|
||||
events.push_back(std::move(crashEvent8));
|
||||
events.push_back(std::move(crashEvent9));
|
||||
events.push_back(std::move(crashEvent10));
|
||||
events.push_back(std::move(screenTurnedOnEvent));
|
||||
events.push_back(std::move(screenTurnedOffEvent));
|
||||
events.push_back(std::move(screenTurnedOnEvent2));
|
||||
events.push_back(std::move(syncOnEvent1));
|
||||
events.push_back(std::move(syncOffEvent1));
|
||||
events.push_back(std::move(syncOnEvent2));
|
||||
events.push_back(std::move(moveToBackgroundEvent1));
|
||||
events.push_back(std::move(moveToForegroundEvent1));
|
||||
events.push_back(std::move(moveToBackgroundEvent2));
|
||||
events.push_back(std::move(moveToForegroundEvent2));
|
||||
|
||||
sortLogEventsByTimestamp(&events);
|
||||
|
||||
for (const auto& event : events) {
|
||||
processor->OnLogEvent(event.get());
|
||||
}
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
|
||||
FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(reports.reports_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
|
||||
auto data = reports.reports(0).metrics(0).count_metrics().data(0);
|
||||
// Validate dimension value.
|
||||
EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
|
||||
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
|
||||
// Uid field.
|
||||
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
|
||||
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
|
||||
}
|
||||
|
||||
TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2) {
|
||||
auto config = CreateStatsdConfig();
|
||||
uint64_t bucketStartTimeNs = 10000000000;
|
||||
uint64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
|
||||
int appUid = 123;
|
||||
auto crashEvent1 = CreateAppCrashEvent(bucketStartTimeNs + 1, appUid);
|
||||
auto crashEvent2 = CreateAppCrashEvent(bucketStartTimeNs + 201, appUid);
|
||||
auto crashEvent3 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 101, appUid);
|
||||
|
||||
auto crashEvent4 = CreateAppCrashEvent(bucketStartTimeNs + 51, appUid);
|
||||
auto crashEvent5 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 299, appUid);
|
||||
auto crashEvent6 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 2001, appUid);
|
||||
|
||||
auto crashEvent7 = CreateAppCrashEvent(bucketStartTimeNs + 16, appUid);
|
||||
auto crashEvent8 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 249, appUid);
|
||||
|
||||
auto crashEvent9 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 351, appUid);
|
||||
auto crashEvent10 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 2, appUid);
|
||||
|
||||
auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
|
||||
bucketStartTimeNs + 2, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
|
||||
bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
|
||||
auto screenTurnedOnEvent2 =
|
||||
CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
|
||||
android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
|
||||
std::vector<int> attributionUids = {appUid, appUid + 1};
|
||||
std::vector<string> attributionTags = {"App1", "GMSCoreModule1"};
|
||||
|
||||
auto syncOnEvent1 = CreateSyncStartEvent(bucketStartTimeNs + 50, attributionUids,
|
||||
attributionTags, "ReadEmail");
|
||||
auto syncOffEvent1 = CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 300, attributionUids,
|
||||
attributionTags, "ReadEmail");
|
||||
auto syncOnEvent2 = CreateSyncStartEvent(bucketStartTimeNs + bucketSizeNs + 2000,
|
||||
attributionUids, attributionTags, "ReadDoc");
|
||||
|
||||
auto moveToBackgroundEvent1 = CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid);
|
||||
auto moveToForegroundEvent1 =
|
||||
CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid);
|
||||
|
||||
auto moveToBackgroundEvent2 =
|
||||
CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid);
|
||||
auto moveToForegroundEvent2 =
|
||||
CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs - 1, appUid);
|
||||
|
||||
/*
|
||||
bucket #1 bucket #2
|
||||
|
||||
|
||||
| | | | | | | | | | (crashEvents)
|
||||
|-------------------------------------|-----------------------------------|---------
|
||||
|
||||
| | (MoveToBkground)
|
||||
|
||||
| | (MoveToForeground)
|
||||
|
||||
| | (SyncIsOn)
|
||||
| (SyncIsOff)
|
||||
| | (ScreenIsOn)
|
||||
| (ScreenIsOff)
|
||||
*/
|
||||
std::vector<std::unique_ptr<LogEvent>> events;
|
||||
events.push_back(std::move(crashEvent1));
|
||||
events.push_back(std::move(crashEvent2));
|
||||
events.push_back(std::move(crashEvent3));
|
||||
events.push_back(std::move(crashEvent4));
|
||||
events.push_back(std::move(crashEvent5));
|
||||
events.push_back(std::move(crashEvent6));
|
||||
events.push_back(std::move(crashEvent7));
|
||||
events.push_back(std::move(crashEvent8));
|
||||
events.push_back(std::move(crashEvent9));
|
||||
events.push_back(std::move(crashEvent10));
|
||||
events.push_back(std::move(screenTurnedOnEvent));
|
||||
events.push_back(std::move(screenTurnedOffEvent));
|
||||
events.push_back(std::move(screenTurnedOnEvent2));
|
||||
events.push_back(std::move(syncOnEvent1));
|
||||
events.push_back(std::move(syncOffEvent1));
|
||||
events.push_back(std::move(syncOnEvent2));
|
||||
events.push_back(std::move(moveToBackgroundEvent1));
|
||||
events.push_back(std::move(moveToForegroundEvent1));
|
||||
events.push_back(std::move(moveToBackgroundEvent2));
|
||||
events.push_back(std::move(moveToForegroundEvent2));
|
||||
|
||||
sortLogEventsByTimestamp(&events);
|
||||
|
||||
for (const auto& event : events) {
|
||||
processor->OnLogEvent(event.get());
|
||||
}
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
|
||||
FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(reports.reports_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 2);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(1).count(), 3);
|
||||
auto data = reports.reports(0).metrics(0).count_metrics().data(0);
|
||||
// Validate dimension value.
|
||||
EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
|
||||
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
|
||||
// Uid field.
|
||||
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
|
||||
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
|
||||
}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
@@ -113,96 +113,107 @@ StatsdConfig MakeGaugeMetricConfig(int64_t minTime) {
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) {
|
||||
// shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
|
||||
// SendConfig(service, MakeConfig());
|
||||
// int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
|
||||
// // initialized with.
|
||||
//
|
||||
// service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
|
||||
// service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 2).get());
|
||||
//
|
||||
// ConfigMetricsReport report = GetReports(service->mProcessor, start + 3);
|
||||
// // Expect no metrics since the bucket has not finished yet.
|
||||
// EXPECT_EQ(1, report.metrics_size());
|
||||
// EXPECT_EQ(0, report.metrics(0).count_metrics().data_size());
|
||||
//}
|
||||
//
|
||||
//TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) {
|
||||
// shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
|
||||
// SendConfig(service, MakeConfig());
|
||||
// int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
|
||||
// // initialized with.
|
||||
//
|
||||
// // Force the uidmap to update at timestamp 2.
|
||||
// service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
|
||||
// // This is a new installation, so there shouldn't be a split (should be same as the without
|
||||
// // split case).
|
||||
// service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
|
||||
// String16(""));
|
||||
// // Goes into the second bucket.
|
||||
// service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 3).get());
|
||||
//
|
||||
// ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
|
||||
// EXPECT_EQ(1, report.metrics_size());
|
||||
// EXPECT_EQ(0, report.metrics(0).count_metrics().data_size());
|
||||
//}
|
||||
//
|
||||
//TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) {
|
||||
// shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
|
||||
// SendConfig(service, MakeConfig());
|
||||
// int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
|
||||
// // initialized with.
|
||||
// service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
|
||||
// {String16("")});
|
||||
//
|
||||
// // Force the uidmap to update at timestamp 2.
|
||||
// service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
|
||||
// service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
|
||||
// String16(""));
|
||||
// // Goes into the second bucket.
|
||||
// service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 3).get());
|
||||
//
|
||||
// ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
|
||||
// backfillStartEndTimestamp(&report);
|
||||
//
|
||||
// ASSERT_EQ(1, report.metrics_size());
|
||||
// ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
|
||||
// ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
|
||||
// EXPECT_TRUE(report.metrics(0).count_metrics().data(0).bucket_info(0).
|
||||
// has_start_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(report.metrics(0).count_metrics().data(0).bucket_info(0).
|
||||
// has_end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
|
||||
//}
|
||||
//
|
||||
//TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) {
|
||||
// shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
|
||||
// SendConfig(service, MakeConfig());
|
||||
// int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
|
||||
// // initialized with.
|
||||
// service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
|
||||
// {String16("")});
|
||||
//
|
||||
// // Force the uidmap to update at timestamp 2.
|
||||
// service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
|
||||
// service->mUidMap->removeApp(start + 2, String16(kApp1.c_str()), 1);
|
||||
// // Goes into the second bucket.
|
||||
// service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 3).get());
|
||||
//
|
||||
// ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
|
||||
// backfillStartEndTimestamp(&report);
|
||||
//
|
||||
// ASSERT_EQ(1, report.metrics_size());
|
||||
// ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
|
||||
// ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
|
||||
// EXPECT_TRUE(report.metrics(0).count_metrics().data(0).bucket_info(0).
|
||||
// has_start_bucket_elapsed_nanos());
|
||||
// EXPECT_TRUE(report.metrics(0).count_metrics().data(0).bucket_info(0).
|
||||
// has_end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
|
||||
//}
|
||||
TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) {
|
||||
shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
|
||||
SendConfig(service, MakeConfig());
|
||||
int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
|
||||
// initialized with.
|
||||
|
||||
service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
|
||||
service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 2, 100).get());
|
||||
|
||||
ConfigMetricsReport report = GetReports(service->mProcessor, start + 3);
|
||||
// Expect no metrics since the bucket has not finished yet.
|
||||
EXPECT_EQ(1, report.metrics_size());
|
||||
EXPECT_EQ(0, report.metrics(0).count_metrics().data_size());
|
||||
}
|
||||
|
||||
TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) {
|
||||
shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
|
||||
SendConfig(service, MakeConfig());
|
||||
int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
|
||||
// initialized with.
|
||||
|
||||
// Force the uidmap to update at timestamp 2.
|
||||
service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
|
||||
// This is a new installation, so there shouldn't be a split (should be same as the without
|
||||
// split case).
|
||||
service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
|
||||
String16(""));
|
||||
// Goes into the second bucket.
|
||||
service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
|
||||
|
||||
ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
|
||||
EXPECT_EQ(1, report.metrics_size());
|
||||
EXPECT_EQ(0, report.metrics(0).count_metrics().data_size());
|
||||
}
|
||||
|
||||
TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) {
|
||||
shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
|
||||
SendConfig(service, MakeConfig());
|
||||
int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
|
||||
// initialized with.
|
||||
service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
|
||||
{String16("")});
|
||||
|
||||
// Force the uidmap to update at timestamp 2.
|
||||
service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
|
||||
service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
|
||||
String16(""));
|
||||
// Goes into the second bucket.
|
||||
service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
|
||||
|
||||
ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
|
||||
backfillStartEndTimestamp(&report);
|
||||
|
||||
ASSERT_EQ(1, report.metrics_size());
|
||||
ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
|
||||
ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
|
||||
EXPECT_TRUE(report.metrics(0)
|
||||
.count_metrics()
|
||||
.data(0)
|
||||
.bucket_info(0)
|
||||
.has_start_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(report.metrics(0)
|
||||
.count_metrics()
|
||||
.data(0)
|
||||
.bucket_info(0)
|
||||
.has_end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
|
||||
}
|
||||
|
||||
TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) {
|
||||
shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
|
||||
SendConfig(service, MakeConfig());
|
||||
int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
|
||||
// initialized with.
|
||||
service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
|
||||
{String16("")});
|
||||
|
||||
// Force the uidmap to update at timestamp 2.
|
||||
service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
|
||||
service->mUidMap->removeApp(start + 2, String16(kApp1.c_str()), 1);
|
||||
// Goes into the second bucket.
|
||||
service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
|
||||
|
||||
ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
|
||||
backfillStartEndTimestamp(&report);
|
||||
|
||||
ASSERT_EQ(1, report.metrics_size());
|
||||
ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
|
||||
ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
|
||||
EXPECT_TRUE(report.metrics(0)
|
||||
.count_metrics()
|
||||
.data(0)
|
||||
.bucket_info(0)
|
||||
.has_start_bucket_elapsed_nanos());
|
||||
EXPECT_TRUE(report.metrics(0)
|
||||
.count_metrics()
|
||||
.data(0)
|
||||
.bucket_info(0)
|
||||
.has_end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
|
||||
}
|
||||
|
||||
TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) {
|
||||
shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
|
||||
|
||||
@@ -64,317 +64,313 @@ StatsdConfig CreateStatsdConfig(bool useCondition = true) {
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(ValueMetricE2eTest, TestPulledEvents) {
|
||||
// auto config = CreateStatsdConfig();
|
||||
// int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
// int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
// SharedRefBase::make<FakeSubsystemSleepCallback>(),
|
||||
// android::util::SUBSYSTEM_SLEEP_STATE);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// processor->mPullerManager->ForceClearPullerCache();
|
||||
//
|
||||
// int startBucketNum = processor->mMetricsManagers.begin()->second->
|
||||
// mAllMetricProducers[0]->getCurrentBucketNum();
|
||||
// EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
//
|
||||
// // When creating the config, the value metric producer should register the alarm at the
|
||||
// // end of the current bucket.
|
||||
// EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
// EXPECT_EQ(bucketSizeNs,
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
// int64_t& expectedPullTimeNs =
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 55);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// auto screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
|
||||
// configAddedTimeNs + 65);
|
||||
// processor->OnLogEvent(screenOnEvent.get());
|
||||
//
|
||||
// screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 75);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// // Pulling alarm arrives on time and reset the sequential pulling alarm.
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
//
|
||||
// screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
|
||||
// configAddedTimeNs + 2 * bucketSizeNs + 15);
|
||||
// processor->OnLogEvent(screenOnEvent.get());
|
||||
//
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
//
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
//
|
||||
// screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 4 * bucketSizeNs + 11);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
//
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
//
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(1, reports.reports_size());
|
||||
// EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
// StatsLogReport::ValueMetricDataWrapper valueMetrics;
|
||||
// sortMetricDataByDimensionsValue(
|
||||
// reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
|
||||
// EXPECT_GT((int)valueMetrics.data_size(), 1);
|
||||
//
|
||||
// auto data = valueMetrics.data(0);
|
||||
// EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
|
||||
// EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
// EXPECT_EQ(1 /* subsystem name field */,
|
||||
// data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
// EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
// // We have 4 buckets, the first one was incomplete since the condition was unknown.
|
||||
// EXPECT_EQ(4, data.bucket_info_size());
|
||||
//
|
||||
// EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, data.bucket_info(0).values_size());
|
||||
//
|
||||
// EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, data.bucket_info(1).values_size());
|
||||
//
|
||||
// EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, data.bucket_info(2).values_size());
|
||||
//
|
||||
// EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, data.bucket_info(3).values_size());
|
||||
//}
|
||||
//
|
||||
//TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) {
|
||||
// auto config = CreateStatsdConfig();
|
||||
// int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
// // 10 mins == 2 bucket durations.
|
||||
// int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
// SharedRefBase::make<FakeSubsystemSleepCallback>(),
|
||||
// android::util::SUBSYSTEM_SLEEP_STATE);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// processor->mPullerManager->ForceClearPullerCache();
|
||||
//
|
||||
// int startBucketNum = processor->mMetricsManagers.begin()->second->
|
||||
// mAllMetricProducers[0]->getCurrentBucketNum();
|
||||
// EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
//
|
||||
// // When creating the config, the value metric producer should register the alarm at the
|
||||
// // end of the current bucket.
|
||||
// EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
// EXPECT_EQ(bucketSizeNs,
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
// int64_t& expectedPullTimeNs =
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// // Screen off/on/off events.
|
||||
// auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 55);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// auto screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
|
||||
// configAddedTimeNs + 65);
|
||||
// processor->OnLogEvent(screenOnEvent.get());
|
||||
//
|
||||
// screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 75);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// // Pulling alarm arrives late by 2 buckets and 1 ns. 2 buckets late is too far away in the
|
||||
// // future, data will be skipped.
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 2 * bucketSizeNs + 1);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// // This screen state change will start a new bucket.
|
||||
// screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
|
||||
// configAddedTimeNs + 4 * bucketSizeNs + 65);
|
||||
// processor->OnLogEvent(screenOnEvent.get());
|
||||
//
|
||||
// // The alarm is delayed but we already created a bucket thanks to the screen state condition.
|
||||
// // This bucket does not have to be skipped since the alarm arrives in time for the next bucket.
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
|
||||
// configAddedTimeNs + 6 * bucketSizeNs + 31);
|
||||
// processor->OnLogEvent(screenOffEvent.get());
|
||||
//
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 8 * bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 9 * bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, configAddedTimeNs + 9 * bucketSizeNs + 10, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(1, reports.reports_size());
|
||||
// EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
// StatsLogReport::ValueMetricDataWrapper valueMetrics;
|
||||
// sortMetricDataByDimensionsValue(
|
||||
// reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
|
||||
// EXPECT_GT((int)valueMetrics.data_size(), 1);
|
||||
//
|
||||
// auto data = valueMetrics.data(0);
|
||||
// EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
|
||||
// EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
// EXPECT_EQ(1 /* subsystem name field */,
|
||||
// data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
// EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
// EXPECT_EQ(3, data.bucket_info_size());
|
||||
//
|
||||
// EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, data.bucket_info(0).values_size());
|
||||
//
|
||||
// EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, data.bucket_info(1).values_size());
|
||||
//
|
||||
// EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 10 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, data.bucket_info(2).values_size());
|
||||
//}
|
||||
//
|
||||
//TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation) {
|
||||
// auto config = CreateStatsdConfig(false);
|
||||
// int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
// int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
// int64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
|
||||
//
|
||||
// auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
|
||||
// *config.add_atom_matcher() = batterySaverStartMatcher;
|
||||
// const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets.
|
||||
// auto metric_activation = config.add_metric_activation();
|
||||
// metric_activation->set_metric_id(metricId);
|
||||
// metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
|
||||
// auto event_activation = metric_activation->add_event_activation();
|
||||
// event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
|
||||
// event_activation->set_ttl_seconds(ttlNs / 1000000000);
|
||||
//
|
||||
// ConfigKey cfgKey;
|
||||
// auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
// SharedRefBase::make<FakeSubsystemSleepCallback>(),
|
||||
// android::util::SUBSYSTEM_SLEEP_STATE);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// processor->mPullerManager->ForceClearPullerCache();
|
||||
//
|
||||
// int startBucketNum = processor->mMetricsManagers.begin()->second->
|
||||
// mAllMetricProducers[0]->getCurrentBucketNum();
|
||||
// EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
// EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
//
|
||||
// // When creating the config, the value metric producer should register the alarm at the
|
||||
// // end of the current bucket.
|
||||
// EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
// EXPECT_EQ(bucketSizeNs,
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
// int64_t& expectedPullTimeNs =
|
||||
// processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// // Pulling alarm arrives on time and reset the sequential pulling alarm.
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 1); // 15 mins + 1 ns.
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
|
||||
// EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
//
|
||||
// // Activate the metric. A pull occurs here
|
||||
// const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
|
||||
// auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
|
||||
// processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
//
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 1); // 20 mins + 1 ns.
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 2); // 25 mins + 2 ns.
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// // Create random event to deactivate metric.
|
||||
// auto deactivationEvent = CreateScreenBrightnessChangedEvent(50, activationNs + ttlNs + 1);
|
||||
// processor->OnLogEvent(deactivationEvent.get());
|
||||
// EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
//
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 3);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// processor->informPullAlarmFired(expectedPullTimeNs + 4);
|
||||
// EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
|
||||
//
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(1, reports.reports_size());
|
||||
// EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
// StatsLogReport::ValueMetricDataWrapper valueMetrics;
|
||||
// sortMetricDataByDimensionsValue(
|
||||
// reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
|
||||
// EXPECT_GT((int)valueMetrics.data_size(), 0);
|
||||
//
|
||||
// auto data = valueMetrics.data(0);
|
||||
// EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
|
||||
// EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
// EXPECT_EQ(1 /* subsystem name field */,
|
||||
// data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
// EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
// // We have 2 full buckets, the two surrounding the activation are dropped.
|
||||
// EXPECT_EQ(2, data.bucket_info_size());
|
||||
//
|
||||
// auto bucketInfo = data.bucket_info(0);
|
||||
// EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, bucketInfo.values_size());
|
||||
//
|
||||
// bucketInfo = data.bucket_info(1);
|
||||
// EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
|
||||
// EXPECT_EQ(1, bucketInfo.values_size());
|
||||
//}
|
||||
TEST(ValueMetricE2eTest, TestPulledEvents) {
|
||||
auto config = CreateStatsdConfig();
|
||||
int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
SharedRefBase::make<FakeSubsystemSleepCallback>(),
|
||||
android::util::SUBSYSTEM_SLEEP_STATE);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
processor->mPullerManager->ForceClearPullerCache();
|
||||
|
||||
int startBucketNum = processor->mMetricsManagers.begin()
|
||||
->second->mAllMetricProducers[0]
|
||||
->getCurrentBucketNum();
|
||||
EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
|
||||
// When creating the config, the value metric producer should register the alarm at the
|
||||
// end of the current bucket.
|
||||
EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
EXPECT_EQ(bucketSizeNs,
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
int64_t& expectedPullTimeNs =
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
auto screenOffEvent =
|
||||
CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
auto screenOnEvent =
|
||||
CreateScreenStateChangedEvent(configAddedTimeNs + 65, android::view::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screenOnEvent.get());
|
||||
|
||||
screenOffEvent =
|
||||
CreateScreenStateChangedEvent(configAddedTimeNs + 75, android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
// Pulling alarm arrives on time and reset the sequential pulling alarm.
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
|
||||
screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 2 * bucketSizeNs + 15,
|
||||
android::view::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screenOnEvent.get());
|
||||
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
|
||||
screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 4 * bucketSizeNs + 11,
|
||||
android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
|
||||
ADB_DUMP, FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(1, reports.reports_size());
|
||||
EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
StatsLogReport::ValueMetricDataWrapper valueMetrics;
|
||||
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
|
||||
EXPECT_GT((int)valueMetrics.data_size(), 1);
|
||||
|
||||
auto data = valueMetrics.data(0);
|
||||
EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
|
||||
EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
EXPECT_EQ(1 /* subsystem name field */,
|
||||
data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
// We have 4 buckets, the first one was incomplete since the condition was unknown.
|
||||
EXPECT_EQ(4, data.bucket_info_size());
|
||||
|
||||
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, data.bucket_info(0).values_size());
|
||||
|
||||
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, data.bucket_info(1).values_size());
|
||||
|
||||
EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, data.bucket_info(2).values_size());
|
||||
|
||||
EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, data.bucket_info(3).values_size());
|
||||
}
|
||||
|
||||
TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) {
|
||||
auto config = CreateStatsdConfig();
|
||||
int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
// 10 mins == 2 bucket durations.
|
||||
int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
SharedRefBase::make<FakeSubsystemSleepCallback>(),
|
||||
android::util::SUBSYSTEM_SLEEP_STATE);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
processor->mPullerManager->ForceClearPullerCache();
|
||||
|
||||
int startBucketNum = processor->mMetricsManagers.begin()
|
||||
->second->mAllMetricProducers[0]
|
||||
->getCurrentBucketNum();
|
||||
EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
|
||||
// When creating the config, the value metric producer should register the alarm at the
|
||||
// end of the current bucket.
|
||||
EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
EXPECT_EQ(bucketSizeNs,
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
int64_t& expectedPullTimeNs =
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
// Screen off/on/off events.
|
||||
auto screenOffEvent =
|
||||
CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
auto screenOnEvent =
|
||||
CreateScreenStateChangedEvent(configAddedTimeNs + 65, android::view::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screenOnEvent.get());
|
||||
|
||||
screenOffEvent =
|
||||
CreateScreenStateChangedEvent(configAddedTimeNs + 75, android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
// Pulling alarm arrives late by 2 buckets and 1 ns. 2 buckets late is too far away in the
|
||||
// future, data will be skipped.
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 2 * bucketSizeNs + 1);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
// This screen state change will start a new bucket.
|
||||
screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 4 * bucketSizeNs + 65,
|
||||
android::view::DISPLAY_STATE_ON);
|
||||
processor->OnLogEvent(screenOnEvent.get());
|
||||
|
||||
// The alarm is delayed but we already created a bucket thanks to the screen state condition.
|
||||
// This bucket does not have to be skipped since the alarm arrives in time for the next bucket.
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 6 * bucketSizeNs + 31,
|
||||
android::view::DISPLAY_STATE_OFF);
|
||||
processor->OnLogEvent(screenOffEvent.get());
|
||||
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 8 * bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 1);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 9 * bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, configAddedTimeNs + 9 * bucketSizeNs + 10, false, true,
|
||||
ADB_DUMP, FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(1, reports.reports_size());
|
||||
EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
StatsLogReport::ValueMetricDataWrapper valueMetrics;
|
||||
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
|
||||
EXPECT_GT((int)valueMetrics.data_size(), 1);
|
||||
|
||||
auto data = valueMetrics.data(0);
|
||||
EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
|
||||
EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
EXPECT_EQ(1 /* subsystem name field */,
|
||||
data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
EXPECT_EQ(3, data.bucket_info_size());
|
||||
|
||||
EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, data.bucket_info(0).values_size());
|
||||
|
||||
EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, data.bucket_info(1).values_size());
|
||||
|
||||
EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 10 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, data.bucket_info(2).values_size());
|
||||
}
|
||||
|
||||
TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation) {
|
||||
auto config = CreateStatsdConfig(false);
|
||||
int64_t baseTimeNs = getElapsedRealtimeNs();
|
||||
int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
|
||||
|
||||
auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
|
||||
*config.add_atom_matcher() = batterySaverStartMatcher;
|
||||
const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets.
|
||||
auto metric_activation = config.add_metric_activation();
|
||||
metric_activation->set_metric_id(metricId);
|
||||
metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
|
||||
auto event_activation = metric_activation->add_event_activation();
|
||||
event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
|
||||
event_activation->set_ttl_seconds(ttlNs / 1000000000);
|
||||
|
||||
ConfigKey cfgKey;
|
||||
auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
|
||||
SharedRefBase::make<FakeSubsystemSleepCallback>(),
|
||||
android::util::SUBSYSTEM_SLEEP_STATE);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
processor->mPullerManager->ForceClearPullerCache();
|
||||
|
||||
int startBucketNum = processor->mMetricsManagers.begin()
|
||||
->second->mAllMetricProducers[0]
|
||||
->getCurrentBucketNum();
|
||||
EXPECT_GT(startBucketNum, (int64_t)0);
|
||||
EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
|
||||
// When creating the config, the value metric producer should register the alarm at the
|
||||
// end of the current bucket.
|
||||
EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
|
||||
EXPECT_EQ(bucketSizeNs,
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
|
||||
int64_t& expectedPullTimeNs =
|
||||
processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
// Pulling alarm arrives on time and reset the sequential pulling alarm.
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 1); // 15 mins + 1 ns.
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
|
||||
EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
|
||||
// Activate the metric. A pull occurs here
|
||||
const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
|
||||
auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
|
||||
processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 1); // 20 mins + 1 ns.
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 2); // 25 mins + 2 ns.
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
// Create random event to deactivate metric.
|
||||
auto deactivationEvent = CreateScreenBrightnessChangedEvent(activationNs + ttlNs + 1, 50);
|
||||
processor->OnLogEvent(deactivationEvent.get());
|
||||
EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
|
||||
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 3);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
processor->informPullAlarmFired(expectedPullTimeNs + 4);
|
||||
EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
|
||||
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
|
||||
ADB_DUMP, FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(1, reports.reports_size());
|
||||
EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
StatsLogReport::ValueMetricDataWrapper valueMetrics;
|
||||
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
|
||||
EXPECT_GT((int)valueMetrics.data_size(), 0);
|
||||
|
||||
auto data = valueMetrics.data(0);
|
||||
EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
|
||||
EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
|
||||
EXPECT_EQ(1 /* subsystem name field */,
|
||||
data.dimensions_in_what().value_tuple().dimensions_value(0).field());
|
||||
EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
|
||||
// We have 2 full buckets, the two surrounding the activation are dropped.
|
||||
EXPECT_EQ(2, data.bucket_info_size());
|
||||
|
||||
auto bucketInfo = data.bucket_info(0);
|
||||
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, bucketInfo.values_size());
|
||||
|
||||
bucketInfo = data.bucket_info(1);
|
||||
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
|
||||
EXPECT_EQ(1, bucketInfo.values_size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test initialization of a simple value metric that is sliced by a state.
|
||||
|
||||
@@ -61,292 +61,290 @@ StatsdConfig CreateStatsdConfig(DurationMetric::AggregationType aggregationType)
|
||||
return config;
|
||||
}
|
||||
|
||||
std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
|
||||
CreateAttribution(222, "GMSCoreModule1"),
|
||||
CreateAttribution(222, "GMSCoreModule2")};
|
||||
std::vector<int> attributionUids1 = {111, 222, 222};
|
||||
std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1", "GMSCoreModule2"};
|
||||
|
||||
std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(111, "App2"),
|
||||
CreateAttribution(222, "GMSCoreModule1"),
|
||||
CreateAttribution(222, "GMSCoreModule2")};
|
||||
std::vector<int> attributionUids2 = {111, 222, 222};
|
||||
std::vector<string> attributionTags2 = {"App2", "GMSCoreModule1", "GMSCoreModule2"};
|
||||
|
||||
// TODO(b/149590301): Update this helper to use new socket schema.
|
||||
///*
|
||||
//Events:
|
||||
//Screen off is met from (200ns,1 min+500ns].
|
||||
//Acquire event for wl1 from 2ns to 1min+2ns
|
||||
//Acquire event for wl2 from 1min-10ns to 2min-15ns
|
||||
//*/
|
||||
//void FeedEvents(StatsdConfig config, sp<StatsLogProcessor> processor) {
|
||||
// uint64_t bucketStartTimeNs = 10000000000;
|
||||
// uint64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
//
|
||||
// auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_ON, bucketStartTimeNs + 1);
|
||||
// auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
|
||||
// android::view::DisplayStateEnum::DISPLAY_STATE_OFF, bucketStartTimeNs + 200);
|
||||
// auto screenTurnedOnEvent2 =
|
||||
// CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
|
||||
// bucketStartTimeNs + bucketSizeNs + 500);
|
||||
//
|
||||
// auto acquireEvent1 = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 2);
|
||||
// auto releaseEvent1 =
|
||||
// CreateReleaseWakelockEvent(attributions1, "wl1", bucketStartTimeNs + bucketSizeNs + 2);
|
||||
// auto acquireEvent2 =
|
||||
// CreateAcquireWakelockEvent(attributions2, "wl2", bucketStartTimeNs + bucketSizeNs - 10);
|
||||
// auto releaseEvent2 = CreateReleaseWakelockEvent(attributions2, "wl2",
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs - 15);
|
||||
//
|
||||
// std::vector<std::unique_ptr<LogEvent>> events;
|
||||
//
|
||||
// events.push_back(std::move(screenTurnedOnEvent));
|
||||
// events.push_back(std::move(screenTurnedOffEvent));
|
||||
// events.push_back(std::move(screenTurnedOnEvent2));
|
||||
// events.push_back(std::move(acquireEvent1));
|
||||
// events.push_back(std::move(acquireEvent2));
|
||||
// events.push_back(std::move(releaseEvent1));
|
||||
// events.push_back(std::move(releaseEvent2));
|
||||
//
|
||||
// sortLogEventsByTimestamp(&events);
|
||||
//
|
||||
// for (const auto& event : events) {
|
||||
// processor->OnLogEvent(event.get());
|
||||
// }
|
||||
//}
|
||||
/*
|
||||
Events:
|
||||
Screen off is met from (200ns,1 min+500ns].
|
||||
Acquire event for wl1 from 2ns to 1min+2ns
|
||||
Acquire event for wl2 from 1min-10ns to 2min-15ns
|
||||
*/
|
||||
void FeedEvents(StatsdConfig config, sp<StatsLogProcessor> processor) {
|
||||
uint64_t bucketStartTimeNs = 10000000000;
|
||||
uint64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
|
||||
auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
|
||||
bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
|
||||
bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
|
||||
auto screenTurnedOnEvent2 =
|
||||
CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 500,
|
||||
android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
|
||||
auto acquireEvent1 = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
|
||||
attributionTags1, "wl1");
|
||||
auto releaseEvent1 = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2,
|
||||
attributionUids1, attributionTags1, "wl1");
|
||||
auto acquireEvent2 = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 10,
|
||||
attributionUids2, attributionTags2, "wl2");
|
||||
auto releaseEvent2 = CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs - 15,
|
||||
attributionUids2, attributionTags2, "wl2");
|
||||
|
||||
std::vector<std::unique_ptr<LogEvent>> events;
|
||||
|
||||
events.push_back(std::move(screenTurnedOnEvent));
|
||||
events.push_back(std::move(screenTurnedOffEvent));
|
||||
events.push_back(std::move(screenTurnedOnEvent2));
|
||||
events.push_back(std::move(acquireEvent1));
|
||||
events.push_back(std::move(acquireEvent2));
|
||||
events.push_back(std::move(releaseEvent1));
|
||||
events.push_back(std::move(releaseEvent2));
|
||||
|
||||
sortLogEventsByTimestamp(&events);
|
||||
|
||||
for (const auto& event : events) {
|
||||
processor->OnLogEvent(event.get());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(b/149590301): Update these tests to use new socket schema.
|
||||
//TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1) {
|
||||
// ConfigKey cfgKey;
|
||||
// auto config = CreateStatsdConfig(DurationMetric::SUM);
|
||||
// uint64_t bucketStartTimeNs = 10000000000;
|
||||
// uint64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// FeedEvents(config, processor);
|
||||
// vector<uint8_t> buffer;
|
||||
// ConfigMetricsReportList reports;
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
//
|
||||
// EXPECT_EQ(reports.reports_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
// // Only 1 dimension output. The tag dimension in the predicate has been aggregated.
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
|
||||
//
|
||||
// auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
// // Validate dimension value.
|
||||
// ValidateAttributionUidDimension(data.dimensions_in_what(),
|
||||
// android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// // Validate bucket info.
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
|
||||
// data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
// // The wakelock holding interval starts from the screen off event and to the end of the 1st
|
||||
// // bucket.
|
||||
// EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs - 200);
|
||||
//}
|
||||
//
|
||||
//TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2) {
|
||||
// ConfigKey cfgKey;
|
||||
// auto config = CreateStatsdConfig(DurationMetric::SUM);
|
||||
// uint64_t bucketStartTimeNs = 10000000000;
|
||||
// uint64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// FeedEvents(config, processor);
|
||||
// vector<uint8_t> buffer;
|
||||
// ConfigMetricsReportList reports;
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(reports.reports_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
|
||||
// // Dump the report after the end of 2nd bucket.
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
|
||||
// auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
// // Validate dimension value.
|
||||
// ValidateAttributionUidDimension(data.dimensions_in_what(),
|
||||
// android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// // Two output buckets.
|
||||
// // The wakelock holding interval in the 1st bucket starts from the screen off event and to
|
||||
// // the end of the 1st bucket.
|
||||
// EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(),
|
||||
// bucketStartTimeNs + bucketSizeNs - (bucketStartTimeNs + 200));
|
||||
// // The wakelock holding interval in the 2nd bucket starts at the beginning of the bucket and
|
||||
// // ends at the second screen on event.
|
||||
// EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 500UL);
|
||||
//}
|
||||
//TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3) {
|
||||
// ConfigKey cfgKey;
|
||||
// auto config = CreateStatsdConfig(DurationMetric::SUM);
|
||||
// uint64_t bucketStartTimeNs = 10000000000;
|
||||
// uint64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// FeedEvents(config, processor);
|
||||
// vector<uint8_t> buffer;
|
||||
// ConfigMetricsReportList reports;
|
||||
//
|
||||
// std::vector<std::unique_ptr<LogEvent>> events;
|
||||
// events.push_back(
|
||||
// CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs + 90));
|
||||
// events.push_back(CreateAcquireWakelockEvent(attributions1, "wl3",
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs + 100));
|
||||
// events.push_back(CreateReleaseWakelockEvent(attributions1, "wl3",
|
||||
// bucketStartTimeNs + 5 * bucketSizeNs + 100));
|
||||
// sortLogEventsByTimestamp(&events);
|
||||
// for (const auto& event : events) {
|
||||
// processor->OnLogEvent(event.get());
|
||||
// }
|
||||
//
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(reports.reports_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 6);
|
||||
// auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
// ValidateAttributionUidDimension(data.dimensions_in_what(),
|
||||
// android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// // The last wakelock holding spans 4 buckets.
|
||||
// EXPECT_EQ((unsigned long long)data.bucket_info(2).duration_nanos(), bucketSizeNs - 100);
|
||||
// EXPECT_EQ((unsigned long long)data.bucket_info(3).duration_nanos(), bucketSizeNs);
|
||||
// EXPECT_EQ((unsigned long long)data.bucket_info(4).duration_nanos(), bucketSizeNs);
|
||||
// EXPECT_EQ((unsigned long long)data.bucket_info(5).duration_nanos(), 100UL);
|
||||
//}
|
||||
//
|
||||
//TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1) {
|
||||
// ConfigKey cfgKey;
|
||||
// auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
|
||||
// uint64_t bucketStartTimeNs = 10000000000;
|
||||
// uint64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// FeedEvents(config, processor);
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
//
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
//
|
||||
// EXPECT_EQ(reports.reports_size(), 1);
|
||||
//
|
||||
// // When using ProtoOutputStream, if nothing written to a sub msg, it won't be treated as
|
||||
// // one. It was previsouly 1 because we had a fake onDumpReport which calls add_metric() by
|
||||
// // itself.
|
||||
// EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
// EXPECT_EQ(0, reports.reports(0).metrics(0).duration_metrics().data_size());
|
||||
//}
|
||||
//
|
||||
//TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2) {
|
||||
// ConfigKey cfgKey;
|
||||
// auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
|
||||
// uint64_t bucketStartTimeNs = 10000000000;
|
||||
// uint64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// FeedEvents(config, processor);
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(reports.reports_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
|
||||
// // Dump the report after the end of 2nd bucket. One dimension with one bucket.
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
|
||||
// auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
// // Validate dimension value.
|
||||
// ValidateAttributionUidDimension(data.dimensions_in_what(),
|
||||
// android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// // The max is acquire event for wl1 to screen off start.
|
||||
// EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs + 2 - 200);
|
||||
//}
|
||||
//
|
||||
//TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3) {
|
||||
// ConfigKey cfgKey;
|
||||
// auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
|
||||
// uint64_t bucketStartTimeNs = 10000000000;
|
||||
// uint64_t bucketSizeNs =
|
||||
// TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
// auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
// EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
// EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
// FeedEvents(config, processor);
|
||||
// ConfigMetricsReportList reports;
|
||||
// vector<uint8_t> buffer;
|
||||
//
|
||||
// std::vector<std::unique_ptr<LogEvent>> events;
|
||||
// events.push_back(
|
||||
// CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs + 90));
|
||||
// events.push_back(CreateAcquireWakelockEvent(attributions1, "wl3",
|
||||
// bucketStartTimeNs + 2 * bucketSizeNs + 100));
|
||||
// events.push_back(CreateReleaseWakelockEvent(attributions1, "wl3",
|
||||
// bucketStartTimeNs + 5 * bucketSizeNs + 100));
|
||||
// sortLogEventsByTimestamp(&events);
|
||||
// for (const auto& event : events) {
|
||||
// processor->OnLogEvent(event.get());
|
||||
// }
|
||||
//
|
||||
// processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true,
|
||||
// ADB_DUMP, FAST, &buffer);
|
||||
// EXPECT_TRUE(buffer.size() > 0);
|
||||
// EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
// backfillDimensionPath(&reports);
|
||||
// backfillStringInReport(&reports);
|
||||
// backfillStartEndTimestamp(&reports);
|
||||
// EXPECT_EQ(reports.reports_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
|
||||
// EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
|
||||
// auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
// ValidateAttributionUidDimension(data.dimensions_in_what(),
|
||||
// android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// // The last wakelock holding spans 4 buckets.
|
||||
// EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 3 * bucketSizeNs);
|
||||
// EXPECT_EQ((unsigned long long)data.bucket_info(1).start_bucket_elapsed_nanos(),
|
||||
// bucketStartTimeNs + 5 * bucketSizeNs);
|
||||
// EXPECT_EQ((unsigned long long)data.bucket_info(1).end_bucket_elapsed_nanos(),
|
||||
// bucketStartTimeNs + 6 * bucketSizeNs);
|
||||
//}
|
||||
TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1) {
|
||||
ConfigKey cfgKey;
|
||||
auto config = CreateStatsdConfig(DurationMetric::SUM);
|
||||
uint64_t bucketStartTimeNs = 10000000000;
|
||||
uint64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
FeedEvents(config, processor);
|
||||
vector<uint8_t> buffer;
|
||||
ConfigMetricsReportList reports;
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
|
||||
FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
|
||||
EXPECT_EQ(reports.reports_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
// Only 1 dimension output. The tag dimension in the predicate has been aggregated.
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
|
||||
|
||||
auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
// Validate dimension value.
|
||||
ValidateAttributionUidDimension(data.dimensions_in_what(),
|
||||
android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// Validate bucket info.
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
|
||||
data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
// The wakelock holding interval starts from the screen off event and to the end of the 1st
|
||||
// bucket.
|
||||
EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs - 200);
|
||||
}
|
||||
|
||||
TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2) {
|
||||
ConfigKey cfgKey;
|
||||
auto config = CreateStatsdConfig(DurationMetric::SUM);
|
||||
uint64_t bucketStartTimeNs = 10000000000;
|
||||
uint64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
FeedEvents(config, processor);
|
||||
vector<uint8_t> buffer;
|
||||
ConfigMetricsReportList reports;
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
|
||||
FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(reports.reports_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
|
||||
// Dump the report after the end of 2nd bucket.
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
|
||||
auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
// Validate dimension value.
|
||||
ValidateAttributionUidDimension(data.dimensions_in_what(),
|
||||
android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// Two output buckets.
|
||||
// The wakelock holding interval in the 1st bucket starts from the screen off event and to
|
||||
// the end of the 1st bucket.
|
||||
EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(),
|
||||
bucketStartTimeNs + bucketSizeNs - (bucketStartTimeNs + 200));
|
||||
// The wakelock holding interval in the 2nd bucket starts at the beginning of the bucket and
|
||||
// ends at the second screen on event.
|
||||
EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 500UL);
|
||||
}
|
||||
|
||||
TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3) {
|
||||
ConfigKey cfgKey;
|
||||
auto config = CreateStatsdConfig(DurationMetric::SUM);
|
||||
uint64_t bucketStartTimeNs = 10000000000;
|
||||
uint64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
FeedEvents(config, processor);
|
||||
vector<uint8_t> buffer;
|
||||
ConfigMetricsReportList reports;
|
||||
|
||||
std::vector<std::unique_ptr<LogEvent>> events;
|
||||
events.push_back(
|
||||
CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 90,
|
||||
android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
|
||||
attributionUids1, attributionTags1, "wl3"));
|
||||
events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs + 100,
|
||||
attributionUids1, attributionTags1, "wl3"));
|
||||
sortLogEventsByTimestamp(&events);
|
||||
for (const auto& event : events) {
|
||||
processor->OnLogEvent(event.get());
|
||||
}
|
||||
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true, ADB_DUMP,
|
||||
FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(reports.reports_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 6);
|
||||
auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
ValidateAttributionUidDimension(data.dimensions_in_what(),
|
||||
android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// The last wakelock holding spans 4 buckets.
|
||||
EXPECT_EQ((unsigned long long)data.bucket_info(2).duration_nanos(), bucketSizeNs - 100);
|
||||
EXPECT_EQ((unsigned long long)data.bucket_info(3).duration_nanos(), bucketSizeNs);
|
||||
EXPECT_EQ((unsigned long long)data.bucket_info(4).duration_nanos(), bucketSizeNs);
|
||||
EXPECT_EQ((unsigned long long)data.bucket_info(5).duration_nanos(), 100UL);
|
||||
}
|
||||
|
||||
TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1) {
|
||||
ConfigKey cfgKey;
|
||||
auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
|
||||
uint64_t bucketStartTimeNs = 10000000000;
|
||||
uint64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
FeedEvents(config, processor);
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
|
||||
FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
|
||||
EXPECT_EQ(reports.reports_size(), 1);
|
||||
|
||||
// When using ProtoOutputStream, if nothing written to a sub msg, it won't be treated as
|
||||
// one. It was previsouly 1 because we had a fake onDumpReport which calls add_metric() by
|
||||
// itself.
|
||||
EXPECT_EQ(1, reports.reports(0).metrics_size());
|
||||
EXPECT_EQ(0, reports.reports(0).metrics(0).duration_metrics().data_size());
|
||||
}
|
||||
|
||||
TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2) {
|
||||
ConfigKey cfgKey;
|
||||
auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
|
||||
uint64_t bucketStartTimeNs = 10000000000;
|
||||
uint64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
FeedEvents(config, processor);
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
|
||||
FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(reports.reports_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
|
||||
// Dump the report after the end of 2nd bucket. One dimension with one bucket.
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
|
||||
auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
// Validate dimension value.
|
||||
ValidateAttributionUidDimension(data.dimensions_in_what(),
|
||||
android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// The max is acquire event for wl1 to screen off start.
|
||||
EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs + 2 - 200);
|
||||
}
|
||||
|
||||
TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3) {
|
||||
ConfigKey cfgKey;
|
||||
auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
|
||||
uint64_t bucketStartTimeNs = 10000000000;
|
||||
uint64_t bucketSizeNs =
|
||||
TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
|
||||
auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
|
||||
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
|
||||
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
|
||||
FeedEvents(config, processor);
|
||||
ConfigMetricsReportList reports;
|
||||
vector<uint8_t> buffer;
|
||||
|
||||
std::vector<std::unique_ptr<LogEvent>> events;
|
||||
events.push_back(
|
||||
CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 90,
|
||||
android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
|
||||
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
|
||||
attributionUids1, attributionTags1, "wl3"));
|
||||
events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs + 100,
|
||||
attributionUids1, attributionTags1, "wl3"));
|
||||
sortLogEventsByTimestamp(&events);
|
||||
for (const auto& event : events) {
|
||||
processor->OnLogEvent(event.get());
|
||||
}
|
||||
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true, ADB_DUMP,
|
||||
FAST, &buffer);
|
||||
EXPECT_TRUE(buffer.size() > 0);
|
||||
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
|
||||
backfillDimensionPath(&reports);
|
||||
backfillStringInReport(&reports);
|
||||
backfillStartEndTimestamp(&reports);
|
||||
EXPECT_EQ(reports.reports_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
|
||||
EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
|
||||
auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
|
||||
ValidateAttributionUidDimension(data.dimensions_in_what(),
|
||||
android::util::WAKELOCK_STATE_CHANGED, 111);
|
||||
// The last wakelock holding spans 4 buckets.
|
||||
EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 3 * bucketSizeNs);
|
||||
EXPECT_EQ((unsigned long long)data.bucket_info(1).start_bucket_elapsed_nanos(),
|
||||
bucketStartTimeNs + 5 * bucketSizeNs);
|
||||
EXPECT_EQ((unsigned long long)data.bucket_info(1).end_bucket_elapsed_nanos(),
|
||||
bucketStartTimeNs + 6 * bucketSizeNs);
|
||||
}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
311
cmds/statsd/tests/external/StatsPuller_test.cpp
vendored
311
cmds/statsd/tests/external/StatsPuller_test.cpp
vendored
@@ -15,11 +15,14 @@
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "../metrics/metrics_test_helper.h"
|
||||
#include "src/stats_log_util.h"
|
||||
#include "stats_event.h"
|
||||
#include "tests/statsd_test_util.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@@ -57,13 +60,22 @@ private:
|
||||
|
||||
FakePuller puller;
|
||||
|
||||
// TODO(b/149590301): Update this helper to use new socket schema.
|
||||
//shared_ptr<LogEvent> createSimpleEvent(int64_t eventTimeNs, int64_t value) {
|
||||
// shared_ptr<LogEvent> event = make_shared<LogEvent>(pullTagId, eventTimeNs);
|
||||
// event->write(value);
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
std::unique_ptr<LogEvent> createSimpleEvent(int64_t eventTimeNs, int64_t value) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, pullTagId);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
|
||||
|
||||
AStatsEvent_writeInt64(statsEvent, value);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
class StatsPullerTest : public ::testing::Test {
|
||||
public:
|
||||
@@ -80,149 +92,148 @@ public:
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
// TODO(b/149590301): Update these tests to use new socket schema.
|
||||
//TEST_F(StatsPullerTest, PullSuccess) {
|
||||
// pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
//
|
||||
// pullSuccess = true;
|
||||
//
|
||||
// vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
// EXPECT_TRUE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(1, dataHolder.size());
|
||||
// EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
|
||||
// EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
|
||||
// EXPECT_EQ(1, dataHolder[0]->size());
|
||||
// EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
|
||||
//
|
||||
// sleep_for(std::chrono::seconds(1));
|
||||
//
|
||||
// pullData.clear();
|
||||
// pullData.push_back(createSimpleEvent(2222L, 44));
|
||||
//
|
||||
// pullSuccess = true;
|
||||
//
|
||||
// EXPECT_TRUE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(1, dataHolder.size());
|
||||
// EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
|
||||
// EXPECT_EQ(2222L, dataHolder[0]->GetElapsedTimestampNs());
|
||||
// EXPECT_EQ(1, dataHolder[0]->size());
|
||||
// EXPECT_EQ(44, dataHolder[0]->getValues()[0].mValue.int_value);
|
||||
//}
|
||||
//
|
||||
//TEST_F(StatsPullerTest, PullFailAfterSuccess) {
|
||||
// pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
//
|
||||
// pullSuccess = true;
|
||||
//
|
||||
// vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
// EXPECT_TRUE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(1, dataHolder.size());
|
||||
// EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
|
||||
// EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
|
||||
// EXPECT_EQ(1, dataHolder[0]->size());
|
||||
// EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
|
||||
//
|
||||
// sleep_for(std::chrono::seconds(1));
|
||||
//
|
||||
// pullData.clear();
|
||||
// pullData.push_back(createSimpleEvent(2222L, 44));
|
||||
//
|
||||
// pullSuccess = false;
|
||||
// dataHolder.clear();
|
||||
// EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(0, dataHolder.size());
|
||||
//
|
||||
// pullSuccess = true;
|
||||
// dataHolder.clear();
|
||||
// EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(0, dataHolder.size());
|
||||
//}
|
||||
//
|
||||
//// Test pull takes longer than timeout, 2nd pull happens shorter than cooldown
|
||||
//TEST_F(StatsPullerTest, PullTakeTooLongAndPullFast) {
|
||||
// pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
// pullSuccess = true;
|
||||
// // timeout is 0.5
|
||||
// pullDelayNs = (long)(0.8 * NS_PER_SEC);
|
||||
//
|
||||
// vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
// EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(0, dataHolder.size());
|
||||
//
|
||||
// pullData.clear();
|
||||
// pullData.push_back(createSimpleEvent(2222L, 44));
|
||||
//
|
||||
// pullSuccess = true;
|
||||
// dataHolder.clear();
|
||||
// EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(0, dataHolder.size());
|
||||
//}
|
||||
//
|
||||
//TEST_F(StatsPullerTest, PullFail) {
|
||||
// pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
//
|
||||
// pullSuccess = false;
|
||||
//
|
||||
// vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
// EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(0, dataHolder.size());
|
||||
//}
|
||||
//
|
||||
//TEST_F(StatsPullerTest, PullTakeTooLong) {
|
||||
// pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
//
|
||||
// pullSuccess = true;
|
||||
// pullDelayNs = NS_PER_SEC;
|
||||
//
|
||||
// vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
// EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(0, dataHolder.size());
|
||||
//}
|
||||
//
|
||||
//TEST_F(StatsPullerTest, PullTooFast) {
|
||||
// pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
//
|
||||
// pullSuccess = true;
|
||||
//
|
||||
// vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
// EXPECT_TRUE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(1, dataHolder.size());
|
||||
// EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
|
||||
// EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
|
||||
// EXPECT_EQ(1, dataHolder[0]->size());
|
||||
// EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
|
||||
//
|
||||
// pullData.clear();
|
||||
// pullData.push_back(createSimpleEvent(2222L, 44));
|
||||
//
|
||||
// pullSuccess = true;
|
||||
//
|
||||
// dataHolder.clear();
|
||||
// EXPECT_TRUE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(1, dataHolder.size());
|
||||
// EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
|
||||
// EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
|
||||
// EXPECT_EQ(1, dataHolder[0]->size());
|
||||
// EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
|
||||
//}
|
||||
//
|
||||
//TEST_F(StatsPullerTest, PullFailsAndTooFast) {
|
||||
// pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
//
|
||||
// pullSuccess = false;
|
||||
//
|
||||
// vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
// EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(0, dataHolder.size());
|
||||
//
|
||||
// pullData.clear();
|
||||
// pullData.push_back(createSimpleEvent(2222L, 44));
|
||||
//
|
||||
// pullSuccess = true;
|
||||
//
|
||||
// EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
// EXPECT_EQ(0, dataHolder.size());
|
||||
//}
|
||||
TEST_F(StatsPullerTest, PullSuccess) {
|
||||
pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
|
||||
pullSuccess = true;
|
||||
|
||||
vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
EXPECT_TRUE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(1, dataHolder.size());
|
||||
EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
|
||||
EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
|
||||
EXPECT_EQ(1, dataHolder[0]->size());
|
||||
EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
|
||||
|
||||
sleep_for(std::chrono::seconds(1));
|
||||
|
||||
pullData.clear();
|
||||
pullData.push_back(createSimpleEvent(2222L, 44));
|
||||
|
||||
pullSuccess = true;
|
||||
|
||||
EXPECT_TRUE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(1, dataHolder.size());
|
||||
EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
|
||||
EXPECT_EQ(2222L, dataHolder[0]->GetElapsedTimestampNs());
|
||||
EXPECT_EQ(1, dataHolder[0]->size());
|
||||
EXPECT_EQ(44, dataHolder[0]->getValues()[0].mValue.int_value);
|
||||
}
|
||||
|
||||
TEST_F(StatsPullerTest, PullFailAfterSuccess) {
|
||||
pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
|
||||
pullSuccess = true;
|
||||
|
||||
vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
EXPECT_TRUE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(1, dataHolder.size());
|
||||
EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
|
||||
EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
|
||||
EXPECT_EQ(1, dataHolder[0]->size());
|
||||
EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
|
||||
|
||||
sleep_for(std::chrono::seconds(1));
|
||||
|
||||
pullData.clear();
|
||||
pullData.push_back(createSimpleEvent(2222L, 44));
|
||||
|
||||
pullSuccess = false;
|
||||
dataHolder.clear();
|
||||
EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(0, dataHolder.size());
|
||||
|
||||
pullSuccess = true;
|
||||
dataHolder.clear();
|
||||
EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(0, dataHolder.size());
|
||||
}
|
||||
|
||||
// Test pull takes longer than timeout, 2nd pull happens shorter than cooldown
|
||||
TEST_F(StatsPullerTest, PullTakeTooLongAndPullFast) {
|
||||
pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
pullSuccess = true;
|
||||
// timeout is 0.5
|
||||
pullDelayNs = (long)(0.8 * NS_PER_SEC);
|
||||
|
||||
vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(0, dataHolder.size());
|
||||
|
||||
pullData.clear();
|
||||
pullData.push_back(createSimpleEvent(2222L, 44));
|
||||
|
||||
pullSuccess = true;
|
||||
dataHolder.clear();
|
||||
EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(0, dataHolder.size());
|
||||
}
|
||||
|
||||
TEST_F(StatsPullerTest, PullFail) {
|
||||
pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
|
||||
pullSuccess = false;
|
||||
|
||||
vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(0, dataHolder.size());
|
||||
}
|
||||
|
||||
TEST_F(StatsPullerTest, PullTakeTooLong) {
|
||||
pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
|
||||
pullSuccess = true;
|
||||
pullDelayNs = NS_PER_SEC;
|
||||
|
||||
vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(0, dataHolder.size());
|
||||
}
|
||||
|
||||
TEST_F(StatsPullerTest, PullTooFast) {
|
||||
pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
|
||||
pullSuccess = true;
|
||||
|
||||
vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
EXPECT_TRUE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(1, dataHolder.size());
|
||||
EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
|
||||
EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
|
||||
EXPECT_EQ(1, dataHolder[0]->size());
|
||||
EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
|
||||
|
||||
pullData.clear();
|
||||
pullData.push_back(createSimpleEvent(2222L, 44));
|
||||
|
||||
pullSuccess = true;
|
||||
|
||||
dataHolder.clear();
|
||||
EXPECT_TRUE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(1, dataHolder.size());
|
||||
EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
|
||||
EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
|
||||
EXPECT_EQ(1, dataHolder[0]->size());
|
||||
EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
|
||||
}
|
||||
|
||||
TEST_F(StatsPullerTest, PullFailsAndTooFast) {
|
||||
pullData.push_back(createSimpleEvent(1111L, 33));
|
||||
|
||||
pullSuccess = false;
|
||||
|
||||
vector<std::shared_ptr<LogEvent>> dataHolder;
|
||||
EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(0, dataHolder.size());
|
||||
|
||||
pullData.clear();
|
||||
pullData.push_back(createSimpleEvent(2222L, 44));
|
||||
|
||||
pullSuccess = true;
|
||||
|
||||
EXPECT_FALSE(puller.Pull(&dataHolder));
|
||||
EXPECT_EQ(0, dataHolder.size());
|
||||
}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
|
||||
389
cmds/statsd/tests/external/puller_util_test.cpp
vendored
389
cmds/statsd/tests/external/puller_util_test.cpp
vendored
@@ -13,12 +13,16 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "external/puller_util.h"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <vector>
|
||||
#include "statslog.h"
|
||||
|
||||
#include "../metrics/metrics_test_helper.h"
|
||||
#include "stats_event.h"
|
||||
#include "statslog.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
@@ -58,212 +62,187 @@ void extractIntoVector(vector<shared_ptr<LogEvent>> events,
|
||||
ret.push_back(vec);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<LogEvent> makeUidLogEvent(uint64_t timestampNs, int uid, int data1, int data2) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, uidAtomTagId);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, uid);
|
||||
AStatsEvent_writeInt32(statsEvent, data1);
|
||||
AStatsEvent_writeInt32(statsEvent, data2);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::shared_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
std::shared_ptr<LogEvent> makeNonUidAtomLogEvent(uint64_t timestampNs, int data1) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, nonUidAtomTagId);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, data1);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::shared_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// TODO(b/149590301): Update these tests to use new socket schema.
|
||||
//TEST(puller_util, MergeNoDimension) {
|
||||
// vector<shared_ptr<LogEvent>> inputData;
|
||||
// shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// // 30->22->31
|
||||
// event->write(isolatedUid);
|
||||
// event->write(hostNonAdditiveData);
|
||||
// event->write(isolatedAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// // 20->22->21
|
||||
// event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// event->write(hostUid);
|
||||
// event->write(hostNonAdditiveData);
|
||||
// event->write(hostAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
// EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
|
||||
// .WillRepeatedly(Return(hostUid));
|
||||
// EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
|
||||
// .WillRepeatedly(ReturnArg<0>());
|
||||
// mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields);
|
||||
//
|
||||
// vector<vector<int>> actual;
|
||||
// extractIntoVector(inputData, actual);
|
||||
// vector<int> expectedV1 = {20, 22, 52};
|
||||
// EXPECT_EQ(1, (int)actual.size());
|
||||
// EXPECT_THAT(actual, Contains(expectedV1));
|
||||
//}
|
||||
//
|
||||
//TEST(puller_util, MergeWithDimension) {
|
||||
// vector<shared_ptr<LogEvent>> inputData;
|
||||
// shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// // 30->32->31
|
||||
// event->write(isolatedUid);
|
||||
// event->write(isolatedNonAdditiveData);
|
||||
// event->write(isolatedAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// // 20->32->21
|
||||
// event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// event->write(hostUid);
|
||||
// event->write(isolatedNonAdditiveData);
|
||||
// event->write(hostAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// // 20->22->21
|
||||
// event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// event->write(hostUid);
|
||||
// event->write(hostNonAdditiveData);
|
||||
// event->write(hostAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
// EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
|
||||
// .WillRepeatedly(Return(hostUid));
|
||||
// EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
|
||||
// .WillRepeatedly(ReturnArg<0>());
|
||||
// mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields);
|
||||
//
|
||||
// vector<vector<int>> actual;
|
||||
// extractIntoVector(inputData, actual);
|
||||
// vector<int> expectedV1 = {20, 22, 21};
|
||||
// vector<int> expectedV2 = {20, 32, 52};
|
||||
// EXPECT_EQ(2, (int)actual.size());
|
||||
// EXPECT_THAT(actual, Contains(expectedV1));
|
||||
// EXPECT_THAT(actual, Contains(expectedV2));
|
||||
//}
|
||||
//
|
||||
//TEST(puller_util, NoMergeHostUidOnly) {
|
||||
// vector<shared_ptr<LogEvent>> inputData;
|
||||
// shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// // 20->32->31
|
||||
// event->write(hostUid);
|
||||
// event->write(isolatedNonAdditiveData);
|
||||
// event->write(isolatedAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// // 20->22->21
|
||||
// event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// event->write(hostUid);
|
||||
// event->write(hostNonAdditiveData);
|
||||
// event->write(hostAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
// EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
|
||||
// .WillRepeatedly(Return(hostUid));
|
||||
// EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
|
||||
// .WillRepeatedly(ReturnArg<0>());
|
||||
// mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields);
|
||||
//
|
||||
// // 20->32->31
|
||||
// // 20->22->21
|
||||
// vector<vector<int>> actual;
|
||||
// extractIntoVector(inputData, actual);
|
||||
// vector<int> expectedV1 = {20, 32, 31};
|
||||
// vector<int> expectedV2 = {20, 22, 21};
|
||||
// EXPECT_EQ(2, (int)actual.size());
|
||||
// EXPECT_THAT(actual, Contains(expectedV1));
|
||||
// EXPECT_THAT(actual, Contains(expectedV2));
|
||||
//}
|
||||
//
|
||||
//TEST(puller_util, IsolatedUidOnly) {
|
||||
// vector<shared_ptr<LogEvent>> inputData;
|
||||
// shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// // 30->32->31
|
||||
// event->write(hostUid);
|
||||
// event->write(isolatedNonAdditiveData);
|
||||
// event->write(isolatedAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// // 30->22->21
|
||||
// event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// event->write(hostUid);
|
||||
// event->write(hostNonAdditiveData);
|
||||
// event->write(hostAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
// EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
|
||||
// .WillRepeatedly(Return(hostUid));
|
||||
// EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
|
||||
// .WillRepeatedly(ReturnArg<0>());
|
||||
// mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields);
|
||||
//
|
||||
// // 20->32->31
|
||||
// // 20->22->21
|
||||
// vector<vector<int>> actual;
|
||||
// extractIntoVector(inputData, actual);
|
||||
// vector<int> expectedV1 = {20, 32, 31};
|
||||
// vector<int> expectedV2 = {20, 22, 21};
|
||||
// EXPECT_EQ(2, (int)actual.size());
|
||||
// EXPECT_THAT(actual, Contains(expectedV1));
|
||||
// EXPECT_THAT(actual, Contains(expectedV2));
|
||||
//}
|
||||
//
|
||||
//TEST(puller_util, MultipleIsolatedUidToOneHostUid) {
|
||||
// vector<shared_ptr<LogEvent>> inputData;
|
||||
// shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// // 30->32->31
|
||||
// event->write(isolatedUid);
|
||||
// event->write(isolatedNonAdditiveData);
|
||||
// event->write(isolatedAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// // 31->32->21
|
||||
// event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// event->write(isolatedUid + 1);
|
||||
// event->write(isolatedNonAdditiveData);
|
||||
// event->write(hostAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// // 20->32->21
|
||||
// event = make_shared<LogEvent>(uidAtomTagId, timestamp);
|
||||
// event->write(hostUid);
|
||||
// event->write(isolatedNonAdditiveData);
|
||||
// event->write(hostAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
// EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(Return(hostUid));
|
||||
// mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields);
|
||||
//
|
||||
// vector<vector<int>> actual;
|
||||
// extractIntoVector(inputData, actual);
|
||||
// vector<int> expectedV1 = {20, 32, 73};
|
||||
// EXPECT_EQ(1, (int)actual.size());
|
||||
// EXPECT_THAT(actual, Contains(expectedV1));
|
||||
//}
|
||||
//
|
||||
//TEST(puller_util, NoNeedToMerge) {
|
||||
// vector<shared_ptr<LogEvent>> inputData;
|
||||
// shared_ptr<LogEvent> event =
|
||||
// make_shared<LogEvent>(nonUidAtomTagId, timestamp);
|
||||
// // 32
|
||||
// event->write(isolatedNonAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// event = make_shared<LogEvent>(nonUidAtomTagId, timestamp);
|
||||
// // 22
|
||||
// event->write(hostNonAdditiveData);
|
||||
// event->init();
|
||||
// inputData.push_back(event);
|
||||
//
|
||||
// sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
// mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, nonUidAtomTagId, {} /*no additive fields*/);
|
||||
//
|
||||
// EXPECT_EQ(2, (int)inputData.size());
|
||||
//}
|
||||
TEST(puller_util, MergeNoDimension) {
|
||||
vector<shared_ptr<LogEvent>> inputData;
|
||||
|
||||
// 30->22->31
|
||||
inputData.push_back(
|
||||
makeUidLogEvent(timestamp, isolatedUid, hostNonAdditiveData, isolatedAdditiveData));
|
||||
|
||||
// 20->22->21
|
||||
inputData.push_back(makeUidLogEvent(timestamp, hostUid, hostNonAdditiveData, hostAdditiveData));
|
||||
|
||||
sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid));
|
||||
EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))).WillRepeatedly(ReturnArg<0>());
|
||||
mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields);
|
||||
|
||||
vector<vector<int>> actual;
|
||||
extractIntoVector(inputData, actual);
|
||||
vector<int> expectedV1 = {20, 22, 52};
|
||||
EXPECT_EQ(1, (int)actual.size());
|
||||
EXPECT_THAT(actual, Contains(expectedV1));
|
||||
}
|
||||
|
||||
TEST(puller_util, MergeWithDimension) {
|
||||
vector<shared_ptr<LogEvent>> inputData;
|
||||
|
||||
// 30->32->31
|
||||
inputData.push_back(
|
||||
makeUidLogEvent(timestamp, isolatedUid, isolatedNonAdditiveData, isolatedAdditiveData));
|
||||
|
||||
// 20->32->21
|
||||
inputData.push_back(
|
||||
makeUidLogEvent(timestamp, hostUid, isolatedNonAdditiveData, hostAdditiveData));
|
||||
|
||||
// 20->22->21
|
||||
inputData.push_back(makeUidLogEvent(timestamp, hostUid, hostNonAdditiveData, hostAdditiveData));
|
||||
|
||||
sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid));
|
||||
EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))).WillRepeatedly(ReturnArg<0>());
|
||||
mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields);
|
||||
|
||||
vector<vector<int>> actual;
|
||||
extractIntoVector(inputData, actual);
|
||||
vector<int> expectedV1 = {20, 22, 21};
|
||||
vector<int> expectedV2 = {20, 32, 52};
|
||||
EXPECT_EQ(2, (int)actual.size());
|
||||
EXPECT_THAT(actual, Contains(expectedV1));
|
||||
EXPECT_THAT(actual, Contains(expectedV2));
|
||||
}
|
||||
|
||||
TEST(puller_util, NoMergeHostUidOnly) {
|
||||
vector<shared_ptr<LogEvent>> inputData;
|
||||
|
||||
// 20->32->31
|
||||
inputData.push_back(
|
||||
makeUidLogEvent(timestamp, hostUid, isolatedNonAdditiveData, isolatedAdditiveData));
|
||||
|
||||
// 20->22->21
|
||||
inputData.push_back(makeUidLogEvent(timestamp, hostUid, hostNonAdditiveData, hostAdditiveData));
|
||||
|
||||
sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid));
|
||||
EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))).WillRepeatedly(ReturnArg<0>());
|
||||
mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields);
|
||||
|
||||
// 20->32->31
|
||||
// 20->22->21
|
||||
vector<vector<int>> actual;
|
||||
extractIntoVector(inputData, actual);
|
||||
vector<int> expectedV1 = {20, 32, 31};
|
||||
vector<int> expectedV2 = {20, 22, 21};
|
||||
EXPECT_EQ(2, (int)actual.size());
|
||||
EXPECT_THAT(actual, Contains(expectedV1));
|
||||
EXPECT_THAT(actual, Contains(expectedV2));
|
||||
}
|
||||
|
||||
TEST(puller_util, IsolatedUidOnly) {
|
||||
vector<shared_ptr<LogEvent>> inputData;
|
||||
|
||||
// 30->32->31
|
||||
inputData.push_back(
|
||||
makeUidLogEvent(timestamp, hostUid, isolatedNonAdditiveData, isolatedAdditiveData));
|
||||
|
||||
// 30->22->21
|
||||
inputData.push_back(makeUidLogEvent(timestamp, hostUid, hostNonAdditiveData, hostAdditiveData));
|
||||
|
||||
sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid));
|
||||
EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))).WillRepeatedly(ReturnArg<0>());
|
||||
mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields);
|
||||
|
||||
// 20->32->31
|
||||
// 20->22->21
|
||||
vector<vector<int>> actual;
|
||||
extractIntoVector(inputData, actual);
|
||||
vector<int> expectedV1 = {20, 32, 31};
|
||||
vector<int> expectedV2 = {20, 22, 21};
|
||||
EXPECT_EQ(2, (int)actual.size());
|
||||
EXPECT_THAT(actual, Contains(expectedV1));
|
||||
EXPECT_THAT(actual, Contains(expectedV2));
|
||||
}
|
||||
|
||||
TEST(puller_util, MultipleIsolatedUidToOneHostUid) {
|
||||
vector<shared_ptr<LogEvent>> inputData;
|
||||
|
||||
// 30->32->31
|
||||
inputData.push_back(
|
||||
makeUidLogEvent(timestamp, isolatedUid, isolatedNonAdditiveData, isolatedAdditiveData));
|
||||
|
||||
// 31->32->21
|
||||
inputData.push_back(
|
||||
makeUidLogEvent(timestamp, isolatedUid + 1, isolatedNonAdditiveData, hostAdditiveData));
|
||||
|
||||
// 20->32->21
|
||||
inputData.push_back(
|
||||
makeUidLogEvent(timestamp, hostUid, isolatedNonAdditiveData, hostAdditiveData));
|
||||
|
||||
sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(Return(hostUid));
|
||||
mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields);
|
||||
|
||||
vector<vector<int>> actual;
|
||||
extractIntoVector(inputData, actual);
|
||||
vector<int> expectedV1 = {20, 32, 73};
|
||||
EXPECT_EQ(1, (int)actual.size());
|
||||
EXPECT_THAT(actual, Contains(expectedV1));
|
||||
}
|
||||
|
||||
TEST(puller_util, NoNeedToMerge) {
|
||||
vector<shared_ptr<LogEvent>> inputData;
|
||||
|
||||
// 32
|
||||
inputData.push_back(makeNonUidAtomLogEvent(timestamp, isolatedNonAdditiveData));
|
||||
|
||||
// 22
|
||||
inputData.push_back(makeNonUidAtomLogEvent(timestamp, hostNonAdditiveData));
|
||||
|
||||
sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, nonUidAtomTagId, {} /*no additive fields*/);
|
||||
|
||||
EXPECT_EQ(2, (int)inputData.size());
|
||||
}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
|
||||
@@ -42,7 +42,7 @@ std::unique_ptr<LogEvent> makeLogEvent(uint64_t timestampNs) {
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/-1, /*pid=*/-1);
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
|
||||
@@ -13,16 +13,19 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/metrics/CountMetricProducer.h"
|
||||
#include "src/stats_log_util.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 "metrics_test_helper.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;
|
||||
@@ -37,366 +40,392 @@ namespace statsd {
|
||||
|
||||
const ConfigKey kConfigKey(0, 12345);
|
||||
|
||||
// TODO(b/149590301): Update these tests to use new socket schema.
|
||||
//TEST(CountMetricProducerTest, TestFirstBucket) {
|
||||
// CountMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
//
|
||||
// CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, 5,
|
||||
// 600 * NS_PER_SEC + NS_PER_SEC / 2);
|
||||
// EXPECT_EQ(600500000000, countProducer.mCurrentBucketStartTimeNs);
|
||||
// EXPECT_EQ(10, countProducer.mCurrentBucketNum);
|
||||
// EXPECT_EQ(660000000005, countProducer.getCurrentBucketEndTimeNs());
|
||||
//}
|
||||
//
|
||||
//TEST(CountMetricProducerTest, TestNonDimensionalEvents) {
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
// int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
|
||||
// int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
|
||||
// int tagId = 1;
|
||||
//
|
||||
// CountMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
//
|
||||
// LogEvent event1(tagId, bucketStartTimeNs + 1);
|
||||
// event1.init();
|
||||
// LogEvent event2(tagId, bucketStartTimeNs + 2);
|
||||
// event2.init();
|
||||
//
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
//
|
||||
// CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
|
||||
// bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// // 2 events in bucket 1.
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
|
||||
//
|
||||
// // Flushes at event #2.
|
||||
// countProducer.flushIfNeededLocked(bucketStartTimeNs + 2);
|
||||
// EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
//
|
||||
// // Flushes.
|
||||
// countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
|
||||
// EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
|
||||
// EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
// countProducer.mPastBuckets.end());
|
||||
// const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(1UL, buckets.size());
|
||||
// EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
|
||||
// EXPECT_EQ(2LL, buckets[0].mCount);
|
||||
//
|
||||
// // 1 matched event happens in bucket 2.
|
||||
// LogEvent event3(tagId, bucketStartTimeNs + bucketSizeNs + 2);
|
||||
// event3.init();
|
||||
//
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
|
||||
// countProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
// EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
|
||||
// EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
// countProducer.mPastBuckets.end());
|
||||
// EXPECT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
// const auto& bucketInfo2 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1];
|
||||
// EXPECT_EQ(bucket2StartTimeNs, bucketInfo2.mBucketStartNs);
|
||||
// EXPECT_EQ(bucket2StartTimeNs + bucketSizeNs, bucketInfo2.mBucketEndNs);
|
||||
// EXPECT_EQ(1LL, bucketInfo2.mCount);
|
||||
//
|
||||
// // nothing happens in bucket 3. we should not record anything for bucket 3.
|
||||
// countProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
|
||||
// EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
|
||||
// EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
// countProducer.mPastBuckets.end());
|
||||
// const auto& buckets3 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(2UL, buckets3.size());
|
||||
//}
|
||||
//
|
||||
//TEST(CountMetricProducerTest, TestEventsWithNonSlicedCondition) {
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
//
|
||||
// CountMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// metric.set_condition(StringToId("SCREEN_ON"));
|
||||
//
|
||||
// LogEvent event1(1, bucketStartTimeNs + 1);
|
||||
// event1.init();
|
||||
//
|
||||
// LogEvent event2(1, bucketStartTimeNs + 10);
|
||||
// event2.init();
|
||||
//
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
//
|
||||
// CountMetricProducer countProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs,
|
||||
// bucketStartTimeNs);
|
||||
//
|
||||
// countProducer.onConditionChanged(true, bucketStartTimeNs);
|
||||
// countProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
|
||||
// EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
//
|
||||
// countProducer.onConditionChanged(false /*new condition*/, bucketStartTimeNs + 2);
|
||||
// // Upon this match event, the matched event1 is flushed.
|
||||
// countProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
|
||||
// EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
//
|
||||
// countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
|
||||
// EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
|
||||
// EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
// countProducer.mPastBuckets.end());
|
||||
// {
|
||||
// const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(1UL, buckets.size());
|
||||
// const auto& bucketInfo = buckets[0];
|
||||
// EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
|
||||
// EXPECT_EQ(1LL, bucketInfo.mCount);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//TEST(CountMetricProducerTest, TestEventsWithSlicedCondition) {
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
//
|
||||
// int tagId = 1;
|
||||
// int conditionTagId = 2;
|
||||
//
|
||||
// CountMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
|
||||
// MetricConditionLink* link = metric.add_links();
|
||||
// link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
|
||||
// buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
|
||||
// buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
|
||||
//
|
||||
// LogEvent event1(tagId, bucketStartTimeNs + 1);
|
||||
// event1.write("111"); // uid
|
||||
// event1.init();
|
||||
// ConditionKey key1;
|
||||
// key1[StringToId("APP_IN_BACKGROUND_PER_UID")] =
|
||||
// {getMockedDimensionKey(conditionTagId, 2, "111")};
|
||||
//
|
||||
// LogEvent event2(tagId, bucketStartTimeNs + 10);
|
||||
// event2.write("222"); // uid
|
||||
// event2.init();
|
||||
// ConditionKey key2;
|
||||
// key2[StringToId("APP_IN_BACKGROUND_PER_UID")] =
|
||||
// {getMockedDimensionKey(conditionTagId, 2, "222")};
|
||||
//
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
|
||||
//
|
||||
// EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
|
||||
//
|
||||
// CountMetricProducer countProducer(kConfigKey, metric, 1 /*condition tracker index*/, wizard,
|
||||
// bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
|
||||
// countProducer.flushIfNeededLocked(bucketStartTimeNs + 1);
|
||||
// EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
//
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
|
||||
// countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
|
||||
// EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
|
||||
// EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
// countProducer.mPastBuckets.end());
|
||||
// const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(1UL, buckets.size());
|
||||
// const auto& bucketInfo = buckets[0];
|
||||
// EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
|
||||
// EXPECT_EQ(1LL, bucketInfo.mCount);
|
||||
//}
|
||||
//
|
||||
//TEST(CountMetricProducerTest, TestEventWithAppUpgrade) {
|
||||
// sp<AlarmMonitor> alarmMonitor;
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
// int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
|
||||
//
|
||||
// int tagId = 1;
|
||||
// int conditionTagId = 2;
|
||||
//
|
||||
// CountMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// Alert alert;
|
||||
// alert.set_num_buckets(3);
|
||||
// alert.set_trigger_if_sum_gt(2);
|
||||
// LogEvent event1(tagId, bucketStartTimeNs + 1);
|
||||
// event1.write("111"); // uid
|
||||
// event1.init();
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, wizard,
|
||||
// bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
|
||||
// EXPECT_TRUE(anomalyTracker != nullptr);
|
||||
//
|
||||
// // Bucket is flushed yet.
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
|
||||
// EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
// EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
|
||||
//
|
||||
// // App upgrade forces bucket flush.
|
||||
// // Check that there's a past bucket and the bucket end is not adjusted.
|
||||
// countProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
// EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
// EXPECT_EQ((long long)bucketStartTimeNs,
|
||||
// countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
|
||||
// EXPECT_EQ((long long)eventUpgradeTimeNs,
|
||||
// countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, countProducer.mCurrentBucketStartTimeNs);
|
||||
// // Anomaly tracker only contains full buckets.
|
||||
// EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
|
||||
//
|
||||
// int64_t lastEndTimeNs = countProducer.getCurrentBucketEndTimeNs();
|
||||
// // Next event occurs in same bucket as partial bucket created.
|
||||
// LogEvent event2(tagId, bucketStartTimeNs + 59 * NS_PER_SEC + 10);
|
||||
// event2.write("222"); // uid
|
||||
// event2.init();
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
|
||||
// EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, countProducer.mCurrentBucketStartTimeNs);
|
||||
// EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
|
||||
//
|
||||
// // Third event in following bucket.
|
||||
// LogEvent event3(tagId, bucketStartTimeNs + 62 * NS_PER_SEC + 10);
|
||||
// event3.write("333"); // uid
|
||||
// event3.init();
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
|
||||
// EXPECT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
// EXPECT_EQ(lastEndTimeNs, countProducer.mCurrentBucketStartTimeNs);
|
||||
// EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
|
||||
//}
|
||||
//
|
||||
//TEST(CountMetricProducerTest, TestEventWithAppUpgradeInNextBucket) {
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
// int64_t eventUpgradeTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
|
||||
//
|
||||
// int tagId = 1;
|
||||
// int conditionTagId = 2;
|
||||
//
|
||||
// CountMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// LogEvent event1(tagId, bucketStartTimeNs + 1);
|
||||
// event1.write("111"); // uid
|
||||
// event1.init();
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, wizard,
|
||||
// bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// // Bucket is flushed yet.
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
|
||||
// EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
//
|
||||
// // App upgrade forces bucket flush.
|
||||
// // Check that there's a past bucket and the bucket end is not adjusted.
|
||||
// countProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
// EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
// EXPECT_EQ((int64_t)bucketStartTimeNs,
|
||||
// countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
// countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, countProducer.mCurrentBucketStartTimeNs);
|
||||
//
|
||||
// // Next event occurs in same bucket as partial bucket created.
|
||||
// LogEvent event2(tagId, bucketStartTimeNs + 70 * NS_PER_SEC + 10);
|
||||
// event2.write("222"); // uid
|
||||
// event2.init();
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
|
||||
// EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
//
|
||||
// // Third event in following bucket.
|
||||
// LogEvent event3(tagId, bucketStartTimeNs + 121 * NS_PER_SEC + 10);
|
||||
// event3.write("333"); // uid
|
||||
// event3.init();
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
|
||||
// EXPECT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
// EXPECT_EQ((int64_t)eventUpgradeTimeNs,
|
||||
// countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
// countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketEndNs);
|
||||
//}
|
||||
//
|
||||
//TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced) {
|
||||
// sp<AlarmMonitor> alarmMonitor;
|
||||
// Alert alert;
|
||||
// alert.set_id(11);
|
||||
// alert.set_metric_id(1);
|
||||
// alert.set_trigger_if_sum_gt(2);
|
||||
// alert.set_num_buckets(2);
|
||||
// const int32_t refPeriodSec = 1;
|
||||
// alert.set_refractory_period_secs(refPeriodSec);
|
||||
//
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
// int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
|
||||
// int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
|
||||
//
|
||||
// CountMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
//
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
|
||||
// bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
|
||||
//
|
||||
// int tagId = 1;
|
||||
// LogEvent event1(tagId, bucketStartTimeNs + 1);
|
||||
// event1.init();
|
||||
// LogEvent event2(tagId, bucketStartTimeNs + 2);
|
||||
// event2.init();
|
||||
// LogEvent event3(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
// event3.init();
|
||||
// LogEvent event4(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 1);
|
||||
// event4.init();
|
||||
// LogEvent event5(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 2);
|
||||
// event5.init();
|
||||
// LogEvent event6(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 3);
|
||||
// event6.init();
|
||||
// LogEvent event7(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC);
|
||||
// event7.init();
|
||||
//
|
||||
// // Two events in bucket #0.
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
|
||||
//
|
||||
// EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
|
||||
// EXPECT_EQ(2L, countProducer.mCurrentSlicedCounter->begin()->second);
|
||||
// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
|
||||
//
|
||||
// // One event in bucket #2. No alarm as bucket #0 is trashed out.
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
|
||||
// EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
|
||||
// EXPECT_EQ(1L, countProducer.mCurrentSlicedCounter->begin()->second);
|
||||
// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
|
||||
//
|
||||
// // Two events in bucket #3.
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event5);
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event6);
|
||||
// EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
|
||||
// EXPECT_EQ(3L, countProducer.mCurrentSlicedCounter->begin()->second);
|
||||
// // Anomaly at event 6 is within refractory period. The alarm is at event 5 timestamp not event 6
|
||||
// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
|
||||
// std::ceil(1.0 * event5.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
|
||||
//
|
||||
// countProducer.onMatchedLogEvent(1 /*log matcher index*/, event7);
|
||||
// EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
|
||||
// EXPECT_EQ(4L, countProducer.mCurrentSlicedCounter->begin()->second);
|
||||
// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
|
||||
// std::ceil(1.0 * event7.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
|
||||
//}
|
||||
namespace {
|
||||
|
||||
void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, atomId);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
}
|
||||
|
||||
void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId, string uid) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, atomId);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeString(statsEvent, uid.c_str());
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(CountMetricProducerTest, TestFirstBucket) {
|
||||
CountMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
|
||||
CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, 5,
|
||||
600 * NS_PER_SEC + NS_PER_SEC / 2);
|
||||
EXPECT_EQ(600500000000, countProducer.mCurrentBucketStartTimeNs);
|
||||
EXPECT_EQ(10, countProducer.mCurrentBucketNum);
|
||||
EXPECT_EQ(660000000005, countProducer.getCurrentBucketEndTimeNs());
|
||||
}
|
||||
|
||||
TEST(CountMetricProducerTest, TestNonDimensionalEvents) {
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
|
||||
int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
|
||||
int tagId = 1;
|
||||
|
||||
CountMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
|
||||
CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
|
||||
bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
// 2 events in bucket 1.
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
|
||||
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
|
||||
|
||||
// Flushes at event #2.
|
||||
countProducer.flushIfNeededLocked(bucketStartTimeNs + 2);
|
||||
EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
|
||||
// Flushes.
|
||||
countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
|
||||
EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
|
||||
EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
countProducer.mPastBuckets.end());
|
||||
const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(1UL, buckets.size());
|
||||
EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
|
||||
EXPECT_EQ(2LL, buckets[0].mCount);
|
||||
|
||||
// 1 matched event happens in bucket 2.
|
||||
LogEvent event3(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 2, tagId);
|
||||
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
|
||||
|
||||
countProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
|
||||
EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
countProducer.mPastBuckets.end());
|
||||
EXPECT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
const auto& bucketInfo2 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1];
|
||||
EXPECT_EQ(bucket2StartTimeNs, bucketInfo2.mBucketStartNs);
|
||||
EXPECT_EQ(bucket2StartTimeNs + bucketSizeNs, bucketInfo2.mBucketEndNs);
|
||||
EXPECT_EQ(1LL, bucketInfo2.mCount);
|
||||
|
||||
// nothing happens in bucket 3. we should not record anything for bucket 3.
|
||||
countProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
|
||||
EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
|
||||
EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
countProducer.mPastBuckets.end());
|
||||
const auto& buckets3 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(2UL, buckets3.size());
|
||||
}
|
||||
|
||||
TEST(CountMetricProducerTest, TestEventsWithNonSlicedCondition) {
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
|
||||
CountMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
metric.set_condition(StringToId("SCREEN_ON"));
|
||||
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
|
||||
CountMetricProducer countProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs,
|
||||
bucketStartTimeNs);
|
||||
|
||||
countProducer.onConditionChanged(true, bucketStartTimeNs);
|
||||
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, bucketStartTimeNs + 1, /*atomId=*/1);
|
||||
countProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
|
||||
|
||||
EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
|
||||
countProducer.onConditionChanged(false /*new condition*/, bucketStartTimeNs + 2);
|
||||
|
||||
// Upon this match event, the matched event1 is flushed.
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, bucketStartTimeNs + 10, /*atomId=*/1);
|
||||
countProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
|
||||
EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
|
||||
countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
|
||||
EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
|
||||
EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
countProducer.mPastBuckets.end());
|
||||
|
||||
const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(1UL, buckets.size());
|
||||
const auto& bucketInfo = buckets[0];
|
||||
EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
|
||||
EXPECT_EQ(1LL, bucketInfo.mCount);
|
||||
}
|
||||
|
||||
TEST(CountMetricProducerTest, TestEventsWithSlicedCondition) {
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
|
||||
int tagId = 1;
|
||||
int conditionTagId = 2;
|
||||
|
||||
CountMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
|
||||
MetricConditionLink* link = metric.add_links();
|
||||
link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
|
||||
buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
|
||||
buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
|
||||
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
|
||||
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, bucketStartTimeNs + 10, tagId, /*uid=*/"222");
|
||||
|
||||
ConditionKey key1;
|
||||
key1[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
|
||||
getMockedDimensionKey(conditionTagId, 2, "111")};
|
||||
|
||||
ConditionKey key2;
|
||||
key2[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
|
||||
getMockedDimensionKey(conditionTagId, 2, "222")};
|
||||
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
|
||||
|
||||
EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
|
||||
|
||||
CountMetricProducer countProducer(kConfigKey, metric, 1 /*condition tracker index*/, wizard,
|
||||
bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
|
||||
countProducer.flushIfNeededLocked(bucketStartTimeNs + 1);
|
||||
EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
|
||||
countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
|
||||
EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
|
||||
EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
countProducer.mPastBuckets.end());
|
||||
const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(1UL, buckets.size());
|
||||
const auto& bucketInfo = buckets[0];
|
||||
EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
|
||||
EXPECT_EQ(1LL, bucketInfo.mCount);
|
||||
}
|
||||
|
||||
TEST(CountMetricProducerTest, TestEventWithAppUpgrade) {
|
||||
sp<AlarmMonitor> alarmMonitor;
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
|
||||
|
||||
int tagId = 1;
|
||||
int conditionTagId = 2;
|
||||
|
||||
CountMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
Alert alert;
|
||||
alert.set_num_buckets(3);
|
||||
alert.set_trigger_if_sum_gt(2);
|
||||
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, wizard,
|
||||
bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
|
||||
EXPECT_TRUE(anomalyTracker != nullptr);
|
||||
|
||||
// Bucket is flushed yet.
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
|
||||
EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
|
||||
|
||||
// App upgrade forces bucket flush.
|
||||
// Check that there's a past bucket and the bucket end is not adjusted.
|
||||
countProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
EXPECT_EQ((long long)bucketStartTimeNs,
|
||||
countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
|
||||
EXPECT_EQ((long long)eventUpgradeTimeNs,
|
||||
countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
|
||||
EXPECT_EQ(eventUpgradeTimeNs, countProducer.mCurrentBucketStartTimeNs);
|
||||
// Anomaly tracker only contains full buckets.
|
||||
EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
|
||||
|
||||
int64_t lastEndTimeNs = countProducer.getCurrentBucketEndTimeNs();
|
||||
// Next event occurs in same bucket as partial bucket created.
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, bucketStartTimeNs + 59 * NS_PER_SEC + 10, tagId, /*uid=*/"222");
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
|
||||
EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
EXPECT_EQ(eventUpgradeTimeNs, countProducer.mCurrentBucketStartTimeNs);
|
||||
EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
|
||||
|
||||
// Third event in following bucket.
|
||||
LogEvent event3(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event3, bucketStartTimeNs + 62 * NS_PER_SEC + 10, tagId, /*uid=*/"333");
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
|
||||
EXPECT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
EXPECT_EQ(lastEndTimeNs, countProducer.mCurrentBucketStartTimeNs);
|
||||
EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
|
||||
}
|
||||
|
||||
TEST(CountMetricProducerTest, TestEventWithAppUpgradeInNextBucket) {
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
int64_t eventUpgradeTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
|
||||
|
||||
int tagId = 1;
|
||||
int conditionTagId = 2;
|
||||
|
||||
CountMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, wizard,
|
||||
bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
// Bucket is flushed yet.
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
|
||||
EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
|
||||
|
||||
// App upgrade forces bucket flush.
|
||||
// Check that there's a past bucket and the bucket end is not adjusted.
|
||||
countProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
EXPECT_EQ((int64_t)bucketStartTimeNs,
|
||||
countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
|
||||
countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
|
||||
EXPECT_EQ(eventUpgradeTimeNs, countProducer.mCurrentBucketStartTimeNs);
|
||||
|
||||
// Next event occurs in same bucket as partial bucket created.
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, bucketStartTimeNs + 70 * NS_PER_SEC + 10, tagId, /*uid=*/"222");
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
|
||||
EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
|
||||
// Third event in following bucket.
|
||||
LogEvent event3(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event3, bucketStartTimeNs + 121 * NS_PER_SEC + 10, tagId, /*uid=*/"333");
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
|
||||
EXPECT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
EXPECT_EQ((int64_t)eventUpgradeTimeNs,
|
||||
countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
|
||||
countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketEndNs);
|
||||
}
|
||||
|
||||
TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced) {
|
||||
sp<AlarmMonitor> alarmMonitor;
|
||||
Alert alert;
|
||||
alert.set_id(11);
|
||||
alert.set_metric_id(1);
|
||||
alert.set_trigger_if_sum_gt(2);
|
||||
alert.set_num_buckets(2);
|
||||
const int32_t refPeriodSec = 1;
|
||||
alert.set_refractory_period_secs(refPeriodSec);
|
||||
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
|
||||
int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
|
||||
|
||||
CountMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
|
||||
bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
|
||||
|
||||
int tagId = 1;
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
|
||||
LogEvent event3(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event3, bucketStartTimeNs + 2 * bucketSizeNs + 1, tagId);
|
||||
LogEvent event4(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event4, bucketStartTimeNs + 3 * bucketSizeNs + 1, tagId);
|
||||
LogEvent event5(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event5, bucketStartTimeNs + 3 * bucketSizeNs + 2, tagId);
|
||||
LogEvent event6(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event6, bucketStartTimeNs + 3 * bucketSizeNs + 3, tagId);
|
||||
LogEvent event7(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event7, bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC, tagId);
|
||||
|
||||
// Two events in bucket #0.
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
|
||||
|
||||
EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
|
||||
EXPECT_EQ(2L, countProducer.mCurrentSlicedCounter->begin()->second);
|
||||
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
|
||||
|
||||
// One event in bucket #2. No alarm as bucket #0 is trashed out.
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
|
||||
EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
|
||||
EXPECT_EQ(1L, countProducer.mCurrentSlicedCounter->begin()->second);
|
||||
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
|
||||
|
||||
// Two events in bucket #3.
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event5);
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event6);
|
||||
EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
|
||||
EXPECT_EQ(3L, countProducer.mCurrentSlicedCounter->begin()->second);
|
||||
// Anomaly at event 6 is within refractory period. The alarm is at event 5 timestamp not event 6
|
||||
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
|
||||
std::ceil(1.0 * event5.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
|
||||
|
||||
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event7);
|
||||
EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
|
||||
EXPECT_EQ(4L, countProducer.mCurrentSlicedCounter->begin()->second);
|
||||
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
|
||||
std::ceil(1.0 * event7.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
|
||||
}
|
||||
|
||||
TEST(CountMetricProducerTest, TestOneWeekTimeUnit) {
|
||||
CountMetric metric;
|
||||
|
||||
@@ -13,17 +13,20 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/metrics/DurationMetricProducer.h"
|
||||
#include "src/stats_log_util.h"
|
||||
#include "metrics_test_helper.h"
|
||||
#include "src/condition/ConditionWizard.h"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "metrics_test_helper.h"
|
||||
#include "src/condition/ConditionWizard.h"
|
||||
#include "src/stats_log_util.h"
|
||||
#include "stats_event.h"
|
||||
|
||||
using namespace android::os::statsd;
|
||||
using namespace testing;
|
||||
using android::sp;
|
||||
@@ -39,6 +42,22 @@ namespace statsd {
|
||||
|
||||
const ConfigKey kConfigKey(0, 12345);
|
||||
|
||||
namespace {
|
||||
|
||||
void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, atomId);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(DurationMetricTrackerTest, TestFirstBucket) {
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
DurationMetric metric;
|
||||
@@ -56,383 +75,386 @@ TEST(DurationMetricTrackerTest, TestFirstBucket) {
|
||||
EXPECT_EQ(660000000005, durationProducer.getCurrentBucketEndTimeNs());
|
||||
}
|
||||
|
||||
// TODO(b/149590301): Update these to use new socket schema.
|
||||
//TEST(DurationMetricTrackerTest, TestNoCondition) {
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
//
|
||||
// DurationMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
//
|
||||
// int tagId = 1;
|
||||
// LogEvent event1(tagId, bucketStartTimeNs + 1);
|
||||
// event1.init();
|
||||
// LogEvent event2(tagId, bucketStartTimeNs + bucketSizeNs + 2);
|
||||
// event2.init();
|
||||
//
|
||||
// FieldMatcher dimensions;
|
||||
// DurationMetricProducer durationProducer(
|
||||
// kConfigKey, metric, -1 /*no condition*/, 1 /* start index */, 2 /* stop index */,
|
||||
// 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
|
||||
// durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
|
||||
// durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
// EXPECT_EQ(1UL, durationProducer.mPastBuckets.size());
|
||||
// EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
// durationProducer.mPastBuckets.end());
|
||||
// const auto& buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(2UL, buckets.size());
|
||||
// EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
|
||||
// EXPECT_EQ(bucketSizeNs - 1LL, buckets[0].mDuration);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[1].mBucketEndNs);
|
||||
// EXPECT_EQ(2LL, buckets[1].mDuration);
|
||||
//}
|
||||
//
|
||||
//TEST(DurationMetricTrackerTest, TestNonSlicedCondition) {
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
//
|
||||
// DurationMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
//
|
||||
// int tagId = 1;
|
||||
// LogEvent event1(tagId, bucketStartTimeNs + 1);
|
||||
// event1.init();
|
||||
// LogEvent event2(tagId, bucketStartTimeNs + 2);
|
||||
// event2.init();
|
||||
// LogEvent event3(tagId, bucketStartTimeNs + bucketSizeNs + 1);
|
||||
// event3.init();
|
||||
// LogEvent event4(tagId, bucketStartTimeNs + bucketSizeNs + 3);
|
||||
// event4.init();
|
||||
//
|
||||
// FieldMatcher dimensions;
|
||||
// DurationMetricProducer durationProducer(
|
||||
// kConfigKey, metric, 0 /* condition index */, 1 /* start index */, 2 /* stop index */,
|
||||
// 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
// durationProducer.mCondition = ConditionState::kFalse;
|
||||
//
|
||||
// EXPECT_FALSE(durationProducer.mCondition);
|
||||
// EXPECT_FALSE(durationProducer.isConditionSliced());
|
||||
//
|
||||
// durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
|
||||
// durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
|
||||
// durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
|
||||
// EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
//
|
||||
// durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
|
||||
// durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
|
||||
// durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
|
||||
// durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
// EXPECT_EQ(1UL, durationProducer.mPastBuckets.size());
|
||||
// EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
// durationProducer.mPastBuckets.end());
|
||||
// const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(1UL, buckets2.size());
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
|
||||
// EXPECT_EQ(1LL, buckets2[0].mDuration);
|
||||
//}
|
||||
//
|
||||
//TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState) {
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
//
|
||||
// DurationMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
//
|
||||
// int tagId = 1;
|
||||
// LogEvent event1(tagId, bucketStartTimeNs + 1);
|
||||
// event1.init();
|
||||
// LogEvent event2(tagId, bucketStartTimeNs + 2);
|
||||
// event2.init();
|
||||
// LogEvent event3(tagId, bucketStartTimeNs + bucketSizeNs + 1);
|
||||
// event3.init();
|
||||
// LogEvent event4(tagId, bucketStartTimeNs + bucketSizeNs + 3);
|
||||
// event4.init();
|
||||
//
|
||||
// FieldMatcher dimensions;
|
||||
// DurationMetricProducer durationProducer(
|
||||
// kConfigKey, metric, 0 /* condition index */, 1 /* start index */, 2 /* stop index */,
|
||||
// 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// EXPECT_EQ(ConditionState::kUnknown, durationProducer.mCondition);
|
||||
// EXPECT_FALSE(durationProducer.isConditionSliced());
|
||||
//
|
||||
// durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
|
||||
// durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
|
||||
// durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
|
||||
// EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
//
|
||||
// durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
|
||||
// durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
|
||||
// durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
|
||||
// durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
// EXPECT_EQ(1UL, durationProducer.mPastBuckets.size());
|
||||
// const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(1UL, buckets2.size());
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
|
||||
// EXPECT_EQ(1LL, buckets2[0].mDuration);
|
||||
//}
|
||||
//
|
||||
//TEST(DurationMetricTrackerTest, TestSumDurationWithUpgrade) {
|
||||
// /**
|
||||
// * The duration starts from the first bucket, through the two partial buckets (10-70sec),
|
||||
// * another bucket, and ends at the beginning of the next full bucket.
|
||||
// * Expected buckets:
|
||||
// * - [10,25]: 14 secs
|
||||
// * - [25,70]: All 45 secs
|
||||
// * - [70,130]: All 60 secs
|
||||
// * - [130, 210]: Only 5 secs (event ended at 135sec)
|
||||
// */
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
// int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
|
||||
// int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
|
||||
// int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
|
||||
//
|
||||
// int tagId = 1;
|
||||
//
|
||||
// DurationMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// FieldMatcher dimensions;
|
||||
// DurationMetricProducer durationProducer(
|
||||
// kConfigKey, metric, -1 /* no condition */, 1 /* start index */, 2 /* stop index */,
|
||||
// 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// LogEvent start_event(tagId, startTimeNs);
|
||||
// start_event.init();
|
||||
// durationProducer.onMatchedLogEvent(1 /* start index*/, start_event);
|
||||
// EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
// EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
//
|
||||
// durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
// EXPECT_EQ(1UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
// std::vector<DurationBucket> buckets =
|
||||
// durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, buckets[0].mBucketEndNs);
|
||||
// EXPECT_EQ(eventUpgradeTimeNs - startTimeNs, buckets[0].mDuration);
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
//
|
||||
// // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
|
||||
// LogEvent end_event(tagId, endTimeNs);
|
||||
// end_event.init();
|
||||
// durationProducer.onMatchedLogEvent(2 /* stop index*/, end_event);
|
||||
// buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(3UL, buckets.size());
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, buckets[1].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketEndNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - eventUpgradeTimeNs, buckets[1].mDuration);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[2].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs);
|
||||
// EXPECT_EQ(bucketSizeNs, buckets[2].mDuration);
|
||||
//}
|
||||
//
|
||||
//TEST(DurationMetricTrackerTest, TestSumDurationWithUpgradeInFollowingBucket) {
|
||||
// /**
|
||||
// * Expected buckets (start at 11s, upgrade at 75s, end at 135s):
|
||||
// * - [10,70]: 59 secs
|
||||
// * - [70,75]: 5 sec
|
||||
// * - [75,130]: 55 secs
|
||||
// */
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
// int64_t eventUpgradeTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
|
||||
// int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
|
||||
// int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
|
||||
//
|
||||
// int tagId = 1;
|
||||
//
|
||||
// DurationMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// FieldMatcher dimensions;
|
||||
// DurationMetricProducer durationProducer(
|
||||
// kConfigKey, metric, -1 /* no condition */, 1 /* start index */, 2 /* stop index */,
|
||||
// 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// LogEvent start_event(tagId, startTimeNs);
|
||||
// start_event.init();
|
||||
// durationProducer.onMatchedLogEvent(1 /* start index*/, start_event);
|
||||
// EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
// EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
//
|
||||
// durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
// EXPECT_EQ(2UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
// std::vector<DurationBucket> buckets =
|
||||
// durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs, buckets[0].mDuration);
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketStartNs);
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, buckets[1].mBucketEndNs);
|
||||
// EXPECT_EQ(eventUpgradeTimeNs - (bucketStartTimeNs + bucketSizeNs), buckets[1].mDuration);
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
//
|
||||
// // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
|
||||
// LogEvent end_event(tagId, endTimeNs);
|
||||
// end_event.init();
|
||||
// durationProducer.onMatchedLogEvent(2 /* stop index*/, end_event);
|
||||
// buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(3UL, buckets.size());
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, buckets[2].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs - eventUpgradeTimeNs, buckets[2].mDuration);
|
||||
//}
|
||||
//
|
||||
//TEST(DurationMetricTrackerTest, TestSumDurationAnomalyWithUpgrade) {
|
||||
// sp<AlarmMonitor> alarmMonitor;
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
// int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
|
||||
// int64_t startTimeNs = bucketStartTimeNs + 1;
|
||||
// int64_t endTimeNs = startTimeNs + 65 * NS_PER_SEC;
|
||||
//
|
||||
// int tagId = 1;
|
||||
//
|
||||
// // Setup metric with alert.
|
||||
// DurationMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
// Alert alert;
|
||||
// alert.set_num_buckets(3);
|
||||
// alert.set_trigger_if_sum_gt(2);
|
||||
//
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// FieldMatcher dimensions;
|
||||
// DurationMetricProducer durationProducer(
|
||||
// kConfigKey, metric, -1 /* no condition */, 1 /* start index */, 2 /* stop index */,
|
||||
// 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// sp<AnomalyTracker> anomalyTracker = durationProducer.addAnomalyTracker(alert, alarmMonitor);
|
||||
// EXPECT_TRUE(anomalyTracker != nullptr);
|
||||
//
|
||||
// LogEvent start_event(tagId, startTimeNs);
|
||||
// start_event.init();
|
||||
// durationProducer.onMatchedLogEvent(1 /* start index*/, start_event);
|
||||
// durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
// // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
|
||||
// LogEvent end_event(tagId, endTimeNs);
|
||||
// end_event.init();
|
||||
// durationProducer.onMatchedLogEvent(2 /* stop index*/, end_event);
|
||||
//
|
||||
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs,
|
||||
// anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
|
||||
//}
|
||||
//
|
||||
//TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgrade) {
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
// int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
|
||||
// int64_t startTimeNs = bucketStartTimeNs + 1;
|
||||
// int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
|
||||
//
|
||||
// int tagId = 1;
|
||||
//
|
||||
// DurationMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// metric.set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
|
||||
// LogEvent event1(tagId, startTimeNs);
|
||||
// event1.write("111"); // uid
|
||||
// event1.init();
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// FieldMatcher dimensions;
|
||||
// DurationMetricProducer durationProducer(
|
||||
// kConfigKey, metric, -1 /* no condition */, 1 /* start index */, 2 /* stop index */,
|
||||
// 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// LogEvent start_event(tagId, startTimeNs);
|
||||
// start_event.init();
|
||||
// durationProducer.onMatchedLogEvent(1 /* start index*/, start_event);
|
||||
// EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
// EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
//
|
||||
// durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
// EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
//
|
||||
// // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
|
||||
// LogEvent end_event(tagId, endTimeNs);
|
||||
// end_event.init();
|
||||
// durationProducer.onMatchedLogEvent(2 /* stop index*/, end_event);
|
||||
// EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
//
|
||||
// durationProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
|
||||
// std::vector<DurationBucket> buckets =
|
||||
// durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(1UL, buckets.size());
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, buckets[0].mBucketEndNs);
|
||||
// EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
|
||||
//}
|
||||
//
|
||||
//TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgradeInNextBucket) {
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
// int64_t eventUpgradeTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
|
||||
// int64_t startTimeNs = bucketStartTimeNs + 1;
|
||||
// int64_t endTimeNs = startTimeNs + 115 * NS_PER_SEC;
|
||||
//
|
||||
// int tagId = 1;
|
||||
//
|
||||
// DurationMetric metric;
|
||||
// metric.set_id(1);
|
||||
// metric.set_bucket(ONE_MINUTE);
|
||||
// metric.set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
|
||||
// LogEvent event1(tagId, startTimeNs);
|
||||
// event1.write("111"); // uid
|
||||
// event1.init();
|
||||
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
// FieldMatcher dimensions;
|
||||
// DurationMetricProducer durationProducer(
|
||||
// kConfigKey, metric, -1 /* no condition */, 1 /* start index */, 2 /* stop index */,
|
||||
// 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
//
|
||||
// LogEvent start_event(tagId, startTimeNs);
|
||||
// start_event.init();
|
||||
// durationProducer.onMatchedLogEvent(1 /* start index*/, start_event);
|
||||
// EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
// EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
//
|
||||
// durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
// EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
//
|
||||
// // Stop occurs in the same partial bucket as created for the app upgrade.
|
||||
// LogEvent end_event(tagId, endTimeNs);
|
||||
// end_event.init();
|
||||
// durationProducer.onMatchedLogEvent(2 /* stop index*/, end_event);
|
||||
// EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
//
|
||||
// durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
// std::vector<DurationBucket> buckets =
|
||||
// durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
// EXPECT_EQ(1UL, buckets.size());
|
||||
// EXPECT_EQ(eventUpgradeTimeNs, buckets[0].mBucketStartNs);
|
||||
// EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketEndNs);
|
||||
// EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
|
||||
//}
|
||||
TEST(DurationMetricTrackerTest, TestNoCondition) {
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
|
||||
DurationMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
|
||||
int tagId = 1;
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, bucketStartTimeNs + bucketSizeNs + 2, tagId);
|
||||
|
||||
FieldMatcher dimensions;
|
||||
DurationMetricProducer durationProducer(kConfigKey, metric, -1 /*no condition*/,
|
||||
1 /* start index */, 2 /* stop index */,
|
||||
3 /* stop_all index */, false /*nesting*/, wizard,
|
||||
dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
|
||||
durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
|
||||
durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
EXPECT_EQ(1UL, durationProducer.mPastBuckets.size());
|
||||
EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
durationProducer.mPastBuckets.end());
|
||||
const auto& buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(2UL, buckets.size());
|
||||
EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
|
||||
EXPECT_EQ(bucketSizeNs - 1LL, buckets[0].mDuration);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[1].mBucketEndNs);
|
||||
EXPECT_EQ(2LL, buckets[1].mDuration);
|
||||
}
|
||||
|
||||
TEST(DurationMetricTrackerTest, TestNonSlicedCondition) {
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
|
||||
DurationMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
|
||||
int tagId = 1;
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
|
||||
LogEvent event3(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 1, tagId);
|
||||
LogEvent event4(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
|
||||
|
||||
FieldMatcher dimensions;
|
||||
DurationMetricProducer durationProducer(kConfigKey, metric, 0 /* condition index */,
|
||||
1 /* start index */, 2 /* stop index */,
|
||||
3 /* stop_all index */, false /*nesting*/, wizard,
|
||||
dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
durationProducer.mCondition = ConditionState::kFalse;
|
||||
|
||||
EXPECT_FALSE(durationProducer.mCondition);
|
||||
EXPECT_FALSE(durationProducer.isConditionSliced());
|
||||
|
||||
durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
|
||||
durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
|
||||
durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
|
||||
EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
|
||||
durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
|
||||
durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
|
||||
durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
|
||||
durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
EXPECT_EQ(1UL, durationProducer.mPastBuckets.size());
|
||||
EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
|
||||
durationProducer.mPastBuckets.end());
|
||||
const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(1UL, buckets2.size());
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
|
||||
EXPECT_EQ(1LL, buckets2[0].mDuration);
|
||||
}
|
||||
|
||||
TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState) {
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
|
||||
DurationMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
|
||||
int tagId = 1;
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
|
||||
LogEvent event3(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 1, tagId);
|
||||
LogEvent event4(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
|
||||
|
||||
FieldMatcher dimensions;
|
||||
DurationMetricProducer durationProducer(kConfigKey, metric, 0 /* condition index */,
|
||||
1 /* start index */, 2 /* stop index */,
|
||||
3 /* stop_all index */, false /*nesting*/, wizard,
|
||||
dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
EXPECT_EQ(ConditionState::kUnknown, durationProducer.mCondition);
|
||||
EXPECT_FALSE(durationProducer.isConditionSliced());
|
||||
|
||||
durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
|
||||
durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
|
||||
durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
|
||||
EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
|
||||
durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
|
||||
durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
|
||||
durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
|
||||
durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
EXPECT_EQ(1UL, durationProducer.mPastBuckets.size());
|
||||
const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(1UL, buckets2.size());
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
|
||||
EXPECT_EQ(1LL, buckets2[0].mDuration);
|
||||
}
|
||||
|
||||
TEST(DurationMetricTrackerTest, TestSumDurationWithUpgrade) {
|
||||
/**
|
||||
* The duration starts from the first bucket, through the two partial buckets (10-70sec),
|
||||
* another bucket, and ends at the beginning of the next full bucket.
|
||||
* Expected buckets:
|
||||
* - [10,25]: 14 secs
|
||||
* - [25,70]: All 45 secs
|
||||
* - [70,130]: All 60 secs
|
||||
* - [130, 210]: Only 5 secs (event ended at 135sec)
|
||||
*/
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
|
||||
int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
|
||||
int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
|
||||
|
||||
int tagId = 1;
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, startTimeNs, tagId);
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, endTimeNs, tagId);
|
||||
|
||||
DurationMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
FieldMatcher dimensions;
|
||||
DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */,
|
||||
1 /* start index */, 2 /* stop index */,
|
||||
3 /* stop_all index */, false /*nesting*/, wizard,
|
||||
dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
|
||||
EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
|
||||
durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
EXPECT_EQ(1UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
std::vector<DurationBucket> buckets =
|
||||
durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
|
||||
EXPECT_EQ(eventUpgradeTimeNs, buckets[0].mBucketEndNs);
|
||||
EXPECT_EQ(eventUpgradeTimeNs - startTimeNs, buckets[0].mDuration);
|
||||
EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
|
||||
// We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
|
||||
durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
|
||||
buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(3UL, buckets.size());
|
||||
EXPECT_EQ(eventUpgradeTimeNs, buckets[1].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketEndNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - eventUpgradeTimeNs, buckets[1].mDuration);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[2].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs);
|
||||
EXPECT_EQ(bucketSizeNs, buckets[2].mDuration);
|
||||
}
|
||||
|
||||
TEST(DurationMetricTrackerTest, TestSumDurationWithUpgradeInFollowingBucket) {
|
||||
/**
|
||||
* Expected buckets (start at 11s, upgrade at 75s, end at 135s):
|
||||
* - [10,70]: 59 secs
|
||||
* - [70,75]: 5 sec
|
||||
* - [75,130]: 55 secs
|
||||
*/
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
int64_t eventUpgradeTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
|
||||
int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
|
||||
int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
|
||||
|
||||
int tagId = 1;
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, startTimeNs, tagId);
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, endTimeNs, tagId);
|
||||
|
||||
DurationMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
FieldMatcher dimensions;
|
||||
DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */,
|
||||
1 /* start index */, 2 /* stop index */,
|
||||
3 /* stop_all index */, false /*nesting*/, wizard,
|
||||
dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
|
||||
EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
|
||||
durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
EXPECT_EQ(2UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
std::vector<DurationBucket> buckets =
|
||||
durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs, buckets[0].mDuration);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketStartNs);
|
||||
EXPECT_EQ(eventUpgradeTimeNs, buckets[1].mBucketEndNs);
|
||||
EXPECT_EQ(eventUpgradeTimeNs - (bucketStartTimeNs + bucketSizeNs), buckets[1].mDuration);
|
||||
EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
|
||||
// We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
|
||||
durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
|
||||
buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(3UL, buckets.size());
|
||||
EXPECT_EQ(eventUpgradeTimeNs, buckets[2].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs - eventUpgradeTimeNs, buckets[2].mDuration);
|
||||
}
|
||||
|
||||
TEST(DurationMetricTrackerTest, TestSumDurationAnomalyWithUpgrade) {
|
||||
sp<AlarmMonitor> alarmMonitor;
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
|
||||
int64_t startTimeNs = bucketStartTimeNs + 1;
|
||||
int64_t endTimeNs = startTimeNs + 65 * NS_PER_SEC;
|
||||
|
||||
int tagId = 1;
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, startTimeNs, tagId);
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, endTimeNs, tagId);
|
||||
|
||||
// Setup metric with alert.
|
||||
DurationMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
Alert alert;
|
||||
alert.set_num_buckets(3);
|
||||
alert.set_trigger_if_sum_gt(2);
|
||||
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
FieldMatcher dimensions;
|
||||
DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */,
|
||||
1 /* start index */, 2 /* stop index */,
|
||||
3 /* stop_all index */, false /*nesting*/, wizard,
|
||||
dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
sp<AnomalyTracker> anomalyTracker = durationProducer.addAnomalyTracker(alert, alarmMonitor);
|
||||
EXPECT_TRUE(anomalyTracker != nullptr);
|
||||
|
||||
durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
|
||||
durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
|
||||
// We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
|
||||
durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
|
||||
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs,
|
||||
anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
|
||||
}
|
||||
|
||||
TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgrade) {
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
|
||||
int64_t startTimeNs = bucketStartTimeNs + 1;
|
||||
int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
|
||||
|
||||
int tagId = 1;
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, startTimeNs, tagId);
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, endTimeNs, tagId);
|
||||
|
||||
DurationMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
metric.set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
|
||||
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
FieldMatcher dimensions;
|
||||
DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */,
|
||||
1 /* start index */, 2 /* stop index */,
|
||||
3 /* stop_all index */, false /*nesting*/, wizard,
|
||||
dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
|
||||
EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
|
||||
durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
|
||||
// We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
|
||||
durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
|
||||
EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
|
||||
durationProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
|
||||
std::vector<DurationBucket> buckets =
|
||||
durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(1UL, buckets.size());
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, buckets[0].mBucketEndNs);
|
||||
EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
|
||||
}
|
||||
|
||||
TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgradeInNextBucket) {
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
|
||||
int64_t eventUpgradeTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
|
||||
int64_t startTimeNs = bucketStartTimeNs + 1;
|
||||
int64_t endTimeNs = startTimeNs + 115 * NS_PER_SEC;
|
||||
|
||||
int tagId = 1;
|
||||
LogEvent event1(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event1, startTimeNs, tagId);
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeLogEvent(&event2, endTimeNs, tagId);
|
||||
|
||||
DurationMetric metric;
|
||||
metric.set_id(1);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
metric.set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
|
||||
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
FieldMatcher dimensions;
|
||||
DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */,
|
||||
1 /* start index */, 2 /* stop index */,
|
||||
3 /* stop_all index */, false /*nesting*/, wizard,
|
||||
dimensions, bucketStartTimeNs, bucketStartTimeNs);
|
||||
|
||||
durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
|
||||
EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
|
||||
EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
|
||||
durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
|
||||
EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
|
||||
// Stop occurs in the same partial bucket as created for the app upgrade.
|
||||
durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
|
||||
EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
|
||||
EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs);
|
||||
|
||||
durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
|
||||
std::vector<DurationBucket> buckets =
|
||||
durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
|
||||
EXPECT_EQ(1UL, buckets.size());
|
||||
EXPECT_EQ(eventUpgradeTimeNs, buckets[0].mBucketStartNs);
|
||||
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketEndNs);
|
||||
EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
|
||||
}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
|
||||
@@ -410,40 +410,75 @@ FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields)
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
// TODO(b/149590301): Update these helpers to use new socket schema.
|
||||
//std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
|
||||
// const android::view::DisplayStateEnum state, uint64_t timestampNs) {
|
||||
// auto event = std::make_unique<LogEvent>(android::util::SCREEN_STATE_CHANGED, timestampNs);
|
||||
// EXPECT_TRUE(event->write(state));
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
|
||||
// auto event = std::make_unique<LogEvent>(
|
||||
// android::util::BATTERY_SAVER_MODE_STATE_CHANGED, timestampNs);
|
||||
// EXPECT_TRUE(event->write(BatterySaverModeStateChanged::ON));
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
|
||||
// auto event = std::make_unique<LogEvent>(
|
||||
// android::util::BATTERY_SAVER_MODE_STATE_CHANGED, timestampNs);
|
||||
// EXPECT_TRUE(event->write(BatterySaverModeStateChanged::OFF));
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(
|
||||
// int level, uint64_t timestampNs) {
|
||||
// auto event = std::make_unique<LogEvent>(android::util::SCREEN_BRIGHTNESS_CHANGED, timestampNs);
|
||||
// EXPECT_TRUE(event->write(level));
|
||||
// event->init();
|
||||
// return event;
|
||||
//
|
||||
//}
|
||||
//
|
||||
std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
|
||||
uint64_t timestampNs, const android::view::DisplayStateEnum state) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::SCREEN_STATE_CHANGED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, state);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::BATTERY_SAVER_MODE_STATE_CHANGED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::ON);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::BATTERY_SAVER_MODE_STATE_CHANGED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::OFF);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::SCREEN_BRIGHTNESS_CHANGED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, level);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
//std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
|
||||
// const std::vector<AttributionNodeInternal>& attributions, const string& jobName,
|
||||
// const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
|
||||
@@ -470,121 +505,212 @@ FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields)
|
||||
// attributions, name, ScheduledJobStateChanged::FINISHED, timestampNs);
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(
|
||||
// const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
|
||||
// const WakelockStateChanged::State state, uint64_t timestampNs) {
|
||||
// auto event = std::make_unique<LogEvent>(android::util::WAKELOCK_STATE_CHANGED, timestampNs);
|
||||
// event->write(attributions);
|
||||
// event->write(android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
|
||||
// event->write(wakelockName);
|
||||
// event->write(state);
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(
|
||||
// const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
|
||||
// uint64_t timestampNs) {
|
||||
// return CreateWakelockStateChangedEvent(
|
||||
// attributions, wakelockName, WakelockStateChanged::ACQUIRE, timestampNs);
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(
|
||||
// const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
|
||||
// uint64_t timestampNs) {
|
||||
// return CreateWakelockStateChangedEvent(
|
||||
// attributions, wakelockName, WakelockStateChanged::RELEASE, timestampNs);
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
|
||||
// const int uid, const ActivityForegroundStateChanged::State state, uint64_t timestampNs) {
|
||||
// auto event = std::make_unique<LogEvent>(
|
||||
// android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, timestampNs);
|
||||
// event->write(uid);
|
||||
// event->write("pkg_name");
|
||||
// event->write("class_name");
|
||||
// event->write(state);
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(const int uid, uint64_t timestampNs) {
|
||||
// return CreateActivityForegroundStateChangedEvent(
|
||||
// uid, ActivityForegroundStateChanged::BACKGROUND, timestampNs);
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(const int uid, uint64_t timestampNs) {
|
||||
// return CreateActivityForegroundStateChangedEvent(
|
||||
// uid, ActivityForegroundStateChanged::FOREGROUND, timestampNs);
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(
|
||||
// const std::vector<AttributionNodeInternal>& attributions, const string& name,
|
||||
// const SyncStateChanged::State state, uint64_t timestampNs) {
|
||||
// auto event = std::make_unique<LogEvent>(android::util::SYNC_STATE_CHANGED, timestampNs);
|
||||
// event->write(attributions);
|
||||
// event->write(name);
|
||||
// event->write(state);
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateSyncStartEvent(
|
||||
// const std::vector<AttributionNodeInternal>& attributions, const string& name,
|
||||
// uint64_t timestampNs) {
|
||||
// return CreateSyncStateChangedEvent(attributions, name, SyncStateChanged::ON, timestampNs);
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateSyncEndEvent(
|
||||
// const std::vector<AttributionNodeInternal>& attributions, const string& name,
|
||||
// uint64_t timestampNs) {
|
||||
// return CreateSyncStateChangedEvent(attributions, name, SyncStateChanged::OFF, timestampNs);
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
|
||||
// const int uid, const ProcessLifeCycleStateChanged::State state, uint64_t timestampNs) {
|
||||
// auto logEvent = std::make_unique<LogEvent>(
|
||||
// android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, timestampNs);
|
||||
// logEvent->write(uid);
|
||||
// logEvent->write("");
|
||||
// logEvent->write(state);
|
||||
// logEvent->init();
|
||||
// return logEvent;
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateAppCrashEvent(const int uid, uint64_t timestampNs) {
|
||||
// return CreateProcessLifeCycleStateChangedEvent(
|
||||
// uid, ProcessLifeCycleStateChanged::CRASHED, timestampNs);
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(const int uid, uint64_t timestampNs) {
|
||||
// auto event = std::make_unique<LogEvent>(android::util::APP_CRASH_OCCURRED, timestampNs);
|
||||
// event->write(uid);
|
||||
// event->write("eventType");
|
||||
// event->write("processName");
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(
|
||||
// int isolatedUid, int hostUid, bool is_create, uint64_t timestampNs) {
|
||||
// auto logEvent = std::make_unique<LogEvent>(
|
||||
// android::util::ISOLATED_UID_CHANGED, timestampNs);
|
||||
// logEvent->write(hostUid);
|
||||
// logEvent->write(isolatedUid);
|
||||
// logEvent->write(is_create);
|
||||
// logEvent->init();
|
||||
// return logEvent;
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
|
||||
// int uid, const android::app::ProcessStateEnum state, uint64_t timestampNs) {
|
||||
// auto event = std::make_unique<LogEvent>(android::util::UID_PROCESS_STATE_CHANGED, timestampNs);
|
||||
// event->write(uid);
|
||||
// event->write(state);
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs,
|
||||
const vector<int>& attributionUids,
|
||||
const vector<string>& attributionTags,
|
||||
const string& wakelockName,
|
||||
const WakelockStateChanged::State state) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::WAKELOCK_STATE_CHANGED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
vector<const char*> cTags(attributionTags.size());
|
||||
for (int i = 0; i < cTags.size(); i++) {
|
||||
cTags[i] = attributionTags[i].c_str();
|
||||
}
|
||||
|
||||
AStatsEvent_writeAttributionChain(statsEvent,
|
||||
reinterpret_cast<const uint32_t*>(attributionUids.data()),
|
||||
cTags.data(), attributionUids.size());
|
||||
AStatsEvent_writeInt32(statsEvent, android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
|
||||
AStatsEvent_writeString(statsEvent, wakelockName.c_str());
|
||||
AStatsEvent_writeInt32(statsEvent, state);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs,
|
||||
const vector<int>& attributionUids,
|
||||
const vector<string>& attributionTags,
|
||||
const string& wakelockName) {
|
||||
return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
|
||||
wakelockName, WakelockStateChanged::ACQUIRE);
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs,
|
||||
const vector<int>& attributionUids,
|
||||
const vector<string>& attributionTags,
|
||||
const string& wakelockName) {
|
||||
return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
|
||||
wakelockName, WakelockStateChanged::RELEASE);
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
|
||||
uint64_t timestampNs, const int uid, const ActivityForegroundStateChanged::State state) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, uid);
|
||||
AStatsEvent_writeString(statsEvent, "pkg_name");
|
||||
AStatsEvent_writeString(statsEvent, "class_name");
|
||||
AStatsEvent_writeInt32(statsEvent, state);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid) {
|
||||
return CreateActivityForegroundStateChangedEvent(timestampNs, uid,
|
||||
ActivityForegroundStateChanged::BACKGROUND);
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid) {
|
||||
return CreateActivityForegroundStateChangedEvent(timestampNs, uid,
|
||||
ActivityForegroundStateChanged::FOREGROUND);
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
|
||||
const vector<int>& attributionUids,
|
||||
const vector<string>& attributionTags,
|
||||
const string& name,
|
||||
const SyncStateChanged::State state) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::SYNC_STATE_CHANGED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
vector<const char*> cTags(attributionTags.size());
|
||||
for (int i = 0; i < cTags.size(); i++) {
|
||||
cTags[i] = attributionTags[i].c_str();
|
||||
}
|
||||
|
||||
AStatsEvent_writeAttributionChain(statsEvent,
|
||||
reinterpret_cast<const uint32_t*>(attributionUids.data()),
|
||||
cTags.data(), attributionUids.size());
|
||||
AStatsEvent_writeString(statsEvent, name.c_str());
|
||||
AStatsEvent_writeInt32(statsEvent, state);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
|
||||
const vector<int>& attributionUids,
|
||||
const vector<string>& attributionTags,
|
||||
const string& name) {
|
||||
return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
|
||||
SyncStateChanged::ON);
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
|
||||
const vector<int>& attributionUids,
|
||||
const vector<string>& attributionTags,
|
||||
const string& name) {
|
||||
return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
|
||||
SyncStateChanged::OFF);
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
|
||||
uint64_t timestampNs, const int uid, const ProcessLifeCycleStateChanged::State state) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, uid);
|
||||
AStatsEvent_writeString(statsEvent, "");
|
||||
AStatsEvent_writeInt32(statsEvent, state);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid) {
|
||||
return CreateProcessLifeCycleStateChangedEvent(timestampNs, uid,
|
||||
ProcessLifeCycleStateChanged::CRASHED);
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::APP_CRASH_OCCURRED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, uid);
|
||||
AStatsEvent_writeString(statsEvent, "eventType");
|
||||
AStatsEvent_writeString(statsEvent, "processName");
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
|
||||
int isolatedUid, bool is_create) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::ISOLATED_UID_CHANGED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, hostUid);
|
||||
AStatsEvent_writeInt32(statsEvent, isolatedUid);
|
||||
AStatsEvent_writeInt32(statsEvent, is_create);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
|
||||
uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state) {
|
||||
AStatsEvent* statsEvent = AStatsEvent_obtain();
|
||||
AStatsEvent_setAtomId(statsEvent, android::util::UID_PROCESS_STATE_CHANGED);
|
||||
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
|
||||
|
||||
AStatsEvent_writeInt32(statsEvent, uid);
|
||||
AStatsEvent_writeInt32(statsEvent, state);
|
||||
AStatsEvent_build(statsEvent);
|
||||
|
||||
size_t size;
|
||||
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
|
||||
|
||||
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
|
||||
logEvent->parseBuffer(buf, size);
|
||||
AStatsEvent_release(statsEvent);
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
|
||||
const StatsdConfig& config, const ConfigKey& key,
|
||||
|
||||
@@ -166,11 +166,10 @@ FieldMatcher CreateAttributionUidDimensions(const int atomId,
|
||||
|
||||
// Create log event for screen state changed.
|
||||
std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
|
||||
const android::view::DisplayStateEnum state, uint64_t timestampNs);
|
||||
uint64_t timestampNs, const android::view::DisplayStateEnum state);
|
||||
|
||||
// Create log event for screen brightness state changed.
|
||||
std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(
|
||||
int level, uint64_t timestampNs);
|
||||
std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level);
|
||||
|
||||
// Create log event when scheduled job starts.
|
||||
std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(
|
||||
@@ -188,45 +187,42 @@ std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs);
|
||||
std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs);
|
||||
|
||||
// Create log event for app moving to background.
|
||||
std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(const int uid, uint64_t timestampNs);
|
||||
std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid);
|
||||
|
||||
// Create log event for app moving to foreground.
|
||||
std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(const int uid, uint64_t timestampNs);
|
||||
std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid);
|
||||
|
||||
// Create log event when the app sync starts.
|
||||
std::unique_ptr<LogEvent> CreateSyncStartEvent(
|
||||
const std::vector<AttributionNodeInternal>& attributions, const string& name,
|
||||
uint64_t timestampNs);
|
||||
std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs, const vector<int>& uids,
|
||||
const vector<string>& tags, const string& name);
|
||||
|
||||
// Create log event when the app sync ends.
|
||||
std::unique_ptr<LogEvent> CreateSyncEndEvent(
|
||||
const std::vector<AttributionNodeInternal>& attributions, const string& name,
|
||||
uint64_t timestampNs);
|
||||
std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs, const vector<int>& uids,
|
||||
const vector<string>& tags, const string& name);
|
||||
|
||||
// Create log event when the app sync ends.
|
||||
std::unique_ptr<LogEvent> CreateAppCrashEvent(
|
||||
const int uid, uint64_t timestampNs);
|
||||
std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid);
|
||||
|
||||
// Create log event for an app crash.
|
||||
std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(const int uid, uint64_t timestampNs);
|
||||
std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid);
|
||||
|
||||
// Create log event for acquiring wakelock.
|
||||
std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(
|
||||
const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
|
||||
uint64_t timestampNs);
|
||||
std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs, const vector<int>& uids,
|
||||
const vector<string>& tags,
|
||||
const string& wakelockName);
|
||||
|
||||
// Create log event for releasing wakelock.
|
||||
std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(
|
||||
const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
|
||||
uint64_t timestampNs);
|
||||
std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs, const vector<int>& uids,
|
||||
const vector<string>& tags,
|
||||
const string& wakelockName);
|
||||
|
||||
// Create log event for releasing wakelock.
|
||||
std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(
|
||||
int isolatedUid, int hostUid, bool is_create, uint64_t timestampNs);
|
||||
std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int isolatedUid,
|
||||
int hostUid, bool is_create);
|
||||
|
||||
// Create log event for uid process state change.
|
||||
std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
|
||||
int uid, const android::app::ProcessStateEnum state, uint64_t timestampNs);
|
||||
uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state);
|
||||
|
||||
// Helper function to create an AttributionNodeInternal proto.
|
||||
AttributionNodeInternal CreateAttribution(const int& uid, const string& tag);
|
||||
|
||||
Reference in New Issue
Block a user