Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions conformance/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# Protobuf conformance tests.

load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_cc//cc:cc_test.bzl", "cc_test")
load("@rules_cc//cc:defs.bzl", "cc_binary", "objc_library")
load("@rules_java//java:defs.bzl", "java_binary")
load("@rules_python//python:py_binary.bzl", "py_binary")
Expand Down Expand Up @@ -130,6 +131,7 @@ cc_library(
srcs = ["binary_json_conformance_suite.cc"],
hdrs = ["binary_json_conformance_suite.h"],
deps = [
":binary_wireformat",
":conformance_cc_proto",
":conformance_test_lib",
"//:test_messages_proto2_cc_proto",
Expand Down Expand Up @@ -191,6 +193,30 @@ cc_library(
],
)

cc_library(
name = "binary_wireformat",
testonly = 1,
srcs = ["binary_wireformat.cc"],
hdrs = ["binary_wireformat.h"],
deps = [
"//src/google/protobuf:endian",
"//src/google/protobuf:protobuf_lite",
"@abseil-cpp//absl/strings",
],
)

cc_test(
name = "binary_wireformat_test",
srcs = ["binary_wireformat_test.cc"],
deps = [
":binary_wireformat",
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
)

cc_binary(
name = "conformance_test_runner",
testonly = 1,
Expand Down
160 changes: 57 additions & 103 deletions conformance/binary_json_conformance_suite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@
#include "json/config.h"
#include "json/reader.h"
#include "json/value.h"
#include "binary_wireformat.h"
#include "conformance/conformance.pb.h"
#include "conformance_test.h"
#include "conformance/test_protos/test_messages_edition2023.pb.h"
#include "editions/golden/test_messages_proto2_editions.pb.h"
#include "editions/golden/test_messages_proto3_editions.pb.h"
#include "google/protobuf/endian.h"
#include "google/protobuf/json/json.h"
#include "google/protobuf/test_messages_proto2.pb.h"
#include "google/protobuf/test_messages_proto3.pb.h"
Expand All @@ -43,14 +43,13 @@
#include "google/protobuf/util/type_resolver_util.h"
#include "google/protobuf/wire_format_lite.h"

using conformance::ConformanceRequest;
using conformance::ConformanceResponse;
using conformance::TestStatus;
using conformance::WireFormat;
using ::conformance::ConformanceRequest;
using ::conformance::ConformanceResponse;
using ::conformance::TestStatus;
using ::conformance::WireFormat;
using google::protobuf::Descriptor;
using google::protobuf::FieldDescriptor;
using google::protobuf::internal::WireFormatLite;
using google::protobuf::internal::little_endian::FromHost;
using google::protobuf::util::NewTypeResolverForDescriptorPool;
using protobuf_test_messages::editions::TestAllTypesEdition2023;
using protobuf_test_messages::proto2::TestAllTypesProto2;
Expand All @@ -77,74 +76,29 @@ std::string GetTypeUrl(const Descriptor* message) {
// We would use CodedOutputStream except that we want more freedom to build
// arbitrary protos (even invalid ones).

// 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, 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 || 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;
}

std::string varint(uint64_t x) {
char buf[VARINT_MAX_LEN];
size_t len = vencode64(x, 0, buf);
return std::string(buf, len);
}

// Encodes a varint that is |extra| bytes longer than it needs to be, but still
// valid.
std::string varint(uint64_t x) { return google::protobuf::conformance::Varint(x).str(); }
std::string longvarint(uint64_t x, int extra) {
char buf[VARINT_MAX_LEN];
size_t len = vencode64(x, extra, buf);
return std::string(buf, len);
}

std::string fixed32(void* data) {
uint32_t data_le;
std::memcpy(&data_le, data, 4);
data_le = FromHost(data_le);
return std::string(reinterpret_cast<char*>(&data_le), 4);
return google::protobuf::conformance::LongVarint(x, extra).str();
}
std::string fixed64(void* data) {
uint64_t data_le;
std::memcpy(&data_le, data, 8);
data_le = FromHost(data_le);
return std::string(reinterpret_cast<char*>(&data_le), 8);
}

std::string delim(const std::string& buf) {
return absl::StrCat(varint(buf.size()), buf);
return google::protobuf::conformance::LengthPrefixed(buf).str();
}
std::string u32(uint32_t u32) { return fixed32(&u32); }
std::string u64(uint64_t u64) { return fixed64(&u64); }
std::string flt(float f) { return fixed32(&f); }
std::string dbl(double d) { return fixed64(&d); }
std::string zz32(int32_t x) {
return varint(WireFormatLite::ZigZagEncode32(x));
std::string u32(uint32_t u32) {
return google::protobuf::conformance::Fixed32(u32).str();
}
std::string zz64(int64_t x) {
return varint(WireFormatLite::ZigZagEncode64(x));
std::string u64(uint64_t u64) {
return google::protobuf::conformance::Fixed64(u64).str();
}
std::string flt(float f) { return google::protobuf::conformance::Float(f).str(); }
std::string dbl(double d) { return google::protobuf::conformance::Double(d).str(); }
std::string zz32(int32_t x) { return google::protobuf::conformance::SInt32(x).str(); }
std::string zz64(int64_t x) { return google::protobuf::conformance::SInt64(x).str(); }

std::string tag(uint32_t fieldnum, char wire_type) {
return varint((fieldnum << 3) | wire_type);
return google::protobuf::conformance::Tag(
fieldnum, static_cast<google::protobuf::conformance::WireType>(wire_type))
.str();
}

std::string tag(int fieldnum, char wire_type) {
return tag(static_cast<uint32_t>(fieldnum), wire_type);
}
Expand All @@ -154,14 +108,13 @@ std::string field(uint32_t fieldnum, char wire_type, std::string content) {
}

std::string group(uint32_t fieldnum, std::string content) {
return absl::StrCat(tag(fieldnum, WireFormatLite::WIRETYPE_START_GROUP),
content,
tag(fieldnum, WireFormatLite::WIRETYPE_END_GROUP));
return google::protobuf::conformance::DelimitedField(fieldnum, std::move(content))
.str();
}

std::string len(uint32_t fieldnum, std::string content) {
return absl::StrCat(tag(fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
delim(content));
return google::protobuf::conformance::LengthPrefixedField(fieldnum, std::move(content))
.str();
}

std::string GetDefaultValue(FieldDescriptor::Type type) {
Expand Down Expand Up @@ -309,7 +262,7 @@ bool BinaryAndJsonConformanceSuite::ParseResponse(
test.set_name(test_name);
switch (response.result_case()) {
case ConformanceResponse::kProtobufPayload: {
if (requested_output != conformance::PROTOBUF) {
if (requested_output != ::conformance::PROTOBUF) {
test.set_failure_message(absl::StrCat(
"Test was asked for ", WireFormatToString(requested_output),
" output but provided PROTOBUF instead."));
Expand All @@ -328,7 +281,7 @@ bool BinaryAndJsonConformanceSuite::ParseResponse(
}

case ConformanceResponse::kJsonPayload: {
if (requested_output != conformance::JSON) {
if (requested_output != ::conformance::JSON) {
test.set_failure_message(absl::StrCat(
"Test was asked for ", WireFormatToString(requested_output),
" output but provided JSON instead."));
Expand Down Expand Up @@ -524,8 +477,8 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
// 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.
ConformanceRequestSetting setting(
level, conformance::PROTOBUF, conformance::PROTOBUF,
conformance::BINARY_TEST, prototype, test_name, proto);
level, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
::conformance::BINARY_TEST, prototype, test_name, proto);

const ConformanceRequest& request = setting.GetRequest();
ConformanceResponse response;
Expand Down Expand Up @@ -587,12 +540,12 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
const std::string& equivalent_text_format,
const Message& prototype) {
ConformanceRequestSetting setting1(
level, conformance::JSON, conformance::PROTOBUF, conformance::JSON_TEST,
prototype, test_name, input_json);
level, ::conformance::JSON, ::conformance::PROTOBUF,
::conformance::JSON_TEST, prototype, test_name, input_json);
suite_.RunValidInputTest(setting1, equivalent_text_format);
ConformanceRequestSetting setting2(level, conformance::JSON,
conformance::JSON, conformance::JSON_TEST,
prototype, test_name, input_json);
ConformanceRequestSetting setting2(
level, ::conformance::JSON, ::conformance::JSON, ::conformance::JSON_TEST,
prototype, test_name, input_json);
suite_.RunValidInputTest(setting2, equivalent_text_format);
}

Expand All @@ -602,8 +555,8 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
const std::string& test_name, ConformanceLevel level,
const MessageType& input, const std::string& equivalent_text_format) {
ConformanceRequestSetting setting(
level, conformance::PROTOBUF, conformance::JSON, conformance::JSON_TEST,
input, test_name, input.SerializeAsString());
level, ::conformance::PROTOBUF, ::conformance::JSON,
::conformance::JSON_TEST, input, test_name, input.SerializeAsString());
suite_.RunValidInputTest(setting, equivalent_text_format);
}

Expand All @@ -615,8 +568,8 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
const std::string& equivalent_text_format) {
MessageType prototype;
ConformanceRequestSetting setting(
level, conformance::JSON, conformance::PROTOBUF,
conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST, prototype, test_name,
level, ::conformance::JSON, ::conformance::PROTOBUF,
::conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST, prototype, test_name,
input_json);
suite_.RunValidInputTest(setting, equivalent_text_format);
}
Expand All @@ -629,8 +582,8 @@ void BinaryAndJsonConformanceSuite::RunValidBinaryProtobufTest(
MessageType prototype;

ConformanceRequestSetting binary_to_binary(
level, conformance::PROTOBUF, conformance::PROTOBUF,
conformance::BINARY_TEST, prototype, test_name, input_protobuf);
level, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
::conformance::BINARY_TEST, prototype, test_name, input_protobuf);
RunValidInputTest(binary_to_binary, equivalent_text_format);
}

Expand All @@ -641,8 +594,8 @@ void BinaryAndJsonConformanceSuite::RunValidRoundtripProtobufTest(
MessageType prototype;

ConformanceRequestSetting binary_to_binary(
level, conformance::PROTOBUF, conformance::PROTOBUF,
conformance::BINARY_TEST, prototype, test_name, input_protobuf);
level, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
::conformance::BINARY_TEST, prototype, test_name, input_protobuf);
RunValidBinaryInputTest(binary_to_binary, input_protobuf);
}

Expand All @@ -654,13 +607,13 @@ void BinaryAndJsonConformanceSuite::RunValidProtobufTest(
MessageType prototype;

ConformanceRequestSetting binary_to_binary(
level, conformance::PROTOBUF, conformance::PROTOBUF,
conformance::BINARY_TEST, prototype, test_name, input_protobuf);
level, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
::conformance::BINARY_TEST, prototype, test_name, input_protobuf);
RunValidInputTest(binary_to_binary, equivalent_text_format);

ConformanceRequestSetting binary_to_json(
level, conformance::PROTOBUF, conformance::JSON, conformance::BINARY_TEST,
prototype, test_name, input_protobuf);
level, ::conformance::PROTOBUF, ::conformance::JSON,
::conformance::BINARY_TEST, prototype, test_name, input_protobuf);
RunValidInputTest(binary_to_json, equivalent_text_format);
}

Expand All @@ -686,8 +639,8 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::RunValidBinaryProtobufTest(
const std::string& input_protobuf, const std::string& expected_protobuf) {
MessageType prototype;
ConformanceRequestSetting setting(
level, conformance::PROTOBUF, conformance::PROTOBUF,
conformance::BINARY_TEST, prototype, test_name, input_protobuf);
level, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
::conformance::BINARY_TEST, prototype, test_name, input_protobuf);
suite_.RunValidBinaryInputTest(setting, expected_protobuf, true);
}

Expand Down Expand Up @@ -735,9 +688,9 @@ void BinaryAndJsonConformanceSuiteImpl<
const std::string& input_json,
const Validator& validator) {
MessageType prototype;
ConformanceRequestSetting setting(level, conformance::JSON, conformance::JSON,
conformance::JSON_TEST, prototype,
test_name, input_json);
ConformanceRequestSetting setting(
level, ::conformance::JSON, ::conformance::JSON, ::conformance::JSON_TEST,
prototype, test_name, input_json);
const ConformanceRequest& request = setting.GetRequest();
ConformanceResponse response;
std::string effective_test_name = absl::StrCat(
Expand Down Expand Up @@ -789,9 +742,9 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::ExpectParseFailureForJson(
MessageType prototype;
// 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.
ConformanceRequestSetting setting(level, conformance::JSON, conformance::JSON,
conformance::JSON_TEST, prototype,
test_name, input_json);
ConformanceRequestSetting setting(
level, ::conformance::JSON, ::conformance::JSON, ::conformance::JSON_TEST,
prototype, test_name, input_json);
const ConformanceRequest& request = setting.GetRequest();
ConformanceResponse response;
std::string effective_test_name =
Expand Down Expand Up @@ -825,8 +778,9 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::

MessageType prototype;
ConformanceRequestSetting setting(
level, conformance::PROTOBUF, conformance::JSON, conformance::JSON_TEST,
prototype, test_name, payload_message.SerializeAsString());
level, ::conformance::PROTOBUF, ::conformance::JSON,
::conformance::JSON_TEST, prototype, test_name,
payload_message.SerializeAsString());
const ConformanceRequest& request = setting.GetRequest();
ConformanceResponse response;
std::string effective_test_name =
Expand Down Expand Up @@ -1595,8 +1549,8 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::TestUnknownOrdering() {
std::string serialized = message.SerializeAsString();

ConformanceRequestSetting setting(
REQUIRED, conformance::PROTOBUF, conformance::PROTOBUF,
conformance::BINARY_TEST, prototype, "UnknownOrdering", serialized);
REQUIRED, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
::conformance::BINARY_TEST, prototype, "UnknownOrdering", serialized);
const ConformanceRequest& request = setting.GetRequest();
ConformanceResponse response;
if (!suite_.RunTest(setting.GetTestName(), request, &response)) {
Expand Down
Loading
Loading