go-libp2p-kad-dht/ext_test.go

280 lines
6.2 KiB
Go
Raw Normal View History

2014-08-10 21:40:17 -07:00
package dht
import (
2014-12-16 14:35:52 -08:00
"math/rand"
2014-08-10 21:40:17 -07:00
"testing"
2014-08-19 19:14:52 -07:00
crand "crypto/rand"
2014-11-10 14:22:56 -08:00
2014-11-20 18:45:05 -08:00
inet "github.com/jbenet/go-ipfs/net"
2014-12-16 14:35:52 -08:00
mocknet "github.com/jbenet/go-ipfs/net/mock"
2014-08-10 21:40:17 -07:00
peer "github.com/jbenet/go-ipfs/peer"
routing "github.com/jbenet/go-ipfs/routing"
pb "github.com/jbenet/go-ipfs/routing/dht/pb"
u "github.com/jbenet/go-ipfs/util"
testutil "github.com/jbenet/go-ipfs/util/testutil"
2014-08-10 21:40:17 -07:00
2014-12-16 14:53:02 -08:00
ggio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/io"
2014-12-16 14:35:52 -08:00
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/go-datastore"
2014-08-10 21:40:17 -07:00
"time"
)
func TestGetFailures(t *testing.T) {
if testing.Short() {
t.SkipNow()
}
2014-09-19 18:11:05 -07:00
2014-12-16 14:35:52 -08:00
ctx := context.Background()
2014-09-17 10:30:38 -07:00
peerstore := peer.NewPeerstore()
local := makePeerString(t, "")
2014-12-16 14:35:52 -08:00
peers := []peer.Peer{local, testutil.RandPeer()}
2014-08-10 21:40:17 -07:00
2014-12-16 14:35:52 -08:00
nets, err := mocknet.MakeNetworks(ctx, peers)
if err != nil {
t.Fatal(err)
}
2014-11-20 18:45:05 -08:00
2014-12-16 14:35:52 -08:00
d := NewDHT(ctx, peers[0], peerstore, nets[0], ds.NewMapDatastore())
d.Update(ctx, peers[1])
// This one should time out
2014-09-18 19:30:04 -07:00
// u.POut("Timout Test\n")
ctx1, _ := context.WithTimeout(context.Background(), time.Second)
2014-12-16 14:35:52 -08:00
if _, err := d.GetValue(ctx1, u.Key("test")); err != nil {
2014-09-18 19:30:04 -07:00
if err != context.DeadlineExceeded {
t.Fatal("Got different error than we expected", err)
}
} else {
t.Fatal("Did not get expected error!")
2014-08-10 21:40:17 -07:00
}
2014-12-16 14:35:52 -08:00
msgs := make(chan *pb.Message, 100)
2014-09-18 19:30:04 -07:00
// u.POut("NotFound Test\n")
// Reply with failures to every message
2014-12-16 14:35:52 -08:00
nets[1].SetHandler(inet.ProtocolDHT, func(s inet.Stream) {
defer s.Close()
pbr := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
pbw := ggio.NewDelimitedWriter(s)
pmes := new(pb.Message)
2014-12-16 14:35:52 -08:00
if err := pbr.ReadMsg(pmes); err != nil {
panic(err)
}
resp := &pb.Message{
2014-09-17 10:30:38 -07:00
Type: pmes.Type,
}
2014-12-16 14:35:52 -08:00
if err := pbw.WriteMsg(resp); err != nil {
panic(err)
}
msgs <- resp
})
// This one should fail with NotFound
ctx2, _ := context.WithTimeout(context.Background(), time.Second)
_, err = d.GetValue(ctx2, u.Key("test"))
if err != nil {
if err != routing.ErrNotFound {
t.Fatalf("Expected ErrNotFound, got: %s", err)
}
} else {
t.Fatal("expected error, got none.")
}
// Now we test this DHT's handleGetValue failure
2014-12-16 14:35:52 -08:00
{
typ := pb.Message_GET_VALUE
str := "hello"
rec, err := d.makePutRecord(u.Key(str), []byte("blah"))
if err != nil {
t.Fatal(err)
}
req := pb.Message{
Type: &typ,
Key: &str,
Record: rec,
}
2014-09-17 10:30:38 -07:00
2014-12-16 14:35:52 -08:00
// u.POut("handleGetValue Test\n")
s, err := nets[1].NewStream(inet.ProtocolDHT, peers[0])
if err != nil {
t.Fatal(err)
}
defer s.Close()
2014-09-17 10:30:38 -07:00
2014-12-16 14:35:52 -08:00
pbr := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
pbw := ggio.NewDelimitedWriter(s)
2014-12-16 14:35:52 -08:00
if err := pbw.WriteMsg(&req); err != nil {
t.Fatal(err)
}
2014-09-18 19:30:04 -07:00
2014-12-16 14:35:52 -08:00
pmes := new(pb.Message)
if err := pbr.ReadMsg(pmes); err != nil {
t.Fatal(err)
}
if pmes.GetRecord() != nil {
t.Fatal("shouldnt have value")
}
if pmes.GetProviderPeers() != nil {
t.Fatal("shouldnt have provider peers")
}
}
2014-08-10 21:40:17 -07:00
}
2014-08-19 19:14:52 -07:00
// TODO: Maybe put these in some sort of "ipfs_testutil" package
func _randPeer() peer.Peer {
id := make(peer.ID, 16)
crand.Read(id)
p := testutil.NewPeerWithID(id)
2014-08-19 19:14:52 -07:00
return p
}
func TestNotFound(t *testing.T) {
if testing.Short() {
t.SkipNow()
}
2014-09-19 18:11:05 -07:00
2014-12-16 14:35:52 -08:00
ctx := context.Background()
2014-09-17 10:30:38 -07:00
peerstore := peer.NewPeerstore()
2014-08-19 19:14:52 -07:00
2014-12-16 14:35:52 -08:00
var peers []peer.Peer
for i := 0; i < 16; i++ {
peers = append(peers, testutil.RandPeer())
}
2014-11-20 18:45:05 -08:00
2014-12-16 14:35:52 -08:00
nets, err := mocknet.MakeNetworks(ctx, peers)
if err != nil {
t.Fatal(err)
}
d := NewDHT(ctx, peers[0], peerstore, nets[0], ds.NewMapDatastore())
2014-08-19 19:14:52 -07:00
2014-12-16 14:35:52 -08:00
for _, p := range peers {
d.Update(ctx, p)
2014-08-19 19:14:52 -07:00
}
// Reply with random peers to every message
2014-12-16 14:35:52 -08:00
for _, neti := range nets {
neti.SetHandler(inet.ProtocolDHT, func(s inet.Stream) {
defer s.Close()
2014-08-19 19:14:52 -07:00
2014-12-16 14:35:52 -08:00
pbr := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
pbw := ggio.NewDelimitedWriter(s)
2014-08-19 19:14:52 -07:00
2014-12-16 14:35:52 -08:00
pmes := new(pb.Message)
if err := pbr.ReadMsg(pmes); err != nil {
panic(err)
2014-08-19 19:14:52 -07:00
}
2014-12-16 14:35:52 -08:00
switch pmes.GetType() {
case pb.Message_GET_VALUE:
resp := &pb.Message{Type: pmes.Type}
ps := []peer.Peer{}
for i := 0; i < 7; i++ {
ps = append(ps, peers[rand.Intn(len(peers))])
}
resp.CloserPeers = pb.PeersToPBPeers(d.network, peers)
if err := pbw.WriteMsg(resp); err != nil {
panic(err)
}
default:
panic("Shouldnt recieve this.")
}
})
}
2014-08-19 19:14:52 -07:00
2014-10-18 04:19:12 -07:00
ctx, _ = context.WithTimeout(ctx, time.Second*5)
v, err := d.GetValue(ctx, u.Key("hello"))
2014-10-30 06:35:29 -07:00
log.Debugf("get value got %v", v)
2014-08-19 19:14:52 -07:00
if err != nil {
switch err {
case routing.ErrNotFound:
2014-08-19 19:14:52 -07:00
//Success!
return
case u.ErrTimeout:
t.Fatal("Should not have gotten timeout!")
default:
t.Fatalf("Got unexpected error: %s", err)
}
}
t.Fatal("Expected to recieve an error.")
}
// If less than K nodes are in the entire network, it should fail when we make
// a GET rpc and nobody has the value
func TestLessThanKResponses(t *testing.T) {
2014-09-19 18:11:05 -07:00
// t.Skip("skipping test because it makes a lot of output")
2014-12-16 14:35:52 -08:00
ctx := context.Background()
2014-09-17 10:30:38 -07:00
peerstore := peer.NewPeerstore()
2014-12-16 14:35:52 -08:00
var peers []peer.Peer
for i := 0; i < 6; i++ {
peers = append(peers, testutil.RandPeer())
}
nets, err := mocknet.MakeNetworks(ctx, peers)
if err != nil {
t.Fatal(err)
}
2014-11-20 18:45:05 -08:00
2014-12-16 14:35:52 -08:00
d := NewDHT(ctx, peers[0], peerstore, nets[0], ds.NewMapDatastore())
2014-12-16 14:35:52 -08:00
for i := 1; i < 5; i++ {
d.Update(ctx, peers[i])
}
// Reply with random peers to every message
2014-12-16 14:35:52 -08:00
for _, neti := range nets {
neti.SetHandler(inet.ProtocolDHT, func(s inet.Stream) {
defer s.Close()
pbr := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
pbw := ggio.NewDelimitedWriter(s)
2014-12-16 14:35:52 -08:00
pmes := new(pb.Message)
if err := pbr.ReadMsg(pmes); err != nil {
panic(err)
}
2014-12-16 14:35:52 -08:00
switch pmes.GetType() {
case pb.Message_GET_VALUE:
resp := &pb.Message{
Type: pmes.Type,
CloserPeers: pb.PeersToPBPeers(d.network, []peer.Peer{peers[1]}),
}
if err := pbw.WriteMsg(resp); err != nil {
panic(err)
}
default:
panic("Shouldnt recieve this.")
2014-09-17 10:30:38 -07:00
}
2014-12-16 14:35:52 -08:00
})
}
2014-10-18 04:19:12 -07:00
ctx, _ = context.WithTimeout(ctx, time.Second*30)
2014-12-16 14:35:52 -08:00
if _, err := d.GetValue(ctx, u.Key("hello")); err != nil {
switch err {
case routing.ErrNotFound:
//Success!
return
case u.ErrTimeout:
t.Fatal("Should not have gotten timeout!")
default:
t.Fatalf("Got unexpected error: %s", err)
}
}
t.Fatal("Expected to recieve an error.")
}