diff options
| -rw-r--r-- | cmds/statsd/src/external/StatsCallbackPuller.cpp | 6 | ||||
| -rw-r--r-- | cmds/statsd/src/logd/LogEvent.cpp | 27 | ||||
| -rw-r--r-- | cmds/statsd/src/logd/LogEvent.h | 49 | ||||
| -rwxr-xr-x | cmds/statsd/src/socket/StatsSocketListener.cpp | 5 | ||||
| -rw-r--r-- | cmds/statsd/tests/LogEvent_test.cpp | 25 | ||||
| -rw-r--r-- | cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp | 296 | ||||
| -rw-r--r-- | cmds/statsd/tests/external/StatsCallbackPuller_test.cpp | 1 | ||||
| -rw-r--r-- | cmds/statsd/tests/statsd_test_util.cpp | 1 |
8 files changed, 210 insertions, 200 deletions
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.cpp b/cmds/statsd/src/external/StatsCallbackPuller.cpp index 0edf40b69087..933f48d1714b 100644 --- a/cmds/statsd/src/external/StatsCallbackPuller.cpp +++ b/cmds/statsd/src/external/StatsCallbackPuller.cpp @@ -66,10 +66,8 @@ bool StatsCallbackPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) { { lock_guard<mutex> lk(*cv_mutex); for (const StatsEventParcel& parcel: output) { - uint8_t* buf = reinterpret_cast<uint8_t*>( - const_cast<int8_t*>(parcel.buffer.data())); - shared_ptr<LogEvent> event = make_shared<LogEvent>( - buf, parcel.buffer.size(), /*uid=*/-1, /*pid=*/-1); + shared_ptr<LogEvent> event = make_shared<LogEvent>(/*uid=*/-1, /*pid=*/-1); + event->parseBuffer((uint8_t*)parcel.buffer.data(), parcel.buffer.size()); sharedData->push_back(event); } *pullSuccess = success; diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index 3e46d131a813..974e203cd612 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -65,18 +65,6 @@ using std::vector; #define ATTRIBUTION_CHAIN_TYPE 0x09 #define ERROR_TYPE 0x0F -// Msg is expected to begin at the start of the serialized atom -- it should not -// include the android_log_header_t or the StatsEventTag. -LogEvent::LogEvent(uint8_t* msg, uint32_t len, int32_t uid, int32_t pid) - : mBuf(msg), - mRemainingLen(len), - mLogdTimestampNs(time(nullptr)), - mLogUid(uid), - mLogPid(pid) -{ - initNew(); -} - LogEvent::LogEvent(const LogEvent& event) { mTagId = event.mTagId; mLogUid = event.mLogUid; @@ -86,6 +74,12 @@ LogEvent::LogEvent(const LogEvent& event) { mValues = event.mValues; } +LogEvent::LogEvent(int32_t uid, int32_t pid) + : mLogdTimestampNs(time(nullptr)), + mLogUid(uid), + mLogPid(pid) { +} + LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs) { mLogdTimestampNs = wallClockTimestampNs; mElapsedTimestampNs = elapsedTimestampNs; @@ -189,9 +183,6 @@ LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value(trainInfo.status))); } -LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) : LogEvent(tagId, timestampNs, timestampNs) { -} - LogEvent::LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid) { mLogdTimestampNs = timestampNs; mTagId = tagId; @@ -467,7 +458,10 @@ void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last) { // This parsing logic is tied to the encoding scheme used in StatsEvent.java and // stats_event.c -void LogEvent::initNew() { +bool LogEvent::parseBuffer(uint8_t* buf, size_t len) { + mBuf = buf; + mRemainingLen = (uint32_t)len; + int32_t pos[] = {1, 1, 1}; bool last[] = {false, false, false}; @@ -529,6 +523,7 @@ void LogEvent::initNew() { if (mRemainingLen != 0) mValid = false; mBuf = nullptr; + return mValid; } uint8_t LogEvent::getTypeId(uint8_t typeInfo) { diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h index e167e6721d01..3940aa8e1243 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -20,7 +20,6 @@ #include <android/util/ProtoOutputStream.h> #include <private/android_logger.h> -#include <stats_event.h> #include <string> #include <vector> @@ -61,14 +60,32 @@ struct InstallTrainInfo { }; /** - * Wrapper for the log_msg structure. + * This class decodes the structured, serialized encoding of an atom into a + * vector of FieldValues. */ class LogEvent { public: /** - * Read a LogEvent from the socket + * \param uid user id of the logging caller + * \param pid process id of the logging caller */ - explicit LogEvent(uint8_t* msg, uint32_t len, int32_t uid, int32_t pid); + explicit LogEvent(int32_t uid, int32_t pid); + + /** + * Parses the atomId, timestamp, and vector of values from a buffer + * containing the StatsEvent/AStatsEvent encoding of an atom. + * + * \param buf a buffer that begins at the start of the serialized atom (it + * should not include the android_log_header_t or the StatsEventTag) + * \param len size of the buffer + * + * \return success of the initialization + */ + bool parseBuffer(uint8_t* buf, size_t len); + + // TODO(b/149590301): delete unused functions below once LogEvent uses the + // new socket schema within test code. Really we would like the only entry + // points into LogEvent to be the above constructor and parseBuffer functions. /** * Constructs a LogEvent with synthetic data for testing. Must call init() before reading. @@ -76,9 +93,6 @@ public: explicit LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs); // For testing. The timestamp is used as both elapsed real time and logd timestamp. - explicit LogEvent(int32_t tagId, int64_t timestampNs); - - // For testing. The timestamp is used as both elapsed real time and logd timestamp. explicit LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid); /** @@ -192,10 +206,6 @@ public: return &mValues; } - bool isValid() { - return mValid; - } - inline LogEvent makeCopy() { return LogEvent(*this); } @@ -222,12 +232,6 @@ private: */ LogEvent(const LogEvent&); - - /** - * Parsing function for new encoding scheme. - */ - void initNew(); - void parseInt32(int32_t* pos, int32_t depth, bool* last); void parseInt64(int32_t* pos, int32_t depth, bool* last); void parseString(int32_t* pos, int32_t depth, bool* last); @@ -238,13 +242,14 @@ private: void parseAttributionChain(int32_t* pos, int32_t depth, bool* last); /** - * mBuf is a pointer to the current location in the buffer being parsed. - * Because the buffer lives on the StatsSocketListener stack, this pointer - * is only valid during the LogEvent constructor. It will be set to null at - * the end of initNew. + * The below three variables are only valid during the execution of + * parseBuffer. There are no guarantees about the state of these variables + * before/after. + * + * TODO (b/150312423): These shouldn't be member variables. We should pass + * them around as parameters. */ uint8_t* mBuf; - uint32_t mRemainingLen; // number of valid bytes left in the buffer being parsed bool mValid = true; // stores whether the event we received from the socket is valid diff --git a/cmds/statsd/src/socket/StatsSocketListener.cpp b/cmds/statsd/src/socket/StatsSocketListener.cpp index 8f0f480cb862..b877cc9c352f 100755 --- a/cmds/statsd/src/socket/StatsSocketListener.cpp +++ b/cmds/statsd/src/socket/StatsSocketListener.cpp @@ -126,7 +126,10 @@ bool StatsSocketListener::onDataAvailable(SocketClient* cli) { uint32_t pid = cred->pid; int64_t oldestTimestamp; - if (!mQueue->push(std::make_unique<LogEvent>(msg, len, uid, pid), &oldestTimestamp)) { + std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(uid, pid); + logEvent->parseBuffer(msg, len); + + if (!mQueue->push(std::move(logEvent), &oldestTimestamp)) { StatsdStats::getInstance().noteEventQueueOverflow(oldestTimestamp); } diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp index 7542faf25123..7458cbf9e9a1 100644 --- a/cmds/statsd/tests/LogEvent_test.cpp +++ b/cmds/statsd/tests/LogEvent_test.cpp @@ -54,8 +54,9 @@ TEST(LogEventTest, TestPrimitiveParsing) { size_t size; uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001); - EXPECT_TRUE(logEvent.isValid()); + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); + EXPECT_TRUE(logEvent.parseBuffer(buf, size)); + EXPECT_EQ(100, logEvent.GetTagId()); EXPECT_EQ(1000, logEvent.GetUid()); EXPECT_EQ(1001, logEvent.GetPid()); @@ -102,8 +103,9 @@ TEST(LogEventTest, TestStringAndByteArrayParsing) { size_t size; uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001); - EXPECT_TRUE(logEvent.isValid()); + LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001); + EXPECT_TRUE(logEvent.parseBuffer(buf, size)); + EXPECT_EQ(100, logEvent.GetTagId()); EXPECT_EQ(1000, logEvent.GetUid()); EXPECT_EQ(1001, logEvent.GetPid()); @@ -137,8 +139,9 @@ TEST(LogEventTest, TestEmptyString) { size_t size; uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001); - EXPECT_TRUE(logEvent.isValid()); + LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001); + EXPECT_TRUE(logEvent.parseBuffer(buf, size)); + EXPECT_EQ(100, logEvent.GetTagId()); EXPECT_EQ(1000, logEvent.GetUid()); EXPECT_EQ(1001, logEvent.GetPid()); @@ -165,8 +168,9 @@ TEST(LogEventTest, TestByteArrayWithNullCharacter) { size_t size; uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001); - EXPECT_TRUE(logEvent.isValid()); + LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001); + EXPECT_TRUE(logEvent.parseBuffer(buf, size)); + EXPECT_EQ(100, logEvent.GetTagId()); EXPECT_EQ(1000, logEvent.GetUid()); EXPECT_EQ(1001, logEvent.GetPid()); @@ -200,8 +204,9 @@ TEST(LogEventTest, TestAttributionChain) { size_t size; uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001); - EXPECT_TRUE(logEvent.isValid()); + LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001); + EXPECT_TRUE(logEvent.parseBuffer(buf, size)); + EXPECT_EQ(100, logEvent.GetTagId()); EXPECT_EQ(1000, logEvent.GetUid()); EXPECT_EQ(1001, logEvent.GetPid()); diff --git a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp index 36094b217303..8701e1790a69 100644 --- a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp +++ b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include "src/condition/SimpleConditionTracker.h" +#include "stats_event.h" #include "tests/statsd_test_util.h" #include <gmock/gmock.h> @@ -31,6 +32,8 @@ namespace android { namespace os { namespace statsd { +namespace { + const ConfigKey kConfigKey(0, 12345); const int ATTRIBUTION_NODE_FIELD_ID = 1; @@ -57,24 +60,33 @@ SimplePredicate getWakeLockHeldCondition(bool countNesting, bool defaultFalse, return simplePredicate; } -void writeAttributionNodesToEvent(LogEvent* event, const std::vector<int> &uids) { - std::vector<AttributionNodeInternal> nodes; - for (size_t i = 0; i < uids.size(); ++i) { - AttributionNodeInternal node; - node.set_uid(uids[i]); - nodes.push_back(node); +void makeWakeLockEvent(LogEvent* logEvent, uint32_t atomId, uint64_t timestamp, + const vector<int>& uids, const string& wl, int acquire) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, atomId); + AStatsEvent_overwriteTimestamp(statsEvent, timestamp); + + vector<std::string> tags(uids.size()); // vector of empty strings + vector<const char*> cTags(uids.size()); + for (int i = 0; i < cTags.size(); i++) { + cTags[i] = tags[i].c_str(); } - event->write(nodes); // attribution chain. + AStatsEvent_writeAttributionChain(statsEvent, reinterpret_cast<const uint32_t*>(uids.data()), + cTags.data(), uids.size()); + + AStatsEvent_writeString(statsEvent, wl.c_str()); + AStatsEvent_writeInt32(statsEvent, acquire); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + logEvent->parseBuffer(buf, size); + + AStatsEvent_release(statsEvent); } -// TODO(b/149590301): Update this helper to use new socket schema. -//void makeWakeLockEvent( -// LogEvent* event, const std::vector<int> &uids, const string& wl, int acquire) { -// writeAttributionNodesToEvent(event, uids); -// event->write(wl); -// event->write(acquire); -// event->init(); -//} +} // anonymous namespace + std::map<int64_t, HashableDimensionKey> getWakeLockQueryKey( const Position position, @@ -265,138 +277,128 @@ TEST(SimpleConditionTrackerTest, TestNonSlicedConditionNestCounting) { EXPECT_TRUE(changedCache[0]); } -// TODO(b/149590301): Update these tests to use new socket schema. -//TEST(SimpleConditionTrackerTest, TestSlicedCondition) { -// 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_UID2"; -// -// 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> uids = {111, 222, 333}; -// -// LogEvent event(1 /*tagId*/, 0 /*timestamp*/); -// makeWakeLockEvent(&event, uids, "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(uids.size(), conditionTracker.mSlicedConditionState.size()); -// } -// EXPECT_TRUE(changedCache[0]); -// if (position == Position::FIRST || -// position == Position::LAST) { -// EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), 1u); -// EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); -// } else { -// EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), uids.size()); -// } -// -// // Now test query -// const auto queryKey = getWakeLockQueryKey(position, uids, conditionName); -// conditionCache[0] = ConditionState::kNotEvaluated; -// -// conditionTracker.isConditionMet(queryKey, allPredicates, -// false, -// conditionCache); -// EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); -// -// // another wake lock acquired by this uid -// LogEvent event2(1 /*tagId*/, 0 /*timestamp*/); -// makeWakeLockEvent(&event2, uids, "wl2", 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]); -// if (position == Position::FIRST || -// position == Position::LAST) { -// EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size()); -// } else { -// EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size()); -// } -// EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty()); -// EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); -// -// -// // wake lock 1 release -// LogEvent event3(1 /*tagId*/, 0 /*timestamp*/); -// makeWakeLockEvent(&event3, uids, "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 wake lock 2 is still held for this uid -// EXPECT_FALSE(changedCache[0]); -// if (position == Position::FIRST || -// position == Position::LAST) { -// EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size()); -// } else { -// EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size()); -// } -// EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty()); -// EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); -// -// LogEvent event4(1 /*tagId*/, 0 /*timestamp*/); -// makeWakeLockEvent(&event4, uids, "wl2", 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]); -// if (position == Position::FIRST || -// position == Position::LAST) { -// EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), 1u); -// EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty()); -// } else { -// EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), uids.size()); -// } -// -// // query again -// conditionCache[0] = ConditionState::kNotEvaluated; -// conditionTracker.isConditionMet(queryKey, allPredicates, -// false, -// conditionCache); -// EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); -// } -// -//} -// +TEST(SimpleConditionTrackerTest, TestSlicedCondition) { + 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_UID2"; + + 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> uids = {111, 222, 333}; + + LogEvent event(/*uid=*/-1, /*pid=*/-1); + makeWakeLockEvent(&event, /*atomId=*/ 1, /*timestamp=*/ 0, uids, "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(event, matcherState, allPredicates, conditionCache, + changedCache); + + if (position == Position::FIRST || position == Position::LAST) { + EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size()); + } else { + EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size()); + } + EXPECT_TRUE(changedCache[0]); + if (position == Position::FIRST || position == Position::LAST) { + EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), 1u); + EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); + } else { + EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), + uids.size()); + } + + // Now test query + const auto queryKey = getWakeLockQueryKey(position, uids, conditionName); + conditionCache[0] = ConditionState::kNotEvaluated; + + conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache); + EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); + + // another wake lock acquired by this uid + LogEvent event2(/*uid=*/-1, /*pid=*/-1); + makeWakeLockEvent(&event2, /*atomId=*/ 1, /*timestamp=*/ 0, uids, "wl2", /*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]); + if (position == Position::FIRST || position == Position::LAST) { + EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size()); + } else { + EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size()); + } + EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty()); + EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); + + + // wake lock 1 release + LogEvent event3(/*uid=*/-1, /*pid=*/-1); + makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/0); + 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 wake lock 2 is still held for this uid + EXPECT_FALSE(changedCache[0]); + if (position == Position::FIRST || position == Position::LAST) { + EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size()); + } else { + EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size()); + } + EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty()); + EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); + + LogEvent event4(/*uid=*/-1, /*pid=*/-1); + makeWakeLockEvent(&event, /*atomId=*/1, /*timestamp=*/ 0, uids, "wl2", /*acquire=*/0); + 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]); + if (position == Position::FIRST || position == Position::LAST) { + EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), 1u); + EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty()); + } else { + EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), + uids.size()); + } + + // query again + conditionCache[0] = ConditionState::kNotEvaluated; + conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache); + EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); + } + +} + //TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) { // std::vector<sp<ConditionTracker>> allConditions; // diff --git a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp b/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp index e416b4c0e29b..1ff66218f22c 100644 --- a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp +++ b/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp @@ -28,6 +28,7 @@ #include "../metrics/metrics_test_helper.h" #include "src/stats_log_util.h" +#include "stats_event.h" #include "tests/statsd_test_util.h" #ifdef __ANDROID__ diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp index 2bfce9b07eb5..d416f1395727 100644 --- a/cmds/statsd/tests/statsd_test_util.cpp +++ b/cmds/statsd/tests/statsd_test_util.cpp @@ -15,6 +15,7 @@ #include "statsd_test_util.h" #include <aidl/android/util/StatsEventParcel.h> +#include "stats_event.h" using aidl::android::util::StatsEventParcel; using std::shared_ptr; |