tests compile

This commit is contained in:
Juan Batiz-Benet 2014-09-17 10:30:38 -07:00 committed by Brian Tiger Chow
parent fdea4d9c5f
commit be2a8df715
2 changed files with 147 additions and 143 deletions

View File

@ -3,11 +3,16 @@ package dht
import ( import (
"testing" "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" 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" ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
ci "github.com/jbenet/go-ipfs/crypto" ci "github.com/jbenet/go-ipfs/crypto"
spipe "github.com/jbenet/go-ipfs/crypto/spipe" spipe "github.com/jbenet/go-ipfs/crypto/spipe"
swarm "github.com/jbenet/go-ipfs/net/swarm" 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" peer "github.com/jbenet/go-ipfs/peer"
u "github.com/jbenet/go-ipfs/util" u "github.com/jbenet/go-ipfs/util"
@ -16,6 +21,30 @@ import (
"time" "time"
) )
func setupDHT(t *testing.T, p *peer.Peer) *IpfsDHT {
ctx := context.TODO()
peerstore := peer.NewPeerstore()
ctx, _ = context.WithCancel(ctx)
dhts := netservice.NewService(nil) // nil handler for now, need to patch it
if err := dhts.Start(ctx); err != nil {
t.Fatal(err)
}
net, err := inet.NewIpfsNetwork(context.TODO(), p, &mux.ProtocolMap{
mux.ProtocolID_Routing: dhts,
})
if err != nil {
t.Fatal(err)
}
d := NewDHT(p, peerstore, net, dhts, ds.NewMapDatastore())
dhts.Handler = d
d.Start()
return d
}
func setupDHTS(n int, t *testing.T) ([]*ma.Multiaddr, []*peer.Peer, []*IpfsDHT) { func setupDHTS(n int, t *testing.T) ([]*ma.Multiaddr, []*peer.Peer, []*IpfsDHT) {
var addrs []*ma.Multiaddr var addrs []*ma.Multiaddr
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
@ -46,14 +75,7 @@ func setupDHTS(n int, t *testing.T) ([]*ma.Multiaddr, []*peer.Peer, []*IpfsDHT)
var dhts []*IpfsDHT var dhts []*IpfsDHT
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
net := swarm.NewSwarm(peers[i]) dhts[i] = setupDHT(t, peers[i])
err := net.Listen()
if err != nil {
t.Fatal(err)
}
d := NewDHT(peers[i], net, ds.NewMapDatastore())
dhts = append(dhts, d)
d.Start()
} }
return addrs, peers, dhts return addrs, peers, dhts
@ -91,19 +113,8 @@ func TestPing(t *testing.T) {
peerA := makePeer(addrA) peerA := makePeer(addrA)
peerB := makePeer(addrB) peerB := makePeer(addrB)
neta := swarm.NewSwarm(peerA) dhtA := setupDHT(t, peerA)
err = neta.Listen() dhtB := setupDHT(t, peerB)
if err != nil {
t.Fatal(err)
}
dhtA := NewDHT(peerA, neta, ds.NewMapDatastore())
netb := swarm.NewSwarm(peerB)
err = netb.Listen()
if err != nil {
t.Fatal(err)
}
dhtB := NewDHT(peerB, netb, ds.NewMapDatastore())
dhtA.Start() dhtA.Start()
dhtB.Start() dhtB.Start()
@ -136,36 +147,14 @@ func TestValueGetSet(t *testing.T) {
peerA := makePeer(addrA) peerA := makePeer(addrA)
peerB := makePeer(addrB) peerB := makePeer(addrB)
neta := swarm.NewSwarm(peerA) dhtA := setupDHT(t, peerA)
err = neta.Listen() dhtB := setupDHT(t, peerB)
if err != nil {
t.Fatal(err)
}
dhtA := NewDHT(peerA, neta, ds.NewMapDatastore())
netb := swarm.NewSwarm(peerB)
err = netb.Listen()
if err != nil {
t.Fatal(err)
}
dhtB := NewDHT(peerB, netb, ds.NewMapDatastore())
dhtA.Start() dhtA.Start()
dhtB.Start() dhtB.Start()
defer dhtA.Halt() defer dhtA.Halt()
defer dhtB.Halt() defer dhtB.Halt()
errsa := dhtA.network.GetErrChan()
errsb := dhtB.network.GetErrChan()
go func() {
select {
case err := <-errsa:
t.Fatal(err)
case err := <-errsb:
t.Fatal(err)
}
}()
_, err = dhtA.Connect(addrB) _, err = dhtA.Connect(addrB)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -5,11 +5,13 @@ import (
crand "crypto/rand" crand "crypto/rand"
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go" 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" ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
swarm "github.com/jbenet/go-ipfs/net/swarm" msg "github.com/jbenet/go-ipfs/net/message"
mux "github.com/jbenet/go-ipfs/net/mux"
peer "github.com/jbenet/go-ipfs/peer" peer "github.com/jbenet/go-ipfs/peer"
u "github.com/jbenet/go-ipfs/util" u "github.com/jbenet/go-ipfs/util"
@ -18,79 +20,84 @@ import (
// fauxNet is a standin for a swarm.Network in order to more easily recreate // fauxNet is a standin for a swarm.Network in order to more easily recreate
// different testing scenarios // different testing scenarios
type fauxNet struct { type fauxSender struct {
Chan *swarm.Chan
handlers []mesHandleFunc handlers []mesHandleFunc
}
swarm.Network func (f *fauxSender) SendRequest(ctx context.Context, m msg.NetMessage) (msg.NetMessage, error) {
for _, h := range f.handlers {
reply := h(m)
if reply != nil {
return reply, nil
}
}
return nil, nil
}
func (f *fauxSender) SendMessage(ctx context.Context, m msg.NetMessage) error {
for _, h := range f.handlers {
reply := h(m)
if reply != nil {
return nil
}
}
return nil
}
// fauxNet is a standin for a swarm.Network in order to more easily recreate
// different testing scenarios
type fauxNet struct {
handlers []mesHandleFunc
} }
// mesHandleFunc is a function that takes in outgoing messages // mesHandleFunc is a function that takes in outgoing messages
// and can respond to them, simulating other peers on the network. // and can respond to them, simulating other peers on the network.
// returning nil will chose not to respond and pass the message onto the // returning nil will chose not to respond and pass the message onto the
// next registered handler // next registered handler
type mesHandleFunc func(*swarm.Message) *swarm.Message type mesHandleFunc func(msg.NetMessage) msg.NetMessage
func newFauxNet() *fauxNet { func (f *fauxNet) AddHandler(fn func(msg.NetMessage) msg.NetMessage) {
fn := new(fauxNet)
fn.Chan = swarm.NewChan(8)
return fn
}
// Instead of 'Listening' Start up a goroutine that will check
// all outgoing messages against registered message handlers,
// and reply if needed
func (f *fauxNet) Listen() error {
go func() {
for {
select {
case in := <-f.Chan.Outgoing:
for _, h := range f.handlers {
reply := h(in)
if reply != nil {
f.Chan.Incoming <- reply
break
}
}
}
}
}()
return nil
}
func (f *fauxNet) AddHandler(fn func(*swarm.Message) *swarm.Message) {
f.handlers = append(f.handlers, fn) f.handlers = append(f.handlers, fn)
} }
func (f *fauxNet) Send(mes *swarm.Message) { // DialPeer attempts to establish a connection to a given peer
f.Chan.Outgoing <- mes func (f *fauxNet) DialPeer(*peer.Peer) error {
return nil
} }
func (f *fauxNet) GetErrChan() chan error { // ClosePeer connection to peer
return f.Chan.Errors func (f *fauxNet) ClosePeer(*peer.Peer) error {
return nil
} }
func (f *fauxNet) GetChannel(t swarm.PBWrapper_MessageType) *swarm.Chan { // IsConnected returns whether a connection to given peer exists.
return f.Chan func (f *fauxNet) IsConnected(*peer.Peer) (bool, error) {
return true, nil
} }
func (f *fauxNet) Connect(addr *ma.Multiaddr) (*peer.Peer, error) { // GetProtocols returns the protocols registered in the network.
return nil, nil func (f *fauxNet) GetProtocols() *mux.ProtocolMap { return nil }
// SendMessage sends given Message out
func (f *fauxNet) SendMessage(msg.NetMessage) error {
return nil
} }
func (f *fauxNet) GetConnection(id peer.ID, addr *ma.Multiaddr) (*peer.Peer, error) { // Close terminates all network operation
return &peer.Peer{ID: id, Addresses: []*ma.Multiaddr{addr}}, nil func (f *fauxNet) Close() error { return nil }
}
func TestGetFailures(t *testing.T) { func TestGetFailures(t *testing.T) {
fn := newFauxNet() ctx := context.Background()
fn.Listen() fn := &fauxNet{}
fs := &fauxSender{}
peerstore := peer.NewPeerstore()
local := new(peer.Peer) local := new(peer.Peer)
local.ID = peer.ID("test_peer") local.ID = peer.ID("test_peer")
d := NewDHT(local, fn, ds.NewMapDatastore()) d := NewDHT(local, peerstore, fn, fs, ds.NewMapDatastore())
other := &peer.Peer{ID: peer.ID("other_peer")} other := &peer.Peer{ID: peer.ID("other_peer")}
@ -109,20 +116,18 @@ func TestGetFailures(t *testing.T) {
} }
// Reply with failures to every message // Reply with failures to every message
fn.AddHandler(func(mes *swarm.Message) *swarm.Message { fn.AddHandler(func(mes msg.NetMessage) msg.NetMessage {
pmes := new(PBDHTMessage) pmes := new(Message)
err := proto.Unmarshal(mes.Data, pmes) err := proto.Unmarshal(mes.Data(), pmes)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
resp := Message{ resp := &Message{
Type: pmes.GetType(), Type: pmes.Type,
ID: pmes.GetId(),
Response: true,
Success: false,
} }
return swarm.NewMessage(mes.Peer, resp.ToProtobuf()) m, err := msg.FromObject(mes.Peer(), resp)
return m
}) })
// This one should fail with NotFound // This one should fail with NotFound
@ -137,27 +142,34 @@ func TestGetFailures(t *testing.T) {
success := make(chan struct{}) success := make(chan struct{})
fn.handlers = nil fn.handlers = nil
fn.AddHandler(func(mes *swarm.Message) *swarm.Message { fn.AddHandler(func(mes msg.NetMessage) msg.NetMessage {
resp := new(PBDHTMessage) resp := new(Message)
err := proto.Unmarshal(mes.Data, resp) err := proto.Unmarshal(mes.Data(), resp)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if resp.GetSuccess() {
t.Fatal("Get returned success when it shouldnt have.")
}
success <- struct{}{} success <- struct{}{}
return nil return nil
}) })
// Now we test this DHT's handleGetValue failure // Now we test this DHT's handleGetValue failure
typ := Message_GET_VALUE
str := "hello"
req := Message{ req := Message{
Type: PBDHTMessage_GET_VALUE, Type: &typ,
Key: "hello", Key: &str,
ID: swarm.GenerateMessageID(),
Value: []byte{0}, Value: []byte{0},
} }
fn.Chan.Incoming <- swarm.NewMessage(other, req.ToProtobuf())
mes, err := msg.FromObject(other, &req)
if err != nil {
t.Error(err)
}
mes, err = fs.SendRequest(ctx, mes)
if err != nil {
t.Error(err)
}
<-success <-success
} }
@ -172,13 +184,14 @@ func _randPeer() *peer.Peer {
} }
func TestNotFound(t *testing.T) { func TestNotFound(t *testing.T) {
fn := newFauxNet() fn := &fauxNet{}
fn.Listen() fs := &fauxSender{}
local := new(peer.Peer) local := new(peer.Peer)
local.ID = peer.ID("test_peer") local.ID = peer.ID("test_peer")
peerstore := peer.NewPeerstore()
d := NewDHT(local, fn, ds.NewMapDatastore()) d := NewDHT(local, peerstore, fn, fs, ds.NewMapDatastore())
d.Start() d.Start()
var ps []*peer.Peer var ps []*peer.Peer
@ -188,26 +201,27 @@ func TestNotFound(t *testing.T) {
} }
// Reply with random peers to every message // Reply with random peers to every message
fn.AddHandler(func(mes *swarm.Message) *swarm.Message { fn.AddHandler(func(mes msg.NetMessage) msg.NetMessage {
pmes := new(PBDHTMessage) pmes := new(Message)
err := proto.Unmarshal(mes.Data, pmes) err := proto.Unmarshal(mes.Data(), pmes)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
switch pmes.GetType() { switch pmes.GetType() {
case PBDHTMessage_GET_VALUE: case Message_GET_VALUE:
resp := Message{ resp := &Message{Type: pmes.Type}
Type: pmes.GetType(),
ID: pmes.GetId(),
Response: true,
Success: false,
}
peers := []*peer.Peer{}
for i := 0; i < 7; i++ { for i := 0; i < 7; i++ {
resp.Peers = append(resp.Peers, _randPeer()) peers = append(peers, _randPeer())
} }
return swarm.NewMessage(mes.Peer, resp.ToProtobuf()) resp.CloserPeers = peersToPBPeers(peers)
mes, err := msg.FromObject(mes.Peer(), resp)
if err != nil {
t.Error(err)
}
return mes
default: default:
panic("Shouldnt recieve this.") panic("Shouldnt recieve this.")
} }
@ -233,13 +247,13 @@ func TestNotFound(t *testing.T) {
// a GET rpc and nobody has the value // a GET rpc and nobody has the value
func TestLessThanKResponses(t *testing.T) { func TestLessThanKResponses(t *testing.T) {
u.Debug = false u.Debug = false
fn := newFauxNet() fn := &fauxNet{}
fn.Listen() fs := &fauxSender{}
peerstore := peer.NewPeerstore()
local := new(peer.Peer) local := new(peer.Peer)
local.ID = peer.ID("test_peer") local.ID = peer.ID("test_peer")
d := NewDHT(local, fn, ds.NewMapDatastore()) d := NewDHT(local, peerstore, fn, fs, ds.NewMapDatastore())
d.Start() d.Start()
var ps []*peer.Peer var ps []*peer.Peer
@ -250,24 +264,25 @@ func TestLessThanKResponses(t *testing.T) {
other := _randPeer() other := _randPeer()
// Reply with random peers to every message // Reply with random peers to every message
fn.AddHandler(func(mes *swarm.Message) *swarm.Message { fn.AddHandler(func(mes msg.NetMessage) msg.NetMessage {
pmes := new(PBDHTMessage) pmes := new(Message)
err := proto.Unmarshal(mes.Data, pmes) err := proto.Unmarshal(mes.Data(), pmes)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
switch pmes.GetType() { switch pmes.GetType() {
case PBDHTMessage_GET_VALUE: case Message_GET_VALUE:
resp := Message{ resp := &Message{
Type: pmes.GetType(), Type: pmes.Type,
ID: pmes.GetId(), CloserPeers: peersToPBPeers([]*peer.Peer{other}),
Response: true,
Success: false,
Peers: []*peer.Peer{other},
} }
return swarm.NewMessage(mes.Peer, resp.ToProtobuf()) mes, err := msg.FromObject(mes.Peer(), resp)
if err != nil {
t.Error(err)
}
return mes
default: default:
panic("Shouldnt recieve this.") panic("Shouldnt recieve this.")
} }