hidl_test: apply gtest.
b/30855757 Convert hidl test to gTest
Note: only test the values received by the client. Doesn't
test the values received by the server... yet.
Change-Id: I1f50e3fefe9bfc3cc07ff48f764c0f20c90175d5
diff --git a/test/Android.mk b/test/Android.mk
index aca4915..7cee786 100644
--- a/test/Android.mk
+++ b/test/Android.mk
@@ -7,6 +7,9 @@
LOCAL_SRC_FILES := \
main.cpp \
+LOCAL_C_INCLUDES := \
+ external/gtest/include
+
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libbase \
@@ -18,6 +21,9 @@
android.hardware.tests.foo@1.0 \
android.hardware.tests.bar@1.0 \
+LOCAL_STATIC_LIBRARIES := \
+ libgtest
+
LOCAL_MODULE_TAGS := samples
LOCAL_CFLAGS := -O0 -g
diff --git a/test/main.cpp b/test/main.cpp
index 918c530..02f64f9 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -5,6 +5,16 @@
#include <android/hardware/tests/foo/1.0/BnFooCallback.h>
#include <android/hardware/tests/bar/1.0/BnBar.h>
+#include <gtest/gtest.h>
+#if GTEST_IS_THREADSAFE
+#include <sys/types.h>
+#include <signal.h>
+#include <errno.h>
+#include <pthread.h>
+#else
+#error "GTest did not detect pthread library."
+#endif
+
#include <hidl/IServiceManager.h>
#include <hwbinder/IPCThreadState.h>
#include <hwbinder/ProcessState.h>
@@ -264,160 +274,260 @@
return out;
}
+
static std::string vecToString(const hidl_vec<int32_t> &vec) {
return arraylikeToString(vec, vec.size());
}
-static void client() {
+static inline void EXPECT_OK(::android::hardware::Status status) {
+ EXPECT_TRUE(status.isOk());
+}
+
+template<typename T, typename S>
+static inline bool EXPECT_ARRAYEQ(const T arr1, const S arr2, size_t size) {
+ for(size_t i = 0; i < size; i++)
+ if(arr1[i] != arr2[i])
+ return false;
+ return true;
+}
+
+
+template <class T>
+static void startServer(T server, const android::hardware::hidl_version kVersion,
+ const char *serviceName,
+ const char *tag) {
using namespace android::hardware;
using android::String16;
+ ALOGI("SERVER(%s) registering", tag);
+ defaultServiceManager()->addService(String16(serviceName), server, kVersion);
+ ALOGI("SERVER(%s) starting", tag);
+ ProcessState::self()->setThreadPoolMaxThreadCount(0);
+ ProcessState::self()->startThreadPool();
+ IPCThreadState::self()->joinThreadPool(); // never ends. needs kill().
+ ALOGI("SERVER(%s) ends.", tag);
+}
- const hidl_version kVersion = make_hidl_version(1, 0);
- sp<IBinder> service =
- defaultServiceManager()->getService(String16("foo"), kVersion);
+class HidlTest : public ::testing::Test {
+public:
+ sp<::android::hardware::IBinder> service;
+ sp<IFoo> foo;
+ sp<IBar> bar;
+ sp<::android::hardware::IBinder> cbService;
+ virtual void SetUp() override {
+ ALOGI("Test setup beginning...");
+ using namespace android::hardware;
+ using android::String16;
+ const hidl_version kVersion = make_hidl_version(1, 0);
- CHECK(service != NULL);
+ service =
+ defaultServiceManager()->getService(String16("foo"), kVersion);
+ ALOGI("CLIENT Found service foo.");
- sp<IFoo> foo = IFoo::asInterface(service);
- CHECK(foo != NULL);
+ CHECK(service != NULL);
+ foo = IFoo::asInterface(service);
+ CHECK(foo != NULL);
+
+ bar = IBar::asInterface(service);
+ CHECK(bar != NULL);
+
+ cbService = defaultServiceManager()->getService(String16("foo callback"), kVersion);
+ ALOGI("Test setup complete");
+ }
+ virtual void TearDown() override {
+ }
+};
+
+class HidlEnvironment : public ::testing::Environment {
+private:
+ pid_t fooCallbackServerPid, barServerPid;
+public:
+ virtual void SetUp() {
+ ALOGI("Environment setup beginning...");
+ // use fork to create and kill to destroy server processes.
+ if ((barServerPid = fork()) == 0) {
+ // Fear me, I am a child.
+ startServer(new Bar, android::hardware::make_hidl_version(1, 0),
+ "foo", "Bar"); // never returns
+ return;
+ }
+
+ if ((fooCallbackServerPid = fork()) == 0) {
+ // Fear me, I am a second child.
+ startServer(new FooCallback, android::hardware::make_hidl_version(1, 0),
+ "foo callback", "FooCalback"); // never returns
+ return;
+ }
+
+ // Fear you not, I am parent.
+ sleep(1);
+ ALOGI("Environment setup complete.");
+ }
+
+ virtual void TearDown() {
+ // clean up by killing server processes.
+ ALOGI("Environment tear-down beginning...");
+ ALOGI("Killing servers...");
+ if(kill(barServerPid, SIGTERM)) {
+ ALOGE("Could not kill barServer; errno = %d", errno);
+ } else {
+ int status;
+ ALOGI("Waiting for barServer to exit...");
+ waitpid(barServerPid, &status, 0);
+ ALOGI("Continuing...");
+ }
+ if(kill(fooCallbackServerPid, SIGTERM)) {
+ ALOGE("Could not kill fooCallbackServer; errno = %d", errno);
+ } else {
+ int status;
+ ALOGI("Waiting for fooCallbackServer to exit...");
+ waitpid(barServerPid, &status, 0);
+ ALOGI("Continuing...");
+ }
+ ALOGI("Servers all killed.");
+ ALOGI("Environment tear-down complete.");
+ }
+};
+
+TEST_F(HidlTest, FooDoThisTest) {
ALOGI("CLIENT call doThis.");
- foo->doThis(1.0f);
+ EXPECT_OK(foo->doThis(1.0f));
ALOGI("CLIENT doThis returned.");
+}
+TEST_F(HidlTest, FooDoThatAndReturnSomethingTest) {
ALOGI("CLIENT call doThatAndReturnSomething.");
int32_t result = foo->doThatAndReturnSomething(2.0f);
ALOGI("CLIENT doThatAndReturnSomething returned %d.", result);
+ EXPECT_EQ(result, 666);
+}
+TEST_F(HidlTest, FooDoQuiteABitTest) {
ALOGI("CLIENT call doQuiteABit");
double something = foo->doQuiteABit(1, 2, 3.0f, 4.0);
ALOGI("CLIENT doQuiteABit returned %f.", something);
+ EXPECT_DOUBLE_EQ(something, 666.5);
+}
+
+TEST_F(HidlTest, FooDoSomethingElseTest) {
ALOGI("CLIENT call doSomethingElse");
int32_t param[15];
for (size_t i = 0; i < sizeof(param) / sizeof(param[0]); ++i) {
param[i] = i;
}
- foo->doSomethingElse(param, [&](const auto &something) {
+ EXPECT_OK(foo->doSomethingElse(param, [&](const auto &something) {
ALOGI("CLIENT doSomethingElse returned %s.",
arraylikeToString(something, 32).c_str());
- });
+ int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
+ 26, 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2};
+ EXPECT_ARRAYEQ(something, expect, 32);
+ }));
+}
+TEST_F(HidlTest, FooDoStuffAndReturnAStringTest) {
ALOGI("CLIENT call doStuffAndReturnAString");
- foo->doStuffAndReturnAString([&](const auto &something) {
+ EXPECT_OK(foo->doStuffAndReturnAString([&](const auto &something) {
ALOGI("CLIENT doStuffAndReturnAString returned '%s'.",
something.c_str());
- });
+ EXPECT_STREQ(something.c_str(), "Hello, world");
+ }));
+}
+TEST_F(HidlTest, FooMapThisVectorTest) {
hidl_vec<int32_t> vecParam;
vecParam.resize(10);
for (size_t i = 0; i < 10; ++i) {
vecParam[i] = i;
}
- foo->mapThisVector(vecParam, [&](const auto &something) {
+ EXPECT_OK(foo->mapThisVector(vecParam, [&](const auto &something) {
ALOGI("CLIENT mapThisVector returned %s.",
vecToString(something).c_str());
- });
+ int32_t expect[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18};
+ EXPECT_ARRAYEQ(something, expect, something.size());
+ }));
+}
+TEST_F(HidlTest, FooCallMeTest) {
ALOGI("CLIENT call callMe.");
- sp<IBinder> cbService = defaultServiceManager()->getService(String16("foo callback"), kVersion);
- foo->callMe(IFooCallback::asInterface(cbService));
+ EXPECT_OK(foo->callMe(IFooCallback::asInterface(cbService)));
ALOGI("CLIENT callMe returned.");
+}
- ALOGI("CLIENT call userAnEnum.");
+TEST_F(HidlTest, FooUseAnEnumTest) {
+ ALOGI("CLIENT call useAnEnum.");
IFoo::SomeEnum sleepy = foo->useAnEnum(IFoo::SomeEnum::quux);
ALOGI("CLIENT useAnEnum returned %u", (unsigned)sleepy);
+ EXPECT_EQ(sleepy, IFoo::SomeEnum::goober);
+}
+TEST_F(HidlTest, FooHaveAGooberTest) {
hidl_vec<IFoo::Goober> gooberVecParam;
gooberVecParam.resize(2);
gooberVecParam[0].name = "Hello";
gooberVecParam[1].name = "World";
ALOGI("CLIENT call haveAGooberVec.");
- foo->haveAGooberVec(gooberVecParam);
+ EXPECT_OK(foo->haveAGooberVec(gooberVecParam));
ALOGI("CLIENT haveAGooberVec returned.");
ALOGI("CLIENT call haveaGoober.");
- foo->haveAGoober(gooberVecParam[0]);
+ EXPECT_OK(foo->haveAGoober(gooberVecParam[0]));
ALOGI("CLIENT haveaGoober returned.");
ALOGI("CLIENT call haveAGooberArray.");
IFoo::Goober gooberArrayParam[20];
- foo->haveAGooberArray(gooberArrayParam);
+ EXPECT_OK(foo->haveAGooberArray(gooberArrayParam));
ALOGI("CLIENT haveAGooberArray returned.");
+}
+TEST_F(HidlTest, FooHaveATypeFromAnotherFileTest) {
ALOGI("CLIENT call haveATypeFromAnotherFile.");
Abc abcParam{};
abcParam.x = "alphabet";
abcParam.y = 3.14f;
abcParam.z = new native_handle_t();
- foo->haveATypeFromAnotherFile(abcParam);
+ EXPECT_OK(foo->haveATypeFromAnotherFile(abcParam));
ALOGI("CLIENT haveATypeFromAnotherFile returned.");
delete abcParam.z;
abcParam.z = NULL;
+}
+TEST_F(HidlTest, FooHaveSomeStringsTest) {
ALOGI("CLIENT call haveSomeStrings.");
hidl_string stringArrayParam[3];
stringArrayParam[0] = "What";
stringArrayParam[1] = "a";
stringArrayParam[2] = "disaster";
- foo->haveSomeStrings(stringArrayParam);
+ EXPECT_OK(foo->haveSomeStrings(stringArrayParam));
ALOGI("CLIENT haveSomeStrings returned.");
+}
+TEST_F(HidlTest, FooHaveAStringVecTest) {
ALOGI("CLIENT call haveAStringVec.");
hidl_vec<hidl_string> stringVecParam;
stringVecParam.resize(3);
stringVecParam[0] = "What";
stringVecParam[1] = "a";
stringVecParam[2] = "disaster";
- foo->haveAStringVec(stringVecParam);
+ EXPECT_OK(foo->haveAStringVec(stringVecParam));
ALOGI("CLIENT haveAStringVec returned.");
+}
- // Now the tricky part, get access to the derived interface.
-
- sp<IBar> bar = IBar::asInterface(service);
- CHECK(bar != NULL);
-
+TEST_F(HidlTest, BarThisIsNewTest) {
+// Now the tricky part, get access to the derived interface.
ALOGI("CLIENT call thisIsNew.");
- bar->thisIsNew();
+ EXPECT_OK(bar->thisIsNew());
ALOGI("CLIENT thisIsNew returned.");
}
-int main() {
- using namespace android::hardware;
- using android::String16;
+int main(int argc, char **argv) {
- if (fork() == 0) {
- sleep(1);
+ ::testing::AddGlobalTestEnvironment(new HidlEnvironment);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
- // Fear me, I am child.
- client();
-
- return 0;
- }
-
- if (fork() == 0) {
- ALOGI("SERVER(FooCallback) registering");
- sp<FooCallback> fcb = new FooCallback;
- const hidl_version kVersion = make_hidl_version(1, 0);
- defaultServiceManager()->addService(String16("foo callback"), fcb, kVersion);
- ALOGI("SERVER(FooCallback) starting");
- ProcessState::self()->setThreadPoolMaxThreadCount(0);
- ProcessState::self()->startThreadPool();
- IPCThreadState::self()->joinThreadPool();
-
- return 0;
- }
-
- ALOGI("SERVER(Bar) registering");
- sp<Bar> bar = new Bar;
- const hidl_version kVersion = make_hidl_version(1, 0);
- defaultServiceManager()->addService(String16("foo"), bar, kVersion);
- ALOGI("SERVER(Bar) starting");
- ProcessState::self()->setThreadPoolMaxThreadCount(0);
- ProcessState::self()->startThreadPool();
- IPCThreadState::self()->joinThreadPool();
-
- return 0;
+ ALOGI("Test result = %d", status);
+ return status;
}