]> Sergey Matveev's repositories - btrtrc.git/blob - fs/torrentfs_test.go
Add magnet-metainfo, tool to download magnet to torrent file
[btrtrc.git] / fs / torrentfs_test.go
1 package torrentfs
2
3 import (
4         "bytes"
5         "fmt"
6         "io/ioutil"
7         "log"
8         "net"
9         "net/http"
10         _ "net/http/pprof"
11         "os"
12         "path/filepath"
13         "testing"
14         "time"
15
16         "bitbucket.org/anacrolix/go.torrent"
17         "bitbucket.org/anacrolix/go.torrent/testutil"
18         "bitbucket.org/anacrolix/go.torrent/util"
19         "github.com/anacrolix/libtorgo/metainfo"
20
21         "bazil.org/fuse"
22         fusefs "bazil.org/fuse/fs"
23 )
24
25 func init() {
26         go http.ListenAndServe(":6061", nil)
27 }
28
29 func TestTCPAddrString(t *testing.T) {
30         ta := &net.TCPAddr{
31                 IP:   net.IPv4(127, 0, 0, 1),
32                 Port: 3000,
33         }
34         s := ta.String()
35         l, err := net.Listen("tcp4", "localhost:3000")
36         if err != nil {
37                 t.Fatal(err)
38         }
39         defer l.Close()
40         c, err := net.Dial("tcp", l.Addr().String())
41         if err != nil {
42                 t.Fatal(err)
43         }
44         defer c.Close()
45         ras := c.RemoteAddr().String()
46         if ras != s {
47                 t.FailNow()
48         }
49 }
50
51 type testLayout struct {
52         BaseDir   string
53         MountDir  string
54         Completed string
55         Metainfo  *metainfo.MetaInfo
56 }
57
58 func (me *testLayout) Destroy() error {
59         return os.RemoveAll(me.BaseDir)
60 }
61
62 func newGreetingLayout() (tl testLayout, err error) {
63         tl.BaseDir, err = ioutil.TempDir("", "torrentfs")
64         if err != nil {
65                 return
66         }
67         tl.Completed = filepath.Join(tl.BaseDir, "completed")
68         os.Mkdir(tl.Completed, 0777)
69         tl.MountDir = filepath.Join(tl.BaseDir, "mnt")
70         os.Mkdir(tl.MountDir, 0777)
71         name := testutil.CreateDummyTorrentData(tl.Completed)
72         metaInfoBuf := &bytes.Buffer{}
73         testutil.CreateMetaInfo(name, metaInfoBuf)
74         tl.Metainfo, err = metainfo.Load(metaInfoBuf)
75         log.Printf("%x", tl.Metainfo.Info.Pieces)
76         return
77 }
78
79 func TestUnmountWedged(t *testing.T) {
80         layout, err := newGreetingLayout()
81         if err != nil {
82                 t.Fatal(err)
83         }
84         defer func() {
85                 err := layout.Destroy()
86                 if err != nil {
87                         t.Log(err)
88                 }
89         }()
90         client, err := torrent.NewClient(&torrent.Config{
91                 DataDir:         filepath.Join(layout.BaseDir, "incomplete"),
92                 DisableTrackers: true,
93                 NoDHT:           true,
94         })
95         log.Printf("%+v", *layout.Metainfo)
96         client.AddTorrent(layout.Metainfo)
97         fs := New(client)
98         fuseConn, err := fuse.Mount(layout.MountDir)
99         if err != nil {
100                 t.Fatal(err)
101         }
102         go func() {
103                 server := fusefs.Server{
104                         FS: fs,
105                         Debug: func(msg interface{}) {
106                                 log.Print(msg)
107                         },
108                 }
109                 server.Serve(fuseConn)
110         }()
111         <-fuseConn.Ready
112         if err := fuseConn.MountError; err != nil {
113                 log.Fatal(err)
114         }
115         go func() {
116                 ioutil.ReadFile(filepath.Join(layout.MountDir, layout.Metainfo.Info.Name))
117         }()
118         time.Sleep(time.Second)
119         fs.Destroy()
120         time.Sleep(time.Second)
121         err = fuse.Unmount(layout.MountDir)
122         if err != nil {
123                 log.Print(err)
124         }
125         err = fuseConn.Close()
126         if err != nil {
127                 t.Log(err)
128         }
129 }
130
131 func TestDownloadOnDemand(t *testing.T) {
132         layout, err := newGreetingLayout()
133         if err != nil {
134                 t.Fatal(err)
135         }
136         seeder, err := torrent.NewClient(&torrent.Config{
137                 DataDir:         layout.Completed,
138                 DisableTrackers: true,
139                 NoDHT:           true,
140         })
141         http.HandleFunc("/seeder", func(w http.ResponseWriter, req *http.Request) {
142                 seeder.WriteStatus(w)
143         })
144         defer seeder.Stop()
145         _, err = seeder.AddMagnet(fmt.Sprintf("magnet:?xt=urn:btih:%x", layout.Metainfo.Info.Hash))
146         if err != nil {
147                 t.Fatal(err)
148         }
149         leecher, err := torrent.NewClient(&torrent.Config{
150                 DataDir:          filepath.Join(layout.BaseDir, "download"),
151                 DownloadStrategy: torrent.NewResponsiveDownloadStrategy(0),
152                 DisableTrackers:  true,
153                 NoDHT:            true,
154         })
155         http.HandleFunc("/leecher", func(w http.ResponseWriter, req *http.Request) {
156                 leecher.WriteStatus(w)
157         })
158         defer leecher.Stop()
159         leecher.AddTorrent(layout.Metainfo)
160         var ih torrent.InfoHash
161         util.CopyExact(ih[:], layout.Metainfo.Info.Hash)
162         leecher.AddPeers(ih, []torrent.Peer{func() torrent.Peer {
163                 tcpAddr := seeder.ListenAddr().(*net.TCPAddr)
164                 return torrent.Peer{
165                         IP:   tcpAddr.IP,
166                         Port: tcpAddr.Port,
167                 }
168         }()})
169         fs := New(leecher)
170         mountDir := layout.MountDir
171         fuseConn, err := fuse.Mount(layout.MountDir)
172         if err != nil {
173                 t.Fatal(err)
174         }
175         defer func() {
176                 if err := fuse.Unmount(mountDir); err != nil {
177                         t.Fatal(err)
178                 }
179         }()
180         go func() {
181                 if err := fusefs.Serve(fuseConn, fs); err != nil {
182                         t.Fatal(err)
183                 }
184                 if err := fuseConn.Close(); err != nil {
185                         t.Fatal(err)
186                 }
187         }()
188         <-fuseConn.Ready
189         if fuseConn.MountError != nil {
190                 t.Fatal(fuseConn.MountError)
191         }
192         go func() {
193                 time.Sleep(10 * time.Second)
194                 if err := fuse.Unmount(mountDir); err != nil {
195                         t.Log(err)
196                 }
197         }()
198         content, err := ioutil.ReadFile(filepath.Join(mountDir, "greeting"))
199         if err != nil {
200                 t.Fatal(err)
201         }
202         if string(content) != testutil.GreetingFileContents {
203                 t.FailNow()
204         }
205 }