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
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)
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)
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
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
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("", "")
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
}
func TestSetMaxEstablishedConn(t *testing.T) {
- ss := testutil.NewStatusServer(t)
- defer ss.Close()
var tts []*Torrent
ih := testutil.GreetingMetaInfo().HashInfoBytes()
cfg := TestingConfig()
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() {
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()
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)
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()
-}