| #include "NVMeDevice.hpp" |
| #include "NVMeIntf.hpp" |
| #include "NVMeMi.hpp" |
| #include "NVMeSubsys.hpp" |
| #include "Utils.hpp" |
| |
| #include <boost/asio/steady_timer.hpp> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| class MockMctpEndpoint : public MctpEndpoint |
| { |
| public: |
| MOCK_METHOD(int, network, (), (const, override)); |
| MOCK_METHOD(uint8_t, eid, (), (const, override)); |
| MOCK_METHOD(void, subscribe, |
| (MctpEndpoint::Event && degraded, |
| MctpEndpoint::Event&& available, |
| MctpEndpoint::Event&& removed), |
| (override)); |
| MOCK_METHOD(void, setMtu, |
| (uint32_t mtu, |
| std::function<void(const std::error_code& ec)>&& completed), |
| (override)); |
| MOCK_METHOD(void, remove, (), (override)); |
| MOCK_METHOD(void, recover, (), (override)); |
| MOCK_METHOD(std::string, describe, (), (const, override)); |
| MOCK_METHOD(bool, isI2cAccessible, (), (const, override)); |
| }; |
| |
| class MockMctpDevice : public MctpDevice |
| { |
| public: |
| MOCK_METHOD(void, setup, |
| (std::function<void(const std::error_code& ec, |
| const std::shared_ptr<MctpEndpoint>& ep)> && |
| action), |
| (override)); |
| MOCK_METHOD(void, remove, (), (override)); |
| MOCK_METHOD(std::string, describe, (), (const, override)); |
| }; |
| |
| TEST(NVMeRecovery, optimisationFailure) |
| { |
| boost::asio::io_context io; |
| |
| auto mctpEp = std::make_shared<MockMctpEndpoint>(); |
| EXPECT_CALL(*mctpEp, describe()) |
| .WillRepeatedly(testing::Return("Mock MCTP Endpoint")); |
| EXPECT_CALL(*mctpEp, eid()).WillRepeatedly(testing::Return(9)); |
| EXPECT_CALL(*mctpEp, network()).WillRepeatedly(testing::Return(1)); |
| EXPECT_CALL(*mctpEp, isI2cAccessible()) |
| .WillRepeatedly(testing::Return(true)); |
| |
| boost::asio::spawn(io, [&](boost::asio::yield_context yield) { |
| MctpEndpoint::Event degradedHandler; |
| MctpEndpoint::Event availableHandler; |
| MctpEndpoint::Event removedHandler; |
| EXPECT_CALL(*mctpEp, subscribe(testing::_, testing::_, testing::_)) |
| .WillOnce(testing::DoAll(testing::SaveArg<0>(°radedHandler), |
| testing::SaveArg<1>(&availableHandler), |
| testing::SaveArg<2>(&removedHandler), |
| testing::InvokeWithoutArgs([&]() { |
| io.post([&]() { availableHandler(mctpEp); }); |
| }))); |
| EXPECT_CALL(*mctpEp, recover()) |
| .Times(testing::Between(1, 3)) |
| .WillRepeatedly(testing::InvokeWithoutArgs([&]() { |
| io.post([&]() { degradedHandler(mctpEp); }); |
| io.post([&]() { availableHandler(mctpEp); }); |
| })); |
| |
| boost::asio::steady_timer timer(io); |
| auto mctpDev = std::make_shared<MockMctpDevice>(); |
| EXPECT_CALL(*mctpDev, describe()) |
| .WillRepeatedly(testing::Return("Mock MCTP Device")); |
| EXPECT_CALL(*mctpDev, setup(testing::_)) |
| .WillOnce(testing::InvokeArgument<0>(std::error_code(), mctpEp)); |
| |
| auto systemBus = std::make_shared<sdbusplus::asio::connection>(io); |
| sdbusplus::asio::object_server objectServer(systemBus, true); |
| auto worker = NVMeMiWorker::create(io); |
| auto intf = NVMeIntf::create<NVMeMi>(io, systemBus, mctpDev, worker); |
| SensorData sensorData{}; |
| auto subsys = NVMeSubsystem::create(io, objectServer, systemBus, "/foo", |
| "bar", sensorData, intf, false); |
| auto nvmeDev = NVMeDevice::create(io, mctpDev, std::move(intf), subsys, |
| std::chrono::seconds(2)); |
| nvmeDev->start(); |
| timer.expires_after(std::chrono::seconds(6)); |
| timer.async_wait(yield); |
| // io.run_for(std::chrono::seconds(6)); |
| |
| nvmeDev->stop(); |
| // io.run_for(std::chrono::seconds(1)); |
| timer.expires_after(std::chrono::seconds(1)); |
| timer.async_wait(yield); |
| |
| // https://stackoverflow.com/a/10289205 |
| EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(mctpEp.get())); |
| EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(mctpDev.get())); |
| io.stop(); |
| }); |
| |
| io.run(); |
| } |
| |
| // Unused, but required to link successfully |
| std::unordered_map<std::string, void*> pluginLibMap = {}; |
| |
| int main(int argc, char** argv) |
| { |
| ::testing::InitGoogleTest(&argc, argv); |
| return RUN_ALL_TESTS(); |
| } |