Package com.google.appengine.tools.mapreduce

Source Code of com.google.appengine.tools.mapreduce.MarshallersTest

// Copyright 2012 Google Inc. All Rights Reserved.

package com.google.appengine.tools.mapreduce;

import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;

import junit.framework.TestCase;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Random;

/**
* @author ohler@google.com (Christian Ohler)
*/
public class MarshallersTest extends TestCase {

  private <T> void checkByteOrder(Marshaller<T> m, T value) {
    {
      ByteBuffer buf = m.toBytes(value);
      buf.order(ByteOrder.BIG_ENDIAN);
      assertEquals(value, m.fromBytes(buf));
    }
    {
      ByteBuffer buf2 = m.toBytes(value);
      buf2.order(ByteOrder.LITTLE_ENDIAN);
      assertEquals(value, m.fromBytes(buf2));
    }
  }

  private <T> void checkMoreCapacity(Marshaller<T> m, T value) {
    ByteBuffer raw = m.toBytes(value);
    ByteBuffer wrapped = ByteBuffer.allocate(raw.remaining() + 10);
    for (byte b = 0; b < 5; b++) {
      wrapped.put(b);
    }
    wrapped.put(raw);
    for (byte b = 0; b < 5; b++) {
      wrapped.put(b);
    }
    wrapped.position(5);
    wrapped.limit(wrapped.capacity() - 5);
    assertEquals(value, m.fromBytes(wrapped));
  }

  private <T> void checkTruncated(Marshaller<T> m, T value) {
    ByteBuffer buf = m.toBytes(value);
    buf.limit(buf.limit() - 1);
    try {
      fail("Got " + m.fromBytes(buf));
    } catch (RuntimeException e) {
      // ok
    }
  }

  private <T> void checkTrailingBytes(Marshaller<T> m, T value) {
    ByteBuffer raw = m.toBytes(value);
    ByteBuffer wrapped = ByteBuffer.allocate(raw.remaining() + 1);
    wrapped.put(raw);
    wrapped.put((byte) 0);
    wrapped.flip();
    try {
      fail("Got " + m.fromBytes(wrapped));
    } catch (RuntimeException e) {
      // ok
    }
  }

  private <T> void assertRoundTripEquality(Marshaller<T> marshaller, T value) {
    ByteBuffer bytes = marshaller.toBytes(value);
    T reconstructed = marshaller.fromBytes(bytes.slice());
    assertEquals(value, reconstructed);
    assertEquals(bytes, marshaller.toBytes(reconstructed));
  }

  /**
   * Perform checks that assume the data is not corrupted.
   */
  private <T> void preformValidChecks(Marshaller<T> m, T value) {
    assertRoundTripEquality(m, value);
    checkByteOrder(m, value);
    checkMoreCapacity(m, value);
  }

  /**
   * Perform all checks including those that attempt to detect corruption.
   */
  private <T> void preformAllChecks(Marshaller<T> m, T value) {
    preformValidChecks(m, value);
    checkTruncated(m, value);
    checkTrailingBytes(m, value);
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  public void testObjectMarshaller() {
    Marshaller m = Marshallers.getSerializationMarshaller();
    // Testing primitives
    preformAllChecks(m, 1);
    preformAllChecks(m, -1L);
    preformAllChecks(m, null);
    preformValidChecks(m,  "");
    preformValidChecks(m, "Foo");
    preformValidChecks(m, KeyValue.of(42L, "foo"));
    // Testing a large object
    Random r = new Random(0);
    preformAllChecks(m, new BigInteger(8 * (1024 * 1024 + 10), r));
    // Testing a map
    ImmutableBiMap<String, String> map = ImmutableBiMap.of("foo", "bar", "baz", "bat");
    preformValidChecks(m, map);
    // Testing a nested object
    preformValidChecks(m, KeyValue.of(42L, KeyValue.of(42L, KeyValue.of(42L, "foo"))));
  }

  public void testLongMarshaller() throws Exception {
    // The serialized format is unspecified, so we only check if the round-trip
    // works, not what the actual bytes are.
    Marshaller<Long> m = Marshallers.getLongMarshaller();
    for (long l = -1000; l < 1000; l++) {
      preformAllChecks(m, l);
    }
    for (long l = Long.MAX_VALUE - 1000; l != Long.MIN_VALUE + 1000; l++) {
      preformAllChecks(m, l);
    }
  }

  public void testIntegerMarshaller() throws Exception {
    // The serialized format is unspecified, so we only check if the round-trip
    // works, not what the actual bytes are.
    Marshaller<Integer> m = Marshallers.getIntegerMarshaller();
    for (int i = -1000; i < 1000; i++) {
      preformAllChecks(m, i);
    }
    for (int i = Integer.MAX_VALUE - 1000; i != Integer.MIN_VALUE + 1000; i++) {
      preformAllChecks(m, i);
    }
  }

  public void testStringMarshaller() throws Exception {
    // The serialized format is unspecified, so we only check if the round-trip
    // works, not what the actual bytes are.
    Marshaller<String> m = Marshallers.getStringMarshaller();
    for (String s : ImmutableList.of("", "a", "b", "ab", "foo",
            "\u0000", "\u0000\uabcd\u1234",
            "\ud801\udc02")) {
      preformValidChecks(m, s);
    }
  }

  public void testKeyValueLongMarshaller() throws Exception {
    // The serialized format is unspecified, so we only check if the round-trip
    // works, not what the actual bytes are.
    Marshaller<KeyValue<Long, Long>> m = Marshallers.getKeyValueMarshaller(
        Marshallers.getLongMarshaller(), Marshallers.getLongMarshaller());
    for (KeyValue<Long, Long> pair :
        ImmutableList.of(KeyValue.of(42L, -1L), KeyValue.of(Long.MAX_VALUE, Long.MIN_VALUE))) {
      preformAllChecks(m, pair);
    }
  }

  public void testKeyValueStringMarshaller() throws Exception {
    // The serialized format is unspecified, so we only check if the round-trip
    // works, not what the actual bytes are.
    Marshaller<KeyValue<String, String>> m = Marshallers.getKeyValueMarshaller(
        Marshallers.getStringMarshaller(), Marshallers.getStringMarshaller());
    for (KeyValue<String, String> pair :
        ImmutableList.of(KeyValue.of("foo", "bar"), KeyValue.of("", "\u00a5123"))) {
      preformValidChecks(m, pair);
    }
  }

  public void testKeyValueIntegers() {
    Marshaller<Integer> intMarshaller = Marshallers.getIntegerMarshaller();
    Marshaller<KeyValue<Integer, Integer>> m =
        Marshallers.<Integer, Integer>getKeyValueMarshaller(intMarshaller, intMarshaller);
    for (int i = 0; i < 10000; i++) {
      assertRoundTripEquality(m, new KeyValue<>(i, -i));
    }
  }

  public void testKeyValueNested() {
    Marshaller<Integer> intMarshaller = Marshallers.getIntegerMarshaller();
    Marshaller<String> stringMarshaller = Marshallers.getStringMarshaller();
    Marshaller<KeyValue<Integer, String>> nestedMarshaller =
        Marshallers.getKeyValueMarshaller(intMarshaller, stringMarshaller);
    Marshaller<KeyValue<KeyValue<Integer, String>, KeyValue<Integer, String>>> m =
        Marshallers.getKeyValueMarshaller(nestedMarshaller, nestedMarshaller);
    for (int i = 0; i < 10000; i++) {
      assertRoundTripEquality(m,
          new KeyValue<>(new KeyValue<>(i, "Foo" + i), new KeyValue<>(-1, "Bar-" + i)));
    }
  }
}
TOP

Related Classes of com.google.appengine.tools.mapreduce.MarshallersTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.