Merge "Add test cases for HidlMemoryCache"
diff --git a/libhidlcache/Android.bp b/libhidlcache/Android.bp
index 7fd5aa7..ea846d8 100644
--- a/libhidlcache/Android.bp
+++ b/libhidlcache/Android.bp
@@ -45,3 +45,26 @@
         "mapping.cpp"
     ],
 }
+
+cc_test {
+   name: "libhidlcache_test",
+    defaults: ["hidl-gen-defaults"],
+
+    shared_libs: [
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "android.hidl.memory.block@1.0",
+        "android.hidl.memory.token@1.0",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libhidlmemory",
+        "libhidlcache",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+    ],
+
+    srcs: ["libhidlcache_test.cpp"],
+}
diff --git a/libhidlcache/libhidlcache_test.cpp b/libhidlcache/libhidlcache_test.cpp
new file mode 100644
index 0000000..ce21c6f
--- /dev/null
+++ b/libhidlcache/libhidlcache_test.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#define LOG_TAG "hidl-cache-test"
+
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <android/hidl/memory/token/1.0/IMemoryToken.h>
+#include <gtest/gtest.h>
+#include <hidlcache/mapping.h>
+#include <hidlmemory/HidlMemoryToken.h>
+#include <hidlmemory/mapping.h>
+#include "HidlMemoryCache.h"
+
+#define EXPECT_OK(__ret__) EXPECT_TRUE(isOk(__ret__))
+
+template <typename T>
+static inline ::testing::AssertionResult isOk(const ::android::hardware::Return<T>& ret) {
+    return ret.isOk() ? (::testing::AssertionSuccess() << ret.description())
+                      : (::testing::AssertionFailure() << ret.description());
+}
+
+namespace android {
+
+namespace hardware {
+void HidlCacheWhiteBoxTest() {
+    using ::android::hardware::HidlMemoryCache;
+    using ::android::hardware::HidlMemoryToken;
+    using ::android::hidl::allocator::V1_0::IAllocator;
+    using ::android::hidl::memory::V1_0::IMemory;
+    using ::android::hidl::memory::token::V1_0::IMemoryToken;
+    using ::android::hidl::memory::block::V1_0::MemoryBlock;
+
+    sp<IAllocator> ashmemAllocator;
+
+    ashmemAllocator = IAllocator::getService("ashmem");
+    ASSERT_NE(nullptr, ashmemAllocator.get());
+    ASSERT_TRUE(ashmemAllocator->isRemote());  // allocator is always remote
+
+    sp<HidlMemory> mem;
+    EXPECT_OK(ashmemAllocator->allocate(1024, [&](bool success, const hidl_memory& _mem) {
+        ASSERT_TRUE(success);
+        mem = HidlMemory::getInstance(_mem);
+    }));
+
+    sp<IMemoryToken> token = new HidlMemoryToken(mem);
+
+    MemoryBlock blk = {token, 0x200 /* size */, 0x100 /* offset */};
+    sp<IMemoryToken> mtoken = blk.token;
+    mtoken->get([&](const hidl_memory& mem) { sp<IMemory> memory = mapMemory(mem); });
+
+    sp<HidlMemoryCache> cache = HidlMemoryCache::getInstance();
+    EXPECT_FALSE(cache->cached(token));
+
+    MemoryBlock blk2 = {token, 0x200 /* size */, 0x300 /* offset */};
+
+    EXPECT_FALSE(cache->cached(token));
+
+    {
+        sp<IMemory> mem1 = cache->fetch(token);
+        EXPECT_TRUE(cache->cached(token));
+        EXPECT_NE(nullptr, cache->getCachedLocked(token).get());
+        sp<IMemory> mem2 = cache->fetch(token);
+        EXPECT_TRUE(cache->cached(token));
+        EXPECT_NE(nullptr, cache->getCachedLocked(token).get());
+    }
+    EXPECT_FALSE(cache->cached(token));
+    {
+        sp<IMemory> mem1 = mapMemory(blk);
+        EXPECT_TRUE(cache->cached(token));
+        EXPECT_NE(nullptr, cache->getCachedLocked(token).get());
+        uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(mem1->getPointer()));
+        EXPECT_NE(nullptr, data);
+    }
+    {
+        sp<IMemory> mem2 = mapMemory(blk);
+        EXPECT_TRUE(cache->cached(token));
+        EXPECT_NE(nullptr, cache->getCachedLocked(token).get());
+    }
+    EXPECT_FALSE(cache->cached(token));
+    EXPECT_TRUE(cache->lock(token));
+    EXPECT_TRUE(cache->cached(token));
+    EXPECT_NE(nullptr, cache->getCachedLocked(token).get());
+    EXPECT_TRUE(cache->unlock(token));
+    EXPECT_FALSE(cache->cached(token));
+}
+}  // namespace hardware
+
+class HidlCacheTest : public ::testing::Test {};
+
+TEST_F(HidlCacheTest, TestAll) {
+    hardware::HidlCacheWhiteBoxTest();
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
+
+}  // namespace android
\ No newline at end of file