/*
* Copyright (c) 2014 Oculus Info Inc.
* http://www.oculusinfo.com/
*
* Released under the MIT License.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.oculusinfo.binning.io.serialization.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import org.apache.avro.file.CodecFactory;
import org.junit.Assert;
import org.junit.Test;
import com.oculusinfo.binning.TileData;
import com.oculusinfo.binning.TileIndex;
import com.oculusinfo.binning.impl.DenseTileData;
import com.oculusinfo.binning.io.serialization.TileSerializer;
import com.oculusinfo.factory.util.Pair;
public class PairAvroSerializerTests {
@SafeVarargs
final <S, T> void testRoundTrip(Class<? extends S> keyType, Class<? extends T> valueType,
Pair<S, T>... data) throws Exception {
TileSerializer<Pair<S, T>> serializer = new PairAvroSerializer<>(keyType, valueType, CodecFactory.nullCodec());
// Create our tile
int n = data.length;
int size = (int) Math.ceil(Math.sqrt(n));
TileData<Pair<S, T>> input = new DenseTileData<>(new TileIndex(0, 0, 0, size, size));
for (int y=0; y<size; ++y) {
for (int x=0; x<size; ++x) {
int i = ((x+size*y));
if (i < n) input.setBin(x, y, data[i]);
}
}
// Send it round-trip through serialization
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.serialize(input, baos);
baos.flush();
baos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
TileData<Pair<S, T>> output = serializer.deserialize(new TileIndex(1, 1, 1, size, size), bais);
// Test to make sure output matches input.
Assert.assertEquals(input.getDefinition(), output.getDefinition());
for (int y=0; y<size; ++y) {
for (int x=0; x<size; ++x) {
Assert.assertEquals(input.getBin(x, y), output.getBin(x, y));
}
}
}
private <S, T> Pair<S, T> p (S s, T t) {
return new Pair<>(s, t);
}
private ByteBuffer bb (int... bytes) {
byte[] asBytes = new byte[bytes.length];
for (int i=0; i<bytes.length; ++i) {
asBytes[i] = (byte) bytes[i];
}
return ByteBuffer.wrap(asBytes);
}
@Test
public void testIntInt() throws Exception {
testRoundTrip(Integer.class, Integer.class,
p(0, 0), p(0, 1), p(0, 2),
p(1, 0), p(1, 1), p(1, 2),
p(2, 0), p(2, 1), p(2, 2));
}
@Test
public void testIntLong() throws Exception {
testRoundTrip(Integer.class, Long.class,
p(0, 0L), p(0, 1L), p(0, 2L),
p(1, 0L), p(1, 1L), p(1, 2L),
p(2, 0L), p(2, 1L), p(2, 2L));
}
@Test
public void testIntFloat() throws Exception {
testRoundTrip(Integer.class, Float.class,
p(0, 0.0f), p(0, 1.0f), p(0, 2.0f),
p(1, 0.0f), p(1, 1.0f), p(1, 2.0f),
p(2, 0.0f), p(2, 1.0f), p(2, 2.0f));
}
@Test
public void testIntDouble() throws Exception {
testRoundTrip(Integer.class, Double.class,
p(0, 0.0), p(0, 1.0), p(0, 2.0),
p(1, 0.0), p(1, 1.0), p(1, 2.0),
p(2, 0.0), p(2, 1.0), p(2, 2.0));
}
@Test
public void testIntBoolean() throws Exception {
testRoundTrip(Integer.class, Boolean.class,
p(0, false), p(0, true),
p(1, true), p(1, false));
}
@Test
public void testIntByteBuffer() throws Exception {
testRoundTrip(Integer.class, ByteBuffer.class,
p(0, bb(0, 1, 2)), p(0, bb(126, 127, 128)), p(0, bb(253, 254, 255)),
p(1, bb(1, 2, 3)), p(1, bb(126, 127, 128)), p(1, bb(252, 253, 254)),
p(2, bb(2, 3, 4)), p(2, bb(126, 127, 128)), p(2, bb(251, 252, 253)));
}
@Test
public void testIntString() throws Exception {
testRoundTrip(Integer.class, String.class,
p(0, "0"), p(0, "1"), p(0, "2"),
p(1, "0"), p(1, "1"), p(1, "2"),
p(2, "0"), p(2, "1"), p(2, "2"));
}
@Test
public void testLongInt() throws Exception {
testRoundTrip(Long.class, Integer.class,
p(0L, 0), p(1L, 0), p(2L, 0),
p(0L, 1), p(1L, 1), p(2L, 1),
p(0L, 2), p(1L, 2), p(2L, 2));
}
@Test
public void testFloatInt() throws Exception {
testRoundTrip(Float.class, Integer.class,
p(0.0f, 0), p(1.0f, 0), p(2.0f, 0),
p(0.0f, 1), p(1.0f, 1), p(2.0f, 1),
p(0.0f, 2), p(1.0f, 2), p(2.0f, 2));
}
@Test
public void testDoubleInt() throws Exception {
testRoundTrip(Double.class, Integer.class,
p(0.0, 0), p(1.0, 0), p(2.0, 0),
p(0.0, 1), p(1.0, 1), p(2.0, 1),
p(0.0, 2), p(1.0, 2), p(2.0, 2));
}
@Test
public void testBooleanInt() throws Exception {
testRoundTrip(Boolean.class, Integer.class,
p(false, 0), p(true, 0),
p(true, 1), p(false, 1));
}
@Test
public void testByteBufferInt() throws Exception {
testRoundTrip(ByteBuffer.class, Integer.class,
p(bb(0, 1, 2), 0), p(bb(126, 127, 128), 0), p(bb(253, 254, 255), 0),
p(bb(1, 2, 3), 1), p(bb(126, 127, 128), 1), p(bb(252, 253, 254), 1),
p(bb(2, 3, 4), 2), p(bb(126, 127, 128), 2), p(bb(251, 252, 253), 2));
}
@Test
public void testStringInt() throws Exception {
testRoundTrip(String.class, Integer.class,
p("0", 0), p("1", 0), p("2", 0),
p("0", 1), p("1", 1), p("2", 1),
p("0", 2), p("1", 2), p("2", 2));
}
}