From 7dcae81096e7543890d92978f2263664bd0e9ade Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot <protobuf-github-bot@google.com> Date: Thu, 6 Jun 2024 15:40:11 -0700 Subject: [PATCH] Add serialization test and parameterize tests to verify behavior in multiple versions of the protocol buffer language. New serialization test will verify the amount of bytes it takes to serialize a message with a field of type INT32 set to different values. PiperOrigin-RevId: 641044189 --- rust/test/BUILD | 16 +++ rust/test/shared/BUILD | 12 ++ rust/test/shared/serialization_test.rs | 182 ++++++++++++++++--------- 3 files changed, 144 insertions(+), 66 deletions(-) diff --git a/rust/test/BUILD b/rust/test/BUILD index f7d0d0aa21..aa673aa048 100644 --- a/rust/test/BUILD +++ b/rust/test/BUILD @@ -10,6 +10,8 @@ UNITTEST_PROTO3_TARGET = "//src/google/protobuf:test_protos" UNITTEST_PROTO3_OPTIONAL_TARGET = "//src/google/protobuf:test_protos" +UNITTEST_EDITION_TARGET = "//src/google/protobuf:test_protos" + rust_upb_proto_library( name = "unittest_upb_rust_proto", testonly = True, @@ -55,6 +57,20 @@ rust_upb_proto_library( deps = [UNITTEST_PROTO3_OPTIONAL_TARGET], ) +rust_cc_proto_library( + name = "unittest_edition_cpp_rust_proto", + testonly = True, + visibility = ["//rust/test/shared:__subpackages__"], + deps = [UNITTEST_EDITION_TARGET], +) + +rust_upb_proto_library( + name = "unittest_edition_upb_rust_proto", + testonly = True, + visibility = ["//rust/test/shared:__subpackages__"], + deps = [UNITTEST_EDITION_TARGET], +) + proto_library( name = "parent_proto", srcs = ["parent.proto"], diff --git a/rust/test/shared/BUILD b/rust/test/shared/BUILD index bdc441caaf..96f589be6f 100644 --- a/rust/test/shared/BUILD +++ b/rust/test/shared/BUILD @@ -227,7 +227,13 @@ rust_test( rust_test( name = "serialization_upb_test", srcs = ["serialization_test.rs"], + proc_macro_deps = [ + "@crate_index//:paste", + ], deps = [ + "//rust/test:unittest_edition_upb_rust_proto", + "//rust/test:unittest_proto3_optional_upb_rust_proto", + "//rust/test:unittest_proto3_upb_rust_proto", "//rust/test:unittest_upb_rust_proto", "@crate_index//:googletest", ], @@ -236,8 +242,14 @@ rust_test( rust_test( name = "serialization_cpp_test", srcs = ["serialization_test.rs"], + proc_macro_deps = [ + "@crate_index//:paste", + ], deps = [ "//rust/test:unittest_cpp_rust_proto", + "//rust/test:unittest_edition_upb_rust_proto", + "//rust/test:unittest_proto3_cpp_rust_proto", + "//rust/test:unittest_proto3_optional_cpp_rust_proto", "@crate_index//:googletest", ], ) diff --git a/rust/test/shared/serialization_test.rs b/rust/test/shared/serialization_test.rs index 4acd57ea57..ab9dd21ca1 100644 --- a/rust/test/shared/serialization_test.rs +++ b/rust/test/shared/serialization_test.rs @@ -6,69 +6,119 @@ // https://developers.google.com/open-source/licenses/bsd use googletest::prelude::*; -use unittest_rust_proto::TestAllTypes; - -#[test] -fn serialize_zero_length() { - let mut msg = TestAllTypes::new(); - - let serialized = msg.serialize().unwrap(); - assert_that!(serialized.len(), eq(0)); - - let serialized = msg.as_view().serialize().unwrap(); - assert_that!(serialized.len(), eq(0)); - - let serialized = msg.as_mut().serialize().unwrap(); - assert_that!(serialized.len(), eq(0)); -} - -#[test] -fn serialize_deserialize_message() { - let mut msg = TestAllTypes::new(); - msg.set_optional_int64(42); - msg.set_optional_bool(true); - msg.set_optional_bytes(b"serialize deserialize test"); - - let serialized = msg.serialize().unwrap(); - - let msg2 = TestAllTypes::parse(&serialized).unwrap(); - assert_that!(msg.optional_int64(), eq(msg2.optional_int64())); - assert_that!(msg.optional_bool(), eq(msg2.optional_bool())); - assert_that!(msg.optional_bytes(), eq(msg2.optional_bytes())); -} - -#[test] -fn deserialize_empty() { - assert!(TestAllTypes::parse(&[]).is_ok()); -} - -#[test] -fn deserialize_error() { - assert!(TestAllTypes::parse(b"not a serialized proto").is_err()); -} - -#[test] -fn set_bytes_with_serialized_data() { - let mut msg = TestAllTypes::new(); - msg.set_optional_int64(42); - msg.set_optional_bool(true); - let mut msg2 = TestAllTypes::new(); - msg2.set_optional_bytes(msg.serialize().unwrap()); - assert_that!(msg2.optional_bytes(), eq(msg.serialize().unwrap().as_ref())); -} - -#[test] -fn deserialize_on_previously_allocated_message() { - let mut msg = TestAllTypes::new(); - msg.set_optional_int64(42); - msg.set_optional_bool(true); - msg.set_optional_bytes(b"serialize deserialize test"); - - let serialized = msg.serialize().unwrap(); - - let mut msg2 = Box::new(TestAllTypes::new()); - assert!(msg2.clear_and_parse(&serialized).is_ok()); - assert_that!(msg.optional_int64(), eq(msg2.optional_int64())); - assert_that!(msg.optional_bool(), eq(msg2.optional_bool())); - assert_that!(msg.optional_bytes(), eq(msg2.optional_bytes())); -} +use paste::paste; +use unittest_edition_rust_proto::TestAllTypes as TestAllTypesEditions; +use unittest_proto3_optional_rust_proto::TestProto3Optional; +use unittest_proto3_rust_proto::TestAllTypes as TestAllTypesProto3; +use unittest_rust_proto::TestAllTypes as TestAllTypesProto2; + +macro_rules! generate_parameterized_serialization_test { + ($(($type: ident, $name_ext: ident)),*) => { + paste! { $( + #[test] + fn [< serialization_zero_length_ $name_ext >]() { + let mut msg = [< $type >]::new(); + + let serialized = msg.serialize().unwrap(); + assert_that!(serialized.len(), eq(0)); + + let serialized = msg.as_view().serialize().unwrap(); + assert_that!(serialized.len(), eq(0)); + + let serialized = msg.as_mut().serialize().unwrap(); + assert_that!(serialized.len(), eq(0)); + } + + #[test] + fn [< serialize_deserialize_message_ $name_ext>]() { + let mut msg = [< $type >]::new(); + msg.set_optional_int64(42); + msg.set_optional_bool(true); + msg.set_optional_bytes(b"serialize deserialize test"); + + let serialized = msg.serialize().unwrap(); + + let msg2 = [< $type >]::parse(&serialized).unwrap(); + assert_that!(msg.optional_int64(), eq(msg2.optional_int64())); + assert_that!(msg.optional_bool(), eq(msg2.optional_bool())); + assert_that!(msg.optional_bytes(), eq(msg2.optional_bytes())); + } + + #[test] + fn [< deserialize_empty_ $name_ext>]() { + assert!([< $type >]::parse(&[]).is_ok()); + } + + #[test] + fn [< deserialize_error_ $name_ext>]() { + assert!([< $type >]::parse(b"not a serialized proto").is_err()); + } + + #[test] + fn [< set_bytes_with_serialized_data_ $name_ext>]() { + let mut msg = [< $type >]::new(); + msg.set_optional_int64(42); + msg.set_optional_bool(true); + let mut msg2 = [< $type >]::new(); + msg2.set_optional_bytes(msg.serialize().unwrap()); + assert_that!(msg2.optional_bytes(), eq(msg.serialize().unwrap().as_ref())); + } + + #[test] + fn [< deserialize_on_previously_allocated_message_ $name_ext>]() { + let mut msg = [< $type >]::new(); + msg.set_optional_int64(42); + msg.set_optional_bool(true); + msg.set_optional_bytes(b"serialize deserialize test"); + + let serialized = msg.serialize().unwrap(); + + let mut msg2 = Box::new([< $type >]::new()); + assert!(msg2.clear_and_parse(&serialized).is_ok()); + assert_that!(msg.optional_int64(), eq(msg2.optional_int64())); + assert_that!(msg.optional_bool(), eq(msg2.optional_bool())); + assert_that!(msg.optional_bytes(), eq(msg2.optional_bytes())); + } + + )* } + }; + } + +generate_parameterized_serialization_test!( + (TestAllTypesProto2, proto2), + (TestAllTypesProto3, proto3), + (TestAllTypesEditions, editions), + (TestProto3Optional, proto3_optional) +); + +macro_rules! generate_parameterized_int32_byte_size_test { + ($(($type: ident, $name_ext: ident)),*) => { + paste! { $( + + #[test] + fn [< test_int32_byte_size_ $name_ext>]() { + let args = vec![(0, 1), (127, 1), (128, 2), (-1, 10)]; + for arg in args { + let value = arg.0; + let expected_value_size = arg.1; + let mut msg = [< $type >]::new(); + // tag for optional_int32 only takes 1 byte + msg.set_optional_int32(value); + let serialized = msg.serialize().unwrap(); + // 1 byte for tag and n from expected_value_size + assert_that!(serialized.len(), eq(expected_value_size + 1), "Test failed. Value: {value}. Expected_value_size: {expected_value_size}."); + } + + } + )* } + }; + } + +generate_parameterized_int32_byte_size_test!( + (TestAllTypesProto2, proto2), + (TestProto3Optional, proto3_optional), /* Test would fail if we were to use + * TestAllTypesProto3: optional_int32 follows "no + * presence" semantics and setting it to 0 (default + * value) will cause it to not be serialized */ + (TestAllTypesEditions, editions) +);