diff options
author | Patrick Venture <venture@google.com> | 2019-02-08 11:47:42 -0800 |
---|---|---|
committer | Patrick Venture <venture@google.com> | 2019-02-08 14:40:52 -0800 |
commit | eeeb867de1fac2d524cd2d0c94d11194bfbfcebb (patch) | |
tree | 816ec10f0e9ffbe4a77e50a06e7bc538fc172b5d | |
parent | 1f802f5e9086f3771a8b1d50c5af4a77be56cee0 (diff) | |
download | phosphor-pid-control-eeeb867de1fac2d524cd2d0c94d11194bfbfcebb.tar.gz phosphor-pid-control-eeeb867de1fac2d524cd2d0c94d11194bfbfcebb.zip |
add support to build sensors from json
Add support to build sensors from a json configuration file.
Change-Id: Ic5bcbcd01e085ab0d4efaed314af8dc7e82b0b9d
Signed-off-by: Patrick Venture <venture@google.com>
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | sensors/buildjson.cpp | 88 | ||||
-rw-r--r-- | sensors/buildjson.hpp | 20 | ||||
-rw-r--r-- | test/Makefile.am | 6 | ||||
-rw-r--r-- | test/sensors_json_unittest.cpp | 100 |
5 files changed, 214 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index 914c558..09a52d5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -63,6 +63,7 @@ libswampd_la_SOURCES = \ sensors/host.cpp \ sensors/builder.cpp \ sensors/builderconfig.cpp \ + sensors/buildjson.cpp \ sensors/manager.cpp \ pid/ec/pid.cpp \ pid/ec/stepwise.cpp \ diff --git a/sensors/buildjson.cpp b/sensors/buildjson.cpp new file mode 100644 index 0000000..7c4c7d6 --- /dev/null +++ b/sensors/buildjson.cpp @@ -0,0 +1,88 @@ +/** + * Copyright 2019 Google Inc. + * + * 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 "sensors/buildjson.hpp" + +#include "conf.hpp" +#include "sensors/sensor.hpp" + +#include <nlohmann/json.hpp> + +using json = nlohmann::json; + +void from_json(const json& j, SensorConfig& s) +{ + j.at("type").get_to(s.type); + j.at("readpath").get_to(s.readpath); + + /* The writepath field is optional in a configuration */ + auto writepath = j.find("writepath"); + if (writepath == j.end()) + { + s.writepath = ""; + } + else + { + j.at("writepath").get_to(s.writepath); + } + + /* The min field is optional in a configuration. */ + auto min = j.find("min"); + if (min == j.end()) + { + s.min = 0; + } + else + { + j.at("min").get_to(s.min); + } + + /* The max field is optional in a configuration. */ + auto max = j.find("max"); + if (max == j.end()) + { + s.max = 0; + } + else + { + j.at("max").get_to(s.max); + } + + /* The timeout field is optional in a configuration. */ + auto timeout = j.find("timeout"); + if (timeout == j.end()) + { + s.timeout = Sensor::getDefaultTimeout(s.type); + } + else + { + j.at("timeout").get_to(s.timeout); + } +} + +std::map<std::string, struct SensorConfig> + buildSensorsFromJson(const json& data) +{ + std::map<std::string, struct SensorConfig> config; + auto sensors = data["sensors"]; + + for (const auto& sensor : sensors) + { + config[sensor["name"]] = sensor.get<struct SensorConfig>(); + } + + return config; +} diff --git a/sensors/buildjson.hpp b/sensors/buildjson.hpp new file mode 100644 index 0000000..c5aacc7 --- /dev/null +++ b/sensors/buildjson.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "conf.hpp" + +#include <map> +#include <nlohmann/json.hpp> +#include <string> + +using json = nlohmann::json; + +/** + * Given a json object generated from a configuration file, build the sensor + * configuration representation. This expecteds the json configuration to be + * valid. + * + * @param[in] data - the json data + * @return a map of sensors. + */ +std::map<std::string, struct SensorConfig> + buildSensorsFromJson(const json& data); diff --git a/test/Makefile.am b/test/Makefile.am index c46284f..fb1d58d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -17,7 +17,8 @@ check_PROGRAMS = sensor_manager_unittest sensor_pluggable_unittest \ sensor_host_unittest util_unittest pid_zone_unittest \ pid_thermalcontroller_unittest pid_fancontroller_unittest \ pid_stepwisecontroller_unittest \ - dbus_passive_unittest dbus_active_unittest + dbus_passive_unittest dbus_active_unittest \ + sensors_json_unittest TESTS = $(check_PROGRAMS) # Until libconfig is mocked out or replaced, include it. @@ -58,3 +59,6 @@ dbus_passive_unittest_LDADD = $(top_builddir)/dbus/util.o \ dbus_active_unittest_SOURCES = dbus_active_unittest.cpp dbus_active_unittest_LDADD = $(top_builddir)/dbus/dbusactiveread.o + +sensors_json_unittest_SOURCES = sensors_json_unittest.cpp +sensors_json_unittest_LDADD = $(top_builddir)/sensors/buildjson.o diff --git a/test/sensors_json_unittest.cpp b/test/sensors_json_unittest.cpp new file mode 100644 index 0000000..99ab3db --- /dev/null +++ b/test/sensors_json_unittest.cpp @@ -0,0 +1,100 @@ +#include "sensors/buildjson.hpp" +#include "sensors/sensor.hpp" + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +TEST(SensorsFromJson, emptyJsonNoSensors) +{ + // If the json has no sensors, the map is empty. + + auto j2 = R"( + { + "sensors": [] + } + )"_json; + + auto output = buildSensorsFromJson(j2); + EXPECT_TRUE(output.empty()); +} + +TEST(SensorsFromJson, oneFanSensor) +{ + // If the json has one sensor, it's in the map. + + auto j2 = R"( + { + "sensors": [{ + "name": "fan1", + "type": "fan", + "readpath": "/xyz/openbmc_project/sensors/fan_tach/fan1", + "writepath": "/sys/devices/platform/ahb/ahb:apb/1e786000.pwm-tacho-controller/hwmon/**/pwm1", + "min": 0, + "max": 255 + }] + } + )"_json; + + auto output = buildSensorsFromJson(j2); + EXPECT_EQ(1, output.size()); + EXPECT_EQ(output["fan1"].type, "fan"); + EXPECT_EQ(output["fan1"].readpath, + "/xyz/openbmc_project/sensors/fan_tach/fan1"); + EXPECT_EQ(output["fan1"].writepath, + "/sys/devices/platform/ahb/ahb:apb/1e786000.pwm-tacho-controller/" + "hwmon/**/pwm1"); + EXPECT_EQ(output["fan1"].min, 0); + EXPECT_EQ(output["fan1"].max, 255); + EXPECT_EQ(output["fan1"].timeout, + Sensor::getDefaultTimeout(output["fan1"].type)); +} + +TEST(SensorsFromJson, validateOptionalFields) +{ + // The writepath, min, max, timeout fields are optional. + + auto j2 = R"( + { + "sensors": [{ + "name": "fan1", + "type": "fan", + "readpath": "/xyz/openbmc_project/sensors/fan_tach/fan1" + }] + } + )"_json; + + auto output = buildSensorsFromJson(j2); + EXPECT_EQ(1, output.size()); + EXPECT_EQ(output["fan1"].type, "fan"); + EXPECT_EQ(output["fan1"].readpath, + "/xyz/openbmc_project/sensors/fan_tach/fan1"); + EXPECT_EQ(output["fan1"].writepath, ""); + EXPECT_EQ(output["fan1"].min, 0); + EXPECT_EQ(output["fan1"].max, 0); + EXPECT_EQ(output["fan1"].timeout, + Sensor::getDefaultTimeout(output["fan1"].type)); +} + +TEST(SensorsFromJson, twoSensors) +{ + // Same as one sensor, but two. + // If a configuration has two sensors with the same name the information + // last is the information used. + + auto j2 = R"( + { + "sensors": [{ + "name": "fan1", + "type": "fan", + "readpath": "/xyz/openbmc_project/sensors/fan_tach/fan1" + }, { + "name": "fan2", + "type": "fan", + "readpath": "/xyz/openbmc_project/sensors/fan_tach/fan1" + }] + } + )"_json; + + auto output = buildSensorsFromJson(j2); + EXPECT_EQ(2, output.size()); +} |