Skip to content

Commit

Permalink
Internal change
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 437772375
  • Loading branch information
ecclesia-robot authored and copybara-github committed Mar 29, 2022
1 parent 101994c commit 8d61785
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 3 deletions.
45 changes: 42 additions & 3 deletions ecclesia/lib/redfish/testing/grpc_dynamic_mockup_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ namespace {

using ::redfish::v1::Request;

constexpr char kResourceKey[] = "redfish-resource";

absl::Status SetGrpcResponseAndReturnStatus(RedfishVariant variant,
redfish::v1::Response* response) {
absl::Status status = absl::OkStatus();
Expand All @@ -65,11 +67,30 @@ absl::Status SetGrpcResponseAndReturnStatus(RedfishVariant variant,
return status;
}

grpc::Status CheckRequestResourceAndMetadataResource(
const grpc::ServerContext& context, const Request& request) {
if (auto it = context.client_metadata().find(kResourceKey);
it == context.client_metadata().end()) {
return grpc::Status(grpc::StatusCode::FAILED_PRECONDITION,
"missing resource URL in client metadata!");
} else if (it->second != request.url()) {
return grpc::Status(
grpc::StatusCode::FAILED_PRECONDITION,
"Resource URL in client metadata and request shall be the same!");
}
return grpc::Status::OK;
}

} // namespace

grpc::Status GrpcDynamicMockupServer::RedfishV1Impl::Get(
grpc::ServerContext* context, const Request* request,
redfish::v1::Response* response) {
if (grpc::Status status =
CheckRequestResourceAndMetadataResource(*context, *request);
!status.ok()) {
return status;
}
absl::MutexLock mu(&patch_lock_);
if (auto itr = rest_get_handlers_.find(request->url());
itr != rest_get_handlers_.end()) {
Expand All @@ -81,6 +102,11 @@ grpc::Status GrpcDynamicMockupServer::RedfishV1Impl::Get(
grpc::Status GrpcDynamicMockupServer::RedfishV1Impl::Post(
grpc::ServerContext* context, const Request* request,
redfish::v1::Response* response) {
if (grpc::Status status =
CheckRequestResourceAndMetadataResource(*context, *request);
!status.ok()) {
return status;
}
absl::MutexLock mu(&patch_lock_);
if (auto itr = rest_post_handlers_.find(request->url());
itr != rest_post_handlers_.end()) {
Expand All @@ -99,6 +125,11 @@ grpc::Status GrpcDynamicMockupServer::RedfishV1Impl::Post(
grpc::Status GrpcDynamicMockupServer::RedfishV1Impl::Patch(
grpc::ServerContext* context, const Request* request,
redfish::v1::Response* response) {
if (grpc::Status status =
CheckRequestResourceAndMetadataResource(*context, *request);
!status.ok()) {
return status;
}
absl::MutexLock mu(&patch_lock_);
if (auto itr = rest_patch_handlers_.find(request->url());
itr != rest_patch_handlers_.end()) {
Expand All @@ -117,12 +148,22 @@ grpc::Status GrpcDynamicMockupServer::RedfishV1Impl::Patch(
grpc::Status GrpcDynamicMockupServer::RedfishV1Impl::Put(
grpc::ServerContext* context, const Request* request,
redfish::v1::Response* response) {
if (grpc::Status status =
CheckRequestResourceAndMetadataResource(*context, *request);
!status.ok()) {
return status;
}
return StatusToGrpcStatus(
absl::UnimplementedError("Put RPC is not implemented yet."));
}
grpc::Status GrpcDynamicMockupServer::RedfishV1Impl::Delete(
grpc::ServerContext* context, const Request* request,
redfish::v1::Response* response) {
if (grpc::Status status =
CheckRequestResourceAndMetadataResource(*context, *request);
!status.ok()) {
return status;
}
// DELETE.
return StatusToGrpcStatus(
absl::UnimplementedError("Delete RPC is not implemented yet."));
Expand Down Expand Up @@ -194,9 +235,7 @@ GrpcDynamicMockupServer::GrpcDynamicMockupServer(
server_ = builder.BuildAndStart();
}

GrpcDynamicMockupServer::~GrpcDynamicMockupServer() {
ClearHandlers();
}
GrpcDynamicMockupServer::~GrpcDynamicMockupServer() { ClearHandlers(); }

void GrpcDynamicMockupServer::ClearHandlers() {
redfish_v1_impl_->ClearHandlers();
Expand Down
111 changes: 111 additions & 0 deletions ecclesia/lib/redfish/testing/grpc_dynamic_mockup_server_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,23 @@ using ::redfish::v1::Response;
using ::testing::Eq;
using ::testing::Test;

class GrpcRedfishCredentialsInTest : public grpc::MetadataCredentialsPlugin {
public:
explicit GrpcRedfishCredentialsInTest(absl::string_view resource)
: resource_(resource) {}
// Sends out the Redfish resource as part of gRPC credentials.
grpc::Status GetMetadata(
grpc::string_ref /*service_url*/, grpc::string_ref /*method_name*/,
const grpc::AuthContext & /*channel_auth_context*/,
std::multimap<grpc::string, grpc::string> *metadata) override {
metadata->insert(std::make_pair("redfish-resource", resource_));
return grpc::Status::OK;
}

private:
std::string resource_;
};

class GrpcRedfishMockUpServerTest : public Test {
protected:
GrpcRedfishMockUpServerTest() {
Expand Down Expand Up @@ -116,15 +133,25 @@ TEST_F(GrpcRedfishMockUpServerTest, TestPostPatchAndGetRequest) {
TEST_F(GrpcRedfishMockUpServerTest, TestPutRequests) {
grpc::ClientContext context;
Request request;
request.set_url("/redfish/v1");
Response response;
context.set_credentials(grpc::experimental::MetadataCredentialsFromPlugin(
std::unique_ptr<grpc::MetadataCredentialsPlugin>(
std::make_unique<GrpcRedfishCredentialsInTest>("/redfish/v1")),
GRPC_SECURITY_NONE));
EXPECT_THAT(AsAbslStatus(stub_->Put(&context, request, &response)),
IsStatusUnimplemented());
}

TEST_F(GrpcRedfishMockUpServerTest, TestDeleteRequests) {
grpc::ClientContext context;
Request request;
request.set_url("/redfish/v1");
Response response;
context.set_credentials(grpc::experimental::MetadataCredentialsFromPlugin(
std::unique_ptr<grpc::MetadataCredentialsPlugin>(
std::make_unique<GrpcRedfishCredentialsInTest>("/redfish/v1")),
GRPC_SECURITY_NONE));
EXPECT_THAT(AsAbslStatus(stub_->Delete(&context, request, &response)),
IsStatusUnimplemented());
}
Expand Down Expand Up @@ -346,5 +373,89 @@ TEST(GrpcRedfishMockUpServerUdsTest, TestUds) {
EXPECT_THAT(res_get->body, Eq(expected));
}

TEST_F(GrpcRedfishMockUpServerTest, MissAuthMetadataReturnsFailure) {
redfish::v1::Request request;
request.set_url("/redfish/v1");
redfish::v1::Response response;
grpc::ClientContext context;
EXPECT_THAT(AsAbslStatus(stub_->Get(&context, request, &response)),
IsStatusFailedPrecondition());
}

TEST_F(GrpcRedfishMockUpServerTest,
AuthMetadataResourceAndRequestResourceMismatchReturnsFailure) {
redfish::v1::Request request;
request.set_url("/redfish/v1");
redfish::v1::Response response;
{
grpc::ClientContext context;
context.set_credentials(grpc::experimental::MetadataCredentialsFromPlugin(
std::unique_ptr<grpc::MetadataCredentialsPlugin>(
std::make_unique<GrpcRedfishCredentialsInTest>("/redfish/v2")),
GRPC_SECURITY_NONE));
EXPECT_THAT(AsAbslStatus(stub_->Get(&context, request, &response)),
IsStatusFailedPrecondition());
}
{
grpc::ClientContext context;
context.set_credentials(grpc::experimental::MetadataCredentialsFromPlugin(
std::unique_ptr<grpc::MetadataCredentialsPlugin>(
std::make_unique<GrpcRedfishCredentialsInTest>("/redfish/v2")),
GRPC_SECURITY_NONE));
EXPECT_THAT(AsAbslStatus(stub_->Patch(&context, request, &response)),
IsStatusFailedPrecondition());
}
{
grpc::ClientContext context;
context.set_credentials(grpc::experimental::MetadataCredentialsFromPlugin(
std::unique_ptr<grpc::MetadataCredentialsPlugin>(
std::make_unique<GrpcRedfishCredentialsInTest>("/redfish/v2")),
GRPC_SECURITY_NONE));
EXPECT_THAT(AsAbslStatus(stub_->Delete(&context, request, &response)),
IsStatusFailedPrecondition());
}
{
grpc::ClientContext context;
context.set_credentials(grpc::experimental::MetadataCredentialsFromPlugin(
std::unique_ptr<grpc::MetadataCredentialsPlugin>(
std::make_unique<GrpcRedfishCredentialsInTest>("/redfish/v2")),
GRPC_SECURITY_NONE));
EXPECT_THAT(AsAbslStatus(stub_->Put(&context, request, &response)),
IsStatusFailedPrecondition());
}
{
grpc::ClientContext context;
context.set_credentials(grpc::experimental::MetadataCredentialsFromPlugin(
std::unique_ptr<grpc::MetadataCredentialsPlugin>(
std::make_unique<GrpcRedfishCredentialsInTest>("/redfish/v2")),
GRPC_SECURITY_NONE));
EXPECT_THAT(AsAbslStatus(stub_->Post(&context, request, &response)),
IsStatusFailedPrecondition());
}
}

TEST_F(GrpcRedfishMockUpServerTest,
AuthMetadataResourceAndRequestResourceMatchReturnsOk) {
bool called = false;
// Register the handler.
mockup_server_->AddHttpGetHandler(
"/redfish/v1",
[&](grpc::ServerContext *context, const ::redfish::v1::Request *request,
Response *response) {
called = true;
return grpc::Status::OK;
});
redfish::v1::Request request;
request.set_url("/redfish/v1");
redfish::v1::Response response;
grpc::ClientContext context;
context.set_credentials(grpc::experimental::MetadataCredentialsFromPlugin(
std::unique_ptr<grpc::MetadataCredentialsPlugin>(
std::make_unique<GrpcRedfishCredentialsInTest>("/redfish/v1")),
GRPC_SECURITY_NONE));
EXPECT_THAT(AsAbslStatus(stub_->Get(&context, request, &response)), IsOk());
EXPECT_TRUE(called);
}

} // namespace
} // namespace ecclesia

0 comments on commit 8d61785

Please sign in to comment.