1 #include "dbus_environment.hpp"
2 #include "helpers.hpp"
3 #include "messages/collect_trigger_id.hpp"
4 #include "messages/trigger_presence_changed_ind.hpp"
5 #include "mocks/json_storage_mock.hpp"
6 #include "mocks/report_manager_mock.hpp"
7 #include "mocks/sensor_mock.hpp"
8 #include "mocks/threshold_mock.hpp"
9 #include "mocks/trigger_factory_mock.hpp"
10 #include "mocks/trigger_manager_mock.hpp"
11 #include "params/trigger_params.hpp"
12 #include "trigger.hpp"
13 #include "trigger_manager.hpp"
14 #include "utils/conversion_trigger.hpp"
15 #include "utils/dbus_path_utils.hpp"
16 #include "utils/messanger.hpp"
17 #include "utils/string_utils.hpp"
18 #include "utils/transform.hpp"
19 #include "utils/tstring.hpp"
20
21 #include <boost/range/combine.hpp>
22
23 using namespace testing;
24 using namespace std::literals::string_literals;
25 using sdbusplus::message::object_path;
26
27 static constexpr size_t expectedTriggerVersion = 2;
28
29 class TestTrigger : public Test
30 {
31 public:
32 TriggerParams triggerParams;
33 TriggerParams triggerDiscreteParams =
34 TriggerParams()
35 .id("DiscreteTrigger")
36 .name("My Discrete Trigger")
37 .thresholdParams(std::vector<discrete::LabeledThresholdParam>{
38 discrete::LabeledThresholdParam{
39 "userId", discrete::Severity::warning,
40 Milliseconds(10).count(), "15.2"},
41 discrete::LabeledThresholdParam{
42 "userId_2", discrete::Severity::critical,
43 Milliseconds(5).count(), "32.7"},
44 });
45
46 std::unique_ptr<ReportManagerMock> reportManagerMockPtr =
47 std::make_unique<NiceMock<ReportManagerMock>>();
48 std::unique_ptr<TriggerManagerMock> triggerManagerMockPtr =
49 std::make_unique<NiceMock<TriggerManagerMock>>();
50 std::unique_ptr<TriggerFactoryMock> triggerFactoryMockPtr =
51 std::make_unique<NiceMock<TriggerFactoryMock>>();
52 testing::NiceMock<StorageMock> storageMock;
53 NiceMock<MockFunction<void(const messages::TriggerPresenceChangedInd)>>
54 triggerPresenceChanged;
55 std::vector<std::shared_ptr<interfaces::Threshold>> thresholdMocks;
56 utils::Messanger messanger;
57 std::unique_ptr<Trigger> sut;
58
TestTrigger()59 TestTrigger() : messanger(DbusEnvironment::getIoc())
60 {
61 messanger.on_receive<messages::TriggerPresenceChangedInd>(
62 [this](const auto& msg) { triggerPresenceChanged.Call(msg); });
63 }
64
SetUp()65 void SetUp() override
66 {
67 sut = makeTrigger(triggerParams);
68 }
69
convertToLabeledSensor(const SensorsInfo & sensorsInfo)70 static std::vector<LabeledSensorInfo> convertToLabeledSensor(
71 const SensorsInfo& sensorsInfo)
72 {
73 return utils::transform(sensorsInfo, [](const auto& sensorInfo) {
74 const auto& [sensorPath, sensorMetadata] = sensorInfo;
75 return LabeledSensorInfo("service1", sensorPath, sensorMetadata);
76 });
77 }
78
makeTrigger(const TriggerParams & params)79 std::unique_ptr<Trigger> makeTrigger(const TriggerParams& params)
80 {
81 thresholdMocks =
82 ThresholdMock::makeThresholds(params.thresholdParams());
83
84 auto id = std::make_unique<const std::string>(params.id());
85
86 return std::make_unique<Trigger>(
87 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
88 std::move(id), params.name(), params.triggerActions(),
89 std::make_shared<std::vector<std::string>>(
90 params.reportIds().begin(), params.reportIds().end()),
91 std::vector<std::shared_ptr<interfaces::Threshold>>(thresholdMocks),
92 *triggerManagerMockPtr, storageMock, *triggerFactoryMockPtr,
93 SensorMock::makeSensorMocks(params.sensors()));
94 }
95
to_file_path(std::string name)96 static interfaces::JsonStorage::FilePath to_file_path(std::string name)
97 {
98 return interfaces::JsonStorage::FilePath(
99 std::to_string(std::hash<std::string>{}(name)));
100 }
101
102 template <class T>
getProperty(const std::string & path,const std::string & property)103 static T getProperty(const std::string& path, const std::string& property)
104 {
105 return DbusEnvironment::getProperty<T>(path, Trigger::triggerIfaceName,
106 property);
107 }
108
109 template <class T>
setProperty(const std::string & path,const std::string & property,const T & newValue)110 static boost::system::error_code setProperty(
111 const std::string& path, const std::string& property, const T& newValue)
112 {
113 return DbusEnvironment::setProperty<T>(path, Trigger::triggerIfaceName,
114 property, newValue);
115 }
116
117 template <class T>
118 struct ChangePropertyParams
119 {
120 Matcher<T> valueBefore = _;
121 T newValue;
122 Matcher<boost::system::error_code> ec =
123 Eq(boost::system::errc::success);
124 Matcher<T> valueAfter = Eq(newValue);
125 };
126
127 template <class T>
changeProperty(const std::string & path,const std::string & property,ChangePropertyParams<T> p)128 static void changeProperty(const std::string& path,
129 const std::string& property,
130 ChangePropertyParams<T> p)
131 {
132 ASSERT_THAT(getProperty<T>(path, property), p.valueBefore);
133 ASSERT_THAT(setProperty<T>(path, property, p.newValue), p.ec);
134 EXPECT_THAT(getProperty<T>(path, property), p.valueAfter);
135 }
136
deleteTrigger(const std::string & path)137 boost::system::error_code deleteTrigger(const std::string& path)
138 {
139 std::promise<boost::system::error_code> methodPromise;
140 DbusEnvironment::getBus()->async_method_call(
141 [&methodPromise](boost::system::error_code ec) {
142 methodPromise.set_value(ec);
143 },
144 DbusEnvironment::serviceName(), path, Trigger::deleteIfaceName,
145 "Delete");
146 return DbusEnvironment::waitForFuture(methodPromise.get_future());
147 }
148 };
149
TEST_F(TestTrigger,checkIfPropertiesAreSet)150 TEST_F(TestTrigger, checkIfPropertiesAreSet)
151 {
152 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
153 Eq(triggerParams.name()));
154 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"), Eq(true));
155 EXPECT_THAT(
156 getProperty<std::vector<std::string>>(sut->getPath(), "TriggerActions"),
157 Eq(utils::transform(
158 triggerParams.triggerActions(),
159 [](const auto& action) { return actionToString(action); })));
160 EXPECT_THAT((getProperty<SensorsInfo>(sut->getPath(), "Sensors")),
161 Eq(utils::fromLabeledSensorsInfo(triggerParams.sensors())));
162 EXPECT_THAT(
163 getProperty<std::vector<object_path>>(sut->getPath(), "Reports"),
164 Eq(triggerParams.reports()));
165 EXPECT_THAT(
166 getProperty<bool>(sut->getPath(), "Discrete"),
167 Eq(isTriggerThresholdDiscrete(triggerParams.thresholdParams())));
168
169 EXPECT_THAT(getProperty<std::vector<numeric::ThresholdParam>>(
170 sut->getPath(), "NumericThresholds"),
171 Eq(std::get<0>(utils::FromLabeledThresholdParamConversion()(
172 triggerParams.numericThresholdParams()))));
173
174 EXPECT_THAT(getProperty<std::vector<discrete::ThresholdParam>>(
175 sut->getPath(), "DiscreteThresholds"),
176 Eq(std::get<1>(utils::FromLabeledThresholdParamConversion()(
177 triggerParams.discreteThresholdParams()))));
178 }
179
TEST_F(TestTrigger,checkBasicGetters)180 TEST_F(TestTrigger, checkBasicGetters)
181 {
182 EXPECT_THAT(sut->getId(), Eq(triggerParams.id()));
183 EXPECT_THAT(sut->getPath(),
184 Eq(utils::constants::triggerDirPath.str + triggerParams.id()));
185 }
186
TEST_F(TestTrigger,setPropertyNameToCorrectValue)187 TEST_F(TestTrigger, setPropertyNameToCorrectValue)
188 {
189 std::string name = "custom name 1234 %^#5";
190 EXPECT_THAT(setProperty(sut->getPath(), "Name", name),
191 Eq(boost::system::errc::success));
192 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"), Eq(name));
193 }
194
TEST_F(TestTrigger,setPropertyReportNames)195 TEST_F(TestTrigger, setPropertyReportNames)
196 {
197 std::vector<object_path> newNames = {
198 utils::constants::reportDirPath / "abc",
199 utils::constants::reportDirPath / "one",
200 utils::constants::reportDirPath / "prefix" / "two"};
201 EXPECT_THAT(setProperty(sut->getPath(), "Reports", newNames),
202 Eq(boost::system::errc::success));
203 EXPECT_THAT(
204 getProperty<std::vector<object_path>>(sut->getPath(), "Reports"),
205 Eq(newNames));
206 }
207
TEST_F(TestTrigger,sendsUpdateWhenReportNamesChanges)208 TEST_F(TestTrigger, sendsUpdateWhenReportNamesChanges)
209 {
210 std::vector<object_path> newPropertyVal = {
211 utils::constants::reportDirPath / "abc",
212 utils::constants::reportDirPath / "one",
213 utils::constants::reportDirPath / "two"};
214
215 EXPECT_CALL(triggerPresenceChanged,
216 Call(FieldsAre(messages::Presence::Exist, triggerParams.id(),
217 UnorderedElementsAre("abc", "one", "two"))));
218
219 EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
220 Eq(boost::system::errc::success));
221 }
222
TEST_F(TestTrigger,sendsUpdateWhenReportNamesChangesToSameValue)223 TEST_F(TestTrigger, sendsUpdateWhenReportNamesChangesToSameValue)
224 {
225 const std::vector<object_path> newPropertyVal = triggerParams.reports();
226
227 EXPECT_CALL(
228 triggerPresenceChanged,
229 Call(FieldsAre(messages::Presence::Exist, triggerParams.id(),
230 UnorderedElementsAreArray(triggerParams.reportIds()))));
231
232 EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
233 Eq(boost::system::errc::success));
234 }
235
TEST_F(TestTrigger,settingPropertyReportNamesThrowsExceptionWhenDuplicateReportIds)236 TEST_F(TestTrigger,
237 settingPropertyReportNamesThrowsExceptionWhenDuplicateReportIds)
238 {
239 std::vector<object_path> newPropertyVal{
240 utils::constants::reportDirPath / "report1",
241 utils::constants::reportDirPath / "report2",
242 utils::constants::reportDirPath / "report1"};
243
244 EXPECT_CALL(triggerPresenceChanged, Call(_)).Times(0);
245
246 EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
247 Eq(boost::system::errc::invalid_argument));
248 }
249
TEST_F(TestTrigger,settingPropertyReportNamesThrowsExceptionWhenReportWithTooManyPrefixes)250 TEST_F(TestTrigger,
251 settingPropertyReportNamesThrowsExceptionWhenReportWithTooManyPrefixes)
252 {
253 std::vector<object_path> newPropertyVal{
254 object_path("/xyz/openbmc_project/Telemetry/Reports/P1/P2/MyReport")};
255
256 EXPECT_CALL(triggerPresenceChanged, Call(_)).Times(0);
257
258 EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
259 Eq(boost::system::errc::invalid_argument));
260 }
261
TEST_F(TestTrigger,settingPropertyReportNamesThrowsExceptionWhenReportWithTooLongPrefix)262 TEST_F(TestTrigger,
263 settingPropertyReportNamesThrowsExceptionWhenReportWithTooLongPrefix)
264 {
265 std::vector<object_path> newPropertyVal{
266 object_path("/xyz/openbmc_project/Telemetry/Reports/" +
267 utils::string_utils::getTooLongPrefix() + "/MyReport")};
268
269 EXPECT_CALL(triggerPresenceChanged, Call(_)).Times(0);
270
271 EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
272 Eq(boost::system::errc::invalid_argument));
273 }
274
TEST_F(TestTrigger,settingPropertyReportNamesThrowsExceptionWhenReportWithTooLongId)275 TEST_F(TestTrigger,
276 settingPropertyReportNamesThrowsExceptionWhenReportWithTooLongId)
277 {
278 std::vector<object_path> newPropertyVal{
279 object_path("/xyz/openbmc_project/Telemetry/Reports/Prefix/" +
280 utils::string_utils::getTooLongId())};
281
282 EXPECT_CALL(triggerPresenceChanged, Call(_)).Times(0);
283
284 EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
285 Eq(boost::system::errc::invalid_argument));
286 }
287
TEST_F(TestTrigger,settingPropertyReportNamesThrowsExceptionWhenReportWithBadPath)288 TEST_F(TestTrigger,
289 settingPropertyReportNamesThrowsExceptionWhenReportWithBadPath)
290 {
291 std::vector<object_path> newPropertyVal{
292 object_path("/xyz/openbmc_project/Telemetry/NotReports/MyReport")};
293
294 EXPECT_CALL(triggerPresenceChanged, Call(_)).Times(0);
295
296 EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
297 Eq(boost::system::errc::invalid_argument));
298 }
299
TEST_F(TestTrigger,setPropertySensors)300 TEST_F(TestTrigger, setPropertySensors)
301 {
302 EXPECT_CALL(*triggerFactoryMockPtr, updateSensors(_, _));
303 for (const auto& threshold : thresholdMocks)
304 {
305 auto thresholdMockPtr =
306 std::dynamic_pointer_cast<NiceMock<ThresholdMock>>(threshold);
307 EXPECT_CALL(*thresholdMockPtr, updateSensors(_));
308 }
309 SensorsInfo newSensors(
310 {std::make_pair(object_path("/abc/def"), "metadata")});
311 EXPECT_THAT(setProperty(sut->getPath(), "Sensors", newSensors),
312 Eq(boost::system::errc::success));
313 }
314
TEST_F(TestTrigger,setPropertyNumericThresholds)315 TEST_F(TestTrigger, setPropertyNumericThresholds)
316 {
317 EXPECT_CALL(*triggerFactoryMockPtr, updateThresholds(_, _, _, _, _, _));
318 auto newThresholds = std::vector<numeric::ThresholdParam>({std::make_tuple(
319 numeric::typeToString(numeric::Type::upperWarning), 10,
320 numeric::directionToString(numeric::Direction::increasing), 12.3)});
321 EXPECT_THAT(setProperty(sut->getPath(), "NumericThresholds", newThresholds),
322 Eq(boost::system::errc::success));
323 }
324
TEST_F(TestTrigger,setPropertyDiscreteThresholds)325 TEST_F(TestTrigger, setPropertyDiscreteThresholds)
326 {
327 EXPECT_CALL(*triggerFactoryMockPtr, updateThresholds(_, _, _, _, _, _));
328 auto newThresholds = std::vector<discrete::ThresholdParam>({std::make_tuple(
329 "discrete threshold", utils::enumToString(discrete::Severity::ok), 10,
330 "12.3")});
331 EXPECT_THAT(setProperty(sut->getPath(), "DiscreteThresholds",
332 newThresholds),
333 Eq(boost::system::errc::success));
334 }
335
TEST_F(TestTrigger,setThresholdParamsWithTooLongDiscreteName)336 TEST_F(TestTrigger, setThresholdParamsWithTooLongDiscreteName)
337 {
338 const std::vector<discrete::ThresholdParam> currentValue =
339 std::get<1>(utils::FromLabeledThresholdParamConversion()(
340 triggerParams.discreteThresholdParams()));
341
342 auto newThresholds = std::vector<discrete::ThresholdParam>({std::make_tuple(
343 utils::string_utils::getTooLongName(),
344 utils::enumToString(discrete::Severity::ok), 10, "12.3")});
345
346 changeProperty<std::vector<discrete::ThresholdParam>>(
347 sut->getPath(), "DiscreteThresholds",
348 {.valueBefore = Eq(currentValue),
349 .newValue = newThresholds,
350 .ec = Eq(boost::system::errc::invalid_argument),
351 .valueAfter = Eq(currentValue)});
352 }
353
TEST_F(TestTrigger,setNameTooLong)354 TEST_F(TestTrigger, setNameTooLong)
355 {
356 std::string currentValue = TriggerParams().name();
357
358 changeProperty<std::string>(
359 sut->getPath(), "Name",
360 {.valueBefore = Eq(currentValue),
361 .newValue = utils::string_utils::getTooLongName(),
362 .ec = Eq(boost::system::errc::invalid_argument),
363 .valueAfter = Eq(currentValue)});
364 }
365
TEST_F(TestTrigger,checkIfNumericCoversionsAreGood)366 TEST_F(TestTrigger, checkIfNumericCoversionsAreGood)
367 {
368 const auto& labeledParamsBase =
369 std::get<std::vector<numeric::LabeledThresholdParam>>(
370 triggerParams.thresholdParams());
371 const auto paramsToCheck =
372 std::visit(utils::FromLabeledThresholdParamConversion(),
373 triggerParams.thresholdParams());
374 const auto labeledParamsToCheck =
375 std::get<std::vector<numeric::LabeledThresholdParam>>(std::visit(
376 utils::ToLabeledThresholdParamConversion(), paramsToCheck));
377
378 for (const auto& [tocheck, base] :
379 boost::combine(labeledParamsToCheck, labeledParamsBase))
380 {
381 EXPECT_THAT(tocheck.at_label<utils::tstring::Type>(),
382 Eq(base.at_label<utils::tstring::Type>()));
383 EXPECT_THAT(tocheck.at_label<utils::tstring::Direction>(),
384 Eq(base.at_label<utils::tstring::Direction>()));
385 EXPECT_THAT(tocheck.at_label<utils::tstring::DwellTime>(),
386 Eq(base.at_label<utils::tstring::DwellTime>()));
387 EXPECT_THAT(tocheck.at_label<utils::tstring::ThresholdValue>(),
388 Eq(base.at_label<utils::tstring::ThresholdValue>()));
389 }
390 }
391
TEST_F(TestTrigger,checkIfDiscreteCoversionsAreGood)392 TEST_F(TestTrigger, checkIfDiscreteCoversionsAreGood)
393 {
394 const auto& labeledParamsBase =
395 std::get<std::vector<discrete::LabeledThresholdParam>>(
396 triggerDiscreteParams.thresholdParams());
397 const auto paramsToCheck =
398 std::visit(utils::FromLabeledThresholdParamConversion(),
399 triggerDiscreteParams.thresholdParams());
400 const auto labeledParamsToCheck =
401 std::get<std::vector<discrete::LabeledThresholdParam>>(std::visit(
402 utils::ToLabeledThresholdParamConversion(), paramsToCheck));
403
404 for (const auto& [tocheck, base] :
405 boost::combine(labeledParamsToCheck, labeledParamsBase))
406 {
407 EXPECT_THAT(tocheck.at_label<utils::tstring::UserId>(),
408 Eq(base.at_label<utils::tstring::UserId>()));
409 EXPECT_THAT(tocheck.at_label<utils::tstring::Severity>(),
410 Eq(base.at_label<utils::tstring::Severity>()));
411 EXPECT_THAT(tocheck.at_label<utils::tstring::DwellTime>(),
412 Eq(base.at_label<utils::tstring::DwellTime>()));
413 EXPECT_THAT(tocheck.at_label<utils::tstring::ThresholdValue>(),
414 Eq(base.at_label<utils::tstring::ThresholdValue>()));
415 }
416 }
417
TEST_F(TestTrigger,deleteTrigger)418 TEST_F(TestTrigger, deleteTrigger)
419 {
420 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
421 EXPECT_CALL(*triggerManagerMockPtr, removeTrigger(sut.get()));
422
423 auto ec = deleteTrigger(sut->getPath());
424 EXPECT_THAT(ec, Eq(boost::system::errc::success));
425 }
426
TEST_F(TestTrigger,sendUpdateWhenTriggerIsDeleted)427 TEST_F(TestTrigger, sendUpdateWhenTriggerIsDeleted)
428 {
429 EXPECT_CALL(triggerPresenceChanged,
430 Call(FieldsAre(messages::Presence::Removed, triggerParams.id(),
431 UnorderedElementsAre())));
432
433 auto ec = deleteTrigger(sut->getPath());
434 EXPECT_THAT(ec, Eq(boost::system::errc::success));
435 }
436
TEST_F(TestTrigger,deletingNonExistingTriggerReturnInvalidRequestDescriptor)437 TEST_F(TestTrigger, deletingNonExistingTriggerReturnInvalidRequestDescriptor)
438 {
439 auto ec =
440 deleteTrigger(utils::constants::triggerDirPath.str + "NonExisting"s);
441 EXPECT_THAT(ec.value(), Eq(EBADR));
442 }
443
TEST_F(TestTrigger,settingPersistencyToFalseRemovesTriggerFromStorage)444 TEST_F(TestTrigger, settingPersistencyToFalseRemovesTriggerFromStorage)
445 {
446 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
447
448 bool persistent = false;
449 EXPECT_THAT(setProperty(sut->getPath(), "Persistent", persistent),
450 Eq(boost::system::errc::success));
451 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"),
452 Eq(persistent));
453 }
454
455 class TestOnChangeTrigger : public TestTrigger
456 {
457 public:
458 TriggerParams onChangeTriggerParams =
459 TriggerParams()
460 .id("DiscreteOnChangeTrigger")
461 .name("My Discrete On Change Trigger")
462 .thresholdParams(std::vector<numeric::LabeledThresholdParam>{});
463
SetUp()464 void SetUp() override
465 {
466 sut = makeTrigger(onChangeTriggerParams);
467 }
468 };
469
TEST_F(TestOnChangeTrigger,isDiscrete)470 TEST_F(TestOnChangeTrigger, isDiscrete)
471 {
472 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Discrete"), Eq(true));
473 }
474
475 class TestTriggerInitialization : public TestTrigger
476 {
477 public:
SetUp()478 void SetUp() override {}
479
480 nlohmann::json storedConfiguration;
481 };
482
TEST_F(TestTriggerInitialization,exceptionDuringTriggerStoreDisablesPersistency)483 TEST_F(TestTriggerInitialization,
484 exceptionDuringTriggerStoreDisablesPersistency)
485 {
486 EXPECT_CALL(storageMock, store(_, _))
487 .WillOnce(Throw(std::runtime_error("Generic error!")));
488
489 sut = makeTrigger(triggerParams);
490
491 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"), Eq(false));
492 }
493
TEST_F(TestTriggerInitialization,creatingTriggerThrowsExceptionWhenIdIsInvalid)494 TEST_F(TestTriggerInitialization, creatingTriggerThrowsExceptionWhenIdIsInvalid)
495 {
496 EXPECT_CALL(storageMock, store(_, _)).Times(0);
497
498 EXPECT_THROW(makeTrigger(triggerParams.id("inv?lidId")),
499 sdbusplus::exception::SdBusError);
500 }
501
TEST_F(TestTriggerInitialization,creatingTriggerUpdatesTriggersIdsInReports)502 TEST_F(TestTriggerInitialization, creatingTriggerUpdatesTriggersIdsInReports)
503 {
504 EXPECT_CALL(
505 triggerPresenceChanged,
506 Call(FieldsAre(messages::Presence::Exist, triggerParams.id(),
507 UnorderedElementsAreArray(triggerParams.reportIds()))));
508
509 sut = makeTrigger(triggerParams);
510 }
511
512 class TestTriggerStore : public TestTrigger
513 {
514 public:
515 nlohmann::json storedConfiguration;
516 nlohmann::json storedDiscreteConfiguration;
517 std::unique_ptr<Trigger> sutDiscrete;
518
SetUp()519 void SetUp() override
520 {
521 ON_CALL(storageMock, store(_, _))
522 .WillByDefault(SaveArg<1>(&storedConfiguration));
523 sut = makeTrigger(triggerParams);
524
525 ON_CALL(storageMock, store(_, _))
526 .WillByDefault(SaveArg<1>(&storedDiscreteConfiguration));
527 sutDiscrete = makeTrigger(triggerDiscreteParams);
528 }
529 };
530
TEST_F(TestTriggerStore,settingPersistencyToTrueStoresTriggerVersion)531 TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerVersion)
532 {
533 ASSERT_THAT(storedConfiguration.at("Version"), Eq(expectedTriggerVersion));
534 }
535
TEST_F(TestTriggerStore,settingPersistencyToTrueStoresTriggerId)536 TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerId)
537 {
538 ASSERT_THAT(storedConfiguration.at("Id"), Eq(triggerParams.id()));
539 }
540
TEST_F(TestTriggerStore,settingPersistencyToTrueStoresTriggerName)541 TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerName)
542 {
543 ASSERT_THAT(storedConfiguration.at("Name"), Eq(triggerParams.name()));
544 }
545
TEST_F(TestTriggerStore,settingPersistencyToTrueStoresTriggerTriggerActions)546 TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerTriggerActions)
547 {
548 ASSERT_THAT(storedConfiguration.at("TriggerActions"),
549 Eq(utils::transform(triggerParams.triggerActions(),
550 [](const auto& action) {
551 return actionToString(action);
552 })));
553 }
554
TEST_F(TestTriggerStore,settingPersistencyToTrueStoresTriggerReportIds)555 TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerReportIds)
556 {
557 ASSERT_THAT(storedConfiguration.at("ReportIds"),
558 Eq(triggerParams.reportIds()));
559 }
560
TEST_F(TestTriggerStore,settingPersistencyToTrueStoresTriggerSensors)561 TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerSensors)
562 {
563 nlohmann::json expectedItem;
564 expectedItem["service"] = "service1";
565 expectedItem["path"] = "/xyz/openbmc_project/sensors/temperature/BMC_Temp";
566 expectedItem["metadata"] = "metadata1";
567
568 ASSERT_THAT(storedConfiguration.at("Sensors"), ElementsAre(expectedItem));
569 }
570
TEST_F(TestTriggerStore,settingPersistencyToTrueStoresTriggerThresholdParams)571 TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerThresholdParams)
572 {
573 nlohmann::json expectedItem0;
574 expectedItem0["type"] = 0;
575 expectedItem0["dwellTime"] = 10;
576 expectedItem0["direction"] = 1;
577 expectedItem0["thresholdValue"] = 0.5;
578
579 nlohmann::json expectedItem1;
580 expectedItem1["type"] = 3;
581 expectedItem1["dwellTime"] = 10;
582 expectedItem1["direction"] = 2;
583 expectedItem1["thresholdValue"] = 90.2;
584
585 ASSERT_THAT(storedConfiguration.at("ThresholdParamsDiscriminator"), Eq(0));
586 ASSERT_THAT(storedConfiguration.at("ThresholdParams"),
587 ElementsAre(expectedItem0, expectedItem1));
588 }
589
TEST_F(TestTriggerStore,settingPersistencyToTrueStoresDiscreteTriggerThresholdParams)590 TEST_F(TestTriggerStore,
591 settingPersistencyToTrueStoresDiscreteTriggerThresholdParams)
592 {
593 nlohmann::json expectedItem0;
594 expectedItem0["userId"] = "userId";
595 expectedItem0["severity"] = discrete::Severity::warning;
596 expectedItem0["dwellTime"] = 10;
597 expectedItem0["thresholdValue"] = "15.2";
598
599 nlohmann::json expectedItem1;
600 expectedItem1["userId"] = "userId_2";
601 expectedItem1["severity"] = discrete::Severity::critical;
602 expectedItem1["dwellTime"] = 5;
603 expectedItem1["thresholdValue"] = "32.7";
604
605 ASSERT_THAT(storedDiscreteConfiguration.at("ThresholdParamsDiscriminator"),
606 Eq(1));
607 ASSERT_THAT(storedDiscreteConfiguration.at("ThresholdParams"),
608 ElementsAre(expectedItem0, expectedItem1));
609 }
610