bitswap_test.go 3.67 KB
Newer Older
Brian Tiger Chow's avatar
Brian Tiger Chow committed
1 2 3
package bitswap

import (
4
	"bytes"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
5 6 7 8 9 10 11 12 13 14
	"testing"
	"time"

	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"
	bstore "github.com/jbenet/go-ipfs/blockstore"
	exchange "github.com/jbenet/go-ipfs/exchange"
	notifications "github.com/jbenet/go-ipfs/exchange/bitswap/notifications"
	strategy "github.com/jbenet/go-ipfs/exchange/bitswap/strategy"
15
	tn "github.com/jbenet/go-ipfs/exchange/bitswap/testnet"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
16 17 18 19 20 21
	peer "github.com/jbenet/go-ipfs/peer"
	testutil "github.com/jbenet/go-ipfs/util/testutil"
)

func TestGetBlockTimeout(t *testing.T) {

22 23 24
	net := tn.VirtualNetwork()
	rs := tn.VirtualRoutingServer()
	g := NewSessionGenerator(net, rs)
25

26
	self := g.Next()
27

Brian Tiger Chow's avatar
Brian Tiger Chow committed
28 29
	ctx, _ := context.WithTimeout(context.Background(), time.Nanosecond)
	block := testutil.NewBlockOrFail(t, "block")
30
	_, err := self.exchange.Block(ctx, block.Key())
Brian Tiger Chow's avatar
Brian Tiger Chow committed
31 32 33 34 35 36 37 38

	if err != context.DeadlineExceeded {
		t.Fatal("Expected DeadlineExceeded error")
	}
}

func TestProviderForKeyButNetworkCannotFind(t *testing.T) {

39 40 41
	net := tn.VirtualNetwork()
	rs := tn.VirtualRoutingServer()
	g := NewSessionGenerator(net, rs)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
42

Brian Tiger Chow's avatar
Brian Tiger Chow committed
43
	block := testutil.NewBlockOrFail(t, "block")
Brian Tiger Chow's avatar
Brian Tiger Chow committed
44 45
	rs.Announce(&peer.Peer{}, block.Key()) // but not on network

46
	solo := g.Next()
Brian Tiger Chow's avatar
Brian Tiger Chow committed
47 48 49 50

	ctx, _ := context.WithTimeout(context.Background(), time.Nanosecond)
	_, err := solo.exchange.Block(ctx, block.Key())

Brian Tiger Chow's avatar
Brian Tiger Chow committed
51 52 53 54 55
	if err != context.DeadlineExceeded {
		t.Fatal("Expected DeadlineExceeded error")
	}
}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
56 57 58 59
// TestGetBlockAfterRequesting...

func TestGetBlockFromPeerAfterPeerAnnounces(t *testing.T) {

60 61
	net := tn.VirtualNetwork()
	rs := tn.VirtualRoutingServer()
Brian Tiger Chow's avatar
Brian Tiger Chow committed
62
	block := testutil.NewBlockOrFail(t, "block")
63
	g := NewSessionGenerator(net, rs)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
64

65
	hasBlock := g.Next()
Brian Tiger Chow's avatar
Brian Tiger Chow committed
66

67 68 69 70 71 72
	if err := hasBlock.blockstore.Put(block); err != nil {
		t.Fatal(err)
	}
	if err := hasBlock.exchange.HasBlock(context.Background(), block); err != nil {
		t.Fatal(err)
	}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
73

74
	wantsBlock := g.Next()
Brian Tiger Chow's avatar
Brian Tiger Chow committed
75 76

	ctx, _ := context.WithTimeout(context.Background(), time.Second)
77
	received, err := wantsBlock.exchange.Block(ctx, block.Key())
Brian Tiger Chow's avatar
Brian Tiger Chow committed
78 79 80 81
	if err != nil {
		t.Log(err)
		t.Fatal("Expected to succeed")
	}
82 83 84 85

	if !bytes.Equal(block.Data, received.Data) {
		t.Fatal("Data doesn't match")
	}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
86 87
}

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
func TestSendToWantingPeer(t *testing.T) {
	t.Log("I get a file from peer |w|. In this message, I receive |w|'s wants")
	t.Log("Peer |w| tells me it wants file |f|, but I don't have it")
	t.Log("Later, peer |o| sends |f| to me")
	t.Log("After receiving |f| from |o|, I send it to the wanting peer |w|")
}

func NewSessionGenerator(
	net tn.Network, rs tn.RoutingServer) SessionGenerator {
	return SessionGenerator{
		net: net,
		rs:  rs,
		seq: 0,
	}
}

type SessionGenerator struct {
	seq int
	net tn.Network
	rs  tn.RoutingServer
}

func (g *SessionGenerator) Next() testnetBitSwap {
	g.seq++
	return session(g.net, g.rs, []byte(string(g.seq)))
}

115
type testnetBitSwap struct {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
116 117 118 119 120
	peer       *peer.Peer
	exchange   exchange.Interface
	blockstore bstore.Blockstore
}

121 122 123 124 125 126
// session creates a test bitswap session.
//
// NB: It's easy make mistakes by providing the same peer ID to two different
// sessions. To safeguard, use the SessionGenerator to generate sessions. It's
// just a much better idea.
func session(net tn.Network, rs tn.RoutingServer, id peer.ID) testnetBitSwap {
127
	p := &peer.Peer{ID: id}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
128 129 130 131 132 133 134 135 136 137 138 139 140

	adapter := net.Adapter(p)
	htc := rs.Client(p)

	blockstore := bstore.NewBlockstore(ds.NewMapDatastore())
	bs := &bitswap{
		blockstore:    blockstore,
		notifications: notifications.New(),
		strategy:      strategy.New(),
		routing:       htc,
		sender:        adapter,
	}
	adapter.SetDelegate(bs)
141
	return testnetBitSwap{
Brian Tiger Chow's avatar
Brian Tiger Chow committed
142 143 144 145 146
		peer:       p,
		exchange:   bs,
		blockstore: blockstore,
	}
}