github.com/anacrolix/torrent@v1.61.0/metainfo/metainfo_test.go (about)

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