func TestJoinUpdatesExistingPeers(t *testing.T) { test := quiz.Test(t) nodeA := testNode() defer nodeA.Close() nodeB := testNode() defer nodeB.Close() nodeC := testNode() defer nodeC.Close() httpclient.Put(nodeA.URL+"/peers/join", nodeB.URL) httpclient.Put(nodeA.URL+"/peers/join", nodeC.URL) var statusCode int var body string statusCode, body = httpclient.Get(nodeA.URL+"/peers", "") test.Expect(statusCode).ToEqual(200) test.Expect(body).ToContain(nodeB.URL) test.Expect(body).ToContain(nodeC.URL) statusCode, body = httpclient.Get(nodeB.URL+"/peers", "") test.Expect(statusCode).ToEqual(200) test.Expect(body).ToContain(nodeA.URL) test.Expect(body).ToContain(nodeC.URL) statusCode, body = httpclient.Get(nodeC.URL+"/peers", "") test.Expect(statusCode).ToEqual(200) test.Expect(body).ToContain(nodeA.URL) test.Expect(body).ToContain(nodeB.URL) }
func TestFetchesAcrossNodes(t *testing.T) { test := quiz.Test(t) serverA := testServer() defer serverA.Close() serverB := testServer() defer serverB.Close() httpclient.Put(serverA.URL+"/peers/join", serverB.URL) // "a"'s hash will be stored on serverB key := "a" var statusCode int var body string statusCode, _ = httpclient.Put(serverA.URL+"/data/"+key, "bar") test.Expect(statusCode).ToEqual(201) statusCode, body = httpclient.Get(serverB.URL+"/data/"+key, "") test.Expect(statusCode).ToEqual(200) test.Expect(body).ToEqual("bar") statusCode, body = httpclient.Get(serverA.URL+"/data/"+key, "") test.Expect(statusCode).ToEqual(200) test.Expect(body).ToEqual("bar") }
func TestNodeSetNValueUpdatesPeersOnJoin(t *testing.T) { test := quiz.Test(t) nodeA := testNode() defer nodeA.Close() nodeB := testNode() defer nodeB.Close() nodeC := testNode() defer nodeC.Close() httpclient.Put(nodeA.URL+"/peers/join", nodeB.URL) statusCode, _ := httpclient.Put(nodeA.URL+"/settings/n", "1") test.Expect(statusCode).ToEqual(201) httpclient.Put(nodeA.URL+"/peers/join", nodeC.URL) _, body := httpclient.Get(nodeA.URL+"/stats", "") test.Expect(body).ToContain(`"nValue":1`) _, body = httpclient.Get(nodeB.URL+"/stats", "") test.Expect(body).ToContain(`"nValue":1`) _, body = httpclient.Get(nodeC.URL+"/stats", "") test.Expect(body).ToContain(`"nValue":1`) }
func TestResizeCleansUpReplicas(t *testing.T) { test := quiz.Test(t) serverA := testServer() defer serverA.Close() serverB := testServer() defer serverB.Close() serverC := testServer() defer serverC.Close() serverD := testServer() defer serverD.Close() httpclient.Put(serverA.URL+"/peers/join", serverB.URL) httpclient.Put(serverA.URL+"/peers/join", serverC.URL) httpclient.Put(serverA.URL+"/settings/n", "1") // this key will be owned by c before and after d joins // however it's replicas will first by a then d key := "a" httpclient.Put(serverA.URL+"/data/"+key, "foo") httpclient.Put(serverA.URL+"/peers/join", serverD.URL) _, aHasKey := serverA.node.values[key] _, cHasKey := serverC.node.values[key] _, dHasKey := serverD.node.values[key] test.Expect(aHasKey).ToBeFalse() test.Expect(cHasKey).ToBeTrue() test.Expect(dHasKey).ToBeTrue() }
func TestNotifyDown(t *testing.T) { test := quiz.Test(t) peer := New("localhost", map[string]string{}, nullLogger) peer.addPeer("remote") peer.NotifyDown("remote") test.Expect(peer.Peers[0]).ToEqual("dead:remote") }
func TestErrorOnNGreaterThanTotalPeers(t *testing.T) { test := quiz.Test(t) nodeA := testNode() defer nodeA.Close() statusCode, _ := httpclient.Put(nodeA.URL+"/settings/n", "5") test.Expect(statusCode).ToEqual(422) }
func TestErrorOnNonIntForNValue(t *testing.T) { test := quiz.Test(t) nodeA := testNode() defer nodeA.Close() statusCode, _ := httpclient.Put(nodeA.URL+"/settings/n", "notint") test.Expect(statusCode).ToEqual(422) }
func TestRingCanHaveNodes(t *testing.T) { test := quiz.Test(t) ring := New() ring.AddNode("A") ring.AddNode("B") test.Expect(ring.NodeCount()).ToEqual(2) }
func TestNodesHaveCorrectVnodeStart(t *testing.T) { test := quiz.Test(t) ring := New() node1 := ring.AddNode("A") node2 := ring.AddNode("B") test.Expect(node1.vnodeStart).ToEqual(uint32(0)) test.Expect(node2.vnodeStart).ToEqual(uint32(2147483137)) }
func TestGetPeerWithNoPeer(t *testing.T) { test := quiz.Test(t) node := testNode() defer node.Close() statusCode, _ := httpclient.Get(node.URL+"/peers", "") test.Expect(statusCode).ToEqual(404) }
func TestFetchUnknownKey(t *testing.T) { test := quiz.Test(t) server := testServer() defer server.Close() statusCode, _ := httpclient.Get(server.URL+"/data/mykey", "bar") test.Expect(statusCode).ToEqual(404) }
func TestNodesSpiltVnodeMaxCount(t *testing.T) { test := quiz.Test(t) ring := New() node1 := ring.AddNode("A") node2 := ring.AddNode("B") test.Expect(node1.vnodeCount).ToEqual(512) test.Expect(node2.vnodeCount).ToEqual(512) }
func TestSetNodes(t *testing.T) { test := quiz.Test(t) ring := New() ring.SetNodes([]string{"A", "B", "C"}) test.Expect(ring.GetNodes()[0]).ToEqual("A") test.Expect(ring.GetNodes()[1]).ToEqual("B") test.Expect(ring.GetNodes()[2]).ToEqual("C") }
func TestNodeDoesntOwnsKeyOutsideVnodeRange(t *testing.T) { test := quiz.Test(t) node := &Node{ vnodeCount: 1, vnodeSize: 1, vnodeStart: 0, } test.Expect(node.OwnsKeyHash(2)).ToBeFalse() }
func TestNodeOwnsKeyInbetweenVnodeRange(t *testing.T) { test := quiz.Test(t) node := &Node{ vnodeCount: 1, vnodeSize: 10, vnodeStart: 0, } test.Expect(node.OwnsKeyHash(7)).ToBeTrue() }
func TestNodeDoesntOwnKeyBelowVnodeStart(t *testing.T) { test := quiz.Test(t) node := &Node{ vnodeCount: 1, vnodeSize: 10, vnodeStart: 10, } test.Expect(node.OwnsKeyHash(7)).ToBeFalse() }
func TestNodeOwnsKeyIfKeyIsVnodeStart(t *testing.T) { test := quiz.Test(t) node := &Node{ vnodeCount: 1, vnodeSize: 1, vnodeStart: 0, } test.Expect(node.OwnsKeyHash(0)).ToBeTrue() }
func TestAddAKey(t *testing.T) { test := quiz.Test(t) server := testServer() defer server.Close() statusCode, body := httpclient.Put(server.URL+"/data/mykey", "bar") test.Expect(statusCode).ToEqual(201) test.Expect(body).ToEqual("bar") }
func TestGetNodes(t *testing.T) { test := quiz.Test(t) ring := New() ring.AddNode("A") ring.AddNode("B") ring.AddNode("C") test.Expect(ring.GetNodes()[0]).ToEqual("A") test.Expect(ring.GetNodes()[1]).ToEqual("B") test.Expect(ring.GetNodes()[2]).ToEqual("C") }
func TestNodeNext(t *testing.T) { test := quiz.Test(t) ring := New() a := ring.AddNode("A") b := ring.AddNode("B") c := ring.AddNode("C") test.Expect(a.next).ToEqual(b) test.Expect(b.next).ToEqual(c) test.Expect(c.next).ToEqual(a) }
func TestNodeSetRing(t *testing.T) { test := quiz.Test(t) node := testNode() defer node.Close() statusCode, _ := httpclient.Put(node.URL+"/ring", `{"ring":["`+node.URL+`","b","c"]}`) test.Expect(statusCode).ToEqual(201) _, body := httpclient.Get(node.URL+"/stats", "") test.Expect(body).ToContain(`"ring":["` + node.URL + `","b","c"]`) }
func TestAddPeer(t *testing.T) { test := quiz.Test(t) node := testNode() defer node.Close() statusCode, _ := httpclient.Put(node.URL+"/peers", "peer.url") test.Expect(statusCode).ToEqual(201) statusCode, body := httpclient.Get(node.URL+"/peers", "") test.Expect(statusCode).ToEqual(200) test.Expect(body).ToEqual(`{"peers":["peer.url"]}`) }
func TestStatsKeys(t *testing.T) { test := quiz.Test(t) server := testServer() defer server.Close() httpclient.Put(server.URL+"/data/mykey", "bar") statusCode, body := httpclient.Get(server.URL+"/stats/keys", "") test.Expect(statusCode).ToEqual(200) test.Expect(body).ToContain(`"count":1`) test.Expect(body).ToContain(`"data":{"mykey":"bar"}`) }
func TestAddPeerFailsOnMultipleCalls(t *testing.T) { test := quiz.Test(t) node := testNode() defer node.Close() var statusCode int statusCode, _ = httpclient.Put(node.URL+"/peers", "peer.url") test.Expect(statusCode).ToEqual(201) statusCode, _ = httpclient.Put(node.URL+"/peers", "peer.url") test.Expect(statusCode).ToEqual(409) }
func TestGetMultiplePeers(t *testing.T) { test := quiz.Test(t) node := testNode() defer node.Close() httpclient.Put(node.URL+"/peers", "peer1.url") httpclient.Put(node.URL+"/peers", "peer2.url") statusCode, body := httpclient.Get(node.URL+"/peers", "") test.Expect(statusCode).ToEqual(200) test.Expect(body).ToEqual(`{"peers":["peer1.url","peer2.url"]}`) }
func TestNodeStats(t *testing.T) { test := quiz.Test(t) node := testNode() defer node.Close() statusCode, body := httpclient.Get(node.URL+"/stats", "") test.Expect(statusCode).ToEqual(200) test.Expect(body).ToContain(`"vnodeCount":1024`) test.Expect(body).ToContain(`"vnodeSize":4194303`) test.Expect(body).ToContain(`"vnodeStart":0`) test.Expect(body).ToContain(`"ring":["` + node.URL + `"]`) }
func TestNodesDontOwnSameKeyHashesOnEdges(t *testing.T) { test := quiz.Test(t) ring := New() node1 := ring.AddNode("A") node2 := ring.AddNode("B") test.Expect(node1.OwnsKeyHash(0)).ToBeTrue() test.Expect(node2.OwnsKeyHash(0)).ToBeFalse() test.Expect(node1.OwnsKeyHash(2147483136)).ToBeTrue() test.Expect(node2.OwnsKeyHash(2147483136)).ToBeFalse() test.Expect(node1.OwnsKeyHash(2147483137)).ToBeFalse() test.Expect(node2.OwnsKeyHash(2147483137)).ToBeTrue() }
func TestKeyDistribution(t *testing.T) { test := quiz.Test(t) ring := New() ring.AddNode("A") ring.AddNode("B") ring.AddNode("C") for i := 1; i <= 100; i++ { ring.AddKey(strconv.Itoa(i)) } for _, node := range ring.nodes { test.Expect(node.keyCount).ToBeLessThan(50) test.Expect(node.keyCount).ToBeGreaterThan(10) } }
func TestFailedWriteUpdatesPeerList(t *testing.T) { test := quiz.Test(t) serverA := testServer() defer serverA.Close() serverB := testServer() peerURL := serverB.URL key := "a" httpclient.Put(serverA.URL+"/peers/join", serverB.URL) serverB.Close() httpclient.Put(serverA.URL+"/data/"+key, "foo") _, body := httpclient.Get(serverA.URL+"/peers", "") test.Expect(body).ToContain("dead:" + peerURL) }
func TestJoinCallsBack(t *testing.T) { test := quiz.Test(t) nodeA := testNode() defer nodeA.Close() nodeB := testNode() defer nodeB.Close() httpclient.Put(nodeA.URL+"/peers/join", nodeB.URL) var statusCode int var body string statusCode, body = httpclient.Get(nodeA.URL+"/peers", "") test.Expect(statusCode).ToEqual(200) test.Expect(body).ToEqual(`{"peers":["` + nodeB.URL + `"]}`) statusCode, body = httpclient.Get(nodeB.URL+"/peers", "") test.Expect(statusCode).ToEqual(200) test.Expect(body).ToEqual(`{"peers":["` + nodeA.URL + `"]}`) }