libgo: update to final Go 1.8 release
[official-gcc.git] / libgo / go / database / sql / sql_test.go
blob450e5f1f8c961d1c0885a4bc97f3de8bcf26bd44
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package sql
7 import (
8 "context"
9 "database/sql/driver"
10 "errors"
11 "fmt"
12 "math/rand"
13 "reflect"
14 "runtime"
15 "strings"
16 "sync"
17 "sync/atomic"
18 "testing"
19 "time"
22 func init() {
23 type dbConn struct {
24 db *DB
25 c *driverConn
27 freedFrom := make(map[dbConn]string)
28 var mu sync.Mutex
29 getFreedFrom := func(c dbConn) string {
30 mu.Lock()
31 defer mu.Unlock()
32 return freedFrom[c]
34 setFreedFrom := func(c dbConn, s string) {
35 mu.Lock()
36 defer mu.Unlock()
37 freedFrom[c] = s
39 putConnHook = func(db *DB, c *driverConn) {
40 idx := -1
41 for i, v := range db.freeConn {
42 if v == c {
43 idx = i
44 break
47 if idx >= 0 {
48 // print before panic, as panic may get lost due to conflicting panic
49 // (all goroutines asleep) elsewhere, since we might not unlock
50 // the mutex in freeConn here.
51 println("double free of conn. conflicts are:\nA) " + getFreedFrom(dbConn{db, c}) + "\n\nand\nB) " + stack())
52 panic("double free of conn.")
54 setFreedFrom(dbConn{db, c}, stack())
58 const fakeDBName = "foo"
60 var chrisBirthday = time.Unix(123456789, 0)
62 func newTestDB(t testing.TB, name string) *DB {
63 db, err := Open("test", fakeDBName)
64 if err != nil {
65 t.Fatalf("Open: %v", err)
67 if _, err := db.Exec("WIPE"); err != nil {
68 t.Fatalf("exec wipe: %v", err)
70 if name == "people" {
71 exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime")
72 exec(t, db, "INSERT|people|name=Alice,age=?,photo=APHOTO", 1)
73 exec(t, db, "INSERT|people|name=Bob,age=?,photo=BPHOTO", 2)
74 exec(t, db, "INSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
76 if name == "magicquery" {
77 // Magic table name and column, known by fakedb_test.go.
78 exec(t, db, "CREATE|magicquery|op=string,millis=int32")
79 exec(t, db, "INSERT|magicquery|op=sleep,millis=10")
81 return db
84 func TestDriverPanic(t *testing.T) {
85 // Test that if driver panics, database/sql does not deadlock.
86 db, err := Open("test", fakeDBName)
87 if err != nil {
88 t.Fatalf("Open: %v", err)
90 expectPanic := func(name string, f func()) {
91 defer func() {
92 err := recover()
93 if err == nil {
94 t.Fatalf("%s did not panic", name)
96 }()
97 f()
100 expectPanic("Exec Exec", func() { db.Exec("PANIC|Exec|WIPE") })
101 exec(t, db, "WIPE") // check not deadlocked
102 expectPanic("Exec NumInput", func() { db.Exec("PANIC|NumInput|WIPE") })
103 exec(t, db, "WIPE") // check not deadlocked
104 expectPanic("Exec Close", func() { db.Exec("PANIC|Close|WIPE") })
105 exec(t, db, "WIPE") // check not deadlocked
106 exec(t, db, "PANIC|Query|WIPE") // should run successfully: Exec does not call Query
107 exec(t, db, "WIPE") // check not deadlocked
109 exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime")
111 expectPanic("Query Query", func() { db.Query("PANIC|Query|SELECT|people|age,name|") })
112 expectPanic("Query NumInput", func() { db.Query("PANIC|NumInput|SELECT|people|age,name|") })
113 expectPanic("Query Close", func() {
114 rows, err := db.Query("PANIC|Close|SELECT|people|age,name|")
115 if err != nil {
116 t.Fatal(err)
118 rows.Close()
120 db.Query("PANIC|Exec|SELECT|people|age,name|") // should run successfully: Query does not call Exec
121 exec(t, db, "WIPE") // check not deadlocked
124 func exec(t testing.TB, db *DB, query string, args ...interface{}) {
125 _, err := db.Exec(query, args...)
126 if err != nil {
127 t.Fatalf("Exec of %q: %v", query, err)
131 func closeDB(t testing.TB, db *DB) {
132 if e := recover(); e != nil {
133 fmt.Printf("Panic: %v\n", e)
134 panic(e)
136 defer setHookpostCloseConn(nil)
137 setHookpostCloseConn(func(_ *fakeConn, err error) {
138 if err != nil {
139 t.Errorf("Error closing fakeConn: %v", err)
142 for i, dc := range db.freeConn {
143 if n := len(dc.openStmt); n > 0 {
144 // Just a sanity check. This is legal in
145 // general, but if we make the tests clean up
146 // their statements first, then we can safely
147 // verify this is always zero here, and any
148 // other value is a leak.
149 t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, len(db.freeConn), n)
152 err := db.Close()
153 if err != nil {
154 t.Fatalf("error closing DB: %v", err)
157 var numOpen int
158 if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
159 numOpen = db.numOpenConns()
160 return numOpen == 0
161 }) {
162 t.Fatalf("%d connections still open after closing DB", numOpen)
166 // numPrepares assumes that db has exactly 1 idle conn and returns
167 // its count of calls to Prepare
168 func numPrepares(t *testing.T, db *DB) int {
169 if n := len(db.freeConn); n != 1 {
170 t.Fatalf("free conns = %d; want 1", n)
172 return db.freeConn[0].ci.(*fakeConn).numPrepare
175 func (db *DB) numDeps() int {
176 db.mu.Lock()
177 defer db.mu.Unlock()
178 return len(db.dep)
181 // Dependencies are closed via a goroutine, so this polls waiting for
182 // numDeps to fall to want, waiting up to d.
183 func (db *DB) numDepsPollUntil(want int, d time.Duration) int {
184 deadline := time.Now().Add(d)
185 for {
186 n := db.numDeps()
187 if n <= want || time.Now().After(deadline) {
188 return n
190 time.Sleep(50 * time.Millisecond)
194 func (db *DB) numFreeConns() int {
195 db.mu.Lock()
196 defer db.mu.Unlock()
197 return len(db.freeConn)
200 func (db *DB) numOpenConns() int {
201 db.mu.Lock()
202 defer db.mu.Unlock()
203 return db.numOpen
206 // clearAllConns closes all connections in db.
207 func (db *DB) clearAllConns(t *testing.T) {
208 db.SetMaxIdleConns(0)
210 if g, w := db.numFreeConns(), 0; g != w {
211 t.Errorf("free conns = %d; want %d", g, w)
214 if n := db.numDepsPollUntil(0, time.Second); n > 0 {
215 t.Errorf("number of dependencies = %d; expected 0", n)
216 db.dumpDeps(t)
220 func (db *DB) dumpDeps(t *testing.T) {
221 for fc := range db.dep {
222 db.dumpDep(t, 0, fc, map[finalCloser]bool{})
226 func (db *DB) dumpDep(t *testing.T, depth int, dep finalCloser, seen map[finalCloser]bool) {
227 seen[dep] = true
228 indent := strings.Repeat(" ", depth)
229 ds := db.dep[dep]
230 for k := range ds {
231 t.Logf("%s%T (%p) waiting for -> %T (%p)", indent, dep, dep, k, k)
232 if fc, ok := k.(finalCloser); ok {
233 if !seen[fc] {
234 db.dumpDep(t, depth+1, fc, seen)
240 func TestQuery(t *testing.T) {
241 db := newTestDB(t, "people")
242 defer closeDB(t, db)
243 prepares0 := numPrepares(t, db)
244 rows, err := db.Query("SELECT|people|age,name|")
245 if err != nil {
246 t.Fatalf("Query: %v", err)
248 type row struct {
249 age int
250 name string
252 got := []row{}
253 for rows.Next() {
254 var r row
255 err = rows.Scan(&r.age, &r.name)
256 if err != nil {
257 t.Fatalf("Scan: %v", err)
259 got = append(got, r)
261 err = rows.Err()
262 if err != nil {
263 t.Fatalf("Err: %v", err)
265 want := []row{
266 {age: 1, name: "Alice"},
267 {age: 2, name: "Bob"},
268 {age: 3, name: "Chris"},
270 if !reflect.DeepEqual(got, want) {
271 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
274 // And verify that the final rows.Next() call, which hit EOF,
275 // also closed the rows connection.
276 if n := db.numFreeConns(); n != 1 {
277 t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
279 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
280 t.Errorf("executed %d Prepare statements; want 1", prepares)
284 // TestQueryContext tests canceling the context while scanning the rows.
285 func TestQueryContext(t *testing.T) {
286 db := newTestDB(t, "people")
287 defer closeDB(t, db)
288 prepares0 := numPrepares(t, db)
290 ctx, cancel := context.WithCancel(context.Background())
291 defer cancel()
293 rows, err := db.QueryContext(ctx, "SELECT|people|age,name|")
294 if err != nil {
295 t.Fatalf("Query: %v", err)
297 type row struct {
298 age int
299 name string
301 got := []row{}
302 index := 0
303 for rows.Next() {
304 if index == 2 {
305 cancel()
306 waitForRowsClose(t, rows, 5*time.Second)
308 var r row
309 err = rows.Scan(&r.age, &r.name)
310 if err != nil {
311 if index == 2 {
312 break
314 t.Fatalf("Scan: %v", err)
316 if index == 2 && err == nil {
317 t.Fatal("expected an error on last scan")
319 got = append(got, r)
320 index++
322 select {
323 case <-ctx.Done():
324 if err := ctx.Err(); err != context.Canceled {
325 t.Fatalf("context err = %v; want context.Canceled")
327 default:
328 t.Fatalf("context err = nil; want context.Canceled")
330 want := []row{
331 {age: 1, name: "Alice"},
332 {age: 2, name: "Bob"},
334 if !reflect.DeepEqual(got, want) {
335 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
338 // And verify that the final rows.Next() call, which hit EOF,
339 // also closed the rows connection.
340 waitForRowsClose(t, rows, 5*time.Second)
341 waitForFree(t, db, 5*time.Second, 1)
342 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
343 t.Errorf("executed %d Prepare statements; want 1", prepares)
347 func waitCondition(waitFor, checkEvery time.Duration, fn func() bool) bool {
348 deadline := time.Now().Add(waitFor)
349 for time.Now().Before(deadline) {
350 if fn() {
351 return true
353 time.Sleep(checkEvery)
355 return false
358 // waitForFree checks db.numFreeConns until either it equals want or
359 // the maxWait time elapses.
360 func waitForFree(t *testing.T, db *DB, maxWait time.Duration, want int) {
361 var numFree int
362 if !waitCondition(maxWait, 5*time.Millisecond, func() bool {
363 numFree = db.numFreeConns()
364 return numFree == want
365 }) {
366 t.Fatalf("free conns after hitting EOF = %d; want %d", numFree, want)
370 func waitForRowsClose(t *testing.T, rows *Rows, maxWait time.Duration) {
371 if !waitCondition(maxWait, 5*time.Millisecond, func() bool {
372 rows.closemu.RLock()
373 defer rows.closemu.RUnlock()
374 return rows.closed
375 }) {
376 t.Fatal("failed to close rows")
380 // TestQueryContextWait ensures that rows and all internal statements are closed when
381 // a query context is closed during execution.
382 func TestQueryContextWait(t *testing.T) {
383 db := newTestDB(t, "people")
384 defer closeDB(t, db)
385 prepares0 := numPrepares(t, db)
387 // TODO(kardianos): convert this from using a timeout to using an explicit
388 // cancel when the query signals that is is "executing" the query.
389 ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond)
390 defer cancel()
392 // This will trigger the *fakeConn.Prepare method which will take time
393 // performing the query. The ctxDriverPrepare func will check the context
394 // after this and close the rows and return an error.
395 _, err := db.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|")
396 if err != context.DeadlineExceeded {
397 t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
400 // Verify closed rows connection after error condition.
401 waitForFree(t, db, 5*time.Second, 1)
402 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
403 // TODO(kardianos): if the context timeouts before the db.QueryContext
404 // executes this check may fail. After adjusting how the context
405 // is canceled above revert this back to a Fatal error.
406 t.Logf("executed %d Prepare statements; want 1", prepares)
410 // TestTxContextWait tests the transaction behavior when the tx context is canceled
411 // during execution of the query.
412 func TestTxContextWait(t *testing.T) {
413 db := newTestDB(t, "people")
414 defer closeDB(t, db)
416 ctx, _ := context.WithTimeout(context.Background(), time.Millisecond*15)
418 tx, err := db.BeginTx(ctx, nil)
419 if err != nil {
420 // Guard against the context being canceled before BeginTx completes.
421 if err == context.DeadlineExceeded {
422 t.Skip("tx context canceled prior to first use")
424 t.Fatal(err)
427 // This will trigger the *fakeConn.Prepare method which will take time
428 // performing the query. The ctxDriverPrepare func will check the context
429 // after this and close the rows and return an error.
430 _, err = tx.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|")
431 if err != context.DeadlineExceeded {
432 t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
435 waitForFree(t, db, 5*time.Second, 0)
438 func TestMultiResultSetQuery(t *testing.T) {
439 db := newTestDB(t, "people")
440 defer closeDB(t, db)
441 prepares0 := numPrepares(t, db)
442 rows, err := db.Query("SELECT|people|age,name|;SELECT|people|name|")
443 if err != nil {
444 t.Fatalf("Query: %v", err)
446 type row1 struct {
447 age int
448 name string
450 type row2 struct {
451 name string
453 got1 := []row1{}
454 for rows.Next() {
455 var r row1
456 err = rows.Scan(&r.age, &r.name)
457 if err != nil {
458 t.Fatalf("Scan: %v", err)
460 got1 = append(got1, r)
462 err = rows.Err()
463 if err != nil {
464 t.Fatalf("Err: %v", err)
466 want1 := []row1{
467 {age: 1, name: "Alice"},
468 {age: 2, name: "Bob"},
469 {age: 3, name: "Chris"},
471 if !reflect.DeepEqual(got1, want1) {
472 t.Errorf("mismatch.\n got1: %#v\nwant: %#v", got1, want1)
475 if !rows.NextResultSet() {
476 t.Errorf("expected another result set")
479 got2 := []row2{}
480 for rows.Next() {
481 var r row2
482 err = rows.Scan(&r.name)
483 if err != nil {
484 t.Fatalf("Scan: %v", err)
486 got2 = append(got2, r)
488 err = rows.Err()
489 if err != nil {
490 t.Fatalf("Err: %v", err)
492 want2 := []row2{
493 {name: "Alice"},
494 {name: "Bob"},
495 {name: "Chris"},
497 if !reflect.DeepEqual(got2, want2) {
498 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got2, want2)
500 if rows.NextResultSet() {
501 t.Errorf("expected no more result sets")
504 // And verify that the final rows.Next() call, which hit EOF,
505 // also closed the rows connection.
506 waitForFree(t, db, 5*time.Second, 1)
507 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
508 t.Errorf("executed %d Prepare statements; want 1", prepares)
512 func TestQueryNamedArg(t *testing.T) {
513 db := newTestDB(t, "people")
514 defer closeDB(t, db)
515 prepares0 := numPrepares(t, db)
516 rows, err := db.Query(
517 // Ensure the name and age parameters only match on placeholder name, not position.
518 "SELECT|people|age,name|name=?name,age=?age",
519 Named("age", 2),
520 Named("name", "Bob"),
522 if err != nil {
523 t.Fatalf("Query: %v", err)
525 type row struct {
526 age int
527 name string
529 got := []row{}
530 for rows.Next() {
531 var r row
532 err = rows.Scan(&r.age, &r.name)
533 if err != nil {
534 t.Fatalf("Scan: %v", err)
536 got = append(got, r)
538 err = rows.Err()
539 if err != nil {
540 t.Fatalf("Err: %v", err)
542 want := []row{
543 {age: 2, name: "Bob"},
545 if !reflect.DeepEqual(got, want) {
546 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
549 // And verify that the final rows.Next() call, which hit EOF,
550 // also closed the rows connection.
551 if n := db.numFreeConns(); n != 1 {
552 t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
554 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
555 t.Errorf("executed %d Prepare statements; want 1", prepares)
559 func TestPoolExhaustOnCancel(t *testing.T) {
560 if testing.Short() {
561 t.Skip("long test")
563 db := newTestDB(t, "people")
564 defer closeDB(t, db)
566 max := 3
568 db.SetMaxOpenConns(max)
570 // First saturate the connection pool.
571 // Then start new requests for a connection that is cancelled after it is requested.
573 var saturate, saturateDone sync.WaitGroup
574 saturate.Add(max)
575 saturateDone.Add(max)
577 for i := 0; i < max; i++ {
578 go func() {
579 saturate.Done()
580 rows, err := db.Query("WAIT|500ms|SELECT|people|name,photo|")
581 if err != nil {
582 t.Fatalf("Query: %v", err)
584 rows.Close()
585 saturateDone.Done()
589 saturate.Wait()
591 // Now cancel the request while it is waiting.
592 ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
593 defer cancel()
595 for i := 0; i < max; i++ {
596 ctxReq, cancelReq := context.WithCancel(ctx)
597 go func() {
598 time.Sleep(time.Millisecond * 100)
599 cancelReq()
601 err := db.PingContext(ctxReq)
602 if err != context.Canceled {
603 t.Fatalf("PingContext (Exhaust): %v", err)
607 saturateDone.Wait()
609 // Now try to open a normal connection.
610 err := db.PingContext(ctx)
611 if err != nil {
612 t.Fatalf("PingContext (Normal): %v", err)
616 func TestByteOwnership(t *testing.T) {
617 db := newTestDB(t, "people")
618 defer closeDB(t, db)
619 rows, err := db.Query("SELECT|people|name,photo|")
620 if err != nil {
621 t.Fatalf("Query: %v", err)
623 type row struct {
624 name []byte
625 photo RawBytes
627 got := []row{}
628 for rows.Next() {
629 var r row
630 err = rows.Scan(&r.name, &r.photo)
631 if err != nil {
632 t.Fatalf("Scan: %v", err)
634 got = append(got, r)
636 corruptMemory := []byte("\xffPHOTO")
637 want := []row{
638 {name: []byte("Alice"), photo: corruptMemory},
639 {name: []byte("Bob"), photo: corruptMemory},
640 {name: []byte("Chris"), photo: corruptMemory},
642 if !reflect.DeepEqual(got, want) {
643 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
646 var photo RawBytes
647 err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo)
648 if err == nil {
649 t.Error("want error scanning into RawBytes from QueryRow")
653 func TestRowsColumns(t *testing.T) {
654 db := newTestDB(t, "people")
655 defer closeDB(t, db)
656 rows, err := db.Query("SELECT|people|age,name|")
657 if err != nil {
658 t.Fatalf("Query: %v", err)
660 cols, err := rows.Columns()
661 if err != nil {
662 t.Fatalf("Columns: %v", err)
664 want := []string{"age", "name"}
665 if !reflect.DeepEqual(cols, want) {
666 t.Errorf("got %#v; want %#v", cols, want)
668 if err := rows.Close(); err != nil {
669 t.Errorf("error closing rows: %s", err)
673 func TestRowsColumnTypes(t *testing.T) {
674 db := newTestDB(t, "people")
675 defer closeDB(t, db)
676 rows, err := db.Query("SELECT|people|age,name|")
677 if err != nil {
678 t.Fatalf("Query: %v", err)
680 tt, err := rows.ColumnTypes()
681 if err != nil {
682 t.Fatalf("ColumnTypes: %v", err)
685 types := make([]reflect.Type, len(tt))
686 for i, tp := range tt {
687 st := tp.ScanType()
688 if st == nil {
689 t.Errorf("scantype is null for column %q", tp.Name())
690 continue
692 types[i] = st
694 values := make([]interface{}, len(tt))
695 for i := range values {
696 values[i] = reflect.New(types[i]).Interface()
698 ct := 0
699 for rows.Next() {
700 err = rows.Scan(values...)
701 if err != nil {
702 t.Fatalf("failed to scan values in %v", err)
704 ct++
705 if ct == 0 {
706 if values[0].(string) != "Bob" {
707 t.Errorf("Expected Bob, got %v", values[0])
709 if values[1].(int) != 2 {
710 t.Errorf("Expected 2, got %v", values[1])
714 if ct != 3 {
715 t.Errorf("expected 3 rows, got %d", ct)
718 if err := rows.Close(); err != nil {
719 t.Errorf("error closing rows: %s", err)
723 func TestQueryRow(t *testing.T) {
724 db := newTestDB(t, "people")
725 defer closeDB(t, db)
726 var name string
727 var age int
728 var birthday time.Time
730 err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age)
731 if err == nil || !strings.Contains(err.Error(), "expected 2 destination arguments") {
732 t.Errorf("expected error from wrong number of arguments; actually got: %v", err)
735 err = db.QueryRow("SELECT|people|bdate|age=?", 3).Scan(&birthday)
736 if err != nil || !birthday.Equal(chrisBirthday) {
737 t.Errorf("chris birthday = %v, err = %v; want %v", birthday, err, chrisBirthday)
740 err = db.QueryRow("SELECT|people|age,name|age=?", 2).Scan(&age, &name)
741 if err != nil {
742 t.Fatalf("age QueryRow+Scan: %v", err)
744 if name != "Bob" {
745 t.Errorf("expected name Bob, got %q", name)
747 if age != 2 {
748 t.Errorf("expected age 2, got %d", age)
751 err = db.QueryRow("SELECT|people|age,name|name=?", "Alice").Scan(&age, &name)
752 if err != nil {
753 t.Fatalf("name QueryRow+Scan: %v", err)
755 if name != "Alice" {
756 t.Errorf("expected name Alice, got %q", name)
758 if age != 1 {
759 t.Errorf("expected age 1, got %d", age)
762 var photo []byte
763 err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo)
764 if err != nil {
765 t.Fatalf("photo QueryRow+Scan: %v", err)
767 want := []byte("APHOTO")
768 if !reflect.DeepEqual(photo, want) {
769 t.Errorf("photo = %q; want %q", photo, want)
773 func TestTxRollbackCommitErr(t *testing.T) {
774 db := newTestDB(t, "people")
775 defer closeDB(t, db)
777 tx, err := db.Begin()
778 if err != nil {
779 t.Fatal(err)
781 err = tx.Rollback()
782 if err != nil {
783 t.Errorf("expected nil error from Rollback; got %v", err)
785 err = tx.Commit()
786 if err != ErrTxDone {
787 t.Errorf("expected %q from Commit; got %q", ErrTxDone, err)
790 tx, err = db.Begin()
791 if err != nil {
792 t.Fatal(err)
794 err = tx.Commit()
795 if err != nil {
796 t.Errorf("expected nil error from Commit; got %v", err)
798 err = tx.Rollback()
799 if err != ErrTxDone {
800 t.Errorf("expected %q from Rollback; got %q", ErrTxDone, err)
804 func TestStatementErrorAfterClose(t *testing.T) {
805 db := newTestDB(t, "people")
806 defer closeDB(t, db)
807 stmt, err := db.Prepare("SELECT|people|age|name=?")
808 if err != nil {
809 t.Fatalf("Prepare: %v", err)
811 err = stmt.Close()
812 if err != nil {
813 t.Fatalf("Close: %v", err)
815 var name string
816 err = stmt.QueryRow("foo").Scan(&name)
817 if err == nil {
818 t.Errorf("expected error from QueryRow.Scan after Stmt.Close")
822 func TestStatementQueryRow(t *testing.T) {
823 db := newTestDB(t, "people")
824 defer closeDB(t, db)
825 stmt, err := db.Prepare("SELECT|people|age|name=?")
826 if err != nil {
827 t.Fatalf("Prepare: %v", err)
829 defer stmt.Close()
830 var age int
831 for n, tt := range []struct {
832 name string
833 want int
835 {"Alice", 1},
836 {"Bob", 2},
837 {"Chris", 3},
839 if err := stmt.QueryRow(tt.name).Scan(&age); err != nil {
840 t.Errorf("%d: on %q, QueryRow/Scan: %v", n, tt.name, err)
841 } else if age != tt.want {
842 t.Errorf("%d: age=%d, want %d", n, age, tt.want)
847 type stubDriverStmt struct {
848 err error
851 func (s stubDriverStmt) Close() error {
852 return s.err
855 func (s stubDriverStmt) NumInput() int {
856 return -1
859 func (s stubDriverStmt) Exec(args []driver.Value) (driver.Result, error) {
860 return nil, nil
863 func (s stubDriverStmt) Query(args []driver.Value) (driver.Rows, error) {
864 return nil, nil
867 // golang.org/issue/12798
868 func TestStatementClose(t *testing.T) {
869 want := errors.New("STMT ERROR")
871 tests := []struct {
872 stmt *Stmt
873 msg string
875 {&Stmt{stickyErr: want}, "stickyErr not propagated"},
876 {&Stmt{tx: &Tx{}, txds: &driverStmt{Locker: &sync.Mutex{}, si: stubDriverStmt{want}}}, "driverStmt.Close() error not propagated"},
878 for _, test := range tests {
879 if err := test.stmt.Close(); err != want {
880 t.Errorf("%s. Got stmt.Close() = %v, want = %v", test.msg, err, want)
885 // golang.org/issue/3734
886 func TestStatementQueryRowConcurrent(t *testing.T) {
887 db := newTestDB(t, "people")
888 defer closeDB(t, db)
889 stmt, err := db.Prepare("SELECT|people|age|name=?")
890 if err != nil {
891 t.Fatalf("Prepare: %v", err)
893 defer stmt.Close()
895 const n = 10
896 ch := make(chan error, n)
897 for i := 0; i < n; i++ {
898 go func() {
899 var age int
900 err := stmt.QueryRow("Alice").Scan(&age)
901 if err == nil && age != 1 {
902 err = fmt.Errorf("unexpected age %d", age)
904 ch <- err
907 for i := 0; i < n; i++ {
908 if err := <-ch; err != nil {
909 t.Error(err)
914 // just a test of fakedb itself
915 func TestBogusPreboundParameters(t *testing.T) {
916 db := newTestDB(t, "foo")
917 defer closeDB(t, db)
918 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
919 _, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion")
920 if err == nil {
921 t.Fatalf("expected error")
923 if err.Error() != `fakedb: invalid conversion to int32 from "bogusconversion"` {
924 t.Errorf("unexpected error: %v", err)
928 func TestExec(t *testing.T) {
929 db := newTestDB(t, "foo")
930 defer closeDB(t, db)
931 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
932 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
933 if err != nil {
934 t.Errorf("Stmt, err = %v, %v", stmt, err)
936 defer stmt.Close()
938 type execTest struct {
939 args []interface{}
940 wantErr string
942 execTests := []execTest{
943 // Okay:
944 {[]interface{}{"Brad", 31}, ""},
945 {[]interface{}{"Brad", int64(31)}, ""},
946 {[]interface{}{"Bob", "32"}, ""},
947 {[]interface{}{7, 9}, ""},
949 // Invalid conversions:
950 {[]interface{}{"Brad", int64(0xFFFFFFFF)}, "sql: converting argument $2 type: sql/driver: value 4294967295 overflows int32"},
951 {[]interface{}{"Brad", "strconv fail"}, `sql: converting argument $2 type: sql/driver: value "strconv fail" can't be converted to int32`},
953 // Wrong number of args:
954 {[]interface{}{}, "sql: expected 2 arguments, got 0"},
955 {[]interface{}{1, 2, 3}, "sql: expected 2 arguments, got 3"},
957 for n, et := range execTests {
958 _, err := stmt.Exec(et.args...)
959 errStr := ""
960 if err != nil {
961 errStr = err.Error()
963 if errStr != et.wantErr {
964 t.Errorf("stmt.Execute #%d: for %v, got error %q, want error %q",
965 n, et.args, errStr, et.wantErr)
970 func TestTxPrepare(t *testing.T) {
971 db := newTestDB(t, "")
972 defer closeDB(t, db)
973 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
974 tx, err := db.Begin()
975 if err != nil {
976 t.Fatalf("Begin = %v", err)
978 stmt, err := tx.Prepare("INSERT|t1|name=?,age=?")
979 if err != nil {
980 t.Fatalf("Stmt, err = %v, %v", stmt, err)
982 defer stmt.Close()
983 _, err = stmt.Exec("Bobby", 7)
984 if err != nil {
985 t.Fatalf("Exec = %v", err)
987 err = tx.Commit()
988 if err != nil {
989 t.Fatalf("Commit = %v", err)
991 // Commit() should have closed the statement
992 if !stmt.closed {
993 t.Fatal("Stmt not closed after Commit")
997 func TestTxStmt(t *testing.T) {
998 db := newTestDB(t, "")
999 defer closeDB(t, db)
1000 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1001 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1002 if err != nil {
1003 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1005 defer stmt.Close()
1006 tx, err := db.Begin()
1007 if err != nil {
1008 t.Fatalf("Begin = %v", err)
1010 txs := tx.Stmt(stmt)
1011 defer txs.Close()
1012 _, err = txs.Exec("Bobby", 7)
1013 if err != nil {
1014 t.Fatalf("Exec = %v", err)
1016 err = tx.Commit()
1017 if err != nil {
1018 t.Fatalf("Commit = %v", err)
1020 // Commit() should have closed the statement
1021 if !txs.closed {
1022 t.Fatal("Stmt not closed after Commit")
1026 // Issue: https://golang.org/issue/2784
1027 // This test didn't fail before because we got lucky with the fakedb driver.
1028 // It was failing, and now not, in github.com/bradfitz/go-sql-test
1029 func TestTxQuery(t *testing.T) {
1030 db := newTestDB(t, "")
1031 defer closeDB(t, db)
1032 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1033 exec(t, db, "INSERT|t1|name=Alice")
1035 tx, err := db.Begin()
1036 if err != nil {
1037 t.Fatal(err)
1039 defer tx.Rollback()
1041 r, err := tx.Query("SELECT|t1|name|")
1042 if err != nil {
1043 t.Fatal(err)
1045 defer r.Close()
1047 if !r.Next() {
1048 if r.Err() != nil {
1049 t.Fatal(r.Err())
1051 t.Fatal("expected one row")
1054 var x string
1055 err = r.Scan(&x)
1056 if err != nil {
1057 t.Fatal(err)
1061 func TestTxQueryInvalid(t *testing.T) {
1062 db := newTestDB(t, "")
1063 defer closeDB(t, db)
1065 tx, err := db.Begin()
1066 if err != nil {
1067 t.Fatal(err)
1069 defer tx.Rollback()
1071 _, err = tx.Query("SELECT|t1|name|")
1072 if err == nil {
1073 t.Fatal("Error expected")
1077 // Tests fix for issue 4433, that retries in Begin happen when
1078 // conn.Begin() returns ErrBadConn
1079 func TestTxErrBadConn(t *testing.T) {
1080 db, err := Open("test", fakeDBName+";badConn")
1081 if err != nil {
1082 t.Fatalf("Open: %v", err)
1084 if _, err := db.Exec("WIPE"); err != nil {
1085 t.Fatalf("exec wipe: %v", err)
1087 defer closeDB(t, db)
1088 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1089 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1090 if err != nil {
1091 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1093 defer stmt.Close()
1094 tx, err := db.Begin()
1095 if err != nil {
1096 t.Fatalf("Begin = %v", err)
1098 txs := tx.Stmt(stmt)
1099 defer txs.Close()
1100 _, err = txs.Exec("Bobby", 7)
1101 if err != nil {
1102 t.Fatalf("Exec = %v", err)
1104 err = tx.Commit()
1105 if err != nil {
1106 t.Fatalf("Commit = %v", err)
1110 // Tests fix for issue 2542, that we release a lock when querying on
1111 // a closed connection.
1112 func TestIssue2542Deadlock(t *testing.T) {
1113 db := newTestDB(t, "people")
1114 closeDB(t, db)
1115 for i := 0; i < 2; i++ {
1116 _, err := db.Query("SELECT|people|age,name|")
1117 if err == nil {
1118 t.Fatalf("expected error")
1123 // From golang.org/issue/3865
1124 func TestCloseStmtBeforeRows(t *testing.T) {
1125 db := newTestDB(t, "people")
1126 defer closeDB(t, db)
1128 s, err := db.Prepare("SELECT|people|name|")
1129 if err != nil {
1130 t.Fatal(err)
1133 r, err := s.Query()
1134 if err != nil {
1135 s.Close()
1136 t.Fatal(err)
1139 err = s.Close()
1140 if err != nil {
1141 t.Fatal(err)
1144 r.Close()
1147 // Tests fix for issue 2788, that we bind nil to a []byte if the
1148 // value in the column is sql null
1149 func TestNullByteSlice(t *testing.T) {
1150 db := newTestDB(t, "")
1151 defer closeDB(t, db)
1152 exec(t, db, "CREATE|t|id=int32,name=nullstring")
1153 exec(t, db, "INSERT|t|id=10,name=?", nil)
1155 var name []byte
1157 err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
1158 if err != nil {
1159 t.Fatal(err)
1161 if name != nil {
1162 t.Fatalf("name []byte should be nil for null column value, got: %#v", name)
1165 exec(t, db, "INSERT|t|id=11,name=?", "bob")
1166 err = db.QueryRow("SELECT|t|name|id=?", 11).Scan(&name)
1167 if err != nil {
1168 t.Fatal(err)
1170 if string(name) != "bob" {
1171 t.Fatalf("name []byte should be bob, got: %q", string(name))
1175 func TestPointerParamsAndScans(t *testing.T) {
1176 db := newTestDB(t, "")
1177 defer closeDB(t, db)
1178 exec(t, db, "CREATE|t|id=int32,name=nullstring")
1180 bob := "bob"
1181 var name *string
1183 name = &bob
1184 exec(t, db, "INSERT|t|id=10,name=?", name)
1185 name = nil
1186 exec(t, db, "INSERT|t|id=20,name=?", name)
1188 err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
1189 if err != nil {
1190 t.Fatalf("querying id 10: %v", err)
1192 if name == nil {
1193 t.Errorf("id 10's name = nil; want bob")
1194 } else if *name != "bob" {
1195 t.Errorf("id 10's name = %q; want bob", *name)
1198 err = db.QueryRow("SELECT|t|name|id=?", 20).Scan(&name)
1199 if err != nil {
1200 t.Fatalf("querying id 20: %v", err)
1202 if name != nil {
1203 t.Errorf("id 20 = %q; want nil", *name)
1207 func TestQueryRowClosingStmt(t *testing.T) {
1208 db := newTestDB(t, "people")
1209 defer closeDB(t, db)
1210 var name string
1211 var age int
1212 err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age, &name)
1213 if err != nil {
1214 t.Fatal(err)
1216 if len(db.freeConn) != 1 {
1217 t.Fatalf("expected 1 free conn")
1219 fakeConn := db.freeConn[0].ci.(*fakeConn)
1220 if made, closed := fakeConn.stmtsMade, fakeConn.stmtsClosed; made != closed {
1221 t.Errorf("statement close mismatch: made %d, closed %d", made, closed)
1225 var atomicRowsCloseHook atomic.Value // of func(*Rows, *error)
1227 func init() {
1228 rowsCloseHook = func() func(*Rows, *error) {
1229 fn, _ := atomicRowsCloseHook.Load().(func(*Rows, *error))
1230 return fn
1234 func setRowsCloseHook(fn func(*Rows, *error)) {
1235 if fn == nil {
1236 // Can't change an atomic.Value back to nil, so set it to this
1237 // no-op func instead.
1238 fn = func(*Rows, *error) {}
1240 atomicRowsCloseHook.Store(fn)
1243 // Test issue 6651
1244 func TestIssue6651(t *testing.T) {
1245 db := newTestDB(t, "people")
1246 defer closeDB(t, db)
1248 var v string
1250 want := "error in rows.Next"
1251 rowsCursorNextHook = func(dest []driver.Value) error {
1252 return fmt.Errorf(want)
1254 defer func() { rowsCursorNextHook = nil }()
1256 err := db.QueryRow("SELECT|people|name|").Scan(&v)
1257 if err == nil || err.Error() != want {
1258 t.Errorf("error = %q; want %q", err, want)
1260 rowsCursorNextHook = nil
1262 want = "error in rows.Close"
1263 setRowsCloseHook(func(rows *Rows, err *error) {
1264 *err = fmt.Errorf(want)
1266 defer setRowsCloseHook(nil)
1267 err = db.QueryRow("SELECT|people|name|").Scan(&v)
1268 if err == nil || err.Error() != want {
1269 t.Errorf("error = %q; want %q", err, want)
1273 type nullTestRow struct {
1274 nullParam interface{}
1275 notNullParam interface{}
1276 scanNullVal interface{}
1279 type nullTestSpec struct {
1280 nullType string
1281 notNullType string
1282 rows [6]nullTestRow
1285 func TestNullStringParam(t *testing.T) {
1286 spec := nullTestSpec{"nullstring", "string", [6]nullTestRow{
1287 {NullString{"aqua", true}, "", NullString{"aqua", true}},
1288 {NullString{"brown", false}, "", NullString{"", false}},
1289 {"chartreuse", "", NullString{"chartreuse", true}},
1290 {NullString{"darkred", true}, "", NullString{"darkred", true}},
1291 {NullString{"eel", false}, "", NullString{"", false}},
1292 {"foo", NullString{"black", false}, nil},
1294 nullTestRun(t, spec)
1297 func TestNullInt64Param(t *testing.T) {
1298 spec := nullTestSpec{"nullint64", "int64", [6]nullTestRow{
1299 {NullInt64{31, true}, 1, NullInt64{31, true}},
1300 {NullInt64{-22, false}, 1, NullInt64{0, false}},
1301 {22, 1, NullInt64{22, true}},
1302 {NullInt64{33, true}, 1, NullInt64{33, true}},
1303 {NullInt64{222, false}, 1, NullInt64{0, false}},
1304 {0, NullInt64{31, false}, nil},
1306 nullTestRun(t, spec)
1309 func TestNullFloat64Param(t *testing.T) {
1310 spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{
1311 {NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
1312 {NullFloat64{13.1, false}, 1, NullFloat64{0, false}},
1313 {-22.9, 1, NullFloat64{-22.9, true}},
1314 {NullFloat64{33.81, true}, 1, NullFloat64{33.81, true}},
1315 {NullFloat64{222, false}, 1, NullFloat64{0, false}},
1316 {10, NullFloat64{31.2, false}, nil},
1318 nullTestRun(t, spec)
1321 func TestNullBoolParam(t *testing.T) {
1322 spec := nullTestSpec{"nullbool", "bool", [6]nullTestRow{
1323 {NullBool{false, true}, true, NullBool{false, true}},
1324 {NullBool{true, false}, false, NullBool{false, false}},
1325 {true, true, NullBool{true, true}},
1326 {NullBool{true, true}, false, NullBool{true, true}},
1327 {NullBool{true, false}, true, NullBool{false, false}},
1328 {true, NullBool{true, false}, nil},
1330 nullTestRun(t, spec)
1333 func nullTestRun(t *testing.T, spec nullTestSpec) {
1334 db := newTestDB(t, "")
1335 defer closeDB(t, db)
1336 exec(t, db, fmt.Sprintf("CREATE|t|id=int32,name=string,nullf=%s,notnullf=%s", spec.nullType, spec.notNullType))
1338 // Inserts with db.Exec:
1339 exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 1, "alice", spec.rows[0].nullParam, spec.rows[0].notNullParam)
1340 exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 2, "bob", spec.rows[1].nullParam, spec.rows[1].notNullParam)
1342 // Inserts with a prepared statement:
1343 stmt, err := db.Prepare("INSERT|t|id=?,name=?,nullf=?,notnullf=?")
1344 if err != nil {
1345 t.Fatalf("prepare: %v", err)
1347 defer stmt.Close()
1348 if _, err := stmt.Exec(3, "chris", spec.rows[2].nullParam, spec.rows[2].notNullParam); err != nil {
1349 t.Errorf("exec insert chris: %v", err)
1351 if _, err := stmt.Exec(4, "dave", spec.rows[3].nullParam, spec.rows[3].notNullParam); err != nil {
1352 t.Errorf("exec insert dave: %v", err)
1354 if _, err := stmt.Exec(5, "eleanor", spec.rows[4].nullParam, spec.rows[4].notNullParam); err != nil {
1355 t.Errorf("exec insert eleanor: %v", err)
1358 // Can't put null val into non-null col
1359 if _, err := stmt.Exec(6, "bob", spec.rows[5].nullParam, spec.rows[5].notNullParam); err == nil {
1360 t.Errorf("expected error inserting nil val with prepared statement Exec")
1363 _, err = db.Exec("INSERT|t|id=?,name=?,nullf=?", 999, nil, nil)
1364 if err == nil {
1365 // TODO: this test fails, but it's just because
1366 // fakeConn implements the optional Execer interface,
1367 // so arguably this is the correct behavior. But
1368 // maybe I should flesh out the fakeConn.Exec
1369 // implementation so this properly fails.
1370 // t.Errorf("expected error inserting nil name with Exec")
1373 paramtype := reflect.TypeOf(spec.rows[0].nullParam)
1374 bindVal := reflect.New(paramtype).Interface()
1376 for i := 0; i < 5; i++ {
1377 id := i + 1
1378 if err := db.QueryRow("SELECT|t|nullf|id=?", id).Scan(bindVal); err != nil {
1379 t.Errorf("id=%d Scan: %v", id, err)
1381 bindValDeref := reflect.ValueOf(bindVal).Elem().Interface()
1382 if !reflect.DeepEqual(bindValDeref, spec.rows[i].scanNullVal) {
1383 t.Errorf("id=%d got %#v, want %#v", id, bindValDeref, spec.rows[i].scanNullVal)
1388 // golang.org/issue/4859
1389 func TestQueryRowNilScanDest(t *testing.T) {
1390 db := newTestDB(t, "people")
1391 defer closeDB(t, db)
1392 var name *string // nil pointer
1393 err := db.QueryRow("SELECT|people|name|").Scan(name)
1394 want := "sql: Scan error on column index 0: destination pointer is nil"
1395 if err == nil || err.Error() != want {
1396 t.Errorf("error = %q; want %q", err.Error(), want)
1400 func TestIssue4902(t *testing.T) {
1401 db := newTestDB(t, "people")
1402 defer closeDB(t, db)
1404 driver := db.driver.(*fakeDriver)
1405 opens0 := driver.openCount
1407 var stmt *Stmt
1408 var err error
1409 for i := 0; i < 10; i++ {
1410 stmt, err = db.Prepare("SELECT|people|name|")
1411 if err != nil {
1412 t.Fatal(err)
1414 err = stmt.Close()
1415 if err != nil {
1416 t.Fatal(err)
1420 opens := driver.openCount - opens0
1421 if opens > 1 {
1422 t.Errorf("opens = %d; want <= 1", opens)
1423 t.Logf("db = %#v", db)
1424 t.Logf("driver = %#v", driver)
1425 t.Logf("stmt = %#v", stmt)
1429 // Issue 3857
1430 // This used to deadlock.
1431 func TestSimultaneousQueries(t *testing.T) {
1432 db := newTestDB(t, "people")
1433 defer closeDB(t, db)
1435 tx, err := db.Begin()
1436 if err != nil {
1437 t.Fatal(err)
1439 defer tx.Rollback()
1441 r1, err := tx.Query("SELECT|people|name|")
1442 if err != nil {
1443 t.Fatal(err)
1445 defer r1.Close()
1447 r2, err := tx.Query("SELECT|people|name|")
1448 if err != nil {
1449 t.Fatal(err)
1451 defer r2.Close()
1454 func TestMaxIdleConns(t *testing.T) {
1455 db := newTestDB(t, "people")
1456 defer closeDB(t, db)
1458 tx, err := db.Begin()
1459 if err != nil {
1460 t.Fatal(err)
1462 tx.Commit()
1463 if got := len(db.freeConn); got != 1 {
1464 t.Errorf("freeConns = %d; want 1", got)
1467 db.SetMaxIdleConns(0)
1469 if got := len(db.freeConn); got != 0 {
1470 t.Errorf("freeConns after set to zero = %d; want 0", got)
1473 tx, err = db.Begin()
1474 if err != nil {
1475 t.Fatal(err)
1477 tx.Commit()
1478 if got := len(db.freeConn); got != 0 {
1479 t.Errorf("freeConns = %d; want 0", got)
1483 func TestMaxOpenConns(t *testing.T) {
1484 if testing.Short() {
1485 t.Skip("skipping in short mode")
1487 defer setHookpostCloseConn(nil)
1488 setHookpostCloseConn(func(_ *fakeConn, err error) {
1489 if err != nil {
1490 t.Errorf("Error closing fakeConn: %v", err)
1494 db := newTestDB(t, "magicquery")
1495 defer closeDB(t, db)
1497 driver := db.driver.(*fakeDriver)
1499 // Force the number of open connections to 0 so we can get an accurate
1500 // count for the test
1501 db.clearAllConns(t)
1503 driver.mu.Lock()
1504 opens0 := driver.openCount
1505 closes0 := driver.closeCount
1506 driver.mu.Unlock()
1508 db.SetMaxIdleConns(10)
1509 db.SetMaxOpenConns(10)
1511 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
1512 if err != nil {
1513 t.Fatal(err)
1516 // Start 50 parallel slow queries.
1517 const (
1518 nquery = 50
1519 sleepMillis = 25
1520 nbatch = 2
1522 var wg sync.WaitGroup
1523 for batch := 0; batch < nbatch; batch++ {
1524 for i := 0; i < nquery; i++ {
1525 wg.Add(1)
1526 go func() {
1527 defer wg.Done()
1528 var op string
1529 if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
1530 t.Error(err)
1534 // Sleep for twice the expected length of time for the
1535 // batch of 50 queries above to finish before starting
1536 // the next round.
1537 time.Sleep(2 * sleepMillis * time.Millisecond)
1539 wg.Wait()
1541 if g, w := db.numFreeConns(), 10; g != w {
1542 t.Errorf("free conns = %d; want %d", g, w)
1545 if n := db.numDepsPollUntil(20, time.Second); n > 20 {
1546 t.Errorf("number of dependencies = %d; expected <= 20", n)
1547 db.dumpDeps(t)
1550 driver.mu.Lock()
1551 opens := driver.openCount - opens0
1552 closes := driver.closeCount - closes0
1553 driver.mu.Unlock()
1555 if opens > 10 {
1556 t.Logf("open calls = %d", opens)
1557 t.Logf("close calls = %d", closes)
1558 t.Errorf("db connections opened = %d; want <= 10", opens)
1559 db.dumpDeps(t)
1562 if err := stmt.Close(); err != nil {
1563 t.Fatal(err)
1566 if g, w := db.numFreeConns(), 10; g != w {
1567 t.Errorf("free conns = %d; want %d", g, w)
1570 if n := db.numDepsPollUntil(10, time.Second); n > 10 {
1571 t.Errorf("number of dependencies = %d; expected <= 10", n)
1572 db.dumpDeps(t)
1575 db.SetMaxOpenConns(5)
1577 if g, w := db.numFreeConns(), 5; g != w {
1578 t.Errorf("free conns = %d; want %d", g, w)
1581 if n := db.numDepsPollUntil(5, time.Second); n > 5 {
1582 t.Errorf("number of dependencies = %d; expected 0", n)
1583 db.dumpDeps(t)
1586 db.SetMaxOpenConns(0)
1588 if g, w := db.numFreeConns(), 5; g != w {
1589 t.Errorf("free conns = %d; want %d", g, w)
1592 if n := db.numDepsPollUntil(5, time.Second); n > 5 {
1593 t.Errorf("number of dependencies = %d; expected 0", n)
1594 db.dumpDeps(t)
1597 db.clearAllConns(t)
1600 // Issue 9453: tests that SetMaxOpenConns can be lowered at runtime
1601 // and affects the subsequent release of connections.
1602 func TestMaxOpenConnsOnBusy(t *testing.T) {
1603 defer setHookpostCloseConn(nil)
1604 setHookpostCloseConn(func(_ *fakeConn, err error) {
1605 if err != nil {
1606 t.Errorf("Error closing fakeConn: %v", err)
1610 db := newTestDB(t, "magicquery")
1611 defer closeDB(t, db)
1613 db.SetMaxOpenConns(3)
1615 ctx := context.Background()
1617 conn0, err := db.conn(ctx, cachedOrNewConn)
1618 if err != nil {
1619 t.Fatalf("db open conn fail: %v", err)
1622 conn1, err := db.conn(ctx, cachedOrNewConn)
1623 if err != nil {
1624 t.Fatalf("db open conn fail: %v", err)
1627 conn2, err := db.conn(ctx, cachedOrNewConn)
1628 if err != nil {
1629 t.Fatalf("db open conn fail: %v", err)
1632 if g, w := db.numOpen, 3; g != w {
1633 t.Errorf("free conns = %d; want %d", g, w)
1636 db.SetMaxOpenConns(2)
1637 if g, w := db.numOpen, 3; g != w {
1638 t.Errorf("free conns = %d; want %d", g, w)
1641 conn0.releaseConn(nil)
1642 conn1.releaseConn(nil)
1643 if g, w := db.numOpen, 2; g != w {
1644 t.Errorf("free conns = %d; want %d", g, w)
1647 conn2.releaseConn(nil)
1648 if g, w := db.numOpen, 2; g != w {
1649 t.Errorf("free conns = %d; want %d", g, w)
1653 // Issue 10886: tests that all connection attempts return when more than
1654 // DB.maxOpen connections are in flight and the first DB.maxOpen fail.
1655 func TestPendingConnsAfterErr(t *testing.T) {
1656 const (
1657 maxOpen = 2
1658 tryOpen = maxOpen*2 + 2
1661 // No queries will be run.
1662 db, err := Open("test", fakeDBName)
1663 if err != nil {
1664 t.Fatalf("Open: %v", err)
1666 defer closeDB(t, db)
1667 defer func() {
1668 for k, v := range db.lastPut {
1669 t.Logf("%p: %v", k, v)
1673 db.SetMaxOpenConns(maxOpen)
1674 db.SetMaxIdleConns(0)
1676 errOffline := errors.New("db offline")
1678 defer func() { setHookOpenErr(nil) }()
1680 errs := make(chan error, tryOpen)
1682 var opening sync.WaitGroup
1683 opening.Add(tryOpen)
1685 setHookOpenErr(func() error {
1686 // Wait for all connections to enqueue.
1687 opening.Wait()
1688 return errOffline
1691 for i := 0; i < tryOpen; i++ {
1692 go func() {
1693 opening.Done() // signal one connection is in flight
1694 _, err := db.Exec("will never run")
1695 errs <- err
1699 opening.Wait() // wait for all workers to begin running
1701 const timeout = 5 * time.Second
1702 to := time.NewTimer(timeout)
1703 defer to.Stop()
1705 // check that all connections fail without deadlock
1706 for i := 0; i < tryOpen; i++ {
1707 select {
1708 case err := <-errs:
1709 if got, want := err, errOffline; got != want {
1710 t.Errorf("unexpected err: got %v, want %v", got, want)
1712 case <-to.C:
1713 t.Fatalf("orphaned connection request(s), still waiting after %v", timeout)
1717 // Wait a reasonable time for the database to close all connections.
1718 tick := time.NewTicker(3 * time.Millisecond)
1719 defer tick.Stop()
1720 for {
1721 select {
1722 case <-tick.C:
1723 db.mu.Lock()
1724 if db.numOpen == 0 {
1725 db.mu.Unlock()
1726 return
1728 db.mu.Unlock()
1729 case <-to.C:
1730 // Closing the database will check for numOpen and fail the test.
1731 return
1736 func TestSingleOpenConn(t *testing.T) {
1737 db := newTestDB(t, "people")
1738 defer closeDB(t, db)
1740 db.SetMaxOpenConns(1)
1742 rows, err := db.Query("SELECT|people|name|")
1743 if err != nil {
1744 t.Fatal(err)
1746 if err = rows.Close(); err != nil {
1747 t.Fatal(err)
1749 // shouldn't deadlock
1750 rows, err = db.Query("SELECT|people|name|")
1751 if err != nil {
1752 t.Fatal(err)
1754 if err = rows.Close(); err != nil {
1755 t.Fatal(err)
1759 func TestStats(t *testing.T) {
1760 db := newTestDB(t, "people")
1761 stats := db.Stats()
1762 if got := stats.OpenConnections; got != 1 {
1763 t.Errorf("stats.OpenConnections = %d; want 1", got)
1766 tx, err := db.Begin()
1767 if err != nil {
1768 t.Fatal(err)
1770 tx.Commit()
1772 closeDB(t, db)
1773 stats = db.Stats()
1774 if got := stats.OpenConnections; got != 0 {
1775 t.Errorf("stats.OpenConnections = %d; want 0", got)
1779 func TestConnMaxLifetime(t *testing.T) {
1780 t0 := time.Unix(1000000, 0)
1781 offset := time.Duration(0)
1783 nowFunc = func() time.Time { return t0.Add(offset) }
1784 defer func() { nowFunc = time.Now }()
1786 db := newTestDB(t, "magicquery")
1787 defer closeDB(t, db)
1789 driver := db.driver.(*fakeDriver)
1791 // Force the number of open connections to 0 so we can get an accurate
1792 // count for the test
1793 db.clearAllConns(t)
1795 driver.mu.Lock()
1796 opens0 := driver.openCount
1797 closes0 := driver.closeCount
1798 driver.mu.Unlock()
1800 db.SetMaxIdleConns(10)
1801 db.SetMaxOpenConns(10)
1803 tx, err := db.Begin()
1804 if err != nil {
1805 t.Fatal(err)
1808 offset = time.Second
1809 tx2, err := db.Begin()
1810 if err != nil {
1811 t.Fatal(err)
1814 tx.Commit()
1815 tx2.Commit()
1817 driver.mu.Lock()
1818 opens := driver.openCount - opens0
1819 closes := driver.closeCount - closes0
1820 driver.mu.Unlock()
1822 if opens != 2 {
1823 t.Errorf("opens = %d; want 2", opens)
1825 if closes != 0 {
1826 t.Errorf("closes = %d; want 0", closes)
1828 if g, w := db.numFreeConns(), 2; g != w {
1829 t.Errorf("free conns = %d; want %d", g, w)
1832 // Expire first conn
1833 offset = time.Second * 11
1834 db.SetConnMaxLifetime(time.Second * 10)
1835 if err != nil {
1836 t.Fatal(err)
1839 tx, err = db.Begin()
1840 if err != nil {
1841 t.Fatal(err)
1843 tx2, err = db.Begin()
1844 if err != nil {
1845 t.Fatal(err)
1847 tx.Commit()
1848 tx2.Commit()
1850 driver.mu.Lock()
1851 opens = driver.openCount - opens0
1852 closes = driver.closeCount - closes0
1853 driver.mu.Unlock()
1855 if opens != 3 {
1856 t.Errorf("opens = %d; want 3", opens)
1858 if closes != 1 {
1859 t.Errorf("closes = %d; want 1", closes)
1863 // golang.org/issue/5323
1864 func TestStmtCloseDeps(t *testing.T) {
1865 if testing.Short() {
1866 t.Skip("skipping in short mode")
1868 defer setHookpostCloseConn(nil)
1869 setHookpostCloseConn(func(_ *fakeConn, err error) {
1870 if err != nil {
1871 t.Errorf("Error closing fakeConn: %v", err)
1875 db := newTestDB(t, "magicquery")
1876 defer closeDB(t, db)
1878 driver := db.driver.(*fakeDriver)
1880 driver.mu.Lock()
1881 opens0 := driver.openCount
1882 closes0 := driver.closeCount
1883 driver.mu.Unlock()
1884 openDelta0 := opens0 - closes0
1886 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
1887 if err != nil {
1888 t.Fatal(err)
1891 // Start 50 parallel slow queries.
1892 const (
1893 nquery = 50
1894 sleepMillis = 25
1895 nbatch = 2
1897 var wg sync.WaitGroup
1898 for batch := 0; batch < nbatch; batch++ {
1899 for i := 0; i < nquery; i++ {
1900 wg.Add(1)
1901 go func() {
1902 defer wg.Done()
1903 var op string
1904 if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
1905 t.Error(err)
1909 // Sleep for twice the expected length of time for the
1910 // batch of 50 queries above to finish before starting
1911 // the next round.
1912 time.Sleep(2 * sleepMillis * time.Millisecond)
1914 wg.Wait()
1916 if g, w := db.numFreeConns(), 2; g != w {
1917 t.Errorf("free conns = %d; want %d", g, w)
1920 if n := db.numDepsPollUntil(4, time.Second); n > 4 {
1921 t.Errorf("number of dependencies = %d; expected <= 4", n)
1922 db.dumpDeps(t)
1925 driver.mu.Lock()
1926 opens := driver.openCount - opens0
1927 closes := driver.closeCount - closes0
1928 openDelta := (driver.openCount - driver.closeCount) - openDelta0
1929 driver.mu.Unlock()
1931 if openDelta > 2 {
1932 t.Logf("open calls = %d", opens)
1933 t.Logf("close calls = %d", closes)
1934 t.Logf("open delta = %d", openDelta)
1935 t.Errorf("db connections opened = %d; want <= 2", openDelta)
1936 db.dumpDeps(t)
1939 if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
1940 return len(stmt.css) <= nquery
1941 }) {
1942 t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery)
1945 if err := stmt.Close(); err != nil {
1946 t.Fatal(err)
1949 if g, w := db.numFreeConns(), 2; g != w {
1950 t.Errorf("free conns = %d; want %d", g, w)
1953 if n := db.numDepsPollUntil(2, time.Second); n > 2 {
1954 t.Errorf("number of dependencies = %d; expected <= 2", n)
1955 db.dumpDeps(t)
1958 db.clearAllConns(t)
1961 // golang.org/issue/5046
1962 func TestCloseConnBeforeStmts(t *testing.T) {
1963 db := newTestDB(t, "people")
1964 defer closeDB(t, db)
1966 defer setHookpostCloseConn(nil)
1967 setHookpostCloseConn(func(_ *fakeConn, err error) {
1968 if err != nil {
1969 t.Errorf("Error closing fakeConn: %v; from %s", err, stack())
1970 db.dumpDeps(t)
1971 t.Errorf("DB = %#v", db)
1975 stmt, err := db.Prepare("SELECT|people|name|")
1976 if err != nil {
1977 t.Fatal(err)
1980 if len(db.freeConn) != 1 {
1981 t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn))
1983 dc := db.freeConn[0]
1984 if dc.closed {
1985 t.Errorf("conn shouldn't be closed")
1988 if n := len(dc.openStmt); n != 1 {
1989 t.Errorf("driverConn num openStmt = %d; want 1", n)
1991 err = db.Close()
1992 if err != nil {
1993 t.Errorf("db Close = %v", err)
1995 if !dc.closed {
1996 t.Errorf("after db.Close, driverConn should be closed")
1998 if n := len(dc.openStmt); n != 0 {
1999 t.Errorf("driverConn num openStmt = %d; want 0", n)
2002 err = stmt.Close()
2003 if err != nil {
2004 t.Errorf("Stmt close = %v", err)
2007 if !dc.closed {
2008 t.Errorf("conn should be closed")
2010 if dc.ci != nil {
2011 t.Errorf("after Stmt Close, driverConn's Conn interface should be nil")
2015 // golang.org/issue/5283: don't release the Rows' connection in Close
2016 // before calling Stmt.Close.
2017 func TestRowsCloseOrder(t *testing.T) {
2018 db := newTestDB(t, "people")
2019 defer closeDB(t, db)
2021 db.SetMaxIdleConns(0)
2022 setStrictFakeConnClose(t)
2023 defer setStrictFakeConnClose(nil)
2025 rows, err := db.Query("SELECT|people|age,name|")
2026 if err != nil {
2027 t.Fatal(err)
2029 err = rows.Close()
2030 if err != nil {
2031 t.Fatal(err)
2035 func TestRowsImplicitClose(t *testing.T) {
2036 db := newTestDB(t, "people")
2037 defer closeDB(t, db)
2039 rows, err := db.Query("SELECT|people|age,name|")
2040 if err != nil {
2041 t.Fatal(err)
2044 want, fail := 2, errors.New("fail")
2045 r := rows.rowsi.(*rowsCursor)
2046 r.errPos, r.err = want, fail
2048 got := 0
2049 for rows.Next() {
2050 got++
2052 if got != want {
2053 t.Errorf("got %d rows, want %d", got, want)
2055 if err := rows.Err(); err != fail {
2056 t.Errorf("got error %v, want %v", err, fail)
2058 if !r.closed {
2059 t.Errorf("r.closed is false, want true")
2063 func TestStmtCloseOrder(t *testing.T) {
2064 db := newTestDB(t, "people")
2065 defer closeDB(t, db)
2067 db.SetMaxIdleConns(0)
2068 setStrictFakeConnClose(t)
2069 defer setStrictFakeConnClose(nil)
2071 _, err := db.Query("SELECT|non_existent|name|")
2072 if err == nil {
2073 t.Fatal("Querying non-existent table should fail")
2077 // Test cases where there's more than maxBadConnRetries bad connections in the
2078 // pool (issue 8834)
2079 func TestManyErrBadConn(t *testing.T) {
2080 manyErrBadConnSetup := func() *DB {
2081 db := newTestDB(t, "people")
2083 nconn := maxBadConnRetries + 1
2084 db.SetMaxIdleConns(nconn)
2085 db.SetMaxOpenConns(nconn)
2086 // open enough connections
2087 func() {
2088 for i := 0; i < nconn; i++ {
2089 rows, err := db.Query("SELECT|people|age,name|")
2090 if err != nil {
2091 t.Fatal(err)
2093 defer rows.Close()
2097 db.mu.Lock()
2098 defer db.mu.Unlock()
2099 if db.numOpen != nconn {
2100 t.Fatalf("unexpected numOpen %d (was expecting %d)", db.numOpen, nconn)
2101 } else if len(db.freeConn) != nconn {
2102 t.Fatalf("unexpected len(db.freeConn) %d (was expecting %d)", len(db.freeConn), nconn)
2104 for _, conn := range db.freeConn {
2105 conn.ci.(*fakeConn).stickyBad = true
2107 return db
2110 // Query
2111 db := manyErrBadConnSetup()
2112 defer closeDB(t, db)
2113 rows, err := db.Query("SELECT|people|age,name|")
2114 if err != nil {
2115 t.Fatal(err)
2117 if err = rows.Close(); err != nil {
2118 t.Fatal(err)
2121 // Exec
2122 db = manyErrBadConnSetup()
2123 defer closeDB(t, db)
2124 _, err = db.Exec("INSERT|people|name=Julia,age=19")
2125 if err != nil {
2126 t.Fatal(err)
2129 // Begin
2130 db = manyErrBadConnSetup()
2131 defer closeDB(t, db)
2132 tx, err := db.Begin()
2133 if err != nil {
2134 t.Fatal(err)
2136 if err = tx.Rollback(); err != nil {
2137 t.Fatal(err)
2140 // Prepare
2141 db = manyErrBadConnSetup()
2142 defer closeDB(t, db)
2143 stmt, err := db.Prepare("SELECT|people|age,name|")
2144 if err != nil {
2145 t.Fatal(err)
2147 if err = stmt.Close(); err != nil {
2148 t.Fatal(err)
2152 // golang.org/issue/5718
2153 func TestErrBadConnReconnect(t *testing.T) {
2154 db := newTestDB(t, "foo")
2155 defer closeDB(t, db)
2156 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
2158 simulateBadConn := func(name string, hook *func() bool, op func() error) {
2159 broken, retried := false, false
2160 numOpen := db.numOpen
2162 // simulate a broken connection on the first try
2163 *hook = func() bool {
2164 if !broken {
2165 broken = true
2166 return true
2168 retried = true
2169 return false
2172 if err := op(); err != nil {
2173 t.Errorf(name+": %v", err)
2174 return
2177 if !broken || !retried {
2178 t.Error(name + ": Failed to simulate broken connection")
2180 *hook = nil
2182 if numOpen != db.numOpen {
2183 t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen)
2184 numOpen = db.numOpen
2188 // db.Exec
2189 dbExec := func() error {
2190 _, err := db.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true)
2191 return err
2193 simulateBadConn("db.Exec prepare", &hookPrepareBadConn, dbExec)
2194 simulateBadConn("db.Exec exec", &hookExecBadConn, dbExec)
2196 // db.Query
2197 dbQuery := func() error {
2198 rows, err := db.Query("SELECT|t1|age,name|")
2199 if err == nil {
2200 err = rows.Close()
2202 return err
2204 simulateBadConn("db.Query prepare", &hookPrepareBadConn, dbQuery)
2205 simulateBadConn("db.Query query", &hookQueryBadConn, dbQuery)
2207 // db.Prepare
2208 simulateBadConn("db.Prepare", &hookPrepareBadConn, func() error {
2209 stmt, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
2210 if err != nil {
2211 return err
2213 stmt.Close()
2214 return nil
2217 // Provide a way to force a re-prepare of a statement on next execution
2218 forcePrepare := func(stmt *Stmt) {
2219 stmt.css = nil
2222 // stmt.Exec
2223 stmt1, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
2224 if err != nil {
2225 t.Fatalf("prepare: %v", err)
2227 defer stmt1.Close()
2228 // make sure we must prepare the stmt first
2229 forcePrepare(stmt1)
2231 stmtExec := func() error {
2232 _, err := stmt1.Exec("Gopher", 3, false)
2233 return err
2235 simulateBadConn("stmt.Exec prepare", &hookPrepareBadConn, stmtExec)
2236 simulateBadConn("stmt.Exec exec", &hookExecBadConn, stmtExec)
2238 // stmt.Query
2239 stmt2, err := db.Prepare("SELECT|t1|age,name|")
2240 if err != nil {
2241 t.Fatalf("prepare: %v", err)
2243 defer stmt2.Close()
2244 // make sure we must prepare the stmt first
2245 forcePrepare(stmt2)
2247 stmtQuery := func() error {
2248 rows, err := stmt2.Query()
2249 if err == nil {
2250 err = rows.Close()
2252 return err
2254 simulateBadConn("stmt.Query prepare", &hookPrepareBadConn, stmtQuery)
2255 simulateBadConn("stmt.Query exec", &hookQueryBadConn, stmtQuery)
2258 // golang.org/issue/11264
2259 func TestTxEndBadConn(t *testing.T) {
2260 db := newTestDB(t, "foo")
2261 defer closeDB(t, db)
2262 db.SetMaxIdleConns(0)
2263 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
2264 db.SetMaxIdleConns(1)
2266 simulateBadConn := func(name string, hook *func() bool, op func() error) {
2267 broken := false
2268 numOpen := db.numOpen
2270 *hook = func() bool {
2271 if !broken {
2272 broken = true
2274 return broken
2277 if err := op(); err != driver.ErrBadConn {
2278 t.Errorf(name+": %v", err)
2279 return
2282 if !broken {
2283 t.Error(name + ": Failed to simulate broken connection")
2285 *hook = nil
2287 if numOpen != db.numOpen {
2288 t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen)
2292 // db.Exec
2293 dbExec := func(endTx func(tx *Tx) error) func() error {
2294 return func() error {
2295 tx, err := db.Begin()
2296 if err != nil {
2297 return err
2299 _, err = tx.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true)
2300 if err != nil {
2301 return err
2303 return endTx(tx)
2306 simulateBadConn("db.Tx.Exec commit", &hookCommitBadConn, dbExec((*Tx).Commit))
2307 simulateBadConn("db.Tx.Exec rollback", &hookRollbackBadConn, dbExec((*Tx).Rollback))
2309 // db.Query
2310 dbQuery := func(endTx func(tx *Tx) error) func() error {
2311 return func() error {
2312 tx, err := db.Begin()
2313 if err != nil {
2314 return err
2316 rows, err := tx.Query("SELECT|t1|age,name|")
2317 if err == nil {
2318 err = rows.Close()
2319 } else {
2320 return err
2322 return endTx(tx)
2325 simulateBadConn("db.Tx.Query commit", &hookCommitBadConn, dbQuery((*Tx).Commit))
2326 simulateBadConn("db.Tx.Query rollback", &hookRollbackBadConn, dbQuery((*Tx).Rollback))
2329 type concurrentTest interface {
2330 init(t testing.TB, db *DB)
2331 finish(t testing.TB)
2332 test(t testing.TB) error
2335 type concurrentDBQueryTest struct {
2336 db *DB
2339 func (c *concurrentDBQueryTest) init(t testing.TB, db *DB) {
2340 c.db = db
2343 func (c *concurrentDBQueryTest) finish(t testing.TB) {
2344 c.db = nil
2347 func (c *concurrentDBQueryTest) test(t testing.TB) error {
2348 rows, err := c.db.Query("SELECT|people|name|")
2349 if err != nil {
2350 t.Error(err)
2351 return err
2353 var name string
2354 for rows.Next() {
2355 rows.Scan(&name)
2357 rows.Close()
2358 return nil
2361 type concurrentDBExecTest struct {
2362 db *DB
2365 func (c *concurrentDBExecTest) init(t testing.TB, db *DB) {
2366 c.db = db
2369 func (c *concurrentDBExecTest) finish(t testing.TB) {
2370 c.db = nil
2373 func (c *concurrentDBExecTest) test(t testing.TB) error {
2374 _, err := c.db.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
2375 if err != nil {
2376 t.Error(err)
2377 return err
2379 return nil
2382 type concurrentStmtQueryTest struct {
2383 db *DB
2384 stmt *Stmt
2387 func (c *concurrentStmtQueryTest) init(t testing.TB, db *DB) {
2388 c.db = db
2389 var err error
2390 c.stmt, err = db.Prepare("SELECT|people|name|")
2391 if err != nil {
2392 t.Fatal(err)
2396 func (c *concurrentStmtQueryTest) finish(t testing.TB) {
2397 if c.stmt != nil {
2398 c.stmt.Close()
2399 c.stmt = nil
2401 c.db = nil
2404 func (c *concurrentStmtQueryTest) test(t testing.TB) error {
2405 rows, err := c.stmt.Query()
2406 if err != nil {
2407 t.Errorf("error on query: %v", err)
2408 return err
2411 var name string
2412 for rows.Next() {
2413 rows.Scan(&name)
2415 rows.Close()
2416 return nil
2419 type concurrentStmtExecTest struct {
2420 db *DB
2421 stmt *Stmt
2424 func (c *concurrentStmtExecTest) init(t testing.TB, db *DB) {
2425 c.db = db
2426 var err error
2427 c.stmt, err = db.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
2428 if err != nil {
2429 t.Fatal(err)
2433 func (c *concurrentStmtExecTest) finish(t testing.TB) {
2434 if c.stmt != nil {
2435 c.stmt.Close()
2436 c.stmt = nil
2438 c.db = nil
2441 func (c *concurrentStmtExecTest) test(t testing.TB) error {
2442 _, err := c.stmt.Exec(3, chrisBirthday)
2443 if err != nil {
2444 t.Errorf("error on exec: %v", err)
2445 return err
2447 return nil
2450 type concurrentTxQueryTest struct {
2451 db *DB
2452 tx *Tx
2455 func (c *concurrentTxQueryTest) init(t testing.TB, db *DB) {
2456 c.db = db
2457 var err error
2458 c.tx, err = c.db.Begin()
2459 if err != nil {
2460 t.Fatal(err)
2464 func (c *concurrentTxQueryTest) finish(t testing.TB) {
2465 if c.tx != nil {
2466 c.tx.Rollback()
2467 c.tx = nil
2469 c.db = nil
2472 func (c *concurrentTxQueryTest) test(t testing.TB) error {
2473 rows, err := c.db.Query("SELECT|people|name|")
2474 if err != nil {
2475 t.Error(err)
2476 return err
2478 var name string
2479 for rows.Next() {
2480 rows.Scan(&name)
2482 rows.Close()
2483 return nil
2486 type concurrentTxExecTest struct {
2487 db *DB
2488 tx *Tx
2491 func (c *concurrentTxExecTest) init(t testing.TB, db *DB) {
2492 c.db = db
2493 var err error
2494 c.tx, err = c.db.Begin()
2495 if err != nil {
2496 t.Fatal(err)
2500 func (c *concurrentTxExecTest) finish(t testing.TB) {
2501 if c.tx != nil {
2502 c.tx.Rollback()
2503 c.tx = nil
2505 c.db = nil
2508 func (c *concurrentTxExecTest) test(t testing.TB) error {
2509 _, err := c.tx.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
2510 if err != nil {
2511 t.Error(err)
2512 return err
2514 return nil
2517 type concurrentTxStmtQueryTest struct {
2518 db *DB
2519 tx *Tx
2520 stmt *Stmt
2523 func (c *concurrentTxStmtQueryTest) init(t testing.TB, db *DB) {
2524 c.db = db
2525 var err error
2526 c.tx, err = c.db.Begin()
2527 if err != nil {
2528 t.Fatal(err)
2530 c.stmt, err = c.tx.Prepare("SELECT|people|name|")
2531 if err != nil {
2532 t.Fatal(err)
2536 func (c *concurrentTxStmtQueryTest) finish(t testing.TB) {
2537 if c.stmt != nil {
2538 c.stmt.Close()
2539 c.stmt = nil
2541 if c.tx != nil {
2542 c.tx.Rollback()
2543 c.tx = nil
2545 c.db = nil
2548 func (c *concurrentTxStmtQueryTest) test(t testing.TB) error {
2549 rows, err := c.stmt.Query()
2550 if err != nil {
2551 t.Errorf("error on query: %v", err)
2552 return err
2555 var name string
2556 for rows.Next() {
2557 rows.Scan(&name)
2559 rows.Close()
2560 return nil
2563 type concurrentTxStmtExecTest struct {
2564 db *DB
2565 tx *Tx
2566 stmt *Stmt
2569 func (c *concurrentTxStmtExecTest) init(t testing.TB, db *DB) {
2570 c.db = db
2571 var err error
2572 c.tx, err = c.db.Begin()
2573 if err != nil {
2574 t.Fatal(err)
2576 c.stmt, err = c.tx.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
2577 if err != nil {
2578 t.Fatal(err)
2582 func (c *concurrentTxStmtExecTest) finish(t testing.TB) {
2583 if c.stmt != nil {
2584 c.stmt.Close()
2585 c.stmt = nil
2587 if c.tx != nil {
2588 c.tx.Rollback()
2589 c.tx = nil
2591 c.db = nil
2594 func (c *concurrentTxStmtExecTest) test(t testing.TB) error {
2595 _, err := c.stmt.Exec(3, chrisBirthday)
2596 if err != nil {
2597 t.Errorf("error on exec: %v", err)
2598 return err
2600 return nil
2603 type concurrentRandomTest struct {
2604 tests []concurrentTest
2607 func (c *concurrentRandomTest) init(t testing.TB, db *DB) {
2608 c.tests = []concurrentTest{
2609 new(concurrentDBQueryTest),
2610 new(concurrentDBExecTest),
2611 new(concurrentStmtQueryTest),
2612 new(concurrentStmtExecTest),
2613 new(concurrentTxQueryTest),
2614 new(concurrentTxExecTest),
2615 new(concurrentTxStmtQueryTest),
2616 new(concurrentTxStmtExecTest),
2618 for _, ct := range c.tests {
2619 ct.init(t, db)
2623 func (c *concurrentRandomTest) finish(t testing.TB) {
2624 for _, ct := range c.tests {
2625 ct.finish(t)
2629 func (c *concurrentRandomTest) test(t testing.TB) error {
2630 ct := c.tests[rand.Intn(len(c.tests))]
2631 return ct.test(t)
2634 func doConcurrentTest(t testing.TB, ct concurrentTest) {
2635 maxProcs, numReqs := 1, 500
2636 if testing.Short() {
2637 maxProcs, numReqs = 4, 50
2639 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
2641 db := newTestDB(t, "people")
2642 defer closeDB(t, db)
2644 ct.init(t, db)
2645 defer ct.finish(t)
2647 var wg sync.WaitGroup
2648 wg.Add(numReqs)
2650 reqs := make(chan bool)
2651 defer close(reqs)
2653 for i := 0; i < maxProcs*2; i++ {
2654 go func() {
2655 for range reqs {
2656 err := ct.test(t)
2657 if err != nil {
2658 wg.Done()
2659 continue
2661 wg.Done()
2666 for i := 0; i < numReqs; i++ {
2667 reqs <- true
2670 wg.Wait()
2673 func TestIssue6081(t *testing.T) {
2674 db := newTestDB(t, "people")
2675 defer closeDB(t, db)
2677 drv := db.driver.(*fakeDriver)
2678 drv.mu.Lock()
2679 opens0 := drv.openCount
2680 closes0 := drv.closeCount
2681 drv.mu.Unlock()
2683 stmt, err := db.Prepare("SELECT|people|name|")
2684 if err != nil {
2685 t.Fatal(err)
2687 setRowsCloseHook(func(rows *Rows, err *error) {
2688 *err = driver.ErrBadConn
2690 defer setRowsCloseHook(nil)
2691 for i := 0; i < 10; i++ {
2692 rows, err := stmt.Query()
2693 if err != nil {
2694 t.Fatal(err)
2696 rows.Close()
2698 if n := len(stmt.css); n > 1 {
2699 t.Errorf("len(css slice) = %d; want <= 1", n)
2701 stmt.Close()
2702 if n := len(stmt.css); n != 0 {
2703 t.Errorf("len(css slice) after Close = %d; want 0", n)
2706 drv.mu.Lock()
2707 opens := drv.openCount - opens0
2708 closes := drv.closeCount - closes0
2709 drv.mu.Unlock()
2710 if opens < 9 {
2711 t.Errorf("opens = %d; want >= 9", opens)
2713 if closes < 9 {
2714 t.Errorf("closes = %d; want >= 9", closes)
2718 // TestIssue18429 attempts to stress rolling back the transaction from a
2719 // context cancel while simultaneously calling Tx.Rollback. Rolling back from a
2720 // context happens concurrently so tx.rollback and tx.Commit must guard against
2721 // double entry.
2723 // In the test, a context is canceled while the query is in process so
2724 // the internal rollback will run concurrently with the explicitly called
2725 // Tx.Rollback.
2726 func TestIssue18429(t *testing.T) {
2727 db := newTestDB(t, "people")
2728 defer closeDB(t, db)
2730 ctx := context.Background()
2731 sem := make(chan bool, 20)
2732 var wg sync.WaitGroup
2734 const milliWait = 30
2736 for i := 0; i < 100; i++ {
2737 sem <- true
2738 wg.Add(1)
2739 go func() {
2740 defer func() {
2741 <-sem
2742 wg.Done()
2744 qwait := (time.Duration(rand.Intn(milliWait)) * time.Millisecond).String()
2746 ctx, cancel := context.WithTimeout(ctx, time.Duration(rand.Intn(milliWait))*time.Millisecond)
2747 defer cancel()
2749 tx, err := db.BeginTx(ctx, nil)
2750 if err != nil {
2751 return
2753 // This is expected to give a cancel error many, but not all the time.
2754 // Test failure will happen with a panic or other race condition being
2755 // reported.
2756 rows, _ := tx.QueryContext(ctx, "WAIT|"+qwait+"|SELECT|people|name|")
2757 if rows != nil {
2758 rows.Close()
2760 // This call will race with the context cancel rollback to complete
2761 // if the rollback itself isn't guarded.
2762 tx.Rollback()
2765 wg.Wait()
2768 // TestIssue18719 closes the context right before use. The sql.driverConn
2769 // will nil out the ci on close in a lock, but if another process uses it right after
2770 // it will panic with on the nil ref.
2772 // See https://golang.org/cl/35550 .
2773 func TestIssue18719(t *testing.T) {
2774 db := newTestDB(t, "people")
2775 defer closeDB(t, db)
2777 ctx, cancel := context.WithCancel(context.Background())
2778 defer cancel()
2780 tx, err := db.BeginTx(ctx, nil)
2781 if err != nil {
2782 t.Fatal(err)
2785 hookTxGrabConn = func() {
2786 cancel()
2788 // Wait for the context to cancel and tx to rollback.
2789 for tx.isDone() == false {
2790 time.Sleep(time.Millisecond * 3)
2793 defer func() { hookTxGrabConn = nil }()
2795 // This call will grab the connection and cancel the context
2796 // after it has done so. Code after must deal with the canceled state.
2797 rows, err := tx.QueryContext(ctx, "SELECT|people|name|")
2798 if err != nil {
2799 rows.Close()
2800 t.Fatalf("expected error %v but got %v", nil, err)
2803 // Rows may be ignored because it will be closed when the context is canceled.
2805 // Do not explicitly rollback. The rollback will happen from the
2806 // canceled context.
2808 cancel()
2809 waitForRowsClose(t, rows, 5*time.Second)
2812 func TestConcurrency(t *testing.T) {
2813 doConcurrentTest(t, new(concurrentDBQueryTest))
2814 doConcurrentTest(t, new(concurrentDBExecTest))
2815 doConcurrentTest(t, new(concurrentStmtQueryTest))
2816 doConcurrentTest(t, new(concurrentStmtExecTest))
2817 doConcurrentTest(t, new(concurrentTxQueryTest))
2818 doConcurrentTest(t, new(concurrentTxExecTest))
2819 doConcurrentTest(t, new(concurrentTxStmtQueryTest))
2820 doConcurrentTest(t, new(concurrentTxStmtExecTest))
2821 doConcurrentTest(t, new(concurrentRandomTest))
2824 func TestConnectionLeak(t *testing.T) {
2825 db := newTestDB(t, "people")
2826 defer closeDB(t, db)
2827 // Start by opening defaultMaxIdleConns
2828 rows := make([]*Rows, defaultMaxIdleConns)
2829 // We need to SetMaxOpenConns > MaxIdleConns, so the DB can open
2830 // a new connection and we can fill the idle queue with the released
2831 // connections.
2832 db.SetMaxOpenConns(len(rows) + 1)
2833 for ii := range rows {
2834 r, err := db.Query("SELECT|people|name|")
2835 if err != nil {
2836 t.Fatal(err)
2838 r.Next()
2839 if err := r.Err(); err != nil {
2840 t.Fatal(err)
2842 rows[ii] = r
2844 // Now we have defaultMaxIdleConns busy connections. Open
2845 // a new one, but wait until the busy connections are released
2846 // before returning control to DB.
2847 drv := db.driver.(*fakeDriver)
2848 drv.waitCh = make(chan struct{}, 1)
2849 drv.waitingCh = make(chan struct{}, 1)
2850 var wg sync.WaitGroup
2851 wg.Add(1)
2852 go func() {
2853 r, err := db.Query("SELECT|people|name|")
2854 if err != nil {
2855 t.Error(err)
2856 return
2858 r.Close()
2859 wg.Done()
2861 // Wait until the goroutine we've just created has started waiting.
2862 <-drv.waitingCh
2863 // Now close the busy connections. This provides a connection for
2864 // the blocked goroutine and then fills up the idle queue.
2865 for _, v := range rows {
2866 v.Close()
2868 // At this point we give the new connection to DB. This connection is
2869 // now useless, since the idle queue is full and there are no pending
2870 // requests. DB should deal with this situation without leaking the
2871 // connection.
2872 drv.waitCh <- struct{}{}
2873 wg.Wait()
2876 // badConn implements a bad driver.Conn, for TestBadDriver.
2877 // The Exec method panics.
2878 type badConn struct{}
2880 func (bc badConn) Prepare(query string) (driver.Stmt, error) {
2881 return nil, errors.New("badConn Prepare")
2884 func (bc badConn) Close() error {
2885 return nil
2888 func (bc badConn) Begin() (driver.Tx, error) {
2889 return nil, errors.New("badConn Begin")
2892 func (bc badConn) Exec(query string, args []driver.Value) (driver.Result, error) {
2893 panic("badConn.Exec")
2896 // badDriver is a driver.Driver that uses badConn.
2897 type badDriver struct{}
2899 func (bd badDriver) Open(name string) (driver.Conn, error) {
2900 return badConn{}, nil
2903 // Issue 15901.
2904 func TestBadDriver(t *testing.T) {
2905 Register("bad", badDriver{})
2906 db, err := Open("bad", "ignored")
2907 if err != nil {
2908 t.Fatal(err)
2910 defer func() {
2911 if r := recover(); r == nil {
2912 t.Error("expected panic")
2913 } else {
2914 if want := "badConn.Exec"; r.(string) != want {
2915 t.Errorf("panic was %v, expected %v", r, want)
2919 defer db.Close()
2920 db.Exec("ignored")
2923 type pingDriver struct {
2924 fails bool
2927 type pingConn struct {
2928 badConn
2929 driver *pingDriver
2932 var pingError = errors.New("Ping failed")
2934 func (pc pingConn) Ping(ctx context.Context) error {
2935 if pc.driver.fails {
2936 return pingError
2938 return nil
2941 var _ driver.Pinger = pingConn{}
2943 func (pd *pingDriver) Open(name string) (driver.Conn, error) {
2944 return pingConn{driver: pd}, nil
2947 func TestPing(t *testing.T) {
2948 driver := &pingDriver{}
2949 Register("ping", driver)
2951 db, err := Open("ping", "ignored")
2952 if err != nil {
2953 t.Fatal(err)
2956 if err := db.Ping(); err != nil {
2957 t.Errorf("err was %#v, expected nil", err)
2958 return
2961 driver.fails = true
2962 if err := db.Ping(); err != pingError {
2963 t.Errorf("err was %#v, expected pingError", err)
2967 func BenchmarkConcurrentDBExec(b *testing.B) {
2968 b.ReportAllocs()
2969 ct := new(concurrentDBExecTest)
2970 for i := 0; i < b.N; i++ {
2971 doConcurrentTest(b, ct)
2975 func BenchmarkConcurrentStmtQuery(b *testing.B) {
2976 b.ReportAllocs()
2977 ct := new(concurrentStmtQueryTest)
2978 for i := 0; i < b.N; i++ {
2979 doConcurrentTest(b, ct)
2983 func BenchmarkConcurrentStmtExec(b *testing.B) {
2984 b.ReportAllocs()
2985 ct := new(concurrentStmtExecTest)
2986 for i := 0; i < b.N; i++ {
2987 doConcurrentTest(b, ct)
2991 func BenchmarkConcurrentTxQuery(b *testing.B) {
2992 b.ReportAllocs()
2993 ct := new(concurrentTxQueryTest)
2994 for i := 0; i < b.N; i++ {
2995 doConcurrentTest(b, ct)
2999 func BenchmarkConcurrentTxExec(b *testing.B) {
3000 b.ReportAllocs()
3001 ct := new(concurrentTxExecTest)
3002 for i := 0; i < b.N; i++ {
3003 doConcurrentTest(b, ct)
3007 func BenchmarkConcurrentTxStmtQuery(b *testing.B) {
3008 b.ReportAllocs()
3009 ct := new(concurrentTxStmtQueryTest)
3010 for i := 0; i < b.N; i++ {
3011 doConcurrentTest(b, ct)
3015 func BenchmarkConcurrentTxStmtExec(b *testing.B) {
3016 b.ReportAllocs()
3017 ct := new(concurrentTxStmtExecTest)
3018 for i := 0; i < b.N; i++ {
3019 doConcurrentTest(b, ct)
3023 func BenchmarkConcurrentRandom(b *testing.B) {
3024 b.ReportAllocs()
3025 ct := new(concurrentRandomTest)
3026 for i := 0; i < b.N; i++ {
3027 doConcurrentTest(b, ct)
3031 func BenchmarkManyConcurrentQueries(b *testing.B) {
3032 b.ReportAllocs()
3033 // To see lock contention in Go 1.4, 16~ cores and 128~ goroutines are required.
3034 const parallelism = 16
3036 db := newTestDB(b, "magicquery")
3037 defer closeDB(b, db)
3038 db.SetMaxIdleConns(runtime.GOMAXPROCS(0) * parallelism)
3040 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
3041 if err != nil {
3042 b.Fatal(err)
3044 defer stmt.Close()
3046 b.SetParallelism(parallelism)
3047 b.RunParallel(func(pb *testing.PB) {
3048 for pb.Next() {
3049 rows, err := stmt.Query("sleep", 1)
3050 if err != nil {
3051 b.Error(err)
3052 return
3054 rows.Close()