#include "test/g3/mock_managed_store_test.hpp"

#include <unistd.h>

#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/functional/any_invocable.h"
#include "absl/status/statusor.h"
#include "boost/asio/detail/exception.hpp"
#include "boost/asio/io_context.hpp"  // NOLINT
#include "boost/beast/http/message.hpp"  //NOLINT
#include "boost/beast/http/string_body.hpp"  //NOLINT
#include "boost/coroutine/exceptions.hpp"
#include "boost/system/detail/errc.hpp"
#include "boost/system/detail/error_code.hpp"
#include "redfish_v1.pb.h"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "test/g3/mock_managed_store.hpp"
#include "sdbusplus/message.hpp"
#include "sdbusplus/message/native_types.hpp"

namespace managedStore {
namespace {

using ::dbus::utility::DBusInteracesMap;
using ::dbus::utility::DBusPropertiesMap;
using ::dbus::utility::DbusVariantType;
using ::dbus::utility::ManagedObjectType;
using ::dbus::utility::MapperGetObject;
using ::dbus::utility::MapperGetSubTreePathsResponse;
using ::dbus::utility::MapperGetSubTreeResponse;
using ::dbus::utility::MapperServiceMap;
using ::dbus::utility::SystemdListUnits;

using ::testing::_;
using ::testing::An;
using ::testing::ElementsAre;

using ManagedType = managedStore::ManagedType;
using DurationType = std::tuple<std::string, int64_t>;

TEST_F(MockManagedStoreTest, ValidateSetPropertyMockWithFailedDbusCall) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();

  boost::system::error_code io_error =
      boost::system::errc::make_error_code(boost::system::errc::io_error);

  EXPECT_CALL(*mock_managed_store_instance_,
              setProperty("service", "path", "interface", "property",
                          dbus::utility::DbusVariantType{"bad_command"}, _))
      .Times(1)
      .WillOnce(SimulateFailedAsyncSetPropertyDbusCallAction::
                    SimulateFailedAsyncSetPropertyDbusCall(io_error));

  mock_managed_store_instance_->setProperty(
      "service", "path", "interface", "property",
      dbus::utility::DbusVariantType{"bad_command"},
      [&async_resp](const boost::system::error_code& ec) {
        if (ec) {
          async_resp->res.jsonValue["status"] = ec.value();
          return;
        }
        async_resp->res.jsonValue =
            nlohmann::json::parse(R"({"status": "success"})");
      });

  EXPECT_FALSE(async_resp->res.jsonValue.contains("status"));

  RunIoUntilDone();

  EXPECT_EQ(async_resp->res.jsonValue["status"], io_error.value());
}

TEST_F(MockManagedStoreTest, ValidateSetPropertyMockWithSuccessfulDbusCall) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();

  EXPECT_CALL(*mock_managed_store_instance_,
              setProperty("service", "path", "interface", "property",
                          dbus::utility::DbusVariantType{"good_command"}, _))
      .Times(1)
      .WillOnce(SimulateSuccessfulAsyncSetPropertyDbusCallAction::
                    SimulateSuccessfulAsyncSetPropertyDbusCall());

  mock_managed_store_instance_->setProperty(
      "service", "path", "interface", "property",
      dbus::utility::DbusVariantType{"good_command"},
      [async_resp](const boost::system::error_code& ec) {
        if (ec) {
          async_resp->res.jsonValue =
              nlohmann::json::parse(R"({"status": "error"})");
          return;
        }
        async_resp->res.jsonValue =
            nlohmann::json::parse(R"({"status": "success"})");
      });

  EXPECT_FALSE(async_resp->res.jsonValue.contains("status"));

  RunIoUntilDone();

  EXPECT_EQ(async_resp->res.jsonValue["status"], "success");
}

TEST_F(MockManagedStoreTest, ValidateSuccessfulPostDbusCallToIoContextMock) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();

  EXPECT_CALL(
      *mock_managed_store_instance_,
      PostDbusCallToIoContextThreadSafe(
          _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
          "service", "path", "interface", "method"))
      .Times(1)
      .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeAction::
                    SimulateSuccessfulAsyncPostDbusCall());

  mock_managed_store_instance_->PostDbusCallToIoContextThreadSafe(
      nullptr,
      [async_resp](const boost::system::error_code& ec) {
        if (ec) {
          async_resp->res.jsonValue =
              nlohmann::json::parse(R"({"status": "error"})");
          return;
        }
        async_resp->res.jsonValue =
            nlohmann::json::parse(R"({"status": "success"})");
      },
      "service", "path", "interface", "method");

  EXPECT_FALSE(async_resp->res.jsonValue.contains("status"));

  RunIoUntilDone();

  EXPECT_EQ(async_resp->res.jsonValue["status"], "success");
}

TEST_F(MockManagedStoreTest, ValidateFailedPostDbusCallToIoContextMock) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();

  EXPECT_CALL(
      *mock_managed_store_instance_,
      PostDbusCallToIoContextThreadSafe(
          _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
          "service", "path", "interface", "method"))
      .Times(1)
      .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeAction::
                    SimulateFailedAsyncPostDbusCall());

  mock_managed_store_instance_->PostDbusCallToIoContextThreadSafe(
      nullptr,
      [async_resp](const boost::system::error_code& ec) {
        if (ec) {
          async_resp->res.jsonValue =
              nlohmann::json::parse(R"({"status": "error"})");
          return;
        }
        async_resp->res.jsonValue =
            nlohmann::json::parse(R"({"status": "success"})");
      },
      "service", "path", "interface", "method");

  EXPECT_FALSE(async_resp->res.jsonValue.contains("status"));

  RunIoUntilDone();

  EXPECT_EQ(async_resp->res.jsonValue["status"], "error");
}

TEST_F(MockManagedStoreTest, VerifyUpsertCorrectlyAddsObjectInManagedStore) {
  DbusVariantType test_value("test_value");
  KeyType key(ManagedType::kManagedProperty, "service",
              sdbusplus::message::object_path("path"), "interface", "property");
  std::shared_ptr<ValueType> original_test_value = CreateValueType(test_value);
  EXPECT_FALSE(
      mock_managed_store_instance_->getMockObjectFromManagedStore(key).ok());
  EXPECT_TRUE(mock_managed_store_instance_
                  ->upsertMockObjectIntoManagedStore(key, original_test_value)
                  .ok());

  absl::StatusOr<std::shared_ptr<ValueType>> obtained_test_value =
      mock_managed_store_instance_->getMockObjectFromManagedStore(key);
  ASSERT_TRUE(obtained_test_value.ok());
  EXPECT_EQ((*obtained_test_value)->serialize(),
            original_test_value->serialize());
}

TEST_F(MockManagedStoreTest, VerifyUpsertCorrectlyUpdatesObjectInManagedStore) {
  KeyType key(ManagedType::kManagedProperty, "service",
              sdbusplus::message::object_path("path"), "interface", "property");
  std::shared_ptr<ValueType> original_test_value =
      CreateValueType(DbusVariantType("test_value"));

  EXPECT_TRUE(mock_managed_store_instance_
                  ->upsertMockObjectIntoManagedStore(key, original_test_value)
                  .ok());

  std::shared_ptr<ValueType> updated_test_value =
      CreateValueType(DbusVariantType("test_value_updated"));
  EXPECT_TRUE(mock_managed_store_instance_
                  ->upsertMockObjectIntoManagedStore(key, updated_test_value)
                  .ok());

  absl::StatusOr<std::shared_ptr<ValueType>> obtained_test_value =
      mock_managed_store_instance_->getMockObjectFromManagedStore(key);
  ASSERT_TRUE(obtained_test_value.ok());
  EXPECT_EQ((*obtained_test_value)->serialize(),
            updated_test_value->serialize());
}

TEST_F(MockManagedStoreTest, VerifyEvictCorrectlyUpdatesObjectInManagedStore) {
  KeyType key(ManagedType::kManagedProperty, "service",
              sdbusplus::message::object_path("path"), "interface", "property");
  std::shared_ptr<ValueType> original_test_value =
      CreateValueType(DbusVariantType("test_value"));

  EXPECT_TRUE(mock_managed_store_instance_
                  ->upsertMockObjectIntoManagedStore(key, original_test_value)
                  .ok());

  EXPECT_TRUE(
      mock_managed_store_instance_->evictMockObjectFromManagedStore(key).ok());

  EXPECT_FALSE(
      mock_managed_store_instance_->getMockObjectFromManagedStore(key).ok());
}

TEST_F(MockManagedStoreTest, IncorrectKeyTypeAndValueTypeUpsertThrowsError) {
  KeyType key(ManagedType::kManagedObject, "service",
              sdbusplus::message::object_path("path"), "interface", "property");
  std::shared_ptr<ValueType> original_test_value =
      CreateValueType(DbusVariantType("test_value"));

  EXPECT_FALSE(mock_managed_store_instance_
                   ->upsertMockObjectIntoManagedStore(key, original_test_value)
                   .ok());
}

// These are sample ways of creating a Mocked Dbus Object

// Top Level
// ObjectPath -> InterfaceMap
// Get each interface of the object

// Interface Map
// Interface -> PropertyMap
// Get each property of the interface

// PropertyMap
// PropertyName -> PropertyValue
// Get each property value of the property name

ManagedObjectType CreateDummyManagedObjectType() {
  return ManagedObjectType({std::make_pair(
      sdbusplus::message::object_path("path"),
      DBusInteracesMap({std::make_pair(
          "interface", DBusPropertiesMap({std::make_pair(
                           "property", DbusVariantType("test_value"))}))}))});
}

// Top Level
// Service to list of interfaces

MapperGetObject CreateDummyMapperGetObject() {
  return MapperGetObject({{"service", {"interface1", "interface2"}}});
}

// Top Level
// Property value

DbusVariantType CreateDummyDbusVariantType() {
  return DbusVariantType("test_value");
}

// Top Level
// PropertyName -> PropertyValue
// Get each property value of the property name

DBusPropertiesMap CreateDummyDBusPropertiesMap() {
  return DBusPropertiesMap(
      {std::make_pair("property", DbusVariantType("test_value"))});
}

// Top Level
// Object path -> MapperServiceMap
// Get the service map of the object path

// MapperServiceMap
// Service -> list of interfaces
// Get the list of interfaces of the service

MapperGetSubTreeResponse CreateDummyMapperGetSubTreeResponse() {
  return MapperGetSubTreeResponse({std::make_pair(
      "path", MapperServiceMap({{"service", {"interface1", "interface2"}}}))});
}

// Top Level
// List of Object Paths

MapperGetSubTreePathsResponse CreateDummyMapperGetSubTreePathsResponse() {
  return MapperGetSubTreePathsResponse({"path1", "path2"});
}

TEST_F(MockManagedStoreTest, CorrectlyUpsertEveryManagedTypeIntoManagedStore) {
  // kManagedProperty
  {
    KeyType key(ManagedType::kManagedProperty, "service",
                sdbusplus::message::object_path("path"), "interface",
                "property");
    std::shared_ptr<ValueType> original_test_value =
        CreateValueType(CreateDummyDbusVariantType());
    EXPECT_TRUE(mock_managed_store_instance_
                    ->upsertMockObjectIntoManagedStore(key, original_test_value)
                    .ok());
  }
  // kManagedObject
  {
    KeyType key(ManagedType::kManagedObject, "service",
                sdbusplus::message::object_path("path"), "interface",
                "property");
    std::shared_ptr<ValueType> original_test_value =
        CreateValueType(CreateDummyManagedObjectType());
    EXPECT_TRUE(mock_managed_store_instance_
                    ->upsertMockObjectIntoManagedStore(key, original_test_value)
                    .ok());
  }
  // kManagedMapperObject
  {
    KeyType key(ManagedType::kManagedMapperObject, "service",
                sdbusplus::message::object_path("path"), "interface",
                "property");
    std::shared_ptr<ValueType> original_test_value =
        CreateValueType(CreateDummyMapperGetObject());
    EXPECT_TRUE(mock_managed_store_instance_
                    ->upsertMockObjectIntoManagedStore(key, original_test_value)
                    .ok());
  }
  // kManagedProperty
  {
    KeyType key(ManagedType::kManagedProperty, "service",
                sdbusplus::message::object_path("path"), "interface",
                "property");
    std::shared_ptr<ValueType> original_test_value =
        CreateValueType(CreateDummyDbusVariantType());
    EXPECT_TRUE(mock_managed_store_instance_
                    ->upsertMockObjectIntoManagedStore(key, original_test_value)
                    .ok());
  }
  // kManagedPropertyMap
  {
    KeyType key(ManagedType::kManagedPropertyMap, "service",
                sdbusplus::message::object_path("path"), "interface",
                "property");
    std::shared_ptr<ValueType> original_test_value =
        CreateValueType(CreateDummyDBusPropertiesMap());
    EXPECT_TRUE(mock_managed_store_instance_
                    ->upsertMockObjectIntoManagedStore(key, original_test_value)
                    .ok());
  }
  // kManagedSubtree
  {
    KeyType key(ManagedType::kManagedSubtree, "path", 9, {"interfaces"});
    std::shared_ptr<ValueType> original_test_value =
        CreateValueType(CreateDummyMapperGetSubTreeResponse());
    EXPECT_TRUE(mock_managed_store_instance_
                    ->upsertMockObjectIntoManagedStore(key, original_test_value)
                    .ok());
  }
  // kManagedSubtreePaths
  {
    KeyType key(ManagedType::kManagedSubtreePaths, "path", 29, {"interfaces"});
    std::shared_ptr<ValueType> original_test_value =
        CreateValueType(CreateDummyMapperGetSubTreePathsResponse());
    EXPECT_TRUE(mock_managed_store_instance_
                    ->upsertMockObjectIntoManagedStore(key, original_test_value)
                    .ok());
  }
}

TEST_F(MockManagedStoreTest, ValidateSuccessfulPostDbusCallWithValue) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();
  const std::vector<DurationType> expected_durations = {{"test_value", 123}};
  EXPECT_CALL(
      *mock_managed_store_instance_,
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(const boost::system::error_code&,
                                     const std::vector<DurationType>&)>&&>(),
          "service", "path", "interface", "method"))
      .Times(1)
      .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction<
                std::vector<DurationType>>::
                    SimulateSuccessfulAsyncPostDbusCallWithValue(
                        std::make_shared<std::vector<DurationType>>(
                            expected_durations)));

  mock_managed_store_instance_->PostDbusCallToIoContextThreadSafe(
      nullptr,
      [async_resp](const boost::system::error_code& ec,
                   const std::vector<DurationType>& duration) {
        if (ec) {
          async_resp->res.jsonValue =
              nlohmann::json::parse(R"({"status": "error"})");
          return;
        }
        async_resp->res.jsonValue["Members"] = duration;
      },
      "service", "path", "interface", "method");

  EXPECT_FALSE(async_resp->res.jsonValue.contains("status"));

  RunIoUntilDone();

  EXPECT_NE(async_resp->res.jsonValue["status"], "error");
  EXPECT_TRUE(async_resp->res.jsonValue.contains("Members"));
  nlohmann::json& members = async_resp->res.jsonValue["Members"];
  EXPECT_EQ(members.size(), 1);
  size_t index = 0;
  for (nlohmann::json& member : members) {
    EXPECT_EQ(member, expected_durations[index++]);
  }
}

TEST_F(MockManagedStoreTest, ValidateFailedPostDbusCallWithValue) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();
  EXPECT_CALL(
      *mock_managed_store_instance_,
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(const boost::system::error_code&,
                                     const std::vector<DurationType>&)>&&>(),
          "service", "path", "interface", "method"))
      .Times(1)
      .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction::
                    SimulateFailedAsyncPostDbusCallWithEmptyValue());

  mock_managed_store_instance_->PostDbusCallToIoContextThreadSafe(
      nullptr,
      [async_resp](const boost::system::error_code& ec,
                   const std::vector<DurationType>& duration) {
        if (ec) {
          async_resp->res.jsonValue =
              nlohmann::json::parse(R"({"status": "error"})");
          async_resp->res.jsonValue["Members"] = duration;
          return;
        }
      },
      "service", "path", "interface", "method");

  EXPECT_FALSE(async_resp->res.jsonValue.contains("status"));

  RunIoUntilDone();

  EXPECT_EQ(async_resp->res.jsonValue["status"], "error");
  EXPECT_TRUE(async_resp->res.jsonValue.contains("Members"));
  EXPECT_TRUE(async_resp->res.jsonValue["Members"].empty());
}

TEST_F(MockManagedStoreTest,
       ValidateSuccessfulPostDbusCallForGetRequestsWithValue) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();
  const std::vector<DurationType> expected_durations = {{"test_value", 123}};
  EXPECT_CALL(
      *mock_managed_store_instance_,
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(const boost::system::error_code&,
                                     const std::vector<DurationType>&)>&&>(),
          "service", "path", "interface", "method"))
      .Times(1)
      .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction<
                std::vector<DurationType>>::
                    SimulateSuccessfulAsyncPostDbusCallWithValue(
                        std::make_shared<std::vector<DurationType>>(
                            expected_durations)));

  mock_managed_store_instance_->PostDbusCallToIoContextThreadSafe(
      nullptr,
      [async_resp](const boost::system::error_code& ec,
                   const std::vector<DurationType>& duration) {
        if (ec) {
          async_resp->res.jsonValue =
              nlohmann::json::parse(R"({"status": "error"})");
          return;
        }
        async_resp->res.jsonValue["Members"] = duration;
      },
      "service", "path", "interface", "method");

  EXPECT_FALSE(async_resp->res.jsonValue.contains("status"));

  RunIoUntilDone();

  EXPECT_NE(async_resp->res.jsonValue["status"], "error");
  EXPECT_TRUE(async_resp->res.jsonValue.contains("Members"));
  nlohmann::json& members = async_resp->res.jsonValue["Members"];
  EXPECT_EQ(members.size(), 1);
  size_t index = 0;
  for (nlohmann::json& member : members) {
    EXPECT_EQ(member, expected_durations[index++]);
  }
}

TEST_F(MockManagedStoreTest,
       ValidateFailedPostDbusCallForGetRequestsWithValue) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();
  boost::system::error_code io_error =
      boost::system::errc::make_error_code(boost::system::errc::io_error);
  EXPECT_CALL(
      *mock_managed_store_instance_,
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(const boost::system::error_code&,
                                     const std::vector<DurationType>&)>&&>(),
          "service", "path", "interface", "method"))
      .Times(1)
      .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction::
                    SimulateFailedAsyncPostDbusCallWithEmptyValue(io_error));

  mock_managed_store_instance_->PostDbusCallToIoContextThreadSafe(
      nullptr,
      [async_resp](const boost::system::error_code& ec,
                   const std::vector<DurationType>& duration) {
        if (ec) {
          async_resp->res.jsonValue["status"] = ec.value();
          async_resp->res.jsonValue["Members"] = duration;
          return;
        }
      },
      "service", "path", "interface", "method");

  EXPECT_FALSE(async_resp->res.jsonValue.contains("status"));

  RunIoUntilDone();

  EXPECT_EQ(async_resp->res.jsonValue["status"], io_error.value());
  EXPECT_TRUE(async_resp->res.jsonValue.contains("Members"));
  EXPECT_TRUE(async_resp->res.jsonValue["Members"].empty());
}

TEST_F(MockManagedStoreTest, ValidateGetSubTreePathsResponseWithUpsert) {
  KeyType key(ManagedType::kManagedSubtreePaths, "path", 0, {"interfaces"});
  std::vector<std::string> insert_paths = {"path1", "path2"};
  std::shared_ptr<ValueType> original_test_value =
      CreateValueType(std::move(insert_paths));

  EXPECT_TRUE(mock_managed_store_instance_
                  ->upsertMockObjectIntoManagedStore(key, original_test_value)
                  .ok());

  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();
  managedStore::ManagedObjectStoreContext context(async_resp);
  std::vector<std::string> response_paths;
  bool is_error = false;
  mock_managed_store_instance_->getSubTreePaths(
      "path", 0, {{"interfaces"}}, context,
      [&is_error, &response_paths](const boost::system::error_code& ec,
                                   const std::vector<std::string>& paths) {
        if (ec) {
          is_error = true;
          return;
        }
        response_paths = paths;
      });

  RunIoUntilDone();

  EXPECT_FALSE(is_error);
  EXPECT_THAT(response_paths, ElementsAre("path1", "path2"));
}

TEST_F(MockManagedStoreTest, ValidateFailedGetSubTreePathsResponse) {
  KeyType key(ManagedType::kManagedSubtreePaths, "path", 0, {"interfaces"});
  std::vector<std::string> insert_paths = {"path1", "path2"};
  std::shared_ptr<ValueType> original_test_value = CreateErrorValueType(
      insert_paths, boost::system::error_code(boost::asio::error::not_found));

  EXPECT_TRUE(mock_managed_store_instance_
                  ->upsertMockObjectIntoManagedStore(key, original_test_value)
                  .ok());

  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();
  managedStore::ManagedObjectStoreContext context(async_resp);
  std::vector<std::string> response_paths;
  bool is_error = false;
  mock_managed_store_instance_->getSubTreePaths(
      "path", 0, {{"interfaces"}}, context,
      [&is_error, &response_paths](const boost::system::error_code& ec,
                                   const std::vector<std::string>& paths) {
        if (ec) {
          is_error = true;
          return;
        }
        response_paths = paths;
      });

  RunIoUntilDone();

  EXPECT_TRUE(is_error);
  EXPECT_TRUE(response_paths.empty());
}

TEST_F(MockManagedStoreTest, MissingEntryInManagedStoreReturnsError) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();
  managedStore::ManagedObjectStoreContext context(async_resp);
  std::vector<std::string> response_paths;
  bool is_error = false;
  mock_managed_store_instance_->getSubTreePaths(
      "path", 0, {{"interfaces"}}, context,
      [&is_error, &response_paths](const boost::system::error_code& ec,
                                   const std::vector<std::string>& paths) {
        if (ec) {
          is_error = true;
          return;
        }
        response_paths = paths;
      });

  RunIoUntilDone();

  EXPECT_TRUE(is_error);
  EXPECT_TRUE(response_paths.empty());
}

TEST_F(MockManagedStoreTest, ValidateFailedPostDbusCallWithExactError) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();
  EXPECT_CALL(
      *mock_managed_store_instance_,
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(const boost::system::error_code&,
                                     const std::vector<DurationType>&)>&&>(),
          "service", "path", "interface", "method"))
      .Times(1)
      .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction::
                    SimulateFailedAsyncPostDbusCallWithEmptyValue(
                        boost::system::errc::make_error_code(
                            boost::system::errc::io_error)));

  mock_managed_store_instance_->PostDbusCallToIoContextThreadSafe(
      nullptr,
      [async_resp](const boost::system::error_code& ec,
                   const std::vector<DurationType>& duration) {
        if (ec) {
          if (ec == boost::system::errc::io_error) {
            async_resp->res.jsonValue =
                nlohmann::json::parse(R"({"status": "io_error"})");
          } else {
            async_resp->res.jsonValue =
                nlohmann::json::parse(R"({"status": "error"})");
          }
          async_resp->res.jsonValue["Members"] = duration;
          return;
        }
      },
      "service", "path", "interface", "method");

  RunIoUntilDone();

  EXPECT_EQ(async_resp->res.jsonValue["status"], "io_error");
  EXPECT_TRUE(async_resp->res.jsonValue.contains("Members"));
  EXPECT_TRUE(async_resp->res.jsonValue["Members"].empty());
}

TEST_F(MockManagedStoreTest,
       ValidateFailedPostDbusCallWithExactMessageAndError) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();
  sdbusplus::message_t expected_msg = sdbusplus::message_t();
  EXPECT_CALL(
      *mock_managed_store_instance_,
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(const boost::system::error_code&,
                                     const sdbusplus::message_t&,
                                     const sdbusplus::message::unix_fd&)>&&>(),
          "service", "path", "interface", "method", "arg"))
      .Times(1)
      .WillOnce(
          SimulateFailedAsyncPostDbusCallThreadSafeWithMsgAndEmptyValueAction::
              SimulateFailedAsyncPostDbusCallWithMsgAndEmptyValue(
                  expected_msg, boost::system::errc::make_error_code(
                                    boost::system::errc::io_error)));
  mock_managed_store_instance_->PostDbusCallToIoContextThreadSafe(
      nullptr,
      [async_resp, expected_msg](const boost::system::error_code& ec,
                                 const sdbusplus::message_t& msg,
                                 const sdbusplus::message::unix_fd& /*fd*/) {
        if (ec) {
          if (ec == boost::system::errc::io_error && msg.is_method_error()) {
            async_resp->res.jsonValue =
                nlohmann::json::parse(R"({"status": "io_error"})");
          } else {
            async_resp->res.jsonValue =
                nlohmann::json::parse(R"({"status": "error"})");
          }
          return;
        }
      },
      "service", "path", "interface", "method", "arg");

  RunIoUntilDone();

  EXPECT_EQ(async_resp->res.jsonValue["status"], "io_error");
  EXPECT_TRUE(async_resp->res.jsonValue["Members"].empty());
}

TEST_F(
    MockManagedStoreTest,
    ValidateFailedPostDbusCallWithStringRetMsgAndFdWithExactMessageAndError) {
  std::shared_ptr<bmcweb::AsyncResp> async_resp =
      std::make_shared<bmcweb::AsyncResp>();
  sdbusplus::message_t expected_msg = sdbusplus::message_t();
  EXPECT_CALL(
      *mock_managed_store_instance_,
      PostDbusCallWithStringRetMsgAndFd(
          _,
          An<absl::AnyInvocable<void(const boost::system::error_code&,
                                     const sdbusplus::message_t&,
                                     const sdbusplus::message::unix_fd&)>&&>(),
          "service", "path", "interface", "method", "arg"))
      .Times(1)
      .WillOnce(
          SimulateFailedAsyncPostDbusCallThreadSafeWithMsgAndEmptyValueAction::
              SimulateFailedAsyncPostDbusCallWithMsgAndEmptyValue(
                  expected_msg, boost::system::errc::make_error_code(
                                    boost::system::errc::io_error)));
  mock_managed_store_instance_->PostDbusCallWithStringRetMsgAndFd(
      nullptr,
      [async_resp, expected_msg](const boost::system::error_code& ec,
                                 const sdbusplus::message_t& msg,
                                 const sdbusplus::message::unix_fd& /*fd*/) {
        if (ec) {
          if (ec == boost::system::errc::io_error && msg.is_method_error()) {
            async_resp->res.jsonValue =
                nlohmann::json::parse(R"({"status": "io_error"})");
          } else {
            async_resp->res.jsonValue =
                nlohmann::json::parse(R"({"status": "error"})");
          }
          return;
        }
      },
      "service", "path", "interface", "method", "arg");

  RunIoUntilDone();

  EXPECT_EQ(async_resp->res.jsonValue["status"], "io_error");
  EXPECT_TRUE(async_resp->res.jsonValue["Members"].empty());
}
}  // namespace
}  // namespace managedStore
