#include "testee.h" #include #include #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; // TODO: Remove this suppression. (void)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