dht_test.go 9.03 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
	"testing"

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

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

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
}

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

53
	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
	sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512)
	if err != nil {
		panic(err)
	}
72
	p, err := peer.WithKeyPair(sk, pk)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
73 74 75
	if err != nil {
		panic(err)
	}
76
	p.AddAddress(addr)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
77 78 79 80
	return p
}

func TestPing(t *testing.T) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
81
	// t.Skip("skipping test to debug another")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
82
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
83
	u.Debug = false
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
84 85 86 87 88 89 90 91 92 93 94 95
	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
96 97
	dhtA := setupDHT(ctx, t, peerA)
	dhtB := setupDHT(ctx, t, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
98 99 100

	defer dhtA.Halt()
	defer dhtB.Halt()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
101 102
	defer dhtA.dialer.(inet.Network).Close()
	defer dhtB.dialer.(inet.Network).Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
103

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
104
	_, err = dhtA.Connect(ctx, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
105 106 107 108 109
	if err != nil {
		t.Fatal(err)
	}

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

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
126
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
127
	u.Debug = false
128
	addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/11235")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
129 130 131
	if err != nil {
		t.Fatal(err)
	}
132
	addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/15679")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
133 134 135 136 137 138 139
	if err != nil {
		t.Fatal(err)
	}

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
140 141
	dhtA := setupDHT(ctx, t, peerA)
	dhtB := setupDHT(ctx, t, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
142 143 144

	defer dhtA.Halt()
	defer dhtB.Halt()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
145 146
	defer dhtA.dialer.(inet.Network).Close()
	defer dhtB.dialer.(inet.Network).Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
147

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
148
	_, err = dhtA.Connect(ctx, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
149 150 151 152
	if err != nil {
		t.Fatal(err)
	}

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

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

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

	u.Debug = false

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
183
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
184 185 186
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
187
			defer dhts[i].dialer.(inet.Network).Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
188 189 190
		}
	}()

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
191
	_, err := dhts[0].Connect(ctx, peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
192 193 194 195
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
196
	_, err = dhts[1].Connect(ctx, peers[2])
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[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
202 203 204 205 206 207 208 209 210 211 212 213 214 215
	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
216
	err = dhts[3].Provide(ctx, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
217 218 219 220 221 222
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

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

Jeromy's avatar
Jeromy committed
226 227 228 229 230 231 232 233
	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
234 235 236
	}
}

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
240
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
241 242
	u.Debug = false

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
243
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
244 245 246
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
247
			defer dhts[i].dialer.(inet.Network).Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
248 249 250
		}
	}()

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
251
	_, err := dhts[0].Connect(ctx, peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
252 253 254 255
	if err != nil {
		t.Fatal(err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
256
	_, err = dhts[1].Connect(ctx, peers[2])
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[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
262 263 264 265 266 267 268 269 270 271 272 273 274 275
	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
276
	err = dhts[3].Provide(ctx, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
277 278 279 280 281 282
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
283 284
	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
285
	select {
Jeromy's avatar
Jeromy committed
286 287 288 289 290 291 292
	case p, ok := <-provs:
		if !ok {
			t.Fatal("Provider channel was closed...")
		}
		if p == nil {
			t.Fatal("Got back nil provider!")
		}
293
		if !p.ID().Equal(dhts[3].self.ID()) {
294
			t.Fatalf("got a provider, but not the right one. %s", p)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
295
		}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
296
	case <-ctxT.Done():
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
297 298 299 300
		t.Fatal("Didnt get back providers")
	}
}

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

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

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
324
	_, err = dhts[1].Connect(ctx, peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
325 326 327 328 329 330 331 332 333
	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
334
	err = dhts[3].Provide(ctx, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
335 336 337 338 339 340
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
341
	ctxT, _ := context.WithTimeout(ctx, time.Second)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
342
	val, err := dhts[0].GetValue(ctxT, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
343 344 345 346 347 348 349 350 351 352 353 354 355
	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
356
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
357 358
	u.Debug = false

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

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

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

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

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

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

392
	if !p.ID().Equal(peers[2].ID()) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
393 394 395
		t.Fatal("Didnt find expected peer.")
	}
}
396 397 398 399

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

400
	runTimes := 10
401

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
405 406
		ctx := context.Background()
		u.Debug = false
407
		addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/11235")
408 409 410
		if err != nil {
			t.Fatal(err)
		}
411
		addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/15679")
412 413 414 415
		if err != nil {
			t.Fatal(err)
		}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
416 417 418 419 420 421 422 423 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
		peerA := makePeer(addrA)
		peerB := makePeer(addrB)

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

		done := make(chan struct{})
		go func() {
			_, err = dhtA.Connect(ctx, peerB)
			if err != nil {
				t.Fatal(err)
			}
			done <- struct{}{}
		}()
		go func() {
			_, err = dhtB.Connect(ctx, peerA)
			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!")
		}

450 451
		dhtA.Halt()
		dhtB.Halt()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
452 453
		dhtA.dialer.(inet.Network).Close()
		dhtB.dialer.(inet.Network).Close()
454 455

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