blob: f3965890e56f9c080442f01f0bf4f5a4dacac6c3 [file] [log] [blame]
Wludzik, Jozef76833cb2020-12-21 14:42:41 +01001#include "dbus_environment.hpp"
2#include "helpers.hpp"
Cezary Zwolaka4e67612021-02-18 13:16:16 +01003#include "mocks/json_storage_mock.hpp"
Wludzik, Jozef76833cb2020-12-21 14:42:41 +01004#include "mocks/trigger_manager_mock.hpp"
5#include "params/trigger_params.hpp"
6#include "trigger.hpp"
7#include "utils/set_exception.hpp"
8
9using namespace testing;
10using namespace std::literals::string_literals;
11
Cezary Zwolaka4e67612021-02-18 13:16:16 +010012static constexpr size_t expectedTriggerVersion = 0;
13
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010014class TestTrigger : public Test
15{
16 public:
17 TriggerParams triggerParams;
18
19 std::unique_ptr<TriggerManagerMock> triggerManagerMockPtr =
20 std::make_unique<NiceMock<TriggerManagerMock>>();
Cezary Zwolaka4e67612021-02-18 13:16:16 +010021 testing::NiceMock<StorageMock> storageMock;
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010022 std::unique_ptr<Trigger> sut;
23
24 void SetUp() override
25 {
Cezary Zwolaka4e67612021-02-18 13:16:16 +010026 sut = makeTrigger(triggerParams);
27 }
28
29 std::unique_ptr<Trigger> makeTrigger(const TriggerParams& params)
30 {
31 return std::make_unique<Trigger>(
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010032 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
Cezary Zwolaka4e67612021-02-18 13:16:16 +010033 params.name(), params.isDiscrete(), params.logToJournal(),
34 params.logToRedfish(), params.updateReport(), params.sensors(),
35 params.reportNames(), params.thresholdParams(),
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010036 std::vector<std::shared_ptr<interfaces::Threshold>>{},
Cezary Zwolaka4e67612021-02-18 13:16:16 +010037 *triggerManagerMockPtr, storageMock);
38 }
39
40 static interfaces::JsonStorage::FilePath to_file_path(std::string name)
41 {
42 return interfaces::JsonStorage::FilePath(
43 std::to_string(std::hash<std::string>{}(name)));
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010044 }
45
46 template <class T>
47 static T getProperty(const std::string& path, const std::string& property)
48 {
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080049 auto propertyPromise = std::promise<T>();
50 auto propertyFuture = propertyPromise.get_future();
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010051 sdbusplus::asio::getProperty<T>(
52 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
53 Trigger::triggerIfaceName, property,
Ed Tanous0e7ae5d2021-02-23 14:06:49 -080054 [&propertyPromise](const boost::system::error_code& ec, T t) {
55 if (ec)
56 {
57 utils::setException(propertyPromise, "GetProperty failed");
58 return;
59 }
60 propertyPromise.set_value(t);
61 });
62 return DbusEnvironment::waitForFuture(std::move(propertyFuture));
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010063 }
64
Cezary Zwolaka4e67612021-02-18 13:16:16 +010065 template <class T>
66 static boost::system::error_code setProperty(const std::string& path,
67 const std::string& property,
68 const T& newValue)
69 {
70 auto setPromise = std::promise<boost::system::error_code>();
71 auto setFuture = setPromise.get_future();
72
73 sdbusplus::asio::setProperty(
74 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
75 Trigger::triggerIfaceName, property, std::move(newValue),
76 [setPromise =
77 std::move(setPromise)](boost::system::error_code ec) mutable {
78 setPromise.set_value(ec);
79 });
80 return DbusEnvironment::waitForFuture(std::move(setFuture));
81 }
82
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010083 boost::system::error_code deleteTrigger(const std::string& path)
84 {
85 std::promise<boost::system::error_code> methodPromise;
86 DbusEnvironment::getBus()->async_method_call(
87 [&methodPromise](boost::system::error_code ec) {
88 methodPromise.set_value(ec);
89 },
90 DbusEnvironment::serviceName(), path, Trigger::deleteIfaceName,
91 "Delete");
92 return DbusEnvironment::waitForFuture(methodPromise.get_future());
93 }
94};
95
96TEST_F(TestTrigger, checkIfPropertiesAreSet)
97{
Cezary Zwolaka4e67612021-02-18 13:16:16 +010098 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"), Eq(true));
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010099 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Discrete"),
100 Eq(triggerParams.isDiscrete()));
101 EXPECT_THAT(getProperty<bool>(sut->getPath(), "LogToJournal"),
102 Eq(triggerParams.logToJournal()));
103 EXPECT_THAT(getProperty<bool>(sut->getPath(), "LogToRedfish"),
104 Eq(triggerParams.logToRedfish()));
105 EXPECT_THAT(getProperty<bool>(sut->getPath(), "UpdateReport"),
106 Eq(triggerParams.updateReport()));
107 EXPECT_THAT((getProperty<std::vector<
108 std::pair<sdbusplus::message::object_path, std::string>>>(
109 sut->getPath(), "Sensors")),
110 Eq(triggerParams.sensors()));
111 EXPECT_THAT(
112 getProperty<std::vector<std::string>>(sut->getPath(), "ReportNames"),
113 Eq(triggerParams.reportNames()));
114 EXPECT_THAT(
115 getProperty<TriggerThresholdParams>(sut->getPath(), "Thresholds"),
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100116 Eq(triggerParams.thresholdParams()));
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100117}
118
119TEST_F(TestTrigger, deleteTrigger)
120{
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100121 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100122 EXPECT_CALL(*triggerManagerMockPtr, removeTrigger(sut.get()));
123 auto ec = deleteTrigger(sut->getPath());
124 EXPECT_THAT(ec, Eq(boost::system::errc::success));
125}
126
127TEST_F(TestTrigger, deletingNonExistingTriggerReturnInvalidRequestDescriptor)
128{
129 auto ec = deleteTrigger(Trigger::triggerDir + "NonExisting"s);
130 EXPECT_THAT(ec.value(), Eq(EBADR));
131}
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100132
133TEST_F(TestTrigger, settingPersistencyToFalseRemovesReportFromStorage)
134{
135 EXPECT_CALL(storageMock, remove(to_file_path(sut->getName())));
136
137 bool persistent = false;
138 EXPECT_THAT(setProperty(sut->getPath(), "Persistent", persistent).value(),
139 Eq(boost::system::errc::success));
140 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"),
141 Eq(persistent));
142}
143
144class TestTriggerErrors : public TestTrigger
145{
146 public:
147 void SetUp() override
148 {}
149
150 nlohmann::json storedConfiguration;
151};
152
153TEST_F(TestTriggerErrors, throwingExceptionDoesNotStoreTriggerReportNames)
154{
155 EXPECT_CALL(storageMock, store(_, _))
156 .WillOnce(Throw(std::runtime_error("Generic error!")));
157
158 sut = makeTrigger(triggerParams);
159
160 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"), Eq(false));
161}
162
163TEST_F(TestTriggerErrors, creatingTriggerThrowsExceptionWhenNameIsInvalid)
164{
165 EXPECT_CALL(storageMock, store(_, _)).Times(0);
166
167 EXPECT_THROW(makeTrigger(triggerParams.name("inv?lidName")),
168 sdbusplus::exception::SdBusError);
169}
170
171class TestTriggerStore : public TestTrigger
172{
173 public:
174 void SetUp() override
175 {
176 ON_CALL(storageMock, store(_, _))
177 .WillByDefault(SaveArg<1>(&storedConfiguration));
178
179 sut = makeTrigger(triggerParams);
180 }
181
182 nlohmann::json storedConfiguration;
183};
184
185TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerVersion)
186{
187 ASSERT_THAT(storedConfiguration.at("Version"), Eq(expectedTriggerVersion));
188}
189
190TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerName)
191{
192 ASSERT_THAT(storedConfiguration.at("Name"), Eq(triggerParams.name()));
193}
194
195TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerIsDiscrete)
196{
197 ASSERT_THAT(storedConfiguration.at("IsDiscrete"),
198 Eq(triggerParams.isDiscrete()));
199}
200
201TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerLogToJournal)
202{
203 ASSERT_THAT(storedConfiguration.at("LogToJournal"),
204 Eq(triggerParams.logToRedfish()));
205}
206
207TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerLogToRedfish)
208{
209 ASSERT_THAT(storedConfiguration.at("LogToRedfish"),
210 Eq(triggerParams.logToRedfish()));
211}
212
213TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerUpdateReport)
214{
215 ASSERT_THAT(storedConfiguration.at("UpdateReport"),
216 Eq(triggerParams.updateReport()));
217}
218
219TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerReportNames)
220{
221 ASSERT_THAT(storedConfiguration.at("ReportNames"),
222 Eq(triggerParams.reportNames()));
223}
224
225TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerSensors)
226{
227 nlohmann::json expectedItem;
228 expectedItem["sensorPath"] =
229 "/xyz/openbmc_project/sensors/temperature/BMC_Temp";
230 expectedItem["sensorMetadata"] = "";
231
232 ASSERT_THAT(storedConfiguration.at("Sensors"), ElementsAre(expectedItem));
233}
234
235TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerThresholdParams)
236{
237 ASSERT_THAT(storedConfiguration.at("ThresholdParamsDiscriminator"), Eq(0));
238
239 nlohmann::json expectedItem0;
240 expectedItem0["type"] = 0;
241 expectedItem0["dwellTime"] = 10;
242 expectedItem0["direction"] = 1;
243 expectedItem0["thresholdValue"] = 0.0;
244
245 nlohmann::json expectedItem1;
246 expectedItem1["type"] = 3;
247 expectedItem1["dwellTime"] = 10;
248 expectedItem1["direction"] = 2;
249 expectedItem1["thresholdValue"] = 90.0;
250
251 ASSERT_THAT(storedConfiguration.at("ThresholdParams"),
252 ElementsAre(expectedItem0, expectedItem1));
253}