diff --git a/ci/test.mk b/ci/test.mk index 6d0751360ee584d2ca3259bccb3703cb491e4e70..0fe0ce19abbe3d9d6fff2cd0d31ddf87e195ae1e 100644 --- a/ci/test.mk +++ b/ci/test.mk @@ -13,10 +13,10 @@ codecov: _gotest _gotest: echo "--- gotest" && go test -parallel=32 -coverprofile=ci/out/coverage.prof -coverpkg=./... ./... - sed -i '/_stringer.go/d' ci/out/coverage.prof - sed -i '/wsjstest\/main.go/d' ci/out/coverage.prof - sed -i '/wsecho.go/d' ci/out/coverage.prof - sed -i '/assert.go/d' ci/out/coverage.prof + sed -i '/_stringer\.go/d' ci/out/coverage.prof + sed -i '/wsjstest\/main\.go/d' ci/out/coverage.prof + sed -i '/wsecho\.go/d' ci/out/coverage.prof + sed -i '/assert\.go/d' ci/out/coverage.prof gotest-wasm: wsjstest echo "--- wsjstest" && ./ci/wasmtest.sh diff --git a/ci/wasmtest.sh b/ci/wasmtest.sh index 21335ce7c1904d6a150e92b078da0a8c1270d907..66d397a2c98665ab4f76a8bb3f4f0d1e555baf7e 100755 --- a/ci/wasmtest.sh +++ b/ci/wasmtest.sh @@ -2,8 +2,17 @@ set -euo pipefail -WS_ECHO_SERVER_URL="$(wsjstest)" -trap 'pkill -KILL wsjstest' EXIT INT +wsjstestOut="$(mktemp -d)/wsjstestOut" +mkfifo "$wsjstestOut" +timeout 15s wsjstest > "$wsjstestOut" & +wsjstestPID="$!" + +WS_ECHO_SERVER_URL="$(head -n 1 "$wsjstestOut")" export WS_ECHO_SERVER_URL GOOS=js GOARCH=wasm go test -exec=wasmbrowsertest ./... + +if ! wait "$wsjstestPID" ; then + echo "wsjstest exited unsuccessfully" + exit 1 +fi diff --git a/conn_common.go b/conn_common.go index 5a11a79c904f890a1507a3ab85982e40a4c2f490..9f0b045a1c54f94057ae2fe932c14c7ccd6dfdf6 100644 --- a/conn_common.go +++ b/conn_common.go @@ -5,7 +5,6 @@ package websocket import ( "context" - "errors" "fmt" "io" "math" @@ -104,8 +103,8 @@ func (c *netConn) Read(p []byte) (int, error) { if c.reader == nil { typ, r, err := c.c.Reader(c.readContext) if err != nil { - var ce CloseError - if errors.As(err, &ce) && (ce.Code == StatusNormalClosure) || (ce.Code == StatusGoingAway) { + switch CloseStatus(err) { + case StatusNormalClosure, StatusGoingAway: c.eofed = true return 0, io.EOF } diff --git a/conn_test.go b/conn_test.go index f3f1a2b0a3380efe3a50c08effaeadc1f8f67367..8dcff944f8662ec187ef87565f84b980f951d615 100644 --- a/conn_test.go +++ b/conn_test.go @@ -589,11 +589,7 @@ func TestConn(t *testing.T) { return err } _, _, err = c.Read(ctx) - var cerr websocket.CloseError - if !errors.As(err, &cerr) || cerr.Code != websocket.StatusProtocolError { - return fmt.Errorf("expected close error with StatusProtocolError: %+v", err) - } - return nil + return assertCloseStatus(err, websocket.StatusProtocolError) }, client: func(ctx context.Context, c *websocket.Conn) error { _, _, err := c.Read(ctx) diff --git a/internal/wsjstest/main.go b/internal/wsjstest/main.go index 5251fb84edec0e7823a005fba24972ec0a5908e2..b8b1cba25b6eb797f02545ca00f53e3dfa5fb3be 100644 --- a/internal/wsjstest/main.go +++ b/internal/wsjstest/main.go @@ -3,63 +3,20 @@ package main import ( - "errors" "fmt" "log" - "net" "net/http" + "net/http/httptest" "os" - "os/exec" + "runtime" + "strings" "nhooyr.io/websocket" "nhooyr.io/websocket/internal/wsecho" ) -func fork() net.Listener { - if os.Getenv("FORKED") != "" { - f := os.NewFile(3, "listener") - l, err := net.FileListener(f) - if err != nil { - log.Fatalf("failed to create listener from fd: %+v", err) - } - return l - } - - l, err := net.Listen("tcp", "localhost:0") - if err != nil { - log.Fatalf("failed to listen: %+v", err) - } - f, err := l.(*net.TCPListener).File() - if err != nil { - log.Fatalf("failed to get file from tcp listener: %+v", err) - } - - cmd := exec.Command(os.Args[0]) - cmd.Stderr = os.Stderr - cmd.Env = append(os.Environ(), - fmt.Sprintf("FORKED=true"), - ) - cmd.ExtraFiles = append(cmd.ExtraFiles, f) - err = cmd.Start() - if err != nil { - log.Fatalf("failed to start command: %+v", err) - } - - fmt.Printf("ws://%v\n", l.Addr().String()) - os.Exit(0) - - panic("unreachable") -} - func main() { - l := fork() - - err := serve(l) - log.Fatalf("failed to serve: %+v", err) -} - -func serve(l net.Listener) error { - return http.Serve(l, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { c, err := websocket.Accept(w, r, &websocket.AcceptOptions{ Subprotocols: []string{"echo"}, InsecureSkipVerify: true, @@ -70,11 +27,14 @@ func serve(l net.Listener) error { defer c.Close(websocket.StatusInternalError, "") err = wsecho.Loop(r.Context(), c) - - var ce websocket.CloseError - if !errors.As(err, &ce) || ce.Code != websocket.StatusNormalClosure { - log.Fatalf("unexpected loop error: %+v", err) + if websocket.CloseStatus(err) != websocket.StatusNormalClosure { + log.Fatalf("unexpected echo loop error: %+v", err) } + + os.Exit(0) })) + wsURL := strings.Replace(s.URL, "http", "ws", 1) + fmt.Printf("%v\n", wsURL) + runtime.Goexit() }