]> Sergey Matveev's repositories - btrtrc.git/blobdiff - peerconn_test.go
Drop support for go 1.20
[btrtrc.git] / peerconn_test.go
index b1ac1dbc987dba423fe38aac7a8fe3d4bf4d258f..e294b6b620590de33886514facd5bfd46cae9bc6 100644 (file)
@@ -12,6 +12,7 @@ import (
        "github.com/frankban/quicktest"
        qt "github.com/frankban/quicktest"
        "github.com/stretchr/testify/require"
+       "golang.org/x/time/rate"
 
        "github.com/anacrolix/torrent/metainfo"
        pp "github.com/anacrolix/torrent/peer_protocol"
@@ -24,7 +25,7 @@ func TestSendBitfieldThenHave(t *testing.T) {
        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)
@@ -32,7 +33,7 @@ func TestSendBitfieldThenHave(t *testing.T) {
        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}*/ )
@@ -106,7 +107,12 @@ func BenchmarkConnectionMainReadLoop(b *testing.B) {
        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{
@@ -175,6 +181,7 @@ func TestConnPexPeerFlags(t *testing.T) {
 }
 
 func TestConnPexEvent(t *testing.T) {
+       c := qt.New(t)
        var (
                udpAddr     = &net.UDPAddr{IP: net.IPv6loopback, Port: 4848}
                tcpAddr     = &net.TCPAddr{IP: net.IPv6loopback, Port: 4848}
@@ -189,27 +196,39 @@ func TestConnPexEvent(t *testing.T) {
                {
                        pexAdd,
                        &PeerConn{Peer: Peer{RemoteAddr: udpAddr, Network: udpAddr.Network()}},
-                       pexEvent{pexAdd, udpAddr, pp.PexSupportsUtp, nil},
+                       pexEvent{pexAdd, udpAddr.AddrPort(), pp.PexSupportsUtp, nil},
                },
                {
                        pexDrop,
-                       &PeerConn{Peer: Peer{RemoteAddr: tcpAddr, Network: tcpAddr.Network(), outgoing: true, PeerListenPort: dialTcpAddr.Port}},
-                       pexEvent{pexDrop, tcpAddr, pp.PexOutgoingConn, nil},
+                       &PeerConn{
+                               Peer:           Peer{RemoteAddr: tcpAddr, Network: tcpAddr.Network(), outgoing: true},
+                               PeerListenPort: dialTcpAddr.Port,
+                       },
+                       pexEvent{pexDrop, tcpAddr.AddrPort(), pp.PexOutgoingConn, nil},
                },
                {
                        pexAdd,
-                       &PeerConn{Peer: Peer{RemoteAddr: tcpAddr, Network: tcpAddr.Network(), PeerListenPort: dialTcpAddr.Port}},
-                       pexEvent{pexAdd, dialTcpAddr, 0, nil},
+                       &PeerConn{
+                               Peer:           Peer{RemoteAddr: tcpAddr, Network: tcpAddr.Network()},
+                               PeerListenPort: dialTcpAddr.Port,
+                       },
+                       pexEvent{pexAdd, dialTcpAddr.AddrPort(), 0, nil},
                },
                {
                        pexDrop,
-                       &PeerConn{Peer: Peer{RemoteAddr: udpAddr, Network: udpAddr.Network(), PeerListenPort: dialUdpAddr.Port}},
-                       pexEvent{pexDrop, dialUdpAddr, pp.PexSupportsUtp, nil},
+                       &PeerConn{
+                               Peer:           Peer{RemoteAddr: udpAddr, Network: udpAddr.Network()},
+                               PeerListenPort: dialUdpAddr.Port,
+                       },
+                       pexEvent{pexDrop, dialUdpAddr.AddrPort(), pp.PexSupportsUtp, nil},
                },
        }
        for i, tc := range testcases {
-               e := tc.c.pexEvent(tc.t)
-               require.EqualValues(t, tc.e, e, i)
+               c.Run(fmt.Sprintf("%v", i), func(c *qt.C) {
+                       e, err := tc.c.pexEvent(tc.t)
+                       c.Assert(err, qt.IsNil)
+                       c.Check(e, qt.Equals, tc.e)
+               })
        }
 }
 
@@ -221,6 +240,7 @@ func TestHaveAllThenBitfield(t *testing.T) {
        pc := PeerConn{
                Peer: Peer{t: tt},
        }
+       pc.initRequestState()
        pc.peerImpl = &pc
        tt.conns[&pc] = struct{}{}
        c.Assert(pc.onPeerSentHaveAll(), qt.IsNil)
@@ -249,14 +269,17 @@ func TestApplyRequestStateWriteBufferConstraints(t *testing.T) {
        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 {
                pc.Network = "udp"
        }
        if ipv6 {
-               pc.RemoteAddr = &net.TCPAddr{IP: net.ParseIP(fmt.Sprintf("::420"))}
+               pc.RemoteAddr = &net.TCPAddr{IP: net.ParseIP("::420")}
        } else {
                pc.RemoteAddr = &net.TCPAddr{IP: net.IPv4(1, 2, 3, 4)}
        }
@@ -270,14 +293,76 @@ func peerConnForPreferredNetworkDirection(localPeerId, remotePeerId int, outgoin
 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)
 }