xref: /openbmc/phosphor-gpio-monitor/test/utest.cpp (revision 86d16f037350afd379d062ca17cab5d553a1c8f2)
19925857aSGunnar Mills #include "evdev.hpp"
2dace680fSPatrick Venture #include "monitor.hpp"
3dace680fSPatrick Venture 
4dace680fSPatrick Venture #include <linux/input.h>
5dace680fSPatrick Venture #include <sys/types.h>
6dace680fSPatrick Venture 
7dace680fSPatrick Venture #include <chrono>
8dace680fSPatrick Venture #include <iostream>
9dace680fSPatrick Venture #include <string>
10dace680fSPatrick Venture 
11dace680fSPatrick Venture #include <gtest/gtest.h>
1232c97273SVishwanatha Subbanna 
1332c97273SVishwanatha Subbanna using namespace phosphor::gpio;
1432c97273SVishwanatha Subbanna 
1532c97273SVishwanatha Subbanna // Exit helper. Ideally should be class but need
1632c97273SVishwanatha Subbanna // this to be used inside a static method.
1732c97273SVishwanatha Subbanna bool completed{};
1832c97273SVishwanatha Subbanna 
1932c97273SVishwanatha Subbanna class GpioTest : public ::testing::Test
2032c97273SVishwanatha Subbanna {
2132c97273SVishwanatha Subbanna   public:
2232c97273SVishwanatha Subbanna     static constexpr auto DEVICE = "/tmp/test_fifo";
2332c97273SVishwanatha Subbanna 
2432c97273SVishwanatha Subbanna     // systemd event handler
2532c97273SVishwanatha Subbanna     sd_event* events;
2632c97273SVishwanatha Subbanna 
2732c97273SVishwanatha Subbanna     // Really needed just for the constructor
2832c97273SVishwanatha Subbanna     decltype(input_event::code) code = 10;
2932c97273SVishwanatha Subbanna 
3032c97273SVishwanatha Subbanna     // Really needed just for the constructor
3132c97273SVishwanatha Subbanna     decltype(input_event::value) value = 10;
3232c97273SVishwanatha Subbanna 
3332c97273SVishwanatha Subbanna     // Need this so that events can be initialized.
3432c97273SVishwanatha Subbanna     int rc;
3532c97273SVishwanatha Subbanna 
3632c97273SVishwanatha Subbanna     // Gets called as part of each TEST_F construction
GpioTest()37dace680fSPatrick Venture     GpioTest() : rc(sd_event_default(&events))
3832c97273SVishwanatha Subbanna     {
3932c97273SVishwanatha Subbanna         // Check for successful creation of event handler
4032c97273SVishwanatha Subbanna         EXPECT_GE(rc, 0);
4132c97273SVishwanatha Subbanna 
4232c97273SVishwanatha Subbanna         // FIFO created to simulate data available
4332c97273SVishwanatha Subbanna         EXPECT_EQ(0, mknod(DEVICE, S_IFIFO | 0666, 0));
4432c97273SVishwanatha Subbanna     }
4532c97273SVishwanatha Subbanna 
4632c97273SVishwanatha Subbanna     // Gets called as part of each TEST_F destruction
~GpioTest()4732c97273SVishwanatha Subbanna     ~GpioTest()
4832c97273SVishwanatha Subbanna     {
4932c97273SVishwanatha Subbanna         EXPECT_EQ(0, remove(DEVICE));
5032c97273SVishwanatha Subbanna 
5132c97273SVishwanatha Subbanna         events = sd_event_unref(events);
5232c97273SVishwanatha Subbanna         EXPECT_EQ(events, nullptr);
5332c97273SVishwanatha Subbanna     }
5432c97273SVishwanatha Subbanna 
5532c97273SVishwanatha Subbanna     // Callback handler on data
callbackHandler(sd_event_source *,int,uint32_t,void *)56*86d16f03SBrad Bishop     static int callbackHandler(sd_event_source*, int, uint32_t, void*)
5732c97273SVishwanatha Subbanna     {
5832c97273SVishwanatha Subbanna         std::cout << "Event fired" << std::endl;
5932c97273SVishwanatha Subbanna         completed = true;
6032c97273SVishwanatha Subbanna         return 0;
6132c97273SVishwanatha Subbanna     }
6232c97273SVishwanatha Subbanna };
6332c97273SVishwanatha Subbanna 
6432c97273SVishwanatha Subbanna /** @brief Makes sure that event never comes for 3 seconds
6532c97273SVishwanatha Subbanna  */
TEST_F(GpioTest,noEventIn3Seconds)6632c97273SVishwanatha Subbanna TEST_F(GpioTest, noEventIn3Seconds)
6732c97273SVishwanatha Subbanna {
6832c97273SVishwanatha Subbanna     using namespace std::chrono;
6932c97273SVishwanatha Subbanna 
7032c97273SVishwanatha Subbanna     phosphor::gpio::EventPtr eventP{events};
7132c97273SVishwanatha Subbanna     events = nullptr;
7232c97273SVishwanatha Subbanna 
7332c97273SVishwanatha Subbanna     const std::string emptyTarget = "";
74dace680fSPatrick Venture     Monitor gpio(DEVICE, code, value, emptyTarget, eventP, false,
75dace680fSPatrick Venture                  callbackHandler, false);
7632c97273SVishwanatha Subbanna 
7732c97273SVishwanatha Subbanna     // Waiting 3 seconds and check if the completion status is set
7832c97273SVishwanatha Subbanna     int count = 0;
7932c97273SVishwanatha Subbanna     while (count < 3)
8032c97273SVishwanatha Subbanna     {
8132c97273SVishwanatha Subbanna         // Returns -0- on timeout and positive number on dispatch
8232c97273SVishwanatha Subbanna         auto sleepTime = duration_cast<microseconds>(seconds(1));
8332c97273SVishwanatha Subbanna         if (!sd_event_run(eventP.get(), sleepTime.count()))
8432c97273SVishwanatha Subbanna         {
8532c97273SVishwanatha Subbanna             count++;
8632c97273SVishwanatha Subbanna         }
8732c97273SVishwanatha Subbanna     }
8832c97273SVishwanatha Subbanna     EXPECT_EQ(false, completed);
8932c97273SVishwanatha Subbanna 
9032c97273SVishwanatha Subbanna     // 3 to cater to another uptick that happens prior to breaking.
9132c97273SVishwanatha Subbanna     EXPECT_EQ(3, count);
9232c97273SVishwanatha Subbanna }
9332c97273SVishwanatha Subbanna 
9432c97273SVishwanatha Subbanna /** @brief Pump data in the middle and expect the callback to be invoked */
TEST_F(GpioTest,pumpDataAndExpectCallBack)9532c97273SVishwanatha Subbanna TEST_F(GpioTest, pumpDataAndExpectCallBack)
9632c97273SVishwanatha Subbanna {
9732c97273SVishwanatha Subbanna     using namespace std::chrono;
9832c97273SVishwanatha Subbanna 
9932c97273SVishwanatha Subbanna     phosphor::gpio::EventPtr eventP{events};
10032c97273SVishwanatha Subbanna     events = nullptr;
10132c97273SVishwanatha Subbanna 
10232c97273SVishwanatha Subbanna     const std::string emptyTarget = "";
103dace680fSPatrick Venture     Monitor gpio(DEVICE, code, value, emptyTarget, eventP, false,
104dace680fSPatrick Venture                  callbackHandler, false);
10532c97273SVishwanatha Subbanna 
10632c97273SVishwanatha Subbanna     // Pump the data in the middle
10732c97273SVishwanatha Subbanna     int count = 0;
10832c97273SVishwanatha Subbanna     while (count < 2 && !completed)
10932c97273SVishwanatha Subbanna     {
11032c97273SVishwanatha Subbanna         if (count == 1)
11132c97273SVishwanatha Subbanna         {
11232c97273SVishwanatha Subbanna             auto pumpData = std::string("echo 'foo' > ") + DEVICE;
11332c97273SVishwanatha Subbanna             EXPECT_GE(0, system(pumpData.c_str()));
11432c97273SVishwanatha Subbanna         }
11532c97273SVishwanatha Subbanna 
11632c97273SVishwanatha Subbanna         // Returns -0- on timeout
11732c97273SVishwanatha Subbanna         auto sleepTime = duration_cast<microseconds>(seconds(1));
11832c97273SVishwanatha Subbanna         if (!sd_event_run(eventP.get(), sleepTime.count()))
11932c97273SVishwanatha Subbanna         {
12032c97273SVishwanatha Subbanna             count++;
12132c97273SVishwanatha Subbanna         }
12232c97273SVishwanatha Subbanna     }
12332c97273SVishwanatha Subbanna     EXPECT_EQ(true, completed);
12432c97273SVishwanatha Subbanna     EXPECT_EQ(1, count);
12532c97273SVishwanatha Subbanna }
126