#include "NVMeMiFake.hpp"
#include "NVMeSubsys.hpp"

#include <dlfcn.h>
#include <valgrind/valgrind.h>

#include <nlohmann/json.hpp>
#include <sdbusplus/asio/connection.hpp>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#define xstr(s) str(s) // NOLINT
#define str(s) #s      // NOLINT

std::unordered_map<std::string, void*> pluginLibMap = {};
class NVMeMiMock :
    public NVMeMiIntf,
    public std::enable_shared_from_this<NVMeMiMock>
{
  public:
    NVMeMiMock(boost::asio::io_context& io, std::chrono::milliseconds delay) :
        fake(std::make_shared<NVMeMiFake>(io, delay))
    {
        ON_CALL(*this, getNID).WillByDefault([]() { return 0; });
        ON_CALL(*this, getEID).WillByDefault([]() { return 0; });
        ON_CALL(*this, miSubsystemHealthStatusPoll)
            .WillByDefault(
                [this](
                    std::function<void(const std::error_code&,
                                       nvme_mi_nvm_ss_health_status*)>&& cb) {
            return fake->miSubsystemHealthStatusPoll(std::move(cb));
        });
        ON_CALL(*this, miScanCtrl)
            .WillByDefault(
                [this](
                    std::function<void(const std::error_code& ec,
                                       const std::vector<nvme_mi_ctrl_t>& list)>
                        cb) { return fake->miScanCtrl(std::move(cb)); });
        ON_CALL(*this, flushOperations)
            .WillByDefault([this](std::function<void()>&& cb) {
            return fake->flushOperations(std::move(cb));
        });
        ON_CALL(*this, adminIdentify)
            .WillByDefault(
                [this](
                    nvme_mi_ctrl_t ctrl, nvme_identify_cns cns, uint32_t nsid,
                    uint16_t cntid,
                    std::function<void(nvme_ex_ptr, std::span<uint8_t>)>&& cb) {
            return fake->adminIdentify(ctrl, cns, nsid, cntid, std::move(cb));
        });
        ON_CALL(*this, adminGetLogPage)
            .WillByDefault([this](nvme_mi_ctrl_t ctrl, nvme_cmd_get_log_lid lid,
                                  uint32_t nsid, uint8_t lsp, uint16_t lsi,
                                  std::function<void(const std::error_code&,
                                                     std::span<uint8_t>)>&& cb,
                                  uint8_t dataArea) {
            return fake->adminGetLogPage(ctrl, lid, nsid, lsp, lsi,
                                         std::move(cb), dataArea);
        });
        ON_CALL(*this, adminFwCommit)
            .WillByDefault([this](nvme_mi_ctrl_t ctrl, nvme_fw_commit_ca action,
                                  uint8_t slot, bool bpid,
                                  std::function<void(const std::error_code&,
                                                     nvme_status_field)>&& cb) {
            return fake->adminFwCommit(ctrl, action, slot, bpid, std::move(cb));
        });
        ON_CALL(*this, adminXfer)
            .WillByDefault(
                [this](
                    nvme_mi_ctrl_t ctrl, const nvme_mi_admin_req_hdr& adminReq,
                    std::span<uint8_t> data, unsigned int timeoutMs,
                    std::function<void(const std::error_code& ec,
                                       const nvme_mi_admin_resp_hdr& adminResp,
                                       std::span<uint8_t> respData)>&& cb) {
            return fake->adminXfer(ctrl, adminReq, data, timeoutMs,
                                   std::move(cb));
        });
        ON_CALL(*this, adminSecuritySend).WillByDefault([]() { return; });
        ON_CALL(*this, adminSecurityReceive).WillByDefault([]() { return; });
        ON_CALL(*this, adminListNamespaces)
            .WillByDefault(
                [this](nvme_mi_ctrl_t ctrl,
                       std::function<void(nvme_ex_ptr ex,
                                          std::vector<uint32_t> ns)>&& cb) {
            // return empty NS list
            return fake->adminListNamespaces(ctrl, std::move(cb));
        });
        ON_CALL(*this, adminFormat).WillByDefault([this](auto&&... args) {
            return fake->adminFormat(std::forward<decltype(args)>(args)...);
        });
    }

    MOCK_METHOD(void, start, (const std::shared_ptr<MctpEndpoint>&),
                (override));
    MOCK_METHOD(void, stop, (), (override));
    MOCK_METHOD(void, recover, (), (override));
    MOCK_METHOD(int, getNID, (), (const override));
    MOCK_METHOD(int, getEID, (), (const override));
    MOCK_METHOD(void, miSubsystemHealthStatusPoll,
                (std::function<void(const std::error_code&,
                                    nvme_mi_nvm_ss_health_status*)>&&),
                (override));
    MOCK_METHOD(void, miScanCtrl,
                (std::function<void(const std::error_code&,
                                    const std::vector<nvme_mi_ctrl_t>&)>),
                (override));
    MOCK_METHOD(bool, flushOperations, (std::function<void()>&&));
    MOCK_METHOD(void, adminIdentify,
                (nvme_mi_ctrl_t ctrl, nvme_identify_cns cns, uint32_t nsid,
                 uint16_t cntid,
                 std::function<void(nvme_ex_ptr, std::span<uint8_t>)>&& cb),
                (override));
    MOCK_METHOD(void, adminGetFeatures,
                (nvme_mi_ctrl_t ctrl, const GetFeaturesRequest& req,
                 std::function<void(nvme_ex_ptr, uint32_t response,
                                    std::span<uint8_t>)>&& cb),
                (override));
    MOCK_METHOD(void, adminSetFeatures,
                (nvme_mi_ctrl_t ctrl, const SetFeaturesRequest& req,
                 std::function<void(nvme_ex_ptr, uint32_t response)>&& cb),
                (override));
    MOCK_METHOD(
        void, adminGetLogPage,
        (nvme_mi_ctrl_t ctrl, nvme_cmd_get_log_lid lid, uint32_t nsid,
         uint8_t lsp, uint16_t lsi,
         std::function<void(const std::error_code&, std::span<uint8_t>)>&& cb,
         uint8_t dataArea),
        (override));
    MOCK_METHOD(
        void, adminFwCommit,
        (nvme_mi_ctrl_t ctrl, nvme_fw_commit_ca action, uint8_t slot, bool bpid,
         std::function<void(const std::error_code&, nvme_status_field)>&& cb),
        (override));
    MOCK_METHOD(void, adminXfer,
                (nvme_mi_ctrl_t ctrl, const nvme_mi_admin_req_hdr& adminReq,
                 std::span<uint8_t> data, unsigned int timeoutMs,
                 std::function<void(const std::error_code& ec,
                                    const nvme_mi_admin_resp_hdr& adminResp,
                                    std::span<uint8_t> respData)>&& cb),
                (override));
    MOCK_METHOD(
        void, adminLockdownInband,
        (nvme_mi_ctrl_t ctrl, uint8_t prohibit,
         const std::vector<uint8_t>& adminCmds,
         const std::vector<uint8_t>& features,
         const std::vector<uint8_t>& logPages,
         std::function<
             void(const std::error_code&, int nvmeStatus, uint32_t comptionDw0,
                  const std::string& failureScope, uint32_t failureId)>&& cb),
        (override));
    MOCK_METHOD(
        void, adminSecuritySend,
        (nvme_mi_ctrl_t ctrl, uint8_t proto, uint16_t protoSpecific,
         std::span<uint8_t> data,
         std::function<void(const std::error_code&, int nvmeStatus)>&& cb),
        (override));
    MOCK_METHOD(void, adminSecurityReceive,
                (nvme_mi_ctrl_t ctrl, uint8_t proto, uint16_t protoSpecific,
                 uint32_t transferLength,
                 std::function<void(const std::error_code&, int nvmeStatus,
                                    const std::span<uint8_t> data)>&& cb),
                (override));

    MOCK_METHOD(
        void, adminFwDownload,
        (nvme_mi_ctrl_t ctrl, std::string firmwarefile,
         std::function<void(const std::error_code&, nvme_status_field)>&& cb),
        (override));

    MOCK_METHOD(void, adminNonDataCmd,
                (nvme_mi_ctrl_t ctrl, uint8_t opcode, uint32_t cdw1,
                 uint32_t cdw2, uint32_t cdw3, uint32_t cdw10, uint32_t cdw11,
                 uint32_t cdw12, uint32_t cdw13, uint32_t cdw14, uint32_t cdw15,
                 std::function<void(const std::error_code&, int nvmeStatus,
                                    uint32_t comptionDw0)>&& cb),
                (override));
    MOCK_METHOD(void, createNamespace,
                (nvme_mi_ctrl_t ctrl, uint64_t size, size_t lbaFormat,
                 bool metadataAtEnd,
                 std::function<void(nvme_ex_ptr ex)>&& submittedCB,
                 std::function<void(nvme_ex_ptr ex, NVMeNSIdentify newid)>&&
                     finishedCB),
                (override));

    MOCK_METHOD(
        void, adminDeleteNamespace,
        (nvme_mi_ctrl_t ctrl, uint32_t nsid,
         std::function<void(const std::error_code&, int nvmeStatus)>&& cb),
        (override));

    MOCK_METHOD(
        void, adminAttachDetachNamespace,
        (nvme_mi_ctrl_t ctrl, uint16_t ctrlid, uint32_t nsid, bool attach,
         std::function<void(const std::error_code&, int nvmeStatus)>&& cb),
        (override));

    MOCK_METHOD(
        void, adminListNamespaces,
        (nvme_mi_ctrl_t ctrl,
         std::function<void(nvme_ex_ptr ex, std::vector<uint32_t> ns)>&& cb),
        (override));

    MOCK_METHOD(void, adminSanitize,
                (nvme_mi_ctrl_t ctrl, enum nvme_sanitize_sanact sanact,
                 uint8_t passes, uint32_t pattern, bool invertPattern,
                 std::function<void(nvme_ex_ptr ex)>&& cb),
                (override));

    MOCK_METHOD(
        void, adminFormat,
        (nvme_mi_ctrl_t ctrl, uint32_t nsid, uint8_t lbaFormat,
         uint8_t secureEraseSetting, uint8_t metadataSettings,
         uint8_t dataProtectionType, uint8_t protectionInformationLocation,
         std::function<void(const std::error_code&, int nvmeStatus)>&& cb),
        (override));

    std::shared_ptr<NVMeMiFake> fake;
};

class NVMeTest : public ::testing::Test
{
  protected:
    NVMeTest() :
        systemBus(std::make_shared<sdbusplus::asio::connection>(io)),
        object_server(systemBus),
        nvme_intf(NVMeIntf::create<::testing::NiceMock<NVMeMiMock>>(
            io, subsysPollTime / 10)),
        mock(*std::dynamic_pointer_cast<NVMeMiMock>(
            std::get<std::shared_ptr<NVMeMiIntf>>(nvme_intf.getInferface()))),
        subsys(std::make_shared<NVMeSubsystem>(
            io, object_server, systemBus, std::string(subsysPath), "NVMe_1",
            SensorData{}, nvme_intf, false))
    {
        systemBus->request_name("xyz.openbmc_project.NVMeTest");
        subsys->unavailableMaxCount = 1;
        subsys->pollingInterval = subsysPollTime;
    }

    static void SetUpTestSuite()
    {
        // Load plugin shared libraries
        try
        {
            for (const auto& entry :
                 std::filesystem::directory_iterator(xstr(BUILDDIR)))
            {
                void* lib = dlopen(entry.path().c_str(), RTLD_NOW);
                if (lib != nullptr)
                {
                    pluginLibMap.emplace(entry.path().filename().string(), lib);
                }
                else
                {
                    std::cerr << "could not load the plugin: " << dlerror()
                              << '\n';
                }
            }
        }
        catch (const std::filesystem::filesystem_error& e)
        {
            std::cerr << "failed to open plugin folder: " << e.what() << '\n';
        }
    }

    void SetUp() override
    {
        subsys->init();
        subsys->start();
    }

    void TearDown() override
    {
        if (subsys)
        {
            subsys->stop();
        }
        io.poll();
        io.restart();
    }

    static constexpr std::string_view subsysPath = // NOLINT
        "/xyz/openbmc_project/inventory/Test_Chassis/Test_NVMe";

    boost::asio::io_context io;
    std::shared_ptr<sdbusplus::asio::connection> systemBus;
    sdbusplus::asio::object_server object_server;

    NVMeIntf nvme_intf;
    NVMeMiMock& mock;
    std::shared_ptr<NVMeSubsystem> subsys;

    const static std::chrono::milliseconds subsysPollTime;
};

const std::chrono::milliseconds NVMeTest::subsysPollTime = []() {
    return (RUNNING_ON_VALGRIND != 0U) ? std::chrono::milliseconds(1000)
                                       : std::chrono::milliseconds(100);
}();

/**
 * @brief Test start and stop function of NVMeSubsystem
 *
 */
TEST_F(NVMeTest, TestSubsystemStartStop)
{
    using ::testing::AtLeast;
    boost::asio::steady_timer timer(io);

    EXPECT_CALL(mock, miSubsystemHealthStatusPoll).Times(AtLeast(1));
    EXPECT_CALL(mock, adminIdentify).Times(AtLeast(1));
    EXPECT_CALL(mock, miScanCtrl).Times(AtLeast(1));

    // wait for subsystem initialization
    timer.expires_after(subsysPollTime * 2);
    timer.async_wait([&](boost::system::error_code) {
        systemBus->async_method_call(
            [&, this](boost::system::error_code, const GetSubTreeType& result) {
            // Only PF and the enabled VF should be listed
            EXPECT_EQ(result.size(), 2);
            subsys->stop();

            // wait for storage controller destruction.
            timer.expires_after(subsysPollTime * 1);
            timer.async_wait([&](boost::system::error_code) {
                systemBus->async_method_call(
                    [&](boost::system::error_code,
                        const GetSubTreeType& result) {
                    // not storage controller should be listed.
                    nlohmann::json j(result);
                    EXPECT_EQ(result.size(), 0)
                        << "The following interfaces remain after STOP: \n"
                        << j.dump(2) << '\n';
                    // restart the subsystem
                    subsys->start();
                    timer.expires_after(subsysPollTime * 2);
                    timer.async_wait([&](boost::system::error_code) {
                        systemBus->async_method_call(
                            [&](boost::system::error_code,
                                const GetSubTreeType& result) {
                            EXPECT_EQ(result.size(), 2);

                            subsys->stop();
                            // subsys.reset();

                            // wait for storage controller destruction.
                            timer.expires_after(subsysPollTime * 1);
                            timer.async_wait([&](boost::system::error_code) {
                                systemBus->async_method_call(
                                    [&](boost::system::error_code,
                                        const GetSubTreeType& result) {
                                    // not storage controller should be listed.
                                    nlohmann::json j(result);
                                    EXPECT_EQ(result.size(), 0)
                                        << "The following interfaces remain after STOP: \n"
                                        << j.dump(2) << '\n';
                                    io.stop();
                                },
                                    "xyz.openbmc_project.ObjectMapper",
                                    "/xyz/openbmc_project/object_mapper",
                                    "xyz.openbmc_project.ObjectMapper",
                                    "GetSubTree", subsysPath, 0,
                                    std::vector<std::string>{
                                        "xyz.openbmc_project.Inventory."
                                        "Item.StorageController"});
                            });
                        },
                            "xyz.openbmc_project.ObjectMapper",
                            "/xyz/openbmc_project/object_mapper",
                            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
                            subsysPath, 0,
                            std::vector<std::string>{
                                "xyz.openbmc_project.Inventory.Item.StorageController"});
                    });
                },
                    "xyz.openbmc_project.ObjectMapper",
                    "/xyz/openbmc_project/object_mapper",
                    "xyz.openbmc_project.ObjectMapper", "GetSubTree",
                    subsysPath, 0,
                    std::vector<std::string>{"xyz.openbmc_project.Inventory."
                                             "Item.StorageController"});
            });
        }, "xyz.openbmc_project.ObjectMapper",
            "/xyz/openbmc_project/object_mapper",
            "xyz.openbmc_project.ObjectMapper", "GetSubTree", subsysPath, 0,
            std::vector<std::string>{
                "xyz.openbmc_project.Inventory.Item.StorageController"});
    });
    io.run();
}

/**
 * @brief Test NVMeMi return DriveFunctional(NSHDS.NSS.DF) = 0
 *
 */
TEST_F(NVMeTest, TestDriveFunctional)
{
    using ::testing::AtLeast;
    boost::asio::steady_timer timer(io);

    EXPECT_CALL(mock, miSubsystemHealthStatusPoll).Times(AtLeast(1));
    EXPECT_CALL(mock, adminIdentify).Times(AtLeast(1));
    EXPECT_CALL(mock, miScanCtrl).Times(AtLeast(1));

    // wait for subsystem initialization
    timer.expires_after(subsysPollTime * 2);
    timer.async_wait([&](boost::system::error_code) {
        systemBus->async_method_call(
            [&](boost::system::error_code, const GetSubTreeType& result) {
            // Only PF and the enabled VF should be listed
            EXPECT_EQ(result.size(), 2);

            // mimik communication error of NVMeMI request
            ON_CALL(mock, miSubsystemHealthStatusPoll)
                .WillByDefault(
                    [&](std::function<void(const std::error_code&,
                                           nvme_mi_nvm_ss_health_status*)>&&
                            cb) {
                std::cerr << "mock device not functional health poll" << '\n';
                // return status.nss.df = 0
                return boost::asio::post(io, [cb = std::move(cb)]() {
                    nvme_mi_nvm_ss_health_status status{};
                    status.nss = 0;
                    cb({}, &status);
                });
            });

            // wait for storage controller destruction.
            timer.expires_after(subsysPollTime * 2);
            timer.async_wait([&](boost::system::error_code) {
                systemBus->async_method_call(
                    [&](boost::system::error_code,
                        const GetSubTreeType& result) {
                    // no storage controller should be listed.
                    nlohmann::json j(result);
                    EXPECT_EQ(result.size(), 0)
                        << "The following interfaces remain after unfunctional: \n"
                        << j.dump(2) << '\n';

                    // restart sending DF = 1
                    ON_CALL(mock, miSubsystemHealthStatusPoll)
                        .WillByDefault(
                            [&](std::function<void(
                                    const std::error_code&,
                                    nvme_mi_nvm_ss_health_status*)>&& cb) {
                        return mock.fake->miSubsystemHealthStatusPoll(
                            std::move(cb));
                    });
                    timer.expires_after(subsysPollTime * 2);
                    timer.async_wait([&](boost::system::error_code) {
                        systemBus->async_method_call(
                            [&](boost::system::error_code,
                                const GetSubTreeType& result) {
                            // storage controller should be restored.
                            EXPECT_EQ(result.size(), 2);

                            subsys->stop();
                            // subsys.reset();

                            // wait for storage controller destruction.
                            timer.expires_after(subsysPollTime * 1);
                            timer.async_wait([&](boost::system::error_code) {
                                systemBus->async_method_call(
                                    [&](boost::system::error_code,
                                        const GetSubTreeType& result) {
                                    // not storage controller should be listed.
                                    nlohmann::json j(result);
                                    EXPECT_EQ(result.size(), 0)
                                        << "The following interfaces remain after STOP: \n"
                                        << j.dump(2) << '\n';
                                    io.stop();
                                },
                                    "xyz.openbmc_project.ObjectMapper",
                                    "/xyz/openbmc_project/object_mapper",
                                    "xyz.openbmc_project.ObjectMapper",
                                    "GetSubTree", subsysPath, 0,
                                    std::vector<std::string>{
                                        "xyz.openbmc_project.Inventory."
                                        "Item.StorageController"});
                            });
                        },
                            "xyz.openbmc_project.ObjectMapper",
                            "/xyz/openbmc_project/object_mapper",
                            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
                            subsysPath, 0,
                            std::vector<std::string>{
                                "xyz.openbmc_project.Inventory."
                                "Item.StorageController"});
                    });
                },
                    "xyz.openbmc_project.ObjectMapper",
                    "/xyz/openbmc_project/object_mapper",
                    "xyz.openbmc_project.ObjectMapper", "GetSubTree",
                    subsysPath, 0,
                    std::vector<std::string>{"xyz.openbmc_project.Inventory."
                                             "Item.StorageController"});
            });
        }, "xyz.openbmc_project.ObjectMapper",
            "/xyz/openbmc_project/object_mapper",
            "xyz.openbmc_project.ObjectMapper", "GetSubTree", subsysPath, 0,
            std::vector<std::string>{
                "xyz.openbmc_project.Inventory.Item.StorageController"});
    });
    io.run();
}

/**
 * @brief Test NVMeMi returns Drive is absent (ec = no_such_device)
 *
 */
TEST_F(NVMeTest, TestDriveAbsent)
{
    using ::testing::AtLeast;
    boost::asio::steady_timer timer(io);

    EXPECT_CALL(mock, miSubsystemHealthStatusPoll).Times(AtLeast(1));
    EXPECT_CALL(mock, adminIdentify).Times(AtLeast(1));
    EXPECT_CALL(mock, miScanCtrl).Times(AtLeast(1));

    // wait for subsystem initialization
    timer.expires_after(subsysPollTime * 2);
    timer.async_wait([&](boost::system::error_code) {
        systemBus->async_method_call(
            [&](boost::system::error_code, const GetSubTreeType& result) {
            // Only PF and the enabled VF should be listed
            EXPECT_EQ(result.size(), 2);

            // mimik communication error of NVMeMI request
            ON_CALL(mock, miSubsystemHealthStatusPoll)
                .WillByDefault(
                    [&](std::function<void(const std::error_code&,
                                           nvme_mi_nvm_ss_health_status*)>&&
                            cb) {
                std::cerr << "mock device absent health poll" << '\n';
                // return no_such_device
                return boost::asio::post(io, [cb = std::move(cb)]() {
                    cb(std::make_error_code(std::errc::no_such_device),
                       nullptr);
                });
            });

            // wait for storage controller destruction.
            timer.expires_after(subsysPollTime * 2);
            timer.async_wait([&](boost::system::error_code) {
                systemBus->async_method_call(
                    [&](boost::system::error_code,
                        const GetSubTreeType& result) {
                    // no storage controller should be listed.
                    nlohmann::json j(result);
                    EXPECT_EQ(result.size(), 0)
                        << "The following interfaces remain after absent: \n"
                        << j.dump(2) << '\n';

                    // restart sending normal polling result
                    ON_CALL(mock, miSubsystemHealthStatusPoll)
                        .WillByDefault(
                            [&](std::function<void(
                                    const std::error_code&,
                                    nvme_mi_nvm_ss_health_status*)>&& cb) {
                        return mock.fake->miSubsystemHealthStatusPoll(
                            std::move(cb));
                    });
                    timer.expires_after(subsysPollTime * 5);
                    timer.async_wait([&](boost::system::error_code) {
                        systemBus->async_method_call(
                            [&](boost::system::error_code,
                                const GetSubTreeType& result) {
                            // storage controller should be restored.
                            EXPECT_EQ(result.size(), 2);

                            subsys->stop();

                            // wait for storage controller destruction.
                            timer.expires_after(subsysPollTime * 1);
                            timer.async_wait([&](boost::system::error_code) {
                                systemBus->async_method_call(
                                    [&](boost::system::error_code,
                                        const GetSubTreeType& result) {
                                    // not storage controller should be listed.
                                    nlohmann::json j(result);
                                    EXPECT_EQ(result.size(), 0)
                                        << "The following interfaces remain after STOP: \n"
                                        << j.dump(2) << '\n';
                                    io.stop();
                                },
                                    "xyz.openbmc_project.ObjectMapper",
                                    "/xyz/openbmc_project/object_mapper",
                                    "xyz.openbmc_project.ObjectMapper",
                                    "GetSubTree", subsysPath, 0,
                                    std::vector<std::string>{
                                        "xyz.openbmc_project.Inventory."
                                        "Item.StorageController"});
                            });
                        },
                            "xyz.openbmc_project.ObjectMapper",
                            "/xyz/openbmc_project/object_mapper",
                            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
                            subsysPath, 0,
                            std::vector<std::string>{
                                "xyz.openbmc_project.Inventory."
                                "Item.StorageController"});
                    });
                },
                    "xyz.openbmc_project.ObjectMapper",
                    "/xyz/openbmc_project/object_mapper",
                    "xyz.openbmc_project.ObjectMapper", "GetSubTree",
                    subsysPath, 0,
                    std::vector<std::string>{"xyz.openbmc_project.Inventory."
                                             "Item.StorageController"});
            });
        }, "xyz.openbmc_project.ObjectMapper",
            "/xyz/openbmc_project/object_mapper",
            "xyz.openbmc_project.ObjectMapper", "GetSubTree", subsysPath, 0,
            std::vector<std::string>{
                "xyz.openbmc_project.Inventory.Item.StorageController"});
    });
    io.run();
}

/**
 * @brief Inject error during subsystem initialization process. The subsystem is
 * expected to recover after the error
 */
TEST_F(NVMeTest, InitErrorInjection)
{
    using ::testing::_;
    using ::testing::AnyNumber;
    using ::testing::AtLeast;
    using ::testing::Eq;
    boost::asio::steady_timer timer(io);

    EXPECT_CALL(mock, miSubsystemHealthStatusPoll).Times(AtLeast(1));
    EXPECT_CALL(mock, miScanCtrl)
        .WillOnce(
            [](const std::function<void(const std::error_code&,
                                        const std::vector<nvme_mi_ctrl_t>&)>&
                   cb) {
        cb(std::make_error_code(std::errc::no_such_device), {});
    }).WillRepeatedly([&](auto&& cb) {
        return mock.fake->miScanCtrl(std::forward<decltype(cb)>(cb));
    });

    EXPECT_CALL(mock, adminIdentify).Times(::testing::AnyNumber());

    // Failed on the first query on id_sec_cntrl_list
    EXPECT_CALL(
        mock,
        adminIdentify(
            _, Eq(nvme_identify_cns::NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST), _,
            _, _))
        .WillOnce([]<class... Args>(Args... args) -> void {
        auto&& cb = std::get<sizeof...(Args) - 1>(std::tie(args...));
        return cb(
            makeLibNVMeError(0, NVME_MI_RESP_INVALID_PARAM, "adminIdentify"),
            {});
    }).WillRepeatedly([&]<class... Args>(Args&&... args) {
        return mock.fake->adminIdentify(std::forward<Args>(args)...);
    });

    // failed on first id_allocated_ns
    EXPECT_CALL(
        mock,
        adminIdentify(_, Eq(nvme_identify_cns::NVME_IDENTIFY_CNS_ALLOCATED_NS),
                      _, _, _))
        .Times(AnyNumber()) // allow to run at 0 times based on given NS number
        .WillOnce([]<class... Args>(Args... args) -> void {
        auto&& cb = std::get<sizeof...(Args) - 1>(std::tie(args...));
        return cb(
            makeLibNVMeError(0, NVME_MI_RESP_INVALID_PARAM, "adminIdentify"),
            {});
    }).WillRepeatedly([&]<class... Args>(Args&&... args) {
        return mock.fake->adminIdentify(std::forward<Args>(args)...);
    });

    // failed on first id_ns_cntrl
    EXPECT_CALL(
        mock,
        adminIdentify(_, Eq(nvme_identify_cns::NVME_IDENTIFY_CNS_NS_CTRL_LIST),
                      _, _, _))
        .Times(AnyNumber()) // allow to run at 0 times based on given NS number
        .WillOnce([]<class... Args>(Args... args) -> void {
        auto&& cb = std::get<sizeof...(Args) - 1>(std::tie(args...));
        return cb(
            makeLibNVMeError(0, NVME_MI_RESP_INVALID_PARAM, "adminIdentify"),
            {});
    }).WillRepeatedly([&]<class... Args>(Args&&... args) {
        return mock.fake->adminIdentify(std::forward<Args>(args)...);
    });

    // failed on first id_cntrl
    EXPECT_CALL(mock,
                adminIdentify(_, Eq(nvme_identify_cns::NVME_IDENTIFY_CNS_CTRL),
                              _, _, _))
        .WillOnce([]<class... Args>(Args... args) -> void {
        auto&& cb = std::get<sizeof...(Args) - 1>(std::tie(args...));
        return cb(
            makeLibNVMeError(0, NVME_MI_RESP_INVALID_PARAM, "adminIdentify"),
            {});
    }).WillRepeatedly([&]<class... Args>(Args&&... args) {
        return mock.fake->adminIdentify(std::forward<Args>(args)...);
    });

    // failed on first id_ns
    EXPECT_CALL(
        mock,
        adminIdentify(_, Eq(nvme_identify_cns::NVME_IDENTIFY_CNS_NS), _, _, _))
        .Times(AnyNumber()) // allow to run at 0 times based on given NS number
        .WillOnce([]<class... Args>(Args... args) -> void {
        auto&& cb = std::get<sizeof...(Args) - 1>(std::tie(args...));
        return cb(
            makeLibNVMeError(0, NVME_MI_RESP_INVALID_PARAM, "adminIdentify"),
            {});
    }).WillRepeatedly([&]<class... Args>(Args&&... args) {
        return mock.fake->adminIdentify(std::forward<Args>(args)...);
    });

    // Failed on list namespace
    EXPECT_CALL(mock, adminListNamespaces)
        .WillOnce([]<class... Args>(Args... args) -> void {
        auto&& cb = std::get<sizeof...(Args) - 1>(std::tie(args...));
        return cb(
            makeLibNVMeError(0, NVME_MI_RESP_INVALID_PARAM, "adminIdentify"),
            {});
    }).WillRepeatedly([&]<class... Args>(Args&&... args) {
        return mock.fake->adminListNamespaces(std::forward<Args>(args)...);
    });

    // wait for subsystem initialization, each failure will introduce 1 second
    // delay for retry
    timer.expires_after(subsysPollTime * (2 + 10 + 4));
    timer.async_wait([&](boost::system::error_code) {
        systemBus->async_method_call(
            [&, this](boost::system::error_code, const GetSubTreeType& result) {
            // Only PF and the enabled VF should be listed
            EXPECT_EQ(result.size(), 2);
            subsys->stop();

            // wait for storage controller destruction.
            timer.expires_after(subsysPollTime * 1);
            timer.async_wait([&](boost::system::error_code) {
                systemBus->async_method_call(
                    [&](boost::system::error_code,
                        const GetSubTreeType& result) {
                    // not storage controller should be listed.
                    nlohmann::json j(result);
                    EXPECT_EQ(result.size(), 0)
                        << "The following interfaces remain after STOP: \n"
                        << j.dump(2) << '\n';
                    io.stop();
                },
                    "xyz.openbmc_project.ObjectMapper",
                    "/xyz/openbmc_project/object_mapper",
                    "xyz.openbmc_project.ObjectMapper", "GetSubTree",
                    subsysPath, 0,
                    std::vector<std::string>{"xyz.openbmc_project.Inventory."
                                             "Item.StorageController"});
            });
        }, "xyz.openbmc_project.ObjectMapper",
            "/xyz/openbmc_project/object_mapper",
            "xyz.openbmc_project.ObjectMapper", "GetSubTree", subsysPath, 0,
            std::vector<std::string>{
                "xyz.openbmc_project.Inventory.Item.StorageController"});
    });
    io.run();
}
/**
 * @brief Test NVMe Format D-Bus method
 *
 */
TEST_F(NVMeTest, TestFormat)
{
    using ::testing::_;
    using ::testing::AtLeast;
    boost::asio::steady_timer timer(io);

    EXPECT_CALL(mock, miSubsystemHealthStatusPoll).Times(AtLeast(1));
    EXPECT_CALL(mock, adminIdentify).Times(AtLeast(1));
    EXPECT_CALL(mock, miScanCtrl).Times(AtLeast(1));

    constexpr uint8_t lbaf1 = 1;
    constexpr uint8_t sesNone = 0;

    mock.fake->fakeMetadataCapabilities =
        1; // MTELBAS = 1, MTSBS = 0 -> Hardware MSET = 1

    EXPECT_CALL(mock, adminFormat)
        .WillOnce(
            [this, lbaf1, sesNone](
                nvme_mi_ctrl_t /*ctrl*/, uint32_t nsid, uint8_t lbaFormat,
                uint8_t secureEraseSetting, uint8_t metadataSettings,
                uint8_t dataProtectionType,
                uint8_t protectionInformationLocation,
                std::function<void(const std::error_code&, int nvmeStatus)>&&
                    cb) {
        EXPECT_EQ(nsid, 1);
        EXPECT_EQ(lbaFormat, lbaf1);
        EXPECT_EQ(secureEraseSetting, sesNone);
        EXPECT_EQ(metadataSettings, 1);
        EXPECT_EQ(dataProtectionType, 0);
        EXPECT_EQ(protectionInformationLocation, 0);
        boost::asio::post(io, [cb = std::move(cb)]() mutable { cb({}, 0); });
    }).WillRepeatedly([&](auto&&... args) {
        return mock.fake->adminFormat(std::forward<decltype(args)>(args)...);
    });

    // wait for subsystem initialization
    timer.expires_after(subsysPollTime * 2);
    timer.async_wait([&](boost::system::error_code) {
        systemBus->async_method_call(
            [&, this](boost::system::error_code ec) {
            EXPECT_FALSE(ec) << "D-Bus error: " << ec.message();

            subsys->stop();
            // wait for storage controller destruction.
            timer.expires_after(subsysPollTime * 1);
            timer.async_wait([&](boost::system::error_code) { io.stop(); });
        }, "xyz.openbmc_project.NVMeTest",
            std::string(subsysPath) + "/controllers/0",
            "xyz.openbmc_project.Nvme.Controller", "Format", lbaf1,
            std::string(
                "xyz.openbmc_project.NVMe.Format.SecureEraseSetting.None"),
            std::string(
                "xyz.openbmc_project.NVMe.Format.DataProtectionType.None"));
    });
    io.run();
}

/**
 * @brief Test NVMe Format D-Bus method with Separate Buffer Metadata (MSET=1)
 *
 */
TEST_F(NVMeTest, TestFormatSeparateBuffer)
{
    using ::testing::_;
    using ::testing::AtLeast;
    boost::asio::steady_timer timer(io);

    EXPECT_CALL(mock, miSubsystemHealthStatusPoll).Times(AtLeast(1));
    EXPECT_CALL(mock, adminIdentify).Times(AtLeast(1));
    EXPECT_CALL(mock, miScanCtrl).Times(AtLeast(1));

    constexpr uint8_t lbaf1 = 1;
    constexpr uint8_t sesNone = 0;

    mock.fake->fakeMetadataCapabilities =
        2; // MTELBAS = 0, MTSBS = 1 -> Hardware MSET = 0

    EXPECT_CALL(mock, adminFormat)
        .WillOnce(
            [this, lbaf1, sesNone](
                nvme_mi_ctrl_t /*ctrl*/, uint32_t nsid, uint8_t lbaFormat,
                uint8_t secureEraseSetting, uint8_t metadataSettings,
                uint8_t dataProtectionType,
                uint8_t protectionInformationLocation,
                std::function<void(const std::error_code&, int nvmeStatus)>&&
                    cb) {
        EXPECT_EQ(nsid, 1);
        EXPECT_EQ(lbaFormat, lbaf1);
        EXPECT_EQ(secureEraseSetting, sesNone);
        EXPECT_EQ(metadataSettings, 0);
        EXPECT_EQ(dataProtectionType, 0);
        EXPECT_EQ(protectionInformationLocation, 0);
        boost::asio::post(io, [cb = std::move(cb)]() mutable { cb({}, 0); });
    }).WillRepeatedly([&](auto&&... args) {
        return mock.fake->adminFormat(std::forward<decltype(args)>(args)...);
    });

    // wait for subsystem initialization
    timer.expires_after(subsysPollTime * 2);
    timer.async_wait([&](boost::system::error_code) {
        systemBus->async_method_call(
            [&, this](boost::system::error_code ec) {
            EXPECT_FALSE(ec);

            subsys->stop();
            // wait for storage controller destruction.
            timer.expires_after(subsysPollTime * 1);
            timer.async_wait([&](boost::system::error_code) { io.stop(); });
        }, "xyz.openbmc_project.NVMeTest",
            std::string(subsysPath) + "/controllers/0",
            "xyz.openbmc_project.Nvme.Controller", "Format", lbaf1,
            std::string(
                "xyz.openbmc_project.NVMe.Format.SecureEraseSetting.None"),
            std::string(
                "xyz.openbmc_project.NVMe.Format.DataProtectionType.None"));
    });
    io.run();
}

/**
 * @brief Test NVMe Format D-Bus method with Crypto Erase (Success)
 *
 */
TEST_F(NVMeTest, TestFormatCryptoEraseSuccess)
{
    using ::testing::_;
    using ::testing::AtLeast;
    boost::asio::steady_timer timer(io);

    EXPECT_CALL(mock, miSubsystemHealthStatusPoll).Times(AtLeast(1));
    EXPECT_CALL(mock, adminIdentify).Times(AtLeast(1));
    EXPECT_CALL(mock, miScanCtrl).Times(AtLeast(1));

    constexpr uint8_t lbaf1 = 1;
    constexpr uint8_t sesCryptoErase = 2;

    mock.fake->fakeMetadataCapabilities =
        1; // MTELBAS = 1, MTSBS = 0 -> Hardware MSET = 1

    EXPECT_CALL(mock, adminFormat)
        .WillOnce(
            [this, lbaf1, sesCryptoErase](
                nvme_mi_ctrl_t /*ctrl*/, uint32_t nsid, uint8_t lbaFormat,
                uint8_t secureEraseSetting, uint8_t metadataSettings,
                uint8_t dataProtectionType,
                uint8_t protectionInformationLocation,
                std::function<void(const std::error_code&, int nvmeStatus)>&&
                    cb) {
        EXPECT_EQ(nsid, 1);
        EXPECT_EQ(lbaFormat, lbaf1);
        EXPECT_EQ(secureEraseSetting, sesCryptoErase);
        EXPECT_EQ(metadataSettings, 1);
        EXPECT_EQ(dataProtectionType, 0);
        EXPECT_EQ(protectionInformationLocation, 0);
        boost::asio::post(io, [cb = std::move(cb)]() mutable { cb({}, 0); });
    }).WillRepeatedly([&](auto&&... args) {
        return mock.fake->adminFormat(std::forward<decltype(args)>(args)...);
    });

    // wait for subsystem initialization
    timer.expires_after(subsysPollTime * 2);
    timer.async_wait([&](boost::system::error_code) {
        systemBus->async_method_call(
            [&, this](boost::system::error_code ec) {
            EXPECT_FALSE(ec);

            subsys->stop();
            // wait for storage controller destruction.
            timer.expires_after(subsysPollTime * 1);
            timer.async_wait([&](boost::system::error_code) { io.stop(); });
        }, "xyz.openbmc_project.NVMeTest",
            std::string(subsysPath) + "/controllers/0",
            "xyz.openbmc_project.Nvme.Controller", "Format", lbaf1,
            std::string(
                "xyz.openbmc_project.NVMe.Format.SecureEraseSetting.CryptoErase"),
            std::string(
                "xyz.openbmc_project.NVMe.Format.DataProtectionType.None"));
    });
    io.run();
}

/**
 * @brief Test NVMe Subsystem Format D-Bus method with Broadcast (Success)
 *
 */
TEST_F(NVMeTest, TestSubsystemFormatBroadcastSuccess)
{
    using ::testing::_;
    using ::testing::AtLeast;
    boost::asio::steady_timer timer(io);

    EXPECT_CALL(mock, miSubsystemHealthStatusPoll).Times(AtLeast(1));
    EXPECT_CALL(mock, adminIdentify).Times(AtLeast(1));
    EXPECT_CALL(mock, miScanCtrl).Times(AtLeast(1));

    constexpr uint8_t lbaf1 = 1;
    constexpr uint8_t sesNone = 0;

    mock.fake->fakeMetadataCapabilities =
        1; // MTELBAS = 1, MTSBS = 0 -> Hardware MSET = 1

    EXPECT_CALL(mock, adminFormat)
        .WillOnce(
            [this, lbaf1, sesNone](
                nvme_mi_ctrl_t /*ctrl*/, uint32_t nsid, uint8_t lbaFormat,
                uint8_t secureEraseSetting, uint8_t metadataSettings,
                uint8_t dataProtectionType,
                uint8_t protectionInformationLocation,
                std::function<void(const std::error_code&, int nvmeStatus)>&&
                    cb) {
        EXPECT_EQ(nsid, NVME_NSID_ALL);
        EXPECT_EQ(lbaFormat, lbaf1);
        EXPECT_EQ(secureEraseSetting, sesNone);
        EXPECT_EQ(metadataSettings, 1);
        EXPECT_EQ(dataProtectionType, 0);
        EXPECT_EQ(protectionInformationLocation, 0);
        boost::asio::post(io, [cb = std::move(cb)]() mutable { cb({}, 0); });
    }).WillRepeatedly([&](auto&&... args) {
        return mock.fake->adminFormat(std::forward<decltype(args)>(args)...);
    });

    // wait for subsystem initialization
    timer.expires_after(subsysPollTime * 2);
    timer.async_wait([&](boost::system::error_code) {
        systemBus->async_method_call(
            [&, this](boost::system::error_code ec) {
            EXPECT_FALSE(ec);

            subsys->stop();
            // wait for storage controller destruction.
            timer.expires_after(subsysPollTime * 1);
            timer.async_wait([&](boost::system::error_code) { io.stop(); });
        }, "xyz.openbmc_project.NVMeTest", std::string(subsysPath),
            "xyz.openbmc_project.Nvme.Storage", "Format", lbaf1,
            std::string(
                "xyz.openbmc_project.NVMe.Format.SecureEraseSetting.None"),
            std::string(
                "xyz.openbmc_project.NVMe.Format.DataProtectionType.None"));
    });
    io.run();
}

/**
 * @brief Test NVMe Format D-Bus method with Crypto Erase (Failure due to FNA)
 *
 */
TEST_F(NVMeTest, TestFormatCryptoEraseFailure)
{
    using ::testing::_;
    using ::testing::AtLeast;
    boost::asio::steady_timer timer(io);

    EXPECT_CALL(mock, miSubsystemHealthStatusPoll).Times(AtLeast(1));
    EXPECT_CALL(mock, adminIdentify).Times(AtLeast(1));
    EXPECT_CALL(mock, miScanCtrl).Times(AtLeast(1));

    constexpr uint8_t lbaf1 = 1;

    mock.fake->fakeMetadataCapabilities =
        1; // MTELBAS = 1, MTSBS = 0 -> Hardware MSET = 1

    // When ses=2, NVMeMi will call adminIdentify (CNS_CTRL) to check FNA bit 2.
    // NVMeMi::adminFormat handles the identify and returns error if bit 2 is 0.
    // In our mock, adminFormat will be called by NVMeSubsystem.
    // The error will be caught by checkLibNVMeError and thrown as an exception.

    EXPECT_CALL(mock, adminFormat)
        .WillOnce(
            [this](nvme_mi_ctrl_t /*ctrl*/, uint32_t /*nsid*/,
                   uint8_t /*lbaFormat*/, uint8_t /*secureEraseSetting*/,
                   uint8_t /*metadataSettings*/, uint8_t /*dataProtectionType*/,
                   uint8_t /*protectionInformationLocation*/,
                   std::function<void(const std::error_code&, int nvmeStatus)>&&
                       cb) {
        // Simulate FNA bit 2 is 0 error
        boost::asio::post(io, [cb = std::move(cb)]() mutable {
            cb(std::make_error_code(std::errc::invalid_argument),
               NVME_SC_INVALID_FIELD);
        });
    }).WillRepeatedly([&](auto&&... args) {
        return mock.fake->adminFormat(std::forward<decltype(args)>(args)...);
    });

    // wait for subsystem initialization
    timer.expires_after(subsysPollTime * 2);
    timer.async_wait([&](boost::system::error_code) {
        systemBus->async_method_call(
            [&, this](boost::system::error_code ec) {
            // Should fail with D-Bus error
            EXPECT_TRUE(ec);

            subsys->stop();
            // wait for storage controller destruction.
            timer.expires_after(subsysPollTime * 1);
            timer.async_wait([&](boost::system::error_code) { io.stop(); });
        }, "xyz.openbmc_project.NVMeTest",
            std::string(subsysPath) + "/controllers/0",
            "xyz.openbmc_project.Nvme.Controller", "Format", lbaf1,
            std::string(
                "xyz.openbmc_project.NVMe.Format.SecureEraseSetting.CryptoErase"),
            std::string(
                "xyz.openbmc_project.NVMe.Format.DataProtectionType.None"));
    });
    io.run();
}

/**
 * @brief Test NVMe Format D-Bus method with UserDataErase (Failure as
 * unsupported)
 *
 */
TEST_F(NVMeTest, TestFormatUserDataEraseFailure)
{
    using ::testing::_;
    using ::testing::AtLeast;
    boost::asio::steady_timer timer(io);

    EXPECT_CALL(mock, miSubsystemHealthStatusPoll).Times(AtLeast(1));
    EXPECT_CALL(mock, adminIdentify).Times(AtLeast(1));
    EXPECT_CALL(mock, miScanCtrl).Times(AtLeast(1));

    constexpr uint8_t lbaf1 = 1;

    mock.fake->fakeMetadataCapabilities =
        1; // MTELBAS = 1, MTSBS = 0 -> Hardware MSET = 1

    // NVMeSubsystem::format should reject UserDataErase directly and throw
    // InvalidArgument. So adminFormat must NEVER be called.
    EXPECT_CALL(mock, adminFormat).Times(0);

    // wait for subsystem initialization
    timer.expires_after(subsysPollTime * 2);
    timer.async_wait([&](boost::system::error_code) {
        systemBus->async_method_call(
            [&, this](boost::system::error_code ec) {
            // Should fail with D-Bus error (InvalidArgument)
            EXPECT_TRUE(ec);

            subsys->stop();
            // wait for storage controller destruction.
            timer.expires_after(subsysPollTime * 1);
            timer.async_wait([&](boost::system::error_code) { io.stop(); });
        }, "xyz.openbmc_project.NVMeTest",
            std::string(subsysPath) + "/controllers/0",
            "xyz.openbmc_project.Nvme.Controller", "Format", lbaf1,
            std::string(
                "xyz.openbmc_project.NVMe.Format.SecureEraseSetting.UserDataErase"),
            std::string(
                "xyz.openbmc_project.NVMe.Format.DataProtectionType.None"));
    });
    io.run();
}

/**
 * @brief Test NVMe Volume Format D-Bus method with Crypto Erase (Success)
 *
 */
TEST_F(NVMeTest, TestVolumeFormatCryptoEraseSuccess)
{
    using ::testing::_;
    using ::testing::AtLeast;
    boost::asio::steady_timer timer(io);

    EXPECT_CALL(mock, miSubsystemHealthStatusPoll).Times(AtLeast(1));
    EXPECT_CALL(mock, adminIdentify).Times(AtLeast(1));
    EXPECT_CALL(mock, miScanCtrl).Times(AtLeast(1));

    constexpr uint8_t lbaf1 = 1;
    constexpr uint8_t sesCryptoErase = 2;

    mock.fake->fakeMetadataCapabilities =
        1; // MTELBAS = 1, MTSBS = 0 -> Hardware MSET = 1

    EXPECT_CALL(mock, adminFormat)
        .WillOnce(
            [this, lbaf1, sesCryptoErase](
                nvme_mi_ctrl_t /*ctrl*/, uint32_t nsid, uint8_t lbaFormat,
                uint8_t secureEraseSetting, uint8_t metadataSettings,
                uint8_t dataProtectionType,
                uint8_t protectionInformationLocation,
                std::function<void(const std::error_code&, int nvmeStatus)>&&
                    cb) {
        EXPECT_EQ(nsid, 1);
        EXPECT_EQ(lbaFormat, lbaf1);
        EXPECT_EQ(secureEraseSetting, sesCryptoErase);
        EXPECT_EQ(metadataSettings, 1);
        EXPECT_EQ(dataProtectionType, 0);
        EXPECT_EQ(protectionInformationLocation, 0);
        boost::asio::post(io, [cb = std::move(cb)]() mutable { cb({}, 0); });
    }).WillRepeatedly([&](auto&&... args) {
        return mock.fake->adminFormat(std::forward<decltype(args)>(args)...);
    });

    // Mock the post-format re-identify call to return LBAF 1 (4KB) and size
    // 2000 blocks
    EXPECT_CALL(mock, adminIdentify(
                          _, nvme_identify_cns::NVME_IDENTIFY_CNS_ALLOCATED_NS,
                          1, _, _))
        .WillOnce([&](auto&&... args) {
        mock.fake->adminIdentify(std::forward<decltype(args)>(args)...);
    })
        .WillOnce(
            [this](nvme_mi_ctrl_t /*ctrl*/, nvme_identify_cns /*cns*/,
                   uint32_t /*nsid*/, uint16_t /*cntid*/,
                   std::function<void(nvme_ex_ptr, std::span<uint8_t>)>&& cb) {
        std::vector<uint8_t> data(NVME_IDENTIFY_DATA_SIZE);
        nvme_id_ns idNs{};
        idNs.flbas = 1;            // LBAF 1
        idNs.lbaf[0].ds = 9;       // 512B
        idNs.lbaf[1].ds = 12;      // 4KB
        idNs.nsze = htole64(2000); // 2000 blocks
        idNs.ncap = htole64(2000);
        std::memcpy(data.data(), &idNs, sizeof(idNs));
        boost::asio::post(io,
                          [cb = std::move(cb),
                           data = std::move(data)]() mutable { cb({}, data); });
    });

    // wait for subsystem initialization
    timer.expires_after(subsysPollTime * 2);
    timer.async_wait([&](boost::system::error_code) {
        systemBus->async_method_call(
            [&, this](boost::system::error_code ec) {
            EXPECT_FALSE(ec);

            // Verify Volume properties after format
            systemBus->async_method_call(
                [&,
                 this](boost::system::error_code ec,
                       const std::map<std::string,
                                      std::variant<uint64_t, uint32_t, bool>>&
                           properties) {
                EXPECT_FALSE(ec);
                auto sizeIt = properties.find("Size");
                ASSERT_NE(sizeIt, properties.end());
                EXPECT_EQ(std::get<uint64_t>(sizeIt->second), 2000 * 4096);

                auto blockSizeIt = properties.find("BlockSize");
                ASSERT_NE(blockSizeIt, properties.end());
                EXPECT_EQ(std::get<uint64_t>(blockSizeIt->second), 4096);

                // Now query Nvme.Volume interface
                systemBus->async_method_call(
                    [&, this](
                        boost::system::error_code ec,
                        const std::map<std::string,
                                       std::variant<uint64_t, uint32_t, bool>>&
                            nvmeProperties) {
                    EXPECT_FALSE(ec);
                    auto lbafIt = nvmeProperties.find("LBAFormat");
                    ASSERT_NE(lbafIt, nvmeProperties.end());
                    EXPECT_EQ(std::get<uint64_t>(lbafIt->second), 1);

                    subsys->stop();
                    // wait for storage controller destruction.
                    timer.expires_after(subsysPollTime * 1);
                    timer.async_wait(
                        [&](boost::system::error_code) { io.stop(); });
                },
                    "xyz.openbmc_project.NVMeTest",
                    std::string(subsysPath) + "/volumes/1",
                    "org.freedesktop.DBus.Properties", "GetAll",
                    "xyz.openbmc_project.Nvme.Volume");
            },
                "xyz.openbmc_project.NVMeTest",
                std::string(subsysPath) + "/volumes/1",
                "org.freedesktop.DBus.Properties", "GetAll",
                "xyz.openbmc_project.Inventory.Item.Volume");
        }, "xyz.openbmc_project.NVMeTest",
            std::string(subsysPath) + "/volumes/1",
            "xyz.openbmc_project.Nvme.Volume", "Format", lbaf1,
            std::string(
                "xyz.openbmc_project.NVMe.Format.SecureEraseSetting.CryptoErase"),
            std::string(
                "xyz.openbmc_project.NVMe.Format.DataProtectionType.None"));
    });
    io.run();
}

int main(int argc, char** argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
