Comment out Statsd tests
Added todos to make them ues the new schema. Bug: 145923087 Test: m -j && bit statsd_test:* Change-Id: I0749760eb3123407b78b9ace9a93967bac727bf5
This commit is contained in:
@@ -105,10 +105,6 @@ cc_defaults {
|
||||
"src/uid_data.proto",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-DNEW_ENCODING_SCHEME",
|
||||
],
|
||||
|
||||
local_include_dirs: [
|
||||
"src",
|
||||
],
|
||||
@@ -316,55 +312,55 @@ cc_test {
|
||||
// statsd micro benchmark
|
||||
//#############################
|
||||
|
||||
cc_benchmark {
|
||||
name: "statsd_benchmark",
|
||||
defaults: ["statsd_defaults"],
|
||||
|
||||
srcs: [
|
||||
// atom_field_options.proto needs field_options.proto, but that is
|
||||
// not included in libprotobuf-cpp-lite, so compile it here.
|
||||
":libprotobuf-internal-protos",
|
||||
|
||||
"benchmark/duration_metric_benchmark.cpp",
|
||||
"benchmark/filter_value_benchmark.cpp",
|
||||
"benchmark/get_dimensions_for_condition_benchmark.cpp",
|
||||
"benchmark/hello_world_benchmark.cpp",
|
||||
"benchmark/log_event_benchmark.cpp",
|
||||
"benchmark/main.cpp",
|
||||
"benchmark/metric_util.cpp",
|
||||
"benchmark/stats_write_benchmark.cpp",
|
||||
"src/atom_field_options.proto",
|
||||
"src/atoms.proto",
|
||||
"src/stats_log.proto",
|
||||
],
|
||||
|
||||
proto: {
|
||||
type: "lite",
|
||||
include_dirs: ["external/protobuf/src"],
|
||||
},
|
||||
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wno-unused-parameter",
|
||||
"-Wno-unused-variable",
|
||||
"-Wno-unused-function",
|
||||
|
||||
// Bug: http://b/29823425 Disable -Wvarargs for Clang update to r271374
|
||||
"-Wno-varargs",
|
||||
],
|
||||
|
||||
static_libs: [
|
||||
"libplatformprotos",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"libgtest_prod",
|
||||
"libprotobuf-cpp-lite",
|
||||
"libstatslog",
|
||||
"libstatssocket",
|
||||
],
|
||||
}
|
||||
//cc_benchmark {
|
||||
// name: "statsd_benchmark",
|
||||
// defaults: ["statsd_defaults"],
|
||||
//
|
||||
// srcs: [
|
||||
// // atom_field_options.proto needs field_options.proto, but that is
|
||||
// // not included in libprotobuf-cpp-lite, so compile it here.
|
||||
// ":libprotobuf-internal-protos",
|
||||
//
|
||||
// "benchmark/duration_metric_benchmark.cpp",
|
||||
// "benchmark/filter_value_benchmark.cpp",
|
||||
// "benchmark/get_dimensions_for_condition_benchmark.cpp",
|
||||
// "benchmark/hello_world_benchmark.cpp",
|
||||
// "benchmark/log_event_benchmark.cpp",
|
||||
// "benchmark/main.cpp",
|
||||
// "benchmark/metric_util.cpp",
|
||||
// "benchmark/stats_write_benchmark.cpp",
|
||||
// "src/atom_field_options.proto",
|
||||
// "src/atoms.proto",
|
||||
// "src/stats_log.proto",
|
||||
// ],
|
||||
//
|
||||
// proto: {
|
||||
// type: "lite",
|
||||
// include_dirs: ["external/protobuf/src"],
|
||||
// },
|
||||
//
|
||||
// cflags: [
|
||||
// "-Wall",
|
||||
// "-Werror",
|
||||
// "-Wno-unused-parameter",
|
||||
// "-Wno-unused-variable",
|
||||
// "-Wno-unused-function",
|
||||
//
|
||||
// // Bug: http://b/29823425 Disable -Wvarargs for Clang update to r271374
|
||||
// "-Wno-varargs",
|
||||
// ],
|
||||
//
|
||||
// static_libs: [
|
||||
// "libplatformprotos",
|
||||
// ],
|
||||
//
|
||||
// shared_libs: [
|
||||
// "libgtest_prod",
|
||||
// "libprotobuf-cpp-lite",
|
||||
// "libstatslog",
|
||||
// "libstatssocket",
|
||||
// ],
|
||||
//}
|
||||
|
||||
// ==== java proto device library (for test only) ==============================
|
||||
java_library {
|
||||
|
||||
@@ -208,12 +208,8 @@ void StatsLogProcessor::onBinaryPushStateChangedEventLocked(LogEvent* event) {
|
||||
trainInfo.requiresLowLatencyMonitor =
|
||||
event->GetBool(5 /*requires low latency monitor field id*/, &err);
|
||||
trainInfo.status = int32_t(event->GetLong(6 /*state field id*/, &err));
|
||||
#ifdef NEW_ENCODING_SCHEME
|
||||
std::vector<uint8_t> trainExperimentIdBytes =
|
||||
event->GetStorage(7 /*experiment ids field id*/, &err);
|
||||
#else
|
||||
string trainExperimentIdString = event->GetString(7 /*experiment ids field id*/, &err);
|
||||
#endif
|
||||
bool is_rollback = event->GetBool(10 /*is rollback field id*/, &err);
|
||||
|
||||
if (err != NO_ERROR) {
|
||||
@@ -221,12 +217,8 @@ void StatsLogProcessor::onBinaryPushStateChangedEventLocked(LogEvent* event) {
|
||||
return;
|
||||
}
|
||||
ExperimentIds trainExperimentIds;
|
||||
#ifdef NEW_ENCODING_SCHEME
|
||||
if (!trainExperimentIds.ParseFromArray(trainExperimentIdBytes.data(),
|
||||
trainExperimentIdBytes.size())) {
|
||||
#else
|
||||
if (!trainExperimentIds.ParseFromString(trainExperimentIdString)) {
|
||||
#endif
|
||||
ALOGE("Failed to parse experimentids in binary push state changed.");
|
||||
return;
|
||||
}
|
||||
@@ -241,11 +233,7 @@ void StatsLogProcessor::onBinaryPushStateChangedEventLocked(LogEvent* event) {
|
||||
int32_t userId = multiuser_get_user_id(uid);
|
||||
|
||||
event->updateValue(2 /*train version field id*/, trainInfo.trainVersionCode, LONG);
|
||||
#ifdef NEW_ENCODING_SCHEME
|
||||
event->updateValue(7 /*experiment ids field id*/, trainExperimentIdProto, STORAGE);
|
||||
#else
|
||||
event->updateValue(7 /*experiment ids field id*/, trainExperimentIdProto, STRING);
|
||||
#endif
|
||||
event->updateValue(8 /*user id field id*/, userId, INT);
|
||||
|
||||
// If this event is a rollback event, then the following bits in the event
|
||||
@@ -352,11 +340,7 @@ void StatsLogProcessor::onWatchdogRollbackOccurredLocked(LogEvent* event) {
|
||||
vector<uint8_t> experimentIdProto;
|
||||
writeExperimentIdsToProto(experimentIds, &experimentIdProto);
|
||||
|
||||
#ifdef NEW_ENCODING_SCHEME
|
||||
event->updateValue(6 /*experiment ids field id*/, experimentIdProto, STORAGE);
|
||||
#else
|
||||
event->updateValue(6 /*experiment ids field id*/, experimentIdProto, STRING);
|
||||
#endif
|
||||
}
|
||||
|
||||
vector<int64_t> StatsLogProcessor::processWatchdogRollbackOccurred(const int32_t rollbackTypeIn,
|
||||
|
||||
@@ -69,8 +69,7 @@ bool StatsCallbackPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
|
||||
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,
|
||||
/*useNewSchema=*/true);
|
||||
buf, parcel.buffer.size(), /*uid=*/-1, /*pid=*/-1);
|
||||
sharedData->push_back(event);
|
||||
}
|
||||
*pullSuccess = success;
|
||||
|
||||
@@ -74,29 +74,7 @@ LogEvent::LogEvent(uint8_t* msg, uint32_t len, int32_t uid, int32_t pid)
|
||||
mLogUid(uid),
|
||||
mLogPid(pid)
|
||||
{
|
||||
#ifdef NEW_ENCODING_SCHEME
|
||||
initNew();
|
||||
# else
|
||||
mContext = create_android_log_parser((char*)msg, len);
|
||||
init(mContext);
|
||||
if (mContext) android_log_destroy(&mContext); // set mContext to NULL
|
||||
#endif
|
||||
}
|
||||
|
||||
LogEvent::LogEvent(uint8_t* msg, uint32_t len, int32_t uid, int32_t pid, bool useNewSchema)
|
||||
: mBuf(msg),
|
||||
mRemainingLen(len),
|
||||
mLogdTimestampNs(time(nullptr)),
|
||||
mLogUid(uid),
|
||||
mLogPid(pid)
|
||||
{
|
||||
if (useNewSchema) {
|
||||
initNew();
|
||||
} else {
|
||||
mContext = create_android_log_parser((char*)msg, len);
|
||||
init(mContext);
|
||||
if (mContext) android_log_destroy(&mContext); // set mContext to NULL
|
||||
}
|
||||
}
|
||||
|
||||
LogEvent::LogEvent(const LogEvent& event) {
|
||||
@@ -225,22 +203,6 @@ LogEvent::LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid) {
|
||||
}
|
||||
}
|
||||
|
||||
void LogEvent::init() {
|
||||
if (mContext) {
|
||||
const char* buffer;
|
||||
size_t len = android_log_write_list_buffer(mContext, &buffer);
|
||||
// turns to reader mode
|
||||
android_log_context contextForRead = create_android_log_parser(buffer, len);
|
||||
if (contextForRead) {
|
||||
init(contextForRead);
|
||||
// destroy the context to save memory.
|
||||
// android_log_destroy will set mContext to NULL
|
||||
android_log_destroy(&contextForRead);
|
||||
}
|
||||
android_log_destroy(&mContext);
|
||||
}
|
||||
}
|
||||
|
||||
LogEvent::~LogEvent() {
|
||||
if (mContext) {
|
||||
// This is for the case when LogEvent is created using the test interface
|
||||
@@ -577,132 +539,6 @@ uint8_t LogEvent::getNumAnnotations(uint8_t typeInfo) {
|
||||
return (typeInfo >> 4) & 0x0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* The elements of each log event are stored as a vector of android_log_list_elements.
|
||||
* The goal is to do as little preprocessing as possible, because we read a tiny fraction
|
||||
* of the elements that are written to the log.
|
||||
*
|
||||
* The idea here is to read through the log items once, we get as much information we need for
|
||||
* matching as possible. Because this log will be matched against lots of matchers.
|
||||
*/
|
||||
void LogEvent::init(android_log_context context) {
|
||||
android_log_list_element elem;
|
||||
int i = 0;
|
||||
int depth = -1;
|
||||
int pos[] = {1, 1, 1};
|
||||
bool isKeyValuePairAtom = false;
|
||||
do {
|
||||
elem = android_log_read_next(context);
|
||||
switch ((int)elem.type) {
|
||||
case EVENT_TYPE_INT:
|
||||
// elem at [0] is EVENT_TYPE_LIST, [1] is the timestamp, [2] is tag id.
|
||||
if (i == 2) {
|
||||
mTagId = elem.data.int32;
|
||||
isKeyValuePairAtom = (mTagId == android::util::KEY_VALUE_PAIRS_ATOM);
|
||||
} else {
|
||||
if (depth < 0 || depth > 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
mValues.push_back(
|
||||
FieldValue(Field(mTagId, pos, depth), Value((int32_t)elem.data.int32)));
|
||||
|
||||
pos[depth]++;
|
||||
}
|
||||
break;
|
||||
case EVENT_TYPE_FLOAT: {
|
||||
if (depth < 0 || depth > 2) {
|
||||
ALOGE("Depth > 2. Not supported!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Handles the oneof field in KeyValuePair atom.
|
||||
if (isKeyValuePairAtom && depth == 2) {
|
||||
pos[depth] = 5;
|
||||
}
|
||||
|
||||
mValues.push_back(FieldValue(Field(mTagId, pos, depth), Value(elem.data.float32)));
|
||||
|
||||
pos[depth]++;
|
||||
|
||||
} break;
|
||||
case EVENT_TYPE_STRING: {
|
||||
if (depth < 0 || depth > 2) {
|
||||
ALOGE("Depth > 2. Not supported!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Handles the oneof field in KeyValuePair atom.
|
||||
if (isKeyValuePairAtom && depth == 2) {
|
||||
pos[depth] = 4;
|
||||
}
|
||||
mValues.push_back(FieldValue(Field(mTagId, pos, depth),
|
||||
Value(string(elem.data.string, elem.len))));
|
||||
|
||||
pos[depth]++;
|
||||
|
||||
} break;
|
||||
case EVENT_TYPE_LONG: {
|
||||
if (i == 1) {
|
||||
mElapsedTimestampNs = elem.data.int64;
|
||||
} else {
|
||||
if (depth < 0 || depth > 2) {
|
||||
ALOGE("Depth > 2. Not supported!");
|
||||
return;
|
||||
}
|
||||
// Handles the oneof field in KeyValuePair atom.
|
||||
if (isKeyValuePairAtom && depth == 2) {
|
||||
pos[depth] = 3;
|
||||
}
|
||||
mValues.push_back(
|
||||
FieldValue(Field(mTagId, pos, depth), Value((int64_t)elem.data.int64)));
|
||||
|
||||
pos[depth]++;
|
||||
}
|
||||
} break;
|
||||
case EVENT_TYPE_LIST:
|
||||
depth++;
|
||||
if (depth > 2) {
|
||||
ALOGE("Depth > 2. Not supported!");
|
||||
return;
|
||||
}
|
||||
pos[depth] = 1;
|
||||
|
||||
break;
|
||||
case EVENT_TYPE_LIST_STOP: {
|
||||
int prevDepth = depth;
|
||||
depth--;
|
||||
if (depth >= 0 && depth < 2) {
|
||||
// Now go back to decorate the previous items that are last at prevDepth.
|
||||
// So that we can later easily match them with Position=Last matchers.
|
||||
pos[prevDepth]--;
|
||||
int path = getEncodedField(pos, prevDepth, false);
|
||||
for (auto it = mValues.rbegin(); it != mValues.rend(); ++it) {
|
||||
if (it->mField.getDepth() >= prevDepth &&
|
||||
it->mField.getPath(prevDepth) == path) {
|
||||
it->mField.decorateLastPos(prevDepth);
|
||||
} else {
|
||||
// Safe to break, because the items are in DFS order.
|
||||
break;
|
||||
}
|
||||
}
|
||||
pos[depth]++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_TYPE_UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
} while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
|
||||
if (isKeyValuePairAtom && mValues.size() > 0) {
|
||||
mValues[0] = FieldValue(Field(android::util::KEY_VALUE_PAIRS_ATOM, getSimpleField(1)),
|
||||
Value((int32_t)mLogUid));
|
||||
}
|
||||
}
|
||||
|
||||
int64_t LogEvent::GetLong(size_t key, status_t* err) const {
|
||||
// TODO(b/110561208): encapsulate the magical operations in Field struct as static functions
|
||||
int field = getSimpleField(key);
|
||||
|
||||
@@ -70,11 +70,6 @@ public:
|
||||
*/
|
||||
explicit LogEvent(uint8_t* msg, uint32_t len, int32_t uid, int32_t pid);
|
||||
|
||||
/**
|
||||
* Temp constructor to use for pulled atoms until we flip the socket schema.
|
||||
*/
|
||||
explicit LogEvent(uint8_t* msg, uint32_t len, int32_t uid, int32_t pid, bool useNewSchema);
|
||||
|
||||
/**
|
||||
* Constructs a LogEvent with synthetic data for testing. Must call init() before reading.
|
||||
*/
|
||||
@@ -171,12 +166,6 @@ public:
|
||||
*/
|
||||
void ToProto(android::util::ProtoOutputStream& out) const;
|
||||
|
||||
/**
|
||||
* Used with the constructor where tag is passed in. Converts the log_event_list to read mode
|
||||
* and prepares the list for reading.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Set elapsed timestamp if the original timestamp is missing.
|
||||
*/
|
||||
@@ -304,11 +293,6 @@ private:
|
||||
uint8_t getTypeId(uint8_t typeInfo);
|
||||
uint8_t getNumAnnotations(uint8_t typeInfo);
|
||||
|
||||
/**
|
||||
* Parses a log_msg into a LogEvent object.
|
||||
*/
|
||||
void init(android_log_context context);
|
||||
|
||||
// The items are naturally sorted in DFS order as we read them. this allows us to do fast
|
||||
// matching.
|
||||
std::vector<FieldValue> mValues;
|
||||
|
||||
@@ -72,65 +72,66 @@ TEST(AtomMatcherTest, TestFieldTranslation_ALL) {
|
||||
EXPECT_EQ((int32_t)0xff7f7f7f, matcher12.mMask);
|
||||
}
|
||||
|
||||
TEST(AtomMatcherTest, TestFilter_ALL) {
|
||||
FieldMatcher matcher1;
|
||||
matcher1.set_field(10);
|
||||
FieldMatcher* child = matcher1.add_child();
|
||||
child->set_field(1);
|
||||
child->set_position(Position::ALL);
|
||||
|
||||
child->add_child()->set_field(1);
|
||||
child->add_child()->set_field(2);
|
||||
|
||||
child = matcher1.add_child();
|
||||
child->set_field(2);
|
||||
|
||||
vector<Matcher> matchers;
|
||||
translateFieldMatcher(matcher1, &matchers);
|
||||
|
||||
AttributionNodeInternal attribution_node1;
|
||||
attribution_node1.set_uid(1111);
|
||||
attribution_node1.set_tag("location1");
|
||||
|
||||
AttributionNodeInternal attribution_node2;
|
||||
attribution_node2.set_uid(2222);
|
||||
attribution_node2.set_tag("location2");
|
||||
|
||||
AttributionNodeInternal attribution_node3;
|
||||
attribution_node3.set_uid(3333);
|
||||
attribution_node3.set_tag("location3");
|
||||
std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
|
||||
attribution_node3};
|
||||
|
||||
// Set up the event
|
||||
LogEvent event(10, 12345);
|
||||
event.write(attribution_nodes);
|
||||
event.write("some value");
|
||||
// Convert to a LogEvent
|
||||
event.init();
|
||||
HashableDimensionKey output;
|
||||
|
||||
filterValues(matchers, event.getValues(), &output);
|
||||
|
||||
EXPECT_EQ((size_t)7, output.getValues().size());
|
||||
EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
|
||||
EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
|
||||
EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
|
||||
EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
|
||||
|
||||
EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField());
|
||||
EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value);
|
||||
EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField());
|
||||
EXPECT_EQ("location2", output.getValues()[3].mValue.str_value);
|
||||
|
||||
EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField());
|
||||
EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value);
|
||||
EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField());
|
||||
EXPECT_EQ("location3", output.getValues()[5].mValue.str_value);
|
||||
|
||||
EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField());
|
||||
EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
|
||||
}
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(AtomMatcherTest, TestFilter_ALL) {
|
||||
// FieldMatcher matcher1;
|
||||
// matcher1.set_field(10);
|
||||
// FieldMatcher* child = matcher1.add_child();
|
||||
// child->set_field(1);
|
||||
// child->set_position(Position::ALL);
|
||||
//
|
||||
// child->add_child()->set_field(1);
|
||||
// child->add_child()->set_field(2);
|
||||
//
|
||||
// child = matcher1.add_child();
|
||||
// child->set_field(2);
|
||||
//
|
||||
// vector<Matcher> matchers;
|
||||
// translateFieldMatcher(matcher1, &matchers);
|
||||
//
|
||||
// AttributionNodeInternal attribution_node1;
|
||||
// attribution_node1.set_uid(1111);
|
||||
// attribution_node1.set_tag("location1");
|
||||
//
|
||||
// AttributionNodeInternal attribution_node2;
|
||||
// attribution_node2.set_uid(2222);
|
||||
// attribution_node2.set_tag("location2");
|
||||
//
|
||||
// AttributionNodeInternal attribution_node3;
|
||||
// attribution_node3.set_uid(3333);
|
||||
// attribution_node3.set_tag("location3");
|
||||
// std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
|
||||
// attribution_node3};
|
||||
//
|
||||
// // Set up the event
|
||||
// LogEvent event(10, 12345);
|
||||
// event.write(attribution_nodes);
|
||||
// event.write("some value");
|
||||
// // Convert to a LogEvent
|
||||
// event.init();
|
||||
// HashableDimensionKey output;
|
||||
//
|
||||
// filterValues(matchers, event.getValues(), &output);
|
||||
//
|
||||
// EXPECT_EQ((size_t)7, output.getValues().size());
|
||||
// EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
|
||||
// EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
|
||||
// EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
|
||||
// EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
|
||||
//
|
||||
// EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField());
|
||||
// EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value);
|
||||
// EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField());
|
||||
// EXPECT_EQ("location2", output.getValues()[3].mValue.str_value);
|
||||
//
|
||||
// EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField());
|
||||
// EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value);
|
||||
// EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField());
|
||||
// EXPECT_EQ("location3", output.getValues()[5].mValue.str_value);
|
||||
//
|
||||
// EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField());
|
||||
// EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
|
||||
//}
|
||||
|
||||
TEST(AtomMatcherTest, TestSubDimension) {
|
||||
HashableDimensionKey dim;
|
||||
@@ -173,60 +174,61 @@ TEST(AtomMatcherTest, TestSubDimension) {
|
||||
EXPECT_TRUE(dim.contains(subDim4));
|
||||
}
|
||||
|
||||
TEST(AtomMatcherTest, TestMetric2ConditionLink) {
|
||||
AttributionNodeInternal attribution_node1;
|
||||
attribution_node1.set_uid(1111);
|
||||
attribution_node1.set_tag("location1");
|
||||
|
||||
AttributionNodeInternal attribution_node2;
|
||||
attribution_node2.set_uid(2222);
|
||||
attribution_node2.set_tag("location2");
|
||||
|
||||
AttributionNodeInternal attribution_node3;
|
||||
attribution_node3.set_uid(3333);
|
||||
attribution_node3.set_tag("location3");
|
||||
std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
|
||||
attribution_node3};
|
||||
|
||||
// Set up the event
|
||||
LogEvent event(10, 12345);
|
||||
event.write(attribution_nodes);
|
||||
event.write("some value");
|
||||
// Convert to a LogEvent
|
||||
event.init();
|
||||
|
||||
FieldMatcher whatMatcher;
|
||||
whatMatcher.set_field(10);
|
||||
FieldMatcher* child11 = whatMatcher.add_child();
|
||||
child11->set_field(1);
|
||||
child11->set_position(Position::ANY);
|
||||
child11 = child11->add_child();
|
||||
child11->set_field(1);
|
||||
|
||||
FieldMatcher conditionMatcher;
|
||||
conditionMatcher.set_field(27);
|
||||
FieldMatcher* child2 = conditionMatcher.add_child();
|
||||
child2->set_field(2);
|
||||
child2->set_position(Position::LAST);
|
||||
|
||||
child2 = child2->add_child();
|
||||
child2->set_field(2);
|
||||
|
||||
Metric2Condition link;
|
||||
|
||||
translateFieldMatcher(whatMatcher, &link.metricFields);
|
||||
translateFieldMatcher(conditionMatcher, &link.conditionFields);
|
||||
|
||||
EXPECT_EQ((size_t)1, link.metricFields.size());
|
||||
EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
|
||||
EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
|
||||
EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
|
||||
|
||||
EXPECT_EQ((size_t)1, link.conditionFields.size());
|
||||
EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
|
||||
EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
|
||||
EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
|
||||
}
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(AtomMatcherTest, TestMetric2ConditionLink) {
|
||||
// AttributionNodeInternal attribution_node1;
|
||||
// attribution_node1.set_uid(1111);
|
||||
// attribution_node1.set_tag("location1");
|
||||
//
|
||||
// AttributionNodeInternal attribution_node2;
|
||||
// attribution_node2.set_uid(2222);
|
||||
// attribution_node2.set_tag("location2");
|
||||
//
|
||||
// AttributionNodeInternal attribution_node3;
|
||||
// attribution_node3.set_uid(3333);
|
||||
// attribution_node3.set_tag("location3");
|
||||
// std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
|
||||
// attribution_node3};
|
||||
//
|
||||
// // Set up the event
|
||||
// LogEvent event(10, 12345);
|
||||
// event.write(attribution_nodes);
|
||||
// event.write("some value");
|
||||
// // Convert to a LogEvent
|
||||
// event.init();
|
||||
//
|
||||
// FieldMatcher whatMatcher;
|
||||
// whatMatcher.set_field(10);
|
||||
// FieldMatcher* child11 = whatMatcher.add_child();
|
||||
// child11->set_field(1);
|
||||
// child11->set_position(Position::ANY);
|
||||
// child11 = child11->add_child();
|
||||
// child11->set_field(1);
|
||||
//
|
||||
// FieldMatcher conditionMatcher;
|
||||
// conditionMatcher.set_field(27);
|
||||
// FieldMatcher* child2 = conditionMatcher.add_child();
|
||||
// child2->set_field(2);
|
||||
// child2->set_position(Position::LAST);
|
||||
//
|
||||
// child2 = child2->add_child();
|
||||
// child2->set_field(2);
|
||||
//
|
||||
// Metric2Condition link;
|
||||
//
|
||||
// translateFieldMatcher(whatMatcher, &link.metricFields);
|
||||
// translateFieldMatcher(conditionMatcher, &link.conditionFields);
|
||||
//
|
||||
// EXPECT_EQ((size_t)1, link.metricFields.size());
|
||||
// EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
|
||||
// EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
|
||||
// EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
|
||||
//
|
||||
// EXPECT_EQ((size_t)1, link.conditionFields.size());
|
||||
// EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
|
||||
// EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
|
||||
// EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
|
||||
//}
|
||||
|
||||
TEST(AtomMatcherTest, TestWriteDimensionPath) {
|
||||
for (auto position : {Position::ANY, Position::ALL, Position::FIRST, Position::LAST}) {
|
||||
@@ -437,49 +439,50 @@ TEST(AtomMatcherTest, TestWriteDimensionLeafNodesToProto) {
|
||||
EXPECT_EQ(99999, dim4.value_long());
|
||||
}
|
||||
|
||||
TEST(AtomMatcherTest, TestWriteAtomToProto) {
|
||||
AttributionNodeInternal attribution_node1;
|
||||
attribution_node1.set_uid(1111);
|
||||
attribution_node1.set_tag("location1");
|
||||
|
||||
AttributionNodeInternal attribution_node2;
|
||||
attribution_node2.set_uid(2222);
|
||||
attribution_node2.set_tag("location2");
|
||||
|
||||
std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2};
|
||||
|
||||
// Set up the event
|
||||
LogEvent event(4, 12345);
|
||||
event.write(attribution_nodes);
|
||||
event.write((int32_t)999);
|
||||
// Convert to a LogEvent
|
||||
event.init();
|
||||
|
||||
android::util::ProtoOutputStream protoOutput;
|
||||
writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
|
||||
|
||||
vector<uint8_t> outData;
|
||||
outData.resize(protoOutput.size());
|
||||
size_t pos = 0;
|
||||
sp<ProtoReader> reader = protoOutput.data();
|
||||
while (reader->readBuffer() != NULL) {
|
||||
size_t toRead = reader->currentToRead();
|
||||
std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
|
||||
pos += toRead;
|
||||
reader->move(toRead);
|
||||
}
|
||||
|
||||
Atom result;
|
||||
EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
|
||||
EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
|
||||
const auto& atom = result.ble_scan_result_received();
|
||||
EXPECT_EQ(2, atom.attribution_node_size());
|
||||
EXPECT_EQ(1111, atom.attribution_node(0).uid());
|
||||
EXPECT_EQ("location1", atom.attribution_node(0).tag());
|
||||
EXPECT_EQ(2222, atom.attribution_node(1).uid());
|
||||
EXPECT_EQ("location2", atom.attribution_node(1).tag());
|
||||
EXPECT_EQ(999, atom.num_results());
|
||||
}
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(AtomMatcherTest, TestWriteAtomToProto) {
|
||||
// AttributionNodeInternal attribution_node1;
|
||||
// attribution_node1.set_uid(1111);
|
||||
// attribution_node1.set_tag("location1");
|
||||
//
|
||||
// AttributionNodeInternal attribution_node2;
|
||||
// attribution_node2.set_uid(2222);
|
||||
// attribution_node2.set_tag("location2");
|
||||
//
|
||||
// std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2};
|
||||
//
|
||||
// // Set up the event
|
||||
// LogEvent event(4, 12345);
|
||||
// event.write(attribution_nodes);
|
||||
// event.write((int32_t)999);
|
||||
// // Convert to a LogEvent
|
||||
// event.init();
|
||||
//
|
||||
// android::util::ProtoOutputStream protoOutput;
|
||||
// writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
|
||||
//
|
||||
// vector<uint8_t> outData;
|
||||
// outData.resize(protoOutput.size());
|
||||
// size_t pos = 0;
|
||||
// sp<ProtoReader> reader = protoOutput.data();
|
||||
// while (reader->readBuffer() != NULL) {
|
||||
// size_t toRead = reader->currentToRead();
|
||||
// std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
|
||||
// pos += toRead;
|
||||
// reader->move(toRead);
|
||||
// }
|
||||
//
|
||||
// Atom result;
|
||||
// EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
|
||||
// EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
|
||||
// const auto& atom = result.ble_scan_result_received();
|
||||
// EXPECT_EQ(2, atom.attribution_node_size());
|
||||
// EXPECT_EQ(1111, atom.attribution_node(0).uid());
|
||||
// EXPECT_EQ("location1", atom.attribution_node(0).tag());
|
||||
// EXPECT_EQ(2222, atom.attribution_node(1).uid());
|
||||
// EXPECT_EQ("location2", atom.attribution_node(1).tag());
|
||||
// EXPECT_EQ(999, atom.num_results());
|
||||
//}
|
||||
|
||||
/*
|
||||
* Test two Matchers is not a subset of one Matcher.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,9 +31,6 @@ using std::vector;
|
||||
using util::ProtoOutputStream;
|
||||
using util::ProtoReader;
|
||||
|
||||
|
||||
#ifdef NEW_ENCODING_SCHEME
|
||||
|
||||
Field getField(int32_t tag, const vector<int32_t>& pos, int32_t depth, const vector<bool>& last) {
|
||||
Field f(tag, (int32_t*)pos.data(), depth);
|
||||
|
||||
@@ -241,480 +238,6 @@ TEST(LogEventTest, TestAttributionChain) {
|
||||
AStatsEvent_release(event);
|
||||
}
|
||||
|
||||
#else // NEW_ENCODING_SCHEME
|
||||
|
||||
TEST(LogEventTest, TestLogParsing) {
|
||||
LogEvent event1(1, 2000);
|
||||
|
||||
std::vector<AttributionNodeInternal> nodes;
|
||||
|
||||
AttributionNodeInternal node1;
|
||||
node1.set_uid(1000);
|
||||
node1.set_tag("tag1");
|
||||
nodes.push_back(node1);
|
||||
|
||||
AttributionNodeInternal node2;
|
||||
node2.set_uid(2000);
|
||||
node2.set_tag("tag2");
|
||||
nodes.push_back(node2);
|
||||
|
||||
event1.write(nodes);
|
||||
event1.write("hello");
|
||||
event1.write((int32_t)10);
|
||||
event1.write((int64_t)20);
|
||||
event1.write((float)1.1);
|
||||
event1.init();
|
||||
|
||||
const auto& items = event1.getValues();
|
||||
EXPECT_EQ((size_t)8, items.size());
|
||||
EXPECT_EQ(1, event1.GetTagId());
|
||||
|
||||
const FieldValue& item0 = event1.getValues()[0];
|
||||
EXPECT_EQ(0x2010101, item0.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item0.mValue.getType());
|
||||
EXPECT_EQ(1000, item0.mValue.int_value);
|
||||
|
||||
const FieldValue& item1 = event1.getValues()[1];
|
||||
EXPECT_EQ(0x2010182, item1.mField.getField());
|
||||
EXPECT_EQ(Type::STRING, item1.mValue.getType());
|
||||
EXPECT_EQ("tag1", item1.mValue.str_value);
|
||||
|
||||
const FieldValue& item2 = event1.getValues()[2];
|
||||
EXPECT_EQ(0x2018201, item2.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item2.mValue.getType());
|
||||
EXPECT_EQ(2000, item2.mValue.int_value);
|
||||
|
||||
const FieldValue& item3 = event1.getValues()[3];
|
||||
EXPECT_EQ(0x2018282, item3.mField.getField());
|
||||
EXPECT_EQ(Type::STRING, item3.mValue.getType());
|
||||
EXPECT_EQ("tag2", item3.mValue.str_value);
|
||||
|
||||
const FieldValue& item4 = event1.getValues()[4];
|
||||
EXPECT_EQ(0x20000, item4.mField.getField());
|
||||
EXPECT_EQ(Type::STRING, item4.mValue.getType());
|
||||
EXPECT_EQ("hello", item4.mValue.str_value);
|
||||
|
||||
const FieldValue& item5 = event1.getValues()[5];
|
||||
EXPECT_EQ(0x30000, item5.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item5.mValue.getType());
|
||||
EXPECT_EQ(10, item5.mValue.int_value);
|
||||
|
||||
const FieldValue& item6 = event1.getValues()[6];
|
||||
EXPECT_EQ(0x40000, item6.mField.getField());
|
||||
EXPECT_EQ(Type::LONG, item6.mValue.getType());
|
||||
EXPECT_EQ((int64_t)20, item6.mValue.long_value);
|
||||
|
||||
const FieldValue& item7 = event1.getValues()[7];
|
||||
EXPECT_EQ(0x50000, item7.mField.getField());
|
||||
EXPECT_EQ(Type::FLOAT, item7.mValue.getType());
|
||||
EXPECT_EQ((float)1.1, item7.mValue.float_value);
|
||||
}
|
||||
|
||||
TEST(LogEventTest, TestKeyValuePairsAtomParsing) {
|
||||
LogEvent event1(83, 2000, 1000);
|
||||
std::map<int32_t, int32_t> int_map;
|
||||
std::map<int32_t, int64_t> long_map;
|
||||
std::map<int32_t, std::string> string_map;
|
||||
std::map<int32_t, float> float_map;
|
||||
|
||||
int_map[11] = 123;
|
||||
int_map[22] = 345;
|
||||
|
||||
long_map[33] = 678L;
|
||||
long_map[44] = 890L;
|
||||
|
||||
string_map[1] = "test2";
|
||||
string_map[2] = "test1";
|
||||
|
||||
float_map[111] = 2.2f;
|
||||
float_map[222] = 1.1f;
|
||||
|
||||
EXPECT_TRUE(event1.writeKeyValuePairs(0, // Logging side logs 0 uid.
|
||||
int_map,
|
||||
long_map,
|
||||
string_map,
|
||||
float_map));
|
||||
event1.init();
|
||||
|
||||
EXPECT_EQ(83, event1.GetTagId());
|
||||
const auto& items = event1.getValues();
|
||||
EXPECT_EQ((size_t)17, items.size());
|
||||
|
||||
const FieldValue& item0 = event1.getValues()[0];
|
||||
EXPECT_EQ(0x10000, item0.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item0.mValue.getType());
|
||||
EXPECT_EQ(1000, item0.mValue.int_value);
|
||||
|
||||
const FieldValue& item1 = event1.getValues()[1];
|
||||
EXPECT_EQ(0x2010201, item1.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item1.mValue.getType());
|
||||
EXPECT_EQ(11, item1.mValue.int_value);
|
||||
|
||||
const FieldValue& item2 = event1.getValues()[2];
|
||||
EXPECT_EQ(0x2010282, item2.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item2.mValue.getType());
|
||||
EXPECT_EQ(123, item2.mValue.int_value);
|
||||
|
||||
const FieldValue& item3 = event1.getValues()[3];
|
||||
EXPECT_EQ(0x2010301, item3.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item3.mValue.getType());
|
||||
EXPECT_EQ(22, item3.mValue.int_value);
|
||||
|
||||
const FieldValue& item4 = event1.getValues()[4];
|
||||
EXPECT_EQ(0x2010382, item4.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item4.mValue.getType());
|
||||
EXPECT_EQ(345, item4.mValue.int_value);
|
||||
|
||||
const FieldValue& item5 = event1.getValues()[5];
|
||||
EXPECT_EQ(0x2010401, item5.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item5.mValue.getType());
|
||||
EXPECT_EQ(33, item5.mValue.int_value);
|
||||
|
||||
const FieldValue& item6 = event1.getValues()[6];
|
||||
EXPECT_EQ(0x2010483, item6.mField.getField());
|
||||
EXPECT_EQ(Type::LONG, item6.mValue.getType());
|
||||
EXPECT_EQ(678L, item6.mValue.int_value);
|
||||
|
||||
const FieldValue& item7 = event1.getValues()[7];
|
||||
EXPECT_EQ(0x2010501, item7.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item7.mValue.getType());
|
||||
EXPECT_EQ(44, item7.mValue.int_value);
|
||||
|
||||
const FieldValue& item8 = event1.getValues()[8];
|
||||
EXPECT_EQ(0x2010583, item8.mField.getField());
|
||||
EXPECT_EQ(Type::LONG, item8.mValue.getType());
|
||||
EXPECT_EQ(890L, item8.mValue.int_value);
|
||||
|
||||
const FieldValue& item9 = event1.getValues()[9];
|
||||
EXPECT_EQ(0x2010601, item9.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item9.mValue.getType());
|
||||
EXPECT_EQ(1, item9.mValue.int_value);
|
||||
|
||||
const FieldValue& item10 = event1.getValues()[10];
|
||||
EXPECT_EQ(0x2010684, item10.mField.getField());
|
||||
EXPECT_EQ(Type::STRING, item10.mValue.getType());
|
||||
EXPECT_EQ("test2", item10.mValue.str_value);
|
||||
|
||||
const FieldValue& item11 = event1.getValues()[11];
|
||||
EXPECT_EQ(0x2010701, item11.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item11.mValue.getType());
|
||||
EXPECT_EQ(2, item11.mValue.int_value);
|
||||
|
||||
const FieldValue& item12 = event1.getValues()[12];
|
||||
EXPECT_EQ(0x2010784, item12.mField.getField());
|
||||
EXPECT_EQ(Type::STRING, item12.mValue.getType());
|
||||
EXPECT_EQ("test1", item12.mValue.str_value);
|
||||
|
||||
const FieldValue& item13 = event1.getValues()[13];
|
||||
EXPECT_EQ(0x2010801, item13.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item13.mValue.getType());
|
||||
EXPECT_EQ(111, item13.mValue.int_value);
|
||||
|
||||
const FieldValue& item14 = event1.getValues()[14];
|
||||
EXPECT_EQ(0x2010885, item14.mField.getField());
|
||||
EXPECT_EQ(Type::FLOAT, item14.mValue.getType());
|
||||
EXPECT_EQ(2.2f, item14.mValue.float_value);
|
||||
|
||||
const FieldValue& item15 = event1.getValues()[15];
|
||||
EXPECT_EQ(0x2018901, item15.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item15.mValue.getType());
|
||||
EXPECT_EQ(222, item15.mValue.int_value);
|
||||
|
||||
const FieldValue& item16 = event1.getValues()[16];
|
||||
EXPECT_EQ(0x2018985, item16.mField.getField());
|
||||
EXPECT_EQ(Type::FLOAT, item16.mValue.getType());
|
||||
EXPECT_EQ(1.1f, item16.mValue.float_value);
|
||||
}
|
||||
|
||||
TEST(LogEventTest, TestLogParsing2) {
|
||||
LogEvent event1(1, 2000);
|
||||
|
||||
std::vector<AttributionNodeInternal> nodes;
|
||||
|
||||
event1.write("hello");
|
||||
|
||||
// repeated msg can be in the middle
|
||||
AttributionNodeInternal node1;
|
||||
node1.set_uid(1000);
|
||||
node1.set_tag("tag1");
|
||||
nodes.push_back(node1);
|
||||
|
||||
AttributionNodeInternal node2;
|
||||
node2.set_uid(2000);
|
||||
node2.set_tag("tag2");
|
||||
nodes.push_back(node2);
|
||||
event1.write(nodes);
|
||||
|
||||
event1.write((int32_t)10);
|
||||
event1.write((int64_t)20);
|
||||
event1.write((float)1.1);
|
||||
event1.init();
|
||||
|
||||
const auto& items = event1.getValues();
|
||||
EXPECT_EQ((size_t)8, items.size());
|
||||
EXPECT_EQ(1, event1.GetTagId());
|
||||
|
||||
const FieldValue& item = event1.getValues()[0];
|
||||
EXPECT_EQ(0x00010000, item.mField.getField());
|
||||
EXPECT_EQ(Type::STRING, item.mValue.getType());
|
||||
EXPECT_EQ("hello", item.mValue.str_value);
|
||||
|
||||
const FieldValue& item0 = event1.getValues()[1];
|
||||
EXPECT_EQ(0x2020101, item0.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item0.mValue.getType());
|
||||
EXPECT_EQ(1000, item0.mValue.int_value);
|
||||
|
||||
const FieldValue& item1 = event1.getValues()[2];
|
||||
EXPECT_EQ(0x2020182, item1.mField.getField());
|
||||
EXPECT_EQ(Type::STRING, item1.mValue.getType());
|
||||
EXPECT_EQ("tag1", item1.mValue.str_value);
|
||||
|
||||
const FieldValue& item2 = event1.getValues()[3];
|
||||
EXPECT_EQ(0x2028201, item2.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item2.mValue.getType());
|
||||
EXPECT_EQ(2000, item2.mValue.int_value);
|
||||
|
||||
const FieldValue& item3 = event1.getValues()[4];
|
||||
EXPECT_EQ(0x2028282, item3.mField.getField());
|
||||
EXPECT_EQ(Type::STRING, item3.mValue.getType());
|
||||
EXPECT_EQ("tag2", item3.mValue.str_value);
|
||||
|
||||
const FieldValue& item5 = event1.getValues()[5];
|
||||
EXPECT_EQ(0x30000, item5.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item5.mValue.getType());
|
||||
EXPECT_EQ(10, item5.mValue.int_value);
|
||||
|
||||
const FieldValue& item6 = event1.getValues()[6];
|
||||
EXPECT_EQ(0x40000, item6.mField.getField());
|
||||
EXPECT_EQ(Type::LONG, item6.mValue.getType());
|
||||
EXPECT_EQ((int64_t)20, item6.mValue.long_value);
|
||||
|
||||
const FieldValue& item7 = event1.getValues()[7];
|
||||
EXPECT_EQ(0x50000, item7.mField.getField());
|
||||
EXPECT_EQ(Type::FLOAT, item7.mValue.getType());
|
||||
EXPECT_EQ((float)1.1, item7.mValue.float_value);
|
||||
}
|
||||
|
||||
TEST(LogEventTest, TestKeyValuePairsEvent) {
|
||||
std::map<int32_t, int32_t> int_map;
|
||||
std::map<int32_t, int64_t> long_map;
|
||||
std::map<int32_t, std::string> string_map;
|
||||
std::map<int32_t, float> float_map;
|
||||
|
||||
int_map[11] = 123;
|
||||
int_map[22] = 345;
|
||||
|
||||
long_map[33] = 678L;
|
||||
long_map[44] = 890L;
|
||||
|
||||
string_map[1] = "test2";
|
||||
string_map[2] = "test1";
|
||||
|
||||
float_map[111] = 2.2f;
|
||||
float_map[222] = 1.1f;
|
||||
|
||||
LogEvent event1(83, 2000, 2001, 10001, int_map, long_map, string_map, float_map);
|
||||
event1.init();
|
||||
|
||||
EXPECT_EQ(83, event1.GetTagId());
|
||||
EXPECT_EQ((int64_t)2000, event1.GetLogdTimestampNs());
|
||||
EXPECT_EQ((int64_t)2001, event1.GetElapsedTimestampNs());
|
||||
EXPECT_EQ((int64_t)10001, event1.GetUid());
|
||||
|
||||
const auto& items = event1.getValues();
|
||||
EXPECT_EQ((size_t)17, items.size());
|
||||
|
||||
const FieldValue& item0 = event1.getValues()[0];
|
||||
EXPECT_EQ(0x00010000, item0.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item0.mValue.getType());
|
||||
EXPECT_EQ(10001, item0.mValue.int_value);
|
||||
|
||||
const FieldValue& item1 = event1.getValues()[1];
|
||||
EXPECT_EQ(0x2020101, item1.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item1.mValue.getType());
|
||||
EXPECT_EQ(11, item1.mValue.int_value);
|
||||
|
||||
const FieldValue& item2 = event1.getValues()[2];
|
||||
EXPECT_EQ(0x2020182, item2.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item2.mValue.getType());
|
||||
EXPECT_EQ(123, item2.mValue.int_value);
|
||||
|
||||
const FieldValue& item3 = event1.getValues()[3];
|
||||
EXPECT_EQ(0x2020201, item3.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item3.mValue.getType());
|
||||
EXPECT_EQ(22, item3.mValue.int_value);
|
||||
|
||||
const FieldValue& item4 = event1.getValues()[4];
|
||||
EXPECT_EQ(0x2020282, item4.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item4.mValue.getType());
|
||||
EXPECT_EQ(345, item4.mValue.int_value);
|
||||
|
||||
const FieldValue& item5 = event1.getValues()[5];
|
||||
EXPECT_EQ(0x2020301, item5.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item5.mValue.getType());
|
||||
EXPECT_EQ(33, item5.mValue.int_value);
|
||||
|
||||
const FieldValue& item6 = event1.getValues()[6];
|
||||
EXPECT_EQ(0x2020383, item6.mField.getField());
|
||||
EXPECT_EQ(Type::LONG, item6.mValue.getType());
|
||||
EXPECT_EQ(678L, item6.mValue.long_value);
|
||||
|
||||
const FieldValue& item7 = event1.getValues()[7];
|
||||
EXPECT_EQ(0x2020401, item7.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item7.mValue.getType());
|
||||
EXPECT_EQ(44, item7.mValue.int_value);
|
||||
|
||||
const FieldValue& item8 = event1.getValues()[8];
|
||||
EXPECT_EQ(0x2020483, item8.mField.getField());
|
||||
EXPECT_EQ(Type::LONG, item8.mValue.getType());
|
||||
EXPECT_EQ(890L, item8.mValue.long_value);
|
||||
|
||||
const FieldValue& item9 = event1.getValues()[9];
|
||||
EXPECT_EQ(0x2020501, item9.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item9.mValue.getType());
|
||||
EXPECT_EQ(1, item9.mValue.int_value);
|
||||
|
||||
const FieldValue& item10 = event1.getValues()[10];
|
||||
EXPECT_EQ(0x2020584, item10.mField.getField());
|
||||
EXPECT_EQ(Type::STRING, item10.mValue.getType());
|
||||
EXPECT_EQ("test2", item10.mValue.str_value);
|
||||
|
||||
const FieldValue& item11 = event1.getValues()[11];
|
||||
EXPECT_EQ(0x2020601, item11.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item11.mValue.getType());
|
||||
EXPECT_EQ(2, item11.mValue.int_value);
|
||||
|
||||
const FieldValue& item12 = event1.getValues()[12];
|
||||
EXPECT_EQ(0x2020684, item12.mField.getField());
|
||||
EXPECT_EQ(Type::STRING, item12.mValue.getType());
|
||||
EXPECT_EQ("test1", item12.mValue.str_value);
|
||||
|
||||
const FieldValue& item13 = event1.getValues()[13];
|
||||
EXPECT_EQ(0x2020701, item13.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item13.mValue.getType());
|
||||
EXPECT_EQ(111, item13.mValue.int_value);
|
||||
|
||||
const FieldValue& item14 = event1.getValues()[14];
|
||||
EXPECT_EQ(0x2020785, item14.mField.getField());
|
||||
EXPECT_EQ(Type::FLOAT, item14.mValue.getType());
|
||||
EXPECT_EQ(2.2f, item14.mValue.float_value);
|
||||
|
||||
const FieldValue& item15 = event1.getValues()[15];
|
||||
EXPECT_EQ(0x2028801, item15.mField.getField());
|
||||
EXPECT_EQ(Type::INT, item15.mValue.getType());
|
||||
EXPECT_EQ(222, item15.mValue.int_value);
|
||||
|
||||
const FieldValue& item16 = event1.getValues()[16];
|
||||
EXPECT_EQ(0x2028885, item16.mField.getField());
|
||||
EXPECT_EQ(Type::FLOAT, item16.mValue.getType());
|
||||
EXPECT_EQ(1.1f, item16.mValue.float_value);
|
||||
}
|
||||
|
||||
TEST(LogEventTest, TestBinaryFieldAtom) {
|
||||
Atom launcherAtom;
|
||||
auto launcher_event = launcherAtom.mutable_launcher_event();
|
||||
launcher_event->set_action(stats::launcher::LauncherAction::LONGPRESS);
|
||||
launcher_event->set_src_state(stats::launcher::LauncherState::OVERVIEW);
|
||||
launcher_event->set_dst_state(stats::launcher::LauncherState::ALLAPPS);
|
||||
|
||||
auto extension = launcher_event->mutable_extension();
|
||||
|
||||
auto src_target = extension->add_src_target();
|
||||
src_target->set_type(stats::launcher::LauncherTarget_Type_ITEM_TYPE);
|
||||
src_target->set_item(stats::launcher::LauncherTarget_Item_FOLDER_ICON);
|
||||
|
||||
auto dst_target = extension->add_dst_target();
|
||||
dst_target->set_type(stats::launcher::LauncherTarget_Type_ITEM_TYPE);
|
||||
dst_target->set_item(stats::launcher::LauncherTarget_Item_WIDGET);
|
||||
|
||||
string extension_str;
|
||||
extension->SerializeToString(&extension_str);
|
||||
|
||||
LogEvent event1(Atom::kLauncherEventFieldNumber, 1000);
|
||||
|
||||
event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS);
|
||||
event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW);
|
||||
event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS);
|
||||
event1.writeBytes(extension_str);
|
||||
event1.init();
|
||||
|
||||
ProtoOutputStream proto;
|
||||
event1.ToProto(proto);
|
||||
|
||||
std::vector<uint8_t> outData;
|
||||
outData.resize(proto.size());
|
||||
size_t pos = 0;
|
||||
sp<ProtoReader> reader = proto.data();
|
||||
while (reader->readBuffer() != NULL) {
|
||||
size_t toRead = reader->currentToRead();
|
||||
std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
|
||||
pos += toRead;
|
||||
reader->move(toRead);
|
||||
}
|
||||
|
||||
std::string result_str(outData.begin(), outData.end());
|
||||
std::string orig_str;
|
||||
launcherAtom.SerializeToString(&orig_str);
|
||||
|
||||
EXPECT_EQ(orig_str, result_str);
|
||||
}
|
||||
|
||||
TEST(LogEventTest, TestBinaryFieldAtom_empty) {
|
||||
Atom launcherAtom;
|
||||
auto launcher_event = launcherAtom.mutable_launcher_event();
|
||||
launcher_event->set_action(stats::launcher::LauncherAction::LONGPRESS);
|
||||
launcher_event->set_src_state(stats::launcher::LauncherState::OVERVIEW);
|
||||
launcher_event->set_dst_state(stats::launcher::LauncherState::ALLAPPS);
|
||||
|
||||
// empty string.
|
||||
string extension_str;
|
||||
|
||||
LogEvent event1(Atom::kLauncherEventFieldNumber, 1000);
|
||||
|
||||
event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS);
|
||||
event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW);
|
||||
event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS);
|
||||
event1.writeBytes(extension_str);
|
||||
event1.init();
|
||||
|
||||
ProtoOutputStream proto;
|
||||
event1.ToProto(proto);
|
||||
|
||||
std::vector<uint8_t> outData;
|
||||
outData.resize(proto.size());
|
||||
size_t pos = 0;
|
||||
sp<ProtoReader> reader = proto.data();
|
||||
while (reader->readBuffer() != NULL) {
|
||||
size_t toRead = reader->currentToRead();
|
||||
std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
|
||||
pos += toRead;
|
||||
reader->move(toRead);
|
||||
}
|
||||
|
||||
std::string result_str(outData.begin(), outData.end());
|
||||
std::string orig_str;
|
||||
launcherAtom.SerializeToString(&orig_str);
|
||||
|
||||
EXPECT_EQ(orig_str, result_str);
|
||||
}
|
||||
|
||||
TEST(LogEventTest, TestWriteExperimentIdsToProto) {
|
||||
std::vector<int64_t> expIds;
|
||||
expIds.push_back(5038);
|
||||
std::vector<uint8_t> proto;
|
||||
|
||||
writeExperimentIdsToProto(expIds, &proto);
|
||||
|
||||
EXPECT_EQ(proto.size(), 3);
|
||||
// Proto wire format for field ID 1, varint
|
||||
EXPECT_EQ(proto[0], 0x08);
|
||||
// varint of 5038, 2 bytes long
|
||||
EXPECT_EQ(proto[1], 0xae);
|
||||
EXPECT_EQ(proto[2], 0x27);
|
||||
}
|
||||
#endif // NEW_ENCODING_SCHEME
|
||||
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
} // namespace android
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,34 +39,35 @@ using android::util::ProtoReader;
|
||||
const string kApp1 = "app1.sharing.1";
|
||||
const string kApp2 = "app2.sharing.1";
|
||||
|
||||
TEST(UidMapTest, TestIsolatedUID) {
|
||||
sp<UidMap> m = new UidMap();
|
||||
sp<StatsPullerManager> pullerManager = new StatsPullerManager();
|
||||
sp<AlarmMonitor> anomalyAlarmMonitor;
|
||||
sp<AlarmMonitor> subscriberAlarmMonitor;
|
||||
// Construct the processor with a dummy sendBroadcast function that does nothing.
|
||||
StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
|
||||
[](const ConfigKey& key) { return true; },
|
||||
[](const int&, const vector<int64_t>&) {return true;});
|
||||
LogEvent addEvent(android::util::ISOLATED_UID_CHANGED, 1);
|
||||
addEvent.write(100); // parent UID
|
||||
addEvent.write(101); // isolated UID
|
||||
addEvent.write(1); // Indicates creation.
|
||||
addEvent.init();
|
||||
|
||||
EXPECT_EQ(101, m->getHostUidOrSelf(101));
|
||||
|
||||
p.OnLogEvent(&addEvent);
|
||||
EXPECT_EQ(100, m->getHostUidOrSelf(101));
|
||||
|
||||
LogEvent removeEvent(android::util::ISOLATED_UID_CHANGED, 1);
|
||||
removeEvent.write(100); // parent UID
|
||||
removeEvent.write(101); // isolated UID
|
||||
removeEvent.write(0); // Indicates removal.
|
||||
removeEvent.init();
|
||||
p.OnLogEvent(&removeEvent);
|
||||
EXPECT_EQ(101, m->getHostUidOrSelf(101));
|
||||
}
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(UidMapTest, TestIsolatedUID) {
|
||||
// sp<UidMap> m = new UidMap();
|
||||
// sp<StatsPullerManager> pullerManager = new StatsPullerManager();
|
||||
// sp<AlarmMonitor> anomalyAlarmMonitor;
|
||||
// sp<AlarmMonitor> subscriberAlarmMonitor;
|
||||
// // Construct the processor with a dummy sendBroadcast function that does nothing.
|
||||
// StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
|
||||
// [](const ConfigKey& key) { return true; },
|
||||
// [](const int&, const vector<int64_t>&) {return true;});
|
||||
// LogEvent addEvent(android::util::ISOLATED_UID_CHANGED, 1);
|
||||
// addEvent.write(100); // parent UID
|
||||
// addEvent.write(101); // isolated UID
|
||||
// addEvent.write(1); // Indicates creation.
|
||||
// addEvent.init();
|
||||
//
|
||||
// EXPECT_EQ(101, m->getHostUidOrSelf(101));
|
||||
//
|
||||
// p.OnLogEvent(&addEvent);
|
||||
// EXPECT_EQ(100, m->getHostUidOrSelf(101));
|
||||
//
|
||||
// LogEvent removeEvent(android::util::ISOLATED_UID_CHANGED, 1);
|
||||
// removeEvent.write(100); // parent UID
|
||||
// removeEvent.write(101); // isolated UID
|
||||
// removeEvent.write(0); // Indicates removal.
|
||||
// removeEvent.init();
|
||||
// p.OnLogEvent(&removeEvent);
|
||||
// EXPECT_EQ(101, m->getHostUidOrSelf(101));
|
||||
//}
|
||||
|
||||
TEST(UidMapTest, TestMatching) {
|
||||
UidMap m;
|
||||
|
||||
@@ -67,13 +67,14 @@ void writeAttributionNodesToEvent(LogEvent* event, const std::vector<int> &uids)
|
||||
event->write(nodes); // attribution chain.
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
// 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();
|
||||
//}
|
||||
|
||||
std::map<int64_t, HashableDimensionKey> getWakeLockQueryKey(
|
||||
const Position position,
|
||||
@@ -264,377 +265,378 @@ TEST(SimpleConditionTrackerTest, TestNonSlicedConditionNestCounting) {
|
||||
EXPECT_TRUE(changedCache[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(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, 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]);
|
||||
}
|
||||
}
|
||||
// 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, 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]);
|
||||
// }
|
||||
//}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
|
||||
@@ -44,65 +44,66 @@ SimplePredicate getUidProcStatePredicate() {
|
||||
return simplePredicate;
|
||||
}
|
||||
|
||||
void makeUidProcStateEvent(int32_t uid, int32_t state, LogEvent* event) {
|
||||
event->write(uid);
|
||||
event->write(state);
|
||||
event->init();
|
||||
}
|
||||
|
||||
TEST(StateConditionTrackerTest, TestStateChange) {
|
||||
int uid1 = 111;
|
||||
int uid2 = 222;
|
||||
|
||||
int state1 = 1001;
|
||||
int state2 = 1002;
|
||||
unordered_map<int64_t, int> trackerNameIndexMap;
|
||||
trackerNameIndexMap[StringToId("UidProcState")] = 0;
|
||||
vector<Matcher> primaryFields;
|
||||
primaryFields.push_back(getSimpleMatcher(kUidProcTag, 1));
|
||||
StateConditionTracker tracker(ConfigKey(12, 123), 123, 0, getUidProcStatePredicate(),
|
||||
trackerNameIndexMap, primaryFields);
|
||||
|
||||
LogEvent event(kUidProcTag, 0 /*timestamp*/);
|
||||
makeUidProcStateEvent(uid1, state1, &event);
|
||||
|
||||
vector<MatchingState> matcherState;
|
||||
matcherState.push_back(MatchingState::kMatched);
|
||||
vector<sp<ConditionTracker>> allPredicates;
|
||||
vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
|
||||
vector<bool> changedCache(1, false);
|
||||
|
||||
tracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, changedCache);
|
||||
EXPECT_EQ(1ULL, tracker.mLastChangedToTrueDimensions.size());
|
||||
EXPECT_EQ(0ULL, tracker.mLastChangedToFalseDimensions.size());
|
||||
EXPECT_TRUE(changedCache[0]);
|
||||
|
||||
changedCache[0] = false;
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
tracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, changedCache);
|
||||
EXPECT_EQ(0ULL, tracker.mLastChangedToTrueDimensions.size());
|
||||
EXPECT_EQ(0ULL, tracker.mLastChangedToFalseDimensions.size());
|
||||
EXPECT_FALSE(changedCache[0]);
|
||||
|
||||
LogEvent event2(kUidProcTag, 0 /*timestamp*/);
|
||||
makeUidProcStateEvent(uid1, state2, &event2);
|
||||
|
||||
changedCache[0] = false;
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
tracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache, changedCache);
|
||||
EXPECT_EQ(1ULL, tracker.mLastChangedToTrueDimensions.size());
|
||||
EXPECT_EQ(1ULL, tracker.mLastChangedToFalseDimensions.size());
|
||||
EXPECT_TRUE(changedCache[0]);
|
||||
|
||||
LogEvent event3(kUidProcTag, 0 /*timestamp*/);
|
||||
makeUidProcStateEvent(uid2, state1, &event3);
|
||||
changedCache[0] = false;
|
||||
conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
tracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache, changedCache);
|
||||
EXPECT_EQ(1ULL, tracker.mLastChangedToTrueDimensions.size());
|
||||
EXPECT_EQ(0ULL, tracker.mLastChangedToFalseDimensions.size());
|
||||
EXPECT_TRUE(changedCache[0]);
|
||||
}
|
||||
// TODO(b/149590301): Update these tests to use new socket schema.
|
||||
//void makeUidProcStateEvent(int32_t uid, int32_t state, LogEvent* event) {
|
||||
// event->write(uid);
|
||||
// event->write(state);
|
||||
// event->init();
|
||||
//}
|
||||
//
|
||||
//TEST(StateConditionTrackerTest, TestStateChange) {
|
||||
// int uid1 = 111;
|
||||
// int uid2 = 222;
|
||||
//
|
||||
// int state1 = 1001;
|
||||
// int state2 = 1002;
|
||||
// unordered_map<int64_t, int> trackerNameIndexMap;
|
||||
// trackerNameIndexMap[StringToId("UidProcState")] = 0;
|
||||
// vector<Matcher> primaryFields;
|
||||
// primaryFields.push_back(getSimpleMatcher(kUidProcTag, 1));
|
||||
// StateConditionTracker tracker(ConfigKey(12, 123), 123, 0, getUidProcStatePredicate(),
|
||||
// trackerNameIndexMap, primaryFields);
|
||||
//
|
||||
// LogEvent event(kUidProcTag, 0 /*timestamp*/);
|
||||
// makeUidProcStateEvent(uid1, state1, &event);
|
||||
//
|
||||
// vector<MatchingState> matcherState;
|
||||
// matcherState.push_back(MatchingState::kMatched);
|
||||
// vector<sp<ConditionTracker>> allPredicates;
|
||||
// vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
|
||||
// vector<bool> changedCache(1, false);
|
||||
//
|
||||
// tracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, changedCache);
|
||||
// EXPECT_EQ(1ULL, tracker.mLastChangedToTrueDimensions.size());
|
||||
// EXPECT_EQ(0ULL, tracker.mLastChangedToFalseDimensions.size());
|
||||
// EXPECT_TRUE(changedCache[0]);
|
||||
//
|
||||
// changedCache[0] = false;
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// tracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, changedCache);
|
||||
// EXPECT_EQ(0ULL, tracker.mLastChangedToTrueDimensions.size());
|
||||
// EXPECT_EQ(0ULL, tracker.mLastChangedToFalseDimensions.size());
|
||||
// EXPECT_FALSE(changedCache[0]);
|
||||
//
|
||||
// LogEvent event2(kUidProcTag, 0 /*timestamp*/);
|
||||
// makeUidProcStateEvent(uid1, state2, &event2);
|
||||
//
|
||||
// changedCache[0] = false;
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// tracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache, changedCache);
|
||||
// EXPECT_EQ(1ULL, tracker.mLastChangedToTrueDimensions.size());
|
||||
// EXPECT_EQ(1ULL, tracker.mLastChangedToFalseDimensions.size());
|
||||
// EXPECT_TRUE(changedCache[0]);
|
||||
//
|
||||
// LogEvent event3(kUidProcTag, 0 /*timestamp*/);
|
||||
// makeUidProcStateEvent(uid2, state1, &event3);
|
||||
// changedCache[0] = false;
|
||||
// conditionCache[0] = ConditionState::kNotEvaluated;
|
||||
// tracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache, changedCache);
|
||||
// EXPECT_EQ(1ULL, tracker.mLastChangedToTrueDimensions.size());
|
||||
// EXPECT_EQ(0ULL, tracker.mLastChangedToFalseDimensions.size());
|
||||
// EXPECT_TRUE(changedCache[0]);
|
||||
//}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
|
||||
@@ -53,184 +53,185 @@ StatsdConfig CreateStatsdConfig(int num_buckets, int threshold) {
|
||||
|
||||
} // namespace
|
||||
|
||||
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));
|
||||
}
|
||||
// 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));
|
||||
//}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
@@ -89,393 +89,394 @@ MetricDimensionKey dimensionKey2(
|
||||
(int32_t)0x02010101), Value((int32_t)222))}),
|
||||
DEFAULT_DIMENSION_KEY);
|
||||
|
||||
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));
|
||||
}
|
||||
// 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));
|
||||
//}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
@@ -55,364 +55,365 @@ StatsdConfig CreateStatsdConfig(const Position position) {
|
||||
|
||||
} // namespace
|
||||
|
||||
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());
|
||||
}
|
||||
// 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());
|
||||
//}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
@@ -56,52 +56,53 @@ StatsdConfig CreateStatsdConfig(int num_buckets, int threshold) {
|
||||
|
||||
} // namespace
|
||||
|
||||
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);
|
||||
}
|
||||
// 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);
|
||||
//}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -63,483 +63,484 @@ StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type,
|
||||
return config;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
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);
|
||||
}
|
||||
} // 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, TestRandomSamplePulledEventsNoCondition) {
|
||||
auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
|
||||
|
||||
@@ -68,219 +68,221 @@ StatsdConfig CreateStatsdConfigForPushedEvent(const GaugeMetric::SamplingType sa
|
||||
return config;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
// 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;
|
||||
//}
|
||||
|
||||
} // namespace
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
// 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());
|
||||
// }
|
||||
//}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -97,249 +97,250 @@ StatsdConfig CreateStatsdConfig() {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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);
|
||||
//}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
@@ -113,95 +113,96 @@ StatsdConfig MakeGaugeMetricConfig(int64_t minTime) {
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
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());
|
||||
}
|
||||
// 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, TestValueMetricWithoutMinPartialBucket) {
|
||||
shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
|
||||
|
||||
@@ -64,316 +64,317 @@ StatsdConfig CreateStatsdConfig(bool useCondition = true) {
|
||||
|
||||
} // namespace
|
||||
|
||||
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());
|
||||
}
|
||||
// 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 initialization of a simple value metric that is sliced by a state.
|
||||
|
||||
@@ -69,282 +69,284 @@ std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(111, "Ap
|
||||
CreateAttribution(222, "GMSCoreModule1"),
|
||||
CreateAttribution(222, "GMSCoreModule2")};
|
||||
|
||||
/*
|
||||
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());
|
||||
}
|
||||
}
|
||||
// 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());
|
||||
// }
|
||||
//}
|
||||
|
||||
} // namespace
|
||||
|
||||
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);
|
||||
}
|
||||
// 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);
|
||||
//}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
298
cmds/statsd/tests/external/StatsPuller_test.cpp
vendored
298
cmds/statsd/tests/external/StatsPuller_test.cpp
vendored
@@ -57,12 +57,13 @@ private:
|
||||
|
||||
FakePuller puller;
|
||||
|
||||
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;
|
||||
}
|
||||
// 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;
|
||||
//}
|
||||
|
||||
class StatsPullerTest : public ::testing::Test {
|
||||
public:
|
||||
@@ -79,148 +80,149 @@ public:
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
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());
|
||||
}
|
||||
// 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());
|
||||
//}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
|
||||
407
cmds/statsd/tests/external/puller_util_test.cpp
vendored
407
cmds/statsd/tests/external/puller_util_test.cpp
vendored
@@ -60,209 +60,210 @@ void extractIntoVector(vector<shared_ptr<LogEvent>> events,
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
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());
|
||||
}
|
||||
// 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());
|
||||
//}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
|
||||
@@ -37,365 +37,366 @@ namespace statsd {
|
||||
|
||||
const ConfigKey kConfigKey(0, 12345);
|
||||
|
||||
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));
|
||||
}
|
||||
// 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));
|
||||
//}
|
||||
|
||||
TEST(CountMetricProducerTest, TestOneWeekTimeUnit) {
|
||||
CountMetric metric;
|
||||
|
||||
@@ -56,382 +56,383 @@ TEST(DurationMetricTrackerTest, TestFirstBucket) {
|
||||
EXPECT_EQ(660000000005, durationProducer.getCurrentBucketEndTimeNs());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// 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);
|
||||
//}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
|
||||
@@ -85,46 +85,47 @@ TEST(EventMetricProducerTest, TestEventsWithNonSlicedCondition) {
|
||||
// eventProducer.onDumpReport();
|
||||
}
|
||||
|
||||
TEST(EventMetricProducerTest, TestEventsWithSlicedCondition) {
|
||||
int64_t bucketStartTimeNs = 10000000000;
|
||||
int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
|
||||
|
||||
int tagId = 1;
|
||||
int conditionTagId = 2;
|
||||
|
||||
EventMetric metric;
|
||||
metric.set_id(1);
|
||||
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);
|
||||
EXPECT_TRUE(event1.write("111"));
|
||||
event1.init();
|
||||
ConditionKey key1;
|
||||
key1[StringToId("APP_IN_BACKGROUND_PER_UID")] = {getMockedDimensionKey(conditionTagId, 2, "111")};
|
||||
|
||||
LogEvent event2(tagId, bucketStartTimeNs + 10);
|
||||
EXPECT_TRUE(event2.write("222"));
|
||||
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));
|
||||
|
||||
EventMetricProducer eventProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs);
|
||||
|
||||
eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
|
||||
eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
|
||||
|
||||
// TODO: get the report and check the content after the ProtoOutputStream change is done.
|
||||
// eventProducer.onDumpReport();
|
||||
}
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(EventMetricProducerTest, TestEventsWithSlicedCondition) {
|
||||
// int64_t bucketStartTimeNs = 10000000000;
|
||||
// int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
|
||||
//
|
||||
// int tagId = 1;
|
||||
// int conditionTagId = 2;
|
||||
//
|
||||
// EventMetric metric;
|
||||
// metric.set_id(1);
|
||||
// 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);
|
||||
// EXPECT_TRUE(event1.write("111"));
|
||||
// event1.init();
|
||||
// ConditionKey key1;
|
||||
// key1[StringToId("APP_IN_BACKGROUND_PER_UID")] = {getMockedDimensionKey(conditionTagId, 2, "111")};
|
||||
//
|
||||
// LogEvent event2(tagId, bucketStartTimeNs + 10);
|
||||
// EXPECT_TRUE(event2.write("222"));
|
||||
// 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));
|
||||
//
|
||||
// EventMetricProducer eventProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs);
|
||||
//
|
||||
// eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
|
||||
// eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
|
||||
//
|
||||
// // TODO: get the report and check the content after the ProtoOutputStream change is done.
|
||||
// // eventProducer.onDumpReport();
|
||||
//}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -105,29 +105,30 @@ void runShellTest(ShellSubscription config, sp<MockUidMap> uidMap,
|
||||
close(fds_data[0]);
|
||||
}
|
||||
|
||||
TEST(ShellSubscriberTest, testPushedSubscription) {
|
||||
sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
|
||||
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
|
||||
vector<std::shared_ptr<LogEvent>> pushedList;
|
||||
|
||||
std::shared_ptr<LogEvent> event1 =
|
||||
std::make_shared<LogEvent>(29 /*screen_state_atom_id*/, 1000 /*timestamp*/);
|
||||
event1->write(::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
event1->init();
|
||||
pushedList.push_back(event1);
|
||||
|
||||
// create a simple config to get screen events
|
||||
ShellSubscription config;
|
||||
config.add_pushed()->set_atom_id(29);
|
||||
|
||||
// this is the expected screen event atom.
|
||||
ShellData shellData;
|
||||
shellData.add_atom()->mutable_screen_state_changed()->set_state(
|
||||
::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
|
||||
runShellTest(config, uidMap, pullerManager, pushedList, shellData);
|
||||
}
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(ShellSubscriberTest, testPushedSubscription) {
|
||||
// sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
//
|
||||
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
|
||||
// vector<std::shared_ptr<LogEvent>> pushedList;
|
||||
//
|
||||
// std::shared_ptr<LogEvent> event1 =
|
||||
// std::make_shared<LogEvent>(29 /*screen_state_atom_id*/, 1000 /*timestamp*/);
|
||||
// event1->write(::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
// event1->init();
|
||||
// pushedList.push_back(event1);
|
||||
//
|
||||
// // create a simple config to get screen events
|
||||
// ShellSubscription config;
|
||||
// config.add_pushed()->set_atom_id(29);
|
||||
//
|
||||
// // this is the expected screen event atom.
|
||||
// ShellData shellData;
|
||||
// shellData.add_atom()->mutable_screen_state_changed()->set_state(
|
||||
// ::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
//
|
||||
// runShellTest(config, uidMap, pullerManager, pushedList, shellData);
|
||||
//}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -160,30 +161,31 @@ ShellSubscription getPulledConfig() {
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(ShellSubscriberTest, testPulledSubscription) {
|
||||
sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
|
||||
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
|
||||
EXPECT_CALL(*pullerManager, Pull(10016, _))
|
||||
.WillRepeatedly(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
|
||||
data->clear();
|
||||
shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, 1111L);
|
||||
event->write(kUid1);
|
||||
event->write(kCpuTime1);
|
||||
event->init();
|
||||
data->push_back(event);
|
||||
// another event
|
||||
event = make_shared<LogEvent>(tagId, 1111L);
|
||||
event->write(kUid2);
|
||||
event->write(kCpuTime2);
|
||||
event->init();
|
||||
data->push_back(event);
|
||||
return true;
|
||||
}));
|
||||
|
||||
runShellTest(getPulledConfig(), uidMap, pullerManager, vector<std::shared_ptr<LogEvent>>(),
|
||||
getExpectedShellData());
|
||||
}
|
||||
// TODO(b/149590301): Update this test to use new socket schema.
|
||||
//TEST(ShellSubscriberTest, testPulledSubscription) {
|
||||
// sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
|
||||
//
|
||||
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
|
||||
// EXPECT_CALL(*pullerManager, Pull(10016, _))
|
||||
// .WillRepeatedly(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
|
||||
// data->clear();
|
||||
// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, 1111L);
|
||||
// event->write(kUid1);
|
||||
// event->write(kCpuTime1);
|
||||
// event->init();
|
||||
// data->push_back(event);
|
||||
// // another event
|
||||
// event = make_shared<LogEvent>(tagId, 1111L);
|
||||
// event->write(kUid2);
|
||||
// event->write(kCpuTime2);
|
||||
// event->init();
|
||||
// data->push_back(event);
|
||||
// return true;
|
||||
// }));
|
||||
//
|
||||
// runShellTest(getPulledConfig(), uidMap, pullerManager, vector<std::shared_ptr<LogEvent>>(),
|
||||
// getExpectedShellData());
|
||||
//}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
|
||||
@@ -56,94 +56,95 @@ int getStateInt(StateManager& mgr, int atomId, const HashableDimensionKey& query
|
||||
return output.mValue.int_value;
|
||||
}
|
||||
|
||||
// START: build event functions.
|
||||
// State with no primary fields - ScreenStateChanged
|
||||
std::shared_ptr<LogEvent> buildScreenEvent(int state) {
|
||||
std::shared_ptr<LogEvent> event =
|
||||
std::make_shared<LogEvent>(android::util::SCREEN_STATE_CHANGED, 1000 /*timestamp*/);
|
||||
event->write((int32_t)state);
|
||||
event->init();
|
||||
return event;
|
||||
}
|
||||
|
||||
// State with one primary field - UidProcessStateChanged
|
||||
std::shared_ptr<LogEvent> buildUidProcessEvent(int uid, int state) {
|
||||
std::shared_ptr<LogEvent> event =
|
||||
std::make_shared<LogEvent>(android::util::UID_PROCESS_STATE_CHANGED, 1000 /*timestamp*/);
|
||||
event->write((int32_t)uid);
|
||||
event->write((int32_t)state);
|
||||
event->init();
|
||||
return event;
|
||||
}
|
||||
|
||||
// State with first uid in attribution chain as primary field - WakelockStateChanged
|
||||
std::shared_ptr<LogEvent> buildPartialWakelockEvent(int uid, const std::string& tag, bool acquire) {
|
||||
std::vector<AttributionNodeInternal> chain;
|
||||
chain.push_back(AttributionNodeInternal());
|
||||
AttributionNodeInternal& attr = chain.back();
|
||||
attr.set_uid(uid);
|
||||
|
||||
std::shared_ptr<LogEvent> event =
|
||||
std::make_shared<LogEvent>(android::util::WAKELOCK_STATE_CHANGED, 1000 /* timestamp */);
|
||||
event->write(chain);
|
||||
event->write((int32_t)1); // PARTIAL_WAKE_LOCK
|
||||
event->write(tag);
|
||||
event->write(acquire ? 1 : 0);
|
||||
event->init();
|
||||
return event;
|
||||
}
|
||||
|
||||
// State with multiple primary fields - OverlayStateChanged
|
||||
std::shared_ptr<LogEvent> buildOverlayEvent(int uid, const std::string& packageName, int state) {
|
||||
std::shared_ptr<LogEvent> event =
|
||||
std::make_shared<LogEvent>(android::util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
|
||||
event->write((int32_t)uid);
|
||||
event->write(packageName);
|
||||
event->write(true); // using_alert_window
|
||||
event->write((int32_t)state);
|
||||
event->init();
|
||||
return event;
|
||||
}
|
||||
|
||||
// Incorrect event - missing fields
|
||||
std::shared_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName, int state) {
|
||||
std::shared_ptr<LogEvent> event =
|
||||
std::make_shared<LogEvent>(android::util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
|
||||
event->write((int32_t)uid);
|
||||
event->write(packageName);
|
||||
event->write((int32_t)state);
|
||||
event->init();
|
||||
return event;
|
||||
}
|
||||
|
||||
// Incorrect event - exclusive state has wrong type
|
||||
std::shared_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::string& packageName) {
|
||||
std::shared_ptr<LogEvent> event =
|
||||
std::make_shared<LogEvent>(android::util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
|
||||
event->write((int32_t)uid);
|
||||
event->write(packageName);
|
||||
event->write(true);
|
||||
event->write("string"); // exclusive state: string instead of int
|
||||
event->init();
|
||||
return event;
|
||||
}
|
||||
|
||||
std::shared_ptr<LogEvent> buildBleScanEvent(int uid, bool acquire, bool reset) {
|
||||
std::vector<AttributionNodeInternal> chain;
|
||||
chain.push_back(AttributionNodeInternal());
|
||||
AttributionNodeInternal& attr = chain.back();
|
||||
attr.set_uid(uid);
|
||||
|
||||
std::shared_ptr<LogEvent> event =
|
||||
std::make_shared<LogEvent>(android::util::BLE_SCAN_STATE_CHANGED, 1000);
|
||||
event->write(chain);
|
||||
event->write(reset ? 2 : acquire ? 1 : 0); // PARTIAL_WAKE_LOCK
|
||||
event->write(0); // filtered
|
||||
event->write(0); // first match
|
||||
event->write(0); // opportunistic
|
||||
event->init();
|
||||
return event;
|
||||
}
|
||||
// TODO(b/149590301): Update these helpers to use new socket schema.
|
||||
//// START: build event functions.
|
||||
//// State with no primary fields - ScreenStateChanged
|
||||
//std::shared_ptr<LogEvent> buildScreenEvent(int state) {
|
||||
// std::shared_ptr<LogEvent> event =
|
||||
// std::make_shared<LogEvent>(android::util::SCREEN_STATE_CHANGED, 1000 /*timestamp*/);
|
||||
// event->write((int32_t)state);
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//// State with one primary field - UidProcessStateChanged
|
||||
//std::shared_ptr<LogEvent> buildUidProcessEvent(int uid, int state) {
|
||||
// std::shared_ptr<LogEvent> event =
|
||||
// std::make_shared<LogEvent>(android::util::UID_PROCESS_STATE_CHANGED, 1000 /*timestamp*/);
|
||||
// event->write((int32_t)uid);
|
||||
// event->write((int32_t)state);
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//// State with first uid in attribution chain as primary field - WakelockStateChanged
|
||||
//std::shared_ptr<LogEvent> buildPartialWakelockEvent(int uid, const std::string& tag, bool acquire) {
|
||||
// std::vector<AttributionNodeInternal> chain;
|
||||
// chain.push_back(AttributionNodeInternal());
|
||||
// AttributionNodeInternal& attr = chain.back();
|
||||
// attr.set_uid(uid);
|
||||
//
|
||||
// std::shared_ptr<LogEvent> event =
|
||||
// std::make_shared<LogEvent>(android::util::WAKELOCK_STATE_CHANGED, 1000 /* timestamp */);
|
||||
// event->write(chain);
|
||||
// event->write((int32_t)1); // PARTIAL_WAKE_LOCK
|
||||
// event->write(tag);
|
||||
// event->write(acquire ? 1 : 0);
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//// State with multiple primary fields - OverlayStateChanged
|
||||
//std::shared_ptr<LogEvent> buildOverlayEvent(int uid, const std::string& packageName, int state) {
|
||||
// std::shared_ptr<LogEvent> event =
|
||||
// std::make_shared<LogEvent>(android::util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
|
||||
// event->write((int32_t)uid);
|
||||
// event->write(packageName);
|
||||
// event->write(true); // using_alert_window
|
||||
// event->write((int32_t)state);
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//// Incorrect event - missing fields
|
||||
//std::shared_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName, int state) {
|
||||
// std::shared_ptr<LogEvent> event =
|
||||
// std::make_shared<LogEvent>(android::util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
|
||||
// event->write((int32_t)uid);
|
||||
// event->write(packageName);
|
||||
// event->write((int32_t)state);
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//// Incorrect event - exclusive state has wrong type
|
||||
//std::shared_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::string& packageName) {
|
||||
// std::shared_ptr<LogEvent> event =
|
||||
// std::make_shared<LogEvent>(android::util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
|
||||
// event->write((int32_t)uid);
|
||||
// event->write(packageName);
|
||||
// event->write(true);
|
||||
// event->write("string"); // exclusive state: string instead of int
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//std::shared_ptr<LogEvent> buildBleScanEvent(int uid, bool acquire, bool reset) {
|
||||
// std::vector<AttributionNodeInternal> chain;
|
||||
// chain.push_back(AttributionNodeInternal());
|
||||
// AttributionNodeInternal& attr = chain.back();
|
||||
// attr.set_uid(uid);
|
||||
//
|
||||
// std::shared_ptr<LogEvent> event =
|
||||
// std::make_shared<LogEvent>(android::util::BLE_SCAN_STATE_CHANGED, 1000);
|
||||
// event->write(chain);
|
||||
// event->write(reset ? 2 : acquire ? 1 : 0); // PARTIAL_WAKE_LOCK
|
||||
// event->write(0); // filtered
|
||||
// event->write(0); // first match
|
||||
// event->write(0); // opportunistic
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
// END: build event functions.
|
||||
|
||||
// START: get primary key functions
|
||||
@@ -292,302 +293,302 @@ TEST(StateTrackerTest, TestUnregisterListener) {
|
||||
EXPECT_EQ(0, mgr.getStateTrackersCount());
|
||||
EXPECT_EQ(-1, mgr.getListenersCount(android::util::SCREEN_STATE_CHANGED));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a binary state atom with nested counting.
|
||||
*
|
||||
* To go from an "ON" state to an "OFF" state with nested counting, we must see
|
||||
* an equal number of "OFF" events as "ON" events.
|
||||
* For example, ACQUIRE, ACQUIRE, RELEASE will still be in the ACQUIRE state.
|
||||
* ACQUIRE, ACQUIRE, RELEASE, RELEASE will be in the RELEASE state.
|
||||
*/
|
||||
TEST(StateTrackerTest, TestStateChangeNested) {
|
||||
sp<TestStateListener> listener = new TestStateListener();
|
||||
StateManager mgr;
|
||||
mgr.registerListener(android::util::WAKELOCK_STATE_CHANGED, listener);
|
||||
|
||||
std::shared_ptr<LogEvent> event1 =
|
||||
buildPartialWakelockEvent(1000 /* uid */, "tag", true /*acquire*/);
|
||||
mgr.onLogEvent(*event1);
|
||||
EXPECT_EQ(1, listener->updates.size());
|
||||
EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
EXPECT_EQ(1, listener->updates[0].mState);
|
||||
listener->updates.clear();
|
||||
|
||||
std::shared_ptr<LogEvent> event2 =
|
||||
buildPartialWakelockEvent(1000 /* uid */, "tag", true /*acquire*/);
|
||||
mgr.onLogEvent(*event2);
|
||||
EXPECT_EQ(0, listener->updates.size());
|
||||
|
||||
std::shared_ptr<LogEvent> event3 =
|
||||
buildPartialWakelockEvent(1000 /* uid */, "tag", false /*release*/);
|
||||
mgr.onLogEvent(*event3);
|
||||
EXPECT_EQ(0, listener->updates.size());
|
||||
|
||||
std::shared_ptr<LogEvent> event4 =
|
||||
buildPartialWakelockEvent(1000 /* uid */, "tag", false /*release*/);
|
||||
mgr.onLogEvent(*event4);
|
||||
EXPECT_EQ(1, listener->updates.size());
|
||||
EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
EXPECT_EQ(0, listener->updates[0].mState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a state atom with a reset state.
|
||||
*
|
||||
* If the reset state value is seen, every state in the map is set to the default
|
||||
* state and every listener is notified.
|
||||
*/
|
||||
TEST(StateTrackerTest, TestStateChangeReset) {
|
||||
sp<TestStateListener> listener = new TestStateListener();
|
||||
StateManager mgr;
|
||||
mgr.registerListener(android::util::BLE_SCAN_STATE_CHANGED, listener);
|
||||
|
||||
std::shared_ptr<LogEvent> event1 =
|
||||
buildBleScanEvent(1000 /* uid */, true /*acquire*/, false /*reset*/);
|
||||
mgr.onLogEvent(*event1);
|
||||
EXPECT_EQ(1, listener->updates.size());
|
||||
EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
|
||||
listener->updates.clear();
|
||||
|
||||
std::shared_ptr<LogEvent> event2 =
|
||||
buildBleScanEvent(2000 /* uid */, true /*acquire*/, false /*reset*/);
|
||||
mgr.onLogEvent(*event2);
|
||||
EXPECT_EQ(1, listener->updates.size());
|
||||
EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
|
||||
listener->updates.clear();
|
||||
|
||||
std::shared_ptr<LogEvent> event3 =
|
||||
buildBleScanEvent(2000 /* uid */, false /*acquire*/, true /*reset*/);
|
||||
mgr.onLogEvent(*event3);
|
||||
EXPECT_EQ(2, listener->updates.size());
|
||||
EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[0].mState);
|
||||
EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[1].mState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test StateManager's onLogEvent and StateListener's onStateChanged correctly
|
||||
* updates listener for states without primary keys.
|
||||
*/
|
||||
TEST(StateTrackerTest, TestStateChangeNoPrimaryFields) {
|
||||
sp<TestStateListener> listener1 = new TestStateListener();
|
||||
StateManager mgr;
|
||||
mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener1);
|
||||
|
||||
// log event
|
||||
std::shared_ptr<LogEvent> event =
|
||||
buildScreenEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
mgr.onLogEvent(*event);
|
||||
|
||||
// check listener was updated
|
||||
EXPECT_EQ(1, listener1->updates.size());
|
||||
EXPECT_EQ(DEFAULT_DIMENSION_KEY, listener1->updates[0].mKey);
|
||||
EXPECT_EQ(2, listener1->updates[0].mState);
|
||||
|
||||
// check StateTracker was updated by querying for state
|
||||
HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY;
|
||||
EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
|
||||
getStateInt(mgr, android::util::SCREEN_STATE_CHANGED, queryKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test StateManager's onLogEvent and StateListener's onStateChanged correctly
|
||||
* updates listener for states with one primary key.
|
||||
*/
|
||||
TEST(StateTrackerTest, TestStateChangeOnePrimaryField) {
|
||||
sp<TestStateListener> listener1 = new TestStateListener();
|
||||
StateManager mgr;
|
||||
mgr.registerListener(android::util::UID_PROCESS_STATE_CHANGED, listener1);
|
||||
|
||||
// log event
|
||||
std::shared_ptr<LogEvent> event =
|
||||
buildUidProcessEvent(1000 /* uid */, android::app::ProcessStateEnum::PROCESS_STATE_TOP);
|
||||
mgr.onLogEvent(*event);
|
||||
|
||||
// check listener was updated
|
||||
EXPECT_EQ(1, listener1->updates.size());
|
||||
EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
EXPECT_EQ(1002, listener1->updates[0].mState);
|
||||
|
||||
// check StateTracker was updated by querying for state
|
||||
HashableDimensionKey queryKey;
|
||||
getUidProcessKey(1000 /* uid */, &queryKey);
|
||||
EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
|
||||
getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED, queryKey));
|
||||
}
|
||||
|
||||
TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) {
|
||||
sp<TestStateListener> listener1 = new TestStateListener();
|
||||
StateManager mgr;
|
||||
mgr.registerListener(android::util::WAKELOCK_STATE_CHANGED, listener1);
|
||||
|
||||
// Log event.
|
||||
std::shared_ptr<LogEvent> event =
|
||||
buildPartialWakelockEvent(1001 /* uid */, "tag1", true /* acquire */);
|
||||
mgr.onLogEvent(*event);
|
||||
|
||||
EXPECT_EQ(1, mgr.getStateTrackersCount());
|
||||
EXPECT_EQ(1, mgr.getListenersCount(android::util::WAKELOCK_STATE_CHANGED));
|
||||
|
||||
// Check listener was updated.
|
||||
EXPECT_EQ(1, listener1->updates.size());
|
||||
EXPECT_EQ(3, listener1->updates[0].mKey.getValues().size());
|
||||
EXPECT_EQ(1001, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
EXPECT_EQ(1, listener1->updates[0].mKey.getValues()[1].mValue.int_value);
|
||||
EXPECT_EQ("tag1", listener1->updates[0].mKey.getValues()[2].mValue.str_value);
|
||||
EXPECT_EQ(WakelockStateChanged::ACQUIRE, listener1->updates[0].mState);
|
||||
|
||||
// Check StateTracker was updated by querying for state.
|
||||
HashableDimensionKey queryKey;
|
||||
getPartialWakelockKey(1001 /* uid */, "tag1", &queryKey);
|
||||
EXPECT_EQ(WakelockStateChanged::ACQUIRE,
|
||||
getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey));
|
||||
|
||||
// No state stored for this query key.
|
||||
HashableDimensionKey queryKey2;
|
||||
getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2);
|
||||
EXPECT_EQ(WakelockStateChanged::RELEASE,
|
||||
getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey2));
|
||||
|
||||
// Partial query fails.
|
||||
HashableDimensionKey queryKey3;
|
||||
getPartialWakelockKey(1001 /* uid */, &queryKey3);
|
||||
EXPECT_EQ(WakelockStateChanged::RELEASE,
|
||||
getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test StateManager's onLogEvent and StateListener's onStateChanged correctly
|
||||
* updates listener for states with multiple primary keys.
|
||||
*/
|
||||
TEST(StateTrackerTest, TestStateChangeMultiplePrimaryFields) {
|
||||
sp<TestStateListener> listener1 = new TestStateListener();
|
||||
StateManager mgr;
|
||||
mgr.registerListener(android::util::OVERLAY_STATE_CHANGED, listener1);
|
||||
|
||||
// log event
|
||||
std::shared_ptr<LogEvent> event =
|
||||
buildOverlayEvent(1000 /* uid */, "package1", 1); // state: ENTERED
|
||||
mgr.onLogEvent(*event);
|
||||
|
||||
// check listener was updated
|
||||
EXPECT_EQ(1, listener1->updates.size());
|
||||
EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
EXPECT_EQ(1, listener1->updates[0].mState);
|
||||
|
||||
// check StateTracker was updated by querying for state
|
||||
HashableDimensionKey queryKey;
|
||||
getOverlayKey(1000 /* uid */, "package1", &queryKey);
|
||||
EXPECT_EQ(OverlayStateChanged::ENTERED,
|
||||
getStateInt(mgr, android::util::OVERLAY_STATE_CHANGED, queryKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test StateManager's onLogEvent and StateListener's onStateChanged
|
||||
* when there is an error extracting state from log event. Listener is not
|
||||
* updated of state change.
|
||||
*/
|
||||
TEST(StateTrackerTest, TestStateChangeEventError) {
|
||||
sp<TestStateListener> listener1 = new TestStateListener();
|
||||
StateManager mgr;
|
||||
mgr.registerListener(android::util::OVERLAY_STATE_CHANGED, listener1);
|
||||
|
||||
// log event
|
||||
std::shared_ptr<LogEvent> event1 =
|
||||
buildIncorrectOverlayEvent(1000 /* uid */, "package1", 1 /* state */);
|
||||
std::shared_ptr<LogEvent> event2 = buildOverlayEventBadStateType(1001 /* uid */, "package2");
|
||||
|
||||
// check listener was updated
|
||||
mgr.onLogEvent(*event1);
|
||||
EXPECT_EQ(0, listener1->updates.size());
|
||||
mgr.onLogEvent(*event2);
|
||||
EXPECT_EQ(0, listener1->updates.size());
|
||||
}
|
||||
|
||||
TEST(StateTrackerTest, TestStateQuery) {
|
||||
sp<TestStateListener> listener1 = new TestStateListener();
|
||||
sp<TestStateListener> listener2 = new TestStateListener();
|
||||
sp<TestStateListener> listener3 = new TestStateListener();
|
||||
sp<TestStateListener> listener4 = new TestStateListener();
|
||||
StateManager mgr;
|
||||
mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener1);
|
||||
mgr.registerListener(android::util::UID_PROCESS_STATE_CHANGED, listener2);
|
||||
mgr.registerListener(android::util::OVERLAY_STATE_CHANGED, listener3);
|
||||
mgr.registerListener(android::util::WAKELOCK_STATE_CHANGED, listener4);
|
||||
|
||||
std::shared_ptr<LogEvent> event1 = buildUidProcessEvent(
|
||||
1000,
|
||||
android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
|
||||
std::shared_ptr<LogEvent> event2 = buildUidProcessEvent(
|
||||
1001,
|
||||
android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE); // state value:
|
||||
// 1003
|
||||
std::shared_ptr<LogEvent> event3 = buildUidProcessEvent(
|
||||
1002,
|
||||
android::app::ProcessStateEnum::PROCESS_STATE_PERSISTENT); // state value: 1000
|
||||
std::shared_ptr<LogEvent> event4 = buildUidProcessEvent(
|
||||
1001,
|
||||
android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
|
||||
std::shared_ptr<LogEvent> event5 =
|
||||
buildScreenEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
std::shared_ptr<LogEvent> event6 =
|
||||
buildOverlayEvent(1000, "package1", OverlayStateChanged::ENTERED);
|
||||
std::shared_ptr<LogEvent> event7 =
|
||||
buildOverlayEvent(1000, "package2", OverlayStateChanged::EXITED);
|
||||
std::shared_ptr<LogEvent> event8 = buildPartialWakelockEvent(1005, "tag1", true);
|
||||
std::shared_ptr<LogEvent> event9 = buildPartialWakelockEvent(1005, "tag2", false);
|
||||
|
||||
mgr.onLogEvent(*event1);
|
||||
mgr.onLogEvent(*event2);
|
||||
mgr.onLogEvent(*event3);
|
||||
mgr.onLogEvent(*event5);
|
||||
mgr.onLogEvent(*event5);
|
||||
mgr.onLogEvent(*event6);
|
||||
mgr.onLogEvent(*event7);
|
||||
mgr.onLogEvent(*event8);
|
||||
mgr.onLogEvent(*event9);
|
||||
|
||||
// Query for UidProcessState of uid 1001
|
||||
HashableDimensionKey queryKey1;
|
||||
getUidProcessKey(1001, &queryKey1);
|
||||
EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
|
||||
getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED, queryKey1));
|
||||
|
||||
// Query for UidProcessState of uid 1004 - not in state map
|
||||
HashableDimensionKey queryKey2;
|
||||
getUidProcessKey(1004, &queryKey2);
|
||||
EXPECT_EQ(-1, getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED,
|
||||
queryKey2)); // default state
|
||||
|
||||
// Query for UidProcessState of uid 1001 - after change in state
|
||||
mgr.onLogEvent(*event4);
|
||||
EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
|
||||
getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED, queryKey1));
|
||||
|
||||
// Query for ScreenState
|
||||
EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
|
||||
getStateInt(mgr, android::util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY));
|
||||
|
||||
// Query for OverlayState of uid 1000, package name "package2"
|
||||
HashableDimensionKey queryKey3;
|
||||
getOverlayKey(1000, "package2", &queryKey3);
|
||||
EXPECT_EQ(OverlayStateChanged::EXITED,
|
||||
getStateInt(mgr, android::util::OVERLAY_STATE_CHANGED, queryKey3));
|
||||
|
||||
// Query for WakelockState of uid 1005, tag 2
|
||||
HashableDimensionKey queryKey4;
|
||||
getPartialWakelockKey(1005, "tag2", &queryKey4);
|
||||
EXPECT_EQ(WakelockStateChanged::RELEASE,
|
||||
getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey4));
|
||||
|
||||
// Query for WakelockState of uid 1005, tag 1
|
||||
HashableDimensionKey queryKey5;
|
||||
getPartialWakelockKey(1005, "tag1", &queryKey5);
|
||||
EXPECT_EQ(WakelockStateChanged::ACQUIRE,
|
||||
getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey5));
|
||||
}
|
||||
// TODO(b/149590301): Update these tests to use new socket schema.
|
||||
///**
|
||||
// * Test a binary state atom with nested counting.
|
||||
// *
|
||||
// * To go from an "ON" state to an "OFF" state with nested counting, we must see
|
||||
// * an equal number of "OFF" events as "ON" events.
|
||||
// * For example, ACQUIRE, ACQUIRE, RELEASE will still be in the ACQUIRE state.
|
||||
// * ACQUIRE, ACQUIRE, RELEASE, RELEASE will be in the RELEASE state.
|
||||
// */
|
||||
//TEST(StateTrackerTest, TestStateChangeNested) {
|
||||
// sp<TestStateListener> listener = new TestStateListener();
|
||||
// StateManager mgr;
|
||||
// mgr.registerListener(android::util::WAKELOCK_STATE_CHANGED, listener);
|
||||
//
|
||||
// std::shared_ptr<LogEvent> event1 =
|
||||
// buildPartialWakelockEvent(1000 /* uid */, "tag", true /*acquire*/);
|
||||
// mgr.onLogEvent(*event1);
|
||||
// EXPECT_EQ(1, listener->updates.size());
|
||||
// EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
// EXPECT_EQ(1, listener->updates[0].mState);
|
||||
// listener->updates.clear();
|
||||
//
|
||||
// std::shared_ptr<LogEvent> event2 =
|
||||
// buildPartialWakelockEvent(1000 /* uid */, "tag", true /*acquire*/);
|
||||
// mgr.onLogEvent(*event2);
|
||||
// EXPECT_EQ(0, listener->updates.size());
|
||||
//
|
||||
// std::shared_ptr<LogEvent> event3 =
|
||||
// buildPartialWakelockEvent(1000 /* uid */, "tag", false /*release*/);
|
||||
// mgr.onLogEvent(*event3);
|
||||
// EXPECT_EQ(0, listener->updates.size());
|
||||
//
|
||||
// std::shared_ptr<LogEvent> event4 =
|
||||
// buildPartialWakelockEvent(1000 /* uid */, "tag", false /*release*/);
|
||||
// mgr.onLogEvent(*event4);
|
||||
// EXPECT_EQ(1, listener->updates.size());
|
||||
// EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
// EXPECT_EQ(0, listener->updates[0].mState);
|
||||
//}
|
||||
//
|
||||
///**
|
||||
// * Test a state atom with a reset state.
|
||||
// *
|
||||
// * If the reset state value is seen, every state in the map is set to the default
|
||||
// * state and every listener is notified.
|
||||
// */
|
||||
//TEST(StateTrackerTest, TestStateChangeReset) {
|
||||
// sp<TestStateListener> listener = new TestStateListener();
|
||||
// StateManager mgr;
|
||||
// mgr.registerListener(android::util::BLE_SCAN_STATE_CHANGED, listener);
|
||||
//
|
||||
// std::shared_ptr<LogEvent> event1 =
|
||||
// buildBleScanEvent(1000 /* uid */, true /*acquire*/, false /*reset*/);
|
||||
// mgr.onLogEvent(*event1);
|
||||
// EXPECT_EQ(1, listener->updates.size());
|
||||
// EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
// EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
|
||||
// listener->updates.clear();
|
||||
//
|
||||
// std::shared_ptr<LogEvent> event2 =
|
||||
// buildBleScanEvent(2000 /* uid */, true /*acquire*/, false /*reset*/);
|
||||
// mgr.onLogEvent(*event2);
|
||||
// EXPECT_EQ(1, listener->updates.size());
|
||||
// EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
// EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
|
||||
// listener->updates.clear();
|
||||
//
|
||||
// std::shared_ptr<LogEvent> event3 =
|
||||
// buildBleScanEvent(2000 /* uid */, false /*acquire*/, true /*reset*/);
|
||||
// mgr.onLogEvent(*event3);
|
||||
// EXPECT_EQ(2, listener->updates.size());
|
||||
// EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[0].mState);
|
||||
// EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[1].mState);
|
||||
//}
|
||||
//
|
||||
///**
|
||||
// * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
|
||||
// * updates listener for states without primary keys.
|
||||
// */
|
||||
//TEST(StateTrackerTest, TestStateChangeNoPrimaryFields) {
|
||||
// sp<TestStateListener> listener1 = new TestStateListener();
|
||||
// StateManager mgr;
|
||||
// mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener1);
|
||||
//
|
||||
// // log event
|
||||
// std::shared_ptr<LogEvent> event =
|
||||
// buildScreenEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
// mgr.onLogEvent(*event);
|
||||
//
|
||||
// // check listener was updated
|
||||
// EXPECT_EQ(1, listener1->updates.size());
|
||||
// EXPECT_EQ(DEFAULT_DIMENSION_KEY, listener1->updates[0].mKey);
|
||||
// EXPECT_EQ(2, listener1->updates[0].mState);
|
||||
//
|
||||
// // check StateTracker was updated by querying for state
|
||||
// HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY;
|
||||
// EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
|
||||
// getStateInt(mgr, android::util::SCREEN_STATE_CHANGED, queryKey));
|
||||
//}
|
||||
//
|
||||
///**
|
||||
// * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
|
||||
// * updates listener for states with one primary key.
|
||||
// */
|
||||
//TEST(StateTrackerTest, TestStateChangeOnePrimaryField) {
|
||||
// sp<TestStateListener> listener1 = new TestStateListener();
|
||||
// StateManager mgr;
|
||||
// mgr.registerListener(android::util::UID_PROCESS_STATE_CHANGED, listener1);
|
||||
//
|
||||
// // log event
|
||||
// std::shared_ptr<LogEvent> event =
|
||||
// buildUidProcessEvent(1000 /* uid */, android::app::ProcessStateEnum::PROCESS_STATE_TOP);
|
||||
// mgr.onLogEvent(*event);
|
||||
//
|
||||
// // check listener was updated
|
||||
// EXPECT_EQ(1, listener1->updates.size());
|
||||
// EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
// EXPECT_EQ(1002, listener1->updates[0].mState);
|
||||
//
|
||||
// // check StateTracker was updated by querying for state
|
||||
// HashableDimensionKey queryKey;
|
||||
// getUidProcessKey(1000 /* uid */, &queryKey);
|
||||
// EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
|
||||
// getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED, queryKey));
|
||||
//}
|
||||
//
|
||||
//TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) {
|
||||
// sp<TestStateListener> listener1 = new TestStateListener();
|
||||
// StateManager mgr;
|
||||
// mgr.registerListener(android::util::WAKELOCK_STATE_CHANGED, listener1);
|
||||
//
|
||||
// // Log event.
|
||||
// std::shared_ptr<LogEvent> event =
|
||||
// buildPartialWakelockEvent(1001 /* uid */, "tag1", true /* acquire */);
|
||||
// mgr.onLogEvent(*event);
|
||||
//
|
||||
// EXPECT_EQ(1, mgr.getStateTrackersCount());
|
||||
// EXPECT_EQ(1, mgr.getListenersCount(android::util::WAKELOCK_STATE_CHANGED));
|
||||
//
|
||||
// // Check listener was updated.
|
||||
// EXPECT_EQ(1, listener1->updates.size());
|
||||
// EXPECT_EQ(3, listener1->updates[0].mKey.getValues().size());
|
||||
// EXPECT_EQ(1001, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
// EXPECT_EQ(1, listener1->updates[0].mKey.getValues()[1].mValue.int_value);
|
||||
// EXPECT_EQ("tag1", listener1->updates[0].mKey.getValues()[2].mValue.str_value);
|
||||
// EXPECT_EQ(WakelockStateChanged::ACQUIRE, listener1->updates[0].mState);
|
||||
//
|
||||
// // Check StateTracker was updated by querying for state.
|
||||
// HashableDimensionKey queryKey;
|
||||
// getPartialWakelockKey(1001 /* uid */, "tag1", &queryKey);
|
||||
// EXPECT_EQ(WakelockStateChanged::ACQUIRE,
|
||||
// getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey));
|
||||
//
|
||||
// // No state stored for this query key.
|
||||
// HashableDimensionKey queryKey2;
|
||||
// getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2);
|
||||
// EXPECT_EQ(WakelockStateChanged::RELEASE,
|
||||
// getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey2));
|
||||
//
|
||||
// // Partial query fails.
|
||||
// HashableDimensionKey queryKey3;
|
||||
// getPartialWakelockKey(1001 /* uid */, &queryKey3);
|
||||
// EXPECT_EQ(WakelockStateChanged::RELEASE,
|
||||
// getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey3));
|
||||
//}
|
||||
//
|
||||
///**
|
||||
// * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
|
||||
// * updates listener for states with multiple primary keys.
|
||||
// */
|
||||
//TEST(StateTrackerTest, TestStateChangeMultiplePrimaryFields) {
|
||||
// sp<TestStateListener> listener1 = new TestStateListener();
|
||||
// StateManager mgr;
|
||||
// mgr.registerListener(android::util::OVERLAY_STATE_CHANGED, listener1);
|
||||
//
|
||||
// // log event
|
||||
// std::shared_ptr<LogEvent> event =
|
||||
// buildOverlayEvent(1000 /* uid */, "package1", 1); // state: ENTERED
|
||||
// mgr.onLogEvent(*event);
|
||||
//
|
||||
// // check listener was updated
|
||||
// EXPECT_EQ(1, listener1->updates.size());
|
||||
// EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
|
||||
// EXPECT_EQ(1, listener1->updates[0].mState);
|
||||
//
|
||||
// // check StateTracker was updated by querying for state
|
||||
// HashableDimensionKey queryKey;
|
||||
// getOverlayKey(1000 /* uid */, "package1", &queryKey);
|
||||
// EXPECT_EQ(OverlayStateChanged::ENTERED,
|
||||
// getStateInt(mgr, android::util::OVERLAY_STATE_CHANGED, queryKey));
|
||||
//}
|
||||
//
|
||||
///**
|
||||
// * Test StateManager's onLogEvent and StateListener's onStateChanged
|
||||
// * when there is an error extracting state from log event. Listener is not
|
||||
// * updated of state change.
|
||||
// */
|
||||
//TEST(StateTrackerTest, TestStateChangeEventError) {
|
||||
// sp<TestStateListener> listener1 = new TestStateListener();
|
||||
// StateManager mgr;
|
||||
// mgr.registerListener(android::util::OVERLAY_STATE_CHANGED, listener1);
|
||||
//
|
||||
// // log event
|
||||
// std::shared_ptr<LogEvent> event1 =
|
||||
// buildIncorrectOverlayEvent(1000 /* uid */, "package1", 1 /* state */);
|
||||
// std::shared_ptr<LogEvent> event2 = buildOverlayEventBadStateType(1001 /* uid */, "package2");
|
||||
//
|
||||
// // check listener was updated
|
||||
// mgr.onLogEvent(*event1);
|
||||
// EXPECT_EQ(0, listener1->updates.size());
|
||||
// mgr.onLogEvent(*event2);
|
||||
// EXPECT_EQ(0, listener1->updates.size());
|
||||
//}
|
||||
//
|
||||
//TEST(StateTrackerTest, TestStateQuery) {
|
||||
// sp<TestStateListener> listener1 = new TestStateListener();
|
||||
// sp<TestStateListener> listener2 = new TestStateListener();
|
||||
// sp<TestStateListener> listener3 = new TestStateListener();
|
||||
// sp<TestStateListener> listener4 = new TestStateListener();
|
||||
// StateManager mgr;
|
||||
// mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener1);
|
||||
// mgr.registerListener(android::util::UID_PROCESS_STATE_CHANGED, listener2);
|
||||
// mgr.registerListener(android::util::OVERLAY_STATE_CHANGED, listener3);
|
||||
// mgr.registerListener(android::util::WAKELOCK_STATE_CHANGED, listener4);
|
||||
//
|
||||
// std::shared_ptr<LogEvent> event1 = buildUidProcessEvent(
|
||||
// 1000,
|
||||
// android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
|
||||
// std::shared_ptr<LogEvent> event2 = buildUidProcessEvent(
|
||||
// 1001,
|
||||
// android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE); // state value:
|
||||
// // 1003
|
||||
// std::shared_ptr<LogEvent> event3 = buildUidProcessEvent(
|
||||
// 1002,
|
||||
// android::app::ProcessStateEnum::PROCESS_STATE_PERSISTENT); // state value: 1000
|
||||
// std::shared_ptr<LogEvent> event4 = buildUidProcessEvent(
|
||||
// 1001,
|
||||
// android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
|
||||
// std::shared_ptr<LogEvent> event5 =
|
||||
// buildScreenEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
|
||||
// std::shared_ptr<LogEvent> event6 =
|
||||
// buildOverlayEvent(1000, "package1", OverlayStateChanged::ENTERED);
|
||||
// std::shared_ptr<LogEvent> event7 =
|
||||
// buildOverlayEvent(1000, "package2", OverlayStateChanged::EXITED);
|
||||
// std::shared_ptr<LogEvent> event8 = buildPartialWakelockEvent(1005, "tag1", true);
|
||||
// std::shared_ptr<LogEvent> event9 = buildPartialWakelockEvent(1005, "tag2", false);
|
||||
//
|
||||
// mgr.onLogEvent(*event1);
|
||||
// mgr.onLogEvent(*event2);
|
||||
// mgr.onLogEvent(*event3);
|
||||
// mgr.onLogEvent(*event5);
|
||||
// mgr.onLogEvent(*event5);
|
||||
// mgr.onLogEvent(*event6);
|
||||
// mgr.onLogEvent(*event7);
|
||||
// mgr.onLogEvent(*event8);
|
||||
// mgr.onLogEvent(*event9);
|
||||
//
|
||||
// // Query for UidProcessState of uid 1001
|
||||
// HashableDimensionKey queryKey1;
|
||||
// getUidProcessKey(1001, &queryKey1);
|
||||
// EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
|
||||
// getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED, queryKey1));
|
||||
//
|
||||
// // Query for UidProcessState of uid 1004 - not in state map
|
||||
// HashableDimensionKey queryKey2;
|
||||
// getUidProcessKey(1004, &queryKey2);
|
||||
// EXPECT_EQ(-1, getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED,
|
||||
// queryKey2)); // default state
|
||||
//
|
||||
// // Query for UidProcessState of uid 1001 - after change in state
|
||||
// mgr.onLogEvent(*event4);
|
||||
// EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
|
||||
// getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED, queryKey1));
|
||||
//
|
||||
// // Query for ScreenState
|
||||
// EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
|
||||
// getStateInt(mgr, android::util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY));
|
||||
//
|
||||
// // Query for OverlayState of uid 1000, package name "package2"
|
||||
// HashableDimensionKey queryKey3;
|
||||
// getOverlayKey(1000, "package2", &queryKey3);
|
||||
// EXPECT_EQ(OverlayStateChanged::EXITED,
|
||||
// getStateInt(mgr, android::util::OVERLAY_STATE_CHANGED, queryKey3));
|
||||
//
|
||||
// // Query for WakelockState of uid 1005, tag 2
|
||||
// HashableDimensionKey queryKey4;
|
||||
// getPartialWakelockKey(1005, "tag2", &queryKey4);
|
||||
// EXPECT_EQ(WakelockStateChanged::RELEASE,
|
||||
// getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey4));
|
||||
//
|
||||
// // Query for WakelockState of uid 1005, tag 1
|
||||
// HashableDimensionKey queryKey5;
|
||||
// getPartialWakelockKey(1005, "tag1", &queryKey5);
|
||||
// EXPECT_EQ(WakelockStateChanged::ACQUIRE,
|
||||
// getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey5));
|
||||
//}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
|
||||
@@ -409,180 +409,181 @@ FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields)
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
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> CreateScheduledJobStateChangedEvent(
|
||||
const std::vector<AttributionNodeInternal>& attributions, const string& jobName,
|
||||
const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
|
||||
auto event = std::make_unique<LogEvent>(android::util::SCHEDULED_JOB_STATE_CHANGED, timestampNs);
|
||||
event->write(attributions);
|
||||
event->write(jobName);
|
||||
event->write(state);
|
||||
event->init();
|
||||
return event;
|
||||
}
|
||||
|
||||
std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(
|
||||
const std::vector<AttributionNodeInternal>& attributions,
|
||||
const string& name, uint64_t timestampNs) {
|
||||
return CreateScheduledJobStateChangedEvent(
|
||||
attributions, name, ScheduledJobStateChanged::STARTED, timestampNs);
|
||||
}
|
||||
|
||||
// Create log event when scheduled job finishes.
|
||||
std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(
|
||||
const std::vector<AttributionNodeInternal>& attributions,
|
||||
const string& name, uint64_t timestampNs) {
|
||||
return CreateScheduledJobStateChangedEvent(
|
||||
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;
|
||||
}
|
||||
// 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> CreateScheduledJobStateChangedEvent(
|
||||
// const std::vector<AttributionNodeInternal>& attributions, const string& jobName,
|
||||
// const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
|
||||
// auto event = std::make_unique<LogEvent>(android::util::SCHEDULED_JOB_STATE_CHANGED, timestampNs);
|
||||
// event->write(attributions);
|
||||
// event->write(jobName);
|
||||
// event->write(state);
|
||||
// event->init();
|
||||
// return event;
|
||||
//}
|
||||
//
|
||||
//std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(
|
||||
// const std::vector<AttributionNodeInternal>& attributions,
|
||||
// const string& name, uint64_t timestampNs) {
|
||||
// return CreateScheduledJobStateChangedEvent(
|
||||
// attributions, name, ScheduledJobStateChanged::STARTED, timestampNs);
|
||||
//}
|
||||
//
|
||||
//// Create log event when scheduled job finishes.
|
||||
//std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(
|
||||
// const std::vector<AttributionNodeInternal>& attributions,
|
||||
// const string& name, uint64_t timestampNs) {
|
||||
// return CreateScheduledJobStateChangedEvent(
|
||||
// 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;
|
||||
//}
|
||||
|
||||
sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
|
||||
const StatsdConfig& config, const ConfigKey& key,
|
||||
|
||||
Reference in New Issue
Block a user