@@ -10,11 +10,10 @@ package http2
1010import (
1111 "bytes"
1212 "context"
13- "errors"
1413 "fmt"
1514 "io"
16- "net"
1715 "net/http"
16+ "os"
1817 "reflect"
1918 "runtime"
2019 "slices"
@@ -104,7 +103,7 @@ type testClientConn struct {
104103
105104 roundtrips []* testRoundTrip
106105
107- netconn testClientConnNetConn
106+ netconn * synctestNetConn
108107}
109108
110109func newTestClientConnFromClientConn (t * testing.T , cc * ClientConn ) * testClientConn {
@@ -114,22 +113,21 @@ func newTestClientConnFromClientConn(t *testing.T, cc *ClientConn) *testClientCo
114113 cc : cc ,
115114 group : cc .t .transportTestHooks .group .(* synctestGroup ),
116115 }
116+ cli , srv := synctestNetPipe (tc .group )
117+ srv .SetReadDeadline (tc .group .Now ())
118+ tc .netconn = srv
117119 tc .enc = hpack .NewEncoder (& tc .encbuf )
118- tc .netconn .gate = newGate ()
119120
120121 // all writes and reads are finished.
121122 //
122123 // cli is the ClientConn's side, srv is the side controlled by the test.
123- cc .tconn = & tc .netconn
124- tc .fr = NewFramer (
125- (* testClientConnNetConnWriteToClient )(& tc .netconn ),
126- (* testClientConnNetConnReadFromClient )(& tc .netconn ),
127- )
124+ cc .tconn = cli
125+ tc .fr = NewFramer (srv , srv )
128126
129127 tc .fr .ReadMetaHeaders = hpack .NewDecoder (initialHeaderTableSize , nil )
130128 tc .fr .SetMaxReadFrameSize (10 << 20 )
131129 t .Cleanup (func () {
132- tc .closeWrite (io . EOF )
130+ tc .closeWrite ()
133131 })
134132 return tc
135133}
@@ -138,8 +136,7 @@ func (tc *testClientConn) readClientPreface() {
138136 tc .t .Helper ()
139137 // Read the client's HTTP/2 preface, sent prior to any HTTP/2 frames.
140138 buf := make ([]byte , len (clientPreface ))
141- r := (* testClientConnNetConnReadFromClient )(& tc .netconn )
142- if _ , err := io .ReadFull (r , buf ); err != nil {
139+ if _ , err := io .ReadFull (tc .netconn , buf ); err != nil {
143140 tc .t .Fatalf ("reading preface: %v" , err )
144141 }
145142 if ! bytes .Equal (buf , clientPreface ) {
@@ -174,26 +171,23 @@ func (tc *testClientConn) advance(d time.Duration) {
174171
175172// hasFrame reports whether a frame is available to be read.
176173func (tc * testClientConn ) hasFrame () bool {
177- tc .netconn .lock ()
178- defer tc .netconn .unlock ()
179- return tc .netconn .fromConn .Len () > 0
174+ return len (tc .netconn .Peek ()) > 0
180175}
181176
182177func (tc * testClientConn ) isClosed () bool {
183- tc .netconn .lock ()
184- defer tc .netconn .unlock ()
185- return tc .netconn .fromConnClosed
178+ return tc .netconn .IsClosedByPeer ()
186179}
187180
188181// readFrame reads the next frame from the conn.
189182func (tc * testClientConn ) readFrame () Frame {
183+ tc .t .Helper ()
190184 tc .sync ()
191185 fr , err := tc .fr .ReadFrame ()
192- if err == io .EOF {
186+ if err == io .EOF || err == os . ErrDeadlineExceeded {
193187 return nil
194188 }
195189 if err != nil {
196- return nil
190+ tc . t . Fatalf ( "ReadFrame: %v" , err )
197191 }
198192 return fr
199193}
@@ -597,10 +591,8 @@ func (tc *testClientConn) writeWindowUpdate(streamID, incr uint32) {
597591
598592// closeWrite causes the net.Conn used by the ClientConn to return a error
599593// from Read calls.
600- func (tc * testClientConn ) closeWrite (err error ) {
601- tc .netconn .lock ()
602- tc .netconn .toConnErr = err
603- tc .netconn .unlock ()
594+ func (tc * testClientConn ) closeWrite () {
595+ tc .netconn .Close ()
604596 tc .sync ()
605597}
606598
@@ -746,80 +738,6 @@ func diffHeaders(got, want http.Header) string {
746738 return fmt .Sprintf ("got: %v\n want: %v" , got , want )
747739}
748740
749- // testClientConnNetConn implements net.Conn,
750- // and is the Conn used by a ClientConn under test.
751- type testClientConnNetConn struct {
752- gate gate
753- toConn bytes.Buffer
754- toConnErr error
755- fromConn bytes.Buffer
756- fromConnClosed bool
757- }
758-
759- func (c * testClientConnNetConn ) lock () {
760- c .gate .lock ()
761- }
762-
763- func (c * testClientConnNetConn ) unlock () {
764- c .gate .unlock (c .toConn .Len () > 0 || c .toConnErr != nil )
765- }
766-
767- func (c * testClientConnNetConn ) Read (b []byte ) (n int , err error ) {
768- if err := c .gate .waitAndLock (context .Background ()); err != nil {
769- return 0 , err
770- }
771- defer c .unlock ()
772- if c .toConn .Len () == 0 && c .toConnErr != nil {
773- return 0 , c .toConnErr
774- }
775- return c .toConn .Read (b )
776- }
777-
778- func (c * testClientConnNetConn ) Write (b []byte ) (n int , err error ) {
779- c .lock ()
780- defer c .unlock ()
781- return c .fromConn .Write (b )
782- }
783-
784- func (c * testClientConnNetConn ) Close () error {
785- c .lock ()
786- defer c .unlock ()
787- c .fromConnClosed = true
788- c .toConn .Reset ()
789- if c .toConnErr == nil {
790- c .toConnErr = errors .New ("connection closed" )
791- }
792- return nil
793- }
794-
795- func (* testClientConnNetConn ) LocalAddr () (_ net.Addr ) { return }
796- func (* testClientConnNetConn ) RemoteAddr () (_ net.Addr ) { return }
797- func (* testClientConnNetConn ) SetDeadline (t time.Time ) error { return nil }
798- func (* testClientConnNetConn ) SetReadDeadline (t time.Time ) error { return nil }
799- func (* testClientConnNetConn ) SetWriteDeadline (t time.Time ) error { return nil }
800-
801- // testClientConnNetConnWriteToClient is a view on a testClientConnNetConn
802- // that implements an io.Writer that sends to the client conn under test.
803- type testClientConnNetConnWriteToClient testClientConnNetConn
804-
805- func (w * testClientConnNetConnWriteToClient ) Write (b []byte ) (n int , err error ) {
806- c := (* testClientConnNetConn )(w )
807- c .gate .lock ()
808- defer c .unlock ()
809- return c .toConn .Write (b )
810- }
811-
812- // testClientConnNetConnReadFromClient is a view on a testClientConnNetConn
813- // that implements an io.Reader that reads data sent by the client conn under test.
814- type testClientConnNetConnReadFromClient testClientConnNetConn
815-
816- func (w * testClientConnNetConnReadFromClient ) Read (b []byte ) (n int , err error ) {
817- c := (* testClientConnNetConn )(w )
818- c .gate .lock ()
819- defer c .unlock ()
820- return c .fromConn .Read (b )
821- }
822-
823741// A testTransport allows testing Transport.RoundTrip against fake servers.
824742// Tests that aren't specifically exercising RoundTrip's retry loop or connection pooling
825743// should use testClientConn instead.
@@ -861,7 +779,7 @@ func newTestTransport(t *testing.T, opts ...func(*Transport)) *testTransport {
861779 buf := make ([]byte , 16 * 1024 )
862780 n := runtime .Stack (buf , true )
863781 t .Logf ("stacks:\n %s" , buf [:n ])
864- t .Fatalf ("%v goroutines still running after test completed, expect 1" , count - 1 )
782+ t .Fatalf ("%v goroutines still running after test completed, expect 1" , count )
865783 }
866784 })
867785
0 commit comments