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