diff options
author | Daniel Norman <danielnorman@google.com> | 2019-07-22 17:32:30 -0700 |
---|---|---|
committer | Daniel Norman <danielnorman@google.com> | 2019-08-01 11:10:41 -0700 |
commit | 5ea7f14be528d0cad546ce04afb7bd9de767f805 (patch) | |
tree | 6c2212e85e3c80cd495035e16dd29bc479f5ef5c /transport/base | |
parent | 0d2a0dab0ed58d03368606f0d78aa0361d97e29a (diff) | |
download | libhidl-5ea7f14be528d0cad546ce04afb7bd9de767f805.tar.gz |
Adds a test to check that services declare the interfaces they serve.
Bug: 138114550
Test: m vts_ibase_test, adb shell /data/nativetest64/vts_ibase_test/vts_ibase_test
Change-Id: Ic902a85839a4e13dd1c811b1df07c3c4a2b5c4f5
Diffstat (limited to 'transport/base')
-rw-r--r-- | transport/base/1.0/vts/functional/Android.bp | 7 | ||||
-rw-r--r-- | transport/base/1.0/vts/functional/vts_ibase_test.cpp | 83 |
2 files changed, 85 insertions, 5 deletions
diff --git a/transport/base/1.0/vts/functional/Android.bp b/transport/base/1.0/vts/functional/Android.bp index f0bd45c..fb9af33 100644 --- a/transport/base/1.0/vts/functional/Android.bp +++ b/transport/base/1.0/vts/functional/Android.bp @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. - cc_test { name: "vts_ibase_test", srcs: [ @@ -29,6 +28,10 @@ cc_test { "libhwbinder", "liblog", "libutils", + "libprotobuf-cpp-lite", + "libhidl-gen-utils", + ], + static_libs: [ + "libinit_test_utils", ], } - diff --git a/transport/base/1.0/vts/functional/vts_ibase_test.cpp b/transport/base/1.0/vts/functional/vts_ibase_test.cpp index 6d66042..38acf8a 100644 --- a/transport/base/1.0/vts/functional/vts_ibase_test.cpp +++ b/transport/base/1.0/vts/functional/vts_ibase_test.cpp @@ -13,17 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include <algorithm> #include <functional> #include <map> #include <string> +#include <android-base/properties.h> +#include <android-base/strings.h> #include <android/hidl/base/1.0/IBase.h> #include <android/hidl/manager/1.0/IServiceManager.h> #include <gtest/gtest.h> +#include <hidl-util/FqInstance.h> #include <hidl/HidlBinderSupport.h> #include <hidl/ServiceManagement.h> +#include <init-test-utils/service_utils.h> +using android::FqInstance; +using android::FQName; +using android::sp; +using android::wp; +using android::base::Result; using android::hardware::hidl_array; using android::hardware::hidl_death_recipient; using android::hardware::hidl_handle; @@ -33,8 +42,8 @@ using android::hardware::IBinder; using android::hardware::toBinder; using android::hidl::base::V1_0::IBase; using android::hidl::manager::V1_0::IServiceManager; -using android::sp; -using android::wp; +using android::init::ServiceInterfacesMap; +using PidInterfacesMap = std::map<pid_t, std::set<FqInstance>>; template <typename T> static inline ::testing::AssertionResult isOk(const ::android::hardware::Return<T>& ret) { @@ -49,6 +58,25 @@ struct Hal { std::string name; // space separated list of android.hidl.foo@1.0::IFoo/instance-name }; +std::string FqInstancesToString(const std::set<FqInstance>& instances) { + std::set<std::string> instance_strings; + for (const FqInstance& instance : instances) { + instance_strings.insert(instance.string()); + } + return android::base::Join(instance_strings, " "); +} + +pid_t GetServiceDebugPid(const std::string& service) { + return android::base::GetIntProperty("init.svc_debug_pid." + service, 0); +} + +template <typename T> +std::set<T> SetDifference(const std::set<T>& a, const std::set<T>& b) { + std::set<T> diff; + std::set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(diff, diff.begin())); + return diff; +} + class VtsHalBaseV1_0TargetTest : public ::testing::Test { public: virtual void SetUp() override { @@ -100,6 +128,25 @@ class VtsHalBaseV1_0TargetTest : public ::testing::Test { } } + PidInterfacesMap GetPidInterfacesMap() { + PidInterfacesMap result; + EXPECT_OK(default_manager_->debugDump([&result](const auto& list) { + for (const auto& debug_info : list) { + if (debug_info.pid != static_cast<int32_t>(IServiceManager::PidConstant::NO_PID)) { + FQName fqName; + ASSERT_TRUE(fqName.setTo(debug_info.interfaceName.c_str())) + << "Unable to parse interface: '" << debug_info.interfaceName.c_str(); + FqInstance fqInstance; + ASSERT_TRUE(fqInstance.setTo(fqName, debug_info.instanceName.c_str())); + if (fqInstance.getFqName() != android::gIBaseFqName) { + result[debug_info.pid].insert(fqInstance); + } + } + } + })); + return result; + } + // default service manager sp<IServiceManager> default_manager_; @@ -165,6 +212,36 @@ TEST_F(VtsHalBaseV1_0TargetTest, HashChain) { }); } +// TODO(b/138114550): Also test that services serve all declared interfaces. +TEST_F(VtsHalBaseV1_0TargetTest, ServiceDeclaresAllServedInterfaces) { + Result<ServiceInterfacesMap> service_interfaces_map = + android::init::GetOnDeviceServiceInterfacesMap(); + ASSERT_TRUE(service_interfaces_map) << service_interfaces_map.error(); + PidInterfacesMap pid_interfaces_map = GetPidInterfacesMap(); + + for (const auto& [service, declared_interfaces] : *service_interfaces_map) { + if (declared_interfaces.empty()) { + std::cout << "[WARNING] Service '" << service << "' does not declare any interfaces" + << std::endl; + continue; + } + pid_t pid = GetServiceDebugPid(service); + // TODO(b/138114550): Check lazy services that are not currently running + // (when pid == 0). + if (pid != 0) { + std::set<FqInstance> served_interfaces = pid_interfaces_map[pid]; + std::set<FqInstance> diff = SetDifference(served_interfaces, declared_interfaces); + EXPECT_TRUE(diff.empty()) + << "Service '" << service << "' serves interfaces that it does not declare." + << std::endl + << " Served: '" << FqInstancesToString(served_interfaces) << "'" << std::endl + << " Declared: '" << FqInstancesToString(declared_interfaces) << "'" + << std::endl + << " Difference: '" << FqInstancesToString(diff) << "'"; + } + } +} + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); |