blob: 17ecf4876f8c166fc7340c14e63192999d9d4707 [file] [log] [blame]
Václav Kubernát97e5ea12021-03-24 00:36:57 +01001#include <iostream>
Tomáš Pecka339bc672020-11-11 15:59:03 +01002#include "trompeloeil_doctest.h"
Václav Kubernát97e5ea12021-03-24 00:36:57 +01003#include <fstream>
4#include <future>
Tomáš Pecka339bc672020-11-11 15:59:03 +01005#include <iterator>
Václav Kubernát97e5ea12021-03-24 00:36:57 +01006#include "fs-helpers/utils.h"
7#include "ietf-hardware/FspYhPsu.h"
Tomáš Pecka339bc672020-11-11 15:59:03 +01008#include "ietf-hardware/IETFHardware.h"
Tomáš Pecka98ad18d2020-11-13 15:39:55 +01009#include "ietf-hardware/sysrepo/Sysrepo.h"
Tomáš Pecka339bc672020-11-11 15:59:03 +010010#include "mock/ietf_hardware.h"
11#include "pretty_printers.h"
12#include "test_log_setup.h"
Tomáš Pecka98ad18d2020-11-13 15:39:55 +010013#include "test_sysrepo_helpers.h"
Tomáš Pecka339bc672020-11-11 15:59:03 +010014#include "tests/configure.cmake.h"
15
16using namespace std::literals;
17
18TEST_CASE("HardwareState")
19{
20 TEST_INIT_LOGS;
Tomáš Pecka83b62e12020-12-16 14:50:49 +010021 static const auto modulePrefix = "/ietf-hardware:hardware"s;
Tomáš Pecka339bc672020-11-11 15:59:03 +010022
23 trompeloeil::sequence seq1;
Tomáš Pecka83b62e12020-12-16 14:50:49 +010024 auto ietfHardware = std::make_shared<velia::ietf_hardware::IETFHardware>();
Tomáš Pecka339bc672020-11-11 15:59:03 +010025
26 auto fans = std::make_shared<FakeHWMon>();
27 auto sysfsTempCpu = std::make_shared<FakeHWMon>();
28 auto sysfsTempFront = std::make_shared<FakeHWMon>();
29 auto sysfsTempMII0 = std::make_shared<FakeHWMon>();
30 auto sysfsTempMII1 = std::make_shared<FakeHWMon>();
Václav Kubernát97e5ea12021-03-24 00:36:57 +010031 auto sysfsVoltageAc = std::make_shared<FakeHWMon>();
32 auto sysfsVoltageDc = std::make_shared<FakeHWMon>();
33 auto sysfsPower = std::make_shared<FakeHWMon>();
34 auto sysfsCurrent = std::make_shared<FakeHWMon>();
Tomáš Pecka339bc672020-11-11 15:59:03 +010035 auto emmc = std::make_shared<FakeEMMC>();
36
37 std::map<std::string, std::string> attributesEMMC;
38 std::map<std::string, int64_t> attributesHWMon;
39
40 // initialize all mocks
41 attributesEMMC = {
42 // FIXME passing initializer_list to macro is hell
43 {"date"s, "02/2017"s},
44 {"serial"s, "0x00a8808d"s},
45 {"name"s, "8GME4R"s},
46 };
47 FAKE_EMMC(emmc, attributesEMMC);
48
49 attributesHWMon = {
50 {"fan1_input"s, 253},
51 {"fan2_input"s, 0},
52 {"fan3_input"s, 1280},
53 {"fan4_input"s, 666},
54 };
55 FAKE_HWMON(fans, attributesHWMon);
56
Václav Kubernát0dee6b92021-04-13 09:14:04 +020057 REQUIRE_CALL(*sysfsTempFront, attribute("temp1_input")).RETURN(30800);
58 REQUIRE_CALL(*sysfsTempCpu, attribute("temp1_input")).RETURN(41800);
59 REQUIRE_CALL(*sysfsTempMII0, attribute("temp1_input")).RETURN(39000);
60 REQUIRE_CALL(*sysfsTempMII1, attribute("temp1_input")).RETURN(36000);
Tomáš Pecka339bc672020-11-11 15:59:03 +010061
Václav Kubernát97e5ea12021-03-24 00:36:57 +010062 REQUIRE_CALL(*sysfsVoltageAc, attribute("in1_input")).RETURN(220000);
63 REQUIRE_CALL(*sysfsVoltageDc, attribute("in1_input")).RETURN(12000);
64 REQUIRE_CALL(*sysfsPower, attribute("power1_input")).RETURN(14000000);
65 REQUIRE_CALL(*sysfsCurrent, attribute("curr1_input")).RETURN(200);
66
Tomáš Pecka339bc672020-11-11 15:59:03 +010067 attributesEMMC = {{"life_time"s, "40"s}};
68 FAKE_EMMC(emmc, attributesEMMC);
69
Václav Kubernát6c17d0a2021-03-29 04:55:31 +020070 using velia::ietf_hardware::data_reader::SensorType;
71 using velia::ietf_hardware::data_reader::StaticData;
72 using velia::ietf_hardware::data_reader::Fans;
73 using velia::ietf_hardware::data_reader::SysfsValue;
74 using velia::ietf_hardware::data_reader::EMMC;
Tomáš Pecka339bc672020-11-11 15:59:03 +010075 // register components into hw state
Václav Kubernát6c17d0a2021-03-29 04:55:31 +020076 ietfHardware->registerDataReader(StaticData("ne", std::nullopt, {{"class", "iana-hardware:chassis"}, {"mfg-name", "CESNET"s}}));
77 ietfHardware->registerDataReader(StaticData("ne:ctrl", "ne", {{"class", "iana-hardware:module"}}));
78 ietfHardware->registerDataReader(Fans("ne:fans", "ne", fans, 4));
79 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-front", "ne:ctrl", sysfsTempFront, 1));
80 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-cpu", "ne:ctrl", sysfsTempCpu, 1));
81 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-internal-0", "ne:ctrl", sysfsTempMII0, 1));
82 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-internal-1", "ne:ctrl", sysfsTempMII1, 1));
Václav Kubernát97e5ea12021-03-24 00:36:57 +010083 ietfHardware->registerDataReader(SysfsValue<SensorType::VoltageAC>("ne:ctrl:voltage-in", "ne:ctrl", sysfsVoltageAc, 1));
84 ietfHardware->registerDataReader(SysfsValue<SensorType::VoltageDC>("ne:ctrl:voltage-out", "ne:ctrl", sysfsVoltageDc, 1));
85 ietfHardware->registerDataReader(SysfsValue<SensorType::Power>("ne:ctrl:power", "ne:ctrl", sysfsPower, 1));
86 ietfHardware->registerDataReader(SysfsValue<SensorType::Current>("ne:ctrl:current", "ne:ctrl", sysfsCurrent, 1));
Václav Kubernát6c17d0a2021-03-29 04:55:31 +020087 ietfHardware->registerDataReader(EMMC("ne:ctrl:emmc", "ne:ctrl", emmc));
Tomáš Pecka339bc672020-11-11 15:59:03 +010088
89 SECTION("Test HardwareState without sysrepo")
90 {
91 std::map<std::string, std::string> expected = {
Tomáš Pecka83b62e12020-12-16 14:50:49 +010092 {"/ietf-hardware:hardware/component[name='ne']/class", "iana-hardware:chassis"},
93 {"/ietf-hardware:hardware/component[name='ne']/mfg-name", "CESNET"},
Tomáš Pecka339bc672020-11-11 15:59:03 +010094
Tomáš Pecka83b62e12020-12-16 14:50:49 +010095 {"/ietf-hardware:hardware/component[name='ne:fans']/class", "iana-hardware:module"},
96 {"/ietf-hardware:hardware/component[name='ne:fans']/parent", "ne"},
97 {"/ietf-hardware:hardware/component[name='ne:fans:fan1']/class", "iana-hardware:fan"},
98 {"/ietf-hardware:hardware/component[name='ne:fans:fan1']/parent", "ne:fans"},
99 {"/ietf-hardware:hardware/component[name='ne:fans:fan1:rpm']/class", "iana-hardware:sensor"},
100 {"/ietf-hardware:hardware/component[name='ne:fans:fan1:rpm']/parent", "ne:fans:fan1"},
101 {"/ietf-hardware:hardware/component[name='ne:fans:fan1:rpm']/sensor-data/oper-status", "ok"},
102 {"/ietf-hardware:hardware/component[name='ne:fans:fan1:rpm']/sensor-data/value", "253"},
103 {"/ietf-hardware:hardware/component[name='ne:fans:fan1:rpm']/sensor-data/value-precision", "0"},
104 {"/ietf-hardware:hardware/component[name='ne:fans:fan1:rpm']/sensor-data/value-scale", "units"},
105 {"/ietf-hardware:hardware/component[name='ne:fans:fan1:rpm']/sensor-data/value-type", "rpm"},
106 {"/ietf-hardware:hardware/component[name='ne:fans:fan2']/class", "iana-hardware:fan"},
107 {"/ietf-hardware:hardware/component[name='ne:fans:fan2']/parent", "ne:fans"},
108 {"/ietf-hardware:hardware/component[name='ne:fans:fan2:rpm']/class", "iana-hardware:sensor"},
109 {"/ietf-hardware:hardware/component[name='ne:fans:fan2:rpm']/parent", "ne:fans:fan2"},
110 {"/ietf-hardware:hardware/component[name='ne:fans:fan2:rpm']/sensor-data/oper-status", "ok"},
111 {"/ietf-hardware:hardware/component[name='ne:fans:fan2:rpm']/sensor-data/value", "0"},
112 {"/ietf-hardware:hardware/component[name='ne:fans:fan2:rpm']/sensor-data/value-precision", "0"},
113 {"/ietf-hardware:hardware/component[name='ne:fans:fan2:rpm']/sensor-data/value-scale", "units"},
114 {"/ietf-hardware:hardware/component[name='ne:fans:fan2:rpm']/sensor-data/value-type", "rpm"},
115 {"/ietf-hardware:hardware/component[name='ne:fans:fan3']/class", "iana-hardware:fan"},
116 {"/ietf-hardware:hardware/component[name='ne:fans:fan3']/parent", "ne:fans"},
117 {"/ietf-hardware:hardware/component[name='ne:fans:fan3:rpm']/class", "iana-hardware:sensor"},
118 {"/ietf-hardware:hardware/component[name='ne:fans:fan3:rpm']/parent", "ne:fans:fan3"},
119 {"/ietf-hardware:hardware/component[name='ne:fans:fan3:rpm']/sensor-data/oper-status", "ok"},
120 {"/ietf-hardware:hardware/component[name='ne:fans:fan3:rpm']/sensor-data/value", "1280"},
121 {"/ietf-hardware:hardware/component[name='ne:fans:fan3:rpm']/sensor-data/value-precision", "0"},
122 {"/ietf-hardware:hardware/component[name='ne:fans:fan3:rpm']/sensor-data/value-scale", "units"},
123 {"/ietf-hardware:hardware/component[name='ne:fans:fan3:rpm']/sensor-data/value-type", "rpm"},
124 {"/ietf-hardware:hardware/component[name='ne:fans:fan4']/class", "iana-hardware:fan"},
125 {"/ietf-hardware:hardware/component[name='ne:fans:fan4']/parent", "ne:fans"},
126 {"/ietf-hardware:hardware/component[name='ne:fans:fan4:rpm']/class", "iana-hardware:sensor"},
127 {"/ietf-hardware:hardware/component[name='ne:fans:fan4:rpm']/parent", "ne:fans:fan4"},
128 {"/ietf-hardware:hardware/component[name='ne:fans:fan4:rpm']/sensor-data/oper-status", "ok"},
129 {"/ietf-hardware:hardware/component[name='ne:fans:fan4:rpm']/sensor-data/value", "666"},
130 {"/ietf-hardware:hardware/component[name='ne:fans:fan4:rpm']/sensor-data/value-precision", "0"},
131 {"/ietf-hardware:hardware/component[name='ne:fans:fan4:rpm']/sensor-data/value-scale", "units"},
132 {"/ietf-hardware:hardware/component[name='ne:fans:fan4:rpm']/sensor-data/value-type", "rpm"},
Tomáš Pecka339bc672020-11-11 15:59:03 +0100133
Tomáš Pecka83b62e12020-12-16 14:50:49 +0100134 {"/ietf-hardware:hardware/component[name='ne:ctrl']/parent", "ne"},
135 {"/ietf-hardware:hardware/component[name='ne:ctrl']/class", "iana-hardware:module"},
Tomáš Pecka339bc672020-11-11 15:59:03 +0100136
Tomáš Pecka83b62e12020-12-16 14:50:49 +0100137 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-cpu']/class", "iana-hardware:sensor"},
138 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-cpu']/parent", "ne:ctrl"},
139 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-cpu']/sensor-data/oper-status", "ok"},
140 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-cpu']/sensor-data/value", "41800"},
141 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-cpu']/sensor-data/value-precision", "0"},
142 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-cpu']/sensor-data/value-scale", "milli"},
143 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-cpu']/sensor-data/value-type", "celsius"},
144 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-front']/class", "iana-hardware:sensor"},
145 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-front']/parent", "ne:ctrl"},
146 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-front']/sensor-data/oper-status", "ok"},
147 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-front']/sensor-data/value", "30800"},
148 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-front']/sensor-data/value-precision", "0"},
149 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-front']/sensor-data/value-scale", "milli"},
150 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-front']/sensor-data/value-type", "celsius"},
151 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-0']/class", "iana-hardware:sensor"},
152 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-0']/parent", "ne:ctrl"},
153 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-0']/sensor-data/oper-status", "ok"},
154 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-0']/sensor-data/value", "39000"},
155 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-0']/sensor-data/value-precision", "0"},
156 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-0']/sensor-data/value-scale", "milli"},
157 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-0']/sensor-data/value-type", "celsius"},
158 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-1']/class", "iana-hardware:sensor"},
159 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-1']/parent", "ne:ctrl"},
160 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-1']/sensor-data/oper-status", "ok"},
161 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-1']/sensor-data/value", "36000"},
162 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-1']/sensor-data/value-precision", "0"},
163 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-1']/sensor-data/value-scale", "milli"},
164 {"/ietf-hardware:hardware/component[name='ne:ctrl:temperature-internal-1']/sensor-data/value-type", "celsius"},
Tomáš Pecka339bc672020-11-11 15:59:03 +0100165
Václav Kubernát97e5ea12021-03-24 00:36:57 +0100166 {"/ietf-hardware:hardware/component[name='ne:ctrl:power']/class", "iana-hardware:sensor"},
167 {"/ietf-hardware:hardware/component[name='ne:ctrl:power']/parent", "ne:ctrl"},
168 {"/ietf-hardware:hardware/component[name='ne:ctrl:power']/sensor-data/oper-status", "ok"},
169 {"/ietf-hardware:hardware/component[name='ne:ctrl:power']/sensor-data/value", "14000000"},
170 {"/ietf-hardware:hardware/component[name='ne:ctrl:power']/sensor-data/value-precision", "0"},
171 {"/ietf-hardware:hardware/component[name='ne:ctrl:power']/sensor-data/value-scale", "micro"},
172 {"/ietf-hardware:hardware/component[name='ne:ctrl:power']/sensor-data/value-type", "watts"},
173
174 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-in']/class", "iana-hardware:sensor"},
175 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-in']/parent", "ne:ctrl"},
176 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-in']/sensor-data/oper-status", "ok"},
177 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-in']/sensor-data/value", "220000"},
178 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-in']/sensor-data/value-precision", "0"},
179 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-in']/sensor-data/value-scale", "micro"},
180 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-in']/sensor-data/value-type", "volts-AC"},
181 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-out']/class", "iana-hardware:sensor"},
182 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-out']/parent", "ne:ctrl"},
183 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-out']/sensor-data/oper-status", "ok"},
184 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-out']/sensor-data/value", "12000"},
185 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-out']/sensor-data/value-precision", "0"},
186 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-out']/sensor-data/value-scale", "micro"},
187 {"/ietf-hardware:hardware/component[name='ne:ctrl:voltage-out']/sensor-data/value-type", "volts-DC"},
188
189 {"/ietf-hardware:hardware/component[name='ne:ctrl:current']/class", "iana-hardware:sensor"},
190 {"/ietf-hardware:hardware/component[name='ne:ctrl:current']/parent", "ne:ctrl"},
191 {"/ietf-hardware:hardware/component[name='ne:ctrl:current']/sensor-data/oper-status", "ok"},
192 {"/ietf-hardware:hardware/component[name='ne:ctrl:current']/sensor-data/value", "200"},
193 {"/ietf-hardware:hardware/component[name='ne:ctrl:current']/sensor-data/value-precision", "0"},
194 {"/ietf-hardware:hardware/component[name='ne:ctrl:current']/sensor-data/value-scale", "milli"},
195 {"/ietf-hardware:hardware/component[name='ne:ctrl:current']/sensor-data/value-type", "amperes"},
196
Tomáš Pecka83b62e12020-12-16 14:50:49 +0100197 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc']/parent", "ne:ctrl"},
198 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc']/class", "iana-hardware:module"},
199 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc']/serial-num", "0x00a8808d"},
200 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc']/mfg-date", "2017-02-01T00:00:00Z"},
201 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc']/model-name", "8GME4R"},
202 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc:lifetime']/class", "iana-hardware:sensor"},
203 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc:lifetime']/parent", "ne:ctrl:emmc"},
204 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc:lifetime']/sensor-data/oper-status", "ok"},
205 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc:lifetime']/sensor-data/value", "40"},
206 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc:lifetime']/sensor-data/value-precision", "0"},
207 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc:lifetime']/sensor-data/value-scale", "units"},
208 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc:lifetime']/sensor-data/value-type", "other"},
209 {"/ietf-hardware:hardware/component[name='ne:ctrl:emmc:lifetime']/sensor-data/units-display", "percent"},
Tomáš Pecka339bc672020-11-11 15:59:03 +0100210 };
211
212 // exclude last-change node
Tomáš Pecka83b62e12020-12-16 14:50:49 +0100213 auto result = ietfHardware->process();
Tomáš Pecka339bc672020-11-11 15:59:03 +0100214 result.erase(modulePrefix + "/last-change");
215 REQUIRE(result == expected);
216 }
Tomáš Pecka98ad18d2020-11-13 15:39:55 +0100217
Tomáš Pecka83b62e12020-12-16 14:50:49 +0100218 SECTION("Test IETF Hardware from sysrepo's view")
Tomáš Pecka98ad18d2020-11-13 15:39:55 +0100219 {
220 TEST_SYSREPO_INIT_LOGS;
Tomáš Pecka749af2e2021-01-14 09:52:09 +0100221 TEST_SYSREPO_INIT;
222 TEST_SYSREPO_INIT_CLIENT;
Tomáš Pecka98ad18d2020-11-13 15:39:55 +0100223
Tomáš Pecka83b62e12020-12-16 14:50:49 +0100224 auto ietfHardwareSysrepo = std::make_shared<velia::ietf_hardware::sysrepo::Sysrepo>(srSubs, ietfHardware);
Tomáš Pecka98ad18d2020-11-13 15:39:55 +0100225
226 SECTION("test last-change")
227 {
228 // at least check that there is some timestamp
Tomáš Pecka749af2e2021-01-14 09:52:09 +0100229 REQUIRE(dataFromSysrepo(client, modulePrefix, SR_DS_OPERATIONAL).count("/last-change") > 0);
Tomáš Pecka98ad18d2020-11-13 15:39:55 +0100230 }
231
232 SECTION("test components")
233 {
234 std::map<std::string, std::string> expected = {
235 {"[name='ne']/name", "ne"},
236 {"[name='ne']/class", "iana-hardware:chassis"},
237 {"[name='ne']/mfg-name", "CESNET"},
238 {"[name='ne']/sensor-data", ""},
239
240 {"[name='ne:fans']/class", "iana-hardware:module"},
241 {"[name='ne:fans']/name", "ne:fans"},
242 {"[name='ne:fans']/parent", "ne"},
243 {"[name='ne:fans']/sensor-data", ""},
244 {"[name='ne:fans:fan1']/class", "iana-hardware:fan"},
245 {"[name='ne:fans:fan1']/name", "ne:fans:fan1"},
246 {"[name='ne:fans:fan1']/parent", "ne:fans"},
247 {"[name='ne:fans:fan1']/sensor-data", ""},
248 {"[name='ne:fans:fan1:rpm']/class", "iana-hardware:sensor"},
249 {"[name='ne:fans:fan1:rpm']/name", "ne:fans:fan1:rpm"},
250 {"[name='ne:fans:fan1:rpm']/parent", "ne:fans:fan1"},
251 {"[name='ne:fans:fan1:rpm']/sensor-data", ""},
252 {"[name='ne:fans:fan1:rpm']/sensor-data/oper-status", "ok"},
253 {"[name='ne:fans:fan1:rpm']/sensor-data/value", "253"},
254 {"[name='ne:fans:fan1:rpm']/sensor-data/value-precision", "0"},
255 {"[name='ne:fans:fan1:rpm']/sensor-data/value-scale", "units"},
256 {"[name='ne:fans:fan1:rpm']/sensor-data/value-type", "rpm"},
257 {"[name='ne:fans:fan2']/class", "iana-hardware:fan"},
258 {"[name='ne:fans:fan2']/name", "ne:fans:fan2"},
259 {"[name='ne:fans:fan2']/parent", "ne:fans"},
260 {"[name='ne:fans:fan2']/sensor-data", ""},
261 {"[name='ne:fans:fan2:rpm']/class", "iana-hardware:sensor"},
262 {"[name='ne:fans:fan2:rpm']/name", "ne:fans:fan2:rpm"},
263 {"[name='ne:fans:fan2:rpm']/parent", "ne:fans:fan2"},
264 {"[name='ne:fans:fan2:rpm']/sensor-data", ""},
265 {"[name='ne:fans:fan2:rpm']/sensor-data/oper-status", "ok"},
266 {"[name='ne:fans:fan2:rpm']/sensor-data/value", "0"},
267 {"[name='ne:fans:fan2:rpm']/sensor-data/value-precision", "0"},
268 {"[name='ne:fans:fan2:rpm']/sensor-data/value-scale", "units"},
269 {"[name='ne:fans:fan2:rpm']/sensor-data/value-type", "rpm"},
270 {"[name='ne:fans:fan3']/class", "iana-hardware:fan"},
271 {"[name='ne:fans:fan3']/name", "ne:fans:fan3"},
272 {"[name='ne:fans:fan3']/parent", "ne:fans"},
273 {"[name='ne:fans:fan3']/sensor-data", ""},
274 {"[name='ne:fans:fan3:rpm']/class", "iana-hardware:sensor"},
275 {"[name='ne:fans:fan3:rpm']/name", "ne:fans:fan3:rpm"},
276 {"[name='ne:fans:fan3:rpm']/parent", "ne:fans:fan3"},
277 {"[name='ne:fans:fan3:rpm']/sensor-data", ""},
278 {"[name='ne:fans:fan3:rpm']/sensor-data/oper-status", "ok"},
279 {"[name='ne:fans:fan3:rpm']/sensor-data/value", "1280"},
280 {"[name='ne:fans:fan3:rpm']/sensor-data/value-precision", "0"},
281 {"[name='ne:fans:fan3:rpm']/sensor-data/value-scale", "units"},
282 {"[name='ne:fans:fan3:rpm']/sensor-data/value-type", "rpm"},
283 {"[name='ne:fans:fan4']/class", "iana-hardware:fan"},
284 {"[name='ne:fans:fan4']/name", "ne:fans:fan4"},
285 {"[name='ne:fans:fan4']/parent", "ne:fans"},
286 {"[name='ne:fans:fan4']/sensor-data", ""},
287 {"[name='ne:fans:fan4:rpm']/class", "iana-hardware:sensor"},
288 {"[name='ne:fans:fan4:rpm']/name", "ne:fans:fan4:rpm"},
289 {"[name='ne:fans:fan4:rpm']/parent", "ne:fans:fan4"},
290 {"[name='ne:fans:fan4:rpm']/sensor-data", ""},
291 {"[name='ne:fans:fan4:rpm']/sensor-data/oper-status", "ok"},
292 {"[name='ne:fans:fan4:rpm']/sensor-data/value", "666"},
293 {"[name='ne:fans:fan4:rpm']/sensor-data/value-precision", "0"},
294 {"[name='ne:fans:fan4:rpm']/sensor-data/value-scale", "units"},
295 {"[name='ne:fans:fan4:rpm']/sensor-data/value-type", "rpm"},
296
297 {"[name='ne:ctrl']/name", "ne:ctrl"},
298 {"[name='ne:ctrl']/parent", "ne"},
299 {"[name='ne:ctrl']/class", "iana-hardware:module"},
300 {"[name='ne:ctrl']/sensor-data", ""},
301
302 {"[name='ne:ctrl:temperature-cpu']/name", "ne:ctrl:temperature-cpu"},
303 {"[name='ne:ctrl:temperature-cpu']/class", "iana-hardware:sensor"},
304 {"[name='ne:ctrl:temperature-cpu']/parent", "ne:ctrl"},
305 {"[name='ne:ctrl:temperature-cpu']/sensor-data", ""},
306 {"[name='ne:ctrl:temperature-cpu']/sensor-data/oper-status", "ok"},
307 {"[name='ne:ctrl:temperature-cpu']/sensor-data/value", "41800"},
308 {"[name='ne:ctrl:temperature-cpu']/sensor-data/value-precision", "0"},
309 {"[name='ne:ctrl:temperature-cpu']/sensor-data/value-scale", "milli"},
310 {"[name='ne:ctrl:temperature-cpu']/sensor-data/value-type", "celsius"},
311 {"[name='ne:ctrl:temperature-front']/name", "ne:ctrl:temperature-front"},
312 {"[name='ne:ctrl:temperature-front']/class", "iana-hardware:sensor"},
313 {"[name='ne:ctrl:temperature-front']/parent", "ne:ctrl"},
314 {"[name='ne:ctrl:temperature-front']/sensor-data", ""},
315 {"[name='ne:ctrl:temperature-front']/sensor-data/oper-status", "ok"},
316 {"[name='ne:ctrl:temperature-front']/sensor-data/value", "30800"},
317 {"[name='ne:ctrl:temperature-front']/sensor-data/value-precision", "0"},
318 {"[name='ne:ctrl:temperature-front']/sensor-data/value-scale", "milli"},
319 {"[name='ne:ctrl:temperature-front']/sensor-data/value-type", "celsius"},
320 {"[name='ne:ctrl:temperature-internal-0']/name", "ne:ctrl:temperature-internal-0"},
321 {"[name='ne:ctrl:temperature-internal-0']/class", "iana-hardware:sensor"},
322 {"[name='ne:ctrl:temperature-internal-0']/parent", "ne:ctrl"},
323 {"[name='ne:ctrl:temperature-internal-0']/sensor-data", ""},
324 {"[name='ne:ctrl:temperature-internal-0']/sensor-data/oper-status", "ok"},
325 {"[name='ne:ctrl:temperature-internal-0']/sensor-data/value", "39000"},
326 {"[name='ne:ctrl:temperature-internal-0']/sensor-data/value-precision", "0"},
327 {"[name='ne:ctrl:temperature-internal-0']/sensor-data/value-scale", "milli"},
328 {"[name='ne:ctrl:temperature-internal-0']/sensor-data/value-type", "celsius"},
329 {"[name='ne:ctrl:temperature-internal-1']/name", "ne:ctrl:temperature-internal-1"},
330 {"[name='ne:ctrl:temperature-internal-1']/class", "iana-hardware:sensor"},
331 {"[name='ne:ctrl:temperature-internal-1']/parent", "ne:ctrl"},
332 {"[name='ne:ctrl:temperature-internal-1']/sensor-data", ""},
333 {"[name='ne:ctrl:temperature-internal-1']/sensor-data/oper-status", "ok"},
334 {"[name='ne:ctrl:temperature-internal-1']/sensor-data/value", "36000"},
335 {"[name='ne:ctrl:temperature-internal-1']/sensor-data/value-precision", "0"},
336 {"[name='ne:ctrl:temperature-internal-1']/sensor-data/value-scale", "milli"},
337 {"[name='ne:ctrl:temperature-internal-1']/sensor-data/value-type", "celsius"},
338
Václav Kubernát97e5ea12021-03-24 00:36:57 +0100339 {"[name='ne:ctrl:power']/name", "ne:ctrl:power"},
340 {"[name='ne:ctrl:power']/class", "iana-hardware:sensor"},
341 {"[name='ne:ctrl:power']/parent", "ne:ctrl"},
342 {"[name='ne:ctrl:power']/sensor-data", ""},
343 {"[name='ne:ctrl:power']/sensor-data/oper-status", "ok"},
344 {"[name='ne:ctrl:power']/sensor-data/value", "14000000"},
345 {"[name='ne:ctrl:power']/sensor-data/value-precision", "0"},
346 {"[name='ne:ctrl:power']/sensor-data/value-scale", "micro"},
347 {"[name='ne:ctrl:power']/sensor-data/value-type", "watts"},
348
349 {"[name='ne:ctrl:voltage-in']/name", "ne:ctrl:voltage-in"},
350 {"[name='ne:ctrl:voltage-in']/class", "iana-hardware:sensor"},
351 {"[name='ne:ctrl:voltage-in']/parent", "ne:ctrl"},
352 {"[name='ne:ctrl:voltage-in']/sensor-data", ""},
353 {"[name='ne:ctrl:voltage-in']/sensor-data/oper-status", "ok"},
354 {"[name='ne:ctrl:voltage-in']/sensor-data/value", "220000"},
355 {"[name='ne:ctrl:voltage-in']/sensor-data/value-precision", "0"},
356 {"[name='ne:ctrl:voltage-in']/sensor-data/value-scale", "micro"},
357 {"[name='ne:ctrl:voltage-in']/sensor-data/value-type", "volts-AC"},
358 {"[name='ne:ctrl:voltage-out']/name", "ne:ctrl:voltage-out"},
359 {"[name='ne:ctrl:voltage-out']/class", "iana-hardware:sensor"},
360 {"[name='ne:ctrl:voltage-out']/parent", "ne:ctrl"},
361 {"[name='ne:ctrl:voltage-out']/sensor-data", ""},
362 {"[name='ne:ctrl:voltage-out']/sensor-data/oper-status", "ok"},
363 {"[name='ne:ctrl:voltage-out']/sensor-data/value", "12000"},
364 {"[name='ne:ctrl:voltage-out']/sensor-data/value-precision", "0"},
365 {"[name='ne:ctrl:voltage-out']/sensor-data/value-scale", "micro"},
366 {"[name='ne:ctrl:voltage-out']/sensor-data/value-type", "volts-DC"},
367
368 {"[name='ne:ctrl:current']/name", "ne:ctrl:current"},
369 {"[name='ne:ctrl:current']/class", "iana-hardware:sensor"},
370 {"[name='ne:ctrl:current']/parent", "ne:ctrl"},
371 {"[name='ne:ctrl:current']/sensor-data", ""},
372 {"[name='ne:ctrl:current']/sensor-data/oper-status", "ok"},
373 {"[name='ne:ctrl:current']/sensor-data/value", "200"},
374 {"[name='ne:ctrl:current']/sensor-data/value-precision", "0"},
375 {"[name='ne:ctrl:current']/sensor-data/value-scale", "milli"},
376 {"[name='ne:ctrl:current']/sensor-data/value-type", "amperes"},
377
Tomáš Pecka98ad18d2020-11-13 15:39:55 +0100378 {"[name='ne:ctrl:emmc']/name", "ne:ctrl:emmc"},
379 {"[name='ne:ctrl:emmc']/parent", "ne:ctrl"},
380 {"[name='ne:ctrl:emmc']/class", "iana-hardware:module"},
381 {"[name='ne:ctrl:emmc']/serial-num", "0x00a8808d"},
382 {"[name='ne:ctrl:emmc']/mfg-date", "2017-02-01T00:00:00Z"},
383 {"[name='ne:ctrl:emmc']/model-name", "8GME4R"},
384 {"[name='ne:ctrl:emmc']/sensor-data", ""},
385 {"[name='ne:ctrl:emmc:lifetime']/name", "ne:ctrl:emmc:lifetime"},
386 {"[name='ne:ctrl:emmc:lifetime']/class", "iana-hardware:sensor"},
387 {"[name='ne:ctrl:emmc:lifetime']/parent", "ne:ctrl:emmc"},
388 {"[name='ne:ctrl:emmc:lifetime']/sensor-data", ""},
389 {"[name='ne:ctrl:emmc:lifetime']/sensor-data/oper-status", "ok"},
390 {"[name='ne:ctrl:emmc:lifetime']/sensor-data/value", "40"},
391 {"[name='ne:ctrl:emmc:lifetime']/sensor-data/value-precision", "0"},
392 {"[name='ne:ctrl:emmc:lifetime']/sensor-data/value-scale", "units"},
393 {"[name='ne:ctrl:emmc:lifetime']/sensor-data/value-type", "other"},
394 {"[name='ne:ctrl:emmc:lifetime']/sensor-data/units-display", "percent"},
395 };
396
Tomáš Pecka749af2e2021-01-14 09:52:09 +0100397 REQUIRE(dataFromSysrepo(client, modulePrefix + "/component", SR_DS_OPERATIONAL) == expected);
Tomáš Pecka98ad18d2020-11-13 15:39:55 +0100398 }
399
400 SECTION("test leafnode query")
401 {
402 const auto xpath = modulePrefix + "/component[name='ne:ctrl:emmc:lifetime']/class";
Tomáš Pecka749af2e2021-01-14 09:52:09 +0100403 client->session_switch_ds(SR_DS_OPERATIONAL);
404 auto val = client->get_item(xpath.c_str());
405 client->session_switch_ds(SR_DS_RUNNING);
Tomáš Pecka98ad18d2020-11-13 15:39:55 +0100406 REQUIRE(!!val);
407 REQUIRE(val->data()->get_identityref() == "iana-hardware:sensor"s);
408 }
409 }
Tomáš Pecka339bc672020-11-11 15:59:03 +0100410}
Václav Kubernát97e5ea12021-03-24 00:36:57 +0100411
412class FakeI2C : public velia::ietf_hardware::TransientI2C {
413public:
414 FakeI2C(const std::string& fakeHwmonRoot)
415 : TransientI2C({}, {}, {})
416 , m_fakeHwmonRoot(fakeHwmonRoot)
417 {
418 }
419
420 MAKE_CONST_MOCK0(isPresent, bool(), override);
421 MAKE_CONST_MOCK0(bind_mock, void());
422 MAKE_CONST_MOCK0(unbind_mock, void());
423
424 void removeHwmonFile(const std::string& name) const
425 {
426 std::filesystem::remove(m_fakeHwmonRoot / ("hwmon" + std::to_string(m_hwmonNo)) / name);
427 }
428
429 void bind() const override
430 {
431 bind_mock();
432 removeDirectoryTreeIfExists(m_fakeHwmonRoot);
433 std::filesystem::create_directory(m_fakeHwmonRoot);
434 std::filesystem::create_directory(m_fakeHwmonRoot / ("hwmon" + std::to_string(m_hwmonNo)));
435
436 for (const auto& filename : {"name", "temp1_input", "temp2_input", "curr1_input", "curr2_input", "curr3_input",
437 "in1_input", "in2_input", "in3_input", "power1_input", "power2_input", "fan1_input"} )
438 {
439 std::ofstream ofs(m_fakeHwmonRoot / ("hwmon" + std::to_string(m_hwmonNo)) / filename);
440 // I don't really care about the values here, I just need the HWMon class to think that the files exist.
441 ofs << 0 << "\n";
442 }
443 }
444 void unbind() const override
445 {
446 unbind_mock();
447 removeDirectoryTreeIfExists(m_fakeHwmonRoot);
448 m_hwmonNo++;
449 }
450
451private:
452
453 std::filesystem::path m_fakeHwmonRoot;
454 mutable std::atomic<int> m_hwmonNo = 1;
455};
456
457TEST_CASE("FspYhPsu")
458{
459 TEST_INIT_LOGS;
460 std::atomic<int> counter = 0;
461 const auto fakeHwmonRoot = CMAKE_CURRENT_BINARY_DIR + "/tests/psu"s;
462 removeDirectoryTreeIfExists(fakeHwmonRoot);
463 auto fakeI2c = std::make_shared<FakeI2C>(fakeHwmonRoot);
464 trompeloeil::sequence seq1;
465 std::shared_ptr<velia::ietf_hardware::FspYhPsu> psu;
466 std::vector<std::unique_ptr<trompeloeil::expectation>> expectations;
467
468 auto i2cPresence = [&counter] {
469 switch (counter) {
470 case 0:
471 case 2:
472 case 4:
473 return false;
474 case 1:
475 case 3:
476 return true;
477 }
478
479 REQUIRE(false);
480 __builtin_unreachable();
481 };
482
483 ALLOW_CALL(*fakeI2c, isPresent()).LR_RETURN(i2cPresence());
484 REQUIRE_CALL(*fakeI2c, bind_mock()).LR_WITH(counter == 1).IN_SEQUENCE(seq1);
485 REQUIRE_CALL(*fakeI2c, unbind_mock()).LR_WITH(counter == 2).IN_SEQUENCE(seq1);
486 REQUIRE_CALL(*fakeI2c, bind_mock()).LR_WITH(counter == 3).IN_SEQUENCE(seq1);
487 REQUIRE_CALL(*fakeI2c, unbind_mock()).LR_WITH(counter == 4).IN_SEQUENCE(seq1);
488
489 psu = std::make_shared<velia::ietf_hardware::FspYhPsu>(fakeHwmonRoot, "psu", fakeI2c);
490
491 for (auto i : {0, 1, 2, 3, 4}) {
492 std::this_thread::sleep_for(std::chrono::seconds(4));
493 velia::ietf_hardware::DataTree expected;
494
495 switch (i) {
496 case 0:
497 break;
498 case 1:
499 expected = {
500 {"/ietf-hardware:hardware/component[name='ne:psu']/class", "iana-hardware:power-supply"},
501 {"/ietf-hardware:hardware/component[name='ne:psu']/parent", "ne"},
502 {"/ietf-hardware:hardware/component[name='ne:psu:current-12V']/class", "iana-hardware:sensor"},
503 {"/ietf-hardware:hardware/component[name='ne:psu:current-12V']/parent", "ne:psu"},
504 {"/ietf-hardware:hardware/component[name='ne:psu:current-12V']/sensor-data/oper-status", "ok"},
505 {"/ietf-hardware:hardware/component[name='ne:psu:current-12V']/sensor-data/value", "0"},
506 {"/ietf-hardware:hardware/component[name='ne:psu:current-12V']/sensor-data/value-precision", "0"},
507 {"/ietf-hardware:hardware/component[name='ne:psu:current-12V']/sensor-data/value-scale", "milli"},
508 {"/ietf-hardware:hardware/component[name='ne:psu:current-12V']/sensor-data/value-type", "amperes"},
509 {"/ietf-hardware:hardware/component[name='ne:psu:current-5Vsb']/class", "iana-hardware:sensor"},
510 {"/ietf-hardware:hardware/component[name='ne:psu:current-5Vsb']/parent", "ne:psu"},
511 {"/ietf-hardware:hardware/component[name='ne:psu:current-5Vsb']/sensor-data/oper-status", "ok"},
512 {"/ietf-hardware:hardware/component[name='ne:psu:current-5Vsb']/sensor-data/value", "0"},
513 {"/ietf-hardware:hardware/component[name='ne:psu:current-5Vsb']/sensor-data/value-precision", "0"},
514 {"/ietf-hardware:hardware/component[name='ne:psu:current-5Vsb']/sensor-data/value-scale", "milli"},
515 {"/ietf-hardware:hardware/component[name='ne:psu:current-5Vsb']/sensor-data/value-type", "amperes"},
516 {"/ietf-hardware:hardware/component[name='ne:psu:current-in']/class", "iana-hardware:sensor"},
517 {"/ietf-hardware:hardware/component[name='ne:psu:current-in']/parent", "ne:psu"},
518 {"/ietf-hardware:hardware/component[name='ne:psu:current-in']/sensor-data/oper-status", "ok"},
519 {"/ietf-hardware:hardware/component[name='ne:psu:current-in']/sensor-data/value", "0"},
520 {"/ietf-hardware:hardware/component[name='ne:psu:current-in']/sensor-data/value-precision", "0"},
521 {"/ietf-hardware:hardware/component[name='ne:psu:current-in']/sensor-data/value-scale", "milli"},
522 {"/ietf-hardware:hardware/component[name='ne:psu:current-in']/sensor-data/value-type", "amperes"},
523 {"/ietf-hardware:hardware/component[name='ne:psu:fan']/class", "iana-hardware:module"},
524 {"/ietf-hardware:hardware/component[name='ne:psu:fan']/parent", "ne:psu"},
525 {"/ietf-hardware:hardware/component[name='ne:psu:fan:fan1']/class", "iana-hardware:fan"},
526 {"/ietf-hardware:hardware/component[name='ne:psu:fan:fan1']/parent", "ne:psu:fan"},
527 {"/ietf-hardware:hardware/component[name='ne:psu:fan:fan1:rpm']/class", "iana-hardware:sensor"},
528 {"/ietf-hardware:hardware/component[name='ne:psu:fan:fan1:rpm']/parent", "ne:psu:fan:fan1"},
529 {"/ietf-hardware:hardware/component[name='ne:psu:fan:fan1:rpm']/sensor-data/oper-status", "ok"},
530 {"/ietf-hardware:hardware/component[name='ne:psu:fan:fan1:rpm']/sensor-data/value", "0"},
531 {"/ietf-hardware:hardware/component[name='ne:psu:fan:fan1:rpm']/sensor-data/value-precision", "0"},
532 {"/ietf-hardware:hardware/component[name='ne:psu:fan:fan1:rpm']/sensor-data/value-scale", "units"},
533 {"/ietf-hardware:hardware/component[name='ne:psu:fan:fan1:rpm']/sensor-data/value-type", "rpm"},
534 {"/ietf-hardware:hardware/component[name='ne:psu:power-in']/class", "iana-hardware:sensor"},
535 {"/ietf-hardware:hardware/component[name='ne:psu:power-in']/parent", "ne:psu"},
536 {"/ietf-hardware:hardware/component[name='ne:psu:power-in']/sensor-data/oper-status", "ok"},
537 {"/ietf-hardware:hardware/component[name='ne:psu:power-in']/sensor-data/value", "0"},
538 {"/ietf-hardware:hardware/component[name='ne:psu:power-in']/sensor-data/value-precision", "0"},
539 {"/ietf-hardware:hardware/component[name='ne:psu:power-in']/sensor-data/value-scale", "micro"},
540 {"/ietf-hardware:hardware/component[name='ne:psu:power-in']/sensor-data/value-type", "watts"},
541 {"/ietf-hardware:hardware/component[name='ne:psu:power-out']/class", "iana-hardware:sensor"},
542 {"/ietf-hardware:hardware/component[name='ne:psu:power-out']/parent", "ne:psu"},
543 {"/ietf-hardware:hardware/component[name='ne:psu:power-out']/sensor-data/oper-status", "ok"},
544 {"/ietf-hardware:hardware/component[name='ne:psu:power-out']/sensor-data/value", "0"},
545 {"/ietf-hardware:hardware/component[name='ne:psu:power-out']/sensor-data/value-precision", "0"},
546 {"/ietf-hardware:hardware/component[name='ne:psu:power-out']/sensor-data/value-scale", "micro"},
547 {"/ietf-hardware:hardware/component[name='ne:psu:power-out']/sensor-data/value-type", "watts"},
548 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-1']/class", "iana-hardware:sensor"},
549 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-1']/parent", "ne:psu"},
550 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-1']/sensor-data/oper-status", "ok"},
551 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-1']/sensor-data/value", "0"},
552 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-1']/sensor-data/value-precision", "0"},
553 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-1']/sensor-data/value-scale", "milli"},
554 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-1']/sensor-data/value-type", "celsius"},
555 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-2']/class", "iana-hardware:sensor"},
556 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-2']/parent", "ne:psu"},
557 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-2']/sensor-data/oper-status", "ok"},
558 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-2']/sensor-data/value", "0"},
559 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-2']/sensor-data/value-precision", "0"},
560 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-2']/sensor-data/value-scale", "milli"},
561 {"/ietf-hardware:hardware/component[name='ne:psu:temperature-2']/sensor-data/value-type", "celsius"},
562 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-12V']/class", "iana-hardware:sensor"},
563 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-12V']/parent", "ne:psu"},
564 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-12V']/sensor-data/oper-status", "ok"},
565 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-12V']/sensor-data/value", "0"},
566 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-12V']/sensor-data/value-precision", "0"},
567 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-12V']/sensor-data/value-scale", "micro"},
568 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-12V']/sensor-data/value-type", "volts-DC"},
569 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-5Vsb']/class", "iana-hardware:sensor"},
570 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-5Vsb']/parent", "ne:psu"},
571 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-5Vsb']/sensor-data/oper-status", "ok"},
572 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-5Vsb']/sensor-data/value", "0"},
573 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-5Vsb']/sensor-data/value-precision", "0"},
574 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-5Vsb']/sensor-data/value-scale", "micro"},
575 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-5Vsb']/sensor-data/value-type", "volts-DC"},
576 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-in']/class", "iana-hardware:sensor"},
577 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-in']/parent", "ne:psu"},
578 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-in']/sensor-data/oper-status", "ok"},
579 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-in']/sensor-data/value", "0"},
580 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-in']/sensor-data/value-precision", "0"},
581 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-in']/sensor-data/value-scale", "micro"},
582 {"/ietf-hardware:hardware/component[name='ne:psu:voltage-in']/sensor-data/value-type", "volts-AC"},
583 };
584 break;
585 case 2:
586 break;
587 case 3:
588 // Here I simulate read failure by a file from the hwmon directory. This happens when the user wants data from
589 // a PSU that's no longer there and the watcher thread didn't unbind it yet.
590 fakeI2c->removeHwmonFile("temp1_input");
591 break;
592 case 4:
593 break;
594 }
595
596 REQUIRE(psu->readValues() == expected);
597
598 counter++;
599 }
600
601 waitForCompletionAndBitMore(seq1);
602}