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