Skip to content
Permalink
Browse files

Replace polling of buffer with channel to fix detected race

  • Loading branch information...
frioux committed Apr 7, 2019
1 parent 2e29d78 commit dd53022de00d254d37f5079ea003e09bb5a5b173
Showing with 23 additions and 27 deletions.
  1. +10 −3 internal/tool/srv/srv.go
  2. +13 −24 internal/tool/srv/srv_test.go
@@ -17,16 +17,23 @@ func Serve(args []string, _ io.Reader) error {
dir = args[1]
}

return serve(dir, os.Stderr)
ch := make(chan net.Addr)

go func() {
addr := <-ch
fmt.Fprintf(os.Stderr, "Serving %s on %s\n", dir, addr)
}()

return serve(dir, ch)
}

func serve(dir string, log io.Writer) error {
func serve(dir string, log chan net.Addr) error {
listener, err := net.Listen("tcp", ":0")
if err != nil {
return errors.Wrap(err, "net.Listen")
}

fmt.Fprintf(log, "Serving %s on %s\n", dir, listener.Addr())
log <- listener.Addr()

return http.Serve(listener, http.FileServer(http.Dir(dir)))
}
@@ -1,42 +1,31 @@
package srv

import (
"bytes"
"io/ioutil"
"math/rand"
"net"
"net/http"
"os"
"regexp"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestServe(t *testing.T) {
buf := &bytes.Buffer{}
go serve(".", buf)

sock := regexp.MustCompile("^Serving . on (.+)\n")

var resp *http.Response
var err error
for i := 1; i < 11; i++ {
m := sock.FindStringSubmatch(buf.String())
if len(m) == 0 {
time.Sleep(time.Millisecond * time.Duration(rand.Intn(i)))
continue
}

resp, err = http.Get("http://" + m[1] + "/srv.go")
if err != nil {
t.Fatalf("Couldn't fetch srv.go: %s", err)
}
break
}
ch := make(chan net.Addr)
go serve(".", ch)

if resp == nil {
var addr net.Addr
timer := time.NewTimer(time.Second)
select {
case <-timer.C:
t.Fatalf("couldn't get response from server within timeout")
case addr = <-ch:
}

resp, err := http.Get("http://" + string(addr.String()) + "/srv.go")
if err != nil {
t.Fatalf("Couldn't fetch srv.go: %s", err)
}

f, err := os.Open("./srv.go")

0 comments on commit dd53022

Please sign in to comment.
You can’t perform that action at this time.