blob: 73057571f3122ffa6f4b2279bd0d364d8bdcc1b8 [file] [log] [blame]
/**
* 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");
}
}