| #include "conformance/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 "conformance/binary_wireformat.h" | |
| #include "conformance/conformance.pb.h" | |
| #include "conformance/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, TestPriority priority, | |
| const ::conformance::ConformanceRequest& request, | |
| const Descriptor& message) { | |
| absl::string_view level = PriorityLevelName(priority); | |
| std::string syntax_identifier = GetEditionIdentifier(message); | |
| return absl::StrCat( | |
| level, ".", 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_, priority_, 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_, priority_, 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_, priority_, 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_, priority_, request_, *type_); | |
| ::conformance::ConformanceResponse response = | |
| testee_->Run(full_name, request_); | |
| return TestResult(full_name, priority_, type_, format, std::move(response)); | |
| } | |
| } // namespace internal | |
| absl::string_view PriorityName(TestPriority priority) { | |
| switch (priority) { | |
| case TestPriority::kP0: | |
| return "P0"; | |
| case TestPriority::kP1: | |
| return "P1"; | |
| } | |
| return "Unknown"; | |
| } | |
| absl::string_view PriorityLevelName(TestPriority priority) { | |
| // TODO: b/564550230 - return PriorityName() once the tests are renamed. | |
| return priority == TestPriority::kP1 ? "Recommended" : "Required"; | |
| } | |
| } // namespace conformance | |
| } // namespace protobuf | |
| } // namespace google |