Add unit test for relative availability after HaveNone

Could help with https://github.com/anacrolix/torrent/issues/813.
This commit is contained in:
Matt Joiner 2023-02-19 13:24:25 +11:00
parent 48b3e66c76
commit e8971ea0f1
No known key found for this signature in database
GPG Key ID: 6B990B8185E7F782
4 changed files with 49 additions and 6 deletions

View File

@ -899,7 +899,7 @@ func (cn *PeerConn) onPeerSentHaveAll() error {
} }
func (cn *PeerConn) peerSentHaveNone() error { func (cn *PeerConn) peerSentHaveNone() error {
if cn.peerSentHaveAll { if !cn.peerSentHaveAll {
cn.t.decPeerPieceAvailability(&cn.Peer) cn.t.decPeerPieceAvailability(&cn.Peer)
} }
cn._peerPieces.Clear() cn._peerPieces.Clear()

View File

@ -45,6 +45,9 @@ func (me *prioritizedPeers) Each(f func(PeerInfo)) {
} }
func (me *prioritizedPeers) Len() int { func (me *prioritizedPeers) Len() int {
if me == nil || me.om == nil {
return 0
}
return me.om.Len() return me.om.Len()
} }

View File

@ -894,17 +894,21 @@ func (t *Torrent) close(wg *sync.WaitGroup) (err error) {
if t.storage != nil { if t.storage != nil {
t.deletePieceRequestOrder() t.deletePieceRequestOrder()
} }
t.assertAllPiecesRelativeAvailabilityZero()
t.pex.Reset()
t.cl.event.Broadcast()
t.pieceStateChanges.Close()
t.updateWantPeersEvent()
return
}
func (t *Torrent) assertAllPiecesRelativeAvailabilityZero() {
for i := range t.pieces { for i := range t.pieces {
p := t.piece(i) p := t.piece(i)
if p.relativeAvailability != 0 { if p.relativeAvailability != 0 {
panic(fmt.Sprintf("piece %v has relative availability %v", i, p.relativeAvailability)) panic(fmt.Sprintf("piece %v has relative availability %v", i, p.relativeAvailability))
} }
} }
t.pex.Reset()
t.cl.event.Broadcast()
t.pieceStateChanges.Close()
t.updateWantPeersEvent()
return
} }
func (t *Torrent) requestOffset(r Request) int64 { func (t *Torrent) requestOffset(r Request) int64 {

View File

@ -6,10 +6,14 @@ import (
"net" "net"
"os" "os"
"path/filepath" "path/filepath"
"sync"
"testing" "testing"
"github.com/anacrolix/generics"
"github.com/anacrolix/log"
"github.com/anacrolix/missinggo/v2" "github.com/anacrolix/missinggo/v2"
"github.com/anacrolix/missinggo/v2/bitmap" "github.com/anacrolix/missinggo/v2/bitmap"
qt "github.com/frankban/quicktest"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -215,3 +219,35 @@ func TestTorrentMetainfoIncompleteMetadata(t *testing.T) {
assert.False(t, tt.haveAllMetadataPieces()) assert.False(t, tt.haveAllMetadataPieces())
assert.Nil(t, tt.Metainfo().InfoBytes) assert.Nil(t, tt.Metainfo().InfoBytes)
} }
func TestRelativeAvailabilityHaveNone(t *testing.T) {
c := qt.New(t)
var err error
cl := Client{
config: TestingConfig(t),
}
tt := Torrent{
cl: &cl,
logger: log.Default,
gotMetainfoC: make(chan struct{}),
}
tt.setChunkSize(2)
generics.MakeMapIfNil(&tt.conns)
pc := PeerConn{}
pc.t = &tt
pc.peerImpl = &pc
pc.initRequestState()
generics.InitNew(&pc.callbacks)
tt.conns[&pc] = struct{}{}
err = pc.peerSentHave(0)
c.Assert(err, qt.IsNil)
info := testutil.Greeting.Info(5)
err = tt.setInfo(&info)
c.Assert(err, qt.IsNil)
tt.onSetInfo()
err = pc.peerSentHaveNone()
c.Assert(err, qt.IsNil)
var wg sync.WaitGroup
tt.close(&wg)
tt.assertAllPiecesRelativeAvailabilityZero()
}