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