dht_test.go 5.5 KB
Newer Older
1 2 3 4
package dht

import (
	"testing"
5

6 7
	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"
8
	ci "github.com/jbenet/go-ipfs/crypto"
9
	identify "github.com/jbenet/go-ipfs/identify"
10
	peer "github.com/jbenet/go-ipfs/peer"
Jeromy's avatar
Jeromy committed
11
	swarm "github.com/jbenet/go-ipfs/swarm"
12 13
	u "github.com/jbenet/go-ipfs/util"

Siraj Ravel's avatar
Siraj Ravel committed
14
	"bytes"
15
	"fmt"
16
	"time"
17 18
)

19 20 21 22 23 24 25 26 27 28 29 30 31 32
func setupDHTS(n int, t *testing.T) ([]*ma.Multiaddr, []*peer.Peer, []*IpfsDHT) {
	var addrs []*ma.Multiaddr
	for i := 0; i < 4; i++ {
		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
	for i := 0; i < 4; i++ {
		p := new(peer.Peer)
		p.AddAddress(addrs[i])
33
		sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512)
34 35 36
		if err != nil {
			panic(err)
		}
37 38
		p.PubKey = pk
		p.PrivKey = sk
Siraj Ravel's avatar
Siraj Ravel committed
39
		id, err := identify.IDFromPubKey(pk)
40 41 42 43
		if err != nil {
			panic(err)
		}
		p.ID = id
44 45 46 47 48
		peers = append(peers, p)
	}

	var dhts []*IpfsDHT
	for i := 0; i < 4; i++ {
Jeromy's avatar
Jeromy committed
49 50
		net := swarm.NewSwarm(peers[i])
		err := net.Listen()
51 52 53
		if err != nil {
			t.Fatal(err)
		}
Jeromy's avatar
Jeromy committed
54
		d := NewDHT(peers[i], net, ds.NewMapDatastore())
55 56 57 58 59 60 61
		dhts = append(dhts, d)
		d.Start()
	}

	return addrs, peers, dhts
}

62 63 64
func makePeer(addr *ma.Multiaddr) *peer.Peer {
	p := new(peer.Peer)
	p.AddAddress(addr)
65
	sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512)
66 67 68
	if err != nil {
		panic(err)
	}
69 70
	p.PrivKey = sk
	p.PubKey = pk
Siraj Ravel's avatar
Siraj Ravel committed
71
	id, err := identify.IDFromPubKey(pk)
72 73 74 75 76 77 78 79
	if err != nil {
		panic(err)
	}

	p.ID = id
	return p
}

80
func TestPing(t *testing.T) {
81
	u.Debug = true
82
	addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/2222")
83 84 85
	if err != nil {
		t.Fatal(err)
	}
86
	addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5678")
87 88 89 90
	if err != nil {
		t.Fatal(err)
	}

91 92
	peerA := makePeer(addrA)
	peerB := makePeer(addrB)
93

94
	neta := swarm.NewSwarm(peerA)
Jeromy's avatar
Jeromy committed
95
	err = neta.Listen()
96 97 98
	if err != nil {
		t.Fatal(err)
	}
Jeromy's avatar
Jeromy committed
99
	dhtA := NewDHT(peerA, neta, ds.NewMapDatastore())
100

101
	netb := swarm.NewSwarm(peerB)
Jeromy's avatar
Jeromy committed
102
	err = netb.Listen()
103 104 105
	if err != nil {
		t.Fatal(err)
	}
Jeromy's avatar
Jeromy committed
106
	dhtB := NewDHT(peerB, netb, ds.NewMapDatastore())
107

108 109
	dhtA.Start()
	dhtB.Start()
110

111
	_, err = dhtA.Connect(addrB)
112 113 114 115 116
	if err != nil {
		t.Fatal(err)
	}

	//Test that we can ping the node
117
	err = dhtA.Ping(peerB, time.Second*2)
118 119 120
	if err != nil {
		t.Fatal(err)
	}
121

122 123
	dhtA.Halt()
	dhtB.Halt()
124 125 126 127
}

func TestValueGetSet(t *testing.T) {
	u.Debug = false
128
	addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/1235")
129 130 131
	if err != nil {
		t.Fatal(err)
	}
132
	addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5679")
133 134 135 136
	if err != nil {
		t.Fatal(err)
	}

137 138
	peerA := makePeer(addrA)
	peerB := makePeer(addrB)
139

140
	neta := swarm.NewSwarm(peerA)
Jeromy's avatar
Jeromy committed
141
	err = neta.Listen()
142 143 144
	if err != nil {
		t.Fatal(err)
	}
Jeromy's avatar
Jeromy committed
145
	dhtA := NewDHT(peerA, neta, ds.NewMapDatastore())
146

147
	netb := swarm.NewSwarm(peerB)
Jeromy's avatar
Jeromy committed
148
	err = netb.Listen()
149 150 151
	if err != nil {
		t.Fatal(err)
	}
Jeromy's avatar
Jeromy committed
152
	dhtB := NewDHT(peerB, netb, ds.NewMapDatastore())
153

154 155
	dhtA.Start()
	dhtB.Start()
156

157 158
	errsa := dhtA.network.GetErrChan()
	errsb := dhtB.network.GetErrChan()
Jeromy's avatar
Jeromy committed
159 160
	go func() {
		select {
161
		case err := <-errsa:
Jeromy's avatar
Jeromy committed
162
			t.Fatal(err)
163
		case err := <-errsb:
Jeromy's avatar
Jeromy committed
164 165 166 167
			t.Fatal(err)
		}
	}()

168
	_, err = dhtA.Connect(addrB)
169 170 171 172
	if err != nil {
		t.Fatal(err)
	}

173
	dhtA.PutValue("hello", []byte("world"))
174

175
	val, err := dhtA.GetValue("hello", time.Second*2)
176 177 178 179 180
	if err != nil {
		t.Fatal(err)
	}

	if string(val) != "world" {
Jeromy's avatar
Jeromy committed
181
		t.Fatalf("Expected 'world' got '%s'", string(val))
182
	}
Siraj Ravel's avatar
Siraj Ravel committed
183

184
}
185 186 187

func TestProvides(t *testing.T) {
	u.Debug = false
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205

	addrs, _, dhts := setupDHTS(4, t)

	_, err := dhts[0].Connect(addrs[1])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(addrs[2])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(addrs[3])
	if err != nil {
		t.Fatal(err)
	}

Chas Leichner's avatar
Chas Leichner committed
206
	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
207 208 209 210
	if err != nil {
		t.Fatal(err)
	}

Siraj Ravel's avatar
Siraj Ravel committed
211 212
	bits, err := dhts[3].getLocal(u.Key("hello"))
	if err != nil && bytes.Equal(bits, []byte("world")) {
Siraj Ravel's avatar
Siraj Ravel committed
213 214 215
		t.Fatal(err)
	}

216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
	err = dhts[3].Provide(u.Key("hello"))
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

	provs, err := dhts[0].FindProviders(u.Key("hello"), time.Second)
	if err != nil {
		t.Fatal(err)
	}

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

	for i := 0; i < 4; i++ {
		dhts[i].Halt()
	}
}

func TestLayeredGet(t *testing.T) {
	u.Debug = false
239
	addrs, _, dhts := setupDHTS(4, t)
240 241 242

	_, err := dhts[0].Connect(addrs[1])
	if err != nil {
243
		t.Fatalf("Failed to connect: %s", err)
244 245 246 247 248 249 250 251 252 253 254 255
	}

	_, err = dhts[1].Connect(addrs[2])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(addrs[3])
	if err != nil {
		t.Fatal(err)
	}

Chas Leichner's avatar
Chas Leichner committed
256
	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
257 258 259 260 261 262 263 264 265 266 267
	if err != nil {
		t.Fatal(err)
	}

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

	time.Sleep(time.Millisecond * 60)

268
	val, err := dhts[0].GetValue(u.Key("hello"), time.Second)
269 270 271 272
	if err != nil {
		t.Fatal(err)
	}

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

277 278 279 280
	for i := 0; i < 4; i++ {
		dhts[i].Halt()
	}
}
Jeromy's avatar
Jeromy committed
281

282
func TestFindPeer(t *testing.T) {
Jeromy's avatar
Jeromy committed
283 284
	u.Debug = false

285
	addrs, peers, dhts := setupDHTS(4, t)
Jeromy's avatar
Jeromy committed
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301

	_, err := dhts[0].Connect(addrs[1])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(addrs[2])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(addrs[3])
	if err != nil {
		t.Fatal(err)
	}

302
	p, err := dhts[0].FindPeer(peers[2].ID, time.Second)
Jeromy's avatar
Jeromy committed
303 304 305 306
	if err != nil {
		t.Fatal(err)
	}

307 308
	if p == nil {
		t.Fatal("Failed to find peer.")
Jeromy's avatar
Jeromy committed
309 310
	}

311 312
	if !p.ID.Equal(peers[2].ID) {
		t.Fatal("Didnt find expected peer.")
Jeromy's avatar
Jeromy committed
313 314 315 316 317 318
	}

	for i := 0; i < 4; i++ {
		dhts[i].Halt()
	}
}