dht_test.go 7.86 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 23 24
	"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"
	spipe "github.com/jbenet/go-ipfs/crypto/spipe"
	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"
)

func setupDHT(t *testing.T, p *peer.Peer) *IpfsDHT {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
25
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
26 27 28 29 30 31 32 33

	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
34
	net, err := inet.NewIpfsNetwork(ctx, p, peerstore, &mux.ProtocolMap{
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
35 36 37 38 39 40 41 42 43 44 45 46 47
		mux.ProtocolID_Routing: dhts,
	})
	if err != nil {
		t.Fatal(err)
	}

	d := NewDHT(p, peerstore, net, dhts, ds.NewMapDatastore())
	dhts.Handler = d
	return d
}

func setupDHTS(n int, t *testing.T) ([]*ma.Multiaddr, []*peer.Peer, []*IpfsDHT) {
	var addrs []*ma.Multiaddr
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
48
	for i := 0; i < n; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
49 50 51 52 53 54 55 56
		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
57
	for i := 0; i < n; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
58 59 60 61
		p := makePeer(addrs[i])
		peers = append(peers, p)
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
62 63
	dhts := make([]*IpfsDHT, n)
	for i := 0; i < n; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
		dhts[i] = setupDHT(t, peers[i])
	}

	return addrs, peers, dhts
}

func makePeer(addr *ma.Multiaddr) *peer.Peer {
	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
	id, err := spipe.IDFromPubKey(pk)
	if err != nil {
		panic(err)
	}

	p.ID = id
	return p
}

func TestPing(t *testing.T) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
89 90 91
	// t.Skip("skipping test to debug another")

	u.Debug = false
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
	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)

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

	defer dhtA.Halt()
	defer dhtB.Halt()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
109 110
	defer dhtA.network.Close()
	defer dhtB.network.Close()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
111

112
	_, err = dhtA.Connect(context.Background(), peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
113 114 115 116 117
	if err != nil {
		t.Fatal(err)
	}

	//Test that we can ping the node
118
	ctx, _ := context.WithTimeout(context.Background(), 5*time.Millisecond)
119
	err = dhtA.Ping(ctx, peerB)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
120 121 122
	if err != nil {
		t.Fatal(err)
	}
123 124 125 126 127 128

	ctx, _ = context.WithTimeout(context.Background(), 5*time.Millisecond)
	err = dhtB.Ping(ctx, peerA)
	if err != nil {
		t.Fatal(err)
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
129 130 131
}

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

	u.Debug = false
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
	addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/1235")
	if err != nil {
		t.Fatal(err)
	}
	addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5679")
	if err != nil {
		t.Fatal(err)
	}

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

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

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

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
163 164
	ctxT, _ = context.WithTimeout(context.Background(), time.Second*2)
	val, err := dhtA.GetValue(ctxT, "hello")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
165 166 167 168 169 170 171 172
	if err != nil {
		t.Fatal(err)
	}

	if string(val) != "world" {
		t.Fatalf("Expected 'world' got '%s'", string(val))
	}

173 174 175 176 177 178 179 180 181
	ctxT, _ = context.WithTimeout(context.Background(), time.Second*2)
	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
182 183
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
184 185 186 187 188 189 190 191 192 193 194 195 196
func TestProvides(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false

	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

197
	_, err := dhts[0].Connect(context.Background(), peers[1])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
198 199 200 201
	if err != nil {
		t.Fatal(err)
	}

202
	_, err = dhts[1].Connect(context.Background(), peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
203 204 205 206
	if err != nil {
		t.Fatal(err)
	}

207
	_, err = dhts[1].Connect(context.Background(), peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
208 209 210 211 212 213 214 215 216 217 218 219 220 221
	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)
	}

222
	err = dhts[3].Provide(context.Background(), u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
223 224 225 226 227 228
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
229 230
	ctxT, _ := context.WithTimeout(context.Background(), time.Second)
	provs, err := dhts[0].FindProviders(ctxT, u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
231 232 233 234 235 236 237 238 239
	if err != nil {
		t.Fatal(err)
	}

	if len(provs) != 1 {
		t.Fatal("Didnt get back providers")
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
240 241 242 243 244 245 246 247 248 249 250 251 252
func TestProvidesAsync(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false

	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

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

258
	_, err = dhts[1].Connect(context.Background(), peers[2])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
259 260 261 262
	if err != nil {
		t.Fatal(err)
	}

263
	_, err = dhts[1].Connect(context.Background(), peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
264 265 266 267 268 269 270 271 272 273 274 275 276 277
	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)
	}

278
	err = dhts[3].Provide(context.Background(), u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

	ctx, _ := context.WithTimeout(context.TODO(), time.Millisecond*300)
	provs := dhts[0].FindProvidersAsync(ctx, u.Key("hello"), 5)
	select {
	case p := <-provs:
		if !p.ID.Equal(dhts[3].self.ID) {
			t.Fatalf("got a provider, but not the right one. %v", p.ID.Pretty())
		}
	case <-ctx.Done():
		t.Fatal("Didnt get back providers")
	}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
297 298 299 300 301 302 303 304 305 306 307 308
func TestLayeredGet(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false
	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

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

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

319
	_, err = dhts[1].Connect(context.Background(), peers[3])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
320 321 322 323 324 325 326 327 328
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
	if err != nil {
		t.Fatal(err)
	}

329
	err = dhts[3].Provide(context.Background(), u.Key("hello"))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
330 331 332 333 334 335
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

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

	u.Debug = false

	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			dhts[i].network.Close()
		}
	}()

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

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

371
	_, err = dhts[1].Connect(context.Background(), 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 377
	ctxT, _ := context.WithTimeout(context.Background(), time.Second)
	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 386 387 388 389
	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.")
	}
}