xref: /openbmc/telemetry/tests/src/test_trigger.cpp (revision 995ebe7ef29c9890e87aa4c0e6772f7a586146da)
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