blob: f85a0c555058acc53765a9ae665c23831ed7fe4b [file] [log] [blame]
#include "redfish-core/lib/external_storer.hpp"
#include "gtest/gtest.h"
namespace
{
class ExternalStorerTest : public ::testing::Test
{
protected:
App app = App(/*allowSessionEmpty=*/true);
std::shared_ptr<external_storer::Hook> hookLogs;
public:
ExternalStorerTest() :
hookLogs(std::make_shared<external_storer::Hook>(
external_storer::makeLogServices()))
{
// Use our own Hook object, as we need it later in destructor
redfish::requestRoutesExternalStorerLogServices(app, hookLogs);
// Customize directory to be non-systemwide for testing
hookLogs->setPathPrefix("./ExternalStorer_Test");
// Clean up partial results of any previous interrupted run
hookLogs->deleteAll();
}
~ExternalStorerTest() override
{
// Clean up after ourselves
hookLogs->deleteAll();
}
ExternalStorerTest(const ExternalStorerTest& copy) = delete;
ExternalStorerTest& operator=(const ExternalStorerTest& assign) = delete;
ExternalStorerTest(ExternalStorerTest&& move) = delete;
ExternalStorerTest& operator=(ExternalStorerTest&& assign) = delete;
};
TEST_F(ExternalStorerTest, CreateGetInstance)
{
// Must not exist originally
auto resp1 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetInstance(resp1, "MyInstance");
EXPECT_EQ(resp1->res.result(), boost::beast::http::status::not_found);
boost::beast::http::request<boost::beast::http::string_body> upBody;
std::error_code ec;
auto upJson = nlohmann::json::object();
upJson["Id"] = "MyInstance";
upJson["Layer"] = "Outer";
upJson["Entries"] = nlohmann::json::object();
upJson["Entries"]["Layer"] = "Inner";
upBody.body() = upJson.dump();
crow::Request req{upBody, ec};
// Create instance
auto resp2 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleCreateInstance(req, resp2);
EXPECT_EQ(resp2->res.result(), boost::beast::http::status::created);
// Must now exist
auto resp3 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetInstance(resp3, "MyInstance");
EXPECT_EQ(resp3->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(resp3->res.jsonValue["Layer"], "Outer");
// Outer layer and inner layer must both be individually customizable
auto resp4 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetMiddle(resp4, "MyInstance", "Entries");
EXPECT_EQ(resp4->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(resp4->res.jsonValue["Layer"], "Inner");
}
TEST_F(ExternalStorerTest, CreateGetMiddle)
{
// Must not exist initially
auto resp1 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetInstance(resp1, "MyInstance");
EXPECT_EQ(resp1->res.result(), boost::beast::http::status::not_found);
boost::beast::http::request<boost::beast::http::string_body> upBody;
std::error_code ec;
auto upJson = nlohmann::json::object();
upJson["Id"] = "MyInstance";
upBody.body() = upJson.dump();
crow::Request req2{upBody, ec};
// Create instance
auto resp2 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleCreateInstance(req2, resp2);
EXPECT_EQ(resp2->res.result(), boost::beast::http::status::created);
// Instance layer must have linkage to middle layer
auto resp3 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetInstance(resp3, "MyInstance");
EXPECT_EQ(resp3->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(resp3->res.jsonValue["Entries"]["@odata.id"],
"/redfish/v1/Systems/system/LogServices/MyInstance/Entries");
// Entry must not initially exist
auto resp4 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetMiddle(resp4, "MyInstance", "Entries");
EXPECT_EQ(resp4->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(resp4->res.jsonValue["Members@odata.count"], 0);
upJson = nlohmann::json::object();
upJson["Id"] = "EntryCreatedFromCreateMiddle";
upJson["Hello"] = "There";
upBody.body() = upJson.dump();
crow::Request req5{upBody, ec};
// Create entry, by using middle layer
auto resp5 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleCreateMiddle(req5, resp5, "MyInstance");
EXPECT_EQ(resp5->res.result(), boost::beast::http::status::created);
// Created entry must now appear in array of entries
auto resp6 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetMiddle(resp6, "MyInstance", "Entries");
EXPECT_EQ(resp6->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(resp6->res.jsonValue["Members@odata.count"], 1);
EXPECT_EQ(
resp6->res.jsonValue["Members"][0]["@odata.id"],
"/redfish/v1/Systems/system/LogServices/MyInstance/Entries/EntryCreatedFromCreateMiddle");
// Entry must now exist
auto resp7 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetEntry(resp7, ""_json_pointer, "MyInstance", "Entries",
"EntryCreatedFromCreateMiddle");
EXPECT_EQ(resp7->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(resp7->res.jsonValue["Hello"], "There");
}
TEST_F(ExternalStorerTest, CreateGetEntry)
{
// Must not exist initially
auto resp1 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetInstance(resp1, "MyInstance");
EXPECT_EQ(resp1->res.result(), boost::beast::http::status::not_found);
boost::beast::http::request<boost::beast::http::string_body> upBody;
std::error_code ec;
auto upJson = nlohmann::json::object();
upJson["Id"] = "MyInstance";
upBody.body() = upJson.dump();
crow::Request req2{upBody, ec};
// Create instance
auto resp2 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleCreateInstance(req2, resp2);
EXPECT_EQ(resp2->res.result(), boost::beast::http::status::created);
// Instance layer must have linkage to middle layer
auto resp3 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetInstance(resp3, "MyInstance");
EXPECT_EQ(resp3->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(resp3->res.jsonValue["Entries"]["@odata.id"],
"/redfish/v1/Systems/system/LogServices/MyInstance/Entries");
// Entry must not initially exist
auto resp4 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetMiddle(resp4, "MyInstance", "Entries");
EXPECT_EQ(resp4->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(resp4->res.jsonValue["Members@odata.count"], 0);
upJson = nlohmann::json::object();
upJson["Id"] = "EntryCreatedFromCreateEntry";
upJson["Hello"] = "There";
upBody.body() = upJson.dump();
crow::Request req5{upBody, ec};
// Create entry, by using entry layer
auto resp5 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleCreateEntry(req5, resp5, "MyInstance", "Entries");
EXPECT_EQ(resp5->res.result(), boost::beast::http::status::created);
upJson = nlohmann::json::object();
upJson["Id"] = "AnotherEntry";
upJson["Hello"] = "Again";
upBody.body() = upJson.dump();
crow::Request req6{upBody, ec};
// Create another entry, also by using entry layer
auto resp6 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleCreateEntry(req6, resp6, "MyInstance", "Entries");
EXPECT_EQ(resp6->res.result(), boost::beast::http::status::created);
// Both entries must now appear in array of entries
auto resp7 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetMiddle(resp7, "MyInstance", "Entries");
EXPECT_EQ(resp7->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(resp7->res.jsonValue["Members@odata.count"], 2);
// Both entries must now exist and be distinct from one another
auto resp8 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetEntry(resp8, ""_json_pointer, "MyInstance", "Entries",
"EntryCreatedFromCreateEntry");
EXPECT_EQ(resp8->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(resp8->res.jsonValue["Hello"], "There");
auto resp9 = std::make_shared<bmcweb::AsyncResp>();
hookLogs->handleGetEntry(resp9, ""_json_pointer, "MyInstance", "Entries",
"AnotherEntry");
EXPECT_EQ(resp9->res.result(), boost::beast::http::status::ok);
EXPECT_EQ(resp9->res.jsonValue["Hello"], "Again");
}
} // namespace