Merge "Make kAshmemMemoryName constexpr"
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 38acf8a..b77b2ad 100644
--- a/transport/base/1.0/vts/functional/vts_ibase_test.cpp
+++ b/transport/base/1.0/vts/functional/vts_ibase_test.cpp
@@ -13,11 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define LOG_TAG "vts_ibase_test"
+
#include <algorithm>
#include <functional>
#include <map>
+#include <mutex>
#include <string>
+#include <thread>
+#include <vector>
+#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android/hidl/base/1.0/IBase.h>
@@ -56,25 +62,38 @@
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());
}
- return android::base::Join(instance_strings, " ");
+ return android::base::Join(instance_strings, "\n");
}
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 {
@@ -114,7 +133,7 @@
// 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}});
}
}
}));
@@ -212,33 +231,73 @@
});
}
-// TODO(b/138114550): Also test that services serve all declared interfaces.
-TEST_F(VtsHalBaseV1_0TargetTest, ServiceDeclaresAllServedInterfaces) {
+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();
+ // 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()) {
- std::cout << "[WARNING] Service '" << service << "' does not declare any interfaces"
- << std::endl;
- continue;
+ LOG(INFO) << "Service '" << service << "' does not declare any interfaces.";
}
+ 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: '" << FqInstancesToString(served_interfaces) << "'" << std::endl
- << " Declared: '" << FqInstancesToString(declared_interfaces) << "'"
- << std::endl
- << " Difference: '" << FqInstancesToString(diff) << "'";
+ 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
+ << 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);
}
}