Skip to content

Commit de7d837

Browse files
committed
tests/serve/serve.go: use a kernel-assigned port
When firing up a minimal server to serve up content so that we can retrieve it using HTTP, make it possible to let the kernel assign us which port to use, so that the script that's calling us doesn't have to make a(n occasionally bad) guess. Signed-off-by: Nalin Dahyabhai <[email protected]>
1 parent fb136a7 commit de7d837

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

tests/helpers.bash

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,23 @@ function setup() {
4040
function starthttpd() {
4141
pushd ${2:-${TESTDIR}} > /dev/null
4242
go build -o serve ${TESTSDIR}/serve/serve.go
43-
HTTP_SERVER_PORT=$((RANDOM+32768))
44-
./serve ${HTTP_SERVER_PORT} ${1:-${BATS_TMPDIR}} &
43+
portfile=$(mktemp)
44+
if test -z "${portfile}"; then
45+
echo error creating temporaty file
46+
exit 1
47+
fi
48+
./serve ${1:-${BATS_TMPDIR}} 0 ${portfile} &
4549
HTTP_SERVER_PID=$!
50+
waited=0
51+
while ! test -s ${portfile} ; do
52+
sleep 0.1
53+
if test $((++waited)) -ge 300 ; then
54+
echo test http server did not start within timeout
55+
exit 1
56+
fi
57+
done
58+
HTTP_SERVER_PORT=$(cat ${portfile})
59+
rm -f ${portfile}
4660
popd > /dev/null
4761
}
4862

tests/serve/serve.go

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package main
22

33
import (
4+
"context"
5+
"io/ioutil"
46
"log"
7+
"net"
58
"net/http"
69
"os"
710
"path/filepath"
11+
"strconv"
812
)
913

1014
func sendThatFile(basepath string) func(w http.ResponseWriter, r *http.Request) {
@@ -30,11 +34,40 @@ func sendThatFile(basepath string) func(w http.ResponseWriter, r *http.Request)
3034

3135
func main() {
3236
args := os.Args
33-
if len(args) < 3 {
34-
log.Fatal("requires listening port and subdirectory path")
37+
if len(args) < 2 {
38+
log.Fatal("requires subdirectory path [and optional port [and optional port file name]]")
39+
}
40+
basedir := args[1]
41+
port := "0"
42+
if len(args) > 2 {
43+
port = args[2]
3544
}
36-
port := args[1]
37-
basedir := args[2]
3845
http.HandleFunc("/", sendThatFile(basedir))
39-
log.Fatal(http.ListenAndServe(":"+port, nil))
46+
server := http.Server{
47+
Addr: ":" + port,
48+
BaseContext: func(l net.Listener) context.Context {
49+
if tcp, ok := l.Addr().(*net.TCPAddr); ok {
50+
if len(args) > 3 {
51+
f, err := ioutil.TempFile(filepath.Dir(args[3]), filepath.Base(args[3]))
52+
if err != nil {
53+
log.Fatalf("%v", err)
54+
}
55+
tempName := f.Name()
56+
bytes := []byte(strconv.Itoa(tcp.Port))
57+
if n, err := f.Write(bytes); err != nil || n != len(bytes) {
58+
if err != nil {
59+
log.Fatalf("%v", err)
60+
}
61+
log.Fatalf("short write: %d != %d", n, len(bytes))
62+
}
63+
f.Close()
64+
if err := os.Rename(tempName, args[3]); err != nil {
65+
log.Fatalf("rename: %v", err)
66+
}
67+
}
68+
}
69+
return context.Background()
70+
},
71+
}
72+
log.Fatal(server.ListenAndServe())
4073
}

0 commit comments

Comments
 (0)