]> Sergey Matveev's repositories - btrtrc.git/commitdiff
fs: Improve tests
authorMatt Joiner <anacrolix@gmail.com>
Wed, 3 Dec 2014 18:53:10 +0000 (12:53 -0600)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 3 Dec 2014 18:53:10 +0000 (12:53 -0600)
fs/torrentfs.go
fs/torrentfs_test.go

index 6fd721b71a4fcefabb45f5870a7e1608cd71a2d4..fd9cb0599a97cb2897bb84a969e11fef02590caa 100644 (file)
@@ -25,9 +25,11 @@ var (
 )
 
 type TorrentFS struct {
-       Client    *torrent.Client
-       destroyed chan struct{}
-       mu        sync.Mutex
+       Client       *torrent.Client
+       destroyed    chan struct{}
+       mu           sync.Mutex
+       blockedReads int
+       event        sync.Cond
 }
 
 var (
@@ -73,6 +75,10 @@ func (n *node) fsPath() string {
 }
 
 func blockingRead(fs *TorrentFS, t torrent.Torrent, off int64, p []byte, intr fusefs.Intr) (n int, err fuse.Error) {
+       fs.mu.Lock()
+       fs.blockedReads++
+       fs.event.Broadcast()
+       fs.mu.Unlock()
        var (
                _n   int
                _err fuse.Error
@@ -91,6 +97,10 @@ func blockingRead(fs *TorrentFS, t torrent.Torrent, off int64, p []byte, intr fu
        case <-intr:
                err = fuse.EINTR
        }
+       fs.mu.Lock()
+       fs.blockedReads--
+       fs.event.Broadcast()
+       fs.mu.Unlock()
        return
 }
 
@@ -296,5 +306,6 @@ func New(cl *torrent.Client) *TorrentFS {
                Client:    cl,
                destroyed: make(chan struct{}),
        }
+       fs.event.L = &fs.mu
        return fs
 }
index 2f9c79fb87d0ddd6481403ae340f55b41ddd8bb6..52591aedd1ea396a860d5c7972cae7cadd8cfde3 100644 (file)
@@ -77,6 +77,8 @@ func newGreetingLayout() (tl testLayout, err error) {
        return
 }
 
+// Unmount without first killing the FUSE connection while there are FUSE
+// operations blocked inside the filesystem code.
 func TestUnmountWedged(t *testing.T) {
        layout, err := newGreetingLayout()
        if err != nil {
@@ -96,7 +98,7 @@ func TestUnmountWedged(t *testing.T) {
                NoDefaultBlocklist: true,
        })
        defer client.Stop()
-       log.Printf("%+v", *layout.Metainfo)
+       t.Logf("%+v", *layout.Metainfo)
        client.AddTorrent(layout.Metainfo)
        fs := New(client)
        fuseConn, err := fuse.Mount(layout.MountDir)
@@ -106,32 +108,50 @@ func TestUnmountWedged(t *testing.T) {
                }
                t.Fatal(err)
        }
+       <-fuseConn.Ready
+       if err := fuseConn.MountError; err != nil {
+               t.Fatal(err)
+       }
        go func() {
                server := fusefs.Server{
                        FS: fs,
                        Debug: func(msg interface{}) {
-                               log.Print(msg)
+                               t.Log(msg)
                        },
                }
                server.Serve(fuseConn)
        }()
-       <-fuseConn.Ready
-       if err := fuseConn.MountError; err != nil {
-               log.Fatal(err)
-       }
+       // Read the greeting file, though it will never be available. This should
+       // "wedge" FUSE, requiring the fs object to be forcibly destroyed. The
+       // read call will return with a FS error.
        go func() {
-               ioutil.ReadFile(filepath.Join(layout.MountDir, layout.Metainfo.Info.Name))
+               _, err := ioutil.ReadFile(filepath.Join(layout.MountDir, layout.Metainfo.Info.Name))
+               if err == nil {
+                       t.Fatal("expected error reading greeting")
+               }
        }()
-       // time.Sleep(time.Second)
+
+       // Wait until the read has blocked inside the filesystem code.
+       fs.mu.Lock()
+       for fs.blockedReads != 1 {
+               fs.event.Wait()
+       }
+       fs.mu.Unlock()
+
        fs.Destroy()
-       // time.Sleep(time.Second)
-       err = fuse.Unmount(layout.MountDir)
-       if err != nil {
-               log.Print(err)
+
+       for {
+               err = fuse.Unmount(layout.MountDir)
+               if err != nil {
+                       t.Logf("error unmounting: %s", err)
+               } else {
+                       break
+               }
        }
+
        err = fuseConn.Close()
        if err != nil {
-               t.Log(err)
+               t.Fatalf("error closing fuse conn: %s", err)
        }
 }
 
@@ -140,6 +160,7 @@ func TestDownloadOnDemand(t *testing.T) {
        if err != nil {
                t.Fatal(err)
        }
+       defer layout.Destroy()
        seeder, err := torrent.NewClient(&torrent.Config{
                DataDir:         layout.Completed,
                DisableTrackers: true,