/*
* Copyright: Almende B.V. (2014), Rotterdam, The Netherlands
* License: The Apache Software License, Version 2.0
*/
package com.almende.test.dht;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.BitSet;
import junit.framework.TestCase;
import org.junit.Test;
import com.almende.dht.Bucket;
import com.almende.dht.Constants;
import com.almende.dht.Key;
import com.almende.dht.Node;
import com.almende.dht.RoutingTable;
import com.almende.util.jackson.JOM;
/**
* The Class TestRpc.
*/
public class TestDht extends TestCase {
final static URI TESTURI = URI.create("http://localhost:1");
/**
* Test keys.
*/
@Test
public void testKeys() {
final Key myKey = new Key(BitSet.valueOf(new long[] { 1029287173,
128237194, 182934729 }));
// Check equals:
assertEquals("Identity test1 failed", myKey, myKey);
assertEquals(
"Identity test2 failed",
myKey,
new Key(BitSet.valueOf(new long[] { 1029287173, 128237194,
182934729 })));
assertNotSame("Identity test3 failed", myKey,
new Key(BitSet.valueOf(new long[] { 1 })));
assertNotSame(
"Identity test4 failed",
myKey,
new Key(BitSet.valueOf(new long[] { 1029287173, 128237194,
182934728 })));
// Check distance:
assertEquals(
"Distance from 0-key not correct",
myKey.dist(new Key()),
new Key(BitSet.valueOf(new long[] { 1029287173, 128237194,
182934729 })));
assertEquals("Distance from myself not 0-key", new Key(),
myKey.dist(myKey));
assertEquals("Distance between 1 and 2 not 3-key",
new Key(BitSet.valueOf(new long[] { 1 })).dist(new Key(BitSet
.valueOf(new long[] { 2 }))),
new Key(BitSet.valueOf(new long[] { 3 })));
assertEquals(
"Distance rank between 1 and 2 not 2",
new Key(BitSet.valueOf(new long[] { 1 })).dist(
new Key(BitSet.valueOf(new long[] { 2 }))).rank(), 2);
// Check rank:
assertEquals("Rank of 0-key not 0", new Key().rank(), 0);
assertEquals("Rank of 1-key not 1",
new Key(BitSet.valueOf(new long[] { 1 })).rank(), 1);
assertEquals("Rank of second long-key not 65",
new Key(BitSet.valueOf(new long[] { 0, 1 })).rank(), 65);
assertEquals("Rank of full long-key not 64",
new Key(BitSet.valueOf(new long[] { -1 })).rank(), 64);
// Check mostly set lists:
final BitSet val = new BitSet(Constants.BITLENGTH);
val.set(0, Constants.BITLENGTH);
assertEquals("Rank of full key not " + Constants.BITLENGTH,
new Key(val).rank(), Constants.BITLENGTH);
val.set(Constants.BITLENGTH - 1, false);
assertEquals(
"Rank of nearly full key not " + (Constants.BITLENGTH - 1),
new Key(val).rank(), Constants.BITLENGTH - 1);
val.set(Constants.BITLENGTH - 1);
assertEquals("Constant BITLENGTH no longer 160?", 160,
Constants.BITLENGTH);
assertEquals(
"Long-filled key not equals to full key",
new Key(val),
new Key(BitSet.valueOf(new long[] { -1, -1,
Long.MAX_VALUE >>> 31 })));
assertEquals("Filled key distance to 0-key is not filled key", new Key(
val).dist(new Key()), new Key(val));
// Check Random keys:
assertNotSame("Two random keys are the same", Key.random(),
Key.random());
assertNotSame("Random key results in 0-key", Key.random(), new Key());
// Check comparison:
assertTrue(
"1-key is not larger than 0-key",
new Key().compareTo(new Key(BitSet.valueOf(new long[] { 1 }))) < 0);
assertTrue("Random key is not larger than 0-key",
new Key().compareTo(Key.random()) < 0);
final BitSet val1 = new BitSet(Constants.BITLENGTH);
val1.set(1);
final BitSet val2 = new BitSet(Constants.BITLENGTH);
val2.set(2);
assertTrue("1-key is not smaller than 2-key",
new Key(val1).compareTo(new Key(val2)) < 0);
assertTrue("2-key is not larger than 1-key",
new Key(val2).compareTo(new Key(val1)) > 0);
assertTrue("2-key is not the same as 2-key",
new Key(val2).compareTo(new Key(val2)) == 0);
assertTrue("Full key is not larger than 1-key",
new Key(val).compareTo(new Key(val1)) > 0);
// Check sorting:
final BitSet val3 = new BitSet(Constants.BITLENGTH);
val3.set(3);
final BitSet val4 = new BitSet(Constants.BITLENGTH);
val4.set(4);
final Key[] arr = new Key[] { new Key(val), new Key(val1),
new Key(val2), new Key(val4), new Key(val3) };
Arrays.sort(arr);
assertEquals("Sorting incorrect", arr[0], new Key(val1));
assertEquals("Sorting incorrect", arr[1], new Key(val2));
assertEquals("Sorting incorrect", arr[2], new Key(val3));
assertEquals("Sorting incorrect", arr[3], new Key(val4));
assertEquals("Sorting incorrect", arr[4], new Key(val));
final Key[] arr1 = new Key[] { Key.fromHexString("01"),
Key.fromHexString("02"), Key.fromHexString("03"),
Key.fromHexString("04"), Key.fromHexString("05"),
Key.fromHexString("06"), Key.fromHexString("07"),
Key.fromHexString("08") };
Arrays.sort(arr1);
assertEquals("Incorrect sorting", "[01, 02, 03, 04, 05, 06, 07, 08]",
Arrays.toString(arr1));
// Check SHA1 keying:
assertEquals("Empty string sha1 key incorrect", Key.digest("")
.toString(), "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709");
assertEquals("Teststring1 sha1 key incorrect", Key.digest("abc")
.toString(), "A9993E364706816ABA3E25717850C26C9CD0D89D");
assertEquals("Teststring2 sha1 key incorrect",
Key.digest("abcdefghijklmnopqrstuvwxyz").toString(),
"32D10C7B8CF96570CA04CE37F2A19D84240D3A89");
// Check syntax sugar:
assertEquals("From HexString results in incorrect key",
Key.fromString("abc"),
Key.fromHexString("A9993E364706816ABA3E25717850C26C9CD0D89D"));
assertEquals(
"From HexString results in incorrect key (empty string key)",
Key.digest(""),
Key.fromHexString("DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"));
assertEquals("From HexString doesn't create 1-key",
new Key(BitSet.valueOf(new long[] { 1 })),
Key.fromHexString("01"));
}
/**
* Test buckets.
*/
@Test
public void testBuckets() {
Bucket bucket = new Bucket(10);
final Node test = new Node(Key.random(10), TESTURI);
bucket.seenNode(test);
assertEquals("getClosestNodes didn't return node", 1,
bucket.getClosestNodes(new Key()).size());
assertEquals("getClosestNodes didn't return same node", test,
bucket.getClosestNodes(new Key()).get(0));
bucket = new Bucket(-1);
final Node test1 = new Node(Key.fromHexString("01"), TESTURI);
final Node test2 = new Node(Key.fromHexString("02"), TESTURI);
final Node test3 = new Node(Key.fromHexString("03"), TESTURI);
final Node test4 = new Node(Key.fromHexString("04"), TESTURI);
final Node test5 = new Node(Key.fromHexString("05"), TESTURI);
final Node test6 = new Node(Key.fromHexString("06"), TESTURI);
final Node test7 = new Node(Key.fromHexString("07"), TESTURI);
final Node test8 = new Node(Key.fromHexString("08"), TESTURI);
bucket.seenNode(test1);
bucket.seenNode(test2);
bucket.seenNode(test3);
bucket.seenNode(test4);
bucket.seenNode(test5);
bucket.seenNode(test6);
bucket.seenNode(test7);
assertEquals("Incorrect order 0", test7,
bucket.getClosestNodes(Key.fromHexString("0F"), 1).get(0));
bucket.seenNode(test8);
assertEquals("Incorrect order 1", test1,
bucket.getClosestNodes(new Key(), 1).get(0));
assertEquals("Incorrect order 2", test2,
bucket.getClosestNodes(new Key(), 2).get(1));
assertEquals("Incorrect order 3", test1,
bucket.getClosestNodes(Key.fromHexString("10"), 1).get(0));
assertEquals("Incorrect order 4", test5,
bucket.getClosestNodes(Key.fromHexString("04"), 2).get(1));
assertEquals("Incorrect order 5", test3,
bucket.getClosestNodes(Key.fromHexString("04")).get(6));
assertEquals("Incorrect order 6", test8,
bucket.getClosestNodes(Key.fromHexString("04")).get(7));
assertEquals("Incorrect order 7", test6,
bucket.getClosestNodes(Key.fromHexString("07"), 2).get(1));
assertEquals("Limit doesn't work", 3,
bucket.getClosestNodes(new Key(), 3).size());
assertEquals("Too large result", 8,
bucket.getClosestNodes(new Key(), 10).size());
assertEquals("Filter not working 1", test2, bucket.getClosestNodes(
new Key(), 1, new Key[] { test1.getKey() }).get(0));
assertEquals(
"Filter not working 2",
test6,
bucket.getClosestNodes(new Key(), 3, new Key[] {
test1.getKey(), test3.getKey(), test5.getKey() }).get(2));
}
/**
* Test table.
*
* @throws IOException
* Signals that an I/O exception has occurred.
*/
@Test
public void testTable() throws IOException {
final RoutingTable rt = new RoutingTable(Key.fromHexString("04"));
rt.seenNode(new Node(Key.fromHexString("05"), TESTURI));
rt.seenNode(new Node(Key.fromHexString("09"), TESTURI));
rt.seenNode(new Node(Key.fromHexString("0D"), TESTURI));
rt.seenNode(new Node(Key.fromHexString("01"), TESTURI));
final Bucket bucket = rt.getBucket(Key.fromHexString("0C"));
assertEquals("Wrong node in bucket 1", Key.fromHexString("0D"),
bucket.getClosestNodes(Key.fromHexString("0F"), 1).get(0).getKey());
assertEquals("Wrong result length 1", 3,
rt.getClosestNodes(Key.fromHexString("0F"), 3).size());
assertEquals("Wrong result length 2", 2,
rt.getClosestNodes(Key.fromHexString("0F"), 2).size());
assertEquals("Wrong result length 3", 4,
rt.getClosestNodes(Key.fromHexString("05"), 10).size());
// Test serialization to JSON:
final String json = JOM.getInstance().writeValueAsString(rt);
final RoutingTable rt2 = JOM.getInstance().readValue(json,
RoutingTable.class);
assertEquals("Routing table key incorrect", Key.fromHexString("04"),
rt2.getMyKey());
final Bucket bucket2 = rt2.getBucket(Key.fromHexString("0C"));
assertEquals("Wrong node in bucket 2", Key.fromHexString("0D"),
bucket2.getClosestNodes(Key.fromHexString("0F"), 1).get(0).getKey());
assertEquals("Wrong result length 4", 3,
rt2.getClosestNodes(Key.fromHexString("0F"), 3).size());
assertEquals("Wrong result length 5", 2,
rt2.getClosestNodes(Key.fromHexString("0F"), 2).size());
assertEquals("Wrong result length 6", 4,
rt2.getClosestNodes(Key.fromHexString("05"), 10).size());
}
}