1// Copyright 2011 Google Inc. All Rights Reserved.
2
3package com.google.common.hash;
4
5import com.google.common.collect.Sets;
6
7import junit.framework.TestCase;
8
9import java.util.Set;
10
11/**
12 * Tests for HashFunctions.
13 *
14 * @author andreou@google.com (Dimitris Andreou)
15 */
16public class HashFunctionsTest extends TestCase {
17  public void testMd5() {
18    assertInvariants(Hashing.md5());
19  }
20
21  public void testMurmur3_138() {
22    assertInvariants(Hashing.murmur3_128());
23  }
24
25  public void testMurmur3_32() {
26    assertInvariants(Hashing.murmur3_32());
27  }
28
29  public void testGoodFastHash() {
30    for (int i = 1; i < 500; i++) {
31      HashFunction hasher = Hashing.goodFastHash(i);
32      assertTrue(hasher.bits() >= i);
33      assertInvariants(hasher);
34    }
35  }
36
37  /**
38   * Checks that a Hasher returns the same HashCode when given the same input, and also
39   * that the collision rate looks sane.
40   */
41  private static void assertInvariants(HashFunction hashFunction) {
42    int objects = 100;
43    Set<HashCode> hashcodes = Sets.newHashSetWithExpectedSize(objects);
44    for (int i = 0; i < objects; i++) {
45      Object o = new Object();
46      HashCode hashcode1 = hashFunction.newHasher().putObject(o, HashTestUtils.BAD_FUNNEL).hash();
47      HashCode hashcode2 = hashFunction.newHasher().putObject(o, HashTestUtils.BAD_FUNNEL).hash();
48      assertEquals(hashcode1, hashcode2); // idempotent
49      assertEquals(hashFunction.bits(), hashcode1.bits());
50      assertEquals(hashFunction.bits(), hashcode1.asBytes().length * 8);
51      hashcodes.add(hashcode1);
52    }
53    assertTrue(hashcodes.size() > objects * 0.95); // quite relaxed test
54
55    assertHashBytesThrowsCorrectExceptions(hashFunction);
56  }
57
58  private static void assertHashBytesThrowsCorrectExceptions(HashFunction hashFunction) {
59    hashFunction.hashBytes(new byte[64], 0, 0);
60
61    try {
62      hashFunction.hashBytes(new byte[128], -1, 128);
63      fail();
64    } catch (IndexOutOfBoundsException ok) {}
65    try {
66      hashFunction.hashBytes(new byte[128], 64, 256 /* too long len */);
67      fail();
68    } catch (IndexOutOfBoundsException ok) {}
69    try {
70      hashFunction.hashBytes(new byte[64], 0, -1);
71      fail();
72    } catch (IndexOutOfBoundsException ok) {}
73  }
74}
75