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