"sync"
"testing"
+ "golang.org/x/time/rate"
+
"github.com/frankban/quicktest"
qt "github.com/frankban/quicktest"
"github.com/stretchr/testify/require"
var cl Client
cl.init(TestingConfig(t))
cl.initLogger()
- c := cl.newConnection(nil, false, nil, "io.Pipe", "")
+ c := cl.newConnection(nil, newConnectionOpts{network: "io.Pipe"})
c.setTorrent(cl.newTorrent(metainfo.Hash{}, nil))
if err := c.t.setInfo(&metainfo.Info{Pieces: make([]byte, metainfo.HashSize*3)}); err != nil {
t.Log(err)
r, w := io.Pipe()
// c.r = r
c.w = w
- c.startWriter()
+ c.startMessageWriter()
c.locker().Lock()
c.t._completedPieces.Add(1)
c.postBitfield( /*[]bool{false, true, false}*/ )
t.onSetInfo()
t._pendingPieces.Add(0)
r, w := net.Pipe()
- cn := cl.newConnection(r, true, r.RemoteAddr(), r.RemoteAddr().Network(), regularNetConnPeerConnConnString(r))
+ cn := cl.newConnection(r, newConnectionOpts{
+ outgoing: true,
+ remoteAddr: r.RemoteAddr(),
+ network: r.RemoteAddr().Network(),
+ connString: regularNetConnPeerConnConnString(r),
+ })
cn.setTorrent(t)
mrlErrChan := make(chan error)
msg := pp.Message{
},
{
pexDrop,
- &PeerConn{Peer: Peer{RemoteAddr: tcpAddr, Network: tcpAddr.Network(), outgoing: true, PeerListenPort: dialTcpAddr.Port}},
+ &PeerConn{Peer: Peer{RemoteAddr: tcpAddr, Network: tcpAddr.Network(), outgoing: true}, PeerListenPort: dialTcpAddr.Port},
pexEvent{pexDrop, tcpAddr, pp.PexOutgoingConn, nil},
},
{
pexAdd,
- &PeerConn{Peer: Peer{RemoteAddr: tcpAddr, Network: tcpAddr.Network(), PeerListenPort: dialTcpAddr.Port}},
+ &PeerConn{Peer: Peer{RemoteAddr: tcpAddr, Network: tcpAddr.Network()}, PeerListenPort: dialTcpAddr.Port},
pexEvent{pexAdd, dialTcpAddr, 0, nil},
},
{
pexDrop,
- &PeerConn{Peer: Peer{RemoteAddr: udpAddr, Network: udpAddr.Network(), PeerListenPort: dialUdpAddr.Port}},
+ &PeerConn{Peer: Peer{RemoteAddr: udpAddr, Network: udpAddr.Network()}, PeerListenPort: dialUdpAddr.Port},
pexEvent{pexDrop, dialUdpAddr, pp.PexSupportsUtp, nil},
},
}
c.Logf("max local to remote requests: %v", maxLocalToRemoteRequests)
}
-func peerConnForPreferredNetworkDirection(localPeerId, remotePeerId int, outgoing, utp, ipv6 bool) *PeerConn {
+func peerConnForPreferredNetworkDirection(
+ localPeerId, remotePeerId int,
+ outgoing, utp, ipv6 bool,
+) *PeerConn {
pc := PeerConn{}
pc.outgoing = outgoing
if utp {
func TestPreferredNetworkDirection(t *testing.T) {
pc := peerConnForPreferredNetworkDirection
c := qt.New(t)
- // Prefer outgoing to higher peer ID
- c.Assert(pc(1, 2, true, false, false).hasPreferredNetworkOver(pc(1, 2, false, false, false)), qt.IsTrue)
- c.Assert(pc(1, 2, false, false, false).hasPreferredNetworkOver(pc(1, 2, true, false, false)), qt.IsFalse)
- c.Assert(pc(2, 1, false, false, false).hasPreferredNetworkOver(pc(2, 1, true, false, false)), qt.IsTrue)
+
+ // Prefer outgoing to lower peer ID
+
+ c.Check(
+ pc(1, 2, true, false, false).hasPreferredNetworkOver(pc(1, 2, false, false, false)),
+ qt.IsFalse,
+ )
+ c.Check(
+ pc(1, 2, false, false, false).hasPreferredNetworkOver(pc(1, 2, true, false, false)),
+ qt.IsTrue,
+ )
+ c.Check(
+ pc(2, 1, false, false, false).hasPreferredNetworkOver(pc(2, 1, true, false, false)),
+ qt.IsFalse,
+ )
+
// Don't prefer uTP
- c.Assert(pc(1, 2, false, true, false).hasPreferredNetworkOver(pc(1, 2, false, false, false)), qt.IsFalse)
+ c.Check(
+ pc(1, 2, false, true, false).hasPreferredNetworkOver(pc(1, 2, false, false, false)),
+ qt.IsFalse,
+ )
// Prefer IPv6
- c.Assert(pc(1, 2, false, false, false).hasPreferredNetworkOver(pc(1, 2, false, false, true)), qt.IsFalse)
+ c.Check(
+ pc(1, 2, false, false, false).hasPreferredNetworkOver(pc(1, 2, false, false, true)),
+ qt.IsFalse,
+ )
// No difference
- c.Assert(pc(1, 2, false, false, false).hasPreferredNetworkOver(pc(1, 2, false, false, false)), qt.IsFalse)
+ c.Check(
+ pc(1, 2, false, false, false).hasPreferredNetworkOver(pc(1, 2, false, false, false)),
+ qt.IsFalse,
+ )
+}
+
+func TestReceiveLargeRequest(t *testing.T) {
+ c := qt.New(t)
+ cl := newTestingClient(t)
+ pc := cl.newConnection(nil, newConnectionOpts{network: "test"})
+ tor := cl.newTorrentForTesting()
+ tor.info = &metainfo.Info{PieceLength: 3 << 20}
+ pc.setTorrent(tor)
+ tor._completedPieces.Add(0)
+ pc.PeerExtensionBytes.SetBit(pp.ExtensionBitFast, true)
+ pc.choking = false
+ pc.initMessageWriter()
+ req := Request{}
+ req.Length = defaultChunkSize
+ c.Assert(pc.fastEnabled(), qt.IsTrue)
+ c.Check(pc.onReadRequest(req, false), qt.IsNil)
+ c.Check(pc.peerRequests, qt.HasLen, 1)
+ req.Length = 2 << 20
+ c.Check(pc.onReadRequest(req, false), qt.IsNil)
+ c.Check(pc.peerRequests, qt.HasLen, 2)
+ pc.peerRequests = nil
+ pc.t.cl.config.UploadRateLimiter = rate.NewLimiter(1, defaultChunkSize)
+ req.Length = defaultChunkSize
+ c.Check(pc.onReadRequest(req, false), qt.IsNil)
+ c.Check(pc.peerRequests, qt.HasLen, 1)
+ req.Length = 2 << 20
+ c.Check(pc.onReadRequest(req, false), qt.IsNil)
+ c.Check(pc.messageWriter.writeBuffer.Len(), qt.Equals, 17)
+}
+
+func TestChunkOverflowsPiece(t *testing.T) {
+ c := qt.New(t)
+ check := func(begin, length, limit pp.Integer, expected bool) {
+ c.Check(chunkOverflowsPiece(ChunkSpec{begin, length}, limit), qt.Equals, expected)
+ }
+ check(2, 3, 1, true)
+ check(2, pp.IntegerMax, 1, true)
+ check(2, pp.IntegerMax, 3, true)
+ check(2, pp.IntegerMax, pp.IntegerMax, true)
+ check(2, pp.IntegerMax-2, pp.IntegerMax, false)
}