routing_test.go 3.44 KB
Newer Older
1 2 3 4 5 6 7 8
package mock

import (
	"bytes"
	"testing"

	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
	"github.com/jbenet/go-ipfs/peer"
9
	"github.com/jbenet/go-ipfs/peer/mock"
10 11 12 13 14 15 16 17 18 19 20 21 22 23
	u "github.com/jbenet/go-ipfs/util"
)

func TestKeyNotFound(t *testing.T) {

	vrs := VirtualRoutingServer()
	empty := vrs.Providers(u.Key("not there"))
	if len(empty) != 0 {
		t.Fatal("should be empty")
	}
}

func TestSetAndGet(t *testing.T) {
	pid := peer.ID([]byte("the peer id"))
24
	p := mockpeer.WithID(pid)
25 26 27 28 29 30 31 32 33 34 35
	k := u.Key("42")
	rs := VirtualRoutingServer()
	err := rs.Announce(p, k)
	if err != nil {
		t.Fatal(err)
	}
	providers := rs.Providers(k)
	if len(providers) != 1 {
		t.Fatal("should be one")
	}
	for _, elem := range providers {
36
		if bytes.Equal(elem.ID(), pid) {
37 38 39 40 41 42 43
			return
		}
	}
	t.Fatal("ID should have matched")
}

func TestClientFindProviders(t *testing.T) {
44
	peer := mockpeer.WithIDString("42")
45 46 47 48 49 50 51 52 53 54 55 56 57 58
	rs := VirtualRoutingServer()
	client := rs.Client(peer)

	k := u.Key("hello")
	err := client.Provide(context.Background(), k)
	if err != nil {
		t.Fatal(err)
	}
	max := 100

	providersFromHashTable := rs.Providers(k)

	isInHT := false
	for _, p := range providersFromHashTable {
59
		if bytes.Equal(p.ID(), peer.ID()) {
60 61 62 63 64 65 66 67 68
			isInHT = true
		}
	}
	if !isInHT {
		t.Fatal("Despite client providing key, peer wasn't in hash table as a provider")
	}
	providersFromClient := client.FindProvidersAsync(context.Background(), u.Key("hello"), max)
	isInClient := false
	for p := range providersFromClient {
69
		if bytes.Equal(p.ID(), peer.ID()) {
70 71 72 73 74 75 76 77 78 79 80 81 82
			isInClient = true
		}
	}
	if !isInClient {
		t.Fatal("Despite client providing key, client didn't receive peer when finding providers")
	}
}

func TestClientOverMax(t *testing.T) {
	rs := VirtualRoutingServer()
	k := u.Key("hello")
	numProvidersForHelloKey := 100
	for i := 0; i < numProvidersForHelloKey; i++ {
83
		peer := mockpeer.WithIDString(string(i))
84 85 86 87 88 89 90 91 92 93 94 95
		err := rs.Announce(peer, k)
		if err != nil {
			t.Fatal(err)
		}
	}
	providersFromHashTable := rs.Providers(k)
	if len(providersFromHashTable) != numProvidersForHelloKey {
		t.Log(1 == len(providersFromHashTable))
		t.Fatal("not all providers were returned")
	}

	max := 10
96
	peer := mockpeer.WithIDString("TODO")
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
	client := rs.Client(peer)

	providersFromClient := client.FindProvidersAsync(context.Background(), k, max)
	i := 0
	for _ = range providersFromClient {
		i++
	}
	if i != max {
		t.Fatal("Too many providers returned")
	}
}

// TODO does dht ensure won't receive self as a provider? probably not.
func TestCanceledContext(t *testing.T) {
	rs := VirtualRoutingServer()
	k := u.Key("hello")

	t.Log("async'ly announce infinite stream of providers for key")
	i := 0
	go func() { // infinite stream
		for {
118
			peer := mockpeer.WithIDString(string(i))
119 120 121 122 123 124 125 126
			err := rs.Announce(peer, k)
			if err != nil {
				t.Fatal(err)
			}
			i++
		}
	}()

127
	local := mockpeer.WithIDString("peer id doesn't matter")
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
	client := rs.Client(local)

	t.Log("warning: max is finite so this test is non-deterministic")
	t.Log("context cancellation could simply take lower priority")
	t.Log("and result in receiving the max number of results")
	max := 1000

	t.Log("cancel the context before consuming")
	ctx, cancelFunc := context.WithCancel(context.Background())
	cancelFunc()
	providers := client.FindProvidersAsync(ctx, k, max)

	numProvidersReturned := 0
	for _ = range providers {
		numProvidersReturned++
	}
	t.Log(numProvidersReturned)

	if numProvidersReturned == max {
		t.Fatal("Context cancel had no effect")
	}
}