Home | History | Annotate | Download | only in lshal
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "Lshal"
     18 #include <android-base/logging.h>
     19 
     20 #include <sstream>
     21 #include <string>
     22 #include <thread>
     23 #include <vector>
     24 
     25 #include <gtest/gtest.h>
     26 #include <gmock/gmock.h>
     27 #include <android/hardware/tests/baz/1.0/IQuux.h>
     28 #include <hidl/HidlTransportSupport.h>
     29 
     30 #include "Lshal.h"
     31 
     32 #define NELEMS(array)   static_cast<int>(sizeof(array) / sizeof(array[0]))
     33 
     34 using namespace testing;
     35 
     36 using ::android::hidl::base::V1_0::IBase;
     37 using ::android::hidl::manager::V1_0::IServiceManager;
     38 using ::android::hidl::manager::V1_0::IServiceNotification;
     39 using ::android::hardware::hidl_death_recipient;
     40 using ::android::hardware::hidl_handle;
     41 using ::android::hardware::hidl_string;
     42 using ::android::hardware::hidl_vec;
     43 
     44 namespace android {
     45 namespace hardware {
     46 namespace tests {
     47 namespace baz {
     48 namespace V1_0 {
     49 namespace implementation {
     50 struct Quux : android::hardware::tests::baz::V1_0::IQuux {
     51     ::android::hardware::Return<void> debug(const hidl_handle& hh, const hidl_vec<hidl_string>& options) override {
     52         const native_handle_t *handle = hh.getNativeHandle();
     53         if (handle->numFds < 1) {
     54             return Void();
     55         }
     56         int fd = handle->data[0];
     57         std::string content{descriptor};
     58         for (const auto &option : options) {
     59             content += "\n";
     60             content += option.c_str();
     61         }
     62         ssize_t written = write(fd, content.c_str(), content.size());
     63         if (written != (ssize_t)content.size()) {
     64             LOG(WARNING) << "SERVER(Quux) debug writes " << written << " bytes < "
     65                     << content.size() << " bytes, errno = " << errno;
     66         }
     67         return Void();
     68     }
     69 };
     70 
     71 } // namespace implementation
     72 } // namespace V1_0
     73 } // namespace baz
     74 } // namespace tests
     75 } // namespace hardware
     76 
     77 namespace lshal {
     78 
     79 
     80 class MockServiceManager : public IServiceManager {
     81 public:
     82     template<typename T>
     83     using R = ::android::hardware::Return<T>;
     84     using String = const hidl_string&;
     85     ~MockServiceManager() = default;
     86 
     87 #define MOCK_METHOD_CB(name) MOCK_METHOD1(name, R<void>(IServiceManager::name##_cb))
     88 
     89     MOCK_METHOD2(get, R<sp<IBase>>(String, String));
     90     MOCK_METHOD2(add, R<bool>(String, const sp<IBase>&));
     91     MOCK_METHOD2(getTransport, R<IServiceManager::Transport>(String, String));
     92     MOCK_METHOD_CB(list);
     93     MOCK_METHOD2(listByInterface, R<void>(String, listByInterface_cb));
     94     MOCK_METHOD3(registerForNotifications, R<bool>(String, String, const sp<IServiceNotification>&));
     95     MOCK_METHOD_CB(debugDump);
     96     MOCK_METHOD2(registerPassthroughClient, R<void>(String, String));
     97     MOCK_METHOD_CB(interfaceChain);
     98     MOCK_METHOD2(debug, R<void>(const hidl_handle&, const hidl_vec<hidl_string>&));
     99     MOCK_METHOD_CB(interfaceDescriptor);
    100     MOCK_METHOD_CB(getHashChain);
    101     MOCK_METHOD0(setHalInstrumentation, R<void>());
    102     MOCK_METHOD2(linkToDeath, R<bool>(const sp<hidl_death_recipient>&, uint64_t));
    103     MOCK_METHOD0(ping, R<void>());
    104     MOCK_METHOD_CB(getDebugInfo);
    105     MOCK_METHOD0(notifySyspropsChanged, R<void>());
    106     MOCK_METHOD1(unlinkToDeath, R<bool>(const sp<hidl_death_recipient>&));
    107 
    108 };
    109 
    110 class LshalTest : public ::testing::Test {
    111 public:
    112     void SetUp() override {
    113         using ::android::hardware::tests::baz::V1_0::IQuux;
    114         using ::android::hardware::tests::baz::V1_0::implementation::Quux;
    115 
    116         err.str("");
    117         out.str("");
    118         serviceManager = new testing::NiceMock<MockServiceManager>();
    119         ON_CALL(*serviceManager, get(_, _)).WillByDefault(Invoke(
    120             [](const auto &iface, const auto &inst) -> ::android::hardware::Return<sp<IBase>> {
    121                 if (iface == IQuux::descriptor && inst == "default")
    122                     return new Quux();
    123                 return nullptr;
    124             }));
    125     }
    126     void TearDown() override {}
    127 
    128     std::stringstream err;
    129     std::stringstream out;
    130     sp<MockServiceManager> serviceManager;
    131 };
    132 
    133 TEST_F(LshalTest, Debug) {
    134     const char *args[] = {
    135         "lshal", "debug", "android.hardware.tests.baz (at) 1.0::IQuux/default", "foo", "bar"
    136     };
    137     EXPECT_EQ(0u, Lshal(out, err, serviceManager, serviceManager)
    138             .main({NELEMS(args), const_cast<char **>(args)}));
    139     EXPECT_THAT(out.str(), StrEq("android.hardware.tests.baz (at) 1.0::IQuux\nfoo\nbar"));
    140     EXPECT_THAT(err.str(), IsEmpty());
    141 }
    142 
    143 TEST_F(LshalTest, Debug2) {
    144     const char *args[] = {
    145         "lshal", "debug", "android.hardware.tests.baz (at) 1.0::IQuux", "baz", "quux"
    146     };
    147     EXPECT_EQ(0u, Lshal(out, err, serviceManager, serviceManager)
    148             .main({NELEMS(args), const_cast<char **>(args)}));
    149     EXPECT_THAT(out.str(), StrEq("android.hardware.tests.baz (at) 1.0::IQuux\nbaz\nquux"));
    150     EXPECT_THAT(err.str(), IsEmpty());
    151 }
    152 
    153 TEST_F(LshalTest, Debug3) {
    154     const char *args[] = {
    155         "lshal", "debug", "android.hardware.tests.doesnotexist (at) 1.0::IDoesNotExist",
    156     };
    157     EXPECT_NE(0u, Lshal(out, err, serviceManager, serviceManager)
    158             .main({NELEMS(args), const_cast<char **>(args)}));
    159     EXPECT_THAT(err.str(), HasSubstr("does not exist"));
    160 }
    161 
    162 } // namespace lshal
    163 } // namespace android
    164 
    165 int main(int argc, char **argv) {
    166     ::testing::InitGoogleMock(&argc, argv);
    167     return RUN_ALL_TESTS();
    168 }
    169