dht_test.go 12.3 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
	"fmt"
6
	"sort"
7
	"sync"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
8
	"testing"
9
	"time"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
10 11 12

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

13
	ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
14
	dssync "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/sync"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
15 16
	ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"

17
	// ci "github.com/jbenet/go-ipfs/crypto"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
18 19 20
	inet "github.com/jbenet/go-ipfs/net"
	peer "github.com/jbenet/go-ipfs/peer"
	u "github.com/jbenet/go-ipfs/util"
21
	testutil "github.com/jbenet/go-ipfs/util/testutil"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
22 23
)

24 25 26 27 28 29 30 31 32 33 34
var testCaseValues = map[u.Key][]byte{}

func init() {
	testCaseValues["hello"] = []byte("world")
	for i := 0; i < 100; i++ {
		k := fmt.Sprintf("%d -- key", i)
		v := fmt.Sprintf("%d -- value", i)
		testCaseValues[u.Key(k)] = []byte(v)
	}
}

35
func setupDHT(ctx context.Context, t *testing.T, addr ma.Multiaddr) *IpfsDHT {
36

37 38 39 40 41 42
	sk, pk, err := testutil.RandKeyPair(512)
	if err != nil {
		t.Fatal(err)
	}

	p, err := peer.IDFromPublicKey(pk)
43 44 45 46
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
47
	peerstore := peer.NewPeerstore()
48 49 50
	peerstore.AddPrivKey(p, sk)
	peerstore.AddPubKey(p, pk)
	peerstore.AddAddress(p, addr)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
51

52
	n, err := inet.NewNetwork(ctx, []ma.Multiaddr{addr}, p, peerstore)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
53 54 55 56
	if err != nil {
		t.Fatal(err)
	}

57 58
	dss := dssync.MutexWrap(ds.NewMapDatastore())
	d := NewDHT(ctx, p, n, dss)
59

Jeromy's avatar
Jeromy committed
60 61 62
	d.Validators["v"] = func(u.Key, []byte) error {
		return nil
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
63 64 65
	return d
}

66 67
func setupDHTS(ctx context.Context, n int, t *testing.T) ([]ma.Multiaddr, []peer.ID, []*IpfsDHT) {
	addrs := make([]ma.Multiaddr, n)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
68
	dhts := make([]*IpfsDHT, n)
69 70
	peers := make([]peer.ID, n)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
71
	for i := 0; i < n; i++ {
72 73 74
		addrs[i] = testutil.RandLocalTCPAddress()
		dhts[i] = setupDHT(ctx, t, addrs[i])
		peers[i] = dhts[i].self
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
75 76 77 78 79
	}

	return addrs, peers, dhts
}

80
func connect(t *testing.T, ctx context.Context, a, b *IpfsDHT) {
81

82 83 84 85
	idB := b.self
	addrB := b.peerstore.Addresses(idB)
	if len(addrB) == 0 {
		t.Fatal("peers setup incorrectly: no local address")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
86
	}
87 88 89 90

	a.peerstore.AddAddresses(idB, addrB)
	if err := a.Connect(ctx, idB); err != nil {
		t.Fatal(err)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
91 92 93 94
	}
}

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

98 99
	addrA := testutil.RandLocalTCPAddress()
	addrB := testutil.RandLocalTCPAddress()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
100

101 102
	dhtA := setupDHT(ctx, t, addrA)
	dhtB := setupDHT(ctx, t, addrB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
103

104 105
	peerA := dhtA.self
	peerB := dhtB.self
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
106

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

112
	connect(t, ctx, dhtA, dhtB)
113

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

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

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

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

131 132
	addrA := testutil.RandLocalTCPAddress()
	addrB := testutil.RandLocalTCPAddress()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
133

134 135
	dhtA := setupDHT(ctx, t, addrA)
	dhtB := setupDHT(ctx, t, addrB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
136

137 138 139 140
	defer dhtA.Close()
	defer dhtB.Close()
	defer dhtA.network.Close()
	defer dhtB.network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
141

Jeromy's avatar
Jeromy committed
142 143 144 145 146 147
	vf := func(u.Key, []byte) error {
		return nil
	}
	dhtA.Validators["v"] = vf
	dhtB.Validators["v"] = vf

148
	connect(t, ctx, dhtA, dhtB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
149

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
153
	ctxT, _ = context.WithTimeout(ctx, time.Second*2)
Jeromy's avatar
Jeromy committed
154
	val, err := dhtA.GetValue(ctxT, "/v/hello")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
155 156 157 158 159 160 161 162
	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
163
	ctxT, _ = context.WithTimeout(ctx, time.Second*2)
Jeromy's avatar
Jeromy committed
164
	val, err = dhtB.GetValue(ctxT, "/v/hello")
165 166 167 168 169 170 171
	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
172 173
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
174 175
func TestProvides(t *testing.T) {
	// t.Skip("skipping test to debug another")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
176
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
177

178
	_, _, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
179 180
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
181
			dhts[i].Close()
182
			defer dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
183 184 185
		}
	}()

186 187 188
	connect(t, ctx, dhts[0], dhts[1])
	connect(t, ctx, dhts[1], dhts[2])
	connect(t, ctx, dhts[1], dhts[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
189

190 191 192 193 194 195 196 197 198 199 200 201 202 203
	for k, v := range testCaseValues {
		t.Logf("adding local values for %s = %s", k, v)
		err := dhts[3].putLocal(k, v)
		if err != nil {
			t.Fatal(err)
		}

		bits, err := dhts[3].getLocal(k)
		if err != nil {
			t.Fatal(err)
		}
		if !bytes.Equal(bits, v) {
			t.Fatal("didn't store the right bits (%s, %s)", k, v)
		}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
204 205
	}

206 207 208 209 210
	for k, _ := range testCaseValues {
		t.Logf("announcing provider for %s", k)
		if err := dhts[3].Provide(ctx, k); err != nil {
			t.Fatal(err)
		}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
211 212
	}

213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
	// what is this timeout for? was 60ms before.
	time.Sleep(time.Millisecond * 6)

	n := 0
	for k, _ := range testCaseValues {
		n = (n + 1) % 3

		t.Logf("getting providers for %s from %d", k, n)
		ctxT, _ := context.WithTimeout(ctx, time.Second)
		provchan := dhts[n].FindProvidersAsync(ctxT, k, 1)

		select {
		case prov := <-provchan:
			if prov.ID == "" {
				t.Fatal("Got back nil provider")
			}
			if prov.ID != dhts[3].self {
				t.Fatal("Got back wrong provider")
			}
		case <-ctxT.Done():
			t.Fatal("Did not get a provider back.")
		}
	}
}

func TestProvidesMany(t *testing.T) {
	t.Skip("this test doesn't work")
	ctx := context.Background()

	nDHTs := 40
	_, _, dhts := setupDHTS(ctx, nDHTs, t)
	defer func() {
		for i := 0; i < nDHTs; i++ {
			dhts[i].Close()
			defer dhts[i].network.Close()
		}
	}()

	t.Logf("connecting %d dhts in a ring", nDHTs)
	for i := 0; i < nDHTs; i++ {
		connect(t, ctx, dhts[i], dhts[(i+1)%len(dhts)])
	}

	// t.Logf("bootstrapping them so they find each other", nDHTs)
	// for _, dht := range dhts {
	// 	bootstrap(t, ctx, dht)
	// }

	d := 0
	for k, v := range testCaseValues {
		d = (d + 1) % len(dhts)
		dht := dhts[d]

		t.Logf("adding local values for %s = %s (on %s)", k, v, dht.self)
		err := dht.putLocal(k, v)
		if err != nil {
			t.Fatal(err)
		}

		bits, err := dht.getLocal(k)
		if err != nil {
			t.Fatal(err)
		}
		if !bytes.Equal(bits, v) {
			t.Fatal("didn't store the right bits (%s, %s)", k, v)
		}

		t.Logf("announcing provider for %s", k)
		if err := dht.Provide(ctx, k); err != nil {
			t.Fatal(err)
		}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
284 285
	}

286 287
	// what is this timeout for? was 60ms before.
	time.Sleep(time.Millisecond * 6)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
288

289 290 291 292 293 294 295
	errchan := make(chan error)

	ctxT, _ := context.WithTimeout(ctx, 5*time.Second)

	var wg sync.WaitGroup
	getProvider := func(dht *IpfsDHT, k u.Key) {
		defer wg.Done()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
296

297 298 299 300 301 302 303 304 305 306
		provchan := dht.FindProvidersAsync(ctxT, k, 1)
		select {
		case prov := <-provchan:
			if prov.ID == "" {
				errchan <- fmt.Errorf("Got back nil provider (%s at %s)", k, dht.self)
			} else if prov.ID != dhts[3].self {
				errchan <- fmt.Errorf("Got back wrong provider (%s at %s)", k, dht.self)
			}
		case <-ctxT.Done():
			errchan <- fmt.Errorf("Did not get a provider back (%s at %s)", k, dht.self)
Jeromy's avatar
Jeromy committed
307
		}
308 309 310 311 312 313 314 315
	}

	for k, _ := range testCaseValues {
		// everyone should be able to find it...
		for _, dht := range dhts {
			t.Logf("getting providers for %s at %s", k, dht.self)
			wg.Add(1)
			go getProvider(dht, k)
316
		}
317 318 319 320 321 322 323 324 325 326 327
	}

	// we need this because of printing errors
	go func() {
		wg.Wait()
		close(errchan)
	}()

	t.Logf("looking through errors")
	for err := range errchan {
		t.Error(err)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
328 329 330
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
331
func TestProvidesAsync(t *testing.T) {
332 333 334
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
335

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

338
	_, _, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
339 340
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
341
			dhts[i].Close()
342
			defer dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
343 344 345
		}
	}()

346 347 348
	connect(t, ctx, dhts[0], dhts[1])
	connect(t, ctx, dhts[1], dhts[2])
	connect(t, ctx, dhts[1], dhts[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
349

350
	err := dhts[3].putLocal(u.Key("hello"), []byte("world"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
351 352 353 354 355 356 357 358 359
	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
360
	err = dhts[3].Provide(ctx, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
361 362 363 364 365 366
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
367 368
	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
369
	select {
Jeromy's avatar
Jeromy committed
370 371 372 373
	case p, ok := <-provs:
		if !ok {
			t.Fatal("Provider channel was closed...")
		}
374
		if p.ID == "" {
Jeromy's avatar
Jeromy committed
375 376
			t.Fatal("Got back nil provider!")
		}
377
		if p.ID != dhts[3].self {
378
			t.Fatalf("got a provider, but not the right one. %s", p)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
379
		}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
380
	case <-ctxT.Done():
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
381 382 383 384
		t.Fatal("Didnt get back providers")
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
385
func TestLayeredGet(t *testing.T) {
386 387 388
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
389

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

392
	_, _, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
393 394
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
395
			dhts[i].Close()
396
			defer dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
397 398 399
		}
	}()

400 401 402
	connect(t, ctx, dhts[0], dhts[1])
	connect(t, ctx, dhts[1], dhts[2])
	connect(t, ctx, dhts[1], dhts[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
403

404
	err := dhts[3].putLocal(u.Key("/v/hello"), []byte("world"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
405 406 407 408
	if err != nil {
		t.Fatal(err)
	}

Jeromy's avatar
Jeromy committed
409
	err = dhts[3].Provide(ctx, u.Key("/v/hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
410 411 412 413 414 415
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
416
	ctxT, _ := context.WithTimeout(ctx, time.Second)
Jeromy's avatar
Jeromy committed
417
	val, err := dhts[0].GetValue(ctxT, u.Key("/v/hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
418 419 420 421 422 423 424 425 426 427 428
	if err != nil {
		t.Fatal(err)
	}

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

}

func TestFindPeer(t *testing.T) {
429 430 431
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
432

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
435
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
436 437
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
438
			dhts[i].Close()
439
			dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
440 441 442
		}
	}()

443 444 445
	connect(t, ctx, dhts[0], dhts[1])
	connect(t, ctx, dhts[1], dhts[2])
	connect(t, ctx, dhts[1], dhts[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
446

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
447
	ctxT, _ := context.WithTimeout(ctx, time.Second)
448
	p, err := dhts[0].FindPeer(ctxT, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
449 450 451 452
	if err != nil {
		t.Fatal(err)
	}

453
	if p.ID == "" {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
454 455 456
		t.Fatal("Failed to find peer.")
	}

457
	if p.ID != peers[2] {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
458 459 460
		t.Fatal("Didnt find expected peer.")
	}
}
461

462
func TestFindPeersConnectedToPeer(t *testing.T) {
463 464
	t.Skip("not quite correct (see note)")

465 466 467 468 469 470 471 472 473 474
	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()
475
			dhts[i].network.Close()
476 477 478 479 480
		}
	}()

	// topology:
	// 0-1, 1-2, 1-3, 2-3
481 482 483 484
	connect(t, ctx, dhts[0], dhts[1])
	connect(t, ctx, dhts[1], dhts[2])
	connect(t, ctx, dhts[1], dhts[3])
	connect(t, ctx, dhts[2], dhts[3])
485 486 487 488 489 490 491

	// 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)
492
	pchan, err := dhts[0].FindPeersConnectedToPeer(ctxT, peers[2])
493 494 495 496
	if err != nil {
		t.Fatal(err)
	}

497 498
	// shouldFind := []peer.ID{peers[1], peers[3]}
	found := []peer.PeerInfo{}
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
	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.")
	}
}

515
func testPeerListsMatch(t *testing.T, p1, p2 []peer.ID) {
516 517 518 519 520 521 522 523 524

	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 {
525
		ids1[i] = string(p)
526 527 528
	}

	for i, p := range p2 {
529
		ids2[i] = string(p)
530 531 532 533 534 535 536 537 538 539 540 541
	}

	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)
		}
	}
}

542
func TestConnectCollision(t *testing.T) {
543 544 545
	if testing.Short() {
		t.SkipNow()
	}
546

547
	runTimes := 10
548

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

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

554 555
		addrA := testutil.RandLocalTCPAddress()
		addrB := testutil.RandLocalTCPAddress()
556

557 558
		dhtA := setupDHT(ctx, t, addrA)
		dhtB := setupDHT(ctx, t, addrB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
559

560 561
		peerA := dhtA.self
		peerB := dhtB.self
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
562

563
		errs := make(chan error)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
564
		go func() {
565
			dhtA.peerstore.AddAddress(peerB, addrB)
566
			err := dhtA.Connect(ctx, peerB)
567
			errs <- err
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
568 569
		}()
		go func() {
570
			dhtB.peerstore.AddAddress(peerA, addrA)
571
			err := dhtB.Connect(ctx, peerA)
572
			errs <- err
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
573 574 575 576
		}()

		timeout := time.After(time.Second)
		select {
577 578 579 580
		case e := <-errs:
			if e != nil {
				t.Fatal(e)
			}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
581 582 583 584
		case <-timeout:
			t.Fatal("Timeout received!")
		}
		select {
585 586 587 588
		case e := <-errs:
			if e != nil {
				t.Fatal(e)
			}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
589 590 591 592
		case <-timeout:
			t.Fatal("Timeout received!")
		}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
593 594
		dhtA.Close()
		dhtB.Close()
595 596
		dhtA.network.Close()
		dhtB.network.Close()
Jeromy's avatar
Jeromy committed
597
	}
598
}