forked from nanopb/nanopb
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add test cases for proto3 has_ field support.
- Loading branch information
1 parent
f866af7
commit e9667c1
Showing
7 changed files
with
408 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Build and run a test that encodes and decodes a message that contains | ||
# all of the Protocol Buffers data types. | ||
|
||
Import("env") | ||
|
||
env.NanopbProto(["alltypes", "alltypes.options"]) | ||
enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) | ||
dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) | ||
|
||
# Test the round-trip from nanopb encoder to nanopb decoder | ||
env.RunTest(enc) | ||
env.RunTest([dec, "encode_alltypes.output"]) | ||
|
||
# Re-encode the data using protoc, and check that the results from nanopb | ||
# match byte-per-byte to the protoc output. | ||
env.Decode("encode_alltypes.output.decoded", | ||
["encode_alltypes.output", "alltypes.proto"], | ||
MESSAGE='AllTypes') | ||
env.Encode("encode_alltypes.output.recoded", | ||
["encode_alltypes.output.decoded", "alltypes.proto"], | ||
MESSAGE='AllTypes') | ||
env.Compare(["encode_alltypes.output", "encode_alltypes.output.recoded"]) | ||
|
||
# Do the same checks with the optional fields present. | ||
env.RunTest("optionals.output", enc, ARGS = ['1']) | ||
env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1']) | ||
env.Decode("optionals.output.decoded", | ||
["optionals.output", "alltypes.proto"], | ||
MESSAGE='AllTypes') | ||
env.Encode("optionals.output.recoded", | ||
["optionals.output.decoded", "alltypes.proto"], | ||
MESSAGE='AllTypes') | ||
env.Compare(["optionals.output", "optionals.output.recoded"]) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
* max_size:16 | ||
* max_count:5 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
syntax = "proto3"; | ||
// package name placeholder | ||
|
||
message SubMessage { | ||
string substuff1 = 1; | ||
int32 substuff2 = 2; | ||
fixed32 substuff3 = 3; | ||
} | ||
|
||
message EmptyMessage { | ||
|
||
} | ||
|
||
enum HugeEnum { | ||
HE_Zero = 0; | ||
Negative = -2147483647; /* protoc doesn't accept -2147483648 here */ | ||
Positive = 2147483647; | ||
} | ||
|
||
message Limits { | ||
int32 int32_min = 1; | ||
int32 int32_max = 2; | ||
uint32 uint32_min = 3; | ||
uint32 uint32_max = 4; | ||
int64 int64_min = 5; | ||
int64 int64_max = 6; | ||
uint64 uint64_min = 7; | ||
uint64 uint64_max = 8; | ||
HugeEnum enum_min = 9; | ||
HugeEnum enum_max = 10; | ||
} | ||
|
||
enum MyEnum { | ||
Zero = 0; | ||
First = 1; | ||
Second = 2; | ||
Truth = 42; | ||
} | ||
|
||
message AllTypes { | ||
int32 sng_int32 = 1; | ||
int64 sng_int64 = 2; | ||
uint32 sng_uint32 = 3; | ||
uint64 sng_uint64 = 4; | ||
sint32 sng_sint32 = 5; | ||
sint64 sng_sint64 = 6; | ||
bool sng_bool = 7; | ||
|
||
fixed32 sng_fixed32 = 8; | ||
sfixed32 sng_sfixed32= 9; | ||
float sng_float = 10; | ||
|
||
fixed64 sng_fixed64 = 11; | ||
sfixed64 sng_sfixed64= 12; | ||
double sng_double = 13; | ||
|
||
string sng_string = 14; | ||
bytes sng_bytes = 15; | ||
SubMessage sng_submsg = 16; | ||
MyEnum sng_enum = 17; | ||
EmptyMessage sng_emptymsg = 18; | ||
|
||
repeated int32 rep_int32 = 21 [packed = true]; | ||
repeated int64 rep_int64 = 22 [packed = true]; | ||
repeated uint32 rep_uint32 = 23 [packed = true]; | ||
repeated uint64 rep_uint64 = 24 [packed = true]; | ||
repeated sint32 rep_sint32 = 25 [packed = true]; | ||
repeated sint64 rep_sint64 = 26 [packed = true]; | ||
repeated bool rep_bool = 27 [packed = true]; | ||
|
||
repeated fixed32 rep_fixed32 = 28 [packed = true]; | ||
repeated sfixed32 rep_sfixed32= 29 [packed = true]; | ||
repeated float rep_float = 30 [packed = true]; | ||
|
||
repeated fixed64 rep_fixed64 = 31 [packed = true]; | ||
repeated sfixed64 rep_sfixed64= 32 [packed = true]; | ||
repeated double rep_double = 33 [packed = true]; | ||
|
||
repeated string rep_string = 34; | ||
repeated bytes rep_bytes = 35; | ||
repeated SubMessage rep_submsg = 36; | ||
repeated MyEnum rep_enum = 37 [packed = true]; | ||
repeated EmptyMessage rep_emptymsg = 38; | ||
|
||
oneof oneof | ||
{ | ||
SubMessage oneof_msg1 = 59; | ||
EmptyMessage oneof_msg2 = 60; | ||
} | ||
|
||
// Check that extreme integer values are handled correctly | ||
Limits req_limits = 98; | ||
|
||
// Just to make sure that the size of the fields has been calculated | ||
// properly, i.e. otherwise a bug in last field might not be detected. | ||
int32 end = 99; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* Tests the decoding of all types. | ||
* This is the counterpart of test_encode3. | ||
* Run e.g. ./test_encode3 | ./test_decode3 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
#include <pb_decode.h> | ||
#include "alltypes.pb.h" | ||
#include "test_helpers.h" | ||
|
||
#define TEST(x) if (!(x)) { \ | ||
printf("Test " #x " failed.\n"); \ | ||
return false; \ | ||
} | ||
|
||
/* This function is called once from main(), it handles | ||
the decoding and checks the fields. */ | ||
bool check_alltypes(pb_istream_t *stream, int mode) | ||
{ | ||
AllTypes alltypes = AllTypes_init_zero; | ||
|
||
/* Fill with garbage to better detect initialization errors */ | ||
memset(&alltypes, 0xAA, sizeof(alltypes)); | ||
|
||
if (!pb_decode(stream, AllTypes_fields, &alltypes)) | ||
return false; | ||
|
||
TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0); | ||
TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0); | ||
TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0); | ||
TEST(alltypes.rep_uint64_count == 5 && alltypes.rep_uint64[4] == 2004 && alltypes.rep_uint64[0] == 0); | ||
TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0); | ||
TEST(alltypes.rep_sint64_count == 5 && alltypes.rep_sint64[4] == -2006 && alltypes.rep_sint64[0] == 0); | ||
TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false); | ||
|
||
TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0); | ||
TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0); | ||
TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f); | ||
|
||
TEST(alltypes.rep_fixed64_count == 5 && alltypes.rep_fixed64[4] == 2011 && alltypes.rep_fixed64[0] == 0); | ||
TEST(alltypes.rep_sfixed64_count == 5 && alltypes.rep_sfixed64[4] == -2012 && alltypes.rep_sfixed64[0] == 0); | ||
TEST(alltypes.rep_double_count == 5 && alltypes.rep_double[4] == 2013.0 && alltypes.rep_double[0] == 0.0); | ||
|
||
TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0'); | ||
TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0); | ||
TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0); | ||
|
||
TEST(alltypes.rep_submsg_count == 5); | ||
TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0'); | ||
TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0); | ||
TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 0); | ||
|
||
TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero); | ||
TEST(alltypes.rep_emptymsg_count == 5); | ||
|
||
if (mode == 0) | ||
{ | ||
/* Expect default values */ | ||
TEST(alltypes.sng_int32 == 0); | ||
TEST(alltypes.sng_int64 == 0); | ||
TEST(alltypes.sng_uint32 == 0); | ||
TEST(alltypes.sng_uint64 == 0); | ||
TEST(alltypes.sng_sint32 == 0); | ||
TEST(alltypes.sng_sint64 == 0); | ||
TEST(alltypes.sng_bool == false); | ||
|
||
TEST(alltypes.sng_fixed32 == 0); | ||
TEST(alltypes.sng_sfixed32 == 0); | ||
TEST(alltypes.sng_float == 0.0f); | ||
|
||
TEST(alltypes.sng_fixed64 == 0); | ||
TEST(alltypes.sng_sfixed64 == 0); | ||
TEST(alltypes.sng_double == 0.0); | ||
|
||
TEST(strcmp(alltypes.sng_string, "") == 0); | ||
TEST(alltypes.sng_bytes.size == 0); | ||
TEST(strcmp(alltypes.sng_submsg.substuff1, "") == 0); | ||
TEST(alltypes.sng_submsg.substuff2 == 0); | ||
TEST(alltypes.sng_submsg.substuff3 == 0); | ||
TEST(alltypes.sng_enum == MyEnum_Zero); | ||
|
||
TEST(alltypes.which_oneof == 0); | ||
} | ||
else | ||
{ | ||
/* Expect filled-in values */ | ||
TEST(alltypes.sng_int32 == 3041); | ||
TEST(alltypes.sng_int64 == 3042); | ||
TEST(alltypes.sng_uint32 == 3043); | ||
TEST(alltypes.sng_uint64 == 3044); | ||
TEST(alltypes.sng_sint32 == 3045); | ||
TEST(alltypes.sng_sint64 == 3046); | ||
TEST(alltypes.sng_bool == true); | ||
|
||
TEST(alltypes.sng_fixed32 == 3048); | ||
TEST(alltypes.sng_sfixed32 == 3049); | ||
TEST(alltypes.sng_float == 3050.0f); | ||
|
||
TEST(alltypes.sng_fixed64 == 3051); | ||
TEST(alltypes.sng_sfixed64 == 3052); | ||
TEST(alltypes.sng_double == 3053.0); | ||
|
||
TEST(strcmp(alltypes.sng_string, "3054") == 0); | ||
TEST(alltypes.sng_bytes.size == 4); | ||
TEST(memcmp(alltypes.sng_bytes.bytes, "3055", 4) == 0); | ||
TEST(strcmp(alltypes.sng_submsg.substuff1, "3056") == 0); | ||
TEST(alltypes.sng_submsg.substuff2 == 3056); | ||
TEST(alltypes.sng_submsg.substuff3 == 0); | ||
TEST(alltypes.sng_enum == MyEnum_Truth); | ||
|
||
TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag); | ||
TEST(strcmp(alltypes.oneof.oneof_msg1.substuff1, "4059") == 0); | ||
TEST(alltypes.oneof.oneof_msg1.substuff2 == 4059); | ||
} | ||
|
||
TEST(alltypes.req_limits.int32_min == INT32_MIN); | ||
TEST(alltypes.req_limits.int32_max == INT32_MAX); | ||
TEST(alltypes.req_limits.uint32_min == 0); | ||
TEST(alltypes.req_limits.uint32_max == UINT32_MAX); | ||
TEST(alltypes.req_limits.int64_min == INT64_MIN); | ||
TEST(alltypes.req_limits.int64_max == INT64_MAX); | ||
TEST(alltypes.req_limits.uint64_min == 0); | ||
TEST(alltypes.req_limits.uint64_max == UINT64_MAX); | ||
TEST(alltypes.req_limits.enum_min == HugeEnum_Negative); | ||
TEST(alltypes.req_limits.enum_max == HugeEnum_Positive); | ||
|
||
TEST(alltypes.end == 1099); | ||
|
||
return true; | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
uint8_t buffer[1024]; | ||
size_t count; | ||
pb_istream_t stream; | ||
|
||
/* Whether to expect the optional values or the default values. */ | ||
int mode = (argc > 1) ? atoi(argv[1]) : 0; | ||
|
||
/* Read the data into buffer */ | ||
SET_BINARY_MODE(stdin); | ||
count = fread(buffer, 1, sizeof(buffer), stdin); | ||
|
||
/* Construct a pb_istream_t for reading from the buffer */ | ||
stream = pb_istream_from_buffer(buffer, count); | ||
|
||
/* Decode and print out the stuff */ | ||
if (!check_alltypes(&stream, mode)) | ||
{ | ||
printf("Parsing failed: %s\n", PB_GET_ERROR(&stream)); | ||
return 1; | ||
} else { | ||
return 0; | ||
} | ||
} |
Oops, something went wrong.