]> Cypherpunks repositories - gostls13.git/commitdiff
database/sql: fix TestPendingConnsAfterErr
authorDaniel Theophanes <kardianos@gmail.com>
Mon, 31 Oct 2016 14:58:41 +0000 (07:58 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 22 Nov 2016 23:35:56 +0000 (23:35 +0000)
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/33418
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/database/sql/sql_test.go

index c46aaf60f85c94d90bddad93bfe9b04e7a61b05a..b64d4dda5a7f8c8b0b0222128bcd5360a133021f 100644 (file)
@@ -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) {