Add gtest cases to test callback handler
Change-Id: If6c1e1616bcf73441648c8e0cb20017a4b218f70
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..db82844
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,12 @@
+AM_CPPFLAGS = -I$(top_srcdir)
+
+# Run all 'check' test programs
+TESTS = $(check_PROGRAMS)
+
+# # Build/add utest to test suite
+check_PROGRAMS = utest
+utest_CPPFLAGS = -Igtest $(GTEST_CPPFLAGS) $(AM_CPPFLAGS) $(SDBUSPLUS_CFLAGS) $(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
+utest_CXXFLAGS = $(PTHREAD_CFLAGS)
+utest_LDFLAGS = -lgtest_main -lgtest $(PTHREAD_LIBS) $(OESDK_TESTCASE_FLAGS) $(SYSTEMD_LIBS) $(SDBUSPLUS_LIBS) $(PHOSPHOR_DBUS_INTERFACES_LIBS)
+utest_SOURCES = utest.cpp
+utest_LDADD = $(top_builddir)/monitor.o
diff --git a/test/utest.cpp b/test/utest.cpp
new file mode 100644
index 0000000..78e1b7e
--- /dev/null
+++ b/test/utest.cpp
@@ -0,0 +1,123 @@
+#include <iostream>
+#include <sys/types.h>
+#include <chrono>
+#include <string>
+#include <linux/input.h>
+#include <gtest/gtest.h>
+#include "monitor.hpp"
+
+using namespace phosphor::gpio;
+
+// Exit helper. Ideally should be class but need
+// this to be used inside a static method.
+bool completed {};
+
+class GpioTest : public ::testing::Test
+{
+ public:
+ static constexpr auto DEVICE = "/tmp/test_fifo";
+
+ // systemd event handler
+ sd_event* events;
+
+ // Really needed just for the constructor
+ decltype(input_event::code) code = 10;
+
+ // Really needed just for the constructor
+ decltype(input_event::value) value = 10;
+
+ // Need this so that events can be initialized.
+ int rc;
+
+ // Gets called as part of each TEST_F construction
+ GpioTest()
+ : rc(sd_event_default(&events))
+ {
+ // Check for successful creation of event handler
+ EXPECT_GE(rc, 0);
+
+ // FIFO created to simulate data available
+ EXPECT_EQ(0, mknod(DEVICE, S_IFIFO|0666, 0));
+ }
+
+ // Gets called as part of each TEST_F destruction
+ ~GpioTest()
+ {
+ EXPECT_EQ(0, remove(DEVICE));
+
+ events = sd_event_unref(events);
+ EXPECT_EQ(events, nullptr);
+ }
+
+ // Callback handler on data
+ static int callbackHandler(sd_event_source* es, int fd,
+ uint32_t revents, void* userData)
+ {
+ std::cout <<"Event fired" << std::endl;
+ completed = true;
+ return 0;
+ }
+};
+
+/** @brief Makes sure that event never comes for 3 seconds
+ */
+TEST_F(GpioTest, noEventIn3Seconds)
+{
+ using namespace std::chrono;
+
+ phosphor::gpio::EventPtr eventP { events };
+ events = nullptr;
+
+ const std::string emptyTarget = "";
+ Monitor gpio(DEVICE, code, value, emptyTarget,
+ eventP, callbackHandler);
+
+ // Waiting 3 seconds and check if the completion status is set
+ int count = 0;
+ while(count < 3)
+ {
+ // Returns -0- on timeout and positive number on dispatch
+ auto sleepTime = duration_cast<microseconds>(seconds(1));
+ if(!sd_event_run(eventP.get(), sleepTime.count()))
+ {
+ count++;
+ }
+ }
+ EXPECT_EQ(false, completed);
+
+ // 3 to cater to another uptick that happens prior to breaking.
+ EXPECT_EQ(3, count);
+}
+
+/** @brief Pump data in the middle and expect the callback to be invoked */
+TEST_F(GpioTest, pumpDataAndExpectCallBack)
+{
+ using namespace std::chrono;
+
+ phosphor::gpio::EventPtr eventP { events };
+ events = nullptr;
+
+ const std::string emptyTarget = "";
+ Monitor gpio(DEVICE, code, value, emptyTarget,
+ eventP, callbackHandler);
+
+ // Pump the data in the middle
+ int count = 0;
+ while(count < 2 && !completed)
+ {
+ if (count == 1)
+ {
+ auto pumpData = std::string("echo 'foo' > ") + DEVICE;
+ EXPECT_GE(0, system(pumpData.c_str()));
+ }
+
+ // Returns -0- on timeout
+ auto sleepTime = duration_cast<microseconds>(seconds(1));
+ if(!sd_event_run(eventP.get(), sleepTime.count()))
+ {
+ count++;
+ }
+ }
+ EXPECT_EQ(true, completed);
+ EXPECT_EQ(1, count);
+}