39 #include <google/protobuf/stubs/stringprintf.h>
40 #include <google/protobuf/message.h>
41 #include <google/protobuf/text_format.h>
42 #include <google/protobuf/util/field_comparator.h>
43 #include <google/protobuf/util/json_util.h>
44 #include <google/protobuf/util/message_differencer.h>
45 #include "conformance.pb.h"
47 using conformance::ConformanceRequest;
48 using conformance::ConformanceResponse;
49 using conformance::WireFormat;
57 static string ToOctString(
const string& binary_string) {
59 for (
size_t i = 0;
i < binary_string.size();
i++) {
64 oct_string.push_back(
'\\');
65 oct_string.push_back(
'0' + high);
66 oct_string.push_back(
'0' + mid);
67 oct_string.push_back(
'0' + low);
78 ConformanceLevel
level,
79 conformance::WireFormat input_format,
80 conformance::WireFormat output_format,
81 conformance::TestCategory test_category,
82 const Message& prototype_message,
83 const string& test_name,
const string&
input)
85 input_format_(input_format),
86 output_format_(output_format),
87 prototype_message_(prototype_message),
88 prototype_message_for_compare_(prototype_message.
New()),
89 test_name_(test_name) {
90 switch (input_format) {
91 case conformance::PROTOBUF: {
96 case conformance::JSON: {
101 case conformance::JSPB: {
106 case conformance::TEXT_FORMAT: {
115 request_.set_test_category(test_category);
117 request_.set_message_type(prototype_message.GetDescriptor()->full_name());
118 request_.set_requested_output_format(output_format);
121 std::unique_ptr<Message>
129 prototype_message_.GetDescriptor()->file()->syntax() ==
132 return StrCat(ConformanceLevelToString(level_),
".", rname,
".",
133 InputFormatString(input_format_),
".", test_name_,
".",
134 OutputFormatString(output_format_));
151 case conformance::PROTOBUF:
152 return "ProtobufInput";
153 case conformance::JSON:
155 case conformance::TEXT_FORMAT:
156 return "TextFormatInput";
166 case conformance::PROTOBUF:
167 return "ProtobufOutput";
168 case conformance::JSON:
170 case conformance::TEXT_FORMAT:
171 return "TextFormatOutput";
181 "ERROR: test %s is in the failure list, but test succeeded. "
182 "Remove it from the failure list.\n",
191 const ConformanceRequest&
request,
192 const ConformanceResponse&
response,
193 const char*
fmt, ...) {
209 request.ShortDebugString().c_str(),
210 response.ShortDebugString().c_str());
214 const ConformanceRequest&
request,
215 const ConformanceResponse&
response) {
218 test_name.c_str(),
request.ShortDebugString().c_str(),
219 response.ShortDebugString().c_str());
225 const ConformanceRequestSetting& setting,
226 const string& equivalent_text_format) {
227 std::unique_ptr<Message> reference_message(setting.NewTestMessage());
229 reference_message.get()))
230 <<
"Failed to parse data for test case: " << setting.GetTestName()
231 <<
", data: " << equivalent_text_format;
232 const string equivalent_wire_format = reference_message->SerializeAsString();
237 const ConformanceRequestSetting& setting,
238 const string& equivalent_wire_format,
bool require_same_wire_format) {
239 const ConformanceRequest&
request = setting.GetRequest();
243 require_same_wire_format);
247 const ConformanceRequestSetting& setting,
248 const string& equivalent_wire_format,
const ConformanceResponse&
response,
249 bool need_report_success,
bool require_same_wire_format) {
250 std::unique_ptr<Message> test_message(setting.NewTestMessage());
251 const ConformanceRequest&
request = setting.GetRequest();
252 const string& test_name = setting.GetTestName();
254 std::unique_ptr<Message> reference_message = setting.NewTestMessage();
256 GOOGLE_CHECK(reference_message->ParseFromString(equivalent_wire_format))
257 <<
"Failed to parse wire data for test case: " << test_name;
260 case ConformanceResponse::RESULT_NOT_SET:
262 "Response didn't have any field in the Response.");
266 case ConformanceResponse::kRuntimeError:
267 case ConformanceResponse::kSerializeError:
269 "Failed to parse input or produce output.");
272 case ConformanceResponse::kSkipped:
289 if (require_same_wire_format) {
291 const string& protobuf_payload =
response.protobuf_payload();
292 check = equivalent_wire_format == protobuf_payload;
293 differences =
StrCat(
"Expect: ", ToOctString(equivalent_wire_format),
294 ", but got: ", ToOctString(protobuf_payload));
296 check = differencer.
Compare(*reference_message, *test_message);
300 if (need_report_success) {
305 "Output was not equivalent to reference message: %s.",
306 differences.c_str());
311 const ConformanceRequest&
request,
313 if (
test_names_.insert(test_name).second ==
false) {
317 string serialized_request;
318 string serialized_response;
319 request.SerializeToString(&serialized_request);
321 runner_->
RunTest(test_name, serialized_request, &serialized_response);
323 if (!
response->ParseFromString(serialized_response)) {
325 response->set_runtime_error(
"response proto could not be parsed.");
330 "conformance test: name=%s, request=%s, response=%s\n",
332 request.ShortDebugString().c_str(),
333 response->ShortDebugString().c_str());
338 const std::set<string>& set_to_check,
341 if (set_to_check.empty()) {
346 for (std::set<string>::const_iterator
iter = set_to_check.begin();
347 iter != set_to_check.end(); ++
iter) {
352 if (!write_to_file.empty()) {
353 std::ofstream os(write_to_file);
355 for (std::set<string>::const_iterator
iter = set_to_check.begin();
356 iter != set_to_check.end(); ++
iter) {
361 write_to_file.c_str());
370 WireFormat wire_format) {
371 switch (wire_format) {
372 case conformance::PROTOBUF:
374 case conformance::JSON:
376 case conformance::JSPB:
378 case conformance::TEXT_FORMAT:
379 return "TEXT_FORMAT";
380 case conformance::UNSPECIFIED:
381 return "UNSPECIFIED";
394 conformance::FailureSet* failure_list) {
403 output_ =
"\nCONFORMANCE TEST BEGIN ====================================\n\n";
407 for (
const string& failure : failure_list->failure()) {
414 "These tests were listed in the failure list, but they "
415 "don't exist. Remove them from the failure list by "
418 " --remove nonexistent_tests.txt")) {
422 "These tests failed. If they can't be fixed right now, "
423 "you can add them to the failure list so the overall "
424 "suite can succeed. Add them to the failure list by "
427 " --add failing_tests.txt")) {
431 "These tests succeeded, even though they were listed in "
432 "the failure list. Remove them from the failure list "
435 " --remove succeeding_tests.txt")) {
441 "These tests were skipped (probably because support for some "
442 "features is not implemented)");
446 "CONFORMANCE SUITE %s: %d successes, %zu skipped, "
447 "%d expected failures, %zu unexpected failures.\n",