hwservicemanager unit tests

Just for lazy service logic now since it is a relatively complicated
state machine.

Bug: 123318663
Test: hwservicemanager_test
Change-Id: Ia3b3168b97107c1ff98e472e19b02db4f2a8ff3b
diff --git a/test_lazy.cpp b/test_lazy.cpp
new file mode 100644
index 0000000..0aeac47
--- /dev/null
+++ b/test_lazy.cpp
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+#include <HidlService.h>
+
+#include <android/hidl/manager/1.2/IClientCallback.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hidl::manager::implementation::HidlService;
+using ::android::hidl::manager::V1_2::IClientCallback;
+using ::android::sp;
+using ::testing::ElementsAre;
+using ::testing::Invoke;
+using ::testing::NiceMock;
+
+class RecordingClientCallback : public IClientCallback {
+public:
+    Return<void> onClients(const sp<IBase>& /*base*/, bool clients) override {
+        stream.push_back(clients);
+        return Void();
+    }
+
+    std::vector<bool> stream;
+};
+
+class MockHidlService : public HidlService {
+public:
+    MockHidlService() : HidlService("fqname", "instance") {}
+    MOCK_METHOD0(getNodeStrongRefCount, ssize_t());
+};
+
+class HidlServiceLazyTest : public ::testing::Test {
+public:
+    // Note that this should include one count for hwservicemanager. A count of
+    // 1 indicates that hwservicemanager is the only process holding the service.
+    void setReportedClientCount(ssize_t count) {
+        mInjectedReportCount = count;
+    }
+
+    std::unique_ptr<HidlService> makeService() {
+        auto service = std::make_unique<NiceMock<MockHidlService>>();
+        ON_CALL(*service, getNodeStrongRefCount()).WillByDefault(Invoke([&]() { return mInjectedReportCount; }));
+        return service;
+    }
+
+protected:
+    void SetUp() override {
+        mInjectedReportCount = -1;
+    }
+
+    ssize_t mInjectedReportCount = -1;
+};
+
+TEST_F(HidlServiceLazyTest, NoChange) {
+    sp<RecordingClientCallback> cb = new RecordingClientCallback;
+
+    std::unique_ptr<HidlService> service = makeService();
+    service->addClientCallback(cb);
+
+    setReportedClientCount(1);
+
+    for (size_t i = 0; i < 100; i++) {
+        service->handleClientCallbacks(true /*onInterval*/);
+    }
+
+    ASSERT_THAT(cb->stream, ElementsAre());
+}
+
+TEST_F(HidlServiceLazyTest, GetAndDrop) {
+    sp<RecordingClientCallback> cb = new RecordingClientCallback;
+
+    std::unique_ptr<HidlService> service = makeService();
+    service->addClientCallback(cb);
+
+    // some other process has the service
+    setReportedClientCount(2);
+    service->handleClientCallbacks(true /*onInterval*/);
+
+    ASSERT_THAT(cb->stream, ElementsAre(true));
+
+    // just hwservicemanager has the service
+    setReportedClientCount(1);
+    service->handleClientCallbacks(true /*onInterval*/);
+
+    ASSERT_THAT(cb->stream, ElementsAre(true));
+    service->handleClientCallbacks(true /*onInterval*/);
+
+    ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
+}
+
+TEST_F(HidlServiceLazyTest, GetGuarantee) {
+    sp<RecordingClientCallback> cb = new RecordingClientCallback;
+
+    std::unique_ptr<HidlService> service = makeService();
+    service->addClientCallback(cb);
+
+    service->guaranteeClient();
+
+    setReportedClientCount(1);
+    service->handleClientCallbacks(false /*onInterval*/);
+    ASSERT_THAT(cb->stream, ElementsAre(true));
+
+    service->handleClientCallbacks(true /*onInterval*/);
+    ASSERT_THAT(cb->stream, ElementsAre(true));
+
+    service->handleClientCallbacks(true /*onInterval*/);
+    ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
+}
+
+TEST_F(HidlServiceLazyTest, ManyUpdatesOffInterval) {
+    sp<RecordingClientCallback> cb = new RecordingClientCallback;
+
+    std::unique_ptr<HidlService> service = makeService();
+    service->addClientCallback(cb);
+
+    // Clients can appear and dissappear as many times as necessary, but they are only considered
+    // dropped when the fixed interval stops.
+    for (size_t i = 0; i < 100; i++) {
+        setReportedClientCount(2);
+        service->handleClientCallbacks(false /*onInterval*/);
+        setReportedClientCount(1);
+        service->handleClientCallbacks(false /*onInterval*/);
+    }
+
+    ASSERT_THAT(cb->stream, ElementsAre(true));
+
+    service->handleClientCallbacks(true /*onInterval*/);
+    ASSERT_THAT(cb->stream, ElementsAre(true));
+
+    service->handleClientCallbacks(true /*onInterval*/);
+    ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
+}