#include "evdev.hpp" #include "monitor.hpp" #include #include #include #include #include #include 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, false, callbackHandler, false); // 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(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, false, callbackHandler, false); // 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(seconds(1)); if (!sd_event_run(eventP.get(), sleepTime.count())) { count++; } } EXPECT_EQ(true, completed); EXPECT_EQ(1, count); }