blob: 196e816ac9a55396b5748cab61838b3fc9ef9a75 [file] [log] [blame]
#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