aboutsummaryrefslogtreecommitdiffhomepage
path: root/conformance/conformance_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'conformance/conformance_test.cc')
-rw-r--r--conformance/conformance_test.cc462
1 files changed, 343 insertions, 119 deletions
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index e9f3a8a8..f1b92056 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -34,11 +34,14 @@
#include "conformance.pb.h"
#include "conformance_test.h"
+#include <google/protobuf/test_messages_proto3.pb.h>
+#include <google/protobuf/test_messages_proto2.pb.h>
+
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/text_format.h>
-#include <google/protobuf/util/json_util.h>
#include <google/protobuf/util/field_comparator.h>
+#include <google/protobuf/util/json_util.h>
#include <google/protobuf/util/message_differencer.h>
#include <google/protobuf/util/type_resolver_util.h>
#include <google/protobuf/wire_format_lite.h>
@@ -47,7 +50,6 @@
using conformance::ConformanceRequest;
using conformance::ConformanceResponse;
-using conformance::TestAllTypes;
using conformance::WireFormat;
using google::protobuf::Descriptor;
using google::protobuf::FieldDescriptor;
@@ -58,6 +60,8 @@ using google::protobuf::util::JsonToBinaryString;
using google::protobuf::util::MessageDifferencer;
using google::protobuf::util::NewTypeResolverForDescriptorPool;
using google::protobuf::util::Status;
+using protobuf_test_messages::proto3::TestAllTypesProto3;
+using protobuf_test_messages::proto2::TestAllTypesProto2;
using std::string;
namespace {
@@ -107,13 +111,18 @@ string cat(const string& a, const string& b,
// The maximum number of bytes that it takes to encode a 64-bit varint.
#define VARINT_MAX_LEN 10
-size_t vencode64(uint64_t val, char *buf) {
+size_t vencode64(uint64_t val, int over_encoded_bytes, char *buf) {
if (val == 0) { buf[0] = 0; return 1; }
size_t i = 0;
while (val) {
uint8_t byte = val & 0x7fU;
val >>= 7;
- if (val) byte |= 0x80U;
+ if (val || over_encoded_bytes) byte |= 0x80U;
+ buf[i++] = byte;
+ }
+ while (over_encoded_bytes--) {
+ assert(i < 10);
+ uint8_t byte = over_encoded_bytes ? 0x80 : 0;
buf[i++] = byte;
}
return i;
@@ -121,7 +130,15 @@ size_t vencode64(uint64_t val, char *buf) {
string varint(uint64_t x) {
char buf[VARINT_MAX_LEN];
- size_t len = vencode64(x, buf);
+ size_t len = vencode64(x, 0, buf);
+ return string(buf, len);
+}
+
+// Encodes a varint that is |extra| bytes longer than it needs to be, but still
+// valid.
+string longvarint(uint64_t x, int extra) {
+ char buf[VARINT_MAX_LEN];
+ size_t len = vencode64(x, extra, buf);
return string(buf, len);
}
@@ -130,8 +147,8 @@ string fixed32(void *data) { return string(static_cast<char*>(data), 4); }
string fixed64(void *data) { return string(static_cast<char*>(data), 8); }
string delim(const string& buf) { return cat(varint(buf.size()), buf); }
-string uint32(uint32_t u32) { return fixed32(&u32); }
-string uint64(uint64_t u64) { return fixed64(&u64); }
+string u32(uint32_t u32) { return fixed32(&u32); }
+string u64(uint64_t u64) { return fixed64(&u64); }
string flt(float f) { return fixed32(&f); }
string dbl(double d) { return fixed64(&d); }
string zz32(int32_t x) { return varint(WireFormatLite::ZigZagEncode32(x)); }
@@ -147,16 +164,19 @@ string submsg(uint32_t fn, const string& buf) {
#define UNKNOWN_FIELD 666
-uint32_t GetFieldNumberForType(FieldDescriptor::Type type, bool repeated) {
- const Descriptor* d = TestAllTypes().GetDescriptor();
+const FieldDescriptor* GetFieldForType(FieldDescriptor::Type type,
+ bool repeated, bool isProto3) {
+
+ const Descriptor* d = isProto3 ?
+ TestAllTypesProto3().GetDescriptor() : TestAllTypesProto2().GetDescriptor();
for (int i = 0; i < d->field_count(); i++) {
const FieldDescriptor* f = d->field(i);
if (f->type() == type && f->is_repeated() == repeated) {
- return f->number();
+ return f;
}
}
GOOGLE_LOG(FATAL) << "Couldn't find field with type " << (int)type;
- return 0;
+ return nullptr;
}
string UpperCase(string str) {
@@ -255,10 +275,19 @@ void ConformanceTestSuite::RunTest(const string& test_name,
void ConformanceTestSuite::RunValidInputTest(
const string& test_name, ConformanceLevel level, const string& input,
WireFormat input_format, const string& equivalent_text_format,
- WireFormat requested_output) {
- TestAllTypes reference_message;
+ WireFormat requested_output, bool isProto3) {
+ auto newTestMessage = [&isProto3]() {
+ Message* newMessage;
+ if (isProto3) {
+ newMessage = new TestAllTypesProto3;
+ } else {
+ newMessage = new TestAllTypesProto2;
+ }
+ return newMessage;
+ };
+ Message* reference_message = newTestMessage();
GOOGLE_CHECK(
- TextFormat::ParseFromString(equivalent_text_format, &reference_message))
+ TextFormat::ParseFromString(equivalent_text_format, reference_message))
<< "Failed to parse data for test case: " << test_name
<< ", data: " << equivalent_text_format;
@@ -266,13 +295,21 @@ void ConformanceTestSuite::RunValidInputTest(
ConformanceResponse response;
switch (input_format) {
- case conformance::PROTOBUF:
+ case conformance::PROTOBUF: {
request.set_protobuf_payload(input);
+ if (isProto3) {
+ request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
+ } else {
+ request.set_message_type("protobuf_test_messages.proto2.TestAllTypesProto2");
+ }
break;
+ }
- case conformance::JSON:
+ case conformance::JSON: {
+ request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
request.set_json_payload(input);
break;
+ }
default:
GOOGLE_LOG(FATAL) << "Unspecified input format";
@@ -282,7 +319,7 @@ void ConformanceTestSuite::RunValidInputTest(
RunTest(test_name, request, &response);
- TestAllTypes test_message;
+ Message *test_message = newTestMessage();
switch (response.result_case()) {
case ConformanceResponse::RESULT_NOT_SET:
@@ -318,10 +355,10 @@ void ConformanceTestSuite::RunValidInputTest(
return;
}
- if (!test_message.ParseFromString(binary_protobuf)) {
+ if (!test_message->ParseFromString(binary_protobuf)) {
ReportFailure(test_name, level, request, response,
- "INTERNAL ERROR: internal JSON->protobuf transcode "
- "yielded unparseable proto.");
+ "INTERNAL ERROR: internal JSON->protobuf transcode "
+ "yielded unparseable proto.");
return;
}
@@ -336,9 +373,9 @@ void ConformanceTestSuite::RunValidInputTest(
return;
}
- if (!test_message.ParseFromString(response.protobuf_payload())) {
+ if (!test_message->ParseFromString(response.protobuf_payload())) {
ReportFailure(test_name, level, request, response,
- "Protobuf output we received from test was unparseable.");
+ "Protobuf output we received from test was unparseable.");
return;
}
@@ -357,7 +394,9 @@ void ConformanceTestSuite::RunValidInputTest(
string differences;
differencer.ReportDifferencesToString(&differences);
- if (differencer.Compare(reference_message, test_message)) {
+ bool check;
+ check = differencer.Compare(*reference_message, *test_message);
+ if (check) {
ReportSuccess(test_name);
} else {
ReportFailure(test_name, level, request, response,
@@ -365,14 +404,19 @@ void ConformanceTestSuite::RunValidInputTest(
differences.c_str());
}
}
-
-// Expect that this precise protobuf will cause a parse error.
-void ConformanceTestSuite::ExpectParseFailureForProto(
- const string& proto, const string& test_name, ConformanceLevel level) {
+void ConformanceTestSuite::ExpectParseFailureForProtoWithProtoVersion (
+ const string& proto, const string& test_name, ConformanceLevel level,
+ bool isProto3) {
ConformanceRequest request;
ConformanceResponse response;
request.set_protobuf_payload(proto);
+ if (isProto3) {
+ request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
+ } else {
+ request.set_message_type("protobuf_test_messages.proto2.TestAllTypesProto2");
+ }
string effective_test_name = ConformanceLevelToString(level) +
+ (isProto3 ? ".Proto3" : ".Proto2") +
".ProtobufInput." + test_name;
// We don't expect output, but if the program erroneously accepts the protobuf
@@ -390,6 +434,13 @@ void ConformanceTestSuite::ExpectParseFailureForProto(
}
}
+// Expect that this precise protobuf will cause a parse error.
+void ConformanceTestSuite::ExpectParseFailureForProto(
+ const string& proto, const string& test_name, ConformanceLevel level) {
+ ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level, true);
+ ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level, false);
+}
+
// Expect that this protobuf will cause a parse error, even if it is followed
// by valid protobuf data. We can try running this twice: once with this
// data verbatim and once with this data followed by some valid data.
@@ -404,33 +455,48 @@ void ConformanceTestSuite::RunValidJsonTest(
const string& test_name, ConformanceLevel level, const string& input_json,
const string& equivalent_text_format) {
RunValidInputTest(
- ConformanceLevelToString(level) + ".JsonInput." + test_name +
+ ConformanceLevelToString(level) + ".Proto3.JsonInput." + test_name +
".ProtobufOutput", level, input_json, conformance::JSON,
- equivalent_text_format, conformance::PROTOBUF);
+ equivalent_text_format, conformance::PROTOBUF, true);
RunValidInputTest(
- ConformanceLevelToString(level) + ".JsonInput." + test_name +
+ ConformanceLevelToString(level) + ".Proto3.JsonInput." + test_name +
".JsonOutput", level, input_json, conformance::JSON,
- equivalent_text_format, conformance::JSON);
+ equivalent_text_format, conformance::JSON, true);
}
void ConformanceTestSuite::RunValidJsonTestWithProtobufInput(
- const string& test_name, ConformanceLevel level, const TestAllTypes& input,
+ const string& test_name, ConformanceLevel level, const TestAllTypesProto3& input,
const string& equivalent_text_format) {
RunValidInputTest(
- ConformanceLevelToString(level) + ".ProtobufInput." + test_name +
+ ConformanceLevelToString(level) + ".Proto3" + ".ProtobufInput." + test_name +
".JsonOutput", level, input.SerializeAsString(), conformance::PROTOBUF,
- equivalent_text_format, conformance::JSON);
+ equivalent_text_format, conformance::JSON, true);
}
void ConformanceTestSuite::RunValidProtobufTest(
- const string& test_name, ConformanceLevel level, const TestAllTypes& input,
- const string& equivalent_text_format) {
- RunValidInputTest("ProtobufInput." + test_name + ".ProtobufOutput", level,
- input.SerializeAsString(), conformance::PROTOBUF,
- equivalent_text_format, conformance::PROTOBUF);
- RunValidInputTest("ProtobufInput." + test_name + ".JsonOutput", level,
- input.SerializeAsString(), conformance::PROTOBUF,
- equivalent_text_format, conformance::JSON);
+ const string& test_name, ConformanceLevel level,
+ const string& input_protobuf, const string& equivalent_text_format,
+ bool isProto3) {
+ string rname = ".Proto3";
+ if (!isProto3) {
+ rname = ".Proto2";
+ }
+ RunValidInputTest(
+ ConformanceLevelToString(level) + rname + ".ProtobufInput." + test_name +
+ ".ProtobufOutput", level, input_protobuf, conformance::PROTOBUF,
+ equivalent_text_format, conformance::PROTOBUF, isProto3);
+ if (isProto3) {
+ RunValidInputTest(
+ ConformanceLevelToString(level) + rname + ".ProtobufInput." + test_name +
+ ".JsonOutput", level, input_protobuf, conformance::PROTOBUF,
+ equivalent_text_format, conformance::JSON, isProto3);
+ }
+}
+
+void ConformanceTestSuite::RunValidProtobufTestWithMessage(
+ const string& test_name, ConformanceLevel level, const Message *input,
+ const string& equivalent_text_format, bool isProto3) {
+ RunValidProtobufTest(test_name, level, input->SerializeAsString(), equivalent_text_format, isProto3);
}
// According to proto3 JSON specification, JSON serializers follow more strict
@@ -445,9 +511,10 @@ void ConformanceTestSuite::RunValidJsonTestWithValidator(
ConformanceResponse response;
request.set_json_payload(input_json);
request.set_requested_output_format(conformance::JSON);
+ request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
string effective_test_name = ConformanceLevelToString(level) +
- ".JsonInput." + test_name + ".Validator";
+ ".Proto3.JsonInput." + test_name + ".Validator";
RunTest(effective_test_name, request, &response);
@@ -483,8 +550,9 @@ void ConformanceTestSuite::ExpectParseFailureForJson(
ConformanceRequest request;
ConformanceResponse response;
request.set_json_payload(input_json);
+ request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
string effective_test_name =
- ConformanceLevelToString(level) + ".JsonInput." + test_name;
+ ConformanceLevelToString(level) + ".Proto3.JsonInput." + test_name;
// We don't expect output, but if the program erroneously accepts the protobuf
// we let it send its response as this. We must not leave it unspecified.
@@ -503,7 +571,7 @@ void ConformanceTestSuite::ExpectParseFailureForJson(
void ConformanceTestSuite::ExpectSerializeFailureForJson(
const string& test_name, ConformanceLevel level, const string& text_format) {
- TestAllTypes payload_message;
+ TestAllTypesProto3 payload_message;
GOOGLE_CHECK(
TextFormat::ParseFromString(text_format, &payload_message))
<< "Failed to parse: " << text_format;
@@ -511,6 +579,7 @@ void ConformanceTestSuite::ExpectSerializeFailureForJson(
ConformanceRequest request;
ConformanceResponse response;
request.set_protobuf_payload(payload_message.SerializeAsString());
+ request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
string effective_test_name =
ConformanceLevelToString(level) + "." + test_name + ".JsonOutput";
request.set_requested_output_format(conformance::JSON);
@@ -526,6 +595,7 @@ void ConformanceTestSuite::ExpectSerializeFailureForJson(
}
}
+//TODO: proto2?
void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
// Incomplete values for each wire type.
static const string incompletes[6] = {
@@ -537,8 +607,8 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
string("abc") // 32BIT
};
- uint32_t fieldnum = GetFieldNumberForType(type, false);
- uint32_t rep_fieldnum = GetFieldNumberForType(type, true);
+ const FieldDescriptor* field = GetFieldForType(type, false, true);
+ const FieldDescriptor* rep_field = GetFieldForType(type, true, true);
WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
static_cast<WireFormatLite::FieldType>(type));
const string& incomplete = incompletes[wire_type];
@@ -546,11 +616,11 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
UpperCase(string(".") + FieldDescriptor::TypeName(type));
ExpectParseFailureForProto(
- tag(fieldnum, wire_type),
+ tag(field->number(), wire_type),
"PrematureEofBeforeKnownNonRepeatedValue" + type_name, REQUIRED);
ExpectParseFailureForProto(
- tag(rep_fieldnum, wire_type),
+ tag(rep_field->number(), wire_type),
"PrematureEofBeforeKnownRepeatedValue" + type_name, REQUIRED);
ExpectParseFailureForProto(
@@ -558,11 +628,11 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
"PrematureEofBeforeUnknownValue" + type_name, REQUIRED);
ExpectParseFailureForProto(
- cat( tag(fieldnum, wire_type), incomplete ),
+ cat( tag(field->number(), wire_type), incomplete ),
"PrematureEofInsideKnownNonRepeatedValue" + type_name, REQUIRED);
ExpectParseFailureForProto(
- cat( tag(rep_fieldnum, wire_type), incomplete ),
+ cat( tag(rep_field->number(), wire_type), incomplete ),
"PrematureEofInsideKnownRepeatedValue" + type_name, REQUIRED);
ExpectParseFailureForProto(
@@ -571,12 +641,12 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
if (wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
ExpectParseFailureForProto(
- cat( tag(fieldnum, wire_type), varint(1) ),
+ cat( tag(field->number(), wire_type), varint(1) ),
"PrematureEofInDelimitedDataForKnownNonRepeatedValue" + type_name,
REQUIRED);
ExpectParseFailureForProto(
- cat( tag(rep_fieldnum, wire_type), varint(1) ),
+ cat( tag(rep_field->number(), wire_type), varint(1) ),
"PrematureEofInDelimitedDataForKnownRepeatedValue" + type_name,
REQUIRED);
@@ -591,7 +661,7 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
cat( tag(WireFormatLite::TYPE_INT32, WireFormatLite::WIRETYPE_VARINT),
incompletes[WireFormatLite::WIRETYPE_VARINT] );
ExpectHardParseFailureForProto(
- cat( tag(fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
+ cat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
varint(incomplete_submsg.size()),
incomplete_submsg ),
"PrematureEofInSubmessageValue" + type_name, REQUIRED);
@@ -601,19 +671,53 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
// Packed region ends in the middle of a value.
ExpectHardParseFailureForProto(
- cat( tag(rep_fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
- varint(incomplete.size()),
- incomplete ),
+ cat(tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
+ varint(incomplete.size()), incomplete),
"PrematureEofInPackedFieldValue" + type_name, REQUIRED);
// EOF in the middle of packed region.
ExpectParseFailureForProto(
- cat( tag(rep_fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
- varint(1) ),
+ cat(tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
+ varint(1)),
"PrematureEofInPackedField" + type_name, REQUIRED);
}
}
+void ConformanceTestSuite::TestValidDataForType(
+ FieldDescriptor::Type type,
+ std::vector<std::pair<std::string, std::string>> values) {
+ for (int isProto3 = 0; isProto3 < 2; isProto3++) {
+ const string type_name =
+ UpperCase(string(".") + FieldDescriptor::TypeName(type));
+ WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
+ static_cast<WireFormatLite::FieldType>(type));
+ const FieldDescriptor* field = GetFieldForType(type, false, isProto3);
+ const FieldDescriptor* rep_field = GetFieldForType(type, true, isProto3);
+
+ RunValidProtobufTest("ValidDataScalar" + type_name, REQUIRED,
+ cat(tag(field->number(), wire_type), values[0].first),
+ field->name() + ": " + values[0].second, isProto3);
+
+ string proto;
+ string text = field->name() + ": " + values.back().second;
+ for (size_t i = 0; i < values.size(); i++) {
+ proto += cat(tag(field->number(), wire_type), values[i].first);
+ }
+ RunValidProtobufTest("RepeatedScalarSelectsLast" + type_name, REQUIRED,
+ proto, text, isProto3);
+
+ proto.clear();
+ text.clear();
+
+ for (size_t i = 0; i < values.size(); i++) {
+ proto += cat(tag(rep_field->number(), wire_type), values[i].first);
+ text += rep_field->name() + ": " + values[i].second + " ";
+ }
+ RunValidProtobufTest("ValidDataRepeated" + type_name, REQUIRED,
+ proto, text, isProto3);
+ }
+}
+
void ConformanceTestSuite::SetFailureList(const string& filename,
const vector<string>& failure_list) {
failure_list_filename_ = filename;
@@ -622,7 +726,7 @@ void ConformanceTestSuite::SetFailureList(const string& filename,
std::inserter(expected_to_fail_, expected_to_fail_.end()));
}
-bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
+bool ConformanceTestSuite::CheckSetEmpty(const std::set<string>& set_to_check,
const std::string& write_to_file,
const std::string& msg) {
if (set_to_check.empty()) {
@@ -630,7 +734,7 @@ bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
} else {
StringAppendF(&output_, "\n");
StringAppendF(&output_, "%s\n\n", msg.c_str());
- for (set<string>::const_iterator iter = set_to_check.begin();
+ for (std::set<string>::const_iterator iter = set_to_check.begin();
iter != set_to_check.end(); ++iter) {
StringAppendF(&output_, " %s\n", iter->c_str());
}
@@ -639,7 +743,7 @@ bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
if (!write_to_file.empty()) {
std::ofstream os(write_to_file);
if (os) {
- for (set<string>::const_iterator iter = set_to_check.begin();
+ for (std::set<string>::const_iterator iter = set_to_check.begin();
iter != set_to_check.end(); ++iter) {
os << *iter << "\n";
}
@@ -653,6 +757,60 @@ bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
}
}
+// TODO: proto2?
+void ConformanceTestSuite::TestIllegalTags() {
+ // field num 0 is illegal
+ string nullfield[] = {
+ "\1DEADBEEF",
+ "\2\1\1",
+ "\3\4",
+ "\5DEAD"
+ };
+ for (int i = 0; i < 4; i++) {
+ string name = "IllegalZeroFieldNum_Case_0";
+ name.back() += i;
+ ExpectParseFailureForProto(nullfield[i], name, REQUIRED);
+ }
+}
+template <class MessageType>
+void ConformanceTestSuite::TestOneofMessage (MessageType &message,
+ bool isProto3) {
+ message.set_oneof_uint32(0);
+ RunValidProtobufTestWithMessage(
+ "OneofZeroUint32", RECOMMENDED, &message, "oneof_uint32: 0", isProto3);
+ message.mutable_oneof_nested_message()->set_a(0);
+ RunValidProtobufTestWithMessage(
+ "OneofZeroMessage", RECOMMENDED, &message,
+ isProto3 ? "oneof_nested_message: {}" : "oneof_nested_message: {a: 0}",
+ isProto3);
+ message.mutable_oneof_nested_message()->set_a(1);
+ RunValidProtobufTestWithMessage(
+ "OneofZeroMessageSetTwice", RECOMMENDED, &message,
+ "oneof_nested_message: {a: 1}",
+ isProto3);
+ message.set_oneof_string("");
+ RunValidProtobufTestWithMessage(
+ "OneofZeroString", RECOMMENDED, &message, "oneof_string: \"\"", isProto3);
+ message.set_oneof_bytes("");
+ RunValidProtobufTestWithMessage(
+ "OneofZeroBytes", RECOMMENDED, &message, "oneof_bytes: \"\"", isProto3);
+ message.set_oneof_bool(false);
+ RunValidProtobufTestWithMessage(
+ "OneofZeroBool", RECOMMENDED, &message, "oneof_bool: false", isProto3);
+ message.set_oneof_uint64(0);
+ RunValidProtobufTestWithMessage(
+ "OneofZeroUint64", RECOMMENDED, &message, "oneof_uint64: 0", isProto3);
+ message.set_oneof_float(0.0f);
+ RunValidProtobufTestWithMessage(
+ "OneofZeroFloat", RECOMMENDED, &message, "oneof_float: 0", isProto3);
+ message.set_oneof_double(0.0);
+ RunValidProtobufTestWithMessage(
+ "OneofZeroDouble", RECOMMENDED, &message, "oneof_double: 0", isProto3);
+ message.set_oneof_enum(MessageType::FOO);
+ RunValidProtobufTestWithMessage(
+ "OneofZeroEnum", RECOMMENDED, &message, "oneof_enum: FOO", isProto3);
+}
+
bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
std::string* output) {
runner_ = runner;
@@ -664,7 +822,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
unexpected_succeeding_tests_.clear();
type_resolver_.reset(NewTypeResolverForDescriptorPool(
kTypeUrlPrefix, DescriptorPool::generated_pool()));
- type_url_ = GetTypeUrl(TestAllTypes::descriptor());
+ type_url_ = GetTypeUrl(TestAllTypesProto3::descriptor());
output_ = "\nCONFORMANCE TEST BEGIN ====================================\n\n";
@@ -673,6 +831,99 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
TestPrematureEOFForType(static_cast<FieldDescriptor::Type>(i));
}
+ TestIllegalTags();
+
+ int64 kInt64Min = -9223372036854775808ULL;
+ int64 kInt64Max = 9223372036854775807ULL;
+ uint64 kUint64Max = 18446744073709551615ULL;
+ int32 kInt32Max = 2147483647;
+ int32 kInt32Min = -2147483648;
+ uint32 kUint32Max = 4294967295UL;
+
+ TestValidDataForType(FieldDescriptor::TYPE_DOUBLE, {
+ {dbl(0.1), "0.1"},
+ {dbl(1.7976931348623157e+308), "1.7976931348623157e+308"},
+ {dbl(2.22507385850720138309e-308), "2.22507385850720138309e-308"}
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_FLOAT, {
+ {flt(0.1), "0.1"},
+ {flt(1.00000075e-36), "1.00000075e-36"},
+ {flt(3.402823e+38), "3.402823e+38"}, // 3.40282347e+38
+ {flt(1.17549435e-38f), "1.17549435e-38"}
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_INT64, {
+ {varint(12345), "12345"},
+ {varint(kInt64Max), std::to_string(kInt64Max)},
+ {varint(kInt64Min), std::to_string(kInt64Min)}
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_UINT64, {
+ {varint(12345), "12345"},
+ {varint(kUint64Max), std::to_string(kUint64Max)},
+ {varint(0), "0"}
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_INT32, {
+ {varint(12345), "12345"},
+ {longvarint(12345, 2), "12345"},
+ {longvarint(12345, 7), "12345"},
+ {varint(kInt32Max), std::to_string(kInt32Max)},
+ {varint(kInt32Min), std::to_string(kInt32Min)},
+ {varint(1LL << 33), std::to_string(static_cast<int32>(1LL << 33))},
+ {varint((1LL << 33) - 1),
+ std::to_string(static_cast<int32>((1LL << 33) - 1))},
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_UINT32, {
+ {varint(12345), "12345"},
+ {longvarint(12345, 2), "12345"},
+ {longvarint(12345, 7), "12345"},
+ {varint(kUint32Max), std::to_string(kUint32Max)}, // UINT32_MAX
+ {varint(0), "0"},
+ {varint(1LL << 33), std::to_string(static_cast<uint32>(1LL << 33))},
+ {varint((1LL << 33) - 1),
+ std::to_string(static_cast<uint32>((1LL << 33) - 1))},
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_FIXED64, {
+ {u64(12345), "12345"},
+ {u64(kUint64Max), std::to_string(kUint64Max)},
+ {u64(0), "0"}
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_FIXED32, {
+ {u32(12345), "12345"},
+ {u32(kUint32Max), std::to_string(kUint32Max)}, // UINT32_MAX
+ {u32(0), "0"}
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_SFIXED64, {
+ {u64(12345), "12345"},
+ {u64(kInt64Max), std::to_string(kInt64Max)},
+ {u64(kInt64Min), std::to_string(kInt64Min)}
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_SFIXED32, {
+ {u32(12345), "12345"},
+ {u32(kInt32Max), std::to_string(kInt32Max)},
+ {u32(kInt32Min), std::to_string(kInt32Min)}
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_BOOL, {
+ {varint(1), "true"},
+ {varint(0), "false"},
+ {varint(12345678), "true"}
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_SINT32, {
+ {zz32(12345), "12345"},
+ {zz32(kInt32Max), std::to_string(kInt32Max)},
+ {zz32(kInt32Min), std::to_string(kInt32Min)}
+ });
+ TestValidDataForType(FieldDescriptor::TYPE_SINT64, {
+ {zz64(12345), "12345"},
+ {zz64(kInt64Max), std::to_string(kInt64Max)},
+ {zz64(kInt64Min), std::to_string(kInt64Min)}
+ });
+
+ // TODO(haberman):
+ // TestValidDataForType(FieldDescriptor::TYPE_STRING
+ // TestValidDataForType(FieldDescriptor::TYPE_GROUP
+ // TestValidDataForType(FieldDescriptor::TYPE_MESSAGE
+ // TestValidDataForType(FieldDescriptor::TYPE_BYTES
+ // TestValidDataForType(FieldDescriptor::TYPE_ENUM
+
RunValidJsonTest("HelloWorld", REQUIRED,
"{\"optionalString\":\"Hello, World!\"}",
"optional_string: 'Hello, World!'");
@@ -685,7 +936,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
R"({
"fieldname1": 1,
"fieldName2": 2,
- "fieldName3": 3,
+ "FieldName3": 3,
"fieldName4": 4
})",
R"(
@@ -725,12 +976,12 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
RunValidJsonTest(
"FieldNameWithDoubleUnderscores", RECOMMENDED,
R"({
- "fieldName13": 13,
- "fieldName14": 14,
+ "FieldName13": 13,
+ "FieldName14": 14,
"fieldName15": 15,
"fieldName16": 16,
"fieldName17": 17,
- "fieldName18": 18
+ "FieldName18": 18
})",
R"(
__field_name13: 13
@@ -873,21 +1124,19 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
"optionalNestedMessage": {a: 1},
"optional_nested_message": {}
})");
- // NOTE: The spec for JSON support is still being sorted out, these may not
- // all be correct.
// Serializers should use lowerCamelCase by default.
RunValidJsonTestWithValidator(
"FieldNameInLowerCamelCase", REQUIRED,
R"({
"fieldname1": 1,
"fieldName2": 2,
- "fieldName3": 3,
+ "FieldName3": 3,
"fieldName4": 4
})",
[](const Json::Value& value) {
return value.isMember("fieldname1") &&
value.isMember("fieldName2") &&
- value.isMember("fieldName3") &&
+ value.isMember("FieldName3") &&
value.isMember("fieldName4");
});
RunValidJsonTestWithValidator(
@@ -921,20 +1170,20 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
RunValidJsonTestWithValidator(
"FieldNameWithDoubleUnderscores", RECOMMENDED,
R"({
- "fieldName13": 13,
- "fieldName14": 14,
+ "FieldName13": 13,
+ "FieldName14": 14,
"fieldName15": 15,
"fieldName16": 16,
"fieldName17": 17,
- "fieldName18": 18
+ "FieldName18": 18
})",
[](const Json::Value& value) {
- return value.isMember("fieldName13") &&
- value.isMember("fieldName14") &&
+ return value.isMember("FieldName13") &&
+ value.isMember("FieldName14") &&
value.isMember("fieldName15") &&
value.isMember("fieldName16") &&
value.isMember("fieldName17") &&
- value.isMember("fieldName18");
+ value.isMember("FieldName18");
});
// Integer fields.
@@ -1072,7 +1321,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
"Int32FieldNegativeWithLeadingZero", REQUIRED,
R"({"optionalInt32": -01})");
// String values must follow the same syntax rule. Specifically leading
- // or traling spaces are not allowed.
+ // or trailing spaces are not allowed.
ExpectParseFailureForJson(
"Int32FieldLeadingSpace", REQUIRED,
R"({"optionalInt32": " 1"})");
@@ -1169,7 +1418,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
"optional_float: -inf");
// Non-cannonical Nan will be correctly normalized.
{
- TestAllTypes message;
+ TestAllTypesProto3 message;
// IEEE floating-point standard 32-bit quiet NaN:
// 0111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
message.set_optional_float(
@@ -1241,7 +1490,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
"optional_double: -inf");
// Non-cannonical Nan will be correctly normalized.
{
- TestAllTypes message;
+ TestAllTypesProto3 message;
message.set_optional_double(
WireFormatLite::DecodeDouble(0x7FFA123456789ABCLL));
RunValidJsonTestWithProtobufInput(
@@ -1356,9 +1605,10 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
"BytesField", REQUIRED,
R"({"optionalBytes": "AQI="})",
R"(optional_bytes: "\x01\x02")");
- ExpectParseFailureForJson(
- "BytesFieldInvalidBase64Characters", REQUIRED,
- R"({"optionalBytes": "-_=="})");
+ RunValidJsonTest(
+ "BytesFieldBase64Url", RECOMMENDED,
+ R"({"optionalBytes": "-_"})",
+ R"(optional_bytes: "\xfb")");
// Message fields.
RunValidJsonTest(
@@ -1371,36 +1621,10 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
"OneofFieldDuplicate", REQUIRED,
R"({"oneofUint32": 1, "oneofString": "test"})");
// Ensure zero values for oneof make it out/backs.
- {
- TestAllTypes message;
- message.set_oneof_uint32(0);
- RunValidProtobufTest(
- "OneofZeroUint32", RECOMMENDED, message, "oneof_uint32: 0");
- message.mutable_oneof_nested_message()->set_a(0);
- RunValidProtobufTest(
- "OneofZeroMessage", RECOMMENDED, message, "oneof_nested_message: {}");
- message.set_oneof_string("");
- RunValidProtobufTest(
- "OneofZeroString", RECOMMENDED, message, "oneof_string: \"\"");
- message.set_oneof_bytes("");
- RunValidProtobufTest(
- "OneofZeroBytes", RECOMMENDED, message, "oneof_bytes: \"\"");
- message.set_oneof_bool(false);
- RunValidProtobufTest(
- "OneofZeroBool", RECOMMENDED, message, "oneof_bool: false");
- message.set_oneof_uint64(0);
- RunValidProtobufTest(
- "OneofZeroUint64", RECOMMENDED, message, "oneof_uint64: 0");
- message.set_oneof_float(0.0f);
- RunValidProtobufTest(
- "OneofZeroFloat", RECOMMENDED, message, "oneof_float: 0");
- message.set_oneof_double(0.0);
- RunValidProtobufTest(
- "OneofZeroDouble", RECOMMENDED, message, "oneof_double: 0");
- message.set_oneof_enum(TestAllTypes::FOO);
- RunValidProtobufTest(
- "OneofZeroEnum", RECOMMENDED, message, "oneof_enum: FOO");
- }
+ TestAllTypesProto3 messageProto3;
+ TestAllTypesProto2 messageProto2;
+ TestOneofMessage(messageProto3, true);
+ TestOneofMessage(messageProto2, false);
RunValidJsonTest(
"OneofZeroUint32", RECOMMENDED,
R"({"oneofUint32": 0})", "oneof_uint32: 0");
@@ -2050,13 +2274,13 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
"Any", REQUIRED,
R"({
"optionalAny": {
- "@type": "type.googleapis.com/conformance.TestAllTypes",
+ "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3",
"optionalInt32": 12345
}
})",
R"(
optional_any: {
- [type.googleapis.com/conformance.TestAllTypes] {
+ [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
optional_int32: 12345
}
}
@@ -2067,7 +2291,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
"optionalAny": {
"@type": "type.googleapis.com/google.protobuf.Any",
"value": {
- "@type": "type.googleapis.com/conformance.TestAllTypes",
+ "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3",
"optionalInt32": 12345
}
}
@@ -2075,7 +2299,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
R"(
optional_any: {
[type.googleapis.com/google.protobuf.Any] {
- [type.googleapis.com/conformance.TestAllTypes] {
+ [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
optional_int32: 12345
}
}
@@ -2087,12 +2311,12 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
R"({
"optionalAny": {
"optionalInt32": 12345,
- "@type": "type.googleapis.com/conformance.TestAllTypes"
+ "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3"
}
})",
R"(
optional_any: {
- [type.googleapis.com/conformance.TestAllTypes] {
+ [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
optional_int32: 12345
}
}