summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Jeffery <andrew@aj.id.au>2018-05-24 16:15:46 +0930
committerAndrew Jeffery <andrew@aj.id.au>2019-04-08 13:48:49 +0930
commit280afaf32b33ece0ab22ab25ed76e67a9600f92b (patch)
tree6b3dd5005f7e74c77a389f4bd9552c476defd835
parent42e02d34113534c2e98dfd321fa79671fa7e1d20 (diff)
downloadphosphor-led-sysfs-280afaf32b33ece0ab22ab25ed76e67a9600f92b.tar.gz
phosphor-led-sysfs-280afaf32b33ece0ab22ab25ed76e67a9600f92b.zip
test: physical: Introduce LED mocks
This removes the dependency on touching the filesystem entirely. All methods are now mocked into an ignored state when called by the NiceMock template class. The filesystem is only touched by the SysfsLed tests, though we still need to provide a temporary path to its constructor in the decended mock class to ensure we're isolated if something does manage to get written. Change-Id: I3955a6e0fb5c3c42887da847239d381ef151fa3e Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
-rw-r--r--test/physical.cpp75
1 files changed, 70 insertions, 5 deletions
diff --git a/test/physical.cpp b/test/physical.cpp
index 4316b16..1b546ed 100644
--- a/test/physical.cpp
+++ b/test/physical.cpp
@@ -1,26 +1,89 @@
#include "physical.hpp"
+#include <sys/param.h>
+
#include <sdbusplus/bus.hpp>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
constexpr auto LED_OBJ = "/foo/bar/led";
-constexpr auto LED_SYSFS = "/sys/class/leds/test";
using Action = sdbusplus::xyz::openbmc_project::Led::server::Physical::Action;
namespace fs = std::experimental::filesystem;
+fs::path create_sandbox()
+{
+ /* If your tests need to touch the filesystem, always use mkdtemp() or
+ * mkstemp() for creating directories and files. Tests can be run in
+ * parallel with `make -j`, and if use the same path in multiple tests they
+ * will stomp on eachother and likely fail.
+ */
+ static constexpr auto tmplt = "/tmp/MockLed.XXXXXX";
+ char buffer[MAXPATHLEN] = {0};
+
+ strncpy(buffer, tmplt, sizeof(buffer) - 1);
+ auto dir = mkdtemp(buffer);
+ if (!dir)
+ {
+ throw std::system_error(errno, std::system_category());
+ }
+
+ /* We want to limit behaviours to mocks, and if methods aren't mocked they
+ * may fall back to their base class implementation. Stop read/write to
+ * directory to prevent streams from creating files.
+ */
+ if (chmod(dir, S_IXUSR | S_IXGRP) == -1)
+ {
+ throw std::system_error(errno, std::system_category());
+ }
+
+ return fs::path(dir);
+}
+
+class MockLed : public phosphor::led::SysfsLed
+{
+ public:
+ /* Use a no-args ctor here to avoid headaches with {Nice,Strict}Mock */
+ MockLed() : SysfsLed(create_sandbox())
+ {
+ }
+
+ virtual ~MockLed()
+ {
+ chmod(root.c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
+ fs::remove_all(root);
+ }
+
+ MOCK_METHOD0(getBrightness, unsigned long());
+ MOCK_METHOD1(setBrightness, void(unsigned long value));
+ MOCK_METHOD0(getMaxBrightness, unsigned long());
+ MOCK_METHOD0(getTrigger, std::string());
+ MOCK_METHOD1(setTrigger, void(const std::string& trigger));
+ MOCK_METHOD0(getDelayOn, unsigned long());
+ MOCK_METHOD1(setDelayOn, void(unsigned long ms));
+ MOCK_METHOD0(getDelayOff, unsigned long());
+ MOCK_METHOD1(setDelayOff, void(unsigned long ms));
+};
+
+using ::testing::NiceMock;
+using ::testing::Return;
+using ::testing::Throw;
+
TEST(Physical, ctor)
{
sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
- phosphor::led::SysfsLed led{fs::path(LED_SYSFS)};
+ /* NiceMock ignores calls to methods with no expectations defined */
+ NiceMock<MockLed> led;
+ ON_CALL(led, getTrigger()).WillByDefault(Return("none"));
phosphor::led::Physical phy(bus, LED_OBJ, led);
}
TEST(Physical, off)
{
sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
- phosphor::led::SysfsLed led{fs::path(LED_SYSFS)};
+ NiceMock<MockLed> led;
+ ON_CALL(led, getTrigger()).WillByDefault(Return("none"));
phosphor::led::Physical phy(bus, LED_OBJ, led);
phy.state(Action::Off);
}
@@ -28,7 +91,8 @@ TEST(Physical, off)
TEST(Physical, on)
{
sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
- phosphor::led::SysfsLed led{fs::path(LED_SYSFS)};
+ NiceMock<MockLed> led;
+ ON_CALL(led, getTrigger()).WillByDefault(Return("none"));
phosphor::led::Physical phy(bus, LED_OBJ, led);
phy.state(Action::On);
}
@@ -36,7 +100,8 @@ TEST(Physical, on)
TEST(Physical, blink)
{
sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
- phosphor::led::SysfsLed led{fs::path(LED_SYSFS)};
+ NiceMock<MockLed> led;
+ ON_CALL(led, getTrigger()).WillByDefault(Return("none"));
phosphor::led::Physical phy(bus, LED_OBJ, led);
phy.state(Action::Blink);
}
OpenPOWER on IntegriCloud