conformance_test.cc
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #include <set>
32 #include <stdarg.h>
33 #include <string>
34 #include <fstream>
35 
36 #include "conformance.pb.h"
37 #include "conformance_test.h"
38 
46 
47 using conformance::ConformanceRequest;
48 using conformance::ConformanceResponse;
49 using conformance::WireFormat;
55 using std::string;
56 
57 namespace google {
58 namespace protobuf {
59 
62  conformance::WireFormat input_format,
63  conformance::WireFormat output_format,
64  conformance::TestCategory test_category,
65  const Message& prototype_message,
66  const string& test_name, const string& input)
67  : level_(level),
68  input_format_(input_format),
69  output_format_(output_format),
70  prototype_message_(prototype_message),
71  prototype_message_for_compare_(prototype_message.New()),
72  test_name_(test_name) {
73  switch (input_format) {
74  case conformance::PROTOBUF: {
75  request_.set_protobuf_payload(input);
76  break;
77  }
78 
79  case conformance::JSON: {
80  request_.set_json_payload(input);
81  break;
82  }
83 
84  case conformance::JSPB: {
85  request_.set_jspb_payload(input);
86  break;
87  }
88 
89  case conformance::TEXT_FORMAT: {
90  request_.set_text_payload(input);
91  break;
92  }
93 
94  default:
95  GOOGLE_LOG(FATAL) << "Unspecified input format";
96  }
97 
98  request_.set_test_category(test_category);
99 
100  request_.set_message_type(prototype_message.GetDescriptor()->full_name());
101  request_.set_requested_output_format(output_format);
102 }
103 
106  return prototype_message_for_compare_->New();
107 }
108 
110  GetTestName() const {
111  string rname =
112  prototype_message_.GetDescriptor()->file()->syntax() ==
113  FileDescriptor::SYNTAX_PROTO3 ? "Proto3" : "Proto2";
114 
115  return StrCat(ConformanceLevelToString(level_), ".",
116  rname, ".",
117  InputFormatString(input_format_),
118  ".", test_name_, ".",
119  OutputFormatString(output_format_));
120 }
121 
124  ConformanceLevel level) const {
125  switch (level) {
126  case REQUIRED: return "Required";
127  case RECOMMENDED: return "Recommended";
128  }
129  GOOGLE_LOG(FATAL) << "Unknown value: " << level;
130  return "";
131 }
132 
134  InputFormatString(conformance::WireFormat format) const {
135  switch (format) {
136  case conformance::PROTOBUF:
137  return "ProtobufInput";
138  case conformance::JSON:
139  return "JsonInput";
140  case conformance::TEXT_FORMAT:
141  return "TextFormatInput";
142  default:
143  GOOGLE_LOG(FATAL) << "Unspecified output format";
144  }
145  return "";
146 }
147 
149  OutputFormatString(conformance::WireFormat format) const {
150  switch (format) {
151  case conformance::PROTOBUF:
152  return "ProtobufOutput";
153  case conformance::JSON:
154  return "JsonOutput";
155  case conformance::TEXT_FORMAT:
156  return "TextFormatOutput";
157  default:
158  GOOGLE_LOG(FATAL) << "Unspecified output format";
159  }
160  return "";
161 }
162 
163 void ConformanceTestSuite::ReportSuccess(const string& test_name) {
164  if (expected_to_fail_.erase(test_name) != 0) {
166  "ERROR: test %s is in the failure list, but test succeeded. "
167  "Remove it from the failure list.\n",
168  test_name.c_str());
169  unexpected_succeeding_tests_.insert(test_name);
170  }
171  successes_++;
172 }
173 
174 void ConformanceTestSuite::ReportFailure(const string& test_name,
176  const ConformanceRequest& request,
177  const ConformanceResponse& response,
178  const char* fmt, ...) {
179  if (expected_to_fail_.erase(test_name) == 1) {
181  if (!verbose_)
182  return;
183  } else if (level == RECOMMENDED && !enforce_recommended_) {
184  StringAppendF(&output_, "WARNING, test=%s: ", test_name.c_str());
185  } else {
186  StringAppendF(&output_, "ERROR, test=%s: ", test_name.c_str());
187  unexpected_failing_tests_.insert(test_name);
188  }
189  va_list args;
190  va_start(args, fmt);
192  va_end(args);
193  StringAppendF(&output_, " request=%s, response=%s\n",
194  request.ShortDebugString().c_str(),
195  response.ShortDebugString().c_str());
196 }
197 
198 void ConformanceTestSuite::ReportSkip(const string& test_name,
199  const ConformanceRequest& request,
200  const ConformanceResponse& response) {
201  if (verbose_) {
202  StringAppendF(&output_, "SKIPPED, test=%s request=%s, response=%s\n",
203  test_name.c_str(), request.ShortDebugString().c_str(),
204  response.ShortDebugString().c_str());
205  }
206  skipped_.insert(test_name);
207 }
208 
210  const ConformanceRequestSetting& setting,
211  const string& equivalent_text_format) {
212  Message* reference_message = setting.GetTestMessage();
213  GOOGLE_CHECK(
214  TextFormat::ParseFromString(equivalent_text_format, reference_message))
215  << "Failed to parse data for test case: " << setting.GetTestName()
216  << ", data: " << equivalent_text_format;
217  const string equivalent_wire_format = reference_message->SerializeAsString();
218  RunValidBinaryInputTest(setting, equivalent_wire_format);
219 }
220 
222  const ConformanceRequestSetting& setting,
223  const string& equivalent_wire_format) {
224  const ConformanceRequest& request = setting.GetRequest();
225  ConformanceResponse response;
226  RunTest(setting.GetTestName(), request, &response);
227  VerifyResponse(setting, equivalent_wire_format, response, true);
228 }
229 
231  const ConformanceRequestSetting& setting,
232  const string& equivalent_wire_format,
233  const ConformanceResponse& response,
234  bool need_report_success) {
235  Message* test_message = setting.GetTestMessage();
236  const ConformanceRequest& request = setting.GetRequest();
237  const string& test_name = setting.GetTestName();
238  ConformanceLevel level = setting.GetLevel();
239  Message* reference_message = setting.GetTestMessage();
240 
241  GOOGLE_CHECK(
242  reference_message->ParseFromString(equivalent_wire_format))
243  << "Failed to parse wire data for test case: " << test_name;
244 
245  switch (response.result_case()) {
246  case ConformanceResponse::RESULT_NOT_SET:
247  ReportFailure(test_name, level, request, response,
248  "Response didn't have any field in the Response.");
249  return;
250 
251  case ConformanceResponse::kParseError:
252  case ConformanceResponse::kRuntimeError:
253  case ConformanceResponse::kSerializeError:
254  ReportFailure(test_name, level, request, response,
255  "Failed to parse input or produce output.");
256  return;
257 
258  case ConformanceResponse::kSkipped:
259  ReportSkip(test_name, request, response);
260  return;
261 
262  default:
263  if (!ParseResponse(response, setting, test_message)) return;
264  }
265 
266  MessageDifferencer differencer;
267  DefaultFieldComparator field_comparator;
268  field_comparator.set_treat_nan_as_equal(true);
269  differencer.set_field_comparator(&field_comparator);
270  string differences;
271  differencer.ReportDifferencesToString(&differences);
272 
273  bool check;
274  check = differencer.Compare(*reference_message, *test_message);
275  if (check) {
276  if (need_report_success) {
277  ReportSuccess(test_name);
278  }
279  } else {
280  ReportFailure(test_name, level, request, response,
281  "Output was not equivalent to reference message: %s.",
282  differences.c_str());
283  }
284 }
285 
286 void ConformanceTestSuite::RunTest(const string& test_name,
287  const ConformanceRequest& request,
288  ConformanceResponse* response) {
289  if (test_names_.insert(test_name).second == false) {
290  GOOGLE_LOG(FATAL) << "Duplicated test name: " << test_name;
291  }
292 
293  string serialized_request;
294  string serialized_response;
295  request.SerializeToString(&serialized_request);
296 
297  runner_->RunTest(test_name, serialized_request, &serialized_response);
298 
299  if (!response->ParseFromString(serialized_response)) {
300  response->Clear();
301  response->set_runtime_error("response proto could not be parsed.");
302  }
303 
304  if (verbose_) {
306  "conformance test: name=%s, request=%s, response=%s\n",
307  test_name.c_str(),
308  request.ShortDebugString().c_str(),
309  response->ShortDebugString().c_str());
310  }
311 }
312 
314  const std::set<string>& set_to_check,
315  const std::string& write_to_file,
316  const std::string& msg) {
317  if (set_to_check.empty()) {
318  return true;
319  } else {
320  StringAppendF(&output_, "\n");
321  StringAppendF(&output_, "%s\n\n", msg.c_str());
322  for (std::set<string>::const_iterator iter = set_to_check.begin();
323  iter != set_to_check.end(); ++iter) {
324  StringAppendF(&output_, " %s\n", iter->c_str());
325  }
326  StringAppendF(&output_, "\n");
327 
328  if (!write_to_file.empty()) {
329  std::ofstream os(write_to_file);
330  if (os) {
331  for (std::set<string>::const_iterator iter = set_to_check.begin();
332  iter != set_to_check.end(); ++iter) {
333  os << *iter << "\n";
334  }
335  } else {
336  StringAppendF(&output_, "Failed to open file: %s\n",
337  write_to_file.c_str());
338  }
339  }
340 
341  return false;
342  }
343 }
344 
346  WireFormat wire_format) {
347  switch (wire_format) {
348  case conformance::PROTOBUF:
349  return "PROTOBUF";
350  case conformance::JSON:
351  return "JSON";
352  case conformance::JSPB:
353  return "JSPB";
354  case conformance::TEXT_FORMAT:
355  return "TEXT_FORMAT";
356  case conformance::UNSPECIFIED:
357  return "UNSPECIFIED";
358  default:
359  GOOGLE_LOG(FATAL) << "unknown wire type: "
360  << wire_format;
361  }
362  return "";
363 }
364 
366  expected_to_fail_.insert(test_name);
367 }
368 
370  std::string* output, const string& filename,
371  conformance::FailureSet* failure_list) {
372  runner_ = runner;
373  successes_ = 0;
374  expected_failures_ = 0;
375  skipped_.clear();
376  test_names_.clear();
379 
380  output_ = "\nCONFORMANCE TEST BEGIN ====================================\n\n";
381 
382  failure_list_filename_ = filename;
383  expected_to_fail_.clear();
384  for (const string& failure : failure_list->failure()) {
385  AddExpectedFailedTest(failure);
386  }
387  RunSuiteImpl();
388 
389  bool ok = true;
390  if (!CheckSetEmpty(expected_to_fail_, "nonexistent_tests.txt",
391  "These tests were listed in the failure list, but they "
392  "don't exist. Remove them from the failure list by "
393  "running:\n"
394  " ./update_failure_list.py " + failure_list_filename_ +
395  " --remove nonexistent_tests.txt")) {
396  ok = false;
397  }
398  if (!CheckSetEmpty(unexpected_failing_tests_, "failing_tests.txt",
399  "These tests failed. If they can't be fixed right now, "
400  "you can add them to the failure list so the overall "
401  "suite can succeed. Add them to the failure list by "
402  "running:\n"
403  " ./update_failure_list.py " + failure_list_filename_ +
404  " --add failing_tests.txt")) {
405  ok = false;
406  }
407  if (!CheckSetEmpty(unexpected_succeeding_tests_, "succeeding_tests.txt",
408  "These tests succeeded, even though they were listed in "
409  "the failure list. Remove them from the failure list "
410  "by running:\n"
411  " ./update_failure_list.py " + failure_list_filename_ +
412  " --remove succeeding_tests.txt")) {
413  ok = false;
414  }
415 
416  if (verbose_) {
418  "These tests were skipped (probably because support for some "
419  "features is not implemented)");
420  }
421 
423  "CONFORMANCE SUITE %s: %d successes, %d skipped, "
424  "%d expected failures, %d unexpected failures.\n",
425  ok ? "PASSED" : "FAILED", successes_, skipped_.size(),
427  StringAppendF(&output_, "\n");
428 
429  output->assign(output_);
430 
431  return ok;
432 }
433 
434 } // namespace protobuf
435 } // namespace google
google::protobuf::Descriptor::full_name
const std::string & full_name() const
response
const std::string response
google::protobuf::ConformanceTestSuite::ConformanceRequestSetting::ConformanceRequestSetting
ConformanceRequestSetting(ConformanceLevel level, conformance::WireFormat input_format, conformance::WireFormat output_format, conformance::TestCategory test_category, const Message &prototype_message, const string &test_name, const string &input)
Definition: conformance_test.cc:60
google::protobuf::util::MessageDifferencer
Definition: message_differencer.h:120
google::protobuf::ConformanceTestSuite::ConformanceLevel
ConformanceLevel
Definition: conformance_test.h:197
google::protobuf::StrCat
string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: strutil.cc:1480
input
std::string input
Definition: tokenizer_unittest.cc:197
FATAL
const int FATAL
Definition: log_severity.h:60
google::protobuf::ConformanceTestRunner
Definition: conformance_test.h:67
google::protobuf::util::DefaultFieldComparator::set_treat_nan_as_equal
void set_treat_nan_as_equal(bool treat_nan_as_equal)
Definition: field_comparator.h:130
message_differencer.h
google::protobuf::ConformanceTestSuite::ConformanceRequestSetting::ConformanceLevelToString
string ConformanceLevelToString(ConformanceLevel level) const
Definition: conformance_test.cc:123
google::protobuf::ConformanceTestSuite::unexpected_failing_tests_
std::set< std::string > unexpected_failing_tests_
Definition: conformance_test.h:307
google::protobuf::ConformanceTestSuite::expected_failures_
int expected_failures_
Definition: conformance_test.h:291
google::protobuf.internal::WireFormat
Definition: wire_format.h:78
google::protobuf::ConformanceTestSuite::RunSuite
bool RunSuite(ConformanceTestRunner *runner, std::string *output, const std::string &filename, conformance::FailureSet *failure_list)
Definition: conformance_test.cc:369
google::protobuf::ConformanceTestSuite::ConformanceRequestSetting::request_
conformance::ConformanceRequest request_
Definition: conformance_test.h:238
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
google::protobuf::ConformanceTestSuite::successes_
int successes_
Definition: conformance_test.h:290
google::protobuf::ConformanceTestSuite::ConformanceRequestSetting::OutputFormatString
virtual string OutputFormatString(conformance::WireFormat format) const
Definition: conformance_test.cc:149
google::protobuf::ConformanceTestSuite::ParseResponse
virtual bool ParseResponse(const conformance::ConformanceResponse &response, const ConformanceRequestSetting &setting, Message *test_message)=0
google::protobuf::ConformanceTestSuite::expected_to_fail_
std::set< std::string > expected_to_fail_
Definition: conformance_test.h:300
google::protobuf::ConformanceTestSuite::ReportFailure
void ReportFailure(const string &test_name, ConformanceLevel level, const conformance::ConformanceRequest &request, const conformance::ConformanceResponse &response, const char *fmt,...)
Definition: conformance_test.cc:174
google::protobuf::StringAppendF
void StringAppendF(string *dst, const char *format,...)
Definition: stringprintf.cc:127
google::protobuf::util::JsonToBinaryString
util::Status JsonToBinaryString(TypeResolver *resolver, const std::string &type_url, StringPiece json_input, std::string *binary_output, const JsonParseOptions &options)
Definition: json_util.cc:207
google::protobuf::ConformanceTestSuite::RECOMMENDED
@ RECOMMENDED
Definition: conformance_test.h:199
google::protobuf::StringAppendV
void StringAppendV(string *dst, const char *format, va_list ap)
Definition: stringprintf.cc:57
google::protobuf::util::MessageDifferencer::set_field_comparator
void set_field_comparator(FieldComparator *comparator)
Definition: message_differencer.cc:288
google::protobuf::TextFormat
Definition: text_format.h:70
ok
ROSCPP_DECL bool ok()
google::protobuf::ConformanceTestSuite::ConformanceRequestSetting
Definition: conformance_test.h:202
google::protobuf::ConformanceTestSuite::RunSuiteImpl
virtual void RunSuiteImpl()=0
strutil.h
google::protobuf::util::MessageDifferencer::Compare
bool Compare(const Message &message1, const Message &message2)
Definition: message_differencer.cc:482
format
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:2773
google::protobuf::TextFormat::ParseFromString
static bool ParseFromString(const std::string &input, Message *output)
Definition: text_format.cc:1496
google::protobuf::python::cdescriptor_pool::New
static PyObject * New(PyTypeObject *type, PyObject *args, PyObject *kwargs)
Definition: descriptor_pool.cc:177
message.h
testing::internal::fmt
GTEST_API_ const char * fmt
Definition: gtest.h:1835
GOOGLE_LOG
#define GOOGLE_LOG(LEVEL)
Definition: logging.h:146
google::protobuf::util::MessageDifferencer::ReportDifferencesToString
void ReportDifferencesToString(std::string *output)
Definition: message_differencer.cc:449
google::protobuf::ConformanceTestSuite::ConformanceRequestSetting::InputFormatString
virtual string InputFormatString(conformance::WireFormat format) const
Definition: conformance_test.cc:134
google::protobuf::ConformanceTestSuite::VerifyResponse
void VerifyResponse(const ConformanceRequestSetting &setting, const string &equivalent_wire_format, const conformance::ConformanceResponse &response, bool need_report_success)
Definition: conformance_test.cc:230
text_format.h
google::protobuf::ConformanceTestSuite::AddExpectedFailedTest
void AddExpectedFailedTest(const std::string &test_name)
Definition: conformance_test.cc:365
google::protobuf::FileDescriptor::SYNTAX_PROTO3
@ SYNTAX_PROTO3
Definition: src/google/protobuf/descriptor.h:1394
google::protobuf::ConformanceTestSuite::ConformanceRequestSetting::GetLevel
const ConformanceLevel GetLevel() const
Definition: conformance_test.h:221
GOOGLE_CHECK
#define GOOGLE_CHECK(EXPRESSION)
Definition: logging.h:153
google::protobuf::ConformanceTestSuite::ReportSkip
void ReportSkip(const string &test_name, const conformance::ConformanceRequest &request, const conformance::ConformanceResponse &response)
Definition: conformance_test.cc:198
google::protobuf::ConformanceTestSuite::ConformanceRequestSetting::GetRequest
const conformance::ConformanceRequest & GetRequest() const
Definition: conformance_test.h:217
aditof::Status
Status
Status of any operation that the TOF sdk performs.
Definition: status_definitions.h:48
google::protobuf::ConformanceTestSuite::RunValidBinaryInputTest
void RunValidBinaryInputTest(const ConformanceRequestSetting &setting, const string &equivalent_wire_format)
Definition: conformance_test.cc:221
google::protobuf::Message
Definition: src/google/protobuf/message.h:205
google::protobuf::ConformanceTestSuite::unexpected_succeeding_tests_
std::set< std::string > unexpected_succeeding_tests_
Definition: conformance_test.h:310
google::protobuf::Message::GetDescriptor
const Descriptor * GetDescriptor() const
Definition: src/google/protobuf/message.h:326
google::protobuf::ConformanceTestSuite::REQUIRED
@ REQUIRED
Definition: conformance_test.h:198
google::protobuf::ConformanceTestSuite::output_
std::string output_
Definition: conformance_test.h:294
google::protobuf::MessageLite::SerializeAsString
std::string SerializeAsString() const
Definition: message_lite.cc:497
field_comparator.h
google::protobuf::ConformanceTestSuite::ReportSuccess
void ReportSuccess(const std::string &test_name)
Definition: conformance_test.cc:163
google::protobuf::ConformanceTestSuite::RunValidInputTest
void RunValidInputTest(const ConformanceRequestSetting &setting, const string &equivalent_text_format)
Definition: conformance_test.cc:209
stringprintf.h
google::protobuf::MessageLite::ParseFromString
bool ParseFromString(const std::string &data)
Definition: message_lite.cc:321
google::protobuf::ConformanceTestRunner::RunTest
virtual void RunTest(const std::string &test_name, const std::string &input, std::string *output)=0
google::protobuf::Message::New
Message * New() const override=0
google::protobuf::ConformanceTestSuite::ConformanceRequestSetting::GetTestName
string GetTestName() const
Definition: conformance_test.cc:110
google::protobuf::ConformanceTestSuite::skipped_
std::set< std::string > skipped_
Definition: conformance_test.h:313
google::protobuf::ConformanceTestSuite::verbose_
bool verbose_
Definition: conformance_test.h:292
google::protobuf::ConformanceTestSuite::runner_
ConformanceTestRunner * runner_
Definition: conformance_test.h:289
google::protobuf::ConformanceTestSuite::WireFormatToString
string WireFormatToString(conformance::WireFormat wire_format)
Definition: conformance_test.cc:345
google::protobuf::ConformanceTestSuite::RunTest
void RunTest(const std::string &test_name, const conformance::ConformanceRequest &request, conformance::ConformanceResponse *response)
Definition: conformance_test.cc:286
google::protobuf::util::DefaultFieldComparator
Definition: field_comparator.h:100
google::protobuf::ConformanceTestSuite::ConformanceRequestSetting::GetTestMessage
Message * GetTestMessage() const
Definition: conformance_test.cc:105
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
json_util.h
google::protobuf::ConformanceTestSuite::CheckSetEmpty
bool CheckSetEmpty(const std::set< string > &set_to_check, const std::string &write_to_file, const std::string &msg)
Definition: conformance_test.cc:313
google::protobuf::ConformanceTestSuite::enforce_recommended_
bool enforce_recommended_
Definition: conformance_test.h:293
level
GLint level
Definition: glcorearb.h:2773
check
static void check(upb_inttable *t)
Definition: php/ext/google/protobuf/upb.c:5088
conformance_test.h
google::protobuf::ConformanceTestSuite::failure_list_filename_
std::string failure_list_filename_
Definition: conformance_test.h:296
google
Definition: data_proto2_to_proto3_util.h:11
benchmarks.python.py_benchmark.args
args
Definition: py_benchmark.py:24
google::protobuf::ConformanceTestSuite::test_names_
std::set< std::string > test_names_
Definition: conformance_test.h:304


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:48