blob: c6b6f18bb35d0445bef3b4cac1d6306cab50e18c [file] [log] [blame]
Vishwanatha Subbanna32c97272017-04-04 14:10:08 +05301#include <iostream>
2#include <sys/types.h>
3#include <chrono>
4#include <string>
5#include <linux/input.h>
6#include <gtest/gtest.h>
7#include "monitor.hpp"
Gunnar Mills99258572017-07-27 15:22:42 -05008#include "evdev.hpp"
Vishwanatha Subbanna32c97272017-04-04 14:10:08 +05309
10using namespace phosphor::gpio;
11
12// Exit helper. Ideally should be class but need
13// this to be used inside a static method.
14bool completed {};
15
16class GpioTest : public ::testing::Test
17{
18 public:
19 static constexpr auto DEVICE = "/tmp/test_fifo";
20
21 // systemd event handler
22 sd_event* events;
23
24 // Really needed just for the constructor
25 decltype(input_event::code) code = 10;
26
27 // Really needed just for the constructor
28 decltype(input_event::value) value = 10;
29
30 // Need this so that events can be initialized.
31 int rc;
32
33 // Gets called as part of each TEST_F construction
34 GpioTest()
35 : rc(sd_event_default(&events))
36 {
37 // Check for successful creation of event handler
38 EXPECT_GE(rc, 0);
39
40 // FIFO created to simulate data available
41 EXPECT_EQ(0, mknod(DEVICE, S_IFIFO|0666, 0));
42 }
43
44 // Gets called as part of each TEST_F destruction
45 ~GpioTest()
46 {
47 EXPECT_EQ(0, remove(DEVICE));
48
49 events = sd_event_unref(events);
50 EXPECT_EQ(events, nullptr);
51 }
52
53 // Callback handler on data
54 static int callbackHandler(sd_event_source* es, int fd,
55 uint32_t revents, void* userData)
56 {
57 std::cout <<"Event fired" << std::endl;
58 completed = true;
59 return 0;
60 }
61};
62
63/** @brief Makes sure that event never comes for 3 seconds
64 */
65TEST_F(GpioTest, noEventIn3Seconds)
66{
67 using namespace std::chrono;
68
69 phosphor::gpio::EventPtr eventP { events };
70 events = nullptr;
71
72 const std::string emptyTarget = "";
73 Monitor gpio(DEVICE, code, value, emptyTarget,
Vishwanatha Subbannaba8de422017-06-19 15:51:01 +053074 eventP, callbackHandler, false);
Vishwanatha Subbanna32c97272017-04-04 14:10:08 +053075
76 // Waiting 3 seconds and check if the completion status is set
77 int count = 0;
78 while(count < 3)
79 {
80 // Returns -0- on timeout and positive number on dispatch
81 auto sleepTime = duration_cast<microseconds>(seconds(1));
82 if(!sd_event_run(eventP.get(), sleepTime.count()))
83 {
84 count++;
85 }
86 }
87 EXPECT_EQ(false, completed);
88
89 // 3 to cater to another uptick that happens prior to breaking.
90 EXPECT_EQ(3, count);
91}
92
93/** @brief Pump data in the middle and expect the callback to be invoked */
94TEST_F(GpioTest, pumpDataAndExpectCallBack)
95{
96 using namespace std::chrono;
97
98 phosphor::gpio::EventPtr eventP { events };
99 events = nullptr;
100
101 const std::string emptyTarget = "";
102 Monitor gpio(DEVICE, code, value, emptyTarget,
Vishwanatha Subbannaba8de422017-06-19 15:51:01 +0530103 eventP, callbackHandler, false);
Vishwanatha Subbanna32c97272017-04-04 14:10:08 +0530104
105 // Pump the data in the middle
106 int count = 0;
107 while(count < 2 && !completed)
108 {
109 if (count == 1)
110 {
111 auto pumpData = std::string("echo 'foo' > ") + DEVICE;
112 EXPECT_GE(0, system(pumpData.c_str()));
113 }
114
115 // Returns -0- on timeout
116 auto sleepTime = duration_cast<microseconds>(seconds(1));
117 if(!sd_event_run(eventP.get(), sleepTime.count()))
118 {
119 count++;
120 }
121 }
122 EXPECT_EQ(true, completed);
123 EXPECT_EQ(1, count);
124}