blob: 8593b97e5bf11989f6d850241909dba1ad059d8d [file] [log] [blame]
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07001#include "pid/ec/pid.hpp"
Patrick Venturea58197c2018-06-11 15:29:45 -07002#include "pid/zone.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07003#include "sensors/manager.hpp"
4#include "test/controller_mock.hpp"
5#include "test/helpers.hpp"
6#include "test/sensor_mock.hpp"
Patrick Venturea58197c2018-06-11 15:29:45 -07007
Patrick Venturea83a3ec2020-08-04 09:52:05 -07008#include <sdbusplus/test/sdbus_mock.hpp>
9
Patrick Venturea58197c2018-06-11 15:29:45 -070010#include <chrono>
11#include <cstring>
Patrick Venturea58197c2018-06-11 15:29:45 -070012#include <vector>
13
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070014#include <gmock/gmock.h>
15#include <gtest/gtest.h>
Patrick Venturea58197c2018-06-11 15:29:45 -070016
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070017using ::testing::_;
Patrick Venturea58197c2018-06-11 15:29:45 -070018using ::testing::IsNull;
19using ::testing::Return;
20using ::testing::StrEq;
Patrick Venturea58197c2018-06-11 15:29:45 -070021
22static std::string modeInterface = "xyz.openbmc_project.Control.Mode";
23
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070024namespace
25{
Patrick Venturea58197c2018-06-11 15:29:45 -070026
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070027TEST(PidZoneConstructorTest, BoringConstructorTest)
28{
Patrick Venturea58197c2018-06-11 15:29:45 -070029 // Build a PID Zone.
30
31 sdbusplus::SdBusMock sdbus_mock_passive, sdbus_mock_host, sdbus_mock_mode;
32 auto bus_mock_passive = sdbusplus::get_mocked_new(&sdbus_mock_passive);
33 auto bus_mock_host = sdbusplus::get_mocked_new(&sdbus_mock_host);
34 auto bus_mock_mode = sdbusplus::get_mocked_new(&sdbus_mock_mode);
35
36 EXPECT_CALL(sdbus_mock_host,
37 sd_bus_add_object_manager(
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070038 IsNull(), _, StrEq("/xyz/openbmc_project/extsensors")))
Patrick Venturea58197c2018-06-11 15:29:45 -070039 .WillOnce(Return(0));
40
James Feist1fe08952019-05-07 09:17:16 -070041 SensorManager m(bus_mock_passive, bus_mock_host);
Patrick Venturea58197c2018-06-11 15:29:45 -070042
43 bool defer = true;
Patrick Venturee2ec0f62018-09-04 12:30:27 -070044 const char* objPath = "/path/";
Patrick Venturea58197c2018-06-11 15:29:45 -070045 int64_t zone = 1;
James Feist3484bed2019-02-25 13:28:18 -080046 double minThermalOutput = 1000.0;
Patrick Venture5f59c0f2018-11-11 12:55:14 -080047 double failSafePercent = 0.75;
Patrick Venturea58197c2018-06-11 15:29:45 -070048
James Feist0709e2f2020-07-08 10:59:45 -070049 double d;
Patrick Venturea58197c2018-06-11 15:29:45 -070050 std::vector<std::string> properties;
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070051 SetupDbusObject(&sdbus_mock_mode, defer, objPath, modeInterface, properties,
James Feist0709e2f2020-07-08 10:59:45 -070052 &d);
Patrick Venturea58197c2018-06-11 15:29:45 -070053
James Feist3484bed2019-02-25 13:28:18 -080054 PIDZone p(zone, minThermalOutput, failSafePercent, m, bus_mock_mode,
55 objPath, defer);
Patrick Venturea58197c2018-06-11 15:29:45 -070056 // Success.
57}
58
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070059} // namespace
Patrick Venturea58197c2018-06-11 15:29:45 -070060
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070061class PidZoneTest : public ::testing::Test
62{
63 protected:
64 PidZoneTest() :
65 property_index(), properties(), sdbus_mock_passive(), sdbus_mock_host(),
66 sdbus_mock_mode()
67 {
68 EXPECT_CALL(sdbus_mock_host,
69 sd_bus_add_object_manager(
70 IsNull(), _, StrEq("/xyz/openbmc_project/extsensors")))
71 .WillOnce(Return(0));
Patrick Venturea58197c2018-06-11 15:29:45 -070072
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070073 auto bus_mock_passive = sdbusplus::get_mocked_new(&sdbus_mock_passive);
74 auto bus_mock_host = sdbusplus::get_mocked_new(&sdbus_mock_host);
75 auto bus_mock_mode = sdbusplus::get_mocked_new(&sdbus_mock_mode);
Patrick Venturea58197c2018-06-11 15:29:45 -070076
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070077 // Compiler weirdly not happy about just instantiating mgr(...);
James Feist1fe08952019-05-07 09:17:16 -070078 SensorManager m(bus_mock_passive, bus_mock_host);
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070079 mgr = std::move(m);
Patrick Venturea58197c2018-06-11 15:29:45 -070080
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070081 SetupDbusObject(&sdbus_mock_mode, defer, objPath, modeInterface,
82 properties, &property_index);
Patrick Venturea58197c2018-06-11 15:29:45 -070083
James Feist3484bed2019-02-25 13:28:18 -080084 zone =
85 std::make_unique<PIDZone>(zoneId, minThermalOutput, failSafePercent,
86 mgr, bus_mock_mode, objPath, defer);
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070087 }
Patrick Venturea58197c2018-06-11 15:29:45 -070088
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070089 // unused
James Feist0709e2f2020-07-08 10:59:45 -070090 double property_index;
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070091 std::vector<std::string> properties;
Patrick Venturea58197c2018-06-11 15:29:45 -070092
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070093 sdbusplus::SdBusMock sdbus_mock_passive;
94 sdbusplus::SdBusMock sdbus_mock_host;
95 sdbusplus::SdBusMock sdbus_mock_mode;
96 int64_t zoneId = 1;
James Feist3484bed2019-02-25 13:28:18 -080097 double minThermalOutput = 1000.0;
Patrick Venture5f59c0f2018-11-11 12:55:14 -080098 double failSafePercent = 0.75;
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070099 bool defer = true;
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700100 const char* objPath = "/path/";
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700101 SensorManager mgr;
Patrick Venturea58197c2018-06-11 15:29:45 -0700102
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700103 std::unique_ptr<PIDZone> zone;
Patrick Venturea58197c2018-06-11 15:29:45 -0700104};
105
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700106TEST_F(PidZoneTest, GetZoneId_ReturnsExpected)
107{
Patrick Venturea58197c2018-06-11 15:29:45 -0700108 // Verifies the zoneId returned is what we expect.
109
Patrick Venture0bbeaf82018-10-30 18:50:31 -0700110 EXPECT_EQ(zoneId, zone->getZoneID());
Patrick Venturea58197c2018-06-11 15:29:45 -0700111}
112
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700113TEST_F(PidZoneTest, GetAndSetManualModeTest_BehavesAsExpected)
114{
Patrick Venturea58197c2018-06-11 15:29:45 -0700115 // Verifies that the zone starts in manual mode. Verifies that one can set
116 // the mode.
117 EXPECT_FALSE(zone->getManualMode());
118
119 zone->setManualMode(true);
120 EXPECT_TRUE(zone->getManualMode());
121}
122
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700123TEST_F(PidZoneTest, RpmSetPoints_AddMaxClear_BehaveAsExpected)
124{
Patrick Venturef7a2dd52019-07-16 14:31:13 -0700125 // Tests addSetPoint, clearSetPoints, determineMaxSetPointRequest
126 // and getMinThermalSetpoint.
Patrick Venturea58197c2018-06-11 15:29:45 -0700127
128 // At least one value must be above the minimum thermal setpoint used in
129 // the constructor otherwise it'll choose that value
Patrick Venture5f59c0f2018-11-11 12:55:14 -0800130 std::vector<double> values = {100, 200, 300, 400, 500, 5000};
Patrick Venturea58197c2018-06-11 15:29:45 -0700131 for (auto v : values)
132 {
Patrick Venture9bbf3332019-07-16 10:50:37 -0700133 zone->addSetPoint(v);
Patrick Venturea58197c2018-06-11 15:29:45 -0700134 }
135
136 // This will pull the maximum RPM setpoint request.
Patrick Venturef7a2dd52019-07-16 14:31:13 -0700137 zone->determineMaxSetPointRequest();
138 EXPECT_EQ(5000, zone->getMaxSetPointRequest());
Patrick Venturea58197c2018-06-11 15:29:45 -0700139
140 // Clear the values, so it'll choose the minimum thermal setpoint.
Patrick Venture9bbf3332019-07-16 10:50:37 -0700141 zone->clearSetPoints();
Patrick Venturea58197c2018-06-11 15:29:45 -0700142
143 // This will go through the RPM set point values and grab the maximum.
Patrick Venturef7a2dd52019-07-16 14:31:13 -0700144 zone->determineMaxSetPointRequest();
145 EXPECT_EQ(zone->getMinThermalSetpoint(), zone->getMaxSetPointRequest());
Patrick Venturea58197c2018-06-11 15:29:45 -0700146}
147
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700148TEST_F(PidZoneTest, RpmSetPoints_AddBelowMinimum_BehavesAsExpected)
149{
Patrick Venturea58197c2018-06-11 15:29:45 -0700150 // Tests adding several RPM setpoints, however, they're all lower than the
Patrick Venture7280e272019-02-11 10:45:32 -0800151 // configured minimal thermal setpoint RPM value.
Patrick Venturea58197c2018-06-11 15:29:45 -0700152
Patrick Venture5f59c0f2018-11-11 12:55:14 -0800153 std::vector<double> values = {100, 200, 300, 400, 500};
Patrick Venturea58197c2018-06-11 15:29:45 -0700154 for (auto v : values)
155 {
Patrick Venture9bbf3332019-07-16 10:50:37 -0700156 zone->addSetPoint(v);
Patrick Venturea58197c2018-06-11 15:29:45 -0700157 }
158
159 // This will pull the maximum RPM setpoint request.
Patrick Venturef7a2dd52019-07-16 14:31:13 -0700160 zone->determineMaxSetPointRequest();
Patrick Venturea58197c2018-06-11 15:29:45 -0700161
162 // Verifies the value returned in the minimal thermal rpm set point.
Patrick Venturef7a2dd52019-07-16 14:31:13 -0700163 EXPECT_EQ(zone->getMinThermalSetpoint(), zone->getMaxSetPointRequest());
Patrick Venturea58197c2018-06-11 15:29:45 -0700164}
165
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700166TEST_F(PidZoneTest, GetFailSafePercent_ReturnsExpected)
167{
Patrick Venturea58197c2018-06-11 15:29:45 -0700168 // Verify the value used to create the object is stored.
169 EXPECT_EQ(failSafePercent, zone->getFailSafePercent());
170}
171
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700172TEST_F(PidZoneTest, ThermalInputs_FailsafeToValid_ReadsSensors)
173{
Patrick Venturea58197c2018-06-11 15:29:45 -0700174 // This test will add a couple thermal inputs, and verify that the zone
175 // initializes into failsafe mode, and will read each sensor.
176
177 std::string name1 = "temp1";
178 int64_t timeout = 1;
179
180 std::unique_ptr<Sensor> sensor1 =
181 std::make_unique<SensorMock>(name1, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700182 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700183
184 std::string name2 = "temp2";
185 std::unique_ptr<Sensor> sensor2 =
186 std::make_unique<SensorMock>(name2, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700187 SensorMock* sensor_ptr2 = reinterpret_cast<SensorMock*>(sensor2.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700188
189 std::string type = "unchecked";
190 mgr.addSensor(type, name1, std::move(sensor1));
191 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
192 mgr.addSensor(type, name2, std::move(sensor2));
193 EXPECT_EQ(mgr.getSensor(name2), sensor_ptr2);
194
195 // Now that the sensors exist, add them to the zone.
196 zone->addThermalInput(name1);
197 zone->addThermalInput(name2);
198
199 // Initialize Zone
200 zone->initializeCache();
201
202 // Verify now in failsafe mode.
203 EXPECT_TRUE(zone->getFailSafeMode());
204
205 ReadReturn r1;
206 r1.value = 10.0;
207 r1.updated = std::chrono::high_resolution_clock::now();
208 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
209
210 ReadReturn r2;
211 r2.value = 11.0;
212 r2.updated = std::chrono::high_resolution_clock::now();
213 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
214
215 // Read the sensors, this will put the values into the cache.
216 zone->updateSensors();
217
218 // We should no longer be in failsafe mode.
219 EXPECT_FALSE(zone->getFailSafeMode());
220
221 EXPECT_EQ(r1.value, zone->getCachedValue(name1));
222 EXPECT_EQ(r2.value, zone->getCachedValue(name2));
223}
224
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700225TEST_F(PidZoneTest, FanInputTest_VerifiesFanValuesCached)
226{
Patrick Venturea58197c2018-06-11 15:29:45 -0700227 // This will add a couple fan inputs, and verify the values are cached.
228
229 std::string name1 = "fan1";
230 int64_t timeout = 2;
231
232 std::unique_ptr<Sensor> sensor1 =
233 std::make_unique<SensorMock>(name1, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700234 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700235
236 std::string name2 = "fan2";
237 std::unique_ptr<Sensor> sensor2 =
238 std::make_unique<SensorMock>(name2, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700239 SensorMock* sensor_ptr2 = reinterpret_cast<SensorMock*>(sensor2.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700240
241 std::string type = "unchecked";
242 mgr.addSensor(type, name1, std::move(sensor1));
243 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
244 mgr.addSensor(type, name2, std::move(sensor2));
245 EXPECT_EQ(mgr.getSensor(name2), sensor_ptr2);
246
247 // Now that the sensors exist, add them to the zone.
248 zone->addFanInput(name1);
249 zone->addFanInput(name2);
250
251 // Initialize Zone
252 zone->initializeCache();
253
254 ReadReturn r1;
255 r1.value = 10.0;
256 r1.updated = std::chrono::high_resolution_clock::now();
257 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
258
259 ReadReturn r2;
260 r2.value = 11.0;
261 r2.updated = std::chrono::high_resolution_clock::now();
262 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
263
264 // Method under test will read through each fan sensor for the zone and
265 // cache the values.
266 zone->updateFanTelemetry();
267
268 EXPECT_EQ(r1.value, zone->getCachedValue(name1));
269 EXPECT_EQ(r2.value, zone->getCachedValue(name2));
270}
271
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700272TEST_F(PidZoneTest, ThermalInput_ValueTimeoutEntersFailSafeMode)
273{
Patrick Venturea58197c2018-06-11 15:29:45 -0700274 // On the second updateSensors call, the updated timestamp will be beyond
275 // the timeout limit.
276
277 int64_t timeout = 1;
278
279 std::string name1 = "temp1";
280 std::unique_ptr<Sensor> sensor1 =
281 std::make_unique<SensorMock>(name1, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700282 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700283
284 std::string name2 = "temp2";
285 std::unique_ptr<Sensor> sensor2 =
286 std::make_unique<SensorMock>(name2, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700287 SensorMock* sensor_ptr2 = reinterpret_cast<SensorMock*>(sensor2.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700288
289 std::string type = "unchecked";
290 mgr.addSensor(type, name1, std::move(sensor1));
291 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
292 mgr.addSensor(type, name2, std::move(sensor2));
293 EXPECT_EQ(mgr.getSensor(name2), sensor_ptr2);
294
295 zone->addThermalInput(name1);
296 zone->addThermalInput(name2);
297
298 // Initialize Zone
299 zone->initializeCache();
300
301 // Verify now in failsafe mode.
302 EXPECT_TRUE(zone->getFailSafeMode());
303
304 ReadReturn r1;
305 r1.value = 10.0;
306 r1.updated = std::chrono::high_resolution_clock::now();
307 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
308
309 ReadReturn r2;
310 r2.value = 11.0;
311 r2.updated = std::chrono::high_resolution_clock::now();
312 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
313
314 zone->updateSensors();
315 EXPECT_FALSE(zone->getFailSafeMode());
316
317 // Ok, so we're not in failsafe mode, so let's set updated to the past.
318 // sensor1 will have an updated field older than its timeout value, but
319 // sensor2 will be fine. :D
320 r1.updated -= std::chrono::seconds(3);
321 r2.updated = std::chrono::high_resolution_clock::now();
322
323 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
324 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
325
326 // Method under test will read each sensor. One sensor's value is older
327 // than the timeout for that sensor and this triggers failsafe mode.
328 zone->updateSensors();
329 EXPECT_TRUE(zone->getFailSafeMode());
330}
331
Will Liangded0ab52019-05-15 17:10:06 +0800332TEST_F(PidZoneTest, FanInputTest_FailsafeToValid_ReadsSensors)
333{
334 // This will add a couple fan inputs, and verify the values are cached.
335
336 std::string name1 = "fan1";
337 int64_t timeout = 2;
338
339 std::unique_ptr<Sensor> sensor1 =
340 std::make_unique<SensorMock>(name1, timeout);
341 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
342
343 std::string name2 = "fan2";
344 std::unique_ptr<Sensor> sensor2 =
345 std::make_unique<SensorMock>(name2, timeout);
346 SensorMock* sensor_ptr2 = reinterpret_cast<SensorMock*>(sensor2.get());
347
348 std::string type = "unchecked";
349 mgr.addSensor(type, name1, std::move(sensor1));
350 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
351 mgr.addSensor(type, name2, std::move(sensor2));
352 EXPECT_EQ(mgr.getSensor(name2), sensor_ptr2);
353
354 // Now that the sensors exist, add them to the zone.
355 zone->addFanInput(name1);
356 zone->addFanInput(name2);
357
358 // Initialize Zone
359 zone->initializeCache();
360
361 // Verify now in failsafe mode.
362 EXPECT_TRUE(zone->getFailSafeMode());
363
364 ReadReturn r1;
365 r1.value = 10.0;
366 r1.updated = std::chrono::high_resolution_clock::now();
367 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
368
369 ReadReturn r2;
370 r2.value = 11.0;
371 r2.updated = std::chrono::high_resolution_clock::now();
372 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
373
374 // Method under test will read through each fan sensor for the zone and
375 // cache the values.
376 zone->updateFanTelemetry();
377
378 // We should no longer be in failsafe mode.
379 EXPECT_FALSE(zone->getFailSafeMode());
380
381 EXPECT_EQ(r1.value, zone->getCachedValue(name1));
382 EXPECT_EQ(r2.value, zone->getCachedValue(name2));
383}
384
385TEST_F(PidZoneTest, FanInputTest_ValueTimeoutEntersFailSafeMode)
386{
387 // This will add a couple fan inputs, and verify the values are cached.
388
389 std::string name1 = "fan1";
390 int64_t timeout = 2;
391
392 std::unique_ptr<Sensor> sensor1 =
393 std::make_unique<SensorMock>(name1, timeout);
394 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
395
396 std::string name2 = "fan2";
397 std::unique_ptr<Sensor> sensor2 =
398 std::make_unique<SensorMock>(name2, timeout);
399 SensorMock* sensor_ptr2 = reinterpret_cast<SensorMock*>(sensor2.get());
400
401 std::string type = "unchecked";
402 mgr.addSensor(type, name1, std::move(sensor1));
403 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
404 mgr.addSensor(type, name2, std::move(sensor2));
405 EXPECT_EQ(mgr.getSensor(name2), sensor_ptr2);
406
407 // Now that the sensors exist, add them to the zone.
408 zone->addFanInput(name1);
409 zone->addFanInput(name2);
410
411 // Initialize Zone
412 zone->initializeCache();
413
414 // Verify now in failsafe mode.
415 EXPECT_TRUE(zone->getFailSafeMode());
416
417 ReadReturn r1;
418 r1.value = 10.0;
419 r1.updated = std::chrono::high_resolution_clock::now();
420 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
421
422 ReadReturn r2;
423 r2.value = 11.0;
424 r2.updated = std::chrono::high_resolution_clock::now();
425 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
426
427 // Method under test will read through each fan sensor for the zone and
428 // cache the values.
429 zone->updateFanTelemetry();
430
431 // We should no longer be in failsafe mode.
432 EXPECT_FALSE(zone->getFailSafeMode());
433
434 r1.updated -= std::chrono::seconds(3);
435 r2.updated = std::chrono::high_resolution_clock::now();
436
437 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
438 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
439
440 zone->updateFanTelemetry();
441 EXPECT_TRUE(zone->getFailSafeMode());
442}
443
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700444TEST_F(PidZoneTest, GetSensorTest_ReturnsExpected)
445{
Patrick Venturea58197c2018-06-11 15:29:45 -0700446 // One can grab a sensor from the manager through the zone.
447
448 int64_t timeout = 1;
449
450 std::string name1 = "temp1";
451 std::unique_ptr<Sensor> sensor1 =
452 std::make_unique<SensorMock>(name1, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700453 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700454
455 std::string type = "unchecked";
456 mgr.addSensor(type, name1, std::move(sensor1));
457 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
458
459 zone->addThermalInput(name1);
460
461 // Verify method under test returns the pointer we expect.
462 EXPECT_EQ(mgr.getSensor(name1), zone->getSensor(name1));
463}
464
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700465TEST_F(PidZoneTest, AddThermalPIDTest_VerifiesThermalPIDsProcessed)
466{
Patrick Venturea58197c2018-06-11 15:29:45 -0700467 // Tests adding a thermal PID controller to the zone, and verifies it's
468 // touched during processing.
469
470 std::unique_ptr<PIDController> tpid =
471 std::make_unique<ControllerMock>("thermal1", zone.get());
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700472 ControllerMock* tmock = reinterpret_cast<ControllerMock*>(tpid.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700473
474 // Access the internal pid configuration to clear it out (unrelated to the
475 // test).
Patrick Venture563a3562018-10-30 09:31:26 -0700476 ec::pid_info_t* info = tpid->getPIDInfo();
Patrick Venturea58197c2018-06-11 15:29:45 -0700477 std::memset(info, 0x00, sizeof(ec::pid_info_t));
478
479 zone->addThermalPID(std::move(tpid));
480
Patrick Venture563a3562018-10-30 09:31:26 -0700481 EXPECT_CALL(*tmock, setptProc()).WillOnce(Return(10.0));
482 EXPECT_CALL(*tmock, inputProc()).WillOnce(Return(11.0));
483 EXPECT_CALL(*tmock, outputProc(_));
Patrick Venturea58197c2018-06-11 15:29:45 -0700484
485 // Method under test will, for each thermal PID, call setpt, input, and
486 // output.
Patrick Venture563a3562018-10-30 09:31:26 -0700487 zone->processThermals();
Patrick Venturea58197c2018-06-11 15:29:45 -0700488}
489
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700490TEST_F(PidZoneTest, AddFanPIDTest_VerifiesFanPIDsProcessed)
491{
Patrick Venturea58197c2018-06-11 15:29:45 -0700492 // Tests adding a fan PID controller to the zone, and verifies it's
493 // touched during processing.
494
495 std::unique_ptr<PIDController> tpid =
496 std::make_unique<ControllerMock>("fan1", zone.get());
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700497 ControllerMock* tmock = reinterpret_cast<ControllerMock*>(tpid.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700498
499 // Access the internal pid configuration to clear it out (unrelated to the
500 // test).
Patrick Venture563a3562018-10-30 09:31:26 -0700501 ec::pid_info_t* info = tpid->getPIDInfo();
Patrick Venturea58197c2018-06-11 15:29:45 -0700502 std::memset(info, 0x00, sizeof(ec::pid_info_t));
503
504 zone->addFanPID(std::move(tpid));
505
Patrick Venture563a3562018-10-30 09:31:26 -0700506 EXPECT_CALL(*tmock, setptProc()).WillOnce(Return(10.0));
507 EXPECT_CALL(*tmock, inputProc()).WillOnce(Return(11.0));
508 EXPECT_CALL(*tmock, outputProc(_));
Patrick Venturea58197c2018-06-11 15:29:45 -0700509
510 // Method under test will, for each fan PID, call setpt, input, and output.
Patrick Venture563a3562018-10-30 09:31:26 -0700511 zone->processFans();
Patrick Venturea58197c2018-06-11 15:29:45 -0700512}
513
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700514TEST_F(PidZoneTest, ManualModeDbusTest_VerifySetManualBehavesAsExpected)
515{
Patrick Venturea58197c2018-06-11 15:29:45 -0700516 // The manual(bool) method is inherited from the dbus mode interface.
517
518 // Verifies that someone doesn't remove the internal call to the dbus
519 // object from which we're inheriting.
520 EXPECT_CALL(sdbus_mock_mode,
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700521 sd_bus_emit_properties_changed_strv(
522 IsNull(), StrEq(objPath), StrEq(modeInterface), NotNull()))
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700523 .WillOnce(Invoke([&](sd_bus* bus, const char* path,
524 const char* interface, char** names) {
Patrick Venturea58197c2018-06-11 15:29:45 -0700525 EXPECT_STREQ("Manual", names[0]);
526 return 0;
527 }));
528
529 // Method under test will set the manual mode to true and broadcast this
530 // change on dbus.
531 zone->manual(true);
532 EXPECT_TRUE(zone->getManualMode());
533}
534
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700535TEST_F(PidZoneTest, FailsafeDbusTest_VerifiesReturnsExpected)
536{
Patrick Venturea58197c2018-06-11 15:29:45 -0700537 // This property is implemented by us as read-only, such that trying to
538 // write to it will have no effect.
539 EXPECT_EQ(zone->failSafe(), zone->getFailSafeMode());
540}