forked from quic-go/quic-go
avoid triggering macOS dual-stack flakiness in HTTP/3 integration tests (#5187)
Unfortunately, there’s still no fix in sight for https://github.com/golang/go/issues/67226.
This commit is contained in:
@@ -368,6 +368,7 @@ func testHTTP3ListenerClosing(t *testing.T, graceful, useApplicationListener boo
|
||||
tlsConf.NextProtos = []string{http3.NextProtoH3}
|
||||
tr := &http3.Transport{TLSClientConfig: tlsConf}
|
||||
defer tr.Close()
|
||||
addDialCallback(t, tr)
|
||||
cl := &http.Client{Transport: tr}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
|
||||
require.NoError(t, err)
|
||||
@@ -396,7 +397,7 @@ func testHTTP3ListenerClosing(t *testing.T, graceful, useApplicationListener boo
|
||||
// the following values will be ignored when using ServeListener
|
||||
TLSConfig: tlsConf,
|
||||
QUICConfig: getQuicConfig(nil),
|
||||
Addr: "127.0.0.1:47283",
|
||||
Addr: "127.0.0.1:0",
|
||||
}
|
||||
|
||||
serveChan := make(chan error, 1)
|
||||
@@ -411,7 +412,17 @@ func testHTTP3ListenerClosing(t *testing.T, graceful, useApplicationListener boo
|
||||
go func() { serveChan <- server.ServeListener(ln) }()
|
||||
} else {
|
||||
go func() { serveChan <- server.ListenAndServe() }()
|
||||
host = server.Addr
|
||||
// The server is listening on a random port, and the only way to get the port
|
||||
// is to parse the Alt-Svc header.
|
||||
var port int
|
||||
require.Eventually(t, func() bool {
|
||||
hdr := make(http.Header)
|
||||
server.SetQUICHeaders(hdr)
|
||||
altSvc := hdr.Get("Alt-Svc")
|
||||
n, err := fmt.Sscanf(altSvc, `h3=":%d"`, &port)
|
||||
return err == nil && n == 1
|
||||
}, time.Second, 10*time.Millisecond)
|
||||
host = fmt.Sprintf("127.0.0.1:%d", port)
|
||||
}
|
||||
|
||||
u := &url.URL{Scheme: "https", Host: host, Path: "/ok"}
|
||||
@@ -471,10 +482,7 @@ func testHTTP3ListenerClosing(t *testing.T, graceful, useApplicationListener boo
|
||||
for range 2 {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
err := dial(t, ctx, u)
|
||||
var h3Err *http3.Error
|
||||
require.ErrorAs(t, err, &h3Err)
|
||||
require.Equal(t, http3.ErrCode(1337), h3Err.ErrorCode)
|
||||
require.ErrorIs(t, dial(t, ctx, u), &http3.Error{ErrorCode: 1337, Remote: true})
|
||||
select {
|
||||
case err := <-errChan:
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -85,6 +85,7 @@ func newHTTP3Client(t *testing.T) *http.Client {
|
||||
QUICConfig: getQuicConfig(&quic.Config{MaxIdleTimeout: 10 * time.Second}),
|
||||
DisableCompression: true,
|
||||
}
|
||||
addDialCallback(t, tr)
|
||||
t.Cleanup(func() { tr.Close() })
|
||||
return &http.Client{Transport: tr}
|
||||
}
|
||||
@@ -356,7 +357,13 @@ func TestHTTPDifferentOrigins(t *testing.T) {
|
||||
})
|
||||
port := startHTTPServer(t, mux)
|
||||
|
||||
cl := newHTTP3Client(t)
|
||||
tr := &http3.Transport{
|
||||
TLSClientConfig: getTLSClientConfigWithoutServerName(),
|
||||
QUICConfig: getQuicConfig(nil),
|
||||
}
|
||||
t.Cleanup(func() { tr.Close() })
|
||||
cl := &http.Client{Transport: tr}
|
||||
|
||||
resp, err := cl.Get(fmt.Sprintf("https://localhost:%d/remote-addr", port))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
@@ -888,6 +895,7 @@ func TestHTTP0RTT(t *testing.T) {
|
||||
DisableCompression: true,
|
||||
}
|
||||
defer tr.Close()
|
||||
addDialCallback(t, tr)
|
||||
|
||||
proxyPort := proxy.LocalAddr().(*net.UDPAddr).Port
|
||||
req, err := http.NewRequest(http3.MethodGet0RTT, fmt.Sprintf("https://localhost:%d/0rtt", proxyPort), nil)
|
||||
@@ -912,6 +920,7 @@ func TestHTTP0RTT(t *testing.T) {
|
||||
DisableCompression: true,
|
||||
}
|
||||
defer tr2.Close()
|
||||
addDialCallback(t, tr2)
|
||||
rsp, err = tr2.RoundTrip(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 200, rsp.StatusCode)
|
||||
@@ -949,6 +958,7 @@ func TestHTTPStreamer(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer conn.CloseWithError(0, "")
|
||||
tr := http3.Transport{}
|
||||
addDialCallback(t, &tr)
|
||||
cc := tr.NewClientConn(conn)
|
||||
str, err := cc.OpenRequestStream(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/quic-go/quic-go/http3"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -62,7 +63,13 @@ func TestHTTPClientTrace(t *testing.T) {
|
||||
}
|
||||
ctx := httptrace.WithClientTrace(context.Background(), &trace)
|
||||
|
||||
cl := newHTTP3Client(t)
|
||||
tr := &http3.Transport{
|
||||
TLSClientConfig: getTLSClientConfigWithoutServerName(),
|
||||
QUICConfig: getQuicConfig(nil),
|
||||
}
|
||||
t.Cleanup(func() { tr.Close() })
|
||||
cl := &http.Client{Transport: tr}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://localhost:%d/client-trace", port), nil)
|
||||
require.NoError(t, err)
|
||||
resp, err := cl.Do(req)
|
||||
|
||||
@@ -10,11 +10,13 @@ import (
|
||||
"math/rand/v2"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/quic-go/quic-go"
|
||||
"github.com/quic-go/quic-go/http3"
|
||||
"github.com/quic-go/quic-go/integrationtests/tools"
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/wire"
|
||||
@@ -298,3 +300,23 @@ func contains0RTTPacket(data []byte) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// addDialCallback explicitly adds the http3.Transport's Dial callback.
|
||||
// This is needed since dialing on dual-stack sockets is flaky on macOS,
|
||||
// see https://github.com/golang/go/issues/67226.
|
||||
func addDialCallback(t *testing.T, tr *http3.Transport) {
|
||||
t.Helper()
|
||||
|
||||
if runtime.GOOS != "darwin" {
|
||||
return
|
||||
}
|
||||
|
||||
require.Nil(t, tr.Dial)
|
||||
tr.Dial = func(ctx context.Context, addr string, tlsConf *tls.Config, conf *quic.Config) (quic.EarlyConnection, error) {
|
||||
a, err := net.ResolveUDPAddr("udp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return quic.DialEarly(ctx, newUDPConnLocalhost(t), a, tlsConf, conf)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user