Merge "Use new socket schema within TestSlicedCondition" into rvc-dev am: 9f9ca14bb5 am: 3f73e911f5

Change-Id: I54c1b1c93db071dd5a23205063e95487d3f34dba
This commit is contained in:
Automerger Merge Worker
2020-02-27 23:34:34 +00:00
8 changed files with 210 additions and 200 deletions

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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());

View File

@@ -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;
//

View File

@@ -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__

View File

@@ -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;