14 "github.com/bradfitz/iter"
15 "github.com/stretchr/testify/assert"
16 "github.com/stretchr/testify/require"
18 "github.com/anacrolix/dht/v2"
19 _ "github.com/anacrolix/envpprof"
20 "github.com/anacrolix/missinggo"
21 "github.com/anacrolix/missinggo/v2/filecache"
23 "github.com/anacrolix/torrent/bencode"
24 "github.com/anacrolix/torrent/internal/testutil"
25 "github.com/anacrolix/torrent/iplist"
26 "github.com/anacrolix/torrent/metainfo"
27 "github.com/anacrolix/torrent/storage"
30 func TestClientDefault(t *testing.T) {
31 cl, err := NewClient(TestingConfig())
32 require.NoError(t, err)
36 func TestClientNilConfig(t *testing.T) {
37 cl, err := NewClient(nil)
38 require.NoError(t, err)
42 func TestBoltPieceCompletionClosedWhenClientClosed(t *testing.T) {
43 cfg := TestingConfig()
44 pc, err := storage.NewBoltPieceCompletion(cfg.DataDir)
45 require.NoError(t, err)
46 ci := storage.NewFileWithCompletion(cfg.DataDir, pc)
48 cfg.DefaultStorage = ci
49 cl, err := NewClient(cfg)
50 require.NoError(t, err)
52 // And again, https://github.com/anacrolix/torrent/issues/158
53 cl, err = NewClient(cfg)
54 require.NoError(t, err)
58 func TestAddDropTorrent(t *testing.T) {
59 cl, err := NewClient(TestingConfig())
60 require.NoError(t, err)
62 dir, mi := testutil.GreetingTestTorrent()
63 defer os.RemoveAll(dir)
64 tt, new, err := cl.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
65 require.NoError(t, err)
67 tt.SetMaxEstablishedConns(0)
68 tt.SetMaxEstablishedConns(1)
72 func TestAddTorrentNoSupportedTrackerSchemes(t *testing.T) {
77 func TestAddTorrentNoUsableURLs(t *testing.T) {
82 func TestAddPeersToUnknownTorrent(t *testing.T) {
87 func TestPieceHashSize(t *testing.T) {
88 assert.Equal(t, 20, pieceHash.Size())
91 func TestTorrentInitialState(t *testing.T) {
92 dir, mi := testutil.GreetingTestTorrent()
93 defer os.RemoveAll(dir)
95 config: TestingConfig(),
100 storage.NewFileWithCompletion(TestingTempDir.NewSub(), storage.NewMapPieceCompletion()),
104 err := tor.setInfoBytes(mi.InfoBytes)
106 require.NoError(t, err)
107 require.Len(t, tor.pieces, 3)
108 tor.pendAllChunkSpecs(0)
110 assert.EqualValues(t, 3, tor.pieceNumPendingChunks(0))
112 assert.EqualValues(t, chunkSpec{4, 1}, chunkIndexSpec(2, tor.pieceLength(0), tor.chunkSize))
115 func TestReducedDialTimeout(t *testing.T) {
116 cfg := NewDefaultClientConfig()
117 for _, _case := range []struct {
121 ExpectedReduced time.Duration
123 {cfg.NominalDialTimeout, 40, 0, cfg.NominalDialTimeout},
124 {cfg.NominalDialTimeout, 40, 1, cfg.NominalDialTimeout},
125 {cfg.NominalDialTimeout, 40, 39, cfg.NominalDialTimeout},
126 {cfg.NominalDialTimeout, 40, 40, cfg.NominalDialTimeout / 2},
127 {cfg.NominalDialTimeout, 40, 80, cfg.NominalDialTimeout / 3},
128 {cfg.NominalDialTimeout, 40, 4000, cfg.NominalDialTimeout / 101},
130 reduced := reducedDialTimeout(cfg.MinDialTimeout, _case.Max, _case.HalfOpenLimit, _case.PendingPeers)
131 expected := _case.ExpectedReduced
132 if expected < cfg.MinDialTimeout {
133 expected = cfg.MinDialTimeout
135 if reduced != expected {
136 t.Fatalf("expected %s, got %s", _case.ExpectedReduced, reduced)
141 func TestAddDropManyTorrents(t *testing.T) {
142 cl, err := NewClient(TestingConfig())
143 require.NoError(t, err)
145 for i := range iter.N(1000) {
147 binary.PutVarint(spec.InfoHash[:], int64(i))
148 tt, new, err := cl.AddTorrentSpec(&spec)
149 assert.NoError(t, err)
155 func fileCachePieceResourceStorage(fc *filecache.Cache) storage.ClientImpl {
156 return storage.NewResourcePieces(fc.AsResourceProvider())
159 func TestMergingTrackersByAddingSpecs(t *testing.T) {
160 cl, err := NewClient(TestingConfig())
161 require.NoError(t, err)
163 spec := TorrentSpec{}
164 T, new, _ := cl.AddTorrentSpec(&spec)
168 spec.Trackers = [][]string{{"http://a"}, {"udp://b"}}
169 _, new, _ = cl.AddTorrentSpec(&spec)
171 assert.EqualValues(t, [][]string{{"http://a"}, {"udp://b"}}, T.metainfo.AnnounceList)
172 // Because trackers are disabled in TestingConfig.
173 assert.EqualValues(t, 0, len(T.trackerAnnouncers))
176 // We read from a piece which is marked completed, but is missing data.
177 func TestCompletedPieceWrongSize(t *testing.T) {
178 cfg := TestingConfig()
179 cfg.DefaultStorage = badStorage{}
180 cl, err := NewClient(cfg)
181 require.NoError(t, err)
183 info := metainfo.Info{
185 Pieces: make([]byte, 20),
186 Files: []metainfo.FileInfo{
187 {Path: []string{"greeting"}, Length: 13},
190 b, err := bencode.Marshal(info)
191 require.NoError(t, err)
192 tt, new, err := cl.AddTorrentSpec(&TorrentSpec{
194 InfoHash: metainfo.HashBytes(b),
196 require.NoError(t, err)
201 b, err = ioutil.ReadAll(r)
203 assert.NoError(t, err)
206 func BenchmarkAddLargeTorrent(b *testing.B) {
207 cfg := TestingConfig()
208 cfg.DisableTCP = true
209 cfg.DisableUTP = true
210 cl, err := NewClient(cfg)
211 require.NoError(b, err)
214 for range iter.N(b.N) {
215 t, err := cl.AddTorrentFromFile("testdata/bootstrap.dat.torrent")
223 func TestResponsive(t *testing.T) {
224 seederDataDir, mi := testutil.GreetingTestTorrent()
225 defer os.RemoveAll(seederDataDir)
226 cfg := TestingConfig()
228 cfg.DataDir = seederDataDir
229 seeder, err := NewClient(cfg)
232 seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
233 seederTorrent.VerifyData()
234 leecherDataDir, err := ioutil.TempDir("", "")
236 defer os.RemoveAll(leecherDataDir)
237 cfg = TestingConfig()
238 cfg.DataDir = leecherDataDir
239 leecher, err := NewClient(cfg)
241 defer leecher.Close()
242 leecherTorrent, _, _ := leecher.AddTorrentSpec(func() (ret *TorrentSpec) {
243 ret = TorrentSpecFromMetaInfo(mi)
247 leecherTorrent.AddClientPeer(seeder)
248 reader := leecherTorrent.NewReader()
250 reader.SetReadahead(0)
251 reader.SetResponsive()
253 _, err = reader.Seek(3, io.SeekStart)
254 require.NoError(t, err)
255 _, err = io.ReadFull(reader, b)
257 assert.EqualValues(t, "lo", string(b))
258 _, err = reader.Seek(11, io.SeekStart)
259 require.NoError(t, err)
260 n, err := io.ReadFull(reader, b)
262 assert.EqualValues(t, 2, n)
263 assert.EqualValues(t, "d\n", string(b))
266 func TestTorrentDroppedDuringResponsiveRead(t *testing.T) {
267 seederDataDir, mi := testutil.GreetingTestTorrent()
268 defer os.RemoveAll(seederDataDir)
269 cfg := TestingConfig()
271 cfg.DataDir = seederDataDir
272 seeder, err := NewClient(cfg)
275 seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
276 seederTorrent.VerifyData()
277 leecherDataDir, err := ioutil.TempDir("", "")
279 defer os.RemoveAll(leecherDataDir)
280 cfg = TestingConfig()
281 cfg.DataDir = leecherDataDir
282 leecher, err := NewClient(cfg)
284 defer leecher.Close()
285 leecherTorrent, _, _ := leecher.AddTorrentSpec(func() (ret *TorrentSpec) {
286 ret = TorrentSpecFromMetaInfo(mi)
290 leecherTorrent.AddClientPeer(seeder)
291 reader := leecherTorrent.NewReader()
293 reader.SetReadahead(0)
294 reader.SetResponsive()
296 _, err = reader.Seek(3, io.SeekStart)
297 require.NoError(t, err)
298 _, err = io.ReadFull(reader, b)
300 assert.EqualValues(t, "lo", string(b))
301 go leecherTorrent.Drop()
302 _, err = reader.Seek(11, io.SeekStart)
303 require.NoError(t, err)
304 n, err := reader.Read(b)
305 assert.EqualError(t, err, "torrent closed")
306 assert.EqualValues(t, 0, n)
309 func TestDHTInheritBlocklist(t *testing.T) {
310 ipl := iplist.New(nil)
311 require.NotNil(t, ipl)
312 cfg := TestingConfig()
313 cfg.IPBlocklist = ipl
315 cl, err := NewClient(cfg)
316 require.NoError(t, err)
319 cl.eachDhtServer(func(s *dht.Server) {
320 assert.Equal(t, ipl, s.IPBlocklist())
323 assert.EqualValues(t, 2, numServers)
326 // Check that stuff is merged in subsequent AddTorrentSpec for the same
328 func TestAddTorrentSpecMerging(t *testing.T) {
329 cl, err := NewClient(TestingConfig())
330 require.NoError(t, err)
332 dir, mi := testutil.GreetingTestTorrent()
333 defer os.RemoveAll(dir)
334 tt, new, err := cl.AddTorrentSpec(&TorrentSpec{
335 InfoHash: mi.HashInfoBytes(),
337 require.NoError(t, err)
339 require.Nil(t, tt.Info())
340 _, new, err = cl.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
341 require.NoError(t, err)
342 require.False(t, new)
343 require.NotNil(t, tt.Info())
346 func TestTorrentDroppedBeforeGotInfo(t *testing.T) {
347 dir, mi := testutil.GreetingTestTorrent()
349 cl, _ := NewClient(TestingConfig())
351 tt, _, _ := cl.AddTorrentSpec(&TorrentSpec{
352 InfoHash: mi.HashInfoBytes(),
355 assert.EqualValues(t, 0, len(cl.Torrents()))
363 func writeTorrentData(ts *storage.Torrent, info metainfo.Info, b []byte) {
364 for i := range iter.N(info.NumPieces()) {
366 ts.Piece(p).WriteAt(b[p.Offset():p.Offset()+p.Length()], 0)
370 func testAddTorrentPriorPieceCompletion(t *testing.T, alreadyCompleted bool, csf func(*filecache.Cache) storage.ClientImpl) {
371 fileCacheDir, err := ioutil.TempDir("", "")
372 require.NoError(t, err)
373 defer os.RemoveAll(fileCacheDir)
374 fileCache, err := filecache.NewCache(fileCacheDir)
375 require.NoError(t, err)
376 greetingDataTempDir, greetingMetainfo := testutil.GreetingTestTorrent()
377 defer os.RemoveAll(greetingDataTempDir)
378 filePieceStore := csf(fileCache)
379 defer filePieceStore.Close()
380 info, err := greetingMetainfo.UnmarshalInfo()
381 require.NoError(t, err)
382 ih := greetingMetainfo.HashInfoBytes()
383 greetingData, err := storage.NewClient(filePieceStore).OpenTorrent(&info, ih)
384 require.NoError(t, err)
385 writeTorrentData(greetingData, info, []byte(testutil.GreetingFileContents))
386 // require.Equal(t, len(testutil.GreetingFileContents), written)
387 // require.NoError(t, err)
388 for i := 0; i < info.NumPieces(); i++ {
390 if alreadyCompleted {
391 require.NoError(t, greetingData.Piece(p).MarkComplete())
394 cfg := TestingConfig()
395 // TODO: Disable network option?
396 cfg.DisableTCP = true
397 cfg.DisableUTP = true
398 cfg.DefaultStorage = filePieceStore
399 cl, err := NewClient(cfg)
400 require.NoError(t, err)
402 tt, err := cl.AddTorrent(greetingMetainfo)
403 require.NoError(t, err)
404 psrs := tt.PieceStateRuns()
405 assert.Len(t, psrs, 1)
406 assert.EqualValues(t, 3, psrs[0].Length)
407 assert.Equal(t, alreadyCompleted, psrs[0].Complete)
408 if alreadyCompleted {
410 b, err := ioutil.ReadAll(r)
411 assert.NoError(t, err)
412 assert.EqualValues(t, testutil.GreetingFileContents, b)
416 func TestAddTorrentPiecesAlreadyCompleted(t *testing.T) {
417 testAddTorrentPriorPieceCompletion(t, true, fileCachePieceResourceStorage)
420 func TestAddTorrentPiecesNotAlreadyCompleted(t *testing.T) {
421 testAddTorrentPriorPieceCompletion(t, false, fileCachePieceResourceStorage)
424 func TestAddMetainfoWithNodes(t *testing.T) {
425 cfg := TestingConfig()
426 cfg.ListenHost = func(string) string { return "" }
428 cfg.DhtStartingNodes = func() ([]dht.Addr, error) { return nil, nil }
429 // For now, we want to just jam the nodes into the table, without
430 // verifying them first. Also the DHT code doesn't support mixing secure
431 // and insecure nodes if security is enabled (yet).
432 // cfg.DHTConfig.NoSecurity = true
433 cl, err := NewClient(cfg)
434 require.NoError(t, err)
436 sum := func() (ret int64) {
437 cl.eachDhtServer(func(s *dht.Server) {
438 ret += s.Stats().OutboundQueriesAttempted
442 assert.EqualValues(t, 0, sum())
443 tt, err := cl.AddTorrentFromFile("metainfo/testdata/issue_65a.torrent")
444 require.NoError(t, err)
445 // Nodes are not added or exposed in Torrent's metainfo. We just randomly
446 // check if the announce-list is here instead. TODO: Add nodes.
447 assert.Len(t, tt.metainfo.AnnounceList, 5)
448 // There are 6 nodes in the torrent file.
449 for sum() != int64(6*len(cl.dhtServers)) {
450 time.Sleep(time.Millisecond)
454 type testDownloadCancelParams struct {
455 SetLeecherStorageCapacity bool
456 LeecherStorageCapacity int64
460 func testDownloadCancel(t *testing.T, ps testDownloadCancelParams) {
461 greetingTempDir, mi := testutil.GreetingTestTorrent()
462 defer os.RemoveAll(greetingTempDir)
463 cfg := TestingConfig()
465 cfg.DataDir = greetingTempDir
466 seeder, err := NewClient(cfg)
467 require.NoError(t, err)
469 defer testutil.ExportStatusWriter(seeder, "s")()
470 seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
471 seederTorrent.VerifyData()
472 leecherDataDir, err := ioutil.TempDir("", "")
473 require.NoError(t, err)
474 defer os.RemoveAll(leecherDataDir)
475 fc, err := filecache.NewCache(leecherDataDir)
476 require.NoError(t, err)
477 if ps.SetLeecherStorageCapacity {
478 fc.SetCapacity(ps.LeecherStorageCapacity)
480 cfg.DefaultStorage = storage.NewResourcePieces(fc.AsResourceProvider())
481 cfg.DataDir = leecherDataDir
482 leecher, err := NewClient(cfg)
483 require.NoError(t, err)
484 defer leecher.Close()
485 defer testutil.ExportStatusWriter(leecher, "l")()
486 leecherGreeting, new, err := leecher.AddTorrentSpec(func() (ret *TorrentSpec) {
487 ret = TorrentSpecFromMetaInfo(mi)
491 require.NoError(t, err)
493 psc := leecherGreeting.SubscribePieceStateChanges()
496 leecherGreeting.cl.lock()
497 leecherGreeting.downloadPiecesLocked(0, leecherGreeting.numPieces())
499 leecherGreeting.cancelPiecesLocked(0, leecherGreeting.NumPieces())
501 leecherGreeting.cl.unlock()
502 done := make(chan struct{})
504 go leecherGreeting.AddClientPeer(seeder)
505 completes := make(map[int]bool, 3)
506 expected := func() map[int]bool {
508 return map[int]bool{0: false, 1: false, 2: false}
510 return map[int]bool{0: true, 1: true, 2: true}
513 for !reflect.DeepEqual(completes, expected) {
515 v := _v.(PieceStateChange)
516 completes[v.Index] = v.Complete
520 func TestTorrentDownloadAll(t *testing.T) {
521 testDownloadCancel(t, testDownloadCancelParams{})
524 func TestTorrentDownloadAllThenCancel(t *testing.T) {
525 testDownloadCancel(t, testDownloadCancelParams{
530 // Ensure that it's an error for a peer to send an invalid have message.
531 func TestPeerInvalidHave(t *testing.T) {
532 cl, err := NewClient(TestingConfig())
533 require.NoError(t, err)
535 info := metainfo.Info{
537 Pieces: make([]byte, 20),
538 Files: []metainfo.FileInfo{{Length: 1}},
540 infoBytes, err := bencode.Marshal(info)
541 require.NoError(t, err)
542 tt, _new, err := cl.AddTorrentSpec(&TorrentSpec{
543 InfoBytes: infoBytes,
544 InfoHash: metainfo.HashBytes(infoBytes),
545 Storage: badStorage{},
547 require.NoError(t, err)
553 assert.NoError(t, cn.peerSentHave(0))
554 assert.Error(t, cn.peerSentHave(1))
557 func TestPieceCompletedInStorageButNotClient(t *testing.T) {
558 greetingTempDir, greetingMetainfo := testutil.GreetingTestTorrent()
559 defer os.RemoveAll(greetingTempDir)
560 cfg := TestingConfig()
561 cfg.DataDir = greetingTempDir
562 seeder, err := NewClient(TestingConfig())
563 require.NoError(t, err)
564 seeder.AddTorrentSpec(&TorrentSpec{
565 InfoBytes: greetingMetainfo.InfoBytes,
569 // Check that when the listen port is 0, all the protocols listened on have
570 // the same port, and it isn't zero.
571 func TestClientDynamicListenPortAllProtocols(t *testing.T) {
572 cl, err := NewClient(TestingConfig())
573 require.NoError(t, err)
575 port := cl.LocalPort()
576 assert.NotEqual(t, 0, port)
577 cl.eachListener(func(s Listener) bool {
578 assert.Equal(t, port, missinggo.AddrPort(s.Addr()))
583 func TestClientDynamicListenTCPOnly(t *testing.T) {
584 cfg := TestingConfig()
585 cfg.DisableUTP = true
586 cfg.DisableTCP = false
587 cl, err := NewClient(cfg)
588 require.NoError(t, err)
590 assert.NotEqual(t, 0, cl.LocalPort())
593 func TestClientDynamicListenUTPOnly(t *testing.T) {
594 cfg := TestingConfig()
595 cfg.DisableTCP = true
596 cfg.DisableUTP = false
597 cl, err := NewClient(cfg)
598 require.NoError(t, err)
600 assert.NotEqual(t, 0, cl.LocalPort())
603 func totalConns(tts []*Torrent) (ret int) {
604 for _, tt := range tts {
612 func TestSetMaxEstablishedConn(t *testing.T) {
614 ih := testutil.GreetingMetaInfo().HashInfoBytes()
615 cfg := TestingConfig()
616 cfg.DisableAcceptRateLimiting = true
617 cfg.dropDuplicatePeerIds = true
618 for i := range iter.N(3) {
619 cl, err := NewClient(cfg)
620 require.NoError(t, err)
622 tt, _ := cl.AddTorrentInfoHash(ih)
623 tt.SetMaxEstablishedConns(2)
624 defer testutil.ExportStatusWriter(cl, fmt.Sprintf("%d", i))()
625 tts = append(tts, tt)
628 for _, tt := range tts {
629 for _, _tt := range tts {
631 tt.AddClientPeer(_tt.cl)
636 waitTotalConns := func(num int) {
637 for totalConns(tts) != num {
639 time.Sleep(time.Millisecond)
644 tts[0].SetMaxEstablishedConns(1)
646 tts[0].SetMaxEstablishedConns(0)
648 tts[0].SetMaxEstablishedConns(1)
651 tts[0].SetMaxEstablishedConns(2)
656 // Creates a file containing its own name as data. Make a metainfo from that, adds it to the given
657 // client, and returns a magnet link.
658 func makeMagnet(t *testing.T, cl *Client, dir string, name string) string {
659 os.MkdirAll(dir, 0770)
660 file, err := os.Create(filepath.Join(dir, name))
661 require.NoError(t, err)
662 file.Write([]byte(name))
664 mi := metainfo.MetaInfo{}
666 info := metainfo.Info{PieceLength: 256 * 1024}
667 err = info.BuildFromFilePath(filepath.Join(dir, name))
668 require.NoError(t, err)
669 mi.InfoBytes, err = bencode.Marshal(info)
670 require.NoError(t, err)
671 magnet := mi.Magnet(name, mi.HashInfoBytes()).String()
672 tr, err := cl.AddTorrent(&mi)
673 require.NoError(t, err)
674 require.True(t, tr.Seeding())
679 // https://github.com/anacrolix/torrent/issues/114
680 func TestMultipleTorrentsWithEncryption(t *testing.T) {
681 testSeederLeecherPair(
683 func(cfg *ClientConfig) {
684 cfg.HeaderObfuscationPolicy.Preferred = true
685 cfg.HeaderObfuscationPolicy.RequirePreferred = true
687 func(cfg *ClientConfig) {
688 cfg.HeaderObfuscationPolicy.RequirePreferred = false
693 // Test that the leecher can download a torrent in its entirety from the seeder. Note that the
694 // seeder config is done first.
695 func testSeederLeecherPair(t *testing.T, seeder func(*ClientConfig), leecher func(*ClientConfig)) {
696 cfg := TestingConfig()
698 cfg.DataDir = filepath.Join(cfg.DataDir, "server")
699 os.Mkdir(cfg.DataDir, 0755)
701 server, err := NewClient(cfg)
702 require.NoError(t, err)
704 defer testutil.ExportStatusWriter(server, "s")()
705 magnet1 := makeMagnet(t, server, cfg.DataDir, "test1")
706 // Extra torrents are added to test the seeder having to match incoming obfuscated headers
707 // against more than one torrent. See issue #114
708 makeMagnet(t, server, cfg.DataDir, "test2")
709 for i := 0; i < 100; i++ {
710 makeMagnet(t, server, cfg.DataDir, fmt.Sprintf("test%d", i+2))
712 cfg = TestingConfig()
713 cfg.DataDir = filepath.Join(cfg.DataDir, "client")
715 client, err := NewClient(cfg)
716 require.NoError(t, err)
718 defer testutil.ExportStatusWriter(client, "c")()
719 tr, err := client.AddMagnet(magnet1)
720 require.NoError(t, err)
721 tr.AddClientPeer(server)
727 // This appears to be the situation with the S3 BitTorrent client.
728 func TestObfuscatedHeaderFallbackSeederDisallowsLeecherPrefers(t *testing.T) {
729 // Leecher prefers obfuscation, but the seeder does not allow it.
730 testSeederLeecherPair(
732 func(cfg *ClientConfig) {
733 cfg.HeaderObfuscationPolicy.Preferred = false
734 cfg.HeaderObfuscationPolicy.RequirePreferred = true
736 func(cfg *ClientConfig) {
737 cfg.HeaderObfuscationPolicy.Preferred = true
738 cfg.HeaderObfuscationPolicy.RequirePreferred = false
743 func TestObfuscatedHeaderFallbackSeederRequiresLeecherPrefersNot(t *testing.T) {
744 // Leecher prefers no obfuscation, but the seeder enforces it.
745 testSeederLeecherPair(
747 func(cfg *ClientConfig) {
748 cfg.HeaderObfuscationPolicy.Preferred = true
749 cfg.HeaderObfuscationPolicy.RequirePreferred = true
751 func(cfg *ClientConfig) {
752 cfg.HeaderObfuscationPolicy.Preferred = false
753 cfg.HeaderObfuscationPolicy.RequirePreferred = false
758 func TestClientAddressInUse(t *testing.T) {
759 s, _ := NewUtpSocket("udp", ":50007", nil)
763 cfg := TestingConfig().SetListenAddr(":50007")
764 cl, err := NewClient(cfg)
765 require.Error(t, err)
769 func TestClientHasDhtServersWhenUtpDisabled(t *testing.T) {
770 cc := TestingConfig()
773 cl, err := NewClient(cc)
774 require.NoError(t, err)
776 assert.NotEmpty(t, cl.DhtServers())
779 func TestIssue335(t *testing.T) {
780 dir, mi := testutil.GreetingTestTorrent()
781 defer os.RemoveAll(dir)
782 cfg := TestingConfig()
786 comp, err := storage.NewBoltPieceCompletion(dir)
787 require.NoError(t, err)
789 cfg.DefaultStorage = storage.NewMMapWithCompletion(dir, comp)
790 cl, err := NewClient(cfg)
791 require.NoError(t, err)
793 tor, new, err := cl.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
794 require.NoError(t, err)
796 require.True(t, cl.WaitAll())
798 _, new, err = cl.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
799 require.NoError(t, err)
801 require.True(t, cl.WaitAll())
804 func TestClientDisabledImplicitNetworksButDhtEnabled(t *testing.T) {
805 cfg := TestingConfig()
806 cfg.DisableTCP = true
807 cfg.DisableUTP = true
809 cl, err := NewClient(cfg)
810 require.NoError(t, err)
812 assert.Empty(t, cl.listeners)
813 assert.NotEmpty(t, cl.DhtServers())