Commit e12f6ee0 authored by Daniel Theophanes's avatar Daniel Theophanes Committed by Brad Fitzpatrick

database/sql: fix TestPendingConnsAfterErr

TestPendingConnsAfterErr showed a failure on slower systems.
Wait and check for the database to close all connections
before pronouncing failure.

A more careful method was attempted but the connection pool
behavior is too dependent on the scheduler behavior to be
predictable.

Fixes #15684

Change-Id: Iafdbc90ba51170c76a079db04c3d5452047433a4
Reviewed-on: https://go-review.googlesource.com/33418Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 199d410d
......@@ -1438,7 +1438,11 @@ func TestPendingConnsAfterErr(t *testing.T) {
tryOpen = maxOpen*2 + 2
)
db := newTestDB(t, "people")
// No queries will be run.
db, err := Open("test", fakeDBName)
if err != nil {
t.Fatalf("Open: %v", err)
}
defer closeDB(t, db)
defer func() {
for k, v := range db.lastPut {
......@@ -1450,29 +1454,29 @@ func TestPendingConnsAfterErr(t *testing.T) {
db.SetMaxIdleConns(0)
errOffline := errors.New("db offline")
defer func() { setHookOpenErr(nil) }()
errs := make(chan error, tryOpen)
unblock := make(chan struct{})
var opening sync.WaitGroup
opening.Add(tryOpen)
setHookOpenErr(func() error {
<-unblock // block until all connections are in flight
// Wait for all connections to enqueue.
opening.Wait()
return errOffline
})
var opening sync.WaitGroup
opening.Add(tryOpen)
for i := 0; i < tryOpen; i++ {
go func() {
opening.Done() // signal one connection is in flight
_, err := db.Exec("INSERT|people|name=Julia,age=19")
_, err := db.Exec("will never run")
errs <- err
}()
}
opening.Wait() // wait for all workers to begin running
time.Sleep(10 * time.Millisecond) // make extra sure all workers are blocked
close(unblock) // let all workers proceed
opening.Wait() // wait for all workers to begin running
const timeout = 5 * time.Second
to := time.NewTimer(timeout)
......@@ -1489,6 +1493,24 @@ func TestPendingConnsAfterErr(t *testing.T) {
t.Fatalf("orphaned connection request(s), still waiting after %v", timeout)
}
}
// Wait a reasonable time for the database to close all connections.
tick := time.NewTicker(3 * time.Millisecond)
defer tick.Stop()
for {
select {
case <-tick.C:
db.mu.Lock()
if db.numOpen == 0 {
db.mu.Unlock()
return
}
db.mu.Unlock()
case <-to.C:
// Closing the database will check for numOpen and fail the test.
return
}
}
}
func TestSingleOpenConn(t *testing.T) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment