|  | #include "absl/cleanup/cleanup.h" | 
|  | #include "app.hpp" | 
|  | #include "bmcweb_config.h" | 
|  |  | 
|  | #include "async_resp.hpp" | 
|  | #include "http_response.hpp" | 
|  | #include "nlohmann/json.hpp" | 
|  | #include "systems.hpp" | 
|  | #include "snapshot_fixture.hpp" | 
|  |  | 
|  | #include <memory> | 
|  | #include <vector> | 
|  |  | 
|  | #include <gmock/gmock.h> // IWYU pragma: keep | 
|  | #include <gtest/gtest.h> // IWYU pragma: keep | 
|  |  | 
|  | // IWYU pragma: no_include <gtest/gtest-message.h> | 
|  | // IWYU pragma: no_include <gtest/gtest-test-part.h> | 
|  | // IWYU pragma: no_include "gtest/gtest_pred_impl.h" | 
|  | // IWYU pragma: no_include <gmock/gmock-matchers.h> | 
|  | // IWYU pragma: no_include <gtest/gtest-matchers.h> | 
|  |  | 
|  | namespace redfish | 
|  | { | 
|  | namespace | 
|  | { | 
|  |  | 
|  | using ::dbus::utility::DbusVariantType; | 
|  | using ::managedStore::KeyType; | 
|  | using ::managedStore::ManagedObjectStoreContext; | 
|  | using ::managedStore::ManagedType; | 
|  | using ::managedStore::SimulateFailedAsyncPostDbusCallThreadSafeAction; | 
|  | using ::managedStore::SimulateSuccessfulAsyncPostDbusCallThreadSafeAction; | 
|  | using ::managedStore::ValueType; | 
|  | using ::testing::An; | 
|  | using ::testing::_; | 
|  |  | 
|  | 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"); | 
|  | allowableValues.emplace_back("ReallyGracefulShutDownTechDebt"); | 
|  | 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); | 
|  | } | 
|  |  | 
|  | 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); | 
|  | } | 
|  |  | 
|  | 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"); | 
|  | } | 
|  |  | 
|  | TEST_F(SnapshotFixture, PostSystemResetAsNMIOnDBusCallFailed){ | 
|  | EXPECT_CALL(*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_, "system"); | 
|  |  | 
|  | RunIoUntilDone(); | 
|  |  | 
|  | EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::internal_server_error); | 
|  | } | 
|  |  | 
|  | TEST_F(SnapshotFixture, PostSystemResetAsNMIOnDBusCallSuccess){ | 
|  | EXPECT_CALL(*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_, "system"); | 
|  |  | 
|  | RunIoUntilDone(); | 
|  |  | 
|  | EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | 
|  | } | 
|  |  | 
|  | TEST_F(SnapshotFixture, PostSystemResetSingleSystemHostResetOnFail){ | 
|  | EXPECT_CALL(*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_, "system"); | 
|  |  | 
|  | RunIoUntilDone(); | 
|  |  | 
|  | EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::internal_server_error); | 
|  | } | 
|  |  | 
|  | TEST_F(SnapshotFixture, PostSystemResetSingleSystemHostResetOnSuccess){ | 
|  | EXPECT_CALL(*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_, "system"); | 
|  |  | 
|  | RunIoUntilDone(); | 
|  |  | 
|  | EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok); | 
|  | } | 
|  |  | 
|  | TEST_F(SnapshotFixture, PostSystemResetSingleSystemChassisResetOnFail){ | 
|  | EXPECT_CALL(*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_, "system"); | 
|  |  | 
|  | RunIoUntilDone(); | 
|  |  | 
|  | EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::internal_server_error); | 
|  | } | 
|  |  | 
|  | TEST_F(SnapshotFixture, PostSystemResetSingleSystemChassisResetOnSuccess){ | 
|  | EXPECT_CALL(*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_, "system"); | 
|  |  | 
|  | 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( | 
|  | 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 = | 
|  | 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( | 
|  | 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( | 
|  | 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 = | 
|  | 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(managedStore::GetManagedObjectStore() | 
|  | ->upsertMockObjectIntoManagedStore( | 
|  | key, CreateMockAssociatedSubtree()) | 
|  | .ok()); | 
|  |  | 
|  | absl::Cleanup mockManagedStoreResetter = [key, | 
|  | originalAssociatedSubtree]() { | 
|  | ASSERT_TRUE( | 
|  | 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, PostSystemResetSingleSystemChassisResetOnSuccessDelay){ | 
|  | handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"ForceOff\", \"Delay\":1} "), share_async_resp_, "system"); | 
|  |  | 
|  | 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/system/Actions/ComputerSystem.Reset"); | 
|  | } | 
|  |  | 
|  | TEST_F(SnapshotFixture, PostSystemResetSingleSystemChassisResetOnFailTimeDelay){ | 
|  | handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"ForceOff\", \"Delay\":901} "), share_async_resp_, "system"); | 
|  |  | 
|  | RunIoUntilDone(); | 
|  |  | 
|  | EXPECT_EQ(share_async_resp_->res.result(),boost::beast::http::status::bad_request); | 
|  | } | 
|  |  | 
|  | TEST_F(SnapshotFixture, PostSystemResetSingleSystemChassisResetOnFailTypeDelay){ | 
|  | handlePostComputerSystemReset(app_, CreateRequest("{\"ResetType\":\"PleaseReset\", \"Delay\":1} "), share_async_resp_, "system"); | 
|  |  | 
|  | 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"); | 
|  | } | 
|  |  | 
|  | } // namespace | 
|  | } // namespace redfish |