176833cb5SWludzik, Jozef #include "dbus_environment.hpp" 276833cb5SWludzik, Jozef #include "helpers.hpp" 3a4e67616SCezary 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" 7*e28aa53dSSzymon Dompke #include "trigger_manager.hpp" 84416fce6SCezary Zwolak #include "utils/conversion_trigger.hpp" 94416fce6SCezary Zwolak #include "utils/transform.hpp" 104416fce6SCezary Zwolak #include "utils/tstring.hpp" 114416fce6SCezary Zwolak 124416fce6SCezary Zwolak #include <boost/range/combine.hpp> 1376833cb5SWludzik, Jozef 1476833cb5SWludzik, Jozef using namespace testing; 1576833cb5SWludzik, Jozef using namespace std::literals::string_literals; 1676833cb5SWludzik, Jozef 17a4e67616SCezary Zwolak static constexpr size_t expectedTriggerVersion = 0; 18a4e67616SCezary Zwolak 1976833cb5SWludzik, Jozef class TestTrigger : public Test 2076833cb5SWludzik, Jozef { 2176833cb5SWludzik, Jozef public: 2276833cb5SWludzik, Jozef TriggerParams triggerParams; 234416fce6SCezary Zwolak TriggerParams triggerDiscreteParams = 244416fce6SCezary Zwolak TriggerParams() 25*e28aa53dSSzymon Dompke .id("DiscreteTrigger") 26*e28aa53dSSzymon Dompke .name("My Discrete Trigger") 274416fce6SCezary Zwolak .thresholdParams(std::vector<discrete::LabeledThresholdParam>{ 284416fce6SCezary Zwolak discrete::LabeledThresholdParam{ 294416fce6SCezary Zwolak "userId", discrete::Severity::warning, 30dcc4e193SKrzysztof Grobelny Milliseconds(10).count(), "15.2"}, 314416fce6SCezary Zwolak discrete::LabeledThresholdParam{ 324416fce6SCezary Zwolak "userId_2", discrete::Severity::critical, 33dcc4e193SKrzysztof Grobelny Milliseconds(5).count(), "32.7"}, 344416fce6SCezary Zwolak }); 3576833cb5SWludzik, Jozef 3676833cb5SWludzik, Jozef std::unique_ptr<TriggerManagerMock> triggerManagerMockPtr = 3776833cb5SWludzik, Jozef std::make_unique<NiceMock<TriggerManagerMock>>(); 38a4e67616SCezary Zwolak testing::NiceMock<StorageMock> storageMock; 3976833cb5SWludzik, Jozef std::unique_ptr<Trigger> sut; 4076833cb5SWludzik, Jozef 4176833cb5SWludzik, Jozef void SetUp() override 4276833cb5SWludzik, Jozef { 43a4e67616SCezary Zwolak sut = makeTrigger(triggerParams); 44a4e67616SCezary Zwolak } 45a4e67616SCezary Zwolak 464416fce6SCezary Zwolak static std::vector<LabeledSensorInfo> 474416fce6SCezary Zwolak convertToLabeledSensor(const SensorsInfo& sensorsInfo) 484416fce6SCezary Zwolak { 494416fce6SCezary Zwolak return utils::transform(sensorsInfo, [](const auto& sensorInfo) { 504416fce6SCezary Zwolak const auto& [sensorPath, sensorMetadata] = sensorInfo; 514416fce6SCezary Zwolak return LabeledSensorInfo("service1", sensorPath, sensorMetadata); 524416fce6SCezary Zwolak }); 534416fce6SCezary Zwolak } 544416fce6SCezary Zwolak 55a4e67616SCezary Zwolak std::unique_ptr<Trigger> makeTrigger(const TriggerParams& params) 56a4e67616SCezary Zwolak { 57a4e67616SCezary Zwolak return std::make_unique<Trigger>( 5876833cb5SWludzik, Jozef DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(), 59*e28aa53dSSzymon Dompke params.id(), params.name(), params.triggerActions(), 60*e28aa53dSSzymon Dompke params.reportNames(), params.sensors(), params.thresholdParams(), 611477fe6aSWludzik, Jozef std::vector<std::shared_ptr<interfaces::Threshold>>{}, 62a4e67616SCezary Zwolak *triggerManagerMockPtr, storageMock); 63a4e67616SCezary Zwolak } 64a4e67616SCezary Zwolak 65a4e67616SCezary Zwolak static interfaces::JsonStorage::FilePath to_file_path(std::string name) 66a4e67616SCezary Zwolak { 67a4e67616SCezary Zwolak return interfaces::JsonStorage::FilePath( 68a4e67616SCezary Zwolak std::to_string(std::hash<std::string>{}(name))); 6976833cb5SWludzik, Jozef } 7076833cb5SWludzik, Jozef 7176833cb5SWludzik, Jozef template <class T> 7276833cb5SWludzik, Jozef static T getProperty(const std::string& path, const std::string& property) 7376833cb5SWludzik, Jozef { 74*e28aa53dSSzymon Dompke return DbusEnvironment::getProperty<T>(path, Trigger::triggerIfaceName, 75*e28aa53dSSzymon Dompke property); 7676833cb5SWludzik, Jozef } 7776833cb5SWludzik, Jozef 78a4e67616SCezary Zwolak template <class T> 79a4e67616SCezary Zwolak static boost::system::error_code setProperty(const std::string& path, 80a4e67616SCezary Zwolak const std::string& property, 81a4e67616SCezary Zwolak const T& newValue) 82a4e67616SCezary Zwolak { 83*e28aa53dSSzymon Dompke return DbusEnvironment::setProperty<T>(path, Trigger::triggerIfaceName, 84*e28aa53dSSzymon Dompke property, newValue); 85a4e67616SCezary Zwolak } 86a4e67616SCezary Zwolak 8776833cb5SWludzik, Jozef boost::system::error_code deleteTrigger(const std::string& path) 8876833cb5SWludzik, Jozef { 8976833cb5SWludzik, Jozef std::promise<boost::system::error_code> methodPromise; 9076833cb5SWludzik, Jozef DbusEnvironment::getBus()->async_method_call( 9176833cb5SWludzik, Jozef [&methodPromise](boost::system::error_code ec) { 9276833cb5SWludzik, Jozef methodPromise.set_value(ec); 9376833cb5SWludzik, Jozef }, 9476833cb5SWludzik, Jozef DbusEnvironment::serviceName(), path, Trigger::deleteIfaceName, 9576833cb5SWludzik, Jozef "Delete"); 9676833cb5SWludzik, Jozef return DbusEnvironment::waitForFuture(methodPromise.get_future()); 9776833cb5SWludzik, Jozef } 9876833cb5SWludzik, Jozef }; 9976833cb5SWludzik, Jozef 10076833cb5SWludzik, Jozef TEST_F(TestTrigger, checkIfPropertiesAreSet) 10176833cb5SWludzik, Jozef { 102*e28aa53dSSzymon Dompke EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"), 103*e28aa53dSSzymon Dompke Eq(triggerParams.name())); 104a4e67616SCezary Zwolak EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"), Eq(true)); 1052001301aSSzymon Dompke EXPECT_THAT( 1062001301aSSzymon Dompke getProperty<std::vector<std::string>>(sut->getPath(), "TriggerActions"), 1072001301aSSzymon Dompke Eq(triggerParams.triggerActions())); 1084416fce6SCezary Zwolak EXPECT_THAT((getProperty<SensorsInfo>(sut->getPath(), "Sensors")), 1094416fce6SCezary Zwolak Eq(utils::fromLabeledSensorsInfo(triggerParams.sensors()))); 11076833cb5SWludzik, Jozef EXPECT_THAT( 11176833cb5SWludzik, Jozef getProperty<std::vector<std::string>>(sut->getPath(), "ReportNames"), 11276833cb5SWludzik, Jozef Eq(triggerParams.reportNames())); 11376833cb5SWludzik, Jozef EXPECT_THAT( 11476833cb5SWludzik, Jozef getProperty<TriggerThresholdParams>(sut->getPath(), "Thresholds"), 1154416fce6SCezary Zwolak Eq(std::visit(utils::FromLabeledThresholdParamConversion(), 1164416fce6SCezary Zwolak triggerParams.thresholdParams()))); 1174416fce6SCezary Zwolak } 1184416fce6SCezary Zwolak 119*e28aa53dSSzymon Dompke TEST_F(TestTrigger, setPropertyNameToCorrectValue) 120*e28aa53dSSzymon Dompke { 121*e28aa53dSSzymon Dompke std::string name = "custom name 1234 %^#5"; 122*e28aa53dSSzymon Dompke EXPECT_THAT(setProperty(sut->getPath(), "Name", name), 123*e28aa53dSSzymon Dompke Eq(boost::system::errc::success)); 124*e28aa53dSSzymon Dompke EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"), Eq(name)); 125*e28aa53dSSzymon Dompke } 126*e28aa53dSSzymon Dompke 1274416fce6SCezary Zwolak TEST_F(TestTrigger, checkIfNumericCoversionsAreGood) 1284416fce6SCezary Zwolak { 1294416fce6SCezary Zwolak const auto& labeledParamsBase = 1304416fce6SCezary Zwolak std::get<std::vector<numeric::LabeledThresholdParam>>( 1314416fce6SCezary Zwolak triggerParams.thresholdParams()); 1324416fce6SCezary Zwolak const auto paramsToCheck = 1334416fce6SCezary Zwolak std::visit(utils::FromLabeledThresholdParamConversion(), 1344416fce6SCezary Zwolak triggerParams.thresholdParams()); 1354416fce6SCezary Zwolak const auto labeledParamsToCheck = 1364416fce6SCezary Zwolak std::get<std::vector<numeric::LabeledThresholdParam>>(std::visit( 1374416fce6SCezary Zwolak utils::ToLabeledThresholdParamConversion(), paramsToCheck)); 1384416fce6SCezary Zwolak 1394416fce6SCezary Zwolak for (const auto& [tocheck, base] : 1404416fce6SCezary Zwolak boost::combine(labeledParamsToCheck, labeledParamsBase)) 1414416fce6SCezary Zwolak { 1424416fce6SCezary Zwolak EXPECT_THAT(tocheck.at_label<utils::tstring::Type>(), 1434416fce6SCezary Zwolak Eq(base.at_label<utils::tstring::Type>())); 1444416fce6SCezary Zwolak EXPECT_THAT(tocheck.at_label<utils::tstring::Direction>(), 1454416fce6SCezary Zwolak Eq(base.at_label<utils::tstring::Direction>())); 1464416fce6SCezary Zwolak EXPECT_THAT(tocheck.at_label<utils::tstring::DwellTime>(), 1474416fce6SCezary Zwolak Eq(base.at_label<utils::tstring::DwellTime>())); 1484416fce6SCezary Zwolak EXPECT_THAT(tocheck.at_label<utils::tstring::ThresholdValue>(), 1494416fce6SCezary Zwolak Eq(base.at_label<utils::tstring::ThresholdValue>())); 1504416fce6SCezary Zwolak } 1514416fce6SCezary Zwolak } 1524416fce6SCezary Zwolak 1534416fce6SCezary Zwolak TEST_F(TestTrigger, checkIfDiscreteCoversionsAreGood) 1544416fce6SCezary Zwolak { 1554416fce6SCezary Zwolak const auto& labeledParamsBase = 1564416fce6SCezary Zwolak std::get<std::vector<discrete::LabeledThresholdParam>>( 1574416fce6SCezary Zwolak triggerDiscreteParams.thresholdParams()); 1584416fce6SCezary Zwolak const auto paramsToCheck = 1594416fce6SCezary Zwolak std::visit(utils::FromLabeledThresholdParamConversion(), 1604416fce6SCezary Zwolak triggerDiscreteParams.thresholdParams()); 1614416fce6SCezary Zwolak const auto labeledParamsToCheck = 1624416fce6SCezary Zwolak std::get<std::vector<discrete::LabeledThresholdParam>>(std::visit( 1634416fce6SCezary Zwolak utils::ToLabeledThresholdParamConversion(), paramsToCheck)); 1644416fce6SCezary Zwolak 1654416fce6SCezary Zwolak for (const auto& [tocheck, base] : 1664416fce6SCezary Zwolak boost::combine(labeledParamsToCheck, labeledParamsBase)) 1674416fce6SCezary Zwolak { 1684416fce6SCezary Zwolak EXPECT_THAT(tocheck.at_label<utils::tstring::UserId>(), 1694416fce6SCezary Zwolak Eq(base.at_label<utils::tstring::UserId>())); 1704416fce6SCezary Zwolak EXPECT_THAT(tocheck.at_label<utils::tstring::Severity>(), 1714416fce6SCezary Zwolak Eq(base.at_label<utils::tstring::Severity>())); 1724416fce6SCezary Zwolak EXPECT_THAT(tocheck.at_label<utils::tstring::DwellTime>(), 1734416fce6SCezary Zwolak Eq(base.at_label<utils::tstring::DwellTime>())); 1744416fce6SCezary Zwolak EXPECT_THAT(tocheck.at_label<utils::tstring::ThresholdValue>(), 1754416fce6SCezary Zwolak Eq(base.at_label<utils::tstring::ThresholdValue>())); 1764416fce6SCezary Zwolak } 17776833cb5SWludzik, Jozef } 17876833cb5SWludzik, Jozef 17976833cb5SWludzik, Jozef TEST_F(TestTrigger, deleteTrigger) 18076833cb5SWludzik, Jozef { 181*e28aa53dSSzymon Dompke EXPECT_CALL(storageMock, remove(to_file_path(sut->getId()))); 18276833cb5SWludzik, Jozef EXPECT_CALL(*triggerManagerMockPtr, removeTrigger(sut.get())); 18376833cb5SWludzik, Jozef auto ec = deleteTrigger(sut->getPath()); 18476833cb5SWludzik, Jozef EXPECT_THAT(ec, Eq(boost::system::errc::success)); 18576833cb5SWludzik, Jozef } 18676833cb5SWludzik, Jozef 18776833cb5SWludzik, Jozef TEST_F(TestTrigger, deletingNonExistingTriggerReturnInvalidRequestDescriptor) 18876833cb5SWludzik, Jozef { 18976833cb5SWludzik, Jozef auto ec = deleteTrigger(Trigger::triggerDir + "NonExisting"s); 19076833cb5SWludzik, Jozef EXPECT_THAT(ec.value(), Eq(EBADR)); 19176833cb5SWludzik, Jozef } 192a4e67616SCezary Zwolak 1934416fce6SCezary Zwolak TEST_F(TestTrigger, settingPersistencyToFalseRemovesTriggerFromStorage) 194a4e67616SCezary Zwolak { 195*e28aa53dSSzymon Dompke EXPECT_CALL(storageMock, remove(to_file_path(sut->getId()))); 196a4e67616SCezary Zwolak 197a4e67616SCezary Zwolak bool persistent = false; 1984416fce6SCezary Zwolak EXPECT_THAT(setProperty(sut->getPath(), "Persistent", persistent), 199a4e67616SCezary Zwolak Eq(boost::system::errc::success)); 200a4e67616SCezary Zwolak EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"), 201a4e67616SCezary Zwolak Eq(persistent)); 202a4e67616SCezary Zwolak } 203a4e67616SCezary Zwolak 204a4e67616SCezary Zwolak class TestTriggerErrors : public TestTrigger 205a4e67616SCezary Zwolak { 206a4e67616SCezary Zwolak public: 207a4e67616SCezary Zwolak void SetUp() override 208a4e67616SCezary Zwolak {} 209a4e67616SCezary Zwolak 210a4e67616SCezary Zwolak nlohmann::json storedConfiguration; 211a4e67616SCezary Zwolak }; 212a4e67616SCezary Zwolak 2134416fce6SCezary Zwolak TEST_F(TestTriggerErrors, exceptionDuringTriggerStoreDisablesPersistency) 214a4e67616SCezary Zwolak { 215a4e67616SCezary Zwolak EXPECT_CALL(storageMock, store(_, _)) 216a4e67616SCezary Zwolak .WillOnce(Throw(std::runtime_error("Generic error!"))); 217a4e67616SCezary Zwolak 218a4e67616SCezary Zwolak sut = makeTrigger(triggerParams); 219a4e67616SCezary Zwolak 220a4e67616SCezary Zwolak EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"), Eq(false)); 221a4e67616SCezary Zwolak } 222a4e67616SCezary Zwolak 223*e28aa53dSSzymon Dompke TEST_F(TestTriggerErrors, creatingTriggerThrowsExceptionWhenIdIsInvalid) 224a4e67616SCezary Zwolak { 225a4e67616SCezary Zwolak EXPECT_CALL(storageMock, store(_, _)).Times(0); 226a4e67616SCezary Zwolak 227*e28aa53dSSzymon Dompke EXPECT_THROW(makeTrigger(triggerParams.id("inv?lidId")), 228a4e67616SCezary Zwolak sdbusplus::exception::SdBusError); 229a4e67616SCezary Zwolak } 230a4e67616SCezary Zwolak 231a4e67616SCezary Zwolak class TestTriggerStore : public TestTrigger 232a4e67616SCezary Zwolak { 233a4e67616SCezary Zwolak public: 2344416fce6SCezary Zwolak nlohmann::json storedConfiguration; 2354416fce6SCezary Zwolak nlohmann::json storedDiscreteConfiguration; 2364416fce6SCezary Zwolak std::unique_ptr<Trigger> sutDiscrete; 2374416fce6SCezary Zwolak 238a4e67616SCezary Zwolak void SetUp() override 239a4e67616SCezary Zwolak { 240a4e67616SCezary Zwolak ON_CALL(storageMock, store(_, _)) 241a4e67616SCezary Zwolak .WillByDefault(SaveArg<1>(&storedConfiguration)); 242a4e67616SCezary Zwolak sut = makeTrigger(triggerParams); 243a4e67616SCezary Zwolak 2444416fce6SCezary Zwolak ON_CALL(storageMock, store(_, _)) 2454416fce6SCezary Zwolak .WillByDefault(SaveArg<1>(&storedDiscreteConfiguration)); 2464416fce6SCezary Zwolak sutDiscrete = makeTrigger(triggerDiscreteParams); 2474416fce6SCezary Zwolak } 248a4e67616SCezary Zwolak }; 249a4e67616SCezary Zwolak 250a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerVersion) 251a4e67616SCezary Zwolak { 252a4e67616SCezary Zwolak ASSERT_THAT(storedConfiguration.at("Version"), Eq(expectedTriggerVersion)); 253a4e67616SCezary Zwolak } 254a4e67616SCezary Zwolak 255*e28aa53dSSzymon Dompke TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerId) 256*e28aa53dSSzymon Dompke { 257*e28aa53dSSzymon Dompke ASSERT_THAT(storedConfiguration.at("Id"), Eq(triggerParams.id())); 258*e28aa53dSSzymon Dompke } 259*e28aa53dSSzymon Dompke 260a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerName) 261a4e67616SCezary Zwolak { 262a4e67616SCezary Zwolak ASSERT_THAT(storedConfiguration.at("Name"), Eq(triggerParams.name())); 263a4e67616SCezary Zwolak } 264a4e67616SCezary Zwolak 2652001301aSSzymon Dompke TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerTriggerActions) 266a4e67616SCezary Zwolak { 2672001301aSSzymon Dompke ASSERT_THAT(storedConfiguration.at("TriggerActions"), 2682001301aSSzymon Dompke Eq(triggerParams.triggerActions())); 269a4e67616SCezary Zwolak } 270a4e67616SCezary Zwolak 271a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerReportNames) 272a4e67616SCezary Zwolak { 273a4e67616SCezary Zwolak ASSERT_THAT(storedConfiguration.at("ReportNames"), 274a4e67616SCezary Zwolak Eq(triggerParams.reportNames())); 275a4e67616SCezary Zwolak } 276a4e67616SCezary Zwolak 277a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerSensors) 278a4e67616SCezary Zwolak { 279a4e67616SCezary Zwolak nlohmann::json expectedItem; 2804416fce6SCezary Zwolak expectedItem["service"] = "service1"; 281a4e67616SCezary Zwolak expectedItem["sensorPath"] = 282a4e67616SCezary Zwolak "/xyz/openbmc_project/sensors/temperature/BMC_Temp"; 2834416fce6SCezary Zwolak expectedItem["sensorMetadata"] = "metadata1"; 284a4e67616SCezary Zwolak 285a4e67616SCezary Zwolak ASSERT_THAT(storedConfiguration.at("Sensors"), ElementsAre(expectedItem)); 286a4e67616SCezary Zwolak } 287a4e67616SCezary Zwolak 288a4e67616SCezary Zwolak TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerThresholdParams) 289a4e67616SCezary Zwolak { 290a4e67616SCezary Zwolak nlohmann::json expectedItem0; 291a4e67616SCezary Zwolak expectedItem0["type"] = 0; 292a4e67616SCezary Zwolak expectedItem0["dwellTime"] = 10; 293a4e67616SCezary Zwolak expectedItem0["direction"] = 1; 2944416fce6SCezary Zwolak expectedItem0["thresholdValue"] = 0.5; 295a4e67616SCezary Zwolak 296a4e67616SCezary Zwolak nlohmann::json expectedItem1; 297a4e67616SCezary Zwolak expectedItem1["type"] = 3; 298a4e67616SCezary Zwolak expectedItem1["dwellTime"] = 10; 299a4e67616SCezary Zwolak expectedItem1["direction"] = 2; 3004416fce6SCezary Zwolak expectedItem1["thresholdValue"] = 90.2; 301a4e67616SCezary Zwolak 3024416fce6SCezary Zwolak ASSERT_THAT(storedConfiguration.at("ThresholdParamsDiscriminator"), Eq(0)); 303a4e67616SCezary Zwolak ASSERT_THAT(storedConfiguration.at("ThresholdParams"), 304a4e67616SCezary Zwolak ElementsAre(expectedItem0, expectedItem1)); 305a4e67616SCezary Zwolak } 3064416fce6SCezary Zwolak 3074416fce6SCezary Zwolak TEST_F(TestTriggerStore, 3084416fce6SCezary Zwolak settingPersistencyToTrueStoresDiscreteTriggerThresholdParams) 3094416fce6SCezary Zwolak { 3104416fce6SCezary Zwolak nlohmann::json expectedItem0; 3114416fce6SCezary Zwolak expectedItem0["userId"] = "userId"; 3124416fce6SCezary Zwolak expectedItem0["severity"] = discrete::Severity::warning; 3134416fce6SCezary Zwolak expectedItem0["dwellTime"] = 10; 3149f346790SSzymon Dompke expectedItem0["thresholdValue"] = "15.2"; 3154416fce6SCezary Zwolak 3164416fce6SCezary Zwolak nlohmann::json expectedItem1; 3174416fce6SCezary Zwolak expectedItem1["userId"] = "userId_2"; 3184416fce6SCezary Zwolak expectedItem1["severity"] = discrete::Severity::critical; 3194416fce6SCezary Zwolak expectedItem1["dwellTime"] = 5; 3209f346790SSzymon Dompke expectedItem1["thresholdValue"] = "32.7"; 3214416fce6SCezary Zwolak 3224416fce6SCezary Zwolak ASSERT_THAT(storedDiscreteConfiguration.at("ThresholdParamsDiscriminator"), 3234416fce6SCezary Zwolak Eq(1)); 3244416fce6SCezary Zwolak ASSERT_THAT(storedDiscreteConfiguration.at("ThresholdParams"), 3254416fce6SCezary Zwolak ElementsAre(expectedItem0, expectedItem1)); 3264416fce6SCezary Zwolak } 327