blob: f3c318762e1f29e223c35e7bad104cdb11401ab9 [file] [log] [blame]
Andrew Jefferya607a0d2018-05-23 16:15:26 +09301#include "physical.hpp"
2
Andrew Jeffery280afaf2018-05-24 16:15:46 +09303#include <sys/param.h>
4
Andrew Jefferya607a0d2018-05-23 16:15:26 +09305#include <sdbusplus/bus.hpp>
6
Andrew Jeffery280afaf2018-05-24 16:15:46 +09307#include <gmock/gmock.h>
Andrew Jefferya607a0d2018-05-23 16:15:26 +09308#include <gtest/gtest.h>
9
10constexpr auto LED_OBJ = "/foo/bar/led";
Andrew Jefferya607a0d2018-05-23 16:15:26 +093011
12using Action = sdbusplus::xyz::openbmc_project::Led::server::Physical::Action;
Andrew Jeffery42e02d32018-05-24 13:34:05 +093013namespace fs = std::experimental::filesystem;
Andrew Jefferya607a0d2018-05-23 16:15:26 +093014
Andrew Jeffery280afaf2018-05-24 16:15:46 +093015fs::path create_sandbox()
16{
17 /* If your tests need to touch the filesystem, always use mkdtemp() or
18 * mkstemp() for creating directories and files. Tests can be run in
19 * parallel with `make -j`, and if use the same path in multiple tests they
20 * will stomp on eachother and likely fail.
21 */
22 static constexpr auto tmplt = "/tmp/MockLed.XXXXXX";
23 char buffer[MAXPATHLEN] = {0};
24
25 strncpy(buffer, tmplt, sizeof(buffer) - 1);
26 auto dir = mkdtemp(buffer);
27 if (!dir)
28 {
29 throw std::system_error(errno, std::system_category());
30 }
31
32 /* We want to limit behaviours to mocks, and if methods aren't mocked they
33 * may fall back to their base class implementation. Stop read/write to
34 * directory to prevent streams from creating files.
35 */
36 if (chmod(dir, S_IXUSR | S_IXGRP) == -1)
37 {
38 throw std::system_error(errno, std::system_category());
39 }
40
41 return fs::path(dir);
42}
43
44class MockLed : public phosphor::led::SysfsLed
45{
46 public:
47 /* Use a no-args ctor here to avoid headaches with {Nice,Strict}Mock */
48 MockLed() : SysfsLed(create_sandbox())
49 {
50 }
51
52 virtual ~MockLed()
53 {
54 chmod(root.c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
55 fs::remove_all(root);
56 }
57
58 MOCK_METHOD0(getBrightness, unsigned long());
59 MOCK_METHOD1(setBrightness, void(unsigned long value));
60 MOCK_METHOD0(getMaxBrightness, unsigned long());
61 MOCK_METHOD0(getTrigger, std::string());
62 MOCK_METHOD1(setTrigger, void(const std::string& trigger));
63 MOCK_METHOD0(getDelayOn, unsigned long());
64 MOCK_METHOD1(setDelayOn, void(unsigned long ms));
65 MOCK_METHOD0(getDelayOff, unsigned long());
66 MOCK_METHOD1(setDelayOff, void(unsigned long ms));
67};
68
Andrew Jefferyaee9c2c2018-05-25 14:05:40 +093069using ::testing::InSequence;
Andrew Jeffery280afaf2018-05-24 16:15:46 +093070using ::testing::NiceMock;
71using ::testing::Return;
72using ::testing::Throw;
73
Andrew Jeffery56692702018-05-25 11:41:43 +093074TEST(Physical, ctor_none_trigger)
Andrew Jefferya607a0d2018-05-23 16:15:26 +093075{
76 sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
Andrew Jeffery280afaf2018-05-24 16:15:46 +093077 /* NiceMock ignores calls to methods with no expectations defined */
78 NiceMock<MockLed> led;
79 ON_CALL(led, getTrigger()).WillByDefault(Return("none"));
Andrew Jeffery42e02d32018-05-24 13:34:05 +093080 phosphor::led::Physical phy(bus, LED_OBJ, led);
Andrew Jefferya607a0d2018-05-23 16:15:26 +093081}
82
Andrew Jeffery56692702018-05-25 11:41:43 +093083TEST(Physical, ctor_timer_trigger)
84{
85 sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
86 NiceMock<MockLed> led;
87 EXPECT_CALL(led, getTrigger()).WillOnce(Return("timer"));
88 EXPECT_CALL(led, getDelayOn()).WillOnce(Return(500));
89 EXPECT_CALL(led, getDelayOff()).WillOnce(Return(500));
90 phosphor::led::Physical phy(bus, LED_OBJ, led);
91}
92
Andrew Jefferya607a0d2018-05-23 16:15:26 +093093TEST(Physical, off)
94{
95 sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
Andrew Jeffery280afaf2018-05-24 16:15:46 +093096 NiceMock<MockLed> led;
Andrew Jeffery30726a02018-05-25 15:03:04 +093097 ON_CALL(led, getMaxBrightness()).WillByDefault(Return(127));
98 EXPECT_CALL(led, getTrigger()).WillOnce(Return("none"));
99 EXPECT_CALL(led, getBrightness()).WillOnce(Return(phosphor::led::DEASSERT));
100 EXPECT_CALL(led, setBrightness(phosphor::led::DEASSERT)).Times(0);
Andrew Jeffery42e02d32018-05-24 13:34:05 +0930101 phosphor::led::Physical phy(bus, LED_OBJ, led);
102 phy.state(Action::Off);
Andrew Jefferya607a0d2018-05-23 16:15:26 +0930103}
104
105TEST(Physical, on)
106{
107 sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
Andrew Jeffery280afaf2018-05-24 16:15:46 +0930108 NiceMock<MockLed> led;
Andrew Jeffery30726a02018-05-25 15:03:04 +0930109 EXPECT_CALL(led, getTrigger()).WillOnce(Return("none"));
110 EXPECT_CALL(led, setTrigger("none"));
111 EXPECT_CALL(led, setBrightness(phosphor::led::ASSERT));
Andrew Jeffery42e02d32018-05-24 13:34:05 +0930112 phosphor::led::Physical phy(bus, LED_OBJ, led);
113 phy.state(Action::On);
Andrew Jefferya607a0d2018-05-23 16:15:26 +0930114}
115
116TEST(Physical, blink)
117{
118 sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
Andrew Jeffery280afaf2018-05-24 16:15:46 +0930119 NiceMock<MockLed> led;
Andrew Jeffery861e5622018-05-25 14:51:45 +0930120 EXPECT_CALL(led, getTrigger()).WillOnce(Return("none"));
121 EXPECT_CALL(led, setTrigger("timer"));
122 EXPECT_CALL(led, setDelayOn(500));
123 EXPECT_CALL(led, setDelayOff(500));
Andrew Jeffery42e02d32018-05-24 13:34:05 +0930124 phosphor::led::Physical phy(bus, LED_OBJ, led);
125 phy.state(Action::Blink);
Andrew Jefferya607a0d2018-05-23 16:15:26 +0930126}
Andrew Jeffery04275e02018-05-25 13:04:39 +0930127
128TEST(Physical, ctor_none_trigger_asserted_brightness)
129{
130 sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
131 NiceMock<MockLed> led;
132 EXPECT_CALL(led, getTrigger()).WillRepeatedly(Return("none"));
133 constexpr auto val = phosphor::led::ASSERT;
134 EXPECT_CALL(led, getBrightness()).WillRepeatedly(Return(val));
135 phosphor::led::Physical phy(bus, LED_OBJ, led);
136}
Andrew Jefferyaee9c2c2018-05-25 14:05:40 +0930137
138TEST(Physical, on_to_off)
139{
140 InSequence s;
141
142 auto bus = sdbusplus::bus::new_default();
143 NiceMock<MockLed> led;
144 EXPECT_CALL(led, getTrigger()).Times(1).WillOnce(Return("none"));
145 constexpr auto deasserted = phosphor::led::DEASSERT;
146 EXPECT_CALL(led, getBrightness()).WillOnce(Return(deasserted));
147 constexpr auto asserted = phosphor::led::ASSERT;
148 EXPECT_CALL(led, setBrightness(asserted));
149 EXPECT_CALL(led, setBrightness(deasserted));
150 phosphor::led::Physical phy(bus, LED_OBJ, led);
151 phy.state(Action::On);
152 phy.state(Action::Off);
153}