hama-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tjungb...@apache.org
Subject svn commit: r1387533 [9/10] - in /hama/trunk: ./ core/ core/src/main/java/org/apache/hama/bsp/ graph/ graph/src/main/java/org/apache/hama/graph/ jdbm/ jdbm/src/ jdbm/src/main/ jdbm/src/main/java/ jdbm/src/main/java/org/ jdbm/src/main/java/org/apache/ j...
Date Wed, 19 Sep 2012 11:52:24 GMT
Added: hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/MapInterfaceTest.java
URL: http://svn.apache.org/viewvc/hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/MapInterfaceTest.java?rev=1387533&view=auto
==============================================================================
--- hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/MapInterfaceTest.java (added)
+++ hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/MapInterfaceTest.java Wed Sep 19 11:52:20 2012
@@ -0,0 +1,1512 @@
+/**
+ * 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.hama.jdbm;
+
+import static java.util.Collections.singleton;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests representing the contract of {@link Map}. Concrete subclasses of this
+ * base class test conformance of concrete {@link Map} subclasses to that
+ * contract.
+ * <p/>
+ * 
+ * @param <K> the type of keys used by the maps under test
+ * @param <V> the type of mapped values used the maps under test
+ */
+public abstract class MapInterfaceTest<K, V> extends TestCase {
+  protected final boolean supportsPut;
+  protected final boolean supportsRemove;
+  protected final boolean supportsClear;
+  protected final boolean allowsNullKeys;
+  protected final boolean allowsNullValues;
+  protected final boolean supportsIteratorRemove;
+
+  /**
+   * Creates a new, empty instance of the class under test.
+   * 
+   * @return a new, empty map instance.
+   * @throws UnsupportedOperationException if it's not possible to make an empty
+   *           instance of the class under test.
+   */
+  protected abstract Map<K, V> makeEmptyMap()
+      throws UnsupportedOperationException;
+
+  /**
+   * Creates a new, non-empty instance of the class under test.
+   * 
+   * @return a new, non-empty map instance.
+   * @throws UnsupportedOperationException if it's not possible to make a
+   *           non-empty instance of the class under test.
+   */
+  protected abstract Map<K, V> makePopulatedMap()
+      throws UnsupportedOperationException;
+
+  /**
+   * Creates a new key that is not expected to be found in
+   * {@link #makePopulatedMap()}.
+   * 
+   * @return a key.
+   * @throws UnsupportedOperationException if it's not possible to make a key
+   *           that will not be found in the map.
+   */
+  protected abstract K getKeyNotInPopulatedMap()
+      throws UnsupportedOperationException;
+
+  /**
+   * Creates a new value that is not expected to be found in
+   * {@link #makePopulatedMap()}.
+   * 
+   * @return a value.
+   * @throws UnsupportedOperationException if it's not possible to make a value
+   *           that will not be found in the map.
+   */
+  protected abstract V getValueNotInPopulatedMap()
+      throws UnsupportedOperationException;
+
+  /**
+   * Constructor with an explicit {@code supportsIteratorRemove} parameter.
+   */
+  protected MapInterfaceTest(boolean allowsNullKeys, boolean allowsNullValues,
+      boolean supportsPut, boolean supportsRemove, boolean supportsClear,
+      boolean supportsIteratorRemove) {
+    this.supportsPut = supportsPut;
+    this.supportsRemove = supportsRemove;
+    this.supportsClear = supportsClear;
+    this.allowsNullKeys = allowsNullKeys;
+    this.allowsNullValues = allowsNullValues;
+    this.supportsIteratorRemove = supportsIteratorRemove;
+  }
+
+  /**
+   * Used by tests that require a map, but don't care whether it's populated or
+   * not.
+   * 
+   * @return a new map instance.
+   */
+  protected Map<K, V> makeEitherMap() {
+    try {
+      return makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return makeEmptyMap();
+    }
+  }
+
+  protected final boolean supportsValuesHashCode(Map<K, V> map) {
+    // get the first non-null value
+    Collection<V> values = map.values();
+    for (V value : values) {
+      if (value != null) {
+        try {
+          value.hashCode();
+        } catch (Exception e) {
+          return false;
+        }
+        return true;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Checks all the properties that should always hold of a map. Also calls
+   * {@link #assertMoreInvariants} to check invariants that are peculiar to
+   * specific implementations.
+   * 
+   * @param map the map to check.
+   * @see #assertMoreInvariants
+   */
+  protected final void assertInvariants(Map<K, V> map) {
+    Set<K> keySet = map.keySet();
+    Collection<V> valueCollection = map.values();
+    Set<Entry<K, V>> entrySet = map.entrySet();
+
+    assertEquals(map.size() == 0, map.isEmpty());
+    assertEquals(map.size(), keySet.size());
+    assertEquals(keySet.size() == 0, keySet.isEmpty());
+    assertEquals(!keySet.isEmpty(), keySet.iterator().hasNext());
+
+    int expectedKeySetHash = 0;
+    for (K key : keySet) {
+      V value = map.get(key);
+      expectedKeySetHash += key != null ? key.hashCode() : 0;
+      assertTrue(map.containsKey(key));
+      assertTrue(map.containsValue(value));
+      assertTrue(valueCollection.contains(value));
+      assertTrue(valueCollection.containsAll(Collections.singleton(value)));
+      assertTrue(entrySet.contains(mapEntry(key, value)));
+      assertTrue(allowsNullKeys || (key != null));
+    }
+    assertEquals(expectedKeySetHash, keySet.hashCode());
+
+    assertEquals(map.size(), valueCollection.size());
+    assertEquals(valueCollection.size() == 0, valueCollection.isEmpty());
+    assertEquals(!valueCollection.isEmpty(), valueCollection.iterator()
+        .hasNext());
+    for (V value : valueCollection) {
+      assertTrue(map.containsValue(value));
+      assertTrue(allowsNullValues || (value != null));
+    }
+
+    assertEquals(map.size(), entrySet.size());
+    assertEquals(entrySet.size() == 0, entrySet.isEmpty());
+    assertEquals(!entrySet.isEmpty(), entrySet.iterator().hasNext());
+    assertTrue(!entrySet.contains("foo"));
+
+    boolean supportsValuesHashCode = supportsValuesHashCode(map);
+    if (supportsValuesHashCode) {
+      int expectedEntrySetHash = 0;
+      for (Entry<K, V> entry : entrySet) {
+        assertTrue(map.containsKey(entry.getKey()));
+        assertTrue(map.containsValue(entry.getValue()));
+        int expectedHash = (entry.getKey() == null ? 0 : entry.getKey()
+            .hashCode())
+            ^ (entry.getValue() == null ? 0 : entry.getValue().hashCode());
+        assertEquals(expectedHash, entry.hashCode());
+        expectedEntrySetHash += expectedHash;
+      }
+      assertEquals(expectedEntrySetHash, entrySet.hashCode());
+      assertTrue(entrySet.containsAll(new HashSet<Entry<K, V>>(entrySet)));
+      assertTrue(entrySet.equals(new HashSet<Entry<K, V>>(entrySet)));
+    }
+
+    Object[] entrySetToArray1 = entrySet.toArray();
+    assertEquals(map.size(), entrySetToArray1.length);
+    assertTrue(Arrays.asList(entrySetToArray1).containsAll(entrySet));
+
+    Entry<?, ?>[] entrySetToArray2 = new Entry<?, ?>[map.size() + 2];
+    entrySetToArray2[map.size()] = mapEntry("foo", 1);
+    assertSame(entrySetToArray2, entrySet.toArray(entrySetToArray2));
+    assertNull(entrySetToArray2[map.size()]);
+    assertTrue(Arrays.asList(entrySetToArray2).containsAll(entrySet));
+
+    Object[] valuesToArray1 = valueCollection.toArray();
+    assertEquals(map.size(), valuesToArray1.length);
+    assertTrue(Arrays.asList(valuesToArray1).containsAll(valueCollection));
+
+    Object[] valuesToArray2 = new Object[map.size() + 2];
+    valuesToArray2[map.size()] = "foo";
+    assertSame(valuesToArray2, valueCollection.toArray(valuesToArray2));
+    assertNull(valuesToArray2[map.size()]);
+    assertTrue(Arrays.asList(valuesToArray2).containsAll(valueCollection));
+
+    if (supportsValuesHashCode) {
+      int expectedHash = 0;
+      for (Entry<K, V> entry : entrySet) {
+        expectedHash += entry.hashCode();
+      }
+      assertEquals(expectedHash, map.hashCode());
+    }
+
+    assertMoreInvariants(map);
+  }
+
+  /**
+   * Override this to check invariants which should hold true for a particular
+   * implementation, but which are not generally applicable to every instance of
+   * Map.
+   * 
+   * @param map the map whose additional invariants to check.
+   */
+  protected void assertMoreInvariants(Map<K, V> map) {
+  }
+
+  public void testClear() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    if (supportsClear) {
+      map.clear();
+      assertTrue(map.isEmpty());
+    } else {
+      try {
+        map.clear();
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testContainsKey() {
+    final Map<K, V> map;
+    final K unmappedKey;
+    try {
+      map = makePopulatedMap();
+      unmappedKey = getKeyNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertTrue(!map.containsKey(unmappedKey));
+    assertTrue(map.containsKey(map.keySet().iterator().next()));
+    if (allowsNullKeys) {
+      map.containsKey(null);
+    } else {
+      try {
+        map.containsKey(null);
+      } catch (NullPointerException optional) {
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testContainsValue() {
+    final Map<K, V> map;
+    final V unmappedValue;
+    try {
+      map = makePopulatedMap();
+      unmappedValue = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertTrue(!map.containsValue(unmappedValue));
+    assertTrue(map.containsValue(map.values().iterator().next()));
+    if (allowsNullValues) {
+      map.containsValue(null);
+    } else {
+      try {
+        map.containsKey(null);
+      } catch (NullPointerException optional) {
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testEntrySet() {
+    final Map<K, V> map;
+    final Set<Entry<K, V>> entrySet;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertInvariants(map);
+
+    entrySet = map.entrySet();
+    final K unmappedKey;
+    final V unmappedValue;
+    try {
+      unmappedKey = getKeyNotInPopulatedMap();
+      unmappedValue = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    for (Entry<K, V> entry : entrySet) {
+      assertTrue(!unmappedKey.equals(entry.getKey()));
+      assertTrue(!unmappedValue.equals(entry.getValue()));
+    }
+  }
+
+  public void testEntrySetForEmptyMap() {
+    final Map<K, V> map;
+    try {
+      map = makeEmptyMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertInvariants(map);
+  }
+
+  public void testEntrySetContainsEntryNullKeyPresent() {
+    if (!allowsNullKeys || !supportsPut) {
+      return;
+    }
+    final Map<K, V> map;
+    final Set<Entry<K, V>> entrySet;
+    try {
+      map = makeEitherMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertInvariants(map);
+
+    entrySet = map.entrySet();
+    final V unmappedValue;
+    try {
+      unmappedValue = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    map.put(null, unmappedValue);
+    Entry<K, V> entry = mapEntry(null, unmappedValue);
+    assertTrue(entrySet.contains(entry));
+    assertTrue(!entrySet.contains(mapEntry(null, null)));
+  }
+
+  public void testEntrySetContainsEntryNullKeyMissing() {
+    final Map<K, V> map;
+    final Set<Entry<K, V>> entrySet;
+    try {
+      map = makeEitherMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertInvariants(map);
+
+    entrySet = map.entrySet();
+    final V unmappedValue;
+    try {
+      unmappedValue = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    Entry<K, V> entry = mapEntry(null, unmappedValue);
+    assertTrue(!entrySet.contains(entry));
+    assertTrue(!entrySet.contains(mapEntry(null, null)));
+  }
+
+  public void testEntrySetIteratorRemove() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    Iterator<Entry<K, V>> iterator = entrySet.iterator();
+    if (supportsIteratorRemove) {
+      int initialSize = map.size();
+      Entry<K, V> entry = iterator.next();
+      iterator.remove();
+      assertEquals(initialSize - 1, map.size());
+      assertTrue(!entrySet.contains(entry));
+      assertInvariants(map);
+      try {
+        iterator.remove();
+        fail("Expected IllegalStateException.");
+      } catch (IllegalStateException e) {
+        // Expected.
+      }
+    } else {
+      try {
+        iterator.next();
+        iterator.remove();
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testEntrySetRemove() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    if (supportsRemove) {
+      int initialSize = map.size();
+      boolean didRemove = entrySet.remove(entrySet.iterator().next());
+      assertTrue(didRemove);
+      assertEquals(initialSize - 1, map.size());
+    } else {
+      try {
+        entrySet.remove(entrySet.iterator().next());
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testEntrySetRemoveMissingKey() {
+    final Map<K, V> map;
+    final K key;
+    try {
+      map = makeEitherMap();
+      key = getKeyNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    Entry<K, V> entry = mapEntry(key, getValueNotInPopulatedMap());
+    int initialSize = map.size();
+    if (supportsRemove) {
+      boolean didRemove = entrySet.remove(entry);
+      assertTrue(!didRemove);
+    } else {
+      try {
+        boolean didRemove = entrySet.remove(entry);
+        assertTrue(!didRemove);
+      } catch (UnsupportedOperationException optional) {
+      }
+    }
+    assertEquals(initialSize, map.size());
+    assertTrue(!map.containsKey(key));
+    assertInvariants(map);
+  }
+
+  public void testEntrySetRemoveDifferentValue() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    K key = map.keySet().iterator().next();
+    Entry<K, V> entry = mapEntry(key, getValueNotInPopulatedMap());
+    int initialSize = map.size();
+    if (supportsRemove) {
+      boolean didRemove = entrySet.remove(entry);
+      assertTrue(!didRemove);
+    } else {
+      try {
+        boolean didRemove = entrySet.remove(entry);
+        assertTrue(!didRemove);
+      } catch (UnsupportedOperationException optional) {
+      }
+    }
+    assertEquals(initialSize, map.size());
+    assertTrue(map.containsKey(key));
+    assertInvariants(map);
+  }
+
+  public void testEntrySetRemoveNullKeyPresent() {
+    if (!allowsNullKeys || !supportsPut || !supportsRemove) {
+      return;
+    }
+    final Map<K, V> map;
+    final Set<Entry<K, V>> entrySet;
+    try {
+      map = makeEitherMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertInvariants(map);
+
+    entrySet = map.entrySet();
+    final V unmappedValue;
+    try {
+      unmappedValue = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    map.put(null, unmappedValue);
+    assertEquals(unmappedValue, map.get(null));
+    assertTrue(map.containsKey(null));
+    Entry<K, V> entry = mapEntry(null, unmappedValue);
+    assertTrue(entrySet.remove(entry));
+    assertNull(map.get(null));
+    assertTrue(!map.containsKey(null));
+  }
+
+  public void testEntrySetRemoveNullKeyMissing() {
+    final Map<K, V> map;
+    try {
+      map = makeEitherMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    Entry<K, V> entry = mapEntry(null, getValueNotInPopulatedMap());
+    int initialSize = map.size();
+    if (supportsRemove) {
+      boolean didRemove = entrySet.remove(entry);
+      assertTrue(!didRemove);
+    } else {
+      try {
+        boolean didRemove = entrySet.remove(entry);
+        assertTrue(!didRemove);
+      } catch (UnsupportedOperationException optional) {
+      }
+    }
+    assertEquals(initialSize, map.size());
+    assertInvariants(map);
+  }
+
+  public void testEntrySetRemoveAll() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    Set<Entry<K, V>> entriesToRemove = singleton(entrySet.iterator().next());
+    if (supportsRemove) {
+      int initialSize = map.size();
+      boolean didRemove = entrySet.removeAll(entriesToRemove);
+      assertTrue(didRemove);
+      assertEquals(initialSize - entriesToRemove.size(), map.size());
+      for (Entry<K, V> entry : entriesToRemove) {
+        assertTrue(!entrySet.contains(entry));
+      }
+    } else {
+      try {
+        entrySet.removeAll(entriesToRemove);
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testEntrySetRemoveAllNullFromEmpty() {
+    final Map<K, V> map;
+    try {
+      map = makeEmptyMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    if (supportsRemove) {
+      try {
+        entrySet.removeAll(null);
+        fail("Expected NullPointerException.");
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    } else {
+      try {
+        entrySet.removeAll(null);
+        fail("Expected UnsupportedOperationException or NullPointerException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testEntrySetRetainAll() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    Set<Entry<K, V>> entriesToRetain = singleton(entrySet.iterator().next());
+    if (supportsRemove) {
+      boolean shouldRemove = (entrySet.size() > entriesToRetain.size());
+      boolean didRemove = entrySet.retainAll(entriesToRetain);
+      assertEquals(shouldRemove, didRemove);
+      assertEquals(entriesToRetain.size(), map.size());
+      for (Entry<K, V> entry : entriesToRetain) {
+        assertTrue(entrySet.contains(entry));
+      }
+    } else {
+      try {
+        entrySet.retainAll(entriesToRetain);
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testEntrySetRetainAllNullFromEmpty() {
+    final Map<K, V> map;
+    try {
+      map = makeEmptyMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    if (supportsRemove) {
+      try {
+        entrySet.retainAll(null);
+        // Returning successfully is not ideal, but tolerated.
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    } else {
+      try {
+        entrySet.retainAll(null);
+        // We have to tolerate a successful return (Sun bug 4802647)
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testEntrySetClear() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    if (supportsClear) {
+      entrySet.clear();
+      assertTrue(entrySet.isEmpty());
+    } else {
+      try {
+        entrySet.clear();
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testEntrySetAddAndAddAll() {
+    final Map<K, V> map = makeEitherMap();
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    final Entry<K, V> entryToAdd = mapEntry(null, null);
+    try {
+      entrySet.add(entryToAdd);
+      fail("Expected UnsupportedOperationException or NullPointerException.");
+    } catch (UnsupportedOperationException e) {
+      // Expected.
+    } catch (NullPointerException e) {
+      // Expected.
+    }
+    assertInvariants(map);
+
+    try {
+      entrySet.addAll(singleton(entryToAdd));
+      fail("Expected UnsupportedOperationException or NullPointerException.");
+    } catch (UnsupportedOperationException e) {
+      // Expected.
+    } catch (NullPointerException e) {
+      // Expected.
+    }
+    assertInvariants(map);
+  }
+
+  public void testEntrySetSetValue() {
+    // TODO: Investigate the extent to which, in practice, maps that support
+    // put() also support Entry.setValue().
+    if (!supportsPut) {
+      return;
+    }
+
+    final Map<K, V> map;
+    final V valueToSet;
+    try {
+      map = makePopulatedMap();
+      valueToSet = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    Entry<K, V> entry = entrySet.iterator().next();
+    final V oldValue = entry.getValue();
+    final V returnedValue = entry.setValue(valueToSet);
+    assertEquals(oldValue, returnedValue);
+    assertTrue(entrySet.contains(mapEntry(entry.getKey(), valueToSet)));
+    assertEquals(valueToSet, map.get(entry.getKey()));
+    assertInvariants(map);
+  }
+
+  public void testEntrySetSetValueSameValue() {
+    // TODO: Investigate the extent to which, in practice, maps that support
+    // put() also support Entry.setValue().
+    if (!supportsPut) {
+      return;
+    }
+
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<Entry<K, V>> entrySet = map.entrySet();
+    Entry<K, V> entry = entrySet.iterator().next();
+    final V oldValue = entry.getValue();
+    final V returnedValue = entry.setValue(oldValue);
+    assertEquals(oldValue, returnedValue);
+    assertTrue(entrySet.contains(mapEntry(entry.getKey(), oldValue)));
+    assertEquals(oldValue, map.get(entry.getKey()));
+    assertInvariants(map);
+  }
+
+  public void testEqualsForEqualMap() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    assertEquals(map, map);
+    assertEquals(makePopulatedMap(), map);
+    assertTrue(!map.equals(Collections.emptyMap()));
+    // no-inspection ObjectEqualsNull
+    assertTrue(!map.equals(null));
+  }
+
+  public void testEqualsForLargerMap() {
+    if (!supportsPut) {
+      return;
+    }
+
+    final Map<K, V> map;
+    final Map<K, V> largerMap;
+    try {
+      map = makePopulatedMap();
+      largerMap = makePopulatedMap();
+      largerMap.put(getKeyNotInPopulatedMap(), getValueNotInPopulatedMap());
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    assertTrue(!map.equals(largerMap));
+  }
+
+  public void testEqualsForSmallerMap() {
+    if (!supportsRemove) {
+      return;
+    }
+
+    final Map<K, V> map;
+    final Map<K, V> smallerMap;
+    try {
+      map = makePopulatedMap();
+      smallerMap = new LinkedHashMap<K, V>(map);
+      // smallerMap = makePopulatedMap();
+      smallerMap.remove(smallerMap.keySet().iterator().next());
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    assertTrue(!map.equals(smallerMap));
+  }
+
+  public void testEqualsForEmptyMap() {
+    final Map<K, V> map;
+    try {
+      map = makeEmptyMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    assertEquals(map, map);
+    assertEquals(makeEmptyMap(), map);
+    assertEquals(Collections.emptyMap(), map);
+    assertTrue(!map.equals(Collections.emptySet()));
+    // noinspection ObjectEqualsNull
+    assertTrue(!map.equals(null));
+  }
+
+  public void testGet() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    for (Entry<K, V> entry : map.entrySet()) {
+      assertEquals(entry.getValue(), map.get(entry.getKey()));
+    }
+
+    K unmappedKey = null;
+    try {
+      unmappedKey = getKeyNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertNull(map.get(unmappedKey));
+  }
+
+  public void testGetForEmptyMap() {
+    final Map<K, V> map;
+    K unmappedKey = null;
+    try {
+      map = makeEmptyMap();
+      unmappedKey = getKeyNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertNull(map.get(unmappedKey));
+  }
+
+  public void testGetNull() {
+    Map<K, V> map = makeEitherMap();
+    if (allowsNullKeys) {
+      if (allowsNullValues) {
+        // TODO: decide what to test here.
+      } else {
+        assertEquals(map.containsKey(null), map.get(null) != null);
+      }
+    } else {
+      try {
+        map.get(null);
+      } catch (NullPointerException optional) {
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testHashCode() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertInvariants(map);
+  }
+
+  public void testHashCodeForEmptyMap() {
+    final Map<K, V> map;
+    try {
+      map = makeEmptyMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertInvariants(map);
+  }
+
+  public void testPutNewKey() {
+    final Map<K, V> map = makeEitherMap();
+    final K keyToPut;
+    final V valueToPut;
+    try {
+      keyToPut = getKeyNotInPopulatedMap();
+      valueToPut = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    if (supportsPut) {
+      int initialSize = map.size();
+      V oldValue = map.put(keyToPut, valueToPut);
+      assertEquals(valueToPut, map.get(keyToPut));
+      assertTrue(map.containsKey(keyToPut));
+      assertTrue(map.containsValue(valueToPut));
+      assertEquals(initialSize + 1, map.size());
+      assertNull(oldValue);
+    } else {
+      try {
+        map.put(keyToPut, valueToPut);
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testPutExistingKey() {
+    final Map<K, V> map;
+    final K keyToPut;
+    final V valueToPut;
+    try {
+      map = makePopulatedMap();
+      valueToPut = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    keyToPut = map.keySet().iterator().next();
+    if (supportsPut) {
+      int initialSize = map.size();
+      map.put(keyToPut, valueToPut);
+      assertEquals(valueToPut, map.get(keyToPut));
+      assertTrue(map.containsKey(keyToPut));
+      assertTrue(map.containsValue(valueToPut));
+      assertEquals(initialSize, map.size());
+    } else {
+      try {
+        map.put(keyToPut, valueToPut);
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testPutNullKey() {
+    if (!supportsPut) {
+      return;
+    }
+    final Map<K, V> map = makeEitherMap();
+    final V valueToPut;
+    try {
+      valueToPut = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    if (allowsNullKeys) {
+      final V oldValue = map.get(null);
+      final V returnedValue = map.put(null, valueToPut);
+      assertEquals(oldValue, returnedValue);
+      assertEquals(valueToPut, map.get(null));
+      assertTrue(map.containsKey(null));
+      assertTrue(map.containsValue(valueToPut));
+    } else {
+      try {
+        map.put(null, valueToPut);
+        fail("Expected RuntimeException");
+      } catch (RuntimeException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testPutNullValue() {
+    if (!supportsPut) {
+      return;
+    }
+    final Map<K, V> map = makeEitherMap();
+    final K keyToPut;
+    try {
+      keyToPut = getKeyNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    if (allowsNullValues) {
+      int initialSize = map.size();
+      final V oldValue = map.get(keyToPut);
+      final V returnedValue = map.put(keyToPut, null);
+      assertEquals(oldValue, returnedValue);
+      assertNull(map.get(keyToPut));
+      assertTrue(map.containsKey(keyToPut));
+      assertTrue(map.containsValue(null));
+      assertEquals(initialSize + 1, map.size());
+    } else {
+      try {
+        map.put(keyToPut, null);
+        fail("Expected RuntimeException");
+      } catch (RuntimeException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testPutNullValueForExistingKey() {
+    if (!supportsPut) {
+      return;
+    }
+    final Map<K, V> map;
+    final K keyToPut;
+    try {
+      map = makePopulatedMap();
+      keyToPut = map.keySet().iterator().next();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    if (allowsNullValues) {
+      int initialSize = map.size();
+      final V oldValue = map.get(keyToPut);
+      final V returnedValue = map.put(keyToPut, null);
+      assertEquals(oldValue, returnedValue);
+      assertNull(map.get(keyToPut));
+      assertTrue(map.containsKey(keyToPut));
+      assertTrue(map.containsValue(null));
+      assertEquals(initialSize, map.size());
+    } else {
+      try {
+        map.put(keyToPut, null);
+        fail("Expected RuntimeException");
+      } catch (RuntimeException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testPutAllNewKey() {
+    final Map<K, V> map = makeEitherMap();
+    final K keyToPut;
+    final V valueToPut;
+    try {
+      keyToPut = getKeyNotInPopulatedMap();
+      valueToPut = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    final Map<K, V> mapToPut = Collections.singletonMap(keyToPut, valueToPut);
+    if (supportsPut) {
+      int initialSize = map.size();
+      map.putAll(mapToPut);
+      assertEquals(valueToPut, map.get(keyToPut));
+      assertTrue(map.containsKey(keyToPut));
+      assertTrue(map.containsValue(valueToPut));
+      assertEquals(initialSize + 1, map.size());
+    } else {
+      try {
+        map.putAll(mapToPut);
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testPutAllExistingKey() {
+    final Map<K, V> map;
+    final K keyToPut;
+    final V valueToPut;
+    try {
+      map = makePopulatedMap();
+      valueToPut = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    keyToPut = map.keySet().iterator().next();
+    final Map<K, V> mapToPut = Collections.singletonMap(keyToPut, valueToPut);
+    int initialSize = map.size();
+    if (supportsPut) {
+      map.putAll(mapToPut);
+      assertEquals(valueToPut, map.get(keyToPut));
+      assertTrue(map.containsKey(keyToPut));
+      assertTrue(map.containsValue(valueToPut));
+    } else {
+      try {
+        map.putAll(mapToPut);
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertEquals(initialSize, map.size());
+    assertInvariants(map);
+  }
+
+  public void testRemove() {
+    final Map<K, V> map;
+    final K keyToRemove;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    keyToRemove = map.keySet().iterator().next();
+    if (supportsRemove) {
+      int initialSize = map.size();
+      V expectedValue = map.get(keyToRemove);
+      V oldValue = map.remove(keyToRemove);
+      assertEquals(expectedValue, oldValue);
+      assertTrue(!map.containsKey(keyToRemove));
+      assertEquals(initialSize - 1, map.size());
+    } else {
+      try {
+        map.remove(keyToRemove);
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testRemoveMissingKey() {
+    final Map<K, V> map;
+    final K keyToRemove;
+    try {
+      map = makePopulatedMap();
+      keyToRemove = getKeyNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    if (supportsRemove) {
+      int initialSize = map.size();
+      assertNull(map.remove(keyToRemove));
+      assertEquals(initialSize, map.size());
+    } else {
+      try {
+        map.remove(keyToRemove);
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testSize() {
+    assertInvariants(makeEitherMap());
+  }
+
+  public void testKeySetClear() {
+    final Map<K, V> map;
+    try {
+      map = makeEitherMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<K> keySet = map.keySet();
+    if (supportsClear) {
+      keySet.clear();
+      assertTrue(keySet.isEmpty());
+    } else {
+      try {
+        keySet.clear();
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testKeySetRemoveAllNullFromEmpty() {
+    final Map<K, V> map;
+    try {
+      map = makeEmptyMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<K> keySet = map.keySet();
+    if (supportsRemove) {
+      try {
+        keySet.removeAll(null);
+        fail("Expected NullPointerException.");
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    } else {
+      try {
+        keySet.removeAll(null);
+        fail("Expected UnsupportedOperationException or NullPointerException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testKeySetRetainAllNullFromEmpty() {
+    final Map<K, V> map;
+    try {
+      map = makeEmptyMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Set<K> keySet = map.keySet();
+    if (supportsRemove) {
+      try {
+        keySet.retainAll(null);
+        // Returning successfully is not ideal, but tolerated.
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    } else {
+      try {
+        keySet.retainAll(null);
+        // We have to tolerate a successful return (Sun bug 4802647)
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testValues() {
+    final Map<K, V> map;
+    final Collection<V> valueCollection;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    assertInvariants(map);
+
+    valueCollection = map.values();
+    final V unmappedValue;
+    try {
+      unmappedValue = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    for (V value : valueCollection) {
+      assertTrue(!unmappedValue.equals(value));
+    }
+  }
+
+  public void testValuesIteratorRemove() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Collection<V> valueCollection = map.values();
+    Iterator<V> iterator = valueCollection.iterator();
+    if (supportsIteratorRemove) {
+      int initialSize = map.size();
+      iterator.next();
+      iterator.remove();
+      assertEquals(initialSize - 1, map.size());
+      // (We can't assert that the values collection no longer contains the
+      // removed value, because the underlying map can have multiple mappings
+      // to the same value.)
+      assertInvariants(map);
+      try {
+        iterator.remove();
+        fail("Expected IllegalStateException.");
+      } catch (IllegalStateException e) {
+        // Expected.
+      }
+    } else {
+      try {
+        iterator.next();
+        iterator.remove();
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testValuesRemove() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Collection<V> valueCollection = map.values();
+    if (supportsRemove) {
+      int initialSize = map.size();
+      valueCollection.remove(valueCollection.iterator().next());
+      assertEquals(initialSize - 1, map.size());
+      // (We can't assert that the values collection no longer contains the
+      // removed value, because the underlying map can have multiple mappings
+      // to the same value.)
+    } else {
+      try {
+        valueCollection.remove(valueCollection.iterator().next());
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testValuesRemoveMissing() {
+    final Map<K, V> map;
+    final V valueToRemove;
+    try {
+      map = makeEitherMap();
+      valueToRemove = getValueNotInPopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Collection<V> valueCollection = map.values();
+    int initialSize = map.size();
+    if (supportsRemove) {
+      assertTrue(!valueCollection.remove(valueToRemove));
+    } else {
+      try {
+        assertTrue(!valueCollection.remove(valueToRemove));
+      } catch (UnsupportedOperationException e) {
+        // Tolerated.
+      }
+    }
+    assertEquals(initialSize, map.size());
+    assertInvariants(map);
+  }
+
+  public void testValuesRemoveAll() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Collection<V> valueCollection = map.values();
+    Set<V> valuesToRemove = singleton(valueCollection.iterator().next());
+    if (supportsRemove) {
+      valueCollection.removeAll(valuesToRemove);
+      for (V value : valuesToRemove) {
+        assertTrue(!valueCollection.contains(value));
+      }
+      for (V value : valueCollection) {
+        assertTrue(!valuesToRemove.contains(value));
+      }
+    } else {
+      try {
+        valueCollection.removeAll(valuesToRemove);
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testValuesRemoveAllNullFromEmpty() {
+    final Map<K, V> map;
+    try {
+      map = makeEmptyMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Collection<V> values = map.values();
+    if (supportsRemove) {
+      try {
+        values.removeAll(null);
+        // Returning successfully is not ideal, but tolerated.
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    } else {
+      try {
+        values.removeAll(null);
+        // We have to tolerate a successful return (Sun bug 4802647)
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testValuesRetainAll() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Collection<V> valueCollection = map.values();
+    Set<V> valuesToRetain = singleton(valueCollection.iterator().next());
+    if (supportsRemove) {
+      valueCollection.retainAll(valuesToRetain);
+      for (V value : valuesToRetain) {
+        assertTrue(valueCollection.contains(value));
+      }
+      for (V value : valueCollection) {
+        assertTrue(valuesToRetain.contains(value));
+      }
+    } else {
+      try {
+        valueCollection.retainAll(valuesToRetain);
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testValuesRetainAllNullFromEmpty() {
+    final Map<K, V> map;
+    try {
+      map = makeEmptyMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Collection<V> values = map.values();
+    if (supportsRemove) {
+      try {
+        values.retainAll(null);
+        // Returning successfully is not ideal, but tolerated.
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    } else {
+      try {
+        values.retainAll(null);
+        // We have to tolerate a successful return (Sun bug 4802647)
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      } catch (NullPointerException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  public void testValuesClear() {
+    final Map<K, V> map;
+    try {
+      map = makePopulatedMap();
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+
+    Collection<V> valueCollection = map.values();
+    if (supportsClear) {
+      valueCollection.clear();
+      assertTrue(valueCollection.isEmpty());
+    } else {
+      try {
+        valueCollection.clear();
+        fail("Expected UnsupportedOperationException.");
+      } catch (UnsupportedOperationException e) {
+        // Expected.
+      }
+    }
+    assertInvariants(map);
+  }
+
+  private static <K, V> Entry<K, V> mapEntry(K key, V value) {
+    return Collections.singletonMap(key, value).entrySet().iterator().next();
+  }
+}

Added: hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/ObjectOutputStreamTest.java
URL: http://svn.apache.org/viewvc/hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/ObjectOutputStreamTest.java?rev=1387533&view=auto
==============================================================================
--- hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/ObjectOutputStreamTest.java (added)
+++ hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/ObjectOutputStreamTest.java Wed Sep 19 11:52:20 2012
@@ -0,0 +1,46 @@
+/**
+ * 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.hama.jdbm;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.hama.jdbm.SerialClassInfoTest.Bean1;
+
+public class ObjectOutputStreamTest extends TestCase {
+
+  @SuppressWarnings("unchecked")
+  <E> E neser(E e) throws IOException, ClassNotFoundException {
+    ByteArrayOutputStream i = new ByteArrayOutputStream();
+    new AdvancedObjectOutputStream(i).writeObject(e);
+    return (E) new AdvancedObjectInputStream(new ByteArrayInputStream(
+        i.toByteArray())).readObject();
+  }
+
+  public void testSimple() throws ClassNotFoundException, IOException {
+
+    Bean1 b = new Bean1("qwe", "rty");
+    Bean1 b2 = neser(b);
+
+    assertEquals(b, b2);
+
+  }
+}

Added: hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageFileTest.java
URL: http://svn.apache.org/viewvc/hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageFileTest.java?rev=1387533&view=auto
==============================================================================
--- hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageFileTest.java (added)
+++ hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageFileTest.java Wed Sep 19 11:52:20 2012
@@ -0,0 +1,133 @@
+/**
+ * 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.hama.jdbm;
+
+import java.io.File;
+
+/**
+ * This class contains all Unit tests for {@link PageFile}.
+ */
+final public class PageFileTest extends TestCaseWithTestFile {
+
+  public static void deleteFile(String filename) {
+    File file = new File(filename);
+
+    if (file.exists()) {
+      try {
+        file.delete();
+      } catch (Exception except) {
+        except.printStackTrace();
+      }
+      if (file.exists()) {
+        System.out.println("WARNING:  Cannot delete file: " + file);
+      }
+    }
+  }
+
+  /**
+   * Test constructor
+   */
+  public void testCtor() throws Exception {
+    PageFile file = newRecordFile();
+    file.close();
+  }
+
+  /**
+   * Test addition of record 0
+   */
+  public void testAddZero() throws Exception {
+    String f = newTestFile();
+    PageFile file = new PageFile(f);
+    PageIo data = file.get(0);
+    data.writeByte(14, (byte) 'b');
+    file.release(0, true);
+    file.close();
+    file = new PageFile(f);
+    data = file.get(0);
+    assertEquals((byte) 'b', data.readByte(14));
+    file.release(0, false);
+    file.close();
+  }
+
+  /**
+   * Test addition of a number of records, with holes.
+   */
+  public void testWithHoles() throws Exception {
+    String f = newTestFile();
+    PageFile file = new PageFile(f);
+
+    // Write recid 0, byte 0 with 'b'
+    PageIo data = file.get(0);
+    data.writeByte(0, (byte) 'b');
+    file.release(0, true);
+
+    // Write recid 10, byte 10 with 'c'
+    data = file.get(10);
+    data.writeByte(10, (byte) 'c');
+    file.release(10, true);
+
+    // Write recid 5, byte 5 with 'e'
+    data = file.get(5);
+    data.writeByte(5, (byte) 'e');
+    file.release(5, false);
+
+    file.close();
+
+    file = new PageFile(f);
+    data = file.get(0);
+    assertEquals("0 = b", (byte) 'b', data.readByte(0));
+    file.release(0, false);
+
+    data = file.get(5);
+    assertEquals("5 = 0", (byte) 'e', data.readByte(5));
+    file.release(5, false);
+
+    data = file.get(10);
+    assertEquals("10 = c", (byte) 'c', data.readByte(10));
+    file.release(10, false);
+
+    file.close();
+  }
+
+  /**
+   * Test wrong release
+   */
+  public void testWrongRelease() throws Exception {
+    PageFile file = newRecordFile();
+
+    // Write recid 0, byte 0 with 'b'
+    PageIo data = file.get(0);
+    data.writeByte(0, (byte) 'b');
+    try {
+      file.release(1, true);
+      fail("expected exception");
+    } catch (NullPointerException except) {
+      // ignore
+    }
+    file.release(0, false);
+
+    file.close();
+
+    // @alex retry to open the file
+    /*
+     * file = new PageFile( testFileName ); PageManager pm = new PageManager(
+     * file ); pm.close(); file.close();
+     */
+  }
+
+}

Added: hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageIoTest.java
URL: http://svn.apache.org/viewvc/hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageIoTest.java?rev=1387533&view=auto
==============================================================================
--- hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageIoTest.java (added)
+++ hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageIoTest.java Wed Sep 19 11:52:20 2012
@@ -0,0 +1,104 @@
+/**
+ * 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.hama.jdbm;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+/**
+ * This class contains all Unit tests for {@link PageIo}.
+ */
+public class PageIoTest extends TestCase {
+
+  private static final short SHORT_VALUE = 0x1234;
+  private static final int INT_VALUE = 0xe7b3c8a1;
+  private static final long LONG_VALUE = 0xfdebca9876543210L;
+  private static final long LONG_VALUE2 = 1231290495545446485L;
+
+  /**
+   * Test writing
+   */
+  public void testWrite() throws Exception {
+    byte[] data = new byte[100];
+    PageIo test = new PageIo(0, data);
+    test.writeShort(0, SHORT_VALUE);
+    test.writeLong(2, LONG_VALUE);
+    test.writeInt(10, INT_VALUE);
+    test.writeLong(14, LONG_VALUE2);
+
+    DataInputStream is = new DataInputStream(new ByteArrayInputStream(data));
+    assertEquals("short", SHORT_VALUE, is.readShort());
+    assertEquals("long", LONG_VALUE, is.readLong());
+    assertEquals("int", INT_VALUE, is.readInt());
+    assertEquals("long", LONG_VALUE2, is.readLong());
+
+    assertEquals("short", SHORT_VALUE, test.readShort(0));
+    assertEquals("long", LONG_VALUE, test.readLong(2));
+    assertEquals("int", INT_VALUE, test.readInt(10));
+    assertEquals("long", LONG_VALUE2, test.readLong(14));
+
+  }
+
+  /**
+   * Test reading
+   */
+  public void testRead() throws Exception {
+    ByteArrayOutputStream bos = new ByteArrayOutputStream(100);
+    DataOutputStream os = new DataOutputStream(bos);
+    os.writeShort(SHORT_VALUE);
+    os.writeLong(LONG_VALUE);
+    os.writeInt(INT_VALUE);
+    os.writeLong(LONG_VALUE2);
+
+    byte[] data = bos.toByteArray();
+    PageIo test = new PageIo(0, data);
+    assertEquals("short", SHORT_VALUE, test.readShort(0));
+    assertEquals("long", LONG_VALUE, test.readLong(2));
+    assertEquals("int", INT_VALUE, test.readInt(10));
+    assertEquals("long", LONG_VALUE2, test.readLong(14));
+  }
+
+  public void testNegativeSixByte() {
+
+    PageIo t = new PageIo(0, ByteBuffer.allocate(Storage.PAGE_SIZE));
+
+    t.writeSixByteLong(0, -11111);
+    assertEquals(-11111, t.readSixByteLong(0));
+
+    t.writeSixByteLong(0, 11111);
+    assertEquals(11111, t.readSixByteLong(0));
+
+  }
+
+  public void testPageHeaderSetWriteRead() throws Exception {
+    PageIo data = new PageIo(0, new byte[Storage.PAGE_SIZE]);
+    data.writeShort(0, Magic.PAGE_MAGIC);
+
+    data.pageHeaderSetNext(10);
+    data.pageHeaderSetPrev(33);
+
+    assertEquals("next", 10, data.pageHeaderGetNext());
+    assertEquals("prev", 33, data.pageHeaderGetPrev());
+  }
+
+}

Added: hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageManagerTest.java
URL: http://svn.apache.org/viewvc/hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageManagerTest.java?rev=1387533&view=auto
==============================================================================
--- hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageManagerTest.java (added)
+++ hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageManagerTest.java Wed Sep 19 11:52:20 2012
@@ -0,0 +1,64 @@
+/**
+ * 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.hama.jdbm;
+
+/**
+ * This class contains all Unit tests for {@link PageManager}.
+ */
+public class PageManagerTest extends TestCaseWithTestFile {
+
+  /**
+   * Test constructor
+   */
+  public void testCtor() throws Exception {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+
+    f.forceClose();
+  }
+
+  /**
+   * Test allocations on a single list.
+   */
+  public void testAllocSingleList() throws Exception {
+    String file = newTestFile();
+    PageFile f = new PageFile(file);
+    PageManager pm = new PageManager(f);
+    for (int i = 0; i < 100; i++) {
+      assertEquals("allocate ", (long) i + 1, pm.allocate(Magic.USED_PAGE));
+    }
+    pm.close();
+    f.close();
+
+    f = new PageFile(file);
+    pm = new PageManager(f);
+
+    long i = 1;
+    for (long cur = pm.getFirst(Magic.USED_PAGE); cur != 0; cur = pm
+        .getNext(cur)) {
+      assertEquals("next", i++, cur);
+      if (i > 120)
+        fail("list structure not ok");
+    }
+    assertEquals("total", 101, i);
+    pm.close();
+    f.close();
+  }
+
+}

Added: hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageTransactionManagerTest.java
URL: http://svn.apache.org/viewvc/hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageTransactionManagerTest.java?rev=1387533&view=auto
==============================================================================
--- hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageTransactionManagerTest.java (added)
+++ hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PageTransactionManagerTest.java Wed Sep 19 11:52:20 2012
@@ -0,0 +1,118 @@
+/**
+ * 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.hama.jdbm;
+
+import java.io.File;
+
+/**
+ * This class contains all Unit tests for {@link PageTransactionManager}. TODO
+ * sort out this testcase
+ */
+public class PageTransactionManagerTest extends TestCaseWithTestFile {
+
+  String file = newTestFile();
+
+  /**
+   * Test constructor. Oops - can only be done indirectly :-)
+   */
+  public void testCtor() throws Exception {
+    PageFile file2 = new PageFile(file);
+
+    file2.forceClose();
+  }
+
+  /**
+   * Test recovery
+   */
+  public void XtestRecovery() throws Exception {
+    PageFile file1 = new PageFile(file);
+
+    // Do three transactions.
+    for (int i = 0; i < 3; i++) {
+      PageIo node = file1.get(i);
+      node.setDirty();
+      file1.release(node);
+      file1.commit();
+    }
+    assertDataSizeEquals("len1", 0);
+    assertLogSizeNotZero("len1");
+
+    file1.forceClose();
+
+    // Leave the old record file in flux, and open it again.
+    // The second instance should start recovery.
+    PageFile file2 = new PageFile(file);
+
+    assertDataSizeEquals("len2", 3 * Storage.PAGE_SIZE);
+    assertLogSizeEquals("len2", 8);
+
+    file2.forceClose();
+
+    // assure we can recover this log file
+    PageFile file3 = new PageFile(file);
+
+    file3.forceClose();
+  }
+
+  /**
+   * Test background synching
+   */
+  public void XtestSynching() throws Exception {
+    PageFile file1 = new PageFile(file);
+
+    // Do enough transactions to fill the first slot
+    int txnCount = 1;
+    for (int i = 0; i < txnCount; i++) {
+      PageIo node = file1.get(i);
+      node.setDirty();
+      file1.release(node);
+      file1.commit();
+    }
+    file1.forceClose();
+
+    // The data file now has the first slotfull
+    assertDataSizeEquals("len1", 1 * Storage.PAGE_SIZE + 6);
+    assertLogSizeNotZero("len1");
+
+    // Leave the old record file in flux, and open it again.
+    // The second instance should start recovery.
+    PageFile file2 = new PageFile(file);
+
+    assertDataSizeEquals("len2", txnCount * Storage.PAGE_SIZE);
+    assertLogSizeEquals("len2", 8);
+
+    file2.forceClose();
+  }
+
+  // Helpers
+
+  void assertDataSizeEquals(String msg, long size) {
+    assertEquals(msg + " data size", size, new File(file + ".t").length());
+  }
+
+  void assertLogSizeEquals(String msg, long size) {
+    assertEquals(msg + " log size", size, new File(file
+        + StorageDisk.transaction_log_file_extension).length());
+  }
+
+  void assertLogSizeNotZero(String msg) {
+    assertTrue(msg + " log size", new File(file
+        + StorageDisk.transaction_log_file_extension).length() != 0);
+  }
+
+}

Added: hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PhysicalFreeRowIdManagerTest.java
URL: http://svn.apache.org/viewvc/hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PhysicalFreeRowIdManagerTest.java?rev=1387533&view=auto
==============================================================================
--- hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PhysicalFreeRowIdManagerTest.java (added)
+++ hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PhysicalFreeRowIdManagerTest.java Wed Sep 19 11:52:20 2012
@@ -0,0 +1,115 @@
+/**
+ * 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.hama.jdbm;
+
+import java.io.IOException;
+
+/**
+ * This class contains all Unit tests for {@link PhysicalFreeRowIdManager}.
+ */
+public class PhysicalFreeRowIdManagerTest extends TestCaseWithTestFile {
+
+  /**
+   * Test constructor
+   */
+  public void testCtor() throws Exception {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PhysicalFreeRowIdManager freeMgr = new PhysicalFreeRowIdManager(f, pm);
+
+    pm.close();
+    f.close();
+  }
+
+  /**
+   * Test basics
+   */
+  public void testBasics() throws Exception {
+
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PhysicalFreeRowIdManager freeMgr = new PhysicalFreeRowIdManager(f, pm);
+
+    // allocate 10,000 bytes - should fail on an empty file.
+    long loc = freeMgr.getFreeRecord(10000);
+    assertTrue("loc is not null?", loc == 0);
+
+    pm.close();
+    f.close();
+  }
+
+  public void testPhysRecRootPage() throws IOException {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+
+    long pageid = pm.allocate(Magic.FREEPHYSIDS_ROOT_PAGE);
+    PageIo p = f.get(pageid);
+    p.writeInt(100, 100);
+    f.release(p);
+    pm.commit();
+    f.commit();
+
+    p = f.get(pageid);
+    assertEquals(p.readInt(100), 100);
+
+  }
+
+  public void test_size_to_root_offset() {
+    for (int i = 1; i < PhysicalFreeRowIdManager.MAX_REC_SIZE; i++) {
+      int offset = PhysicalFreeRowIdManager.sizeToRootOffset(i);
+
+      assertTrue(offset <= Storage.PAGE_SIZE);
+    }
+  }
+
+  public void test_record_reallocation() throws IOException {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PhysicalFreeRowIdManager freeMgr = new PhysicalFreeRowIdManager(f, pm);
+
+    freeMgr.putFreeRecord(1000, 100);
+    freeMgr.commit();
+
+    assertEquals(1000,
+        freeMgr.getFreeRecord(100 - PhysicalFreeRowIdManager.ROOT_SLOT_SIZE));
+    assertEquals(0,
+        freeMgr.getFreeRecord(100 - PhysicalFreeRowIdManager.ROOT_SLOT_SIZE));
+
+  }
+
+  public void test_all_sizes_deallocation() throws IOException {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PhysicalFreeRowIdManager freeMgr = new PhysicalFreeRowIdManager(f, pm);
+
+    for (int i = 1; i < PhysicalFreeRowIdManager.MAX_REC_SIZE; i++) {
+
+      freeMgr.putFreeRecord(1000, i);
+      freeMgr.commit();
+
+      assertEquals(1000,
+          freeMgr.getFreeRecord(i - PhysicalFreeRowIdManager.ROOT_SLOT_SIZE));
+      assertEquals(0,
+          freeMgr.getFreeRecord(i - PhysicalFreeRowIdManager.ROOT_SLOT_SIZE));
+    }
+    pm.close();
+    f.close();
+
+  }
+
+}

Added: hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PhysicalRowIdManagerTest.java
URL: http://svn.apache.org/viewvc/hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PhysicalRowIdManagerTest.java?rev=1387533&view=auto
==============================================================================
--- hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PhysicalRowIdManagerTest.java (added)
+++ hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/PhysicalRowIdManagerTest.java Wed Sep 19 11:52:20 2012
@@ -0,0 +1,231 @@
+/**
+ * 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.hama.jdbm;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class contains all Unit tests for {@link PhysicalRowIdManager}.
+ */
+public class PhysicalRowIdManagerTest extends TestCaseWithTestFile {
+
+  private byte[] data = new byte[100000];
+
+  /**
+   * Test constructor
+   */
+  public void testCtor() throws Exception {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PageFile free = newRecordFile();
+    PageManager pmfree = new PageManager(free);
+
+    PhysicalRowIdManager physMgr = new PhysicalRowIdManager(f, pm);
+
+    f.forceClose();
+  }
+
+  /**
+   * Test basics
+   */
+  public void testBasics() throws Exception {
+
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PageFile free = newRecordFile();
+    PageManager pmfree = new PageManager(free);
+    PhysicalRowIdManager physMgr = new PhysicalRowIdManager(f, pm);
+
+    // insert a 10,000 byte record.
+    byte[] data = UtilTT.makeRecord(10000, (byte) 1);
+    long loc = physMgr.insert(data, 0, data.length);
+    DataInputOutput a1 = new DataInputOutput();
+    physMgr.fetch(a1, loc);
+    assertTrue("check data1",
+        UtilTT.checkRecord(a1.toByteArray(), 10000, (byte) 1));
+
+    // update it as a 20,000 byte record.
+    data = UtilTT.makeRecord(20000, (byte) 2);
+    long loc2 = physMgr.update(loc, data, 0, data.length);
+    DataInputOutput a2 = new DataInputOutput();
+    physMgr.fetch(a2, loc2);
+    assertTrue("check data2",
+        UtilTT.checkRecord(a2.toByteArray(), 20000, (byte) 2));
+
+    // insert a third record. This'll effectively page the first one
+    // from growing
+    data = UtilTT.makeRecord(20, (byte) 3);
+    long loc3 = physMgr.insert(data, 0, data.length);
+    DataInputOutput a3 = new DataInputOutput();
+    physMgr.fetch(a3, loc3);
+    assertTrue("check data3",
+        UtilTT.checkRecord(a3.toByteArray(), 20, (byte) 3));
+
+    // now, grow the first record again
+    data = UtilTT.makeRecord(30000, (byte) 4);
+    loc2 = physMgr.update(loc2, data, 0, data.length);
+    DataInputOutput a4 = new DataInputOutput();
+    physMgr.fetch(a4, loc2);
+    assertTrue("check data4",
+        UtilTT.checkRecord(a4.toByteArray(), 30000, (byte) 4));
+
+    // delete the record
+    physMgr.free(loc2);
+
+    f.forceClose();
+  }
+
+  public void testTwoRecords() throws IOException {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PhysicalRowIdManager physmgr = new PhysicalRowIdManager(f, pm);
+
+    physmgr.insert(new byte[1024], 0, 1024);
+    physmgr.insert(new byte[100], 0, 100);
+
+    assertEquals(listRecords(pm), arrayList(1024, 100));
+
+  }
+
+  public void testDeleteRecord() throws IOException {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PhysicalRowIdManager physmgr = new PhysicalRowIdManager(f, pm);
+
+    physmgr.insert(data, 0, 1024);
+    long recid = physmgr.insert(data, 0, 100);
+    physmgr.insert(data, 0, 700);
+    physmgr.free(recid);
+
+    assertEquals(listRecords(pm), arrayList(1024, -100, 700));
+
+  }
+
+  public void testTwoLargeRecord() throws IOException {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PhysicalRowIdManager physmgr = new PhysicalRowIdManager(f, pm);
+
+    physmgr.insert(data, 0, 5000);
+    physmgr.insert(data, 0, 5000);
+
+    assertEquals(listRecords(pm), arrayList(5000, 5000));
+
+  }
+
+  public void testManyLargeRecord() throws IOException {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PhysicalRowIdManager physmgr = new PhysicalRowIdManager(f, pm);
+
+    physmgr.insert(data, 0, 5002);
+    long id1 = physmgr.insert(data, 0, 5003);
+    physmgr.insert(data, 0, 5005);
+    long id2 = physmgr.insert(data, 0, 5006);
+    physmgr.insert(data, 0, 5007);
+    physmgr.insert(data, 0, 5008);
+    physmgr.free(id1);
+    physmgr.free(id2);
+
+    assertEquals(listRecords(pm),
+        arrayList(5002, -5003, 5005, -5006, 5007, 5008));
+
+  }
+
+  public void testSplitRecordAcrossPage() throws IOException {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PhysicalRowIdManager physmgr = new PhysicalRowIdManager(f, pm);
+
+    physmgr.insert(data, 0, 3000);
+    long id = physmgr.insert(data, 0, 3000);
+    physmgr.insert(data, 0, 1000);
+    physmgr.free(id);
+
+    // record which crosses page should be sliced to two, so it does not cross
+    // the page
+    int firstSize = Storage.PAGE_SIZE - Magic.DATA_PAGE_O_DATA
+        - RecordHeader.SIZE - 3000 - RecordHeader.SIZE;
+    int secondSize = 3000 - firstSize - RecordHeader.SIZE;
+
+    // TODO decide about this
+    // assertEquals(listRecords(pm), arrayList(3000,-firstSize,-secondSize,
+    // 1000));
+
+  }
+
+  public void testFreeMidPages() throws IOException {
+    PageFile f = newRecordFile();
+    PageManager pm = new PageManager(f);
+    PhysicalRowIdManager physmgr = new PhysicalRowIdManager(f, pm);
+
+    physmgr.insert(data, 0, 3000);
+    long id = physmgr.insert(data, 0, 30000);
+    physmgr.insert(data, 0, 1000);
+    physmgr.free(id);
+
+    // if record occupies multiple pages, mid pages should be freed and record
+    // trimmed.
+    int newSize = 30000;
+
+    while (newSize > Storage.PAGE_SIZE - Magic.DATA_PAGE_O_DATA)
+      newSize = newSize - (Storage.PAGE_SIZE - Magic.DATA_PAGE_O_DATA);
+
+    assertEquals(listRecords(pm), arrayList(3000, -newSize, 1000));
+
+  }
+
+  /** return list of records in pageman, negative numbers are free records */
+  List<Integer> listRecords(PageManager pageman) throws IOException {
+    int pos = Magic.DATA_PAGE_O_DATA;
+    List<Integer> ret = new ArrayList<Integer>();
+    for (long pageid = pageman.getFirst(Magic.USED_PAGE); pageid != 0; pageid = pageman
+        .getNext(pageid)) {
+
+      PageIo page = pageman.file.get(pageid);
+
+      while (pos < Storage.PAGE_SIZE - RecordHeader.SIZE) {
+
+        int size = RecordHeader.getAvailableSize(page, (short) pos);
+        if (size == 0)
+          break;
+        int currSize = RecordHeader.getCurrentSize(page, (short) pos);
+        pos += size + RecordHeader.SIZE;
+        if (currSize == 0)
+          size = -size;
+        ret.add(size);
+      }
+
+      pos = pos + Magic.DATA_PAGE_O_DATA - Storage.PAGE_SIZE;
+
+      pageman.file.release(page);
+    }
+
+    return ret;
+  }
+
+  List<Integer> arrayList(Integer... args) {
+    ArrayList<Integer> ret = new ArrayList<Integer>();
+    for (Integer i : args)
+      ret.add(i);
+    return ret;
+  }
+
+}

Added: hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/RecordHeaderTest.java
URL: http://svn.apache.org/viewvc/hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/RecordHeaderTest.java?rev=1387533&view=auto
==============================================================================
--- hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/RecordHeaderTest.java (added)
+++ hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/RecordHeaderTest.java Wed Sep 19 11:52:20 2012
@@ -0,0 +1,152 @@
+/**
+ * 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.hama.jdbm;
+
+import java.util.Random;
+
+import junit.framework.TestCase;
+
+/**
+ * This class contains all Unit tests for {@link RecordHeader}.
+ */
+public class RecordHeaderTest extends TestCase {
+
+  /**
+   * Test basics - read and write at an offset
+   */
+  public void testReadWrite() throws Exception {
+    byte[] data = new byte[Storage.PAGE_SIZE];
+    PageIo test = new PageIo(0, data);
+    // RecordHeader hdr = new RecordHeader(test, (short) 6);
+    RecordHeader.setAvailableSize(test, (short) 6, 2345);
+    RecordHeader.setCurrentSize(test, (short) 6, 2300);
+
+    assertEquals("current size", 2300,
+        RecordHeader.getCurrentSize(test, (short) 6));
+    assertEquals("available size", 2345,
+        RecordHeader.getAvailableSize(test, (short) 6));
+  }
+
+  public void testRecordSize() {
+
+    System.out.println("MAX_RECORD_SIZE " + RecordHeader.MAX_RECORD_SIZE);
+
+    assertEquals("inconsistent rounding at max rec size",
+        RecordHeader.MAX_RECORD_SIZE,
+        RecordHeader.roundAvailableSize(RecordHeader.MAX_RECORD_SIZE));
+
+    byte[] data = new byte[Storage.PAGE_SIZE];
+    PageIo test = new PageIo(0, data);
+    Random r = new Random();
+    // RecordHeader hdr = new RecordHeader(test, (short) 6);
+
+    for (int size = 2; size <= RecordHeader.MAX_RECORD_SIZE; size++) {
+      // set size
+      int currSize = size;
+      int availSize = RecordHeader.roundAvailableSize(currSize);
+
+      assertTrue(availSize - currSize < RecordHeader.MAX_SIZE_SPACE);
+      assertTrue(currSize <= availSize);
+
+      assertEquals(
+          "size rounding function does not provide consistent results "
+              + availSize, availSize,
+          RecordHeader.roundAvailableSize(availSize));
+
+      // make sure it writes and reads back correctly
+      RecordHeader.setAvailableSize(test, (short) 6, availSize);
+      assertEquals("available size", availSize,
+          RecordHeader.getAvailableSize(test, (short) 6));
+      RecordHeader.setCurrentSize(test, (short) 6, currSize);
+
+      assertEquals("current size", currSize,
+          RecordHeader.getCurrentSize(test, (short) 6));
+
+      // try random size within given offset
+      int newCurrSize = availSize - r.nextInt(RecordHeader.MAX_SIZE_SPACE);
+      if (newCurrSize < 0)
+        newCurrSize = 0;
+      RecordHeader.setCurrentSize(test, (short) 6, newCurrSize);
+      assertEquals("current size", newCurrSize,
+          RecordHeader.getCurrentSize(test, (short) 6));
+
+      RecordHeader.setCurrentSize(test, (short) 6, 0);
+
+      size++;
+
+      // comment out next line to do full test
+      if (size > 1e6)
+        size = (int) (size * 1.01);
+    }
+
+  }
+
+  public void testMaxRecordSize() {
+
+    long max = 0;
+    for (int i = 0; i < 1e7; i++) {
+      int deconverted = RecordHeader.deconvertAvailSize(RecordHeader
+          .convertAvailSize(i));
+      if (i == deconverted) {
+        max = i;
+      }
+    }
+    assertEquals("Maximal record size does not match the calculated one: "
+        + max, max, RecordHeader.MAX_RECORD_SIZE);
+
+  }
+
+  public void testRoundingSmall() {
+    for (int i = 0; i <= Short.MAX_VALUE; i++) {
+      assertEquals(i, RecordHeader.convertAvailSize(i));
+    }
+  }
+
+  public void testRounding() {
+
+    for (int i = 0; i < RecordHeader.MAX_RECORD_SIZE; i++) {
+      int deconverted = RecordHeader.deconvertAvailSize(RecordHeader
+          .convertAvailSize(i));
+      assertTrue("deconverted size is smaller than actual: " + i + " versus "
+          + deconverted, deconverted >= i);
+    }
+
+  }
+
+  public void testSetCurrentSize() {
+    PageIo b = new PageIo(4l, new byte[Storage.PAGE_SIZE]);
+    short pos = 10;
+
+    RecordHeader.setAvailableSize(b, pos, 1000);
+    assertEquals(1000, RecordHeader.getAvailableSize(b, pos));
+    RecordHeader.setCurrentSize(b, pos, 900);
+    assertEquals(900, RecordHeader.getCurrentSize(b, pos));
+    RecordHeader.setCurrentSize(b, pos, 0);
+    assertEquals(0, RecordHeader.getCurrentSize(b, pos));
+    RecordHeader.setCurrentSize(b, pos, 1000 - 254);
+    assertEquals(1000 - 254, RecordHeader.getCurrentSize(b, pos));
+
+    short pos2 = 20;
+    RecordHeader.setAvailableSize(b, pos2, 10000);
+    assertEquals(10000, RecordHeader.getAvailableSize(b, pos2));
+    RecordHeader.setCurrentSize(b, pos2, 10000);
+    assertEquals(10000, RecordHeader.getCurrentSize(b, pos2));
+
+  }
+
+}

Added: hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/RollbackTest.java
URL: http://svn.apache.org/viewvc/hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/RollbackTest.java?rev=1387533&view=auto
==============================================================================
--- hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/RollbackTest.java (added)
+++ hama/trunk/jdbm/src/test/java/org/apache/hama/jdbm/RollbackTest.java Wed Sep 19 11:52:20 2012
@@ -0,0 +1,107 @@
+/**
+ * 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.hama.jdbm;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class RollbackTest extends TestCaseWithTestFile {
+
+  public void test_treemap() throws IOException {
+    DB db = newDBCache();
+    Map<Integer, String> map = db.createTreeMap("collectionName");
+
+    map.put(1, "one");
+    map.put(2, "two");
+
+    assertEquals(2, map.size());
+    db.commit(); // persist changes into disk
+
+    map.put(3, "three");
+    assertEquals(3, map.size());
+    db.rollback(); // revert recent changes
+    assertEquals(2, map.size());
+  }
+
+  public void test_hashmap() throws IOException {
+    DB db = newDBCache();
+    Map<Integer, String> map = db.createHashMap("collectionName");
+
+    map.put(1, "one");
+    map.put(2, "two");
+
+    assertEquals(2, map.size());
+    db.commit(); // persist changes into disk
+
+    map.put(3, "three");
+    assertEquals(3, map.size());
+    db.rollback(); // revert recent changes
+    assertEquals(2, map.size());
+  }
+
+  public void test_treeset() throws IOException {
+    DB db = newDBCache();
+    Set<Integer> c = db.createTreeSet("collectionName");
+
+    c.add(1);
+    c.add(2);
+
+    assertEquals(2, c.size());
+    db.commit(); // persist changes into disk
+
+    c.add(3);
+    assertEquals(3, c.size());
+    db.rollback(); // revert recent changes
+    assertEquals(2, c.size());
+  }
+
+  public void test_hashset() throws IOException {
+    DB db = newDBCache();
+    Set<Integer> c = db.createHashSet("collectionName");
+
+    c.add(1);
+    c.add(2);
+
+    assertEquals(2, c.size());
+    db.commit(); // persist changes into disk
+
+    c.add(3);
+    assertEquals(3, c.size());
+    db.rollback(); // revert recent changes
+    assertEquals(2, c.size());
+  }
+
+  public void test_linkedlist() throws IOException {
+    DB db = newDBCache();
+    List<Integer> c = db.createLinkedList("collectionName");
+
+    c.add(1);
+    c.add(2);
+
+    assertEquals(2, c.size());
+    db.commit(); // persist changes into disk
+
+    c.add(3);
+    assertEquals(3, c.size());
+    db.rollback(); // revert recent changes
+    assertEquals(2, c.size());
+  }
+
+}



Mime
View raw message