testinstance.go 3.92 KB
Newer Older
1
package testsession
2 3

import (
4
	"context"
5 6
	"time"

7 8 9 10 11 12 13 14 15 16 17
	bitswap "gitlab.dms3.io/dms3/go-bitswap"
	bsnet "gitlab.dms3.io/dms3/go-bitswap/network"
	tn "gitlab.dms3.io/dms3/go-bitswap/testnet"
	ds "gitlab.dms3.io/dms3/go-datastore"
	delayed "gitlab.dms3.io/dms3/go-datastore/delayed"
	ds_sync "gitlab.dms3.io/dms3/go-datastore/sync"
	blockstore "gitlab.dms3.io/dms3/go-dms3-blockstore"
	delay "gitlab.dms3.io/dms3/go-dms3-delay"
	peer "gitlab.dms3.io/p2p/go-p2p-core/peer"
	p2ptestutil "gitlab.dms3.io/p2p/go-p2p-netutil"
	tnet "gitlab.dms3.io/p2p/go-p2p-testing/net"
18 19
)

20
// NewTestInstanceGenerator generates a new InstanceGenerator for the given
21
// testnet
22
func NewTestInstanceGenerator(net tn.Network, netOptions []bsnet.NetOpt, bsOptions []bitswap.Option) InstanceGenerator {
23
	ctx, cancel := context.WithCancel(context.Background())
24
	return InstanceGenerator{
25 26 27 28 29 30
		net:        net,
		seq:        0,
		ctx:        ctx, // TODO take ctx as param to Next, Instances
		cancel:     cancel,
		bsOptions:  bsOptions,
		netOptions: netOptions,
31 32 33
	}
}

34 35
// InstanceGenerator generates new test instances of bitswap+dependencies
type InstanceGenerator struct {
36 37 38 39 40 41
	seq        int
	net        tn.Network
	ctx        context.Context
	cancel     context.CancelFunc
	bsOptions  []bitswap.Option
	netOptions []bsnet.NetOpt
42 43
}

44
// Close closes the clobal context, shutting down all test instances
45
func (g *InstanceGenerator) Close() error {
46
	g.cancel()
47
	return nil // for Closer interface
48 49
}

50
// Next generates a new instance of bitswap + dependencies
51
func (g *InstanceGenerator) Next() Instance {
52
	g.seq++
53
	p, err := p2ptestutil.RandTestBogusIdentity()
Brian Tiger Chow's avatar
Brian Tiger Chow committed
54 55 56
	if err != nil {
		panic("FIXME") // TODO change signature
	}
57
	return NewInstance(g.ctx, g.net, p, g.netOptions, g.bsOptions)
58 59
}

dirkmc's avatar
dirkmc committed
60 61
// Instances creates N test instances of bitswap + dependencies and connects
// them to each other
62
func (g *InstanceGenerator) Instances(n int) []Instance {
rht's avatar
rht committed
63
	var instances []Instance
64 65 66 67
	for j := 0; j < n; j++ {
		inst := g.Next()
		instances = append(instances, inst)
	}
68 69 70 71 72 73
	ConnectInstances(instances)
	return instances
}

// ConnectInstances connects the given instances to each other
func ConnectInstances(instances []Instance) {
74 75 76
	for i, inst := range instances {
		for j := i + 1; j < len(instances); j++ {
			oinst := instances[j]
Steven Allen's avatar
Steven Allen committed
77 78 79 80
			err := inst.Adapter.ConnectTo(context.Background(), oinst.Peer)
			if err != nil {
				panic(err.Error())
			}
81 82
		}
	}
83 84
}

85
// Instance is a test instance of bitswap + dependencies for integration testing
86
type Instance struct {
87 88 89 90
	Peer            peer.ID
	Exchange        *bitswap.Bitswap
	blockstore      blockstore.Blockstore
	Adapter         bsnet.BitSwapNetwork
91 92 93
	blockstoreDelay delay.D
}

94
// Blockstore returns the block store for this test instance
95 96 97 98
func (i *Instance) Blockstore() blockstore.Blockstore {
	return i.blockstore
}

99 100
// SetBlockstoreLatency customizes the artificial delay on receiving blocks
// from a blockstore test instance.
101 102
func (i *Instance) SetBlockstoreLatency(t time.Duration) time.Duration {
	return i.blockstoreDelay.Set(t)
103 104
}

105
// NewInstance creates a test bitswap instance.
106 107
//
// NB: It's easy make mistakes by providing the same peer ID to two different
108
// instances. To safeguard, use the InstanceGenerator to generate instances. It's
109
// just a much better idea.
110
func NewInstance(ctx context.Context, net tn.Network, p tnet.Identity, netOptions []bsnet.NetOpt, bsOptions []bitswap.Option) Instance {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
111
	bsdelay := delay.Fixed(0)
112

113
	adapter := net.Adapter(p, netOptions...)
114
	dstore := ds_sync.MutexWrap(delayed.New(ds.NewMapDatastore(), bsdelay))
115

116 117 118
	bstore, err := blockstore.CachedBlockstore(ctx,
		blockstore.NewBlockstore(ds_sync.MutexWrap(dstore)),
		blockstore.DefaultCacheOpts())
119
	if err != nil {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
120
		panic(err.Error()) // FIXME perhaps change signature and return error.
121
	}
122

123
	bs := bitswap.New(ctx, adapter, bstore, bsOptions...).(*bitswap.Bitswap)
124 125

	return Instance{
126
		Adapter:         adapter,
Brian Tiger Chow's avatar
Brian Tiger Chow committed
127
		Peer:            p.ID(),
128 129 130
		Exchange:        bs,
		blockstore:      bstore,
		blockstoreDelay: bsdelay,
131 132
	}
}