From 54e2c116e585d1ce51876cf0eaa4df0d7228ed17 Mon Sep 17 00:00:00 2001 From: David Grossman Date: Mon, 1 May 2023 14:23:26 -0700 Subject: [PATCH] Nails down record default spec for unions (#486) --- .../AvroWireFormatCompatibilityTest.java | 37 +++++++++++++++++++ ...rdWithDefaultUnionFieldCorrect_reader.avsc | 26 +++++++++++++ ...nionFieldIncorrectFlatNotation_reader.avsc | 26 +++++++++++++ ...onFieldIncorrectObjectNotation_reader.avsc | 28 ++++++++++++++ .../RecordWithDefaultUnionField_writer.avsc | 6 +++ 5 files changed, 123 insertions(+) create mode 100644 helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldCorrect_reader.avsc create mode 100644 helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldIncorrectFlatNotation_reader.avsc create mode 100644 helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldIncorrectObjectNotation_reader.avsc create mode 100644 helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionField_writer.avsc diff --git a/helper/tests/helper-tests-allavro/src/test/java/com/linkedin/avroutil1/compatibility/AvroWireFormatCompatibilityTest.java b/helper/tests/helper-tests-allavro/src/test/java/com/linkedin/avroutil1/compatibility/AvroWireFormatCompatibilityTest.java index 02f1ab78d..86f7f5fc1 100644 --- a/helper/tests/helper-tests-allavro/src/test/java/com/linkedin/avroutil1/compatibility/AvroWireFormatCompatibilityTest.java +++ b/helper/tests/helper-tests-allavro/src/test/java/com/linkedin/avroutil1/compatibility/AvroWireFormatCompatibilityTest.java @@ -9,7 +9,9 @@ import com.linkedin.avroutil1.testcommon.TestUtil; import org.apache.avro.AvroTypeException; import org.apache.avro.Schema; +import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericDatumReader; +import org.apache.avro.generic.GenericRecord; import org.apache.avro.generic.IndexedRecord; import org.apache.avro.io.BinaryDecoder; import org.apache.avro.io.Decoder; @@ -98,4 +100,39 @@ public void testCompatibleJsonParsingOfWrongNumericLiterals() throws Exception { Assert.assertEquals(deserialized2.get(schema.getField("floatField").pos()), 3.0f); Assert.assertEquals(deserialized2.get(schema.getField("doubleField").pos()), 4.0d); } + + @Test + public void demonstrateDefaultRecordsUnionFieldMustBeFirstElement() throws Exception { + Schema writerSchema = + AvroCompatibilityHelper.parse(TestUtil.load("allavro/RecordWithDefaultUnionField_writer.avsc")); + GenericData.Record record = new GenericData.Record(writerSchema); + byte[] bytes = AvroCodecUtil.serializeBinary(record); + + // uses 1st field (correct) + Schema correctReaderSchema = + AvroCompatibilityHelper.parse(TestUtil.load("allavro/RecordWithDefaultUnionFieldCorrect_reader.avsc")); + GenericRecord deserializedGenericRecord = + AvroCodecUtil.deserializeAsGeneric(bytes, writerSchema, correctReaderSchema); + Assert.assertEquals(deserializedGenericRecord.get("mainField").toString(), "{\"f1\": \"default\"}"); + + // tries to use 2nd field as default (object notation) + Schema incorrectReaderSchemaUsingObjectNotation = AvroCompatibilityHelper.parse( + TestUtil.load("allavro/RecordWithDefaultUnionFieldIncorrectObjectNotation_reader.avsc")); + try { + AvroCodecUtil.deserializeAsGeneric(bytes, writerSchema, incorrectReaderSchemaUsingObjectNotation); + Assert.fail("Expected exception"); + } catch (Exception e) { + Assert.assertTrue(e.getClass().getName().contains("AvroTypeException")); + } + + // tries to use 2nd field as default (flat notation) + Schema incorrectReaderSchemaUsingFlatNotation = AvroCompatibilityHelper.parse( + TestUtil.load("allavro/RecordWithDefaultUnionFieldIncorrectFlatNotation_reader.avsc")); + try { + AvroCodecUtil.deserializeAsGeneric(bytes, writerSchema, incorrectReaderSchemaUsingFlatNotation); + Assert.fail("Expected exception"); + } catch (Exception e) { + Assert.assertTrue(e.getClass().getName().contains("AvroTypeException")); + } + } } diff --git a/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldCorrect_reader.avsc b/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldCorrect_reader.avsc new file mode 100644 index 000000000..3a98ef8cb --- /dev/null +++ b/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldCorrect_reader.avsc @@ -0,0 +1,26 @@ +{ + "type": "record", + "name": "SchemaWithRecordDefault", + "fields": [ + { + "name": "mainField", + "type": { + "type": "record", + "name": "InnerRecord", + "fields": [ + { + "name": "f1", + "type": [ + "string", + "int", + "null" + ] + } + ] + }, + "default": { + "f1": "default" + } + } + ] +} \ No newline at end of file diff --git a/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldIncorrectFlatNotation_reader.avsc b/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldIncorrectFlatNotation_reader.avsc new file mode 100644 index 000000000..ad37434b5 --- /dev/null +++ b/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldIncorrectFlatNotation_reader.avsc @@ -0,0 +1,26 @@ +{ + "type": "record", + "name": "SchemaWithRecordDefault", + "fields": [ + { + "name": "mainField", + "type": { + "type": "record", + "name": "InnerRecord", + "fields": [ + { + "name": "f1", + "type": [ + "string", + "int", + "null" + ] + } + ] + }, + "default": { + "f1": null + } + } + ] +} \ No newline at end of file diff --git a/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldIncorrectObjectNotation_reader.avsc b/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldIncorrectObjectNotation_reader.avsc new file mode 100644 index 000000000..ca0a35926 --- /dev/null +++ b/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionFieldIncorrectObjectNotation_reader.avsc @@ -0,0 +1,28 @@ +{ + "type": "record", + "name": "SchemaWithRecordDefault", + "fields": [ + { + "name": "mainField", + "type": { + "type": "record", + "name": "InnerRecord", + "fields": [ + { + "name": "f1", + "type": [ + "string", + "int", + "null" + ] + } + ] + }, + "default": { + "f1": { + "int": 1 + } + } + } + ] +} \ No newline at end of file diff --git a/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionField_writer.avsc b/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionField_writer.avsc new file mode 100644 index 000000000..8c47cdf74 --- /dev/null +++ b/helper/tests/helper-tests-allavro/src/test/resources/allavro/RecordWithDefaultUnionField_writer.avsc @@ -0,0 +1,6 @@ +{ + "type": "record", + "name": "SchemaWithRecordDefault", + "fields": [ + ] +} \ No newline at end of file