android13/packages/modules/StatsD/statsd/tests/e2e/EventMetric_e2e_test.cpp

267 lines
12 KiB
C++

// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <gtest/gtest.h>
#include <vector>
#include "flags/FlagProvider.h"
#include "src/StatsLogProcessor.h"
#include "src/state/StateTracker.h"
#include "src/stats_log_util.h"
#include "tests/statsd_test_util.h"
namespace android {
namespace os {
namespace statsd {
#ifdef __ANDROID__
// Setup for test fixture.
class EventMetricE2eTest : public ::testing::Test {
void SetUp() override {
FlagProvider::getInstance().overrideFuncs(&isAtLeastSFuncTrue);
}
void TearDown() override {
FlagProvider::getInstance().resetOverrides();
}
};
TEST_F(EventMetricE2eTest, TestEventMetricDataAggregated) {
StatsdConfig config;
config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
AtomMatcher wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
*config.add_atom_matcher() = wakelockAcquireMatcher;
EventMetric wakelockEventMetric =
createEventMetric("EventWakelockStateChanged", wakelockAcquireMatcher.id(), nullopt);
*config.add_event_metric() = wakelockEventMetric;
ConfigKey key(123, 987);
uint64_t bucketStartTimeNs = 10000000000; // 0:10
sp<StatsLogProcessor> processor =
CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
// Initialize log events before update.
std::vector<std::unique_ptr<LogEvent>> events;
int app1Uid = 123;
vector<int> attributionUids = {app1Uid};
std::vector<string> attributionTags = {"App1"};
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC,
attributionUids, attributionTags, "wl1"));
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 20 * NS_PER_SEC,
attributionUids, attributionTags, "wl1"));
events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 30 * NS_PER_SEC,
attributionUids, attributionTags, "wl2"));
// Send log events to StatsLogProcessor.
for (auto& event : events) {
processor->OnLogEvent(event.get());
}
uint64_t dumpTimeNs = bucketStartTimeNs + 100 * NS_PER_SEC;
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillStringInReport(&reports);
backfillStartEndTimestamp(&reports);
backfillAggregatedAtoms(&reports);
ASSERT_EQ(reports.reports_size(), 1);
ConfigMetricsReport report = reports.reports(0);
ASSERT_EQ(report.metrics_size(), 1);
StatsLogReport wakelockEventMetricReport = report.metrics(0);
EXPECT_EQ(wakelockEventMetricReport.metric_id(), wakelockEventMetric.id());
EXPECT_TRUE(wakelockEventMetricReport.has_event_metrics());
ASSERT_EQ(wakelockEventMetricReport.event_metrics().data_size(), 3);
auto data = wakelockEventMetricReport.event_metrics().data(0);
EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 10 * NS_PER_SEC);
EXPECT_EQ(data.atom().wakelock_state_changed().tag(), "wl1");
data = wakelockEventMetricReport.event_metrics().data(1);
EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 20 * NS_PER_SEC);
EXPECT_EQ(data.atom().wakelock_state_changed().tag(), "wl1");
data = wakelockEventMetricReport.event_metrics().data(2);
EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 30 * NS_PER_SEC);
EXPECT_EQ(data.atom().wakelock_state_changed().tag(), "wl2");
}
TEST_F(EventMetricE2eTest, TestRepeatedFieldsAndEmptyArrays) {
StatsdConfig config;
config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
AtomMatcher testAtomReportedAtomMatcher =
CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
*config.add_atom_matcher() = testAtomReportedAtomMatcher;
EventMetric testAtomReportedEventMetric =
createEventMetric("EventTestAtomReported", testAtomReportedAtomMatcher.id(), nullopt);
*config.add_event_metric() = testAtomReportedEventMetric;
ConfigKey key(123, 987);
uint64_t bucketStartTimeNs = 10000000000; // 0:10
sp<StatsLogProcessor> processor =
CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
// Initialize log events before update.
std::vector<std::unique_ptr<LogEvent>> events;
vector<int> intArray = {3, 6};
vector<int64_t> longArray = {1000L, 10002L};
vector<float> floatArray = {0.3f, 0.09f};
vector<string> stringArray = {"str1", "str2"};
int boolArrayLength = 2;
bool boolArray[boolArrayLength];
boolArray[0] = 1;
boolArray[1] = 0;
vector<bool> boolArrayVector = {1, 0};
vector<int> enumArray = {TestAtomReported::ON, TestAtomReported::OFF};
events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
bucketStartTimeNs + 10 * NS_PER_SEC, intArray, longArray, floatArray, stringArray,
boolArray, boolArrayLength, enumArray));
events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
bucketStartTimeNs + 20 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, {}));
events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
bucketStartTimeNs + 30 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArray));
// Send log events to StatsLogProcessor.
for (auto& event : events) {
processor->OnLogEvent(event.get());
}
uint64_t dumpTimeNs = bucketStartTimeNs + 100 * NS_PER_SEC;
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillStringInReport(&reports);
backfillStartEndTimestamp(&reports);
backfillAggregatedAtoms(&reports);
ASSERT_EQ(reports.reports_size(), 1);
ConfigMetricsReport report = reports.reports(0);
ASSERT_EQ(report.metrics_size(), 1);
StatsLogReport testAtomEventMetricReport = report.metrics(0);
EXPECT_EQ(testAtomEventMetricReport.metric_id(), testAtomReportedEventMetric.id());
EXPECT_TRUE(testAtomEventMetricReport.has_event_metrics());
ASSERT_EQ(testAtomEventMetricReport.event_metrics().data_size(), 3);
EventMetricData data = testAtomEventMetricReport.event_metrics().data(0);
EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 10 * NS_PER_SEC);
TestAtomReported atom = data.atom().test_atom_reported();
EXPECT_THAT(atom.repeated_int_field(), ElementsAreArray(intArray));
EXPECT_THAT(atom.repeated_long_field(), ElementsAreArray(longArray));
EXPECT_THAT(atom.repeated_float_field(), ElementsAreArray(floatArray));
EXPECT_THAT(atom.repeated_string_field(), ElementsAreArray(stringArray));
EXPECT_THAT(atom.repeated_boolean_field(), ElementsAreArray(boolArrayVector));
EXPECT_THAT(atom.repeated_enum_field(), ElementsAreArray(enumArray));
data = testAtomEventMetricReport.event_metrics().data(1);
atom = data.atom().test_atom_reported();
EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 20 * NS_PER_SEC);
EXPECT_EQ(atom.repeated_int_field_size(), 0);
EXPECT_EQ(atom.repeated_long_field_size(), 0);
EXPECT_EQ(atom.repeated_float_field_size(), 0);
EXPECT_EQ(atom.repeated_string_field_size(), 0);
EXPECT_EQ(atom.repeated_boolean_field_size(), 0);
EXPECT_EQ(atom.repeated_enum_field_size(), 0);
data = testAtomEventMetricReport.event_metrics().data(2);
atom = data.atom().test_atom_reported();
EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 30 * NS_PER_SEC);
EXPECT_EQ(atom.repeated_int_field_size(), 0);
EXPECT_EQ(atom.repeated_long_field_size(), 0);
EXPECT_EQ(atom.repeated_float_field_size(), 0);
EXPECT_EQ(atom.repeated_string_field_size(), 0);
EXPECT_EQ(atom.repeated_boolean_field_size(), 0);
EXPECT_THAT(atom.repeated_enum_field(), ElementsAreArray(enumArray));
}
TEST_F(EventMetricE2eTest, TestMatchRepeatedFieldPositionFirst) {
StatsdConfig config;
config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
AtomMatcher testAtomReportedStateFirstOnAtomMatcher =
CreateTestAtomRepeatedStateFirstOnAtomMatcher();
*config.add_atom_matcher() = testAtomReportedStateFirstOnAtomMatcher;
EventMetric testAtomReportedEventMetric = createEventMetric(
"EventTestAtomReported", testAtomReportedStateFirstOnAtomMatcher.id(), nullopt);
*config.add_event_metric() = testAtomReportedEventMetric;
ConfigKey key(123, 987);
uint64_t bucketStartTimeNs = 10000000000; // 0:10
sp<StatsLogProcessor> processor =
CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
// Initialize log events before update.
std::vector<std::unique_ptr<LogEvent>> events;
vector<int> enumArrayNoMatch = {TestAtomReported::OFF, TestAtomReported::ON};
vector<int> enumArrayMatch = {TestAtomReported::ON, TestAtomReported::OFF};
events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
bucketStartTimeNs + 10 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayNoMatch));
events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
bucketStartTimeNs + 20 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayMatch));
// No matching is done on an empty array.
events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
bucketStartTimeNs + 30 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, {}));
// Send log events to StatsLogProcessor.
for (auto& event : events) {
processor->OnLogEvent(event.get());
}
uint64_t dumpTimeNs = bucketStartTimeNs + 100 * NS_PER_SEC;
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillStringInReport(&reports);
backfillStartEndTimestamp(&reports);
backfillAggregatedAtoms(&reports);
ASSERT_EQ(reports.reports_size(), 1);
ConfigMetricsReport report = reports.reports(0);
ASSERT_EQ(report.metrics_size(), 1);
StatsLogReport testAtomEventMetricReport = report.metrics(0);
EXPECT_EQ(testAtomEventMetricReport.metric_id(), testAtomReportedEventMetric.id());
EXPECT_TRUE(testAtomEventMetricReport.has_event_metrics());
ASSERT_EQ(testAtomEventMetricReport.event_metrics().data_size(), 1);
EventMetricData data = testAtomEventMetricReport.event_metrics().data(0);
EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 20 * NS_PER_SEC);
TestAtomReported atom = data.atom().test_atom_reported();
ASSERT_EQ(atom.repeated_int_field_size(), 0);
ASSERT_EQ(atom.repeated_long_field_size(), 0);
ASSERT_EQ(atom.repeated_float_field_size(), 0);
ASSERT_EQ(atom.repeated_string_field_size(), 0);
ASSERT_EQ(atom.repeated_boolean_field_size(), 0);
EXPECT_THAT(atom.repeated_enum_field(), ElementsAreArray(enumArrayMatch));
}
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
} // namespace statsd
} // namespace os
} // namespace android