summaryrefslogtreecommitdiff
path: root/transport/base
diff options
context:
space:
mode:
authorDaniel Norman <danielnorman@google.com>2019-08-06 14:56:08 -0700
committerDaniel Norman <danielnorman@google.com>2019-08-07 14:08:10 -0700
commita94480aee3d843c6d612ad474618d42534988380 (patch)
tree9d807854b2c08a05409f05ec3805280ec5e9b95c /transport/base
parentbf4ed32bb1f50531fe11f48b880664d4917a45b6 (diff)
downloadlibhidl-a94480aee3d843c6d612ad474618d42534988380.tar.gz
Starts up lazy services before checking running interfaces.
Bug: 138114550 Test: /data/nativetest64/vts_ibase_test/vts_ibase_test Change-Id: I0899b2c982ce2111ed2bbcf9d72ac6832ff76199
Diffstat (limited to 'transport/base')
-rw-r--r--transport/base/1.0/vts/functional/vts_ibase_test.cpp120
1 files changed, 79 insertions, 41 deletions
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 a0b4e71..b77b2ad 100644
--- a/transport/base/1.0/vts/functional/vts_ibase_test.cpp
+++ b/transport/base/1.0/vts/functional/vts_ibase_test.cpp
@@ -18,7 +18,10 @@
#include <algorithm>
#include <functional>
#include <map>
+#include <mutex>
#include <string>
+#include <thread>
+#include <vector>
#include <android-base/logging.h>
#include <android-base/properties.h>
@@ -59,9 +62,11 @@ static inline ::testing::AssertionResult isOk(const ::android::hardware::Return<
struct Hal {
sp<IBase> service;
std::string name; // space separated list of android.hidl.foo@1.0::IFoo/instance-name
+ FqInstance fq_instance;
};
-std::string FqInstancesToString(const std::set<FqInstance>& instances) {
+template <typename T>
+std::string FqInstancesToString(const T& instances) {
std::set<std::string> instance_strings;
for (const FqInstance& instance : instances) {
instance_strings.insert(instance.string());
@@ -73,11 +78,22 @@ 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;
+std::map<std::string, std::vector<Hal>> gDeclaredServiceHalMap;
+std::mutex gDeclaredServiceHalMapMutex;
+
+void GetHal(const std::string& service, const FqInstance& instance) {
+ if (instance.getFqName() == android::gIBaseFqName) {
+ return;
+ }
+
+ sp<IBase> hal = android::hardware::details::getRawServiceInternal(
+ instance.getFqName().string(), instance.getInstance(), true /*retry*/,
+ false /*getStub*/);
+ // Add to gDeclaredServiceHalMap if getRawServiceInternal() returns (even if
+ // the returned HAL is null). getRawServiceInternal() won't return if the
+ // HAL is in the VINTF but unable to start.
+ std::lock_guard<std::mutex> guard(gDeclaredServiceHalMapMutex);
+ gDeclaredServiceHalMap[service].push_back(Hal{.service = hal, .fq_instance = instance});
}
class VtsHalBaseV1_0TargetTest : public ::testing::Test {
@@ -117,7 +133,7 @@ class VtsHalBaseV1_0TargetTest : public ::testing::Test {
// include all the names this is registered as for error messages
iter->second.name += " " + strName;
} else {
- all_hals_.insert(iter, {binder, Hal{service, strName}});
+ all_hals_.insert(iter, {binder, Hal{.service = service, .name = strName}});
}
}
}));
@@ -219,47 +235,69 @@ TEST_F(VtsHalBaseV1_0TargetTest, ServiceProvidesAndDeclaresTheSameInterfaces) {
Result<ServiceInterfacesMap> service_interfaces_map =
android::init::GetOnDeviceServiceInterfacesMap();
ASSERT_TRUE(service_interfaces_map) << service_interfaces_map.error();
- PidInterfacesMap pid_interfaces_map = GetPidInterfacesMap();
- for (auto [service, declared_interfaces] : *service_interfaces_map) {
+ // Attempt to get handles to all known declared interfaces. This will cause
+ // any non-running lazy HALs to start up.
+ // Results are saved in gDeclaredServiceHalMap.
+ for (const auto& [service, declared_interfaces] : *service_interfaces_map) {
if (declared_interfaces.empty()) {
- LOG(INFO) << "Service '" << service << "' does not declare any interfaces."
- << std::endl;
- continue;
+ LOG(INFO) << "Service '" << service << "' does not declare any interfaces.";
}
- for (auto it = declared_interfaces.begin(); it != declared_interfaces.end();) {
- if (it->getFqName() == android::gIBaseFqName) {
- it = declared_interfaces.erase(it);
- } else {
- ++it;
- }
+ for (const auto& instance : declared_interfaces) {
+ std::thread(GetHal, service, instance).detach();
}
+ }
+ // Allow the threads 5 seconds to attempt to get each HAL. Any HAL whose
+ // thread is stuck during retrieval is excluded from this test.
+ sleep(5);
+
+ std::lock_guard<std::mutex> guard(gDeclaredServiceHalMapMutex);
+ PidInterfacesMap pid_interfaces_map = GetPidInterfacesMap();
+
+ // For each service that had at least one thread return from attempting to
+ // retrieve a HAL:
+ for (const auto& [service, hals] : gDeclaredServiceHalMap) {
+ // Assert that the service is running.
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:" << std::endl
- << FqInstancesToString(served_interfaces) << std::endl
- << " Declared: " << std::endl
- << FqInstancesToString(declared_interfaces) << std::endl
- << " Difference: " << std::endl
- << FqInstancesToString(diff);
- diff = SetDifference(declared_interfaces, served_interfaces);
- EXPECT_TRUE(diff.empty())
- << "Service '" << service << "' declares interfaces that it does not serve."
+ ASSERT_NE(pid, 0) << "Service '" << service << "' is not running.";
+
+ std::set<FqInstance> declared_interfaces;
+ for (const auto& hal : hals) {
+ declared_interfaces.insert(hal.fq_instance);
+ }
+
+ // Warn for any threads that were stuck when attempting to retrieve a
+ // HAL.
+ std::vector<FqInstance> missing_declared_interfaces;
+ std::set_difference((*service_interfaces_map)[service].begin(),
+ (*service_interfaces_map)[service].end(), declared_interfaces.begin(),
+ declared_interfaces.end(),
+ std::back_inserter(missing_declared_interfaces));
+ if (!missing_declared_interfaces.empty()) {
+ LOG(WARNING)
+ << "Service '" << service
+ << "' declares interfaces that are present in the VINTF but unable to start:"
<< std::endl
- << " Declared: " << std::endl
- << FqInstancesToString(declared_interfaces) << std::endl
- << " Served:" << std::endl
- << FqInstancesToString(served_interfaces) << std::endl
- << " Difference: " << std::endl
- << FqInstancesToString(diff);
+ << FqInstancesToString(missing_declared_interfaces);
}
+
+ // Expect that the set of interfaces running at this PID is the same as
+ // the set of interfaces declared by this service.
+ std::set<FqInstance> served_interfaces = pid_interfaces_map[pid];
+ std::vector<FqInstance> served_declared_diff;
+ std::set_symmetric_difference(declared_interfaces.begin(), declared_interfaces.end(),
+ served_interfaces.begin(), served_interfaces.end(),
+ std::back_inserter(served_declared_diff));
+
+ EXPECT_TRUE(served_declared_diff.empty())
+ << "Service '" << service << "' serves and declares different interfaces."
+ << std::endl
+ << " Served:" << std::endl
+ << FqInstancesToString(served_interfaces) << std::endl
+ << " Declared: " << std::endl
+ << FqInstancesToString(declared_interfaces) << std::endl
+ << " Difference: " << std::endl
+ << FqInstancesToString(served_declared_diff);
}
}