]> Sergey Matveev's repositories - btrtrc.git/blob - metainfo/metainfo_test.go
Drop support for go 1.20
[btrtrc.git] / metainfo / metainfo_test.go
1 package metainfo
2
3 import (
4         "io"
5         "os"
6         "path"
7         "path/filepath"
8         "strings"
9         "testing"
10
11         "github.com/anacrolix/missinggo/v2"
12         qt "github.com/frankban/quicktest"
13         "github.com/stretchr/testify/assert"
14         "github.com/stretchr/testify/require"
15
16         "github.com/anacrolix/torrent/bencode"
17 )
18
19 func testFile(t *testing.T, filename string) {
20         mi, err := LoadFromFile(filename)
21         require.NoError(t, err)
22         info, err := mi.UnmarshalInfo()
23         require.NoError(t, err)
24
25         if len(info.Files) == 1 {
26                 t.Logf("Single file: %s (length: %d)\n", info.Name, info.Files[0].Length)
27         } else {
28                 t.Logf("Multiple files: %s\n", info.Name)
29                 for _, f := range info.Files {
30                         t.Logf(" - %s (length: %d)\n", path.Join(f.Path...), f.Length)
31                 }
32         }
33
34         for _, group := range mi.AnnounceList {
35                 for _, tracker := range group {
36                         t.Logf("Tracker: %s\n", tracker)
37                 }
38         }
39
40         b, err := bencode.Marshal(&info)
41         require.NoError(t, err)
42         assert.EqualValues(t, string(b), string(mi.InfoBytes))
43 }
44
45 func TestFile(t *testing.T) {
46         testFile(t, "testdata/archlinux-2011.08.19-netinstall-i686.iso.torrent")
47         testFile(t, "testdata/continuum.torrent")
48         testFile(t, "testdata/23516C72685E8DB0C8F15553382A927F185C4F01.torrent")
49         testFile(t, "testdata/trackerless.torrent")
50 }
51
52 // Ensure that the correct number of pieces are generated when hashing files.
53 func TestNumPieces(t *testing.T) {
54         for _, _case := range []struct {
55                 PieceLength int64
56                 Files       []FileInfo
57                 NumPieces   int
58         }{
59                 {256 * 1024, []FileInfo{{Length: 1024*1024 + -1}}, 4},
60                 {256 * 1024, []FileInfo{{Length: 1024 * 1024}}, 4},
61                 {256 * 1024, []FileInfo{{Length: 1024*1024 + 1}}, 5},
62                 {5, []FileInfo{{Length: 1}, {Length: 12}}, 3},
63                 {5, []FileInfo{{Length: 4}, {Length: 12}}, 4},
64         } {
65                 info := Info{
66                         Files:       _case.Files,
67                         PieceLength: _case.PieceLength,
68                 }
69                 err := info.GeneratePieces(func(fi FileInfo) (io.ReadCloser, error) {
70                         return io.NopCloser(missinggo.ZeroReader), nil
71                 })
72                 assert.NoError(t, err)
73                 assert.EqualValues(t, _case.NumPieces, info.NumPieces())
74         }
75 }
76
77 func touchFile(path string) (err error) {
78         f, err := os.Create(path)
79         if err != nil {
80                 return
81         }
82         err = f.Close()
83         return
84 }
85
86 func TestBuildFromFilePathOrder(t *testing.T) {
87         td := t.TempDir()
88         require.NoError(t, touchFile(filepath.Join(td, "b")))
89         require.NoError(t, touchFile(filepath.Join(td, "a")))
90         info := Info{
91                 PieceLength: 1,
92         }
93         require.NoError(t, info.BuildFromFilePath(td))
94         assert.EqualValues(t, []FileInfo{{
95                 Path: []string{"a"},
96         }, {
97                 Path: []string{"b"},
98         }}, info.Files)
99 }
100
101 func testUnmarshal(t *testing.T, input string, expected *MetaInfo) {
102         var actual MetaInfo
103         err := bencode.Unmarshal([]byte(input), &actual)
104         if expected == nil {
105                 assert.Error(t, err)
106                 return
107         }
108         assert.NoError(t, err)
109         assert.EqualValues(t, *expected, actual)
110 }
111
112 func TestUnmarshal(t *testing.T) {
113         testUnmarshal(t, `de`, &MetaInfo{})
114         testUnmarshal(t, `d4:infoe`, nil)
115         testUnmarshal(t, `d4:infoabce`, nil)
116         testUnmarshal(t, `d4:infodee`, &MetaInfo{InfoBytes: []byte("de")})
117 }
118
119 func TestMetainfoWithListURLList(t *testing.T) {
120         mi, err := LoadFromFile("testdata/SKODAOCTAVIA336x280_archive.torrent")
121         require.NoError(t, err)
122         assert.Len(t, mi.UrlList, 3)
123         qt.Assert(t, mi.Magnet(nil, nil).String(), qt.ContentEquals,
124                 strings.Join([]string{
125                         "magnet:?xt=urn:btih:d4b197dff199aad447a9a352e31528adbbd97922",
126                         "tr=http%3A%2F%2Fbt1.archive.org%3A6969%2Fannounce",
127                         "tr=http%3A%2F%2Fbt2.archive.org%3A6969%2Fannounce",
128                         "ws=https%3A%2F%2Farchive.org%2Fdownload%2F",
129                         "ws=http%3A%2F%2Fia601600.us.archive.org%2F26%2Fitems%2F",
130                         "ws=http%3A%2F%2Fia801600.us.archive.org%2F26%2Fitems%2F",
131                 }, "&"))
132 }
133
134 func TestMetainfoWithStringURLList(t *testing.T) {
135         mi, err := LoadFromFile("testdata/flat-url-list.torrent")
136         require.NoError(t, err)
137         assert.Len(t, mi.UrlList, 1)
138         qt.Assert(t, mi.Magnet(nil, nil).String(), qt.ContentEquals,
139                 strings.Join([]string{
140                         "magnet:?xt=urn:btih:9da24e606e4ed9c7b91c1772fb5bf98f82bd9687",
141                         "tr=http%3A%2F%2Fbt1.archive.org%3A6969%2Fannounce",
142                         "tr=http%3A%2F%2Fbt2.archive.org%3A6969%2Fannounce",
143                         "ws=https%3A%2F%2Farchive.org%2Fdownload%2F",
144                 }, "&"))
145 }
146
147 // https://github.com/anacrolix/torrent/issues/247
148 //
149 // The decoder buffer wasn't cleared before starting the next dict item after
150 // a syntax error on a field with the ignore_unmarshal_type_error tag.
151 func TestStringCreationDate(t *testing.T) {
152         var mi MetaInfo
153         assert.NoError(t, bencode.Unmarshal([]byte("d13:creation date23:29.03.2018 22:18:14 UTC4:infodee"), &mi))
154 }
155
156 // See https://github.com/anacrolix/torrent/issues/843.
157 func TestUnmarshalEmptyStringNodes(t *testing.T) {
158         var mi MetaInfo
159         c := qt.New(t)
160         err := bencode.Unmarshal([]byte("d5:nodes0:e"), &mi)
161         c.Assert(err, qt.IsNil)
162 }