dht_test.go 8.83 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 9 10 11 12 13 14 15 16 17 18 19 20 21 22
	"testing"

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

	ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
	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"
)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
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
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
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 53
		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)
	}

	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 72 73 74 75
	p := new(peer.Peer)
	p.AddAddress(addr)
	sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512)
	if err != nil {
		panic(err)
	}
	p.PrivKey = sk
	p.PubKey = pk
76
	id, err := peer.IDFromPubKey(pk)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
77 78 79 80 81 82 83 84 85
	if err != nil {
		panic(err)
	}

	p.ID = id
	return p
}

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

	defer dhtA.Halt()
	defer dhtB.Halt()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
106 107
	defer dhtA.network.Close()
	defer dhtB.network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
108

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
109
	_, err = dhtA.Connect(ctx, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
110 111 112 113 114
	if err != nil {
		t.Fatal(err)
	}

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

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

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

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
145 146
	dhtA := setupDHT(ctx, t, peerA)
	dhtB := setupDHT(ctx, t, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
147 148 149

	defer dhtA.Halt()
	defer dhtB.Halt()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
150 151
	defer dhtA.network.Close()
	defer dhtB.network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
152

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
153
	_, err = dhtA.Connect(ctx, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
154 155 156 157
	if err != nil {
		t.Fatal(err)
	}

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
182 183
func TestProvides(t *testing.T) {
	// t.Skip("skipping test to debug another")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
184
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
185 186 187

	u.Debug = false

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
188
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
189 190 191 192 193 194 195
	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
196
	_, err := dhts[0].Connect(ctx, peers[1])
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[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
202 203 204 205
	if err != nil {
		t.Fatal(err)
	}

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

	time.Sleep(time.Millisecond * 60)

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

Jeromy's avatar
Jeromy committed
231 232 233 234 235 236 237 238
	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
239 240 241
	}
}

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
245
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
246 247
	u.Debug = false

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
248
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
249 250 251 252 253 254 255
	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
256
	_, err := dhts[0].Connect(ctx, peers[1])
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[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
262 263 264 265
	if err != nil {
		t.Fatal(err)
	}

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

	time.Sleep(time.Millisecond * 60)

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
303
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
304
	u.Debug = false
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
305
	_, peers, dhts := setupDHTS(ctx, 4, t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
306 307 308 309 310 311 312
	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
313
	_, err := dhts[0].Connect(ctx, peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
314 315 316 317
	if err != nil {
		t.Fatalf("Failed to connect: %s", err)
	}

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

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

	time.Sleep(time.Millisecond * 60)

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
366
	_, err := dhts[0].Connect(ctx, peers[1])
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[2])
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
	_, err = dhts[1].Connect(ctx, peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
377 378 379 380
	if err != nil {
		t.Fatal(err)
	}

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

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

	if !p.ID.Equal(peers[2].ID) {
		t.Fatal("Didnt find expected peer.")
	}
}
395 396 397 398

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

399
	runTimes := 10
400

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
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 444 445 446 447 448
		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!")
		}

449 450 451 452 453 454
		dhtA.Halt()
		dhtB.Halt()
		dhtA.network.Close()
		dhtB.network.Close()

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