]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Rework status export in tests to allow count > 1 without a server for every test
authorMatt Joiner <anacrolix@gmail.com>
Tue, 26 Jun 2018 09:54:48 +0000 (19:54 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Tue, 26 Jun 2018 09:54:48 +0000 (19:54 +1000)
.circleci/config.yml
client_test.go
fs/torrentfs_test.go
internal/testutil/status_writer.go

index d01aafdc68763cb556e933f691ae86442e7c1d6e..464d417e9aa94404796946a3f8a0d9558547af86 100644 (file)
@@ -22,7 +22,7 @@ jobs:
       - run: sudo apt-get update
       - run: sudo apt install fuse pv
       - run: go get -t -d -v -race $PROJECT_GO_PACKAGE/...
-      - run: go test -v -race $PROJECT_GO_PACKAGE/...
+      - run: go test -v -race $PROJECT_GO_PACKAGE/... -count 2
       - run: go test -bench . $PROJECT_GO_PACKAGE/...
       - run: CGO_ENABLED=0 go get -t -d -v $PROJECT_GO_PACKAGE/...
       - run: set +e; CGO_ENABLED=0 go test -v $PROJECT_GO_PACKAGE/...; true
index 7921f90cd6500aebe020547e6539c6745e4eef59..76893d7303402f78fdd3d376a086f3c477606388 100644 (file)
@@ -311,7 +311,7 @@ func testClientTransfer(t *testing.T, ps testClientTransferParams) {
        seeder, err := NewClient(cfg)
        require.NoError(t, err)
        if ps.ExportClientStatus {
-               testutil.ExportStatusWriter(seeder, "s")
+               defer testutil.ExportStatusWriter(seeder, "s")()
        }
        seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
        // Run a Stats right after Closing the Client. This will trigger the Stats
@@ -337,7 +337,7 @@ func testClientTransfer(t *testing.T, ps testClientTransferParams) {
        require.NoError(t, err)
        defer leecher.Close()
        if ps.ExportClientStatus {
-               testutil.ExportStatusWriter(leecher, "l")
+               defer testutil.ExportStatusWriter(leecher, "l")()
        }
        leecherTorrent, new, err := leecher.AddTorrentSpec(func() (ret *TorrentSpec) {
                ret = TorrentSpecFromMetaInfo(mi)
@@ -396,7 +396,7 @@ func TestSeedAfterDownloading(t *testing.T) {
        seeder, err := NewClient(cfg)
        require.NoError(t, err)
        defer seeder.Close()
-       testutil.ExportStatusWriter(seeder, "s")
+       defer testutil.ExportStatusWriter(seeder, "s")()
        seederTorrent, ok, err := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
        require.NoError(t, err)
        assert.True(t, ok)
@@ -410,7 +410,7 @@ func TestSeedAfterDownloading(t *testing.T) {
        leecher, err := NewClient(cfg)
        require.NoError(t, err)
        defer leecher.Close()
-       testutil.ExportStatusWriter(leecher, "l")
+       defer testutil.ExportStatusWriter(leecher, "l")()
 
        cfg = TestingConfig()
        cfg.Seed = false
@@ -420,7 +420,7 @@ func TestSeedAfterDownloading(t *testing.T) {
        leecherLeecher, _ := NewClient(cfg)
        require.NoError(t, err)
        defer leecherLeecher.Close()
-       testutil.ExportStatusWriter(leecherLeecher, "ll")
+       defer testutil.ExportStatusWriter(leecherLeecher, "ll")()
        leecherGreeting, ok, err := leecher.AddTorrentSpec(func() (ret *TorrentSpec) {
                ret = TorrentSpecFromMetaInfo(mi)
                ret.ChunkSize = 2
@@ -769,7 +769,7 @@ func testDownloadCancel(t *testing.T, ps testDownloadCancelParams) {
        seeder, err := NewClient(cfg)
        require.NoError(t, err)
        defer seeder.Close()
-       testutil.ExportStatusWriter(seeder, "s")
+       defer testutil.ExportStatusWriter(seeder, "s")()
        seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
        seederTorrent.VerifyData()
        leecherDataDir, err := ioutil.TempDir("", "")
@@ -784,7 +784,7 @@ func testDownloadCancel(t *testing.T, ps testDownloadCancelParams) {
        cfg.DataDir = leecherDataDir
        leecher, _ := NewClient(cfg)
        defer leecher.Close()
-       testutil.ExportStatusWriter(leecher, "l")
+       defer testutil.ExportStatusWriter(leecher, "l")()
        leecherGreeting, new, err := leecher.AddTorrentSpec(func() (ret *TorrentSpec) {
                ret = TorrentSpecFromMetaInfo(mi)
                ret.ChunkSize = 2
@@ -930,8 +930,6 @@ func totalConns(tts []*Torrent) (ret int) {
 }
 
 func TestSetMaxEstablishedConn(t *testing.T) {
-       ss := testutil.NewStatusServer(t)
-       defer ss.Close()
        var tts []*Torrent
        ih := testutil.GreetingMetaInfo().HashInfoBytes()
        cfg := TestingConfig()
@@ -943,7 +941,7 @@ func TestSetMaxEstablishedConn(t *testing.T) {
                defer cl.Close()
                tt, _ := cl.AddTorrentInfoHash(ih)
                tt.SetMaxEstablishedConns(2)
-               ss.HandleStatusWriter(cl, fmt.Sprintf("/%d", i))
+               defer testutil.ExportStatusWriter(cl, fmt.Sprintf("%d", i))()
                tts = append(tts, tt)
        }
        addPeers := func() {
@@ -1007,7 +1005,7 @@ func TestMultipleTorrentsWithEncryption(t *testing.T) {
        server, err := NewClient(cfg)
        require.NoError(t, err)
        defer server.Close()
-       testutil.ExportStatusWriter(server, "s")
+       defer testutil.ExportStatusWriter(server, "s")()
        magnet1 := makeMagnet(t, server, cfg.DataDir, "test1")
        makeMagnet(t, server, cfg.DataDir, "test2")
        cfg = TestingConfig()
@@ -1017,7 +1015,7 @@ func TestMultipleTorrentsWithEncryption(t *testing.T) {
        client, err := NewClient(cfg)
        require.NoError(t, err)
        defer client.Close()
-       testutil.ExportStatusWriter(client, "c")
+       defer testutil.ExportStatusWriter(client, "c")()
        tr, err := client.AddMagnet(magnet1)
        require.NoError(t, err)
        tr.AddClientPeer(server)
index 8ac69bb70731e7285a6fa7a85c7f995e8ca9e106..fb326cc52ecba1f6d68b068b99e008c7c3957ac5 100644 (file)
@@ -174,7 +174,7 @@ func TestDownloadOnDemand(t *testing.T) {
        seeder, err := torrent.NewClient(cfg)
        require.NoError(t, err)
        defer seeder.Close()
-       testutil.ExportStatusWriter(seeder, "s")
+       defer testutil.ExportStatusWriter(seeder, "s")()
        // Just to mix things up, the seeder starts with the data, but the leecher
        // starts with the metainfo.
        seederTorrent, err := seeder.AddMagnet(fmt.Sprintf("magnet:?xt=urn:btih:%s", layout.Metainfo.HashInfoBytes().HexString()))
index 0266e3eba856efee21e4765c3a358f94ddde79f2..5ce66c612865b98d5f12c302973aa3bc93d1ad8f 100644 (file)
@@ -3,51 +3,50 @@ package testutil
 import (
        "fmt"
        "io"
-       "log"
-       "net"
        "net/http"
-       "testing"
+       "sync"
 
        "github.com/anacrolix/missinggo"
-       "github.com/stretchr/testify/require"
 )
 
 type StatusWriter interface {
        WriteStatus(io.Writer)
 }
 
-// Use StatusServer instead to allow -count > 1 when testing.
-func ExportStatusWriter(sw StatusWriter, path string) {
+// The key is the route pattern. The value is nil when the resource is
+// released.
+var (
+       mu  sync.Mutex
+       sws = map[string]StatusWriter{}
+)
+
+func ExportStatusWriter(sw StatusWriter, path string) (release func()) {
+       pattern := fmt.Sprintf("/%s/%s", missinggo.GetTestName(), path)
+       release = func() {
+               mu.Lock()
+               defer mu.Unlock()
+               sws[pattern] = nil
+       }
+       mu.Lock()
+       defer mu.Unlock()
+       if curSw, ok := sws[pattern]; ok {
+               if curSw != nil {
+                       panic(fmt.Sprintf("%q still in use", pattern))
+               }
+               sws[pattern] = sw
+               return
+       }
        http.HandleFunc(
-               fmt.Sprintf("/%s/%s", missinggo.GetTestName(), path),
+               pattern,
                func(w http.ResponseWriter, r *http.Request) {
+                       sw := sws[pattern]
+                       if sw == nil {
+                               http.NotFound(w, r)
+                               return
+                       }
                        sw.WriteStatus(w)
                },
        )
-}
-
-type StatusServer struct {
-       sm http.ServeMux
-       l  net.Listener
-}
-
-func NewStatusServer(t *testing.T) (ret *StatusServer) {
-       l, err := net.Listen("tcp", "localhost:0")
-       require.NoError(t, err)
-       ret = &StatusServer{
-               l: l,
-       }
-       log.Printf("serving status at %q", l.Addr())
-       go http.Serve(l, &ret.sm)
+       sws[pattern] = sw
        return
 }
-
-func (me *StatusServer) HandleStatusWriter(sw StatusWriter, path string) {
-       me.sm.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
-               sw.WriteStatus(w)
-       })
-}
-
-func (me StatusServer) Close() {
-       me.l.Close()
-}