2014-06-28 17:40:39 +08:00
|
|
|
package metainfo
|
2012-06-28 04:26:56 +08:00
|
|
|
|
2014-12-02 13:27:17 +08:00
|
|
|
import (
|
2015-10-29 22:21:09 +08:00
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
2016-07-07 17:40:26 +08:00
|
|
|
"os"
|
2014-12-02 13:27:17 +08:00
|
|
|
"path"
|
2016-07-07 17:40:26 +08:00
|
|
|
"path/filepath"
|
2021-02-24 09:11:41 +08:00
|
|
|
"strings"
|
2014-12-02 13:27:17 +08:00
|
|
|
"testing"
|
|
|
|
|
2021-06-23 15:24:50 +08:00
|
|
|
"github.com/anacrolix/missinggo/v2"
|
2021-02-24 09:03:16 +08:00
|
|
|
qt "github.com/frankban/quicktest"
|
2015-10-29 22:21:09 +08:00
|
|
|
"github.com/stretchr/testify/assert"
|
2016-04-04 13:39:26 +08:00
|
|
|
"github.com/stretchr/testify/require"
|
2019-08-21 18:58:40 +08:00
|
|
|
|
|
|
|
"github.com/anacrolix/torrent/bencode"
|
2014-12-02 13:27:17 +08:00
|
|
|
)
|
2012-06-28 04:26:56 +08:00
|
|
|
|
2016-02-23 18:50:07 +08:00
|
|
|
func testFile(t *testing.T, filename string) {
|
2012-07-02 03:05:10 +08:00
|
|
|
mi, err := LoadFromFile(filename)
|
2016-05-05 20:40:38 +08:00
|
|
|
require.NoError(t, err)
|
2016-09-20 10:25:40 +08:00
|
|
|
info, err := mi.UnmarshalInfo()
|
|
|
|
require.NoError(t, err)
|
2012-06-28 04:26:56 +08:00
|
|
|
|
2016-08-26 18:29:05 +08:00
|
|
|
if len(info.Files) == 1 {
|
|
|
|
t.Logf("Single file: %s (length: %d)\n", info.Name, info.Files[0].Length)
|
2012-07-11 04:30:05 +08:00
|
|
|
} else {
|
2016-08-26 18:29:05 +08:00
|
|
|
t.Logf("Multiple files: %s\n", info.Name)
|
|
|
|
for _, f := range info.Files {
|
2012-06-28 04:26:56 +08:00
|
|
|
t.Logf(" - %s (length: %d)\n", path.Join(f.Path...), f.Length)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-02 03:05:10 +08:00
|
|
|
for _, group := range mi.AnnounceList {
|
2012-06-28 04:26:56 +08:00
|
|
|
for _, tracker := range group {
|
|
|
|
t.Logf("Tracker: %s\n", tracker)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-26 18:29:05 +08:00
|
|
|
b, err := bencode.Marshal(&info)
|
2016-04-04 13:39:26 +08:00
|
|
|
require.NoError(t, err)
|
2016-08-26 18:29:05 +08:00
|
|
|
assert.EqualValues(t, string(b), string(mi.InfoBytes))
|
2012-06-28 04:26:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestFile(t *testing.T) {
|
2016-02-23 18:50:07 +08:00
|
|
|
testFile(t, "testdata/archlinux-2011.08.19-netinstall-i686.iso.torrent")
|
|
|
|
testFile(t, "testdata/continuum.torrent")
|
|
|
|
testFile(t, "testdata/23516C72685E8DB0C8F15553382A927F185C4F01.torrent")
|
|
|
|
testFile(t, "testdata/trackerless.torrent")
|
2012-06-28 04:26:56 +08:00
|
|
|
}
|
2015-10-29 22:21:09 +08:00
|
|
|
|
|
|
|
// Ensure that the correct number of pieces are generated when hashing files.
|
|
|
|
func TestNumPieces(t *testing.T) {
|
|
|
|
for _, _case := range []struct {
|
|
|
|
PieceLength int64
|
|
|
|
Files []FileInfo
|
|
|
|
NumPieces int
|
|
|
|
}{
|
|
|
|
{256 * 1024, []FileInfo{{Length: 1024*1024 + -1}}, 4},
|
|
|
|
{256 * 1024, []FileInfo{{Length: 1024 * 1024}}, 4},
|
|
|
|
{256 * 1024, []FileInfo{{Length: 1024*1024 + 1}}, 5},
|
|
|
|
{5, []FileInfo{{Length: 1}, {Length: 12}}, 3},
|
|
|
|
{5, []FileInfo{{Length: 4}, {Length: 12}}, 4},
|
|
|
|
} {
|
|
|
|
info := Info{
|
|
|
|
Files: _case.Files,
|
|
|
|
PieceLength: _case.PieceLength,
|
|
|
|
}
|
|
|
|
err := info.GeneratePieces(func(fi FileInfo) (io.ReadCloser, error) {
|
2016-02-04 22:20:02 +08:00
|
|
|
return ioutil.NopCloser(missinggo.ZeroReader), nil
|
2015-10-29 22:21:09 +08:00
|
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.EqualValues(t, _case.NumPieces, info.NumPieces())
|
|
|
|
}
|
|
|
|
}
|
2016-07-07 17:40:26 +08:00
|
|
|
|
|
|
|
func touchFile(path string) (err error) {
|
|
|
|
f, err := os.Create(path)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
err = f.Close()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBuildFromFilePathOrder(t *testing.T) {
|
2022-02-02 15:26:46 +08:00
|
|
|
td := t.TempDir()
|
2016-07-07 17:40:26 +08:00
|
|
|
require.NoError(t, touchFile(filepath.Join(td, "b")))
|
|
|
|
require.NoError(t, touchFile(filepath.Join(td, "a")))
|
|
|
|
info := Info{
|
|
|
|
PieceLength: 1,
|
|
|
|
}
|
|
|
|
require.NoError(t, info.BuildFromFilePath(td))
|
|
|
|
assert.EqualValues(t, []FileInfo{{
|
|
|
|
Path: []string{"a"},
|
|
|
|
}, {
|
|
|
|
Path: []string{"b"},
|
|
|
|
}}, info.Files)
|
|
|
|
}
|
2016-08-26 18:29:05 +08:00
|
|
|
|
|
|
|
func testUnmarshal(t *testing.T, input string, expected *MetaInfo) {
|
|
|
|
var actual MetaInfo
|
|
|
|
err := bencode.Unmarshal([]byte(input), &actual)
|
|
|
|
if expected == nil {
|
|
|
|
assert.Error(t, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.EqualValues(t, *expected, actual)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUnmarshal(t *testing.T) {
|
|
|
|
testUnmarshal(t, `de`, &MetaInfo{})
|
2018-01-25 18:46:50 +08:00
|
|
|
testUnmarshal(t, `d4:infoe`, nil)
|
2016-08-26 18:29:05 +08:00
|
|
|
testUnmarshal(t, `d4:infoabce`, nil)
|
|
|
|
testUnmarshal(t, `d4:infodee`, &MetaInfo{InfoBytes: []byte("de")})
|
|
|
|
}
|
2017-06-16 15:07:30 +08:00
|
|
|
|
|
|
|
func TestMetainfoWithListURLList(t *testing.T) {
|
|
|
|
mi, err := LoadFromFile("testdata/SKODAOCTAVIA336x280_archive.torrent")
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Len(t, mi.UrlList, 3)
|
2021-02-24 09:03:16 +08:00
|
|
|
qt.Assert(t, mi.Magnet(nil, nil).String(), qt.ContentEquals,
|
2021-02-24 09:11:41 +08:00
|
|
|
strings.Join([]string{
|
|
|
|
"magnet:?xt=urn:btih:d4b197dff199aad447a9a352e31528adbbd97922",
|
|
|
|
"tr=http%3A%2F%2Fbt1.archive.org%3A6969%2Fannounce",
|
|
|
|
"tr=http%3A%2F%2Fbt2.archive.org%3A6969%2Fannounce",
|
|
|
|
"ws=https%3A%2F%2Farchive.org%2Fdownload%2F",
|
|
|
|
"ws=http%3A%2F%2Fia601600.us.archive.org%2F26%2Fitems%2F",
|
|
|
|
"ws=http%3A%2F%2Fia801600.us.archive.org%2F26%2Fitems%2F",
|
|
|
|
}, "&"))
|
2017-06-16 15:07:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestMetainfoWithStringURLList(t *testing.T) {
|
|
|
|
mi, err := LoadFromFile("testdata/flat-url-list.torrent")
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Len(t, mi.UrlList, 1)
|
2021-02-24 09:03:16 +08:00
|
|
|
qt.Assert(t, mi.Magnet(nil, nil).String(), qt.ContentEquals,
|
2021-02-24 09:11:41 +08:00
|
|
|
strings.Join([]string{
|
|
|
|
"magnet:?xt=urn:btih:9da24e606e4ed9c7b91c1772fb5bf98f82bd9687",
|
|
|
|
"tr=http%3A%2F%2Fbt1.archive.org%3A6969%2Fannounce",
|
|
|
|
"tr=http%3A%2F%2Fbt2.archive.org%3A6969%2Fannounce",
|
|
|
|
"ws=https%3A%2F%2Farchive.org%2Fdownload%2F",
|
|
|
|
}, "&"))
|
2017-06-16 15:07:30 +08:00
|
|
|
}
|
2018-04-13 15:07:19 +08:00
|
|
|
|
|
|
|
// https://github.com/anacrolix/torrent/issues/247
|
|
|
|
//
|
|
|
|
// The decoder buffer wasn't cleared before starting the next dict item after
|
|
|
|
// a syntax error on a field with the ignore_unmarshal_type_error tag.
|
|
|
|
func TestStringCreationDate(t *testing.T) {
|
|
|
|
var mi MetaInfo
|
|
|
|
assert.NoError(t, bencode.Unmarshal([]byte("d13:creation date23:29.03.2018 22:18:14 UTC4:infodee"), &mi))
|
|
|
|
}
|