| #include <array> | |
| #include <cstdint> | |
| #include <cstdio> | |
| #include <fstream> | |
| #include <ios> | |
| #include <memory> | |
| #include <optional> | |
| #include <string> | |
| #include <string_view> | |
| #include <tuple> | |
| #include <utility> | |
| #include <vector> | |
| #include "gbmc_settings/bios_settings.pb.h" | |
| #include <gmock/gmock.h> | |
| #include <gtest/gtest.h> | |
| #include "absl/cleanup/cleanup.h" | |
| #include "absl/functional/any_invocable.h" | |
| #include "absl/status/status.h" | |
| #include "absl/status/statusor.h" | |
| #include "boost/system/detail/error_code.hpp" // NOLINT | |
| #include "http_request.hpp" | |
| #include "logging.hpp" | |
| #include "async_resp.hpp" | |
| #include "dbus_utility.hpp" | |
| #include "subprocess_utils.hpp" | |
| #include "subprocess_utils_fake.hpp" | |
| #include "systems.hpp" | |
| #include "test/redfish-core/lib/snapshot_fixture.hpp" | |
| #include <nlohmann/json.hpp> | |
| #include "tlbmc/hal/system_registry_mock.h" | |
| #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/native_types.hpp" | |
| #include "google/protobuf/text_format.h" | |
| #include "google/protobuf/util/message_differencer.h" | |
| namespace redfish { | |
| namespace { | |
| using ::dbus::utility::DbusVariantType; | |
| using ::gbmc::settings::BootOption; | |
| using ::gbmc::settings::BootSourceOverrideEnabled; | |
| using ::gbmc::settings::BootSourceOverrideTarget; | |
| using ::managedStore::KeyType; | |
| using ::managedStore::ManagedType; | |
| using ::managedStore::SimulateFailedAsyncPostDbusCallThreadSafeAction; | |
| using ::managedStore:: | |
| SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction; | |
| using ::managedStore::SimulateSuccessfulAsyncPostDbusCallThreadSafeAction; | |
| using ::managedStore:: | |
| SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction; | |
| using ::managedStore::ValueType; | |
| using ::milotic_tlbmc::MockSystemRegistry; | |
| using ::testing::_; | |
| using ::testing::An; | |
| TEST(HandlerSystemTest, VerifyCreateResetActionInfoResponse) { | |
| auto shareAsyncResp = std::make_shared<bmcweb::AsyncResp>(); | |
| createResetActionInfoResponse(shareAsyncResp, "test"); | |
| nlohmann::json& json = shareAsyncResp->res.jsonValue; | |
| EXPECT_EQ(json["@odata.id"], "/redfish/v1/Systems/test/ResetActionInfo"); | |
| EXPECT_EQ(json["@odata.type"], "#ActionInfo.v1_1_2.ActionInfo"); | |
| EXPECT_EQ(json["Name"], "Reset Action Info"); | |
| EXPECT_EQ(json["Id"], "ResetActionInfo"); | |
| nlohmann::json::array_t parameters; | |
| nlohmann::json::object_t parameter; | |
| parameter["Name"] = "ResetType"; | |
| parameter["Required"] = true; | |
| parameter["DataType"] = "String"; | |
| parameter["Delay"] = "Number"; | |
| nlohmann::json::array_t allowableValues; | |
| allowableValues.emplace_back("On"); | |
| allowableValues.emplace_back("ForceOff"); | |
| allowableValues.emplace_back("ForceOn"); | |
| allowableValues.emplace_back("ForceRestart"); | |
| allowableValues.emplace_back("GracefulRestart"); | |
| allowableValues.emplace_back("GracefulShutdown"); | |
| allowableValues.emplace_back("PowerCycle"); | |
| allowableValues.emplace_back("Nmi"); | |
| #ifdef BMCWEB_ENABLE_REALLY_GRACEFUL_SHUTDOWN | |
| allowableValues.emplace_back("ReallyGracefulShutDownTechDebt"); | |
| #endif | |
| parameter["AllowableValues"] = std::move(allowableValues); | |
| parameters.emplace_back(std::move(parameter)); | |
| nlohmann::json::object_t delayParameter; | |
| delayParameter["Name"] = "Delay"; | |
| delayParameter["Required"] = false; | |
| delayParameter["DataType"] = "Number"; | |
| parameters.emplace_back(std::move(delayParameter)); | |
| EXPECT_EQ(json["Parameters"], parameters); | |
| } | |
| TEST(GetSystemResetCommandFromInputTest, TestOnAndForceOnReturnCorrectly) { | |
| SystemResetCommand systemResetCommandOn = | |
| GetSystemResetCommandFromInput("On"); | |
| EXPECT_EQ(systemResetCommandOn.command, | |
| "xyz.openbmc_project.State.Host.Transition.On"); | |
| EXPECT_TRUE(systemResetCommandOn.hostCommand); | |
| EXPECT_TRUE(systemResetCommandOn.validCommand); | |
| SystemResetCommand systemResetCommandForceOn = | |
| GetSystemResetCommandFromInput("ForceOn"); | |
| EXPECT_EQ(systemResetCommandForceOn.command, | |
| "xyz.openbmc_project.State.Host.Transition.On"); | |
| EXPECT_TRUE(systemResetCommandForceOn.hostCommand); | |
| EXPECT_TRUE(systemResetCommandForceOn.validCommand); | |
| } | |
| TEST(GetSystemResetCommandFromInputTest, TestForceOffReturnCorrectly) { | |
| SystemResetCommand systemResetCommandOn = | |
| GetSystemResetCommandFromInput("ForceOff"); | |
| EXPECT_EQ(systemResetCommandOn.command, | |
| "xyz.openbmc_project.State.Chassis.Transition.Off"); | |
| EXPECT_FALSE(systemResetCommandOn.hostCommand); | |
| EXPECT_TRUE(systemResetCommandOn.validCommand); | |
| } | |
| TEST(GetSystemResetCommandFromInputTest, TestForceRestartReturnCorrectly) { | |
| SystemResetCommand systemResetCommandOn = | |
| GetSystemResetCommandFromInput("ForceRestart"); | |
| EXPECT_EQ(systemResetCommandOn.command, | |
| "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"); | |
| EXPECT_TRUE(systemResetCommandOn.hostCommand); | |
| EXPECT_TRUE(systemResetCommandOn.validCommand); | |
| } | |
| TEST(GetSystemResetCommandFromInputTest, TestGracefulShutdownReturnCorrectly) { | |
| SystemResetCommand systemResetCommandOn = | |
| GetSystemResetCommandFromInput("GracefulShutdown"); | |
| EXPECT_EQ(systemResetCommandOn.command, | |
| "xyz.openbmc_project.State.Host.Transition.Off"); | |
| EXPECT_TRUE(systemResetCommandOn.hostCommand); | |
| EXPECT_TRUE(systemResetCommandOn.validCommand); | |
| } | |
| TEST(GetSystemResetCommandFromInputTest, TestGracefulRestartReturnCorrectly) { | |
| SystemResetCommand systemResetCommandOn = | |
| GetSystemResetCommandFromInput("GracefulRestart"); | |
| EXPECT_EQ(systemResetCommandOn.command, | |
| "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"); | |
| EXPECT_TRUE(systemResetCommandOn.hostCommand); | |
| EXPECT_TRUE(systemResetCommandOn.validCommand); | |
| } | |
| TEST(GetSystemResetCommandFromInputTest, TestPowerCycleReturnCorrectly) { | |
| SystemResetCommand systemResetCommandOn = | |
| GetSystemResetCommandFromInput("PowerCycle"); | |
| EXPECT_EQ(systemResetCommandOn.command, | |
| "xyz.openbmc_project.State.Host.Transition.Reboot"); | |
| EXPECT_TRUE(systemResetCommandOn.hostCommand); | |
| EXPECT_TRUE(systemResetCommandOn.validCommand); | |
| } | |
| #ifdef BMCWEB_ENABLE_REALLY_GRACEFUL_SHUTDOWN | |
| TEST(GetSystemResetCommandFromInputTest, | |
| TestReallyGracefulShutDownTechDebtReturnCorrectly) { | |
| SystemResetCommand systemResetCommandOn = | |
| GetSystemResetCommandFromInput("ReallyGracefulShutDownTechDebt"); | |
| EXPECT_EQ(systemResetCommandOn.command, | |
| "xyz.openbmc_project.State.Host.Transition.ReallyGracefulShutDown"); | |
| EXPECT_TRUE(systemResetCommandOn.hostCommand); | |
| EXPECT_TRUE(systemResetCommandOn.validCommand); | |
| } | |
| #endif | |
| TEST(GetSystemResetCommandFromInputTest, TestInvalidInput) { | |
| SystemResetCommand systemResetCommandOn = | |
| GetSystemResetCommandFromInput("SomeInvalidInput"); | |
| EXPECT_FALSE(systemResetCommandOn.validCommand); | |
| } | |
| TEST(GetSystemSuffixHelperTest, TestAllInputs) { | |
| // Empty, invalid strings | |
| EXPECT_EQ("", getSystemSuffix("")); | |
| EXPECT_EQ("", getSystemSuffix("asdf")); | |
| EXPECT_EQ("", getSystemSuffix("syste")); | |
| // Valid Systems/ | |
| EXPECT_EQ("", getSystemSuffix("system")); | |
| EXPECT_EQ("1", getSystemSuffix("system1")); | |
| EXPECT_EQ("13", getSystemSuffix("system13")); | |
| EXPECT_EQ("FUTURE", getSystemSuffix("systemFUTURE")); | |
| } | |
| TEST(HandlerSystemTest, HelpersValuesEnable) { | |
| auto shareAsyncResp = std::make_shared<bmcweb::AsyncResp>(); | |
| nlohmann::json& json = shareAsyncResp->res.jsonValue; | |
| json["MemorySummary"]["Status"]["State"] = "Disabled"; | |
| json["ProcessorSummary"]["Count"] = 1; | |
| json["ProcessorSummary"]["Status"]["State"] = "Disabled"; | |
| updateDimmProperties(shareAsyncResp, true); | |
| modifyCpuPresenceState(shareAsyncResp, true); | |
| modifyCpuFunctionalState(shareAsyncResp, true); | |
| EXPECT_EQ(json["MemorySummary"]["Status"]["State"], "Enabled"); | |
| EXPECT_EQ(json["ProcessorSummary"]["Count"], 2); | |
| EXPECT_EQ(json["ProcessorSummary"]["Status"]["State"], "Enabled"); | |
| } | |
| class SystemResetSnapshotFixture : public SnapshotFixture { | |
| protected: | |
| static void SetupDbusMockIfNeeded() { | |
| #ifdef BMCWEB_ALLOW_NON_HARDCODED_SINGLEHOST_SYSTEM | |
| managedStore::KeyType systemKey( | |
| managedStore::ManagedType::kManagedSubtreePaths, "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system1"}; | |
| ASSERT_TRUE( | |
| dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| systemKey, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| managedStore::KeyType hostAssocKey( | |
| managedStore::ManagedType::kManagedAssociatedSubtree, | |
| "/xyz/openbmc_project/inventory/system1/host_power", | |
| "/xyz/openbmc_project/state", 0, {"xyz.openbmc_project.State.Host"}); | |
| dbus::utility::MapperGetSubTreeResponse mockHostAssoc = { | |
| { "/xyz/openbmc_project/state/host0", | |
| { | |
| { "xyz.openbmc_project.State.Host", | |
| {"xyz.openbmc_project.State.Host"} } | |
| } }}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| hostAssocKey, | |
| managedStore::MockManagedStoreTest::CreateValueType( | |
| mockHostAssoc)) | |
| .ok()); | |
| managedStore::KeyType chassisAssocKey( | |
| managedStore::ManagedType::kManagedAssociatedSubtree, | |
| "/xyz/openbmc_project/inventory/system1/chassis_power", | |
| "/xyz/openbmc_project/state", 0, {"xyz.openbmc_project.State.Chassis"}); | |
| dbus::utility::MapperGetSubTreeResponse mockChassisAssoc = { | |
| { "/xyz/openbmc_project/state/chassis0", | |
| { | |
| { "xyz.openbmc_project.State.Chassis", | |
| {"xyz.openbmc_project.State.Chassis"} } | |
| } }}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| chassisAssocKey, | |
| managedStore::MockManagedStoreTest::CreateValueType( | |
| mockChassisAssoc)) | |
| .ok()); | |
| #endif | |
| } | |
| static std::string GetTestSystemName() { | |
| #ifdef BMCWEB_ALLOW_NON_HARDCODED_SINGLEHOST_SYSTEM | |
| return "system1"; | |
| #else | |
| return "system"; | |
| #endif | |
| } | |
| }; | |
| TEST_F(SystemResetSnapshotFixture, PostSystemResetAsNMIOnDBusCallFailed) { | |
| SetupDbusMockIfNeeded(); | |
| EXPECT_CALL( | |
| *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()), | |
| PostDbusCallToIoContextThreadSafe( | |
| _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(), | |
| "xyz.openbmc_project.Control.Host.NMI", | |
| "/xyz/openbmc_project/control/host0/nmi", | |
| "xyz.openbmc_project.Control.Host.NMI", "NMI")) | |
| .Times(1) | |
| .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeAction:: | |
| SimulateFailedAsyncPostDbusCall()); | |
| handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"Nmi\"}"), | |
| share_async_resp_, GetTestSystemName()); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SystemResetSnapshotFixture, PostSystemResetAsNMIOnDBusCallSuccess) { | |
| SetupDbusMockIfNeeded(); | |
| EXPECT_CALL( | |
| *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()), | |
| PostDbusCallToIoContextThreadSafe( | |
| _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(), | |
| "xyz.openbmc_project.Control.Host.NMI", | |
| "/xyz/openbmc_project/control/host0/nmi", | |
| "xyz.openbmc_project.Control.Host.NMI", "NMI")) | |
| .Times(1) | |
| .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeAction:: | |
| SimulateSuccessfulAsyncPostDbusCall()); | |
| handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"Nmi\"}"), | |
| share_async_resp_, GetTestSystemName()); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | |
| } | |
| TEST_F(SystemResetSnapshotFixture, PostSystemResetSingleSystemHostResetOnFail) { | |
| SetupDbusMockIfNeeded(); | |
| EXPECT_CALL( | |
| *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()), | |
| PostDbusCallToIoContextThreadSafe( | |
| _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(), | |
| "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", | |
| "org.freedesktop.DBus.Properties", "Set", | |
| "xyz.openbmc_project.State.Host", "RequestedHostTransition", | |
| dbus::utility::DbusVariantType( | |
| "xyz.openbmc_project.State.Host.Transition.On"))) | |
| .Times(1) | |
| .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeAction:: | |
| SimulateFailedAsyncPostDbusCall()); | |
| handlePostComputerSystemReset(app_, | |
| CreateRequest("{\"ResetType\":\"ForceOn\"}"), | |
| share_async_resp_, GetTestSystemName()); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SystemResetSnapshotFixture, | |
| PostSystemResetSingleSystemHostResetOnSuccess) { | |
| SetupDbusMockIfNeeded(); | |
| EXPECT_CALL( | |
| *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()), | |
| PostDbusCallToIoContextThreadSafe( | |
| _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(), | |
| "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", | |
| "org.freedesktop.DBus.Properties", "Set", | |
| "xyz.openbmc_project.State.Host", "RequestedHostTransition", | |
| dbus::utility::DbusVariantType( | |
| "xyz.openbmc_project.State.Host.Transition.On"))) | |
| .Times(1) | |
| .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeAction:: | |
| SimulateSuccessfulAsyncPostDbusCall()); | |
| handlePostComputerSystemReset(app_, | |
| CreateRequest("{\"ResetType\":\"ForceOn\"}"), | |
| share_async_resp_, GetTestSystemName()); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | |
| } | |
| TEST_F(SystemResetSnapshotFixture, | |
| PostSystemResetSingleSystemChassisResetOnFail) { | |
| SetupDbusMockIfNeeded(); | |
| EXPECT_CALL( | |
| *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()), | |
| PostDbusCallToIoContextThreadSafe( | |
| _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(), | |
| "xyz.openbmc_project.State.Chassis", | |
| "/xyz/openbmc_project/state/chassis0", | |
| "org.freedesktop.DBus.Properties", "Set", | |
| "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", | |
| dbus::utility::DbusVariantType( | |
| "xyz.openbmc_project.State.Chassis.Transition.Off"))) | |
| .Times(1) | |
| .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeAction:: | |
| SimulateFailedAsyncPostDbusCall()); | |
| handlePostComputerSystemReset(app_, | |
| CreateRequest("{\"ResetType\":\"ForceOff\"}"), | |
| share_async_resp_, GetTestSystemName()); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SystemResetSnapshotFixture, | |
| PostSystemResetSingleSystemChassisResetOnSuccess) { | |
| SetupDbusMockIfNeeded(); | |
| EXPECT_CALL( | |
| *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()), | |
| PostDbusCallToIoContextThreadSafe( | |
| _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(), | |
| "xyz.openbmc_project.State.Chassis", | |
| "/xyz/openbmc_project/state/chassis0", | |
| "org.freedesktop.DBus.Properties", "Set", | |
| "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", | |
| dbus::utility::DbusVariantType( | |
| "xyz.openbmc_project.State.Chassis.Transition.Off"))) | |
| .Times(1) | |
| .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeAction:: | |
| SimulateSuccessfulAsyncPostDbusCall()); | |
| handlePostComputerSystemReset(app_, | |
| CreateRequest("{\"ResetType\":\"ForceOff\"}"), | |
| share_async_resp_, GetTestSystemName()); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | |
| } | |
| TEST_F(SnapshotFixture, CheckComputerSystemHostStateSingleHost) { | |
| KeyType key( | |
| ManagedType::kManagedProperty, "xyz.openbmc_project.State.Host", | |
| sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"), | |
| "xyz.openbmc_project.State.Host", "CurrentHostState"); | |
| const std::array<std::tuple<std::string, std::string, std::string>, 6> | |
| testCases{ | |
| {{"xyz.openbmc_project.State.Host.HostState.Running", "On", | |
| "Enabled"}, | |
| {"xyz.openbmc_project.State.Host.HostState.Quiesced", "On", | |
| "Quiesced"}, | |
| {"xyz.openbmc_project.State.Host.HostState.DiagnosticMode", "On", | |
| "InTest"}, | |
| {"xyz.openbmc_project.State.Host.HostState.TransitioningToRunning", | |
| "PoweringOn", "Starting"}, | |
| {"xyz.openbmc_project.State.Host.HostState.TransitioningToOff", | |
| "PoweringOff", "Disabled"}, | |
| {"xyz.openbmc_project.State.Host.HostState.OtherDummy", "Off", | |
| "Disabled"}}}; | |
| for (auto testCase : testCases) { | |
| const auto [currentHostState, powerState, status] = testCase; | |
| DbusVariantType targetState = currentHostState; | |
| std::shared_ptr<ValueType> mockHostStateValue = | |
| managedStore::MockManagedStoreTest::CreateValueType( | |
| std::move(targetState)); | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore(key, mockHostStateValue) | |
| .ok()); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_TRUE(json.contains("PowerState")); | |
| EXPECT_TRUE(json.contains("Status")); | |
| EXPECT_EQ(json["PowerState"], powerState); | |
| EXPECT_TRUE(json["Status"].contains("State")); | |
| EXPECT_EQ(json["Status"]["State"], status); | |
| } | |
| } | |
| TEST_F(SnapshotFixture, GetSystemHostPowerAssociatedSubTreeFailed) { | |
| // Looking for | |
| // kManagedAssociatedSubtree|/xyz/openbmc_project/state|0|xyz.openbmc_project.State.Host|/host_power | |
| KeyType key(ManagedType::kManagedAssociatedSubtree, "/host_power", | |
| "/xyz/openbmc_project/state", 0, | |
| {"xyz.openbmc_project.State.Host"}); | |
| absl::StatusOr<std::shared_ptr<ValueType>> associatedSubtreeObjectsStatusOr = | |
| dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->getMockObjectFromManagedStore(key); | |
| ASSERT_TRUE(associatedSubtreeObjectsStatusOr.ok()); | |
| // TODO(b/416746677): Uncomment after the bug is fixed | |
| // ASSERT_EQ(associatedSubtreeObjectsStatusOr.value()->managedType, | |
| // ManagedType::kManagedSubtreePaths); | |
| std::optional<dbus::utility::MapperGetSubTreeResponse> | |
| originalAssociatedSubtree = | |
| associatedSubtreeObjectsStatusOr.value()->managedSubtree; | |
| ASSERT_TRUE(originalAssociatedSubtree.has_value()); | |
| ASSERT_TRUE( | |
| dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateErrorValueType( | |
| originalAssociatedSubtree.value(), | |
| boost::system::errc::make_error_code( | |
| boost::system::errc::io_error))) | |
| .ok()); | |
| absl::Cleanup mockManagedStoreResetter = [key, originalAssociatedSubtree]() { | |
| ASSERT_TRUE( | |
| dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| originalAssociatedSubtree.value())) | |
| .ok()); | |
| }; | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| std::shared_ptr<ValueType> CreateMockAssociatedSubtree() { | |
| dbus::utility::MapperGetSubTreeResponse mockAssociatedSubtree = { | |
| std::make_pair( | |
| "/xyz/openbmc_project/state/host1", | |
| dbus::utility::MapperServiceMap{ | |
| {std::make_pair("xyz.openbmc_project.Chassis.Buttons1", | |
| std::vector<std::string>{ | |
| "org.freedesktop.DBus.Introspectable", | |
| "org.freedesktop.DBus.Peer", | |
| "org.freedesktop.DBus.Properties", | |
| "xyz.openbmc_project.State.Host", | |
| }), | |
| std::make_pair("xyz.openbmc_project.Control.Host.RestartCause1", | |
| std::vector<std::string>{ | |
| "org.freedesktop.DBus.Introspectable", | |
| "org.freedesktop.DBus.Peer", | |
| "org.freedesktop.DBus.Properties", | |
| "xyz.openbmc_project.State.Host", | |
| })}}), | |
| std::make_pair( | |
| "/xyz/openbmc_project/state/host2", | |
| dbus::utility::MapperServiceMap{ | |
| {std::make_pair("xyz.openbmc_project.Chassis.Buttons1", | |
| std::vector<std::string>{ | |
| "org.freedesktop.DBus.Introspectable", | |
| "org.freedesktop.DBus.Peer", | |
| "org.freedesktop.DBus.Properties", | |
| "xyz.openbmc_project.State.Host", | |
| }), | |
| std::make_pair("xyz.openbmc_project.Control.Host.RestartCause1", | |
| std::vector<std::string>{ | |
| "org.freedesktop.DBus.Introspectable", | |
| "org.freedesktop.DBus.Peer", | |
| "org.freedesktop.DBus.Properties", | |
| "xyz.openbmc_project.State.Host", | |
| })}}), | |
| }; | |
| return managedStore::MockManagedStoreTest::CreateValueType( | |
| std::move(mockAssociatedSubtree)); | |
| } | |
| TEST_F(SnapshotFixture, | |
| GetSystemHostPowerAssociatedSubTreeHasMoreThanOneObjects) { | |
| crow::Logger::setLogLevel(crow::LogLevel::Error); | |
| // Looking for | |
| // kManagedAssociatedSubtree|/xyz/openbmc_project/state|0|xyz.openbmc_project.State.Host|/host_power | |
| KeyType key(ManagedType::kManagedAssociatedSubtree, "/host_power", | |
| "/xyz/openbmc_project/state", 0, | |
| {"xyz.openbmc_project.State.Host"}); | |
| absl::StatusOr<std::shared_ptr<ValueType>> associatedSubtreeObjectsStatusOr = | |
| dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->getMockObjectFromManagedStore(key); | |
| ASSERT_TRUE(associatedSubtreeObjectsStatusOr.ok()); | |
| // TODO(b/416746677): Uncomment after the bug is fixed | |
| // ASSERT_EQ(associatedSubtreeObjectsStatusOr.value()->managedType, | |
| // ManagedType::kManagedSubtreePaths); | |
| std::optional<dbus::utility::MapperGetSubTreeResponse> | |
| originalAssociatedSubtree = | |
| associatedSubtreeObjectsStatusOr.value()->managedSubtree; | |
| ASSERT_TRUE(originalAssociatedSubtree.has_value()); | |
| ASSERT_TRUE( | |
| dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore(key, CreateMockAssociatedSubtree()) | |
| .ok()); | |
| absl::Cleanup mockManagedStoreResetter = [key, originalAssociatedSubtree]() { | |
| ASSERT_TRUE( | |
| dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| originalAssociatedSubtree.value())) | |
| .ok()); | |
| }; | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, GetSystemHostPowerAssociatedSubTreeHasEmptyObjects) { | |
| KeyType key(ManagedType::kManagedAssociatedSubtree, "system1/host_power", | |
| "/xyz/openbmc_project/state", 0, | |
| {"xyz.openbmc_project.State.Host"}); | |
| dbus::utility::MapperGetSubTreeResponse mockAssociatedSubtree; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| std::move(mockAssociatedSubtree))) | |
| .ok()); | |
| KeyType chassis_key(ManagedType::kManagedAssociatedSubtree, | |
| "system1/chassis_power", "/xyz/openbmc_project/state", 0, | |
| {"xyz.openbmc_project.State.Chassis"}); | |
| dbus::utility::MapperGetSubTreeResponse mockChassisSubtree; | |
| ASSERT_TRUE( | |
| dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| chassis_key, managedStore::MockManagedStoreTest::CreateValueType( | |
| std::move(mockChassisSubtree))) | |
| .ok()); | |
| handleComputerSystem(share_async_resp_, "system1", "system1", true); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["PowerState"], "Unknown"); | |
| EXPECT_EQ(json["Status"]["State"], "Unknown"); | |
| EXPECT_EQ(json["LastResetTime"], "Unknown"); | |
| } | |
| TEST_F(SystemResetSnapshotFixture, | |
| PostSystemResetSingleSystemChassisResetOnSuccessDelay) { | |
| SetupDbusMockIfNeeded(); | |
| SubprocessUtilsFake subprocessUtilsFake; | |
| SubprocessUtilsBase::setInstance( | |
| std::make_unique<SubprocessUtilsFake>(subprocessUtilsFake)); | |
| handlePostComputerSystemReset( | |
| app_, CreateRequest("{\"ResetType\":\"ForceOff\", \"Delay\":1} "), | |
| share_async_resp_, GetTestSystemName()); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | |
| EXPECT_EQ(share_async_resp_->res.jsonValue["ResetString"], | |
| "systemd-run --on-active=1 --timer-property=AccuracySec=100ms -- " | |
| "curl -d {\"ResetType\":\"ForceOff\"} -H Content-Type: " | |
| "application/json -X POST " | |
| "localhost:80/redfish/v1/Systems/" + | |
| GetTestSystemName() + "/Actions/ComputerSystem.Reset"); | |
| } | |
| TEST_F(SystemResetSnapshotFixture, | |
| PostSystemResetSingleSystemChassisResetOnFailTimeDelay) { | |
| SetupDbusMockIfNeeded(); | |
| handlePostComputerSystemReset( | |
| app_, CreateRequest("{\"ResetType\":\"ForceOff\", \"Delay\":901} "), | |
| share_async_resp_, GetTestSystemName()); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::bad_request); | |
| } | |
| TEST_F(SystemResetSnapshotFixture, | |
| PostSystemResetSingleSystemChassisResetOnFailTypeDelay) { | |
| SetupDbusMockIfNeeded(); | |
| handlePostComputerSystemReset( | |
| app_, CreateRequest("{\"ResetType\":\"PleaseReset\", \"Delay\":1} "), | |
| share_async_resp_, GetTestSystemName()); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::bad_request); | |
| } | |
| TEST_F(SnapshotFixture, HandleGetSystemBootGuestOSInfo) { | |
| handleGetSystemBootGuestOSInfo(app_, CreateRequest(""), share_async_resp_, | |
| "system2"); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["@odata.id"], | |
| "/redfish/v1/System/system2/Oem/Google/BootGuestOSActionInfo"); | |
| } | |
| TEST_F(SnapshotFixture, handleGetBareMetalInstanceBase) { | |
| handleGetBareMetalInstance(app_, CreateRequest(""), share_async_resp_, | |
| "system1"); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["@odata.id"], | |
| "/redfish/v1/Systems/system1/Oem/Google/BareMetalInstance"); | |
| EXPECT_EQ(json["@odata.type"], | |
| "#GoogleBareMetalInstance.v1_0_0.GoogleBareMetalInstance"); | |
| } | |
| TEST_F(SystemResetSnapshotFixture, HandleGetBootNumber) { | |
| SetupDbusMockIfNeeded(); | |
| std::string biosPath = | |
| #ifdef BMCWEB_ALLOW_NON_HARDCODED_SINGLEHOST_SYSTEM | |
| "/xyz/openbmc_project/inventory/system1/chassis/motherboard/bios"; | |
| #else | |
| "/xyz/openbmc_project/inventory/system/chassis/motherboard/bios"; | |
| #endif | |
| KeyType key(ManagedType::kManagedProperty, | |
| "xyz.openbmc_project.Smbios.MDR_V2", | |
| sdbusplus::message::object_path(biosPath), | |
| "xyz.openbmc_project.State.Host", "BootCount"); | |
| uint32_t staleNum = 999; | |
| std::shared_ptr<ValueType> staleBootCountValue = | |
| managedStore::MockManagedStoreTest::CreateValueType(std::move(staleNum)); | |
| ASSERT_TRUE( | |
| dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore(key, staleBootCountValue) | |
| .ok()); | |
| EXPECT_CALL( | |
| *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()), | |
| PostDbusCallToIoContextThreadSafe( | |
| _, | |
| An<absl::AnyInvocable<void(const boost::system::error_code&, | |
| const DbusVariantType&)>&&>(), | |
| "xyz.openbmc_project.Smbios.MDR_V2", biosPath, | |
| "org.freedesktop.DBus.Properties", "Get", | |
| "xyz.openbmc_project.State.Host", "BootCount")) | |
| .Times(1) | |
| .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeWithValueAction< | |
| DbusVariantType>:: | |
| SimulateSuccessfulAsyncPostDbusCallWithValue( | |
| std::make_shared<DbusVariantType>(uint32_t{1000}))); | |
| handleGetBootNumber(app_, CreateRequest(""), share_async_resp_, | |
| GetTestSystemName()); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["@odata.id"], "/redfish/v1/Systems/" + GetTestSystemName() + | |
| "/Oem/Google/BootNumber"); | |
| EXPECT_EQ(json["@odata.type"], "#GoogleBootNumber.v1_0_0.GoogleBootNumber"); | |
| EXPECT_TRUE(json.contains("BootNumber")); | |
| EXPECT_EQ(json["BootNumber"], 1000); | |
| } | |
| TEST_F(SystemResetSnapshotFixture, HandleGetBootNumberOnDBusCallFailed) { | |
| SetupDbusMockIfNeeded(); | |
| std::string biosPath = | |
| #ifdef BMCWEB_ALLOW_NON_HARDCODED_SINGLEHOST_SYSTEM | |
| "/xyz/openbmc_project/inventory/system1/chassis/motherboard/bios"; | |
| #else | |
| "/xyz/openbmc_project/inventory/system/chassis/motherboard/bios"; | |
| #endif | |
| EXPECT_CALL( | |
| *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()), | |
| PostDbusCallToIoContextThreadSafe( | |
| _, | |
| An<absl::AnyInvocable<void(const boost::system::error_code&, | |
| const DbusVariantType&)>&&>(), | |
| "xyz.openbmc_project.Smbios.MDR_V2", biosPath, | |
| "org.freedesktop.DBus.Properties", "Get", | |
| "xyz.openbmc_project.State.Host", "BootCount")) | |
| .Times(1) | |
| .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeWithEmptyValueAction:: | |
| SimulateFailedAsyncPostDbusCallWithEmptyValue()); | |
| handleGetBootNumber(app_, CreateRequest(""), share_async_resp_, | |
| GetTestSystemName()); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["@odata.id"], "/redfish/v1/Systems/" + GetTestSystemName() + | |
| "/Oem/Google/BootNumber"); | |
| EXPECT_EQ(json["@odata.type"], "#GoogleBootNumber.v1_0_0.GoogleBootNumber"); | |
| EXPECT_FALSE(json.contains("BootNumber")); | |
| } | |
| TEST_F(SnapshotFixture, SingleHostPlatformIncludesBios) { | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_TRUE(json.contains("Bios")); | |
| EXPECT_EQ(json["Bios"]["@odata.id"], "/redfish/v1/Systems/system/Bios"); | |
| } | |
| TEST(SystemsTest, SetAndGetBootOrder) { | |
| const std::string biosSettingFile = "/tmp/oem_bios_setting.test"; | |
| // Ensure file is removed before and after test | |
| std::remove(biosSettingFile.c_str()); | |
| auto cleanup = | |
| absl::MakeCleanup([&]() { std::remove(biosSettingFile.c_str()); }); | |
| auto asyncResp = std::make_shared<bmcweb::AsyncResp>(); | |
| // Test setting the boot order | |
| std::vector<std::string> bootOrderToWrite = {"Boot0001", "Boot0000", | |
| "Boot0028"}; | |
| setBootOrder(asyncResp, bootOrderToWrite, biosSettingFile); | |
| // Verify the file content | |
| std::ifstream fileIn(biosSettingFile, std::ios::binary); | |
| ASSERT_TRUE(fileIn.is_open()); | |
| std::vector<uint16_t> bootIndices; | |
| uint16_t index; | |
| while (fileIn.read(reinterpret_cast<char*>(&index), sizeof(index))) { | |
| bootIndices.push_back(index); | |
| } | |
| fileIn.close(); | |
| ASSERT_EQ(bootIndices.size(), 3); | |
| EXPECT_EQ(bootIndices[0], 1); | |
| EXPECT_EQ(bootIndices[1], 0); | |
| EXPECT_EQ(bootIndices[2], 0x28); | |
| // Test getting the boot order | |
| asyncResp->res.clear(); | |
| getBootOrder(asyncResp, biosSettingFile); | |
| EXPECT_EQ(asyncResp->res.jsonValue["Boot"]["BootOrder"], bootOrderToWrite); | |
| } | |
| TEST(SystemsTest, SetAndGetBootOrderHex) { | |
| const std::string biosSettingFile = "/tmp/oem_bios_setting.test"; | |
| // Ensure file is removed before and after test | |
| std::remove(biosSettingFile.c_str()); | |
| auto cleanup = | |
| absl::MakeCleanup([&]() { std::remove(biosSettingFile.c_str()); }); | |
| auto asyncResp = std::make_shared<bmcweb::AsyncResp>(); | |
| // Test setting the boot order | |
| std::vector<std::string> bootOrderToWrite = {"Boot0001", "Boot0000", | |
| "BootFFFE"}; | |
| setBootOrder(asyncResp, bootOrderToWrite, biosSettingFile); | |
| // Verify the file content | |
| std::ifstream fileIn(biosSettingFile, std::ios::binary); | |
| ASSERT_TRUE(fileIn.is_open()); | |
| std::vector<uint16_t> bootIndices; | |
| uint16_t index; | |
| while (fileIn.read(reinterpret_cast<char*>(&index), sizeof(index))) { | |
| bootIndices.push_back(index); | |
| } | |
| fileIn.close(); | |
| ASSERT_EQ(bootIndices.size(), 3); | |
| EXPECT_EQ(bootIndices[0], 1); | |
| EXPECT_EQ(bootIndices[1], 0); | |
| EXPECT_EQ(bootIndices[2], 0xFFFE); | |
| // Test getting the boot order | |
| asyncResp->res.clear(); | |
| getBootOrder(asyncResp, biosSettingFile); | |
| EXPECT_EQ(asyncResp->res.jsonValue["Boot"]["BootOrder"], bootOrderToWrite); | |
| } | |
| TEST(SystemsTest, SetBootOrderInvalidFormat) { | |
| const std::string biosSettingFile = "/tmp/oem_bios_setting.test"; | |
| std::remove(biosSettingFile.c_str()); | |
| auto cleanup = | |
| absl::MakeCleanup([&]() { std::remove(biosSettingFile.c_str()); }); | |
| auto asyncResp = std::make_shared<bmcweb::AsyncResp>(); | |
| std::vector<std::string> bootOrderToWrite = {"InvalidBoot0001"}; | |
| setBootOrder(asyncResp, bootOrderToWrite, biosSettingFile); | |
| // Expect an error message | |
| EXPECT_EQ(asyncResp->res.result(), boost::beast::http::status::bad_request); | |
| // File should not have been created or should be empty | |
| std::ifstream fileIn(biosSettingFile, std::ios::binary | std::ios::ate); | |
| EXPECT_TRUE(!fileIn.is_open() || fileIn.tellg() == 0); | |
| } | |
| TEST(SystemsTest, SetBootOrderIndexOutOfRange) { | |
| const std::string biosSettingFile = "/tmp/oem_bios_setting.test"; | |
| std::remove(biosSettingFile.c_str()); | |
| auto cleanup = | |
| absl::MakeCleanup([&]() { std::remove(biosSettingFile.c_str()); }); | |
| auto asyncResp = std::make_shared<bmcweb::AsyncResp>(); | |
| std::vector<std::string> bootOrderToWrite = {"Boot99999"}; | |
| setBootOrder(asyncResp, bootOrderToWrite, biosSettingFile); | |
| // Expect an error message | |
| EXPECT_EQ(asyncResp->res.result(), boost::beast::http::status::bad_request); | |
| // File should not have been created or should be empty | |
| std::ifstream fileIn(biosSettingFile, std::ios::binary | std::ios::ate); | |
| EXPECT_TRUE(!fileIn.is_open() || fileIn.tellg() == 0); | |
| } | |
| TEST(SystemsTest, SetBootOrderMixedCaseHex) { | |
| const std::string biosSettingFile = "/tmp/oem_bios_setting.test"; | |
| // Ensure file is removed before and after test | |
| std::remove(biosSettingFile.c_str()); | |
| auto cleanup = | |
| absl::MakeCleanup([&]() { std::remove(biosSettingFile.c_str()); }); | |
| auto asyncResp = std::make_shared<bmcweb::AsyncResp>(); | |
| // Test setting the boot order with mixed-case hex values | |
| std::vector<std::string> bootOrderToWrite = {"Boot000f", "Boot0E40"}; | |
| setBootOrder(asyncResp, bootOrderToWrite, biosSettingFile); | |
| // Verify the file content | |
| std::ifstream fileIn(biosSettingFile, std::ios::binary); | |
| ASSERT_TRUE(fileIn.is_open()); | |
| std::vector<uint16_t> bootIndices; | |
| uint16_t index; | |
| while (fileIn.read(reinterpret_cast<char*>(&index), sizeof(index))) { | |
| bootIndices.push_back(index); | |
| } | |
| fileIn.close(); | |
| ASSERT_EQ(bootIndices.size(), 2); | |
| EXPECT_EQ(bootIndices[0], 0x000f); | |
| EXPECT_EQ(bootIndices[1], 0x0e40); | |
| // Test getting the boot order | |
| asyncResp->res.clear(); | |
| getBootOrder(asyncResp, biosSettingFile); | |
| // getBootOrder normalizes to uppercase hex | |
| std::vector<std::string> expectedBootOrder = {"Boot000F", "Boot0E40"}; | |
| EXPECT_EQ(asyncResp->res.jsonValue["Boot"]["BootOrder"], expectedBootOrder); | |
| } | |
| TEST(SystemsTest, GetBiosSettingPath) { | |
| absl::StatusOr<std::string> path1 = getBiosSettingPath("system"); | |
| ASSERT_TRUE(path1.ok()); | |
| EXPECT_EQ(*path1, "/var/google/oem_bios_setting"); | |
| absl::StatusOr<std::string> path2 = getBiosSettingPath("system1"); | |
| ASSERT_TRUE(path2.ok()); | |
| EXPECT_EQ(*path2, "/var/google/system1/oem_bios_setting"); | |
| absl::StatusOr<std::string> path3 = getBiosSettingPath("system2"); | |
| ASSERT_TRUE(path3.ok()); | |
| EXPECT_EQ(*path3, "/var/google/system2/oem_bios_setting"); | |
| absl::StatusOr<std::string> path4 = getBiosSettingPath("unknown_system"); | |
| ASSERT_FALSE(path4.ok()); | |
| EXPECT_EQ(path4.status().code(), absl::StatusCode::kInvalidArgument); | |
| } | |
| #ifdef ENABLE_REDFISH_CONFIGURE_IFS | |
| TEST_F(SnapshotFixture, GetIfsPropertiesPresent) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBase64EncodedIfsPattern("system1")) | |
| .WillOnce(::testing::Return("SGVsbG8h")); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "system1", "system1", true); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Actions"]["Oem"]["Google"] | |
| ["#GoogleComputerSystem.ResetCpuIfsPattern"]["target"], | |
| "/redfish/v1/Systems/system1/Actions/Oem/" | |
| "GoogleComputerSystem.ResetCpuIfsPattern"); | |
| EXPECT_EQ(json["Oem"]["Google"]["CpuIfsPatternBase64"], "SGVsbG8h"); | |
| } | |
| TEST_F(SnapshotFixture, GetIfsPropertiesEmptyPattern) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBase64EncodedIfsPattern("system1")) | |
| .WillOnce(::testing::Return("")); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "system1", "system1", true); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Oem"]["Google"]["CpuIfsPatternBase64"], ""); | |
| } | |
| TEST_F(SnapshotFixture, GetIfsPropertiesErrorFallback) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBase64EncodedIfsPattern("system1")) | |
| .WillOnce( | |
| ::testing::Return(absl::InternalError("Simulated internal error"))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "system1", "system1", true); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| #else | |
| TEST_F(SnapshotFixture, GetIfsPropertiesFlagOff) { | |
| handleComputerSystem(share_async_resp_, "system1", "system1", true); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_FALSE(json.contains("Actions") && json["Actions"].contains("Oem") && | |
| json["Actions"]["Oem"].contains("Google") && | |
| json["Actions"]["Oem"]["Google"].contains( | |
| "#GoogleComputerSystem.ResetCpuIfsPattern")); | |
| EXPECT_FALSE(json.contains("Oem") && json["Oem"].contains("Google") && | |
| json["Oem"]["Google"].contains("CpuIfsPatternBase64")); | |
| } | |
| #endif | |
| #ifdef BMCWEB_ALLOW_NON_HARDCODED_SINGLEHOST_SYSTEM | |
| TEST_F(SnapshotFixture, HandleGetSystemsCollectionSingleHostFallbackDisabled) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system1"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| handleGetSystemsCollection(app_, CreateRequest(""), share_async_resp_); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Members"].size(), 1); | |
| EXPECT_EQ(json["Members"][0]["@odata.id"], "/redfish/v1/Systems/system1"); | |
| } | |
| #endif | |
| TEST_F(SnapshotFixture, GetBootNextPresent) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootNext("system")) | |
| .WillOnce(::testing::Return("Boot0001")); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootNext"], "Boot0001"); | |
| } | |
| TEST_F(SnapshotFixture, GetBootNextNotFound) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootNext("system")) | |
| .WillOnce(::testing::Return(absl::NotFoundError(""))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_FALSE(json["Boot"].contains("BootNext")); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootNext) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, SetBootNext("system", "Boot0002")) | |
| .WillOnce(::testing::Return(absl::OkStatus())); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest("{\"Boot\": {\"BootNext\": \"Boot0002\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::no_content); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootNextRegistryNull) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(nullptr); | |
| crow::Request req = CreateRequest("{\"Boot\": {\"BootNext\": \"Boot0002\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootNextSetFailed) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, SetBootNext("system", "Boot0002")) | |
| .WillOnce(::testing::Return( | |
| absl::InternalError("Simulated write failure"))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest("{\"Boot\": {\"BootNext\": \"Boot0002\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, GetBootSourceOverrideTargetPresent) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootSourceOverrideTarget("system")) | |
| .WillOnce( | |
| ::testing::Return(BootSourceOverrideTarget:: | |
| BOOT_SOURCE_OVERRIDE_TARGET_UEFI_BOOT_NEXT)); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideTarget"], "UefiBootNext"); | |
| std::vector<std::string> expectedAllowableValues = {"None", "UefiBootNext", | |
| "Diags", "UefiHttp"}; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"], | |
| expectedAllowableValues); | |
| } | |
| TEST_F(SnapshotFixture, GetBootSourceOverrideTargetNotFound) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootSourceOverrideTarget("system")) | |
| .WillOnce(::testing::Return(absl::NotFoundError(""))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideTarget"], "None"); | |
| std::vector<std::string> expectedAllowableValues = {"None", "UefiBootNext", | |
| "Diags", "UefiHttp"}; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"], | |
| expectedAllowableValues); | |
| } | |
| TEST_F(SnapshotFixture, GetBootSourceOverrideTargetUnspecified) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootSourceOverrideTarget("system")) | |
| .WillOnce(::testing::Return( | |
| BootSourceOverrideTarget::BOOT_SOURCE_OVERRIDE_TARGET_UNSPECIFIED)); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideTarget"], "None"); | |
| std::vector<std::string> expectedAllowableValues = {"None", "UefiBootNext", | |
| "Diags", "UefiHttp"}; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"], | |
| expectedAllowableValues); | |
| } | |
| TEST_F(SnapshotFixture, GetBootSourceOverrideTargetDiags) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootSourceOverrideTarget("system")) | |
| .WillOnce(::testing::Return( | |
| BootSourceOverrideTarget::BOOT_SOURCE_OVERRIDE_TARGET_DIAGS)); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideTarget"], "Diags"); | |
| } | |
| TEST_F(SnapshotFixture, GetBootSourceOverrideTargetUefiHttp) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootSourceOverrideTarget("system")) | |
| .WillOnce(::testing::Return( | |
| BootSourceOverrideTarget::BOOT_SOURCE_OVERRIDE_TARGET_UEFI_HTTP)); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideTarget"], "UefiHttp"); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideTarget) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL( | |
| *mock_registry, | |
| SetBootSourceOverrideTarget( | |
| "system", | |
| BootSourceOverrideTarget::BOOT_SOURCE_OVERRIDE_TARGET_UEFI_BOOT_NEXT)) | |
| .WillOnce(::testing::Return(absl::OkStatus())); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"Boot\": {\"BootSourceOverrideTarget\": \"UefiBootNext\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::no_content); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideTargetNone) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL( | |
| *mock_registry, | |
| SetBootSourceOverrideTarget( | |
| "system", | |
| BootSourceOverrideTarget::BOOT_SOURCE_OVERRIDE_TARGET_UNSPECIFIED)) | |
| .WillOnce(::testing::Return(absl::OkStatus())); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = | |
| CreateRequest("{\"Boot\": {\"BootSourceOverrideTarget\": \"None\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::no_content); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideTargetDiags) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, | |
| SetBootSourceOverrideTarget( | |
| "system", | |
| BootSourceOverrideTarget::BOOT_SOURCE_OVERRIDE_TARGET_DIAGS)) | |
| .WillOnce(::testing::Return(absl::OkStatus())); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = | |
| CreateRequest("{\"Boot\": {\"BootSourceOverrideTarget\": \"Diags\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::no_content); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideTargetUefiHttp) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL( | |
| *mock_registry, | |
| SetBootSourceOverrideTarget( | |
| "system", | |
| BootSourceOverrideTarget::BOOT_SOURCE_OVERRIDE_TARGET_UEFI_HTTP)) | |
| .WillOnce(::testing::Return(absl::OkStatus())); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = | |
| CreateRequest("{\"Boot\": {\"BootSourceOverrideTarget\": \"UefiHttp\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::no_content); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideTargetInvalidValue) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, SetBootSourceOverrideTarget).Times(0); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"Boot\": {\"BootSourceOverrideTarget\": \"InvalidTarget\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::bad_request); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideTargetSetFailed) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL( | |
| *mock_registry, | |
| SetBootSourceOverrideTarget( | |
| "system", | |
| BootSourceOverrideTarget::BOOT_SOURCE_OVERRIDE_TARGET_UEFI_BOOT_NEXT)) | |
| .WillOnce( | |
| ::testing::Return(absl::InternalError("Simulated write failure"))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"Boot\": {\"BootSourceOverrideTarget\": \"UefiBootNext\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, GetBootSourceOverrideEnabledPresent) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootSourceOverrideEnabled("system")) | |
| .WillOnce(::testing::Return( | |
| BootSourceOverrideEnabled::BOOT_SOURCE_OVERRIDE_ENABLED_ONCE)); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideEnabled"], "Once"); | |
| std::vector<std::string> expectedAllowableValues = {"Disabled", "Once", | |
| "Continuous"}; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideEnabled@Redfish.AllowableValues"], | |
| expectedAllowableValues); | |
| } | |
| TEST_F(SnapshotFixture, GetBootSourceOverrideEnabledContinuous) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootSourceOverrideEnabled("system")) | |
| .WillOnce(::testing::Return( | |
| BootSourceOverrideEnabled::BOOT_SOURCE_OVERRIDE_ENABLED_CONTINUOUS)); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideEnabled"], "Continuous"); | |
| } | |
| TEST_F(SnapshotFixture, GetBootSourceOverrideEnabledNotFound) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootSourceOverrideEnabled("system")) | |
| .WillOnce(::testing::Return(absl::NotFoundError(""))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideEnabled"], "Disabled"); | |
| std::vector<std::string> expectedAllowableValues = {"Disabled", "Once", | |
| "Continuous"}; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideEnabled@Redfish.AllowableValues"], | |
| expectedAllowableValues); | |
| } | |
| TEST_F(SnapshotFixture, GetBootSourceOverrideEnabledUnspecified) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootSourceOverrideEnabled("system")) | |
| .WillOnce(::testing::Return( | |
| BootSourceOverrideEnabled::BOOT_SOURCE_OVERRIDE_ENABLED_UNSPECIFIED)); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideEnabled"], "Disabled"); | |
| std::vector<std::string> expectedAllowableValues = {"Disabled", "Once", | |
| "Continuous"}; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideEnabled@Redfish.AllowableValues"], | |
| expectedAllowableValues); | |
| } | |
| TEST_F(SnapshotFixture, GetBootSourceOverrideEnabledDisabled) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootSourceOverrideEnabled("system")) | |
| .WillOnce(::testing::Return( | |
| BootSourceOverrideEnabled::BOOT_SOURCE_OVERRIDE_ENABLED_DISABLED)); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootSourceOverrideEnabled"], "Disabled"); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideEnabledOnce) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, | |
| SetBootSourceOverrideEnabled( | |
| "system", | |
| BootSourceOverrideEnabled::BOOT_SOURCE_OVERRIDE_ENABLED_ONCE)) | |
| .WillOnce(::testing::Return(absl::OkStatus())); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = | |
| CreateRequest("{\"Boot\": {\"BootSourceOverrideEnabled\": \"Once\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::no_content); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideEnabledContinuous) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL( | |
| *mock_registry, | |
| SetBootSourceOverrideEnabled( | |
| "system", | |
| BootSourceOverrideEnabled::BOOT_SOURCE_OVERRIDE_ENABLED_CONTINUOUS)) | |
| .WillOnce(::testing::Return(absl::OkStatus())); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"Boot\": {\"BootSourceOverrideEnabled\": \"Continuous\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::no_content); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideEnabledDisabled) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL( | |
| *mock_registry, | |
| SetBootSourceOverrideEnabled( | |
| "system", | |
| BootSourceOverrideEnabled::BOOT_SOURCE_OVERRIDE_ENABLED_DISABLED)) | |
| .WillOnce(::testing::Return(absl::OkStatus())); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"Boot\": {\"BootSourceOverrideEnabled\": \"Disabled\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::no_content); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideEnabledInvalidValue) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, SetBootSourceOverrideEnabled).Times(0); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"Boot\": {\"BootSourceOverrideEnabled\": \"InvalidValue\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::bad_request); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideEnabledSetFailed) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, | |
| SetBootSourceOverrideEnabled( | |
| "system", | |
| BootSourceOverrideEnabled::BOOT_SOURCE_OVERRIDE_ENABLED_ONCE)) | |
| .WillOnce( | |
| ::testing::Return(absl::InternalError("Simulated write failure"))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = | |
| CreateRequest("{\"Boot\": {\"BootSourceOverrideEnabled\": \"Once\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootSourceOverrideEnabledRegistryNull) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(nullptr); | |
| crow::Request req = | |
| CreateRequest("{\"Boot\": {\"BootSourceOverrideEnabled\": \"Once\"}}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchComputerSystemCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, GetComputerSystemPopulatesBootOptionsLink) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| handleComputerSystem(share_async_resp_, "", "system", false); | |
| RunIoUntilDone(); | |
| nlohmann::json& json = share_async_resp_->res.jsonValue; | |
| EXPECT_EQ(json["Boot"]["BootOptions"]["@odata.id"], | |
| "/redfish/v1/Systems/system/Boot/BootOptions"); | |
| } | |
| TEST_F(SnapshotFixture, GetBootOptionCollectionEmpty) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootOptions("system")) | |
| .WillOnce(::testing::Return(std::vector<BootOption>{})); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest(); | |
| handleGetBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | |
| EXPECT_EQ(share_async_resp_->res.jsonValue, nlohmann::json::parse(R"json({ | |
| "@odata.id": "/redfish/v1/Systems/system/Boot/BootOptions", | |
| "@odata.type": "#BootOptionCollection.BootOptionCollection", | |
| "Name": "Boot Option Collection", | |
| "Description": "Collection of UEFI Boot Options", | |
| "Members@odata.count": 0, | |
| "Members": [] | |
| })json")); | |
| } | |
| TEST_F(SnapshotFixture, GetBootOptionCollectionRegistryNull) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(nullptr); | |
| crow::Request req = CreateRequest(); | |
| handleGetBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, GetBootOptionCollectionRegistryError) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootOptions("system")) | |
| .WillOnce(::testing::Return(absl::InternalError("Simulated failure"))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest(); | |
| handleGetBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, GetBootOptionCollectionSuccess) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| BootOption boot_option_1; | |
| ASSERT_TRUE( | |
| google::protobuf::TextFormat::ParseFromString(R"pb( | |
| boot_option_reference: "Boot0001" | |
| display_name: "UEFI: PXE IPv4" | |
| boot_option_enabled: true | |
| )pb", | |
| &boot_option_1)); | |
| BootOption boot_option_2; | |
| ASSERT_TRUE( | |
| google::protobuf::TextFormat::ParseFromString(R"pb( | |
| boot_option_reference: "Boot0002" | |
| display_name: "UEFI: NVMe0" | |
| boot_option_enabled: false | |
| )pb", | |
| &boot_option_2)); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootOptions("system")) | |
| .WillOnce(::testing::Return( | |
| std::vector<BootOption>{boot_option_1, boot_option_2})); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest(); | |
| handleGetBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | |
| EXPECT_EQ(share_async_resp_->res.jsonValue, nlohmann::json::parse(R"json({ | |
| "@odata.id": "/redfish/v1/Systems/system/Boot/BootOptions", | |
| "@odata.type": "#BootOptionCollection.BootOptionCollection", | |
| "Name": "Boot Option Collection", | |
| "Description": "Collection of UEFI Boot Options", | |
| "Members@odata.count": 2, | |
| "Members": [ | |
| {"@odata.id": "/redfish/v1/Systems/system/Boot/BootOptions/Boot0001"}, | |
| {"@odata.id": "/redfish/v1/Systems/system/Boot/BootOptions/Boot0002"} | |
| ] | |
| })json")); | |
| } | |
| TEST_F(SnapshotFixture, GetBootOptionCollectionMultiHost) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system/board/mb1/system1", | |
| "/xyz/openbmc_project/inventory/system/board/mb2/system2"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| BootOption boot_option; | |
| ASSERT_TRUE( | |
| google::protobuf::TextFormat::ParseFromString(R"pb( | |
| boot_option_reference: "Boot0001" | |
| display_name: "Host 1 PXE" | |
| boot_option_enabled: true | |
| )pb", | |
| &boot_option)); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootOptions("system1")) | |
| .WillOnce(::testing::Return(std::vector<BootOption>{boot_option})); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest(); | |
| handleGetBootOptionCollection(app_, req, share_async_resp_, "system1"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | |
| EXPECT_EQ(share_async_resp_->res.jsonValue, nlohmann::json::parse(R"json({ | |
| "@odata.id": "/redfish/v1/Systems/system1/Boot/BootOptions", | |
| "@odata.type": "#BootOptionCollection.BootOptionCollection", | |
| "Name": "Boot Option Collection", | |
| "Description": "Collection of UEFI Boot Options", | |
| "Members@odata.count": 1, | |
| "Members": [ | |
| {"@odata.id": "/redfish/v1/Systems/system1/Boot/BootOptions/Boot0001"} | |
| ] | |
| })json")); | |
| } | |
| TEST_F(SnapshotFixture, PostBootOptionCollectionSuccess) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| BootOption expected; | |
| ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( | |
| R"pb( | |
| boot_option_reference: "Boot0001" | |
| display_name: "UEFI: PXE IPv4" | |
| boot_option_enabled: true | |
| uefi_device_path: "PciRoot(0x0)/Pci(0x1,0x0)" | |
| )pb", | |
| &expected)); | |
| BootOption actual; | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, AddBootOption("system", _)) | |
| .WillOnce(::testing::DoAll(::testing::SaveArg<1>(&actual), | |
| ::testing::Return(absl::OkStatus()))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"BootOptionReference\": \"Boot0001\", " | |
| "\"DisplayName\": \"UEFI: PXE IPv4\", " | |
| "\"BootOptionEnabled\": true, " | |
| "\"UefiDevicePath\": \"PciRoot(0x0)/Pci(0x1,0x0)\"}"); | |
| req.req.method(boost::beast::http::verb::post); | |
| handlePostBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::created); | |
| EXPECT_EQ(share_async_resp_->res.getHeaderValue("Location"), | |
| "/redfish/v1/Systems/system/Boot/BootOptions/Boot0001"); | |
| EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(expected, actual)); | |
| } | |
| TEST_F(SnapshotFixture, PostBootOptionCollectionDefaultEnabled) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| BootOption expected; | |
| ASSERT_TRUE( | |
| google::protobuf::TextFormat::ParseFromString(R"pb( | |
| boot_option_reference: "Boot0001" | |
| display_name: "UEFI: PXE IPv4" | |
| boot_option_enabled: true | |
| )pb", | |
| &expected)); | |
| BootOption actual; | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, AddBootOption("system", _)) | |
| .WillOnce(::testing::DoAll(::testing::SaveArg<1>(&actual), | |
| ::testing::Return(absl::OkStatus()))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"BootOptionReference\": \"Boot0001\", " | |
| "\"DisplayName\": \"UEFI: PXE IPv4\"}"); | |
| req.req.method(boost::beast::http::verb::post); | |
| handlePostBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::created); | |
| EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(expected, actual)); | |
| } | |
| TEST_F(SnapshotFixture, PostBootOptionCollectionIgnoresOdataAnnotations) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| BootOption expected; | |
| ASSERT_TRUE( | |
| google::protobuf::TextFormat::ParseFromString(R"pb( | |
| boot_option_reference: "Boot0001" | |
| display_name: "UEFI: PXE IPv4" | |
| boot_option_enabled: true | |
| )pb", | |
| &expected)); | |
| BootOption actual; | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, AddBootOption("system", _)) | |
| .WillOnce(::testing::DoAll(::testing::SaveArg<1>(&actual), | |
| ::testing::Return(absl::OkStatus()))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest(R"json({ | |
| "@odata.type": "#BootOption.v1_0_4.BootOption", | |
| "BootOptionReference": "Boot0001", | |
| "DisplayName": "UEFI: PXE IPv4" | |
| })json"); | |
| req.req.method(boost::beast::http::verb::post); | |
| handlePostBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::created); | |
| EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(expected, actual)); | |
| } | |
| TEST_F(SnapshotFixture, PostBootOptionCollectionConflict) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, AddBootOption("system", _)) | |
| .WillOnce( | |
| ::testing::Return(absl::AlreadyExistsError("Duplicate Boot0001"))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"BootOptionReference\": \"Boot0001\", " | |
| "\"DisplayName\": \"UEFI: PXE IPv4\"}"); | |
| req.req.method(boost::beast::http::verb::post); | |
| handlePostBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::conflict); | |
| } | |
| TEST_F(SnapshotFixture, PostBootOptionCollectionMissingRequiredField) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, AddBootOption).Times(0); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest("{\"BootOptionReference\": \"Boot0001\"}"); | |
| req.req.method(boost::beast::http::verb::post); | |
| handlePostBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::bad_request); | |
| } | |
| TEST_F(SnapshotFixture, PostBootOptionCollectionEmptyReference) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, AddBootOption).Times(0); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"BootOptionReference\": \"\", " | |
| "\"DisplayName\": \"UEFI: PXE IPv4\"}"); | |
| req.req.method(boost::beast::http::verb::post); | |
| handlePostBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::bad_request); | |
| } | |
| TEST(ParseBootReferenceTest, ValidReferences) { | |
| EXPECT_EQ(parseBootReference("Boot0001"), 0x0001); | |
| EXPECT_EQ(parseBootReference("Boot000A"), 0x000A); | |
| EXPECT_EQ(parseBootReference("Bootffff"), 0xFFFF); | |
| } | |
| TEST(ParseBootReferenceTest, InvalidReferences) { | |
| EXPECT_EQ(parseBootReference(""), std::nullopt); | |
| EXPECT_EQ(parseBootReference("Boot"), std::nullopt); | |
| EXPECT_EQ(parseBootReference("foo"), std::nullopt); | |
| EXPECT_EQ(parseBootReference("BootXYZ"), std::nullopt); | |
| EXPECT_EQ(parseBootReference("Boot0001x"), std::nullopt); | |
| EXPECT_EQ(parseBootReference("Boot10000"), std::nullopt); | |
| } | |
| TEST_F(SnapshotFixture, PostBootOptionCollectionReferenceMissingBootPrefix) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, AddBootOption).Times(0); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"BootOptionReference\": \"foo\", " | |
| "\"DisplayName\": \"UEFI: PXE IPv4\"}"); | |
| req.req.method(boost::beast::http::verb::post); | |
| handlePostBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::bad_request); | |
| } | |
| TEST_F(SnapshotFixture, PostBootOptionCollectionReferenceNonHexSuffix) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, AddBootOption).Times(0); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest( | |
| "{\"BootOptionReference\": \"BootXYZ\", " | |
| "\"DisplayName\": \"UEFI: PXE IPv4\"}"); | |
| req.req.method(boost::beast::http::verb::post); | |
| handlePostBootOptionCollection(app_, req, share_async_resp_, "system"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::bad_request); | |
| } | |
| TEST_F(SnapshotFixture, GetBootOptionSuccess) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| BootOption boot_option; | |
| ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( | |
| R"pb( | |
| boot_option_reference: "Boot0001" | |
| display_name: "UEFI: PXE IPv4" | |
| boot_option_enabled: true | |
| uefi_device_path: "PciRoot(0x0)/Pci(0x1,0x0)" | |
| )pb", | |
| &boot_option)); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootOption("system", "Boot0001")) | |
| .WillOnce(::testing::Return(boot_option)); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest(); | |
| handleGetBootOption(app_, req, share_async_resp_, "system", "Boot0001"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | |
| EXPECT_EQ(share_async_resp_->res.jsonValue, nlohmann::json::parse(R"json({ | |
| "@odata.id": "/redfish/v1/Systems/system/Boot/BootOptions/Boot0001", | |
| "@odata.type": "#BootOption.v1_0_4.BootOption", | |
| "Id": "Boot0001", | |
| "Name": "Boot Option", | |
| "Description": "UEFI Boot Option", | |
| "BootOptionReference": "Boot0001", | |
| "DisplayName": "UEFI: PXE IPv4", | |
| "BootOptionEnabled": true, | |
| "UefiDevicePath": "PciRoot(0x0)/Pci(0x1,0x0)" | |
| })json")); | |
| } | |
| TEST_F(SnapshotFixture, GetBootOptionRegistryNull) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(nullptr); | |
| crow::Request req = CreateRequest(); | |
| handleGetBootOption(app_, req, share_async_resp_, "system", "Boot0001"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, GetBootOptionRegistryError) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootOption("system", "Boot0001")) | |
| .WillOnce(::testing::Return(absl::InternalError("Simulated failure"))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest(); | |
| handleGetBootOption(app_, req, share_async_resp_, "system", "Boot0001"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, GetBootOptionNotFound) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, GetBootOption("system", "Boot9999")) | |
| .WillOnce(::testing::Return(absl::NotFoundError("Not found"))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest(); | |
| handleGetBootOption(app_, req, share_async_resp_, "system", "Boot9999"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::not_found); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootOptionSuccess) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, | |
| UpdateBootOptionEnabled("system", "Boot0001", false)) | |
| .WillOnce(::testing::Return(absl::OkStatus())); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest("{\"BootOptionEnabled\": false}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchBootOption(app_, req, share_async_resp_, "system", "Boot0001"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::no_content); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootOptionRegistryNull) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(nullptr); | |
| crow::Request req = CreateRequest("{\"BootOptionEnabled\": false}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchBootOption(app_, req, share_async_resp_, "system", "Boot0001"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootOptionRegistryError) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, | |
| UpdateBootOptionEnabled("system", "Boot0001", false)) | |
| .WillOnce(::testing::Return(absl::InternalError("Simulated failure"))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest("{\"BootOptionEnabled\": false}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchBootOption(app_, req, share_async_resp_, "system", "Boot0001"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::internal_server_error); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootOptionNotFound) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, | |
| UpdateBootOptionEnabled("system", "Boot9999", false)) | |
| .WillOnce(::testing::Return(absl::NotFoundError("Not found"))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest("{\"BootOptionEnabled\": false}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchBootOption(app_, req, share_async_resp_, "system", "Boot9999"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::not_found); | |
| } | |
| TEST_F(SnapshotFixture, PatchBootOptionReadOnlyPropertyRejected) { | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, UpdateBootOptionEnabled).Times(0); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest("{\"DisplayName\": \"New Name\"}"); | |
| req.req.method(boost::beast::http::verb::patch); | |
| handlePatchBootOption(app_, req, share_async_resp_, "system", "Boot0001"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::bad_request); | |
| } | |
| TEST_F(SnapshotFixture, DeleteBootOptionSuccess) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, DeleteBootOption("system", "Boot0001")) | |
| .WillOnce(::testing::Return(absl::OkStatus())); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest(); | |
| req.req.method(boost::beast::http::verb::delete_); | |
| handleDeleteBootOption(app_, req, share_async_resp_, "system", "Boot0001"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::no_content); | |
| } | |
| TEST_F(SnapshotFixture, DeleteBootOptionNotFound) { | |
| managedStore::KeyType key(managedStore::ManagedType::kManagedSubtreePaths, | |
| "/", 0, | |
| {"xyz.openbmc_project.Inventory.Item.System"}); | |
| std::vector<std::string> mockSystems = { | |
| "/xyz/openbmc_project/inventory/system"}; | |
| ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>( | |
| managedStore::GetManagedObjectStore()) | |
| ->upsertMockObjectIntoManagedStore( | |
| key, managedStore::MockManagedStoreTest::CreateValueType( | |
| mockSystems)) | |
| .ok()); | |
| auto mock_registry = std::make_shared<MockSystemRegistry>(); | |
| EXPECT_CALL(*mock_registry, DeleteBootOption("system", "Boot9999")) | |
| .WillOnce(::testing::Return(absl::NotFoundError("Not found"))); | |
| managedStore::GetManagedObjectStore()->SetSystemRegistry(mock_registry); | |
| crow::Request req = CreateRequest(); | |
| req.req.method(boost::beast::http::verb::delete_); | |
| handleDeleteBootOption(app_, req, share_async_resp_, "system", "Boot9999"); | |
| RunIoUntilDone(); | |
| EXPECT_EQ(share_async_resp_->res.result(), | |
| boost::beast::http::status::not_found); | |
| } | |
| } // namespace | |
| } // namespace redfish |