blob: c00dc2de15e8fec232c2a557fb60f91d372c6baf [file] [log] [blame]
#include "./rpc_fuzzing/rpc_executor.h"
#include <memory>
#include <utility>
#include <vector>
#include "google/protobuf/descriptor.h"
#include "google/protobuf/message.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "./fuzztest/internal/logging.h"
namespace fuzztest::internal {
absl::Status RpcExecutor::Execute(RpcSequence& sequence) {
responses_.clear();
responses_.reserve(sequence.size());
absl::Status status;
for (RpcNode& node : sequence) {
status = ExecuteOne(node);
if (!status.ok()) {
return status;
}
}
return status;
}
const google::protobuf::Message& RpcExecutor::GetRpcNodeResponse(RpcNodeID node_id) {
FUZZTEST_INTERNAL_CHECK(node_id < responses_.size(),
"The dependency source doesn't exist!");
return *responses_[node_id];
}
std::vector<const google::protobuf::Message*> RpcExecutor::GetResponses() const {
std::vector<const google::protobuf::Message*> responses;
responses.reserve(responses_.size());
for (const std::unique_ptr<google::protobuf::Message>& response : responses_) {
responses.push_back(response.get());
}
return responses;
}
absl::Status RpcExecutor::ExecuteOne(RpcNode& node) {
for (const RpcDataFlowEdge& dep : node.dependencies()) {
// Assign value to dynamic fields.
const google::protobuf::Message& save_response = GetRpcNodeResponse(dep.from_node_id);
CopyField(dep.from_field, save_response, dep.to_field, node.request());
}
absl::StatusOr<std::unique_ptr<google::protobuf::Message>> response =
stub_->CallMethod(node.method(), node.request());
if (!response.ok()) return std::move(response).status();
responses_.push_back(*std::move(response));
return absl::OkStatus();
}
} // namespace fuzztest::internal