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