dht_test.go 14 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
	ctx, cancel := context.WithCancel(ctx)

98
	rounds := 1
99 100 101
	for i := 0; i < rounds; i++ {
		fmt.Printf("bootstrapping round %d/%d\n", i, rounds)

102 103 104 105
		// tried async. sequential fares much better. compare:
		// 100 async https://gist.github.com/jbenet/56d12f0578d5f34810b2
		// 100 sync https://gist.github.com/jbenet/6c59e7c15426e48aaedd
		// probably because results compound
106
		for _, dht := range dhts {
107 108
			fmt.Printf("bootstrapping round %d/%d -- %s\n", i, rounds, dht.self)
			dht.Bootstrap(ctx, 3)
109
		}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
110
	}
111 112

	cancel()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
113 114
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

227 228 229 230 231
	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
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
	// 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
259 260 261
func TestBootstrap(t *testing.T) {
	ctx := context.Background()

262
	nDHTs := 10
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
263 264 265 266 267 268 269 270 271 272 273 274 275
	_, _, 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)])
	}

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

309
	<-time.After(100 * time.Millisecond)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
310
	t.Logf("bootstrapping them so they find each other", nDHTs)
311 312 313 314 315 316 317 318 319 320 321
	ctxT, _ := context.WithTimeout(ctx, 5*time.Second)
	bootstrap(t, ctxT, dhts)

	<-time.After(5 * time.Second)
	// 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("")
	}
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345

	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
346 347
	}

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

351 352
	errchan := make(chan error)

353
	ctxT, _ = context.WithTimeout(ctx, 5*time.Second)
354 355 356 357

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

359 360 361 362 363 364 365 366 367 368
		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
369
		}
370 371 372 373 374 375 376 377
	}

	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)
378
		}
379 380 381 382 383 384 385 386 387 388 389
	}

	// 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
390 391 392
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
393
func TestProvidesAsync(t *testing.T) {
394 395 396
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
397

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

400
	_, _, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
401 402
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
403
			dhts[i].Close()
404
			defer dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
405 406 407
		}
	}()

408 409 410
	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
411

412
	err := dhts[3].putLocal(u.Key("hello"), []byte("world"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
413 414 415 416 417 418 419 420 421
	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
422
	err = dhts[3].Provide(ctx, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
423 424 425 426 427 428
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
429 430
	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
431
	select {
Jeromy's avatar
Jeromy committed
432 433 434 435
	case p, ok := <-provs:
		if !ok {
			t.Fatal("Provider channel was closed...")
		}
436
		if p.ID == "" {
Jeromy's avatar
Jeromy committed
437 438
			t.Fatal("Got back nil provider!")
		}
439
		if p.ID != dhts[3].self {
440
			t.Fatalf("got a provider, but not the right one. %s", p)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
441
		}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
442
	case <-ctxT.Done():
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
443 444 445 446
		t.Fatal("Didnt get back providers")
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
447
func TestLayeredGet(t *testing.T) {
448 449 450
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
451

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

454
	_, _, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
455 456
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
457
			dhts[i].Close()
458
			defer dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
459 460 461
		}
	}()

462 463 464
	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
465

466
	err := dhts[3].putLocal(u.Key("/v/hello"), []byte("world"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
467 468 469 470
	if err != nil {
		t.Fatal(err)
	}

Jeromy's avatar
Jeromy committed
471
	err = dhts[3].Provide(ctx, u.Key("/v/hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
472 473 474 475 476 477
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
478
	ctxT, _ := context.WithTimeout(ctx, time.Second)
Jeromy's avatar
Jeromy committed
479
	val, err := dhts[0].GetValue(ctxT, u.Key("/v/hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
480 481 482 483 484 485 486 487 488 489 490
	if err != nil {
		t.Fatal(err)
	}

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

}

func TestFindPeer(t *testing.T) {
491 492 493
	if testing.Short() {
		t.SkipNow()
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
494

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
497
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
498 499
	defer func() {
		for i := 0; i < 4; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
500
			dhts[i].Close()
501
			dhts[i].network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
502 503 504
		}
	}()

505 506 507
	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
508

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
509
	ctxT, _ := context.WithTimeout(ctx, time.Second)
510
	p, err := dhts[0].FindPeer(ctxT, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
511 512 513 514
	if err != nil {
		t.Fatal(err)
	}

515
	if p.ID == "" {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
516 517 518
		t.Fatal("Failed to find peer.")
	}

519
	if p.ID != peers[2] {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
520 521 522
		t.Fatal("Didnt find expected peer.")
	}
}
523

524
func TestFindPeersConnectedToPeer(t *testing.T) {
525 526
	t.Skip("not quite correct (see note)")

527 528 529 530 531 532 533 534 535 536
	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()
537
			dhts[i].network.Close()
538 539 540 541 542
		}
	}()

	// topology:
	// 0-1, 1-2, 1-3, 2-3
543 544 545 546
	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])
547 548 549 550 551 552 553

	// 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)
554
	pchan, err := dhts[0].FindPeersConnectedToPeer(ctxT, peers[2])
555 556 557 558
	if err != nil {
		t.Fatal(err)
	}

559 560
	// shouldFind := []peer.ID{peers[1], peers[3]}
	found := []peer.PeerInfo{}
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
	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.")
	}
}

577
func testPeerListsMatch(t *testing.T, p1, p2 []peer.ID) {
578 579 580 581 582 583 584 585 586

	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 {
587
		ids1[i] = string(p)
588 589 590
	}

	for i, p := range p2 {
591
		ids2[i] = string(p)
592 593 594 595 596 597 598 599 600 601 602 603
	}

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

604
func TestConnectCollision(t *testing.T) {
605 606 607
	if testing.Short() {
		t.SkipNow()
	}
608

609
	runTimes := 10
610

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

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

616 617
		addrA := testutil.RandLocalTCPAddress()
		addrB := testutil.RandLocalTCPAddress()
618

619 620
		dhtA := setupDHT(ctx, t, addrA)
		dhtB := setupDHT(ctx, t, addrB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
621

622 623
		peerA := dhtA.self
		peerB := dhtB.self
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
624

625
		errs := make(chan error)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
626
		go func() {
627
			dhtA.peerstore.AddAddress(peerB, addrB)
628
			err := dhtA.Connect(ctx, peerB)
629
			errs <- err
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
630 631
		}()
		go func() {
632
			dhtB.peerstore.AddAddress(peerA, addrA)
633
			err := dhtB.Connect(ctx, peerA)
634
			errs <- err
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
635 636 637 638
		}()

		timeout := time.After(time.Second)
		select {
639 640 641 642
		case e := <-errs:
			if e != nil {
				t.Fatal(e)
			}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
643 644 645 646
		case <-timeout:
			t.Fatal("Timeout received!")
		}
		select {
647 648 649 650
		case e := <-errs:
			if e != nil {
				t.Fatal(e)
			}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
651 652 653 654
		case <-timeout:
			t.Fatal("Timeout received!")
		}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
655 656
		dhtA.Close()
		dhtB.Close()
657 658
		dhtA.network.Close()
		dhtB.network.Close()
Jeromy's avatar
Jeromy committed
659
	}
660
}