1 #include "dbus_environment.hpp" 2 #include "fakes/clock_fake.hpp" 3 #include "helpers.hpp" 4 #include "messages/collect_trigger_id.hpp" 5 #include "messages/trigger_presence_changed_ind.hpp" 6 #include "messages/update_report_ind.hpp" 7 #include "mocks/json_storage_mock.hpp" 8 #include "mocks/metric_mock.hpp" 9 #include "mocks/report_factory_mock.hpp" 10 #include "mocks/report_manager_mock.hpp" 11 #include "params/report_params.hpp" 12 #include "report.hpp" 13 #include "report_manager.hpp" 14 #include "utils/clock.hpp" 15 #include "utils/contains.hpp" 16 #include "utils/conv_container.hpp" 17 #include "utils/dbus_path_utils.hpp" 18 #include "utils/messanger.hpp" 19 #include "utils/transform.hpp" 20 #include "utils/tstring.hpp" 21 22 #include <sdbusplus/exception.hpp> 23 24 using namespace testing; 25 using namespace std::literals::string_literals; 26 using namespace std::chrono_literals; 27 using sdbusplus::message::object_path; 28 namespace tstring = utils::tstring; 29 30 using ErrorMessageDbusType = std::tuple<std::string, std::string>; 31 using ErrorMessagesDbusType = std::vector<ErrorMessageDbusType>; 32 33 constexpr Milliseconds systemTimestamp = 55ms; 34 35 namespace 36 { 37 38 ReportParams defaultParams() 39 { 40 return ReportParams(); 41 } 42 43 ReportParams defaultOnChangeParams() 44 { 45 return defaultParams().reportingType(ReportingType::onChange); 46 } 47 48 } // namespace 49 50 class TestReport : public Test 51 { 52 public: 53 std::unique_ptr<ReportManagerMock> reportManagerMock = 54 std::make_unique<NiceMock<ReportManagerMock>>(); 55 std::unique_ptr<ReportFactoryMock> reportFactoryMock = 56 std::make_unique<NiceMock<ReportFactoryMock>>(); 57 nlohmann::json storedConfiguration; 58 NiceMock<StorageMock> storageMock; 59 std::vector<std::shared_ptr<MetricMock>> metricMocks; 60 std::unique_ptr<ClockFake> clockFakePtr = std::make_unique<ClockFake>(); 61 ClockFake& clockFake = *clockFakePtr; 62 std::unique_ptr<Report> sut; 63 utils::Messanger messanger; 64 65 MockFunction<void()> checkPoint; 66 67 TestReport() : messanger(DbusEnvironment::getIoc()) 68 { 69 clockFake.system.set(systemTimestamp); 70 ON_CALL(storageMock, store(to_file_path(ReportParams().reportId()), _)) 71 .WillByDefault(SaveArg<1>(&storedConfiguration)); 72 } 73 74 void initMetricMocks( 75 const std::vector<LabeledMetricParameters>& metricParameters) 76 { 77 for (auto i = metricMocks.size(); i < metricParameters.size(); ++i) 78 { 79 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>()); 80 } 81 metricMocks.resize(metricParameters.size()); 82 83 std::vector<MetricValue> readings{{MetricValue{"a", "b", 17.1, 114}, 84 MetricValue{"aa", "bb", 42.0, 74}}}; 85 readings.resize(metricParameters.size()); 86 87 for (size_t i = 0; i < metricParameters.size(); ++i) 88 { 89 ON_CALL(*metricMocks[i], getUpdatedReadings()) 90 .WillByDefault(ReturnRefOfCopy(std::vector({readings[i]}))); 91 ON_CALL(*metricMocks[i], dumpConfiguration()) 92 .WillByDefault(Return(metricParameters[i])); 93 } 94 } 95 96 std::vector<std::shared_ptr<interfaces::Metric>> 97 getMetricsFromReadingParams(const ReadingParameters& params) 98 { 99 const auto metricParameters = 100 reportFactoryMock->convertMetricParams(params); 101 std::vector<std::shared_ptr<MetricMock>> metricMocks; 102 103 for (size_t i = 0; i < metricParameters.size(); ++i) 104 { 105 metricMocks.emplace_back(std::make_shared<NiceMock<MetricMock>>()); 106 ON_CALL(*metricMocks[i], dumpConfiguration()) 107 .WillByDefault(Return(metricParameters[i])); 108 } 109 110 return utils::convContainer<std::shared_ptr<interfaces::Metric>>( 111 metricMocks); 112 } 113 114 void SetUp() override 115 { 116 sut = makeReport(defaultParams()); 117 } 118 119 static interfaces::JsonStorage::FilePath to_file_path(std::string id) 120 { 121 return interfaces::JsonStorage::FilePath( 122 std::to_string(std::hash<std::string>{}(id))); 123 } 124 125 std::unique_ptr<Report> makeReport(const ReportParams& params) 126 { 127 initMetricMocks(params.metricParameters()); 128 129 return std::make_unique<Report>( 130 DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(), 131 params.reportId(), params.reportName(), params.reportingType(), 132 params.reportActions(), params.interval(), params.appendLimit(), 133 params.reportUpdates(), *reportManagerMock, storageMock, 134 utils::convContainer<std::shared_ptr<interfaces::Metric>>( 135 metricMocks), 136 *reportFactoryMock, params.enabled(), std::move(clockFakePtr), 137 params.readings()); 138 } 139 140 template <class T> 141 static T getProperty(const std::string& path, const std::string& property) 142 { 143 return DbusEnvironment::getProperty<T>(path, Report::reportIfaceName, 144 property); 145 } 146 147 template <class T> 148 static boost::system::error_code setProperty(const std::string& path, 149 const std::string& property, 150 const T& newValue) 151 { 152 return DbusEnvironment::setProperty<T>(path, Report::reportIfaceName, 153 property, newValue); 154 } 155 156 template <class T> 157 struct ChangePropertyParams 158 { 159 Matcher<T> valueBefore = _; 160 T newValue; 161 Matcher<boost::system::error_code> ec = 162 Eq(boost::system::errc::success); 163 Matcher<T> valueAfter = Eq(newValue); 164 }; 165 166 template <class T> 167 static void changeProperty(const std::string& path, 168 const std::string& property, 169 ChangePropertyParams<T> p) 170 { 171 ASSERT_THAT(getProperty<T>(path, property), p.valueBefore); 172 ASSERT_THAT(setProperty<T>(path, property, p.newValue), p.ec); 173 EXPECT_THAT(getProperty<T>(path, property), p.valueAfter); 174 } 175 176 boost::system::error_code call(const std::string& path, 177 const std::string& interface, 178 const std::string& method) 179 { 180 std::promise<boost::system::error_code> methodPromise; 181 DbusEnvironment::getBus()->async_method_call( 182 [&methodPromise](boost::system::error_code ec) { 183 methodPromise.set_value(ec); 184 }, 185 DbusEnvironment::serviceName(), path, interface, method); 186 return DbusEnvironment::waitForFuture(methodPromise.get_future()); 187 } 188 189 boost::system::error_code update(const std::string& path) 190 { 191 return call(path, Report::reportIfaceName, "Update"); 192 } 193 194 boost::system::error_code deleteReport(const std::string& path) 195 { 196 return call(path, Report::deleteIfaceName, "Delete"); 197 } 198 199 static std::pair<std::string, std::vector<std::string>> 200 makeStateDetail(const std::string& detailType, 201 std::vector<std::string> detailArgs) 202 { 203 return make_pair(detailType, detailArgs); 204 } 205 }; 206 207 TEST_F(TestReport, returnsId) 208 { 209 EXPECT_THAT(sut->getId(), Eq(defaultParams().reportId())); 210 } 211 212 TEST_F(TestReport, verifyIfPropertiesHaveValidValue) 213 { 214 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), 215 Eq(defaultParams().enabled())); 216 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"), 217 Eq(defaultParams().interval().count())); 218 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true)); 219 EXPECT_THAT( 220 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"), 221 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) { 222 return utils::enumToString(v); 223 }))); 224 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"), 225 Eq(utils::contains(defaultParams().reportActions(), 226 ReportAction::emitsReadingsUpdate))); 227 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"), 228 Eq(defaultParams().appendLimit())); 229 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"), 230 Eq(utils::enumToString(defaultParams().reportingType()))); 231 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"), 232 Eq(utils::enumToString(defaultParams().reportUpdates()))); 233 EXPECT_THAT( 234 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"), 235 Eq(utils::contains(defaultParams().reportActions(), 236 ReportAction::logToMetricReportsCollection))); 237 EXPECT_THAT(getProperty<ReadingParameters>( 238 sut->getPath(), "ReadingParametersFutureVersion"), 239 Eq(toReadingParameters(defaultParams().metricParameters()))); 240 EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"), 241 Eq(defaultParams().reportName())); 242 EXPECT_THAT( 243 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"), 244 IsEmpty()); 245 EXPECT_THAT( 246 getProperty<ErrorMessagesDbusType>(sut->getPath(), "ErrorMessages"), 247 IsEmpty()); 248 } 249 250 TEST_F(TestReport, readingsAreInitialyEmpty) 251 { 252 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"), 253 Eq(Readings{})); 254 } 255 256 TEST_F(TestReport, setReadingParametersWithNewParams) 257 { 258 ReadingParameters newParams = toReadingParameters( 259 std::vector<LabeledMetricParameters>{{LabeledMetricParameters{ 260 {LabeledSensorInfo{"Service", 261 "/xyz/openbmc_project/sensors/power/psu", 262 "NewMetadata123"}}, 263 OperationType::avg, 264 "NewMetricId123", 265 CollectionTimeScope::startup, 266 CollectionDuration(250ms)}}}); 267 auto metrics = getMetricsFromReadingParams(newParams); 268 269 EXPECT_CALL(*reportFactoryMock, updateMetrics(_, _, _)) 270 .WillOnce(SetArgReferee<0>(metrics)); 271 EXPECT_THAT( 272 setProperty(sut->getPath(), "ReadingParametersFutureVersion", newParams) 273 .value(), 274 Eq(boost::system::errc::success)); 275 EXPECT_THAT(getProperty<ReadingParameters>( 276 sut->getPath(), "ReadingParametersFutureVersion"), 277 Eq(newParams)); 278 } 279 280 TEST_F(TestReport, setReportingTypeWithValidNewType) 281 { 282 changeProperty<std::string>( 283 sut->getPath(), "ReportingType", 284 {.valueBefore = Not(Eq(utils::enumToString(ReportingType::onRequest))), 285 .newValue = utils::enumToString(ReportingType::onRequest)}); 286 } 287 288 TEST_F(TestReport, setReportingTypeWithInvalidType) 289 { 290 const std::string currentValue = 291 utils::enumToString(defaultParams().reportingType()); 292 293 changeProperty<std::string>( 294 sut->getPath(), "ReportingType", 295 {.valueBefore = Eq(currentValue), 296 .newValue = "Periodic_ABC", 297 .ec = Eq(boost::system::errc::invalid_argument), 298 .valueAfter = Eq(currentValue)}); 299 } 300 301 TEST_F(TestReport, setReportActionsWithValidNewActions) 302 { 303 std::vector<std::string> newActions = {"EmitsReadingsUpdate"}; 304 std::vector<std::string> currActions = 305 utils::transform(defaultParams().reportActions(), 306 [](const auto v) { return utils::enumToString(v); }); 307 308 EXPECT_THAT(newActions, Ne(currActions)); 309 EXPECT_THAT( 310 setProperty(sut->getPath(), "ReportActions", newActions).value(), 311 Eq(boost::system::errc::success)); 312 EXPECT_THAT( 313 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"), 314 UnorderedElementsAre("EmitsReadingsUpdate", 315 "LogToMetricReportsCollection")); 316 } 317 318 TEST_F(TestReport, setReportActionsWithValidUnsortedActions) 319 { 320 std::vector<std::string> newActions = {"LogToMetricReportsCollection", 321 "EmitsReadingsUpdate"}; 322 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate", 323 "LogToMetricReportsCollection"}; 324 std::vector<std::string> currActions = 325 utils::transform(defaultParams().reportActions(), 326 [](const auto v) { return utils::enumToString(v); }); 327 328 EXPECT_THAT(newActions, Ne(currActions)); 329 EXPECT_THAT( 330 setProperty(sut->getPath(), "ReportActions", newActions).value(), 331 Eq(boost::system::errc::success)); 332 EXPECT_THAT( 333 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"), 334 Eq(expectedActions)); 335 } 336 337 TEST_F(TestReport, setReportActionsWithEmptyActions) 338 { 339 std::vector<std::string> newActions = {}; 340 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"}; 341 std::vector<std::string> currActions = 342 utils::transform(defaultParams().reportActions(), 343 [](const auto v) { return utils::enumToString(v); }); 344 345 EXPECT_THAT(newActions, Ne(currActions)); 346 EXPECT_THAT( 347 setProperty(sut->getPath(), "ReportActions", newActions).value(), 348 Eq(boost::system::errc::success)); 349 EXPECT_THAT( 350 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"), 351 Eq(expectedActions)); 352 } 353 354 TEST_F(TestReport, setReportActionsWithInvalidActions) 355 { 356 std::vector<std::string> invalidActions = {"EmitsReadingsUpdate_1"}; 357 EXPECT_THAT( 358 setProperty(sut->getPath(), "ReportActions", invalidActions).value(), 359 Eq(boost::system::errc::invalid_argument)); 360 EXPECT_THAT( 361 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"), 362 Eq(utils::transform(defaultParams().reportActions(), [](const auto v) { 363 return utils::enumToString(v); 364 }))); 365 } 366 367 TEST_F(TestReport, createReportWithEmptyActions) 368 { 369 std::vector<std::string> expectedActions = {"LogToMetricReportsCollection"}; 370 371 sut = makeReport(ReportParams().reportId("TestId_1").reportActions({})); 372 EXPECT_THAT( 373 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"), 374 Eq(expectedActions)); 375 } 376 377 TEST_F(TestReport, createReportWithValidUnsortedActions) 378 { 379 std::vector<std::string> newActions = {"LogToMetricReportsCollection", 380 "EmitsReadingsUpdate"}; 381 std::vector<std::string> expectedActions = {"EmitsReadingsUpdate", 382 "LogToMetricReportsCollection"}; 383 384 sut = makeReport( 385 ReportParams() 386 .reportId("TestId_1") 387 .reportActions(utils::transform(newActions, [](const auto& action) { 388 return utils::toReportAction(action); 389 }))); 390 EXPECT_THAT( 391 getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"), 392 Eq(expectedActions)); 393 } 394 395 TEST_F(TestReport, setEnabledWithNewValue) 396 { 397 bool newValue = !defaultParams().enabled(); 398 EXPECT_THAT(setProperty(sut->getPath(), "Enabled", newValue).value(), 399 Eq(boost::system::errc::success)); 400 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Enabled"), Eq(newValue)); 401 } 402 403 TEST_F(TestReport, setIntervalWithValidValue) 404 { 405 uint64_t newValue = ReportManager::minInterval.count() * 42; 406 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(), 407 Eq(boost::system::errc::success)); 408 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"), 409 Eq(newValue)); 410 } 411 412 TEST_F( 413 TestReport, 414 settingIntervalWithInvalidValueDoesNotChangePropertyAndReturnsInvalidArgument) 415 { 416 uint64_t newValue = ReportManager::minInterval.count() - 1; 417 EXPECT_THAT(setProperty(sut->getPath(), "Interval", newValue).value(), 418 Eq(boost::system::errc::invalid_argument)); 419 EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"), 420 Eq(defaultParams().interval().count())); 421 } 422 423 TEST_F(TestReport, settingInvalidReportingTypeCreatesErrorMessage) 424 { 425 auto report = makeReport(defaultParams() 426 .reportId("report2") 427 .reportingType(ReportingType::onRequest) 428 .interval(Milliseconds{0})); 429 430 EXPECT_THAT( 431 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic") 432 .value(), 433 Eq(boost::system::errc::success)); 434 435 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"), 436 Eq("Periodic")); 437 EXPECT_THAT( 438 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"), 439 UnorderedElementsAre( 440 ErrorMessageDbusType( 441 utils::enumToString(ErrorType::propertyConflict), "Interval"), 442 ErrorMessageDbusType( 443 utils::enumToString(ErrorType::propertyConflict), 444 "ReportingType"))); 445 } 446 447 TEST_F(TestReport, settingValidReportingTypeRemovesErrors) 448 { 449 auto report = makeReport(defaultParams() 450 .reportId("report2") 451 .reportingType(ReportingType::onRequest) 452 .interval(Milliseconds{0})); 453 454 EXPECT_THAT( 455 setProperty<std::string>(report->getPath(), "ReportingType", "Periodic") 456 .value(), 457 Eq(boost::system::errc::success)); 458 EXPECT_THAT(setProperty<std::string>(report->getPath(), "ReportingType", 459 "OnRequest") 460 .value(), 461 Eq(boost::system::errc::success)); 462 463 EXPECT_THAT(getProperty<std::string>(report->getPath(), "ReportingType"), 464 Eq("OnRequest")); 465 EXPECT_THAT( 466 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"), 467 IsEmpty()); 468 } 469 470 TEST_F(TestReport, settingInvalidIntervalDisablesReport) 471 { 472 auto report = makeReport(defaultParams() 473 .reportId("report2") 474 .reportingType(ReportingType::periodic) 475 .interval(ReportManager::minInterval)); 476 477 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(), 478 Eq(boost::system::errc::success)); 479 480 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"), Eq(0u)); 481 EXPECT_THAT( 482 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"), 483 UnorderedElementsAre( 484 ErrorMessageDbusType( 485 utils::enumToString(ErrorType::propertyConflict), "Interval"), 486 ErrorMessageDbusType( 487 utils::enumToString(ErrorType::propertyConflict), 488 "ReportingType"))); 489 } 490 491 TEST_F(TestReport, settingValidIntervalEnablesReport) 492 { 493 auto report = makeReport(defaultParams() 494 .reportId("report2") 495 .reportingType(ReportingType::periodic) 496 .interval(ReportManager::minInterval)); 497 498 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 0).value(), 499 Eq(boost::system::errc::success)); 500 EXPECT_THAT(setProperty<uint64_t>(report->getPath(), "Interval", 501 ReportManager::minInterval.count()) 502 .value(), 503 Eq(boost::system::errc::success)); 504 505 EXPECT_THAT(getProperty<uint64_t>(report->getPath(), "Interval"), 506 Eq(ReportManager::minInterval.count())); 507 EXPECT_THAT( 508 getProperty<ErrorMessagesDbusType>(report->getPath(), "ErrorMessages"), 509 IsEmpty()); 510 } 511 512 TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect) 513 { 514 EXPECT_THAT( 515 setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(), 516 Eq(boost::system::errc::read_only_file_system)); 517 EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"), 518 Eq(utils::contains(defaultParams().reportActions(), 519 ReportAction::emitsReadingsUpdate))); 520 } 521 522 TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect) 523 { 524 EXPECT_THAT( 525 setProperty(sut->getPath(), "LogToMetricReportsCollection", true) 526 .value(), 527 Eq(boost::system::errc::read_only_file_system)); 528 EXPECT_THAT( 529 getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"), 530 Eq(utils::contains(defaultParams().reportActions(), 531 ReportAction::logToMetricReportsCollection))); 532 } 533 534 TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage) 535 { 536 EXPECT_CALL(storageMock, store(_, _)).Times(0); 537 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId()))) 538 .Times(AtLeast(1)); 539 540 bool persistency = false; 541 EXPECT_THAT(setProperty(sut->getPath(), "Persistency", persistency).value(), 542 Eq(boost::system::errc::success)); 543 EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), 544 Eq(persistency)); 545 } 546 547 TEST_F(TestReport, deleteReport) 548 { 549 EXPECT_CALL(*reportManagerMock, removeReport(sut.get())); 550 auto ec = deleteReport(sut->getPath()); 551 EXPECT_THAT(ec, Eq(boost::system::errc::success)); 552 } 553 554 TEST_F(TestReport, deletingNonExistingReportReturnInvalidRequestDescriptor) 555 { 556 auto ec = 557 deleteReport(utils::constants::reportDirPath.str + "NonExisting"s); 558 EXPECT_THAT(ec.value(), Eq(EBADR)); 559 } 560 561 TEST_F(TestReport, deleteReportExpectThatFileIsRemoveFromStorage) 562 { 563 EXPECT_CALL(storageMock, store(_, _)).Times(0); 564 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId()))) 565 .Times(AtLeast(1)); 566 567 auto ec = deleteReport(sut->getPath()); 568 EXPECT_THAT(ec, Eq(boost::system::errc::success)); 569 } 570 571 TEST_F(TestReport, updatesTriggerIdWhenTriggerIsAdded) 572 { 573 utils::Messanger messanger(DbusEnvironment::getIoc()); 574 575 messanger.send(messages::TriggerPresenceChangedInd{ 576 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}}); 577 messanger.send(messages::TriggerPresenceChangedInd{ 578 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}}); 579 messanger.send(messages::TriggerPresenceChangedInd{ 580 messages::Presence::Exist, "trigger2", {"someOtherReport"}}); 581 messanger.send(messages::TriggerPresenceChangedInd{ 582 messages::Presence::Exist, 583 "trigger3", 584 {"someOtherReport", defaultParams().reportId()}}); 585 586 EXPECT_THAT( 587 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"), 588 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1", 589 utils::constants::triggerDirPath / "trigger3")); 590 } 591 592 TEST_F(TestReport, updatesTriggerIdWhenTriggerIsRemoved) 593 { 594 utils::Messanger messanger(DbusEnvironment::getIoc()); 595 596 messanger.send(messages::TriggerPresenceChangedInd{ 597 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}}); 598 messanger.send(messages::TriggerPresenceChangedInd{ 599 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}}); 600 messanger.send(messages::TriggerPresenceChangedInd{ 601 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}}); 602 603 messanger.send(messages::TriggerPresenceChangedInd{ 604 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}}); 605 messanger.send(messages::TriggerPresenceChangedInd{ 606 messages::Presence::Removed, "trigger2", {}}); 607 messanger.send(messages::TriggerPresenceChangedInd{ 608 messages::Presence::Removed, "trigger1", {defaultParams().reportId()}}); 609 610 EXPECT_THAT( 611 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"), 612 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger3")); 613 } 614 615 TEST_F(TestReport, updatesTriggerIdWhenTriggerIsModified) 616 { 617 utils::Messanger messanger(DbusEnvironment::getIoc()); 618 619 messanger.send(messages::TriggerPresenceChangedInd{ 620 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}}); 621 messanger.send(messages::TriggerPresenceChangedInd{ 622 messages::Presence::Exist, "trigger2", {defaultParams().reportId()}}); 623 messanger.send(messages::TriggerPresenceChangedInd{ 624 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}}); 625 626 messanger.send(messages::TriggerPresenceChangedInd{ 627 messages::Presence::Exist, "trigger1", {defaultParams().reportId()}}); 628 messanger.send(messages::TriggerPresenceChangedInd{ 629 messages::Presence::Exist, "trigger2", {}}); 630 messanger.send(messages::TriggerPresenceChangedInd{ 631 messages::Presence::Exist, "trigger3", {defaultParams().reportId()}}); 632 633 EXPECT_THAT( 634 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"), 635 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1", 636 utils::constants::triggerDirPath / "trigger3")); 637 } 638 639 class TestReportStore : 640 public TestReport, 641 public WithParamInterface<std::pair<std::string, nlohmann::json>> 642 { 643 void SetUp() override 644 {} 645 }; 646 647 INSTANTIATE_TEST_SUITE_P( 648 _, TestReportStore, 649 Values( 650 std::make_pair("Enabled"s, nlohmann::json(defaultParams().enabled())), 651 std::make_pair("Version"s, nlohmann::json(6)), 652 std::make_pair("Id"s, nlohmann::json(defaultParams().reportId())), 653 std::make_pair("Name"s, nlohmann::json(defaultParams().reportName())), 654 std::make_pair("ReportingType", 655 nlohmann::json(defaultParams().reportingType())), 656 std::make_pair("ReportActions", nlohmann::json(utils::transform( 657 defaultParams().reportActions(), 658 [](const auto v) { 659 return utils::toUnderlying(v); 660 }))), 661 std::make_pair("Interval", 662 nlohmann::json(defaultParams().interval().count())), 663 std::make_pair("AppendLimit", 664 nlohmann::json(ReportParams().appendLimit())), 665 std::make_pair( 666 "ReadingParameters", 667 nlohmann::json( 668 {{{tstring::SensorPath::str(), 669 {{{tstring::Service::str(), "Service"}, 670 {tstring::Path::str(), 671 "/xyz/openbmc_project/sensors/power/p1"}, 672 {tstring::Metadata::str(), "metadata1"}}}}, 673 {tstring::OperationType::str(), OperationType::avg}, 674 {tstring::Id::str(), "MetricId1"}, 675 {tstring::CollectionTimeScope::str(), 676 CollectionTimeScope::point}, 677 {tstring::CollectionDuration::str(), 0}}, 678 {{tstring::SensorPath::str(), 679 {{{tstring::Service::str(), "Service"}, 680 {tstring::Path::str(), 681 "/xyz/openbmc_project/sensors/power/p2"}, 682 {tstring::Metadata::str(), "metadata2"}}}}, 683 {tstring::OperationType::str(), OperationType::avg}, 684 {tstring::Id::str(), "MetricId2"}, 685 {tstring::CollectionTimeScope::str(), 686 CollectionTimeScope::point}, 687 {tstring::CollectionDuration::str(), 0}}})))); 688 689 TEST_P(TestReportStore, settingPersistencyToTrueStoresReport) 690 { 691 sut = makeReport(defaultParams()); 692 693 { 694 InSequence seq; 695 EXPECT_CALL(storageMock, remove(to_file_path(sut->getId()))); 696 EXPECT_CALL(checkPoint, Call()); 697 EXPECT_CALL(storageMock, store(to_file_path(sut->getId()), _)); 698 } 699 700 setProperty(sut->getPath(), "Persistency", false); 701 checkPoint.Call(); 702 setProperty(sut->getPath(), "Persistency", true); 703 704 const auto& [key, value] = GetParam(); 705 706 ASSERT_THAT(storedConfiguration.at(key), Eq(value)); 707 } 708 709 TEST_P(TestReportStore, reportIsSavedToStorageAfterCreated) 710 { 711 EXPECT_CALL(storageMock, 712 store(to_file_path(defaultParams().reportId()), _)); 713 714 sut = makeReport(defaultParams()); 715 716 const auto& [key, value] = GetParam(); 717 718 ASSERT_THAT(storedConfiguration.at(key), Eq(value)); 719 } 720 721 class TestReportValidNames : 722 public TestReport, 723 public WithParamInterface<ReportParams> 724 { 725 public: 726 void SetUp() override 727 {} 728 }; 729 730 INSTANTIATE_TEST_SUITE_P( 731 ValidNames, TestReportValidNames, 732 Values(defaultParams().reportName("Valid_1"), 733 defaultParams().reportName("Valid_1/Valid_2"), 734 defaultParams().reportName("Valid_1/Valid_2/Valid_3"))); 735 736 TEST_P(TestReportValidNames, reportCtorDoesNotThrowOnValidName) 737 { 738 EXPECT_NO_THROW(makeReport(GetParam())); 739 } 740 741 class TestReportInvalidIds : 742 public TestReport, 743 public WithParamInterface<ReportParams> 744 { 745 public: 746 void SetUp() override 747 {} 748 }; 749 750 INSTANTIATE_TEST_SUITE_P(InvalidNames, TestReportInvalidIds, 751 Values(defaultParams().reportId("/"), 752 defaultParams().reportId("/Invalid"), 753 defaultParams().reportId("Invalid/"), 754 defaultParams().reportId("Invalid/Invalid/"), 755 defaultParams().reportId("Invalid?"))); 756 757 TEST_P(TestReportInvalidIds, failsToCreateReportWithInvalidName) 758 { 759 EXPECT_CALL(storageMock, store).Times(0); 760 761 EXPECT_THROW(makeReport(GetParam()), sdbusplus::exception::SdBusError); 762 } 763 764 class TestReportAllReportTypes : 765 public TestReport, 766 public WithParamInterface<ReportParams> 767 { 768 public: 769 void SetUp() override 770 { 771 sut = makeReport(GetParam()); 772 } 773 }; 774 775 INSTANTIATE_TEST_SUITE_P( 776 _, TestReportAllReportTypes, 777 Values(defaultParams().reportingType(ReportingType::onRequest), 778 defaultParams().reportingType(ReportingType::onChange), 779 defaultParams() 780 .reportingType(ReportingType::periodic) 781 .interval(ReportManager::minInterval))); 782 783 TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType) 784 { 785 EXPECT_THAT(utils::toReportingType( 786 getProperty<std::string>(sut->getPath(), "ReportingType")), 787 Eq(GetParam().reportingType())); 788 } 789 790 TEST_P(TestReportAllReportTypes, readingsAreUpdated) 791 { 792 clockFake.system.advance(10ms); 793 794 messanger.send(messages::UpdateReportInd{{sut->getId()}}); 795 const auto [timestamp, readings] = 796 getProperty<Readings>(sut->getPath(), "Readings"); 797 798 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms)); 799 } 800 801 TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIsDisabled) 802 { 803 clockFake.system.advance(10ms); 804 805 setProperty(sut->getPath(), "Enabled", false); 806 messanger.send(messages::UpdateReportInd{{sut->getId()}}); 807 const auto [timestamp, readings] = 808 getProperty<Readings>(sut->getPath(), "Readings"); 809 810 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms)); 811 } 812 813 TEST_P(TestReportAllReportTypes, readingsAreNotUpdatedWhenReportIdDiffers) 814 { 815 clockFake.system.advance(10ms); 816 817 messanger.send(messages::UpdateReportInd{{sut->getId() + "x"s}}); 818 const auto [timestamp, readings] = 819 getProperty<Readings>(sut->getPath(), "Readings"); 820 821 EXPECT_THAT(Milliseconds{timestamp}, Eq(0ms)); 822 } 823 824 class TestReportOnRequestType : public TestReport 825 { 826 void SetUp() override 827 { 828 sut = 829 makeReport(defaultParams().reportingType(ReportingType::onRequest)); 830 } 831 }; 832 833 TEST_F(TestReportOnRequestType, updatesReadingTimestamp) 834 { 835 clockFake.system.advance(10ms); 836 837 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success)); 838 839 const auto [timestamp, readings] = 840 getProperty<Readings>(sut->getPath(), "Readings"); 841 842 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms)); 843 } 844 845 TEST_F(TestReportOnRequestType, updatesReadingWhenUpdateIsCalled) 846 { 847 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success)); 848 849 const auto [timestamp, readings] = 850 getProperty<Readings>(sut->getPath(), "Readings"); 851 852 EXPECT_THAT(readings, 853 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u), 854 std::make_tuple("aa"s, "bb"s, 42.0, 74u))); 855 } 856 857 class TestReportNonOnRequestType : 858 public TestReport, 859 public WithParamInterface<ReportParams> 860 { 861 void SetUp() override 862 { 863 sut = makeReport(GetParam()); 864 } 865 }; 866 867 INSTANTIATE_TEST_SUITE_P( 868 _, TestReportNonOnRequestType, 869 Values(defaultParams().reportingType(ReportingType::periodic), 870 defaultParams().reportingType(ReportingType::onChange))); 871 872 TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall) 873 { 874 ASSERT_THAT(update(sut->getPath()), Eq(boost::system::errc::success)); 875 876 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"), 877 Eq(Readings{})); 878 } 879 880 class TestReportNonPeriodicReport : 881 public TestReport, 882 public WithParamInterface<ReportParams> 883 { 884 public: 885 void SetUp() override 886 { 887 sut = makeReport(GetParam()); 888 } 889 }; 890 891 INSTANTIATE_TEST_SUITE_P( 892 _, TestReportNonPeriodicReport, 893 Values(defaultParams().reportingType(ReportingType::onRequest), 894 defaultParams().reportingType(ReportingType::onChange))); 895 896 TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires) 897 { 898 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms); 899 900 EXPECT_THAT(getProperty<Readings>(sut->getPath(), "Readings"), 901 Eq(Readings{})); 902 } 903 904 class TestReportPeriodicReport : public TestReport 905 { 906 void SetUp() override 907 { 908 sut = makeReport(defaultParams() 909 .reportingType(ReportingType::periodic) 910 .interval(ReportManager::minInterval)); 911 } 912 }; 913 914 TEST_F(TestReportPeriodicReport, readingTimestampIsUpdatedAfterIntervalExpires) 915 { 916 clockFake.system.advance(10ms); 917 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms); 918 919 const auto [timestamp, readings] = 920 getProperty<Readings>(sut->getPath(), "Readings"); 921 922 EXPECT_THAT(Milliseconds{timestamp}, Eq(systemTimestamp + 10ms)); 923 } 924 925 TEST_F(TestReportPeriodicReport, readingsAreUpdatedAfterIntervalExpires) 926 { 927 DbusEnvironment::sleepFor(ReportManager::minInterval + 1ms); 928 929 const auto [timestamp, readings] = 930 getProperty<Readings>(sut->getPath(), "Readings"); 931 932 EXPECT_THAT(readings, 933 ElementsAre(std::make_tuple("a"s, "b"s, 17.1, 114u), 934 std::make_tuple("aa"s, "bb"s, 42.0, 74u))); 935 } 936 937 struct ReportUpdatesReportParams 938 { 939 ReportParams reportParams; 940 std::vector<ReadingData> expectedReadings; 941 bool expectedEnabled; 942 }; 943 944 class TestReportWithReportUpdatesAndLimit : 945 public TestReport, 946 public WithParamInterface<ReportUpdatesReportParams> 947 { 948 void SetUp() override 949 { 950 sut = makeReport(ReportParams(GetParam().reportParams) 951 .reportingType(ReportingType::periodic) 952 .interval(std::chrono::hours(1000))); 953 } 954 }; 955 956 INSTANTIATE_TEST_SUITE_P( 957 _, TestReportWithReportUpdatesAndLimit, 958 Values( 959 ReportUpdatesReportParams{ 960 defaultParams() 961 .reportUpdates(ReportUpdates::appendWrapsWhenFull) 962 .appendLimit(5), 963 std::vector<ReadingData>{{std::make_tuple("aa"s, "bb"s, 42.0, 74u), 964 std::make_tuple("a"s, "b"s, 17.1, 114u), 965 std::make_tuple("aa"s, "bb"s, 42.0, 74u), 966 std::make_tuple("aa"s, "bb"s, 42.0, 74u), 967 std::make_tuple("a"s, "b"s, 17.1, 114u)}}, 968 true}, 969 ReportUpdatesReportParams{ 970 defaultParams() 971 .reportUpdates(ReportUpdates::appendWrapsWhenFull) 972 .appendLimit(4), 973 std::vector<ReadingData>{ 974 {std::make_tuple("a"s, "b"s, 17.1, 114u), 975 std::make_tuple("aa"s, "bb"s, 42.0, 74u), 976 std::make_tuple("a"s, "b"s, 17.1, 114u), 977 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}}, 978 true}, 979 ReportUpdatesReportParams{ 980 defaultParams() 981 .reportUpdates(ReportUpdates::appendWrapsWhenFull) 982 .appendLimit(0), 983 std::vector<ReadingData>{}, true}, 984 ReportUpdatesReportParams{ 985 defaultParams() 986 .reportUpdates(ReportUpdates::appendStopsWhenFull) 987 .appendLimit(10), 988 std::vector<ReadingData>{ 989 {std::make_tuple("a"s, "b"s, 17.1, 114u), 990 std::make_tuple("aa"s, "bb"s, 42.0, 74u), 991 std::make_tuple("a"s, "b"s, 17.1, 114u), 992 std::make_tuple("aa"s, "bb"s, 42.0, 74u), 993 std::make_tuple("a"s, "b"s, 17.1, 114u), 994 std::make_tuple("aa"s, "bb"s, 42.0, 74u), 995 std::make_tuple("a"s, "b"s, 17.1, 114u), 996 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}}, 997 true}, 998 ReportUpdatesReportParams{ 999 defaultParams() 1000 .reportUpdates(ReportUpdates::appendStopsWhenFull) 1001 .appendLimit(5), 1002 std::vector<ReadingData>{{std::make_tuple("a"s, "b"s, 17.1, 114u), 1003 std::make_tuple("aa"s, "bb"s, 42.0, 74u), 1004 std::make_tuple("a"s, "b"s, 17.1, 114u), 1005 std::make_tuple("aa"s, "bb"s, 42.0, 74u), 1006 std::make_tuple("a"s, "b"s, 17.1, 114u)}}, 1007 false}, 1008 ReportUpdatesReportParams{ 1009 defaultParams() 1010 .reportUpdates(ReportUpdates::appendStopsWhenFull) 1011 .appendLimit(4), 1012 std::vector<ReadingData>{ 1013 {std::make_tuple("a"s, "b"s, 17.1, 114u), 1014 std::make_tuple("aa"s, "bb"s, 42.0, 74u), 1015 std::make_tuple("a"s, "b"s, 17.1, 114u), 1016 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}}, 1017 false}, 1018 ReportUpdatesReportParams{ 1019 defaultParams() 1020 .reportUpdates(ReportUpdates::appendStopsWhenFull) 1021 .appendLimit(0), 1022 std::vector<ReadingData>{}, false}, 1023 ReportUpdatesReportParams{ 1024 defaultParams() 1025 .reportUpdates(ReportUpdates::overwrite) 1026 .appendLimit(500), 1027 std::vector<ReadingData>{ 1028 {std::make_tuple("a"s, "b"s, 17.1, 114u), 1029 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}}, 1030 true}, 1031 ReportUpdatesReportParams{ 1032 defaultParams() 1033 .reportUpdates(ReportUpdates::overwrite) 1034 .appendLimit(1), 1035 std::vector<ReadingData>{ 1036 {std::make_tuple("a"s, "b"s, 17.1, 114u), 1037 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}}, 1038 true}, 1039 ReportUpdatesReportParams{ 1040 defaultParams() 1041 .reportUpdates(ReportUpdates::overwrite) 1042 .appendLimit(0), 1043 std::vector<ReadingData>{ 1044 {std::make_tuple("a"s, "b"s, 17.1, 114u), 1045 std::make_tuple("aa"s, "bb"s, 42.0, 74u)}}, 1046 true})); 1047 1048 TEST_P(TestReportWithReportUpdatesAndLimit, 1049 readingsAreUpdatedAfterIntervalExpires) 1050 { 1051 for (int i = 0; i < 4; i++) 1052 { 1053 messanger.send(messages::UpdateReportInd{{sut->getId()}}); 1054 } 1055 1056 const auto [timestamp, readings] = 1057 getProperty<Readings>(sut->getPath(), "Readings"); 1058 const auto enabled = getProperty<bool>(sut->getPath(), "Enabled"); 1059 1060 EXPECT_THAT(readings, ElementsAreArray(GetParam().expectedReadings)); 1061 EXPECT_EQ(enabled, GetParam().expectedEnabled); 1062 } 1063 1064 class TestReportInitialization : public TestReport 1065 { 1066 public: 1067 void SetUp() override 1068 { 1069 initMetricMocks(defaultParams().metricParameters()); 1070 } 1071 1072 void monitorProc(sdbusplus::message::message& msg) 1073 { 1074 std::string iface; 1075 std::vector<std::pair<std::string, std::variant<Readings>>> 1076 changed_properties; 1077 std::vector<std::string> invalidated_properties; 1078 1079 msg.read(iface, changed_properties, invalidated_properties); 1080 1081 if (iface == Report::reportIfaceName) 1082 { 1083 for (const auto& [name, value] : changed_properties) 1084 { 1085 if (name == "Readings") 1086 { 1087 readingsUpdated.Call(); 1088 } 1089 } 1090 } 1091 } 1092 1093 void makeMonitor() 1094 { 1095 monitor = std::make_unique<sdbusplus::bus::match_t>( 1096 *DbusEnvironment::getBus(), 1097 sdbusplus::bus::match::rules::propertiesChanged( 1098 sut->getPath(), Report::reportIfaceName), 1099 [this](auto& msg) { monitorProc(msg); }); 1100 } 1101 1102 std::unique_ptr<sdbusplus::bus::match_t> monitor; 1103 MockFunction<void()> readingsUpdated; 1104 }; 1105 1106 TEST_F(TestReportInitialization, 1107 registersForMetricUpdatesWhenOnChangeReportCreated) 1108 { 1109 std::vector<const interfaces::MetricListener*> args; 1110 for (auto& metric : metricMocks) 1111 { 1112 EXPECT_CALL(*metric, registerForUpdates(_)) 1113 .WillOnce(Invoke([&args](const interfaces::MetricListener& report) { 1114 args.emplace_back(&report); 1115 })); 1116 ; 1117 } 1118 1119 sut = makeReport(defaultParams().reportingType(ReportingType::onChange)); 1120 1121 EXPECT_THAT(args, SizeIs(metricMocks.size())); 1122 for (const auto* reportPtr : args) 1123 { 1124 EXPECT_THAT(reportPtr, Eq(sut.get())); 1125 } 1126 } 1127 1128 TEST_F(TestReportInitialization, 1129 deregistersForMetricUpdatesWhenOnChangeReportDestroyed) 1130 { 1131 sut = makeReport(defaultParams().reportingType(ReportingType::onChange)); 1132 1133 for (auto& metric : metricMocks) 1134 { 1135 EXPECT_CALL(*metric, 1136 unregisterFromUpdates(Ref( 1137 static_cast<interfaces::MetricListener&>(*sut.get())))); 1138 } 1139 1140 sut = nullptr; 1141 } 1142 1143 TEST_F(TestReportInitialization, 1144 metricsAreInitializedWhenEnabledReportConstructed) 1145 { 1146 for (auto& metric : metricMocks) 1147 { 1148 EXPECT_CALL(*metric, initialize()); 1149 } 1150 sut = makeReport(defaultParams().enabled(true)); 1151 } 1152 1153 TEST_F(TestReportInitialization, 1154 metricsAreNotInitializedWhenDisabledReportConstructed) 1155 { 1156 for (auto& metric : metricMocks) 1157 { 1158 EXPECT_CALL(*metric, initialize()).Times(0); 1159 } 1160 sut = makeReport(defaultParams().enabled(false)); 1161 } 1162 1163 TEST_F(TestReportInitialization, 1164 emitReadingsUpdateIsTrueReadingsPropertiesChangedSingalEmits) 1165 { 1166 EXPECT_CALL(readingsUpdated, Call()) 1167 .WillOnce( 1168 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated"))); 1169 1170 const auto elapsed = DbusEnvironment::measureTime([this] { 1171 sut = makeReport(defaultParams() 1172 .reportingType(ReportingType::periodic) 1173 .reportActions({ReportAction::emitsReadingsUpdate}) 1174 .interval(ReportManager::minInterval)); 1175 makeMonitor(); 1176 EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated")); 1177 }); 1178 1179 EXPECT_THAT(elapsed, AllOf(Ge(ReportManager::minInterval), 1180 Lt(ReportManager::minInterval * 2))); 1181 } 1182 1183 TEST_F(TestReportInitialization, 1184 emitReadingsUpdateIsFalseReadingsPropertiesChangesSigalDoesNotEmits) 1185 { 1186 EXPECT_CALL(readingsUpdated, Call()).Times(0); 1187 1188 sut = makeReport(defaultParams() 1189 .reportingType(ReportingType::periodic) 1190 .reportActions({})); 1191 makeMonitor(); 1192 DbusEnvironment::sleepFor(defaultParams().interval() * 2); 1193 } 1194 1195 TEST_F(TestReportInitialization, appendLimitDeducedProperly) 1196 { 1197 sut = makeReport( 1198 defaultParams().appendLimit(std::numeric_limits<uint64_t>::max())); 1199 auto appendLimit = getProperty<uint64_t>(sut->getPath(), "AppendLimit"); 1200 EXPECT_EQ(appendLimit, 2ull); 1201 } 1202 1203 TEST_F(TestReportInitialization, appendLimitSetToUintMaxIsStoredCorrectly) 1204 { 1205 sut = makeReport( 1206 ReportParams().appendLimit(std::numeric_limits<uint64_t>::max())); 1207 1208 ASSERT_THAT(storedConfiguration.at("AppendLimit"), 1209 Eq(std::numeric_limits<uint64_t>::max())); 1210 } 1211 1212 TEST_F(TestReportInitialization, triggerIdsPropertyIsInitialzed) 1213 { 1214 for (const auto& triggerId : {"trigger1", "trigger2"}) 1215 { 1216 messanger.on_receive<messages::CollectTriggerIdReq>( 1217 [this, triggerId](const auto& msg) { 1218 messanger.send(messages::CollectTriggerIdResp{triggerId}); 1219 }); 1220 } 1221 1222 sut = makeReport(ReportParams()); 1223 1224 EXPECT_THAT( 1225 getProperty<std::vector<object_path>>(sut->getPath(), "Triggers"), 1226 UnorderedElementsAre(utils::constants::triggerDirPath / "trigger1", 1227 utils::constants::triggerDirPath / "trigger2")); 1228 } 1229 1230 TEST_F(TestReportInitialization, 1231 metricValuesAreNotStoredForReportUpdatesDifferentThanAppendStopsWhenFull) 1232 { 1233 sut = makeReport(ReportParams() 1234 .reportingType(ReportingType::periodic) 1235 .interval(1h) 1236 .reportUpdates(ReportUpdates::appendWrapsWhenFull) 1237 .readings(Readings{{}, {{}}})); 1238 1239 ASSERT_THAT(storedConfiguration.find("MetricValues"), 1240 Eq(storedConfiguration.end())); 1241 } 1242 1243 TEST_F(TestReportInitialization, metricValuesAreNotStoredForOnRequestReport) 1244 { 1245 sut = makeReport(ReportParams() 1246 .reportingType(ReportingType::onRequest) 1247 .reportUpdates(ReportUpdates::appendStopsWhenFull) 1248 .readings(Readings{{}, {{}}})); 1249 1250 ASSERT_THAT(storedConfiguration.find("MetricValues"), 1251 Eq(storedConfiguration.end())); 1252 } 1253 1254 TEST_F(TestReportInitialization, 1255 metricValuesAreStoredForNonOnRequestReportWithAppendStopsWhenFull) 1256 { 1257 const auto readings = Readings{{}, {{}}}; 1258 1259 sut = makeReport(ReportParams() 1260 .reportingType(ReportingType::periodic) 1261 .interval(1h) 1262 .reportUpdates(ReportUpdates::appendStopsWhenFull) 1263 .readings(readings)); 1264 1265 ASSERT_THAT(storedConfiguration.at("MetricValues").get<LabeledReadings>(), 1266 Eq(utils::toLabeledReadings(readings))); 1267 } 1268 1269 class TestReportInitializationOnChangeReport : public TestReportInitialization 1270 { 1271 public: 1272 void SetUp() override 1273 { 1274 initMetricMocks(params.metricParameters()); 1275 } 1276 1277 ReportParams params = defaultOnChangeParams(); 1278 }; 1279 1280 TEST_F(TestReportInitializationOnChangeReport, 1281 doesntUpdateReadingsWhenNotRequired) 1282 { 1283 EXPECT_CALL(*metricMocks[0], updateReadings(_)).Times(0); 1284 1285 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(false)); 1286 1287 sut = makeReport(params); 1288 1289 DbusEnvironment::sleepFor(500ms); 1290 } 1291 1292 TEST_F(TestReportInitializationOnChangeReport, updatesReadingsWhenRequired) 1293 { 1294 EXPECT_CALL(*metricMocks[0], updateReadings(_)) 1295 .WillOnce(Return()) 1296 .WillOnce( 1297 InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated"))) 1298 .WillRepeatedly(Return()); 1299 1300 ON_CALL(*metricMocks[0], isTimerRequired()).WillByDefault(Return(true)); 1301 1302 sut = makeReport(params); 1303 1304 DbusEnvironment::waitForFuture("readingsUpdated"); 1305 } 1306