1 #include "dbus_environment.hpp" 2 #include "mocks/report_factory_mock.hpp" 3 #include "report_manager.hpp" 4 5 using namespace testing; 6 7 class TestReportManager : public Test 8 { 9 public: 10 std::string defaultReportName = "TestReport"; 11 std::string defaultReportType = "Periodic"; 12 bool defaultEmitReadingSignal = true; 13 bool defaultLogToMetricReportCollection = true; 14 uint64_t defaultInterval = ReportManager::minInterval.count(); 15 ReadingParameters defaultReadingParams = {}; 16 17 std::unique_ptr<ReportFactoryMock> reportFactoryMockPtr = 18 std::make_unique<StrictMock<ReportFactoryMock>>(); 19 ReportFactoryMock& reportFactoryMock = *reportFactoryMockPtr; 20 ReportManager sut = ReportManager(std::move(reportFactoryMockPtr), 21 DbusEnvironment::getObjServer()); 22 23 MockFunction<void(std::string)> checkPoint; 24 25 void TearDown() override 26 { 27 DbusEnvironment::synchronizeIoc(); 28 } 29 30 std::pair<boost::system::error_code, std::string> 31 addReport(const std::string& reportName, 32 uint64_t interval = ReportManager::minInterval.count()) 33 { 34 std::promise<std::pair<boost::system::error_code, std::string>> 35 addReportPromise; 36 DbusEnvironment::getBus()->async_method_call( 37 [&addReportPromise](boost::system::error_code ec, 38 const std::string& path) { 39 addReportPromise.set_value({ec, path}); 40 }, 41 DbusEnvironment::serviceName(), ReportManager::reportManagerPath, 42 ReportManager::reportManagerIfaceName, "AddReport", reportName, 43 defaultReportType, defaultEmitReadingSignal, 44 defaultLogToMetricReportCollection, interval, defaultReadingParams); 45 return DbusEnvironment::waitForFuture(addReportPromise.get_future()) 46 .value_or(std::pair<boost::system::error_code, std::string>{}); 47 } 48 49 template <class T> 50 static T getProperty(std::string property) 51 { 52 std::promise<T> propertyPromise; 53 sdbusplus::asio::getProperty<T>( 54 *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), 55 ReportManager::reportManagerPath, 56 ReportManager::reportManagerIfaceName, property, 57 [&propertyPromise](boost::system::error_code ec) { 58 EXPECT_THAT(static_cast<bool>(ec), ::testing::Eq(false)); 59 propertyPromise.set_value(T{}); 60 }, 61 [&propertyPromise](T t) { propertyPromise.set_value(t); }); 62 return DbusEnvironment::waitForFuture(propertyPromise.get_future()) 63 .value_or(T{}); 64 } 65 }; 66 67 TEST_F(TestReportManager, minInterval) 68 { 69 EXPECT_THAT(getProperty<uint64_t>("MinInterval"), 70 Eq(static_cast<uint64_t>(ReportManager::minInterval.count()))); 71 } 72 73 TEST_F(TestReportManager, maxReports) 74 { 75 EXPECT_THAT(getProperty<uint32_t>("MaxReports"), 76 Eq(ReportManager::maxReports)); 77 } 78 79 TEST_F(TestReportManager, addReport) 80 { 81 auto reportMockPtr = 82 std::make_unique<NiceMock<ReportMock>>(defaultReportName); 83 auto& reportMock = *reportMockPtr; 84 85 EXPECT_CALL(reportFactoryMock, 86 make(defaultReportName, defaultReportType, 87 defaultEmitReadingSignal, 88 defaultLogToMetricReportCollection, 89 std::chrono::milliseconds{defaultInterval}, 90 defaultReadingParams, Ref(sut))) 91 .WillOnce(Return(ByMove(std::move(reportMockPtr)))); 92 93 auto [ec, path] = addReport(defaultReportName); 94 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success)); 95 EXPECT_THAT(path, Eq(reportMock.getPath())); 96 } 97 98 TEST_F(TestReportManager, failToAddReportTwice) 99 { 100 EXPECT_CALL(reportFactoryMock, make(_, _, _, _, _, _, _)); 101 102 addReport(defaultReportName); 103 104 auto [ec, path] = addReport(defaultReportName); 105 EXPECT_THAT(ec.value(), Eq(boost::system::errc::file_exists)); 106 EXPECT_THAT(path, Eq(std::string())); 107 } 108 109 TEST_F(TestReportManager, failToAddReportWithInvalidInterval) 110 { 111 EXPECT_CALL(reportFactoryMock, make(_, _, _, _, _, _, _)).Times(0); 112 113 uint64_t interval = defaultInterval - 1; 114 115 auto [ec, path] = addReport(defaultReportName, interval); 116 EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument)); 117 EXPECT_THAT(path, Eq(std::string())); 118 } 119 120 TEST_F(TestReportManager, failToAddReportWhenMaxReportIsReached) 121 { 122 EXPECT_CALL(reportFactoryMock, make(_, _, _, _, _, _, _)) 123 .Times(ReportManager::maxReports); 124 125 for (size_t i = 0; i < ReportManager::maxReports; i++) 126 { 127 std::string reportName = defaultReportName + std::to_string(i); 128 129 auto [ec, path] = addReport(reportName); 130 EXPECT_THAT(ec.value(), Eq(boost::system::errc::success)); 131 } 132 133 std::string reportName = 134 defaultReportName + std::to_string(ReportManager::maxReports); 135 auto [ec, path] = addReport(reportName); 136 EXPECT_THAT(ec.value(), Eq(boost::system::errc::too_many_files_open)); 137 EXPECT_THAT(path, Eq(std::string())); 138 } 139 140 TEST_F(TestReportManager, removeReport) 141 { 142 auto reportMockPtr = 143 std::make_unique<NiceMock<ReportMock>>(defaultReportName); 144 auto& reportMock = *reportMockPtr; 145 146 { 147 InSequence seq; 148 EXPECT_CALL(reportFactoryMock, make(_, _, _, _, _, _, _)) 149 .WillOnce(Return(ByMove(std::move(reportMockPtr)))); 150 EXPECT_CALL(reportMock, Die()); 151 EXPECT_CALL(checkPoint, Call("end")); 152 } 153 154 addReport(defaultReportName); 155 sut.removeReport(&reportMock); 156 checkPoint.Call("end"); 157 } 158 159 TEST_F(TestReportManager, removingReportThatIsNotInContainerHasNoEffect) 160 { 161 auto reportMockPtr = 162 std::make_unique<NiceMock<ReportMock>>(defaultReportName); 163 auto& reportMock = *reportMockPtr; 164 165 { 166 InSequence seq; 167 EXPECT_CALL(checkPoint, Call("end")); 168 EXPECT_CALL(reportMock, Die()); 169 } 170 171 sut.removeReport(&reportMock); 172 checkPoint.Call("end"); 173 } 174 175 TEST_F(TestReportManager, removingSameReportTwiceHasNoSideEffect) 176 { 177 auto reportMockPtr = 178 std::make_unique<NiceMock<ReportMock>>(defaultReportName); 179 auto& reportMock = *reportMockPtr; 180 181 { 182 InSequence seq; 183 EXPECT_CALL(reportFactoryMock, 184 make(defaultReportName, _, _, _, _, _, _)) 185 .WillOnce(Return(ByMove(std::move(reportMockPtr)))); 186 EXPECT_CALL(reportMock, Die()); 187 EXPECT_CALL(checkPoint, Call("end")); 188 } 189 190 addReport(defaultReportName); 191 sut.removeReport(&reportMock); 192 sut.removeReport(&reportMock); 193 checkPoint.Call("end"); 194 } 195