blob: bcd042b64bc382f5b5adaa9a7d63b029f0deb474 [file]
#include "storage.hpp"
#include <systemd/sd-bus.h>
#include <cerrno>
#include <filesystem>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/functional/any_invocable.h"
#include "boost/asio/error.hpp" // NOLINT
#include "boost/beast/core/string_type.hpp" // NOLINT
#include "boost/beast/http/message.hpp" // NOLINT
#include "boost/beast/http/status.hpp" // NOLINT
#include "boost/system/detail/error_code.hpp" // NOLINT
#include "boost/system/error_code.hpp" // NOLINT
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "storage_utils.hpp"
#include "test/redfish-core/lib/snapshot_fixture.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "test/g3/mock_managed_store.hpp"
#include "test/g3/mock_managed_store_test.hpp"
#include "sdbusplus/message.hpp"
#include "sdbusplus/message/native_types.hpp"
#include "sdbusplus/test/sdbus_mock.hpp"
namespace redfish {
namespace {
using ::managedStore::KeyType;
using ::managedStore::ManagedType;
using ::managedStore::
SimulateFailedAsyncPostDbusCallThreadSafeWithMsgAndEmptyValueAction;
using ::managedStore::SimulateFailedAsyncSetPropertyDbusCallAction;
using ::managedStore::SimulateSuccessfulAsyncSetPropertyDbusCallAction;
using ::managedStore::ValueType;
using ::testing::_;
using ::testing::An;
class StorageSnapshotFixture : public SnapshotFixture {
protected:
dbus::utility::MapperGetSubTreeResponse subtree = {
{"/drive_0", {{"connection", {}}}},
{"/drive_1", {}},
};
std::string path = "/xyz/openbmc_project/inventory/Board/device_1";
std::string connection = "xyz.test";
};
TEST_F(StorageSnapshotFixture, SetResetTypeOk) {
EXPECT_CALL(
*dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore()),
setProperty(_, _, "xyz.openbmc_project.State.Drive",
"RequestedDriveTransition", std::string("PowerCycle"), _))
.Times(1)
.WillOnce(SimulateSuccessfulAsyncSetPropertyDbusCallAction::
SimulateSuccessfulAsyncSetPropertyDbusCall());
setResetType(share_async_resp_, "drive_0", "PowerCycle", subtree);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}
TEST_F(StorageSnapshotFixture, SetResetTypeFailed) {
EXPECT_CALL(
*dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore()),
setProperty(_, _, "xyz.openbmc_project.State.Drive",
"RequestedDriveTransition", std::string("PowerCycle"), _))
.Times(1)
.WillOnce(SimulateFailedAsyncSetPropertyDbusCallAction::
SimulateFailedAsyncSetPropertyDbusCall());
setResetType(share_async_resp_, "drive_0", "PowerCycle", subtree);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::internal_server_error);
}
TEST_F(StorageSnapshotFixture, SetResetTypeInvalidDriveId) {
setResetType(share_async_resp_, "drive_2", "PowerCycle", subtree);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::not_found);
}
TEST_F(StorageSnapshotFixture, SetResetTypeInvalidConnection) {
setResetType(share_async_resp_, "drive_1", "PowerCycle", subtree);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::internal_server_error);
}
TEST_F(StorageSnapshotFixture, DriveServiceLabelOnlyResponse) {
auto response = std::make_shared<bmcweb::AsyncResp>();
nlohmann::json& json = response->res.jsonValue;
/* Mock the Drive object*/
std::vector<std::string> interfaces = {
storage_utils::driveInterface,
"xyz.openbmc_project.Inventory.Decorator.LocationCode",
};
// Insert interfaces getObject call
KeyType locationTypeKey(ManagedType::kManagedMapperObject, path, {});
dbus::utility::MapperGetObject locationTypeValue{{connection, interfaces}};
std::shared_ptr<ValueType> mockLocationType =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(locationTypeValue));
ASSERT_TRUE(
dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(locationTypeKey, mockLocationType)
.ok());
// Insert service label
std::string serviceLabel = "X2";
KeyType key(ManagedType::kManagedProperty, connection,
sdbusplus::message::object_path(path),
"xyz.openbmc_project.Inventory.Decorator.LocationCode",
"LocationCode");
std::shared_ptr<ValueType> mockServiceLabel =
managedStore::MockManagedStoreTest::CreateValueType(serviceLabel);
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(key, mockServiceLabel)
.ok());
/* Mock an empty Drive assocation */
KeyType getAssociatedSubTreeKey(ManagedType::kManagedAssociatedSubtree,
path + "/chassis",
"/xyz/openbmc_project/inventory", 0,
{"xyz.openbmc_project.Inventory.Item.Board"});
dbus::utility::MapperGetSubTreeResponse subtree = {};
std::shared_ptr<ValueType> mockSubtree =
managedStore::MockManagedStoreTest::CreateValueType(std::move(subtree));
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(getAssociatedSubTreeKey,
mockSubtree)
.ok());
addAllDriveInfo(response, "", connection, path, interfaces, "");
RunIoUntilDone();
EXPECT_EQ(json["PhysicalLocation"]["PartLocation"]["ServiceLabel"],
serviceLabel);
EXPECT_EQ(json["PhysicalLocation"]["PartLocation"]["LocationType"], nullptr);
EXPECT_EQ(json["PhysicalLocation"]["PartLocationContext"],
"PlaceHolderAndShouldNotBeUsed");
EXPECT_EQ(json["PhysicalLocation"]["Oem"]["Google"]["Devpath"], "/phys");
}
TEST_F(StorageSnapshotFixture, DriveServiceLabelAndTypeResponse) {
auto response = std::make_shared<bmcweb::AsyncResp>();
nlohmann::json& json = response->res.jsonValue;
/* Mock the Drive object*/
std::vector<std::string> interfaces = {
storage_utils::driveInterface,
"xyz.openbmc_project.Inventory.Decorator.LocationCode",
"xyz.openbmc_project.Inventory.Connector.Embedded",
};
// Insert interfaces getObject call
KeyType locationTypeKey(ManagedType::kManagedMapperObject, path, {});
dbus::utility::MapperGetObject locationTypeValue{{connection, interfaces}};
std::shared_ptr<ValueType> mockLocationType =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(locationTypeValue));
ASSERT_TRUE(
dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(locationTypeKey, mockLocationType)
.ok());
std::string serviceLabel = "X2";
KeyType key(ManagedType::kManagedProperty, connection,
sdbusplus::message::object_path(path),
"xyz.openbmc_project.Inventory.Decorator.LocationCode",
"LocationCode");
std::shared_ptr<ValueType> mockServiceLabel =
managedStore::MockManagedStoreTest::CreateValueType(serviceLabel);
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(key, mockServiceLabel)
.ok());
/* Mock an empty Drive assocation */
KeyType getAssociatedSubTreeKey(ManagedType::kManagedAssociatedSubtree,
path + "/chassis",
"/xyz/openbmc_project/inventory", 0,
{"xyz.openbmc_project.Inventory.Item.Board"});
dbus::utility::MapperGetSubTreeResponse subtree = {};
std::shared_ptr<ValueType> mockSubtree =
managedStore::MockManagedStoreTest::CreateValueType(std::move(subtree));
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(getAssociatedSubTreeKey,
mockSubtree)
.ok());
addAllDriveInfo(response, "", connection, path, interfaces, "");
RunIoUntilDone();
EXPECT_EQ(json["PhysicalLocation"]["PartLocation"]["ServiceLabel"], "X2");
EXPECT_EQ(json["PhysicalLocation"]["PartLocation"]["LocationType"],
"Embedded");
EXPECT_EQ(json["PhysicalLocation"]["PartLocationContext"],
"PlaceHolderAndShouldNotBeUsed");
EXPECT_EQ(json["PhysicalLocation"]["Oem"]["Google"]["Devpath"],
"/phys:device:X2");
}
/**
* @brief: Mock a parent object that containing the target object
* @param[in] objectPath the current object path
* @param[in] objectType the current object type presented as dbus
interface
* @param[in] parentConnection service name for the parent object
* @param[in] parentPath parent object path; return empty list on empty
string
* @param[in] parentType parent type present as dbus interace
* @param[in] serviceLabel parent service_label/location_code property;
return
* ec on dbus read when empty string
*/
void mockParent(const std::string& objectPath, const std::string& objectType,
const std::string& parentConnection,
const std::string& parentPath, const std::string& parentType,
const std::string& serviceLabel,
const std::string& locationType = "Slot") {
// define the assocation tags
std::string forwardTag = "contained_by";
std::string backwardTag = "containing";
if (objectType == storage_utils::driveInterface &&
parentType == storage_utils::chassisInterface) {
forwardTag = "chassis";
backwardTag = "drive";
} else if (objectType == storage_utils::storageInterface &&
parentType == storage_utils::driveInterface) {
forwardTag = "drive";
backwardTag = "storage";
} else if (objectType == storage_utils::controllerInterface &&
parentType == storage_utils::storageInterface) {
forwardTag = "storage";
backwardTag = "storage_controller";
} else if (objectType == storage_utils::volumeInterface &&
parentType == storage_utils::storageInterface) {
forwardTag = "contained";
backwardTag = "containing";
}
// insert assocation mock
KeyType getAssociatedSubTreeKey(
ManagedType::kManagedAssociatedSubtree,
(std::filesystem::path(objectPath) / forwardTag).string(),
"/xyz/openbmc_project/inventory", 0, {parentType});
dbus::utility::MapperGetSubTreeResponse subtree =
parentPath.empty() ? dbus::utility::MapperGetSubTreeResponse{}
: dbus::utility::MapperGetSubTreeResponse{
{parentPath,
{{parentConnection,
{parentType,
{"xyz.openbmc_project.Inventory.Decorator."
"LocationCode"}}}}},
};
std::shared_ptr<ValueType> mockSubtree =
managedStore::MockManagedStoreTest::CreateValueType(std::move(subtree));
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(getAssociatedSubTreeKey,
mockSubtree)
.ok());
// insert service label mock
KeyType parentLocationKey(
ManagedType::kManagedProperty, parentConnection,
sdbusplus::message::object_path(parentPath),
"xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode");
std::shared_ptr<ValueType> mockServiceLabel =
serviceLabel.empty()
? managedStore::MockManagedStoreTest::CreateErrorValueType(
serviceLabel,
boost::system::error_code(boost::asio::error::not_found))
: managedStore::MockManagedStoreTest::CreateValueType(serviceLabel);
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(parentLocationKey,
mockServiceLabel)
.ok());
// insert location type mock
KeyType parentLocationTypeKey(ManagedType::kManagedMapperObject, parentPath,
{});
dbus::utility::MapperGetObject parentLocationTypeValue{
{parentConnection,
{{"xyz.openbmc_project.Inventory.Decorator.LocationCode"},
std::string{"xyz.openbmc_project.Inventory.Connector."} +
locationType}}};
std::shared_ptr<ValueType> mockLocationType =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(parentLocationTypeValue));
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(parentLocationTypeKey,
mockLocationType)
.ok());
}
TEST_F(StorageSnapshotFixture, DriveLocationContextOnlyResponse) {
auto response = std::make_shared<bmcweb::AsyncResp>();
nlohmann::json& json = response->res.jsonValue;
std::vector<std::string> interfaces = {
storage_utils::driveInterface,
};
// Insert interfaces getObject call
KeyType locationTypeKey(ManagedType::kManagedMapperObject, path, {});
dbus::utility::MapperGetObject locationTypeValue{{connection, interfaces}};
std::shared_ptr<ValueType> mockLocationType =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(locationTypeValue));
ASSERT_TRUE(
dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(locationTypeKey, mockLocationType)
.ok());
// Parent of Drive
mockParent(path, storage_utils::driveInterface, "test.chassis.0",
"/xyz/openbmc_project/inventory/Board/chassis_0",
storage_utils::chassisInterface, "C");
// Parent of Chassis0
mockParent("/xyz/openbmc_project/inventory/Board/chassis_0",
storage_utils::chassisInterface, "test.chassis.1",
"/xyz/openbmc_project/inventory/Board/chassis_1",
storage_utils::chassisInterface, "A");
// Parent of Chassis1
mockParent("/xyz/openbmc_project/inventory/Board/chassis_1",
storage_utils::chassisInterface, "test.chassis.2",
"/xyz/openbmc_project/inventory/Board/chassis_2",
storage_utils::chassisInterface, "B");
// Mock empty parents of Chassis2
mockParent("/xyz/openbmc_project/inventory/Board/chassis_2",
storage_utils::chassisInterface, "", "",
storage_utils::chassisInterface, "");
addAllDriveInfo(response, "", connection, path, interfaces, "");
RunIoUntilDone();
EXPECT_EQ(json["PhysicalLocation"]["PartLocation"]["ServiceLabel"], nullptr);
EXPECT_EQ(json["PhysicalLocation"]["PartLocation"]["LocationType"], nullptr);
EXPECT_EQ(json["PhysicalLocation"]["PartLocationContext"],
"PlaceHolderAndShouldNotBeUsed");
EXPECT_EQ(json["PhysicalLocation"]["Oem"]["Google"]["Devpath"],
"/phys/B/A/C");
}
TEST_F(StorageSnapshotFixture, DriveAllLocationResponse) {
auto response = std::make_shared<bmcweb::AsyncResp>();
nlohmann::json& json = response->res.jsonValue;
std::vector<std::string> interfaces = {
storage_utils::driveInterface,
"xyz.openbmc_project.Inventory.Decorator.LocationCode",
"xyz.openbmc_project.Inventory.Connector.Embedded",
};
// Insert interfaces getObject call
KeyType locationTypeKey(ManagedType::kManagedMapperObject, path, {});
dbus::utility::MapperGetObject locationTypeValue{{connection, interfaces}};
std::shared_ptr<ValueType> mockLocationType =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(locationTypeValue));
ASSERT_TRUE(
dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(locationTypeKey, mockLocationType)
.ok());
std::string serviceLabel = "X2";
KeyType key(ManagedType::kManagedProperty, connection,
sdbusplus::message::object_path(path),
"xyz.openbmc_project.Inventory.Decorator.LocationCode",
"LocationCode");
std::shared_ptr<ValueType> mockServiceLabel =
managedStore::MockManagedStoreTest::CreateValueType(serviceLabel);
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(key, mockServiceLabel)
.ok());
// Parent of Drive
mockParent(path, storage_utils::driveInterface, "test.chassis.0",
"/xyz/openbmc_project/inventory/Board/chassis_0",
storage_utils::chassisInterface, "C");
// Parent of Chassis0
mockParent("/xyz/openbmc_project/inventory/Board/chassis_0",
storage_utils::chassisInterface, "test.chassis.1",
"/xyz/openbmc_project/inventory/Board/chassis_1",
storage_utils::chassisInterface, "A");
// Parent of Chassis1
mockParent("/xyz/openbmc_project/inventory/Board/chassis_1",
storage_utils::chassisInterface, "test.chassis.2",
"/xyz/openbmc_project/inventory/Board/chassis_2",
storage_utils::chassisInterface, "B");
// Mock empty parents of Chassis2
mockParent("/xyz/openbmc_project/inventory/Board/chassis_2",
storage_utils::chassisInterface, "", "",
storage_utils::chassisInterface, "");
addAllDriveInfo(response, "", connection, path, interfaces, "");
RunIoUntilDone();
EXPECT_EQ(json["PhysicalLocation"]["PartLocation"]["ServiceLabel"], "X2");
EXPECT_EQ(json["PhysicalLocation"]["PartLocation"]["LocationType"],
"Embedded");
EXPECT_EQ(json["PhysicalLocation"]["PartLocationContext"],
"PlaceHolderAndShouldNotBeUsed");
EXPECT_EQ(json["PhysicalLocation"]["Oem"]["Google"]["Devpath"],
"/phys/B/A/C:device:X2");
}
TEST_F(StorageSnapshotFixture, StorageControllerAllLocationResponse) {
auto response = std::make_shared<bmcweb::AsyncResp>();
nlohmann::json& json = response->res.jsonValue;
/* Mock a physical controller with LocationCode/LocationType */
std::vector<std::string> interfaces = {
storage_utils::controllerInterface,
"xyz.openbmc_project.Inventory.Decorator.LocationCode",
"xyz.openbmc_project.Inventory.Connector.Embedded",
};
// Insert interfaces getObject call
KeyType locationTypeKey(ManagedType::kManagedMapperObject,
path + "/storage_controller_0", {});
dbus::utility::MapperGetObject locationTypeValue{{connection, interfaces}};
std::shared_ptr<ValueType> mockLocationType =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(locationTypeValue));
ASSERT_TRUE(
dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(locationTypeKey, mockLocationType)
.ok());
std::string serviceLabel = "X2";
KeyType key(ManagedType::kManagedProperty, connection,
sdbusplus::message::object_path(path) / "storage_controller_0",
"xyz.openbmc_project.Inventory.Decorator.LocationCode",
"LocationCode");
std::shared_ptr<ValueType> mockServiceLabel =
managedStore::MockManagedStoreTest::CreateValueType(serviceLabel);
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(key, mockServiceLabel)
.ok());
// Parent of Storage Controller
mockParent(path + "/storage_controller_0", storage_utils::controllerInterface,
"test.storage.0", path + "/storage_0",
storage_utils::storageInterface, "Storage");
// Parent of Storage
mockParent(path + "/storage_0", storage_utils::storageInterface,
"test.drive.0", path + "/drive_0", storage_utils::driveInterface,
"Drive");
// Parent of Drive
mockParent(path + "/drive_0", storage_utils::driveInterface, "test.chassis.0",
path, storage_utils::chassisInterface, "C");
// Parent of Chassis0
mockParent(path, storage_utils::chassisInterface, "test.chassis.1",
"/xyz/openbmc_project/inventory/Board/chassis_1",
storage_utils::chassisInterface, "A");
// Parent of Chassis1
mockParent("/xyz/openbmc_project/inventory/Board/chassis_1",
storage_utils::chassisInterface, "test.chassis.2",
"/xyz/openbmc_project/inventory/Board/chassis_2",
storage_utils::chassisInterface, "B");
// Mock empty parents of Chassis2
mockParent("/xyz/openbmc_project/inventory/Board/chassis_2",
storage_utils::chassisInterface, "", "",
storage_utils::chassisInterface, "");
storage_utils::tryGetLocation(response, connection,
path + "/storage_controller_0",
storage_utils::controllerInterface, interfaces);
RunIoUntilDone();
EXPECT_EQ(json["Location"]["PartLocation"]["ServiceLabel"], "X2");
EXPECT_EQ(json["Location"]["PartLocation"]["LocationType"], "Embedded");
EXPECT_EQ(json["Location"]["PartLocationContext"],
"PlaceHolderAndShouldNotBeUsed");
// storage should not be part of the location info
EXPECT_EQ(json["Location"]["Oem"]["Google"]["Devpath"],
"/phys/B/A/C/Drive:device:X2");
// None-NVMe controller should have no logic tag
EXPECT_EQ(json["Location"]["Oem"]["Google"]["EmbeddedLocationContext"],
nullptr);
json.clear();
/* Mock a logical NVMe controller w/o LocationType */
interfaces = {storage_utils::controllerInterface,
"xyz.openbmc_project.Inventory.Decorator.LocationCode",
"xyz.openbmc_project.NVMe.MetricStore"};
// Insert interfaces getObject call
dbus::utility::MapperGetObject locationTypeValue2{{connection, interfaces}};
std::shared_ptr<ValueType> mockLocationType2 =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(locationTypeValue2));
ASSERT_TRUE(
dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(locationTypeKey, mockLocationType2)
.ok());
storage_utils::tryGetLocation(response, connection,
path + "/storage_controller_0",
storage_utils::controllerInterface, interfaces);
RunIoUntilDone();
EXPECT_EQ(json["Location"]["PartLocation"]["ServiceLabel"], "X2");
EXPECT_EQ(json["Location"]["PartLocation"]["LocationType"], nullptr);
EXPECT_EQ(json["Location"]["PartLocationContext"],
"PlaceHolderAndShouldNotBeUsed");
// storage should not be part of the devpath
EXPECT_EQ(json["Location"]["Oem"]["Google"]["Devpath"], "/phys/B/A/C/Drive");
// NVMe controller should have logic tag
EXPECT_EQ(json["Location"]["Oem"]["Google"]["EmbeddedLocationContext"],
"controller:storage_controller_0");
}
void mockStorageObject(std::string storageName, std::string& storagePath) {
storagePath = "/xyz/openbmc_project/inventory/system/board/ParentStorage/" +
storageName;
KeyType key(ManagedType::kManagedSubtree, "/xyz/openbmc_project/inventory", 0,
{"xyz.openbmc_project.Inventory.Item.Storage"});
dbus::utility::MapperGetSubTreeResponse mockSubtreeResponse{
{storagePath,
{{"xyz.openbmc_project.NVMe",
std::vector<std::string>{
"xyz.openbmc_project.Nvme.Storage",
"xyz.openbmc_project.Inventory.Item.Storage"}}}}};
std::shared_ptr<ValueType> subtree =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(mockSubtreeResponse));
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(key, subtree)
.ok());
KeyType key2(ManagedType::kManagedAssociatedSubtreePaths,
storagePath + "/contained_by", "/xyz/openbmc_project/inventory",
0, {"xyz.openbmc_project.Inventory.Item.System"});
std::vector<std::string> system({}); // empty means system
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
key2, managedStore::MockManagedStoreTest::CreateValueType(
std::move(system)))
.ok());
}
void addVolumeToMockStorage(std::string storagePath, std::string volumeName,
std::string& volumePath,
bool includeMetricStore = true) {
std::vector<std::string> volIfaces(
{"xyz.openbmc_project.Inventory.Item.Volume",
"xyz.openbmc_project.Nvme.Volume"});
if (includeMetricStore) {
volIfaces.push_back("xyz.openbmc_project.NVMe.MetricStore");
}
volumePath = storagePath + "/volumes/" + volumeName;
KeyType getAssociatedSubTreeKey(
ManagedType::kManagedAssociatedSubtree, storagePath + "/containing",
"/xyz/openbmc_project/inventory", 0,
{"xyz.openbmc_project.Inventory.Item.Volume"});
dbus::utility::MapperGetSubTreeResponse mockSubtreeResponse{
{volumePath, {{"xyz.openbmc_project.NVMe", volIfaces}}}};
std::shared_ptr<ValueType> subtree =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(mockSubtreeResponse));
ASSERT_TRUE(
dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(getAssociatedSubTreeKey, subtree)
.ok());
}
void mockItemVolumeData(std::string volumePath) {
KeyType key2(ManagedType::kManagedPropertyMap, "xyz.openbmc_project.NVMe",
volumePath, "xyz.openbmc_project.Inventory.Item.Volume");
dbus::utility::DBusPropertiesMap getAllItemVolumeMap{
{std::make_pair("BlockSize", 4096UL),
std::make_pair("Size", 3221225472000ULL)}};
std::shared_ptr<ValueType> getAllItemVolume =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(getAllItemVolumeMap));
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(key2, getAllItemVolume)
.ok());
}
void mockNvmeVolumeData(std::string volumePath) {
KeyType key3(ManagedType::kManagedPropertyMap, "xyz.openbmc_project.NVMe",
volumePath, "xyz.openbmc_project.Nvme.Volume");
dbus::utility::DBusPropertiesMap getAllVolumeMap{
{std::make_pair("NamespaceId", 1U), std::make_pair("LBAFormat", 0UL)}};
std::shared_ptr<ValueType> getAllVolume =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(getAllVolumeMap));
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(key3, getAllVolume)
.ok());
}
void mockAvoidLocationCheckForVolume(std::string volumePath) {
// adding empty object to avoid location check
KeyType locationKey(ManagedType::kManagedMapperObject, volumePath, {});
dbus::utility::MapperGetObject locationTypeValue{{}};
std::shared_ptr<ValueType> mockLocationType =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(locationTypeValue));
ASSERT_TRUE(
dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(locationKey, mockLocationType)
.ok());
// create empty storage reverse association to avoid storage check
KeyType getAssociatedSubTreeKey(
ManagedType::kManagedAssociatedSubtree, volumePath + "/contained",
"/xyz/openbmc_project/inventory", 0,
{"xyz.openbmc_project.Inventory.Item.Storage"});
dbus::utility::MapperGetSubTreeResponse mockSubtreeResponse{};
std::shared_ptr<ValueType> subtree =
managedStore::MockManagedStoreTest::CreateValueType(
std::move(mockSubtreeResponse));
ASSERT_TRUE(
dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(getAssociatedSubTreeKey, subtree)
.ok());
}
void mockMetricStore(std::string volumePath, bool failed = false) {
KeyType key(ManagedType::kManagedProperty, "xyz.openbmc_project.NVMe",
volumePath, "xyz.openbmc_project.NVMe.MetricStore",
"MetricCollection");
if (failed) {
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->evictMockObjectFromManagedStore(key)
.ok());
} else {
std::shared_ptr<ValueType> metricCollection =
managedStore::MockManagedStoreTest::CreateValueType<
dbus::utility::DbusVariantType>(
std::vector<std::string>({"FirstMetric", "SecondMetric"}));
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(key, metricCollection)
.ok());
}
}
void checkGenericVolumeMockData(nlohmann::json& json) {
EXPECT_EQ(json["@odata.id"],
"/redfish/v1/Systems/system/Storage/storage_nvme/Volumes/1");
EXPECT_EQ(json["@odata.type"], "#Volume.v1_9_0.Volume");
EXPECT_EQ(json["BlockSizeBytes"], 4096);
EXPECT_EQ(json["Capacity"]["Data"]["ProvisionedBytes"], 3221225472000);
EXPECT_EQ(json["Id"], "1");
EXPECT_EQ(json["NVMeNamespaceProperties"]["LBAFormat"]["LBADataSizeBytes"],
4096);
EXPECT_EQ(json["NVMeNamespaceProperties"]["LBAFormat"]["LBAFormatType"],
"LBAFormat0");
EXPECT_EQ(json["NVMeNamespaceProperties"]["NamespaceId"], "0x00000001");
EXPECT_EQ(json["Name"], "Namespace 1");
}
TEST_F(StorageSnapshotFixture, StorageVolumeHandlerCheck) {
std::string storageName = "storage_nvme";
std::string volumeName = "1";
std::string storagePath;
mockStorageObject(storageName, storagePath);
std::string volumePath;
addVolumeToMockStorage(storagePath, volumeName, volumePath);
mockItemVolumeData(volumePath);
mockNvmeVolumeData(volumePath);
mockMetricStore(volumePath);
// Skip location check due to it's complexity and
// since this test is targeting Metrics
mockAvoidLocationCheckForVolume(volumePath);
storageVolumeHandler(app_, CreateRequest(), share_async_resp_, "system",
storageName, volumeName);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
nlohmann::json& json = share_async_resp_->res.jsonValue;
checkGenericVolumeMockData(json);
EXPECT_EQ(json["Oem"]["Google"]["FirstMetric"]["DataUri"],
"/redfish/v1/Systems/system/Storage/storage_nvme/Volumes/1/Oem/"
"Google/Metrics/FirstMetric");
EXPECT_EQ(json["Oem"]["Google"]["SecondMetric"]["DataUri"],
"/redfish/v1/Systems/system/Storage/storage_nvme/Volumes/1/Oem/"
"Google/Metrics/SecondMetric");
}
TEST_F(StorageSnapshotFixture, StorageVolumeHandlerCheckWithoutItemVolume) {
std::string storageName = "storage_nvme";
std::string volumeName = "1";
std::string storagePath;
mockStorageObject(storageName, storagePath);
std::string volumePath;
addVolumeToMockStorage(storagePath, volumeName, volumePath);
mockNvmeVolumeData(volumePath);
mockMetricStore(volumePath);
// remove item volume from store
// previous testcases can affect this, hence removing
KeyType itemVolumeKey(ManagedType::kManagedPropertyMap,
"xyz.openbmc_project.NVMe", volumePath,
"xyz.openbmc_project.Inventory.Item.Volume");
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->evictMockObjectFromManagedStore(itemVolumeKey)
.ok());
// Skip location check due to it's complexity and
// since this test is targeting Metrics
mockAvoidLocationCheckForVolume(volumePath);
storageVolumeHandler(app_, CreateRequest(), share_async_resp_, "system",
storageName, volumeName);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
nlohmann::json& json = share_async_resp_->res.jsonValue;
EXPECT_EQ(json["@odata.id"],
"/redfish/v1/Systems/system/Storage/storage_nvme/Volumes/1");
EXPECT_EQ(json["@odata.type"], "#Volume.v1_9_0.Volume");
EXPECT_FALSE(json.contains("BlockSizeBytes"));
EXPECT_FALSE(json.contains("Capacity"));
EXPECT_FALSE(json.contains("NVMeNamespaceProperties"));
EXPECT_EQ(json["Id"], "1");
EXPECT_EQ(json["Name"], std::string("Volume ") + volumeName);
EXPECT_EQ(json["Oem"]["Google"]["FirstMetric"]["DataUri"],
"/redfish/v1/Systems/system/Storage/storage_nvme/Volumes/1/Oem/"
"Google/Metrics/FirstMetric");
EXPECT_EQ(json["Oem"]["Google"]["SecondMetric"]["DataUri"],
"/redfish/v1/Systems/system/Storage/storage_nvme/Volumes/1/Oem/"
"Google/Metrics/SecondMetric");
}
TEST_F(StorageSnapshotFixture, StorageVolumeHandlerCheckWithoutMetricStore) {
std::string storageName = "storage_nvme";
std::string volumeName = "1";
std::string storagePath;
mockStorageObject(storageName, storagePath);
std::string volumePath;
addVolumeToMockStorage(storagePath, volumeName, volumePath, false);
mockItemVolumeData(volumePath);
mockNvmeVolumeData(volumePath);
// Skip location check due to it's complexity and
// since this test is targeting Metrics
mockAvoidLocationCheckForVolume(volumePath);
storageVolumeHandler(app_, CreateRequest(), share_async_resp_, "system",
storageName, volumeName);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
nlohmann::json& json = share_async_resp_->res.jsonValue;
checkGenericVolumeMockData(json);
EXPECT_FALSE(json["Oem"]["Google"].contains("FirstMetric"));
}
TEST_F(StorageSnapshotFixture, StorageVolumeHandlerCheckWithMetricStoreError) {
std::string storageName = "storage_nvme";
std::string volumeName = "1";
std::string storagePath;
mockStorageObject(storageName, storagePath);
std::string volumePath;
addVolumeToMockStorage(storagePath, volumeName, volumePath);
mockItemVolumeData(volumePath);
mockNvmeVolumeData(volumePath);
mockMetricStore(volumePath, true);
// Skip location check due to it's complexity and
// since this test is targeting Metrics
mockAvoidLocationCheckForVolume(volumePath);
storageVolumeHandler(app_, CreateRequest(), share_async_resp_, "system",
storageName, volumeName);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
nlohmann::json& json = share_async_resp_->res.jsonValue;
checkGenericVolumeMockData(json);
EXPECT_FALSE(json["Oem"]["Google"].contains("FirstMetric"));
}
TEST_F(StorageSnapshotFixture, StorageVolumeGetMetricError) {
std::string storageName = "storage_nvme";
std::string volumeName = "1";
std::string storagePath;
mockStorageObject(storageName, storagePath);
std::string volumePath;
addVolumeToMockStorage(storagePath, volumeName, volumePath);
mockMetricStore(volumePath);
std::string metricId = "FirstMetric";
testing::StrictMock<sdbusplus::SdBusMock> sdbus;
EXPECT_CALL(sdbus,
sd_bus_message_new_method_call(testing::_, testing::_, nullptr,
nullptr, nullptr, nullptr))
.WillRepeatedly(testing::Return(0));
sd_bus_error err;
err.name = "xyz.openbmc_project.Common.Error.Unavailable";
EXPECT_CALL(sdbus, sd_bus_message_get_error(testing::_))
.WillRepeatedly(testing::Return(&err));
// intentionally failing
// want to test only properties not the metric data since there is no
// existing model to mock fd
sdbusplus::message_t msg = sdbusplus::get_mocked_new(&sdbus).new_method_call(
nullptr, nullptr, nullptr, nullptr);
EXPECT_CALL(
*dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore()),
PostDbusCallToIoContextThreadSafe(
_,
An<absl::AnyInvocable<void(const boost::system::error_code&,
const sdbusplus::message_t&,
const sdbusplus::message::unix_fd&)>&&>(),
"xyz.openbmc_project.NVMe", volumePath,
"xyz.openbmc_project.NVMe.MetricStore", "GetMetric", metricId))
.Times(testing::AtMost(1))
.WillOnce(
SimulateFailedAsyncPostDbusCallThreadSafeWithMsgAndEmptyValueAction::
SimulateFailedAsyncPostDbusCallWithMsgAndEmptyValue(msg));
handleStorageVolumeMetricGet(share_async_resp_, "system", storageName,
volumeName, metricId);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::internal_server_error);
nlohmann::json& json = share_async_resp_->res.jsonValue;
EXPECT_EQ(json["@odata.id"],
"/redfish/v1/Systems/system/Storage/storage_nvme/Volumes/1/Oem/"
"Google/Metrics/FirstMetric");
EXPECT_EQ(json["Name"], "FirstMetric");
}
TEST_F(StorageSnapshotFixture, HandleChassisDriveGetInvalidDriveNotFound) {
handleChassisDriveGet(app_, CreateRequest(), share_async_resp_, "platform1",
"invalid_drive");
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::not_found);
}
TEST_F(StorageSnapshotFixture, HandleChassisDriveGetInvalidChassisNotFound) {
handleChassisDriveGet(app_, CreateRequest(), share_async_resp_,
"invalid_chassis", "invalid_drive");
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::not_found);
}
TEST_F(StorageSnapshotFixture, HandleChassisDriveGetEbadr) {
managedStore::KeyType driveAssocKey(
managedStore::ManagedType::kManagedProperty,
"xyz.openbmc_project.ObjectMapper",
sdbusplus::message::object_path(
"/xyz/openbmc_project/inventory/system/board/platform1/drive"),
"xyz.openbmc_project.Association", "endpoints");
ASSERT_TRUE(
dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
driveAssocKey, CreateErrorValueType(
dbus::utility::DbusVariantType{},
boost::system::error_code(
EBADR, boost::system::generic_category())))
.ok());
handleChassisDriveGet(app_, CreateRequest(), share_async_resp_, "platform1",
"invalid_drive");
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::not_found);
}
TEST_F(StorageSnapshotFixture, HandleChassisDriveGetEnoent) {
managedStore::KeyType driveAssocKey(
managedStore::ManagedType::kManagedProperty,
"xyz.openbmc_project.ObjectMapper",
sdbusplus::message::object_path(
"/xyz/openbmc_project/inventory/system/board/platform1/drive"),
"xyz.openbmc_project.Association", "endpoints");
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
driveAssocKey,
CreateErrorValueType(
dbus::utility::DbusVariantType{},
boost::system::error_code(
ENOENT, boost::system::generic_category())))
.ok());
handleChassisDriveGet(app_, CreateRequest(), share_async_resp_, "platform1",
"invalid_drive");
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::not_found);
}
TEST_F(StorageSnapshotFixture, HandleChassisDriveGetDbusError) {
managedStore::KeyType driveAssocKey(
managedStore::ManagedType::kManagedProperty,
"xyz.openbmc_project.ObjectMapper",
sdbusplus::message::object_path(
"/xyz/openbmc_project/inventory/system/board/platform1/drive"),
"xyz.openbmc_project.Association", "endpoints");
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
driveAssocKey,
CreateErrorValueType(dbus::utility::DbusVariantType{},
boost::system::errc::make_error_code(
boost::system::errc::io_error)))
.ok());
handleChassisDriveGet(app_, CreateRequest(), share_async_resp_, "platform1",
"invalid_drive");
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::internal_server_error);
}
TEST_F(StorageSnapshotFixture, BuildDriveFound) {
KeyType storageSubtreeKey(ManagedType::kManagedSubtree,
"/xyz/openbmc_project/inventory", 0,
{"xyz.openbmc_project.Inventory.Item.Storage"});
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
storageSubtreeKey,
managedStore::MockManagedStoreTest::CreateValueType(
dbus::utility::MapperGetSubTreeResponse{}))
.ok());
std::string driveName = "drive_0";
dbus::utility::MapperGetSubTreeResponse mockSubtree = {
{"/xyz/openbmc_project/inventory/drive_0",
{{"xyz.openbmc_project.Drive", {}}}},
};
buildDrive(share_async_resp_, "platform1", driveName,
boost::system::error_code{}, mockSubtree);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(share_async_resp_->res.jsonValue["@odata.id"],
"/redfish/v1/Chassis/platform1/Drives/drive_0");
EXPECT_EQ(share_async_resp_->res.jsonValue["Name"], "drive_0");
EXPECT_EQ(share_async_resp_->res.jsonValue["Id"], "drive_0");
EXPECT_EQ(share_async_resp_->res.jsonValue["Status"]["State"], "Enabled");
}
TEST_F(StorageSnapshotFixture, BuildDriveNotFound) {
dbus::utility::MapperGetSubTreeResponse mockSubtree = {
{"/xyz/openbmc_project/inventory/other_drive",
{{"xyz.openbmc_project.Drive", {}}}},
};
buildDrive(share_async_resp_, "platform1", "drive_0",
boost::system::error_code{}, mockSubtree);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::not_found);
}
TEST_F(StorageSnapshotFixture, BuildDriveEmptyConnectionNames) {
dbus::utility::MapperGetSubTreeResponse mockSubtree = {
{"/xyz/openbmc_project/inventory/drive_0", {}},
};
buildDrive(share_async_resp_, "platform1", "drive_0",
boost::system::error_code{}, mockSubtree);
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::not_found);
}
TEST_F(StorageSnapshotFixture, BuildDriveDbusError) {
buildDrive(
share_async_resp_, "platform1", "drive_0",
boost::system::errc::make_error_code(boost::system::errc::io_error), {});
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::internal_server_error);
}
TEST_F(StorageSnapshotFixture, HandleChassisDriveGetValidDrive) {
KeyType storageSubtreeKey(ManagedType::kManagedSubtree,
"/xyz/openbmc_project/inventory", 0,
{"xyz.openbmc_project.Inventory.Item.Storage"});
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
storageSubtreeKey,
managedStore::MockManagedStoreTest::CreateValueType(
dbus::utility::MapperGetSubTreeResponse{}))
.ok());
managedStore::KeyType driveAssocKey(
managedStore::ManagedType::kManagedProperty,
"xyz.openbmc_project.ObjectMapper",
sdbusplus::message::object_path(
"/xyz/openbmc_project/inventory/system/board/platform1/drive"),
"xyz.openbmc_project.Association", "endpoints");
dbus::utility::MapperEndPoints driveEndpoints = {
"/xyz/openbmc_project/inventory/system/chassis/drive0"};
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
driveAssocKey,
managedStore::MockManagedStoreTest::CreateValueType(
dbus::utility::DbusVariantType(driveEndpoints)))
.ok());
managedStore::KeyType driveSubtreeKey(
managedStore::ManagedType::kManagedSubtree,
"/xyz/openbmc_project/inventory", 0,
{"xyz.openbmc_project.Inventory.Item.Drive"});
dbus::utility::MapperGetSubTreeResponse mockDriveSubtree = {
{"/xyz/openbmc_project/inventory/system/chassis/drive0",
{{"xyz.openbmc_project.DriveService", {}}}},
};
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
driveSubtreeKey,
managedStore::MockManagedStoreTest::CreateValueType(
std::move(mockDriveSubtree)))
.ok());
handleChassisDriveGet(app_, CreateRequest(), share_async_resp_, "platform1",
"drive0");
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(share_async_resp_->res.jsonValue["@odata.id"],
"/redfish/v1/Chassis/platform1/Drives/drive0");
EXPECT_EQ(share_async_resp_->res.jsonValue["Name"], "drive0");
EXPECT_EQ(share_async_resp_->res.jsonValue["Id"], "drive0");
}
TEST_F(StorageSnapshotFixture, HandleChassisDriveGetDriveNotInSubtree) {
managedStore::KeyType driveAssocKey(
managedStore::ManagedType::kManagedProperty,
"xyz.openbmc_project.ObjectMapper",
sdbusplus::message::object_path(
"/xyz/openbmc_project/inventory/system/board/platform1/drive"),
"xyz.openbmc_project.Association", "endpoints");
dbus::utility::MapperEndPoints driveEndpoints = {
"/xyz/openbmc_project/inventory/system/chassis/drive0"};
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
driveAssocKey,
managedStore::MockManagedStoreTest::CreateValueType(
dbus::utility::DbusVariantType(driveEndpoints)))
.ok());
managedStore::KeyType driveSubtreeKey(
managedStore::ManagedType::kManagedSubtree,
"/xyz/openbmc_project/inventory", 0,
{"xyz.openbmc_project.Inventory.Item.Drive"});
dbus::utility::MapperGetSubTreeResponse mockDriveSubtree = {};
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
driveSubtreeKey,
managedStore::MockManagedStoreTest::CreateValueType(
std::move(mockDriveSubtree)))
.ok());
handleChassisDriveGet(app_, CreateRequest(), share_async_resp_, "platform1",
"drive0");
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::not_found);
}
TEST_F(StorageSnapshotFixture, HandlePostDriveResetActionDbusError) {
managedStore::KeyType driveAssocKey(
managedStore::ManagedType::kManagedProperty,
"xyz.openbmc_project.ObjectMapper",
sdbusplus::message::object_path(
"/xyz/openbmc_project/inventory/system/board/platform1/drive"),
"xyz.openbmc_project.Association", "endpoints");
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
driveAssocKey,
CreateErrorValueType(dbus::utility::DbusVariantType{},
boost::system::errc::make_error_code(
boost::system::errc::io_error)))
.ok());
handlePostDriveResetAction(app_, CreateRequest(), share_async_resp_,
"platform1", "drive_0");
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::internal_server_error);
}
TEST_F(StorageSnapshotFixture, HandleGetDriveResetActionInfoDbusError) {
managedStore::KeyType driveAssocKey(
managedStore::ManagedType::kManagedProperty,
"xyz.openbmc_project.ObjectMapper",
sdbusplus::message::object_path(
"/xyz/openbmc_project/inventory/system/board/platform1/drive"),
"xyz.openbmc_project.Association", "endpoints");
ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
managedStore::GetManagedObjectStore())
->upsertMockObjectIntoManagedStore(
driveAssocKey,
CreateErrorValueType(dbus::utility::DbusVariantType{},
boost::system::errc::make_error_code(
boost::system::errc::io_error)))
.ok());
handleGetDriveResetActionInfo(app_, CreateRequest(), share_async_resp_,
"platform1", "drive_0");
RunIoUntilDone();
EXPECT_EQ(share_async_resp_->res.result(),
boost::beast::http::status::internal_server_error);
}
} // namespace
} // namespace redfish