From d300de134e69b2e21b6def1df88a04b21275ccd9 Mon Sep 17 00:00:00 2001 From: Damien Neil Date: Wed, 21 Sep 2022 12:13:49 -0700 Subject: [PATCH] http2: don't rely on double-close of a net.Conn failing The js_wasm net.Conn implementation doesn't return an error on double-closing a connection. Update tests to not rely on this behavior. Change-Id: I674c6cd6364b7351d627626cf5bd9f59b3c2b96c Reviewed-on: https://go-review.googlesource.com/c/net/+/432515 Run-TryBot: Damien Neil TryBot-Result: Gopher Robot Reviewed-by: Bryan Mills --- http2/transport_test.go | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/http2/transport_test.go b/http2/transport_test.go index ff20c3b6..685659ae 100644 --- a/http2/transport_test.go +++ b/http2/transport_test.go @@ -5930,6 +5930,20 @@ func TestTransportClosesConnAfterGoAwayLastStream(t *testing.T) { testTransportClosesConnAfterGoAway(t, 1) } +type closeOnceConn struct { + net.Conn + closed uint32 +} + +var errClosed = errors.New("Close of closed connection") + +func (c *closeOnceConn) Close() error { + if atomic.CompareAndSwapUint32(&c.closed, 0, 1) { + return c.Conn.Close() + } + return errClosed +} + // testTransportClosesConnAfterGoAway verifies that the transport // closes a connection after reading a GOAWAY from it. // @@ -5938,6 +5952,7 @@ func TestTransportClosesConnAfterGoAwayLastStream(t *testing.T) { // when 1, the transport reads the response after receiving the GOAWAY. func testTransportClosesConnAfterGoAway(t *testing.T, lastStream uint32) { ct := newClientTester(t) + ct.cc = &closeOnceConn{Conn: ct.cc} var wg sync.WaitGroup wg.Add(1) @@ -5951,12 +5966,10 @@ func testTransportClosesConnAfterGoAway(t *testing.T, lastStream uint32) { if gotErr, wantErr := err != nil, lastStream == 0; gotErr != wantErr { t.Errorf("RoundTrip got error %v (want error: %v)", err, wantErr) } - if err = ct.cc.Close(); err == nil { - err = fmt.Errorf("expected error on Close") - } else if strings.Contains(err.Error(), "use of closed network") { - err = nil + if err = ct.cc.Close(); err != errClosed { + return fmt.Errorf("ct.cc.Close() = %v, want errClosed", err) } - return err + return nil } ct.server = func() error {