176833cb5SWludzik, Jozef #include "dbus_environment.hpp"
276833cb5SWludzik, Jozef #include "helpers.hpp"
3*a4e67616SCezary Zwolak #include "mocks/json_storage_mock.hpp"
476833cb5SWludzik, Jozef #include "mocks/trigger_manager_mock.hpp"
576833cb5SWludzik, Jozef #include "params/trigger_params.hpp"
676833cb5SWludzik, Jozef #include "trigger.hpp"
776833cb5SWludzik, Jozef #include "utils/set_exception.hpp"
876833cb5SWludzik, Jozef 
976833cb5SWludzik, Jozef using namespace testing;
1076833cb5SWludzik, Jozef using namespace std::literals::string_literals;
1176833cb5SWludzik, Jozef 
12*a4e67616SCezary Zwolak static constexpr size_t expectedTriggerVersion = 0;
13*a4e67616SCezary Zwolak 
1476833cb5SWludzik, Jozef class TestTrigger : public Test
1576833cb5SWludzik, Jozef {
1676833cb5SWludzik, Jozef   public:
1776833cb5SWludzik, Jozef     TriggerParams triggerParams;
1876833cb5SWludzik, Jozef 
1976833cb5SWludzik, Jozef     std::unique_ptr<TriggerManagerMock> triggerManagerMockPtr =
2076833cb5SWludzik, Jozef         std::make_unique<NiceMock<TriggerManagerMock>>();
21*a4e67616SCezary Zwolak     testing::NiceMock<StorageMock> storageMock;
2276833cb5SWludzik, Jozef     std::unique_ptr<Trigger> sut;
2376833cb5SWludzik, Jozef 
2476833cb5SWludzik, Jozef     void SetUp() override
2576833cb5SWludzik, Jozef     {
26*a4e67616SCezary Zwolak         sut = makeTrigger(triggerParams);
27*a4e67616SCezary Zwolak     }
28*a4e67616SCezary Zwolak 
29*a4e67616SCezary Zwolak     std::unique_ptr<Trigger> makeTrigger(const TriggerParams& params)
30*a4e67616SCezary Zwolak     {
31*a4e67616SCezary Zwolak         return std::make_unique<Trigger>(
3276833cb5SWludzik, Jozef             DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
33*a4e67616SCezary Zwolak             params.name(), params.isDiscrete(), params.logToJournal(),
34*a4e67616SCezary Zwolak             params.logToRedfish(), params.updateReport(), params.sensors(),
35*a4e67616SCezary Zwolak             params.reportNames(), params.thresholdParams(),
361477fe6aSWludzik, Jozef             std::vector<std::shared_ptr<interfaces::Threshold>>{},
37*a4e67616SCezary Zwolak             *triggerManagerMockPtr, storageMock);
38*a4e67616SCezary Zwolak     }
39*a4e67616SCezary Zwolak 
40*a4e67616SCezary Zwolak     static interfaces::JsonStorage::FilePath to_file_path(std::string name)
41*a4e67616SCezary Zwolak     {
42*a4e67616SCezary Zwolak         return interfaces::JsonStorage::FilePath(
43*a4e67616SCezary Zwolak             std::to_string(std::hash<std::string>{}(name)));
4476833cb5SWludzik, Jozef     }
4576833cb5SWludzik, Jozef 
4676833cb5SWludzik, Jozef     template <class T>
4776833cb5SWludzik, Jozef     static T getProperty(const std::string& path, const std::string& property)
4876833cb5SWludzik, Jozef     {
490e7ae5dbSEd Tanous         auto propertyPromise = std::promise<T>();
500e7ae5dbSEd Tanous         auto propertyFuture = propertyPromise.get_future();
5176833cb5SWludzik, Jozef         sdbusplus::asio::getProperty<T>(
5276833cb5SWludzik, Jozef             *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
5376833cb5SWludzik, Jozef             Trigger::triggerIfaceName, property,
540e7ae5dbSEd Tanous             [&propertyPromise](const boost::system::error_code& ec, T t) {
550e7ae5dbSEd Tanous                 if (ec)
560e7ae5dbSEd Tanous                 {
5776833cb5SWludzik, Jozef                     utils::setException(propertyPromise, "GetProperty failed");
580e7ae5dbSEd Tanous                     return;
590e7ae5dbSEd Tanous                 }
600e7ae5dbSEd Tanous                 propertyPromise.set_value(t);
610e7ae5dbSEd Tanous             });
620e7ae5dbSEd Tanous         return DbusEnvironment::waitForFuture(std::move(propertyFuture));
6376833cb5SWludzik, Jozef     }
6476833cb5SWludzik, Jozef 
65*a4e67616SCezary Zwolak     template <class T>
66*a4e67616SCezary Zwolak     static boost::system::error_code setProperty(const std::string& path,
67*a4e67616SCezary Zwolak                                                  const std::string& property,
68*a4e67616SCezary Zwolak                                                  const T& newValue)
69*a4e67616SCezary Zwolak     {
70*a4e67616SCezary Zwolak         auto setPromise = std::promise<boost::system::error_code>();
71*a4e67616SCezary Zwolak         auto setFuture = setPromise.get_future();
72*a4e67616SCezary Zwolak 
73*a4e67616SCezary Zwolak         sdbusplus::asio::setProperty(
74*a4e67616SCezary Zwolak             *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
75*a4e67616SCezary Zwolak             Trigger::triggerIfaceName, property, std::move(newValue),
76*a4e67616SCezary Zwolak             [setPromise =
77*a4e67616SCezary Zwolak                  std::move(setPromise)](boost::system::error_code ec) mutable {
78*a4e67616SCezary Zwolak                 setPromise.set_value(ec);
79*a4e67616SCezary Zwolak             });
80*a4e67616SCezary Zwolak         return DbusEnvironment::waitForFuture(std::move(setFuture));
81*a4e67616SCezary Zwolak     }
82*a4e67616SCezary Zwolak 
8376833cb5SWludzik, Jozef     boost::system::error_code deleteTrigger(const std::string& path)
8476833cb5SWludzik, Jozef     {
8576833cb5SWludzik, Jozef         std::promise<boost::system::error_code> methodPromise;
8676833cb5SWludzik, Jozef         DbusEnvironment::getBus()->async_method_call(
8776833cb5SWludzik, Jozef             [&methodPromise](boost::system::error_code ec) {
8876833cb5SWludzik, Jozef                 methodPromise.set_value(ec);
8976833cb5SWludzik, Jozef             },
9076833cb5SWludzik, Jozef             DbusEnvironment::serviceName(), path, Trigger::deleteIfaceName,
9176833cb5SWludzik, Jozef             "Delete");
9276833cb5SWludzik, Jozef         return DbusEnvironment::waitForFuture(methodPromise.get_future());
9376833cb5SWludzik, Jozef     }
9476833cb5SWludzik, Jozef };
9576833cb5SWludzik, Jozef 
9676833cb5SWludzik, Jozef TEST_F(TestTrigger, checkIfPropertiesAreSet)
9776833cb5SWludzik, Jozef {
98*a4e67616SCezary Zwolak     EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"), Eq(true));
9976833cb5SWludzik, Jozef     EXPECT_THAT(getProperty<bool>(sut->getPath(), "Discrete"),
10076833cb5SWludzik, Jozef                 Eq(triggerParams.isDiscrete()));
10176833cb5SWludzik, Jozef     EXPECT_THAT(getProperty<bool>(sut->getPath(), "LogToJournal"),
10276833cb5SWludzik, Jozef                 Eq(triggerParams.logToJournal()));
10376833cb5SWludzik, Jozef     EXPECT_THAT(getProperty<bool>(sut->getPath(), "LogToRedfish"),
10476833cb5SWludzik, Jozef                 Eq(triggerParams.logToRedfish()));
10576833cb5SWludzik, Jozef     EXPECT_THAT(getProperty<bool>(sut->getPath(), "UpdateReport"),
10676833cb5SWludzik, Jozef                 Eq(triggerParams.updateReport()));
10776833cb5SWludzik, Jozef     EXPECT_THAT((getProperty<std::vector<
10876833cb5SWludzik, Jozef                      std::pair<sdbusplus::message::object_path, std::string>>>(
10976833cb5SWludzik, Jozef                     sut->getPath(), "Sensors")),
11076833cb5SWludzik, Jozef                 Eq(triggerParams.sensors()));
11176833cb5SWludzik, Jozef     EXPECT_THAT(
11276833cb5SWludzik, Jozef         getProperty<std::vector<std::string>>(sut->getPath(), "ReportNames"),
11376833cb5SWludzik, Jozef         Eq(triggerParams.reportNames()));
11476833cb5SWludzik, Jozef     EXPECT_THAT(
11576833cb5SWludzik, Jozef         getProperty<TriggerThresholdParams>(sut->getPath(), "Thresholds"),
1161477fe6aSWludzik, Jozef         Eq(triggerParams.thresholdParams()));
11776833cb5SWludzik, Jozef }
11876833cb5SWludzik, Jozef 
11976833cb5SWludzik, Jozef TEST_F(TestTrigger, deleteTrigger)
12076833cb5SWludzik, Jozef {
121*a4e67616SCezary Zwolak     EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
12276833cb5SWludzik, Jozef     EXPECT_CALL(*triggerManagerMockPtr, removeTrigger(sut.get()));
12376833cb5SWludzik, Jozef     auto ec = deleteTrigger(sut->getPath());
12476833cb5SWludzik, Jozef     EXPECT_THAT(ec, Eq(boost::system::errc::success));
12576833cb5SWludzik, Jozef }
12676833cb5SWludzik, Jozef 
12776833cb5SWludzik, Jozef TEST_F(TestTrigger, deletingNonExistingTriggerReturnInvalidRequestDescriptor)
12876833cb5SWludzik, Jozef {
12976833cb5SWludzik, Jozef     auto ec = deleteTrigger(Trigger::triggerDir + "NonExisting"s);
13076833cb5SWludzik, Jozef     EXPECT_THAT(ec.value(), Eq(EBADR));
13176833cb5SWludzik, Jozef }
132*a4e67616SCezary Zwolak 
133*a4e67616SCezary Zwolak TEST_F(TestTrigger, settingPersistencyToFalseRemovesReportFromStorage)
134*a4e67616SCezary Zwolak {
135*a4e67616SCezary Zwolak     EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
136*a4e67616SCezary Zwolak 
137*a4e67616SCezary Zwolak     bool persistent = false;
138*a4e67616SCezary Zwolak     EXPECT_THAT(setProperty(sut->getPath(), "Persistent", persistent).value(),
139*a4e67616SCezary Zwolak                 Eq(boost::system::errc::success));
140*a4e67616SCezary Zwolak     EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"),
141*a4e67616SCezary Zwolak                 Eq(persistent));
142*a4e67616SCezary Zwolak }
143*a4e67616SCezary Zwolak 
144*a4e67616SCezary Zwolak class TestTriggerErrors : public TestTrigger
145*a4e67616SCezary Zwolak {
146*a4e67616SCezary Zwolak   public:
147*a4e67616SCezary Zwolak     void SetUp() override
148*a4e67616SCezary Zwolak     {}
149*a4e67616SCezary Zwolak 
150*a4e67616SCezary Zwolak     nlohmann::json storedConfiguration;
151*a4e67616SCezary Zwolak };
152*a4e67616SCezary Zwolak 
153*a4e67616SCezary Zwolak TEST_F(TestTriggerErrors, throwingExceptionDoesNotStoreTriggerReportNames)
154*a4e67616SCezary Zwolak {
155*a4e67616SCezary Zwolak     EXPECT_CALL(storageMock, store(_, _))
156*a4e67616SCezary Zwolak         .WillOnce(Throw(std::runtime_error("Generic error!")));
157*a4e67616SCezary Zwolak 
158*a4e67616SCezary Zwolak     sut = makeTrigger(triggerParams);
159*a4e67616SCezary Zwolak 
160*a4e67616SCezary Zwolak     EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"), Eq(false));
161*a4e67616SCezary Zwolak }
162*a4e67616SCezary Zwolak 
163*a4e67616SCezary Zwolak TEST_F(TestTriggerErrors, creatingTriggerThrowsExceptionWhenNameIsInvalid)
164*a4e67616SCezary Zwolak {
165*a4e67616SCezary Zwolak     EXPECT_CALL(storageMock, store(_, _)).Times(0);
166*a4e67616SCezary Zwolak 
167*a4e67616SCezary Zwolak     EXPECT_THROW(makeTrigger(triggerParams.name("inv?lidName")),
168*a4e67616SCezary Zwolak                  sdbusplus::exception::SdBusError);
169*a4e67616SCezary Zwolak }
170*a4e67616SCezary Zwolak 
171*a4e67616SCezary Zwolak class TestTriggerStore : public TestTrigger
172*a4e67616SCezary Zwolak {
173*a4e67616SCezary Zwolak   public:
174*a4e67616SCezary Zwolak     void SetUp() override
175*a4e67616SCezary Zwolak     {
176*a4e67616SCezary Zwolak         ON_CALL(storageMock, store(_, _))
177*a4e67616SCezary Zwolak             .WillByDefault(SaveArg<1>(&storedConfiguration));
178*a4e67616SCezary Zwolak 
179*a4e67616SCezary Zwolak         sut = makeTrigger(triggerParams);
180*a4e67616SCezary Zwolak     }
181*a4e67616SCezary Zwolak 
182*a4e67616SCezary Zwolak     nlohmann::json storedConfiguration;
183*a4e67616SCezary Zwolak };
184*a4e67616SCezary Zwolak 
185*a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerVersion)
186*a4e67616SCezary Zwolak {
187*a4e67616SCezary Zwolak     ASSERT_THAT(storedConfiguration.at("Version"), Eq(expectedTriggerVersion));
188*a4e67616SCezary Zwolak }
189*a4e67616SCezary Zwolak 
190*a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerName)
191*a4e67616SCezary Zwolak {
192*a4e67616SCezary Zwolak     ASSERT_THAT(storedConfiguration.at("Name"), Eq(triggerParams.name()));
193*a4e67616SCezary Zwolak }
194*a4e67616SCezary Zwolak 
195*a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerIsDiscrete)
196*a4e67616SCezary Zwolak {
197*a4e67616SCezary Zwolak     ASSERT_THAT(storedConfiguration.at("IsDiscrete"),
198*a4e67616SCezary Zwolak                 Eq(triggerParams.isDiscrete()));
199*a4e67616SCezary Zwolak }
200*a4e67616SCezary Zwolak 
201*a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerLogToJournal)
202*a4e67616SCezary Zwolak {
203*a4e67616SCezary Zwolak     ASSERT_THAT(storedConfiguration.at("LogToJournal"),
204*a4e67616SCezary Zwolak                 Eq(triggerParams.logToRedfish()));
205*a4e67616SCezary Zwolak }
206*a4e67616SCezary Zwolak 
207*a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerLogToRedfish)
208*a4e67616SCezary Zwolak {
209*a4e67616SCezary Zwolak     ASSERT_THAT(storedConfiguration.at("LogToRedfish"),
210*a4e67616SCezary Zwolak                 Eq(triggerParams.logToRedfish()));
211*a4e67616SCezary Zwolak }
212*a4e67616SCezary Zwolak 
213*a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerUpdateReport)
214*a4e67616SCezary Zwolak {
215*a4e67616SCezary Zwolak     ASSERT_THAT(storedConfiguration.at("UpdateReport"),
216*a4e67616SCezary Zwolak                 Eq(triggerParams.updateReport()));
217*a4e67616SCezary Zwolak }
218*a4e67616SCezary Zwolak 
219*a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerReportNames)
220*a4e67616SCezary Zwolak {
221*a4e67616SCezary Zwolak     ASSERT_THAT(storedConfiguration.at("ReportNames"),
222*a4e67616SCezary Zwolak                 Eq(triggerParams.reportNames()));
223*a4e67616SCezary Zwolak }
224*a4e67616SCezary Zwolak 
225*a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerSensors)
226*a4e67616SCezary Zwolak {
227*a4e67616SCezary Zwolak     nlohmann::json expectedItem;
228*a4e67616SCezary Zwolak     expectedItem["sensorPath"] =
229*a4e67616SCezary Zwolak         "/xyz/openbmc_project/sensors/temperature/BMC_Temp";
230*a4e67616SCezary Zwolak     expectedItem["sensorMetadata"] = "";
231*a4e67616SCezary Zwolak 
232*a4e67616SCezary Zwolak     ASSERT_THAT(storedConfiguration.at("Sensors"), ElementsAre(expectedItem));
233*a4e67616SCezary Zwolak }
234*a4e67616SCezary Zwolak 
235*a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerThresholdParams)
236*a4e67616SCezary Zwolak {
237*a4e67616SCezary Zwolak     ASSERT_THAT(storedConfiguration.at("ThresholdParamsDiscriminator"), Eq(0));
238*a4e67616SCezary Zwolak 
239*a4e67616SCezary Zwolak     nlohmann::json expectedItem0;
240*a4e67616SCezary Zwolak     expectedItem0["type"] = 0;
241*a4e67616SCezary Zwolak     expectedItem0["dwellTime"] = 10;
242*a4e67616SCezary Zwolak     expectedItem0["direction"] = 1;
243*a4e67616SCezary Zwolak     expectedItem0["thresholdValue"] = 0.0;
244*a4e67616SCezary Zwolak 
245*a4e67616SCezary Zwolak     nlohmann::json expectedItem1;
246*a4e67616SCezary Zwolak     expectedItem1["type"] = 3;
247*a4e67616SCezary Zwolak     expectedItem1["dwellTime"] = 10;
248*a4e67616SCezary Zwolak     expectedItem1["direction"] = 2;
249*a4e67616SCezary Zwolak     expectedItem1["thresholdValue"] = 90.0;
250*a4e67616SCezary Zwolak 
251*a4e67616SCezary Zwolak     ASSERT_THAT(storedConfiguration.at("ThresholdParams"),
252*a4e67616SCezary Zwolak                 ElementsAre(expectedItem0, expectedItem1));
253*a4e67616SCezary Zwolak }
254