9 "github.com/anacrolix/missinggo/pubsub"
10 "github.com/bradfitz/iter"
11 "github.com/stretchr/testify/assert"
12 "github.com/stretchr/testify/require"
14 "github.com/anacrolix/torrent/metainfo"
15 pp "github.com/anacrolix/torrent/peer_protocol"
16 "github.com/anacrolix/torrent/storage"
19 // Ensure that no race exists between sending a bitfield, and a subsequent
20 // Have that would potentially alter it.
21 func TestSendBitfieldThenHave(t *testing.T) {
30 c.writerCond.L = &c.t.cl.mu
31 go c.writer(time.Minute)
33 c.Bitfield([]bool{false, true, false})
39 n, err := io.ReadFull(r, b)
41 // This will cause connection.writer to terminate.
44 require.NoError(t, err)
45 require.EqualValues(t, 15, n)
46 // Here we see that the bitfield doesn't have piece 2 set, as that should
47 // arrive in the following Have message.
48 require.EqualValues(t, "\x00\x00\x00\x02\x05@\x00\x00\x00\x05\x04\x00\x00\x00\x02", string(b))
51 type torrentStorage struct {
55 func (me *torrentStorage) Close() error { return nil }
57 func (me *torrentStorage) Piece(mp metainfo.Piece) storage.PieceImpl {
61 func (me *torrentStorage) Completion() storage.Completion {
62 return storage.Completion{}
65 func (me *torrentStorage) MarkComplete() error {
69 func (me *torrentStorage) MarkNotComplete() error {
73 func (me *torrentStorage) ReadAt([]byte, int64) (int, error) {
74 panic("shouldn't be called")
77 func (me *torrentStorage) WriteAt(b []byte, _ int64) (int, error) {
78 if len(b) != defaultChunkSize {
85 func BenchmarkConnectionMainReadLoop(b *testing.B) {
87 ts := &torrentStorage{}
90 storage: &storage.Torrent{ts},
91 pieceStateChanges: pubsub.NewPubSub(),
93 require.NoError(b, t.setInfo(&metainfo.Info{
94 Pieces: make([]byte, 20),
98 t.setChunkSize(defaultChunkSize)
99 t.pendingPieces.Set(0, PiecePriorityNormal.BitmapPriority())
105 mrlErr := make(chan error)
108 err := cn.mainReadLoop()
116 Piece: make([]byte, defaultChunkSize),
118 wb, err := msg.MarshalBinary()
119 require.NoError(b, err)
120 b.SetBytes(int64(len(msg.Piece)))
122 for range iter.N(b.N) {
124 t.pieces[0].dirtyChunks.Clear()
126 n, err := w.Write(wb)
127 require.NoError(b, err)
128 require.EqualValues(b, len(wb), n)
132 require.NoError(b, <-mrlErr)
133 require.EqualValues(b, b.N, cn.stats.ChunksReadUseful)
136 func TestConnectionReceiveBadChunkIndex(t *testing.T) {
140 require.False(t, cn.t.haveInfo())
141 assert.NotPanics(t, func() { cn.receiveChunk(&pp.Message{}) })
142 cn.t.info = &metainfo.Info{}
143 require.True(t, cn.t.haveInfo())
144 assert.NotPanics(t, func() { cn.receiveChunk(&pp.Message{}) })