dht_test.go 13.5 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
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
94
func bootstrap(t *testing.T, ctx context.Context, dhts []*IpfsDHT) {
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110

	// try multiple rounds...
	rounds := 5
	for i := 0; i < rounds; i++ {
		fmt.Printf("bootstrapping round %d/%d\n", i, rounds)

		var wg sync.WaitGroup
		for _, dht := range dhts {
			wg.Add(1)
			go func() {
				defer wg.Done()
				dht.Bootstrap(ctx)
			}()
		}
		wg.Wait()

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
111 112 113
	}
}

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

118 119
	addrA := testutil.RandLocalTCPAddress()
	addrB := testutil.RandLocalTCPAddress()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
120

121 122
	dhtA := setupDHT(ctx, t, addrA)
	dhtB := setupDHT(ctx, t, addrB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
123

124 125
	peerA := dhtA.self
	peerB := dhtB.self
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
126

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
127 128
	defer dhtA.Close()
	defer dhtB.Close()
129 130
	defer dhtA.network.Close()
	defer dhtB.network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
131

132
	connect(t, ctx, dhtA, dhtB)
133

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
134
	//Test that we can ping the node
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
135
	ctxT, _ := context.WithTimeout(ctx, 100*time.Millisecond)
136
	if err := dhtA.Ping(ctxT, peerB); err != nil {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
137 138
		t.Fatal(err)
	}
139

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
140
	ctxT, _ = context.WithTimeout(ctx, 100*time.Millisecond)
141
	if err := dhtB.Ping(ctxT, peerA); err != nil {
142 143
		t.Fatal(err)
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
144 145 146
}

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

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

151 152
	addrA := testutil.RandLocalTCPAddress()
	addrB := testutil.RandLocalTCPAddress()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
153

154 155
	dhtA := setupDHT(ctx, t, addrA)
	dhtB := setupDHT(ctx, t, addrB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
156

157 158 159 160
	defer dhtA.Close()
	defer dhtB.Close()
	defer dhtA.network.Close()
	defer dhtB.network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
161

Jeromy's avatar
Jeromy committed
162 163 164 165 166 167
	vf := func(u.Key, []byte) error {
		return nil
	}
	dhtA.Validators["v"] = vf
	dhtB.Validators["v"] = vf

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

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
194 195
func TestProvides(t *testing.T) {
	// t.Skip("skipping test to debug another")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
196
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
197

198
	_, _, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
199 200
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
201
			dhts[i].Close()
202
			defer dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
203 204 205
		}
	}()

206 207 208
	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
209

210 211 212 213 214 215 216 217 218 219 220 221 222 223
	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
224 225
	}

226 227 228 229 230
	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
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
	// 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.")
		}
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
func TestBootstrap(t *testing.T) {
	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)])
	}

275 276
	<-time.After(100 * time.Millisecond)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
277
	t.Logf("bootstrapping them so they find each other", nDHTs)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
278 279
	ctxT, _ := context.WithTimeout(ctx, 5*time.Second)
	bootstrap(t, ctxT, dhts)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
280 281 282 283 284 285 286 287 288 289

	// the routing tables should be full now. let's inspect them.
	t.Logf("checking routing table of %d", nDHTs)
	for _, dht := range dhts {
		fmt.Printf("checking routing table of %s\n", dht.self)
		dht.routingTable.Print()
		fmt.Println("")
	}
}

290 291
func TestProvidesMany(t *testing.T) {
	t.Skip("this test doesn't work")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
292
	// t.Skip("skipping test to debug another")
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
	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)])
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
309 310
	t.Logf("bootstrapping them so they find each other", nDHTs)
	bootstrap(t, ctx, dhts)
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334

	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
335 336
	}

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

340 341 342 343 344 345 346
	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
347

348 349 350 351 352 353 354 355 356 357
		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
358
		}
359 360 361 362 363 364 365 366
	}

	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)
367
		}
368 369 370 371 372 373 374 375 376 377 378
	}

	// 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
379 380 381
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
382
func TestProvidesAsync(t *testing.T) {
383 384 385
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
386

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

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

397 398 399
	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
400

401
	err := dhts[3].putLocal(u.Key("hello"), []byte("world"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
402 403 404 405 406 407 408 409 410
	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
411
	err = dhts[3].Provide(ctx, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
412 413 414 415 416 417
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
418 419
	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
420
	select {
Jeromy's avatar
Jeromy committed
421 422 423 424
	case p, ok := <-provs:
		if !ok {
			t.Fatal("Provider channel was closed...")
		}
425
		if p.ID == "" {
Jeromy's avatar
Jeromy committed
426 427
			t.Fatal("Got back nil provider!")
		}
428
		if p.ID != dhts[3].self {
429
			t.Fatalf("got a provider, but not the right one. %s", p)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
430
		}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
431
	case <-ctxT.Done():
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
432 433 434 435
		t.Fatal("Didnt get back providers")
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
436
func TestLayeredGet(t *testing.T) {
437 438 439
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
440

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

443
	_, _, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
444 445
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
446
			dhts[i].Close()
447
			defer dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
448 449 450
		}
	}()

451 452 453
	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
454

455
	err := dhts[3].putLocal(u.Key("/v/hello"), []byte("world"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
456 457 458 459
	if err != nil {
		t.Fatal(err)
	}

Jeromy's avatar
Jeromy committed
460
	err = dhts[3].Provide(ctx, u.Key("/v/hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
461 462 463 464 465 466
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
467
	ctxT, _ := context.WithTimeout(ctx, time.Second)
Jeromy's avatar
Jeromy committed
468
	val, err := dhts[0].GetValue(ctxT, u.Key("/v/hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
469 470 471 472 473 474 475 476 477 478 479
	if err != nil {
		t.Fatal(err)
	}

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

}

func TestFindPeer(t *testing.T) {
480 481 482
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
483

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
486
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
487 488
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
489
			dhts[i].Close()
490
			dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
491 492 493
		}
	}()

494 495 496
	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
497

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
498
	ctxT, _ := context.WithTimeout(ctx, time.Second)
499
	p, err := dhts[0].FindPeer(ctxT, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
500 501 502 503
	if err != nil {
		t.Fatal(err)
	}

504
	if p.ID == "" {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
505 506 507
		t.Fatal("Failed to find peer.")
	}

508
	if p.ID != peers[2] {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
509 510 511
		t.Fatal("Didnt find expected peer.")
	}
}
512

513
func TestFindPeersConnectedToPeer(t *testing.T) {
514 515
	t.Skip("not quite correct (see note)")

516 517 518 519 520 521 522 523 524 525
	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()
526
			dhts[i].network.Close()
527 528 529 530 531
		}
	}()

	// topology:
	// 0-1, 1-2, 1-3, 2-3
532 533 534 535
	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])
536 537 538 539 540 541 542

	// 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)
543
	pchan, err := dhts[0].FindPeersConnectedToPeer(ctxT, peers[2])
544 545 546 547
	if err != nil {
		t.Fatal(err)
	}

548 549
	// shouldFind := []peer.ID{peers[1], peers[3]}
	found := []peer.PeerInfo{}
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
	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.")
	}
}

566
func testPeerListsMatch(t *testing.T, p1, p2 []peer.ID) {
567 568 569 570 571 572 573 574 575

	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 {
576
		ids1[i] = string(p)
577 578 579
	}

	for i, p := range p2 {
580
		ids2[i] = string(p)
581 582 583 584 585 586 587 588 589 590 591 592
	}

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

593
func TestConnectCollision(t *testing.T) {
594 595 596
	if testing.Short() {
		t.SkipNow()
	}
597

598
	runTimes := 10
599

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

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

605 606
		addrA := testutil.RandLocalTCPAddress()
		addrB := testutil.RandLocalTCPAddress()
607

608 609
		dhtA := setupDHT(ctx, t, addrA)
		dhtB := setupDHT(ctx, t, addrB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
610

611 612
		peerA := dhtA.self
		peerB := dhtB.self
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
613

614
		errs := make(chan error)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
615
		go func() {
616
			dhtA.peerstore.AddAddress(peerB, addrB)
617
			err := dhtA.Connect(ctx, peerB)
618
			errs <- err
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
619 620
		}()
		go func() {
621
			dhtB.peerstore.AddAddress(peerA, addrA)
622
			err := dhtB.Connect(ctx, peerA)
623
			errs <- err
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
624 625 626 627
		}()

		timeout := time.After(time.Second)
		select {
628 629 630 631
		case e := <-errs:
			if e != nil {
				t.Fatal(e)
			}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
632 633 634 635
		case <-timeout:
			t.Fatal("Timeout received!")
		}
		select {
636 637 638 639
		case e := <-errs:
			if e != nil {
				t.Fatal(e)
			}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
640 641 642 643
		case <-timeout:
			t.Fatal("Timeout received!")
		}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
644 645
		dhtA.Close()
		dhtB.Close()
646 647
		dhtA.network.Close()
		dhtB.network.Close()
Jeromy's avatar
Jeromy committed
648
	}
649
}