centralized_test.go 4.14 KB
Newer Older
Brian Tiger Chow's avatar
Brian Tiger Chow committed
1
package mockrouting
2 3 4

import (
	"testing"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
5
	"time"
6 7

	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
8
	peer "github.com/jbenet/go-ipfs/peer"
9
	u "github.com/jbenet/go-ipfs/util"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
10
	delay "github.com/jbenet/go-ipfs/util/delay"
11 12 13 14
)

func TestKeyNotFound(t *testing.T) {

15
	var pi = peer.PeerInfo{ID: peer.ID("the peer id")}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
16 17
	var key = u.Key("mock key")
	var ctx = context.Background()
18

Brian Tiger Chow's avatar
Brian Tiger Chow committed
19
	rs := NewServer()
20
	providers := rs.Client(pi).FindProvidersAsync(ctx, key, 10)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
21 22 23
	_, ok := <-providers
	if ok {
		t.Fatal("should be closed")
24 25 26 27
	}
}

func TestClientFindProviders(t *testing.T) {
28
	pi := peer.PeerInfo{ID: peer.ID("42")}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
29
	rs := NewServer()
30
	client := rs.Client(pi)
31 32 33 34 35 36

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

	// This is bad... but simulating networks is hard
	time.Sleep(time.Millisecond * 300)
40 41
	max := 100

42
	providersFromHashTable, err := rs.Client(pi).FindProviders(context.Background(), k)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
43 44 45
	if err != nil {
		t.Fatal(err)
	}
46 47

	isInHT := false
48 49
	for _, pi := range providersFromHashTable {
		if pi.ID == pi.ID {
50 51 52 53 54 55 56 57
			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
58 59
	for pi := range providersFromClient {
		if pi.ID == pi.ID {
60 61 62 63 64 65 66 67 68
			isInClient = true
		}
	}
	if !isInClient {
		t.Fatal("Despite client providing key, client didn't receive peer when finding providers")
	}
}

func TestClientOverMax(t *testing.T) {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
69
	rs := NewServer()
70 71 72
	k := u.Key("hello")
	numProvidersForHelloKey := 100
	for i := 0; i < numProvidersForHelloKey; i++ {
73 74
		pi := peer.PeerInfo{ID: peer.ID(i)}
		err := rs.Client(pi).Provide(context.Background(), k)
75 76 77 78 79 80
		if err != nil {
			t.Fatal(err)
		}
	}

	max := 10
81 82
	pi := peer.PeerInfo{ID: peer.ID("TODO")}
	client := rs.Client(pi)
83 84 85 86 87 88 89 90 91 92 93 94 95

	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) {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
96
	rs := NewServer()
97 98
	k := u.Key("hello")

99 100 101 102 103 104
	// avoid leaking goroutine, without using the context to signal
	// (we want the goroutine to keep trying to publish on a
	// cancelled context until we've tested it doesnt do anything.)
	done := make(chan struct{})
	defer func() { done <- struct{}{} }()

105 106 107 108
	t.Log("async'ly announce infinite stream of providers for key")
	i := 0
	go func() { // infinite stream
		for {
109 110 111 112 113 114 115
			select {
			case <-done:
				t.Log("exiting async worker")
				return
			default:
			}

116 117
			pi := peer.PeerInfo{ID: peer.ID(i)}
			err := rs.Client(pi).Provide(context.Background(), k)
118
			if err != nil {
119
				t.Error(err)
120 121 122 123 124
			}
			i++
		}
	}()

125
	local := peer.PeerInfo{ID: peer.ID("peer id doesn't matter")}
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
	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")
	}
}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
148 149 150

func TestValidAfter(t *testing.T) {

151
	var pi = peer.PeerInfo{ID: peer.ID("the peer id")}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
152 153 154 155 156 157 158 159 160
	var key = u.Key("mock key")
	var ctx = context.Background()
	conf := DelayConfig{
		ValueVisibility: delay.Fixed(1 * time.Hour),
		Query:           delay.Fixed(0),
	}

	rs := NewServerWithDelay(conf)

161
	rs.Client(pi).Provide(ctx, key)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
162

163 164
	var providers []peer.PeerInfo
	providers, err := rs.Client(pi).FindProviders(ctx, key)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
165 166 167 168 169 170 171 172
	if err != nil {
		t.Fatal(err)
	}
	if len(providers) > 0 {
		t.Fail()
	}

	conf.ValueVisibility.Set(0)
173
	providers, err = rs.Client(pi).FindProviders(ctx, key)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
174 175 176
	if err != nil {
		t.Fatal(err)
	}
177
	t.Log("providers", providers)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
178 179 180 181
	if len(providers) != 1 {
		t.Fail()
	}
}