Files
frameworks_base/cmds/statsd/tests/external/puller_util_test.cpp
Chenjie Yu ec67661bdf Refactor cpu stats pullers
use same cpu stats readers with BatteryStats so that
1) both throttle to avoid too frequent pulls
2) cached value is served within throttle interval to avoid double
pulling by both statsd and BatteryStats

To run unit tests:
bit
FrameworksCoreTests:com.android.internal.os.KernelUidCpuFreqTimeReaderTest
bit
FrameworksCoreTests:com.android.internal.os.KernelUidCpuClusterTimeReaderTest
bit
FrameworksCoreTests:com.android.internal.os.KernelUidCpuActiveTimeReaderTest

make -j56 statsd_test && adb sync data && adb shell
/data/nativetest64/statsd_test/statsd_test

Test: cts test, unit test
Bug: 73745189
Bug: 73780619
Bug: 73360959

Merged-In: I10a9bc91ca67fa812f4cd71c4fbd73c1a5ba580e

Change-Id: I10a9bc91ca67fa812f4cd71c4fbd73c1a5ba580e
2018-03-07 21:43:00 +00:00

270 lines
8.1 KiB
C++

// Copyright (C) 2018 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 "external/puller_util.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <stdio.h>
#include <vector>
#include "../metrics/metrics_test_helper.h"
#ifdef __ANDROID__
namespace android {
namespace os {
namespace statsd {
using namespace testing;
using std::make_shared;
using std::shared_ptr;
using std::vector;
using testing::Contains;
/*
* Test merge isolated and host uid
*/
int uidAtomTagId = android::util::CPU_CLUSTER_TIME;
int nonUidAtomTagId = android::util::SYSTEM_UPTIME;
int timestamp = 1234;
int isolatedUid = 30;
int isolatedAdditiveData = 31;
int isolatedNonAdditiveData = 32;
int hostUid = 20;
int hostAdditiveData = 21;
int hostNonAdditiveData = 22;
void extractIntoVector(vector<shared_ptr<LogEvent>> events,
vector<vector<int>>& ret) {
ret.clear();
status_t err;
for (const auto& event : events) {
vector<int> vec;
vec.push_back(event->GetInt(1, &err));
vec.push_back(event->GetInt(2, &err));
vec.push_back(event->GetInt(3, &err));
ret.push_back(vec);
}
}
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>());
mergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
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>());
mergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
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>());
mergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
// 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>());
mergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
// 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));
mergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
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>();
mergeIsolatedUidsToHostUid(inputData, uidMap, nonUidAtomTagId);
EXPECT_EQ(2, (int)inputData.size());
}
} // namespace statsd
} // namespace os
} // namespace android
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif