Skip to content

Commit

Permalink
Don't verify data at startup, add Torrent.Piece.VerifyData and Torren…
Browse files Browse the repository at this point in the history
…t.VerifyData for this purpose

This has the side effect of deflaking a lot of tests that race to verify data when a torrent is added.
  • Loading branch information
anacrolix committed Sep 15, 2017
1 parent b39df82 commit 2aa20b3
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 21 deletions.
25 changes: 14 additions & 11 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,8 @@ func testClientTransfer(t *testing.T, ps testClientTransferParams) {
if ps.ExportClientStatus {
testutil.ExportStatusWriter(seeder, "s")
}
// seederTorrent, new, err := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
_, new, err := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
require.NoError(t, err)
assert.True(t, new)
seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
seederTorrent.VerifyData()
// Create leecher and a Torrent.
leecherDataDir, err := ioutil.TempDir("", "")
require.NoError(t, err)
Expand Down Expand Up @@ -454,7 +452,8 @@ func TestSeedAfterDownloading(t *testing.T) {
require.NoError(t, err)
defer seeder.Close()
testutil.ExportStatusWriter(seeder, "s")
seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
seederTorrent.VerifyData()
cfg.DataDir, err = ioutil.TempDir("", "")
require.NoError(t, err)
defer os.RemoveAll(cfg.DataDir)
Expand Down Expand Up @@ -619,7 +618,8 @@ func TestResponsive(t *testing.T) {
seeder, err := NewClient(cfg)
require.Nil(t, err)
defer seeder.Close()
seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
seederTorrent.VerifyData()
leecherDataDir, err := ioutil.TempDir("", "")
require.Nil(t, err)
defer os.RemoveAll(leecherDataDir)
Expand Down Expand Up @@ -661,7 +661,8 @@ func TestTorrentDroppedDuringResponsiveRead(t *testing.T) {
seeder, err := NewClient(cfg)
require.Nil(t, err)
defer seeder.Close()
seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
seederTorrent.VerifyData()
leecherDataDir, err := ioutil.TempDir("", "")
require.Nil(t, err)
defer os.RemoveAll(leecherDataDir)
Expand Down Expand Up @@ -759,6 +760,7 @@ func testAddTorrentPriorPieceCompletion(t *testing.T, alreadyCompleted bool, csf
greetingDataTempDir, greetingMetainfo := testutil.GreetingTestTorrent()
defer os.RemoveAll(greetingDataTempDir)
filePieceStore := csf(fileCache)
defer filePieceStore.Close()
info, err := greetingMetainfo.UnmarshalInfo()
require.NoError(t, err)
ih := greetingMetainfo.HashInfoBytes()
Expand All @@ -770,8 +772,7 @@ func testAddTorrentPriorPieceCompletion(t *testing.T, alreadyCompleted bool, csf
for i := 0; i < info.NumPieces(); i++ {
p := info.Piece(i)
if alreadyCompleted {
err := greetingData.Piece(p).MarkComplete()
assert.NoError(t, err)
require.NoError(t, greetingData.Piece(p).MarkComplete())
}
}
cfg := TestingConfig()
Expand Down Expand Up @@ -844,7 +845,8 @@ func testDownloadCancel(t *testing.T, ps testDownloadCancelParams) {
if ps.ExportClientStatus {
testutil.ExportStatusWriter(seeder, "s")
}
seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
seederTorrent.VerifyData()
leecherDataDir, err := ioutil.TempDir("", "")
require.NoError(t, err)
defer os.RemoveAll(leecherDataDir)
Expand Down Expand Up @@ -1064,7 +1066,8 @@ func makeMagnet(t *testing.T, cl *Client, dir string, name string) string {
magnet := mi.Magnet(name, mi.HashInfoBytes()).String()
tr, err := cl.AddTorrent(&mi)
require.NoError(t, err)
assert.True(t, tr.Seeding())
require.True(t, tr.Seeding())
tr.VerifyData()
return magnet
}

Expand Down
24 changes: 20 additions & 4 deletions piece.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ type piece struct {
index int
// Chunks we've written to since the last check. The chunk offset and
// length can be determined by the request chunkSize in use.
DirtyChunks bitmap.Bitmap
Hashing bool
QueuedForHash bool
EverHashed bool
DirtyChunks bitmap.Bitmap

Hashing bool
QueuedForHash bool
EverHashed bool
numVerifies int64

PublicPieceState PieceState
priority piecePriority

Expand Down Expand Up @@ -157,3 +160,16 @@ func (p *piece) bytesLeft() (ret pp.Integer) {
}
return p.length() - p.numDirtyBytes()
}

func (p *piece) VerifyData() {
p.t.cl.mu.Lock()
defer p.t.cl.mu.Unlock()
target := p.numVerifies + 1
if p.Hashing {
target++
}
p.t.queuePieceCheck(p.index)
for p.numVerifies < target {
p.t.cl.event.Wait()
}
}
6 changes: 6 additions & 0 deletions t.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,9 @@ func (t *Torrent) AddTrackers(announceList [][]string) {
defer t.cl.mu.Unlock()
t.addTrackers(announceList)
}

func (t *Torrent) Piece(i int) *piece {
t.cl.mu.Lock()
defer t.cl.mu.Unlock()
return &t.pieces[i]
}
19 changes: 13 additions & 6 deletions torrent.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,13 +284,13 @@ func (t *Torrent) setInfoBytes(b []byte) error {
}
for i := range t.pieces {
t.updatePieceCompletion(i)
t.pieces[i].QueuedForHash = true
// t.pieces[i].QueuedForHash = true
}
go func() {
for i := range t.pieces {
t.verifyPiece(i)
}
}()
// go func() {
// for i := range t.pieces {
// t.verifyPiece(i)
// }
// }()
return nil
}

Expand Down Expand Up @@ -1485,6 +1485,7 @@ func (t *Torrent) verifyPiece(piece int) {
cl.mu.Unlock()
sum := t.hashPiece(piece)
cl.mu.Lock()
p.numVerifies++
p.Hashing = false
t.pieceHashed(piece, sum == p.Hash)
}
Expand Down Expand Up @@ -1518,3 +1519,9 @@ func (t *Torrent) queuePieceCheck(pieceIndex int) {
t.publishPieceChange(pieceIndex)
go t.verifyPiece(pieceIndex)
}

func (t *Torrent) VerifyData() {
for i := range iter.N(t.NumPieces()) {
t.Piece(i).VerifyData()
}
}

0 comments on commit 2aa20b3

Please sign in to comment.