Skip to content

Commit

Permalink
Debug flaky testcases with in memory network
Browse files Browse the repository at this point in the history
Changes httptest.Server to use an in memory network. This makes testing
more robust to ephemeral port issues under load. Two flaky test cases
were now easily reproducible and fixed. Both occured from races between
starting the network request in a go routine and checking for a http2
stream and erroring if not. This can error on Send or Receive depending
on how fast the request can complete.

See: golang/go#14200
  • Loading branch information
emcfarlane committed Sep 18, 2023
1 parent 525cf76 commit 4c43e4b
Show file tree
Hide file tree
Showing 12 changed files with 258 additions and 300 deletions.
12 changes: 3 additions & 9 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"

connect "connectrpc.com/connect"
"connectrpc.com/connect/internal/assert"
"connectrpc.com/connect/internal/connecttest"
pingv1 "connectrpc.com/connect/internal/gen/connect/ping/v1"
"connectrpc.com/connect/internal/gen/connect/ping/v1/pingv1connect"
)
Expand All @@ -38,10 +38,7 @@ func BenchmarkConnect(b *testing.B) {
&ExamplePingServer{},
),
)
server := httptest.NewUnstartedServer(mux)
server.EnableHTTP2 = true
server.StartTLS()
b.Cleanup(server.Close)
server := connecttest.StartHTTP2TestServer(b, mux)

httpClient := server.Client()
httpTransport, ok := httpClient.Transport.(*http.Transport)
Expand Down Expand Up @@ -113,10 +110,7 @@ func BenchmarkREST(b *testing.B) {
assert.Nil(b, err)
}

server := httptest.NewUnstartedServer(http.HandlerFunc(handler))
server.EnableHTTP2 = true
server.StartTLS()
b.Cleanup(server.Close)
server := connecttest.StartHTTP2TestServer(b, http.HandlerFunc(handler))
twoMiB := strings.Repeat("a", 2*1024*1024)
b.ResetTimer()

Expand Down
7 changes: 3 additions & 4 deletions client_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,16 @@ import (

func Example_client() {
logger := log.New(os.Stdout, "" /* prefix */, 0 /* flags */)
// Unfortunately, pkg.go.dev can't run examples that actually use the
// network. To keep this example runnable, we'll use an HTTP server and
// client that communicate over in-memory pipes. The client is still a plain
// To keep this example runnable, we'll use an HTTP server and client
// that communicate over in-memory pipes. The client is still a plain
// *http.Client!
var httpClient *http.Client = examplePingServer.Client()

// By default, clients use the Connect protocol. Add connect.WithGRPC() or
// connect.WithGRPCWeb() to switch protocols.
client := pingv1connect.NewPingServiceClient(
httpClient,
examplePingServer.URL(),
examplePingServer.URL,
)
response, err := client.Ping(
context.Background(),
Expand Down
13 changes: 3 additions & 10 deletions client_ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ import (
"context"
"errors"
"net/http"
"net/http/httptest"
"strings"
"testing"

connect "connectrpc.com/connect"
"connectrpc.com/connect/internal/assert"
"connectrpc.com/connect/internal/connecttest"
pingv1 "connectrpc.com/connect/internal/gen/connect/ping/v1"
"connectrpc.com/connect/internal/gen/connect/ping/v1/pingv1connect"
)
Expand Down Expand Up @@ -75,10 +75,7 @@ func TestClientPeer(t *testing.T) {
t.Parallel()
mux := http.NewServeMux()
mux.Handle(pingv1connect.NewPingServiceHandler(pingServer{}))
server := httptest.NewUnstartedServer(mux)
server.EnableHTTP2 = true
server.StartTLS()
t.Cleanup(server.Close)
server := connecttest.StartHTTP2TestServer(t, mux)

run := func(t *testing.T, unaryHTTPMethod string, opts ...connect.ClientOption) {
t.Helper()
Expand Down Expand Up @@ -157,11 +154,7 @@ func TestGetNotModified(t *testing.T) {

mux := http.NewServeMux()
mux.Handle(pingv1connect.NewPingServiceHandler(&notModifiedPingServer{etag: etag}))
server := httptest.NewUnstartedServer(mux)
server.EnableHTTP2 = true
server.StartTLS()
t.Cleanup(server.Close)

server := connecttest.StartHTTP2TestServer(t, mux)
client := pingv1connect.NewPingServiceClient(
server.Client(),
server.URL,
Expand Down
7 changes: 2 additions & 5 deletions client_get_fallback_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ package connect
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"

"connectrpc.com/connect/internal/assert"
"connectrpc.com/connect/internal/connecttest"
pingv1 "connectrpc.com/connect/internal/gen/connect/ping/v1"
)

Expand All @@ -38,10 +38,7 @@ func TestClientUnaryGetFallback(t *testing.T) {
},
WithIdempotency(IdempotencyNoSideEffects),
))
server := httptest.NewUnstartedServer(mux)
server.EnableHTTP2 = true
server.StartTLS()
t.Cleanup(server.Close)
server := connecttest.StartHTTP2TestServer(t, mux)

client := NewClient[pingv1.PingRequest, pingv1.PingResponse](
server.Client(),
Expand Down
6 changes: 2 additions & 4 deletions compression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ package connect
import (
"context"
"net/http"
"net/http/httptest"
"testing"

"connectrpc.com/connect/internal/assert"
"connectrpc.com/connect/internal/connecttest"
"google.golang.org/protobuf/types/known/emptypb"
)

Expand All @@ -42,9 +42,7 @@ func TestAcceptEncodingOrdering(t *testing.T) {
w.WriteHeader(http.StatusOK)
called = true
})
server := httptest.NewServer(verify)
t.Cleanup(server.Close)

server := connecttest.StartHTTPTestServer(t, verify)
client := NewClient[emptypb.Empty, emptypb.Empty](
server.Client(),
server.URL,
Expand Down
Loading

0 comments on commit 4c43e4b

Please sign in to comment.