Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2e32819 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Convert CAN bus HAL VTS to parametrized gtest am: f1545853

Change-Id: Ib3072ffe3ea143b1ee2a20844d0b69375abc8234
parents ccf37b0f f1545853
Loading
Loading
Loading
Loading
+25 −37
Original line number Diff line number Diff line
@@ -14,22 +14,20 @@
 * limitations under the License.
 */

#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <android/hardware/automotive/can/1.0/ICanBus.h>
#include <android/hardware/automotive/can/1.0/types.h>
#include <can-vts-utils/can-hal-printers.h>
#include <can-vts-utils/environment-utils.h>
#include <gmock/gmock.h>
#include <hidl-utils/hidl-utils.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>

namespace android::hardware::automotive::can::V1_0::vts {

using hardware::hidl_vec;

static utils::SimpleHidlEnvironment<ICanBus>* gEnv = nullptr;

struct CanMessageListener : public can::V1_0::ICanMessageListener {
    virtual Return<void> onReceive(const can::V1_0::CanMessage&) override { return {}; }
};
@@ -38,7 +36,7 @@ struct CanErrorListener : public can::V1_0::ICanErrorListener {
    virtual Return<void> onError(ErrorEvent, bool) override { return {}; }
};

class CanBusHalTest : public ::testing::VtsHalHidlTargetTestBase {
class CanBusHalTest : public ::testing::TestWithParam<std::string> {
  protected:
    virtual void SetUp() override;
    virtual void TearDown() override;
@@ -51,9 +49,8 @@ class CanBusHalTest : public ::testing::VtsHalHidlTargetTestBase {
};

void CanBusHalTest::SetUp() {
    const auto serviceName = gEnv->getServiceName<ICanBus>();
    mCanBus = getService<ICanBus>(serviceName);
    ASSERT_TRUE(mCanBus) << "Couldn't open CAN Bus: " << serviceName;
    mCanBus = ICanBus::getService(GetParam());
    ASSERT_TRUE(mCanBus) << "Couldn't open CAN Bus: " << GetParam();
}

void CanBusHalTest::TearDown() {
@@ -75,7 +72,7 @@ sp<ICloseHandle> CanBusHalTest::listenForErrors(const sp<ICanErrorListener>& lis
    return res;
}

TEST_F(CanBusHalTest, SendNoPayload) {
TEST_P(CanBusHalTest, SendNoPayload) {
    CanMessage msg = {};
    msg.id = 0x123;
    ASSERT_NE(mCanBus, nullptr);
@@ -83,7 +80,7 @@ TEST_F(CanBusHalTest, SendNoPayload) {
    ASSERT_EQ(Result::OK, result);
}

TEST_F(CanBusHalTest, Send8B) {
TEST_P(CanBusHalTest, Send8B) {
    CanMessage msg = {};
    msg.id = 0x234;
    msg.payload = {1, 2, 3, 4, 5, 6, 7, 8};
@@ -92,7 +89,7 @@ TEST_F(CanBusHalTest, Send8B) {
    ASSERT_EQ(Result::OK, result);
}

TEST_F(CanBusHalTest, SendZeroId) {
TEST_P(CanBusHalTest, SendZeroId) {
    CanMessage msg = {};
    msg.payload = {1, 2, 3};

@@ -100,7 +97,7 @@ TEST_F(CanBusHalTest, SendZeroId) {
    ASSERT_EQ(Result::OK, result);
}

TEST_F(CanBusHalTest, SendTooLong) {
TEST_P(CanBusHalTest, SendTooLong) {
    CanMessage msg = {};
    msg.id = 0x123;
    msg.payload = hidl_vec<uint8_t>(102400);  // 100kiB
@@ -109,14 +106,14 @@ TEST_F(CanBusHalTest, SendTooLong) {
    ASSERT_EQ(Result::PAYLOAD_TOO_LONG, result);
}

TEST_F(CanBusHalTest, ListenNoFilter) {
TEST_P(CanBusHalTest, ListenNoFilter) {
    const auto [result, closeHandle] = listen({}, new CanMessageListener());
    ASSERT_EQ(Result::OK, result);

    closeHandle->close().assertOk();
}

TEST_F(CanBusHalTest, ListenSomeFilter) {
TEST_P(CanBusHalTest, ListenSomeFilter) {
    hidl_vec<CanMessageFilter> filters = {
            {0x123, 0x1FF, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE, false},
            {0x001, 0x00F, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE, true},
@@ -129,12 +126,12 @@ TEST_F(CanBusHalTest, ListenSomeFilter) {
    closeHandle->close().assertOk();
}

TEST_F(CanBusHalTest, ListenNull) {
TEST_P(CanBusHalTest, ListenNull) {
    const auto [result, closeHandle] = listen({}, nullptr);
    ASSERT_EQ(Result::INVALID_ARGUMENTS, result);
}

TEST_F(CanBusHalTest, DoubleCloseListener) {
TEST_P(CanBusHalTest, DoubleCloseListener) {
    const auto [result, closeHandle] = listen({}, new CanMessageListener());
    ASSERT_EQ(Result::OK, result);

@@ -142,12 +139,12 @@ TEST_F(CanBusHalTest, DoubleCloseListener) {
    closeHandle->close().assertOk();
}

TEST_F(CanBusHalTest, DontCloseListener) {
TEST_P(CanBusHalTest, DontCloseListener) {
    const auto [result, closeHandle] = listen({}, new CanMessageListener());
    ASSERT_EQ(Result::OK, result);
}

TEST_F(CanBusHalTest, DoubleCloseErrorListener) {
TEST_P(CanBusHalTest, DoubleCloseErrorListener) {
    auto closeHandle = listenForErrors(new CanErrorListener());
    ASSERT_NE(nullptr, closeHandle.get());

@@ -155,7 +152,7 @@ TEST_F(CanBusHalTest, DoubleCloseErrorListener) {
    closeHandle->close().assertOk();
}

TEST_F(CanBusHalTest, DoubleCloseNullErrorListener) {
TEST_P(CanBusHalTest, DoubleCloseNullErrorListener) {
    auto closeHandle = listenForErrors(nullptr);
    ASSERT_NE(nullptr, closeHandle.get());

@@ -163,13 +160,11 @@ TEST_F(CanBusHalTest, DoubleCloseNullErrorListener) {
    closeHandle->close().assertOk();
}

TEST_F(CanBusHalTest, DontCloseErrorListener) {
TEST_P(CanBusHalTest, DontCloseErrorListener) {
    auto closeHandle = listenForErrors(new CanErrorListener());
    ASSERT_NE(nullptr, closeHandle.get());
}

}  // namespace android::hardware::automotive::can::V1_0::vts

/**
 * This test requires that you bring up a valid bus first.
 *
@@ -177,19 +172,12 @@ TEST_F(CanBusHalTest, DontCloseErrorListener) {
 * mma -j && adb root && adb remount && adb sync
 *
 * Example manual invocation:
 * adb shell canhalctrl up <NAME_OF_VALID_BUS> socketcan can0 125000
 * adb shell /data/nativetest64/VtsHalCanBusV1_0TargetTest/VtsHalCanBusV1_0TargetTest\
 *     --hal_service_instance=android.hardware.automotive.can@1.0::ICanBus/<NAME_OF_VALID_BUS>
 *     --gtest_filter=*_<NAME_OF_VALID_BUS>
 */
int main(int argc, char** argv) {
    using android::hardware::automotive::can::V1_0::ICanBus;
    using android::hardware::automotive::can::V1_0::vts::gEnv;
    using android::hardware::automotive::can::V1_0::vts::utils::SimpleHidlEnvironment;
    setenv("TREBLE_TESTING_OVERRIDE", "true", true);
    android::base::SetDefaultTag("CanBusVts");
    android::base::SetMinimumLogSeverity(android::base::VERBOSE);
    gEnv = new SimpleHidlEnvironment<ICanBus>;
    ::testing::AddGlobalTestEnvironment(gEnv);
    ::testing::InitGoogleTest(&argc, argv);
    gEnv->init(&argc, argv);
    return RUN_ALL_TESTS();
}
INSTANTIATE_TEST_SUITE_P(  //
        PerInstance, CanBusHalTest, testing::ValuesIn(getAllHalInstanceNames(ICanBus::descriptor)),
        PrintInstanceNameToString);

}  // namespace android::hardware::automotive::can::V1_0::vts
+29 −45
Original line number Diff line number Diff line
@@ -14,7 +14,6 @@
 * limitations under the License.
 */

#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <android/hardware/automotive/can/1.0/ICanBus.h>
@@ -23,9 +22,11 @@
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <can-vts-utils/bus-enumerator.h>
#include <can-vts-utils/can-hal-printers.h>
#include <can-vts-utils/environment-utils.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <hidl-utils/hidl-utils.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
#include <utils/Mutex.h>
#include <utils/SystemClock.h>

@@ -39,8 +40,6 @@ using namespace std::chrono_literals;
using hardware::hidl_vec;
using InterfaceType = ICanController::InterfaceType;

static utils::SimpleHidlEnvironment<ICanController>* gEnv = nullptr;

struct CanMessageListener : public can::V1_0::ICanMessageListener {
    DISALLOW_COPY_AND_ASSIGN(CanMessageListener);

@@ -133,12 +132,11 @@ struct Bus {
    sp<ICanBus> mBus;
};

class CanBusVirtualHalTest : public ::testing::VtsHalHidlTargetTestBase {
class CanBusVirtualHalTest : public ::testing::TestWithParam<std::string> {
  protected:
    virtual void SetUp() override;

    virtual void TearDown() override;
    static void SetUpTestCase();
    static void TearDownTestCase();

    Bus makeBus();

@@ -147,13 +145,10 @@ class CanBusVirtualHalTest : public ::testing::VtsHalHidlTargetTestBase {

  private:
    unsigned mLastIface = 0;
    static sp<ICanController> mCanController;
    static bool mVirtualSupported;
    sp<ICanController> mCanController = nullptr;
    static bool mTestCaseInitialized;
};

sp<ICanController> CanBusVirtualHalTest::mCanController = nullptr;
bool CanBusVirtualHalTest::mVirtualSupported;
hidl_vec<hidl_string> CanBusVirtualHalTest::mBusNames;
bool CanBusVirtualHalTest::mTestCaseInitialized = false;

@@ -170,29 +165,27 @@ static void clearTimestamps(std::vector<CanMessage>& messages) {
}

void CanBusVirtualHalTest::SetUp() {
    if (!mVirtualSupported) GTEST_SKIP();
    ASSERT_TRUE(mTestCaseInitialized);
}

void CanBusVirtualHalTest::SetUpTestCase() {
    const auto serviceName = gEnv->getServiceName<ICanController>();
    mCanController = getService<ICanController>(serviceName);
    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << serviceName;
    mCanController = ICanController::getService(GetParam());
    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << GetParam();

    hidl_vec<InterfaceType> supported;
    mCanController->getSupportedInterfaceTypes(hidl_utils::fill(&supported)).assertOk();
    mVirtualSupported = supported.contains(InterfaceType::VIRTUAL);
    if (!supported.contains(InterfaceType::VIRTUAL)) GTEST_SKIP();
}

void CanBusVirtualHalTest::TearDown() {
    mCanController.clear();
}

void CanBusVirtualHalTest::SetUpTestCase() {
    mBusNames = utils::getBusNames();
    ASSERT_NE(0u, mBusNames.size()) << "No ICanBus HALs defined in device manifest";

    mTestCaseInitialized = true;
}

void CanBusVirtualHalTest::TearDownTestCase() {
    mCanController.clear();
}

Bus CanBusVirtualHalTest::makeBus() {
    const auto idx = mLastIface++;
    EXPECT_LT(idx, mBusNames.size());
@@ -204,7 +197,7 @@ Bus CanBusVirtualHalTest::makeBus() {
    return Bus(mCanController, config);
}

TEST_F(CanBusVirtualHalTest, Send) {
TEST_P(CanBusVirtualHalTest, Send) {
    auto bus = makeBus();

    CanMessage msg = {};
@@ -214,7 +207,7 @@ TEST_F(CanBusVirtualHalTest, Send) {
    bus.send(msg);
}

TEST_F(CanBusVirtualHalTest, SendAfterClose) {
TEST_P(CanBusVirtualHalTest, SendAfterClose) {
    auto bus = makeBus();
    auto zombie = bus.get();
    bus.reset();
@@ -223,7 +216,7 @@ TEST_F(CanBusVirtualHalTest, SendAfterClose) {
    ASSERT_EQ(Result::INTERFACE_DOWN, result);
}

TEST_F(CanBusVirtualHalTest, SendAndRecv) {
TEST_P(CanBusVirtualHalTest, SendAndRecv) {
    if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
    auto bus1 = makeBus();
    auto bus2 = makeBus();
@@ -243,7 +236,7 @@ TEST_F(CanBusVirtualHalTest, SendAndRecv) {
    ASSERT_EQ(msg, messages[0]);
}

TEST_F(CanBusVirtualHalTest, DownOneOfTwo) {
TEST_P(CanBusVirtualHalTest, DownOneOfTwo) {
    if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";

    auto bus1 = makeBus();
@@ -254,7 +247,7 @@ TEST_F(CanBusVirtualHalTest, DownOneOfTwo) {
    bus1.send({});
}

TEST_F(CanBusVirtualHalTest, FilterPositive) {
TEST_P(CanBusVirtualHalTest, FilterPositive) {
    if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
    auto bus1 = makeBus();
    auto bus2 = makeBus();
@@ -418,7 +411,7 @@ TEST_F(CanBusVirtualHalTest, FilterPositive) {
    ASSERT_EQ(expectedPositive, messagesPositive);
}

TEST_F(CanBusVirtualHalTest, FilterNegative) {
TEST_P(CanBusVirtualHalTest, FilterNegative) {
    if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
    auto bus1 = makeBus();
    auto bus2 = makeBus();
@@ -612,7 +605,7 @@ TEST_F(CanBusVirtualHalTest, FilterNegative) {
    ASSERT_EQ(expectedNegative, messagesNegative);
}

TEST_F(CanBusVirtualHalTest, FilterMixed) {
TEST_P(CanBusVirtualHalTest, FilterMixed) {
    if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
    auto bus1 = makeBus();
    auto bus2 = makeBus();
@@ -871,22 +864,13 @@ TEST_F(CanBusVirtualHalTest, FilterMixed) {
    ASSERT_EQ(expectedMixed, messagesMixed);
}

}  // namespace android::hardware::automotive::can::V1_0::vts

/**
 * Example manual invocation:
 * adb shell /data/nativetest64/VtsHalCanBusVirtualV1_0TargetTest/VtsHalCanBusVirtualV1_0TargetTest\
 *     --hal_service_instance=android.hardware.automotive.can@1.0::ICanController/socketcan
 * adb shell /data/nativetest64/VtsHalCanBusVirtualV1_0TargetTest/VtsHalCanBusVirtualV1_0TargetTest
 */
int main(int argc, char** argv) {
    using android::hardware::automotive::can::V1_0::ICanController;
    using android::hardware::automotive::can::V1_0::vts::gEnv;
    using android::hardware::automotive::can::V1_0::vts::utils::SimpleHidlEnvironment;
    android::base::SetDefaultTag("CanBusVirtualVts");
    android::base::SetMinimumLogSeverity(android::base::VERBOSE);
    gEnv = new SimpleHidlEnvironment<ICanController>;
    ::testing::AddGlobalTestEnvironment(gEnv);
    ::testing::InitGoogleTest(&argc, argv);
    gEnv->init(&argc, argv);
    return RUN_ALL_TESTS();
}
INSTANTIATE_TEST_SUITE_P(  //
        PerInstance, CanBusVirtualHalTest,
        testing::ValuesIn(getAllHalInstanceNames(ICanController::descriptor)),
        PrintInstanceNameToString);

}  // namespace android::hardware::automotive::can::V1_0::vts
+22 −34
Original line number Diff line number Diff line
@@ -14,7 +14,6 @@
 * limitations under the License.
 */

#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <android/hardware/automotive/can/1.0/ICanBus.h>
@@ -23,9 +22,10 @@
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <can-vts-utils/bus-enumerator.h>
#include <can-vts-utils/can-hal-printers.h>
#include <can-vts-utils/environment-utils.h>
#include <gmock/gmock.h>
#include <hidl-utils/hidl-utils.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>

namespace android::hardware::automotive::can::V1_0::vts {

@@ -33,9 +33,7 @@ using hardware::hidl_vec;
using InterfaceType = ICanController::InterfaceType;
using IfId = ICanController::BusConfig::InterfaceId;

static utils::SimpleHidlEnvironment<ICanController>* gEnv = nullptr;

class CanControllerHalTest : public ::testing::VtsHalHidlTargetTestBase {
class CanControllerHalTest : public ::testing::TestWithParam<std::string> {
  protected:
    virtual void SetUp() override;
    virtual void TearDown() override;
@@ -61,9 +59,8 @@ bool CanControllerHalTest::mTestCaseInitialized = false;
void CanControllerHalTest::SetUp() {
    ASSERT_TRUE(mTestCaseInitialized);

    const auto serviceName = gEnv->getServiceName<ICanController>();
    mCanController = getService<ICanController>(serviceName);
    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << serviceName;
    mCanController = ICanController::getService(GetParam());
    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << GetParam();
}

void CanControllerHalTest::TearDown() {
@@ -130,12 +127,12 @@ void CanControllerHalTest::assertRegistered(std::string srvname, bool expectRegi
            << " (should be otherwise)";
}

TEST_F(CanControllerHalTest, SupportsSomething) {
TEST_P(CanControllerHalTest, SupportsSomething) {
    const auto supported = getSupportedInterfaceTypes();
    ASSERT_GT(supported.size(), 0u);
}

TEST_F(CanControllerHalTest, BringUpDown) {
TEST_P(CanControllerHalTest, BringUpDown) {
    const std::string name = mBusNames[0];

    assertRegistered(name, false);
@@ -148,12 +145,12 @@ TEST_F(CanControllerHalTest, BringUpDown) {
    assertRegistered(name, false);
}

TEST_F(CanControllerHalTest, DownDummy) {
TEST_P(CanControllerHalTest, DownDummy) {
    const auto result = mCanController->downInterface("imnotup");
    ASSERT_FALSE(result);
}

TEST_F(CanControllerHalTest, UpTwice) {
TEST_P(CanControllerHalTest, UpTwice) {
    const std::string name = mBusNames[0];

    assertRegistered(name, false);
@@ -169,7 +166,7 @@ TEST_F(CanControllerHalTest, UpTwice) {
    assertRegistered(name, false);
}

TEST_F(CanControllerHalTest, ConfigCompatibility) {
TEST_P(CanControllerHalTest, ConfigCompatibility) {
    // using random-ish addresses, which may not be valid - we can't test the success case
    // TODO(b/146214370): move interfaceId constructors to a library
    IfId virtualCfg = {};
@@ -231,7 +228,7 @@ TEST_F(CanControllerHalTest, ConfigCompatibility) {
    }
}

TEST_F(CanControllerHalTest, FailEmptyName) {
TEST_P(CanControllerHalTest, FailEmptyName) {
    const std::string name = "";

    assertRegistered(name, false);
@@ -241,7 +238,7 @@ TEST_F(CanControllerHalTest, FailEmptyName) {
    assertRegistered(name, false);
}

TEST_F(CanControllerHalTest, FailBadName) {
TEST_P(CanControllerHalTest, FailBadName) {
    // 33 characters (name can be at most 32 characters long)
    const std::string name = "ab012345678901234567890123456789c";

@@ -252,7 +249,7 @@ TEST_F(CanControllerHalTest, FailBadName) {
    assertRegistered(name, false);
}

TEST_F(CanControllerHalTest, FailBadVirtualAddress) {
TEST_P(CanControllerHalTest, FailBadVirtualAddress) {
    const std::string name = mBusNames[0];

    assertRegistered(name, false);
@@ -262,7 +259,7 @@ TEST_F(CanControllerHalTest, FailBadVirtualAddress) {
    assertRegistered(name, false);
}

TEST_F(CanControllerHalTest, FailBadSocketcanAddress) {
TEST_P(CanControllerHalTest, FailBadSocketcanAddress) {
    const std::string name = mBusNames[0];

    assertRegistered(name, false);
@@ -277,7 +274,7 @@ TEST_F(CanControllerHalTest, FailBadSocketcanAddress) {
    assertRegistered(name, false);
}

TEST_F(CanControllerHalTest, FailBadSlcanAddress) {
TEST_P(CanControllerHalTest, FailBadSlcanAddress) {
    const std::string name = mBusNames[0];

    assertRegistered(name, false);
@@ -292,22 +289,13 @@ TEST_F(CanControllerHalTest, FailBadSlcanAddress) {
    assertRegistered(name, false);
}

}  // namespace android::hardware::automotive::can::V1_0::vts

/**
 * Example manual invocation:
 * adb shell /data/nativetest64/VtsHalCanControllerV1_0TargetTest/VtsHalCanControllerV1_0TargetTest\
 *     --hal_service_instance=android.hardware.automotive.can@1.0::ICanController/socketcan
 * adb shell /data/nativetest64/VtsHalCanControllerV1_0TargetTest/VtsHalCanControllerV1_0TargetTest
 */
int main(int argc, char** argv) {
    using android::hardware::automotive::can::V1_0::ICanController;
    using android::hardware::automotive::can::V1_0::vts::gEnv;
    using android::hardware::automotive::can::V1_0::vts::utils::SimpleHidlEnvironment;
    android::base::SetDefaultTag("CanControllerVts");
    android::base::SetMinimumLogSeverity(android::base::VERBOSE);
    gEnv = new SimpleHidlEnvironment<ICanController>;
    ::testing::AddGlobalTestEnvironment(gEnv);
    ::testing::InitGoogleTest(&argc, argv);
    gEnv->init(&argc, argv);
    return RUN_ALL_TESTS();
}
INSTANTIATE_TEST_SUITE_P(  //
        PerInstance, CanControllerHalTest,
        testing::ValuesIn(getAllHalInstanceNames(ICanController::descriptor)),
        PrintInstanceNameToString);

}  // namespace android::hardware::automotive::can::V1_0::vts
+0 −60
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <VtsHalHidlTargetTestEnvBase.h>

namespace android::hardware::automotive::can::V1_0::vts::utils {

/**
 * Simple test environment.
 *
 * This is a helper class to instantiate a test environment without boilerplate code for cases where
 * there is no need to pass more parameters than just HIDL service instance name.
 *
 * The class implements registerTestServices() by calling registerTestService() on every HIDL
 * interface provided as parameter to this template.
 *
 * Example usage:
 *     static utils::SimpleHidlEnvironment<IMyService>* gEnv = nullptr;
 *
 *     void CanBusHalTest::SetUp() {
 *         const auto serviceName = gEnv->getServiceName<IMyService>();
 *         (...)
 *     }
 *
 *     int main(int argc, char** argv) {
 *         gEnv = new SimpleHidlEnvironment<IMyService>;
 *         ::testing::AddGlobalTestEnvironment(gEnv);
 *         ::testing::InitGoogleTest(&argc, argv);
 *         gEnv->init(&argc, argv);
 *         return RUN_ALL_TESTS();
 *     }
 *
 * \param T... HIDL interface names to register for a test service
 */
template <typename... T>
class SimpleHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
  public:
    virtual void registerTestServices() override {
        // Call registerTestService() for every HIDL interface using this template.
        using expander = int[];
        (void)expander{0, (registerTestService<T>(), 0)...};
    }
};

}  // namespace android::hardware::automotive::can::V1_0::vts::utils