blob: 5da10f89b43c50a60559042c16c2afb005f75362 [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
8#include <chrono>
9#include <cstring>
Patrick Venturea58197c2018-06-11 15:29:45 -070010#include <sdbusplus/test/sdbus_mock.hpp>
11#include <vector>
12
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070013#include <gmock/gmock.h>
14#include <gtest/gtest.h>
Patrick Venturea58197c2018-06-11 15:29:45 -070015
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070016using ::testing::_;
Patrick Venturea58197c2018-06-11 15:29:45 -070017using ::testing::IsNull;
18using ::testing::Return;
19using ::testing::StrEq;
Patrick Venturea58197c2018-06-11 15:29:45 -070020
21static std::string modeInterface = "xyz.openbmc_project.Control.Mode";
22
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070023namespace
24{
Patrick Venturea58197c2018-06-11 15:29:45 -070025
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070026TEST(PidZoneConstructorTest, BoringConstructorTest)
27{
Patrick Venturea58197c2018-06-11 15:29:45 -070028 // Build a PID Zone.
29
30 sdbusplus::SdBusMock sdbus_mock_passive, sdbus_mock_host, sdbus_mock_mode;
31 auto bus_mock_passive = sdbusplus::get_mocked_new(&sdbus_mock_passive);
32 auto bus_mock_host = sdbusplus::get_mocked_new(&sdbus_mock_host);
33 auto bus_mock_mode = sdbusplus::get_mocked_new(&sdbus_mock_mode);
34
35 EXPECT_CALL(sdbus_mock_host,
36 sd_bus_add_object_manager(
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070037 IsNull(), _, StrEq("/xyz/openbmc_project/extsensors")))
Patrick Venturea58197c2018-06-11 15:29:45 -070038 .WillOnce(Return(0));
39
James Feist1fe08952019-05-07 09:17:16 -070040 SensorManager m(bus_mock_passive, bus_mock_host);
Patrick Venturea58197c2018-06-11 15:29:45 -070041
42 bool defer = true;
Patrick Venturee2ec0f62018-09-04 12:30:27 -070043 const char* objPath = "/path/";
Patrick Venturea58197c2018-06-11 15:29:45 -070044 int64_t zone = 1;
James Feist3484bed2019-02-25 13:28:18 -080045 double minThermalOutput = 1000.0;
Patrick Venture5f59c0f2018-11-11 12:55:14 -080046 double failSafePercent = 0.75;
Patrick Venturea58197c2018-06-11 15:29:45 -070047
48 int i;
49 std::vector<std::string> properties;
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070050 SetupDbusObject(&sdbus_mock_mode, defer, objPath, modeInterface, properties,
51 &i);
Patrick Venturea58197c2018-06-11 15:29:45 -070052
James Feist3484bed2019-02-25 13:28:18 -080053 PIDZone p(zone, minThermalOutput, failSafePercent, m, bus_mock_mode,
54 objPath, defer);
Patrick Venturea58197c2018-06-11 15:29:45 -070055 // Success.
56}
57
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070058} // namespace
Patrick Venturea58197c2018-06-11 15:29:45 -070059
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070060class PidZoneTest : public ::testing::Test
61{
62 protected:
63 PidZoneTest() :
64 property_index(), properties(), sdbus_mock_passive(), sdbus_mock_host(),
65 sdbus_mock_mode()
66 {
67 EXPECT_CALL(sdbus_mock_host,
68 sd_bus_add_object_manager(
69 IsNull(), _, StrEq("/xyz/openbmc_project/extsensors")))
70 .WillOnce(Return(0));
Patrick Venturea58197c2018-06-11 15:29:45 -070071
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070072 auto bus_mock_passive = sdbusplus::get_mocked_new(&sdbus_mock_passive);
73 auto bus_mock_host = sdbusplus::get_mocked_new(&sdbus_mock_host);
74 auto bus_mock_mode = sdbusplus::get_mocked_new(&sdbus_mock_mode);
Patrick Venturea58197c2018-06-11 15:29:45 -070075
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070076 // Compiler weirdly not happy about just instantiating mgr(...);
James Feist1fe08952019-05-07 09:17:16 -070077 SensorManager m(bus_mock_passive, bus_mock_host);
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070078 mgr = std::move(m);
Patrick Venturea58197c2018-06-11 15:29:45 -070079
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070080 SetupDbusObject(&sdbus_mock_mode, defer, objPath, modeInterface,
81 properties, &property_index);
Patrick Venturea58197c2018-06-11 15:29:45 -070082
James Feist3484bed2019-02-25 13:28:18 -080083 zone =
84 std::make_unique<PIDZone>(zoneId, minThermalOutput, failSafePercent,
85 mgr, bus_mock_mode, objPath, defer);
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070086 }
Patrick Venturea58197c2018-06-11 15:29:45 -070087
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070088 // unused
89 int property_index;
90 std::vector<std::string> properties;
Patrick Venturea58197c2018-06-11 15:29:45 -070091
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070092 sdbusplus::SdBusMock sdbus_mock_passive;
93 sdbusplus::SdBusMock sdbus_mock_host;
94 sdbusplus::SdBusMock sdbus_mock_mode;
95 int64_t zoneId = 1;
James Feist3484bed2019-02-25 13:28:18 -080096 double minThermalOutput = 1000.0;
Patrick Venture5f59c0f2018-11-11 12:55:14 -080097 double failSafePercent = 0.75;
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070098 bool defer = true;
Patrick Venturee2ec0f62018-09-04 12:30:27 -070099 const char* objPath = "/path/";
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700100 SensorManager mgr;
Patrick Venturea58197c2018-06-11 15:29:45 -0700101
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700102 std::unique_ptr<PIDZone> zone;
Patrick Venturea58197c2018-06-11 15:29:45 -0700103};
104
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700105TEST_F(PidZoneTest, GetZoneId_ReturnsExpected)
106{
Patrick Venturea58197c2018-06-11 15:29:45 -0700107 // Verifies the zoneId returned is what we expect.
108
Patrick Venture0bbeaf82018-10-30 18:50:31 -0700109 EXPECT_EQ(zoneId, zone->getZoneID());
Patrick Venturea58197c2018-06-11 15:29:45 -0700110}
111
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700112TEST_F(PidZoneTest, GetAndSetManualModeTest_BehavesAsExpected)
113{
Patrick Venturea58197c2018-06-11 15:29:45 -0700114 // Verifies that the zone starts in manual mode. Verifies that one can set
115 // the mode.
116 EXPECT_FALSE(zone->getManualMode());
117
118 zone->setManualMode(true);
119 EXPECT_TRUE(zone->getManualMode());
120}
121
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700122TEST_F(PidZoneTest, RpmSetPoints_AddMaxClear_BehaveAsExpected)
123{
Patrick Venturef7a2dd52019-07-16 14:31:13 -0700124 // Tests addSetPoint, clearSetPoints, determineMaxSetPointRequest
125 // and getMinThermalSetpoint.
Patrick Venturea58197c2018-06-11 15:29:45 -0700126
127 // At least one value must be above the minimum thermal setpoint used in
128 // the constructor otherwise it'll choose that value
Patrick Venture5f59c0f2018-11-11 12:55:14 -0800129 std::vector<double> values = {100, 200, 300, 400, 500, 5000};
Patrick Venturea58197c2018-06-11 15:29:45 -0700130 for (auto v : values)
131 {
Patrick Venture9bbf3332019-07-16 10:50:37 -0700132 zone->addSetPoint(v);
Patrick Venturea58197c2018-06-11 15:29:45 -0700133 }
134
135 // This will pull the maximum RPM setpoint request.
Patrick Venturef7a2dd52019-07-16 14:31:13 -0700136 zone->determineMaxSetPointRequest();
137 EXPECT_EQ(5000, zone->getMaxSetPointRequest());
Patrick Venturea58197c2018-06-11 15:29:45 -0700138
139 // Clear the values, so it'll choose the minimum thermal setpoint.
Patrick Venture9bbf3332019-07-16 10:50:37 -0700140 zone->clearSetPoints();
Patrick Venturea58197c2018-06-11 15:29:45 -0700141
142 // This will go through the RPM set point values and grab the maximum.
Patrick Venturef7a2dd52019-07-16 14:31:13 -0700143 zone->determineMaxSetPointRequest();
144 EXPECT_EQ(zone->getMinThermalSetpoint(), zone->getMaxSetPointRequest());
Patrick Venturea58197c2018-06-11 15:29:45 -0700145}
146
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700147TEST_F(PidZoneTest, RpmSetPoints_AddBelowMinimum_BehavesAsExpected)
148{
Patrick Venturea58197c2018-06-11 15:29:45 -0700149 // Tests adding several RPM setpoints, however, they're all lower than the
Patrick Venture7280e272019-02-11 10:45:32 -0800150 // configured minimal thermal setpoint RPM value.
Patrick Venturea58197c2018-06-11 15:29:45 -0700151
Patrick Venture5f59c0f2018-11-11 12:55:14 -0800152 std::vector<double> values = {100, 200, 300, 400, 500};
Patrick Venturea58197c2018-06-11 15:29:45 -0700153 for (auto v : values)
154 {
Patrick Venture9bbf3332019-07-16 10:50:37 -0700155 zone->addSetPoint(v);
Patrick Venturea58197c2018-06-11 15:29:45 -0700156 }
157
158 // This will pull the maximum RPM setpoint request.
Patrick Venturef7a2dd52019-07-16 14:31:13 -0700159 zone->determineMaxSetPointRequest();
Patrick Venturea58197c2018-06-11 15:29:45 -0700160
161 // Verifies the value returned in the minimal thermal rpm set point.
Patrick Venturef7a2dd52019-07-16 14:31:13 -0700162 EXPECT_EQ(zone->getMinThermalSetpoint(), zone->getMaxSetPointRequest());
Patrick Venturea58197c2018-06-11 15:29:45 -0700163}
164
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700165TEST_F(PidZoneTest, GetFailSafePercent_ReturnsExpected)
166{
Patrick Venturea58197c2018-06-11 15:29:45 -0700167 // Verify the value used to create the object is stored.
168 EXPECT_EQ(failSafePercent, zone->getFailSafePercent());
169}
170
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700171TEST_F(PidZoneTest, ThermalInputs_FailsafeToValid_ReadsSensors)
172{
Patrick Venturea58197c2018-06-11 15:29:45 -0700173 // This test will add a couple thermal inputs, and verify that the zone
174 // initializes into failsafe mode, and will read each sensor.
175
176 std::string name1 = "temp1";
177 int64_t timeout = 1;
178
179 std::unique_ptr<Sensor> sensor1 =
180 std::make_unique<SensorMock>(name1, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700181 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700182
183 std::string name2 = "temp2";
184 std::unique_ptr<Sensor> sensor2 =
185 std::make_unique<SensorMock>(name2, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700186 SensorMock* sensor_ptr2 = reinterpret_cast<SensorMock*>(sensor2.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700187
188 std::string type = "unchecked";
189 mgr.addSensor(type, name1, std::move(sensor1));
190 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
191 mgr.addSensor(type, name2, std::move(sensor2));
192 EXPECT_EQ(mgr.getSensor(name2), sensor_ptr2);
193
194 // Now that the sensors exist, add them to the zone.
195 zone->addThermalInput(name1);
196 zone->addThermalInput(name2);
197
198 // Initialize Zone
199 zone->initializeCache();
200
201 // Verify now in failsafe mode.
202 EXPECT_TRUE(zone->getFailSafeMode());
203
204 ReadReturn r1;
205 r1.value = 10.0;
206 r1.updated = std::chrono::high_resolution_clock::now();
207 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
208
209 ReadReturn r2;
210 r2.value = 11.0;
211 r2.updated = std::chrono::high_resolution_clock::now();
212 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
213
214 // Read the sensors, this will put the values into the cache.
215 zone->updateSensors();
216
217 // We should no longer be in failsafe mode.
218 EXPECT_FALSE(zone->getFailSafeMode());
219
220 EXPECT_EQ(r1.value, zone->getCachedValue(name1));
221 EXPECT_EQ(r2.value, zone->getCachedValue(name2));
222}
223
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700224TEST_F(PidZoneTest, FanInputTest_VerifiesFanValuesCached)
225{
Patrick Venturea58197c2018-06-11 15:29:45 -0700226 // This will add a couple fan inputs, and verify the values are cached.
227
228 std::string name1 = "fan1";
229 int64_t timeout = 2;
230
231 std::unique_ptr<Sensor> sensor1 =
232 std::make_unique<SensorMock>(name1, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700233 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700234
235 std::string name2 = "fan2";
236 std::unique_ptr<Sensor> sensor2 =
237 std::make_unique<SensorMock>(name2, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700238 SensorMock* sensor_ptr2 = reinterpret_cast<SensorMock*>(sensor2.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700239
240 std::string type = "unchecked";
241 mgr.addSensor(type, name1, std::move(sensor1));
242 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
243 mgr.addSensor(type, name2, std::move(sensor2));
244 EXPECT_EQ(mgr.getSensor(name2), sensor_ptr2);
245
246 // Now that the sensors exist, add them to the zone.
247 zone->addFanInput(name1);
248 zone->addFanInput(name2);
249
250 // Initialize Zone
251 zone->initializeCache();
252
253 ReadReturn r1;
254 r1.value = 10.0;
255 r1.updated = std::chrono::high_resolution_clock::now();
256 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
257
258 ReadReturn r2;
259 r2.value = 11.0;
260 r2.updated = std::chrono::high_resolution_clock::now();
261 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
262
263 // Method under test will read through each fan sensor for the zone and
264 // cache the values.
265 zone->updateFanTelemetry();
266
267 EXPECT_EQ(r1.value, zone->getCachedValue(name1));
268 EXPECT_EQ(r2.value, zone->getCachedValue(name2));
269}
270
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700271TEST_F(PidZoneTest, ThermalInput_ValueTimeoutEntersFailSafeMode)
272{
Patrick Venturea58197c2018-06-11 15:29:45 -0700273 // On the second updateSensors call, the updated timestamp will be beyond
274 // the timeout limit.
275
276 int64_t timeout = 1;
277
278 std::string name1 = "temp1";
279 std::unique_ptr<Sensor> sensor1 =
280 std::make_unique<SensorMock>(name1, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700281 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700282
283 std::string name2 = "temp2";
284 std::unique_ptr<Sensor> sensor2 =
285 std::make_unique<SensorMock>(name2, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700286 SensorMock* sensor_ptr2 = reinterpret_cast<SensorMock*>(sensor2.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700287
288 std::string type = "unchecked";
289 mgr.addSensor(type, name1, std::move(sensor1));
290 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
291 mgr.addSensor(type, name2, std::move(sensor2));
292 EXPECT_EQ(mgr.getSensor(name2), sensor_ptr2);
293
294 zone->addThermalInput(name1);
295 zone->addThermalInput(name2);
296
297 // Initialize Zone
298 zone->initializeCache();
299
300 // Verify now in failsafe mode.
301 EXPECT_TRUE(zone->getFailSafeMode());
302
303 ReadReturn r1;
304 r1.value = 10.0;
305 r1.updated = std::chrono::high_resolution_clock::now();
306 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
307
308 ReadReturn r2;
309 r2.value = 11.0;
310 r2.updated = std::chrono::high_resolution_clock::now();
311 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
312
313 zone->updateSensors();
314 EXPECT_FALSE(zone->getFailSafeMode());
315
316 // Ok, so we're not in failsafe mode, so let's set updated to the past.
317 // sensor1 will have an updated field older than its timeout value, but
318 // sensor2 will be fine. :D
319 r1.updated -= std::chrono::seconds(3);
320 r2.updated = std::chrono::high_resolution_clock::now();
321
322 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
323 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
324
325 // Method under test will read each sensor. One sensor's value is older
326 // than the timeout for that sensor and this triggers failsafe mode.
327 zone->updateSensors();
328 EXPECT_TRUE(zone->getFailSafeMode());
329}
330
Will Liangded0ab52019-05-15 17:10:06 +0800331TEST_F(PidZoneTest, FanInputTest_FailsafeToValid_ReadsSensors)
332{
333 // This will add a couple fan inputs, and verify the values are cached.
334
335 std::string name1 = "fan1";
336 int64_t timeout = 2;
337
338 std::unique_ptr<Sensor> sensor1 =
339 std::make_unique<SensorMock>(name1, timeout);
340 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
341
342 std::string name2 = "fan2";
343 std::unique_ptr<Sensor> sensor2 =
344 std::make_unique<SensorMock>(name2, timeout);
345 SensorMock* sensor_ptr2 = reinterpret_cast<SensorMock*>(sensor2.get());
346
347 std::string type = "unchecked";
348 mgr.addSensor(type, name1, std::move(sensor1));
349 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
350 mgr.addSensor(type, name2, std::move(sensor2));
351 EXPECT_EQ(mgr.getSensor(name2), sensor_ptr2);
352
353 // Now that the sensors exist, add them to the zone.
354 zone->addFanInput(name1);
355 zone->addFanInput(name2);
356
357 // Initialize Zone
358 zone->initializeCache();
359
360 // Verify now in failsafe mode.
361 EXPECT_TRUE(zone->getFailSafeMode());
362
363 ReadReturn r1;
364 r1.value = 10.0;
365 r1.updated = std::chrono::high_resolution_clock::now();
366 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
367
368 ReadReturn r2;
369 r2.value = 11.0;
370 r2.updated = std::chrono::high_resolution_clock::now();
371 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
372
373 // Method under test will read through each fan sensor for the zone and
374 // cache the values.
375 zone->updateFanTelemetry();
376
377 // We should no longer be in failsafe mode.
378 EXPECT_FALSE(zone->getFailSafeMode());
379
380 EXPECT_EQ(r1.value, zone->getCachedValue(name1));
381 EXPECT_EQ(r2.value, zone->getCachedValue(name2));
382}
383
384TEST_F(PidZoneTest, FanInputTest_ValueTimeoutEntersFailSafeMode)
385{
386 // This will add a couple fan inputs, and verify the values are cached.
387
388 std::string name1 = "fan1";
389 int64_t timeout = 2;
390
391 std::unique_ptr<Sensor> sensor1 =
392 std::make_unique<SensorMock>(name1, timeout);
393 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
394
395 std::string name2 = "fan2";
396 std::unique_ptr<Sensor> sensor2 =
397 std::make_unique<SensorMock>(name2, timeout);
398 SensorMock* sensor_ptr2 = reinterpret_cast<SensorMock*>(sensor2.get());
399
400 std::string type = "unchecked";
401 mgr.addSensor(type, name1, std::move(sensor1));
402 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
403 mgr.addSensor(type, name2, std::move(sensor2));
404 EXPECT_EQ(mgr.getSensor(name2), sensor_ptr2);
405
406 // Now that the sensors exist, add them to the zone.
407 zone->addFanInput(name1);
408 zone->addFanInput(name2);
409
410 // Initialize Zone
411 zone->initializeCache();
412
413 // Verify now in failsafe mode.
414 EXPECT_TRUE(zone->getFailSafeMode());
415
416 ReadReturn r1;
417 r1.value = 10.0;
418 r1.updated = std::chrono::high_resolution_clock::now();
419 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
420
421 ReadReturn r2;
422 r2.value = 11.0;
423 r2.updated = std::chrono::high_resolution_clock::now();
424 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
425
426 // Method under test will read through each fan sensor for the zone and
427 // cache the values.
428 zone->updateFanTelemetry();
429
430 // We should no longer be in failsafe mode.
431 EXPECT_FALSE(zone->getFailSafeMode());
432
433 r1.updated -= std::chrono::seconds(3);
434 r2.updated = std::chrono::high_resolution_clock::now();
435
436 EXPECT_CALL(*sensor_ptr1, read()).WillOnce(Return(r1));
437 EXPECT_CALL(*sensor_ptr2, read()).WillOnce(Return(r2));
438
439 zone->updateFanTelemetry();
440 EXPECT_TRUE(zone->getFailSafeMode());
441}
442
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700443TEST_F(PidZoneTest, GetSensorTest_ReturnsExpected)
444{
Patrick Venturea58197c2018-06-11 15:29:45 -0700445 // One can grab a sensor from the manager through the zone.
446
447 int64_t timeout = 1;
448
449 std::string name1 = "temp1";
450 std::unique_ptr<Sensor> sensor1 =
451 std::make_unique<SensorMock>(name1, timeout);
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700452 SensorMock* sensor_ptr1 = reinterpret_cast<SensorMock*>(sensor1.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700453
454 std::string type = "unchecked";
455 mgr.addSensor(type, name1, std::move(sensor1));
456 EXPECT_EQ(mgr.getSensor(name1), sensor_ptr1);
457
458 zone->addThermalInput(name1);
459
460 // Verify method under test returns the pointer we expect.
461 EXPECT_EQ(mgr.getSensor(name1), zone->getSensor(name1));
462}
463
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700464TEST_F(PidZoneTest, AddThermalPIDTest_VerifiesThermalPIDsProcessed)
465{
Patrick Venturea58197c2018-06-11 15:29:45 -0700466 // Tests adding a thermal PID controller to the zone, and verifies it's
467 // touched during processing.
468
469 std::unique_ptr<PIDController> tpid =
470 std::make_unique<ControllerMock>("thermal1", zone.get());
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700471 ControllerMock* tmock = reinterpret_cast<ControllerMock*>(tpid.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700472
473 // Access the internal pid configuration to clear it out (unrelated to the
474 // test).
Patrick Venture563a3562018-10-30 09:31:26 -0700475 ec::pid_info_t* info = tpid->getPIDInfo();
Patrick Venturea58197c2018-06-11 15:29:45 -0700476 std::memset(info, 0x00, sizeof(ec::pid_info_t));
477
478 zone->addThermalPID(std::move(tpid));
479
Patrick Venture563a3562018-10-30 09:31:26 -0700480 EXPECT_CALL(*tmock, setptProc()).WillOnce(Return(10.0));
481 EXPECT_CALL(*tmock, inputProc()).WillOnce(Return(11.0));
482 EXPECT_CALL(*tmock, outputProc(_));
Patrick Venturea58197c2018-06-11 15:29:45 -0700483
484 // Method under test will, for each thermal PID, call setpt, input, and
485 // output.
Patrick Venture563a3562018-10-30 09:31:26 -0700486 zone->processThermals();
Patrick Venturea58197c2018-06-11 15:29:45 -0700487}
488
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700489TEST_F(PidZoneTest, AddFanPIDTest_VerifiesFanPIDsProcessed)
490{
Patrick Venturea58197c2018-06-11 15:29:45 -0700491 // Tests adding a fan PID controller to the zone, and verifies it's
492 // touched during processing.
493
494 std::unique_ptr<PIDController> tpid =
495 std::make_unique<ControllerMock>("fan1", zone.get());
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700496 ControllerMock* tmock = reinterpret_cast<ControllerMock*>(tpid.get());
Patrick Venturea58197c2018-06-11 15:29:45 -0700497
498 // Access the internal pid configuration to clear it out (unrelated to the
499 // test).
Patrick Venture563a3562018-10-30 09:31:26 -0700500 ec::pid_info_t* info = tpid->getPIDInfo();
Patrick Venturea58197c2018-06-11 15:29:45 -0700501 std::memset(info, 0x00, sizeof(ec::pid_info_t));
502
503 zone->addFanPID(std::move(tpid));
504
Patrick Venture563a3562018-10-30 09:31:26 -0700505 EXPECT_CALL(*tmock, setptProc()).WillOnce(Return(10.0));
506 EXPECT_CALL(*tmock, inputProc()).WillOnce(Return(11.0));
507 EXPECT_CALL(*tmock, outputProc(_));
Patrick Venturea58197c2018-06-11 15:29:45 -0700508
509 // Method under test will, for each fan PID, call setpt, input, and output.
Patrick Venture563a3562018-10-30 09:31:26 -0700510 zone->processFans();
Patrick Venturea58197c2018-06-11 15:29:45 -0700511}
512
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700513TEST_F(PidZoneTest, ManualModeDbusTest_VerifySetManualBehavesAsExpected)
514{
Patrick Venturea58197c2018-06-11 15:29:45 -0700515 // The manual(bool) method is inherited from the dbus mode interface.
516
517 // Verifies that someone doesn't remove the internal call to the dbus
518 // object from which we're inheriting.
519 EXPECT_CALL(sdbus_mock_mode,
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700520 sd_bus_emit_properties_changed_strv(
521 IsNull(), StrEq(objPath), StrEq(modeInterface), NotNull()))
Patrick Venturee2ec0f62018-09-04 12:30:27 -0700522 .WillOnce(Invoke([&](sd_bus* bus, const char* path,
523 const char* interface, char** names) {
Patrick Venturea58197c2018-06-11 15:29:45 -0700524 EXPECT_STREQ("Manual", names[0]);
525 return 0;
526 }));
527
528 // Method under test will set the manual mode to true and broadcast this
529 // change on dbus.
530 zone->manual(true);
531 EXPECT_TRUE(zone->getManualMode());
532}
533
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700534TEST_F(PidZoneTest, FailsafeDbusTest_VerifiesReturnsExpected)
535{
Patrick Venturea58197c2018-06-11 15:29:45 -0700536 // This property is implemented by us as read-only, such that trying to
537 // write to it will have no effect.
538 EXPECT_EQ(zone->failSafe(), zone->getFailSafeMode());
539}