Skip to content

Commit f1fae2e

Browse files
committed
Add pqtest.Fake.Close()
So we can close the listener after tests end. Also organize a few conn.Close() and rows.Close() tests different; had that lying around from investigating some other PRs and might as well commit here.
1 parent 3815d03 commit f1fae2e

5 files changed

Lines changed: 140 additions & 129 deletions

File tree

conn_test.go

Lines changed: 56 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -297,28 +297,6 @@ func TestStatment(t *testing.T) {
297297
}
298298
}
299299

300-
func TestRowsCloseBeforeDone(t *testing.T) {
301-
db := pqtest.MustDB(t)
302-
303-
r, err := db.Query("SELECT 1")
304-
if err != nil {
305-
t.Fatal(err)
306-
}
307-
308-
err = r.Close()
309-
if err != nil {
310-
t.Fatal(err)
311-
}
312-
313-
if r.Next() {
314-
t.Fatal("unexpected row")
315-
}
316-
317-
if r.Err() != nil {
318-
t.Fatal(r.Err())
319-
}
320-
}
321-
322300
func TestParameterCountMismatch(t *testing.T) {
323301
db := pqtest.MustDB(t)
324302

@@ -672,58 +650,62 @@ func TestBadConn(t *testing.T) {
672650
}
673651
}
674652

675-
// TestCloseBadConn tests that the underlying connection can be closed with
676-
// Close after an error.
677-
func TestCloseBadConn(t *testing.T) {
678-
host := os.Getenv("PGHOST")
679-
if host == "" {
680-
host = "localhost"
681-
}
682-
if host[0] == '/' {
683-
t.Skip("cannot test bad connection close with a Unix-domain PGHOST")
684-
}
685-
port := os.Getenv("PGPORT")
686-
if port == "" {
687-
port = "5432"
688-
}
689-
nc, err := net.Dial("tcp", host+":"+port)
690-
if err != nil {
691-
t.Fatal(err)
692-
}
693-
cn := conn{c: nc}
694-
cn.handleError(io.EOF)
695-
696-
// Verify we can write before closing.
697-
if _, err := nc.Write(nil); err != nil {
698-
t.Fatal(err)
699-
}
700-
// First close should close the connection.
701-
if err := cn.Close(); err != nil {
702-
t.Fatal(err)
703-
}
653+
func TestConnClose(t *testing.T) {
654+
// Ensure the underlying connection can be closed with Close after an error.
655+
t.Run("CloseBadConn", func(t *testing.T) {
656+
host := os.Getenv("PGHOST")
657+
if host == "" {
658+
host = "localhost"
659+
}
660+
if host[0] == '/' {
661+
t.Skip("cannot test bad connection close with a Unix-domain PGHOST")
662+
}
663+
port := os.Getenv("PGPORT")
664+
if port == "" {
665+
port = "5432"
666+
}
667+
nc, err := net.Dial("tcp", host+":"+port)
668+
if err != nil {
669+
t.Fatal(err)
670+
}
671+
cn := conn{c: nc}
672+
cn.handleError(io.EOF)
704673

705-
// During the Go 1.9 cycle, https://github.com/golang/go/commit/3792db5
706-
// changed this error from
707-
//
708-
// net.errClosing = errors.New("use of closed network connection")
709-
//
710-
// to
711-
//
712-
// internal/poll.ErrClosing = errors.New("use of closed file or network connection")
713-
const errClosing = "use of closed"
674+
// Verify we can write before closing and then close.
675+
if _, err := nc.Write(nil); err != nil {
676+
t.Fatal(err)
677+
}
678+
if err := cn.Close(); err != nil {
679+
t.Fatal(err)
680+
}
714681

715-
// Verify write after closing fails.
716-
if _, err := nc.Write(nil); err == nil {
717-
t.Fatal("expected error")
718-
} else if !strings.Contains(err.Error(), errClosing) {
719-
t.Fatalf("expected %s error, got %s", errClosing, err)
720-
}
721-
// Verify second close fails.
722-
if err := cn.Close(); err == nil {
723-
t.Fatal("expected error")
724-
} else if !strings.Contains(err.Error(), errClosing) {
725-
t.Fatalf("expected %s error, got %s", errClosing, err)
726-
}
682+
// During the Go 1.9 cycle, https://github.com/golang/go/commit/3792db5
683+
// changed this error from
684+
//
685+
// net.errClosing = errors.New("use of closed network connection")
686+
//
687+
// to
688+
//
689+
// internal/poll.ErrClosing = errors.New("use of closed file or network connection")
690+
const errClosing = "use of closed"
691+
692+
// Verify write after closing fails.
693+
_, err = nc.Write(nil)
694+
if err == nil {
695+
t.Fatal("expected error")
696+
}
697+
if !strings.Contains(err.Error(), errClosing) {
698+
t.Fatalf("expected %s error, got %s", errClosing, err)
699+
}
700+
// Verify second close fails.
701+
err = cn.Close()
702+
if err == nil {
703+
t.Fatal("expected error")
704+
}
705+
if !strings.Contains(err.Error(), errClosing) {
706+
t.Fatalf("expected %s error, got %s", errClosing, err)
707+
}
708+
})
727709
}
728710

729711
func TestErrorOnExec(t *testing.T) {
@@ -926,8 +908,7 @@ func TestSimpleQuery(t *testing.T) {
926908
func TestSimpleQueryWithoutResponse(t *testing.T) {
927909
t.Parallel()
928910

929-
f := pqtest.NewFake(t)
930-
f.Accept(func(cn net.Conn) {
911+
f := pqtest.NewFake(t, func(f pqtest.Fake, cn net.Conn) {
931912
f.Startup(cn, nil)
932913
for {
933914
code, _, ok := f.ReadMsg(cn)
@@ -945,6 +926,7 @@ func TestSimpleQueryWithoutResponse(t *testing.T) {
945926
}
946927
}
947928
})
929+
defer f.Close()
948930

949931
db := pqtest.MustDB(t, f.DSN())
950932
if err := db.Ping(); err != nil {
@@ -1421,35 +1403,6 @@ func TestRowsResultTag(t *testing.T) {
14211403
}
14221404
}
14231405

1424-
// TestQuickClose tests that closing a query early allows a subsequent query to work.
1425-
func TestQuickClose(t *testing.T) {
1426-
t.Parallel()
1427-
db := pqtest.MustDB(t)
1428-
1429-
tx, err := db.Begin()
1430-
if err != nil {
1431-
t.Fatal(err)
1432-
}
1433-
rows, err := tx.Query("SELECT 1; SELECT 2;")
1434-
if err != nil {
1435-
t.Fatal(err)
1436-
}
1437-
if err := rows.Close(); err != nil {
1438-
t.Fatal(err)
1439-
}
1440-
1441-
var id int
1442-
if err := tx.QueryRow("SELECT 3").Scan(&id); err != nil {
1443-
t.Fatal(err)
1444-
}
1445-
if id != 3 {
1446-
t.Fatalf("unexpected %d", id)
1447-
}
1448-
if err := tx.Commit(); err != nil {
1449-
t.Fatal(err)
1450-
}
1451-
}
1452-
14531406
func TestMultipleResult(t *testing.T) {
14541407
t.Parallel()
14551408
db := pqtest.MustDB(t)

connector_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,8 @@ func TestConfigClone(t *testing.T) {
482482
func TestConnectMulti(t *testing.T) {
483483
var (
484484
connectedTo [3]bool
485-
accept = func(f pqtest.Fake, n int) func(net.Conn) {
486-
return func(cn net.Conn) {
485+
accept = func(n int) func(pqtest.Fake, net.Conn) {
486+
return func(f pqtest.Fake, cn net.Conn) {
487487
clientParams, ok := f.ReadStartup(cn)
488488
if !ok {
489489
return
@@ -523,13 +523,13 @@ func TestConnectMulti(t *testing.T) {
523523
}
524524
}
525525
}
526-
f1 = pqtest.NewFake(t)
527-
f2 = pqtest.NewFake(t)
528-
f3 = pqtest.NewFake(t)
526+
f1 = pqtest.NewFake(t, accept(0))
527+
f2 = pqtest.NewFake(t, accept(1))
528+
f3 = pqtest.NewFake(t, accept(2))
529529
)
530-
f1.Accept(accept(f1, 0))
531-
f2.Accept(accept(f2, 1))
532-
f3.Accept(accept(f3, 2))
530+
defer f1.Close()
531+
defer f2.Close()
532+
defer f3.Close()
533533

534534
// The host from the test servers is always 127.0.0.1. Can't reliably use
535535
// anything else AFAIK, as macOS only routes 127.0.0.1 instead of 127/8 like
@@ -691,8 +691,7 @@ func TestConnectionTargetSessionAttrs(t *testing.T) {
691691
inrec = &b
692692
}
693693

694-
f := pqtest.NewFake(t)
695-
f.Accept(func(cn net.Conn) {
694+
f := pqtest.NewFake(t, func(f pqtest.Fake, cn net.Conn) {
696695
f.Startup(cn, tt.params)
697696
for {
698697
code, _, ok := f.ReadMsg(cn)
@@ -713,6 +712,7 @@ func TestConnectionTargetSessionAttrs(t *testing.T) {
713712
}
714713
}
715714
})
715+
defer f.Close()
716716

717717
db := pqtest.MustDB(t, f.DSN()+" "+tt.dsn)
718718

internal/pqtest/fake.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@ type Fake struct {
3030
//
3131
// fmt.Println("\n" + f.DSN())
3232
// time.Sleep(9 * time.Minute)
33-
func NewFake(t testing.TB) Fake {
33+
func NewFake(t testing.TB, fun func(Fake, net.Conn)) Fake {
3434
l, err := net.Listen("tcp", "127.0.0.1:")
3535
if err != nil {
3636
t.Fatal(err)
3737
}
38-
return Fake{l: l, t: t}
38+
39+
f := Fake{l: l, t: t}
40+
f.accept(fun)
41+
return f
3942
}
4043

4144
// DSN is the DSN to connect to for this server.
@@ -65,16 +68,22 @@ func (f Fake) Port() string {
6568
return p
6669
}
6770

71+
func (f Fake) Close() {
72+
f.l.Close()
73+
}
74+
6875
// Accept callback for new connections.
69-
func (f Fake) Accept(fun func(net.Conn)) {
76+
func (f Fake) accept(fun func(Fake, net.Conn)) {
7077
go func() {
7178
for {
7279
cn, err := f.l.Accept()
7380
if err != nil {
74-
f.t.Errorf("accepting connection: %s", err)
81+
if !errors.Is(err, net.ErrClosed) {
82+
f.t.Errorf("accepting connection: %s", err)
83+
}
7584
return
7685
}
77-
go fun(cn)
86+
go fun(f, cn)
7887
}
7988
}()
8089
}
@@ -157,10 +166,7 @@ func (f Fake) read(cn net.Conn, startup bool) (proto.RequestCode, []byte, bool)
157166
func (f Fake) WriteMsg(cn net.Conn, code proto.ResponseCode, msg string) {
158167
l := []byte{byte(code), 0, 0, 0, 0}
159168
binary.BigEndian.PutUint32(l[1:], uint32(len(msg)+4))
160-
_, err := cn.Write(append(l, msg...))
161-
if err != nil {
162-
f.t.Error(err)
163-
}
169+
cn.Write(append(l, msg...))
164170
}
165171

166172
// SimpleQuery responds to a simpleQuery workflow; values are as a col, value

notify_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func TestNewListenerConn(t *testing.T) {
7979
defer l.Close()
8080
}
8181

82-
func TestConnListen(t *testing.T) {
82+
func TestListenerConnListen(t *testing.T) {
8383
l, channel := newTestListenerConn(t)
8484

8585
defer l.Close()
@@ -102,7 +102,7 @@ func TestConnListen(t *testing.T) {
102102
}
103103
}
104104

105-
func TestConnUnlisten(t *testing.T) {
105+
func TestListenerConnUnlisten(t *testing.T) {
106106
l, channel := newTestListenerConn(t)
107107

108108
defer l.Close()
@@ -140,7 +140,7 @@ func TestConnUnlisten(t *testing.T) {
140140
}
141141
}
142142

143-
func TestConnUnlistenAll(t *testing.T) {
143+
func TestListenerConnUnlistenAll(t *testing.T) {
144144
l, channel := newTestListenerConn(t)
145145

146146
defer l.Close()
@@ -178,7 +178,7 @@ func TestConnUnlistenAll(t *testing.T) {
178178
}
179179
}
180180

181-
func TestConnClose(t *testing.T) {
181+
func TestListenerConnClose(t *testing.T) {
182182
l, _ := newTestListenerConn(t)
183183
defer l.Close()
184184

@@ -192,7 +192,7 @@ func TestConnClose(t *testing.T) {
192192
}
193193
}
194194

195-
func TestConnPing(t *testing.T) {
195+
func TestListernerConnPing(t *testing.T) {
196196
l, _ := newTestListenerConn(t)
197197
defer l.Close()
198198
err := l.Ping()
@@ -210,7 +210,7 @@ func TestConnPing(t *testing.T) {
210210
}
211211

212212
// Test for deadlock where a query fails while another one is queued
213-
func TestConnExecDeadlock(t *testing.T) {
213+
func TestListenerConnExecDeadlock(t *testing.T) {
214214
l, _ := newTestListenerConn(t)
215215
defer l.Close()
216216

@@ -269,7 +269,7 @@ func TestListenerConnCloseWhileQueryIsExecuting(t *testing.T) {
269269
wg.Wait()
270270
}
271271

272-
func TestNotifyExtra(t *testing.T) {
272+
func TestListenerNotifyExtra(t *testing.T) {
273273
db := pqtest.MustDB(t)
274274

275275
l, channel := newTestListenerConn(t)

0 commit comments

Comments
 (0)