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