]> Sergey Matveev's repositories - btrtrc.git/blobdiff - metainfo/metainfo_test.go
chore: remove refs to deprecated io/ioutil
[btrtrc.git] / metainfo / metainfo_test.go
index b7cb314607381b16dfe04b40810c8b4f1088a5dd..335631f9850c7ba6b135612c38ed89958e48bfa9 100644 (file)
@@ -1,19 +1,32 @@
 package metainfo
 
-import "testing"
-import "path"
+import (
+       "io"
+       "os"
+       "path"
+       "path/filepath"
+       "strings"
+       "testing"
 
-func test_file(t *testing.T, filename string) {
+       "github.com/anacrolix/missinggo/v2"
+       qt "github.com/frankban/quicktest"
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
+
+       "github.com/anacrolix/torrent/bencode"
+)
+
+func testFile(t *testing.T, filename string) {
        mi, err := LoadFromFile(filename)
-       if err != nil {
-               t.Fatal(err)
-       }
+       require.NoError(t, err)
+       info, err := mi.UnmarshalInfo()
+       require.NoError(t, err)
 
-       if len(mi.Files) == 1 {
-               t.Logf("Single file: %s (length: %d)\n", mi.Name, mi.Files[0].Length)
+       if len(info.Files) == 1 {
+               t.Logf("Single file: %s (length: %d)\n", info.Name, info.Files[0].Length)
        } else {
-               t.Logf("Multiple files: %s\n", mi.Name)
-               for _, f := range mi.Files {
+               t.Logf("Multiple files: %s\n", info.Name)
+               for _, f := range info.Files {
                        t.Logf(" - %s (length: %d)\n", path.Join(f.Path...), f.Length)
                }
        }
@@ -23,13 +36,127 @@ func test_file(t *testing.T, filename string) {
                        t.Logf("Tracker: %s\n", tracker)
                }
        }
-       for _, url := range mi.WebSeedURLs {
-               t.Logf("URL: %s\n", url)
-       }
 
+       b, err := bencode.Marshal(&info)
+       require.NoError(t, err)
+       assert.EqualValues(t, string(b), string(mi.InfoBytes))
 }
 
 func TestFile(t *testing.T) {
-       test_file(t, "_testdata/archlinux-2011.08.19-netinstall-i686.iso.torrent")
-       test_file(t, "_testdata/continuum.torrent")
+       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")
+}
+
+// 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) {
+                       return io.NopCloser(missinggo.ZeroReader), nil
+               })
+               assert.NoError(t, err)
+               assert.EqualValues(t, _case.NumPieces, info.NumPieces())
+       }
+}
+
+func touchFile(path string) (err error) {
+       f, err := os.Create(path)
+       if err != nil {
+               return
+       }
+       err = f.Close()
+       return
+}
+
+func TestBuildFromFilePathOrder(t *testing.T) {
+       td := t.TempDir()
+       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)
+}
+
+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{})
+       testUnmarshal(t, `d4:infoe`, nil)
+       testUnmarshal(t, `d4:infoabce`, nil)
+       testUnmarshal(t, `d4:infodee`, &MetaInfo{InfoBytes: []byte("de")})
+}
+
+func TestMetainfoWithListURLList(t *testing.T) {
+       mi, err := LoadFromFile("testdata/SKODAOCTAVIA336x280_archive.torrent")
+       require.NoError(t, err)
+       assert.Len(t, mi.UrlList, 3)
+       qt.Assert(t, mi.Magnet(nil, nil).String(), qt.ContentEquals,
+               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",
+               }, "&"))
+}
+
+func TestMetainfoWithStringURLList(t *testing.T) {
+       mi, err := LoadFromFile("testdata/flat-url-list.torrent")
+       require.NoError(t, err)
+       assert.Len(t, mi.UrlList, 1)
+       qt.Assert(t, mi.Magnet(nil, nil).String(), qt.ContentEquals,
+               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",
+               }, "&"))
+}
+
+// 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))
+}
+
+// See https://github.com/anacrolix/torrent/issues/843.
+func TestUnmarshalEmptyStringNodes(t *testing.T) {
+       var mi MetaInfo
+       c := qt.New(t)
+       err := bencode.Unmarshal([]byte("d5:nodes0:e"), &mi)
+       c.Assert(err, qt.IsNil)
 }