dht_test.go 8.77 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.network.Close()
	defer dhtB.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.network.Close()
	defer dhtB.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 187 188 189 190
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

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 247 248 249 250
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

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 286
	select {
	case p := <-provs:
287
		if !p.ID().Equal(dhts[3].self.ID()) {
288
			t.Fatalf("got a provider, but not the right one. %s", p)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
289
		}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
290
	case <-ctxT.Done():
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
291 292 293 294
		t.Fatal("Didnt get back providers")
	}
}

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
298
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
299
	u.Debug = false
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
300
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
301 302 303 304 305 306 307
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
308
	_, err := dhts[0].Connect(ctx, peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
309 310 311 312
	if err != nil {
		t.Fatalf("Failed to connect: %s", err)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
313
	_, err = dhts[1].Connect(ctx, peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
314 315 316 317
	if err != nil {
		t.Fatal(err)
	}

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

	time.Sleep(time.Millisecond * 60)

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
353
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
354 355 356 357 358 359 360
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			dhts[i].network.Close()
		}
	}()

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
361
	_, err := dhts[0].Connect(ctx, peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
362 363 364 365
	if err != nil {
		t.Fatal(err)
	}

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
376
	ctxT, _ := context.WithTimeout(ctx, time.Second)
377
	p, err := dhts[0].FindPeer(ctxT, peers[2].ID())
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
378 379 380 381 382 383 384 385
	if err != nil {
		t.Fatal(err)
	}

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

386
	if !p.ID().Equal(peers[2].ID()) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
387 388 389
		t.Fatal("Didnt find expected peer.")
	}
}
390 391 392 393

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

394
	runTimes := 10
395

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
399 400
		ctx := context.Background()
		u.Debug = false
401
		addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/11235")
402 403 404
		if err != nil {
			t.Fatal(err)
		}
405
		addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/15679")
406 407 408 409
		if err != nil {
			t.Fatal(err)
		}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
410 411 412 413 414 415 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
		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!")
		}

444 445 446 447 448 449
		dhtA.Halt()
		dhtB.Halt()
		dhtA.network.Close()
		dhtB.network.Close()

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