Merge "Use new socket schema within TestSlicedCondition" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
9f9ca14bb5
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include <android/util/ProtoOutputStream.h>
|
||||
#include <private/android_logger.h>
|
||||
#include <stats_event.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -61,23 +60,38 @@ 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.
|
||||
*/
|
||||
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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
//
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user