#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
