Skip to content

Commit

Permalink
rackmon: Support non-contiguous address ranges
Browse files Browse the repository at this point in the history
Summary:
Currently rackmon assumes a register map has a single contiguous address range.
But, the ORv2 design required a non-contiguous address ranges, hence
this change.

Test Plan: Verified with gtest.

Reviewed By: amithash

Differential Revision: D52855799

fbshipit-source-id: b57475aa982e291d2fb44c6fc1e064b7f4dc6415
  • Loading branch information
jagpalgill authored and facebook-github-bot committed Jan 21, 2024
1 parent d70cb43 commit ff8a4f5
Show file tree
Hide file tree
Showing 13 changed files with 64 additions and 45 deletions.
8 changes: 4 additions & 4 deletions common/recipes-core/rackmon2/rackmon/Rackmon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ void Rackmon::loadRegisterMap(const nlohmann::json& config) {
// Precomputing this makes our scan soooo much easier.
// its 256 bytes wasted. but worth it. TODO use a
// interval list with an iterator to waste less bytes.
for (uint16_t addr = config["address_range"][0];
addr <= config["address_range"][1];
++addr) {
allPossibleDevAddrs_.push_back(uint8_t(addr));
for (auto range : config["address_range"]) {
for (uint16_t addr = range[0]; addr <= range[1]; ++addr) {
allPossibleDevAddrs_.push_back(uint8_t(addr));
}
}
nextDeviceToProbe_ = allPossibleDevAddrs_.begin();
monitorInterval_ = std::chrono::seconds(registerMapDB_.minMonitorInterval());
Expand Down
3 changes: 2 additions & 1 deletion common/recipes-core/rackmon2/rackmon/RackmonSvcUnix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ void RackmonUNIXSocketService::handleJSONCommand(
}

try {
std::string resp_s = resp.dump(-1, ' ', false, json::error_handler_t::replace);
std::string resp_s =
resp.dump(-1, ' ', false, json::error_handler_t::replace);
cli->send(resp_s.c_str(), resp_s.length());
} catch (std::exception& e) {
logError << "Unable to send response: " << e.what() << std::endl;
Expand Down
12 changes: 10 additions & 2 deletions common/recipes-core/rackmon2/rackmon/Register.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ using nlohmann::json;
namespace rackmon {

bool AddrRange::contains(uint8_t addr) const {
return addr >= range.first && addr <= range.second;
for (auto item : range) {
if (addr >= item.first && addr <= item.second) {
return true;
}
}
return false;
}

void RegisterValue::makeString(const std::vector<uint16_t>& reg) {
Expand Down Expand Up @@ -275,8 +280,11 @@ time_t RegisterMapDatabase::minMonitorInterval() const {
}

void from_json(const json& j, AddrRange& a) {
a.range = j;
for (auto& r : j) {
a.range.emplace_back(r);
}
}

void to_json(json& j, const AddrRange& a) {
j = a.range;
}
Expand Down
8 changes: 4 additions & 4 deletions common/recipes-core/rackmon2/rackmon/Register.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,11 @@ void from_json(const nlohmann::json& j, BaudrateConfig& m);
// to allow for it to be used as a key in a map --> This allows
// for us to do quick lookups of addr to register map to use.
struct AddrRange {
// pair of start and end address.
std::pair<uint8_t, uint8_t> range{};
// vector of pair of start and end address.
std::vector<std::pair<uint8_t, uint8_t>> range{};
AddrRange() = default;
explicit AddrRange(uint8_t a, uint8_t b) : range(a, b) {}
explicit AddrRange(uint8_t a) : range(a, a) {}
explicit AddrRange(const std::vector<std::pair<uint8_t, uint8_t>>& addrRange)
: range(addrRange) {}

bool contains(uint8_t) const;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"name": "ORV2_PSU",
"address_range": [
160,
191
[160, 191]
],
"probe_register": 104,
"default_baudrate": 19200,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"name": "ORV3_BBU",
"address_range": [
64,
127
[64, 127]
],
"probe_register": 8,
"default_baudrate": 19200,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"name": "ORV3_POWER_TETHER",
"address_range": [
8,
9
[8, 9]
],
"probe_register": 8,
"default_baudrate": 19200,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"name": "ORV3_PSU",
"address_range": [
192,
255
[192, 255]
],
"probe_register": 8,
"default_baudrate": 19200,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"name": "ORV3_RPU",
"address_range": [
12,
12
[12, 12]
],
"probe_register": 36864,
"default_baudrate": 19200,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@
},
"address_range": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"minItems": 1,
"maxItems": 256,
"items": {
"type": "integer",
"minimum": 0,
"maximum": 255
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"type": "integer",
"minimum": 0,
"maximum": 255
}
}
},
"probe_register": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ModbusDeviceTest : public ::testing::Test {
RegisterMap regmap;
std::string regmap_s = R"({
"name": "orv3_psu",
"address_range": [110, 140],
"address_range": [[110, 140]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 19200,
Expand Down Expand Up @@ -628,7 +628,7 @@ TEST(ModbusSpecialHandler, BasicHandlingStringValuePeriodic) {
Modbus mock_modbus{};
RegisterMap mock_rmap = R"({
"name": "orv3_psu",
"address_range": [110, 140],
"address_range": [[110, 140]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 19200,
Expand Down Expand Up @@ -686,7 +686,7 @@ TEST(ModbusSpecialHandler, BasicHandlingIntegerOneShot) {
Modbus mock_modbus{};
RegisterMap mock_rmap = R"({
"name": "orv3_psu",
"address_range": [110, 140],
"address_range": [[110, 140]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 19200,
Expand Down Expand Up @@ -742,7 +742,7 @@ TEST(ModbusSpecialHandler, BasicHandlingIntegerOneShot) {
static nlohmann::json getBaudrateRegmap() {
std::string regmap_s = R"({
"name": "orv3_psu",
"address_range": [5, 7],
"address_range": [[5, 7]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 115200,
Expand Down
6 changes: 3 additions & 3 deletions common/recipes-core/rackmon2/rackmon/tests/RackmonTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class RackmonTest : public ::testing::Test {

std::string json1 = R"({
"name": "orv2_psu",
"address_range": [160, 162],
"address_range": [[160, 162]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 19200,
Expand Down Expand Up @@ -174,7 +174,7 @@ class RackmonTest : public ::testing::Test {
TEST_F(RackmonTest, BasicLoad) {
std::string json2 = R"({
"name": "orv3_psu",
"address_range": [110, 112],
"address_range": [[110, 112]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 19200,
Expand Down Expand Up @@ -390,7 +390,7 @@ TEST_F(RackmonTest, DormantRecovery) {
})"_json;
json regmapConfig = R"({
"name": "orv2_psu",
"address_range": [161, 161],
"address_range": [[161, 161]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 19200,
Expand Down
34 changes: 22 additions & 12 deletions common/recipes-core/rackmon2/rackmon/tests/RegisterMapTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,23 @@ using namespace rackmon;
//--------------------------------------------------------

TEST(AddrRangeTest, Basic) {
AddrRange a(10, 20);
AddrRange a({{10, 20}, {25, 30}});
EXPECT_TRUE(a.contains(10));
EXPECT_TRUE(a.contains(11));
EXPECT_TRUE(a.contains(20));
EXPECT_TRUE(a.contains(19));
EXPECT_TRUE(a.contains(25));
EXPECT_TRUE(a.contains(30));
EXPECT_FALSE(a.contains(9));
EXPECT_FALSE(a.contains(21));
EXPECT_FALSE(a.contains(24));
EXPECT_FALSE(a.contains(31));
}

TEST(RegisterMapTest, JSONCoversion) {
std::string inp = R"({
"name": "orv2_psu",
"address_range": [160, 191],
"address_range": [[160, 191]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 19200,
Expand All @@ -57,8 +61,10 @@ TEST(RegisterMapTest, JSONCoversion) {
})";
nlohmann::json j = nlohmann::json::parse(inp);
RegisterMap rmap = j;
EXPECT_EQ(rmap.applicableAddresses.range.first, 160);
EXPECT_EQ(rmap.applicableAddresses.range.second, 191);
EXPECT_TRUE(std::any_of(
rmap.applicableAddresses.range.cbegin(),
rmap.applicableAddresses.range.cend(),
[](auto const& ent) { return (ent.first == 160 && ent.second == 191); }));
EXPECT_EQ(rmap.probeRegister, 104);
EXPECT_EQ(rmap.defaultBaudrate, 19200);
EXPECT_EQ(rmap.preferredBaudrate, 19200);
Expand All @@ -84,7 +90,7 @@ TEST(RegisterMapTest, JSONCoversion) {
TEST(RegisterMapTest, JSONCoversionBaudrate) {
std::string inp = R"({
"name": "orv2_psu",
"address_range": [160, 191],
"address_range": [[160, 191]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 19200,
Expand All @@ -107,8 +113,10 @@ TEST(RegisterMapTest, JSONCoversionBaudrate) {
})";
nlohmann::json j = nlohmann::json::parse(inp);
RegisterMap rmap = j;
EXPECT_EQ(rmap.applicableAddresses.range.first, 160);
EXPECT_EQ(rmap.applicableAddresses.range.second, 191);
EXPECT_TRUE(std::any_of(
rmap.applicableAddresses.range.cbegin(),
rmap.applicableAddresses.range.cend(),
[](auto const& ent) { return (ent.first == 160 && ent.second == 191); }));
EXPECT_EQ(rmap.probeRegister, 104);
EXPECT_EQ(rmap.defaultBaudrate, 19200);
EXPECT_EQ(rmap.preferredBaudrate, 19200);
Expand All @@ -126,7 +134,7 @@ TEST(RegisterMapTest, JSONCoversionBaudrate) {
TEST(RegisterMapTest, JSONCoversionSpecial) {
std::string inp = R"({
"name": "orv2_psu",
"address_range": [160, 191],
"address_range": [[160, 191]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 19200,
Expand Down Expand Up @@ -161,8 +169,10 @@ TEST(RegisterMapTest, JSONCoversionSpecial) {
})";
nlohmann::json j = nlohmann::json::parse(inp);
RegisterMap rmap = j;
EXPECT_EQ(rmap.applicableAddresses.range.first, 160);
EXPECT_EQ(rmap.applicableAddresses.range.second, 191);
EXPECT_TRUE(std::any_of(
rmap.applicableAddresses.range.cbegin(),
rmap.applicableAddresses.range.cend(),
[](auto const& ent) { return (ent.first == 160 && ent.second == 191); }));
EXPECT_EQ(rmap.probeRegister, 104);
EXPECT_EQ(rmap.defaultBaudrate, 19200);
EXPECT_EQ(rmap.preferredBaudrate, 19200);
Expand Down Expand Up @@ -192,7 +202,7 @@ class RegisterMapDatabaseTest : public ::testing::Test {
mkdir(r_test_dir.c_str(), 0755);
json1 = R"({
"name": "orv2_psu",
"address_range": [160, 191],
"address_range": [[160, 191]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 19200,
Expand All @@ -208,7 +218,7 @@ class RegisterMapDatabaseTest : public ::testing::Test {
})";
json2 = R"({
"name": "orv3_psu",
"address_range": [110, 140],
"address_range": [[110, 140]],
"probe_register": 104,
"default_baudrate": 19200,
"preferred_baudrate": 19200,
Expand Down

0 comments on commit ff8a4f5

Please sign in to comment.