diff options
author | Daniel Norman <danielnorman@google.com> | 2021-02-08 11:11:06 -0800 |
---|---|---|
committer | Daniel Norman <danielnorman@google.com> | 2021-02-08 14:07:55 -0800 |
commit | f86b976dba9b016816efa57156e791fffd498d64 (patch) | |
tree | 62e68f2885e6a7a73bf3386e8459f8fe98528ade /power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp | |
parent | a0da4d07b75fa61fcb4f5648ba304cbf4ac50f6a (diff) | |
parent | 7fd5ae363319c3d8fa9128c39075ea82799989ab (diff) |
Merge SP1A.210208.001
Change-Id: I0c596171de3bcead62935db7388b784e55444080
Diffstat (limited to 'power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp')
-rw-r--r-- | power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp | 360 |
1 files changed, 322 insertions, 38 deletions
diff --git a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp index 1d3082191a..bed3fdf352 100644 --- a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp +++ b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp @@ -21,10 +21,21 @@ #include <android/binder_manager.h> #include <android/binder_process.h> -using aidl::android::hardware::power::stats::ChannelInfo; +#include <algorithm> +#include <iterator> +#include <random> +#include <unordered_map> + +using aidl::android::hardware::power::stats::Channel; +using aidl::android::hardware::power::stats::EnergyConsumer; +using aidl::android::hardware::power::stats::EnergyConsumerAttribution; +using aidl::android::hardware::power::stats::EnergyConsumerResult; +using aidl::android::hardware::power::stats::EnergyConsumerType; using aidl::android::hardware::power::stats::EnergyMeasurement; using aidl::android::hardware::power::stats::IPowerStats; -using aidl::android::hardware::power::stats::PowerEntityInfo; +using aidl::android::hardware::power::stats::PowerEntity; +using aidl::android::hardware::power::stats::State; +using aidl::android::hardware::power::stats::StateResidency; using aidl::android::hardware::power::stats::StateResidencyResult; using ndk::SpAIBinder; @@ -37,94 +48,367 @@ class PowerStatsAidl : public testing::TestWithParam<std::string> { ASSERT_NE(nullptr, powerstats.get()); } + template <typename T> + std::vector<T> getRandomSubset(std::vector<T> const& collection); + + void testNameValid(const std::string& name); + + template <typename T, typename S> + void testUnique(std::vector<T> const& collection, S T::*field); + + template <typename T, typename S, typename R> + void testMatching(std::vector<T> const& c1, R T::*f1, std::vector<S> const& c2, R S::*f2); + std::shared_ptr<IPowerStats> powerstats; }; -TEST_P(PowerStatsAidl, TestReadEnergyMeter) { - std::vector<EnergyMeasurement> data; - ASSERT_TRUE(powerstats->readEnergyMeters({}, &data).isOk()); +// Returns a random subset from a collection +template <typename T> +std::vector<T> PowerStatsAidl::getRandomSubset(std::vector<T> const& collection) { + if (collection.empty()) { + return {}; + } + + std::vector<T> selected; + std::sample(collection.begin(), collection.end(), std::back_inserter(selected), + rand() % collection.size() + 1, std::mt19937{std::random_device{}()}); + + return selected; +} + +// Tests whether a name is valid +void PowerStatsAidl::testNameValid(const std::string& name) { + EXPECT_NE(name, ""); +} + +// Tests whether the fields in a given collection are unique +template <typename T, typename S> +void PowerStatsAidl::testUnique(std::vector<T> const& collection, S T::*field) { + std::set<S> cSet; + for (auto const& elem : collection) { + EXPECT_TRUE(cSet.insert(elem.*field).second); + } +} + +template <typename T, typename S, typename R> +void PowerStatsAidl::testMatching(std::vector<T> const& c1, R T::*f1, std::vector<S> const& c2, + R S::*f2) { + std::set<R> c1fields, c2fields; + for (auto elem : c1) { + c1fields.insert(elem.*f1); + } + + for (auto elem : c2) { + c2fields.insert(elem.*f2); + } + + EXPECT_EQ(c1fields, c2fields); } // Each PowerEntity must have a valid name TEST_P(PowerStatsAidl, ValidatePowerEntityNames) { - std::vector<PowerEntityInfo> infos; + std::vector<PowerEntity> infos; ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); for (auto info : infos) { - EXPECT_NE(info.powerEntityName, ""); + testNameValid(info.name); } } // Each power entity must have a unique name TEST_P(PowerStatsAidl, ValidatePowerEntityUniqueNames) { - std::vector<PowerEntityInfo> infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - std::set<std::string> names; - for (auto info : infos) { - EXPECT_TRUE(names.insert(info.powerEntityName).second); - } + testUnique(entities, &PowerEntity::name); } // Each PowerEntity must have a unique ID TEST_P(PowerStatsAidl, ValidatePowerEntityIds) { - std::vector<PowerEntityInfo> infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - std::set<int32_t> ids; - for (auto info : infos) { - EXPECT_TRUE(ids.insert(info.powerEntityId).second); + testUnique(entities, &PowerEntity::id); +} + +// Each power entity must have at least one state +TEST_P(PowerStatsAidl, ValidateStateSize) { + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + + for (auto entity : entities) { + EXPECT_GT(entity.states.size(), 0); } } // Each state must have a valid name TEST_P(PowerStatsAidl, ValidateStateNames) { - std::vector<PowerEntityInfo> infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - for (auto info : infos) { - for (auto state : info.states) { - EXPECT_NE(state.stateName, ""); + for (auto entity : entities) { + for (auto state : entity.states) { + testNameValid(state.name); } } } // Each state must have a name that is unique to the given PowerEntity TEST_P(PowerStatsAidl, ValidateStateUniqueNames) { - std::vector<PowerEntityInfo> infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - for (auto info : infos) { - std::set<std::string> stateNames; - for (auto state : info.states) { - EXPECT_TRUE(stateNames.insert(state.stateName).second); - } + for (auto entity : entities) { + testUnique(entity.states, &State::name); } } // Each state must have an ID that is unique to the given PowerEntity TEST_P(PowerStatsAidl, ValidateStateUniqueIds) { - std::vector<PowerEntityInfo> infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - for (auto info : infos) { - std::set<int32_t> stateIds; - for (auto state : info.states) { - EXPECT_TRUE(stateIds.insert(state.stateId).second); - } + for (auto entity : entities) { + testUnique(entity.states, &State::id); } } +// State residency must return a valid status TEST_P(PowerStatsAidl, TestGetStateResidency) { std::vector<StateResidencyResult> results; ASSERT_TRUE(powerstats->getStateResidency({}, &results).isOk()); } +// State residency must return all results +TEST_P(PowerStatsAidl, TestGetStateResidencyAllResults) { + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + + std::vector<StateResidencyResult> results; + ASSERT_TRUE(powerstats->getStateResidency({}, &results).isOk()); + + testMatching(entities, &PowerEntity::id, results, &StateResidencyResult::id); +} + +// Each result must contain all state residencies +TEST_P(PowerStatsAidl, TestGetStateResidencyAllStateResidencies) { + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + + std::vector<StateResidencyResult> results; + ASSERT_TRUE(powerstats->getStateResidency({}, &results).isOk()); + + for (auto entity : entities) { + auto it = std::find_if(results.begin(), results.end(), + [&entity](const auto& x) { return x.id == entity.id; }); + ASSERT_NE(it, results.end()); + + testMatching(entity.states, &State::id, it->stateResidencyData, &StateResidency::id); + } +} + +// State residency must return results for each requested power entity +TEST_P(PowerStatsAidl, TestGetStateResidencySelectedResults) { + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + if (entities.empty()) { + return; + } + + std::vector<PowerEntity> selectedEntities = getRandomSubset(entities); + std::vector<int32_t> selectedIds; + for (auto const& entity : selectedEntities) { + selectedIds.push_back(entity.id); + } + + std::vector<StateResidencyResult> selectedResults; + ASSERT_TRUE(powerstats->getStateResidency(selectedIds, &selectedResults).isOk()); + + testMatching(selectedEntities, &PowerEntity::id, selectedResults, &StateResidencyResult::id); +} + +// Energy meter info must return a valid status TEST_P(PowerStatsAidl, TestGetEnergyMeterInfo) { - std::vector<ChannelInfo> info; + std::vector<Channel> info; ASSERT_TRUE(powerstats->getEnergyMeterInfo(&info).isOk()); } +// Each channel must have a valid name and subsystem +TEST_P(PowerStatsAidl, ValidateChannelNames) { + std::vector<Channel> channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + for (auto channel : channels) { + testNameValid(channel.name); + testNameValid(channel.subsystem); + } +} + +// Each channel must have a unique name +TEST_P(PowerStatsAidl, ValidateChannelUniqueNames) { + std::vector<Channel> channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + + testUnique(channels, &Channel::name); +} + +// Each channel must have a unique ID +TEST_P(PowerStatsAidl, ValidateChannelUniqueIds) { + std::vector<Channel> channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + + testUnique(channels, &Channel::id); +} + +// Reading energy meter must return a valid status +TEST_P(PowerStatsAidl, TestReadEnergyMeter) { + std::vector<EnergyMeasurement> data; + ASSERT_TRUE(powerstats->readEnergyMeter({}, &data).isOk()); +} + +// Reading energy meter must return results for all available channels +TEST_P(PowerStatsAidl, TestGetAllEnergyMeasurements) { + std::vector<Channel> channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + + std::vector<EnergyMeasurement> measurements; + ASSERT_TRUE(powerstats->readEnergyMeter({}, &measurements).isOk()); + + testMatching(channels, &Channel::id, measurements, &EnergyMeasurement::id); +} + +// Reading energy must must return results for each selected channel +TEST_P(PowerStatsAidl, TestGetSelectedEnergyMeasurements) { + std::vector<Channel> channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + if (channels.empty()) { + return; + } + + std::vector<Channel> selectedChannels = getRandomSubset(channels); + std::vector<int32_t> selectedIds; + for (auto const& channel : selectedChannels) { + selectedIds.push_back(channel.id); + } + + std::vector<EnergyMeasurement> selectedMeasurements; + ASSERT_TRUE(powerstats->readEnergyMeter(selectedIds, &selectedMeasurements).isOk()); + + testMatching(selectedChannels, &Channel::id, selectedMeasurements, &EnergyMeasurement::id); +} + +// Energy consumer info must return a valid status +TEST_P(PowerStatsAidl, TestGetEnergyConsumerInfo) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); +} + +// Each energy consumer must have a unique id +TEST_P(PowerStatsAidl, TestGetEnergyConsumerUniqueId) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + testUnique(consumers, &EnergyConsumer::id); +} + +// Each energy consumer must have a valid name +TEST_P(PowerStatsAidl, ValidateEnergyConsumerNames) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + for (auto consumer : consumers) { + testNameValid(consumer.name); + } +} + +// Each energy consumer must have a unique name +TEST_P(PowerStatsAidl, ValidateEnergyConsumerUniqueNames) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + testUnique(consumers, &EnergyConsumer::name); +} + +// Energy consumers of the same type must have ordinals that are 0,1,2,..., N - 1 +TEST_P(PowerStatsAidl, ValidateEnergyConsumerOrdinals) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + std::unordered_map<EnergyConsumerType, std::set<int32_t>> ordinalMap; + + // Ordinals must be unique for each type + for (auto consumer : consumers) { + EXPECT_TRUE(ordinalMap[consumer.type].insert(consumer.ordinal).second); + } + + // Min ordinal must be 0, max ordinal must be N - 1 + for (const auto& [unused, ordinals] : ordinalMap) { + EXPECT_EQ(0, *std::min_element(ordinals.begin(), ordinals.end())); + EXPECT_EQ(ordinals.size() - 1, *std::max_element(ordinals.begin(), ordinals.end())); + } +} + +// Energy consumed must return a valid status +TEST_P(PowerStatsAidl, TestGetEnergyConsumed) { + std::vector<EnergyConsumerResult> results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); +} + +// Energy consumed must return data for all energy consumers +TEST_P(PowerStatsAidl, TestGetAllEnergyConsumed) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + std::vector<EnergyConsumerResult> results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); + + testMatching(consumers, &EnergyConsumer::id, results, &EnergyConsumerResult::id); +} + +// Energy consumed must return data for each selected energy consumer +TEST_P(PowerStatsAidl, TestGetSelectedEnergyConsumed) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + if (consumers.empty()) { + return; + } + + std::vector<EnergyConsumer> selectedConsumers = getRandomSubset(consumers); + std::vector<int32_t> selectedIds; + for (auto const& consumer : selectedConsumers) { + selectedIds.push_back(consumer.id); + } + + std::vector<EnergyConsumerResult> selectedResults; + ASSERT_TRUE(powerstats->getEnergyConsumed(selectedIds, &selectedResults).isOk()); + + testMatching(selectedConsumers, &EnergyConsumer::id, selectedResults, + &EnergyConsumerResult::id); +} + +// Energy consumed attribution uids must be unique for a given energy consumer +TEST_P(PowerStatsAidl, ValidateEnergyConsumerAttributionUniqueUids) { + std::vector<EnergyConsumerResult> results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); + + for (auto result : results) { + testUnique(result.attribution, &EnergyConsumerAttribution::uid); + } +} + +// Energy consumed total energy >= sum total of uid-attributed energy +TEST_P(PowerStatsAidl, TestGetEnergyConsumedAttributedEnergy) { + std::vector<EnergyConsumerResult> results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); + + for (auto result : results) { + int64_t totalAttributedEnergyUWs = 0; + for (auto attribution : result.attribution) { + totalAttributedEnergyUWs += attribution.energyUWs; + } + EXPECT_TRUE(result.energyUWs >= totalAttributedEnergyUWs); + } +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerStatsAidl); INSTANTIATE_TEST_SUITE_P( PowerStats, PowerStatsAidl, |