diff options
-rw-r--r-- | sysfs.cpp | 107 | ||||
-rw-r--r-- | sysfs.hpp | 55 | ||||
-rw-r--r-- | test/Makefile.am.include | 8 | ||||
-rw-r--r-- | test/sysfs.cpp | 111 |
4 files changed, 280 insertions, 1 deletions
diff --git a/sysfs.cpp b/sysfs.cpp new file mode 100644 index 0000000..44ad8d6 --- /dev/null +++ b/sysfs.cpp @@ -0,0 +1,107 @@ +/** + * Copyright © 2019 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sysfs.hpp" + +#include <fstream> +#include <iostream> +#include <string> + +namespace fs = std::experimental::filesystem; + +namespace phosphor +{ +namespace led +{ + +constexpr char SysfsLed::BRIGHTNESS[]; +constexpr char SysfsLed::MAX_BRIGHTNESS[]; +constexpr char SysfsLed::TRIGGER[]; +constexpr char SysfsLed::DELAY_ON[]; +constexpr char SysfsLed::DELAY_OFF[]; + +template <typename T> +T get_sysfs_attr(const fs::path& path); + +template <> +std::string get_sysfs_attr(const fs::path& path) +{ + std::string content; + std::ifstream file(path); + file >> content; + return content; +} + +template <> +unsigned long get_sysfs_attr(const fs::path& path) +{ + std::string content = get_sysfs_attr<std::string>(std::move(path)); + return std::strtoul(content.c_str(), nullptr, 0); +} + +template <typename T> +void set_sysfs_attr(const fs::path& path, const T& value) +{ + std::ofstream file(path); + file << value; +} + +unsigned long SysfsLed::getBrightness() +{ + return get_sysfs_attr<unsigned long>(root / BRIGHTNESS); +} + +void SysfsLed::setBrightness(unsigned long brightness) +{ + set_sysfs_attr<unsigned long>(root / BRIGHTNESS, brightness); +} + +unsigned long SysfsLed::getMaxBrightness() +{ + return get_sysfs_attr<unsigned long>(root / MAX_BRIGHTNESS); +} + +std::string SysfsLed::getTrigger() +{ + return get_sysfs_attr<std::string>(root / TRIGGER); +} + +void SysfsLed::setTrigger(const std::string& trigger) +{ + set_sysfs_attr<std::string>(root / TRIGGER, trigger); +} + +unsigned long SysfsLed::getDelayOn() +{ + return get_sysfs_attr<unsigned long>(root / DELAY_ON); +} + +void SysfsLed::setDelayOn(unsigned long ms) +{ + set_sysfs_attr<unsigned long>(root / DELAY_ON, ms); +} + +unsigned long SysfsLed::getDelayOff() +{ + return get_sysfs_attr<unsigned long>(root / DELAY_OFF); +} + +void SysfsLed::setDelayOff(unsigned long ms) +{ + set_sysfs_attr<unsigned long>(root / DELAY_OFF, ms); +} +} // namespace led +} // namespace phosphor diff --git a/sysfs.hpp b/sysfs.hpp new file mode 100644 index 0000000..290c97f --- /dev/null +++ b/sysfs.hpp @@ -0,0 +1,55 @@ +/** + * Copyright © 2019 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include <experimental/filesystem> + +namespace phosphor +{ +namespace led +{ +class SysfsLed +{ + public: + SysfsLed(std::experimental::filesystem::path&& root) : root(std::move(root)) + { + } + SysfsLed() = delete; + SysfsLed(const SysfsLed& other) = delete; + + virtual ~SysfsLed() = default; + + virtual unsigned long getBrightness(); + virtual void setBrightness(unsigned long value); + virtual unsigned long getMaxBrightness(); + virtual std::string getTrigger(); + virtual void setTrigger(const std::string& trigger); + virtual unsigned long getDelayOn(); + virtual void setDelayOn(unsigned long ms); + virtual unsigned long getDelayOff(); + virtual void setDelayOff(unsigned long ms); + + protected: + static constexpr char BRIGHTNESS[] = "brightness"; + static constexpr char MAX_BRIGHTNESS[] = "max_brightness"; + static constexpr char TRIGGER[] = "trigger"; + static constexpr char DELAY_ON[] = "delay_on"; + static constexpr char DELAY_OFF[] = "delay_off"; + + std::experimental::filesystem::path root; +}; +} // namespace led +} // namespace phosphor diff --git a/test/Makefile.am.include b/test/Makefile.am.include index dd41dd8..95fe19e 100644 --- a/test/Makefile.am.include +++ b/test/Makefile.am.include @@ -14,6 +14,7 @@ AM_CXXFLAGS = \ $(PHOSPHOR_DBUS_INTERFACES_CXXFLAGS) \ $(CODE_COVERAGE_CXXFLAGS) AM_LDFLAGS = \ + -lstdc++fs \ $(SDBUSPLUS_LIBS) \ $(PHOSPHOR_DBUS_INTERFACES_LIBS) \ $(CODE_COVERAGE_LIBS) \ @@ -22,4 +23,9 @@ AM_LDFLAGS = \ test_physical_SOURCES = %reldir%/physical.cpp test_physical_LDADD = physical.o -check_PROGRAMS += %reldir%/physical +test_sysfs_SOURCES = %reldir%/sysfs.cpp +test_sysfs_LDADD = sysfs.cpp + +check_PROGRAMS += \ + %reldir%/physical \ + %reldir%/sysfs diff --git a/test/sysfs.cpp b/test/sysfs.cpp new file mode 100644 index 0000000..e8339e7 --- /dev/null +++ b/test/sysfs.cpp @@ -0,0 +1,111 @@ +/** + * Copyright © 2019 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sysfs.hpp" + +#include <sys/param.h> + +#include <cerrno> +#include <cstdlib> +#include <fstream> + +#include <gtest/gtest.h> + +namespace fs = std::experimental::filesystem; + +constexpr unsigned long MAX_BRIGHTNESS_VAL = 128; + +class FakeSysfsLed : public phosphor::led::SysfsLed +{ + public: + static FakeSysfsLed create() + { + static constexpr auto tmplt = "/tmp/FakeSysfsLed.XXXXXX"; + char buffer[MAXPATHLEN] = {0}; + + strncpy(buffer, tmplt, sizeof(buffer) - 1); + char* dir = mkdtemp(buffer); + if (!dir) + throw std::system_error(errno, std::system_category()); + + return FakeSysfsLed(fs::path(dir)); + } + + ~FakeSysfsLed() + { + fs::remove_all(root); + } + + private: + FakeSysfsLed(fs::path&& path) : SysfsLed(std::move(path)) + { + std::string attrs[4] = {BRIGHTNESS, TRIGGER, DELAY_ON, DELAY_OFF}; + for (const auto& attr : attrs) + { + fs::path p = root / attr; + std::ofstream f(p, std::ios::out); + f.exceptions(f.failbit); + } + + fs::path p = root / MAX_BRIGHTNESS; + std::ofstream f(p, std::ios::out); + f.exceptions(f.failbit); + f << MAX_BRIGHTNESS_VAL; + } +}; + +TEST(Sysfs, getBrightness) +{ + constexpr unsigned long brightness = 127; + FakeSysfsLed fsl = FakeSysfsLed::create(); + + fsl.setBrightness(brightness); + ASSERT_EQ(brightness, fsl.getBrightness()); +} + +TEST(Sysfs, getMaxBrightness) +{ + FakeSysfsLed fsl = FakeSysfsLed::create(); + + ASSERT_EQ(MAX_BRIGHTNESS_VAL, fsl.getMaxBrightness()); +} + +TEST(Sysfs, getTrigger) +{ + constexpr auto trigger = "none"; + FakeSysfsLed fsl = FakeSysfsLed::create(); + + fsl.setTrigger(trigger); + ASSERT_EQ(trigger, fsl.getTrigger()); +} + +TEST(Sysfs, getDelayOn) +{ + constexpr unsigned long delayOn = 250; + FakeSysfsLed fsl = FakeSysfsLed::create(); + + fsl.setDelayOn(delayOn); + ASSERT_EQ(delayOn, fsl.getDelayOn()); +} + +TEST(Sysfs, getDelayOff) +{ + constexpr unsigned long delayOff = 750; + FakeSysfsLed fsl = FakeSysfsLed::create(); + + fsl.setDelayOff(delayOff); + ASSERT_EQ(delayOff, fsl.getDelayOff()); +} |