mirror of
https://github.com/protobuf-c/protobuf-c.git
synced 2024-12-29 07:19:42 +08:00
8cd5f6764b
i'm confused as to why these fields exist, since the typical implementation of a "temporary alloc" would be something like alloca(), and alloca() is usually just inlined code that adjusts the stack pointer, which is not a function whose address could be taken. this breaks the API/ABI and will require a note in the ChangeLog. possibly we could revisit the idea of "temporary allocations" by using C99 variable length arrays. this would have the advantage of being standardized, unlike alloca().
1693 lines
55 KiB
C
1693 lines
55 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "t/test-full.pb-c.h"
|
|
#include "t/generated-code2/test-full-cxx-output.inc"
|
|
|
|
#define TEST_ENUM_SMALL_TYPE_NAME Foo__TestEnumSmall
|
|
#define TEST_ENUM_SMALL(shortname) FOO__TEST_ENUM_SMALL__##shortname
|
|
#define TEST_ENUM_TYPE_NAME Foo__TestEnum
|
|
#include "common-test-arrays.h"
|
|
#define N_ELEMENTS(arr) (sizeof(arr)/sizeof((arr)[0]))
|
|
|
|
/* ==== helper functions ==== */
|
|
static protobuf_c_boolean
|
|
are_bytes_equal (unsigned actual_len,
|
|
const uint8_t *actual_data,
|
|
unsigned expected_len,
|
|
const uint8_t *expected_data)
|
|
{
|
|
if (actual_len != expected_len)
|
|
return 0;
|
|
return memcmp (actual_data, expected_data, actual_len) == 0;
|
|
}
|
|
static void
|
|
dump_bytes_stderr (size_t len, const uint8_t *data)
|
|
{
|
|
size_t i;
|
|
for (i = 0; i < len; i++)
|
|
fprintf(stderr," %02x", data[i]);
|
|
fprintf(stderr,"\n");
|
|
}
|
|
static void
|
|
test_versus_static_array(unsigned actual_len,
|
|
const uint8_t *actual_data,
|
|
unsigned expected_len,
|
|
const uint8_t *expected_data,
|
|
const char *static_buf_name,
|
|
const char *filename,
|
|
unsigned lineno)
|
|
{
|
|
if (are_bytes_equal (actual_len, actual_data, expected_len, expected_data))
|
|
return;
|
|
|
|
fprintf (stderr, "test_versus_static_array failed:\n"
|
|
"actual: [length=%u]\n", actual_len);
|
|
dump_bytes_stderr (actual_len, actual_data);
|
|
fprintf (stderr, "expected: [length=%u] [buffer %s]\n",
|
|
expected_len, static_buf_name);
|
|
dump_bytes_stderr (expected_len, expected_data);
|
|
fprintf (stderr, "at line %u of %s.\n", lineno, filename);
|
|
abort();
|
|
}
|
|
|
|
#define TEST_VERSUS_STATIC_ARRAY(actual_len, actual_data, buf) \
|
|
test_versus_static_array(actual_len,actual_data, \
|
|
sizeof(buf), buf, #buf, __FILE__, __LINE__)
|
|
|
|
/* rv is unpacked message */
|
|
static void *
|
|
test_compare_pack_methods (ProtobufCMessage *message,
|
|
size_t *packed_len_out,
|
|
uint8_t **packed_out)
|
|
{
|
|
unsigned char scratch[16];
|
|
ProtobufCBufferSimple bs = PROTOBUF_C_BUFFER_SIMPLE_INIT (scratch);
|
|
size_t siz1 = protobuf_c_message_get_packed_size (message);
|
|
size_t siz2;
|
|
size_t siz3 = protobuf_c_message_pack_to_buffer (message, &bs.base);
|
|
void *packed1 = malloc (siz1);
|
|
void *rv;
|
|
assert (packed1 != NULL);
|
|
assert (siz1 == siz3);
|
|
siz2 = protobuf_c_message_pack (message, packed1);
|
|
assert (siz1 == siz2);
|
|
assert (bs.len == siz1);
|
|
assert (memcmp (bs.data, packed1, siz1) == 0);
|
|
rv = protobuf_c_message_unpack (message->descriptor, NULL, siz1, packed1);
|
|
assert (rv != NULL);
|
|
PROTOBUF_C_BUFFER_SIMPLE_CLEAR (&bs);
|
|
*packed_len_out = siz1;
|
|
*packed_out = packed1;
|
|
return rv;
|
|
}
|
|
|
|
#define NUMERIC_EQUALS(a,b) ((a) == (b))
|
|
#define STRING_EQUALS(a,b) (strcmp((a),(b))==0)
|
|
|
|
static protobuf_c_boolean
|
|
binary_data_equals (ProtobufCBinaryData a, ProtobufCBinaryData b)
|
|
{
|
|
if (a.len != b.len)
|
|
return 0;
|
|
return memcmp (a.data, b.data, a.len) == 0;
|
|
}
|
|
|
|
static protobuf_c_boolean
|
|
submesses_equals (Foo__SubMess *a, Foo__SubMess *b)
|
|
{
|
|
assert(a->base.descriptor == &foo__sub_mess__descriptor);
|
|
assert(b->base.descriptor == &foo__sub_mess__descriptor);
|
|
return a->test == b->test;
|
|
}
|
|
|
|
/* === the actual tests === */
|
|
|
|
|
|
/* === misc fencepost tests === */
|
|
static void test_enum_small (void)
|
|
{
|
|
|
|
#define DO_TEST(UC_VALUE) \
|
|
do{ \
|
|
Foo__TestMessRequiredEnumSmall small = FOO__TEST_MESS_REQUIRED_ENUM_SMALL__INIT; \
|
|
size_t len; \
|
|
uint8_t *data; \
|
|
Foo__TestMessRequiredEnumSmall *unpacked; \
|
|
small.test = FOO__TEST_ENUM_SMALL__##UC_VALUE; \
|
|
unpacked = test_compare_pack_methods ((ProtobufCMessage*)&small, &len, &data); \
|
|
assert (unpacked->test == FOO__TEST_ENUM_SMALL__##UC_VALUE); \
|
|
foo__test_mess_required_enum_small__free_unpacked (unpacked, NULL); \
|
|
TEST_VERSUS_STATIC_ARRAY (len, data, test_enum_small_##UC_VALUE); \
|
|
free (data); \
|
|
}while(0)
|
|
|
|
assert (sizeof (Foo__TestEnumSmall) == 4);
|
|
|
|
DO_TEST(VALUE);
|
|
DO_TEST(OTHER_VALUE);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_enum_big (void)
|
|
{
|
|
Foo__TestMessRequiredEnum big = FOO__TEST_MESS_REQUIRED_ENUM__INIT;
|
|
size_t len;
|
|
uint8_t *data;
|
|
Foo__TestMessRequiredEnum *unpacked;
|
|
|
|
assert (sizeof (Foo__TestEnum) == 4);
|
|
|
|
#define DO_ONE_TEST(shortname, numeric_value, encoded_len) \
|
|
do{ \
|
|
big.test = FOO__TEST_ENUM__##shortname; \
|
|
unpacked = test_compare_pack_methods ((ProtobufCMessage*)&big, &len, &data); \
|
|
assert (unpacked->test == FOO__TEST_ENUM__##shortname); \
|
|
foo__test_mess_required_enum__free_unpacked (unpacked, NULL); \
|
|
TEST_VERSUS_STATIC_ARRAY (len, data, test_enum_big_##shortname); \
|
|
assert (encoded_len + 1 == len); \
|
|
assert (big.test == numeric_value); \
|
|
free (data); \
|
|
}while(0)
|
|
|
|
DO_ONE_TEST(VALUE0, 0, 1);
|
|
DO_ONE_TEST(VALUE127, 127, 1);
|
|
DO_ONE_TEST(VALUE128, 128, 2);
|
|
DO_ONE_TEST(VALUE16383, 16383, 2);
|
|
DO_ONE_TEST(VALUE16384, 16384, 3);
|
|
DO_ONE_TEST(VALUE2097151, 2097151, 3);
|
|
DO_ONE_TEST(VALUE2097152, 2097152, 4);
|
|
DO_ONE_TEST(VALUE268435455, 268435455, 4);
|
|
DO_ONE_TEST(VALUE268435456, 268435456, 5);
|
|
|
|
#undef DO_ONE_TEST
|
|
}
|
|
static void test_field_numbers (void)
|
|
{
|
|
size_t len;
|
|
uint8_t *data;
|
|
|
|
#define DO_ONE_TEST(num, exp_len) \
|
|
{ \
|
|
Foo__TestFieldNo##num t = FOO__TEST_FIELD_NO##num##__INIT; \
|
|
Foo__TestFieldNo##num *t2; \
|
|
t.test = "tst"; \
|
|
t2 = test_compare_pack_methods ((ProtobufCMessage*)(&t), &len, &data); \
|
|
assert (strcmp (t2->test, "tst") == 0); \
|
|
TEST_VERSUS_STATIC_ARRAY (len, data, test_field_number_##num); \
|
|
assert (len == exp_len); \
|
|
free (data); \
|
|
foo__test_field_no##num##__free_unpacked (t2, NULL); \
|
|
}
|
|
DO_ONE_TEST (15, 1 + 1 + 3);
|
|
DO_ONE_TEST (16, 2 + 1 + 3);
|
|
DO_ONE_TEST (2047, 2 + 1 + 3);
|
|
DO_ONE_TEST (2048, 3 + 1 + 3);
|
|
DO_ONE_TEST (262143, 3 + 1 + 3);
|
|
DO_ONE_TEST (262144, 4 + 1 + 3);
|
|
DO_ONE_TEST (33554431, 4 + 1 + 3);
|
|
DO_ONE_TEST (33554432, 5 + 1 + 3);
|
|
#undef DO_ONE_TEST
|
|
}
|
|
|
|
/* === Required type fields === */
|
|
|
|
#define DO_TEST_REQUIRED(Type, TYPE, type, value, example_packed_data, equal_func) \
|
|
do{ \
|
|
Foo__TestMessRequired##Type opt = FOO__TEST_MESS_REQUIRED_##TYPE##__INIT; \
|
|
Foo__TestMessRequired##Type *mess; \
|
|
size_t len; uint8_t *data; \
|
|
opt.test = value; \
|
|
mess = test_compare_pack_methods (&opt.base, &len, &data); \
|
|
TEST_VERSUS_STATIC_ARRAY (len, data, example_packed_data); \
|
|
assert (equal_func (mess->test, value)); \
|
|
foo__test_mess_required_##type##__free_unpacked (mess, NULL); \
|
|
free (data); \
|
|
}while(0)
|
|
static void test_required_int32 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(Int32, INT32, int32, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(INT32_MIN, test_required_int32_min);
|
|
DO_TEST(-1000, test_required_int32_m1000);
|
|
DO_TEST(0, test_required_int32_0);
|
|
DO_TEST(INT32_MAX, test_required_int32_max);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_sint32 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(SInt32, SINT32, sint32, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(INT32_MIN, test_required_sint32_min);
|
|
DO_TEST(-1000, test_required_sint32_m1000);
|
|
DO_TEST(0, test_required_sint32_0);
|
|
DO_TEST(INT32_MAX, test_required_sint32_max);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_sfixed32 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(SFixed32, SFIXED32, sfixed32, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(INT32_MIN, test_required_sfixed32_min);
|
|
DO_TEST(-1000, test_required_sfixed32_m1000);
|
|
DO_TEST(0, test_required_sfixed32_0);
|
|
DO_TEST(INT32_MAX, test_required_sfixed32_max);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_uint32 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(UInt32, UINT32, uint32, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(0, test_required_uint32_0);
|
|
DO_TEST(MILLION, test_required_uint32_million);
|
|
DO_TEST(UINT32_MAX, test_required_uint32_max);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_fixed32 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(Fixed32, FIXED32, fixed32, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(0, test_required_fixed32_0);
|
|
DO_TEST(MILLION, test_required_fixed32_million);
|
|
DO_TEST(UINT32_MAX, test_required_fixed32_max);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_int64 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(Int64, INT64, int64, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(INT64_MIN, test_required_int64_min);
|
|
DO_TEST(-TRILLION, test_required_int64_mtril);
|
|
DO_TEST(0, test_required_int64_0);
|
|
DO_TEST(QUADRILLION, test_required_int64_quad);
|
|
DO_TEST(INT64_MAX, test_required_int64_max);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_sint64 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(SInt64, SINT64, sint64, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(INT64_MIN, test_required_sint64_min);
|
|
DO_TEST(-TRILLION, test_required_sint64_mtril);
|
|
DO_TEST(0, test_required_sint64_0);
|
|
DO_TEST(QUADRILLION, test_required_sint64_quad);
|
|
DO_TEST(INT64_MAX, test_required_sint64_max);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_sfixed64 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(SFixed64, SFIXED64, sfixed64, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(INT64_MIN, test_required_sfixed64_min);
|
|
DO_TEST(-TRILLION, test_required_sfixed64_mtril);
|
|
DO_TEST(0, test_required_sfixed64_0);
|
|
DO_TEST(QUADRILLION, test_required_sfixed64_quad);
|
|
DO_TEST(INT64_MAX, test_required_sfixed64_max);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_uint64 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(UInt64, UINT64, uint64, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(0, test_required_uint64_0);
|
|
DO_TEST(THOUSAND, test_required_uint64_thou);
|
|
DO_TEST(MILLION, test_required_uint64_mill);
|
|
DO_TEST(BILLION, test_required_uint64_bill);
|
|
DO_TEST(TRILLION, test_required_uint64_tril);
|
|
DO_TEST(QUADRILLION, test_required_uint64_quad);
|
|
DO_TEST(QUINTILLION, test_required_uint64_quint);
|
|
DO_TEST(UINT64_MAX, test_required_uint64_max);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_fixed64 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(Fixed64, FIXED64, fixed64, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(0, test_required_fixed64_0);
|
|
DO_TEST(THOUSAND, test_required_fixed64_thou);
|
|
DO_TEST(MILLION, test_required_fixed64_mill);
|
|
DO_TEST(BILLION, test_required_fixed64_bill);
|
|
DO_TEST(TRILLION, test_required_fixed64_tril);
|
|
DO_TEST(QUADRILLION, test_required_fixed64_quad);
|
|
DO_TEST(QUINTILLION, test_required_fixed64_quint);
|
|
DO_TEST(UINT64_MAX, test_required_fixed64_max);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_float (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(Float, FLOAT, float, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(-THOUSAND, test_required_float_mthou);
|
|
DO_TEST(0, test_required_float_0);
|
|
DO_TEST(420, test_required_float_420);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_double (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(Double, DOUBLE, double, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(-THOUSAND, test_required_double_mthou);
|
|
DO_TEST(0, test_required_double_0);
|
|
DO_TEST(420, test_required_double_420);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_bool (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(Bool, BOOL, bool, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(0, test_required_bool_0);
|
|
DO_TEST(1, test_required_bool_1);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_TestEnumSmall (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(EnumSmall, ENUM_SMALL, enum_small, value, example_packed_data, NUMERIC_EQUALS)
|
|
DO_TEST(FOO__TEST_ENUM_SMALL__VALUE, test_required_enum_small_VALUE);
|
|
DO_TEST(FOO__TEST_ENUM_SMALL__OTHER_VALUE, test_required_enum_small_OTHER_VALUE);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_TestEnum (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(Enum, ENUM, enum, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (FOO__TEST_ENUM__VALUE0, test_required_enum_0);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE1, test_required_enum_1);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE127, test_required_enum_127);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE128, test_required_enum_128);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE16383, test_required_enum_16383);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE16384, test_required_enum_16384);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE2097151, test_required_enum_2097151);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE2097152, test_required_enum_2097152);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE268435455, test_required_enum_268435455);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE268435456, test_required_enum_268435456);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_string (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED(String, STRING, string, value, example_packed_data, STRING_EQUALS)
|
|
|
|
DO_TEST("", test_required_string_empty);
|
|
DO_TEST("hello", test_required_string_hello);
|
|
DO_TEST("two hundred xs follow: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", test_required_string_long);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_bytes (void)
|
|
{
|
|
static ProtobufCBinaryData bd_empty = { 0, (uint8_t*)"" };
|
|
static ProtobufCBinaryData bd_hello = { 5, (uint8_t*)"hello" };
|
|
static ProtobufCBinaryData bd_random = { 5, (uint8_t*)"\1\0\375\2\4" };
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED (Bytes, BYTES, bytes, value, example_packed_data, binary_data_equals)
|
|
DO_TEST (bd_empty, test_required_bytes_empty);
|
|
DO_TEST (bd_hello, test_required_bytes_hello);
|
|
DO_TEST (bd_random, test_required_bytes_random);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_required_SubMess (void)
|
|
{
|
|
Foo__SubMess submess = FOO__SUB_MESS__INIT;
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_REQUIRED (Message, MESSAGE, message, value, example_packed_data, submesses_equals)
|
|
submess.test = 0;
|
|
DO_TEST (&submess, test_required_submess_0);
|
|
submess.test = 42;
|
|
DO_TEST (&submess, test_required_submess_42);
|
|
#undef DO_TEST
|
|
}
|
|
|
|
/* === Optional type fields === */
|
|
static void test_empty_optional (void)
|
|
{
|
|
Foo__TestMessOptional mess = FOO__TEST_MESS_OPTIONAL__INIT;
|
|
size_t len;
|
|
uint8_t *data;
|
|
Foo__TestMessOptional *mess2 = test_compare_pack_methods (&mess.base, &len, &data);
|
|
assert (len == 0);
|
|
free (data);
|
|
foo__test_mess_optional__free_unpacked (mess2, NULL);
|
|
}
|
|
|
|
|
|
#define DO_TEST_OPTIONAL(base_member, value, example_packed_data, equal_func) \
|
|
do{ \
|
|
Foo__TestMessOptional opt = FOO__TEST_MESS_OPTIONAL__INIT; \
|
|
Foo__TestMessOptional *mess; \
|
|
size_t len; uint8_t *data; \
|
|
opt.has_##base_member = 1; \
|
|
opt.base_member = value; \
|
|
mess = test_compare_pack_methods (&opt.base, &len, &data); \
|
|
TEST_VERSUS_STATIC_ARRAY (len, data, example_packed_data); \
|
|
assert (mess->has_##base_member); \
|
|
assert (equal_func (mess->base_member, value)); \
|
|
foo__test_mess_optional__free_unpacked (mess, NULL); \
|
|
free (data); \
|
|
}while(0)
|
|
|
|
static void test_optional_int32 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_int32, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (INT32_MIN, test_optional_int32_min);
|
|
DO_TEST (-1, test_optional_int32_m1);
|
|
DO_TEST (0, test_optional_int32_0);
|
|
DO_TEST (666, test_optional_int32_666);
|
|
DO_TEST (INT32_MAX, test_optional_int32_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_optional_sint32 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_sint32, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (INT32_MIN, test_optional_sint32_min);
|
|
DO_TEST (-1, test_optional_sint32_m1);
|
|
DO_TEST (0, test_optional_sint32_0);
|
|
DO_TEST (666, test_optional_sint32_666);
|
|
DO_TEST (INT32_MAX, test_optional_sint32_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
static void test_optional_sfixed32 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_sfixed32, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (INT32_MIN, test_optional_sfixed32_min);
|
|
DO_TEST (-1, test_optional_sfixed32_m1);
|
|
DO_TEST (0, test_optional_sfixed32_0);
|
|
DO_TEST (666, test_optional_sfixed32_666);
|
|
DO_TEST (INT32_MAX, test_optional_sfixed32_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
static void test_optional_int64 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_int64, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (INT64_MIN, test_optional_int64_min);
|
|
DO_TEST (-1111111111LL, test_optional_int64_m1111111111LL);
|
|
DO_TEST (0, test_optional_int64_0);
|
|
DO_TEST (QUINTILLION, test_optional_int64_quintillion);
|
|
DO_TEST (INT64_MAX, test_optional_int64_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
static void test_optional_sint64 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_sint64, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (INT64_MIN, test_optional_sint64_min);
|
|
DO_TEST (-1111111111LL, test_optional_sint64_m1111111111LL);
|
|
DO_TEST (0, test_optional_sint64_0);
|
|
DO_TEST (QUINTILLION, test_optional_sint64_quintillion);
|
|
DO_TEST (INT64_MAX, test_optional_sint64_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
static void test_optional_sfixed64 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_sfixed64, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (INT64_MIN, test_optional_sfixed64_min);
|
|
DO_TEST (-1111111111LL, test_optional_sfixed64_m1111111111LL);
|
|
DO_TEST (0, test_optional_sfixed64_0);
|
|
DO_TEST (QUINTILLION, test_optional_sfixed64_quintillion);
|
|
DO_TEST (INT64_MAX, test_optional_sfixed64_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_optional_uint32 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_uint32, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (0, test_optional_uint32_0);
|
|
DO_TEST (669, test_optional_uint32_669);
|
|
DO_TEST (UINT32_MAX, test_optional_uint32_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_optional_fixed32 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_fixed32, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (0, test_optional_fixed32_0);
|
|
DO_TEST (669, test_optional_fixed32_669);
|
|
DO_TEST (UINT32_MAX, test_optional_fixed32_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_optional_uint64 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_uint64, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (0, test_optional_uint64_0);
|
|
DO_TEST (669669669669669ULL, test_optional_uint64_669669669669669);
|
|
DO_TEST (UINT64_MAX, test_optional_uint64_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_optional_fixed64 (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_fixed64, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (0, test_optional_fixed64_0);
|
|
DO_TEST (669669669669669ULL, test_optional_fixed64_669669669669669);
|
|
DO_TEST (UINT64_MAX, test_optional_fixed64_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_optional_float (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_float, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (-100, test_optional_float_m100);
|
|
DO_TEST (0, test_optional_float_0);
|
|
DO_TEST (141243, test_optional_float_141243);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
static void test_optional_double (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_double, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (-100, test_optional_double_m100);
|
|
DO_TEST (0, test_optional_double_0);
|
|
DO_TEST (141243, test_optional_double_141243);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
static void test_optional_bool (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_boolean, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (0, test_optional_bool_0);
|
|
DO_TEST (1, test_optional_bool_1);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
static void test_optional_TestEnumSmall (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_enum_small, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (0, test_optional_enum_small_0);
|
|
DO_TEST (1, test_optional_enum_small_1);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_optional_TestEnum (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL(test_enum, value, example_packed_data, NUMERIC_EQUALS)
|
|
|
|
DO_TEST (FOO__TEST_ENUM__VALUE0, test_optional_enum_0);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE1, test_optional_enum_1);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE127, test_optional_enum_127);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE128, test_optional_enum_128);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE16383, test_optional_enum_16383);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE16384, test_optional_enum_16384);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE2097151, test_optional_enum_2097151);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE2097152, test_optional_enum_2097152);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE268435455, test_optional_enum_268435455);
|
|
DO_TEST (FOO__TEST_ENUM__VALUE268435456, test_optional_enum_268435456);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
#define DO_TEST_OPTIONAL__NO_HAS(base_member, value, example_packed_data, equal_func) \
|
|
do{ \
|
|
Foo__TestMessOptional opt = FOO__TEST_MESS_OPTIONAL__INIT; \
|
|
Foo__TestMessOptional *mess; \
|
|
size_t len; uint8_t *data; \
|
|
opt.base_member = value; \
|
|
mess = test_compare_pack_methods (&opt.base, &len, &data); \
|
|
TEST_VERSUS_STATIC_ARRAY (len, data, example_packed_data); \
|
|
assert (mess->base_member != NULL); \
|
|
assert (equal_func (mess->base_member, value)); \
|
|
foo__test_mess_optional__free_unpacked (mess, NULL); \
|
|
free (data); \
|
|
}while(0)
|
|
|
|
static void test_optional_string (void)
|
|
{
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL__NO_HAS (test_string, value, example_packed_data, STRING_EQUALS)
|
|
DO_TEST ("", test_optional_string_empty);
|
|
DO_TEST ("hello", test_optional_string_hello);
|
|
#undef DO_TEST
|
|
}
|
|
static void test_optional_bytes (void)
|
|
{
|
|
static ProtobufCBinaryData bd_empty = { 0, (uint8_t*)"" };
|
|
static ProtobufCBinaryData bd_hello = { 5, (uint8_t*)"hello" };
|
|
static ProtobufCBinaryData bd_random = { 5, (uint8_t*)"\1\0\375\2\4" };
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL (test_bytes, value, example_packed_data, binary_data_equals)
|
|
DO_TEST (bd_empty, test_optional_bytes_empty);
|
|
DO_TEST (bd_hello, test_optional_bytes_hello);
|
|
DO_TEST (bd_random, test_optional_bytes_random);
|
|
#undef DO_TEST
|
|
}
|
|
static void test_optional_SubMess (void)
|
|
{
|
|
Foo__SubMess submess = FOO__SUB_MESS__INIT;
|
|
#define DO_TEST(value, example_packed_data) \
|
|
DO_TEST_OPTIONAL__NO_HAS (test_message, value, example_packed_data, submesses_equals)
|
|
submess.test = 0;
|
|
DO_TEST (&submess, test_optional_submess_0);
|
|
submess.test = 42;
|
|
DO_TEST (&submess, test_optional_submess_42);
|
|
#undef DO_TEST
|
|
}
|
|
/* === repeated type fields === */
|
|
#define DO_TEST_REPEATED(lc_member_name, cast, \
|
|
static_array, example_packed_data, \
|
|
equals_macro) \
|
|
do{ \
|
|
Foo__TestMess mess = FOO__TEST_MESS__INIT; \
|
|
Foo__TestMess *mess2; \
|
|
size_t len; \
|
|
uint8_t *data; \
|
|
unsigned i; \
|
|
mess.n_##lc_member_name = N_ELEMENTS (static_array); \
|
|
mess.lc_member_name = cast static_array; \
|
|
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); \
|
|
assert(mess2->n_##lc_member_name == N_ELEMENTS (static_array)); \
|
|
for (i = 0; i < N_ELEMENTS (static_array); i++) \
|
|
assert(equals_macro(mess2->lc_member_name[i], static_array[i])); \
|
|
TEST_VERSUS_STATIC_ARRAY (len, data, example_packed_data); \
|
|
free (data); \
|
|
foo__test_mess__free_unpacked (mess2, NULL); \
|
|
}while(0)
|
|
|
|
static void test_empty_repeated (void)
|
|
{
|
|
Foo__TestMess mess = FOO__TEST_MESS__INIT;
|
|
size_t len;
|
|
uint8_t *data;
|
|
Foo__TestMess *mess2 = test_compare_pack_methods (&mess.base, &len, &data);
|
|
assert (len == 0);
|
|
free (data);
|
|
foo__test_mess__free_unpacked (mess2, NULL);
|
|
}
|
|
|
|
static void test_repeated_int32 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_int32, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int32_arr0, test_repeated_int32_arr0);
|
|
DO_TEST (int32_arr1, test_repeated_int32_arr1);
|
|
DO_TEST (int32_arr_min_max, test_repeated_int32_arr_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_sint32 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_sint32, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int32_arr0, test_repeated_sint32_arr0);
|
|
DO_TEST (int32_arr1, test_repeated_sint32_arr1);
|
|
DO_TEST (int32_arr_min_max, test_repeated_sint32_arr_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_sfixed32 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_sfixed32, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int32_arr0, test_repeated_sfixed32_arr0);
|
|
DO_TEST (int32_arr1, test_repeated_sfixed32_arr1);
|
|
DO_TEST (int32_arr_min_max, test_repeated_sfixed32_arr_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_uint32 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_uint32, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (uint32_roundnumbers, test_repeated_uint32_roundnumbers);
|
|
DO_TEST (uint32_0_max, test_repeated_uint32_0_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
|
|
|
|
static void test_repeated_fixed32 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_fixed32, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (uint32_roundnumbers, test_repeated_fixed32_roundnumbers);
|
|
DO_TEST (uint32_0_max, test_repeated_fixed32_0_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_int64 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_int64, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int64_roundnumbers, test_repeated_int64_roundnumbers);
|
|
DO_TEST (int64_min_max, test_repeated_int64_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_sint64 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_sint64, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int64_roundnumbers, test_repeated_sint64_roundnumbers);
|
|
DO_TEST (int64_min_max, test_repeated_sint64_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_sfixed64 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_sfixed64, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int64_roundnumbers, test_repeated_sfixed64_roundnumbers);
|
|
DO_TEST (int64_min_max, test_repeated_sfixed64_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_uint64 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_uint64, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(uint64_roundnumbers, test_repeated_uint64_roundnumbers);
|
|
DO_TEST(uint64_0_1_max, test_repeated_uint64_0_1_max);
|
|
DO_TEST(uint64_random, test_repeated_uint64_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_fixed64 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_fixed64, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(uint64_roundnumbers, test_repeated_fixed64_roundnumbers);
|
|
DO_TEST(uint64_0_1_max, test_repeated_fixed64_0_1_max);
|
|
DO_TEST(uint64_random, test_repeated_fixed64_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_float (void)
|
|
{
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_float, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(float_random, test_repeated_float_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_double (void)
|
|
{
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_double, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(double_random, test_repeated_double_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_boolean (void)
|
|
{
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_boolean, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(boolean_0, test_repeated_boolean_0);
|
|
DO_TEST(boolean_1, test_repeated_boolean_1);
|
|
DO_TEST(boolean_random, test_repeated_boolean_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_TestEnumSmall (void)
|
|
{
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_enum_small, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(enum_small_0, test_repeated_enum_small_0);
|
|
DO_TEST(enum_small_1, test_repeated_enum_small_1);
|
|
DO_TEST(enum_small_random, test_repeated_enum_small_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_TestEnum (void)
|
|
{
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_enum, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(enum_0, test_repeated_enum_0);
|
|
DO_TEST(enum_1, test_repeated_enum_1);
|
|
DO_TEST(enum_random, test_repeated_enum_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_string (void)
|
|
{
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_string, (char **), \
|
|
static_array, example_packed_data, \
|
|
STRING_EQUALS)
|
|
|
|
DO_TEST(repeated_strings_0, test_repeated_strings_0);
|
|
DO_TEST(repeated_strings_1, test_repeated_strings_1);
|
|
DO_TEST(repeated_strings_2, test_repeated_strings_2);
|
|
DO_TEST(repeated_strings_3, test_repeated_strings_3);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_bytes (void)
|
|
{
|
|
static ProtobufCBinaryData test_binary_data_0[] = {
|
|
{ 4, (uint8_t *) "text" },
|
|
{ 9, (uint8_t *) "str\1\2\3\4\5\0" },
|
|
{ 10, (uint8_t *) "gobble\0foo" }
|
|
};
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_bytes, , \
|
|
static_array, example_packed_data, \
|
|
binary_data_equals)
|
|
|
|
DO_TEST (test_binary_data_0, test_repeated_bytes_0);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_repeated_SubMess (void)
|
|
{
|
|
static Foo__SubMess submess0 = FOO__SUB_MESS__INIT;
|
|
static Foo__SubMess submess1 = FOO__SUB_MESS__INIT;
|
|
static Foo__SubMess submess2 = FOO__SUB_MESS__INIT;
|
|
static Foo__SubMess *submesses[3] = { &submess0, &submess1, &submess2 };
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_REPEATED(test_message, , \
|
|
static_array, example_packed_data, \
|
|
submesses_equals)
|
|
|
|
DO_TEST (submesses, test_repeated_submess_0);
|
|
submess0.test = 42;
|
|
submess1.test = -10000;
|
|
submess2.test = 667;
|
|
DO_TEST (submesses, test_repeated_submess_1);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
#define DO_TEST_PACKED_REPEATED(lc_member_name, cast, \
|
|
static_array, example_packed_data, \
|
|
equals_macro) \
|
|
do{ \
|
|
Foo__TestMessPacked mess = FOO__TEST_MESS_PACKED__INIT; \
|
|
Foo__TestMessPacked *mess2; \
|
|
size_t len; \
|
|
uint8_t *data; \
|
|
unsigned i; \
|
|
mess.n_##lc_member_name = N_ELEMENTS (static_array); \
|
|
mess.lc_member_name = cast static_array; \
|
|
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); \
|
|
TEST_VERSUS_STATIC_ARRAY (len, data, example_packed_data); \
|
|
assert(mess2->n_##lc_member_name == N_ELEMENTS (static_array)); \
|
|
for (i = 0; i < N_ELEMENTS (static_array); i++) \
|
|
assert(equals_macro(mess2->lc_member_name[i], static_array[i])); \
|
|
free (data); \
|
|
foo__test_mess_packed__free_unpacked (mess2, NULL); \
|
|
}while(0)
|
|
|
|
static void test_packed_repeated_int32 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_int32, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int32_arr0, test_packed_repeated_int32_arr0);
|
|
DO_TEST (int32_arr1, test_packed_repeated_int32_arr1);
|
|
DO_TEST (int32_arr_min_max, test_packed_repeated_int32_arr_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_sint32 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_sint32, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int32_arr0, test_packed_repeated_sint32_arr0);
|
|
DO_TEST (int32_arr1, test_packed_repeated_sint32_arr1);
|
|
DO_TEST (int32_arr_min_max, test_packed_repeated_sint32_arr_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_sfixed32 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_sfixed32, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int32_arr0, test_packed_repeated_sfixed32_arr0);
|
|
DO_TEST (int32_arr1, test_packed_repeated_sfixed32_arr1);
|
|
DO_TEST (int32_arr_min_max, test_packed_repeated_sfixed32_arr_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_uint32 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_uint32, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (uint32_roundnumbers, test_packed_repeated_uint32_roundnumbers);
|
|
DO_TEST (uint32_0_max, test_packed_repeated_uint32_0_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
|
|
|
|
static void test_packed_repeated_fixed32 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_fixed32, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (uint32_roundnumbers, test_packed_repeated_fixed32_roundnumbers);
|
|
DO_TEST (uint32_0_max, test_packed_repeated_fixed32_0_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_int64 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_int64, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int64_roundnumbers, test_packed_repeated_int64_roundnumbers);
|
|
DO_TEST (int64_min_max, test_packed_repeated_int64_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_sint64 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_sint64, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int64_roundnumbers, test_packed_repeated_sint64_roundnumbers);
|
|
DO_TEST (int64_min_max, test_packed_repeated_sint64_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_sfixed64 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_sfixed64, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST (int64_roundnumbers, test_packed_repeated_sfixed64_roundnumbers);
|
|
DO_TEST (int64_min_max, test_packed_repeated_sfixed64_min_max);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_uint64 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_uint64, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(uint64_roundnumbers, test_packed_repeated_uint64_roundnumbers);
|
|
DO_TEST(uint64_0_1_max, test_packed_repeated_uint64_0_1_max);
|
|
DO_TEST(uint64_random, test_packed_repeated_uint64_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_fixed64 (void)
|
|
{
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_fixed64, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(uint64_roundnumbers, test_packed_repeated_fixed64_roundnumbers);
|
|
DO_TEST(uint64_0_1_max, test_packed_repeated_fixed64_0_1_max);
|
|
DO_TEST(uint64_random, test_packed_repeated_fixed64_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_float (void)
|
|
{
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_float, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(float_random, test_packed_repeated_float_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_double (void)
|
|
{
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_double, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(double_random, test_packed_repeated_double_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_boolean (void)
|
|
{
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_boolean, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(boolean_0, test_packed_repeated_boolean_0);
|
|
DO_TEST(boolean_1, test_packed_repeated_boolean_1);
|
|
DO_TEST(boolean_random, test_packed_repeated_boolean_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_TestEnumSmall (void)
|
|
{
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_enum_small, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(enum_small_0, test_packed_repeated_enum_small_0);
|
|
DO_TEST(enum_small_1, test_packed_repeated_enum_small_1);
|
|
DO_TEST(enum_small_random, test_packed_repeated_enum_small_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
static void test_packed_repeated_TestEnum (void)
|
|
{
|
|
|
|
#define DO_TEST(static_array, example_packed_data) \
|
|
DO_TEST_PACKED_REPEATED(test_enum, , \
|
|
static_array, example_packed_data, \
|
|
NUMERIC_EQUALS)
|
|
|
|
DO_TEST(enum_0, test_packed_repeated_enum_0);
|
|
DO_TEST(enum_1, test_packed_repeated_enum_1);
|
|
DO_TEST(enum_random, test_packed_repeated_enum_random);
|
|
|
|
#undef DO_TEST
|
|
}
|
|
|
|
|
|
static void test_unknown_fields (void)
|
|
{
|
|
static Foo__EmptyMess mess = FOO__EMPTY_MESS__INIT;
|
|
static Foo__EmptyMess *mess2;
|
|
ProtobufCMessageUnknownField fields[2];
|
|
size_t len; uint8_t *data;
|
|
|
|
mess.base.n_unknown_fields = 2;
|
|
mess.base.unknown_fields = fields;
|
|
|
|
fields[0].tag = 5454;
|
|
fields[0].wire_type = PROTOBUF_C_WIRE_TYPE_VARINT;
|
|
fields[0].len = 2;
|
|
fields[0].data = (uint8_t*)"\377\1";
|
|
fields[1].tag = 5555;
|
|
fields[1].wire_type = PROTOBUF_C_WIRE_TYPE_32BIT;
|
|
fields[1].len = 4;
|
|
fields[1].data = (uint8_t*)"\4\1\0\0";
|
|
mess2 = test_compare_pack_methods (&mess.base, &len, &data);
|
|
assert (mess2->base.n_unknown_fields == 2);
|
|
assert (mess2->base.unknown_fields[0].tag == 5454);
|
|
assert (mess2->base.unknown_fields[0].wire_type == PROTOBUF_C_WIRE_TYPE_VARINT);
|
|
assert (mess2->base.unknown_fields[0].len == 2);
|
|
assert (memcmp (mess2->base.unknown_fields[0].data, fields[0].data, 2) == 0);
|
|
assert (mess2->base.unknown_fields[1].tag == 5555);
|
|
assert (mess2->base.unknown_fields[1].wire_type == PROTOBUF_C_WIRE_TYPE_32BIT);
|
|
assert (mess2->base.unknown_fields[1].len == 4);
|
|
assert (memcmp (mess2->base.unknown_fields[1].data, fields[1].data, 4) == 0);
|
|
TEST_VERSUS_STATIC_ARRAY (len, data, test_unknown_fields_0);
|
|
free (data);
|
|
foo__empty_mess__free_unpacked (mess2, NULL);
|
|
|
|
fields[0].tag = 6666;
|
|
fields[0].wire_type = PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
|
|
fields[0].len = 9;
|
|
fields[0].data = (uint8_t*)"\10xxxxxxxx";
|
|
fields[1].tag = 7777;
|
|
fields[1].wire_type = PROTOBUF_C_WIRE_TYPE_64BIT;
|
|
fields[1].len = 8;
|
|
fields[1].data = (uint8_t*)"\1\1\1\0\0\0\0\0";
|
|
mess2 = test_compare_pack_methods (&mess.base, &len, &data);
|
|
assert (mess2->base.n_unknown_fields == 2);
|
|
assert (mess2->base.unknown_fields[0].tag == 6666);
|
|
assert (mess2->base.unknown_fields[0].wire_type == PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED);
|
|
assert (mess2->base.unknown_fields[0].len == 9);
|
|
assert (memcmp (mess2->base.unknown_fields[0].data, fields[0].data, 9) == 0);
|
|
assert (mess2->base.unknown_fields[1].tag == 7777);
|
|
assert (mess2->base.unknown_fields[1].wire_type == PROTOBUF_C_WIRE_TYPE_64BIT);
|
|
assert (mess2->base.unknown_fields[1].len == 8);
|
|
assert (memcmp (mess2->base.unknown_fields[1].data, fields[1].data, 8) == 0);
|
|
TEST_VERSUS_STATIC_ARRAY (len, data, test_unknown_fields_1);
|
|
free (data);
|
|
foo__empty_mess__free_unpacked (mess2, NULL);
|
|
}
|
|
|
|
static void
|
|
test_enum_descriptor (const ProtobufCEnumDescriptor *desc)
|
|
{
|
|
unsigned i;
|
|
for (i = 0; i < desc->n_values; i++)
|
|
{
|
|
const ProtobufCEnumValue *sv = desc->values + i;
|
|
const ProtobufCEnumValue *vv;
|
|
const ProtobufCEnumValue *vn;
|
|
vv = protobuf_c_enum_descriptor_get_value (desc, sv->value);
|
|
vn = protobuf_c_enum_descriptor_get_value_by_name (desc, sv->name);
|
|
assert (sv == vv);
|
|
assert (sv == vn);
|
|
}
|
|
for (i = 0; i < desc->n_value_names; i++)
|
|
{
|
|
const char *name = desc->values_by_name[i].name;
|
|
const ProtobufCEnumValue *v;
|
|
v = protobuf_c_enum_descriptor_get_value_by_name (desc, name);
|
|
assert (v != NULL);
|
|
}
|
|
}
|
|
static void
|
|
test_enum_by_name (const ProtobufCEnumDescriptor *desc,
|
|
const char *name,
|
|
int expected_value)
|
|
{
|
|
const ProtobufCEnumValue *v;
|
|
v = protobuf_c_enum_descriptor_get_value_by_name (desc, name);
|
|
assert (v != NULL);
|
|
assert (v->value == expected_value);
|
|
}
|
|
|
|
static void
|
|
test_enum_lookups (void)
|
|
{
|
|
test_enum_descriptor (&foo__test_enum__descriptor);
|
|
test_enum_descriptor (&foo__test_enum_small__descriptor);
|
|
test_enum_descriptor (&foo__test_enum_dup_values__descriptor);
|
|
#define TEST_ENUM_DUP_VALUES(str, shortname) \
|
|
test_enum_by_name (&foo__test_enum_dup_values__descriptor, \
|
|
str, FOO__TEST_ENUM_DUP_VALUES__##shortname)
|
|
TEST_ENUM_DUP_VALUES ("VALUE_A", VALUE_A);
|
|
TEST_ENUM_DUP_VALUES ("VALUE_B", VALUE_B);
|
|
TEST_ENUM_DUP_VALUES ("VALUE_C", VALUE_C);
|
|
TEST_ENUM_DUP_VALUES ("VALUE_D", VALUE_D);
|
|
TEST_ENUM_DUP_VALUES ("VALUE_E", VALUE_E);
|
|
TEST_ENUM_DUP_VALUES ("VALUE_F", VALUE_F);
|
|
TEST_ENUM_DUP_VALUES ("VALUE_AA", VALUE_AA);
|
|
TEST_ENUM_DUP_VALUES ("VALUE_BB", VALUE_BB);
|
|
#undef TEST_ENUM_DUP_VALUES
|
|
}
|
|
|
|
static void
|
|
test_message_descriptor (const ProtobufCMessageDescriptor *desc)
|
|
{
|
|
unsigned i;
|
|
for (i = 0; i < desc->n_fields; i++)
|
|
{
|
|
const ProtobufCFieldDescriptor *f = desc->fields + i;
|
|
const ProtobufCFieldDescriptor *fv;
|
|
const ProtobufCFieldDescriptor *fn;
|
|
fv = protobuf_c_message_descriptor_get_field (desc, f->id);
|
|
fn = protobuf_c_message_descriptor_get_field_by_name (desc, f->name);
|
|
assert (f == fv);
|
|
assert (f == fn);
|
|
}
|
|
}
|
|
static void
|
|
test_message_lookups (void)
|
|
{
|
|
test_message_descriptor (&foo__test_mess__descriptor);
|
|
test_message_descriptor (&foo__test_mess_optional__descriptor);
|
|
test_message_descriptor (&foo__test_mess_required_enum__descriptor);
|
|
}
|
|
|
|
static void
|
|
assert_required_default_values_are_default (Foo__DefaultRequiredValues *mess)
|
|
{
|
|
assert (mess->v_int32 == -42);
|
|
assert (mess->v_uint32 == 666);
|
|
assert (mess->v_int64 == 100000);
|
|
assert (mess->v_uint64 == 100001);
|
|
assert (mess->v_float == 2.5);
|
|
assert (mess->v_double == 4.5);
|
|
assert (strcmp (mess->v_string, "hi mom\n") == 0);
|
|
assert (mess->v_bytes.len = /* a */ 1
|
|
+ /* space */ 1
|
|
+ /* NUL */ 1
|
|
+ /* space */ 1
|
|
+ /* "character" */ 9);
|
|
assert (memcmp (mess->v_bytes.data, "a \0 character", 13) == 0);
|
|
}
|
|
|
|
|
|
static void
|
|
test_required_default_values (void)
|
|
{
|
|
Foo__DefaultRequiredValues mess = FOO__DEFAULT_REQUIRED_VALUES__INIT;
|
|
Foo__DefaultRequiredValues *mess2;
|
|
size_t len; uint8_t *data;
|
|
assert_required_default_values_are_default (&mess);
|
|
mess2 = test_compare_pack_methods (&mess.base, &len, &data);
|
|
free (data);
|
|
assert_required_default_values_are_default (mess2);
|
|
foo__default_required_values__free_unpacked (mess2, NULL);
|
|
}
|
|
|
|
static void
|
|
assert_optional_default_values_are_default (Foo__DefaultOptionalValues *mess)
|
|
{
|
|
assert (!mess->has_v_int32);
|
|
assert (mess->v_int32 == -42);
|
|
assert (!mess->has_v_uint32);
|
|
assert (mess->v_uint32 == 666);
|
|
assert (!mess->has_v_int64);
|
|
assert (mess->v_int64 == 100000);
|
|
assert (!mess->has_v_uint64);
|
|
assert (mess->v_uint64 == 100001);
|
|
assert (!mess->has_v_float);
|
|
assert (mess->v_float == 2.5);
|
|
assert (!mess->has_v_double);
|
|
assert (mess->v_double == 4.5);
|
|
assert (strcmp (mess->v_string, "hi mom\n") == 0);
|
|
assert (!mess->has_v_bytes);
|
|
assert (mess->v_bytes.len = /* a */ 1
|
|
+ /* space */ 1
|
|
+ /* NUL */ 1
|
|
+ /* space */ 1
|
|
+ /* "character" */ 9);
|
|
assert (memcmp (mess->v_bytes.data, "a \0 character", 13) == 0);
|
|
}
|
|
|
|
static void
|
|
test_optional_default_values (void)
|
|
{
|
|
Foo__DefaultOptionalValues mess = FOO__DEFAULT_OPTIONAL_VALUES__INIT;
|
|
Foo__DefaultOptionalValues *mess2;
|
|
size_t len; uint8_t *data;
|
|
assert_optional_default_values_are_default (&mess);
|
|
mess2 = test_compare_pack_methods (&mess.base, &len, &data);
|
|
assert (len == 0); /* no non-default values */
|
|
free (data);
|
|
assert_optional_default_values_are_default (mess2);
|
|
foo__default_optional_values__free_unpacked (mess2, NULL);
|
|
}
|
|
|
|
static void
|
|
test_field_merge (void)
|
|
{
|
|
Foo__TestMessOptional msg1 = FOO__TEST_MESS_OPTIONAL__INIT;
|
|
Foo__SubMess sub1 = FOO__SUB_MESS__INIT;
|
|
Foo__SubMess__SubSubMess subsub1 = FOO__SUB_MESS__SUB_SUB_MESS__INIT;
|
|
|
|
msg1.has_test_int32 = 1;
|
|
msg1.test_int32 = 12345;
|
|
msg1.has_test_sint32 = 1;
|
|
msg1.test_sint32 = -12345;
|
|
msg1.has_test_int64 = 1;
|
|
msg1.test_int64 = 232;
|
|
msg1.test_string = "123";
|
|
msg1.test_message = &sub1;
|
|
sub1.has_val1 = 1;
|
|
sub1.val1 = 4;
|
|
sub1.has_val2 = 1;
|
|
sub1.val2 = 5;
|
|
int32_t arr1[] = {0, 1};
|
|
sub1.n_rep = 2;
|
|
sub1.rep = arr1;
|
|
sub1.sub1 = &subsub1;
|
|
sub1.sub2 = &subsub1;
|
|
subsub1.n_rep = 2;
|
|
subsub1.rep = arr1;
|
|
subsub1.str1 = "test";
|
|
|
|
size_t msg_size = foo__test_mess_optional__get_packed_size (&msg1);
|
|
|
|
Foo__TestMessOptional msg2 = FOO__TEST_MESS_OPTIONAL__INIT;
|
|
Foo__SubMess sub2 = FOO__SUB_MESS__INIT;
|
|
Foo__SubMess__SubSubMess subsub2 = FOO__SUB_MESS__SUB_SUB_MESS__INIT;
|
|
|
|
msg2.has_test_int64 = 1;
|
|
msg2.test_int64 = 2;
|
|
msg2.has_test_enum = 1;
|
|
msg2.test_enum = FOO__TEST_ENUM__VALUE128;
|
|
msg2.test_string = "456";
|
|
msg2.test_message = &sub2;
|
|
sub2.has_val2 = 1;
|
|
sub2.val2 = 666;
|
|
int32_t arr2[] = {2, 3};
|
|
sub2.n_rep = 2;
|
|
sub2.rep = arr2;
|
|
sub2.sub1 = &subsub2;
|
|
subsub2.has_val1 = 1;
|
|
subsub2.val1 = 1;
|
|
|
|
msg_size += foo__test_mess_optional__get_packed_size (&msg2);
|
|
|
|
uint8_t *packed_buffer = (uint8_t *)malloc (msg_size);
|
|
|
|
size_t packed_size = foo__test_mess_optional__pack (&msg1, packed_buffer);
|
|
packed_size += foo__test_mess_optional__pack (&msg2, packed_buffer + packed_size);
|
|
|
|
assert (packed_size == msg_size);
|
|
|
|
Foo__TestMessOptional *merged = foo__test_mess_optional__unpack
|
|
(NULL, msg_size, packed_buffer);
|
|
|
|
assert (merged->has_test_int32 && merged->test_int32 == msg1.test_int32);
|
|
assert (merged->has_test_sint32 && merged->test_sint32 == msg1.test_sint32);
|
|
assert (merged->has_test_int64 && merged->test_int64 == msg2.test_int64);
|
|
assert (merged->has_test_enum && merged->test_enum == msg2.test_enum);
|
|
assert (strcmp (merged->test_string, msg2.test_string) == 0);
|
|
assert (merged->test_message->has_val1 && merged->test_message->val1 == sub1.val1);
|
|
assert (merged->test_message->has_val2 && merged->test_message->val2 == sub2.val2);
|
|
/* Repeated fields should get concatenated */
|
|
int32_t merged_arr[] = {2, 3, 0, 1};
|
|
assert (merged->test_message->n_rep == 4 &&
|
|
memcmp(merged->test_message->rep, merged_arr, sizeof(merged_arr)) == 0);
|
|
|
|
assert (merged->test_message->sub1->val1 == subsub2.val1);
|
|
assert (memcmp(merged->test_message->sub1->bytes1.data,
|
|
subsub2.bytes1.data, subsub2.bytes1.len) == 0);
|
|
assert (strcmp(merged->test_message->sub1->str1, subsub1.str1) == 0);
|
|
assert (merged->test_message->sub1->n_rep == subsub1.n_rep &&
|
|
memcmp(merged->test_message->sub1->rep, arr1, sizeof(arr1)) == 0);
|
|
|
|
assert (!merged->test_message->sub2->has_val1
|
|
&& merged->test_message->sub2->val1 == subsub1.val1);
|
|
|
|
free (packed_buffer);
|
|
foo__test_mess_optional__free_unpacked (merged, NULL);
|
|
}
|
|
|
|
static struct alloc_data {
|
|
uint32_t alloc_count;
|
|
int32_t allocs_left;
|
|
} test_allocator_data;
|
|
|
|
static void *test_alloc(void *allocator_data, size_t size)
|
|
{
|
|
struct alloc_data *ad = allocator_data;
|
|
void *rv = NULL;
|
|
if (ad->allocs_left-- > 0)
|
|
rv = malloc (size);
|
|
/* fprintf (stderr, "alloc %d = %p\n", size, rv); */
|
|
if (rv)
|
|
ad->alloc_count++;
|
|
return rv;
|
|
}
|
|
|
|
static void test_free (void *allocator_data, void *data)
|
|
{
|
|
struct alloc_data *ad = allocator_data;
|
|
/* fprintf (stderr, "free %p\n", data); */
|
|
free (data);
|
|
if (data)
|
|
ad->alloc_count--;
|
|
}
|
|
|
|
static ProtobufCAllocator test_allocator = {
|
|
.alloc = test_alloc,
|
|
.free = test_free,
|
|
.allocator_data = &test_allocator_data,
|
|
};
|
|
|
|
#define SETUP_TEST_ALLOC_BUFFER(pbuf, len) \
|
|
uint8_t bytes[] = "some bytes", *pbuf; \
|
|
size_t len, _len2; \
|
|
Foo__DefaultRequiredValues _req = FOO__DEFAULT_REQUIRED_VALUES__INIT; \
|
|
Foo__AllocValues _mess = FOO__ALLOC_VALUES__INIT; \
|
|
_mess.a_string = "some string"; \
|
|
_mess.r_string = repeated_strings_2; \
|
|
_mess.n_r_string = sizeof(repeated_strings_2) / sizeof(*repeated_strings_2); \
|
|
_mess.a_bytes.len = sizeof(bytes); \
|
|
_mess.a_bytes.data = bytes; \
|
|
_mess.a_mess = &_req; \
|
|
len = foo__alloc_values__get_packed_size (&_mess); \
|
|
pbuf = malloc (len); \
|
|
assert (pbuf); \
|
|
_len2 = foo__alloc_values__pack (&_mess, pbuf); \
|
|
assert (len == _len2);
|
|
|
|
static void
|
|
test_alloc_graceful_cleanup (uint8_t *packed, size_t len, int good_allocs)
|
|
{
|
|
Foo__AllocValues *mess;
|
|
test_allocator_data.alloc_count = 0;
|
|
test_allocator_data.allocs_left = good_allocs;
|
|
mess = foo__alloc_values__unpack (&test_allocator, len, packed);
|
|
assert (test_allocator_data.allocs_left < 0 ? !mess : !!mess);
|
|
if (mess)
|
|
foo__alloc_values__free_unpacked (mess, &test_allocator);
|
|
assert (0 == test_allocator_data.alloc_count);
|
|
}
|
|
|
|
static void
|
|
test_alloc_free_all (void)
|
|
{
|
|
SETUP_TEST_ALLOC_BUFFER (packed, len);
|
|
test_alloc_graceful_cleanup (packed, len, INT32_MAX);
|
|
free (packed);
|
|
}
|
|
|
|
/* TODO: test alloc failure for slab, unknown fields */
|
|
static void
|
|
test_alloc_fail (void)
|
|
{
|
|
int i = 0;
|
|
SETUP_TEST_ALLOC_BUFFER (packed, len);
|
|
do test_alloc_graceful_cleanup (packed, len, i++);
|
|
while (test_allocator_data.allocs_left < 0);
|
|
free (packed);
|
|
}
|
|
|
|
/* === simple testing framework === */
|
|
|
|
typedef void (*TestFunc) (void);
|
|
|
|
typedef struct {
|
|
const char *name;
|
|
TestFunc func;
|
|
} Test;
|
|
|
|
static Test tests[] =
|
|
{
|
|
{ "small enums", test_enum_small },
|
|
{ "big enums", test_enum_big },
|
|
{ "test field numbers", test_field_numbers },
|
|
|
|
{ "test required int32", test_required_int32 },
|
|
{ "test required sint32", test_required_sint32 },
|
|
{ "test required sfixed32", test_required_sfixed32 },
|
|
{ "test required int64", test_required_int64 },
|
|
{ "test required sint64", test_required_sint64 },
|
|
{ "test required sfixed64", test_required_sfixed64 },
|
|
{ "test required uint32", test_required_uint32 },
|
|
{ "test required fixed32", test_required_fixed32 },
|
|
{ "test required uint64", test_required_uint64 },
|
|
{ "test required fixed64", test_required_fixed64 },
|
|
{ "test required float", test_required_float },
|
|
{ "test required double", test_required_double },
|
|
{ "test required bool", test_required_bool },
|
|
{ "test required TestEnumSmall", test_required_TestEnumSmall },
|
|
{ "test required TestEnum", test_required_TestEnum },
|
|
{ "test required string", test_required_string },
|
|
{ "test required bytes", test_required_bytes },
|
|
{ "test required SubMess", test_required_SubMess },
|
|
|
|
{ "test empty optional" ,test_empty_optional },
|
|
{ "test optional int32", test_optional_int32 },
|
|
{ "test optional sint32", test_optional_sint32 },
|
|
{ "test optional sfixed32", test_optional_sfixed32 },
|
|
{ "test optional int64", test_optional_int64 },
|
|
{ "test optional sint64", test_optional_sint64 },
|
|
{ "test optional sfixed64", test_optional_sfixed64 },
|
|
{ "test optional uint32", test_optional_uint32 },
|
|
{ "test optional fixed32", test_optional_fixed32 },
|
|
{ "test optional uint64", test_optional_uint64 },
|
|
{ "test optional fixed64", test_optional_fixed64 },
|
|
{ "test optional float", test_optional_float },
|
|
{ "test optional double", test_optional_double },
|
|
{ "test optional bool", test_optional_bool },
|
|
{ "test optional TestEnumSmall", test_optional_TestEnumSmall },
|
|
{ "test optional TestEnum", test_optional_TestEnum },
|
|
{ "test optional string", test_optional_string },
|
|
{ "test optional bytes", test_optional_bytes },
|
|
{ "test optional SubMess", test_optional_SubMess },
|
|
|
|
{ "test empty repeated" ,test_empty_repeated },
|
|
{ "test repeated int32" ,test_repeated_int32 },
|
|
{ "test repeated sint32" ,test_repeated_sint32 },
|
|
{ "test repeated sfixed32" ,test_repeated_sfixed32 },
|
|
{ "test repeated uint32", test_repeated_uint32 },
|
|
{ "test repeated int64", test_repeated_int64 },
|
|
{ "test repeated sint64", test_repeated_sint64 },
|
|
{ "test repeated sfixed64", test_repeated_sfixed64 },
|
|
{ "test repeated fixed32", test_repeated_fixed32 },
|
|
{ "test repeated uint64", test_repeated_uint64 },
|
|
{ "test repeated fixed64", test_repeated_fixed64 },
|
|
{ "test repeated float", test_repeated_float },
|
|
{ "test repeated double", test_repeated_double },
|
|
{ "test repeated boolean", test_repeated_boolean },
|
|
{ "test repeated TestEnumSmall", test_repeated_TestEnumSmall },
|
|
{ "test repeated TestEnum", test_repeated_TestEnum },
|
|
{ "test repeated string", test_repeated_string },
|
|
{ "test repeated bytes", test_repeated_bytes },
|
|
{ "test repeated SubMess", test_repeated_SubMess },
|
|
|
|
{ "test packed repeated int32", test_packed_repeated_int32 },
|
|
{ "test packed repeated sint32", test_packed_repeated_sint32 },
|
|
{ "test packed repeated sfixed32" ,test_packed_repeated_sfixed32 },
|
|
{ "test packed repeated uint32", test_packed_repeated_uint32 },
|
|
{ "test packed repeated int64", test_packed_repeated_int64 },
|
|
{ "test packed repeated sint64", test_packed_repeated_sint64 },
|
|
{ "test packed repeated sfixed64", test_packed_repeated_sfixed64 },
|
|
{ "test packed repeated fixed32", test_packed_repeated_fixed32 },
|
|
{ "test packed repeated uint64", test_packed_repeated_uint64 },
|
|
{ "test packed repeated fixed64", test_packed_repeated_fixed64 },
|
|
{ "test packed repeated float", test_packed_repeated_float },
|
|
{ "test packed repeated double", test_packed_repeated_double },
|
|
{ "test packed repeated boolean", test_packed_repeated_boolean },
|
|
{ "test packed repeated TestEnumSmall", test_packed_repeated_TestEnumSmall },
|
|
{ "test packed repeated TestEnum", test_packed_repeated_TestEnum },
|
|
|
|
{ "test unknown fields", test_unknown_fields },
|
|
|
|
{ "test enum lookups", test_enum_lookups },
|
|
{ "test message lookups", test_message_lookups },
|
|
|
|
{ "test required default values", test_required_default_values },
|
|
{ "test optional default values", test_optional_default_values },
|
|
|
|
{ "test field merge", test_field_merge },
|
|
|
|
{ "test free unpacked", test_alloc_free_all },
|
|
{ "test alloc failure", test_alloc_fail },
|
|
};
|
|
#define n_tests (sizeof(tests)/sizeof(Test))
|
|
|
|
int main ()
|
|
{
|
|
unsigned i;
|
|
for (i = 0; i < n_tests; i++)
|
|
{
|
|
fprintf (stderr, "Test: %s... ", tests[i].name);
|
|
tests[i].func ();
|
|
fprintf (stderr, " done.\n");
|
|
}
|
|
return 0;
|
|
}
|