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