diff --git a/lang/rust/Cargo.lock b/lang/rust/Cargo.lock index 1acf9bcd8dd..7097a7ec324 100644 --- a/lang/rust/Cargo.lock +++ b/lang/rust/Cargo.lock @@ -98,6 +98,7 @@ dependencies = [ name = "apache-avro-test-helper" version = "0.15.0" dependencies = [ + "anyhow", "color-backtrace", "ctor 0.2.0", "env_logger", diff --git a/lang/rust/avro/examples/benchmark.rs b/lang/rust/avro/examples/benchmark.rs index 4cf0f1365f7..c3eac431393 100644 --- a/lang/rust/avro/examples/benchmark.rs +++ b/lang/rust/avro/examples/benchmark.rs @@ -20,6 +20,7 @@ use apache_avro::{ types::{Record, Value}, Reader, Writer, }; +use apache_avro_test_helper::TestResult; use std::{ io::{BufReader, BufWriter}, time::{Duration, Instant}, @@ -45,7 +46,7 @@ fn benchmark( big_or_small: &str, count: usize, runs: usize, -) -> anyhow::Result<()> { +) -> TestResult { let mut records = Vec::new(); for __ in 0..count { records.push(record.clone()); @@ -100,7 +101,7 @@ fn benchmark( Ok(()) } -fn main() -> anyhow::Result<()> { +fn main() -> TestResult { let raw_small_schema = r#" {"namespace": "test", "type": "record", "name": "Test", "fields": [{"type": {"type": "string"}, "name": "field"}]} "#; diff --git a/lang/rust/avro/examples/generate_interop_data.rs b/lang/rust/avro/examples/generate_interop_data.rs index 72b4d10b220..35a6dc7c090 100644 --- a/lang/rust/avro/examples/generate_interop_data.rs +++ b/lang/rust/avro/examples/generate_interop_data.rs @@ -20,6 +20,7 @@ use apache_avro::{ types::{Record, Value}, Codec, Writer, }; +use apache_avro_test_helper::TestResult; use std::{ collections::HashMap, io::{BufWriter, Write}, @@ -74,7 +75,7 @@ fn create_datum(schema: &Schema) -> Record { datum } -fn main() -> anyhow::Result<()> { +fn main() -> TestResult { let schema_str = std::fs::read_to_string("../../share/test/schemas/interop.avsc") .expect("Unable to read the interop Avro schema"); let schema = Schema::parse_str(schema_str.as_str())?; @@ -104,7 +105,7 @@ fn main() -> anyhow::Result<()> { Ok(()) } -fn write_user_metadata(writer: &mut Writer>) -> anyhow::Result<()> { +fn write_user_metadata(writer: &mut Writer>) -> TestResult { writer.add_user_metadata("user_metadata".to_string(), b"someByteArray")?; Ok(()) diff --git a/lang/rust/avro/examples/test_interop_data.rs b/lang/rust/avro/examples/test_interop_data.rs index 611c0e19238..736b1fd7d03 100644 --- a/lang/rust/avro/examples/test_interop_data.rs +++ b/lang/rust/avro/examples/test_interop_data.rs @@ -16,13 +16,14 @@ // under the License. use apache_avro::Reader; +use apache_avro_test_helper::TestResult; use std::{ collections::HashMap, ffi::OsStr, io::{BufReader, Read}, }; -fn main() -> anyhow::Result<()> { +fn main() -> TestResult { let mut expected_user_metadata: HashMap> = HashMap::new(); expected_user_metadata.insert("user_metadata".to_string(), b"someByteArray".to_vec()); diff --git a/lang/rust/avro/src/codec.rs b/lang/rust/avro/src/codec.rs index 0866ff62d53..c34da0bfcb2 100644 --- a/lang/rust/avro/src/codec.rs +++ b/lang/rust/avro/src/codec.rs @@ -186,55 +186,58 @@ impl Codec { mod tests { use super::*; use pretty_assertions::{assert_eq, assert_ne}; + use apache_avro_test_helper::TestResult; const INPUT: &[u8] = b"theanswertolifetheuniverseandeverythingis42theanswertolifetheuniverseandeverythingis4theanswertolifetheuniverseandeverythingis2"; #[test] - fn null_compress_and_decompress() { + fn null_compress_and_decompress() -> TestResult { let codec = Codec::Null; let mut stream = INPUT.to_vec(); - codec.compress(&mut stream).unwrap(); + codec.compress(&mut stream)?; assert_eq!(INPUT, stream.as_slice()); - codec.decompress(&mut stream).unwrap(); + codec.decompress(&mut stream)?; assert_eq!(INPUT, stream.as_slice()); + Ok(()) } #[test] - fn deflate_compress_and_decompress() { - compress_and_decompress(Codec::Deflate); + fn deflate_compress_and_decompress()-> TestResult { + compress_and_decompress(Codec::Deflate) } #[cfg(feature = "snappy")] #[test] - fn snappy_compress_and_decompress() { - compress_and_decompress(Codec::Snappy); + fn snappy_compress_and_decompress()-> TestResult { + compress_and_decompress(Codec::Snappy) } #[cfg(feature = "zstandard")] #[test] - fn zstd_compress_and_decompress() { - compress_and_decompress(Codec::Zstandard); + fn zstd_compress_and_decompress()-> TestResult { + compress_and_decompress(Codec::Zstandard) } #[cfg(feature = "bzip")] #[test] - fn bzip_compress_and_decompress() { - compress_and_decompress(Codec::Bzip2); + fn bzip_compress_and_decompress()-> TestResult { + compress_and_decompress(Codec::Bzip2) } #[cfg(feature = "xz")] #[test] - fn xz_compress_and_decompress() { - compress_and_decompress(Codec::Xz); + fn xz_compress_and_decompress()-> TestResult { + compress_and_decompress(Codec::Xz) } - fn compress_and_decompress(codec: Codec) { + fn compress_and_decompress(codec: Codec) -> TestResult { let mut stream = INPUT.to_vec(); - codec.compress(&mut stream).unwrap(); + codec.compress(&mut stream)?; assert_ne!(INPUT, stream.as_slice()); assert!(INPUT.len() > stream.len()); - codec.decompress(&mut stream).unwrap(); + codec.decompress(&mut stream)?; assert_eq!(INPUT, stream.as_slice()); + Ok(()) } #[test] diff --git a/lang/rust/avro/src/de.rs b/lang/rust/avro/src/de.rs index a1b52e6c53e..a2e7a0e52bd 100644 --- a/lang/rust/avro/src/de.rs +++ b/lang/rust/avro/src/de.rs @@ -654,6 +654,8 @@ mod tests { use std::sync::atomic::Ordering; use uuid::Uuid; + use apache_avro_test_helper::TestResult; + use super::*; #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] @@ -749,7 +751,7 @@ mod tests { } #[test] - fn test_from_value() { + fn test_from_value() -> TestResult { let test = Value::Record(vec![ ("a".to_owned(), Value::Long(27)), ("b".to_owned(), Value::String("foo".to_owned())), @@ -758,7 +760,7 @@ mod tests { a: 27, b: "foo".to_owned(), }; - let final_value: Test = from_value(&test).unwrap(); + let final_value: Test = from_value(&test)?; assert_eq!(final_value, expected); let test_inner = Value::Record(vec![ @@ -773,18 +775,20 @@ mod tests { ]); let expected_inner = TestInner { a: expected, b: 35 }; - let final_value: TestInner = from_value(&test_inner).unwrap(); - assert_eq!(final_value, expected_inner) + let final_value: TestInner = from_value(&test_inner)?; + assert_eq!(final_value, expected_inner); + + Ok(()) } #[test] - fn test_from_value_unit_enum() { + fn test_from_value_unit_enum() -> TestResult { let expected = TestUnitExternalEnum { a: UnitExternalEnum::Val1, }; let test = Value::Record(vec![("a".to_owned(), Value::Enum(0, "Val1".to_owned()))]); - let final_value: TestUnitExternalEnum = from_value(&test).unwrap(); + let final_value: TestUnitExternalEnum = from_value(&test)?; assert_eq!( final_value, expected, "Error deserializing unit external enum" @@ -798,7 +802,7 @@ mod tests { "a".to_owned(), Value::Record(vec![("t".to_owned(), Value::String("Val1".to_owned()))]), )]); - let final_value: TestUnitInternalEnum = from_value(&test).unwrap(); + let final_value: TestUnitInternalEnum = from_value(&test)?; assert_eq!( final_value, expected, "Error deserializing unit internal enum" @@ -811,7 +815,7 @@ mod tests { "a".to_owned(), Value::Record(vec![("t".to_owned(), Value::String("Val1".to_owned()))]), )]); - let final_value: TestUnitAdjacentEnum = from_value(&test).unwrap(); + let final_value: TestUnitAdjacentEnum = from_value(&test)?; assert_eq!( final_value, expected, "Error deserializing unit adjacent enum" @@ -821,15 +825,16 @@ mod tests { }; let test = Value::Record(vec![("a".to_owned(), Value::Null)]); - let final_value: TestUnitUntaggedEnum = from_value(&test).unwrap(); + let final_value: TestUnitUntaggedEnum = from_value(&test)?; assert_eq!( final_value, expected, "Error deserializing unit untagged enum" ); + Ok(()) } #[test] - fn avro_3645_3646_test_from_value_enum() { + fn avro_3645_3646_test_from_value_enum() -> TestResult { #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)] struct TestNullExternalEnum { a: NullExternalEnum, @@ -901,13 +906,15 @@ mod tests { ]; for (expected, test) in data.iter() { - let actual: TestNullExternalEnum = from_value(test).unwrap(); + let actual: TestNullExternalEnum = from_value(test)?; assert_eq!(actual, *expected); } + + Ok(()) } #[test] - fn test_from_value_single_value_enum() { + fn test_from_value_single_value_enum() -> TestResult { let expected = TestSingleValueExternalEnum { a: SingleValueExternalEnum::Double(64.0), }; @@ -922,15 +929,17 @@ mod tests { ), ]), )]); - let final_value: TestSingleValueExternalEnum = from_value(&test).unwrap(); + let final_value: TestSingleValueExternalEnum = from_value(&test)?; assert_eq!( final_value, expected, "Error deserializing single value external enum(union)" ); + + Ok(()) } #[test] - fn test_from_value_struct_enum() { + fn test_from_value_struct_enum() -> TestResult { let expected = TestStructExternalEnum { a: StructExternalEnum::Val1 { x: 1.0, y: 2.0 }, }; @@ -951,15 +960,17 @@ mod tests { ), ]), )]); - let final_value: TestStructExternalEnum = from_value(&test).unwrap(); + let final_value: TestStructExternalEnum = from_value(&test)?; assert_eq!( final_value, expected, "error deserializing struct external enum(union)" ); + + Ok(()) } #[test] - fn test_avro_3692_from_value_struct_flatten() { + fn test_avro_3692_from_value_struct_flatten() -> TestResult { #[derive(Deserialize, PartialEq, Debug)] struct S1 { f1: String, @@ -981,12 +992,14 @@ mod tests { ("f1".to_owned(), "Hello".into()), ("f2".to_owned(), "World".into()), ]); - let final_value: S1 = from_value(&test).unwrap(); + let final_value: S1 = from_value(&test)?; assert_eq!(final_value, expected); + + Ok(()) } #[test] - fn test_from_value_tuple_enum() { + fn test_from_value_tuple_enum() -> TestResult { let expected = TestTupleExternalEnum { a: TupleExternalEnum::Val1(1.0, 2.0), }; @@ -1004,17 +1017,17 @@ mod tests { ), ]), )]); - let final_value: TestTupleExternalEnum = from_value(&test).unwrap(); + let final_value: TestTupleExternalEnum = from_value(&test)?; assert_eq!( final_value, expected, "error serializing tuple external enum(union)" ); - } - type TestResult = anyhow::Result>; + Ok(()) + } #[test] - fn test_date() -> TestResult<()> { + fn test_date() -> TestResult { let raw_value = 1; let value = Value::Date(raw_value); let result = crate::from_value::(&value)?; @@ -1023,7 +1036,7 @@ mod tests { } #[test] - fn test_time_millis() -> TestResult<()> { + fn test_time_millis() -> TestResult { let raw_value = 1; let value = Value::TimeMillis(raw_value); let result = crate::from_value::(&value)?; @@ -1032,7 +1045,7 @@ mod tests { } #[test] - fn test_time_micros() -> TestResult<()> { + fn test_time_micros() -> TestResult { let raw_value = 1; let value = Value::TimeMicros(raw_value); let result = crate::from_value::(&value)?; @@ -1041,7 +1054,7 @@ mod tests { } #[test] - fn test_timestamp_millis() -> TestResult<()> { + fn test_timestamp_millis() -> TestResult { let raw_value = 1; let value = Value::TimestampMillis(raw_value); let result = crate::from_value::(&value)?; @@ -1050,7 +1063,7 @@ mod tests { } #[test] - fn test_timestamp_micros() -> TestResult<()> { + fn test_timestamp_micros() -> TestResult { let raw_value = 1; let value = Value::TimestampMicros(raw_value); let result = crate::from_value::(&value)?; @@ -1059,16 +1072,16 @@ mod tests { } #[test] - fn test_from_value_uuid_str() -> TestResult<()> { + fn test_from_value_uuid_str() -> TestResult { let raw_value = "9ec535ff-3e2a-45bd-91d3-0a01321b5a49"; - let value = Value::Uuid(Uuid::parse_str(raw_value).unwrap()); + let value = Value::Uuid(Uuid::parse_str(raw_value)?); let result = crate::from_value::(&value)?; assert_eq!(result.to_string(), raw_value); Ok(()) } #[test] - fn test_from_value_uuid_slice() -> TestResult<()> { + fn test_from_value_uuid_slice() -> TestResult { let raw_value = &[4, 54, 67, 12, 43, 2, 2, 76, 32, 50, 87, 5, 1, 33, 43, 87]; let value = Value::Uuid(Uuid::from_slice(raw_value)?); let result = crate::from_value::(&value)?; @@ -1077,7 +1090,7 @@ mod tests { } #[test] - fn test_from_value_with_union() -> TestResult<()> { + fn test_from_value_with_union() -> TestResult { // AVRO-3232 test for deserialize_any on missing fields on the destination struct: // Error: DeserializeValue("Unsupported union") // Error: DeserializeValue("incorrect value of type: String") @@ -1227,7 +1240,7 @@ mod tests { } #[test] - fn avro_3747_human_readable_false() -> TestResult<()> { + fn avro_3747_human_readable_false() -> TestResult { use serde::de::Deserializer as SerdeDeserializer; let is_human_readable = false; @@ -1241,7 +1254,7 @@ mod tests { } #[test] - fn avro_3747_human_readable_true() -> TestResult<()> { + fn avro_3747_human_readable_true() -> TestResult { use serde::de::Deserializer as SerdeDeserializer; crate::util::SERDE_HUMAN_READABLE.store(true, Ordering::Release); diff --git a/lang/rust/avro/src/decimal.rs b/lang/rust/avro/src/decimal.rs index e67430384eb..4373205dfa8 100644 --- a/lang/rust/avro/src/decimal.rs +++ b/lang/rust/avro/src/decimal.rs @@ -104,22 +104,27 @@ mod tests { use super::*; use pretty_assertions::assert_eq; use std::convert::TryFrom; + use apache_avro_test_helper::TestResult; #[test] - fn test_decimal_from_bytes_from_ref_decimal() { + fn test_decimal_from_bytes_from_ref_decimal() -> TestResult { let input = vec![1, 24]; let d = Decimal::from(&input); - let output = >::try_from(&d).unwrap(); + let output = >::try_from(&d)?; assert_eq!(output, input); + + Ok(()) } #[test] - fn test_decimal_from_bytes_from_owned_decimal() { + fn test_decimal_from_bytes_from_owned_decimal() -> TestResult { let input = vec![1, 24]; let d = Decimal::from(&input); - let output = >::try_from(d).unwrap(); + let output = >::try_from(d)?; assert_eq!(output, input); + + Ok(()) } } diff --git a/lang/rust/avro/src/decode.rs b/lang/rust/avro/src/decode.rs index 31b76243a3a..39efefced1a 100644 --- a/lang/rust/avro/src/decode.rs +++ b/lang/rust/avro/src/decode.rs @@ -305,47 +305,56 @@ mod tests { }; use pretty_assertions::assert_eq; use std::collections::HashMap; + use apache_avro_test_helper::TestResult; #[test] - fn test_decode_array_without_size() { + fn test_decode_array_without_size() -> TestResult { let mut input: &[u8] = &[6, 2, 4, 6, 0]; let result = decode(&Schema::Array(Box::new(Schema::Int)), &mut input); - assert_eq!(Array(vec!(Int(1), Int(2), Int(3))), result.unwrap()); + assert_eq!(Array(vec!(Int(1), Int(2), Int(3))), result?); + + Ok(()) } #[test] - fn test_decode_array_with_size() { + fn test_decode_array_with_size() -> TestResult { let mut input: &[u8] = &[5, 6, 2, 4, 6, 0]; let result = decode(&Schema::Array(Box::new(Schema::Int)), &mut input); - assert_eq!(Array(vec!(Int(1), Int(2), Int(3))), result.unwrap()); + assert_eq!(Array(vec!(Int(1), Int(2), Int(3))), result?); + + Ok(()) } #[test] - fn test_decode_map_without_size() { + fn test_decode_map_without_size() -> TestResult { let mut input: &[u8] = &[0x02, 0x08, 0x74, 0x65, 0x73, 0x74, 0x02, 0x00]; let result = decode(&Schema::Map(Box::new(Schema::Int)), &mut input); let mut expected = HashMap::new(); expected.insert(String::from("test"), Int(1)); - assert_eq!(Map(expected), result.unwrap()); + assert_eq!(Map(expected), result?); + + Ok(()) } #[test] - fn test_decode_map_with_size() { + fn test_decode_map_with_size() -> TestResult { let mut input: &[u8] = &[0x01, 0x0C, 0x08, 0x74, 0x65, 0x73, 0x74, 0x02, 0x00]; let result = decode(&Schema::Map(Box::new(Schema::Int)), &mut input); let mut expected = HashMap::new(); expected.insert(String::from("test"), Int(1)); - assert_eq!(Map(expected), result.unwrap()); + assert_eq!(Map(expected), result?); + + Ok(()) } #[test] - fn test_negative_decimal_value() { + fn test_negative_decimal_value() -> TestResult { use crate::{encode::encode, schema::Name}; use num_bigint::ToBigInt; let inner = Box::new(Schema::Fixed(FixedSchema { size: 2, doc: None, - name: Name::new("decimal").unwrap(), + name: Name::new("decimal")?, aliases: None, attributes: Default::default(), })); @@ -361,17 +370,19 @@ mod tests { encode(&value, &schema, &mut buffer).expect(&success(&value, &schema)); let mut bytes = &buffer[..]; - let result = decode(&schema, &mut bytes).unwrap(); + let result = decode(&schema, &mut bytes)?; assert_eq!(result, value); + + Ok(()) } #[test] - fn test_decode_decimal_with_bigger_than_necessary_size() { + fn test_decode_decimal_with_bigger_than_necessary_size() -> TestResult { use crate::{encode::encode, schema::Name}; use num_bigint::ToBigInt; let inner = Box::new(Schema::Fixed(FixedSchema { size: 13, - name: Name::new("decimal").unwrap(), + name: Name::new("decimal")?, aliases: None, doc: None, attributes: Default::default(), @@ -388,12 +399,14 @@ mod tests { encode(&value, &schema, &mut buffer).expect(&success(&value, &schema)); let mut bytes: &[u8] = &buffer[..]; - let result = decode(&schema, &mut bytes).unwrap(); + let result = decode(&schema, &mut bytes)?; assert_eq!(result, value); + + Ok(()) } #[test] - fn test_avro_3448_recursive_definition_decode_union() { + fn test_avro_3448_recursive_definition_decode_union() -> TestResult { // if encoding fails in this test check the corresponding test in encode let schema = Schema::parse_str( r#" @@ -419,7 +432,7 @@ mod tests { ] }"#, ) - .unwrap(); + ?; let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]); let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]); @@ -453,10 +466,12 @@ mod tests { &schema )) ); + + Ok(()) } #[test] - fn test_avro_3448_recursive_definition_decode_array() { + fn test_avro_3448_recursive_definition_decode_array() -> TestResult { let schema = Schema::parse_str( r#" { @@ -484,7 +499,7 @@ mod tests { ] }"#, ) - .unwrap(); + ?; let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]); let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]); @@ -501,11 +516,13 @@ mod tests { "Failed to decode using recursive definitions with schema:\n {:?}\n", &schema )) - ) + ); + + Ok(()) } #[test] - fn test_avro_3448_recursive_definition_decode_map() { + fn test_avro_3448_recursive_definition_decode_map() -> TestResult { let schema = Schema::parse_str( r#" { @@ -533,7 +550,7 @@ mod tests { ] }"#, ) - .unwrap(); + ?; let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]); let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]); @@ -553,11 +570,13 @@ mod tests { "Failed to decode using recursive definitions with schema:\n {:?}\n", &schema )) - ) + ); + + Ok(()) } #[test] - fn test_avro_3448_proper_multi_level_decoding_middle_namespace() { + fn test_avro_3448_proper_multi_level_decoding_middle_namespace() -> TestResult { // if encoding fails in this test check the corresponding test in encode let schema = r#" { @@ -601,7 +620,7 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]); let middle_record_variation_1 = Value::Record(vec![( "middle_field_1".into(), @@ -668,10 +687,12 @@ mod tests { &schema )) ); + + Ok(()) } #[test] - fn test_avro_3448_proper_multi_level_decoding_inner_namespace() { + fn test_avro_3448_proper_multi_level_decoding_inner_namespace() -> TestResult { // if encoding fails in this test check the corresponding test in encode let schema = r#" { @@ -716,7 +737,7 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]); let middle_record_variation_1 = Value::Record(vec![( "middle_field_1".into(), @@ -783,5 +804,7 @@ mod tests { &schema )) ); + + Ok(()) } } diff --git a/lang/rust/avro/src/reader.rs b/lang/rust/avro/src/reader.rs index bdd318861a1..f83c30f3f60 100644 --- a/lang/rust/avro/src/reader.rs +++ b/lang/rust/avro/src/reader.rs @@ -532,6 +532,7 @@ mod tests { use pretty_assertions::assert_eq; use serde::Deserialize; use std::io::Cursor; + use apache_avro_test_helper::TestResult; const SCHEMA: &str = r#" { @@ -569,8 +570,8 @@ mod tests { ]; #[test] - fn test_from_avro_datum() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_from_avro_datum() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let mut encoded: &'static [u8] = &[54, 6, 102, 111, 111]; let mut record = Record::new(&schema).unwrap(); @@ -579,13 +580,15 @@ mod tests { let expected = record.into(); assert_eq!( - from_avro_datum(&schema, &mut encoded, None).unwrap(), + from_avro_datum(&schema, &mut encoded, None)?, expected ); + + Ok(()) } #[test] - fn test_from_avro_datum_with_union_to_struct() { + fn test_from_avro_datum_with_union_to_struct() -> TestResult { const TEST_RECORD_SCHEMA_3240: &str = r#" { "type": "record", @@ -628,7 +631,7 @@ mod tests { a_nullable_string: Option, } - let schema = Schema::parse_str(TEST_RECORD_SCHEMA_3240).unwrap(); + let schema = Schema::parse_str(TEST_RECORD_SCHEMA_3240)?; let mut encoded: &'static [u8] = &[54, 6, 102, 111, 111]; let expected_record: TestRecord3240 = TestRecord3240 { @@ -638,32 +641,36 @@ mod tests { a_nullable_string: None, }; - let avro_datum = from_avro_datum(&schema, &mut encoded, None).unwrap(); + let avro_datum = from_avro_datum(&schema, &mut encoded, None)?; let parsed_record: TestRecord3240 = match &avro_datum { - Value::Record(_) => from_value::(&avro_datum).unwrap(), + Value::Record(_) => from_value::(&avro_datum)?, unexpected => { panic!("could not map avro data to struct, found unexpected: {unexpected:?}") } }; assert_eq!(parsed_record, expected_record); + + Ok(()) } #[test] - fn test_null_union() { - let schema = Schema::parse_str(UNION_SCHEMA).unwrap(); + fn test_null_union() -> TestResult { + let schema = Schema::parse_str(UNION_SCHEMA)?; let mut encoded: &'static [u8] = &[2, 0]; assert_eq!( - from_avro_datum(&schema, &mut encoded, None).unwrap(), + from_avro_datum(&schema, &mut encoded, None)?, Value::Union(1, Box::new(Value::Long(0))) ); + + Ok(()) } #[test] - fn test_reader_iterator() { - let schema = Schema::parse_str(SCHEMA).unwrap(); - let reader = Reader::with_schema(&schema, ENCODED).unwrap(); + fn test_reader_iterator() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; + let reader = Reader::with_schema(&schema, ENCODED)?; let mut record1 = Record::new(&schema).unwrap(); record1.put("a", 27i64); @@ -676,20 +683,24 @@ mod tests { let expected = vec![record1.into(), record2.into()]; for (i, value) in reader.enumerate() { - assert_eq!(value.unwrap(), expected[i]); + assert_eq!(value?, expected[i]); } + + Ok(()) } #[test] - fn test_reader_invalid_header() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_reader_invalid_header() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let invalid = ENCODED.iter().copied().skip(1).collect::>(); assert!(Reader::with_schema(&schema, &invalid[..]).is_err()); + + Ok(()) } #[test] - fn test_reader_invalid_block() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_reader_invalid_block() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let invalid = ENCODED .iter() .copied() @@ -699,32 +710,38 @@ mod tests { .into_iter() .rev() .collect::>(); - let reader = Reader::with_schema(&schema, &invalid[..]).unwrap(); + let reader = Reader::with_schema(&schema, &invalid[..])?; for value in reader { assert!(value.is_err()); } + + Ok(()) } #[test] - fn test_reader_empty_buffer() { + fn test_reader_empty_buffer() -> TestResult { let empty = Cursor::new(Vec::new()); assert!(Reader::new(empty).is_err()); + + Ok(()) } #[test] - fn test_reader_only_header() { + fn test_reader_only_header() -> TestResult { let invalid = ENCODED.iter().copied().take(165).collect::>(); - let reader = Reader::new(&invalid[..]).unwrap(); + let reader = Reader::new(&invalid[..])?; for value in reader { assert!(value.is_err()); } + + Ok(()) } #[test] - fn test_avro_3405_read_user_metadata_success() { + fn test_avro_3405_read_user_metadata_success() -> TestResult { use crate::writer::Writer; - let schema = Schema::parse_str(SCHEMA).unwrap(); + let schema = Schema::parse_str(SCHEMA)?; let mut writer = Writer::new(&schema, Vec::new()); let mut user_meta_data: HashMap> = HashMap::new(); @@ -736,20 +753,22 @@ mod tests { user_meta_data.insert("vecKey".to_string(), vec![1, 2, 3]); for (k, v) in user_meta_data.iter() { - writer.add_user_metadata(k.to_string(), v).unwrap(); + writer.add_user_metadata(k.to_string(), v)?; } let mut record = Record::new(&schema).unwrap(); record.put("a", 27i64); record.put("b", "foo"); - writer.append(record.clone()).unwrap(); - writer.append(record.clone()).unwrap(); - writer.flush().unwrap(); - let result = writer.into_inner().unwrap(); + writer.append(record.clone())?; + writer.append(record.clone())?; + writer.flush()?; + let result = writer.into_inner()?; - let reader = Reader::new(&result[..]).unwrap(); + let reader = Reader::new(&result[..])?; assert_eq!(reader.user_metadata(), &user_meta_data); + + Ok(()) } #[derive(Deserialize, Clone, PartialEq, Debug)] @@ -833,7 +852,7 @@ mod tests { } #[test] - fn test_avro_3507_single_object_reader() { + fn test_avro_3507_single_object_reader() -> TestResult { let obj = TestSingleObjectReader { a: 42, b: 3.33, @@ -860,10 +879,12 @@ mod tests { .expect("Should read"); let expected_value: Value = obj.into(); assert_eq!(expected_value, val); + + Ok(()) } #[test] - fn avro_3642_test_single_object_reader_incomplete_reads() { + fn avro_3642_test_single_object_reader_incomplete_reads() -> TestResult { let obj = TestSingleObjectReader { a: 42, b: 3.33, @@ -892,10 +913,12 @@ mod tests { .expect("Should read"); let expected_value: Value = obj.into(); assert_eq!(expected_value, val); + + Ok(()) } #[test] - fn test_avro_3507_reader_parity() { + fn test_avro_3507_reader_parity() -> TestResult { let obj = TestSingleObjectReader { a: 42, b: 3.33, @@ -935,7 +958,9 @@ mod tests { let expected_value: Value = obj.clone().into(); assert_eq!(obj, read_obj1); assert_eq!(obj, read_obj2); - assert_eq!(val, expected_value) + assert_eq!(val, expected_value); + + Ok(()) } #[cfg(not(feature = "snappy"))] diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs index 629647abc5c..907a0622223 100644 --- a/lang/rust/avro/src/schema.rs +++ b/lang/rust/avro/src/schema.rs @@ -276,12 +276,12 @@ impl Name { /// use apache_avro::schema::Name; /// /// assert_eq!( - /// Name::new("some_name").unwrap().fully_qualified_name(&Some("some_namespace".into())), - /// Name::new("some_namespace.some_name").unwrap() + /// Name::new("some_name")?.fully_qualified_name(&Some("some_namespace".into())), + /// Name::new("some_namespace.some_name")? /// ); /// assert_eq!( - /// Name::new("some_namespace.some_name").unwrap().fully_qualified_name(&Some("other_namespace".into())), - /// Name::new("some_namespace.some_name").unwrap() + /// Name::new("some_namespace.some_name")?.fully_qualified_name(&Some("other_namespace".into())), + /// Name::new("some_namespace.some_name")? /// ); /// ``` pub fn fully_qualified_name(&self, enclosing_namespace: &Namespace) -> Name { @@ -840,7 +840,7 @@ impl Schema { /// during parsing. /// /// If two of the input schemas have the same fullname, an Error will be returned. - pub fn parse_list(input: &[&str]) -> Result, Error> { + pub fn parse_list(input: &[&str]) -> AvroResult> { let mut input_schemas: HashMap = HashMap::with_capacity(input.len()); let mut input_order: Vec = Vec::with_capacity(input.len()); for js in input { @@ -2073,6 +2073,7 @@ mod tests { use super::*; use pretty_assertions::assert_eq; use serde_json::json; + use apache_avro_test_helper::TestResult; #[test] fn test_invalid_schema() { @@ -2080,31 +2081,35 @@ mod tests { } #[test] - fn test_primitive_schema() { - assert_eq!(Schema::Null, Schema::parse_str("\"null\"").unwrap()); - assert_eq!(Schema::Int, Schema::parse_str("\"int\"").unwrap()); - assert_eq!(Schema::Double, Schema::parse_str("\"double\"").unwrap()); + fn test_primitive_schema() -> TestResult { + assert_eq!(Schema::Null, Schema::parse_str("\"null\"")?); + assert_eq!(Schema::Int, Schema::parse_str("\"int\"")?); + assert_eq!(Schema::Double, Schema::parse_str("\"double\"")?); + Ok(()) } #[test] - fn test_array_schema() { - let schema = Schema::parse_str(r#"{"type": "array", "items": "string"}"#).unwrap(); + fn test_array_schema() -> TestResult { + let schema = Schema::parse_str(r#"{"type": "array", "items": "string"}"#)?; assert_eq!(Schema::Array(Box::new(Schema::String)), schema); + Ok(()) } #[test] - fn test_map_schema() { - let schema = Schema::parse_str(r#"{"type": "map", "values": "double"}"#).unwrap(); + fn test_map_schema() -> TestResult { + let schema = Schema::parse_str(r#"{"type": "map", "values": "double"}"#)?; assert_eq!(Schema::Map(Box::new(Schema::Double)), schema); + Ok(()) } #[test] - fn test_union_schema() { - let schema = Schema::parse_str(r#"["null", "int"]"#).unwrap(); + fn test_union_schema() -> TestResult { + let schema = Schema::parse_str(r#"["null", "int"]"#)?; assert_eq!( - Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int]).unwrap()), + Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int])?), schema ); + Ok(()) } #[test] @@ -2114,10 +2119,10 @@ mod tests { } #[test] - fn test_multi_union_schema() { + fn test_multi_union_schema() -> TestResult { let schema = Schema::parse_str(r#"["null", "int", "float", "string", "bytes"]"#); assert!(schema.is_ok()); - let schema = schema.unwrap(); + let schema = schema?; assert_eq!(SchemaKind::from(&schema), SchemaKind::Union); let union_schema = match schema { Schema::Union(u) => u, @@ -2140,11 +2145,12 @@ mod tests { SchemaKind::Bytes ); assert_eq!(variants.next(), None); + + Ok(()) } - // AVRO-3621 #[test] - fn test_avro_3621_nullable_record_field() { + fn test_avro_3621_nullable_record_field() -> TestResult { let nullable_record_field = RecordField { name: "next".to_string(), doc: None, @@ -2160,7 +2166,7 @@ mod tests { }, }, ]) - .unwrap(), + ?, ), order: RecordFieldOrder::Ascending, position: 1, @@ -2181,11 +2187,12 @@ mod tests { }; assert!(!non_nullable_record_field.is_nullable()); + Ok(()) } // AVRO-3248 #[test] - fn test_union_of_records() { + fn test_union_of_records() -> TestResult { use std::iter::FromIterator; // A and B are the same except the name. @@ -2214,14 +2221,13 @@ mod tests { ] }"#; - let schema_c = Schema::parse_list(&[schema_str_a, schema_str_b, schema_str_c]) - .unwrap() + let schema_c = Schema::parse_list(&[schema_str_a, schema_str_b, schema_str_c])? .last() .unwrap() .clone(); let schema_c_expected = Schema::Record(RecordSchema { - name: Name::new("C").unwrap(), + name: Name::new("C")?, aliases: None, doc: None, fields: vec![RecordField { @@ -2232,13 +2238,13 @@ mod tests { schema: Schema::Union( UnionSchema::new(vec![ Schema::Ref { - name: Name::new("A").unwrap(), + name: Name::new("A")?, }, Schema::Ref { - name: Name::new("B").unwrap(), + name: Name::new("B")?, }, ]) - .unwrap(), + ?, ), order: RecordFieldOrder::Ignore, position: 0, @@ -2249,11 +2255,11 @@ mod tests { }); assert_eq!(schema_c, schema_c_expected); + Ok(()) } - // AVRO-3584 : recursion in type definitions #[test] - fn avro_3584_test_recursion_records() { + fn avro_3584_test_recursion_records() -> TestResult { // A and B are the same except the name. let schema_str_a = r#"{ "name": "A", @@ -2267,7 +2273,7 @@ mod tests { "fields": [ {"name": "field_one", "type": "A"} ] }"#; - let list = Schema::parse_list(&[schema_str_a, schema_str_b]).unwrap(); + let list = Schema::parse_list(&[schema_str_a, schema_str_b])?; let schema_a = list.first().unwrap().clone(); @@ -2276,17 +2282,18 @@ mod tests { let f1 = fields.get(0); let ref_schema = Schema::Ref { - name: Name::new("B").unwrap(), + name: Name::new("B")?, }; assert_eq!(ref_schema, f1.unwrap().schema); } _ => panic!("Expected a record schema!"), } + + Ok(()) } - // AVRO-3248 #[test] - fn test_nullable_record() { + fn test_avro_3248_nullable_record() -> TestResult { use std::iter::FromIterator; let schema_str_a = r#"{ @@ -2306,14 +2313,13 @@ mod tests { ] }"#; - let schema_option_a = Schema::parse_list(&[schema_str_a, schema_str_option_a]) - .unwrap() + let schema_option_a = Schema::parse_list(&[schema_str_a, schema_str_option_a])? .last() .unwrap() .clone(); let schema_option_a_expected = Schema::Record(RecordSchema { - name: Name::new("OptionA").unwrap(), + name: Name::new("OptionA")?, aliases: None, doc: None, fields: vec![RecordField { @@ -2325,10 +2331,10 @@ mod tests { UnionSchema::new(vec![ Schema::Null, Schema::Ref { - name: Name::new("A").unwrap(), + name: Name::new("A")?, }, ]) - .unwrap(), + ?, ), order: RecordFieldOrder::Ignore, position: 0, @@ -2339,10 +2345,12 @@ mod tests { }); assert_eq!(schema_option_a, schema_option_a_expected); + + Ok(()) } #[test] - fn test_record_schema() { + fn test_record_schema() -> TestResult { let parsed = Schema::parse_str( r#" { @@ -2355,14 +2363,14 @@ mod tests { } "#, ) - .unwrap(); + ?; let mut lookup = BTreeMap::new(); lookup.insert("a".to_owned(), 0); lookup.insert("b".to_owned(), 1); let expected = Schema::Record(RecordSchema { - name: Name::new("test").unwrap(), + name: Name::new("test")?, aliases: None, doc: None, fields: vec![ @@ -2392,11 +2400,12 @@ mod tests { }); assert_eq!(parsed, expected); + + Ok(()) } - // AVRO-3302 #[test] - fn test_record_schema_with_currently_parsing_schema() { + fn test_avro_3302_record_schema_with_currently_parsing_schema() -> TestResult { let schema = Schema::parse_str( r#" { @@ -2416,7 +2425,7 @@ mod tests { } "#, ) - .unwrap(); + ?; let mut lookup = BTreeMap::new(); lookup.insert("recordField".to_owned(), 0); @@ -2426,7 +2435,7 @@ mod tests { node_lookup.insert("label".to_owned(), 0); let expected = Schema::Record(RecordSchema { - name: Name::new("test").unwrap(), + name: Name::new("test")?, aliases: None, doc: None, fields: vec![RecordField { @@ -2435,7 +2444,7 @@ mod tests { default: None, aliases: None, schema: Schema::Record(RecordSchema { - name: Name::new("Node").unwrap(), + name: Name::new("Node")?, aliases: None, doc: None, fields: vec![ @@ -2455,7 +2464,7 @@ mod tests { default: None, aliases: None, schema: Schema::Array(Box::new(Schema::Ref { - name: Name::new("Node").unwrap(), + name: Name::new("Node")?, })), order: RecordFieldOrder::Ascending, position: 1, @@ -2477,11 +2486,13 @@ mod tests { let canonical_form = &schema.canonical_form(); let expected = r#"{"name":"test","type":"record","fields":[{"name":"recordField","type":{"name":"Node","type":"record","fields":[{"name":"label","type":"string"},{"name":"children","type":{"type":"array","items":"Node"}}]}}]}"#; assert_eq!(canonical_form, &expected); + + Ok(()) } // https://github.com/flavray/avro-rs/pull/99#issuecomment-1016948451 #[test] - fn test_parsing_of_recursive_type_enum() { + fn test_parsing_of_recursive_type_enum() -> TestResult { let schema = r#" { "type": "record", @@ -2525,14 +2536,16 @@ mod tests { } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let schema_str = schema.canonical_form(); let expected = r#"{"name":"office.User","type":"record","fields":[{"name":"details","type":[{"name":"Employee","type":"record","fields":[{"name":"gender","type":{"name":"Gender","type":"enum","symbols":["male","female"]}}]},{"name":"Manager","type":"record","fields":[{"name":"gender","type":"Gender"}]}]}]}"#; assert_eq!(schema_str, expected); + + Ok(()) } #[test] - fn test_parsing_of_recursive_type_fixed() { + fn test_parsing_of_recursive_type_fixed() -> TestResult { let schema = r#" { "type": "record", @@ -2573,15 +2586,16 @@ mod tests { } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let schema_str = schema.canonical_form(); let expected = r#"{"name":"office.User","type":"record","fields":[{"name":"details","type":[{"name":"Employee","type":"record","fields":[{"name":"id","type":{"name":"EmployeeId","type":"fixed","size":16}}]},{"name":"Manager","type":"record","fields":[{"name":"id","type":"EmployeeId"}]}]}]}"#; assert_eq!(schema_str, expected); + + Ok(()) } - // AVRO-3302 #[test] - fn test_record_schema_with_currently_parsing_schema_aliases() { + fn test_avro_3302_record_schema_with_currently_parsing_schema_aliases() -> TestResult { let schema = Schema::parse_str( r#" { @@ -2595,7 +2609,7 @@ mod tests { } "#, ) - .unwrap(); + ?; let mut lookup = BTreeMap::new(); lookup.insert("value".to_owned(), 0); @@ -2634,7 +2648,7 @@ mod tests { }, }, ]) - .unwrap(), + ?, ), order: RecordFieldOrder::Ascending, position: 1, @@ -2649,11 +2663,12 @@ mod tests { let canonical_form = &schema.canonical_form(); let expected = r#"{"name":"LongList","type":"record","fields":[{"name":"value","type":"long"},{"name":"next","type":["null","LongList"]}]}"#; assert_eq!(canonical_form, &expected); + + Ok(()) } - // AVRO-3370 #[test] - fn test_record_schema_with_currently_parsing_schema_named_record() { + fn test_avro_3370_record_schema_with_currently_parsing_schema_named_record() -> TestResult { let schema = Schema::parse_str( r#" { @@ -2666,7 +2681,7 @@ mod tests { } "#, ) - .unwrap(); + ?; let mut lookup = BTreeMap::new(); lookup.insert("value".to_owned(), 0); @@ -2714,11 +2729,12 @@ mod tests { let canonical_form = &schema.canonical_form(); let expected = r#"{"name":"record","type":"record","fields":[{"name":"value","type":"long"},{"name":"next","type":"record"}]}"#; assert_eq!(canonical_form, &expected); + + Ok(()) } - // AVRO-3370 #[test] - fn test_record_schema_with_currently_parsing_schema_named_enum() { + fn test_avro_3370_record_schema_with_currently_parsing_schema_named_enum() -> TestResult { let schema = Schema::parse_str( r#" { @@ -2735,7 +2751,7 @@ mod tests { } "#, ) - .unwrap(); + ?; let mut lookup = BTreeMap::new(); lookup.insert("enum".to_owned(), 0); @@ -2796,11 +2812,12 @@ mod tests { let canonical_form = &schema.canonical_form(); let expected = r#"{"name":"record","type":"record","fields":[{"name":"enum","type":{"name":"enum","type":"enum","symbols":["one","two","three"]}},{"name":"next","type":{"name":"enum","type":"enum","symbols":["one","two","three"]}}]}"#; assert_eq!(canonical_form, &expected); + + Ok(()) } - // AVRO-3370 #[test] - fn test_record_schema_with_currently_parsing_schema_named_fixed() { + fn test_avro_3370_record_schema_with_currently_parsing_schema_named_fixed() -> TestResult { let schema = Schema::parse_str( r#" { @@ -2817,7 +2834,7 @@ mod tests { } "#, ) - .unwrap(); + ?; let mut lookup = BTreeMap::new(); lookup.insert("fixed".to_owned(), 0); @@ -2878,16 +2895,18 @@ mod tests { let canonical_form = &schema.canonical_form(); let expected = r#"{"name":"record","type":"record","fields":[{"name":"fixed","type":{"name":"fixed","type":"fixed","size":456}},{"name":"next","type":{"name":"fixed","type":"fixed","size":456}}]}"#; assert_eq!(canonical_form, &expected); + + Ok(()) } #[test] - fn test_enum_schema() { + fn test_enum_schema() -> TestResult { let schema = Schema::parse_str( r#"{"type": "enum", "name": "Suit", "symbols": ["diamonds", "spades", "clubs", "hearts"]}"#, - ).unwrap(); + )?; let expected = Schema::Enum(EnumSchema { - name: Name::new("Suit").unwrap(), + name: Name::new("Suit")?, aliases: None, doc: None, symbols: vec![ @@ -2900,32 +2919,38 @@ mod tests { }); assert_eq!(expected, schema); + + Ok(()) } #[test] - fn test_enum_schema_duplicate() { + fn test_enum_schema_duplicate() -> TestResult { // Duplicate "diamonds" let schema = Schema::parse_str( r#"{"type": "enum", "name": "Suit", "symbols": ["diamonds", "spades", "clubs", "diamonds"]}"#, ); assert!(schema.is_err()); + + Ok(()) } #[test] - fn test_enum_schema_name() { + fn test_enum_schema_name() -> TestResult { // Invalid name "0000" does not match [A-Za-z_][A-Za-z0-9_]* let schema = Schema::parse_str( r#"{"type": "enum", "name": "Enum", "symbols": ["0000", "variant"]}"#, ); assert!(schema.is_err()); + + Ok(()) } #[test] - fn test_fixed_schema() { - let schema = Schema::parse_str(r#"{"type": "fixed", "name": "test", "size": 16}"#).unwrap(); + fn test_fixed_schema() -> TestResult { + let schema = Schema::parse_str(r#"{"type": "fixed", "name": "test", "size": 16}"#)?; let expected = Schema::Fixed(FixedSchema { - name: Name::new("test").unwrap(), + name: Name::new("test")?, aliases: None, doc: None, size: 16usize, @@ -2933,17 +2958,19 @@ mod tests { }); assert_eq!(expected, schema); + + Ok(()) } #[test] - fn test_fixed_schema_with_documentation() { + fn test_fixed_schema_with_documentation() -> TestResult { let schema = Schema::parse_str( r#"{"type": "fixed", "name": "test", "size": 16, "doc": "FixedSchema documentation"}"#, ) - .unwrap(); + ?; let expected = Schema::Fixed(FixedSchema { - name: Name::new("test").unwrap(), + name: Name::new("test")?, aliases: None, doc: Some(String::from("FixedSchema documentation")), size: 16usize, @@ -2951,27 +2978,31 @@ mod tests { }); assert_eq!(expected, schema); + + Ok(()) } #[test] - fn test_no_documentation() { + fn test_no_documentation() -> TestResult { let schema = Schema::parse_str(r#"{"type": "enum", "name": "Coin", "symbols": ["heads", "tails"]}"#) - .unwrap(); + ?; let doc = match schema { Schema::Enum(EnumSchema { doc, .. }) => doc, - _ => return, + _ => unreachable!(), }; assert!(doc.is_none()); + + Ok(()) } #[test] - fn test_documentation() { + fn test_documentation() -> TestResult { let schema = Schema::parse_str( r#"{"type": "enum", "name": "Coin", "doc": "Some documentation", "symbols": ["heads", "tails"]}"# - ).unwrap(); + )?; let doc = match schema { Schema::Enum(EnumSchema { doc, .. }) => doc, @@ -2979,6 +3010,8 @@ mod tests { }; assert_eq!("Some documentation".to_owned(), doc.unwrap()); + + Ok(()) } // Tests to ensure Schema is Send + Sync. These tests don't need to _do_ anything, if they can @@ -3001,8 +3034,7 @@ mod tests { } #[test] - #[cfg_attr(miri, ignore)] // Sha256 uses an inline assembly instructions which is not supported by miri - fn test_schema_fingerprint() { + fn test_schema_fingerprint() -> TestResult { use crate::rabin::Rabin; use md5::Md5; use sha2::Sha256; @@ -3019,7 +3051,7 @@ mod tests { } "#; - let schema = Schema::parse_str(raw_schema).unwrap(); + let schema = Schema::parse_str(raw_schema)?; assert_eq!( "abf662f831715ff78f88545a05a9262af75d6406b54e1a8a174ff1d2b75affc4", format!("{}", schema.fingerprint::()) @@ -3032,33 +3064,39 @@ mod tests { assert_eq!( "28cf0a67d9937bb3", format!("{}", schema.fingerprint::()) - ) + ); + + Ok(()) } #[test] - fn test_logical_types() { - let schema = Schema::parse_str(r#"{"type": "int", "logicalType": "date"}"#).unwrap(); + fn test_logical_types() -> TestResult { + let schema = Schema::parse_str(r#"{"type": "int", "logicalType": "date"}"#)?; assert_eq!(schema, Schema::Date); let schema = - Schema::parse_str(r#"{"type": "long", "logicalType": "timestamp-micros"}"#).unwrap(); + Schema::parse_str(r#"{"type": "long", "logicalType": "timestamp-micros"}"#)?; assert_eq!(schema, Schema::TimestampMicros); + + Ok(()) } #[test] - fn test_nullable_logical_type() { + fn test_nullable_logical_type() -> TestResult { let schema = Schema::parse_str( r#"{"type": ["null", {"type": "long", "logicalType": "timestamp-micros"}]}"#, ) - .unwrap(); + ?; assert_eq!( schema, - Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::TimestampMicros]).unwrap()) + Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::TimestampMicros])?) ); + + Ok(()) } #[test] - fn record_field_order_from_str() { + fn record_field_order_from_str() -> TestResult { use std::str::FromStr; assert_eq!( @@ -3074,11 +3112,12 @@ mod tests { RecordFieldOrder::Ignore ); assert!(RecordFieldOrder::from_str("not an ordering").is_err()); + + Ok(()) } - /// AVRO-3374 #[test] - fn test_avro_3374_preserve_namespace_for_primitive() { + fn test_avro_3374_preserve_namespace_for_primitive() -> TestResult { let schema = Schema::parse_str( r#" { @@ -3091,17 +3130,19 @@ mod tests { } "#, ) - .unwrap(); + ?; let json = schema.canonical_form(); assert_eq!( json, r#"{"name":"ns.int","type":"record","fields":[{"name":"value","type":"int"},{"name":"next","type":["null","ns.int"]}]}"# ); + + Ok(()) } #[test] - fn test_avro_3433_preserve_schema_refs_in_json() { + fn test_avro_3433_preserve_schema_refs_in_json() -> TestResult { let schema = r#" { "name": "test.test", @@ -3116,14 +3157,16 @@ mod tests { } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let expected = r#"{"name":"test.test","type":"record","fields":[{"name":"bar","type":{"name":"test.foo","type":"record","fields":[{"name":"id","type":"long"}]}},{"name":"baz","type":"test.foo"}]}"#; assert_eq!(schema.canonical_form(), expected); + + Ok(()) } #[test] - fn test_read_namespace_from_name() { + fn test_read_namespace_from_name() -> TestResult { let schema = r#" { "name": "space.name", @@ -3137,17 +3180,19 @@ mod tests { } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; if let Schema::Record(RecordSchema { name, .. }) = schema { assert_eq!(name.name, "name"); assert_eq!(name.namespace, Some("space".to_string())); } else { panic!("Expected a record schema!"); } + + Ok(()) } #[test] - fn test_namespace_from_name_has_priority_over_from_field() { + fn test_namespace_from_name_has_priority_over_from_field() -> TestResult { let schema = r#" { "name": "space1.name", @@ -3162,16 +3207,18 @@ mod tests { } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; if let Schema::Record(RecordSchema { name, .. }) = schema { assert_eq!(name.namespace, Some("space1".to_string())); } else { panic!("Expected a record schema!"); } + + Ok(()) } #[test] - fn test_namespace_from_field() { + fn test_namespace_from_field() -> TestResult { let schema = r#" { "name": "name", @@ -3186,20 +3233,24 @@ mod tests { } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; if let Schema::Record(RecordSchema { name, .. }) = schema { assert_eq!(name.namespace, Some("space2".to_string())); } else { panic!("Expected a record schema!"); } + + Ok(()) } #[test] /// Zero-length namespace is considered as no-namespace. - fn test_namespace_from_name_with_empty_value() { - let name = Name::new(".name").unwrap(); + fn test_namespace_from_name_with_empty_value() -> TestResult { + let name = Name::new(".name")?; assert_eq!(name.name, "name"); assert_eq!(name.namespace, None); + + Ok(()) } #[test] @@ -3221,7 +3272,7 @@ mod tests { } #[test] - fn avro_3448_test_proper_resolution_inner_record_inherited_namespace() { + fn avro_3448_test_proper_resolution_inner_record_inherited_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3251,16 +3302,18 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "space.inner_record_name"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_resolution_inner_record_qualified_namespace() { + fn avro_3448_test_proper_resolution_inner_record_qualified_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3290,16 +3343,18 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "space.inner_record_name"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_resolution_inner_enum_inherited_namespace() { + fn avro_3448_test_proper_resolution_inner_enum_inherited_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3324,16 +3379,18 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "space.inner_enum_name"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_resolution_inner_enum_qualified_namespace() { + fn avro_3448_test_proper_resolution_inner_enum_qualified_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3358,16 +3415,18 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "space.inner_enum_name"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_resolution_inner_fixed_inherited_namespace() { + fn avro_3448_test_proper_resolution_inner_fixed_inherited_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3392,16 +3451,18 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "space.inner_fixed_name"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_resolution_inner_fixed_qualified_namespace() { + fn avro_3448_test_proper_resolution_inner_fixed_qualified_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3426,16 +3487,18 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "space.inner_fixed_name"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_resolution_inner_record_inner_namespace() { + fn avro_3448_test_proper_resolution_inner_record_inner_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3466,16 +3529,18 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "inner_space.inner_record_name"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_resolution_inner_enum_inner_namespace() { + fn avro_3448_test_proper_resolution_inner_enum_inner_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3501,16 +3566,18 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "inner_space.inner_enum_name"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_resolution_inner_fixed_inner_namespace() { + fn avro_3448_test_proper_resolution_inner_fixed_inner_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3536,16 +3603,18 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "inner_space.inner_fixed_name"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_multi_level_resolution_inner_record_outer_namespace() { + fn avro_3448_test_proper_multi_level_resolution_inner_record_outer_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3587,7 +3656,7 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 3); for s in &[ @@ -3595,12 +3664,14 @@ mod tests { "space.middle_record_name", "space.inner_record_name", ] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_multi_level_resolution_inner_record_middle_namespace() { + fn avro_3448_test_proper_multi_level_resolution_inner_record_middle_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3643,7 +3714,7 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 3); for s in &[ @@ -3651,12 +3722,14 @@ mod tests { "middle_namespace.middle_record_name", "middle_namespace.inner_record_name", ] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_multi_level_resolution_inner_record_inner_namespace() { + fn avro_3448_test_proper_multi_level_resolution_inner_record_inner_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3700,7 +3773,7 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 3); for s in &[ @@ -3708,12 +3781,14 @@ mod tests { "middle_namespace.middle_record_name", "inner_namespace.inner_record_name", ] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_in_array_resolution_inherited_namespace() { + fn avro_3448_test_proper_in_array_resolution_inherited_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3743,16 +3818,18 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "space.in_array_record"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3448_test_proper_in_map_resolution_inherited_namespace() { + fn avro_3448_test_proper_in_map_resolution_inherited_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3782,16 +3859,18 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "space.in_map_record"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } + + Ok(()) } #[test] - fn avro_3466_test_to_json_inner_enum_inner_namespace() { + fn avro_3466_test_to_json_inner_enum_inner_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3817,23 +3896,25 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); // confirm we have expected 2 full-names assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "inner_space.inner_enum_name"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } // convert Schema back to JSON string let schema_str = serde_json::to_string(&schema).expect("test failed"); let _schema = Schema::parse_str(&schema_str).expect("test failed"); assert_eq!(schema, _schema); + + Ok(()) } #[test] - fn avro_3466_test_to_json_inner_fixed_inner_namespace() { + fn avro_3466_test_to_json_inner_fixed_inner_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -3859,19 +3940,21 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse"); // confirm we have expected 2 full-names assert_eq!(rs.get_names().len(), 2); for s in &["space.record_name", "inner_space.inner_fixed_name"] { - assert!(rs.get_names().contains_key(&Name::new(s).unwrap())); + assert!(rs.get_names().contains_key(&Name::new(s)?)); } // convert Schema back to JSON string let schema_str = serde_json::to_string(&schema).expect("test failed"); let _schema = Schema::parse_str(&schema_str).expect("test failed"); assert_eq!(schema, _schema); + + Ok(()) } fn assert_avro_3512_aliases(aliases: &Aliases) { @@ -3889,7 +3972,7 @@ mod tests { } #[test] - fn avro_3512_alias_with_null_namespace_record() { + fn avro_3512_alias_with_null_namespace_record() -> TestResult { let schema = Schema::parse_str( r#" { @@ -3903,17 +3986,19 @@ mod tests { } "#, ) - .unwrap(); + ?; if let Schema::Record(RecordSchema { ref aliases, .. }) = schema { assert_avro_3512_aliases(aliases); } else { panic!("The Schema should be a record: {schema:?}"); } + + Ok(()) } #[test] - fn avro_3512_alias_with_null_namespace_enum() { + fn avro_3512_alias_with_null_namespace_enum() -> TestResult { let schema = Schema::parse_str( r#" { @@ -3927,17 +4012,19 @@ mod tests { } "#, ) - .unwrap(); + ?; if let Schema::Enum(EnumSchema { ref aliases, .. }) = schema { assert_avro_3512_aliases(aliases); } else { panic!("The Schema should be an enum: {schema:?}"); } + + Ok(()) } #[test] - fn avro_3512_alias_with_null_namespace_fixed() { + fn avro_3512_alias_with_null_namespace_fixed() -> TestResult { let schema = Schema::parse_str( r#" { @@ -3949,17 +4036,19 @@ mod tests { } "#, ) - .unwrap(); + ?; if let Schema::Fixed(FixedSchema { ref aliases, .. }) = schema { assert_avro_3512_aliases(aliases); } else { panic!("The Schema should be a fixed: {schema:?}"); } + + Ok(()) } #[test] - fn avro_3518_serialize_aliases_record() { + fn avro_3518_serialize_aliases_record() -> TestResult { let schema = Schema::parse_str( r#" { @@ -3979,19 +4068,21 @@ mod tests { } "#, ) - .unwrap(); + ?; - let value = serde_json::to_value(&schema).unwrap(); - let serialized = serde_json::to_string(&value).unwrap(); + let value = serde_json::to_value(&schema)?; + let serialized = serde_json::to_string(&value)?; assert_eq!( r#"{"aliases":["space.b","x.y","c"],"fields":[{"aliases":["time1","ns.time2"],"default":123,"name":"time","type":"long"}],"name":"a","namespace":"space","type":"record"}"#, &serialized ); - assert_eq!(schema, Schema::parse_str(&serialized).unwrap()); + assert_eq!(schema, Schema::parse_str(&serialized)?); + + Ok(()) } #[test] - fn avro_3518_serialize_aliases_enum() { + fn avro_3518_serialize_aliases_enum() -> TestResult { let schema = Schema::parse_str( r#" { @@ -4005,19 +4096,21 @@ mod tests { } "#, ) - .unwrap(); + ?; - let value = serde_json::to_value(&schema).unwrap(); - let serialized = serde_json::to_string(&value).unwrap(); + let value = serde_json::to_value(&schema)?; + let serialized = serde_json::to_string(&value)?; assert_eq!( r#"{"aliases":["space.b","x.y","c"],"name":"a","namespace":"space","symbols":["symbol1","symbol2"],"type":"enum"}"#, &serialized ); - assert_eq!(schema, Schema::parse_str(&serialized).unwrap()); + assert_eq!(schema, Schema::parse_str(&serialized)?); + + Ok(()) } #[test] - fn avro_3518_serialize_aliases_fixed() { + fn avro_3518_serialize_aliases_fixed() -> TestResult { let schema = Schema::parse_str( r#" { @@ -4029,19 +4122,21 @@ mod tests { } "#, ) - .unwrap(); + ?; - let value = serde_json::to_value(&schema).unwrap(); - let serialized = serde_json::to_string(&value).unwrap(); + let value = serde_json::to_value(&schema)?; + let serialized = serde_json::to_string(&value)?; assert_eq!( r#"{"aliases":["space.b","x.y","c"],"name":"a","namespace":"space","size":12,"type":"fixed"}"#, &serialized ); - assert_eq!(schema, Schema::parse_str(&serialized).unwrap()); + assert_eq!(schema, Schema::parse_str(&serialized)?); + + Ok(()) } #[test] - fn avro_3130_parse_anonymous_union_type() { + fn avro_3130_parse_anonymous_union_type() -> TestResult { let schema_str = r#" { "type": "record", @@ -4061,10 +4156,10 @@ mod tests { ] } "#; - let schema = Schema::parse_str(schema_str).unwrap(); + let schema = Schema::parse_str(schema_str)?; if let Schema::Record(RecordSchema { name, fields, .. }) = schema { - assert_eq!(name, Name::new("AccountEvent").unwrap()); + assert_eq!(name, Name::new("AccountEvent")?); let field = &fields[0]; assert_eq!(&field.name, "NullableLongArray"); @@ -4087,10 +4182,12 @@ mod tests { } else { panic!("Expected Schema::Record"); } + + Ok(()) } #[test] - fn avro_custom_attributes_schema_without_attributes() { + fn avro_custom_attributes_schema_without_attributes() -> TestResult { let schemata_str = [ r#" { @@ -4118,9 +4215,11 @@ mod tests { "#, ]; for schema_str in schemata_str.iter() { - let schema = Schema::parse_str(schema_str).unwrap(); + let schema = Schema::parse_str(schema_str)?; assert_eq!(schema.custom_attributes(), Some(&Default::default())); } + + Ok(()) } const CUSTOM_ATTRS_SUFFIX: &str = r#" @@ -4134,7 +4233,7 @@ mod tests { "#; #[test] - fn avro_3609_custom_attributes_schema_with_attributes() { + fn avro_3609_custom_attributes_schema_with_attributes() -> TestResult { let schemata_str = [ r#" { @@ -4175,13 +4274,15 @@ mod tests { .replace("{{{}}}", CUSTOM_ATTRS_SUFFIX) .as_str(), ) - .unwrap(); + ?; assert_eq!( schema.custom_attributes(), Some(&expected_custom_attibutes()) ); } + + Ok(()) } fn expected_custom_attibutes() -> BTreeMap { @@ -4200,7 +4301,7 @@ mod tests { } #[test] - fn avro_3609_custom_attributes_record_field_without_attributes() { + fn avro_3609_custom_attributes_record_field_without_attributes() -> TestResult { let schema_str = String::from( r#" { @@ -4219,11 +4320,11 @@ mod tests { ); let schema = - Schema::parse_str(schema_str.replace("{{{}}}", CUSTOM_ATTRS_SUFFIX).as_str()).unwrap(); + Schema::parse_str(schema_str.replace("{{{}}}", CUSTOM_ATTRS_SUFFIX).as_str())?; match schema { Schema::Record(RecordSchema { name, fields, .. }) => { - assert_eq!(name, Name::new("Rec").unwrap()); + assert_eq!(name, Name::new("Rec")?); assert_eq!(fields.len(), 1); let field = &fields[0]; assert_eq!(&field.name, "field_one"); @@ -4231,10 +4332,12 @@ mod tests { } _ => panic!("Expected Schema::Record"), } + + Ok(()) } #[test] - fn avro_3625_null_is_first() { + fn avro_3625_null_is_first() -> TestResult { let schema_str = String::from( r#" { @@ -4247,11 +4350,11 @@ mod tests { "#, ); - let schema = Schema::parse_str(&schema_str).unwrap(); + let schema = Schema::parse_str(&schema_str)?; match schema { Schema::Record(RecordSchema { name, fields, .. }) => { - assert_eq!(name, Name::new("union_schema_test").unwrap()); + assert_eq!(name, Name::new("union_schema_test")?); assert_eq!(fields.len(), 1); let field = &fields[0]; assert_eq!(&field.name, "a"); @@ -4268,10 +4371,12 @@ mod tests { } _ => panic!("Expected Schema::Record"), } + + Ok(()) } #[test] - fn avro_3625_null_is_last() { + fn avro_3625_null_is_last() -> TestResult { let schema_str = String::from( r#" { @@ -4284,11 +4389,11 @@ mod tests { "#, ); - let schema = Schema::parse_str(&schema_str).unwrap(); + let schema = Schema::parse_str(&schema_str)?; match schema { Schema::Record(RecordSchema { name, fields, .. }) => { - assert_eq!(name, Name::new("union_schema_test").unwrap()); + assert_eq!(name, Name::new("union_schema_test")?); assert_eq!(fields.len(), 1); let field = &fields[0]; assert_eq!(&field.name, "a"); @@ -4304,10 +4409,12 @@ mod tests { } _ => panic!("Expected Schema::Record"), } + + Ok(()) } #[test] - fn avro_3625_null_is_the_middle() { + fn avro_3625_null_is_the_middle() -> TestResult { let schema_str = String::from( r#" { @@ -4320,11 +4427,11 @@ mod tests { "#, ); - let schema = Schema::parse_str(&schema_str).unwrap(); + let schema = Schema::parse_str(&schema_str)?; match schema { Schema::Record(RecordSchema { name, fields, .. }) => { - assert_eq!(name, Name::new("union_schema_test").unwrap()); + assert_eq!(name, Name::new("union_schema_test")?); assert_eq!(fields.len(), 1); let field = &fields[0]; assert_eq!(&field.name, "a"); @@ -4341,10 +4448,12 @@ mod tests { } _ => panic!("Expected Schema::Record"), } + + Ok(()) } #[test] - fn avro_3649_default_notintfirst() { + fn avro_3649_default_notintfirst() -> TestResult { let schema_str = String::from( r#" { @@ -4357,11 +4466,11 @@ mod tests { "#, ); - let schema = Schema::parse_str(&schema_str).unwrap(); + let schema = Schema::parse_str(&schema_str)?; match schema { Schema::Record(RecordSchema { name, fields, .. }) => { - assert_eq!(name, Name::new("union_schema_test").unwrap()); + assert_eq!(name, Name::new("union_schema_test")?); assert_eq!(fields.len(), 1); let field = &fields[0]; assert_eq!(&field.name, "a"); @@ -4377,10 +4486,12 @@ mod tests { } _ => panic!("Expected Schema::Record"), } + + Ok(()) } #[test] - fn avro_3709_parsing_of_record_field_aliases() { + fn avro_3709_parsing_of_record_field_aliases() -> TestResult { let schema = r#" { "name": "rec", @@ -4395,7 +4506,7 @@ mod tests { } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; if let Schema::Record(RecordSchema { fields, .. }) = schema { let num_field = &fields[0]; assert_eq!(num_field.name, "num"); @@ -4403,10 +4514,12 @@ mod tests { } else { panic!("Expected a record schema!"); } + + Ok(()) } #[test] - fn avro_3735_parse_enum_namespace() { + fn avro_3735_parse_enum_namespace() -> TestResult { let schema = r#" { "type": "record", @@ -4453,24 +4566,26 @@ mod tests { pub bar_use: Bar, } - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let foo = Foo { bar_init: Bar::Bar0, bar_use: Bar::Bar1, }; - let avro_value = crate::to_value(foo).unwrap(); + let avro_value = crate::to_value(foo)?; assert!(avro_value.validate(&schema)); let mut writer = crate::Writer::new(&schema, Vec::new()); // schema validation happens here - writer.append(avro_value).unwrap(); + writer.append(avro_value)?; + + Ok(()) } #[test] - fn avro_3755_deserialize() { + fn avro_3755_deserialize() -> TestResult { #[derive( Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, serde::Deserialize, serde::Serialize, )] @@ -4543,21 +4658,21 @@ mod tests { ] }"#; - let writer_schema = Schema::parse_str(writer_schema).unwrap(); + let writer_schema = Schema::parse_str(writer_schema)?; let foo = Foo { bar_init: Bar::Bar0, bar_use: Bar::Bar1, }; - let avro_value = crate::to_value(foo).unwrap(); + let avro_value = crate::to_value(foo)?; assert!( avro_value.validate(&writer_schema), "value is valid for schema", ); - let datum = crate::to_avro_datum(&writer_schema, avro_value).unwrap(); + let datum = crate::to_avro_datum(&writer_schema, avro_value)?; let mut x = &datum[..]; - let reader_schema = Schema::parse_str(reader_schema).unwrap(); + let reader_schema = Schema::parse_str(reader_schema)?; let deser_value = - crate::from_avro_datum(&writer_schema, &mut x, Some(&reader_schema)).unwrap(); + crate::from_avro_datum(&writer_schema, &mut x, Some(&reader_schema))?; match deser_value { types::Value::Record(fields) => { assert_eq!(fields.len(), 2); @@ -4568,5 +4683,7 @@ mod tests { } _ => panic!("Expected Value::Record"), } + + Ok(()) } } diff --git a/lang/rust/avro/src/schema_compatibility.rs b/lang/rust/avro/src/schema_compatibility.rs index aad8fde36b9..dcd70f2b127 100644 --- a/lang/rust/avro/src/schema_compatibility.rs +++ b/lang/rust/avro/src/schema_compatibility.rs @@ -326,6 +326,7 @@ impl SchemaCompatibility { #[cfg(test)] mod tests { + use apache_avro_test_helper::TestResult; use super::*; fn int_array_schema() -> Schema { @@ -589,15 +590,14 @@ mod tests { } #[test] - fn test_missing_field() { + fn test_missing_field() -> TestResult { let reader_schema = Schema::parse_str( r#" {"type":"record", "name":"Record", "fields":[ {"name":"oldfield1", "type":"int"} ]} "#, - ) - .unwrap(); + )?; assert!(SchemaCompatibility::can_read( &writer_schema(), &reader_schema, @@ -606,18 +606,19 @@ mod tests { &reader_schema, &writer_schema() )); + + Ok(()) } #[test] - fn test_missing_second_field() { + fn test_missing_second_field() -> TestResult { let reader_schema = Schema::parse_str( r#" {"type":"record", "name":"Record", "fields":[ {"name":"oldfield2", "type":"string"} ]} "#, - ) - .unwrap(); + )?; assert!(SchemaCompatibility::can_read( &writer_schema(), &reader_schema @@ -626,10 +627,12 @@ mod tests { &reader_schema, &writer_schema() )); + + Ok(()) } #[test] - fn test_all_fields() { + fn test_all_fields() -> TestResult { let reader_schema = Schema::parse_str( r#" {"type":"record", "name":"Record", "fields":[ @@ -637,8 +640,7 @@ mod tests { {"name":"oldfield2", "type":"string"} ]} "#, - ) - .unwrap(); + )?; assert!(SchemaCompatibility::can_read( &writer_schema(), &reader_schema @@ -647,10 +649,12 @@ mod tests { &reader_schema, &writer_schema() )); + + Ok(()) } #[test] - fn test_new_field_with_default() { + fn test_new_field_with_default() -> TestResult { let reader_schema = Schema::parse_str( r#" {"type":"record", "name":"Record", "fields":[ @@ -658,8 +662,7 @@ mod tests { {"name":"newfield1", "type":"int", "default":42} ]} "#, - ) - .unwrap(); + )?; assert!(SchemaCompatibility::can_read( &writer_schema(), &reader_schema @@ -668,10 +671,12 @@ mod tests { &reader_schema, &writer_schema() )); + + Ok(()) } #[test] - fn test_new_field() { + fn test_new_field() -> TestResult { let reader_schema = Schema::parse_str( r#" {"type":"record", "name":"Record", "fields":[ @@ -679,8 +684,7 @@ mod tests { {"name":"newfield1", "type":"int"} ]} "#, - ) - .unwrap(); + )?; assert!(!SchemaCompatibility::can_read( &writer_schema(), &reader_schema @@ -689,6 +693,8 @@ mod tests { &reader_schema, &writer_schema() )); + + Ok(()) } #[test] @@ -720,7 +726,7 @@ mod tests { } #[test] - fn test_union_reader_writer_subset_incompatiblity() { + fn test_union_reader_writer_subset_incompatibility() { // reader union schema must contain all writer union branches let union_writer = union_schema(vec![Schema::Int, Schema::String]); let union_reader = union_schema(vec![Schema::String]); @@ -730,15 +736,14 @@ mod tests { } #[test] - fn test_incompatible_record_field() { + fn test_incompatible_record_field() -> TestResult { let string_schema = Schema::parse_str( r#" {"type":"record", "name":"MyRecord", "namespace":"ns", "fields": [ {"name":"field1", "type":"string"} ]} "#, - ) - .unwrap(); + )?; let int_schema = Schema::parse_str( r#" @@ -746,25 +751,26 @@ mod tests { {"name":"field1", "type":"int"} ]} "#, - ) - .unwrap(); + )?; assert!(!SchemaCompatibility::can_read(&string_schema, &int_schema)); + + Ok(()) } #[test] - fn test_enum_symbols() { + fn test_enum_symbols() -> TestResult { let enum_schema1 = Schema::parse_str( r#" {"type":"enum", "name":"MyEnum", "symbols":["A","B"]} "#, - ) - .unwrap(); + )?; let enum_schema2 = - Schema::parse_str(r#"{"type":"enum", "name":"MyEnum", "symbols":["A","B","C"]}"#) - .unwrap(); + Schema::parse_str(r#"{"type":"enum", "name":"MyEnum", "symbols":["A","B","C"]}"#)?; assert!(!SchemaCompatibility::can_read(&enum_schema2, &enum_schema1)); assert!(SchemaCompatibility::can_read(&enum_schema1, &enum_schema2)); + + Ok(()) } fn point_2d_schema() -> Schema { diff --git a/lang/rust/avro/src/ser.rs b/lang/rust/avro/src/ser.rs index 2237c1d9926..a2567f64fd5 100644 --- a/lang/rust/avro/src/ser.rs +++ b/lang/rust/avro/src/ser.rs @@ -492,6 +492,7 @@ mod tests { use pretty_assertions::assert_eq; use serde::{Deserialize, Serialize}; use std::sync::atomic::Ordering; + use apache_avro_test_helper::TestResult; #[derive(Debug, Deserialize, Serialize, Clone)] struct Test { @@ -683,7 +684,7 @@ mod tests { } #[test] - fn test_to_value() { + fn test_to_value() -> TestResult { let test = Test { a: 27, b: "foo".to_owned(), @@ -693,7 +694,7 @@ mod tests { ("b".to_owned(), Value::String("foo".to_owned())), ]); - assert_eq!(to_value(test.clone()).unwrap(), expected); + assert_eq!(to_value(test.clone())?, expected); let test_inner = TestInner { a: test, b: 35 }; @@ -708,11 +709,13 @@ mod tests { ("b".to_owned(), Value::Int(35)), ]); - assert_eq!(to_value(test_inner).unwrap(), expected_inner); + assert_eq!(to_value(test_inner)?, expected_inner); + + Ok(()) } #[test] - fn test_to_value_unit_enum() { + fn test_to_value_unit_enum() -> TestResult { let test = TestUnitExternalEnum { a: UnitExternalEnum::Val1, }; @@ -720,7 +723,7 @@ mod tests { let expected = Value::Record(vec![("a".to_owned(), Value::Enum(0, "Val1".to_owned()))]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "Error serializing unit external enum" ); @@ -735,7 +738,7 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "Error serializing unit internal enum" ); @@ -750,7 +753,7 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "Error serializing unit adjacent enum" ); @@ -762,14 +765,16 @@ mod tests { let expected = Value::Record(vec![("a".to_owned(), Value::Null)]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "Error serializing unit untagged enum" ); + + Ok(()) } #[test] - fn test_to_value_single_value_enum() { + fn test_to_value_single_value_enum() -> TestResult { let test = TestSingleValueExternalEnum { a: SingleValueExternalEnum::Double(64.0), }; @@ -786,7 +791,7 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "Error serializing single value external enum" ); @@ -811,7 +816,7 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "Error serializing single value adjacent enum" ); @@ -823,14 +828,16 @@ mod tests { let expected = Value::Record(vec![("a".to_owned(), Value::Double(64.0))]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "Error serializing single value untagged enum" ); + + Ok(()) } #[test] - fn test_to_value_struct_enum() { + fn test_to_value_struct_enum() -> TestResult { let test = TestStructExternalEnum { a: StructExternalEnum::Val1 { x: 1.0, y: 2.0 }, }; @@ -852,7 +859,7 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "error serializing struct external enum" ); @@ -872,7 +879,7 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "error serializing struct internal enum" ); @@ -895,7 +902,7 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "error serializing struct adjacent enum" ); @@ -912,7 +919,7 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "error serializing struct untagged enum" ); @@ -934,14 +941,16 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "error serializing struct untagged enum variant" ); + + Ok(()) } #[test] - fn test_to_value_tuple_enum() { + fn test_to_value_tuple_enum() -> TestResult { let test = TestTupleExternalEnum { a: TupleExternalEnum::Val2(1.0, 2.0, 3.0), }; @@ -962,7 +971,7 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "error serializing tuple external enum" ); @@ -983,7 +992,7 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "error serializing tuple adjacent enum" ); @@ -998,10 +1007,12 @@ mod tests { )]); assert_eq!( - to_value(test).unwrap(), + to_value(test)?, expected, "error serializing tuple untagged enum" ); + + Ok(()) } #[test] diff --git a/lang/rust/avro/src/types.rs b/lang/rust/avro/src/types.rs index 93e81e98e36..e8d4d8774ea 100644 --- a/lang/rust/avro/src/types.rs +++ b/lang/rust/avro/src/types.rs @@ -1031,9 +1031,10 @@ mod tests { use apache_avro_test_helper::logger::{assert_logged, assert_not_logged}; use pretty_assertions::assert_eq; use uuid::Uuid; + use apache_avro_test_helper::TestResult; #[test] - fn validate() { + fn validate() -> TestResult { let value_schema_valid = vec![ (Value::Int(42), Schema::Int, true, ""), (Value::Int(43), Schema::Long, true, ""), @@ -1047,19 +1048,19 @@ mod tests { ), ( Value::Union(0, Box::new(Value::Null)), - Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int]).unwrap()), + Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int])?), true, "", ), ( Value::Union(1, Box::new(Value::Int(42))), - Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int]).unwrap()), + Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int])?), true, "", ), ( Value::Union(0, Box::new(Value::Null)), - Schema::Union(UnionSchema::new(vec![Schema::Double, Schema::Int]).unwrap()), + Schema::Union(UnionSchema::new(vec![Schema::Double, Schema::Int])?), false, "Invalid value: Union(0, Null) for schema: Union(UnionSchema { schemas: [Double, Int], variant_index: {Int: 1, Double: 0} }). Reason: Unsupported value-schema combination", ), @@ -1072,7 +1073,7 @@ mod tests { Schema::String, Schema::Int, ]) - .unwrap(), + ?, ), true, "", @@ -1080,14 +1081,14 @@ mod tests { ( Value::Union(1, Box::new(Value::Long(42i64))), Schema::Union( - UnionSchema::new(vec![Schema::Null, Schema::TimestampMillis]).unwrap(), + UnionSchema::new(vec![Schema::Null, Schema::TimestampMillis])?, ), true, "", ), ( Value::Union(2, Box::new(Value::Long(1_i64))), - Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int]).unwrap()), + Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int])?), false, "Invalid value: Union(2, Long(1)) for schema: Union(UnionSchema { schemas: [Null, Int], variant_index: {Null: 0, Int: 1} }). Reason: No schema in the union at position '2'", ), @@ -1178,10 +1179,12 @@ mod tests { assert_eq!(expected_err_message, full_err_message); } } + + Ok(()) } #[test] - fn validate_fixed() { + fn validate_fixed() -> TestResult { let schema = Schema::Fixed(FixedSchema { size: 4, name: Name::new("some_fixed").unwrap(), @@ -1211,10 +1214,12 @@ mod tests { ) .as_str(), ); + + Ok(()) } #[test] - fn validate_enum() { + fn validate_enum() -> TestResult { let schema = Schema::Enum(EnumSchema { name: Name::new("some_enum").unwrap(), aliases: None, @@ -1283,10 +1288,12 @@ mod tests { ) .as_str(), ); + + Ok(()) } #[test] - fn validate_record() { + fn validate_record() -> TestResult { // { // "type": "record", // "fields": [ @@ -1330,7 +1337,7 @@ mod tests { default: Some(JsonValue::Null), aliases: None, schema: Schema::Union( - UnionSchema::new(vec![Schema::Null, Schema::Int]).unwrap(), + UnionSchema::new(vec![Schema::Null, Schema::Int])?, ), order: RecordFieldOrder::Ascending, position: 2, @@ -1422,7 +1429,7 @@ mod tests { Field with name '"b"' is not a member of the map items"#, ); - let union_schema = Schema::Union(UnionSchema::new(vec![Schema::Null, schema]).unwrap()); + let union_schema = Schema::Union(UnionSchema::new(vec![Schema::Null, schema])?); assert!(Value::Union( 1, @@ -1445,33 +1452,41 @@ Field with name '"b"' is not a member of the map items"#, )) ) .validate(&union_schema)); + + Ok(()) } #[test] - fn resolve_bytes_ok() { + fn resolve_bytes_ok() -> TestResult { let value = Value::Array(vec![Value::Int(0), Value::Int(42)]); assert_eq!( - value.resolve(&Schema::Bytes).unwrap(), + value.resolve(&Schema::Bytes)?, Value::Bytes(vec![0u8, 42u8]) ); + + Ok(()) } #[test] - fn resolve_string_from_bytes() { + fn resolve_string_from_bytes() -> TestResult { let value = Value::Bytes(vec![97, 98, 99]); assert_eq!( - value.resolve(&Schema::String).unwrap(), + value.resolve(&Schema::String)?, Value::String("abc".to_string()) ); + + Ok(()) } #[test] - fn resolve_string_from_fixed() { + fn resolve_string_from_fixed() -> TestResult { let value = Value::Fixed(3, vec![97, 98, 99]); assert_eq!( - value.resolve(&Schema::String).unwrap(), + value.resolve(&Schema::String)?, Value::String("abc".to_string()) ); + + Ok(()) } #[test] @@ -1481,7 +1496,7 @@ Field with name '"b"' is not a member of the map items"#, } #[test] - fn resolve_decimal_bytes() { + fn resolve_decimal_bytes() -> TestResult { let value = Value::Decimal(Decimal::from(vec![1, 2])); value .clone() @@ -1490,8 +1505,10 @@ Field with name '"b"' is not a member of the map items"#, scale: 4, inner: Box::new(Schema::Bytes), })) - .unwrap(); + ?; assert!(value.resolve(&Schema::String).is_err()); + + Ok(()) } #[test] @@ -1592,10 +1609,12 @@ Field with name '"b"' is not a member of the map items"#, } #[test] - fn resolve_uuid() { - let value = Value::Uuid(Uuid::parse_str("1481531d-ccc9-46d9-a56f-5b67459c0537").unwrap()); + fn resolve_uuid() -> TestResult { + let value = Value::Uuid(Uuid::parse_str("1481531d-ccc9-46d9-a56f-5b67459c0537")?); assert!(value.clone().resolve(&Schema::Uuid).is_ok()); assert!(value.resolve(&Schema::TimestampMicros).is_err()); + + Ok(()) } #[test] @@ -1605,7 +1624,7 @@ Field with name '"b"' is not a member of the map items"#, } #[test] - fn test_avro_3621_resolve_to_nullable_union() { + fn test_avro_3621_resolve_to_nullable_union() -> TestResult { let schema = Schema::parse_str( r#"{ "type": "record", @@ -1639,7 +1658,7 @@ Field with name '"b"' is not a member of the map items"#, ] }"#, ) - .unwrap(); + ?; let value = Value::Record(vec![( "event".to_string(), @@ -1652,33 +1671,35 @@ Field with name '"b"' is not a member of the map items"#, Value::Record(vec![("size".to_string(), Value::Int(1))]), )]); assert!(value.resolve(&schema).is_err()); + + Ok(()) } #[test] - fn json_from_avro() { - assert_eq!(JsonValue::try_from(Value::Null).unwrap(), JsonValue::Null); + fn json_from_avro() -> TestResult { + assert_eq!(JsonValue::try_from(Value::Null)?, JsonValue::Null); assert_eq!( - JsonValue::try_from(Value::Boolean(true)).unwrap(), + JsonValue::try_from(Value::Boolean(true))?, JsonValue::Bool(true) ); assert_eq!( - JsonValue::try_from(Value::Int(1)).unwrap(), + JsonValue::try_from(Value::Int(1))?, JsonValue::Number(1.into()) ); assert_eq!( - JsonValue::try_from(Value::Long(1)).unwrap(), + JsonValue::try_from(Value::Long(1))?, JsonValue::Number(1.into()) ); assert_eq!( - JsonValue::try_from(Value::Float(1.0)).unwrap(), + JsonValue::try_from(Value::Float(1.0))?, JsonValue::Number(Number::from_f64(1.0).unwrap()) ); assert_eq!( - JsonValue::try_from(Value::Double(1.0)).unwrap(), + JsonValue::try_from(Value::Double(1.0))?, JsonValue::Number(Number::from_f64(1.0).unwrap()) ); assert_eq!( - JsonValue::try_from(Value::Bytes(vec![1, 2, 3])).unwrap(), + JsonValue::try_from(Value::Bytes(vec![1, 2, 3]))?, JsonValue::Array(vec![ JsonValue::Number(1.into()), JsonValue::Number(2.into()), @@ -1686,11 +1707,11 @@ Field with name '"b"' is not a member of the map items"#, ]) ); assert_eq!( - JsonValue::try_from(Value::String("test".into())).unwrap(), + JsonValue::try_from(Value::String("test".into()))?, JsonValue::String("test".into()) ); assert_eq!( - JsonValue::try_from(Value::Fixed(3, vec![1, 2, 3])).unwrap(), + JsonValue::try_from(Value::Fixed(3, vec![1, 2, 3]))?, JsonValue::Array(vec![ JsonValue::Number(1.into()), JsonValue::Number(2.into()), @@ -1698,12 +1719,12 @@ Field with name '"b"' is not a member of the map items"#, ]) ); assert_eq!( - JsonValue::try_from(Value::Enum(1, "test_enum".into())).unwrap(), + JsonValue::try_from(Value::Enum(1, "test_enum".into()))?, JsonValue::String("test_enum".into()) ); assert_eq!( JsonValue::try_from(Value::Union(1, Box::new(Value::String("test_enum".into())))) - .unwrap(), + ?, JsonValue::String("test_enum".into()) ); assert_eq!( @@ -1712,7 +1733,7 @@ Field with name '"b"' is not a member of the map items"#, Value::Int(2), Value::Int(3) ])) - .unwrap(), + ?, JsonValue::Array(vec![ JsonValue::Number(1.into()), JsonValue::Number(2.into()), @@ -1729,7 +1750,7 @@ Field with name '"b"' is not a member of the map items"#, .into_iter() .collect() )) - .unwrap(), + ?, JsonValue::Object( vec![ ("v1".to_string(), JsonValue::Number(1.into())), @@ -1746,7 +1767,7 @@ Field with name '"b"' is not a member of the map items"#, ("v2".to_string(), Value::Int(2)), ("v3".to_string(), Value::Int(3)) ])) - .unwrap(), + ?, JsonValue::Object( vec![ ("v1".to_string(), JsonValue::Number(1.into())), @@ -1758,11 +1779,11 @@ Field with name '"b"' is not a member of the map items"#, ) ); assert_eq!( - JsonValue::try_from(Value::Date(1)).unwrap(), + JsonValue::try_from(Value::Date(1))?, JsonValue::Number(1.into()) ); assert_eq!( - JsonValue::try_from(Value::Decimal(vec![1, 2, 3].into())).unwrap(), + JsonValue::try_from(Value::Decimal(vec![1, 2, 3].into()))?, JsonValue::Array(vec![ JsonValue::Number(1.into()), JsonValue::Number(2.into()), @@ -1770,26 +1791,26 @@ Field with name '"b"' is not a member of the map items"#, ]) ); assert_eq!( - JsonValue::try_from(Value::TimeMillis(1)).unwrap(), + JsonValue::try_from(Value::TimeMillis(1))?, JsonValue::Number(1.into()) ); assert_eq!( - JsonValue::try_from(Value::TimeMicros(1)).unwrap(), + JsonValue::try_from(Value::TimeMicros(1))?, JsonValue::Number(1.into()) ); assert_eq!( - JsonValue::try_from(Value::TimestampMillis(1)).unwrap(), + JsonValue::try_from(Value::TimestampMillis(1))?, JsonValue::Number(1.into()) ); assert_eq!( - JsonValue::try_from(Value::TimestampMicros(1)).unwrap(), + JsonValue::try_from(Value::TimestampMicros(1))?, JsonValue::Number(1.into()) ); assert_eq!( JsonValue::try_from(Value::Duration( [1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8].into() )) - .unwrap(), + ?, JsonValue::Array(vec![ JsonValue::Number(1.into()), JsonValue::Number(2.into()), @@ -1807,15 +1828,17 @@ Field with name '"b"' is not a member of the map items"#, ); assert_eq!( JsonValue::try_from(Value::Uuid( - Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8").unwrap() + Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")? )) - .unwrap(), + ?, JsonValue::String("936da01f-9abd-4d9d-80c7-02af85c822a8".into()) ); + + Ok(()) } #[test] - fn test_avro_3433_recursive_resolves_record() { + fn test_avro_3433_recursive_resolves_record() -> TestResult { let schema = Schema::parse_str( r#" { @@ -1840,7 +1863,7 @@ Field with name '"b"' is not a member of the map items"#, ] }"#, ) - .unwrap(); + ?; let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]); let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]); @@ -1848,10 +1871,12 @@ Field with name '"b"' is not a member of the map items"#, outer .resolve(&schema) .expect("Record definition defined in one field must be available in other field"); + + Ok(()) } #[test] - fn test_avro_3433_recursive_resolves_array() { + fn test_avro_3433_recursive_resolves_array() -> TestResult { let schema = Schema::parse_str( r#" { @@ -1882,7 +1907,7 @@ Field with name '"b"' is not a member of the map items"#, ] }"#, ) - .unwrap(); + ?; let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]); let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]); @@ -1896,10 +1921,12 @@ Field with name '"b"' is not a member of the map items"#, outer_value .resolve(&schema) .expect("Record defined in array definition must be resolvable from map"); + + Ok(()) } #[test] - fn test_avro_3433_recursive_resolves_map() { + fn test_avro_3433_recursive_resolves_map() -> TestResult { let schema = Schema::parse_str( r#" { @@ -1927,7 +1954,7 @@ Field with name '"b"' is not a member of the map items"#, ] }"#, ) - .unwrap(); + ?; let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]); let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]); @@ -1941,10 +1968,12 @@ Field with name '"b"' is not a member of the map items"#, outer_value .resolve(&schema) .expect("Record defined in record field must be resolvable from map field"); + + Ok(()) } #[test] - fn test_avro_3433_recursive_resolves_record_wrapper() { + fn test_avro_3433_recursive_resolves_record_wrapper() -> TestResult { let schema = Schema::parse_str( r#" { @@ -1976,7 +2005,7 @@ Field with name '"b"' is not a member of the map items"#, ] }"#, ) - .unwrap(); + ?; let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]); let inner_value2 = Value::Record(vec![( @@ -1986,10 +2015,12 @@ Field with name '"b"' is not a member of the map items"#, let outer_value = Value::Record(vec![("a".into(), inner_value1), ("b".into(), inner_value2)]); outer_value.resolve(&schema).expect("Record schema defined in field must be resolvable in Record schema defined in other field"); + + Ok(()) } #[test] - fn test_avro_3433_recursive_resolves_map_and_array() { + fn test_avro_3433_recursive_resolves_map_and_array() -> TestResult { let schema = Schema::parse_str( r#" { @@ -2020,7 +2051,7 @@ Field with name '"b"' is not a member of the map items"#, ] }"#, ) - .unwrap(); + ?; let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]); let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]); @@ -2034,10 +2065,12 @@ Field with name '"b"' is not a member of the map items"#, outer_value .resolve(&schema) .expect("Record defined in map definition must be resolvable from array"); + + Ok(()) } #[test] - fn test_avro_3433_recursive_resolves_union() { + fn test_avro_3433_recursive_resolves_union() -> TestResult { let schema = Schema::parse_str( r#" { @@ -2062,7 +2095,7 @@ Field with name '"b"' is not a member of the map items"#, ] }"#, ) - .unwrap(); + ?; let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]); let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]); @@ -2077,10 +2110,12 @@ Field with name '"b"' is not a member of the map items"#, outer2 .resolve(&schema) .expect("Record definition defined in union must be resolved in other field"); + + Ok(()) } #[test] - fn test_avro_3461_test_multi_level_resolve_outer_namespace() { + fn test_avro_3461_test_multi_level_resolve_outer_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -2122,7 +2157,7 @@ Field with name '"b"' is not a member of the map items"#, ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]); let middle_record_variation_1 = Value::Record(vec![( "middle_field_1".into(), @@ -2163,10 +2198,12 @@ Field with name '"b"' is not a member of the map items"#, outer_record_variation_3 .resolve(&schema) .expect("Should be able to resolve value to the schema that is it's definition"); + + Ok(()) } #[test] - fn test_avro_3461_test_multi_level_resolve_middle_namespace() { + fn test_avro_3461_test_multi_level_resolve_middle_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -2209,7 +2246,7 @@ Field with name '"b"' is not a member of the map items"#, ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]); let middle_record_variation_1 = Value::Record(vec![( "middle_field_1".into(), @@ -2250,10 +2287,12 @@ Field with name '"b"' is not a member of the map items"#, outer_record_variation_3 .resolve(&schema) .expect("Should be able to resolve value to the schema that is it's definition"); + + Ok(()) } #[test] - fn test_avro_3461_test_multi_level_resolve_inner_namespace() { + fn test_avro_3461_test_multi_level_resolve_inner_namespace() -> TestResult { let schema = r#" { "name": "record_name", @@ -2297,7 +2336,7 @@ Field with name '"b"' is not a member of the map items"#, ] } "#; - let schema = Schema::parse_str(schema).unwrap(); + let schema = Schema::parse_str(schema)?; let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]); let middle_record_variation_1 = Value::Record(vec![( @@ -2339,10 +2378,12 @@ Field with name '"b"' is not a member of the map items"#, outer_record_variation_3 .resolve(&schema) .expect("Should be able to resolve value to the schema that is it's definition"); + + Ok(()) } #[test] - fn test_avro_3460_validation_with_refs() { + fn test_avro_3460_validation_with_refs() -> TestResult { let schema = Schema::parse_str( r#" { @@ -2367,7 +2408,7 @@ Field with name '"b"' is not a member of the map items"#, ] }"#, ) - .unwrap(); + ?; let inner_value_right = Value::Record(vec![("z".into(), Value::Int(3))]); let inner_value_wrong1 = Value::Record(vec![("z".into(), Value::Null)]); @@ -2390,10 +2431,12 @@ Field with name '"b"' is not a member of the map items"#, !outer2.validate(&schema), "field b record is invalid against the schema" ); // this should pass, but doesn't + + Ok(()) } #[test] - fn test_avro_3460_validation_with_refs_real_struct() { + fn test_avro_3460_validation_with_refs_real_struct() -> TestResult { use crate::ser::Serializer; use serde::Serialize; @@ -2444,7 +2487,7 @@ Field with name '"b"' is not a member of the map items"#, ] }"#, ) - .unwrap(); + ?; let test_inner = TestInner { z: 3 }; let test_outer1 = TestRefSchemaStruct1 { @@ -2461,11 +2504,11 @@ Field with name '"b"' is not a member of the map items"#, }; let mut ser = Serializer::default(); - let test_outer1: Value = test_outer1.serialize(&mut ser).unwrap(); + let test_outer1: Value = test_outer1.serialize(&mut ser)?; let mut ser = Serializer::default(); - let test_outer2: Value = test_outer2.serialize(&mut ser).unwrap(); + let test_outer2: Value = test_outer2.serialize(&mut ser)?; let mut ser = Serializer::default(); - let test_outer3: Value = test_outer3.serialize(&mut ser).unwrap(); + let test_outer3: Value = test_outer3.serialize(&mut ser)?; assert!( !test_outer1.validate(&schema), @@ -2479,9 +2522,11 @@ Field with name '"b"' is not a member of the map items"#, !test_outer3.validate(&schema), "field b record is invalid against the schema" ); + + Ok(()) } - fn avro_3674_with_or_without_namespace(with_namespace: bool) { + fn avro_3674_with_or_without_namespace(with_namespace: bool) -> TestResult { use crate::ser::Serializer; use serde::Serialize; @@ -2523,7 +2568,7 @@ Field with name '"b"' is not a member of the map items"#, }, ); - let schema = Schema::parse_str(&schema_str).unwrap(); + let schema = Schema::parse_str(&schema_str)?; #[derive(Serialize)] enum EnumType { @@ -2552,25 +2597,27 @@ Field with name '"b"' is not a member of the map items"#, }; let mut ser = Serializer::default(); - let test_value: Value = msg.serialize(&mut ser).unwrap(); + let test_value: Value = msg.serialize(&mut ser)?; assert!(test_value.validate(&schema), "test_value should validate"); assert!( test_value.resolve(&schema).is_ok(), "test_value should resolve" ); + + Ok(()) } #[test] - fn test_avro_3674_validate_no_namespace_resolution() { - avro_3674_with_or_without_namespace(false); + fn test_avro_3674_validate_no_namespace_resolution() -> TestResult { + avro_3674_with_or_without_namespace(false) } #[test] - fn test_avro_3674_validate_with_namespace_resolution() { - avro_3674_with_or_without_namespace(true); + fn test_avro_3674_validate_with_namespace_resolution() -> TestResult { + avro_3674_with_or_without_namespace(true) } - fn avro_3688_schema_resolution_panic(set_field_b: bool) { + fn avro_3688_schema_resolution_panic(set_field_b: bool) -> TestResult { use crate::ser::Serializer; use serde::{Deserialize, Serialize}; @@ -2617,7 +2664,7 @@ Field with name '"b"' is not a member of the map items"#, field_b: Option, } - let schema = Schema::parse_str(schema_str).unwrap(); + let schema = Schema::parse_str(schema_str)?; let msg = Message { field_a: Some(Inner { @@ -2633,26 +2680,28 @@ Field with name '"b"' is not a member of the map items"#, }; let mut ser = Serializer::default(); - let test_value: Value = msg.serialize(&mut ser).unwrap(); + let test_value: Value = msg.serialize(&mut ser)?; assert!(test_value.validate(&schema), "test_value should validate"); assert!( test_value.resolve(&schema).is_ok(), "test_value should resolve" ); + + Ok(()) } #[test] - fn test_avro_3688_field_b_not_set() { - avro_3688_schema_resolution_panic(false); + fn test_avro_3688_field_b_not_set()-> TestResult { + avro_3688_schema_resolution_panic(false) } #[test] - fn test_avro_3688_field_b_set() { - avro_3688_schema_resolution_panic(true); + fn test_avro_3688_field_b_set()-> TestResult { + avro_3688_schema_resolution_panic(true) } #[test] - fn test_avro_3764_use_resolve_schemata() { + fn test_avro_3764_use_resolve_schemata() -> TestResult { let referenced_schema = r#"{"name": "enumForReference", "type": "enum", "symbols": ["A", "B"]}"#; let main_schema = r#"{"name": "recordWithReference", "type": "record", "fields": [{"name": "reference", "type": "enumForReference"}]}"#; @@ -2663,19 +2712,18 @@ Field with name '"b"' is not a member of the map items"#, "reference": "A" } "#, - ) - .unwrap(); + )?; let avro_value = Value::from(value); - let schemas = Schema::parse_list(&[main_schema, referenced_schema]).unwrap(); + let schemas = Schema::parse_list(&[main_schema, referenced_schema])?; let main_schema = schemas.get(0).unwrap(); let schemata: Vec<_> = schemas.iter().skip(1).collect(); let resolve_result = avro_value .clone() - .resolve_schemata(main_schema, schemata.clone()); + .resolve_schemata(main_schema, schemata); assert!( resolve_result.is_ok(), @@ -2689,5 +2737,7 @@ Field with name '"b"' is not a member of the map items"#, "result of resolving without schemata should be err, got: {:?}", resolve_result ); + + Ok(()) } } diff --git a/lang/rust/avro/src/util.rs b/lang/rust/avro/src/util.rs index d94acce7a85..5ce901ed4b7 100644 --- a/lang/rust/avro/src/util.rs +++ b/lang/rust/avro/src/util.rs @@ -188,6 +188,7 @@ pub(crate) fn is_human_readable() -> bool { mod tests { use super::*; use pretty_assertions::assert_eq; + use apache_avro_test_helper::TestResult; #[test] fn test_zigzag() { @@ -280,8 +281,10 @@ mod tests { } #[test] - fn test_safe_len() { - assert_eq!(42usize, safe_len(42usize).unwrap()); + fn test_safe_len() -> TestResult { + assert_eq!(42usize, safe_len(42usize)?); assert!(safe_len(1024 * 1024 * 1024).is_err()); + + Ok(()) } } diff --git a/lang/rust/avro/src/writer.rs b/lang/rust/avro/src/writer.rs index 58d13d40f06..83e863455f2 100644 --- a/lang/rust/avro/src/writer.rs +++ b/lang/rust/avro/src/writer.rs @@ -639,6 +639,8 @@ mod tests { use pretty_assertions::assert_eq; use serde::{Deserialize, Serialize}; + use apache_avro_test_helper::TestResult; + const AVRO_OBJECT_HEADER_LEN: usize = AVRO_OBJECT_HEADER.len(); const SCHEMA: &str = r#" @@ -661,8 +663,8 @@ mod tests { const UNION_SCHEMA: &str = r#"["null", "long"]"#; #[test] - fn test_to_avro_datum() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_to_avro_datum() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let mut record = Record::new(&schema).unwrap(); record.put("a", 27i64); record.put("b", "foo"); @@ -672,33 +674,37 @@ mod tests { zig_i64(3, &mut expected); expected.extend(vec![b'f', b'o', b'o'].into_iter()); - assert_eq!(to_avro_datum(&schema, record).unwrap(), expected); + assert_eq!(to_avro_datum(&schema, record)?, expected); + + Ok(()) } #[test] - fn test_union_not_null() { - let schema = Schema::parse_str(UNION_SCHEMA).unwrap(); + fn test_union_not_null() -> TestResult { + let schema = Schema::parse_str(UNION_SCHEMA)?; let union = Value::Union(1, Box::new(Value::Long(3))); let mut expected = Vec::new(); zig_i64(1, &mut expected); zig_i64(3, &mut expected); - assert_eq!(to_avro_datum(&schema, union).unwrap(), expected); + assert_eq!(to_avro_datum(&schema, union)?, expected); + + Ok(()) } #[test] - fn test_union_null() { - let schema = Schema::parse_str(UNION_SCHEMA).unwrap(); + fn test_union_null() -> TestResult { + let schema = Schema::parse_str(UNION_SCHEMA)?; let union = Value::Union(0, Box::new(Value::Null)); let mut expected = Vec::new(); zig_i64(0, &mut expected); - assert_eq!(to_avro_datum(&schema, union).unwrap(), expected); - } + assert_eq!(to_avro_datum(&schema, union)?, expected); - type TestResult = anyhow::Result>; + Ok(()) + } fn logical_type_test + Clone>( schema_str: &'static str, @@ -708,7 +714,7 @@ mod tests { raw_schema: &Schema, raw_value: T, - ) -> TestResult<()> { + ) -> TestResult { let schema = Schema::parse_str(schema_str)?; assert_eq!(&schema, expected_schema); // The serialized format should be the same as the schema. @@ -718,13 +724,13 @@ mod tests { // Should deserialize from the schema into the logical type. let mut r = ser.as_slice(); - let de = crate::from_avro_datum(&schema, &mut r, None).unwrap(); + let de = crate::from_avro_datum(&schema, &mut r, None)?; assert_eq!(de, value); Ok(()) } #[test] - fn date() -> TestResult<()> { + fn date() -> TestResult { logical_type_test( r#"{"type": "int", "logicalType": "date"}"#, &Schema::Date, @@ -735,7 +741,7 @@ mod tests { } #[test] - fn time_millis() -> TestResult<()> { + fn time_millis() -> TestResult { logical_type_test( r#"{"type": "int", "logicalType": "time-millis"}"#, &Schema::TimeMillis, @@ -746,7 +752,7 @@ mod tests { } #[test] - fn time_micros() -> TestResult<()> { + fn time_micros() -> TestResult { logical_type_test( r#"{"type": "long", "logicalType": "time-micros"}"#, &Schema::TimeMicros, @@ -757,7 +763,7 @@ mod tests { } #[test] - fn timestamp_millis() -> TestResult<()> { + fn timestamp_millis() -> TestResult { logical_type_test( r#"{"type": "long", "logicalType": "timestamp-millis"}"#, &Schema::TimestampMillis, @@ -768,7 +774,7 @@ mod tests { } #[test] - fn timestamp_micros() -> TestResult<()> { + fn timestamp_micros() -> TestResult { logical_type_test( r#"{"type": "long", "logicalType": "timestamp-micros"}"#, &Schema::TimestampMicros, @@ -779,10 +785,10 @@ mod tests { } #[test] - fn decimal_fixed() -> TestResult<()> { + fn decimal_fixed() -> TestResult { let size = 30; let inner = Schema::Fixed(FixedSchema { - name: Name::new("decimal").unwrap(), + name: Name::new("decimal")?, aliases: None, doc: None, size, @@ -803,7 +809,7 @@ mod tests { } #[test] - fn decimal_bytes() -> TestResult<()> { + fn decimal_bytes() -> TestResult { let inner = Schema::Bytes; let value = vec![0u8; 10]; logical_type_test( @@ -820,9 +826,9 @@ mod tests { } #[test] - fn duration() -> TestResult<()> { + fn duration() -> TestResult { let inner = Schema::Fixed(FixedSchema { - name: Name::new("duration").unwrap(), + name: Name::new("duration")?, aliases: None, doc: None, size: 12, @@ -843,18 +849,18 @@ mod tests { } #[test] - fn test_writer_append() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_writer_append() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let mut writer = Writer::new(&schema, Vec::new()); let mut record = Record::new(&schema).unwrap(); record.put("a", 27i64); record.put("b", "foo"); - let n1 = writer.append(record.clone()).unwrap(); - let n2 = writer.append(record.clone()).unwrap(); - let n3 = writer.flush().unwrap(); - let result = writer.into_inner().unwrap(); + let n1 = writer.append(record.clone())?; + let n2 = writer.append(record.clone())?; + let n3 = writer.flush()?; + let result = writer.into_inner()?; assert_eq!(n1 + n2 + n3, result.len()); @@ -872,11 +878,13 @@ mod tests { &result[last_data_byte - data.len()..last_data_byte], data.as_slice() ); + + Ok(()) } #[test] - fn test_writer_extend() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_writer_extend() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let mut writer = Writer::new(&schema, Vec::new()); let mut record = Record::new(&schema).unwrap(); @@ -885,9 +893,9 @@ mod tests { let record_copy = record.clone(); let records = vec![record, record_copy]; - let n1 = writer.extend(records.into_iter()).unwrap(); - let n2 = writer.flush().unwrap(); - let result = writer.into_inner().unwrap(); + let n1 = writer.extend(records.into_iter())?; + let n2 = writer.flush()?; + let result = writer.into_inner()?; assert_eq!(n1 + n2, result.len()); @@ -905,6 +913,8 @@ mod tests { &result[last_data_byte - data.len()..last_data_byte], data.as_slice() ); + + Ok(()) } #[derive(Debug, Clone, Deserialize, Serialize)] @@ -914,8 +924,8 @@ mod tests { } #[test] - fn test_writer_append_ser() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_writer_append_ser() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let mut writer = Writer::new(&schema, Vec::new()); let record = TestSerdeSerialize { @@ -923,9 +933,9 @@ mod tests { b: "foo".to_owned(), }; - let n1 = writer.append_ser(record).unwrap(); - let n2 = writer.flush().unwrap(); - let result = writer.into_inner().unwrap(); + let n1 = writer.append_ser(record)?; + let n2 = writer.flush()?; + let result = writer.into_inner()?; assert_eq!(n1 + n2, result.len()); @@ -942,11 +952,13 @@ mod tests { &result[last_data_byte - data.len()..last_data_byte], data.as_slice() ); + + Ok(()) } #[test] - fn test_writer_extend_ser() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_writer_extend_ser() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let mut writer = Writer::new(&schema, Vec::new()); let record = TestSerdeSerialize { @@ -956,9 +968,9 @@ mod tests { let record_copy = record.clone(); let records = vec![record, record_copy]; - let n1 = writer.extend_ser(records.into_iter()).unwrap(); - let n2 = writer.flush().unwrap(); - let result = writer.into_inner().unwrap(); + let n1 = writer.extend_ser(records.into_iter())?; + let n2 = writer.flush()?; + let result = writer.into_inner()?; assert_eq!(n1 + n2, result.len()); @@ -976,6 +988,8 @@ mod tests { &result[last_data_byte - data.len()..last_data_byte], data.as_slice() ); + + Ok(()) } fn make_writer_with_codec(schema: &Schema) -> Writer<'_, Vec> { @@ -991,15 +1005,15 @@ mod tests { .build() } - fn check_writer(mut writer: Writer<'_, Vec>, schema: &Schema) { + fn check_writer(mut writer: Writer<'_, Vec>, schema: &Schema) -> TestResult { let mut record = Record::new(schema).unwrap(); record.put("a", 27i64); record.put("b", "foo"); - let n1 = writer.append(record.clone()).unwrap(); - let n2 = writer.append(record.clone()).unwrap(); - let n3 = writer.flush().unwrap(); - let result = writer.into_inner().unwrap(); + let n1 = writer.append(record.clone())?; + let n2 = writer.append(record.clone())?; + let n3 = writer.flush()?; + let result = writer.into_inner()?; assert_eq!(n1 + n2 + n3, result.len()); @@ -1008,7 +1022,7 @@ mod tests { zig_i64(3, &mut data); data.extend(b"foo"); data.extend(data.clone()); - Codec::Deflate.compress(&mut data).unwrap(); + Codec::Deflate.compress(&mut data)?; // starts with magic assert_eq!(&result[..AVRO_OBJECT_HEADER_LEN], AVRO_OBJECT_HEADER); @@ -1018,24 +1032,26 @@ mod tests { &result[last_data_byte - data.len()..last_data_byte], data.as_slice() ); + + Ok(()) } #[test] - fn test_writer_with_codec() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_writer_with_codec() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let writer = make_writer_with_codec(&schema); - check_writer(writer, &schema); + check_writer(writer, &schema) } #[test] - fn test_writer_with_builder() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_writer_with_builder() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let writer = make_writer_with_builder(&schema); - check_writer(writer, &schema); + check_writer(writer, &schema) } #[test] - fn test_logical_writer() { + fn test_logical_writer() -> TestResult { const LOGICAL_TYPE_SCHEMA: &str = r#" { "type": "record", @@ -1055,7 +1071,7 @@ mod tests { } "#; let codec = Codec::Deflate; - let schema = Schema::parse_str(LOGICAL_TYPE_SCHEMA).unwrap(); + let schema = Schema::parse_str(LOGICAL_TYPE_SCHEMA)?; let mut writer = Writer::builder() .schema(&schema) .codec(codec) @@ -1071,10 +1087,10 @@ mod tests { let mut record2 = Record::new(&schema).unwrap(); record2.put("a", Value::Union(0, Box::new(Value::Null))); - let n1 = writer.append(record1).unwrap(); - let n2 = writer.append(record2).unwrap(); - let n3 = writer.flush().unwrap(); - let result = writer.into_inner().unwrap(); + let n1 = writer.append(record1)?; + let n2 = writer.append(record2)?; + let n3 = writer.flush()?; + let result = writer.into_inner()?; assert_eq!(n1 + n2 + n3, result.len()); @@ -1085,7 +1101,7 @@ mod tests { // byte indicating null zig_i64(0, &mut data); - codec.compress(&mut data).unwrap(); + codec.compress(&mut data)?; // starts with magic assert_eq!(&result[..AVRO_OBJECT_HEADER_LEN], AVRO_OBJECT_HEADER); @@ -1095,47 +1111,43 @@ mod tests { &result[last_data_byte - data.len()..last_data_byte], data.as_slice() ); + + Ok(()) } #[test] - fn test_avro_3405_writer_add_metadata_success() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_avro_3405_writer_add_metadata_success() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let mut writer = Writer::new(&schema, Vec::new()); - writer - .add_user_metadata("stringKey".to_string(), String::from("stringValue")) - .unwrap(); - writer - .add_user_metadata("strKey".to_string(), "strValue") - .unwrap(); - writer - .add_user_metadata("bytesKey".to_string(), b"bytesValue") - .unwrap(); - writer - .add_user_metadata("vecKey".to_string(), vec![1, 2, 3]) - .unwrap(); + writer.add_user_metadata("stringKey".to_string(), String::from("stringValue"))?; + writer.add_user_metadata("strKey".to_string(), "strValue")?; + writer.add_user_metadata("bytesKey".to_string(), b"bytesValue")?; + writer.add_user_metadata("vecKey".to_string(), vec![1, 2, 3])?; let mut record = Record::new(&schema).unwrap(); record.put("a", 27i64); record.put("b", "foo"); - writer.append(record.clone()).unwrap(); - writer.append(record.clone()).unwrap(); - writer.flush().unwrap(); - let result = writer.into_inner().unwrap(); + writer.append(record.clone())?; + writer.append(record.clone())?; + writer.flush()?; + let result = writer.into_inner()?; assert_eq!(result.len(), 260); + + Ok(()) } #[test] - fn test_avro_3405_writer_add_metadata_failure() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_avro_3405_writer_add_metadata_failure() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let mut writer = Writer::new(&schema, Vec::new()); let mut record = Record::new(&schema).unwrap(); record.put("a", 27i64); record.put("b", "foo"); - writer.append(record.clone()).unwrap(); + writer.append(record.clone())?; match writer.add_user_metadata("stringKey".to_string(), String::from("value2")) { Err(e @ Error::FileHeaderAlreadyWritten) => { @@ -1144,11 +1156,13 @@ mod tests { Err(e) => panic!("Unexpected error occurred while writing user metadata: {e:?}"), Ok(_) => panic!("Expected an error that metadata cannot be added after adding data"), } + + Ok(()) } #[test] - fn test_avro_3405_writer_add_metadata_reserved_prefix_failure() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_avro_3405_writer_add_metadata_reserved_prefix_failure() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let mut writer = Writer::new(&schema, Vec::new()); let key = "avro.stringKey".to_string(); @@ -1161,11 +1175,13 @@ mod tests { ), Ok(_) => panic!("Expected an error that the metadata key cannot be prefixed with 'avro.'"), } + + Ok(()) } #[test] - fn test_avro_3405_writer_add_metadata_with_builder_api_success() { - let schema = Schema::parse_str(SCHEMA).unwrap(); + fn test_avro_3405_writer_add_metadata_with_builder_api_success() -> TestResult { + let schema = Schema::parse_str(SCHEMA)?; let mut user_meta_data: HashMap = HashMap::new(); user_meta_data.insert( @@ -1182,6 +1198,8 @@ mod tests { .build(); assert_eq!(writer.user_metadata, user_meta_data); + + Ok(()) } #[derive(Serialize, Clone)] @@ -1234,7 +1252,7 @@ mod tests { } #[test] - fn test_single_object_writer() { + fn test_single_object_writer() -> TestResult { let mut buf: Vec = Vec::new(); let obj = TestSingleObjectWriter { a: 300, @@ -1268,11 +1286,13 @@ mod tests { &mut msg_binary, ) .expect("encode should have failed by here as a dependency of any writing"); - assert_eq!(&buf[10..], &msg_binary[..]) + assert_eq!(&buf[10..], &msg_binary[..]); + + Ok(()) } #[test] - fn test_writer_parity() { + fn test_writer_parity() -> TestResult { let obj1 = TestSingleObjectWriter { a: 300, b: 34.555, @@ -1302,5 +1322,7 @@ mod tests { .expect("Serialization expected"); assert_eq!(buf1, buf2); assert_eq!(buf1, buf3); + + Ok(()) } } diff --git a/lang/rust/avro/tests/append_to_existing.rs b/lang/rust/avro/tests/append_to_existing.rs index 7b3874746bd..2ea59d95c56 100644 --- a/lang/rust/avro/tests/append_to_existing.rs +++ b/lang/rust/avro/tests/append_to_existing.rs @@ -20,9 +20,10 @@ use apache_avro::{ types::{Record, Value}, AvroResult, Reader, Schema, Writer, }; +use apache_avro_test_helper::TestResult; #[test] -fn avro_3630_append_to_an_existing_file() { +fn avro_3630_append_to_an_existing_file() -> TestResult { let schema_str = r#" { "type": "record", @@ -53,6 +54,8 @@ fn avro_3630_append_to_an_existing_file() { check(value, i); i += 1 } + + Ok(()) } /// Simulates reading from a pre-existing .avro file and returns its bytes diff --git a/lang/rust/avro/tests/io.rs b/lang/rust/avro/tests/io.rs index 9d3dc7b79f3..7c3d5e9613b 100644 --- a/lang/rust/avro/tests/io.rs +++ b/lang/rust/avro/tests/io.rs @@ -20,6 +20,7 @@ use apache_avro::{from_avro_datum, to_avro_datum, types::Value, Error, Schema}; use lazy_static::lazy_static; use pretty_assertions::assert_eq; use std::io::Cursor; +use apache_avro_test_helper::TestResult; lazy_static! { static ref SCHEMAS_TO_VALIDATE: Vec<(&'static str, Value)> = vec![ @@ -99,44 +100,52 @@ lazy_static! { } #[test] -fn test_validate() { +fn test_validate() -> TestResult { for (raw_schema, value) in SCHEMAS_TO_VALIDATE.iter() { - let schema = Schema::parse_str(raw_schema).unwrap(); + let schema = Schema::parse_str(raw_schema)?; assert!( value.validate(&schema), "value {value:?} does not validate schema: {raw_schema}" ); } + + Ok(()) } #[test] -fn test_round_trip() { +fn test_round_trip() -> TestResult { for (raw_schema, value) in SCHEMAS_TO_VALIDATE.iter() { - let schema = Schema::parse_str(raw_schema).unwrap(); + let schema = Schema::parse_str(raw_schema)?; let encoded = to_avro_datum(&schema, value.clone()).unwrap(); let decoded = from_avro_datum(&schema, &mut Cursor::new(encoded), None).unwrap(); assert_eq!(value, &decoded); } + + Ok(()) } #[test] -fn test_binary_int_encoding() { +fn test_binary_int_encoding() -> TestResult { for (number, hex_encoding) in BINARY_ENCODINGS.iter() { - let encoded = to_avro_datum(&Schema::Int, Value::Int(*number as i32)).unwrap(); + let encoded = to_avro_datum(&Schema::Int, Value::Int(*number as i32))?; assert_eq!(&encoded, hex_encoding); } + + Ok(()) } #[test] -fn test_binary_long_encoding() { +fn test_binary_long_encoding() -> TestResult { for (number, hex_encoding) in BINARY_ENCODINGS.iter() { - let encoded = to_avro_datum(&Schema::Long, Value::Long(*number)).unwrap(); + let encoded = to_avro_datum(&Schema::Long, Value::Long(*number))?; assert_eq!(&encoded, hex_encoding); } + + Ok(()) } #[test] -fn test_schema_promotion() { +fn test_schema_promotion() -> TestResult { // Each schema is present in order of promotion (int -> long, long -> float, float -> double) // Each value represents the expected decoded value when promoting a value previously encoded with a promotable schema let promotable_schemas = vec![r#""int""#, r#""long""#, r#""float""#, r#""double""#]; @@ -147,11 +156,11 @@ fn test_schema_promotion() { Value::Double(219.0), ]; for (i, writer_raw_schema) in promotable_schemas.iter().enumerate() { - let writer_schema = Schema::parse_str(writer_raw_schema).unwrap(); + let writer_schema = Schema::parse_str(writer_raw_schema)?; let original_value = &promotable_values[i]; for (j, reader_raw_schema) in promotable_schemas.iter().enumerate().skip(i + 1) { - let reader_schema = Schema::parse_str(reader_raw_schema).unwrap(); - let encoded = to_avro_datum(&writer_schema, original_value.clone()).unwrap(); + let reader_schema = Schema::parse_str(reader_raw_schema)?; + let encoded = to_avro_datum(&writer_schema, original_value.clone())?; let decoded = from_avro_datum( &writer_schema, &mut Cursor::new(encoded), @@ -163,28 +172,30 @@ fn test_schema_promotion() { assert_eq!(decoded, promotable_values[j]); } } + + Ok(()) } #[test] -fn test_unknown_symbol() { +fn test_unknown_symbol() -> TestResult { let writer_schema = - Schema::parse_str(r#"{"type": "enum", "name": "Test", "symbols": ["FOO", "BAR"]}"#) - .unwrap(); + Schema::parse_str(r#"{"type": "enum", "name": "Test", "symbols": ["FOO", "BAR"]}"#)?; let reader_schema = - Schema::parse_str(r#"{"type": "enum", "name": "Test", "symbols": ["BAR", "BAZ"]}"#) - .unwrap(); + Schema::parse_str(r#"{"type": "enum", "name": "Test", "symbols": ["BAR", "BAZ"]}"#)?; let original_value = Value::Enum(0, "FOO".to_string()); - let encoded = to_avro_datum(&writer_schema, original_value).unwrap(); + let encoded = to_avro_datum(&writer_schema, original_value)?; let decoded = from_avro_datum( &writer_schema, &mut Cursor::new(encoded), Some(&reader_schema), ); assert!(decoded.is_err()); + + Ok(()) } #[test] -fn test_default_value() { +fn test_default_value() -> TestResult { for (field_type, default_json, default_datum) in DEFAULT_VALUE_EXAMPLES.iter() { let reader_schema = Schema::parse_str(&format!( r#"{{ @@ -194,26 +205,26 @@ fn test_default_value() { {{"name": "H", "type": {field_type}, "default": {default_json}}} ] }}"# - )) - .unwrap(); + ))?; let datum_to_read = Value::Record(vec![("H".to_string(), default_datum.clone())]); - let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone()).unwrap(); + let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone())?; let datum_read = from_avro_datum( &LONG_RECORD_SCHEMA, &mut Cursor::new(encoded), Some(&reader_schema), - ) - .unwrap(); + )?; assert_eq!( datum_read, datum_to_read, "{} -> {}", *field_type, *default_json ); } + + Ok(()) } #[test] -fn test_no_default_value() { +fn test_no_default_value() -> TestResult { let reader_schema = Schema::parse_str( r#"{ "type": "record", @@ -222,19 +233,20 @@ fn test_no_default_value() { {"name": "H", "type": "int"} ] }"#, - ) - .unwrap(); - let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone()).unwrap(); + )?; + let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone())?; let result = from_avro_datum( &LONG_RECORD_SCHEMA, &mut Cursor::new(encoded), Some(&reader_schema), ); assert!(result.is_err()); + + Ok(()) } #[test] -fn test_projection() { +fn test_projection() -> TestResult { let reader_schema = Schema::parse_str( r#" { @@ -246,24 +258,24 @@ fn test_projection() { ] } "#, - ) - .unwrap(); + )?; let datum_to_read = Value::Record(vec![ ("E".to_string(), Value::Int(5)), ("F".to_string(), Value::Int(6)), ]); - let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone()).unwrap(); + let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone())?; let datum_read = from_avro_datum( &LONG_RECORD_SCHEMA, &mut Cursor::new(encoded), Some(&reader_schema), - ) - .unwrap(); + )?; assert_eq!(datum_to_read, datum_read); + + Ok(()) } #[test] -fn test_field_order() { +fn test_field_order() -> TestResult { let reader_schema = Schema::parse_str( r#" { @@ -275,20 +287,20 @@ fn test_field_order() { ] } "#, - ) - .unwrap(); + )?; let datum_to_read = Value::Record(vec![ ("F".to_string(), Value::Int(6)), ("E".to_string(), Value::Int(5)), ]); - let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone()).unwrap(); + let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone())?; let datum_read = from_avro_datum( &LONG_RECORD_SCHEMA, &mut Cursor::new(encoded), Some(&reader_schema), - ) - .unwrap(); + )?; assert_eq!(datum_to_read, datum_read); + + Ok(()) } #[test] @@ -304,8 +316,7 @@ fn test_type_exception() -> Result<(), String> { ] } "#, - ) - .unwrap(); + ).unwrap(); let datum_to_write = Value::Record(vec![ ("E".to_string(), Value::Int(5)), ("F".to_string(), Value::String(String::from("Bad"))), diff --git a/lang/rust/avro/tests/schema.rs b/lang/rust/avro/tests/schema.rs index 5018dc5dd9d..46292daeaf0 100644 --- a/lang/rust/avro/tests/schema.rs +++ b/lang/rust/avro/tests/schema.rs @@ -21,7 +21,7 @@ use apache_avro::{ types::{Record, Value}, Codec, Error, Reader, Schema, Writer, }; -use apache_avro_test_helper::init; +use apache_avro_test_helper::{init, TestResult}; use lazy_static::lazy_static; const PRIMITIVE_EXAMPLES: &[(&str, bool)] = &[ @@ -612,7 +612,7 @@ lazy_static! { } #[test] -fn test_correct_recursive_extraction() { +fn test_correct_recursive_extraction() -> TestResult { init(); let raw_outer_schema = r#"{ "type": "record", @@ -633,7 +633,7 @@ fn test_correct_recursive_extraction() { } ] }"#; - let outer_schema = Schema::parse_str(raw_outer_schema).unwrap(); + let outer_schema = Schema::parse_str(raw_outer_schema)?; if let Schema::Record(RecordSchema { fields: outer_fields, .. @@ -658,10 +658,12 @@ fn test_correct_recursive_extraction() { } else { panic!("outer schema {outer_schema:?} should have been a record") } + + Ok(()) } #[test] -fn test_parse() { +fn test_parse() -> TestResult { init(); for (raw_schema, valid) in EXAMPLES.iter() { let schema = Schema::parse_str(raw_schema); @@ -677,36 +679,39 @@ fn test_parse() { ) } } + Ok(()) } #[test] /// Test that the string generated by an Avro Schema object is, in fact, a valid Avro schema. -fn test_valid_cast_to_string_after_parse() { +fn test_valid_cast_to_string_after_parse() -> TestResult { init(); for (raw_schema, _) in VALID_EXAMPLES.iter() { - let schema = Schema::parse_str(raw_schema).unwrap(); - Schema::parse_str(schema.canonical_form().as_str()).unwrap(); + let schema = Schema::parse_str(raw_schema)?; + Schema::parse_str(schema.canonical_form().as_str())?; } + Ok(()) } #[test] /// 1. Given a string, parse it to get Avro schema "original". /// 2. Serialize "original" to a string and parse that string to generate Avro schema "round trip". /// 3. Ensure "original" and "round trip" schemas are equivalent. -fn test_equivalence_after_round_trip() { +fn test_equivalence_after_round_trip() -> TestResult { init(); for (raw_schema, _) in VALID_EXAMPLES.iter() { - let original_schema = Schema::parse_str(raw_schema).unwrap(); + let original_schema = Schema::parse_str(raw_schema)?; let round_trip_schema = - Schema::parse_str(original_schema.canonical_form().as_str()).unwrap(); + Schema::parse_str(original_schema.canonical_form().as_str())?; assert_eq!(original_schema, round_trip_schema); } + Ok(()) } #[test] /// Test that a list of schemas whose definitions do not depend on each other produces the same /// result as parsing each element of the list individually -fn test_parse_list_without_cross_deps() { +fn test_parse_list_without_cross_deps() -> TestResult { init(); let schema_str_1 = r#"{ "name": "A", @@ -721,12 +726,13 @@ fn test_parse_list_without_cross_deps() { "size": 16 }"#; let schema_strs = [schema_str_1, schema_str_2]; - let schemas = Schema::parse_list(&schema_strs).expect("Test failed"); + let schemas = Schema::parse_list(&schema_strs)?; for schema_str in &schema_strs { - let parsed = Schema::parse_str(schema_str).expect("Test failed"); + let parsed = Schema::parse_str(schema_str)?; assert!(schemas.contains(&parsed)); } + Ok(()) } #[test] @@ -734,7 +740,7 @@ fn test_parse_list_without_cross_deps() { /// perform the necessary schema composition. This should work regardless of the order in which /// the schemas are input. /// However, the output order is guaranteed to be the same as the input order. -fn test_parse_list_with_cross_deps_basic() { +fn test_parse_list_with_cross_deps_basic() -> TestResult { init(); let schema_a_str = r#"{ "name": "A", @@ -753,15 +759,16 @@ fn test_parse_list_with_cross_deps_basic() { let schema_strs_first = [schema_a_str, schema_b_str]; let schema_strs_second = [schema_b_str, schema_a_str]; - let schemas_first = Schema::parse_list(&schema_strs_first).expect("Test failed"); - let schemas_second = Schema::parse_list(&schema_strs_second).expect("Test failed"); + let schemas_first = Schema::parse_list(&schema_strs_first)?; + let schemas_second = Schema::parse_list(&schema_strs_second)?; assert_eq!(schemas_first[0], schemas_second[1]); assert_eq!(schemas_first[1], schemas_second[0]); + Ok(()) } #[test] -fn test_parse_list_recursive_type() { +fn test_parse_list_recursive_type() -> TestResult { init(); let schema_str_1 = r#"{ "name": "A", @@ -781,13 +788,14 @@ fn test_parse_list_recursive_type() { }"#; let schema_strs_first = [schema_str_1, schema_str_2]; let schema_strs_second = [schema_str_2, schema_str_1]; - let _ = Schema::parse_list(&schema_strs_first).expect("Test failed"); - let _ = Schema::parse_list(&schema_strs_second).expect("Test failed"); + let _ = Schema::parse_list(&schema_strs_first)?; + let _ = Schema::parse_list(&schema_strs_second)?; + Ok(()) } #[test] /// Test that schema composition resolves namespaces. -fn test_parse_list_with_cross_deps_and_namespaces() { +fn test_parse_list_with_cross_deps_and_namespaces() -> TestResult { init(); let schema_a_str = r#"{ "name": "A", @@ -805,16 +813,18 @@ fn test_parse_list_with_cross_deps_and_namespaces() { ] }"#; - let schemas_first = Schema::parse_list(&[schema_a_str, schema_b_str]).expect("Test failed"); - let schemas_second = Schema::parse_list(&[schema_b_str, schema_a_str]).expect("Test failed"); + let schemas_first = Schema::parse_list(&[schema_a_str, schema_b_str])?; + let schemas_second = Schema::parse_list(&[schema_b_str, schema_a_str])?; assert_eq!(schemas_first[0], schemas_second[1]); assert_eq!(schemas_first[1], schemas_second[0]); + + Ok(()) } #[test] /// Test that schema composition fails on namespace errors. -fn test_parse_list_with_cross_deps_and_namespaces_error() { +fn test_parse_list_with_cross_deps_and_namespaces_error() -> TestResult { init(); let schema_str_1 = r#"{ "name": "A", @@ -836,12 +846,14 @@ fn test_parse_list_with_cross_deps_and_namespaces_error() { let schema_strs_second = [schema_str_2, schema_str_1]; let _ = Schema::parse_list(&schema_strs_first).expect_err("Test failed"); let _ = Schema::parse_list(&schema_strs_second).expect_err("Test failed"); + + Ok(()) } #[test] // // test that field's RecordSchema could be referenced by a following field by full name -fn test_parse_reused_record_schema_by_fullname() { +fn test_parse_reused_record_schema_by_fullname() -> TestResult { init(); let schema_str = r#" { @@ -879,7 +891,7 @@ fn test_parse_reused_record_schema_by_fullname() { let schema = Schema::parse_str(schema_str); assert!(schema.is_ok()); - match schema.unwrap() { + match schema? { Schema::Record(RecordSchema { ref name, aliases: _, @@ -914,6 +926,8 @@ fn test_parse_reused_record_schema_by_fullname() { } unexpected => unreachable!("Unexpected schema type: {:?}", unexpected), } + + Ok(()) } /// Return all permutations of an input slice @@ -956,7 +970,7 @@ fn permutation_indices(indices: Vec) -> Vec> { #[test] /// Test that a type that depends on more than one other type is parsed correctly when all /// definitions are passed in as a list. This should work regardless of the ordering of the list. -fn test_parse_list_multiple_dependencies() { +fn test_parse_list_multiple_dependencies() -> TestResult { init(); let schema_a_str = r#"{ "name": "A", @@ -979,22 +993,23 @@ fn test_parse_list_multiple_dependencies() { }"#; let parsed = - Schema::parse_list(&[schema_a_str, schema_b_str, schema_c_str]).expect("Test failed"); + Schema::parse_list(&[schema_a_str, schema_b_str, schema_c_str])?; let schema_strs = vec![schema_a_str, schema_b_str, schema_c_str]; for schema_str_perm in permutations(&schema_strs) { let schema_str_perm: Vec<&str> = schema_str_perm.iter().map(|s| **s).collect(); - let schemas = Schema::parse_list(&schema_str_perm).expect("Test failed"); + let schemas = Schema::parse_list(&schema_str_perm)?; assert_eq!(schemas.len(), 3); for parsed_schema in &parsed { assert!(schemas.contains(parsed_schema)); } } + Ok(()) } #[test] /// Test that a type that is depended on by more than one other type is parsed correctly when all /// definitions are passed in as a list. This should work regardless of the ordering of the list. -fn test_parse_list_shared_dependency() { +fn test_parse_list_shared_dependency() -> TestResult { init(); let schema_a_str = r#"{ "name": "A", @@ -1019,21 +1034,22 @@ fn test_parse_list_shared_dependency() { }"#; let parsed = - Schema::parse_list(&[schema_a_str, schema_b_str, schema_c_str]).expect("Test failed"); + Schema::parse_list(&[schema_a_str, schema_b_str, schema_c_str])?; let schema_strs = vec![schema_a_str, schema_b_str, schema_c_str]; for schema_str_perm in permutations(&schema_strs) { let schema_str_perm: Vec<&str> = schema_str_perm.iter().map(|s| **s).collect(); - let schemas = Schema::parse_list(&schema_str_perm).expect("Test failed"); + let schemas = Schema::parse_list(&schema_str_perm)?; assert_eq!(schemas.len(), 3); for parsed_schema in &parsed { assert!(schemas.contains(parsed_schema)); } } + Ok(()) } #[test] /// Test that trying to parse two schemas with the same fullname returns an Error -fn test_name_collision_error() { +fn test_name_collision_error() -> TestResult { init(); let schema_str_1 = r#"{ "name": "foo.A", @@ -1052,11 +1068,12 @@ fn test_name_collision_error() { }"#; let _ = Schema::parse_list(&[schema_str_1, schema_str_2]).expect_err("Test failed"); + Ok(()) } #[test] /// Test that having the same name but different fullnames does not return an error -fn test_namespace_prevents_collisions() { +fn test_namespace_prevents_collisions() -> TestResult { init(); let schema_str_1 = r#"{ "name": "A", @@ -1074,10 +1091,11 @@ fn test_namespace_prevents_collisions() { ] }"#; - let parsed = Schema::parse_list(&[schema_str_1, schema_str_2]).expect("Test failed"); - let parsed_1 = Schema::parse_str(schema_str_1).expect("Test failed"); - let parsed_2 = Schema::parse_str(schema_str_2).expect("Test failed"); + let parsed = Schema::parse_list(&[schema_str_1, schema_str_2])?; + let parsed_1 = Schema::parse_str(schema_str_1)?; + let parsed_2 = Schema::parse_str(schema_str_2)?; assert_eq!(parsed, vec!(parsed_1, parsed_2)); + Ok(()) } // The fullname is determined in one of the following ways: @@ -1106,96 +1124,105 @@ fn test_namespace_prevents_collisions() { // equivalent. #[test] -fn test_fullname_name_and_namespace_specified() { +fn test_fullname_name_and_namespace_specified() -> TestResult { init(); let name: Name = - serde_json::from_str(r#"{"name": "a", "namespace": "o.a.h", "aliases": null}"#).unwrap(); + serde_json::from_str(r#"{"name": "a", "namespace": "o.a.h", "aliases": null}"#)?; let fullname = name.fullname(None); assert_eq!("o.a.h.a", fullname); + Ok(()) } #[test] -fn test_fullname_fullname_and_namespace_specified() { +fn test_fullname_fullname_and_namespace_specified() -> TestResult { init(); - let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d", "namespace": "o.a.h"}"#).unwrap(); + let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d", "namespace": "o.a.h"}"#)?; assert_eq!(&name.name, "d"); assert_eq!(name.namespace, Some("a.b.c".to_owned())); let fullname = name.fullname(None); assert_eq!("a.b.c.d", fullname); + Ok(()) } #[test] -fn test_fullname_name_and_default_namespace_specified() { +fn test_fullname_name_and_default_namespace_specified() -> TestResult { init(); - let name: Name = serde_json::from_str(r#"{"name": "a", "namespace": null}"#).unwrap(); + let name: Name = serde_json::from_str(r#"{"name": "a", "namespace": null}"#)?; assert_eq!(&name.name, "a"); assert_eq!(name.namespace, None); let fullname = name.fullname(Some("b.c.d".into())); assert_eq!("b.c.d.a", fullname); + Ok(()) } #[test] -fn test_fullname_fullname_and_default_namespace_specified() { +fn test_fullname_fullname_and_default_namespace_specified() -> TestResult { init(); - let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d", "namespace": null}"#).unwrap(); + let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d", "namespace": null}"#)?; assert_eq!(&name.name, "d"); assert_eq!(name.namespace, Some("a.b.c".to_owned())); let fullname = name.fullname(Some("o.a.h".into())); assert_eq!("a.b.c.d", fullname); + Ok(()) } #[test] -fn test_avro_3452_parsing_name_without_namespace() { +fn test_avro_3452_parsing_name_without_namespace() -> TestResult { init(); - let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d"}"#).unwrap(); + let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d"}"#)?; assert_eq!(&name.name, "d"); assert_eq!(name.namespace, Some("a.b.c".to_owned())); let fullname = name.fullname(None); assert_eq!("a.b.c.d", fullname); + Ok(()) } #[test] -fn test_avro_3452_parsing_name_with_leading_dot_without_namespace() { +fn test_avro_3452_parsing_name_with_leading_dot_without_namespace() -> TestResult { init(); - let name: Name = serde_json::from_str(r#"{"name": ".a"}"#).unwrap(); + let name: Name = serde_json::from_str(r#"{"name": ".a"}"#)?; assert_eq!(&name.name, "a"); assert_eq!(name.namespace, None); assert_eq!("a", name.fullname(None)); + Ok(()) } #[test] -fn test_avro_3452_parse_json_without_name_field() { +fn test_avro_3452_parse_json_without_name_field() -> TestResult { init(); let result: serde_json::error::Result = serde_json::from_str(r#"{"unknown": "a"}"#); assert!(&result.is_err()); assert_eq!(result.unwrap_err().to_string(), "No `name` field"); + Ok(()) } #[test] -fn test_fullname_fullname_namespace_and_default_namespace_specified() { +fn test_fullname_fullname_namespace_and_default_namespace_specified() -> TestResult { init(); let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d", "namespace": "o.a.a", "aliases": null}"#) - .unwrap(); + ?; assert_eq!(&name.name, "d"); assert_eq!(name.namespace, Some("a.b.c".to_owned())); let fullname = name.fullname(Some("o.a.h".into())); assert_eq!("a.b.c.d", fullname); + Ok(()) } #[test] -fn test_fullname_name_namespace_and_default_namespace_specified() { +fn test_fullname_name_namespace_and_default_namespace_specified() -> TestResult { init(); let name: Name = - serde_json::from_str(r#"{"name": "a", "namespace": "o.a.a", "aliases": null}"#).unwrap(); + serde_json::from_str(r#"{"name": "a", "namespace": "o.a.a", "aliases": null}"#)?; assert_eq!(&name.name, "a"); assert_eq!(name.namespace, Some("o.a.a".to_owned())); let fullname = name.fullname(Some("o.a.h".into())); assert_eq!("o.a.a.a", fullname); + Ok(()) } #[test] -fn test_doc_attributes() { +fn test_doc_attributes() -> TestResult { init(); fn assert_doc(schema: &Schema) { match schema { @@ -1208,7 +1235,7 @@ fn test_doc_attributes() { } for (raw_schema, _) in DOC_EXAMPLES.iter() { - let original_schema = Schema::parse_str(raw_schema).unwrap(); + let original_schema = Schema::parse_str(raw_schema)?; assert_doc(&original_schema); if let Schema::Record(RecordSchema { fields, .. }) = original_schema { for f in fields { @@ -1216,6 +1243,7 @@ fn test_doc_attributes() { } } } + Ok(()) } /* @@ -1233,17 +1261,17 @@ fn test_other_attributes() { } for (raw_schema, _) in OTHER_ATTRIBUTES_EXAMPLES.iter() { - let schema = Schema::parse_str(raw_schema).unwrap(); + let schema = Schema::parse_str(raw_schema)?; // all inputs have at least some user-defined attributes assert!(schema.other_attributes.is_some()); - for prop in schema.other_attributes.unwrap().iter() { + for prop in schema.other_attributes?.iter() { assert_attribute_type(prop); } if let Schema::Record { fields, .. } = schema { for f in fields { // all fields in the record have at least some user-defined attributes assert!(f.schema.other_attributes.is_some()); - for prop in f.schema.other_attributes.unwrap().iter() { + for prop in f.schema.other_attributes?.iter() { assert_attribute_type(prop); } } @@ -1272,7 +1300,7 @@ fn test_root_error_is_not_swallowed_on_parse_error() -> Result<(), String> { // AVRO-3302 #[test] -fn test_record_schema_with_cyclic_references() { +fn test_record_schema_with_cyclic_references() -> TestResult { init(); let schema = Schema::parse_str( r#" @@ -1293,7 +1321,7 @@ fn test_record_schema_with_cyclic_references() { } "#, ) - .unwrap(); + ?; let mut datum = Record::new(&schema).unwrap(); datum.put( @@ -1326,16 +1354,17 @@ fn test_record_schema_with_cyclic_references() { if let Err(err) = writer.append(datum) { panic!("An error occurred while writing datum: {err:?}") } - let bytes = writer.into_inner().unwrap(); + let bytes = writer.into_inner()?; assert_eq!(316, bytes.len()); match Reader::new(&mut bytes.as_slice()) { Ok(mut reader) => match reader.next() { - Some(value) => log::debug!("{:?}", value.unwrap()), + Some(value) => log::debug!("{:?}", value?), None => panic!("No value was read!"), }, Err(err) => panic!("An error occurred while reading datum: {err:?}"), } + Ok(()) } /* @@ -1343,12 +1372,12 @@ fn test_record_schema_with_cyclic_references() { #[test] fn test_decimal_valid_type_attributes() { init(); - let fixed_decimal = Schema::parse_str(DECIMAL_LOGICAL_TYPE_ATTRIBUTES[0]).unwrap(); + let fixed_decimal = Schema::parse_str(DECIMAL_LOGICAL_TYPE_ATTRIBUTES[0])?; assert_eq!(4, fixed_decimal.get_attribute("precision")); assert_eq!(2, fixed_decimal.get_attribute("scale")); assert_eq!(2, fixed_decimal.get_attribute("size")); - let bytes_decimal = Schema::parse_str(DECIMAL_LOGICAL_TYPE_ATTRIBUTES[1]).unwrap(); + let bytes_decimal = Schema::parse_str(DECIMAL_LOGICAL_TYPE_ATTRIBUTES[1])?; assert_eq!(4, bytes_decimal.get_attribute("precision")); assert_eq!(0, bytes_decimal.get_attribute("scale")); } @@ -1356,7 +1385,7 @@ fn test_decimal_valid_type_attributes() { // https://github.com/flavray/avro-rs/issues/47 #[test] -fn avro_old_issue_47() { +fn avro_old_issue_47() -> TestResult { init(); let schema_str = r#" { @@ -1367,7 +1396,7 @@ fn avro_old_issue_47() { {"name": "b", "type": "string"} ] }"#; - let schema = Schema::parse_str(schema_str).unwrap(); + let schema = Schema::parse_str(schema_str)?; use serde::{Deserialize, Serialize}; @@ -1382,5 +1411,6 @@ fn avro_old_issue_47() { a: 1, }; - let _ = to_avro_datum(&schema, to_value(record).unwrap()).unwrap(); + let _ = to_avro_datum(&schema, to_value(record)?)?; + Ok(()) } diff --git a/lang/rust/avro/tests/shared.rs b/lang/rust/avro/tests/shared.rs index f5686129cbc..ab85604e50e 100644 --- a/lang/rust/avro/tests/shared.rs +++ b/lang/rust/avro/tests/shared.rs @@ -23,11 +23,12 @@ use std::{ path::Path, slice::Iter, }; +use apache_avro_test_helper::TestResult; const ROOT_DIRECTORY: &str = "../../../share/test/data/schemas"; #[test] -fn test_schema() { +fn test_schema() -> TestResult { let directory: ReadDir = scan_shared_folder(); let mut result: Result<(), ErrorsDesc> = Ok(()); for f in directory { @@ -54,6 +55,7 @@ fn test_schema() { if let Err(e) = result { core::panic!("{}", e) } + Ok(()) } #[derive(Debug)] diff --git a/lang/rust/avro/tests/to_from_avro_datum_schemata.rs b/lang/rust/avro/tests/to_from_avro_datum_schemata.rs index d05025ab75b..e27f1e625ac 100644 --- a/lang/rust/avro/tests/to_from_avro_datum_schemata.rs +++ b/lang/rust/avro/tests/to_from_avro_datum_schemata.rs @@ -18,7 +18,7 @@ use apache_avro::{ from_avro_datum_schemata, to_avro_datum_schemata, types::Value, Codec, Reader, Schema, Writer, }; -use apache_avro_test_helper::init; +use apache_avro_test_helper::{init, TestResult}; static SCHEMA_A_STR: &str = r#"{ "name": "A", @@ -37,7 +37,7 @@ static SCHEMA_B_STR: &str = r#"{ }"#; #[test] -fn test_avro_3683_multiple_schemata_to_from_avro_datum() { +fn test_avro_3683_multiple_schemata_to_from_avro_datum() -> TestResult { init(); let record: Value = Value::Record(vec![( @@ -45,21 +45,23 @@ fn test_avro_3683_multiple_schemata_to_from_avro_datum() { Value::Record(vec![(String::from("field_a"), Value::Float(1.0))]), )]); - let schemata: Vec = Schema::parse_list(&[SCHEMA_A_STR, SCHEMA_B_STR]).unwrap(); + let schemata: Vec = Schema::parse_list(&[SCHEMA_A_STR, SCHEMA_B_STR])?; let schemata: Vec<&Schema> = schemata.iter().collect(); // this is the Schema we want to use for write/read let schema_b = schemata[1]; let expected: Vec = vec![0, 0, 128, 63]; - let actual = to_avro_datum_schemata(schema_b, schemata.clone(), record.clone()).unwrap(); + let actual = to_avro_datum_schemata(schema_b, schemata.clone(), record.clone())?; assert_eq!(actual, expected); - let value = from_avro_datum_schemata(schema_b, schemata, &mut actual.as_slice(), None).unwrap(); + let value = from_avro_datum_schemata(schema_b, schemata, &mut actual.as_slice(), None)?; assert_eq!(value, record); + + Ok(()) } #[test] -fn test_avro_3683_multiple_schemata_writer_reader() { +fn test_avro_3683_multiple_schemata_writer_reader() -> TestResult { init(); let record: Value = Value::Record(vec![( @@ -67,7 +69,7 @@ fn test_avro_3683_multiple_schemata_writer_reader() { Value::Record(vec![(String::from("field_a"), Value::Float(1.0))]), )]); - let schemata: Vec = Schema::parse_list(&[SCHEMA_A_STR, SCHEMA_B_STR]).unwrap(); + let schemata: Vec = Schema::parse_list(&[SCHEMA_A_STR, SCHEMA_B_STR])?; let schemata: Vec<&Schema> = schemata.iter().collect(); // this is the Schema we want to use for write/read @@ -75,10 +77,12 @@ fn test_avro_3683_multiple_schemata_writer_reader() { let mut output: Vec = Vec::new(); let mut writer = Writer::with_schemata(schema_b, schemata.clone(), &mut output, Codec::Null); - writer.append(record.clone()).unwrap(); - writer.flush().unwrap(); + writer.append(record.clone())?; + writer.flush()?; - let reader = Reader::with_schemata(schema_b, schemata, output.as_slice()).unwrap(); + let reader = Reader::with_schemata(schema_b, schemata, output.as_slice())?; let value = reader.into_iter().next().unwrap().unwrap(); assert_eq!(value, record); + + Ok(()) } diff --git a/lang/rust/avro_test_helper/Cargo.toml b/lang/rust/avro_test_helper/Cargo.toml index 811cc579d96..402b261957f 100644 --- a/lang/rust/avro_test_helper/Cargo.toml +++ b/lang/rust/avro_test_helper/Cargo.toml @@ -31,6 +31,7 @@ documentation = "https://docs.rs/apache-avro-test-helper" [dependencies] +anyhow = { default-features = false, version = "1.0.71", features = ["std"] } color-backtrace = { default-features = false, version = "0.5.1" } ctor = { default-features = false, version = "0.2.0" } env_logger = { default-features = false, version = "0.10.0" } diff --git a/lang/rust/avro_test_helper/src/lib.rs b/lang/rust/avro_test_helper/src/lib.rs index 235b4c5184d..545bccc8927 100644 --- a/lang/rust/avro_test_helper/src/lib.rs +++ b/lang/rust/avro_test_helper/src/lib.rs @@ -45,6 +45,22 @@ fn after_all() { logger::clear_log_messages(); } +/// A custom error type for tests. +#[derive(Debug)] +pub enum TestError {} + +/// A converter of any error into [TestError]. +/// It is used to print better error messages in the tests. +/// Borrowed from https://bluxte.net/musings/2023/01/08/improving_failure_messages_rust_tests/ +impl From for TestError { + #[track_caller] + fn from(err: Err) -> Self { + panic!("{}: {}", std::any::type_name::(), err); + } +} + +pub type TestResult = anyhow::Result<(), TestError>; + /// Does nothing. Just loads the crate. /// Should be used in the integration tests, because they do not use [dev-dependencies] /// and do not auto-load this crate.