1
2
3
4
5 package sql
6
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"
20 )
21
22 func init() {
23 type dbConn struct {
24 db *DB
25 c *driverConn
26 }
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]
33 }
34 setFreedFrom := func(c dbConn, s string) {
35 mu.Lock()
36 defer mu.Unlock()
37 freedFrom[c] = s
38 }
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
45 }
46 }
47 if idx >= 0 {
48
49
50
51 println("double free of conn. conflicts are:\nA) " + getFreedFrom(dbConn{db, c}) + "\n\nand\nB) " + stack())
52 panic("double free of conn.")
53 }
54 setFreedFrom(dbConn{db, c}, stack())
55 }
56 }
57
58 const fakeDBName = "foo"
59
60 var chrisBirthday = time.Unix(123456789, 0)
61
62 func newTestDB(t testing.TB, name string) *DB {
63 return newTestDBConnector(t, &fakeConnector{name: fakeDBName}, name)
64 }
65
66 func newTestDBConnector(t testing.TB, fc *fakeConnector, name string) *DB {
67 fc.name = fakeDBName
68 db := OpenDB(fc)
69 if _, err := db.Exec("WIPE"); err != nil {
70 t.Fatalf("exec wipe: %v", err)
71 }
72 if name == "people" {
73 exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime")
74 exec(t, db, "INSERT|people|name=Alice,age=?,photo=APHOTO", 1)
75 exec(t, db, "INSERT|people|name=Bob,age=?,photo=BPHOTO", 2)
76 exec(t, db, "INSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
77 }
78 if name == "magicquery" {
79
80 exec(t, db, "CREATE|magicquery|op=string,millis=int32")
81 exec(t, db, "INSERT|magicquery|op=sleep,millis=10")
82 }
83 if name == "tx_status" {
84
85 exec(t, db, "CREATE|tx_status|tx_status=string")
86 exec(t, db, "INSERT|tx_status|tx_status=invalid")
87 }
88 return db
89 }
90
91 func TestOpenDB(t *testing.T) {
92 db := OpenDB(dsnConnector{dsn: fakeDBName, driver: fdriver})
93 if db.Driver() != fdriver {
94 t.Fatalf("OpenDB should return the driver of the Connector")
95 }
96 }
97
98 func TestDriverPanic(t *testing.T) {
99
100 db, err := Open("test", fakeDBName)
101 if err != nil {
102 t.Fatalf("Open: %v", err)
103 }
104 expectPanic := func(name string, f func()) {
105 defer func() {
106 err := recover()
107 if err == nil {
108 t.Fatalf("%s did not panic", name)
109 }
110 }()
111 f()
112 }
113
114 expectPanic("Exec Exec", func() { db.Exec("PANIC|Exec|WIPE") })
115 exec(t, db, "WIPE")
116 expectPanic("Exec NumInput", func() { db.Exec("PANIC|NumInput|WIPE") })
117 exec(t, db, "WIPE")
118 expectPanic("Exec Close", func() { db.Exec("PANIC|Close|WIPE") })
119 exec(t, db, "WIPE")
120 exec(t, db, "PANIC|Query|WIPE")
121 exec(t, db, "WIPE")
122
123 exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime")
124
125 expectPanic("Query Query", func() { db.Query("PANIC|Query|SELECT|people|age,name|") })
126 expectPanic("Query NumInput", func() { db.Query("PANIC|NumInput|SELECT|people|age,name|") })
127 expectPanic("Query Close", func() {
128 rows, err := db.Query("PANIC|Close|SELECT|people|age,name|")
129 if err != nil {
130 t.Fatal(err)
131 }
132 rows.Close()
133 })
134 db.Query("PANIC|Exec|SELECT|people|age,name|")
135 exec(t, db, "WIPE")
136 }
137
138 func exec(t testing.TB, db *DB, query string, args ...interface{}) {
139 t.Helper()
140 _, err := db.Exec(query, args...)
141 if err != nil {
142 t.Fatalf("Exec of %q: %v", query, err)
143 }
144 }
145
146 func closeDB(t testing.TB, db *DB) {
147 if e := recover(); e != nil {
148 fmt.Printf("Panic: %v\n", e)
149 panic(e)
150 }
151 defer setHookpostCloseConn(nil)
152 setHookpostCloseConn(func(_ *fakeConn, err error) {
153 if err != nil {
154 t.Errorf("Error closing fakeConn: %v", err)
155 }
156 })
157 db.mu.Lock()
158 for i, dc := range db.freeConn {
159 if n := len(dc.openStmt); n > 0 {
160
161
162
163
164
165 t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, len(db.freeConn), n)
166 }
167 }
168 db.mu.Unlock()
169
170 err := db.Close()
171 if err != nil {
172 t.Fatalf("error closing DB: %v", err)
173 }
174
175 var numOpen int
176 if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
177 numOpen = db.numOpenConns()
178 return numOpen == 0
179 }) {
180 t.Fatalf("%d connections still open after closing DB", numOpen)
181 }
182 }
183
184
185
186 func numPrepares(t *testing.T, db *DB) int {
187 if n := len(db.freeConn); n != 1 {
188 t.Fatalf("free conns = %d; want 1", n)
189 }
190 return db.freeConn[0].ci.(*fakeConn).numPrepare
191 }
192
193 func (db *DB) numDeps() int {
194 db.mu.Lock()
195 defer db.mu.Unlock()
196 return len(db.dep)
197 }
198
199
200
201 func (db *DB) numDepsPollUntil(want int, d time.Duration) int {
202 deadline := time.Now().Add(d)
203 for {
204 n := db.numDeps()
205 if n <= want || time.Now().After(deadline) {
206 return n
207 }
208 time.Sleep(50 * time.Millisecond)
209 }
210 }
211
212 func (db *DB) numFreeConns() int {
213 db.mu.Lock()
214 defer db.mu.Unlock()
215 return len(db.freeConn)
216 }
217
218 func (db *DB) numOpenConns() int {
219 db.mu.Lock()
220 defer db.mu.Unlock()
221 return db.numOpen
222 }
223
224
225 func (db *DB) clearAllConns(t *testing.T) {
226 db.SetMaxIdleConns(0)
227
228 if g, w := db.numFreeConns(), 0; g != w {
229 t.Errorf("free conns = %d; want %d", g, w)
230 }
231
232 if n := db.numDepsPollUntil(0, time.Second); n > 0 {
233 t.Errorf("number of dependencies = %d; expected 0", n)
234 db.dumpDeps(t)
235 }
236 }
237
238 func (db *DB) dumpDeps(t *testing.T) {
239 for fc := range db.dep {
240 db.dumpDep(t, 0, fc, map[finalCloser]bool{})
241 }
242 }
243
244 func (db *DB) dumpDep(t *testing.T, depth int, dep finalCloser, seen map[finalCloser]bool) {
245 seen[dep] = true
246 indent := strings.Repeat(" ", depth)
247 ds := db.dep[dep]
248 for k := range ds {
249 t.Logf("%s%T (%p) waiting for -> %T (%p)", indent, dep, dep, k, k)
250 if fc, ok := k.(finalCloser); ok {
251 if !seen[fc] {
252 db.dumpDep(t, depth+1, fc, seen)
253 }
254 }
255 }
256 }
257
258 func TestQuery(t *testing.T) {
259 db := newTestDB(t, "people")
260 defer closeDB(t, db)
261 prepares0 := numPrepares(t, db)
262 rows, err := db.Query("SELECT|people|age,name|")
263 if err != nil {
264 t.Fatalf("Query: %v", err)
265 }
266 type row struct {
267 age int
268 name string
269 }
270 got := []row{}
271 for rows.Next() {
272 var r row
273 err = rows.Scan(&r.age, &r.name)
274 if err != nil {
275 t.Fatalf("Scan: %v", err)
276 }
277 got = append(got, r)
278 }
279 err = rows.Err()
280 if err != nil {
281 t.Fatalf("Err: %v", err)
282 }
283 want := []row{
284 {age: 1, name: "Alice"},
285 {age: 2, name: "Bob"},
286 {age: 3, name: "Chris"},
287 }
288 if !reflect.DeepEqual(got, want) {
289 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
290 }
291
292
293
294 if n := db.numFreeConns(); n != 1 {
295 t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
296 }
297 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
298 t.Errorf("executed %d Prepare statements; want 1", prepares)
299 }
300 }
301
302
303 func TestQueryContext(t *testing.T) {
304 db := newTestDB(t, "people")
305 defer closeDB(t, db)
306 prepares0 := numPrepares(t, db)
307
308 ctx, cancel := context.WithCancel(context.Background())
309 defer cancel()
310
311 rows, err := db.QueryContext(ctx, "SELECT|people|age,name|")
312 if err != nil {
313 t.Fatalf("Query: %v", err)
314 }
315 type row struct {
316 age int
317 name string
318 }
319 got := []row{}
320 index := 0
321 for rows.Next() {
322 if index == 2 {
323 cancel()
324 waitForRowsClose(t, rows, 5*time.Second)
325 }
326 var r row
327 err = rows.Scan(&r.age, &r.name)
328 if err != nil {
329 if index == 2 {
330 break
331 }
332 t.Fatalf("Scan: %v", err)
333 }
334 if index == 2 && err != context.Canceled {
335 t.Fatalf("Scan: %v; want context.Canceled", err)
336 }
337 got = append(got, r)
338 index++
339 }
340 select {
341 case <-ctx.Done():
342 if err := ctx.Err(); err != context.Canceled {
343 t.Fatalf("context err = %v; want context.Canceled", err)
344 }
345 default:
346 t.Fatalf("context err = nil; want context.Canceled")
347 }
348 want := []row{
349 {age: 1, name: "Alice"},
350 {age: 2, name: "Bob"},
351 }
352 if !reflect.DeepEqual(got, want) {
353 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
354 }
355
356
357
358 waitForRowsClose(t, rows, 5*time.Second)
359 waitForFree(t, db, 5*time.Second, 1)
360 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
361 t.Errorf("executed %d Prepare statements; want 1", prepares)
362 }
363 }
364
365 func waitCondition(waitFor, checkEvery time.Duration, fn func() bool) bool {
366 deadline := time.Now().Add(waitFor)
367 for time.Now().Before(deadline) {
368 if fn() {
369 return true
370 }
371 time.Sleep(checkEvery)
372 }
373 return false
374 }
375
376
377
378 func waitForFree(t *testing.T, db *DB, maxWait time.Duration, want int) {
379 var numFree int
380 if !waitCondition(maxWait, 5*time.Millisecond, func() bool {
381 numFree = db.numFreeConns()
382 return numFree == want
383 }) {
384 t.Fatalf("free conns after hitting EOF = %d; want %d", numFree, want)
385 }
386 }
387
388 func waitForRowsClose(t *testing.T, rows *Rows, maxWait time.Duration) {
389 if !waitCondition(maxWait, 5*time.Millisecond, func() bool {
390 rows.closemu.RLock()
391 defer rows.closemu.RUnlock()
392 return rows.closed
393 }) {
394 t.Fatal("failed to close rows")
395 }
396 }
397
398
399
400 func TestQueryContextWait(t *testing.T) {
401 db := newTestDB(t, "people")
402 defer closeDB(t, db)
403 prepares0 := numPrepares(t, db)
404
405
406
407 ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond)
408 defer cancel()
409
410
411
412
413 _, err := db.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|")
414 if err != context.DeadlineExceeded {
415 t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
416 }
417
418
419 waitForFree(t, db, 5*time.Second, 1)
420 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
421
422
423
424 t.Logf("executed %d Prepare statements; want 1", prepares)
425 }
426 }
427
428
429
430 func TestTxContextWait(t *testing.T) {
431 db := newTestDB(t, "people")
432 defer closeDB(t, db)
433
434 ctx, cancel := context.WithCancel(context.Background())
435
436 tx, err := db.BeginTx(ctx, nil)
437 if err != nil {
438 t.Fatal(err)
439 }
440 tx.keepConnOnRollback = false
441
442 go func() {
443 time.Sleep(15 * time.Millisecond)
444 cancel()
445 }()
446
447
448
449 _, err = tx.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|")
450 if err != context.Canceled {
451 t.Fatalf("expected QueryContext to error with context canceled but returned %v", err)
452 }
453
454 waitForFree(t, db, 5*time.Second, 0)
455 }
456
457
458
459 func TestTxContextWaitNoDiscard(t *testing.T) {
460 db := newTestDB(t, "people")
461 defer closeDB(t, db)
462
463 ctx, cancel := context.WithTimeout(context.Background(), 15*time.Millisecond)
464 defer cancel()
465
466 tx, err := db.BeginTx(ctx, nil)
467 if err != nil {
468
469 if err == context.DeadlineExceeded {
470 t.Skip("tx context canceled prior to first use")
471 }
472 t.Fatal(err)
473 }
474
475
476
477
478 _, err = tx.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|")
479 if err != context.DeadlineExceeded {
480 t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
481 }
482
483 waitForFree(t, db, 5*time.Second, 1)
484 }
485
486
487
488
489 func TestUnsupportedOptions(t *testing.T) {
490 db := newTestDB(t, "people")
491 defer closeDB(t, db)
492 _, err := db.BeginTx(context.Background(), &TxOptions{
493 Isolation: LevelSerializable, ReadOnly: true,
494 })
495 if err == nil {
496 t.Fatal("expected error when using unsupported options, got nil")
497 }
498 }
499
500 func TestMultiResultSetQuery(t *testing.T) {
501 db := newTestDB(t, "people")
502 defer closeDB(t, db)
503 prepares0 := numPrepares(t, db)
504 rows, err := db.Query("SELECT|people|age,name|;SELECT|people|name|")
505 if err != nil {
506 t.Fatalf("Query: %v", err)
507 }
508 type row1 struct {
509 age int
510 name string
511 }
512 type row2 struct {
513 name string
514 }
515 got1 := []row1{}
516 for rows.Next() {
517 var r row1
518 err = rows.Scan(&r.age, &r.name)
519 if err != nil {
520 t.Fatalf("Scan: %v", err)
521 }
522 got1 = append(got1, r)
523 }
524 err = rows.Err()
525 if err != nil {
526 t.Fatalf("Err: %v", err)
527 }
528 want1 := []row1{
529 {age: 1, name: "Alice"},
530 {age: 2, name: "Bob"},
531 {age: 3, name: "Chris"},
532 }
533 if !reflect.DeepEqual(got1, want1) {
534 t.Errorf("mismatch.\n got1: %#v\nwant: %#v", got1, want1)
535 }
536
537 if !rows.NextResultSet() {
538 t.Errorf("expected another result set")
539 }
540
541 got2 := []row2{}
542 for rows.Next() {
543 var r row2
544 err = rows.Scan(&r.name)
545 if err != nil {
546 t.Fatalf("Scan: %v", err)
547 }
548 got2 = append(got2, r)
549 }
550 err = rows.Err()
551 if err != nil {
552 t.Fatalf("Err: %v", err)
553 }
554 want2 := []row2{
555 {name: "Alice"},
556 {name: "Bob"},
557 {name: "Chris"},
558 }
559 if !reflect.DeepEqual(got2, want2) {
560 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got2, want2)
561 }
562 if rows.NextResultSet() {
563 t.Errorf("expected no more result sets")
564 }
565
566
567
568 waitForFree(t, db, 5*time.Second, 1)
569 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
570 t.Errorf("executed %d Prepare statements; want 1", prepares)
571 }
572 }
573
574 func TestQueryNamedArg(t *testing.T) {
575 db := newTestDB(t, "people")
576 defer closeDB(t, db)
577 prepares0 := numPrepares(t, db)
578 rows, err := db.Query(
579
580 "SELECT|people|age,name|name=?name,age=?age",
581 Named("age", 2),
582 Named("name", "Bob"),
583 )
584 if err != nil {
585 t.Fatalf("Query: %v", err)
586 }
587 type row struct {
588 age int
589 name string
590 }
591 got := []row{}
592 for rows.Next() {
593 var r row
594 err = rows.Scan(&r.age, &r.name)
595 if err != nil {
596 t.Fatalf("Scan: %v", err)
597 }
598 got = append(got, r)
599 }
600 err = rows.Err()
601 if err != nil {
602 t.Fatalf("Err: %v", err)
603 }
604 want := []row{
605 {age: 2, name: "Bob"},
606 }
607 if !reflect.DeepEqual(got, want) {
608 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
609 }
610
611
612
613 if n := db.numFreeConns(); n != 1 {
614 t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
615 }
616 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
617 t.Errorf("executed %d Prepare statements; want 1", prepares)
618 }
619 }
620
621 func TestPoolExhaustOnCancel(t *testing.T) {
622 if testing.Short() {
623 t.Skip("long test")
624 }
625
626 max := 3
627 var saturate, saturateDone sync.WaitGroup
628 saturate.Add(max)
629 saturateDone.Add(max)
630
631 donePing := make(chan bool)
632 state := 0
633
634
635
636
637
638
639
640 waiter := func(ctx context.Context) {
641 switch state {
642 case 0:
643
644 case 1:
645 saturate.Done()
646 select {
647 case <-ctx.Done():
648 case <-donePing:
649 }
650 case 2:
651 }
652 }
653 db := newTestDBConnector(t, &fakeConnector{waiter: waiter}, "people")
654 defer closeDB(t, db)
655
656 db.SetMaxOpenConns(max)
657
658
659
660
661 state = 1
662 for i := 0; i < max; i++ {
663 go func() {
664 rows, err := db.Query("SELECT|people|name,photo|")
665 if err != nil {
666 t.Errorf("Query: %v", err)
667 return
668 }
669 rows.Close()
670 saturateDone.Done()
671 }()
672 }
673
674 saturate.Wait()
675 if t.Failed() {
676 t.FailNow()
677 }
678 state = 2
679
680
681 ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
682 defer cancel()
683
684 for i := 0; i < max; i++ {
685 ctxReq, cancelReq := context.WithCancel(ctx)
686 go func() {
687 time.Sleep(100 * time.Millisecond)
688 cancelReq()
689 }()
690 err := db.PingContext(ctxReq)
691 if err != context.Canceled {
692 t.Fatalf("PingContext (Exhaust): %v", err)
693 }
694 }
695 close(donePing)
696 saturateDone.Wait()
697
698
699 err := db.PingContext(ctx)
700 if err != nil {
701 t.Fatalf("PingContext (Normal): %v", err)
702 }
703 }
704
705 func TestRowsColumns(t *testing.T) {
706 db := newTestDB(t, "people")
707 defer closeDB(t, db)
708 rows, err := db.Query("SELECT|people|age,name|")
709 if err != nil {
710 t.Fatalf("Query: %v", err)
711 }
712 cols, err := rows.Columns()
713 if err != nil {
714 t.Fatalf("Columns: %v", err)
715 }
716 want := []string{"age", "name"}
717 if !reflect.DeepEqual(cols, want) {
718 t.Errorf("got %#v; want %#v", cols, want)
719 }
720 if err := rows.Close(); err != nil {
721 t.Errorf("error closing rows: %s", err)
722 }
723 }
724
725 func TestRowsColumnTypes(t *testing.T) {
726 db := newTestDB(t, "people")
727 defer closeDB(t, db)
728 rows, err := db.Query("SELECT|people|age,name|")
729 if err != nil {
730 t.Fatalf("Query: %v", err)
731 }
732 tt, err := rows.ColumnTypes()
733 if err != nil {
734 t.Fatalf("ColumnTypes: %v", err)
735 }
736
737 types := make([]reflect.Type, len(tt))
738 for i, tp := range tt {
739 st := tp.ScanType()
740 if st == nil {
741 t.Errorf("scantype is null for column %q", tp.Name())
742 continue
743 }
744 types[i] = st
745 }
746 values := make([]interface{}, len(tt))
747 for i := range values {
748 values[i] = reflect.New(types[i]).Interface()
749 }
750 ct := 0
751 for rows.Next() {
752 err = rows.Scan(values...)
753 if err != nil {
754 t.Fatalf("failed to scan values in %v", err)
755 }
756 if ct == 1 {
757 if age := *values[0].(*int32); age != 2 {
758 t.Errorf("Expected 2, got %v", age)
759 }
760 if name := *values[1].(*string); name != "Bob" {
761 t.Errorf("Expected Bob, got %v", name)
762 }
763 }
764 ct++
765 }
766 if ct != 3 {
767 t.Errorf("expected 3 rows, got %d", ct)
768 }
769
770 if err := rows.Close(); err != nil {
771 t.Errorf("error closing rows: %s", err)
772 }
773 }
774
775 func TestQueryRow(t *testing.T) {
776 db := newTestDB(t, "people")
777 defer closeDB(t, db)
778 var name string
779 var age int
780 var birthday time.Time
781
782 err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age)
783 if err == nil || !strings.Contains(err.Error(), "expected 2 destination arguments") {
784 t.Errorf("expected error from wrong number of arguments; actually got: %v", err)
785 }
786
787 err = db.QueryRow("SELECT|people|bdate|age=?", 3).Scan(&birthday)
788 if err != nil || !birthday.Equal(chrisBirthday) {
789 t.Errorf("chris birthday = %v, err = %v; want %v", birthday, err, chrisBirthday)
790 }
791
792 err = db.QueryRow("SELECT|people|age,name|age=?", 2).Scan(&age, &name)
793 if err != nil {
794 t.Fatalf("age QueryRow+Scan: %v", err)
795 }
796 if name != "Bob" {
797 t.Errorf("expected name Bob, got %q", name)
798 }
799 if age != 2 {
800 t.Errorf("expected age 2, got %d", age)
801 }
802
803 err = db.QueryRow("SELECT|people|age,name|name=?", "Alice").Scan(&age, &name)
804 if err != nil {
805 t.Fatalf("name QueryRow+Scan: %v", err)
806 }
807 if name != "Alice" {
808 t.Errorf("expected name Alice, got %q", name)
809 }
810 if age != 1 {
811 t.Errorf("expected age 1, got %d", age)
812 }
813
814 var photo []byte
815 err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo)
816 if err != nil {
817 t.Fatalf("photo QueryRow+Scan: %v", err)
818 }
819 want := []byte("APHOTO")
820 if !reflect.DeepEqual(photo, want) {
821 t.Errorf("photo = %q; want %q", photo, want)
822 }
823 }
824
825 func TestRowErr(t *testing.T) {
826 db := newTestDB(t, "people")
827
828 err := db.QueryRowContext(context.Background(), "SELECT|people|bdate|age=?", 3).Err()
829 if err != nil {
830 t.Errorf("Unexpected err = %v; want %v", err, nil)
831 }
832
833 ctx, cancel := context.WithCancel(context.Background())
834 cancel()
835
836 err = db.QueryRowContext(ctx, "SELECT|people|bdate|age=?", 3).Err()
837 exp := "context canceled"
838 if err == nil || !strings.Contains(err.Error(), exp) {
839 t.Errorf("Expected err = %v; got %v", exp, err)
840 }
841 }
842
843 func TestTxRollbackCommitErr(t *testing.T) {
844 db := newTestDB(t, "people")
845 defer closeDB(t, db)
846
847 tx, err := db.Begin()
848 if err != nil {
849 t.Fatal(err)
850 }
851 err = tx.Rollback()
852 if err != nil {
853 t.Errorf("expected nil error from Rollback; got %v", err)
854 }
855 err = tx.Commit()
856 if err != ErrTxDone {
857 t.Errorf("expected %q from Commit; got %q", ErrTxDone, err)
858 }
859
860 tx, err = db.Begin()
861 if err != nil {
862 t.Fatal(err)
863 }
864 err = tx.Commit()
865 if err != nil {
866 t.Errorf("expected nil error from Commit; got %v", err)
867 }
868 err = tx.Rollback()
869 if err != ErrTxDone {
870 t.Errorf("expected %q from Rollback; got %q", ErrTxDone, err)
871 }
872 }
873
874 func TestStatementErrorAfterClose(t *testing.T) {
875 db := newTestDB(t, "people")
876 defer closeDB(t, db)
877 stmt, err := db.Prepare("SELECT|people|age|name=?")
878 if err != nil {
879 t.Fatalf("Prepare: %v", err)
880 }
881 err = stmt.Close()
882 if err != nil {
883 t.Fatalf("Close: %v", err)
884 }
885 var name string
886 err = stmt.QueryRow("foo").Scan(&name)
887 if err == nil {
888 t.Errorf("expected error from QueryRow.Scan after Stmt.Close")
889 }
890 }
891
892 func TestStatementQueryRow(t *testing.T) {
893 db := newTestDB(t, "people")
894 defer closeDB(t, db)
895 stmt, err := db.Prepare("SELECT|people|age|name=?")
896 if err != nil {
897 t.Fatalf("Prepare: %v", err)
898 }
899 defer stmt.Close()
900 var age int
901 for n, tt := range []struct {
902 name string
903 want int
904 }{
905 {"Alice", 1},
906 {"Bob", 2},
907 {"Chris", 3},
908 } {
909 if err := stmt.QueryRow(tt.name).Scan(&age); err != nil {
910 t.Errorf("%d: on %q, QueryRow/Scan: %v", n, tt.name, err)
911 } else if age != tt.want {
912 t.Errorf("%d: age=%d, want %d", n, age, tt.want)
913 }
914 }
915 }
916
917 type stubDriverStmt struct {
918 err error
919 }
920
921 func (s stubDriverStmt) Close() error {
922 return s.err
923 }
924
925 func (s stubDriverStmt) NumInput() int {
926 return -1
927 }
928
929 func (s stubDriverStmt) Exec(args []driver.Value) (driver.Result, error) {
930 return nil, nil
931 }
932
933 func (s stubDriverStmt) Query(args []driver.Value) (driver.Rows, error) {
934 return nil, nil
935 }
936
937
938 func TestStatementClose(t *testing.T) {
939 want := errors.New("STMT ERROR")
940
941 tests := []struct {
942 stmt *Stmt
943 msg string
944 }{
945 {&Stmt{stickyErr: want}, "stickyErr not propagated"},
946 {&Stmt{cg: &Tx{}, cgds: &driverStmt{Locker: &sync.Mutex{}, si: stubDriverStmt{want}}}, "driverStmt.Close() error not propagated"},
947 }
948 for _, test := range tests {
949 if err := test.stmt.Close(); err != want {
950 t.Errorf("%s. Got stmt.Close() = %v, want = %v", test.msg, err, want)
951 }
952 }
953 }
954
955
956 func TestStatementQueryRowConcurrent(t *testing.T) {
957 db := newTestDB(t, "people")
958 defer closeDB(t, db)
959 stmt, err := db.Prepare("SELECT|people|age|name=?")
960 if err != nil {
961 t.Fatalf("Prepare: %v", err)
962 }
963 defer stmt.Close()
964
965 const n = 10
966 ch := make(chan error, n)
967 for i := 0; i < n; i++ {
968 go func() {
969 var age int
970 err := stmt.QueryRow("Alice").Scan(&age)
971 if err == nil && age != 1 {
972 err = fmt.Errorf("unexpected age %d", age)
973 }
974 ch <- err
975 }()
976 }
977 for i := 0; i < n; i++ {
978 if err := <-ch; err != nil {
979 t.Error(err)
980 }
981 }
982 }
983
984
985 func TestBogusPreboundParameters(t *testing.T) {
986 db := newTestDB(t, "foo")
987 defer closeDB(t, db)
988 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
989 _, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion")
990 if err == nil {
991 t.Fatalf("expected error")
992 }
993 if err.Error() != `fakedb: invalid conversion to int32 from "bogusconversion"` {
994 t.Errorf("unexpected error: %v", err)
995 }
996 }
997
998 func TestExec(t *testing.T) {
999 db := newTestDB(t, "foo")
1000 defer closeDB(t, db)
1001 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1002 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1003 if err != nil {
1004 t.Errorf("Stmt, err = %v, %v", stmt, err)
1005 }
1006 defer stmt.Close()
1007
1008 type execTest struct {
1009 args []interface{}
1010 wantErr string
1011 }
1012 execTests := []execTest{
1013
1014 {[]interface{}{"Brad", 31}, ""},
1015 {[]interface{}{"Brad", int64(31)}, ""},
1016 {[]interface{}{"Bob", "32"}, ""},
1017 {[]interface{}{7, 9}, ""},
1018
1019
1020 {[]interface{}{"Brad", int64(0xFFFFFFFF)}, "sql: converting argument $2 type: sql/driver: value 4294967295 overflows int32"},
1021 {[]interface{}{"Brad", "strconv fail"}, `sql: converting argument $2 type: sql/driver: value "strconv fail" can't be converted to int32`},
1022
1023
1024 {[]interface{}{}, "sql: expected 2 arguments, got 0"},
1025 {[]interface{}{1, 2, 3}, "sql: expected 2 arguments, got 3"},
1026 }
1027 for n, et := range execTests {
1028 _, err := stmt.Exec(et.args...)
1029 errStr := ""
1030 if err != nil {
1031 errStr = err.Error()
1032 }
1033 if errStr != et.wantErr {
1034 t.Errorf("stmt.Execute #%d: for %v, got error %q, want error %q",
1035 n, et.args, errStr, et.wantErr)
1036 }
1037 }
1038 }
1039
1040 func TestTxPrepare(t *testing.T) {
1041 db := newTestDB(t, "")
1042 defer closeDB(t, db)
1043 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1044 tx, err := db.Begin()
1045 if err != nil {
1046 t.Fatalf("Begin = %v", err)
1047 }
1048 stmt, err := tx.Prepare("INSERT|t1|name=?,age=?")
1049 if err != nil {
1050 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1051 }
1052 defer stmt.Close()
1053 _, err = stmt.Exec("Bobby", 7)
1054 if err != nil {
1055 t.Fatalf("Exec = %v", err)
1056 }
1057 err = tx.Commit()
1058 if err != nil {
1059 t.Fatalf("Commit = %v", err)
1060 }
1061
1062 if !stmt.closed {
1063 t.Fatal("Stmt not closed after Commit")
1064 }
1065 }
1066
1067 func TestTxStmt(t *testing.T) {
1068 db := newTestDB(t, "")
1069 defer closeDB(t, db)
1070 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1071 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1072 if err != nil {
1073 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1074 }
1075 defer stmt.Close()
1076 tx, err := db.Begin()
1077 if err != nil {
1078 t.Fatalf("Begin = %v", err)
1079 }
1080 txs := tx.Stmt(stmt)
1081 defer txs.Close()
1082 _, err = txs.Exec("Bobby", 7)
1083 if err != nil {
1084 t.Fatalf("Exec = %v", err)
1085 }
1086 err = tx.Commit()
1087 if err != nil {
1088 t.Fatalf("Commit = %v", err)
1089 }
1090
1091 if !txs.closed {
1092 t.Fatal("Stmt not closed after Commit")
1093 }
1094 }
1095
1096 func TestTxStmtPreparedOnce(t *testing.T) {
1097 db := newTestDB(t, "")
1098 defer closeDB(t, db)
1099 exec(t, db, "CREATE|t1|name=string,age=int32")
1100
1101 prepares0 := numPrepares(t, db)
1102
1103
1104 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1105 if err != nil {
1106 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1107 }
1108 defer stmt.Close()
1109
1110 tx, err := db.Begin()
1111 if err != nil {
1112 t.Fatalf("Begin = %v", err)
1113 }
1114
1115 txs1 := tx.Stmt(stmt)
1116 txs2 := tx.Stmt(stmt)
1117
1118 _, err = txs1.Exec("Go", 7)
1119 if err != nil {
1120 t.Fatalf("Exec = %v", err)
1121 }
1122 txs1.Close()
1123
1124 _, err = txs2.Exec("Gopher", 8)
1125 if err != nil {
1126 t.Fatalf("Exec = %v", err)
1127 }
1128 txs2.Close()
1129
1130 err = tx.Commit()
1131 if err != nil {
1132 t.Fatalf("Commit = %v", err)
1133 }
1134
1135 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
1136 t.Errorf("executed %d Prepare statements; want 1", prepares)
1137 }
1138 }
1139
1140 func TestTxStmtClosedRePrepares(t *testing.T) {
1141 db := newTestDB(t, "")
1142 defer closeDB(t, db)
1143 exec(t, db, "CREATE|t1|name=string,age=int32")
1144
1145 prepares0 := numPrepares(t, db)
1146
1147
1148 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1149 if err != nil {
1150 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1151 }
1152 tx, err := db.Begin()
1153 if err != nil {
1154 t.Fatalf("Begin = %v", err)
1155 }
1156 err = stmt.Close()
1157 if err != nil {
1158 t.Fatalf("stmt.Close() = %v", err)
1159 }
1160
1161 txs := tx.Stmt(stmt)
1162 if txs.stickyErr != nil {
1163 t.Fatal(txs.stickyErr)
1164 }
1165 if txs.parentStmt != nil {
1166 t.Fatal("expected nil parentStmt")
1167 }
1168 _, err = txs.Exec(`Eric`, 82)
1169 if err != nil {
1170 t.Fatalf("txs.Exec = %v", err)
1171 }
1172
1173 err = txs.Close()
1174 if err != nil {
1175 t.Fatalf("txs.Close = %v", err)
1176 }
1177
1178 tx.Rollback()
1179
1180 if prepares := numPrepares(t, db) - prepares0; prepares != 2 {
1181 t.Errorf("executed %d Prepare statements; want 2", prepares)
1182 }
1183 }
1184
1185 func TestParentStmtOutlivesTxStmt(t *testing.T) {
1186 db := newTestDB(t, "")
1187 defer closeDB(t, db)
1188 exec(t, db, "CREATE|t1|name=string,age=int32")
1189
1190
1191 db.SetMaxOpenConns(1)
1192
1193 prepares0 := numPrepares(t, db)
1194
1195
1196 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1197 if err != nil {
1198 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1199 }
1200 defer stmt.Close()
1201 tx, err := db.Begin()
1202 if err != nil {
1203 t.Fatalf("Begin = %v", err)
1204 }
1205 txs := tx.Stmt(stmt)
1206 if len(stmt.css) != 1 {
1207 t.Fatalf("len(stmt.css) = %v; want 1", len(stmt.css))
1208 }
1209 err = txs.Close()
1210 if err != nil {
1211 t.Fatalf("txs.Close() = %v", err)
1212 }
1213 err = tx.Rollback()
1214 if err != nil {
1215 t.Fatalf("tx.Rollback() = %v", err)
1216 }
1217
1218 _, err = txs.Exec("Suzan", 30)
1219 if err == nil {
1220 t.Fatalf("txs.Exec(), expected err")
1221 }
1222
1223 _, err = stmt.Exec("Janina", 25)
1224 if err != nil {
1225 t.Fatalf("stmt.Exec() = %v", err)
1226 }
1227
1228 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
1229 t.Errorf("executed %d Prepare statements; want 1", prepares)
1230 }
1231 }
1232
1233
1234
1235
1236 func TestTxStmtFromTxStmtRePrepares(t *testing.T) {
1237 db := newTestDB(t, "")
1238 defer closeDB(t, db)
1239 exec(t, db, "CREATE|t1|name=string,age=int32")
1240 prepares0 := numPrepares(t, db)
1241
1242 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1243 if err != nil {
1244 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1245 }
1246 defer stmt.Close()
1247
1248 tx, err := db.Begin()
1249 if err != nil {
1250 t.Fatalf("Begin = %v", err)
1251 }
1252 txs1 := tx.Stmt(stmt)
1253
1254
1255
1256 txs2 := tx.Stmt(txs1)
1257 if txs2.stickyErr != nil {
1258 t.Fatal(txs2.stickyErr)
1259 }
1260 if txs2.parentStmt != nil {
1261 t.Fatal("expected nil parentStmt")
1262 }
1263 _, err = txs2.Exec(`Eric`, 82)
1264 if err != nil {
1265 t.Fatal(err)
1266 }
1267
1268 err = txs1.Close()
1269 if err != nil {
1270 t.Fatalf("txs1.Close = %v", err)
1271 }
1272 err = txs2.Close()
1273 if err != nil {
1274 t.Fatalf("txs1.Close = %v", err)
1275 }
1276 err = tx.Rollback()
1277 if err != nil {
1278 t.Fatalf("tx.Rollback = %v", err)
1279 }
1280
1281 if prepares := numPrepares(t, db) - prepares0; prepares != 2 {
1282 t.Errorf("executed %d Prepare statements; want 2", prepares)
1283 }
1284 }
1285
1286
1287
1288
1289 func TestTxQuery(t *testing.T) {
1290 db := newTestDB(t, "")
1291 defer closeDB(t, db)
1292 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1293 exec(t, db, "INSERT|t1|name=Alice")
1294
1295 tx, err := db.Begin()
1296 if err != nil {
1297 t.Fatal(err)
1298 }
1299 defer tx.Rollback()
1300
1301 r, err := tx.Query("SELECT|t1|name|")
1302 if err != nil {
1303 t.Fatal(err)
1304 }
1305 defer r.Close()
1306
1307 if !r.Next() {
1308 if r.Err() != nil {
1309 t.Fatal(r.Err())
1310 }
1311 t.Fatal("expected one row")
1312 }
1313
1314 var x string
1315 err = r.Scan(&x)
1316 if err != nil {
1317 t.Fatal(err)
1318 }
1319 }
1320
1321 func TestTxQueryInvalid(t *testing.T) {
1322 db := newTestDB(t, "")
1323 defer closeDB(t, db)
1324
1325 tx, err := db.Begin()
1326 if err != nil {
1327 t.Fatal(err)
1328 }
1329 defer tx.Rollback()
1330
1331 _, err = tx.Query("SELECT|t1|name|")
1332 if err == nil {
1333 t.Fatal("Error expected")
1334 }
1335 }
1336
1337
1338
1339 func TestTxErrBadConn(t *testing.T) {
1340 db, err := Open("test", fakeDBName+";badConn")
1341 if err != nil {
1342 t.Fatalf("Open: %v", err)
1343 }
1344 if _, err := db.Exec("WIPE"); err != nil {
1345 t.Fatalf("exec wipe: %v", err)
1346 }
1347 defer closeDB(t, db)
1348 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1349 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1350 if err != nil {
1351 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1352 }
1353 defer stmt.Close()
1354 tx, err := db.Begin()
1355 if err != nil {
1356 t.Fatalf("Begin = %v", err)
1357 }
1358 txs := tx.Stmt(stmt)
1359 defer txs.Close()
1360 _, err = txs.Exec("Bobby", 7)
1361 if err != nil {
1362 t.Fatalf("Exec = %v", err)
1363 }
1364 err = tx.Commit()
1365 if err != nil {
1366 t.Fatalf("Commit = %v", err)
1367 }
1368 }
1369
1370 func TestConnQuery(t *testing.T) {
1371 db := newTestDB(t, "people")
1372 defer closeDB(t, db)
1373
1374 ctx, cancel := context.WithCancel(context.Background())
1375 defer cancel()
1376 conn, err := db.Conn(ctx)
1377 if err != nil {
1378 t.Fatal(err)
1379 }
1380 conn.dc.ci.(*fakeConn).skipDirtySession = true
1381 defer conn.Close()
1382
1383 var name string
1384 err = conn.QueryRowContext(ctx, "SELECT|people|name|age=?", 3).Scan(&name)
1385 if err != nil {
1386 t.Fatal(err)
1387 }
1388 if name != "Chris" {
1389 t.Fatalf("unexpected result, got %q want Chris", name)
1390 }
1391
1392 err = conn.PingContext(ctx)
1393 if err != nil {
1394 t.Fatal(err)
1395 }
1396 }
1397
1398 func TestConnRaw(t *testing.T) {
1399 db := newTestDB(t, "people")
1400 defer closeDB(t, db)
1401
1402 ctx, cancel := context.WithCancel(context.Background())
1403 defer cancel()
1404 conn, err := db.Conn(ctx)
1405 if err != nil {
1406 t.Fatal(err)
1407 }
1408 conn.dc.ci.(*fakeConn).skipDirtySession = true
1409 defer conn.Close()
1410
1411 sawFunc := false
1412 err = conn.Raw(func(dc interface{}) error {
1413 sawFunc = true
1414 if _, ok := dc.(*fakeConn); !ok {
1415 return fmt.Errorf("got %T want *fakeConn", dc)
1416 }
1417 return nil
1418 })
1419 if err != nil {
1420 t.Fatal(err)
1421 }
1422 if !sawFunc {
1423 t.Fatal("Raw func not called")
1424 }
1425
1426 func() {
1427 defer func() {
1428 x := recover()
1429 if x == nil {
1430 t.Fatal("expected panic")
1431 }
1432 conn.closemu.Lock()
1433 closed := conn.dc == nil
1434 conn.closemu.Unlock()
1435 if !closed {
1436 t.Fatal("expected connection to be closed after panic")
1437 }
1438 }()
1439 err = conn.Raw(func(dc interface{}) error {
1440 panic("Conn.Raw panic should return an error")
1441 })
1442 t.Fatal("expected panic from Raw func")
1443 }()
1444 }
1445
1446 func TestCursorFake(t *testing.T) {
1447 db := newTestDB(t, "people")
1448 defer closeDB(t, db)
1449
1450 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
1451 defer cancel()
1452
1453 exec(t, db, "CREATE|peoplecursor|list=table")
1454 exec(t, db, "INSERT|peoplecursor|list=people!name!age")
1455
1456 rows, err := db.QueryContext(ctx, `SELECT|peoplecursor|list|`)
1457 if err != nil {
1458 t.Fatal(err)
1459 }
1460 defer rows.Close()
1461
1462 if !rows.Next() {
1463 t.Fatal("no rows")
1464 }
1465 var cursor = &Rows{}
1466 err = rows.Scan(cursor)
1467 if err != nil {
1468 t.Fatal(err)
1469 }
1470 defer cursor.Close()
1471
1472 const expectedRows = 3
1473 var currentRow int64
1474
1475 var n int64
1476 var s string
1477 for cursor.Next() {
1478 currentRow++
1479 err = cursor.Scan(&s, &n)
1480 if err != nil {
1481 t.Fatal(err)
1482 }
1483 if n != currentRow {
1484 t.Errorf("expected number(Age)=%d, got %d", currentRow, n)
1485 }
1486 }
1487 if currentRow != expectedRows {
1488 t.Errorf("expected %d rows, got %d rows", expectedRows, currentRow)
1489 }
1490 }
1491
1492 func TestInvalidNilValues(t *testing.T) {
1493 var date1 time.Time
1494 var date2 int
1495
1496 tests := []struct {
1497 name string
1498 input interface{}
1499 expectedError string
1500 }{
1501 {
1502 name: "time.Time",
1503 input: &date1,
1504 expectedError: `sql: Scan error on column index 0, name "bdate": unsupported Scan, storing driver.Value type <nil> into type *time.Time`,
1505 },
1506 {
1507 name: "int",
1508 input: &date2,
1509 expectedError: `sql: Scan error on column index 0, name "bdate": converting NULL to int is unsupported`,
1510 },
1511 }
1512
1513 for _, tt := range tests {
1514 t.Run(tt.name, func(t *testing.T) {
1515 db := newTestDB(t, "people")
1516 defer closeDB(t, db)
1517
1518 ctx, cancel := context.WithCancel(context.Background())
1519 defer cancel()
1520 conn, err := db.Conn(ctx)
1521 if err != nil {
1522 t.Fatal(err)
1523 }
1524 conn.dc.ci.(*fakeConn).skipDirtySession = true
1525 defer conn.Close()
1526
1527 err = conn.QueryRowContext(ctx, "SELECT|people|bdate|age=?", 1).Scan(tt.input)
1528 if err == nil {
1529 t.Fatal("expected error when querying nil column, but succeeded")
1530 }
1531 if err.Error() != tt.expectedError {
1532 t.Fatalf("Expected error: %s\nReceived: %s", tt.expectedError, err.Error())
1533 }
1534
1535 err = conn.PingContext(ctx)
1536 if err != nil {
1537 t.Fatal(err)
1538 }
1539 })
1540 }
1541 }
1542
1543 func TestConnTx(t *testing.T) {
1544 db := newTestDB(t, "people")
1545 defer closeDB(t, db)
1546
1547 ctx, cancel := context.WithCancel(context.Background())
1548 defer cancel()
1549 conn, err := db.Conn(ctx)
1550 if err != nil {
1551 t.Fatal(err)
1552 }
1553 conn.dc.ci.(*fakeConn).skipDirtySession = true
1554 defer conn.Close()
1555
1556 tx, err := conn.BeginTx(ctx, nil)
1557 if err != nil {
1558 t.Fatal(err)
1559 }
1560 insertName, insertAge := "Nancy", 33
1561 _, err = tx.ExecContext(ctx, "INSERT|people|name=?,age=?,photo=APHOTO", insertName, insertAge)
1562 if err != nil {
1563 t.Fatal(err)
1564 }
1565 err = tx.Commit()
1566 if err != nil {
1567 t.Fatal(err)
1568 }
1569
1570 var selectName string
1571 err = conn.QueryRowContext(ctx, "SELECT|people|name|age=?", insertAge).Scan(&selectName)
1572 if err != nil {
1573 t.Fatal(err)
1574 }
1575 if selectName != insertName {
1576 t.Fatalf("got %q want %q", selectName, insertName)
1577 }
1578 }
1579
1580
1581
1582
1583 func TestConnIsValid(t *testing.T) {
1584 db := newTestDB(t, "people")
1585 defer closeDB(t, db)
1586
1587 db.SetMaxOpenConns(1)
1588
1589 ctx := context.Background()
1590
1591 c, err := db.Conn(ctx)
1592 if err != nil {
1593 t.Fatal(err)
1594 }
1595
1596 err = c.Raw(func(raw interface{}) error {
1597 dc := raw.(*fakeConn)
1598 dc.stickyBad = true
1599 return nil
1600 })
1601 if err != nil {
1602 t.Fatal(err)
1603 }
1604 c.Close()
1605
1606 if len(db.freeConn) > 0 && db.freeConn[0].ci.(*fakeConn).stickyBad {
1607 t.Fatal("bad connection returned to pool; expected bad connection to be discarded")
1608 }
1609 }
1610
1611
1612
1613 func TestIssue2542Deadlock(t *testing.T) {
1614 db := newTestDB(t, "people")
1615 closeDB(t, db)
1616 for i := 0; i < 2; i++ {
1617 _, err := db.Query("SELECT|people|age,name|")
1618 if err == nil {
1619 t.Fatalf("expected error")
1620 }
1621 }
1622 }
1623
1624
1625 func TestCloseStmtBeforeRows(t *testing.T) {
1626 db := newTestDB(t, "people")
1627 defer closeDB(t, db)
1628
1629 s, err := db.Prepare("SELECT|people|name|")
1630 if err != nil {
1631 t.Fatal(err)
1632 }
1633
1634 r, err := s.Query()
1635 if err != nil {
1636 s.Close()
1637 t.Fatal(err)
1638 }
1639
1640 err = s.Close()
1641 if err != nil {
1642 t.Fatal(err)
1643 }
1644
1645 r.Close()
1646 }
1647
1648
1649
1650 func TestNullByteSlice(t *testing.T) {
1651 db := newTestDB(t, "")
1652 defer closeDB(t, db)
1653 exec(t, db, "CREATE|t|id=int32,name=nullstring")
1654 exec(t, db, "INSERT|t|id=10,name=?", nil)
1655
1656 var name []byte
1657
1658 err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
1659 if err != nil {
1660 t.Fatal(err)
1661 }
1662 if name != nil {
1663 t.Fatalf("name []byte should be nil for null column value, got: %#v", name)
1664 }
1665
1666 exec(t, db, "INSERT|t|id=11,name=?", "bob")
1667 err = db.QueryRow("SELECT|t|name|id=?", 11).Scan(&name)
1668 if err != nil {
1669 t.Fatal(err)
1670 }
1671 if string(name) != "bob" {
1672 t.Fatalf("name []byte should be bob, got: %q", string(name))
1673 }
1674 }
1675
1676 func TestPointerParamsAndScans(t *testing.T) {
1677 db := newTestDB(t, "")
1678 defer closeDB(t, db)
1679 exec(t, db, "CREATE|t|id=int32,name=nullstring")
1680
1681 bob := "bob"
1682 var name *string
1683
1684 name = &bob
1685 exec(t, db, "INSERT|t|id=10,name=?", name)
1686 name = nil
1687 exec(t, db, "INSERT|t|id=20,name=?", name)
1688
1689 err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
1690 if err != nil {
1691 t.Fatalf("querying id 10: %v", err)
1692 }
1693 if name == nil {
1694 t.Errorf("id 10's name = nil; want bob")
1695 } else if *name != "bob" {
1696 t.Errorf("id 10's name = %q; want bob", *name)
1697 }
1698
1699 err = db.QueryRow("SELECT|t|name|id=?", 20).Scan(&name)
1700 if err != nil {
1701 t.Fatalf("querying id 20: %v", err)
1702 }
1703 if name != nil {
1704 t.Errorf("id 20 = %q; want nil", *name)
1705 }
1706 }
1707
1708 func TestQueryRowClosingStmt(t *testing.T) {
1709 db := newTestDB(t, "people")
1710 defer closeDB(t, db)
1711 var name string
1712 var age int
1713 err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age, &name)
1714 if err != nil {
1715 t.Fatal(err)
1716 }
1717 if len(db.freeConn) != 1 {
1718 t.Fatalf("expected 1 free conn")
1719 }
1720 fakeConn := db.freeConn[0].ci.(*fakeConn)
1721 if made, closed := fakeConn.stmtsMade, fakeConn.stmtsClosed; made != closed {
1722 t.Errorf("statement close mismatch: made %d, closed %d", made, closed)
1723 }
1724 }
1725
1726 var atomicRowsCloseHook atomic.Value
1727
1728 func init() {
1729 rowsCloseHook = func() func(*Rows, *error) {
1730 fn, _ := atomicRowsCloseHook.Load().(func(*Rows, *error))
1731 return fn
1732 }
1733 }
1734
1735 func setRowsCloseHook(fn func(*Rows, *error)) {
1736 if fn == nil {
1737
1738
1739 fn = func(*Rows, *error) {}
1740 }
1741 atomicRowsCloseHook.Store(fn)
1742 }
1743
1744
1745 func TestIssue6651(t *testing.T) {
1746 db := newTestDB(t, "people")
1747 defer closeDB(t, db)
1748
1749 var v string
1750
1751 want := "error in rows.Next"
1752 rowsCursorNextHook = func(dest []driver.Value) error {
1753 return fmt.Errorf(want)
1754 }
1755 defer func() { rowsCursorNextHook = nil }()
1756
1757 err := db.QueryRow("SELECT|people|name|").Scan(&v)
1758 if err == nil || err.Error() != want {
1759 t.Errorf("error = %q; want %q", err, want)
1760 }
1761 rowsCursorNextHook = nil
1762
1763 want = "error in rows.Close"
1764 setRowsCloseHook(func(rows *Rows, err *error) {
1765 *err = fmt.Errorf(want)
1766 })
1767 defer setRowsCloseHook(nil)
1768 err = db.QueryRow("SELECT|people|name|").Scan(&v)
1769 if err == nil || err.Error() != want {
1770 t.Errorf("error = %q; want %q", err, want)
1771 }
1772 }
1773
1774 type nullTestRow struct {
1775 nullParam interface{}
1776 notNullParam interface{}
1777 scanNullVal interface{}
1778 }
1779
1780 type nullTestSpec struct {
1781 nullType string
1782 notNullType string
1783 rows [6]nullTestRow
1784 }
1785
1786 func TestNullStringParam(t *testing.T) {
1787 spec := nullTestSpec{"nullstring", "string", [6]nullTestRow{
1788 {NullString{"aqua", true}, "", NullString{"aqua", true}},
1789 {NullString{"brown", false}, "", NullString{"", false}},
1790 {"chartreuse", "", NullString{"chartreuse", true}},
1791 {NullString{"darkred", true}, "", NullString{"darkred", true}},
1792 {NullString{"eel", false}, "", NullString{"", false}},
1793 {"foo", NullString{"black", false}, nil},
1794 }}
1795 nullTestRun(t, spec)
1796 }
1797
1798 func TestNullInt64Param(t *testing.T) {
1799 spec := nullTestSpec{"nullint64", "int64", [6]nullTestRow{
1800 {NullInt64{31, true}, 1, NullInt64{31, true}},
1801 {NullInt64{-22, false}, 1, NullInt64{0, false}},
1802 {22, 1, NullInt64{22, true}},
1803 {NullInt64{33, true}, 1, NullInt64{33, true}},
1804 {NullInt64{222, false}, 1, NullInt64{0, false}},
1805 {0, NullInt64{31, false}, nil},
1806 }}
1807 nullTestRun(t, spec)
1808 }
1809
1810 func TestNullInt32Param(t *testing.T) {
1811 spec := nullTestSpec{"nullint32", "int32", [6]nullTestRow{
1812 {NullInt32{31, true}, 1, NullInt32{31, true}},
1813 {NullInt32{-22, false}, 1, NullInt32{0, false}},
1814 {22, 1, NullInt32{22, true}},
1815 {NullInt32{33, true}, 1, NullInt32{33, true}},
1816 {NullInt32{222, false}, 1, NullInt32{0, false}},
1817 {0, NullInt32{31, false}, nil},
1818 }}
1819 nullTestRun(t, spec)
1820 }
1821
1822 func TestNullInt16Param(t *testing.T) {
1823 spec := nullTestSpec{"nullint16", "int16", [6]nullTestRow{
1824 {NullInt16{31, true}, 1, NullInt16{31, true}},
1825 {NullInt16{-22, false}, 1, NullInt16{0, false}},
1826 {22, 1, NullInt16{22, true}},
1827 {NullInt16{33, true}, 1, NullInt16{33, true}},
1828 {NullInt16{222, false}, 1, NullInt16{0, false}},
1829 {0, NullInt16{31, false}, nil},
1830 }}
1831 nullTestRun(t, spec)
1832 }
1833
1834 func TestNullByteParam(t *testing.T) {
1835 spec := nullTestSpec{"nullbyte", "byte", [6]nullTestRow{
1836 {NullByte{31, true}, 1, NullByte{31, true}},
1837 {NullByte{0, false}, 1, NullByte{0, false}},
1838 {22, 1, NullByte{22, true}},
1839 {NullByte{33, true}, 1, NullByte{33, true}},
1840 {NullByte{222, false}, 1, NullByte{0, false}},
1841 {0, NullByte{31, false}, nil},
1842 }}
1843 nullTestRun(t, spec)
1844 }
1845
1846 func TestNullFloat64Param(t *testing.T) {
1847 spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{
1848 {NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
1849 {NullFloat64{13.1, false}, 1, NullFloat64{0, false}},
1850 {-22.9, 1, NullFloat64{-22.9, true}},
1851 {NullFloat64{33.81, true}, 1, NullFloat64{33.81, true}},
1852 {NullFloat64{222, false}, 1, NullFloat64{0, false}},
1853 {10, NullFloat64{31.2, false}, nil},
1854 }}
1855 nullTestRun(t, spec)
1856 }
1857
1858 func TestNullBoolParam(t *testing.T) {
1859 spec := nullTestSpec{"nullbool", "bool", [6]nullTestRow{
1860 {NullBool{false, true}, true, NullBool{false, true}},
1861 {NullBool{true, false}, false, NullBool{false, false}},
1862 {true, true, NullBool{true, true}},
1863 {NullBool{true, true}, false, NullBool{true, true}},
1864 {NullBool{true, false}, true, NullBool{false, false}},
1865 {true, NullBool{true, false}, nil},
1866 }}
1867 nullTestRun(t, spec)
1868 }
1869
1870 func TestNullTimeParam(t *testing.T) {
1871 t0 := time.Time{}
1872 t1 := time.Date(2000, 1, 1, 8, 9, 10, 11, time.UTC)
1873 t2 := time.Date(2010, 1, 1, 8, 9, 10, 11, time.UTC)
1874 spec := nullTestSpec{"nulldatetime", "datetime", [6]nullTestRow{
1875 {NullTime{t1, true}, t2, NullTime{t1, true}},
1876 {NullTime{t1, false}, t2, NullTime{t0, false}},
1877 {t1, t2, NullTime{t1, true}},
1878 {NullTime{t1, true}, t2, NullTime{t1, true}},
1879 {NullTime{t1, false}, t2, NullTime{t0, false}},
1880 {t2, NullTime{t1, false}, nil},
1881 }}
1882 nullTestRun(t, spec)
1883 }
1884
1885 func nullTestRun(t *testing.T, spec nullTestSpec) {
1886 db := newTestDB(t, "")
1887 defer closeDB(t, db)
1888 exec(t, db, fmt.Sprintf("CREATE|t|id=int32,name=string,nullf=%s,notnullf=%s", spec.nullType, spec.notNullType))
1889
1890
1891 exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 1, "alice", spec.rows[0].nullParam, spec.rows[0].notNullParam)
1892 exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 2, "bob", spec.rows[1].nullParam, spec.rows[1].notNullParam)
1893
1894
1895 stmt, err := db.Prepare("INSERT|t|id=?,name=?,nullf=?,notnullf=?")
1896 if err != nil {
1897 t.Fatalf("prepare: %v", err)
1898 }
1899 defer stmt.Close()
1900 if _, err := stmt.Exec(3, "chris", spec.rows[2].nullParam, spec.rows[2].notNullParam); err != nil {
1901 t.Errorf("exec insert chris: %v", err)
1902 }
1903 if _, err := stmt.Exec(4, "dave", spec.rows[3].nullParam, spec.rows[3].notNullParam); err != nil {
1904 t.Errorf("exec insert dave: %v", err)
1905 }
1906 if _, err := stmt.Exec(5, "eleanor", spec.rows[4].nullParam, spec.rows[4].notNullParam); err != nil {
1907 t.Errorf("exec insert eleanor: %v", err)
1908 }
1909
1910
1911 if _, err := stmt.Exec(6, "bob", spec.rows[5].nullParam, spec.rows[5].notNullParam); err == nil {
1912 t.Errorf("expected error inserting nil val with prepared statement Exec")
1913 }
1914
1915 _, err = db.Exec("INSERT|t|id=?,name=?,nullf=?", 999, nil, nil)
1916 if err == nil {
1917
1918
1919
1920
1921
1922
1923 }
1924
1925 paramtype := reflect.TypeOf(spec.rows[0].nullParam)
1926 bindVal := reflect.New(paramtype).Interface()
1927
1928 for i := 0; i < 5; i++ {
1929 id := i + 1
1930 if err := db.QueryRow("SELECT|t|nullf|id=?", id).Scan(bindVal); err != nil {
1931 t.Errorf("id=%d Scan: %v", id, err)
1932 }
1933 bindValDeref := reflect.ValueOf(bindVal).Elem().Interface()
1934 if !reflect.DeepEqual(bindValDeref, spec.rows[i].scanNullVal) {
1935 t.Errorf("id=%d got %#v, want %#v", id, bindValDeref, spec.rows[i].scanNullVal)
1936 }
1937 }
1938 }
1939
1940
1941 func TestQueryRowNilScanDest(t *testing.T) {
1942 db := newTestDB(t, "people")
1943 defer closeDB(t, db)
1944 var name *string
1945 err := db.QueryRow("SELECT|people|name|").Scan(name)
1946 want := `sql: Scan error on column index 0, name "name": destination pointer is nil`
1947 if err == nil || err.Error() != want {
1948 t.Errorf("error = %q; want %q", err.Error(), want)
1949 }
1950 }
1951
1952 func TestIssue4902(t *testing.T) {
1953 db := newTestDB(t, "people")
1954 defer closeDB(t, db)
1955
1956 driver := db.Driver().(*fakeDriver)
1957 opens0 := driver.openCount
1958
1959 var stmt *Stmt
1960 var err error
1961 for i := 0; i < 10; i++ {
1962 stmt, err = db.Prepare("SELECT|people|name|")
1963 if err != nil {
1964 t.Fatal(err)
1965 }
1966 err = stmt.Close()
1967 if err != nil {
1968 t.Fatal(err)
1969 }
1970 }
1971
1972 opens := driver.openCount - opens0
1973 if opens > 1 {
1974 t.Errorf("opens = %d; want <= 1", opens)
1975 t.Logf("db = %#v", db)
1976 t.Logf("driver = %#v", driver)
1977 t.Logf("stmt = %#v", stmt)
1978 }
1979 }
1980
1981
1982
1983 func TestSimultaneousQueries(t *testing.T) {
1984 db := newTestDB(t, "people")
1985 defer closeDB(t, db)
1986
1987 tx, err := db.Begin()
1988 if err != nil {
1989 t.Fatal(err)
1990 }
1991 defer tx.Rollback()
1992
1993 r1, err := tx.Query("SELECT|people|name|")
1994 if err != nil {
1995 t.Fatal(err)
1996 }
1997 defer r1.Close()
1998
1999 r2, err := tx.Query("SELECT|people|name|")
2000 if err != nil {
2001 t.Fatal(err)
2002 }
2003 defer r2.Close()
2004 }
2005
2006 func TestMaxIdleConns(t *testing.T) {
2007 db := newTestDB(t, "people")
2008 defer closeDB(t, db)
2009
2010 tx, err := db.Begin()
2011 if err != nil {
2012 t.Fatal(err)
2013 }
2014 tx.Commit()
2015 if got := len(db.freeConn); got != 1 {
2016 t.Errorf("freeConns = %d; want 1", got)
2017 }
2018
2019 db.SetMaxIdleConns(0)
2020
2021 if got := len(db.freeConn); got != 0 {
2022 t.Errorf("freeConns after set to zero = %d; want 0", got)
2023 }
2024
2025 tx, err = db.Begin()
2026 if err != nil {
2027 t.Fatal(err)
2028 }
2029 tx.Commit()
2030 if got := len(db.freeConn); got != 0 {
2031 t.Errorf("freeConns = %d; want 0", got)
2032 }
2033 }
2034
2035 func TestMaxOpenConns(t *testing.T) {
2036 if testing.Short() {
2037 t.Skip("skipping in short mode")
2038 }
2039 defer setHookpostCloseConn(nil)
2040 setHookpostCloseConn(func(_ *fakeConn, err error) {
2041 if err != nil {
2042 t.Errorf("Error closing fakeConn: %v", err)
2043 }
2044 })
2045
2046 db := newTestDB(t, "magicquery")
2047 defer closeDB(t, db)
2048
2049 driver := db.Driver().(*fakeDriver)
2050
2051
2052
2053 db.clearAllConns(t)
2054
2055 driver.mu.Lock()
2056 opens0 := driver.openCount
2057 closes0 := driver.closeCount
2058 driver.mu.Unlock()
2059
2060 db.SetMaxIdleConns(10)
2061 db.SetMaxOpenConns(10)
2062
2063 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
2064 if err != nil {
2065 t.Fatal(err)
2066 }
2067
2068
2069 const (
2070 nquery = 50
2071 sleepMillis = 25
2072 nbatch = 2
2073 )
2074 var wg sync.WaitGroup
2075 for batch := 0; batch < nbatch; batch++ {
2076 for i := 0; i < nquery; i++ {
2077 wg.Add(1)
2078 go func() {
2079 defer wg.Done()
2080 var op string
2081 if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
2082 t.Error(err)
2083 }
2084 }()
2085 }
2086
2087
2088
2089 time.Sleep(2 * sleepMillis * time.Millisecond)
2090 }
2091 wg.Wait()
2092
2093 if g, w := db.numFreeConns(), 10; g != w {
2094 t.Errorf("free conns = %d; want %d", g, w)
2095 }
2096
2097 if n := db.numDepsPollUntil(20, time.Second); n > 20 {
2098 t.Errorf("number of dependencies = %d; expected <= 20", n)
2099 db.dumpDeps(t)
2100 }
2101
2102 driver.mu.Lock()
2103 opens := driver.openCount - opens0
2104 closes := driver.closeCount - closes0
2105 driver.mu.Unlock()
2106
2107 if opens > 10 {
2108 t.Logf("open calls = %d", opens)
2109 t.Logf("close calls = %d", closes)
2110 t.Errorf("db connections opened = %d; want <= 10", opens)
2111 db.dumpDeps(t)
2112 }
2113
2114 if err := stmt.Close(); err != nil {
2115 t.Fatal(err)
2116 }
2117
2118 if g, w := db.numFreeConns(), 10; g != w {
2119 t.Errorf("free conns = %d; want %d", g, w)
2120 }
2121
2122 if n := db.numDepsPollUntil(10, time.Second); n > 10 {
2123 t.Errorf("number of dependencies = %d; expected <= 10", n)
2124 db.dumpDeps(t)
2125 }
2126
2127 db.SetMaxOpenConns(5)
2128
2129 if g, w := db.numFreeConns(), 5; g != w {
2130 t.Errorf("free conns = %d; want %d", g, w)
2131 }
2132
2133 if n := db.numDepsPollUntil(5, time.Second); n > 5 {
2134 t.Errorf("number of dependencies = %d; expected 0", n)
2135 db.dumpDeps(t)
2136 }
2137
2138 db.SetMaxOpenConns(0)
2139
2140 if g, w := db.numFreeConns(), 5; g != w {
2141 t.Errorf("free conns = %d; want %d", g, w)
2142 }
2143
2144 if n := db.numDepsPollUntil(5, time.Second); n > 5 {
2145 t.Errorf("number of dependencies = %d; expected 0", n)
2146 db.dumpDeps(t)
2147 }
2148
2149 db.clearAllConns(t)
2150 }
2151
2152
2153
2154 func TestMaxOpenConnsOnBusy(t *testing.T) {
2155 defer setHookpostCloseConn(nil)
2156 setHookpostCloseConn(func(_ *fakeConn, err error) {
2157 if err != nil {
2158 t.Errorf("Error closing fakeConn: %v", err)
2159 }
2160 })
2161
2162 db := newTestDB(t, "magicquery")
2163 defer closeDB(t, db)
2164
2165 db.SetMaxOpenConns(3)
2166
2167 ctx := context.Background()
2168
2169 conn0, err := db.conn(ctx, cachedOrNewConn)
2170 if err != nil {
2171 t.Fatalf("db open conn fail: %v", err)
2172 }
2173
2174 conn1, err := db.conn(ctx, cachedOrNewConn)
2175 if err != nil {
2176 t.Fatalf("db open conn fail: %v", err)
2177 }
2178
2179 conn2, err := db.conn(ctx, cachedOrNewConn)
2180 if err != nil {
2181 t.Fatalf("db open conn fail: %v", err)
2182 }
2183
2184 if g, w := db.numOpen, 3; g != w {
2185 t.Errorf("free conns = %d; want %d", g, w)
2186 }
2187
2188 db.SetMaxOpenConns(2)
2189 if g, w := db.numOpen, 3; g != w {
2190 t.Errorf("free conns = %d; want %d", g, w)
2191 }
2192
2193 conn0.releaseConn(nil)
2194 conn1.releaseConn(nil)
2195 if g, w := db.numOpen, 2; g != w {
2196 t.Errorf("free conns = %d; want %d", g, w)
2197 }
2198
2199 conn2.releaseConn(nil)
2200 if g, w := db.numOpen, 2; g != w {
2201 t.Errorf("free conns = %d; want %d", g, w)
2202 }
2203 }
2204
2205
2206
2207 func TestPendingConnsAfterErr(t *testing.T) {
2208 const (
2209 maxOpen = 2
2210 tryOpen = maxOpen*2 + 2
2211 )
2212
2213
2214 db, err := Open("test", fakeDBName)
2215 if err != nil {
2216 t.Fatalf("Open: %v", err)
2217 }
2218 defer closeDB(t, db)
2219 defer func() {
2220 for k, v := range db.lastPut {
2221 t.Logf("%p: %v", k, v)
2222 }
2223 }()
2224
2225 db.SetMaxOpenConns(maxOpen)
2226 db.SetMaxIdleConns(0)
2227
2228 errOffline := errors.New("db offline")
2229
2230 defer func() { setHookOpenErr(nil) }()
2231
2232 errs := make(chan error, tryOpen)
2233
2234 var opening sync.WaitGroup
2235 opening.Add(tryOpen)
2236
2237 setHookOpenErr(func() error {
2238
2239 opening.Wait()
2240 return errOffline
2241 })
2242
2243 for i := 0; i < tryOpen; i++ {
2244 go func() {
2245 opening.Done()
2246 _, err := db.Exec("will never run")
2247 errs <- err
2248 }()
2249 }
2250
2251 opening.Wait()
2252
2253 const timeout = 5 * time.Second
2254 to := time.NewTimer(timeout)
2255 defer to.Stop()
2256
2257
2258 for i := 0; i < tryOpen; i++ {
2259 select {
2260 case err := <-errs:
2261 if got, want := err, errOffline; got != want {
2262 t.Errorf("unexpected err: got %v, want %v", got, want)
2263 }
2264 case <-to.C:
2265 t.Fatalf("orphaned connection request(s), still waiting after %v", timeout)
2266 }
2267 }
2268
2269
2270 tick := time.NewTicker(3 * time.Millisecond)
2271 defer tick.Stop()
2272 for {
2273 select {
2274 case <-tick.C:
2275 db.mu.Lock()
2276 if db.numOpen == 0 {
2277 db.mu.Unlock()
2278 return
2279 }
2280 db.mu.Unlock()
2281 case <-to.C:
2282
2283 return
2284 }
2285 }
2286 }
2287
2288 func TestSingleOpenConn(t *testing.T) {
2289 db := newTestDB(t, "people")
2290 defer closeDB(t, db)
2291
2292 db.SetMaxOpenConns(1)
2293
2294 rows, err := db.Query("SELECT|people|name|")
2295 if err != nil {
2296 t.Fatal(err)
2297 }
2298 if err = rows.Close(); err != nil {
2299 t.Fatal(err)
2300 }
2301
2302 rows, err = db.Query("SELECT|people|name|")
2303 if err != nil {
2304 t.Fatal(err)
2305 }
2306 if err = rows.Close(); err != nil {
2307 t.Fatal(err)
2308 }
2309 }
2310
2311 func TestStats(t *testing.T) {
2312 db := newTestDB(t, "people")
2313 stats := db.Stats()
2314 if got := stats.OpenConnections; got != 1 {
2315 t.Errorf("stats.OpenConnections = %d; want 1", got)
2316 }
2317
2318 tx, err := db.Begin()
2319 if err != nil {
2320 t.Fatal(err)
2321 }
2322 tx.Commit()
2323
2324 closeDB(t, db)
2325 stats = db.Stats()
2326 if got := stats.OpenConnections; got != 0 {
2327 t.Errorf("stats.OpenConnections = %d; want 0", got)
2328 }
2329 }
2330
2331 func TestConnMaxLifetime(t *testing.T) {
2332 t0 := time.Unix(1000000, 0)
2333 offset := time.Duration(0)
2334
2335 nowFunc = func() time.Time { return t0.Add(offset) }
2336 defer func() { nowFunc = time.Now }()
2337
2338 db := newTestDB(t, "magicquery")
2339 defer closeDB(t, db)
2340
2341 driver := db.Driver().(*fakeDriver)
2342
2343
2344
2345 db.clearAllConns(t)
2346
2347 driver.mu.Lock()
2348 opens0 := driver.openCount
2349 closes0 := driver.closeCount
2350 driver.mu.Unlock()
2351
2352 db.SetMaxIdleConns(10)
2353 db.SetMaxOpenConns(10)
2354
2355 tx, err := db.Begin()
2356 if err != nil {
2357 t.Fatal(err)
2358 }
2359
2360 offset = time.Second
2361 tx2, err := db.Begin()
2362 if err != nil {
2363 t.Fatal(err)
2364 }
2365
2366 tx.Commit()
2367 tx2.Commit()
2368
2369 driver.mu.Lock()
2370 opens := driver.openCount - opens0
2371 closes := driver.closeCount - closes0
2372 driver.mu.Unlock()
2373
2374 if opens != 2 {
2375 t.Errorf("opens = %d; want 2", opens)
2376 }
2377 if closes != 0 {
2378 t.Errorf("closes = %d; want 0", closes)
2379 }
2380 if g, w := db.numFreeConns(), 2; g != w {
2381 t.Errorf("free conns = %d; want %d", g, w)
2382 }
2383
2384
2385 offset = 11 * time.Second
2386 db.SetConnMaxLifetime(10 * time.Second)
2387 if err != nil {
2388 t.Fatal(err)
2389 }
2390
2391 tx, err = db.Begin()
2392 if err != nil {
2393 t.Fatal(err)
2394 }
2395 tx2, err = db.Begin()
2396 if err != nil {
2397 t.Fatal(err)
2398 }
2399 tx.Commit()
2400 tx2.Commit()
2401
2402 driver.mu.Lock()
2403 opens = driver.openCount - opens0
2404 closes = driver.closeCount - closes0
2405 driver.mu.Unlock()
2406
2407 if opens != 3 {
2408 t.Errorf("opens = %d; want 3", opens)
2409 }
2410 if closes != 1 {
2411 t.Errorf("closes = %d; want 1", closes)
2412 }
2413 }
2414
2415
2416 func TestStmtCloseDeps(t *testing.T) {
2417 if testing.Short() {
2418 t.Skip("skipping in short mode")
2419 }
2420 defer setHookpostCloseConn(nil)
2421 setHookpostCloseConn(func(_ *fakeConn, err error) {
2422 if err != nil {
2423 t.Errorf("Error closing fakeConn: %v", err)
2424 }
2425 })
2426
2427 db := newTestDB(t, "magicquery")
2428 defer closeDB(t, db)
2429
2430 driver := db.Driver().(*fakeDriver)
2431
2432 driver.mu.Lock()
2433 opens0 := driver.openCount
2434 closes0 := driver.closeCount
2435 driver.mu.Unlock()
2436 openDelta0 := opens0 - closes0
2437
2438 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
2439 if err != nil {
2440 t.Fatal(err)
2441 }
2442
2443
2444 const (
2445 nquery = 50
2446 sleepMillis = 25
2447 nbatch = 2
2448 )
2449 var wg sync.WaitGroup
2450 for batch := 0; batch < nbatch; batch++ {
2451 for i := 0; i < nquery; i++ {
2452 wg.Add(1)
2453 go func() {
2454 defer wg.Done()
2455 var op string
2456 if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
2457 t.Error(err)
2458 }
2459 }()
2460 }
2461
2462
2463
2464 time.Sleep(2 * sleepMillis * time.Millisecond)
2465 }
2466 wg.Wait()
2467
2468 if g, w := db.numFreeConns(), 2; g != w {
2469 t.Errorf("free conns = %d; want %d", g, w)
2470 }
2471
2472 if n := db.numDepsPollUntil(4, time.Second); n > 4 {
2473 t.Errorf("number of dependencies = %d; expected <= 4", n)
2474 db.dumpDeps(t)
2475 }
2476
2477 driver.mu.Lock()
2478 opens := driver.openCount - opens0
2479 closes := driver.closeCount - closes0
2480 openDelta := (driver.openCount - driver.closeCount) - openDelta0
2481 driver.mu.Unlock()
2482
2483 if openDelta > 2 {
2484 t.Logf("open calls = %d", opens)
2485 t.Logf("close calls = %d", closes)
2486 t.Logf("open delta = %d", openDelta)
2487 t.Errorf("db connections opened = %d; want <= 2", openDelta)
2488 db.dumpDeps(t)
2489 }
2490
2491 if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
2492 return len(stmt.css) <= nquery
2493 }) {
2494 t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery)
2495 }
2496
2497 if err := stmt.Close(); err != nil {
2498 t.Fatal(err)
2499 }
2500
2501 if g, w := db.numFreeConns(), 2; g != w {
2502 t.Errorf("free conns = %d; want %d", g, w)
2503 }
2504
2505 if n := db.numDepsPollUntil(2, time.Second); n > 2 {
2506 t.Errorf("number of dependencies = %d; expected <= 2", n)
2507 db.dumpDeps(t)
2508 }
2509
2510 db.clearAllConns(t)
2511 }
2512
2513
2514 func TestCloseConnBeforeStmts(t *testing.T) {
2515 db := newTestDB(t, "people")
2516 defer closeDB(t, db)
2517
2518 defer setHookpostCloseConn(nil)
2519 setHookpostCloseConn(func(_ *fakeConn, err error) {
2520 if err != nil {
2521 t.Errorf("Error closing fakeConn: %v; from %s", err, stack())
2522 db.dumpDeps(t)
2523 t.Errorf("DB = %#v", db)
2524 }
2525 })
2526
2527 stmt, err := db.Prepare("SELECT|people|name|")
2528 if err != nil {
2529 t.Fatal(err)
2530 }
2531
2532 if len(db.freeConn) != 1 {
2533 t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn))
2534 }
2535 dc := db.freeConn[0]
2536 if dc.closed {
2537 t.Errorf("conn shouldn't be closed")
2538 }
2539
2540 if n := len(dc.openStmt); n != 1 {
2541 t.Errorf("driverConn num openStmt = %d; want 1", n)
2542 }
2543 err = db.Close()
2544 if err != nil {
2545 t.Errorf("db Close = %v", err)
2546 }
2547 if !dc.closed {
2548 t.Errorf("after db.Close, driverConn should be closed")
2549 }
2550 if n := len(dc.openStmt); n != 0 {
2551 t.Errorf("driverConn num openStmt = %d; want 0", n)
2552 }
2553
2554 err = stmt.Close()
2555 if err != nil {
2556 t.Errorf("Stmt close = %v", err)
2557 }
2558
2559 if !dc.closed {
2560 t.Errorf("conn should be closed")
2561 }
2562 if dc.ci != nil {
2563 t.Errorf("after Stmt Close, driverConn's Conn interface should be nil")
2564 }
2565 }
2566
2567
2568
2569 func TestRowsCloseOrder(t *testing.T) {
2570 db := newTestDB(t, "people")
2571 defer closeDB(t, db)
2572
2573 db.SetMaxIdleConns(0)
2574 setStrictFakeConnClose(t)
2575 defer setStrictFakeConnClose(nil)
2576
2577 rows, err := db.Query("SELECT|people|age,name|")
2578 if err != nil {
2579 t.Fatal(err)
2580 }
2581 err = rows.Close()
2582 if err != nil {
2583 t.Fatal(err)
2584 }
2585 }
2586
2587 func TestRowsImplicitClose(t *testing.T) {
2588 db := newTestDB(t, "people")
2589 defer closeDB(t, db)
2590
2591 rows, err := db.Query("SELECT|people|age,name|")
2592 if err != nil {
2593 t.Fatal(err)
2594 }
2595
2596 want, fail := 2, errors.New("fail")
2597 r := rows.rowsi.(*rowsCursor)
2598 r.errPos, r.err = want, fail
2599
2600 got := 0
2601 for rows.Next() {
2602 got++
2603 }
2604 if got != want {
2605 t.Errorf("got %d rows, want %d", got, want)
2606 }
2607 if err := rows.Err(); err != fail {
2608 t.Errorf("got error %v, want %v", err, fail)
2609 }
2610 if !r.closed {
2611 t.Errorf("r.closed is false, want true")
2612 }
2613 }
2614
2615 func TestStmtCloseOrder(t *testing.T) {
2616 db := newTestDB(t, "people")
2617 defer closeDB(t, db)
2618
2619 db.SetMaxIdleConns(0)
2620 setStrictFakeConnClose(t)
2621 defer setStrictFakeConnClose(nil)
2622
2623 _, err := db.Query("SELECT|non_existent|name|")
2624 if err == nil {
2625 t.Fatal("Querying non-existent table should fail")
2626 }
2627 }
2628
2629
2630
2631 func TestManyErrBadConn(t *testing.T) {
2632 manyErrBadConnSetup := func(first ...func(db *DB)) *DB {
2633 db := newTestDB(t, "people")
2634
2635 for _, f := range first {
2636 f(db)
2637 }
2638
2639 nconn := maxBadConnRetries + 1
2640 db.SetMaxIdleConns(nconn)
2641 db.SetMaxOpenConns(nconn)
2642
2643 func() {
2644 for i := 0; i < nconn; i++ {
2645 rows, err := db.Query("SELECT|people|age,name|")
2646 if err != nil {
2647 t.Fatal(err)
2648 }
2649 defer rows.Close()
2650 }
2651 }()
2652
2653 db.mu.Lock()
2654 defer db.mu.Unlock()
2655 if db.numOpen != nconn {
2656 t.Fatalf("unexpected numOpen %d (was expecting %d)", db.numOpen, nconn)
2657 } else if len(db.freeConn) != nconn {
2658 t.Fatalf("unexpected len(db.freeConn) %d (was expecting %d)", len(db.freeConn), nconn)
2659 }
2660 for _, conn := range db.freeConn {
2661 conn.Lock()
2662 conn.ci.(*fakeConn).stickyBad = true
2663 conn.Unlock()
2664 }
2665 return db
2666 }
2667
2668
2669 db := manyErrBadConnSetup()
2670 defer closeDB(t, db)
2671 rows, err := db.Query("SELECT|people|age,name|")
2672 if err != nil {
2673 t.Fatal(err)
2674 }
2675 if err = rows.Close(); err != nil {
2676 t.Fatal(err)
2677 }
2678
2679
2680 db = manyErrBadConnSetup()
2681 defer closeDB(t, db)
2682 _, err = db.Exec("INSERT|people|name=Julia,age=19")
2683 if err != nil {
2684 t.Fatal(err)
2685 }
2686
2687
2688 db = manyErrBadConnSetup()
2689 defer closeDB(t, db)
2690 tx, err := db.Begin()
2691 if err != nil {
2692 t.Fatal(err)
2693 }
2694 if err = tx.Rollback(); err != nil {
2695 t.Fatal(err)
2696 }
2697
2698
2699 db = manyErrBadConnSetup()
2700 defer closeDB(t, db)
2701 stmt, err := db.Prepare("SELECT|people|age,name|")
2702 if err != nil {
2703 t.Fatal(err)
2704 }
2705 if err = stmt.Close(); err != nil {
2706 t.Fatal(err)
2707 }
2708
2709
2710 db = manyErrBadConnSetup(func(db *DB) {
2711 stmt, err = db.Prepare("INSERT|people|name=Julia,age=19")
2712 if err != nil {
2713 t.Fatal(err)
2714 }
2715 })
2716 defer closeDB(t, db)
2717 _, err = stmt.Exec()
2718 if err != nil {
2719 t.Fatal(err)
2720 }
2721 if err = stmt.Close(); err != nil {
2722 t.Fatal(err)
2723 }
2724
2725
2726 db = manyErrBadConnSetup(func(db *DB) {
2727 stmt, err = db.Prepare("SELECT|people|age,name|")
2728 if err != nil {
2729 t.Fatal(err)
2730 }
2731 })
2732 defer closeDB(t, db)
2733 rows, err = stmt.Query()
2734 if err != nil {
2735 t.Fatal(err)
2736 }
2737 if err = rows.Close(); err != nil {
2738 t.Fatal(err)
2739 }
2740 if err = stmt.Close(); err != nil {
2741 t.Fatal(err)
2742 }
2743
2744
2745 db = manyErrBadConnSetup()
2746 defer closeDB(t, db)
2747 ctx, cancel := context.WithCancel(context.Background())
2748 defer cancel()
2749 conn, err := db.Conn(ctx)
2750 if err != nil {
2751 t.Fatal(err)
2752 }
2753 conn.dc.ci.(*fakeConn).skipDirtySession = true
2754 err = conn.Close()
2755 if err != nil {
2756 t.Fatal(err)
2757 }
2758
2759
2760 db = manyErrBadConnSetup()
2761 defer closeDB(t, db)
2762 err = db.PingContext(ctx)
2763 if err != nil {
2764 t.Fatal(err)
2765 }
2766 }
2767
2768
2769 func TestTxCannotCommitAfterRollback(t *testing.T) {
2770 db := newTestDB(t, "tx_status")
2771 defer closeDB(t, db)
2772
2773
2774 var txStatus string
2775 err := db.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
2776 if err != nil {
2777 t.Fatal(err)
2778 }
2779 if g, w := txStatus, "autocommit"; g != w {
2780 t.Fatalf("tx_status=%q, wanted %q", g, w)
2781 }
2782
2783 ctx, cancel := context.WithCancel(context.Background())
2784 defer cancel()
2785
2786 tx, err := db.BeginTx(ctx, nil)
2787 if err != nil {
2788 t.Fatal(err)
2789 }
2790
2791
2792
2793
2794 tx.txi.(*fakeTx).c.skipDirtySession = true
2795
2796 defer tx.Rollback()
2797
2798 err = tx.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
2799 if err != nil {
2800 t.Fatal(err)
2801 }
2802 if g, w := txStatus, "transaction"; g != w {
2803 t.Fatalf("tx_status=%q, wanted %q", g, w)
2804 }
2805
2806
2807
2808
2809 sendQuery := make(chan struct{})
2810
2811
2812 bypassRowsAwaitDone = true
2813 hookTxGrabConn = func() {
2814 cancel()
2815 <-sendQuery
2816 }
2817 rollbackHook = func() {
2818 close(sendQuery)
2819 }
2820 defer func() {
2821 hookTxGrabConn = nil
2822 rollbackHook = nil
2823 bypassRowsAwaitDone = false
2824 }()
2825
2826 err = tx.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
2827 if err != nil {
2828
2829 t.Fatal(err)
2830 }
2831 if g, w := txStatus, "transaction"; g != w {
2832 t.Fatalf("tx_status=%q, wanted %q", g, w)
2833 }
2834 }
2835
2836
2837 func TestTxStmtDeadlock(t *testing.T) {
2838 db := newTestDB(t, "people")
2839 defer closeDB(t, db)
2840
2841 ctx, cancel := context.WithCancel(context.Background())
2842 defer cancel()
2843 tx, err := db.BeginTx(ctx, nil)
2844 if err != nil {
2845 t.Fatal(err)
2846 }
2847
2848 stmt, err := tx.Prepare("SELECT|people|name,age|age=?")
2849 if err != nil {
2850 t.Fatal(err)
2851 }
2852 cancel()
2853
2854 for i := 0; i < 1e3; i++ {
2855
2856
2857 _, err = stmt.Query(1)
2858 if err != nil {
2859 break
2860 }
2861 }
2862 _ = tx.Rollback()
2863 }
2864
2865
2866
2867
2868 func TestConnExpiresFreshOutOfPool(t *testing.T) {
2869 execCases := []struct {
2870 expired bool
2871 badReset bool
2872 }{
2873 {false, false},
2874 {true, false},
2875 {false, true},
2876 }
2877
2878 t0 := time.Unix(1000000, 0)
2879 offset := time.Duration(0)
2880 offsetMu := sync.RWMutex{}
2881
2882 nowFunc = func() time.Time {
2883 offsetMu.RLock()
2884 defer offsetMu.RUnlock()
2885 return t0.Add(offset)
2886 }
2887 defer func() { nowFunc = time.Now }()
2888
2889 ctx, cancel := context.WithCancel(context.Background())
2890 defer cancel()
2891
2892 db := newTestDB(t, "magicquery")
2893 defer closeDB(t, db)
2894
2895 db.SetMaxOpenConns(1)
2896
2897 for _, ec := range execCases {
2898 ec := ec
2899 name := fmt.Sprintf("expired=%t,badReset=%t", ec.expired, ec.badReset)
2900 t.Run(name, func(t *testing.T) {
2901 db.clearAllConns(t)
2902
2903 db.SetMaxIdleConns(1)
2904 db.SetConnMaxLifetime(10 * time.Second)
2905
2906 conn, err := db.conn(ctx, alwaysNewConn)
2907 if err != nil {
2908 t.Fatal(err)
2909 }
2910
2911 afterPutConn := make(chan struct{})
2912 waitingForConn := make(chan struct{})
2913
2914 go func() {
2915 defer close(afterPutConn)
2916
2917 conn, err := db.conn(ctx, alwaysNewConn)
2918 if err == nil {
2919 db.putConn(conn, err, false)
2920 } else {
2921 t.Errorf("db.conn: %v", err)
2922 }
2923 }()
2924 go func() {
2925 defer close(waitingForConn)
2926
2927 for {
2928 if t.Failed() {
2929 return
2930 }
2931 db.mu.Lock()
2932 ct := len(db.connRequests)
2933 db.mu.Unlock()
2934 if ct > 0 {
2935 return
2936 }
2937 time.Sleep(10 * time.Millisecond)
2938 }
2939 }()
2940
2941 <-waitingForConn
2942
2943 if t.Failed() {
2944 return
2945 }
2946
2947 offsetMu.Lock()
2948 if ec.expired {
2949 offset = 11 * time.Second
2950 } else {
2951 offset = time.Duration(0)
2952 }
2953 offsetMu.Unlock()
2954
2955 conn.ci.(*fakeConn).stickyBad = ec.badReset
2956
2957 db.putConn(conn, err, true)
2958
2959 <-afterPutConn
2960 })
2961 }
2962 }
2963
2964
2965
2966 func TestIssue20575(t *testing.T) {
2967 db := newTestDB(t, "people")
2968 defer closeDB(t, db)
2969
2970 tx, err := db.Begin()
2971 if err != nil {
2972 t.Fatal(err)
2973 }
2974 ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
2975 defer cancel()
2976 _, err = tx.QueryContext(ctx, "SELECT|people|age,name|")
2977 if err != nil {
2978 t.Fatal(err)
2979 }
2980
2981 err = tx.Rollback()
2982 if err != nil {
2983 t.Fatal(err)
2984 }
2985 select {
2986 default:
2987 case <-ctx.Done():
2988 t.Fatal("timeout: failed to rollback query without closing rows:", ctx.Err())
2989 }
2990 }
2991
2992
2993
2994 func TestIssue20622(t *testing.T) {
2995 db := newTestDB(t, "people")
2996 defer closeDB(t, db)
2997
2998 ctx, cancel := context.WithCancel(context.Background())
2999 defer cancel()
3000
3001 tx, err := db.BeginTx(ctx, nil)
3002 if err != nil {
3003 t.Fatal(err)
3004 }
3005
3006 rows, err := tx.Query("SELECT|people|age,name|")
3007 if err != nil {
3008 t.Fatal(err)
3009 }
3010
3011 count := 0
3012 for rows.Next() {
3013 count++
3014 var age int
3015 var name string
3016 if err := rows.Scan(&age, &name); err != nil {
3017 t.Fatal("scan failed", err)
3018 }
3019
3020 if count == 1 {
3021 cancel()
3022 }
3023 time.Sleep(100 * time.Millisecond)
3024 }
3025 rows.Close()
3026 tx.Commit()
3027 }
3028
3029
3030 func TestErrBadConnReconnect(t *testing.T) {
3031 db := newTestDB(t, "foo")
3032 defer closeDB(t, db)
3033 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
3034
3035 simulateBadConn := func(name string, hook *func() bool, op func() error) {
3036 broken, retried := false, false
3037 numOpen := db.numOpen
3038
3039
3040 *hook = func() bool {
3041 if !broken {
3042 broken = true
3043 return true
3044 }
3045 retried = true
3046 return false
3047 }
3048
3049 if err := op(); err != nil {
3050 t.Errorf(name+": %v", err)
3051 return
3052 }
3053
3054 if !broken || !retried {
3055 t.Error(name + ": Failed to simulate broken connection")
3056 }
3057 *hook = nil
3058
3059 if numOpen != db.numOpen {
3060 t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen)
3061 numOpen = db.numOpen
3062 }
3063 }
3064
3065
3066 dbExec := func() error {
3067 _, err := db.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true)
3068 return err
3069 }
3070 simulateBadConn("db.Exec prepare", &hookPrepareBadConn, dbExec)
3071 simulateBadConn("db.Exec exec", &hookExecBadConn, dbExec)
3072
3073
3074 dbQuery := func() error {
3075 rows, err := db.Query("SELECT|t1|age,name|")
3076 if err == nil {
3077 err = rows.Close()
3078 }
3079 return err
3080 }
3081 simulateBadConn("db.Query prepare", &hookPrepareBadConn, dbQuery)
3082 simulateBadConn("db.Query query", &hookQueryBadConn, dbQuery)
3083
3084
3085 simulateBadConn("db.Prepare", &hookPrepareBadConn, func() error {
3086 stmt, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
3087 if err != nil {
3088 return err
3089 }
3090 stmt.Close()
3091 return nil
3092 })
3093
3094
3095 forcePrepare := func(stmt *Stmt) {
3096 stmt.css = nil
3097 }
3098
3099
3100 stmt1, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
3101 if err != nil {
3102 t.Fatalf("prepare: %v", err)
3103 }
3104 defer stmt1.Close()
3105
3106 forcePrepare(stmt1)
3107
3108 stmtExec := func() error {
3109 _, err := stmt1.Exec("Gopher", 3, false)
3110 return err
3111 }
3112 simulateBadConn("stmt.Exec prepare", &hookPrepareBadConn, stmtExec)
3113 simulateBadConn("stmt.Exec exec", &hookExecBadConn, stmtExec)
3114
3115
3116 stmt2, err := db.Prepare("SELECT|t1|age,name|")
3117 if err != nil {
3118 t.Fatalf("prepare: %v", err)
3119 }
3120 defer stmt2.Close()
3121
3122 forcePrepare(stmt2)
3123
3124 stmtQuery := func() error {
3125 rows, err := stmt2.Query()
3126 if err == nil {
3127 err = rows.Close()
3128 }
3129 return err
3130 }
3131 simulateBadConn("stmt.Query prepare", &hookPrepareBadConn, stmtQuery)
3132 simulateBadConn("stmt.Query exec", &hookQueryBadConn, stmtQuery)
3133 }
3134
3135
3136 func TestTxEndBadConn(t *testing.T) {
3137 db := newTestDB(t, "foo")
3138 defer closeDB(t, db)
3139 db.SetMaxIdleConns(0)
3140 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
3141 db.SetMaxIdleConns(1)
3142
3143 simulateBadConn := func(name string, hook *func() bool, op func() error) {
3144 broken := false
3145 numOpen := db.numOpen
3146
3147 *hook = func() bool {
3148 if !broken {
3149 broken = true
3150 }
3151 return broken
3152 }
3153
3154 if err := op(); err != driver.ErrBadConn {
3155 t.Errorf(name+": %v", err)
3156 return
3157 }
3158
3159 if !broken {
3160 t.Error(name + ": Failed to simulate broken connection")
3161 }
3162 *hook = nil
3163
3164 if numOpen != db.numOpen {
3165 t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen)
3166 }
3167 }
3168
3169
3170 dbExec := func(endTx func(tx *Tx) error) func() error {
3171 return func() error {
3172 tx, err := db.Begin()
3173 if err != nil {
3174 return err
3175 }
3176 _, err = tx.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true)
3177 if err != nil {
3178 return err
3179 }
3180 return endTx(tx)
3181 }
3182 }
3183 simulateBadConn("db.Tx.Exec commit", &hookCommitBadConn, dbExec((*Tx).Commit))
3184 simulateBadConn("db.Tx.Exec rollback", &hookRollbackBadConn, dbExec((*Tx).Rollback))
3185
3186
3187 dbQuery := func(endTx func(tx *Tx) error) func() error {
3188 return func() error {
3189 tx, err := db.Begin()
3190 if err != nil {
3191 return err
3192 }
3193 rows, err := tx.Query("SELECT|t1|age,name|")
3194 if err == nil {
3195 err = rows.Close()
3196 } else {
3197 return err
3198 }
3199 return endTx(tx)
3200 }
3201 }
3202 simulateBadConn("db.Tx.Query commit", &hookCommitBadConn, dbQuery((*Tx).Commit))
3203 simulateBadConn("db.Tx.Query rollback", &hookRollbackBadConn, dbQuery((*Tx).Rollback))
3204 }
3205
3206 type concurrentTest interface {
3207 init(t testing.TB, db *DB)
3208 finish(t testing.TB)
3209 test(t testing.TB) error
3210 }
3211
3212 type concurrentDBQueryTest struct {
3213 db *DB
3214 }
3215
3216 func (c *concurrentDBQueryTest) init(t testing.TB, db *DB) {
3217 c.db = db
3218 }
3219
3220 func (c *concurrentDBQueryTest) finish(t testing.TB) {
3221 c.db = nil
3222 }
3223
3224 func (c *concurrentDBQueryTest) test(t testing.TB) error {
3225 rows, err := c.db.Query("SELECT|people|name|")
3226 if err != nil {
3227 t.Error(err)
3228 return err
3229 }
3230 var name string
3231 for rows.Next() {
3232 rows.Scan(&name)
3233 }
3234 rows.Close()
3235 return nil
3236 }
3237
3238 type concurrentDBExecTest struct {
3239 db *DB
3240 }
3241
3242 func (c *concurrentDBExecTest) init(t testing.TB, db *DB) {
3243 c.db = db
3244 }
3245
3246 func (c *concurrentDBExecTest) finish(t testing.TB) {
3247 c.db = nil
3248 }
3249
3250 func (c *concurrentDBExecTest) test(t testing.TB) error {
3251 _, err := c.db.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
3252 if err != nil {
3253 t.Error(err)
3254 return err
3255 }
3256 return nil
3257 }
3258
3259 type concurrentStmtQueryTest struct {
3260 db *DB
3261 stmt *Stmt
3262 }
3263
3264 func (c *concurrentStmtQueryTest) init(t testing.TB, db *DB) {
3265 c.db = db
3266 var err error
3267 c.stmt, err = db.Prepare("SELECT|people|name|")
3268 if err != nil {
3269 t.Fatal(err)
3270 }
3271 }
3272
3273 func (c *concurrentStmtQueryTest) finish(t testing.TB) {
3274 if c.stmt != nil {
3275 c.stmt.Close()
3276 c.stmt = nil
3277 }
3278 c.db = nil
3279 }
3280
3281 func (c *concurrentStmtQueryTest) test(t testing.TB) error {
3282 rows, err := c.stmt.Query()
3283 if err != nil {
3284 t.Errorf("error on query: %v", err)
3285 return err
3286 }
3287
3288 var name string
3289 for rows.Next() {
3290 rows.Scan(&name)
3291 }
3292 rows.Close()
3293 return nil
3294 }
3295
3296 type concurrentStmtExecTest struct {
3297 db *DB
3298 stmt *Stmt
3299 }
3300
3301 func (c *concurrentStmtExecTest) init(t testing.TB, db *DB) {
3302 c.db = db
3303 var err error
3304 c.stmt, err = db.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
3305 if err != nil {
3306 t.Fatal(err)
3307 }
3308 }
3309
3310 func (c *concurrentStmtExecTest) finish(t testing.TB) {
3311 if c.stmt != nil {
3312 c.stmt.Close()
3313 c.stmt = nil
3314 }
3315 c.db = nil
3316 }
3317
3318 func (c *concurrentStmtExecTest) test(t testing.TB) error {
3319 _, err := c.stmt.Exec(3, chrisBirthday)
3320 if err != nil {
3321 t.Errorf("error on exec: %v", err)
3322 return err
3323 }
3324 return nil
3325 }
3326
3327 type concurrentTxQueryTest struct {
3328 db *DB
3329 tx *Tx
3330 }
3331
3332 func (c *concurrentTxQueryTest) init(t testing.TB, db *DB) {
3333 c.db = db
3334 var err error
3335 c.tx, err = c.db.Begin()
3336 if err != nil {
3337 t.Fatal(err)
3338 }
3339 }
3340
3341 func (c *concurrentTxQueryTest) finish(t testing.TB) {
3342 if c.tx != nil {
3343 c.tx.Rollback()
3344 c.tx = nil
3345 }
3346 c.db = nil
3347 }
3348
3349 func (c *concurrentTxQueryTest) test(t testing.TB) error {
3350 rows, err := c.db.Query("SELECT|people|name|")
3351 if err != nil {
3352 t.Error(err)
3353 return err
3354 }
3355 var name string
3356 for rows.Next() {
3357 rows.Scan(&name)
3358 }
3359 rows.Close()
3360 return nil
3361 }
3362
3363 type concurrentTxExecTest struct {
3364 db *DB
3365 tx *Tx
3366 }
3367
3368 func (c *concurrentTxExecTest) init(t testing.TB, db *DB) {
3369 c.db = db
3370 var err error
3371 c.tx, err = c.db.Begin()
3372 if err != nil {
3373 t.Fatal(err)
3374 }
3375 }
3376
3377 func (c *concurrentTxExecTest) finish(t testing.TB) {
3378 if c.tx != nil {
3379 c.tx.Rollback()
3380 c.tx = nil
3381 }
3382 c.db = nil
3383 }
3384
3385 func (c *concurrentTxExecTest) test(t testing.TB) error {
3386 _, err := c.tx.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
3387 if err != nil {
3388 t.Error(err)
3389 return err
3390 }
3391 return nil
3392 }
3393
3394 type concurrentTxStmtQueryTest struct {
3395 db *DB
3396 tx *Tx
3397 stmt *Stmt
3398 }
3399
3400 func (c *concurrentTxStmtQueryTest) init(t testing.TB, db *DB) {
3401 c.db = db
3402 var err error
3403 c.tx, err = c.db.Begin()
3404 if err != nil {
3405 t.Fatal(err)
3406 }
3407 c.stmt, err = c.tx.Prepare("SELECT|people|name|")
3408 if err != nil {
3409 t.Fatal(err)
3410 }
3411 }
3412
3413 func (c *concurrentTxStmtQueryTest) finish(t testing.TB) {
3414 if c.stmt != nil {
3415 c.stmt.Close()
3416 c.stmt = nil
3417 }
3418 if c.tx != nil {
3419 c.tx.Rollback()
3420 c.tx = nil
3421 }
3422 c.db = nil
3423 }
3424
3425 func (c *concurrentTxStmtQueryTest) test(t testing.TB) error {
3426 rows, err := c.stmt.Query()
3427 if err != nil {
3428 t.Errorf("error on query: %v", err)
3429 return err
3430 }
3431
3432 var name string
3433 for rows.Next() {
3434 rows.Scan(&name)
3435 }
3436 rows.Close()
3437 return nil
3438 }
3439
3440 type concurrentTxStmtExecTest struct {
3441 db *DB
3442 tx *Tx
3443 stmt *Stmt
3444 }
3445
3446 func (c *concurrentTxStmtExecTest) init(t testing.TB, db *DB) {
3447 c.db = db
3448 var err error
3449 c.tx, err = c.db.Begin()
3450 if err != nil {
3451 t.Fatal(err)
3452 }
3453 c.stmt, err = c.tx.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
3454 if err != nil {
3455 t.Fatal(err)
3456 }
3457 }
3458
3459 func (c *concurrentTxStmtExecTest) finish(t testing.TB) {
3460 if c.stmt != nil {
3461 c.stmt.Close()
3462 c.stmt = nil
3463 }
3464 if c.tx != nil {
3465 c.tx.Rollback()
3466 c.tx = nil
3467 }
3468 c.db = nil
3469 }
3470
3471 func (c *concurrentTxStmtExecTest) test(t testing.TB) error {
3472 _, err := c.stmt.Exec(3, chrisBirthday)
3473 if err != nil {
3474 t.Errorf("error on exec: %v", err)
3475 return err
3476 }
3477 return nil
3478 }
3479
3480 type concurrentRandomTest struct {
3481 tests []concurrentTest
3482 }
3483
3484 func (c *concurrentRandomTest) init(t testing.TB, db *DB) {
3485 c.tests = []concurrentTest{
3486 new(concurrentDBQueryTest),
3487 new(concurrentDBExecTest),
3488 new(concurrentStmtQueryTest),
3489 new(concurrentStmtExecTest),
3490 new(concurrentTxQueryTest),
3491 new(concurrentTxExecTest),
3492 new(concurrentTxStmtQueryTest),
3493 new(concurrentTxStmtExecTest),
3494 }
3495 for _, ct := range c.tests {
3496 ct.init(t, db)
3497 }
3498 }
3499
3500 func (c *concurrentRandomTest) finish(t testing.TB) {
3501 for _, ct := range c.tests {
3502 ct.finish(t)
3503 }
3504 }
3505
3506 func (c *concurrentRandomTest) test(t testing.TB) error {
3507 ct := c.tests[rand.Intn(len(c.tests))]
3508 return ct.test(t)
3509 }
3510
3511 func doConcurrentTest(t testing.TB, ct concurrentTest) {
3512 maxProcs, numReqs := 1, 500
3513 if testing.Short() {
3514 maxProcs, numReqs = 4, 50
3515 }
3516 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
3517
3518 db := newTestDB(t, "people")
3519 defer closeDB(t, db)
3520
3521 ct.init(t, db)
3522 defer ct.finish(t)
3523
3524 var wg sync.WaitGroup
3525 wg.Add(numReqs)
3526
3527 reqs := make(chan bool)
3528 defer close(reqs)
3529
3530 for i := 0; i < maxProcs*2; i++ {
3531 go func() {
3532 for range reqs {
3533 err := ct.test(t)
3534 if err != nil {
3535 wg.Done()
3536 continue
3537 }
3538 wg.Done()
3539 }
3540 }()
3541 }
3542
3543 for i := 0; i < numReqs; i++ {
3544 reqs <- true
3545 }
3546
3547 wg.Wait()
3548 }
3549
3550 func TestIssue6081(t *testing.T) {
3551 db := newTestDB(t, "people")
3552 defer closeDB(t, db)
3553
3554 drv := db.Driver().(*fakeDriver)
3555 drv.mu.Lock()
3556 opens0 := drv.openCount
3557 closes0 := drv.closeCount
3558 drv.mu.Unlock()
3559
3560 stmt, err := db.Prepare("SELECT|people|name|")
3561 if err != nil {
3562 t.Fatal(err)
3563 }
3564 setRowsCloseHook(func(rows *Rows, err *error) {
3565 *err = driver.ErrBadConn
3566 })
3567 defer setRowsCloseHook(nil)
3568 for i := 0; i < 10; i++ {
3569 rows, err := stmt.Query()
3570 if err != nil {
3571 t.Fatal(err)
3572 }
3573 rows.Close()
3574 }
3575 if n := len(stmt.css); n > 1 {
3576 t.Errorf("len(css slice) = %d; want <= 1", n)
3577 }
3578 stmt.Close()
3579 if n := len(stmt.css); n != 0 {
3580 t.Errorf("len(css slice) after Close = %d; want 0", n)
3581 }
3582
3583 drv.mu.Lock()
3584 opens := drv.openCount - opens0
3585 closes := drv.closeCount - closes0
3586 drv.mu.Unlock()
3587 if opens < 9 {
3588 t.Errorf("opens = %d; want >= 9", opens)
3589 }
3590 if closes < 9 {
3591 t.Errorf("closes = %d; want >= 9", closes)
3592 }
3593 }
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606 func TestIssue18429(t *testing.T) {
3607 db := newTestDB(t, "people")
3608 defer closeDB(t, db)
3609
3610 ctx := context.Background()
3611 sem := make(chan bool, 20)
3612 var wg sync.WaitGroup
3613
3614 const milliWait = 30
3615
3616 for i := 0; i < 100; i++ {
3617 sem <- true
3618 wg.Add(1)
3619 go func() {
3620 defer func() {
3621 <-sem
3622 wg.Done()
3623 }()
3624 qwait := (time.Duration(rand.Intn(milliWait)) * time.Millisecond).String()
3625
3626 ctx, cancel := context.WithTimeout(ctx, time.Duration(rand.Intn(milliWait))*time.Millisecond)
3627 defer cancel()
3628
3629 tx, err := db.BeginTx(ctx, nil)
3630 if err != nil {
3631 return
3632 }
3633
3634
3635
3636 rows, _ := tx.QueryContext(ctx, "WAIT|"+qwait+"|SELECT|people|name|")
3637 if rows != nil {
3638 var name string
3639
3640 for rows.Next() {
3641
3642 rows.Scan(&name)
3643 }
3644 rows.Close()
3645 }
3646
3647
3648 tx.Rollback()
3649 }()
3650 }
3651 wg.Wait()
3652 }
3653
3654
3655 func TestIssue20160(t *testing.T) {
3656 db := newTestDB(t, "people")
3657 defer closeDB(t, db)
3658
3659 ctx := context.Background()
3660 sem := make(chan bool, 20)
3661 var wg sync.WaitGroup
3662
3663 const milliWait = 30
3664
3665 stmt, err := db.PrepareContext(ctx, "SELECT|people|name|")
3666 if err != nil {
3667 t.Fatal(err)
3668 }
3669 defer stmt.Close()
3670
3671 for i := 0; i < 100; i++ {
3672 sem <- true
3673 wg.Add(1)
3674 go func() {
3675 defer func() {
3676 <-sem
3677 wg.Done()
3678 }()
3679 ctx, cancel := context.WithTimeout(ctx, time.Duration(rand.Intn(milliWait))*time.Millisecond)
3680 defer cancel()
3681
3682
3683
3684
3685 rows, _ := stmt.QueryContext(ctx)
3686 if rows != nil {
3687 rows.Close()
3688 }
3689 }()
3690 }
3691 wg.Wait()
3692 }
3693
3694
3695
3696
3697
3698
3699 func TestIssue18719(t *testing.T) {
3700 db := newTestDB(t, "people")
3701 defer closeDB(t, db)
3702
3703 ctx, cancel := context.WithCancel(context.Background())
3704 defer cancel()
3705
3706 tx, err := db.BeginTx(ctx, nil)
3707 if err != nil {
3708 t.Fatal(err)
3709 }
3710
3711 hookTxGrabConn = func() {
3712 cancel()
3713
3714
3715 for tx.isDone() == false {
3716 time.Sleep(3 * time.Millisecond)
3717 }
3718 }
3719 defer func() { hookTxGrabConn = nil }()
3720
3721
3722
3723 _, err = tx.QueryContext(ctx, "SELECT|people|name|")
3724 if err != nil {
3725 t.Fatalf("expected error %v but got %v", nil, err)
3726 }
3727
3728
3729
3730
3731
3732
3733 cancel()
3734 }
3735
3736 func TestIssue20647(t *testing.T) {
3737 db := newTestDB(t, "people")
3738 defer closeDB(t, db)
3739
3740 ctx, cancel := context.WithCancel(context.Background())
3741 defer cancel()
3742
3743 conn, err := db.Conn(ctx)
3744 if err != nil {
3745 t.Fatal(err)
3746 }
3747 conn.dc.ci.(*fakeConn).skipDirtySession = true
3748 defer conn.Close()
3749
3750 stmt, err := conn.PrepareContext(ctx, "SELECT|people|name|")
3751 if err != nil {
3752 t.Fatal(err)
3753 }
3754 defer stmt.Close()
3755
3756 rows1, err := stmt.QueryContext(ctx)
3757 if err != nil {
3758 t.Fatal("rows1", err)
3759 }
3760 defer rows1.Close()
3761
3762 rows2, err := stmt.QueryContext(ctx)
3763 if err != nil {
3764 t.Fatal("rows2", err)
3765 }
3766 defer rows2.Close()
3767
3768 if rows1.dc != rows2.dc {
3769 t.Fatal("stmt prepared on Conn does not use same connection")
3770 }
3771 }
3772
3773 func TestConcurrency(t *testing.T) {
3774 list := []struct {
3775 name string
3776 ct concurrentTest
3777 }{
3778 {"Query", new(concurrentDBQueryTest)},
3779 {"Exec", new(concurrentDBExecTest)},
3780 {"StmtQuery", new(concurrentStmtQueryTest)},
3781 {"StmtExec", new(concurrentStmtExecTest)},
3782 {"TxQuery", new(concurrentTxQueryTest)},
3783 {"TxExec", new(concurrentTxExecTest)},
3784 {"TxStmtQuery", new(concurrentTxStmtQueryTest)},
3785 {"TxStmtExec", new(concurrentTxStmtExecTest)},
3786 {"Random", new(concurrentRandomTest)},
3787 }
3788 for _, item := range list {
3789 t.Run(item.name, func(t *testing.T) {
3790 doConcurrentTest(t, item.ct)
3791 })
3792 }
3793 }
3794
3795 func TestConnectionLeak(t *testing.T) {
3796 db := newTestDB(t, "people")
3797 defer closeDB(t, db)
3798
3799 rows := make([]*Rows, defaultMaxIdleConns)
3800
3801
3802
3803 db.SetMaxOpenConns(len(rows) + 1)
3804 for ii := range rows {
3805 r, err := db.Query("SELECT|people|name|")
3806 if err != nil {
3807 t.Fatal(err)
3808 }
3809 r.Next()
3810 if err := r.Err(); err != nil {
3811 t.Fatal(err)
3812 }
3813 rows[ii] = r
3814 }
3815
3816
3817
3818 drv := db.Driver().(*fakeDriver)
3819 drv.waitCh = make(chan struct{}, 1)
3820 drv.waitingCh = make(chan struct{}, 1)
3821 var wg sync.WaitGroup
3822 wg.Add(1)
3823 go func() {
3824 r, err := db.Query("SELECT|people|name|")
3825 if err != nil {
3826 t.Error(err)
3827 return
3828 }
3829 r.Close()
3830 wg.Done()
3831 }()
3832
3833 <-drv.waitingCh
3834
3835
3836 for _, v := range rows {
3837 v.Close()
3838 }
3839
3840
3841
3842
3843 drv.waitCh <- struct{}{}
3844 wg.Wait()
3845 }
3846
3847 func TestStatsMaxIdleClosedZero(t *testing.T) {
3848 db := newTestDB(t, "people")
3849 defer closeDB(t, db)
3850
3851 db.SetMaxOpenConns(1)
3852 db.SetMaxIdleConns(1)
3853 db.SetConnMaxLifetime(0)
3854
3855 preMaxIdleClosed := db.Stats().MaxIdleClosed
3856
3857 for i := 0; i < 10; i++ {
3858 rows, err := db.Query("SELECT|people|name|")
3859 if err != nil {
3860 t.Fatal(err)
3861 }
3862 rows.Close()
3863 }
3864
3865 st := db.Stats()
3866 maxIdleClosed := st.MaxIdleClosed - preMaxIdleClosed
3867 t.Logf("MaxIdleClosed: %d", maxIdleClosed)
3868 if maxIdleClosed != 0 {
3869 t.Fatal("expected 0 max idle closed conns, got: ", maxIdleClosed)
3870 }
3871 }
3872
3873 func TestStatsMaxIdleClosedTen(t *testing.T) {
3874 db := newTestDB(t, "people")
3875 defer closeDB(t, db)
3876
3877 db.SetMaxOpenConns(1)
3878 db.SetMaxIdleConns(0)
3879 db.SetConnMaxLifetime(0)
3880
3881 preMaxIdleClosed := db.Stats().MaxIdleClosed
3882
3883 for i := 0; i < 10; i++ {
3884 rows, err := db.Query("SELECT|people|name|")
3885 if err != nil {
3886 t.Fatal(err)
3887 }
3888 rows.Close()
3889 }
3890
3891 st := db.Stats()
3892 maxIdleClosed := st.MaxIdleClosed - preMaxIdleClosed
3893 t.Logf("MaxIdleClosed: %d", maxIdleClosed)
3894 if maxIdleClosed != 10 {
3895 t.Fatal("expected 0 max idle closed conns, got: ", maxIdleClosed)
3896 }
3897 }
3898
3899 func TestMaxIdleTime(t *testing.T) {
3900 list := []struct {
3901 wantMaxIdleTime time.Duration
3902 wantIdleClosed int64
3903 timeOffset time.Duration
3904 }{
3905 {time.Nanosecond, 1, 10 * time.Millisecond},
3906 {time.Hour, 0, 10 * time.Millisecond},
3907 }
3908 baseTime := time.Unix(0, 0)
3909 defer func() {
3910 nowFunc = time.Now
3911 }()
3912 for _, item := range list {
3913 nowFunc = func() time.Time {
3914 return baseTime
3915 }
3916 t.Run(fmt.Sprintf("%v", item.wantMaxIdleTime), func(t *testing.T) {
3917 db := newTestDB(t, "people")
3918 defer closeDB(t, db)
3919
3920 db.SetMaxOpenConns(1)
3921 db.SetMaxIdleConns(1)
3922 db.SetConnMaxIdleTime(item.wantMaxIdleTime)
3923 db.SetConnMaxLifetime(0)
3924
3925 preMaxIdleClosed := db.Stats().MaxIdleTimeClosed
3926
3927 if err := db.Ping(); err != nil {
3928 t.Fatal(err)
3929 }
3930
3931 nowFunc = func() time.Time {
3932 return baseTime.Add(item.timeOffset)
3933 }
3934
3935 db.mu.Lock()
3936 closing := db.connectionCleanerRunLocked()
3937 db.mu.Unlock()
3938 for _, c := range closing {
3939 c.Close()
3940 }
3941 if g, w := int64(len(closing)), item.wantIdleClosed; g != w {
3942 t.Errorf("got: %d; want %d closed conns", g, w)
3943 }
3944
3945 st := db.Stats()
3946 maxIdleClosed := st.MaxIdleTimeClosed - preMaxIdleClosed
3947 if g, w := maxIdleClosed, item.wantIdleClosed; g != w {
3948 t.Errorf(" got: %d; want %d max idle closed conns", g, w)
3949 }
3950 })
3951 }
3952 }
3953
3954 type nvcDriver struct {
3955 fakeDriver
3956 skipNamedValueCheck bool
3957 }
3958
3959 func (d *nvcDriver) Open(dsn string) (driver.Conn, error) {
3960 c, err := d.fakeDriver.Open(dsn)
3961 fc := c.(*fakeConn)
3962 fc.db.allowAny = true
3963 return &nvcConn{fc, d.skipNamedValueCheck}, err
3964 }
3965
3966 type nvcConn struct {
3967 *fakeConn
3968 skipNamedValueCheck bool
3969 }
3970
3971 type decimalInt struct {
3972 value int
3973 }
3974
3975 type doNotInclude struct{}
3976
3977 var _ driver.NamedValueChecker = &nvcConn{}
3978
3979 func (c *nvcConn) CheckNamedValue(nv *driver.NamedValue) error {
3980 if c.skipNamedValueCheck {
3981 return driver.ErrSkip
3982 }
3983 switch v := nv.Value.(type) {
3984 default:
3985 return driver.ErrSkip
3986 case Out:
3987 switch ov := v.Dest.(type) {
3988 default:
3989 return errors.New("unknown NameValueCheck OUTPUT type")
3990 case *string:
3991 *ov = "from-server"
3992 nv.Value = "OUT:*string"
3993 }
3994 return nil
3995 case decimalInt, []int64:
3996 return nil
3997 case doNotInclude:
3998 return driver.ErrRemoveArgument
3999 }
4000 }
4001
4002 func TestNamedValueChecker(t *testing.T) {
4003 Register("NamedValueCheck", &nvcDriver{})
4004 db, err := Open("NamedValueCheck", "")
4005 if err != nil {
4006 t.Fatal(err)
4007 }
4008 defer db.Close()
4009
4010 ctx, cancel := context.WithCancel(context.Background())
4011 defer cancel()
4012
4013 _, err = db.ExecContext(ctx, "WIPE")
4014 if err != nil {
4015 t.Fatal("exec wipe", err)
4016 }
4017
4018 _, err = db.ExecContext(ctx, "CREATE|keys|dec1=any,str1=string,out1=string,array1=any")
4019 if err != nil {
4020 t.Fatal("exec create", err)
4021 }
4022
4023 o1 := ""
4024 _, err = db.ExecContext(ctx, "INSERT|keys|dec1=?A,str1=?,out1=?O1,array1=?", Named("A", decimalInt{123}), "hello", Named("O1", Out{Dest: &o1}), []int64{42, 128, 707}, doNotInclude{})
4025 if err != nil {
4026 t.Fatal("exec insert", err)
4027 }
4028 var (
4029 str1 string
4030 dec1 decimalInt
4031 arr1 []int64
4032 )
4033 err = db.QueryRowContext(ctx, "SELECT|keys|dec1,str1,array1|").Scan(&dec1, &str1, &arr1)
4034 if err != nil {
4035 t.Fatal("select", err)
4036 }
4037
4038 list := []struct{ got, want interface{} }{
4039 {o1, "from-server"},
4040 {dec1, decimalInt{123}},
4041 {str1, "hello"},
4042 {arr1, []int64{42, 128, 707}},
4043 }
4044
4045 for index, item := range list {
4046 if !reflect.DeepEqual(item.got, item.want) {
4047 t.Errorf("got %#v wanted %#v for index %d", item.got, item.want, index)
4048 }
4049 }
4050 }
4051
4052 func TestNamedValueCheckerSkip(t *testing.T) {
4053 Register("NamedValueCheckSkip", &nvcDriver{skipNamedValueCheck: true})
4054 db, err := Open("NamedValueCheckSkip", "")
4055 if err != nil {
4056 t.Fatal(err)
4057 }
4058 defer db.Close()
4059
4060 ctx, cancel := context.WithCancel(context.Background())
4061 defer cancel()
4062
4063 _, err = db.ExecContext(ctx, "WIPE")
4064 if err != nil {
4065 t.Fatal("exec wipe", err)
4066 }
4067
4068 _, err = db.ExecContext(ctx, "CREATE|keys|dec1=any")
4069 if err != nil {
4070 t.Fatal("exec create", err)
4071 }
4072
4073 _, err = db.ExecContext(ctx, "INSERT|keys|dec1=?A", Named("A", decimalInt{123}))
4074 if err == nil {
4075 t.Fatalf("expected error with bad argument, got %v", err)
4076 }
4077 }
4078
4079 func TestOpenConnector(t *testing.T) {
4080 Register("testctx", &fakeDriverCtx{})
4081 db, err := Open("testctx", "people")
4082 if err != nil {
4083 t.Fatal(err)
4084 }
4085 defer db.Close()
4086
4087 c, ok := db.connector.(*fakeConnector)
4088 if !ok {
4089 t.Fatal("not using *fakeConnector")
4090 }
4091
4092 if err := db.Close(); err != nil {
4093 t.Fatal(err)
4094 }
4095
4096 if !c.closed {
4097 t.Fatal("connector is not closed")
4098 }
4099 }
4100
4101 type ctxOnlyDriver struct {
4102 fakeDriver
4103 }
4104
4105 func (d *ctxOnlyDriver) Open(dsn string) (driver.Conn, error) {
4106 conn, err := d.fakeDriver.Open(dsn)
4107 if err != nil {
4108 return nil, err
4109 }
4110 return &ctxOnlyConn{fc: conn.(*fakeConn)}, nil
4111 }
4112
4113 var (
4114 _ driver.Conn = &ctxOnlyConn{}
4115 _ driver.QueryerContext = &ctxOnlyConn{}
4116 _ driver.ExecerContext = &ctxOnlyConn{}
4117 )
4118
4119 type ctxOnlyConn struct {
4120 fc *fakeConn
4121
4122 queryCtxCalled bool
4123 execCtxCalled bool
4124 }
4125
4126 func (c *ctxOnlyConn) Begin() (driver.Tx, error) {
4127 return c.fc.Begin()
4128 }
4129
4130 func (c *ctxOnlyConn) Close() error {
4131 return c.fc.Close()
4132 }
4133
4134
4135
4136 func (c *ctxOnlyConn) Prepare(q string) (driver.Stmt, error) {
4137 panic("not used")
4138 }
4139
4140 func (c *ctxOnlyConn) PrepareContext(ctx context.Context, q string) (driver.Stmt, error) {
4141 return c.fc.PrepareContext(ctx, q)
4142 }
4143
4144 func (c *ctxOnlyConn) QueryContext(ctx context.Context, q string, args []driver.NamedValue) (driver.Rows, error) {
4145 c.queryCtxCalled = true
4146 return c.fc.QueryContext(ctx, q, args)
4147 }
4148
4149 func (c *ctxOnlyConn) ExecContext(ctx context.Context, q string, args []driver.NamedValue) (driver.Result, error) {
4150 c.execCtxCalled = true
4151 return c.fc.ExecContext(ctx, q, args)
4152 }
4153
4154
4155
4156 func TestQueryExecContextOnly(t *testing.T) {
4157
4158 var connType driver.Conn = &ctxOnlyConn{}
4159 if _, ok := connType.(driver.Execer); ok {
4160 t.Fatalf("%T must not implement driver.Execer", connType)
4161 }
4162 if _, ok := connType.(driver.Queryer); ok {
4163 t.Fatalf("%T must not implement driver.Queryer", connType)
4164 }
4165
4166 Register("ContextOnly", &ctxOnlyDriver{})
4167 db, err := Open("ContextOnly", "")
4168 if err != nil {
4169 t.Fatal(err)
4170 }
4171 defer db.Close()
4172
4173 ctx, cancel := context.WithCancel(context.Background())
4174 defer cancel()
4175
4176 conn, err := db.Conn(ctx)
4177 if err != nil {
4178 t.Fatal("db.Conn", err)
4179 }
4180 defer conn.Close()
4181 coc := conn.dc.ci.(*ctxOnlyConn)
4182 coc.fc.skipDirtySession = true
4183
4184 _, err = conn.ExecContext(ctx, "WIPE")
4185 if err != nil {
4186 t.Fatal("exec wipe", err)
4187 }
4188
4189 _, err = conn.ExecContext(ctx, "CREATE|keys|v1=string")
4190 if err != nil {
4191 t.Fatal("exec create", err)
4192 }
4193 expectedValue := "value1"
4194 _, err = conn.ExecContext(ctx, "INSERT|keys|v1=?", expectedValue)
4195 if err != nil {
4196 t.Fatal("exec insert", err)
4197 }
4198 rows, err := conn.QueryContext(ctx, "SELECT|keys|v1|")
4199 if err != nil {
4200 t.Fatal("query select", err)
4201 }
4202 v1 := ""
4203 for rows.Next() {
4204 err = rows.Scan(&v1)
4205 if err != nil {
4206 t.Fatal("rows scan", err)
4207 }
4208 }
4209 rows.Close()
4210
4211 if v1 != expectedValue {
4212 t.Fatalf("expected %q, got %q", expectedValue, v1)
4213 }
4214
4215 if !coc.execCtxCalled {
4216 t.Error("ExecContext not called")
4217 }
4218 if !coc.queryCtxCalled {
4219 t.Error("QueryContext not called")
4220 }
4221 }
4222
4223 type alwaysErrScanner struct{}
4224
4225 var errTestScanWrap = errors.New("errTestScanWrap")
4226
4227 func (alwaysErrScanner) Scan(interface{}) error {
4228 return errTestScanWrap
4229 }
4230
4231
4232 func TestRowsScanProperlyWrapsErrors(t *testing.T) {
4233 db := newTestDB(t, "people")
4234 defer closeDB(t, db)
4235
4236 rows, err := db.Query("SELECT|people|age|")
4237 if err != nil {
4238 t.Fatalf("Query: %v", err)
4239 }
4240
4241 var res alwaysErrScanner
4242
4243 for rows.Next() {
4244 err = rows.Scan(&res)
4245 if err == nil {
4246 t.Fatal("expecting back an error")
4247 }
4248 if !errors.Is(err, errTestScanWrap) {
4249 t.Fatalf("errors.Is mismatch\n%v\nWant: %v", err, errTestScanWrap)
4250 }
4251
4252 if !strings.Contains(err.Error(), errTestScanWrap.Error()) {
4253 t.Fatalf("Error %v does not contain %v", err, errTestScanWrap)
4254 }
4255 }
4256 }
4257
4258
4259
4260 type badConn struct{}
4261
4262 func (bc badConn) Prepare(query string) (driver.Stmt, error) {
4263 return nil, errors.New("badConn Prepare")
4264 }
4265
4266 func (bc badConn) Close() error {
4267 return nil
4268 }
4269
4270 func (bc badConn) Begin() (driver.Tx, error) {
4271 return nil, errors.New("badConn Begin")
4272 }
4273
4274 func (bc badConn) Exec(query string, args []driver.Value) (driver.Result, error) {
4275 panic("badConn.Exec")
4276 }
4277
4278
4279 type badDriver struct{}
4280
4281 func (bd badDriver) Open(name string) (driver.Conn, error) {
4282 return badConn{}, nil
4283 }
4284
4285
4286 func TestBadDriver(t *testing.T) {
4287 Register("bad", badDriver{})
4288 db, err := Open("bad", "ignored")
4289 if err != nil {
4290 t.Fatal(err)
4291 }
4292 defer func() {
4293 if r := recover(); r == nil {
4294 t.Error("expected panic")
4295 } else {
4296 if want := "badConn.Exec"; r.(string) != want {
4297 t.Errorf("panic was %v, expected %v", r, want)
4298 }
4299 }
4300 }()
4301 defer db.Close()
4302 db.Exec("ignored")
4303 }
4304
4305 type pingDriver struct {
4306 fails bool
4307 }
4308
4309 type pingConn struct {
4310 badConn
4311 driver *pingDriver
4312 }
4313
4314 var pingError = errors.New("Ping failed")
4315
4316 func (pc pingConn) Ping(ctx context.Context) error {
4317 if pc.driver.fails {
4318 return pingError
4319 }
4320 return nil
4321 }
4322
4323 var _ driver.Pinger = pingConn{}
4324
4325 func (pd *pingDriver) Open(name string) (driver.Conn, error) {
4326 return pingConn{driver: pd}, nil
4327 }
4328
4329 func TestPing(t *testing.T) {
4330 driver := &pingDriver{}
4331 Register("ping", driver)
4332
4333 db, err := Open("ping", "ignored")
4334 if err != nil {
4335 t.Fatal(err)
4336 }
4337
4338 if err := db.Ping(); err != nil {
4339 t.Errorf("err was %#v, expected nil", err)
4340 return
4341 }
4342
4343 driver.fails = true
4344 if err := db.Ping(); err != pingError {
4345 t.Errorf("err was %#v, expected pingError", err)
4346 }
4347 }
4348
4349
4350 func TestTypedString(t *testing.T) {
4351 db := newTestDB(t, "people")
4352 defer closeDB(t, db)
4353
4354 type Str string
4355 var scanned Str
4356
4357 err := db.QueryRow("SELECT|people|name|name=?", "Alice").Scan(&scanned)
4358 if err != nil {
4359 t.Fatal(err)
4360 }
4361 expected := Str("Alice")
4362 if scanned != expected {
4363 t.Errorf("expected %+v, got %+v", expected, scanned)
4364 }
4365 }
4366
4367 func BenchmarkConcurrentDBExec(b *testing.B) {
4368 b.ReportAllocs()
4369 ct := new(concurrentDBExecTest)
4370 for i := 0; i < b.N; i++ {
4371 doConcurrentTest(b, ct)
4372 }
4373 }
4374
4375 func BenchmarkConcurrentStmtQuery(b *testing.B) {
4376 b.ReportAllocs()
4377 ct := new(concurrentStmtQueryTest)
4378 for i := 0; i < b.N; i++ {
4379 doConcurrentTest(b, ct)
4380 }
4381 }
4382
4383 func BenchmarkConcurrentStmtExec(b *testing.B) {
4384 b.ReportAllocs()
4385 ct := new(concurrentStmtExecTest)
4386 for i := 0; i < b.N; i++ {
4387 doConcurrentTest(b, ct)
4388 }
4389 }
4390
4391 func BenchmarkConcurrentTxQuery(b *testing.B) {
4392 b.ReportAllocs()
4393 ct := new(concurrentTxQueryTest)
4394 for i := 0; i < b.N; i++ {
4395 doConcurrentTest(b, ct)
4396 }
4397 }
4398
4399 func BenchmarkConcurrentTxExec(b *testing.B) {
4400 b.ReportAllocs()
4401 ct := new(concurrentTxExecTest)
4402 for i := 0; i < b.N; i++ {
4403 doConcurrentTest(b, ct)
4404 }
4405 }
4406
4407 func BenchmarkConcurrentTxStmtQuery(b *testing.B) {
4408 b.ReportAllocs()
4409 ct := new(concurrentTxStmtQueryTest)
4410 for i := 0; i < b.N; i++ {
4411 doConcurrentTest(b, ct)
4412 }
4413 }
4414
4415 func BenchmarkConcurrentTxStmtExec(b *testing.B) {
4416 b.ReportAllocs()
4417 ct := new(concurrentTxStmtExecTest)
4418 for i := 0; i < b.N; i++ {
4419 doConcurrentTest(b, ct)
4420 }
4421 }
4422
4423 func BenchmarkConcurrentRandom(b *testing.B) {
4424 b.ReportAllocs()
4425 ct := new(concurrentRandomTest)
4426 for i := 0; i < b.N; i++ {
4427 doConcurrentTest(b, ct)
4428 }
4429 }
4430
4431 func BenchmarkManyConcurrentQueries(b *testing.B) {
4432 b.ReportAllocs()
4433
4434 const parallelism = 16
4435
4436 db := newTestDB(b, "magicquery")
4437 defer closeDB(b, db)
4438 db.SetMaxIdleConns(runtime.GOMAXPROCS(0) * parallelism)
4439
4440 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
4441 if err != nil {
4442 b.Fatal(err)
4443 }
4444 defer stmt.Close()
4445
4446 b.SetParallelism(parallelism)
4447 b.RunParallel(func(pb *testing.PB) {
4448 for pb.Next() {
4449 rows, err := stmt.Query("sleep", 1)
4450 if err != nil {
4451 b.Error(err)
4452 return
4453 }
4454 rows.Close()
4455 }
4456 })
4457 }
4458
View as plain text