/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.avro.specific; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import junit.framework.Assert; import org.apache.avro.AvroRuntimeException; import org.apache.avro.Foo; import org.apache.avro.Interop; import org.apache.avro.Kind; import org.apache.avro.MD5; import org.apache.avro.Node; import org.apache.avro.ipc.specific.PageView; import org.apache.avro.ipc.specific.Person; import org.apache.avro.ipc.specific.ProductPage; import org.junit.Ignore; import org.junit.Test; /** * Unit test for the SpecificRecordBuilder class. */ public class TestSpecificRecordBuilder { @Test public void testSpecificBuilder() { // Create a new builder, and leave some fields with default values empty: Person.Builder builder = Person.newBuilder().setName("James Gosling").setYearOfBirth(1955).setState("CA"); Assert.assertTrue(builder.hasName()); Assert.assertEquals("James Gosling", builder.getName().toString()); Assert.assertTrue(builder.hasYearOfBirth()); Assert.assertEquals(new Integer(1955), builder.getYearOfBirth()); Assert.assertFalse(builder.hasCountry()); Assert.assertNull(builder.getCountry()); Assert.assertTrue(builder.hasState()); Assert.assertEquals("CA", builder.getState().toString()); Assert.assertFalse(builder.hasFriends()); Assert.assertNull(builder.getFriends()); Assert.assertFalse(builder.hasLanguages()); Assert.assertNull(builder.getLanguages()); Person person = builder.build(); Assert.assertEquals("James Gosling", person.getName().toString()); Assert.assertEquals(new Integer(1955), person.getYearOfBirth()); Assert.assertEquals("US", person.getCountry().toString()); // country should default to "US" Assert.assertEquals("CA", person.getState().toString()); Assert.assertNotNull(person.getFriends()); // friends should default to an empty list Assert.assertEquals(0, person.getFriends().size()); Assert.assertNotNull(person.getLanguages()); // Languages should now be "English" and "Java" Assert.assertEquals(2, person.getLanguages().size()); Assert.assertEquals("English", person.getLanguages().get(0).toString()); Assert.assertEquals("Java", person.getLanguages().get(1).toString()); // Test copy constructors: Assert.assertEquals(builder, Person.newBuilder(builder)); Assert.assertEquals(person, Person.newBuilder(person).build()); Person.Builder builderCopy = Person.newBuilder(person); Assert.assertEquals("James Gosling", builderCopy.getName().toString()); Assert.assertEquals(new Integer(1955), builderCopy.getYearOfBirth()); Assert.assertEquals("US", builderCopy.getCountry().toString()); // country should default to "US" Assert.assertEquals("CA", builderCopy.getState().toString()); Assert.assertNotNull(builderCopy.getFriends()); // friends should default to an empty list Assert.assertEquals(0, builderCopy.getFriends().size()); // Test clearing fields: builderCopy.clearFriends().clearCountry(); Assert.assertFalse(builderCopy.hasFriends()); Assert.assertFalse(builderCopy.hasCountry()); Assert.assertNull(builderCopy.getFriends()); Assert.assertNull(builderCopy.getCountry()); Person person2 = builderCopy.build(); Assert.assertNotNull(person2.getFriends()); Assert.assertTrue(person2.getFriends().isEmpty()); } @Test public void testUnions() { long datetime = 1234L; String product = "widget"; PageView p = PageView.newBuilder() .setDatetime(1234L) .setPageContext(ProductPage.newBuilder() .setProduct(product) .build()) .build(); Assert.assertEquals(datetime, p.getDatetime().longValue()); Assert.assertEquals(ProductPage.class, p.getPageContext().getClass()); Assert.assertEquals(product, ((ProductPage)p.getPageContext()).getProduct()); PageView p2 = PageView.newBuilder(p).build(); Assert.assertEquals(datetime, p2.getDatetime().longValue()); Assert.assertEquals(ProductPage.class, p2.getPageContext().getClass()); Assert.assertEquals(product, ((ProductPage)p2.getPageContext()).getProduct()); Assert.assertEquals(p, p2); } @Test public void testInterop() { Interop interop = Interop.newBuilder() .setNullField(null) .setArrayField(Arrays.asList(new Double[] { 3.14159265, 6.022 })) .setBoolField(true) .setBytesField(ByteBuffer.allocate(4).put(new byte[] { 3, 2, 1, 0 })) .setDoubleField(1.41421) .setEnumField(Kind.C) .setFixedField(new MD5( new byte[] { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 })) .setFloatField(1.61803f) .setIntField(64) .setLongField(1024) .setMapField(Collections.singletonMap("Foo1", new Foo())) .setRecordField(new Node()) .setStringField("MyInterop") .setUnionField(2.71828) .build(); Interop copy = Interop.newBuilder(interop).build(); Assert.assertEquals(interop.getArrayField().size(), copy.getArrayField().size()); Assert.assertEquals(interop.getArrayField(), copy.getArrayField()); Assert.assertEquals(interop.getBoolField(), copy.getBoolField()); Assert.assertEquals(interop.getBytesField(), copy.getBytesField()); Assert.assertEquals(interop.getDoubleField(), copy.getDoubleField()); Assert.assertEquals(interop.getEnumField(), copy.getEnumField()); Assert.assertEquals(interop.getFixedField(), copy.getFixedField()); Assert.assertEquals(interop.getFloatField(), copy.getFloatField()); Assert.assertEquals(interop.getIntField(), copy.getIntField()); Assert.assertEquals(interop.getLongField(), copy.getLongField()); Assert.assertEquals(interop.getMapField(), copy.getMapField()); Assert.assertEquals(interop.getRecordField(), copy.getRecordField()); Assert.assertEquals(interop.getStringField(), copy.getStringField()); Assert.assertEquals(interop.getUnionField(), copy.getUnionField()); Assert.assertEquals(interop, copy); } @Test(expected=org.apache.avro.AvroRuntimeException.class) public void attemptToSetNonNullableFieldToNull() { Person.newBuilder().setName(null); } @Test(expected=org.apache.avro.AvroRuntimeException.class) public void buildWithoutSettingRequiredFields1() { Person.newBuilder().build(); } @Test public void buildWithoutSettingRequiredFields2() { // Omit required non-primitive field try { Person.newBuilder().setYearOfBirth(1900).setState("MA").build(); Assert.fail("Should have thrown " + AvroRuntimeException.class.getCanonicalName()); } catch (AvroRuntimeException e) { // Exception should mention that the 'name' field has not been set Assert.assertTrue(e.getMessage().contains("name")); } } @Test public void buildWithoutSettingRequiredFields3() { // Omit required primitive field try { Person.newBuilder().setName("Anon").setState("CA").build(); Assert.fail("Should have thrown " + AvroRuntimeException.class.getCanonicalName()); } catch (AvroRuntimeException e) { // Exception should mention that the 'year_of_birth' field has not been set Assert.assertTrue(e.getMessage().contains("year_of_birth")); } } @Ignore @Test public void testBuilderPerformance() { int count = 1000000; List<Person> friends = new ArrayList<Person>(0); List<String> languages = new ArrayList<String>(Arrays.asList(new String[] { "English", "Java" })); long startTimeNanos = System.nanoTime(); for (int ii = 0; ii < count; ii++) { Person.newBuilder().setName("James Gosling").setYearOfBirth(1955).setCountry("US").setState("CA").setFriends(friends). setLanguages(languages).build(); } long durationNanos = System.nanoTime() - startTimeNanos; double durationMillis = durationNanos / 1e6d; System.out.println("Built " + count + " records in " + durationMillis + "ms (" + (count / (durationMillis / 1000d)) + " records/sec, " + (durationMillis / count) + "ms/record"); } @Ignore @Test public void testBuilderPerformanceWithDefaultValues() { int count = 1000000; long startTimeNanos = System.nanoTime(); for (int ii = 0; ii < count; ii++) { Person.newBuilder().setName("James Gosling").setYearOfBirth(1955).setState("CA").build(); } long durationNanos = System.nanoTime() - startTimeNanos; double durationMillis = durationNanos / 1e6d; System.out.println("Built " + count + " records in " + durationMillis + "ms (" + (count / (durationMillis / 1000d)) + " records/sec, " + (durationMillis / count) + "ms/record"); } @Ignore @Test @SuppressWarnings("deprecation") public void testManualBuildPerformance() { int count = 1000000; List<Person> friends = new ArrayList<Person>(0); List<String> languages = new ArrayList<String>(Arrays.asList(new String[] { "English", "Java" })); long startTimeNanos = System.nanoTime(); for (int ii = 0; ii < count; ii++) { Person person = new Person(); person.name = "James Gosling"; person.year_of_birth = 1955; person.state = "CA"; person.country = "US"; person.friends = friends; person.languages = languages; } long durationNanos = System.nanoTime() - startTimeNanos; double durationMillis = durationNanos / 1e6d; System.out.println("Built " + count + " records in " + durationMillis + "ms (" + (count / (durationMillis / 1000d)) + " records/sec, " + (durationMillis / count) + "ms/record"); } }