Fix failing statsd unit tests

Unit tests are failing due to migrating subsystem sleep state outside of
statsd. This registers a fake subsystem sleep state puller to mock the
pulls so they dont all fail.

Test: bit statsd_test:*
Change-Id: I9636c2bd6e853fb6f93c824868553c269f795910
This commit is contained in:
Tej Singh
2020-02-03 17:24:27 -08:00
parent e2deab502f
commit 730ed2992c
6 changed files with 93 additions and 35 deletions

View File

@@ -84,7 +84,7 @@ bool StatsPullerManager::PullLocked(int tagId, vector<shared_ptr<LogEvent>>* dat
}
return ret;
} else {
VLOG("Unknown tagId %d", tagId);
ALOGW("StatsPullerManager: Unknown tagId %d", tagId);
return false; // Return early since we don't know what to pull.
}
}

View File

@@ -14,12 +14,12 @@
#include <gtest/gtest.h>
#include <vector>
#include "src/StatsLogProcessor.h"
#include "src/stats_log_util.h"
#include "tests/statsd_test_util.h"
#include <vector>
namespace android {
namespace os {
namespace statsd {
@@ -29,12 +29,13 @@ namespace statsd {
namespace {
const int64_t metricId = 123456;
const int32_t ATOM_TAG = android::util::SUBSYSTEM_SLEEP_STATE;
StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type,
bool useCondition = true) {
StatsdConfig config;
config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
auto atomMatcher = CreateSimpleAtomMatcher("TestMatcher", android::util::SUBSYSTEM_SLEEP_STATE);
auto atomMatcher = CreateSimpleAtomMatcher("TestMatcher", ATOM_TAG);
*config.add_atom_matcher() = atomMatcher;
*config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
*config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
@@ -51,7 +52,7 @@ StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type,
gaugeMetric->set_sampling_type(sampling_type);
gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
*gaugeMetric->mutable_dimensions_in_what() =
CreateDimensions(android::util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
CreateDimensions(ATOM_TAG, {1 /* subsystem name */});
gaugeMetric->set_bucket(FIVE_MINUTES);
gaugeMetric->set_max_pull_delay_sec(INT_MAX);
config.set_hash_strings_in_metric_report(false);
@@ -69,8 +70,8 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) {
TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
ConfigKey cfgKey;
auto processor = CreateStatsLogProcessor(
baseTimeNs, configAddedTimeNs, config, cfgKey);
auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
new FakeSubsystemSleepCallback(), ATOM_TAG);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
processor->mPullerManager->ForceClearPullerCache();
@@ -144,7 +145,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) {
EXPECT_GT((int)gaugeMetrics.data_size(), 1);
auto data = gaugeMetrics.data(0);
EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
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());
@@ -214,8 +215,8 @@ TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) {
TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
ConfigKey cfgKey;
auto processor = CreateStatsLogProcessor(
baseTimeNs, configAddedTimeNs, config, cfgKey);
auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
new FakeSubsystemSleepCallback(), ATOM_TAG);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
processor->mPullerManager->ForceClearPullerCache();
@@ -267,7 +268,7 @@ TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) {
EXPECT_GT((int)gaugeMetrics.data_size(), 1);
auto data = gaugeMetrics.data(0);
EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
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());
@@ -315,8 +316,8 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) {
TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
ConfigKey cfgKey;
auto processor = CreateStatsLogProcessor(
baseTimeNs, configAddedTimeNs, config, cfgKey);
auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
new FakeSubsystemSleepCallback, ATOM_TAG);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
processor->mPullerManager->ForceClearPullerCache();
@@ -371,7 +372,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) {
EXPECT_GT((int)gaugeMetrics.data_size(), 1);
auto data = gaugeMetrics.data(0);
EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
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());
@@ -424,8 +425,8 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation) {
event_activation->set_ttl_seconds(ttlNs / 1000000000);
ConfigKey cfgKey;
auto processor = CreateStatsLogProcessor(
baseTimeNs, configAddedTimeNs, config, cfgKey);
auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
new FakeSubsystemSleepCallback(), ATOM_TAG);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
processor->mPullerManager->ForceClearPullerCache();
@@ -493,7 +494,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation) {
EXPECT_GT((int)gaugeMetrics.data_size(), 0);
auto data = gaugeMetrics.data(0);
EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
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());
@@ -542,8 +543,8 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition) {
TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
ConfigKey cfgKey;
auto processor = CreateStatsLogProcessor(
baseTimeNs, configAddedTimeNs, config, cfgKey);
auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
new FakeSubsystemSleepCallback(), ATOM_TAG);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
processor->mPullerManager->ForceClearPullerCache();
@@ -586,7 +587,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition) {
EXPECT_GT((int)gaugeMetrics.data_size(), 0);
auto data = gaugeMetrics.data(0);
EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
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());

View File

@@ -12,22 +12,24 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <android/os/BnPullAtomCallback.h>
#include <android/os/IPullAtomResultReceiver.h>
#include <binder/IPCThreadState.h>
#include <gtest/gtest.h>
#include <binder/IPCThreadState.h>
#include <vector>
#include "src/StatsLogProcessor.h"
#include "src/StatsService.h"
#include "src/stats_log_util.h"
#include "tests/statsd_test_util.h"
#include <vector>
namespace android {
namespace os {
namespace statsd {
#ifdef __ANDROID__
namespace {
const string kApp1 = "app1.sharing.1";
const int kConfigKey = 789130123; // Randomly chosen to avoid collisions with existing configs.
const int kCallingUid = 0; // Randomly chosen
@@ -109,6 +111,7 @@ StatsdConfig MakeGaugeMetricConfig(int64_t minTime) {
gaugeMetric->set_min_bucket_size_nanos(minTime);
return config;
}
} // anonymous namespace
TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) {
StatsService service(nullptr, nullptr);
@@ -202,6 +205,9 @@ TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) {
TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) {
StatsService service(nullptr, nullptr);
service.mPullerManager->RegisterPullAtomCallback(
/*uid=*/0, android::util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
new FakeSubsystemSleepCallback());
// Partial buckets don't occur when app is first installed.
service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
SendConfig(service, MakeValueMetricConfig(0));
@@ -220,6 +226,9 @@ TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) {
TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) {
StatsService service(nullptr, nullptr);
service.mPullerManager->RegisterPullAtomCallback(
/*uid=*/0, android::util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
new FakeSubsystemSleepCallback());
// Partial buckets don't occur when app is first installed.
service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
SendConfig(service, MakeValueMetricConfig(60 * NS_PER_SEC /* One minute */));

View File

@@ -69,8 +69,9 @@ TEST(ValueMetricE2eTest, TestPulledEvents) {
TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
ConfigKey cfgKey;
auto processor = CreateStatsLogProcessor(
baseTimeNs, configAddedTimeNs, config, cfgKey);
auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
new FakeSubsystemSleepCallback(),
android::util::SUBSYSTEM_SLEEP_STATE);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
processor->mPullerManager->ForceClearPullerCache();
@@ -173,8 +174,9 @@ TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) {
TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
ConfigKey cfgKey;
auto processor = CreateStatsLogProcessor(
baseTimeNs, configAddedTimeNs, config, cfgKey);
auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
new FakeSubsystemSleepCallback(),
android::util::SUBSYSTEM_SLEEP_STATE);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
processor->mPullerManager->ForceClearPullerCache();
@@ -285,8 +287,9 @@ TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation) {
event_activation->set_ttl_seconds(ttlNs / 1000000000);
ConfigKey cfgKey;
auto processor = CreateStatsLogProcessor(
baseTimeNs, configAddedTimeNs, config, cfgKey);
auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
new FakeSubsystemSleepCallback(),
android::util::SUBSYSTEM_SLEEP_STATE);
EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
processor->mPullerManager->ForceClearPullerCache();

View File

@@ -580,9 +580,15 @@ std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
}
sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
const StatsdConfig& config, const ConfigKey& key) {
const StatsdConfig& config, const ConfigKey& key,
const sp<IPullAtomCallback>& puller,
const int32_t atomTag) {
sp<UidMap> uidMap = new UidMap();
sp<StatsPullerManager> pullerManager = new StatsPullerManager();
if (puller != nullptr) {
pullerManager->RegisterPullAtomCallback(/*uid=*/0, atomTag, NS_PER_SEC, NS_PER_SEC * 10, {},
puller);
}
sp<AlarmMonitor> anomalyAlarmMonitor =
new AlarmMonitor(1, [](const sp<IStatsCompanionService>&, int64_t){},
[](const sp<IStatsCompanionService>&){});
@@ -942,6 +948,34 @@ void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) {
}
}
binder::Status FakeSubsystemSleepCallback::onPullAtom(
int atomTag, const sp<IPullAtomResultReceiver>& resultReceiver) {
// Convert stats_events into StatsEventParcels.
std::vector<android::util::StatsEventParcel> parcels;
for (int i = 1; i < 3; i++) {
stats_event* event = stats_event_obtain();
stats_event_set_atom_id(event, atomTag);
std::string subsystemName = "subsystem_name_";
subsystemName = subsystemName + std::to_string(i);
stats_event_write_string8(event, subsystemName.c_str());
stats_event_write_string8(event, "subsystem_subname foo");
stats_event_write_int64(event, /*count= */ i);
stats_event_write_int64(event, /*time_millis= */ i * 100);
stats_event_build(event);
size_t size;
uint8_t* buffer = stats_event_get_buffer(event, &size);
android::util::StatsEventParcel p;
// vector.assign() creates a copy, but this is inevitable unless
// stats_event.h/c uses a vector as opposed to a buffer.
p.buffer.assign(buffer, buffer + size);
parcels.push_back(std::move(p));
stats_event_release(event);
}
resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
return binder::Status::ok();
}
} // namespace statsd
} // namespace os
} // namespace android

View File

@@ -14,12 +14,16 @@
#pragma once
#include <android/os/BnPullAtomCallback.h>
#include <android/os/IPullAtomCallback.h>
#include <android/os/IPullAtomResultReceiver.h>
#include <gtest/gtest.h>
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "src/StatsLogProcessor.h"
#include "src/logd/LogEvent.h"
#include "src/hash.h"
#include "src/logd/LogEvent.h"
#include "src/stats_log_util.h"
#include "statslog.h"
@@ -224,9 +228,10 @@ std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
AttributionNodeInternal CreateAttribution(const int& uid, const string& tag);
// Create a statsd log event processor upon the start time in seconds, config and key.
sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs,
const int64_t currentTimeNs,
const StatsdConfig& config, const ConfigKey& key);
sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
const StatsdConfig& config, const ConfigKey& key,
const sp<IPullAtomCallback>& puller = nullptr,
const int32_t atomTag = 0 /*for puller only*/);
// Util function to sort the log events by timestamp.
void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events);
@@ -278,6 +283,12 @@ bool backfillDimensionPath(const DimensionsValue& path,
const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
DimensionsValue* dimension);
class FakeSubsystemSleepCallback : public BnPullAtomCallback {
public:
binder::Status onPullAtom(int atomTag,
const sp<IPullAtomResultReceiver>& resultReceiver) override;
};
template <typename T>
void backfillDimensionPath(const DimensionsValue& whatPath,
const DimensionsValue& conditionPath,