dht_test.go 8.66 KB
Newer Older
1 2
package dht

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
3
import (
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
4
	"bytes"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
	"testing"

	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"

	ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
	ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"

	ci "github.com/jbenet/go-ipfs/crypto"
	inet "github.com/jbenet/go-ipfs/net"
	mux "github.com/jbenet/go-ipfs/net/mux"
	netservice "github.com/jbenet/go-ipfs/net/service"
	peer "github.com/jbenet/go-ipfs/peer"
	u "github.com/jbenet/go-ipfs/util"

	"fmt"
	"time"
)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
23
func setupDHT(ctx context.Context, t *testing.T, p *peer.Peer) *IpfsDHT {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
24 25 26 27 28 29 30
	peerstore := peer.NewPeerstore()

	dhts := netservice.NewService(nil) // nil handler for now, need to patch it
	if err := dhts.Start(ctx); err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
31
	net, err := inet.NewIpfsNetwork(ctx, p, peerstore, &mux.ProtocolMap{
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
32 33 34 35 36 37
		mux.ProtocolID_Routing: dhts,
	})
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
38
	d := NewDHT(ctx, p, peerstore, net, dhts, ds.NewMapDatastore())
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
39
	dhts.SetHandler(d)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
40 41 42
	return d
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
43
func setupDHTS(ctx context.Context, n int, t *testing.T) ([]ma.Multiaddr, []*peer.Peer, []*IpfsDHT) {
44
	var addrs []ma.Multiaddr
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
45
	for i := 0; i < n; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
46 47 48 49 50 51 52 53
		a, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 5000+i))
		if err != nil {
			t.Fatal(err)
		}
		addrs = append(addrs, a)
	}

	var peers []*peer.Peer
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
54
	for i := 0; i < n; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
55 56 57 58
		p := makePeer(addrs[i])
		peers = append(peers, p)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
59 60
	dhts := make([]*IpfsDHT, n)
	for i := 0; i < n; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
61
		dhts[i] = setupDHT(ctx, t, peers[i])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
62 63 64 65 66
	}

	return addrs, peers, dhts
}

67
func makePeer(addr ma.Multiaddr) *peer.Peer {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
68 69 70 71 72 73 74 75
	p := new(peer.Peer)
	p.AddAddress(addr)
	sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512)
	if err != nil {
		panic(err)
	}
	p.PrivKey = sk
	p.PubKey = pk
76
	id, err := peer.IDFromPubKey(pk)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
77 78 79 80 81 82 83 84 85
	if err != nil {
		panic(err)
	}

	p.ID = id
	return p
}

func TestPing(t *testing.T) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
86
	// t.Skip("skipping test to debug another")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
87
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
88
	u.Debug = false
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
89 90 91 92 93 94 95 96 97 98 99 100
	addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/2222")
	if err != nil {
		t.Fatal(err)
	}
	addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5678")
	if err != nil {
		t.Fatal(err)
	}

	peerA := makePeer(addrA)
	peerB := makePeer(addrB)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
101 102
	dhtA := setupDHT(ctx, t, peerA)
	dhtB := setupDHT(ctx, t, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
103 104 105

	defer dhtA.Halt()
	defer dhtB.Halt()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
106 107
	defer dhtA.network.Close()
	defer dhtB.network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
108

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
109
	_, err = dhtA.Connect(ctx, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
110 111 112 113 114
	if err != nil {
		t.Fatal(err)
	}

	//Test that we can ping the node
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
115 116
	ctxT, _ := context.WithTimeout(ctx, 5*time.Millisecond)
	err = dhtA.Ping(ctxT, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
117 118 119
	if err != nil {
		t.Fatal(err)
	}
120

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
121 122
	ctxT, _ = context.WithTimeout(ctx, 5*time.Millisecond)
	err = dhtB.Ping(ctxT, peerA)
123 124 125
	if err != nil {
		t.Fatal(err)
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
126 127 128
}

func TestValueGetSet(t *testing.T) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
129 130
	// t.Skip("skipping test to debug another")

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
131
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
132
	u.Debug = false
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
133 134 135 136 137 138 139 140 141 142 143 144
	addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/1235")
	if err != nil {
		t.Fatal(err)
	}
	addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5679")
	if err != nil {
		t.Fatal(err)
	}

	peerA := makePeer(addrA)
	peerB := makePeer(addrB)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
145 146
	dhtA := setupDHT(ctx, t, peerA)
	dhtB := setupDHT(ctx, t, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
147 148 149

	defer dhtA.Halt()
	defer dhtB.Halt()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
150 151
	defer dhtA.network.Close()
	defer dhtB.network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
152

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
153
	_, err = dhtA.Connect(ctx, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
154 155 156 157
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
158
	ctxT, _ := context.WithTimeout(ctx, time.Second)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
159
	dhtA.PutValue(ctxT, "hello", []byte("world"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
160

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
161
	ctxT, _ = context.WithTimeout(ctx, time.Second*2)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
162
	val, err := dhtA.GetValue(ctxT, "hello")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
163 164 165 166 167 168 169 170
	if err != nil {
		t.Fatal(err)
	}

	if string(val) != "world" {
		t.Fatalf("Expected 'world' got '%s'", string(val))
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
171
	ctxT, _ = context.WithTimeout(ctx, time.Second*2)
172 173 174 175 176 177 178 179
	val, err = dhtB.GetValue(ctxT, "hello")
	if err != nil {
		t.Fatal(err)
	}

	if string(val) != "world" {
		t.Fatalf("Expected 'world' got '%s'", string(val))
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
180 181
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
182 183
func TestProvides(t *testing.T) {
	// t.Skip("skipping test to debug another")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
184
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
185 186 187

	u.Debug = false

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
188
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
189 190 191 192 193 194 195
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
196
	_, err := dhts[0].Connect(ctx, peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
197 198 199 200
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
201
	_, err = dhts[1].Connect(ctx, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
202 203 204 205
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
206
	_, err = dhts[1].Connect(ctx, peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
207 208 209 210 211 212 213 214 215 216 217 218 219 220
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
	if err != nil {
		t.Fatal(err)
	}

	bits, err := dhts[3].getLocal(u.Key("hello"))
	if err != nil && bytes.Equal(bits, []byte("world")) {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
221
	err = dhts[3].Provide(ctx, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
222 223 224 225 226 227
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
228
	ctxT, _ := context.WithTimeout(ctx, time.Second)
Jeromy's avatar
Jeromy committed
229
	provchan := dhts[0].FindProvidersAsync(ctxT, u.Key("hello"), 1)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
230

Jeromy's avatar
Jeromy committed
231 232 233 234 235 236 237 238
	after := time.After(time.Second)
	select {
	case prov := <-provchan:
		if prov == nil {
			t.Fatal("Got back nil provider")
		}
	case <-after:
		t.Fatal("Did not get a provider back.")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
239 240 241
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
242 243 244
func TestProvidesAsync(t *testing.T) {
	// t.Skip("skipping test to debug another")

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
245
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
246 247
	u.Debug = false

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
248
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
249 250 251 252 253 254 255
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
256
	_, err := dhts[0].Connect(ctx, peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
257 258 259 260
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
261
	_, err = dhts[1].Connect(ctx, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
262 263 264 265
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
266
	_, err = dhts[1].Connect(ctx, peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
267 268 269 270 271 272 273 274 275 276 277 278 279 280
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
	if err != nil {
		t.Fatal(err)
	}

	bits, err := dhts[3].getLocal(u.Key("hello"))
	if err != nil && bytes.Equal(bits, []byte("world")) {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
281
	err = dhts[3].Provide(ctx, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
282 283 284 285 286 287
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
288 289
	ctxT, _ := context.WithTimeout(ctx, time.Millisecond*300)
	provs := dhts[0].FindProvidersAsync(ctxT, u.Key("hello"), 5)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
290 291 292
	select {
	case p := <-provs:
		if !p.ID.Equal(dhts[3].self.ID) {
293
			t.Fatalf("got a provider, but not the right one. %s", p)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
294
		}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
295
	case <-ctxT.Done():
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
296 297 298 299
		t.Fatal("Didnt get back providers")
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
300 301 302
func TestLayeredGet(t *testing.T) {
	// t.Skip("skipping test to debug another")

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
303
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
304
	u.Debug = false
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
305
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
306 307 308 309 310 311 312
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
313
	_, err := dhts[0].Connect(ctx, peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
314 315 316 317
	if err != nil {
		t.Fatalf("Failed to connect: %s", err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
318
	_, err = dhts[1].Connect(ctx, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
319 320 321 322
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
323
	_, err = dhts[1].Connect(ctx, peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
324 325 326 327 328 329 330 331 332
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
333
	err = dhts[3].Provide(ctx, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
334 335 336 337 338 339
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
340
	ctxT, _ := context.WithTimeout(ctx, time.Second)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
341
	val, err := dhts[0].GetValue(ctxT, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
342 343 344 345 346 347 348 349 350 351 352 353 354
	if err != nil {
		t.Fatal(err)
	}

	if string(val) != "world" {
		t.Fatal("Got incorrect value.")
	}

}

func TestFindPeer(t *testing.T) {
	// t.Skip("skipping test to debug another")

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
355
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
356 357
	u.Debug = false

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
358
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
359 360 361 362 363 364 365
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			dhts[i].network.Close()
		}
	}()

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
366
	_, err := dhts[0].Connect(ctx, peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
367 368 369 370
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
371
	_, err = dhts[1].Connect(ctx, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
372 373 374 375
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
376
	_, err = dhts[1].Connect(ctx, peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
377 378 379 380
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
381
	ctxT, _ := context.WithTimeout(ctx, time.Second)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
382
	p, err := dhts[0].FindPeer(ctxT, peers[2].ID)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
383 384 385 386 387 388 389 390 391 392 393 394
	if err != nil {
		t.Fatal(err)
	}

	if p == nil {
		t.Fatal("Failed to find peer.")
	}

	if !p.ID.Equal(peers[2].ID) {
		t.Fatal("Didnt find expected peer.")
	}
}
395 396 397 398

func TestConnectCollision(t *testing.T) {
	// t.Skip("skipping test to debug another")

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
399
	ctx := context.Background()
400 401 402 403 404 405 406 407 408 409 410 411 412
	u.Debug = false
	addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/1235")
	if err != nil {
		t.Fatal(err)
	}
	addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5679")
	if err != nil {
		t.Fatal(err)
	}

	peerA := makePeer(addrA)
	peerB := makePeer(addrB)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
413 414
	dhtA := setupDHT(ctx, t, peerA)
	dhtB := setupDHT(ctx, t, peerB)
415 416 417 418 419 420 421 422

	defer dhtA.Halt()
	defer dhtB.Halt()
	defer dhtA.network.Close()
	defer dhtB.network.Close()

	done := make(chan struct{})
	go func() {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
423
		_, err = dhtA.Connect(ctx, peerB)
424 425 426 427 428 429
		if err != nil {
			t.Fatal(err)
		}
		done <- struct{}{}
	}()
	go func() {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
430
		_, err = dhtB.Connect(ctx, peerA)
431 432 433 434 435 436
		if err != nil {
			t.Fatal(err)
		}
		done <- struct{}{}
	}()

Jeromy's avatar
Jeromy committed
437 438 439 440 441 442 443 444 445 446 447
	timeout := time.After(time.Second * 5)
	select {
	case <-done:
	case <-timeout:
		t.Fatal("Timeout received!")
	}
	select {
	case <-done:
	case <-timeout:
		t.Fatal("Timeout received!")
	}
448
}