#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 "nlohmann/json.hpp"
#include "dbus_utility.hpp" // NOLINT
#include "async_resp.hpp" // NOLINT
#include "http_request.hpp" // NOLINT
#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(*managedStore::GetManagedObjectStore(),
              setProperty("service", "path", "interface", "property",
                          dbus::utility::DbusVariantType{"bad_command"}, _))
      .Times(1)
      .WillOnce(SimulateFailedAsyncSetPropertyDbusCallAction::
                    SimulateFailedAsyncSetPropertyDbusCall(io_error));

  managedStore::GetManagedObjectStore()->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(*managedStore::GetManagedObjectStore(),
              setProperty("service", "path", "interface", "property",
                          dbus::utility::DbusVariantType{"good_command"}, _))
      .Times(1)
      .WillOnce(SimulateSuccessfulAsyncSetPropertyDbusCallAction::
                    SimulateSuccessfulAsyncSetPropertyDbusCall());

  managedStore::GetManagedObjectStore()->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(
      *managedStore::GetManagedObjectStore(),
      PostDbusCallToIoContextThreadSafe(
          _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
          "service", "path", "interface", "method"))
      .Times(1)
      .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeAction::
                    SimulateSuccessfulAsyncPostDbusCall());

  managedStore::GetManagedObjectStore()->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(
      *managedStore::GetManagedObjectStore(),
      PostDbusCallToIoContextThreadSafe(
          _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
          "service", "path", "interface", "method"))
      .Times(1)
      .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeAction::
                    SimulateFailedAsyncPostDbusCall());

  managedStore::GetManagedObjectStore()->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(managedStore::GetManagedObjectStore()
                   ->getMockObjectFromManagedStore(key)
                   .ok());
  EXPECT_TRUE(managedStore::GetManagedObjectStore()
                  ->upsertMockObjectIntoManagedStore(key, original_test_value)
                  .ok());

  absl::StatusOr<std::shared_ptr<ValueType>> obtained_test_value =
      managedStore::GetManagedObjectStore()->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(managedStore::GetManagedObjectStore()
                  ->upsertMockObjectIntoManagedStore(key, original_test_value)
                  .ok());

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

  absl::StatusOr<std::shared_ptr<ValueType>> obtained_test_value =
      managedStore::GetManagedObjectStore()->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(managedStore::GetManagedObjectStore()
                  ->upsertMockObjectIntoManagedStore(key, original_test_value)
                  .ok());

  EXPECT_TRUE(managedStore::GetManagedObjectStore()
                  ->evictMockObjectFromManagedStore(key)
                  .ok());

  EXPECT_FALSE(managedStore::GetManagedObjectStore()
                   ->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(managedStore::GetManagedObjectStore()
                   ->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(managedStore::GetManagedObjectStore()
                    ->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(managedStore::GetManagedObjectStore()
                    ->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(managedStore::GetManagedObjectStore()
                    ->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(managedStore::GetManagedObjectStore()
                    ->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(managedStore::GetManagedObjectStore()
                    ->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(managedStore::GetManagedObjectStore()
                    ->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(managedStore::GetManagedObjectStore()
                    ->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(
      *managedStore::GetManagedObjectStore(),
      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)));

  managedStore::GetManagedObjectStore()->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(
      *managedStore::GetManagedObjectStore(),
      PostDbusCallToIoContextThreadSafe(
          _,
          An<absl::AnyInvocable<void(const boost::system::error_code&,
                                     const std::vector<DurationType>&)>&&>(),
          "service", "path", "interface", "method"))
      .Times(1)
      .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction::
                    SimulateFailedAsyncPostDbusCallWithEmptyValue());

  managedStore::GetManagedObjectStore()->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(
      *managedStore::GetManagedObjectStore(),
      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)));

  managedStore::GetManagedObjectStore()->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(
      *managedStore::GetManagedObjectStore(),
      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));

  managedStore::GetManagedObjectStore()->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(managedStore::GetManagedObjectStore()
                  ->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;
  managedStore::GetManagedObjectStore()->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(managedStore::GetManagedObjectStore()
                  ->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;
  managedStore::GetManagedObjectStore()->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;
  managedStore::GetManagedObjectStore()->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(
      *managedStore::GetManagedObjectStore(),
      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)));

  managedStore::GetManagedObjectStore()->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(
      *managedStore::GetManagedObjectStore(),
      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)));
  managedStore::GetManagedObjectStore()->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());
}
}  // namespace
}  // namespace managedStore
