2017-09-12 19:12:56 +08:00
|
|
|
package peer_protocol
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"io"
|
|
|
|
"sync"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/bradfitz/iter"
|
2018-07-12 07:54:06 +08:00
|
|
|
"github.com/stretchr/testify/assert"
|
2017-09-12 19:12:56 +08:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func BenchmarkDecodePieces(t *testing.B) {
|
|
|
|
r, w := io.Pipe()
|
2017-09-12 19:32:01 +08:00
|
|
|
const pieceLen = 1 << 14
|
2017-09-12 19:12:56 +08:00
|
|
|
msg := Message{
|
|
|
|
Type: Piece,
|
|
|
|
Index: 0,
|
|
|
|
Begin: 1,
|
2017-09-12 19:32:01 +08:00
|
|
|
Piece: make([]byte, pieceLen),
|
2017-09-12 19:12:56 +08:00
|
|
|
}
|
|
|
|
b, err := msg.MarshalBinary()
|
|
|
|
require.NoError(t, err)
|
|
|
|
t.SetBytes(int64(len(b)))
|
2017-09-12 19:32:01 +08:00
|
|
|
defer r.Close()
|
2017-09-12 19:12:56 +08:00
|
|
|
go func() {
|
2017-09-12 19:32:01 +08:00
|
|
|
defer w.Close()
|
2017-09-12 19:12:56 +08:00
|
|
|
for {
|
|
|
|
n, err := w.Write(b)
|
2017-09-12 19:32:01 +08:00
|
|
|
if err == io.ErrClosedPipe {
|
|
|
|
return
|
|
|
|
}
|
2017-09-12 19:12:56 +08:00
|
|
|
require.NoError(t, err)
|
2017-09-12 19:32:01 +08:00
|
|
|
require.Equal(t, len(b), n)
|
2017-09-12 19:12:56 +08:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
d := Decoder{
|
2017-09-12 19:32:01 +08:00
|
|
|
// Emulate what package torrent's client would do.
|
2017-09-12 19:12:56 +08:00
|
|
|
R: bufio.NewReader(r),
|
|
|
|
MaxLength: 1 << 18,
|
|
|
|
Pool: &sync.Pool{
|
|
|
|
New: func() interface{} {
|
2018-01-25 14:43:45 +08:00
|
|
|
b := make([]byte, pieceLen)
|
|
|
|
return &b
|
2017-09-12 19:12:56 +08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for range iter.N(t.N) {
|
|
|
|
var msg Message
|
|
|
|
require.NoError(t, d.Decode(&msg))
|
2017-09-12 19:32:01 +08:00
|
|
|
// WWJD
|
2017-11-07 13:11:59 +08:00
|
|
|
d.Pool.Put(&msg.Piece)
|
2017-09-12 19:12:56 +08:00
|
|
|
}
|
|
|
|
}
|
2018-07-12 07:54:06 +08:00
|
|
|
|
|
|
|
func TestDecodeShortPieceEOF(t *testing.T) {
|
|
|
|
r, w := io.Pipe()
|
|
|
|
go func() {
|
|
|
|
w.Write(Message{Type: Piece, Piece: make([]byte, 1)}.MustMarshalBinary())
|
|
|
|
w.Close()
|
|
|
|
}()
|
|
|
|
d := Decoder{
|
|
|
|
R: bufio.NewReader(r),
|
|
|
|
MaxLength: 1 << 15,
|
|
|
|
Pool: &sync.Pool{New: func() interface{} {
|
|
|
|
b := make([]byte, 2)
|
|
|
|
return &b
|
|
|
|
}},
|
|
|
|
}
|
|
|
|
var m Message
|
|
|
|
require.NoError(t, d.Decode(&m))
|
|
|
|
assert.Len(t, m.Piece, 1)
|
|
|
|
assert.Equal(t, io.EOF, d.Decode(&m))
|
|
|
|
}
|
2018-07-14 09:37:56 +08:00
|
|
|
|
|
|
|
func TestDecodeOverlongPiece(t *testing.T) {
|
|
|
|
r, w := io.Pipe()
|
|
|
|
go func() {
|
|
|
|
w.Write(Message{Type: Piece, Piece: make([]byte, 3)}.MustMarshalBinary())
|
|
|
|
w.Close()
|
|
|
|
}()
|
|
|
|
d := Decoder{
|
|
|
|
R: bufio.NewReader(r),
|
|
|
|
MaxLength: 1 << 15,
|
|
|
|
Pool: &sync.Pool{New: func() interface{} {
|
|
|
|
b := make([]byte, 2)
|
|
|
|
return &b
|
|
|
|
}},
|
|
|
|
}
|
|
|
|
var m Message
|
2018-07-14 09:50:43 +08:00
|
|
|
require.Error(t, d.Decode(&m))
|
2018-07-14 09:37:56 +08:00
|
|
|
}
|