dht_test.go 10.6 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"
5
	"math/rand"
6
	"sort"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
7 8 9 10
	"testing"

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

11
	ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
12 13 14 15 16 17
	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"
	peer "github.com/jbenet/go-ipfs/peer"
	u "github.com/jbenet/go-ipfs/util"
18
	testutil "github.com/jbenet/go-ipfs/util/testutil"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
19 20 21 22 23

	"fmt"
	"time"
)

24 25 26 27 28 29 30 31 32 33
func randMultiaddr(t *testing.T) ma.Multiaddr {

	s := fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 10000+rand.Intn(40000))
	a, err := ma.NewMultiaddr(s)
	if err != nil {
		t.Fatal(err)
	}
	return a
}

34
func setupDHT(ctx context.Context, t *testing.T, p peer.Peer) *IpfsDHT {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
35 36
	peerstore := peer.NewPeerstore()

37
	n, err := inet.NewNetwork(ctx, p.Addresses(), p, peerstore)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
38 39 40 41
	if err != nil {
		t.Fatal(err)
	}

42 43
	d := NewDHT(ctx, p, peerstore, n, ds.NewMapDatastore())

Jeromy's avatar
Jeromy committed
44 45 46
	d.Validators["v"] = func(u.Key, []byte) error {
		return nil
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
47 48 49
	return d
}

50
func setupDHTS(ctx context.Context, n int, t *testing.T) ([]ma.Multiaddr, []peer.Peer, []*IpfsDHT) {
51
	var addrs []ma.Multiaddr
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
52
	for i := 0; i < n; i++ {
53 54
		r := rand.Intn(40000)
		a, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 10000+r))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
55 56 57 58 59 60
		if err != nil {
			t.Fatal(err)
		}
		addrs = append(addrs, a)
	}

61
	var peers []peer.Peer
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
62
	for i := 0; i < n; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
63 64 65 66
		p := makePeer(addrs[i])
		peers = append(peers, p)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
67 68
	dhts := make([]*IpfsDHT, n)
	for i := 0; i < n; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
69
		dhts[i] = setupDHT(ctx, t, peers[i])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
70 71 72 73 74
	}

	return addrs, peers, dhts
}

75 76 77 78 79 80 81 82
func makePeerString(t *testing.T, addr string) peer.Peer {
	maddr, err := ma.NewMultiaddr(addr)
	if err != nil {
		t.Fatal(err)
	}
	return makePeer(maddr)
}

83
func makePeer(addr ma.Multiaddr) peer.Peer {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
84 85 86 87
	sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512)
	if err != nil {
		panic(err)
	}
88
	p, err := testutil.NewPeerWithKeyPair(sk, pk)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
89 90 91
	if err != nil {
		panic(err)
	}
92
	p.AddAddress(addr)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
93 94 95 96
	return p
}

func TestPing(t *testing.T) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
97
	// t.Skip("skipping test to debug another")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
98
	ctx := context.Background()
99 100 101

	addrA := randMultiaddr(t)
	addrB := randMultiaddr(t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
102 103 104 105

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
106 107
	dhtA := setupDHT(ctx, t, peerA)
	dhtB := setupDHT(ctx, t, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
108

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
109 110
	defer dhtA.Close()
	defer dhtB.Close()
111 112
	defer dhtA.network.Close()
	defer dhtB.network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
113

114
	if err := dhtA.Connect(ctx, peerB); err != nil {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
115 116 117
		t.Fatal(err)
	}

118 119 120 121
	// if err := dhtB.Connect(ctx, peerA); err != nil {
	// 	t.Fatal(err)
	// }

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
122
	//Test that we can ping the node
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
123
	ctxT, _ := context.WithTimeout(ctx, 100*time.Millisecond)
124
	if err := dhtA.Ping(ctxT, peerB); err != nil {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
125 126
		t.Fatal(err)
	}
127

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
128
	ctxT, _ = context.WithTimeout(ctx, 100*time.Millisecond)
129
	if err := dhtB.Ping(ctxT, peerA); err != nil {
130 131
		t.Fatal(err)
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
132 133 134
}

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
137
	ctx := context.Background()
138 139 140

	addrA := randMultiaddr(t)
	addrB := randMultiaddr(t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
141 142 143 144

	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

Jeromy's avatar
Jeromy committed
148 149 150 151 152 153
	vf := func(u.Key, []byte) error {
		return nil
	}
	dhtA.Validators["v"] = vf
	dhtB.Validators["v"] = vf

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
154 155
	defer dhtA.Close()
	defer dhtB.Close()
156 157
	defer dhtA.network.Close()
	defer dhtB.network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
158

159
	err := dhtA.Connect(ctx, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
160 161 162 163
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
164
	ctxT, _ := context.WithTimeout(ctx, time.Second)
Jeromy's avatar
Jeromy committed
165
	dhtA.PutValue(ctxT, "/v/hello", []byte("world"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
166

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
167
	ctxT, _ = context.WithTimeout(ctx, time.Second*2)
Jeromy's avatar
Jeromy committed
168
	val, err := dhtA.GetValue(ctxT, "/v/hello")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
169 170 171 172 173 174 175 176
	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
177
	ctxT, _ = context.WithTimeout(ctx, time.Second*2)
Jeromy's avatar
Jeromy committed
178
	val, err = dhtB.GetValue(ctxT, "/v/hello")
179 180 181 182 183 184 185
	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
186 187
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
188 189
func TestProvides(t *testing.T) {
	// t.Skip("skipping test to debug another")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
190
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
191

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

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

205
	err = dhts[1].Connect(ctx, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
206 207 208 209
	if err != nil {
		t.Fatal(err)
	}

210
	err = dhts[1].Connect(ctx, peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
211 212 213 214 215 216 217 218 219 220 221 222 223 224
	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
225
	err = dhts[3].Provide(ctx, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
226 227 228 229 230 231
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

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

Jeromy's avatar
Jeromy committed
235 236 237 238 239 240 241 242
	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
243 244 245
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
246
func TestProvidesAsync(t *testing.T) {
247 248 249
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
250

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
251
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
252

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
253
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
254 255
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
256
			dhts[i].Close()
257
			defer dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
258 259 260
		}
	}()

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

266
	err = dhts[1].Connect(ctx, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
267 268 269 270
	if err != nil {
		t.Fatal(err)
	}

271
	err = dhts[1].Connect(ctx, peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
272 273 274 275 276 277 278 279 280 281 282 283 284 285
	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
286
	err = dhts[3].Provide(ctx, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
287 288 289 290 291 292
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
293 294
	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
295
	select {
Jeromy's avatar
Jeromy committed
296 297 298 299 300 301 302
	case p, ok := <-provs:
		if !ok {
			t.Fatal("Provider channel was closed...")
		}
		if p == nil {
			t.Fatal("Got back nil provider!")
		}
303
		if !p.ID().Equal(dhts[3].self.ID()) {
304
			t.Fatalf("got a provider, but not the right one. %s", p)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
305
		}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
306
	case <-ctxT.Done():
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
307 308 309 310
		t.Fatal("Didnt get back providers")
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
311
func TestLayeredGet(t *testing.T) {
312 313 314
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
315

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
316
	ctx := context.Background()
317

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
318
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
319 320
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
321
			dhts[i].Close()
322
			defer dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
323 324 325
		}
	}()

326
	err := dhts[0].Connect(ctx, peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
327 328 329 330
	if err != nil {
		t.Fatalf("Failed to connect: %s", err)
	}

331
	err = dhts[1].Connect(ctx, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
332 333 334 335
	if err != nil {
		t.Fatal(err)
	}

336
	err = dhts[1].Connect(ctx, peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
337 338 339 340
	if err != nil {
		t.Fatal(err)
	}

Jeromy's avatar
Jeromy committed
341
	err = dhts[3].putLocal(u.Key("/v/hello"), []byte("world"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
342 343 344 345
	if err != nil {
		t.Fatal(err)
	}

Jeromy's avatar
Jeromy committed
346
	err = dhts[3].Provide(ctx, u.Key("/v/hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
347 348 349 350 351 352
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
353
	ctxT, _ := context.WithTimeout(ctx, time.Second)
Jeromy's avatar
Jeromy committed
354
	val, err := dhts[0].GetValue(ctxT, u.Key("/v/hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
355 356 357 358 359 360 361 362 363 364 365
	if err != nil {
		t.Fatal(err)
	}

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

}

func TestFindPeer(t *testing.T) {
366 367 368
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
369

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
370
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
371

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
372
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
373 374
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
375
			dhts[i].Close()
376
			dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
377 378 379
		}
	}()

380
	err := dhts[0].Connect(ctx, peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
381 382 383 384
	if err != nil {
		t.Fatal(err)
	}

385
	err = dhts[1].Connect(ctx, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
386 387 388 389
	if err != nil {
		t.Fatal(err)
	}

390
	err = dhts[1].Connect(ctx, peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
391 392 393 394
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
395
	ctxT, _ := context.WithTimeout(ctx, time.Second)
396
	p, err := dhts[0].FindPeer(ctxT, peers[2].ID())
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
397 398 399 400 401 402 403 404
	if err != nil {
		t.Fatal(err)
	}

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

405
	if !p.ID().Equal(peers[2].ID()) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
406 407 408
		t.Fatal("Didnt find expected peer.")
	}
}
409

410
func TestFindPeersConnectedToPeer(t *testing.T) {
411 412
	t.Skip("not quite correct (see note)")

413 414 415 416 417 418 419 420 421 422
	if testing.Short() {
		t.SkipNow()
	}

	ctx := context.Background()

	_, peers, dhts := setupDHTS(ctx, 4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Close()
423
			dhts[i].network.Close()
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
		}
	}()

	// topology:
	// 0-1, 1-2, 1-3, 2-3
	err := dhts[0].Connect(ctx, peers[1])
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[1].Connect(ctx, peers[2])
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[1].Connect(ctx, peers[3])
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[2].Connect(ctx, peers[3])
	if err != nil {
		t.Fatal(err)
	}

	// fmt.Println("0 is", peers[0])
	// fmt.Println("1 is", peers[1])
	// fmt.Println("2 is", peers[2])
	// fmt.Println("3 is", peers[3])

	ctxT, _ := context.WithTimeout(ctx, time.Second)
	pchan, err := dhts[0].FindPeersConnectedToPeer(ctxT, peers[2].ID())
	if err != nil {
		t.Fatal(err)
	}

	// shouldFind := []peer.Peer{peers[1], peers[3]}
	found := []peer.Peer{}
	for nextp := range pchan {
		found = append(found, nextp)
	}

	// fmt.Printf("querying 0 (%s) FindPeersConnectedToPeer 2 (%s)\n", peers[0], peers[2])
	// fmt.Println("should find 1, 3", shouldFind)
	// fmt.Println("found", found)

	// testPeerListsMatch(t, shouldFind, found)

	log.Warning("TestFindPeersConnectedToPeer is not quite correct")
	if len(found) == 0 {
		t.Fatal("didn't find any peers.")
	}
}

func testPeerListsMatch(t *testing.T, p1, p2 []peer.Peer) {

	if len(p1) != len(p2) {
		t.Fatal("did not find as many peers as should have", p1, p2)
	}

	ids1 := make([]string, len(p1))
	ids2 := make([]string, len(p2))

	for i, p := range p1 {
		ids1[i] = p.ID().Pretty()
	}

	for i, p := range p2 {
		ids2[i] = p.ID().Pretty()
	}

	sort.Sort(sort.StringSlice(ids1))
	sort.Sort(sort.StringSlice(ids2))

	for i := range ids1 {
		if ids1[i] != ids2[i] {
			t.Fatal("Didnt find expected peer", ids1[i], ids2)
		}
	}
}

505
func TestConnectCollision(t *testing.T) {
506 507 508
	if testing.Short() {
		t.SkipNow()
	}
509

510
	runTimes := 10
511

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
512 513
	for rtime := 0; rtime < runTimes; rtime++ {
		log.Notice("Running Time: ", rtime)
514

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
515
		ctx := context.Background()
516 517 518

		addrA := randMultiaddr(t)
		addrB := randMultiaddr(t)
519

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
520 521 522 523 524 525 526 527
		peerA := makePeer(addrA)
		peerB := makePeer(addrB)

		dhtA := setupDHT(ctx, t, peerA)
		dhtB := setupDHT(ctx, t, peerB)

		done := make(chan struct{})
		go func() {
528
			err := dhtA.Connect(ctx, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
529 530 531 532 533 534
			if err != nil {
				t.Fatal(err)
			}
			done <- struct{}{}
		}()
		go func() {
535
			err := dhtB.Connect(ctx, peerA)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
			if err != nil {
				t.Fatal(err)
			}
			done <- struct{}{}
		}()

		timeout := time.After(time.Second)
		select {
		case <-done:
		case <-timeout:
			t.Fatal("Timeout received!")
		}
		select {
		case <-done:
		case <-timeout:
			t.Fatal("Timeout received!")
		}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
554 555
		dhtA.Close()
		dhtB.Close()
556 557
		dhtA.network.Close()
		dhtB.network.Close()
558 559

		<-time.After(200 * time.Millisecond)
Jeromy's avatar
Jeromy committed
560
	}
561
}