Skip to content

Commit e83430b

Browse files
mkruskal-googlecopybara-github
authored andcommitted
Extract helpers for manipulating binary wireformat in conformance tests
PiperOrigin-RevId: 759264980
1 parent 9b766a1 commit e83430b

File tree

5 files changed

+811
-103
lines changed

5 files changed

+811
-103
lines changed

conformance/BUILD

+26
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# Protobuf conformance tests.
99

1010
load("@rules_cc//cc:cc_library.bzl", "cc_library")
11+
load("@rules_cc//cc:cc_test.bzl", "cc_test")
1112
load("@rules_cc//cc:defs.bzl", "cc_binary", "objc_library")
1213
load("@rules_java//java:defs.bzl", "java_binary")
1314
load("@rules_python//python:py_binary.bzl", "py_binary")
@@ -130,6 +131,7 @@ cc_library(
130131
srcs = ["binary_json_conformance_suite.cc"],
131132
hdrs = ["binary_json_conformance_suite.h"],
132133
deps = [
134+
":binary_wireformat",
133135
":conformance_cc_proto",
134136
":conformance_test_lib",
135137
"//:test_messages_proto2_cc_proto",
@@ -191,6 +193,30 @@ cc_library(
191193
],
192194
)
193195

196+
cc_library(
197+
name = "binary_wireformat",
198+
testonly = 1,
199+
srcs = ["binary_wireformat.cc"],
200+
hdrs = ["binary_wireformat.h"],
201+
deps = [
202+
"//src/google/protobuf:endian",
203+
"//src/google/protobuf:protobuf_lite",
204+
"@abseil-cpp//absl/strings",
205+
],
206+
)
207+
208+
cc_test(
209+
name = "binary_wireformat_test",
210+
srcs = ["binary_wireformat_test.cc"],
211+
deps = [
212+
":binary_wireformat",
213+
"@abseil-cpp//absl/strings",
214+
"@abseil-cpp//absl/strings:string_view",
215+
"@googletest//:gtest",
216+
"@googletest//:gtest_main",
217+
],
218+
)
219+
194220
cc_binary(
195221
name = "conformance_test_runner",
196222
testonly = 1,

conformance/binary_json_conformance_suite.cc

+57-103
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@
2929
#include "json/config.h"
3030
#include "json/reader.h"
3131
#include "json/value.h"
32+
#include "binary_wireformat.h"
3233
#include "conformance/conformance.pb.h"
3334
#include "conformance_test.h"
3435
#include "conformance/test_protos/test_messages_edition2023.pb.h"
3536
#include "editions/golden/test_messages_proto2_editions.pb.h"
3637
#include "editions/golden/test_messages_proto3_editions.pb.h"
37-
#include "google/protobuf/endian.h"
3838
#include "google/protobuf/json/json.h"
3939
#include "google/protobuf/test_messages_proto2.pb.h"
4040
#include "google/protobuf/test_messages_proto3.pb.h"
@@ -43,14 +43,13 @@
4343
#include "google/protobuf/util/type_resolver_util.h"
4444
#include "google/protobuf/wire_format_lite.h"
4545

46-
using conformance::ConformanceRequest;
47-
using conformance::ConformanceResponse;
48-
using conformance::TestStatus;
49-
using conformance::WireFormat;
46+
using ::conformance::ConformanceRequest;
47+
using ::conformance::ConformanceResponse;
48+
using ::conformance::TestStatus;
49+
using ::conformance::WireFormat;
5050
using google::protobuf::Descriptor;
5151
using google::protobuf::FieldDescriptor;
5252
using google::protobuf::internal::WireFormatLite;
53-
using google::protobuf::internal::little_endian::FromHost;
5453
using google::protobuf::util::NewTypeResolverForDescriptorPool;
5554
using protobuf_test_messages::editions::TestAllTypesEdition2023;
5655
using protobuf_test_messages::proto2::TestAllTypesProto2;
@@ -77,74 +76,29 @@ std::string GetTypeUrl(const Descriptor* message) {
7776
// We would use CodedOutputStream except that we want more freedom to build
7877
// arbitrary protos (even invalid ones).
7978

80-
// The maximum number of bytes that it takes to encode a 64-bit varint.
81-
#define VARINT_MAX_LEN 10
82-
83-
size_t vencode64(uint64_t val, int over_encoded_bytes, char* buf) {
84-
if (val == 0) {
85-
buf[0] = 0;
86-
return 1;
87-
}
88-
size_t i = 0;
89-
while (val) {
90-
uint8_t byte = val & 0x7fU;
91-
val >>= 7;
92-
if (val || over_encoded_bytes) byte |= 0x80U;
93-
buf[i++] = byte;
94-
}
95-
while (over_encoded_bytes--) {
96-
assert(i < 10);
97-
uint8_t byte = over_encoded_bytes ? 0x80 : 0;
98-
buf[i++] = byte;
99-
}
100-
return i;
101-
}
102-
103-
std::string varint(uint64_t x) {
104-
char buf[VARINT_MAX_LEN];
105-
size_t len = vencode64(x, 0, buf);
106-
return std::string(buf, len);
107-
}
108-
109-
// Encodes a varint that is |extra| bytes longer than it needs to be, but still
110-
// valid.
79+
std::string varint(uint64_t x) { return google::protobuf::conformance::Varint(x).str(); }
11180
std::string longvarint(uint64_t x, int extra) {
112-
char buf[VARINT_MAX_LEN];
113-
size_t len = vencode64(x, extra, buf);
114-
return std::string(buf, len);
115-
}
116-
117-
std::string fixed32(void* data) {
118-
uint32_t data_le;
119-
std::memcpy(&data_le, data, 4);
120-
data_le = FromHost(data_le);
121-
return std::string(reinterpret_cast<char*>(&data_le), 4);
81+
return google::protobuf::conformance::LongVarint(x, extra).str();
12282
}
123-
std::string fixed64(void* data) {
124-
uint64_t data_le;
125-
std::memcpy(&data_le, data, 8);
126-
data_le = FromHost(data_le);
127-
return std::string(reinterpret_cast<char*>(&data_le), 8);
128-
}
129-
13083
std::string delim(const std::string& buf) {
131-
return absl::StrCat(varint(buf.size()), buf);
84+
return google::protobuf::conformance::LengthPrefixed(buf).str();
13285
}
133-
std::string u32(uint32_t u32) { return fixed32(&u32); }
134-
std::string u64(uint64_t u64) { return fixed64(&u64); }
135-
std::string flt(float f) { return fixed32(&f); }
136-
std::string dbl(double d) { return fixed64(&d); }
137-
std::string zz32(int32_t x) {
138-
return varint(WireFormatLite::ZigZagEncode32(x));
86+
std::string u32(uint32_t u32) {
87+
return google::protobuf::conformance::Fixed32(u32).str();
13988
}
140-
std::string zz64(int64_t x) {
141-
return varint(WireFormatLite::ZigZagEncode64(x));
89+
std::string u64(uint64_t u64) {
90+
return google::protobuf::conformance::Fixed64(u64).str();
14291
}
92+
std::string flt(float f) { return google::protobuf::conformance::Float(f).str(); }
93+
std::string dbl(double d) { return google::protobuf::conformance::Double(d).str(); }
94+
std::string zz32(int32_t x) { return google::protobuf::conformance::SInt32(x).str(); }
95+
std::string zz64(int64_t x) { return google::protobuf::conformance::SInt64(x).str(); }
14396

14497
std::string tag(uint32_t fieldnum, char wire_type) {
145-
return varint((fieldnum << 3) | wire_type);
98+
return google::protobuf::conformance::Tag(
99+
fieldnum, static_cast<google::protobuf::conformance::WireType>(wire_type))
100+
.str();
146101
}
147-
148102
std::string tag(int fieldnum, char wire_type) {
149103
return tag(static_cast<uint32_t>(fieldnum), wire_type);
150104
}
@@ -154,14 +108,13 @@ std::string field(uint32_t fieldnum, char wire_type, std::string content) {
154108
}
155109

156110
std::string group(uint32_t fieldnum, std::string content) {
157-
return absl::StrCat(tag(fieldnum, WireFormatLite::WIRETYPE_START_GROUP),
158-
content,
159-
tag(fieldnum, WireFormatLite::WIRETYPE_END_GROUP));
111+
return google::protobuf::conformance::DelimitedField(fieldnum, std::move(content))
112+
.str();
160113
}
161114

162115
std::string len(uint32_t fieldnum, std::string content) {
163-
return absl::StrCat(tag(fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
164-
delim(content));
116+
return google::protobuf::conformance::LengthPrefixedField(fieldnum, std::move(content))
117+
.str();
165118
}
166119

167120
std::string GetDefaultValue(FieldDescriptor::Type type) {
@@ -309,7 +262,7 @@ bool BinaryAndJsonConformanceSuite::ParseResponse(
309262
test.set_name(test_name);
310263
switch (response.result_case()) {
311264
case ConformanceResponse::kProtobufPayload: {
312-
if (requested_output != conformance::PROTOBUF) {
265+
if (requested_output != ::conformance::PROTOBUF) {
313266
test.set_failure_message(absl::StrCat(
314267
"Test was asked for ", WireFormatToString(requested_output),
315268
" output but provided PROTOBUF instead."));
@@ -328,7 +281,7 @@ bool BinaryAndJsonConformanceSuite::ParseResponse(
328281
}
329282

330283
case ConformanceResponse::kJsonPayload: {
331-
if (requested_output != conformance::JSON) {
284+
if (requested_output != ::conformance::JSON) {
332285
test.set_failure_message(absl::StrCat(
333286
"Test was asked for ", WireFormatToString(requested_output),
334287
" output but provided JSON instead."));
@@ -524,8 +477,8 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
524477
// We don't expect output, but if the program erroneously accepts the protobuf
525478
// we let it send its response as this. We must not leave it unspecified.
526479
ConformanceRequestSetting setting(
527-
level, conformance::PROTOBUF, conformance::PROTOBUF,
528-
conformance::BINARY_TEST, prototype, test_name, proto);
480+
level, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
481+
::conformance::BINARY_TEST, prototype, test_name, proto);
529482

530483
const ConformanceRequest& request = setting.GetRequest();
531484
ConformanceResponse response;
@@ -587,12 +540,12 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
587540
const std::string& equivalent_text_format,
588541
const Message& prototype) {
589542
ConformanceRequestSetting setting1(
590-
level, conformance::JSON, conformance::PROTOBUF, conformance::JSON_TEST,
591-
prototype, test_name, input_json);
543+
level, ::conformance::JSON, ::conformance::PROTOBUF,
544+
::conformance::JSON_TEST, prototype, test_name, input_json);
592545
suite_.RunValidInputTest(setting1, equivalent_text_format);
593-
ConformanceRequestSetting setting2(level, conformance::JSON,
594-
conformance::JSON, conformance::JSON_TEST,
595-
prototype, test_name, input_json);
546+
ConformanceRequestSetting setting2(
547+
level, ::conformance::JSON, ::conformance::JSON, ::conformance::JSON_TEST,
548+
prototype, test_name, input_json);
596549
suite_.RunValidInputTest(setting2, equivalent_text_format);
597550
}
598551

@@ -602,8 +555,8 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
602555
const std::string& test_name, ConformanceLevel level,
603556
const MessageType& input, const std::string& equivalent_text_format) {
604557
ConformanceRequestSetting setting(
605-
level, conformance::PROTOBUF, conformance::JSON, conformance::JSON_TEST,
606-
input, test_name, input.SerializeAsString());
558+
level, ::conformance::PROTOBUF, ::conformance::JSON,
559+
::conformance::JSON_TEST, input, test_name, input.SerializeAsString());
607560
suite_.RunValidInputTest(setting, equivalent_text_format);
608561
}
609562

@@ -615,8 +568,8 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
615568
const std::string& equivalent_text_format) {
616569
MessageType prototype;
617570
ConformanceRequestSetting setting(
618-
level, conformance::JSON, conformance::PROTOBUF,
619-
conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST, prototype, test_name,
571+
level, ::conformance::JSON, ::conformance::PROTOBUF,
572+
::conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST, prototype, test_name,
620573
input_json);
621574
suite_.RunValidInputTest(setting, equivalent_text_format);
622575
}
@@ -629,8 +582,8 @@ void BinaryAndJsonConformanceSuite::RunValidBinaryProtobufTest(
629582
MessageType prototype;
630583

631584
ConformanceRequestSetting binary_to_binary(
632-
level, conformance::PROTOBUF, conformance::PROTOBUF,
633-
conformance::BINARY_TEST, prototype, test_name, input_protobuf);
585+
level, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
586+
::conformance::BINARY_TEST, prototype, test_name, input_protobuf);
634587
RunValidInputTest(binary_to_binary, equivalent_text_format);
635588
}
636589

@@ -641,8 +594,8 @@ void BinaryAndJsonConformanceSuite::RunValidRoundtripProtobufTest(
641594
MessageType prototype;
642595

643596
ConformanceRequestSetting binary_to_binary(
644-
level, conformance::PROTOBUF, conformance::PROTOBUF,
645-
conformance::BINARY_TEST, prototype, test_name, input_protobuf);
597+
level, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
598+
::conformance::BINARY_TEST, prototype, test_name, input_protobuf);
646599
RunValidBinaryInputTest(binary_to_binary, input_protobuf);
647600
}
648601

@@ -654,13 +607,13 @@ void BinaryAndJsonConformanceSuite::RunValidProtobufTest(
654607
MessageType prototype;
655608

656609
ConformanceRequestSetting binary_to_binary(
657-
level, conformance::PROTOBUF, conformance::PROTOBUF,
658-
conformance::BINARY_TEST, prototype, test_name, input_protobuf);
610+
level, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
611+
::conformance::BINARY_TEST, prototype, test_name, input_protobuf);
659612
RunValidInputTest(binary_to_binary, equivalent_text_format);
660613

661614
ConformanceRequestSetting binary_to_json(
662-
level, conformance::PROTOBUF, conformance::JSON, conformance::BINARY_TEST,
663-
prototype, test_name, input_protobuf);
615+
level, ::conformance::PROTOBUF, ::conformance::JSON,
616+
::conformance::BINARY_TEST, prototype, test_name, input_protobuf);
664617
RunValidInputTest(binary_to_json, equivalent_text_format);
665618
}
666619

@@ -686,8 +639,8 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::RunValidBinaryProtobufTest(
686639
const std::string& input_protobuf, const std::string& expected_protobuf) {
687640
MessageType prototype;
688641
ConformanceRequestSetting setting(
689-
level, conformance::PROTOBUF, conformance::PROTOBUF,
690-
conformance::BINARY_TEST, prototype, test_name, input_protobuf);
642+
level, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
643+
::conformance::BINARY_TEST, prototype, test_name, input_protobuf);
691644
suite_.RunValidBinaryInputTest(setting, expected_protobuf, true);
692645
}
693646

@@ -735,9 +688,9 @@ void BinaryAndJsonConformanceSuiteImpl<
735688
const std::string& input_json,
736689
const Validator& validator) {
737690
MessageType prototype;
738-
ConformanceRequestSetting setting(level, conformance::JSON, conformance::JSON,
739-
conformance::JSON_TEST, prototype,
740-
test_name, input_json);
691+
ConformanceRequestSetting setting(
692+
level, ::conformance::JSON, ::conformance::JSON, ::conformance::JSON_TEST,
693+
prototype, test_name, input_json);
741694
const ConformanceRequest& request = setting.GetRequest();
742695
ConformanceResponse response;
743696
std::string effective_test_name = absl::StrCat(
@@ -789,9 +742,9 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::ExpectParseFailureForJson(
789742
MessageType prototype;
790743
// We don't expect output, but if the program erroneously accepts the protobuf
791744
// we let it send its response as this. We must not leave it unspecified.
792-
ConformanceRequestSetting setting(level, conformance::JSON, conformance::JSON,
793-
conformance::JSON_TEST, prototype,
794-
test_name, input_json);
745+
ConformanceRequestSetting setting(
746+
level, ::conformance::JSON, ::conformance::JSON, ::conformance::JSON_TEST,
747+
prototype, test_name, input_json);
795748
const ConformanceRequest& request = setting.GetRequest();
796749
ConformanceResponse response;
797750
std::string effective_test_name =
@@ -825,8 +778,9 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
825778

826779
MessageType prototype;
827780
ConformanceRequestSetting setting(
828-
level, conformance::PROTOBUF, conformance::JSON, conformance::JSON_TEST,
829-
prototype, test_name, payload_message.SerializeAsString());
781+
level, ::conformance::PROTOBUF, ::conformance::JSON,
782+
::conformance::JSON_TEST, prototype, test_name,
783+
payload_message.SerializeAsString());
830784
const ConformanceRequest& request = setting.GetRequest();
831785
ConformanceResponse response;
832786
std::string effective_test_name =
@@ -1595,8 +1549,8 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::TestUnknownOrdering() {
15951549
std::string serialized = message.SerializeAsString();
15961550

15971551
ConformanceRequestSetting setting(
1598-
REQUIRED, conformance::PROTOBUF, conformance::PROTOBUF,
1599-
conformance::BINARY_TEST, prototype, "UnknownOrdering", serialized);
1552+
REQUIRED, ::conformance::PROTOBUF, ::conformance::PROTOBUF,
1553+
::conformance::BINARY_TEST, prototype, "UnknownOrdering", serialized);
16001554
const ConformanceRequest& request = setting.GetRequest();
16011555
ConformanceResponse response;
16021556
if (!suite_.RunTest(setting.GetTestName(), request, &response)) {

0 commit comments

Comments
 (0)