blob: ac53478afd2b3ff1c7d09e2cd61ab78f26cc992c [file] [log] [blame]
#include "testee.h"
#include <string>
#include <utility>
#include "absl/log/absl_check.h"
#include "absl/log/absl_log.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "binary_wireformat.h"
#include "conformance/conformance.pb.h"
#include "naming.h"
#include "google/protobuf/descriptor.h"
namespace google {
namespace protobuf {
namespace conformance {
namespace internal {
namespace {
using ::conformance::ConformanceRequest;
using ::conformance::ConformanceResponse;
::conformance::WireFormat GetInputFormat(
const ::conformance::ConformanceRequest& request) {
switch (request.payload_case()) {
case ::conformance::ConformanceRequest::kProtobufPayload:
return ::conformance::PROTOBUF;
case ::conformance::ConformanceRequest::kJsonPayload:
return ::conformance::JSON;
case ::conformance::ConformanceRequest::kTextPayload:
return ::conformance::TEXT_FORMAT;
default:
ABSL_LOG(FATAL) << "Unsupported input format";
}
return ::conformance::UNSPECIFIED;
}
std::string GetTestName(absl::string_view test_name, TestStrictness strictness,
const ::conformance::ConformanceRequest& request,
const Descriptor& message) {
absl::string_view strictness_string =
strictness == TestStrictness::kRequired ? "Required" : "Recommended";
std::string syntax_identifier = GetEditionIdentifier(message);
return absl::StrCat(
strictness_string, ".", syntax_identifier, ".",
GetFormatIdentifier(GetInputFormat(request)), "Input.", test_name, ".",
GetFormatIdentifier(request.requested_output_format()), "Output");
}
} // namespace
::conformance::ConformanceResponse Testee::Run(
absl::string_view test_name, const ConformanceRequest& request) {
ABSL_CHECK(test_names_ran_.emplace(test_name).second)
<< "Duplicated test name: " << test_name;
std::string serialized_request;
request.SerializeToString(&serialized_request);
std::string serialized_response =
runner_->RunTest(test_name, serialized_request);
ConformanceResponse response;
if (!response.ParseFromString(serialized_response)) {
response.set_runtime_error("response proto could not be parsed.");
}
return response;
}
InMemoryMessage Test::ParseBinary(const Descriptor* type, Wire input) && {
::conformance::ConformanceRequest request;
request.set_protobuf_payload(std::move(input).data());
request.set_test_category(::conformance::BINARY_TEST);
request.set_message_type(type->full_name());
return InMemoryMessage(testee_, name_, strictness_, type, std::move(request));
}
InMemoryMessage Test::ParseText(const Descriptor* type,
absl::string_view input) && {
::conformance::ConformanceRequest request;
request.set_text_payload(input);
request.set_test_category(::conformance::TEXT_FORMAT_TEST);
request.set_message_type(type->full_name());
return InMemoryMessage(testee_, name_, strictness_, type, std::move(request));
}
InMemoryMessage Test::ParseJson(const Descriptor* type, absl::string_view input,
JsonParseOptions options) && {
::conformance::ConformanceRequest request;
request.set_json_payload(input);
if (options.ignore_unknown_fields) {
request.set_test_category(::conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST);
} else {
request.set_test_category(::conformance::JSON_TEST);
}
request.set_message_type(type->full_name());
return InMemoryMessage(testee_, name_, strictness_, type, std::move(request));
}
TestResult InMemoryMessage::SerializeBinary() && {
return SerializeImpl(::conformance::PROTOBUF);
}
TestResult InMemoryMessage::SerializeText(TextSerializationOptions options) && {
if (options.print_unknown_fields) {
request_.set_print_unknown_fields(true);
}
return SerializeImpl(::conformance::TEXT_FORMAT);
}
TestResult InMemoryMessage::SerializeJson() && {
return SerializeImpl(::conformance::JSON);
}
TestResult InMemoryMessage::SerializeImpl(
const ::conformance::WireFormat format) {
request_.set_requested_output_format(format);
std::string full_name = GetTestName(name_, strictness_, request_, *type_);
::conformance::ConformanceResponse response =
testee_->Run(full_name, request_);
return TestResult(full_name, strictness_, type_, format, std::move(response));
}
} // namespace internal
} // namespace conformance
} // namespace protobuf
} // namespace google