Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
2ff42dcf
Commit
2ff42dcf
authored
Dec 14, 2016
by
Joshua Haberman
Committed by
GitHub
Dec 14, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added conformance testing for binary primitive types. (#2491)
This is basic and more tests will be added over time.
parent
f983302c
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
162 additions
and
37 deletions
+162
-37
conformance_test.cc
conformance/conformance_test.cc
+154
-34
conformance_test.h
conformance/conformance_test.h
+8
-3
No files found.
conformance/conformance_test.cc
View file @
2ff42dcf
...
...
@@ -132,8 +132,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
u
int
32
(
uint32_t
u32
)
{
return
fixed32
(
&
u32
);
}
string
u
int
64
(
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
));
}
...
...
@@ -149,16 +149,17 @@ string submsg(uint32_t fn, const string& buf) {
#define UNKNOWN_FIELD 666
uint32_t
GetFieldNumberForType
(
FieldDescriptor
::
Type
type
,
bool
repeated
)
{
const
FieldDescriptor
*
GetFieldForType
(
FieldDescriptor
::
Type
type
,
bool
repeated
)
{
const
Descriptor
*
d
=
TestAllTypes
().
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
)
{
...
...
@@ -425,16 +426,24 @@ void ConformanceTestSuite::RunValidJsonTestWithProtobufInput(
}
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
,
const
string
&
test_name
,
ConformanceLevel
level
,
const
string
&
input_protobuf
,
const
string
&
equivalent_text_format
)
{
RunValidInputTest
(
ConformanceLevelToString
(
level
)
+
".ProtobufInput."
+
test_name
+
".ProtobufOutput"
,
level
,
input_protobuf
,
conformance
::
PROTOBUF
,
equivalent_text_format
,
conformance
::
PROTOBUF
);
RunValidInputTest
(
"ProtobufInput."
+
test_name
+
".JsonOutput"
,
level
,
input
.
SerializeAsString
(),
conformance
::
PROTOBUF
,
RunValidInputTest
(
ConformanceLevelToString
(
level
)
+
".ProtobufInput."
+
test_name
+
".JsonOutput"
,
level
,
input_protobuf
,
conformance
::
PROTOBUF
,
equivalent_text_format
,
conformance
::
JSON
);
}
void
ConformanceTestSuite
::
RunValidProtobufTestWithMessage
(
const
string
&
test_name
,
ConformanceLevel
level
,
const
TestAllTypes
&
input
,
const
string
&
equivalent_text_format
)
{
RunValidProtobufTest
(
test_name
,
level
,
input
.
SerializeAsString
(),
equivalent_text_format
);
}
// According to proto3 JSON specification, JSON serializers follow more strict
// rules than parsers (e.g., a serializer must serialize int32 values as JSON
// numbers while the parser is allowed to accept them as JSON strings). This
...
...
@@ -539,8 +548,8 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
string
(
"abc"
)
// 32BIT
};
uint32_t
fieldnum
=
GetFieldNumber
ForType
(
type
,
false
);
uint32_t
rep_fieldnum
=
GetFieldNumber
ForType
(
type
,
true
);
const
FieldDescriptor
*
field
=
GetField
ForType
(
type
,
false
);
const
FieldDescriptor
*
rep_field
=
GetField
ForType
(
type
,
true
);
WireFormatLite
::
WireType
wire_type
=
WireFormatLite
::
WireTypeForFieldType
(
static_cast
<
WireFormatLite
::
FieldType
>
(
type
));
const
string
&
incomplete
=
incompletes
[
wire_type
];
...
...
@@ -548,11 +557,11 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
UpperCase
(
string
(
"."
)
+
FieldDescriptor
::
TypeName
(
type
));
ExpectParseFailureForProto
(
tag
(
field
num
,
wire_type
),
tag
(
field
->
number
()
,
wire_type
),
"PrematureEofBeforeKnownNonRepeatedValue"
+
type_name
,
REQUIRED
);
ExpectParseFailureForProto
(
tag
(
rep_field
num
,
wire_type
),
tag
(
rep_field
->
number
()
,
wire_type
),
"PrematureEofBeforeKnownRepeatedValue"
+
type_name
,
REQUIRED
);
ExpectParseFailureForProto
(
...
...
@@ -560,11 +569,11 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
"PrematureEofBeforeUnknownValue"
+
type_name
,
REQUIRED
);
ExpectParseFailureForProto
(
cat
(
tag
(
field
num
,
wire_type
),
incomplete
),
cat
(
tag
(
field
->
number
()
,
wire_type
),
incomplete
),
"PrematureEofInsideKnownNonRepeatedValue"
+
type_name
,
REQUIRED
);
ExpectParseFailureForProto
(
cat
(
tag
(
rep_field
num
,
wire_type
),
incomplete
),
cat
(
tag
(
rep_field
->
number
()
,
wire_type
),
incomplete
),
"PrematureEofInsideKnownRepeatedValue"
+
type_name
,
REQUIRED
);
ExpectParseFailureForProto
(
...
...
@@ -573,12 +582,12 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
if
(
wire_type
==
WireFormatLite
::
WIRETYPE_LENGTH_DELIMITED
)
{
ExpectParseFailureForProto
(
cat
(
tag
(
field
num
,
wire_type
),
varint
(
1
)
),
cat
(
tag
(
field
->
number
()
,
wire_type
),
varint
(
1
)
),
"PrematureEofInDelimitedDataForKnownNonRepeatedValue"
+
type_name
,
REQUIRED
);
ExpectParseFailureForProto
(
cat
(
tag
(
rep_field
num
,
wire_type
),
varint
(
1
)
),
cat
(
tag
(
rep_field
->
number
()
,
wire_type
),
varint
(
1
)
),
"PrematureEofInDelimitedDataForKnownRepeatedValue"
+
type_name
,
REQUIRED
);
...
...
@@ -593,7 +602,7 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
cat
(
tag
(
WireFormatLite
::
TYPE_INT32
,
WireFormatLite
::
WIRETYPE_VARINT
),
incompletes
[
WireFormatLite
::
WIRETYPE_VARINT
]
);
ExpectHardParseFailureForProto
(
cat
(
tag
(
field
num
,
WireFormatLite
::
WIRETYPE_LENGTH_DELIMITED
),
cat
(
tag
(
field
->
number
()
,
WireFormatLite
::
WIRETYPE_LENGTH_DELIMITED
),
varint
(
incomplete_submsg
.
size
()),
incomplete_submsg
),
"PrematureEofInSubmessageValue"
+
type_name
,
REQUIRED
);
...
...
@@ -603,19 +612,50 @@ 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
)
{
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
);
const
FieldDescriptor
*
rep_field
=
GetFieldForType
(
type
,
true
);
RunValidProtobufTest
(
"ValidDataScalar"
+
type_name
,
REQUIRED
,
cat
(
tag
(
field
->
number
(),
wire_type
),
values
[
0
].
first
),
field
->
name
()
+
": "
+
values
[
0
].
second
);
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
);
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
);
}
void
ConformanceTestSuite
::
SetFailureList
(
const
string
&
filename
,
const
vector
<
string
>&
failure_list
)
{
failure_list_filename_
=
filename
;
...
...
@@ -675,6 +715,86 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
TestPrematureEOFForType
(
static_cast
<
FieldDescriptor
::
Type
>
(
i
));
}
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
(
3.402823e+38
),
"3.402823e+38"
},
// 3.40282347e+38
{
flt
(
1.17549435e-38
f
),
"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"
},
{
varint
(
kInt32Max
),
std
::
to_string
(
kInt32Max
)},
{
varint
(
kInt32Min
),
std
::
to_string
(
kInt32Min
)},
});
TestValidDataForType
(
FieldDescriptor
::
TYPE_UINT32
,
{
{
varint
(
12345
),
"12345"
},
{
varint
(
kUint32Max
),
std
::
to_string
(
kUint32Max
)},
// UINT32_MAX
{
varint
(
0
),
"0"
}
});
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!'"
);
...
...
@@ -1374,31 +1494,31 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
{
TestAllTypes
message
;
message
.
set_oneof_uint32
(
0
);
RunValidProtobufTest
(
RunValidProtobufTest
WithMessage
(
"OneofZeroUint32"
,
RECOMMENDED
,
message
,
"oneof_uint32: 0"
);
message
.
mutable_oneof_nested_message
()
->
set_a
(
0
);
RunValidProtobufTest
(
RunValidProtobufTest
WithMessage
(
"OneofZeroMessage"
,
RECOMMENDED
,
message
,
"oneof_nested_message: {}"
);
message
.
set_oneof_string
(
""
);
RunValidProtobufTest
(
RunValidProtobufTest
WithMessage
(
"OneofZeroString"
,
RECOMMENDED
,
message
,
"oneof_string:
\"\"
"
);
message
.
set_oneof_bytes
(
""
);
RunValidProtobufTest
(
RunValidProtobufTest
WithMessage
(
"OneofZeroBytes"
,
RECOMMENDED
,
message
,
"oneof_bytes:
\"\"
"
);
message
.
set_oneof_bool
(
false
);
RunValidProtobufTest
(
RunValidProtobufTest
WithMessage
(
"OneofZeroBool"
,
RECOMMENDED
,
message
,
"oneof_bool: false"
);
message
.
set_oneof_uint64
(
0
);
RunValidProtobufTest
(
RunValidProtobufTest
WithMessage
(
"OneofZeroUint64"
,
RECOMMENDED
,
message
,
"oneof_uint64: 0"
);
message
.
set_oneof_float
(
0.0
f
);
RunValidProtobufTest
(
RunValidProtobufTest
WithMessage
(
"OneofZeroFloat"
,
RECOMMENDED
,
message
,
"oneof_float: 0"
);
message
.
set_oneof_double
(
0.0
);
RunValidProtobufTest
(
RunValidProtobufTest
WithMessage
(
"OneofZeroDouble"
,
RECOMMENDED
,
message
,
"oneof_double: 0"
);
message
.
set_oneof_enum
(
TestAllTypes
::
FOO
);
RunValidProtobufTest
(
RunValidProtobufTest
WithMessage
(
"OneofZeroEnum"
,
RECOMMENDED
,
message
,
"oneof_enum: FOO"
);
}
RunValidJsonTest
(
...
...
conformance/conformance_test.h
View file @
2ff42dcf
...
...
@@ -175,9 +175,11 @@ class ConformanceTestSuite {
ConformanceLevel
level
,
const
protobuf_test_messages
::
proto3
::
TestAllTypes
&
input
,
const
string
&
equivalent_text_format
);
void
RunValidProtobufTest
(
const
string
&
test_name
,
ConformanceLevel
level
,
void
RunValidProtobufTest
(
const
string
&
test_name
,
ConformanceLevel
level
,
const
string
&
input_protobuf
,
const
string
&
equivalent_text_format
);
void
RunValidProtobufTestWithMessage
(
const
string
&
test_name
,
ConformanceLevel
level
,
const
protobuf_test_messages
::
proto3
::
TestAllTypes
&
input
,
const
string
&
equivalent_text_format
);
...
...
@@ -199,6 +201,9 @@ class ConformanceTestSuite {
const
std
::
string
&
test_name
,
ConformanceLevel
level
);
void
TestPrematureEOFForType
(
google
::
protobuf
::
FieldDescriptor
::
Type
type
);
void
TestValidDataForType
(
google
::
protobuf
::
FieldDescriptor
::
Type
,
std
::
vector
<
std
::
pair
<
std
::
string
,
std
::
string
>>
values
);
bool
CheckSetEmpty
(
const
set
<
string
>&
set_to_check
,
const
std
::
string
&
write_to_file
,
const
std
::
string
&
msg
);
ConformanceTestRunner
*
runner_
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment