power/stats: Add VTS test cases for power.stats HAL
Adding VTS test cases for power.stats HAL functions
getPowerEntityInfo, getPowerEntityStateInfo, and getPowerEntityStateResidencyData
Bug: 118365266
Test: run vts -m VtsHalPowerStatsV1_0Target
Change-Id: Ib60ac0b37bd30663c5e7434546cdcfbf64915538
(cherry picked from commit a630f84814
)
Merged-In: Ib60ac0b37bd30663c5e7434546cdcfbf64915538
This commit is contained in:
parent
810ba8df2b
commit
0a624b957a
3 changed files with 297 additions and 26 deletions
|
@ -105,9 +105,9 @@ interface IPowerStats {
|
|||
* consumption.
|
||||
*
|
||||
* @return powerEntityInfos List of information on each PowerEntity
|
||||
* @return status SUCCESS on success or NOT_SUPPORTED if
|
||||
* feature is not enabled or FILESYSTEM_ERROR on filesystem nodes
|
||||
* access error.
|
||||
* @return status SUCCESS on success, NOT_SUPPORTED if feature is not
|
||||
* enabled, FILESYSTEM_ERROR if there was an error accessing the
|
||||
* filesystem.
|
||||
*/
|
||||
getPowerEntityInfo()
|
||||
generates(vec<PowerEntityInfo> powerEntityInfos, Status status);
|
||||
|
@ -123,12 +123,11 @@ interface IPowerStats {
|
|||
* information for all PowerEntity(s) pass an empty vector.
|
||||
*
|
||||
* @return powerEntityStateSpaces PowerEntity state space information for
|
||||
* each specified PowerEntity.
|
||||
* @return status SUCCESS if powerEntityStateInfos contains state space
|
||||
* information for at least one PowerEntity, NOT_SUPPORTED if feature
|
||||
* is not enabled, INVALID_INPUT if no requested PowerEntity(s)
|
||||
* provide state space information, FILESYSTEM_ERROR if no state space
|
||||
* information is returned due to filesystem errors.
|
||||
* each specified PowerEntity that provides state space information.
|
||||
* @return status SUCCESS on success, NOT_SUPPORTED if feature is not
|
||||
* enabled, FILESYSTEM_ERROR if there was an error accessing the
|
||||
* filesystem, INVALID_INPUT if any requested PowerEntity(s) do not
|
||||
* provide state space information and there was not a filesystem error.
|
||||
*/
|
||||
getPowerEntityStateInfo(vec<uint32_t> powerEntityIds)
|
||||
generates(vec<PowerEntityStateSpace> powerEntityStateSpaces,
|
||||
|
@ -148,13 +147,12 @@ interface IPowerStats {
|
|||
* residency data is requested. PowerEntity name to ID mapping may
|
||||
* be queried from getPowerEntityInfo(). To get state residency
|
||||
* data for all PowerEntity(s) pass an empty vector.
|
||||
* @return stateResidencyResults state residency data for the
|
||||
* specified powerEntity(s)
|
||||
* @return status SUCCESS if stateResidencyResults contains residency
|
||||
* data for at least one PowerEntity, NOT_SUPPORTED if
|
||||
* feature is not enabled, INVALID_INPUT if no requested
|
||||
* PowerEntity(s) provide state residency data, FILESYSTEM_ERROR
|
||||
* if no data is returned due to filesystem errors.
|
||||
* @return stateResidencyResults state residency data for each specified
|
||||
* PowerEntity that provides state residency data.
|
||||
* @return status SUCCESS on success, NOT_SUPPORTED if feature is not
|
||||
* enabled, FILESYSTEM_ERROR if there was an error accessing the
|
||||
* filesystem, INVALID_INPUT if any requested PowerEntity(s) do not
|
||||
* provide state residency data and there was not a filesystem error.
|
||||
*/
|
||||
getPowerEntityStateResidencyData(vec<uint32_t> powerEntityIds)
|
||||
generates(vec<PowerEntityStateResidencyResult> stateResidencyResults,
|
||||
|
|
|
@ -69,19 +69,18 @@ enum PowerEntityType : uint32_t {
|
|||
* given PowerEntity.
|
||||
*/
|
||||
struct PowerEntityInfo {
|
||||
/** ID corresponding to the PowerEntity */
|
||||
/** Unique ID corresponding to the PowerEntity */
|
||||
uint32_t powerEntityId;
|
||||
/**
|
||||
* Name of the PowerEntity. This is unique and opaque to the
|
||||
* Android framework
|
||||
*/
|
||||
/** Name of the PowerEntity */
|
||||
string powerEntityName;
|
||||
/** Type of the PowerEntity */
|
||||
PowerEntityType type;
|
||||
};
|
||||
|
||||
struct PowerEntityStateInfo {
|
||||
/** ID corresponding to the state */
|
||||
/**
|
||||
* ID corresponding to the state. Unique for a given PowerEntityStateSpace
|
||||
*/
|
||||
uint32_t powerEntityStateId;
|
||||
/** Name of the state */
|
||||
string powerEntityStateName;
|
||||
|
@ -93,7 +92,7 @@ struct PowerEntityStateInfo {
|
|||
* PowerEntity provides residency data for.
|
||||
*/
|
||||
struct PowerEntityStateSpace {
|
||||
/** ID of the corresponding PowerEntity */
|
||||
/** Unique ID of the corresponding PowerEntity */
|
||||
uint32_t powerEntityId;
|
||||
|
||||
/** List of states that the PowerEntity may reside in */
|
||||
|
@ -102,7 +101,7 @@ struct PowerEntityStateSpace {
|
|||
|
||||
/** Contains residency data for a single state */
|
||||
struct PowerEntityStateResidencyData {
|
||||
/** ID of the corresponding PowerEntityStateInfo */
|
||||
/** Unique ID of the corresponding PowerEntityStateInfo */
|
||||
uint32_t powerEntityStateId;
|
||||
/**
|
||||
* Total time in milliseconds that the corresponding PowerEntity resided
|
||||
|
@ -122,7 +121,7 @@ struct PowerEntityStateResidencyData {
|
|||
};
|
||||
|
||||
struct PowerEntityStateResidencyResult {
|
||||
/** ID of the corresponding PowerEntity */
|
||||
/** Unique ID of the corresponding PowerEntity */
|
||||
uint32_t powerEntityId;
|
||||
/** Residency data for each state the PowerEntity's state space */
|
||||
vec<PowerEntityStateResidencyData> stateResidencyData;
|
||||
|
|
|
@ -40,6 +40,9 @@ using android::hardware::Return;
|
|||
using android::hardware::Void;
|
||||
using android::hardware::power::stats::V1_0::EnergyData;
|
||||
using android::hardware::power::stats::V1_0::IPowerStats;
|
||||
using android::hardware::power::stats::V1_0::PowerEntityInfo;
|
||||
using android::hardware::power::stats::V1_0::PowerEntityStateResidencyResult;
|
||||
using android::hardware::power::stats::V1_0::PowerEntityStateSpace;
|
||||
using android::hardware::power::stats::V1_0::RailInfo;
|
||||
using android::hardware::power::stats::V1_0::Status;
|
||||
|
||||
|
@ -68,9 +71,281 @@ class PowerStatsHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
|||
|
||||
virtual void TearDown() override {}
|
||||
|
||||
void getInfos(hidl_vec<PowerEntityInfo>& infos);
|
||||
void getStateSpaces(hidl_vec<PowerEntityStateSpace>& stateSpaces,
|
||||
const std::vector<uint32_t>& ids);
|
||||
void getResidencyResults(hidl_vec<PowerEntityStateResidencyResult>& results,
|
||||
const std::vector<uint32_t>& ids);
|
||||
void getRandomIds(std::vector<uint32_t>& ids);
|
||||
|
||||
sp<IPowerStats> service_;
|
||||
};
|
||||
|
||||
void PowerStatsHidlTest::getInfos(hidl_vec<PowerEntityInfo>& infos) {
|
||||
Status status;
|
||||
Return<void> ret = service_->getPowerEntityInfo([&status, &infos](auto rInfos, auto rStatus) {
|
||||
status = rStatus;
|
||||
infos = rInfos;
|
||||
});
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
|
||||
if (status == Status::SUCCESS) {
|
||||
ASSERT_NE(infos.size(), 0) << "powerEntityInfos must have entries if supported";
|
||||
} else {
|
||||
ASSERT_EQ(status, Status::NOT_SUPPORTED);
|
||||
ASSERT_EQ(infos.size(), 0);
|
||||
LOG(INFO) << "getPowerEntityInfo not supported";
|
||||
}
|
||||
}
|
||||
|
||||
void PowerStatsHidlTest::getStateSpaces(hidl_vec<PowerEntityStateSpace>& stateSpaces,
|
||||
const std::vector<uint32_t>& ids = {}) {
|
||||
Status status;
|
||||
Return<void> ret = service_->getPowerEntityStateInfo(
|
||||
ids, [&status, &stateSpaces](auto rStateSpaces, auto rStatus) {
|
||||
status = rStatus;
|
||||
stateSpaces = rStateSpaces;
|
||||
});
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
|
||||
if (status == Status::SUCCESS) {
|
||||
ASSERT_NE(stateSpaces.size(), 0) << "powerEntityStateSpaces must have entries if supported";
|
||||
} else {
|
||||
ASSERT_EQ(status, Status::NOT_SUPPORTED);
|
||||
ASSERT_EQ(stateSpaces.size(), 0);
|
||||
LOG(INFO) << "getPowerEntityStateInfo not supported";
|
||||
}
|
||||
}
|
||||
|
||||
void PowerStatsHidlTest::getResidencyResults(hidl_vec<PowerEntityStateResidencyResult>& results,
|
||||
const std::vector<uint32_t>& ids = {}) {
|
||||
Status status;
|
||||
Return<void> ret = service_->getPowerEntityStateResidencyData(
|
||||
ids, [&status, &results](auto rResults, auto rStatus) {
|
||||
status = rStatus;
|
||||
results = rResults;
|
||||
});
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
|
||||
if (status == Status::SUCCESS) {
|
||||
ASSERT_NE(results.size(), 0);
|
||||
} else {
|
||||
ASSERT_EQ(status, Status::NOT_SUPPORTED);
|
||||
ASSERT_EQ(results.size(), 0);
|
||||
LOG(INFO) << "getPowerEntityStateResidencyData not supported";
|
||||
}
|
||||
}
|
||||
|
||||
void PowerStatsHidlTest::getRandomIds(std::vector<uint32_t>& ids) {
|
||||
hidl_vec<PowerEntityStateSpace> stateSpaces;
|
||||
getStateSpaces(stateSpaces);
|
||||
|
||||
if (stateSpaces.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto stateSpace : stateSpaces) {
|
||||
ids.push_back(stateSpace.powerEntityId);
|
||||
}
|
||||
|
||||
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
|
||||
auto gen = std::default_random_engine(seed);
|
||||
std::uniform_int_distribution<uint32_t> dist(1, stateSpaces.size());
|
||||
|
||||
std::shuffle(ids.begin(), ids.end(), gen);
|
||||
ids.resize(dist(gen));
|
||||
}
|
||||
|
||||
// Each PowerEntity must have a valid name
|
||||
TEST_F(PowerStatsHidlTest, ValidatePowerEntityNames) {
|
||||
hidl_vec<PowerEntityInfo> infos;
|
||||
getInfos(infos);
|
||||
for (auto info : infos) {
|
||||
ASSERT_NE(info.powerEntityName, "");
|
||||
}
|
||||
}
|
||||
|
||||
// Each PowerEntity must have a unique ID
|
||||
TEST_F(PowerStatsHidlTest, ValidatePowerEntityIds) {
|
||||
hidl_vec<PowerEntityInfo> infos;
|
||||
getInfos(infos);
|
||||
|
||||
set<uint32_t> ids;
|
||||
for (auto info : infos) {
|
||||
ASSERT_TRUE(ids.insert(info.powerEntityId).second);
|
||||
}
|
||||
}
|
||||
|
||||
// Each PowerEntityStateSpace must have an associated PowerEntityInfo
|
||||
TEST_F(PowerStatsHidlTest, ValidateStateInfoAssociation) {
|
||||
hidl_vec<PowerEntityInfo> infos;
|
||||
getInfos(infos);
|
||||
|
||||
hidl_vec<PowerEntityStateSpace> stateSpaces;
|
||||
getStateSpaces(stateSpaces);
|
||||
|
||||
std::set<uint32_t> ids;
|
||||
for (auto info : infos) {
|
||||
ids.insert(info.powerEntityId);
|
||||
}
|
||||
|
||||
for (auto stateSpace : stateSpaces) {
|
||||
ASSERT_NE(ids.count(stateSpace.powerEntityId), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Each state must have a valid name
|
||||
TEST_F(PowerStatsHidlTest, ValidateStateNames) {
|
||||
hidl_vec<PowerEntityStateSpace> stateSpaces;
|
||||
getStateSpaces(stateSpaces);
|
||||
|
||||
for (auto stateSpace : stateSpaces) {
|
||||
for (auto state : stateSpace.states) {
|
||||
ASSERT_NE(state.powerEntityStateName, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Each state must have an ID that is unique to the PowerEntityStateSpace
|
||||
TEST_F(PowerStatsHidlTest, ValidateStateUniqueIds) {
|
||||
hidl_vec<PowerEntityStateSpace> stateSpaces;
|
||||
getStateSpaces(stateSpaces);
|
||||
|
||||
for (auto stateSpace : stateSpaces) {
|
||||
set<uint32_t> stateIds;
|
||||
for (auto state : stateSpace.states) {
|
||||
ASSERT_TRUE(stateIds.insert(state.powerEntityStateId).second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getPowerEntityStateInfo must support passing in requested IDs
|
||||
// Results must contain state space information for all requested IDs
|
||||
TEST_F(PowerStatsHidlTest, ValidateStateInfoAssociationSelect) {
|
||||
std::vector<uint32_t> randomIds;
|
||||
getRandomIds(randomIds);
|
||||
|
||||
if (randomIds.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
hidl_vec<PowerEntityStateSpace> stateSpaces;
|
||||
getStateSpaces(stateSpaces, randomIds);
|
||||
|
||||
ASSERT_EQ(stateSpaces.size(), randomIds.size());
|
||||
|
||||
std::set<uint32_t> ids;
|
||||
for (auto id : randomIds) {
|
||||
ids.insert(id);
|
||||
}
|
||||
for (auto stateSpace : stateSpaces) {
|
||||
ASSERT_NE(ids.count(stateSpace.powerEntityId), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Requested state space info must match initially obtained stateinfos
|
||||
TEST_F(PowerStatsHidlTest, ValidateStateInfoSelect) {
|
||||
hidl_vec<PowerEntityStateSpace> stateSpaces;
|
||||
getStateSpaces(stateSpaces);
|
||||
if (stateSpaces.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> randomIds;
|
||||
getRandomIds(randomIds);
|
||||
ASSERT_FALSE(randomIds.empty());
|
||||
|
||||
hidl_vec<PowerEntityStateSpace> selectedStateSpaces;
|
||||
getStateSpaces(selectedStateSpaces, randomIds);
|
||||
|
||||
std::map<uint32_t, PowerEntityStateSpace> stateSpaceMap;
|
||||
for (auto stateSpace : stateSpaces) {
|
||||
stateSpaceMap[stateSpace.powerEntityId] = stateSpace;
|
||||
}
|
||||
|
||||
for (auto stateSpace : selectedStateSpaces) {
|
||||
auto it = stateSpaceMap.find(stateSpace.powerEntityId);
|
||||
ASSERT_NE(it, stateSpaceMap.end());
|
||||
|
||||
ASSERT_EQ(stateSpace.states.size(), it->second.states.size());
|
||||
for (auto i = 0; i < stateSpace.states.size(); i++) {
|
||||
ASSERT_EQ(stateSpace.states[i].powerEntityStateId,
|
||||
it->second.states[i].powerEntityStateId);
|
||||
ASSERT_EQ(stateSpace.states[i].powerEntityStateName,
|
||||
it->second.states[i].powerEntityStateName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stateResidencyResults must contain results for every PowerEntityStateSpace
|
||||
// returned by getPowerEntityStateInfo
|
||||
TEST_F(PowerStatsHidlTest, ValidateResidencyResultsAssociation) {
|
||||
hidl_vec<PowerEntityStateSpace> stateSpaces;
|
||||
getStateSpaces(stateSpaces);
|
||||
|
||||
hidl_vec<PowerEntityStateResidencyResult> results;
|
||||
getResidencyResults(results);
|
||||
|
||||
std::map<uint32_t, PowerEntityStateResidencyResult> resultsMap;
|
||||
for (auto result : results) {
|
||||
resultsMap[result.powerEntityId] = result;
|
||||
}
|
||||
|
||||
for (auto stateSpace : stateSpaces) {
|
||||
auto it = resultsMap.find(stateSpace.powerEntityId);
|
||||
ASSERT_NE(it, resultsMap.end());
|
||||
|
||||
ASSERT_EQ(stateSpace.states.size(), it->second.stateResidencyData.size());
|
||||
|
||||
std::set<uint32_t> stateIds;
|
||||
for (auto residency : it->second.stateResidencyData) {
|
||||
stateIds.insert(residency.powerEntityStateId);
|
||||
}
|
||||
|
||||
for (auto state : stateSpace.states) {
|
||||
ASSERT_NE(stateIds.count(state.powerEntityStateId), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getPowerEntityStateResidencyData must support passing in requested IDs
|
||||
// stateResidencyResults must contain results for each PowerEntityStateSpace
|
||||
// returned by getPowerEntityStateInfo
|
||||
TEST_F(PowerStatsHidlTest, ValidateResidencyResultsAssociationSelect) {
|
||||
std::vector<uint32_t> randomIds;
|
||||
getRandomIds(randomIds);
|
||||
if (randomIds.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
hidl_vec<PowerEntityStateSpace> stateSpaces;
|
||||
getStateSpaces(stateSpaces, randomIds);
|
||||
|
||||
hidl_vec<PowerEntityStateResidencyResult> results;
|
||||
getResidencyResults(results, randomIds);
|
||||
|
||||
std::map<uint32_t, PowerEntityStateResidencyResult> resultsMap;
|
||||
for (auto result : results) {
|
||||
resultsMap[result.powerEntityId] = result;
|
||||
}
|
||||
|
||||
for (auto stateSpace : stateSpaces) {
|
||||
auto it = resultsMap.find(stateSpace.powerEntityId);
|
||||
ASSERT_NE(it, resultsMap.end());
|
||||
|
||||
ASSERT_EQ(stateSpace.states.size(), it->second.stateResidencyData.size());
|
||||
|
||||
std::set<uint32_t> stateIds;
|
||||
for (auto residency : it->second.stateResidencyData) {
|
||||
stateIds.insert(residency.powerEntityStateId);
|
||||
}
|
||||
|
||||
for (auto state : stateSpace.states) {
|
||||
ASSERT_NE(stateIds.count(state.powerEntityStateId), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PowerStatsHidlTest, ValidateRailInfo) {
|
||||
hidl_vec<RailInfo> rails[2];
|
||||
Status s;
|
||||
|
@ -299,7 +574,6 @@ int main(int argc, char** argv) {
|
|||
LOG(INFO) << "Test result = " << status;
|
||||
return status;
|
||||
}
|
||||
|
||||
} // namespace vts
|
||||
} // namespace stats
|
||||
} // namespace power
|
||||
|
|
Loading…
Reference in a new issue