diff --git a/pdl-compiler/scripts/generate_cxx_backend_tests.py b/pdl-compiler/scripts/generate_cxx_backend_tests.py index 5b497b5..324f851 100755 --- a/pdl-compiler/scripts/generate_cxx_backend_tests.py +++ b/pdl-compiler/scripts/generate_cxx_backend_tests.py @@ -147,6 +147,9 @@ def check_members(decl: ast.Declaration, var: str, expected: object) -> List[str generated_tests = [] for (test_nr, test) in enumerate(tests): + if 'packed' not in test: + continue + child_packet_id = test.get('packet', packet.id) child_packet = packet.file.packet_scope[child_packet_id] @@ -308,31 +311,50 @@ def output_bytes(output: str) -> List[str]: generated_tests = [] for (test_nr, test) in enumerate(tests): - if 'expected_error' in test: + if 'unpacked' not in test: continue child_packet_id = test.get('packet', packet.id) child_packet = packet.file.packet_scope[child_packet_id] (built_packet, intermediate_declarations) = build_packet(child_packet, 'packet', test['unpacked']) - generated_tests.append( - dedent("""\ - - TEST_F({serializer_test_suite}, {packet_id}_Case{test_nr}) {{ - std::vector expected_output {{ - {output_bytes} - }}; - {intermediate_declarations} - {child_packet_id}Builder packet = {built_packet}; - ASSERT_EQ(packet.SerializeToBytes(), expected_output); - }} - """).format(serializer_test_suite=serializer_test_suite, - packet_id=packet.id, - child_packet_id=child_packet_id, - test_nr=test_nr, - output_bytes=indent(output_bytes(test['packed']), 2), - built_packet=built_packet, - intermediate_declarations=indent(intermediate_declarations, 1))) + if 'expected_error' in test: + generated_tests.append( + dedent("""\ + + TEST_F({serializer_test_suite}, {packet_id}_Invalid_Case{test_nr}) {{ + {intermediate_declarations} + {child_packet_id}Builder packet = {built_packet}; + std::vector output; + ASSERT_FALSE(packet.Serialize(output)); + }} + """).format(serializer_test_suite=serializer_test_suite, + packet_id=packet.id, + child_packet_id=child_packet_id, + test_nr=test_nr, + built_packet=built_packet, + intermediate_declarations=indent(intermediate_declarations, 1))) + else: + generated_tests.append( + dedent("""\ + + TEST_F({serializer_test_suite}, {packet_id}_Case{test_nr}) {{ + std::vector expected_output {{ + {output_bytes} + }}; + {intermediate_declarations} + {child_packet_id}Builder packet = {built_packet}; + std::vector output; + ASSERT_TRUE(packet.Serialize(output)); + ASSERT_EQ(output, expected_output); + }} + """).format(serializer_test_suite=serializer_test_suite, + packet_id=packet.id, + child_packet_id=child_packet_id, + test_nr=test_nr, + output_bytes=indent(output_bytes(test['packed']), 2), + built_packet=built_packet, + intermediate_declarations=indent(intermediate_declarations, 1))) return ''.join(generated_tests) diff --git a/pdl-compiler/src/backends/common/test.rs b/pdl-compiler/src/backends/common/test.rs index 601331a..292acc9 100644 --- a/pdl-compiler/src/backends/common/test.rs +++ b/pdl-compiler/src/backends/common/test.rs @@ -10,7 +10,8 @@ pub struct Packet { #[derive(Debug, Deserialize)] pub struct TestVector { - pub packed: String, + #[serde(default)] + pub packed: Option, #[serde(default)] pub unpacked: Option, pub packet: Option, diff --git a/pdl-compiler/src/backends/java/test.rs b/pdl-compiler/src/backends/java/test.rs index 6b9c115..099183d 100644 --- a/pdl-compiler/src/backends/java/test.rs +++ b/pdl-compiler/src/backends/java/test.rs @@ -96,6 +96,10 @@ fn get_test_cases(file: &str, exclude_packets: &[String]) -> Result, if t.packet.as_ref().is_some_and(|p| exclude_packets.contains(p)) { return false; } + // Skip negative serialization test vectors. + if t.packed.is_none() { + return false; + } true }); } @@ -159,8 +163,10 @@ impl TestVector { ) -> impl FormatInto + 'a { let maybe_child = self.packet.as_ref().unwrap_or(id); + let packed = self.packed.as_deref().unwrap(); + quote_fn! { - $(java::block_comment(iter::once(format!("0x{}", &self.packed))))$['\n'] + $(java::block_comment(iter::once(format!("0x{}", packed))))$['\n'] static void testEncode$test_id() { $(Class::name_from_id(maybe_child)) packet = $(build_packet_from_fields( self.packet.as_ref().unwrap_or(id), @@ -168,7 +174,7 @@ impl TestVector { decls )); byte[] encodedPacket = packet.toBytes(); - byte[] expectedBytes = $(hex_to_array(&self.packed)); + byte[] expectedBytes = $(hex_to_array(packed)); assert $(&*import::ARRAYS).equals(expectedBytes, encodedPacket); } } @@ -192,11 +198,12 @@ impl TestVector { .map(|child_id| Class::name_from_id(child_id)) .unwrap_or(Class::name_from_id(id)) ); + let packed = self.packed.as_deref().unwrap(); quote_fn! { $(java::block_comment(iter::once(format!("{}", self.unpacked.as_ref().unwrap()))))$['\n'] static void testDecode$test_id() { - $(&packet_name) decodedPacket = $(&packet_name).fromBytes($(hex_to_array(&self.packed))); + $(&packet_name) decodedPacket = $(&packet_name).fromBytes($(hex_to_array(packed))); $(self.gen_asserts_for_fields(id, decls)) } } @@ -212,11 +219,12 @@ impl TestVector { .as_ref() .map(|child_id| Class::name_from_id(child_id)) .unwrap_or(Class::name_from_id(id)); + let packed = self.packed.as_deref().unwrap(); quote_fn! { static void testDecodeInvalid$test_id() { try { - $(&packet_name).fromBytes($(hex_to_array(&self.packed))); + $(&packet_name).fromBytes($(hex_to_array(packed))); throw new AssertionError("Expected exception"); } catch (Exception e) { // expected diff --git a/pdl-compiler/src/backends/rust/test.rs b/pdl-compiler/src/backends/rust/test.rs index 34c707d..cac3408 100644 --- a/pdl-compiler/src/backends/rust/test.rs +++ b/pdl-compiler/src/backends/rust/test.rs @@ -49,7 +49,7 @@ fn to_json(value: &T) -> syn::LitStr { /// /// Unit variants like `"TrailingBytesError"` become `DecodeError::TrailingBytesError`. /// Struct variants like `"LengthError"` become `DecodeError::LengthError { .. }`. -fn error_variant_pattern(variant: &str) -> proc_macro2::TokenStream { +fn decode_error_variant_pattern(variant: &str) -> proc_macro2::TokenStream { let variant_ident = format_ident!("{}", variant); match variant { "UnwrapError" | "TrailingBytesError" => { @@ -61,6 +61,12 @@ fn error_variant_pattern(variant: &str) -> proc_macro2::TokenStream { } } +/// Map an error variant name to a `matches!` pattern for `EncodeError`. +fn encode_error_variant_pattern(variant: &str) -> proc_macro2::TokenStream { + let variant_ident = format_ident!("{}", variant); + quote! { EncodeError::#variant_ident { .. } } +} + fn generate_unit_tests(input: &str, packet_names: &[&str]) -> Result { eprintln!("Reading test vectors from {input}, will use {} packets", packet_names.len()); @@ -78,84 +84,112 @@ fn generate_unit_tests(input: &str, packet_names: &[&str]) -> Result { + // Invalid parsing vector: assert that decode_full returns the expected error variant. + let packed = hexadecimal_to_vec(packed_hex); + let parse_test_name = format_ident!( + "test_parse_invalid_{}_vector_{}_0x{}", + test_packet, + i + 1, + packed_hex + ); + let pattern = decode_error_variant_pattern(expected_error); + tests.push(quote! { + #[test] + fn #parse_test_name() { + let packed = #packed; + let result = #packet_name::decode_full(&packed); + assert!( + matches!(result, Err(#pattern)), + "expected Err({}) but got {:?}", + stringify!(#pattern), + result, + ); + } + }); + } + (None, Some(unpacked), Some(expected_error)) => { + // Invalid serialization vector: assert that encode_to_vec returns the expected error variant. + let serialize_test_name = + format_ident!("test_serialize_invalid_{}_vector_{}", test_packet, i + 1,); + let object = unpacked.as_object().unwrap_or_else(|| { + panic!("Expected test vector object, found: {unpacked}") + }); + let json = to_json(&object); + let pattern = encode_error_variant_pattern(expected_error); + tests.push(quote! { + #[test] + fn #serialize_test_name() { + let packet: #packet_name = serde_json::from_str(#json) + .expect("Could not create packet from canonical JSON data"); + let result = packet.encode_to_vec(); + assert!( + matches!(result, Err(#pattern)), + "expected Err({}) but got {:?}", + stringify!(#pattern), + result, + ); + } + }); + } + (Some(packed_hex), Some(unpacked), None) => { + // Valid vector: existing logic. + let packed = hexadecimal_to_vec(packed_hex); + let parse_test_name = format_ident!( + "test_parse_{}_vector_{}_0x{}", + test_packet, + i + 1, + packed_hex + ); + let serialize_test_name = format_ident!( + "test_serialize_{}_vector_{}_0x{}", + test_packet, + i + 1, + packed_hex + ); - let object = unpacked - .as_object() - .unwrap_or_else(|| panic!("Expected test vector object, found: {unpacked}")); - let assertions = object.iter().map(|(key, value)| { - let getter = format_ident!("{key}"); - let expected = format_ident!("expected_{key}"); - let json = to_json(&value); - quote! { - let #expected: serde_json::Value = serde_json::from_str(#json) - .expect("Could not create expected value from canonical JSON data"); - assert_eq!(json!(actual.#getter()), #expected); - } - }); + let object = unpacked.as_object().unwrap_or_else(|| { + panic!("Expected test vector object, found: {unpacked}") + }); + let assertions = object.iter().map(|(key, value)| { + let getter = format_ident!("{key}"); + let expected = format_ident!("expected_{key}"); + let json = to_json(&value); + quote! { + let #expected: serde_json::Value = serde_json::from_str(#json) + .expect("Could not create expected value from canonical JSON data"); + assert_eq!(json!(actual.#getter()), #expected); + } + }); - let json = to_json(&object); - tests.push(quote! { - #[test] - fn #parse_test_name() { - let packed = #packed; - let actual = #packet_name::decode_full(&packed).unwrap(); - assert_eq!(actual.encoded_len(), packed.len()); - #(#assertions)* - } + let json = to_json(&object); + tests.push(quote! { + #[test] + fn #parse_test_name() { + let packed = #packed; + let actual = #packet_name::decode_full(&packed).unwrap(); + assert_eq!(actual.encoded_len(), packed.len()); + #(#assertions)* + } - #[test] - fn #serialize_test_name() { - let packet: #packet_name = serde_json::from_str(#json) - .expect("Could not create packet from canonical JSON data"); - let packed: Vec = #packed; - assert_eq!(packet.encoded_len(), packed.len()); - assert_eq!(packet.encode_to_vec(), Ok(packed)); - } - }); - } else { - panic!( - "Test vector for {test_packet} (index {i}) has neither \ - 'unpacked' nor 'expected_error'" - ); + #[test] + fn #serialize_test_name() { + let packet: #packet_name = serde_json::from_str(#json) + .expect("Could not create packet from canonical JSON data"); + let packed: Vec = #packed; + assert_eq!(packet.encoded_len(), packed.len()); + assert_eq!(packet.encode_to_vec(), Ok(packed)); + } + }); + } + _ => { + panic!( + "Unexpected test vector combination for {test_packet} (index {i}): {test_vector:?}" + ); + } } } } @@ -165,7 +199,7 @@ fn generate_unit_tests(input: &str, packet_names: &[&str]) -> Result Result { "Struct_Enum_Field", "Struct_FixedEnum_Field", "Struct_FixedScalar_Field", + "Struct_Reserved_Field", "Struct_Size_Field", "Struct_Struct_Field", "Enum_Incomplete_Truncated_Closed", diff --git a/pdl-compiler/tests/canonical/be_test_vectors.json b/pdl-compiler/tests/canonical/be_test_vectors.json index 1f9c6d2..9fe6f08 100644 --- a/pdl-compiler/tests/canonical/be_test_vectors.json +++ b/pdl-compiler/tests/canonical/be_test_vectors.json @@ -5106,6 +5106,426 @@ { "packed": "03010203", "expected_error": "ArraySizeError" + }, + { + "unpacked": { + "array": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Scalar_Field", + "tests": [ + { + "unpacked": { + "a": 128, + "c": 0 + }, + "expected_error": "InvalidScalarValue" + }, + { + "unpacked": { + "a": 0, + "c": 144115188075855872 + }, + "expected_error": "InvalidScalarValue" + } + ] + }, + { + "packet": "Packet_Reserved_Field", + "tests": [ + { + "unpacked": { + "a": 128, + "c": 0 + }, + "expected_error": "InvalidScalarValue" + }, + { + "unpacked": { + "a": 0, + "c": 36028797018963968 + }, + "expected_error": "InvalidScalarValue" + } + ] + }, + { + "packet": "Packet_Optional_Scalar_Field", + "tests": [ + { + "unpacked": { + "a": 16777216, + "b": null + }, + "expected_error": "InvalidScalarValue" + } + ] + }, + { + "packet": "Struct_Reserved_Field", + "tests": [ + { + "unpacked": { + "s": { + "a": 128, + "c": 0 + } + }, + "expected_error": "InvalidScalarValue" + }, + { + "unpacked": { + "s": { + "a": 0, + "c": 36028797018963968 + } + }, + "expected_error": "InvalidScalarValue" + } + ] + }, + { + "packet": "Struct_Optional_Scalar_Field", + "tests": [ + { + "unpacked": { + "s": { + "a": 16777216, + "b": null + } + }, + "expected_error": "InvalidScalarValue" + } + ] + }, + { + "packet": "Packet_Size_Field", + "tests": [ + { + "unpacked": { + "a": 0, + "b": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Payload_Field_VariableSize", + "tests": [ + { + "unpacked": { + "payload": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Payload_Field_SizeModifier", + "tests": [ + { + "unpacked": { + "payload": [0, 1, 2, 3, 4, 5] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Body_Field_VariableSize", + "tests": [ + { + "unpacked": { + "payload": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_ByteElement_VariableSize", + "tests": [ + { + "unpacked": { + "array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_SizedElement_VariableSize", + "tests": [ + { + "unpacked": { + "array": [ + {"a": 0}, + {"a": 1}, + {"a": 2}, + {"a": 3}, + {"a": 4}, + {"a": 5}, + {"a": 6}, + {"a": 7}, + {"a": 8}, + {"a": 9}, + {"a": 10}, + {"a": 11}, + {"a": 12}, + {"a": 13}, + {"a": 14}, + {"a": 15} + ] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_UnsizedElement_VariableSize", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [1, 2, 3, 4]} + ] + }, + "expected_error": "SizeOverflow" + }, + { + "unpacked": { + "array": [ + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]} + ] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_SizedElement_VariableSize_Padded", + "tests": [ + { + "unpacked": { + "array": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_UnsizedElement_VariableCount_Padded", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]} + ] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_VariableElementSize_ConstantSize", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]}, + {"array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]}, + {"array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]}, + {"array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]} + ] + }, + "expected_error": "SizeOverflow" + }, + { + "unpacked": { + "array": [ + {"array": [1]}, + {"array": [1, 2]}, + {"array": [1]}, + {"array": [1]} + ] + }, + "expected_error": "InvalidArrayElementSize" + } + ] + }, + { + "packet": "Packet_Array_Field_VariableElementSize_VariableSize", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [1]}, + {"array": [1, 2]} + ], + "tail": [] + }, + "expected_error": "InvalidArrayElementSize" + } + ] + }, + { + "packet": "Packet_Array_Field_VariableElementSize_VariableCount", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [1]}, + {"array": [1, 2]} + ], + "tail": [] + }, + "expected_error": "InvalidArrayElementSize" + } + ] + }, + { + "packet": "Packet_Array_Field_VariableElementSize_UnknownSize", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [1]}, + {"array": [1, 2]} + ] + }, + "expected_error": "InvalidArrayElementSize" + } + ] + }, + { + "packet": "Struct_Size_Field", + "tests": [ + { + "unpacked": { + "s": { + "a": 0, + "b": [0, 1, 2, 3, 4, 5, 6, 7] + } + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Struct_Array_Field_ByteElement_VariableSize", + "tests": [ + { + "unpacked": { + "s": { + "array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + } + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Struct_Array_Field_SizedElement_VariableSize_Padded", + "tests": [ + { + "unpacked": { + "s": { + "array": [0, 1, 2, 3, 4, 5, 6, 7] + } + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Struct_Array_Field_UnsizedElement_VariableCount_Padded", + "tests": [ + { + "unpacked": { + "s": { + "array": [ + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]} + ] + } + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Count_Field", + "tests": [ + { + "unpacked": { + "a": 0, + "b": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "CountOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_ByteElement_VariableCount", + "tests": [ + { + "unpacked": { + "array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + }, + "expected_error": "CountOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_ScalarElement_VariableCount", + "tests": [ + { + "unpacked": { + "array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + }, + "expected_error": "CountOverflow" + } + ] + }, + { + "packet": "Struct_Count_Field", + "tests": [ + { + "unpacked": { + "s": { + "a": 0, + "b": [0, 1, 2, 3, 4, 5, 6, 7] + } + }, + "expected_error": "CountOverflow" + } + ] + }, + { + "packet": "Struct_Array_Field_ByteElement_VariableCount", + "tests": [ + { + "unpacked": { + "s": { + "array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + } + }, + "expected_error": "CountOverflow" } ] } diff --git a/pdl-compiler/tests/canonical/le_test_vectors.json b/pdl-compiler/tests/canonical/le_test_vectors.json index c1e1c18..5e7a005 100644 --- a/pdl-compiler/tests/canonical/le_test_vectors.json +++ b/pdl-compiler/tests/canonical/le_test_vectors.json @@ -5466,5 +5466,430 @@ } } ] + }, + { + "packet": "Packet_Scalar_Field", + "tests": [ + { + "unpacked": { + "a": 128, + "c": 0 + }, + "expected_error": "InvalidScalarValue" + }, + { + "unpacked": { + "a": 0, + "c": 144115188075855872 + }, + "expected_error": "InvalidScalarValue" + } + ] + }, + { + "packet": "Packet_Reserved_Field", + "tests": [ + { + "unpacked": { + "a": 128, + "c": 0 + }, + "expected_error": "InvalidScalarValue" + }, + { + "unpacked": { + "a": 0, + "c": 36028797018963968 + }, + "expected_error": "InvalidScalarValue" + } + ] + }, + { + "packet": "Packet_Optional_Scalar_Field", + "tests": [ + { + "unpacked": { + "a": 16777216, + "b": null + }, + "expected_error": "InvalidScalarValue" + } + ] + }, + { + "packet": "Struct_Reserved_Field", + "tests": [ + { + "unpacked": { + "s": { + "a": 128, + "c": 0 + } + }, + "expected_error": "InvalidScalarValue" + }, + { + "unpacked": { + "s": { + "a": 0, + "c": 36028797018963968 + } + }, + "expected_error": "InvalidScalarValue" + } + ] + }, + { + "packet": "Struct_Optional_Scalar_Field", + "tests": [ + { + "unpacked": { + "s": { + "a": 16777216, + "b": null + } + }, + "expected_error": "InvalidScalarValue" + } + ] + }, + { + "packet": "Packet_Size_Field", + "tests": [ + { + "unpacked": { + "a": 0, + "b": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Payload_Field_VariableSize", + "tests": [ + { + "unpacked": { + "payload": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Payload_Field_SizeModifier", + "tests": [ + { + "unpacked": { + "payload": [0, 1, 2, 3, 4, 5] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Body_Field_VariableSize", + "tests": [ + { + "unpacked": { + "payload": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_ByteElement_VariableSize", + "tests": [ + { + "unpacked": { + "array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_ScalarElement_VariableSize", + "tests": [ + { + "unpacked": { + "array": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_SizedElement_VariableSize", + "tests": [ + { + "unpacked": { + "array": [ + {"a": 0}, + {"a": 1}, + {"a": 2}, + {"a": 3}, + {"a": 4}, + {"a": 5}, + {"a": 6}, + {"a": 7}, + {"a": 8}, + {"a": 9}, + {"a": 10}, + {"a": 11}, + {"a": 12}, + {"a": 13}, + {"a": 14}, + {"a": 15} + ] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_UnsizedElement_VariableSize", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [1, 2, 3, 4]} + ] + }, + "expected_error": "SizeOverflow" + }, + { + "unpacked": { + "array": [ + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]} + ] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_SizedElement_VariableSize_Padded", + "tests": [ + { + "unpacked": { + "array": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_UnsizedElement_VariableCount_Padded", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]} + ] + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_VariableElementSize_ConstantSize", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]}, + {"array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]}, + {"array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]}, + {"array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]} + ] + }, + "expected_error": "SizeOverflow" + }, + { + "unpacked": { + "array": [ + {"array": [1]}, + {"array": [1, 2]}, + {"array": [1]}, + {"array": [1]} + ] + }, + "expected_error": "InvalidArrayElementSize" + } + ] + }, + { + "packet": "Packet_Array_Field_VariableElementSize_VariableSize", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [1]}, + {"array": [1, 2]} + ], + "tail": [] + }, + "expected_error": "InvalidArrayElementSize" + } + ] + }, + { + "packet": "Packet_Array_Field_VariableElementSize_VariableCount", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [1]}, + {"array": [1, 2]} + ], + "tail": [] + }, + "expected_error": "InvalidArrayElementSize" + } + ] + }, + { + "packet": "Packet_Array_Field_VariableElementSize_UnknownSize", + "tests": [ + { + "unpacked": { + "array": [ + {"array": [1]}, + {"array": [1, 2]} + ] + }, + "expected_error": "InvalidArrayElementSize" + } + ] + }, + { + "packet": "Struct_Size_Field", + "tests": [ + { + "unpacked": { + "s": { + "a": 0, + "b": [0, 1, 2, 3, 4, 5, 6, 7] + } + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Struct_Array_Field_ByteElement_VariableSize", + "tests": [ + { + "unpacked": { + "s": { + "array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + } + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Struct_Array_Field_SizedElement_VariableSize_Padded", + "tests": [ + { + "unpacked": { + "s": { + "array": [0, 1, 2, 3, 4, 5, 6, 7] + } + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Struct_Array_Field_UnsizedElement_VariableCount_Padded", + "tests": [ + { + "unpacked": { + "s": { + "array": [ + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]}, + {"array": [1, 2, 3]} + ] + } + }, + "expected_error": "SizeOverflow" + } + ] + }, + { + "packet": "Packet_Count_Field", + "tests": [ + { + "unpacked": { + "a": 0, + "b": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "expected_error": "CountOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_ByteElement_VariableCount", + "tests": [ + { + "unpacked": { + "array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + }, + "expected_error": "CountOverflow" + } + ] + }, + { + "packet": "Packet_Array_Field_ScalarElement_VariableCount", + "tests": [ + { + "unpacked": { + "array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + }, + "expected_error": "CountOverflow" + } + ] + }, + { + "packet": "Struct_Count_Field", + "tests": [ + { + "unpacked": { + "s": { + "a": 0, + "b": [0, 1, 2, 3, 4, 5, 6, 7] + } + }, + "expected_error": "CountOverflow" + } + ] + }, + { + "packet": "Struct_Array_Field_ByteElement_VariableCount", + "tests": [ + { + "unpacked": { + "s": { + "array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + } + }, + "expected_error": "CountOverflow" + } + ] } ] diff --git a/pdl-compiler/tests/python_generator_test.py b/pdl-compiler/tests/python_generator_test.py index 0ac7264..d3fa395 100644 --- a/pdl-compiler/tests/python_generator_test.py +++ b/pdl-compiler/tests/python_generator_test.py @@ -108,6 +108,8 @@ def testLittleEndian(self): # method for this test. cls = getattr(le_backend, packet) for test in tests: + if 'packed' not in test: + continue if 'expected_error' in test: exception_cls = getattr(le_backend, test['expected_error']) with self.assertRaises(exception_cls): @@ -136,6 +138,8 @@ def testBigEndian(self): # method for this test. cls = getattr(be_backend, packet) for test in tests: + if 'packed' not in test: + continue if 'expected_error' in test: with self.assertRaises((Exception, ValueError)): cls.parse_all(bytes.fromhex(test['packed']))