github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/src/database/sql/sql_test.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 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 "testing" 18 "time" 19 ) 20 21 func init() { 22 type dbConn struct { 23 db *DB 24 c *driverConn 25 } 26 freedFrom := make(map[dbConn]string) 27 putConnHook = func(db *DB, c *driverConn) { 28 idx := -1 29 for i, v := range db.freeConn { 30 if v == c { 31 idx = i 32 break 33 } 34 } 35 if idx >= 0 { 36 // print before panic, as panic may get lost due to conflicting panic 37 // (all goroutines asleep) elsewhere, since we might not unlock 38 // the mutex in freeConn here. 39 println("double free of conn. conflicts are:\nA) " + freedFrom[dbConn{db, c}] + "\n\nand\nB) " + stack()) 40 panic("double free of conn.") 41 } 42 freedFrom[dbConn{db, c}] = stack() 43 } 44 } 45 46 const fakeDBName = "foo" 47 48 var chrisBirthday = time.Unix(123456789, 0) 49 50 func newTestDB(t testing.TB, name string) *DB { 51 db, err := Open("test", fakeDBName) 52 if err != nil { 53 t.Fatalf("Open: %v", err) 54 } 55 if _, err := db.Exec("WIPE"); err != nil { 56 t.Fatalf("exec wipe: %v", err) 57 } 58 if name == "people" { 59 exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime") 60 exec(t, db, "INSERT|people|name=Alice,age=?,photo=APHOTO", 1) 61 exec(t, db, "INSERT|people|name=Bob,age=?,photo=BPHOTO", 2) 62 exec(t, db, "INSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday) 63 } 64 if name == "magicquery" { 65 // Magic table name and column, known by fakedb_test.go. 66 exec(t, db, "CREATE|magicquery|op=string,millis=int32") 67 exec(t, db, "INSERT|magicquery|op=sleep,millis=10") 68 } 69 return db 70 } 71 72 func TestDriverPanic(t *testing.T) { 73 // Test that if driver panics, database/sql does not deadlock. 74 db, err := Open("test", fakeDBName) 75 if err != nil { 76 t.Fatalf("Open: %v", err) 77 } 78 expectPanic := func(name string, f func()) { 79 defer func() { 80 err := recover() 81 if err == nil { 82 t.Fatalf("%s did not panic", name) 83 } 84 }() 85 f() 86 } 87 88 expectPanic("Exec Exec", func() { db.Exec("PANIC|Exec|WIPE") }) 89 exec(t, db, "WIPE") // check not deadlocked 90 expectPanic("Exec NumInput", func() { db.Exec("PANIC|NumInput|WIPE") }) 91 exec(t, db, "WIPE") // check not deadlocked 92 expectPanic("Exec Close", func() { db.Exec("PANIC|Close|WIPE") }) 93 exec(t, db, "WIPE") // check not deadlocked 94 exec(t, db, "PANIC|Query|WIPE") // should run successfully: Exec does not call Query 95 exec(t, db, "WIPE") // check not deadlocked 96 97 exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime") 98 99 expectPanic("Query Query", func() { db.Query("PANIC|Query|SELECT|people|age,name|") }) 100 expectPanic("Query NumInput", func() { db.Query("PANIC|NumInput|SELECT|people|age,name|") }) 101 expectPanic("Query Close", func() { 102 rows, err := db.Query("PANIC|Close|SELECT|people|age,name|") 103 if err != nil { 104 t.Fatal(err) 105 } 106 rows.Close() 107 }) 108 db.Query("PANIC|Exec|SELECT|people|age,name|") // should run successfully: Query does not call Exec 109 exec(t, db, "WIPE") // check not deadlocked 110 } 111 112 func exec(t testing.TB, db *DB, query string, args ...interface{}) { 113 _, err := db.Exec(query, args...) 114 if err != nil { 115 t.Fatalf("Exec of %q: %v", query, err) 116 } 117 } 118 119 func closeDB(t testing.TB, db *DB) { 120 if e := recover(); e != nil { 121 fmt.Printf("Panic: %v\n", e) 122 panic(e) 123 } 124 defer setHookpostCloseConn(nil) 125 setHookpostCloseConn(func(_ *fakeConn, err error) { 126 if err != nil { 127 t.Errorf("Error closing fakeConn: %v", err) 128 } 129 }) 130 for i, dc := range db.freeConn { 131 if n := len(dc.openStmt); n > 0 { 132 // Just a sanity check. This is legal in 133 // general, but if we make the tests clean up 134 // their statements first, then we can safely 135 // verify this is always zero here, and any 136 // other value is a leak. 137 t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, len(db.freeConn), n) 138 } 139 } 140 err := db.Close() 141 if err != nil { 142 t.Fatalf("error closing DB: %v", err) 143 } 144 db.mu.Lock() 145 count := db.numOpen 146 db.mu.Unlock() 147 if count != 0 { 148 t.Fatalf("%d connections still open after closing DB", count) 149 } 150 } 151 152 // numPrepares assumes that db has exactly 1 idle conn and returns 153 // its count of calls to Prepare 154 func numPrepares(t *testing.T, db *DB) int { 155 if n := len(db.freeConn); n != 1 { 156 t.Fatalf("free conns = %d; want 1", n) 157 } 158 return db.freeConn[0].ci.(*fakeConn).numPrepare 159 } 160 161 func (db *DB) numDeps() int { 162 db.mu.Lock() 163 defer db.mu.Unlock() 164 return len(db.dep) 165 } 166 167 // Dependencies are closed via a goroutine, so this polls waiting for 168 // numDeps to fall to want, waiting up to d. 169 func (db *DB) numDepsPollUntil(want int, d time.Duration) int { 170 deadline := time.Now().Add(d) 171 for { 172 n := db.numDeps() 173 if n <= want || time.Now().After(deadline) { 174 return n 175 } 176 time.Sleep(50 * time.Millisecond) 177 } 178 } 179 180 func (db *DB) numFreeConns() int { 181 db.mu.Lock() 182 defer db.mu.Unlock() 183 return len(db.freeConn) 184 } 185 186 // clearAllConns closes all connections in db. 187 func (db *DB) clearAllConns(t *testing.T) { 188 db.SetMaxIdleConns(0) 189 190 if g, w := db.numFreeConns(), 0; g != w { 191 t.Errorf("free conns = %d; want %d", g, w) 192 } 193 194 if n := db.numDepsPollUntil(0, time.Second); n > 0 { 195 t.Errorf("number of dependencies = %d; expected 0", n) 196 db.dumpDeps(t) 197 } 198 } 199 200 func (db *DB) dumpDeps(t *testing.T) { 201 for fc := range db.dep { 202 db.dumpDep(t, 0, fc, map[finalCloser]bool{}) 203 } 204 } 205 206 func (db *DB) dumpDep(t *testing.T, depth int, dep finalCloser, seen map[finalCloser]bool) { 207 seen[dep] = true 208 indent := strings.Repeat(" ", depth) 209 ds := db.dep[dep] 210 for k := range ds { 211 t.Logf("%s%T (%p) waiting for -> %T (%p)", indent, dep, dep, k, k) 212 if fc, ok := k.(finalCloser); ok { 213 if !seen[fc] { 214 db.dumpDep(t, depth+1, fc, seen) 215 } 216 } 217 } 218 } 219 220 func TestQuery(t *testing.T) { 221 db := newTestDB(t, "people") 222 defer closeDB(t, db) 223 prepares0 := numPrepares(t, db) 224 rows, err := db.Query("SELECT|people|age,name|") 225 if err != nil { 226 t.Fatalf("Query: %v", err) 227 } 228 type row struct { 229 age int 230 name string 231 } 232 got := []row{} 233 for rows.Next() { 234 var r row 235 err = rows.Scan(&r.age, &r.name) 236 if err != nil { 237 t.Fatalf("Scan: %v", err) 238 } 239 got = append(got, r) 240 } 241 err = rows.Err() 242 if err != nil { 243 t.Fatalf("Err: %v", err) 244 } 245 want := []row{ 246 {age: 1, name: "Alice"}, 247 {age: 2, name: "Bob"}, 248 {age: 3, name: "Chris"}, 249 } 250 if !reflect.DeepEqual(got, want) { 251 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want) 252 } 253 254 // And verify that the final rows.Next() call, which hit EOF, 255 // also closed the rows connection. 256 if n := db.numFreeConns(); n != 1 { 257 t.Fatalf("free conns after query hitting EOF = %d; want 1", n) 258 } 259 if prepares := numPrepares(t, db) - prepares0; prepares != 1 { 260 t.Errorf("executed %d Prepare statements; want 1", prepares) 261 } 262 } 263 264 func TestQueryContext(t *testing.T) { 265 db := newTestDB(t, "people") 266 defer closeDB(t, db) 267 prepares0 := numPrepares(t, db) 268 269 ctx, cancel := context.WithCancel(context.Background()) 270 defer cancel() 271 272 rows, err := db.QueryContext(ctx, "SELECT|people|age,name|") 273 if err != nil { 274 t.Fatalf("Query: %v", err) 275 } 276 type row struct { 277 age int 278 name string 279 } 280 got := []row{} 281 index := 0 282 for rows.Next() { 283 if index == 2 { 284 cancel() 285 time.Sleep(10 * time.Millisecond) 286 } 287 var r row 288 err = rows.Scan(&r.age, &r.name) 289 if err != nil { 290 if index == 2 { 291 break 292 } 293 t.Fatalf("Scan: %v", err) 294 } 295 if index == 2 && err == nil { 296 t.Fatal("expected an error on last scan") 297 } 298 got = append(got, r) 299 index++ 300 } 301 err = rows.Err() 302 if err != nil { 303 t.Fatalf("Err: %v", err) 304 } 305 want := []row{ 306 {age: 1, name: "Alice"}, 307 {age: 2, name: "Bob"}, 308 } 309 if !reflect.DeepEqual(got, want) { 310 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want) 311 } 312 313 // And verify that the final rows.Next() call, which hit EOF, 314 // also closed the rows connection. 315 if n := db.numFreeConns(); n != 1 { 316 t.Fatalf("free conns after query hitting EOF = %d; want 1", n) 317 } 318 if prepares := numPrepares(t, db) - prepares0; prepares != 1 { 319 t.Errorf("executed %d Prepare statements; want 1", prepares) 320 } 321 } 322 323 func TestMultiResultSetQuery(t *testing.T) { 324 db := newTestDB(t, "people") 325 defer closeDB(t, db) 326 prepares0 := numPrepares(t, db) 327 rows, err := db.Query("SELECT|people|age,name|;SELECT|people|name|") 328 if err != nil { 329 t.Fatalf("Query: %v", err) 330 } 331 type row1 struct { 332 age int 333 name string 334 } 335 type row2 struct { 336 name string 337 } 338 got1 := []row1{} 339 for rows.Next() { 340 var r row1 341 err = rows.Scan(&r.age, &r.name) 342 if err != nil { 343 t.Fatalf("Scan: %v", err) 344 } 345 got1 = append(got1, r) 346 } 347 err = rows.Err() 348 if err != nil { 349 t.Fatalf("Err: %v", err) 350 } 351 want1 := []row1{ 352 {age: 1, name: "Alice"}, 353 {age: 2, name: "Bob"}, 354 {age: 3, name: "Chris"}, 355 } 356 if !reflect.DeepEqual(got1, want1) { 357 t.Errorf("mismatch.\n got1: %#v\nwant: %#v", got1, want1) 358 } 359 360 if !rows.NextResultSet() { 361 t.Errorf("expected another result set") 362 } 363 364 got2 := []row2{} 365 for rows.Next() { 366 var r row2 367 err = rows.Scan(&r.name) 368 if err != nil { 369 t.Fatalf("Scan: %v", err) 370 } 371 got2 = append(got2, r) 372 } 373 err = rows.Err() 374 if err != nil { 375 t.Fatalf("Err: %v", err) 376 } 377 want2 := []row2{ 378 {name: "Alice"}, 379 {name: "Bob"}, 380 {name: "Chris"}, 381 } 382 if !reflect.DeepEqual(got2, want2) { 383 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got2, want2) 384 } 385 if rows.NextResultSet() { 386 t.Errorf("expected no more result sets") 387 } 388 389 // And verify that the final rows.Next() call, which hit EOF, 390 // also closed the rows connection. 391 if n := db.numFreeConns(); n != 1 { 392 t.Fatalf("free conns after query hitting EOF = %d; want 1", n) 393 } 394 if prepares := numPrepares(t, db) - prepares0; prepares != 1 { 395 t.Errorf("executed %d Prepare statements; want 1", prepares) 396 } 397 } 398 399 func TestQueryNamedParam(t *testing.T) { 400 db := newTestDB(t, "people") 401 defer closeDB(t, db) 402 prepares0 := numPrepares(t, db) 403 rows, err := db.Query( 404 // Ensure the name and age parameters only match on placeholder name, not position. 405 "SELECT|people|age,name|name=?name,age=?age", 406 Param("?age", 2), 407 Param("?name", "Bob"), 408 ) 409 if err != nil { 410 t.Fatalf("Query: %v", err) 411 } 412 type row struct { 413 age int 414 name string 415 } 416 got := []row{} 417 for rows.Next() { 418 var r row 419 err = rows.Scan(&r.age, &r.name) 420 if err != nil { 421 t.Fatalf("Scan: %v", err) 422 } 423 got = append(got, r) 424 } 425 err = rows.Err() 426 if err != nil { 427 t.Fatalf("Err: %v", err) 428 } 429 want := []row{ 430 {age: 2, name: "Bob"}, 431 } 432 if !reflect.DeepEqual(got, want) { 433 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want) 434 } 435 436 // And verify that the final rows.Next() call, which hit EOF, 437 // also closed the rows connection. 438 if n := db.numFreeConns(); n != 1 { 439 t.Fatalf("free conns after query hitting EOF = %d; want 1", n) 440 } 441 if prepares := numPrepares(t, db) - prepares0; prepares != 1 { 442 t.Errorf("executed %d Prepare statements; want 1", prepares) 443 } 444 } 445 446 func TestByteOwnership(t *testing.T) { 447 db := newTestDB(t, "people") 448 defer closeDB(t, db) 449 rows, err := db.Query("SELECT|people|name,photo|") 450 if err != nil { 451 t.Fatalf("Query: %v", err) 452 } 453 type row struct { 454 name []byte 455 photo RawBytes 456 } 457 got := []row{} 458 for rows.Next() { 459 var r row 460 err = rows.Scan(&r.name, &r.photo) 461 if err != nil { 462 t.Fatalf("Scan: %v", err) 463 } 464 got = append(got, r) 465 } 466 corruptMemory := []byte("\xffPHOTO") 467 want := []row{ 468 {name: []byte("Alice"), photo: corruptMemory}, 469 {name: []byte("Bob"), photo: corruptMemory}, 470 {name: []byte("Chris"), photo: corruptMemory}, 471 } 472 if !reflect.DeepEqual(got, want) { 473 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want) 474 } 475 476 var photo RawBytes 477 err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo) 478 if err == nil { 479 t.Error("want error scanning into RawBytes from QueryRow") 480 } 481 } 482 483 func TestRowsColumns(t *testing.T) { 484 db := newTestDB(t, "people") 485 defer closeDB(t, db) 486 rows, err := db.Query("SELECT|people|age,name|") 487 if err != nil { 488 t.Fatalf("Query: %v", err) 489 } 490 cols, err := rows.Columns() 491 if err != nil { 492 t.Fatalf("Columns: %v", err) 493 } 494 want := []string{"age", "name"} 495 if !reflect.DeepEqual(cols, want) { 496 t.Errorf("got %#v; want %#v", cols, want) 497 } 498 if err := rows.Close(); err != nil { 499 t.Errorf("error closing rows: %s", err) 500 } 501 } 502 503 func TestRowsColumnTypes(t *testing.T) { 504 db := newTestDB(t, "people") 505 defer closeDB(t, db) 506 rows, err := db.Query("SELECT|people|age,name|") 507 if err != nil { 508 t.Fatalf("Query: %v", err) 509 } 510 tt, err := rows.ColumnTypes() 511 if err != nil { 512 t.Fatalf("ColumnTypes: %v", err) 513 } 514 515 types := make([]reflect.Type, len(tt)) 516 for i, tp := range tt { 517 st := tp.ScanType() 518 if st == nil { 519 t.Errorf("scantype is null for column %q", tp.Name()) 520 continue 521 } 522 types[i] = st 523 } 524 values := make([]interface{}, len(tt)) 525 for i := range values { 526 values[i] = reflect.New(types[i]).Interface() 527 } 528 ct := 0 529 for rows.Next() { 530 err = rows.Scan(values...) 531 if err != nil { 532 t.Fatalf("failed to scan values in %v", err) 533 } 534 ct++ 535 if ct == 0 { 536 if values[0].(string) != "Bob" { 537 t.Errorf("Expected Bob, got %v", values[0]) 538 } 539 if values[1].(int) != 2 { 540 t.Errorf("Expected 2, got %v", values[1]) 541 } 542 } 543 } 544 if ct != 3 { 545 t.Errorf("expected 3 rows, got %d", ct) 546 } 547 548 if err := rows.Close(); err != nil { 549 t.Errorf("error closing rows: %s", err) 550 } 551 } 552 553 func TestQueryRow(t *testing.T) { 554 db := newTestDB(t, "people") 555 defer closeDB(t, db) 556 var name string 557 var age int 558 var birthday time.Time 559 560 err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age) 561 if err == nil || !strings.Contains(err.Error(), "expected 2 destination arguments") { 562 t.Errorf("expected error from wrong number of arguments; actually got: %v", err) 563 } 564 565 err = db.QueryRow("SELECT|people|bdate|age=?", 3).Scan(&birthday) 566 if err != nil || !birthday.Equal(chrisBirthday) { 567 t.Errorf("chris birthday = %v, err = %v; want %v", birthday, err, chrisBirthday) 568 } 569 570 err = db.QueryRow("SELECT|people|age,name|age=?", 2).Scan(&age, &name) 571 if err != nil { 572 t.Fatalf("age QueryRow+Scan: %v", err) 573 } 574 if name != "Bob" { 575 t.Errorf("expected name Bob, got %q", name) 576 } 577 if age != 2 { 578 t.Errorf("expected age 2, got %d", age) 579 } 580 581 err = db.QueryRow("SELECT|people|age,name|name=?", "Alice").Scan(&age, &name) 582 if err != nil { 583 t.Fatalf("name QueryRow+Scan: %v", err) 584 } 585 if name != "Alice" { 586 t.Errorf("expected name Alice, got %q", name) 587 } 588 if age != 1 { 589 t.Errorf("expected age 1, got %d", age) 590 } 591 592 var photo []byte 593 err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo) 594 if err != nil { 595 t.Fatalf("photo QueryRow+Scan: %v", err) 596 } 597 want := []byte("APHOTO") 598 if !reflect.DeepEqual(photo, want) { 599 t.Errorf("photo = %q; want %q", photo, want) 600 } 601 } 602 603 func TestStatementErrorAfterClose(t *testing.T) { 604 db := newTestDB(t, "people") 605 defer closeDB(t, db) 606 stmt, err := db.Prepare("SELECT|people|age|name=?") 607 if err != nil { 608 t.Fatalf("Prepare: %v", err) 609 } 610 err = stmt.Close() 611 if err != nil { 612 t.Fatalf("Close: %v", err) 613 } 614 var name string 615 err = stmt.QueryRow("foo").Scan(&name) 616 if err == nil { 617 t.Errorf("expected error from QueryRow.Scan after Stmt.Close") 618 } 619 } 620 621 func TestStatementQueryRow(t *testing.T) { 622 db := newTestDB(t, "people") 623 defer closeDB(t, db) 624 stmt, err := db.Prepare("SELECT|people|age|name=?") 625 if err != nil { 626 t.Fatalf("Prepare: %v", err) 627 } 628 defer stmt.Close() 629 var age int 630 for n, tt := range []struct { 631 name string 632 want int 633 }{ 634 {"Alice", 1}, 635 {"Bob", 2}, 636 {"Chris", 3}, 637 } { 638 if err := stmt.QueryRow(tt.name).Scan(&age); err != nil { 639 t.Errorf("%d: on %q, QueryRow/Scan: %v", n, tt.name, err) 640 } else if age != tt.want { 641 t.Errorf("%d: age=%d, want %d", n, age, tt.want) 642 } 643 } 644 } 645 646 type stubDriverStmt struct { 647 err error 648 } 649 650 func (s stubDriverStmt) Close() error { 651 return s.err 652 } 653 654 func (s stubDriverStmt) NumInput() int { 655 return -1 656 } 657 658 func (s stubDriverStmt) Exec(args []driver.Value) (driver.Result, error) { 659 return nil, nil 660 } 661 662 func (s stubDriverStmt) Query(args []driver.Value) (driver.Rows, error) { 663 return nil, nil 664 } 665 666 // golang.org/issue/12798 667 func TestStatementClose(t *testing.T) { 668 want := errors.New("STMT ERROR") 669 670 tests := []struct { 671 stmt *Stmt 672 msg string 673 }{ 674 {&Stmt{stickyErr: want}, "stickyErr not propagated"}, 675 {&Stmt{tx: &Tx{}, txsi: &driverStmt{&sync.Mutex{}, stubDriverStmt{want}}}, "driverStmt.Close() error not propagated"}, 676 } 677 for _, test := range tests { 678 if err := test.stmt.Close(); err != want { 679 t.Errorf("%s. Got stmt.Close() = %v, want = %v", test.msg, err, want) 680 } 681 } 682 } 683 684 // golang.org/issue/3734 685 func TestStatementQueryRowConcurrent(t *testing.T) { 686 db := newTestDB(t, "people") 687 defer closeDB(t, db) 688 stmt, err := db.Prepare("SELECT|people|age|name=?") 689 if err != nil { 690 t.Fatalf("Prepare: %v", err) 691 } 692 defer stmt.Close() 693 694 const n = 10 695 ch := make(chan error, n) 696 for i := 0; i < n; i++ { 697 go func() { 698 var age int 699 err := stmt.QueryRow("Alice").Scan(&age) 700 if err == nil && age != 1 { 701 err = fmt.Errorf("unexpected age %d", age) 702 } 703 ch <- err 704 }() 705 } 706 for i := 0; i < n; i++ { 707 if err := <-ch; err != nil { 708 t.Error(err) 709 } 710 } 711 } 712 713 // just a test of fakedb itself 714 func TestBogusPreboundParameters(t *testing.T) { 715 db := newTestDB(t, "foo") 716 defer closeDB(t, db) 717 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 718 _, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion") 719 if err == nil { 720 t.Fatalf("expected error") 721 } 722 if err.Error() != `fakedb: invalid conversion to int32 from "bogusconversion"` { 723 t.Errorf("unexpected error: %v", err) 724 } 725 } 726 727 func TestExec(t *testing.T) { 728 db := newTestDB(t, "foo") 729 defer closeDB(t, db) 730 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 731 stmt, err := db.Prepare("INSERT|t1|name=?,age=?") 732 if err != nil { 733 t.Errorf("Stmt, err = %v, %v", stmt, err) 734 } 735 defer stmt.Close() 736 737 type execTest struct { 738 args []interface{} 739 wantErr string 740 } 741 execTests := []execTest{ 742 // Okay: 743 {[]interface{}{"Brad", 31}, ""}, 744 {[]interface{}{"Brad", int64(31)}, ""}, 745 {[]interface{}{"Bob", "32"}, ""}, 746 {[]interface{}{7, 9}, ""}, 747 748 // Invalid conversions: 749 {[]interface{}{"Brad", int64(0xFFFFFFFF)}, "sql: converting argument $2 type: sql/driver: value 4294967295 overflows int32"}, 750 {[]interface{}{"Brad", "strconv fail"}, `sql: converting argument $2 type: sql/driver: value "strconv fail" can't be converted to int32`}, 751 752 // Wrong number of args: 753 {[]interface{}{}, "sql: expected 2 arguments, got 0"}, 754 {[]interface{}{1, 2, 3}, "sql: expected 2 arguments, got 3"}, 755 } 756 for n, et := range execTests { 757 _, err := stmt.Exec(et.args...) 758 errStr := "" 759 if err != nil { 760 errStr = err.Error() 761 } 762 if errStr != et.wantErr { 763 t.Errorf("stmt.Execute #%d: for %v, got error %q, want error %q", 764 n, et.args, errStr, et.wantErr) 765 } 766 } 767 } 768 769 func TestTxPrepare(t *testing.T) { 770 db := newTestDB(t, "") 771 defer closeDB(t, db) 772 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 773 tx, err := db.Begin() 774 if err != nil { 775 t.Fatalf("Begin = %v", err) 776 } 777 stmt, err := tx.Prepare("INSERT|t1|name=?,age=?") 778 if err != nil { 779 t.Fatalf("Stmt, err = %v, %v", stmt, err) 780 } 781 defer stmt.Close() 782 _, err = stmt.Exec("Bobby", 7) 783 if err != nil { 784 t.Fatalf("Exec = %v", err) 785 } 786 err = tx.Commit() 787 if err != nil { 788 t.Fatalf("Commit = %v", err) 789 } 790 // Commit() should have closed the statement 791 if !stmt.closed { 792 t.Fatal("Stmt not closed after Commit") 793 } 794 } 795 796 func TestTxStmt(t *testing.T) { 797 db := newTestDB(t, "") 798 defer closeDB(t, db) 799 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 800 stmt, err := db.Prepare("INSERT|t1|name=?,age=?") 801 if err != nil { 802 t.Fatalf("Stmt, err = %v, %v", stmt, err) 803 } 804 defer stmt.Close() 805 tx, err := db.Begin() 806 if err != nil { 807 t.Fatalf("Begin = %v", err) 808 } 809 txs := tx.Stmt(stmt) 810 defer txs.Close() 811 _, err = txs.Exec("Bobby", 7) 812 if err != nil { 813 t.Fatalf("Exec = %v", err) 814 } 815 err = tx.Commit() 816 if err != nil { 817 t.Fatalf("Commit = %v", err) 818 } 819 // Commit() should have closed the statement 820 if !txs.closed { 821 t.Fatal("Stmt not closed after Commit") 822 } 823 } 824 825 // Issue: https://golang.org/issue/2784 826 // This test didn't fail before because we got lucky with the fakedb driver. 827 // It was failing, and now not, in github.com/bradfitz/go-sql-test 828 func TestTxQuery(t *testing.T) { 829 db := newTestDB(t, "") 830 defer closeDB(t, db) 831 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 832 exec(t, db, "INSERT|t1|name=Alice") 833 834 tx, err := db.Begin() 835 if err != nil { 836 t.Fatal(err) 837 } 838 defer tx.Rollback() 839 840 r, err := tx.Query("SELECT|t1|name|") 841 if err != nil { 842 t.Fatal(err) 843 } 844 defer r.Close() 845 846 if !r.Next() { 847 if r.Err() != nil { 848 t.Fatal(r.Err()) 849 } 850 t.Fatal("expected one row") 851 } 852 853 var x string 854 err = r.Scan(&x) 855 if err != nil { 856 t.Fatal(err) 857 } 858 } 859 860 func TestTxQueryInvalid(t *testing.T) { 861 db := newTestDB(t, "") 862 defer closeDB(t, db) 863 864 tx, err := db.Begin() 865 if err != nil { 866 t.Fatal(err) 867 } 868 defer tx.Rollback() 869 870 _, err = tx.Query("SELECT|t1|name|") 871 if err == nil { 872 t.Fatal("Error expected") 873 } 874 } 875 876 // Tests fix for issue 4433, that retries in Begin happen when 877 // conn.Begin() returns ErrBadConn 878 func TestTxErrBadConn(t *testing.T) { 879 db, err := Open("test", fakeDBName+";badConn") 880 if err != nil { 881 t.Fatalf("Open: %v", err) 882 } 883 if _, err := db.Exec("WIPE"); err != nil { 884 t.Fatalf("exec wipe: %v", err) 885 } 886 defer closeDB(t, db) 887 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 888 stmt, err := db.Prepare("INSERT|t1|name=?,age=?") 889 if err != nil { 890 t.Fatalf("Stmt, err = %v, %v", stmt, err) 891 } 892 defer stmt.Close() 893 tx, err := db.Begin() 894 if err != nil { 895 t.Fatalf("Begin = %v", err) 896 } 897 txs := tx.Stmt(stmt) 898 defer txs.Close() 899 _, err = txs.Exec("Bobby", 7) 900 if err != nil { 901 t.Fatalf("Exec = %v", err) 902 } 903 err = tx.Commit() 904 if err != nil { 905 t.Fatalf("Commit = %v", err) 906 } 907 } 908 909 // Tests fix for issue 2542, that we release a lock when querying on 910 // a closed connection. 911 func TestIssue2542Deadlock(t *testing.T) { 912 db := newTestDB(t, "people") 913 closeDB(t, db) 914 for i := 0; i < 2; i++ { 915 _, err := db.Query("SELECT|people|age,name|") 916 if err == nil { 917 t.Fatalf("expected error") 918 } 919 } 920 } 921 922 // From golang.org/issue/3865 923 func TestCloseStmtBeforeRows(t *testing.T) { 924 db := newTestDB(t, "people") 925 defer closeDB(t, db) 926 927 s, err := db.Prepare("SELECT|people|name|") 928 if err != nil { 929 t.Fatal(err) 930 } 931 932 r, err := s.Query() 933 if err != nil { 934 s.Close() 935 t.Fatal(err) 936 } 937 938 err = s.Close() 939 if err != nil { 940 t.Fatal(err) 941 } 942 943 r.Close() 944 } 945 946 // Tests fix for issue 2788, that we bind nil to a []byte if the 947 // value in the column is sql null 948 func TestNullByteSlice(t *testing.T) { 949 db := newTestDB(t, "") 950 defer closeDB(t, db) 951 exec(t, db, "CREATE|t|id=int32,name=nullstring") 952 exec(t, db, "INSERT|t|id=10,name=?", nil) 953 954 var name []byte 955 956 err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name) 957 if err != nil { 958 t.Fatal(err) 959 } 960 if name != nil { 961 t.Fatalf("name []byte should be nil for null column value, got: %#v", name) 962 } 963 964 exec(t, db, "INSERT|t|id=11,name=?", "bob") 965 err = db.QueryRow("SELECT|t|name|id=?", 11).Scan(&name) 966 if err != nil { 967 t.Fatal(err) 968 } 969 if string(name) != "bob" { 970 t.Fatalf("name []byte should be bob, got: %q", string(name)) 971 } 972 } 973 974 func TestPointerParamsAndScans(t *testing.T) { 975 db := newTestDB(t, "") 976 defer closeDB(t, db) 977 exec(t, db, "CREATE|t|id=int32,name=nullstring") 978 979 bob := "bob" 980 var name *string 981 982 name = &bob 983 exec(t, db, "INSERT|t|id=10,name=?", name) 984 name = nil 985 exec(t, db, "INSERT|t|id=20,name=?", name) 986 987 err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name) 988 if err != nil { 989 t.Fatalf("querying id 10: %v", err) 990 } 991 if name == nil { 992 t.Errorf("id 10's name = nil; want bob") 993 } else if *name != "bob" { 994 t.Errorf("id 10's name = %q; want bob", *name) 995 } 996 997 err = db.QueryRow("SELECT|t|name|id=?", 20).Scan(&name) 998 if err != nil { 999 t.Fatalf("querying id 20: %v", err) 1000 } 1001 if name != nil { 1002 t.Errorf("id 20 = %q; want nil", *name) 1003 } 1004 } 1005 1006 func TestQueryRowClosingStmt(t *testing.T) { 1007 db := newTestDB(t, "people") 1008 defer closeDB(t, db) 1009 var name string 1010 var age int 1011 err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age, &name) 1012 if err != nil { 1013 t.Fatal(err) 1014 } 1015 if len(db.freeConn) != 1 { 1016 t.Fatalf("expected 1 free conn") 1017 } 1018 fakeConn := db.freeConn[0].ci.(*fakeConn) 1019 if made, closed := fakeConn.stmtsMade, fakeConn.stmtsClosed; made != closed { 1020 t.Errorf("statement close mismatch: made %d, closed %d", made, closed) 1021 } 1022 } 1023 1024 // Test issue 6651 1025 func TestIssue6651(t *testing.T) { 1026 db := newTestDB(t, "people") 1027 defer closeDB(t, db) 1028 1029 var v string 1030 1031 want := "error in rows.Next" 1032 rowsCursorNextHook = func(dest []driver.Value) error { 1033 return fmt.Errorf(want) 1034 } 1035 defer func() { rowsCursorNextHook = nil }() 1036 err := db.QueryRow("SELECT|people|name|").Scan(&v) 1037 if err == nil || err.Error() != want { 1038 t.Errorf("error = %q; want %q", err, want) 1039 } 1040 rowsCursorNextHook = nil 1041 1042 want = "error in rows.Close" 1043 rowsCloseHook = func(rows *Rows, err *error) { 1044 *err = fmt.Errorf(want) 1045 } 1046 defer func() { rowsCloseHook = nil }() 1047 err = db.QueryRow("SELECT|people|name|").Scan(&v) 1048 if err == nil || err.Error() != want { 1049 t.Errorf("error = %q; want %q", err, want) 1050 } 1051 } 1052 1053 type nullTestRow struct { 1054 nullParam interface{} 1055 notNullParam interface{} 1056 scanNullVal interface{} 1057 } 1058 1059 type nullTestSpec struct { 1060 nullType string 1061 notNullType string 1062 rows [6]nullTestRow 1063 } 1064 1065 func TestNullStringParam(t *testing.T) { 1066 spec := nullTestSpec{"nullstring", "string", [6]nullTestRow{ 1067 {NullString{"aqua", true}, "", NullString{"aqua", true}}, 1068 {NullString{"brown", false}, "", NullString{"", false}}, 1069 {"chartreuse", "", NullString{"chartreuse", true}}, 1070 {NullString{"darkred", true}, "", NullString{"darkred", true}}, 1071 {NullString{"eel", false}, "", NullString{"", false}}, 1072 {"foo", NullString{"black", false}, nil}, 1073 }} 1074 nullTestRun(t, spec) 1075 } 1076 1077 func TestNullInt64Param(t *testing.T) { 1078 spec := nullTestSpec{"nullint64", "int64", [6]nullTestRow{ 1079 {NullInt64{31, true}, 1, NullInt64{31, true}}, 1080 {NullInt64{-22, false}, 1, NullInt64{0, false}}, 1081 {22, 1, NullInt64{22, true}}, 1082 {NullInt64{33, true}, 1, NullInt64{33, true}}, 1083 {NullInt64{222, false}, 1, NullInt64{0, false}}, 1084 {0, NullInt64{31, false}, nil}, 1085 }} 1086 nullTestRun(t, spec) 1087 } 1088 1089 func TestNullFloat64Param(t *testing.T) { 1090 spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{ 1091 {NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}}, 1092 {NullFloat64{13.1, false}, 1, NullFloat64{0, false}}, 1093 {-22.9, 1, NullFloat64{-22.9, true}}, 1094 {NullFloat64{33.81, true}, 1, NullFloat64{33.81, true}}, 1095 {NullFloat64{222, false}, 1, NullFloat64{0, false}}, 1096 {10, NullFloat64{31.2, false}, nil}, 1097 }} 1098 nullTestRun(t, spec) 1099 } 1100 1101 func TestNullBoolParam(t *testing.T) { 1102 spec := nullTestSpec{"nullbool", "bool", [6]nullTestRow{ 1103 {NullBool{false, true}, true, NullBool{false, true}}, 1104 {NullBool{true, false}, false, NullBool{false, false}}, 1105 {true, true, NullBool{true, true}}, 1106 {NullBool{true, true}, false, NullBool{true, true}}, 1107 {NullBool{true, false}, true, NullBool{false, false}}, 1108 {true, NullBool{true, false}, nil}, 1109 }} 1110 nullTestRun(t, spec) 1111 } 1112 1113 func nullTestRun(t *testing.T, spec nullTestSpec) { 1114 db := newTestDB(t, "") 1115 defer closeDB(t, db) 1116 exec(t, db, fmt.Sprintf("CREATE|t|id=int32,name=string,nullf=%s,notnullf=%s", spec.nullType, spec.notNullType)) 1117 1118 // Inserts with db.Exec: 1119 exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 1, "alice", spec.rows[0].nullParam, spec.rows[0].notNullParam) 1120 exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 2, "bob", spec.rows[1].nullParam, spec.rows[1].notNullParam) 1121 1122 // Inserts with a prepared statement: 1123 stmt, err := db.Prepare("INSERT|t|id=?,name=?,nullf=?,notnullf=?") 1124 if err != nil { 1125 t.Fatalf("prepare: %v", err) 1126 } 1127 defer stmt.Close() 1128 if _, err := stmt.Exec(3, "chris", spec.rows[2].nullParam, spec.rows[2].notNullParam); err != nil { 1129 t.Errorf("exec insert chris: %v", err) 1130 } 1131 if _, err := stmt.Exec(4, "dave", spec.rows[3].nullParam, spec.rows[3].notNullParam); err != nil { 1132 t.Errorf("exec insert dave: %v", err) 1133 } 1134 if _, err := stmt.Exec(5, "eleanor", spec.rows[4].nullParam, spec.rows[4].notNullParam); err != nil { 1135 t.Errorf("exec insert eleanor: %v", err) 1136 } 1137 1138 // Can't put null val into non-null col 1139 if _, err := stmt.Exec(6, "bob", spec.rows[5].nullParam, spec.rows[5].notNullParam); err == nil { 1140 t.Errorf("expected error inserting nil val with prepared statement Exec") 1141 } 1142 1143 _, err = db.Exec("INSERT|t|id=?,name=?,nullf=?", 999, nil, nil) 1144 if err == nil { 1145 // TODO: this test fails, but it's just because 1146 // fakeConn implements the optional Execer interface, 1147 // so arguably this is the correct behavior. But 1148 // maybe I should flesh out the fakeConn.Exec 1149 // implementation so this properly fails. 1150 // t.Errorf("expected error inserting nil name with Exec") 1151 } 1152 1153 paramtype := reflect.TypeOf(spec.rows[0].nullParam) 1154 bindVal := reflect.New(paramtype).Interface() 1155 1156 for i := 0; i < 5; i++ { 1157 id := i + 1 1158 if err := db.QueryRow("SELECT|t|nullf|id=?", id).Scan(bindVal); err != nil { 1159 t.Errorf("id=%d Scan: %v", id, err) 1160 } 1161 bindValDeref := reflect.ValueOf(bindVal).Elem().Interface() 1162 if !reflect.DeepEqual(bindValDeref, spec.rows[i].scanNullVal) { 1163 t.Errorf("id=%d got %#v, want %#v", id, bindValDeref, spec.rows[i].scanNullVal) 1164 } 1165 } 1166 } 1167 1168 // golang.org/issue/4859 1169 func TestQueryRowNilScanDest(t *testing.T) { 1170 db := newTestDB(t, "people") 1171 defer closeDB(t, db) 1172 var name *string // nil pointer 1173 err := db.QueryRow("SELECT|people|name|").Scan(name) 1174 want := "sql: Scan error on column index 0: destination pointer is nil" 1175 if err == nil || err.Error() != want { 1176 t.Errorf("error = %q; want %q", err.Error(), want) 1177 } 1178 } 1179 1180 func TestIssue4902(t *testing.T) { 1181 db := newTestDB(t, "people") 1182 defer closeDB(t, db) 1183 1184 driver := db.driver.(*fakeDriver) 1185 opens0 := driver.openCount 1186 1187 var stmt *Stmt 1188 var err error 1189 for i := 0; i < 10; i++ { 1190 stmt, err = db.Prepare("SELECT|people|name|") 1191 if err != nil { 1192 t.Fatal(err) 1193 } 1194 err = stmt.Close() 1195 if err != nil { 1196 t.Fatal(err) 1197 } 1198 } 1199 1200 opens := driver.openCount - opens0 1201 if opens > 1 { 1202 t.Errorf("opens = %d; want <= 1", opens) 1203 t.Logf("db = %#v", db) 1204 t.Logf("driver = %#v", driver) 1205 t.Logf("stmt = %#v", stmt) 1206 } 1207 } 1208 1209 // Issue 3857 1210 // This used to deadlock. 1211 func TestSimultaneousQueries(t *testing.T) { 1212 db := newTestDB(t, "people") 1213 defer closeDB(t, db) 1214 1215 tx, err := db.Begin() 1216 if err != nil { 1217 t.Fatal(err) 1218 } 1219 defer tx.Rollback() 1220 1221 r1, err := tx.Query("SELECT|people|name|") 1222 if err != nil { 1223 t.Fatal(err) 1224 } 1225 defer r1.Close() 1226 1227 r2, err := tx.Query("SELECT|people|name|") 1228 if err != nil { 1229 t.Fatal(err) 1230 } 1231 defer r2.Close() 1232 } 1233 1234 func TestMaxIdleConns(t *testing.T) { 1235 db := newTestDB(t, "people") 1236 defer closeDB(t, db) 1237 1238 tx, err := db.Begin() 1239 if err != nil { 1240 t.Fatal(err) 1241 } 1242 tx.Commit() 1243 if got := len(db.freeConn); got != 1 { 1244 t.Errorf("freeConns = %d; want 1", got) 1245 } 1246 1247 db.SetMaxIdleConns(0) 1248 1249 if got := len(db.freeConn); got != 0 { 1250 t.Errorf("freeConns after set to zero = %d; want 0", got) 1251 } 1252 1253 tx, err = db.Begin() 1254 if err != nil { 1255 t.Fatal(err) 1256 } 1257 tx.Commit() 1258 if got := len(db.freeConn); got != 0 { 1259 t.Errorf("freeConns = %d; want 0", got) 1260 } 1261 } 1262 1263 func TestMaxOpenConns(t *testing.T) { 1264 if testing.Short() { 1265 t.Skip("skipping in short mode") 1266 } 1267 defer setHookpostCloseConn(nil) 1268 setHookpostCloseConn(func(_ *fakeConn, err error) { 1269 if err != nil { 1270 t.Errorf("Error closing fakeConn: %v", err) 1271 } 1272 }) 1273 1274 db := newTestDB(t, "magicquery") 1275 defer closeDB(t, db) 1276 1277 driver := db.driver.(*fakeDriver) 1278 1279 // Force the number of open connections to 0 so we can get an accurate 1280 // count for the test 1281 db.clearAllConns(t) 1282 1283 driver.mu.Lock() 1284 opens0 := driver.openCount 1285 closes0 := driver.closeCount 1286 driver.mu.Unlock() 1287 1288 db.SetMaxIdleConns(10) 1289 db.SetMaxOpenConns(10) 1290 1291 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?") 1292 if err != nil { 1293 t.Fatal(err) 1294 } 1295 1296 // Start 50 parallel slow queries. 1297 const ( 1298 nquery = 50 1299 sleepMillis = 25 1300 nbatch = 2 1301 ) 1302 var wg sync.WaitGroup 1303 for batch := 0; batch < nbatch; batch++ { 1304 for i := 0; i < nquery; i++ { 1305 wg.Add(1) 1306 go func() { 1307 defer wg.Done() 1308 var op string 1309 if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows { 1310 t.Error(err) 1311 } 1312 }() 1313 } 1314 // Sleep for twice the expected length of time for the 1315 // batch of 50 queries above to finish before starting 1316 // the next round. 1317 time.Sleep(2 * sleepMillis * time.Millisecond) 1318 } 1319 wg.Wait() 1320 1321 if g, w := db.numFreeConns(), 10; g != w { 1322 t.Errorf("free conns = %d; want %d", g, w) 1323 } 1324 1325 if n := db.numDepsPollUntil(20, time.Second); n > 20 { 1326 t.Errorf("number of dependencies = %d; expected <= 20", n) 1327 db.dumpDeps(t) 1328 } 1329 1330 driver.mu.Lock() 1331 opens := driver.openCount - opens0 1332 closes := driver.closeCount - closes0 1333 driver.mu.Unlock() 1334 1335 if opens > 10 { 1336 t.Logf("open calls = %d", opens) 1337 t.Logf("close calls = %d", closes) 1338 t.Errorf("db connections opened = %d; want <= 10", opens) 1339 db.dumpDeps(t) 1340 } 1341 1342 if err := stmt.Close(); err != nil { 1343 t.Fatal(err) 1344 } 1345 1346 if g, w := db.numFreeConns(), 10; g != w { 1347 t.Errorf("free conns = %d; want %d", g, w) 1348 } 1349 1350 if n := db.numDepsPollUntil(10, time.Second); n > 10 { 1351 t.Errorf("number of dependencies = %d; expected <= 10", n) 1352 db.dumpDeps(t) 1353 } 1354 1355 db.SetMaxOpenConns(5) 1356 1357 if g, w := db.numFreeConns(), 5; g != w { 1358 t.Errorf("free conns = %d; want %d", g, w) 1359 } 1360 1361 if n := db.numDepsPollUntil(5, time.Second); n > 5 { 1362 t.Errorf("number of dependencies = %d; expected 0", n) 1363 db.dumpDeps(t) 1364 } 1365 1366 db.SetMaxOpenConns(0) 1367 1368 if g, w := db.numFreeConns(), 5; g != w { 1369 t.Errorf("free conns = %d; want %d", g, w) 1370 } 1371 1372 if n := db.numDepsPollUntil(5, time.Second); n > 5 { 1373 t.Errorf("number of dependencies = %d; expected 0", n) 1374 db.dumpDeps(t) 1375 } 1376 1377 db.clearAllConns(t) 1378 } 1379 1380 // Issue 9453: tests that SetMaxOpenConns can be lowered at runtime 1381 // and affects the subsequent release of connections. 1382 func TestMaxOpenConnsOnBusy(t *testing.T) { 1383 defer setHookpostCloseConn(nil) 1384 setHookpostCloseConn(func(_ *fakeConn, err error) { 1385 if err != nil { 1386 t.Errorf("Error closing fakeConn: %v", err) 1387 } 1388 }) 1389 1390 db := newTestDB(t, "magicquery") 1391 defer closeDB(t, db) 1392 1393 db.SetMaxOpenConns(3) 1394 1395 ctx := context.Background() 1396 1397 conn0, err := db.conn(ctx, cachedOrNewConn) 1398 if err != nil { 1399 t.Fatalf("db open conn fail: %v", err) 1400 } 1401 1402 conn1, err := db.conn(ctx, cachedOrNewConn) 1403 if err != nil { 1404 t.Fatalf("db open conn fail: %v", err) 1405 } 1406 1407 conn2, err := db.conn(ctx, cachedOrNewConn) 1408 if err != nil { 1409 t.Fatalf("db open conn fail: %v", err) 1410 } 1411 1412 if g, w := db.numOpen, 3; g != w { 1413 t.Errorf("free conns = %d; want %d", g, w) 1414 } 1415 1416 db.SetMaxOpenConns(2) 1417 if g, w := db.numOpen, 3; g != w { 1418 t.Errorf("free conns = %d; want %d", g, w) 1419 } 1420 1421 conn0.releaseConn(nil) 1422 conn1.releaseConn(nil) 1423 if g, w := db.numOpen, 2; g != w { 1424 t.Errorf("free conns = %d; want %d", g, w) 1425 } 1426 1427 conn2.releaseConn(nil) 1428 if g, w := db.numOpen, 2; g != w { 1429 t.Errorf("free conns = %d; want %d", g, w) 1430 } 1431 } 1432 1433 // Issue 10886: tests that all connection attempts return when more than 1434 // DB.maxOpen connections are in flight and the first DB.maxOpen fail. 1435 func TestPendingConnsAfterErr(t *testing.T) { 1436 const ( 1437 maxOpen = 2 1438 tryOpen = maxOpen*2 + 2 1439 ) 1440 1441 db := newTestDB(t, "people") 1442 defer closeDB(t, db) 1443 defer func() { 1444 for k, v := range db.lastPut { 1445 t.Logf("%p: %v", k, v) 1446 } 1447 }() 1448 1449 db.SetMaxOpenConns(maxOpen) 1450 db.SetMaxIdleConns(0) 1451 1452 errOffline := errors.New("db offline") 1453 defer func() { setHookOpenErr(nil) }() 1454 1455 errs := make(chan error, tryOpen) 1456 1457 unblock := make(chan struct{}) 1458 setHookOpenErr(func() error { 1459 <-unblock // block until all connections are in flight 1460 return errOffline 1461 }) 1462 1463 var opening sync.WaitGroup 1464 opening.Add(tryOpen) 1465 for i := 0; i < tryOpen; i++ { 1466 go func() { 1467 opening.Done() // signal one connection is in flight 1468 _, err := db.Exec("INSERT|people|name=Julia,age=19") 1469 errs <- err 1470 }() 1471 } 1472 1473 opening.Wait() // wait for all workers to begin running 1474 time.Sleep(10 * time.Millisecond) // make extra sure all workers are blocked 1475 close(unblock) // let all workers proceed 1476 1477 const timeout = 5 * time.Second 1478 to := time.NewTimer(timeout) 1479 defer to.Stop() 1480 1481 // check that all connections fail without deadlock 1482 for i := 0; i < tryOpen; i++ { 1483 select { 1484 case err := <-errs: 1485 if got, want := err, errOffline; got != want { 1486 t.Errorf("unexpected err: got %v, want %v", got, want) 1487 } 1488 case <-to.C: 1489 t.Fatalf("orphaned connection request(s), still waiting after %v", timeout) 1490 } 1491 } 1492 } 1493 1494 func TestSingleOpenConn(t *testing.T) { 1495 db := newTestDB(t, "people") 1496 defer closeDB(t, db) 1497 1498 db.SetMaxOpenConns(1) 1499 1500 rows, err := db.Query("SELECT|people|name|") 1501 if err != nil { 1502 t.Fatal(err) 1503 } 1504 if err = rows.Close(); err != nil { 1505 t.Fatal(err) 1506 } 1507 // shouldn't deadlock 1508 rows, err = db.Query("SELECT|people|name|") 1509 if err != nil { 1510 t.Fatal(err) 1511 } 1512 if err = rows.Close(); err != nil { 1513 t.Fatal(err) 1514 } 1515 } 1516 1517 func TestStats(t *testing.T) { 1518 db := newTestDB(t, "people") 1519 stats := db.Stats() 1520 if got := stats.OpenConnections; got != 1 { 1521 t.Errorf("stats.OpenConnections = %d; want 1", got) 1522 } 1523 1524 tx, err := db.Begin() 1525 if err != nil { 1526 t.Fatal(err) 1527 } 1528 tx.Commit() 1529 1530 closeDB(t, db) 1531 stats = db.Stats() 1532 if got := stats.OpenConnections; got != 0 { 1533 t.Errorf("stats.OpenConnections = %d; want 0", got) 1534 } 1535 } 1536 1537 func TestConnMaxLifetime(t *testing.T) { 1538 t0 := time.Unix(1000000, 0) 1539 offset := time.Duration(0) 1540 1541 nowFunc = func() time.Time { return t0.Add(offset) } 1542 defer func() { nowFunc = time.Now }() 1543 1544 db := newTestDB(t, "magicquery") 1545 defer closeDB(t, db) 1546 1547 driver := db.driver.(*fakeDriver) 1548 1549 // Force the number of open connections to 0 so we can get an accurate 1550 // count for the test 1551 db.clearAllConns(t) 1552 1553 driver.mu.Lock() 1554 opens0 := driver.openCount 1555 closes0 := driver.closeCount 1556 driver.mu.Unlock() 1557 1558 db.SetMaxIdleConns(10) 1559 db.SetMaxOpenConns(10) 1560 1561 tx, err := db.Begin() 1562 if err != nil { 1563 t.Fatal(err) 1564 } 1565 1566 offset = time.Second 1567 tx2, err := db.Begin() 1568 if err != nil { 1569 t.Fatal(err) 1570 } 1571 1572 tx.Commit() 1573 tx2.Commit() 1574 1575 driver.mu.Lock() 1576 opens := driver.openCount - opens0 1577 closes := driver.closeCount - closes0 1578 driver.mu.Unlock() 1579 1580 if opens != 2 { 1581 t.Errorf("opens = %d; want 2", opens) 1582 } 1583 if closes != 0 { 1584 t.Errorf("closes = %d; want 0", closes) 1585 } 1586 if g, w := db.numFreeConns(), 2; g != w { 1587 t.Errorf("free conns = %d; want %d", g, w) 1588 } 1589 1590 // Expire first conn 1591 offset = time.Second * 11 1592 db.SetConnMaxLifetime(time.Second * 10) 1593 if err != nil { 1594 t.Fatal(err) 1595 } 1596 1597 tx, err = db.Begin() 1598 if err != nil { 1599 t.Fatal(err) 1600 } 1601 tx2, err = db.Begin() 1602 if err != nil { 1603 t.Fatal(err) 1604 } 1605 tx.Commit() 1606 tx2.Commit() 1607 1608 driver.mu.Lock() 1609 opens = driver.openCount - opens0 1610 closes = driver.closeCount - closes0 1611 driver.mu.Unlock() 1612 1613 if opens != 3 { 1614 t.Errorf("opens = %d; want 3", opens) 1615 } 1616 if closes != 1 { 1617 t.Errorf("closes = %d; want 1", closes) 1618 } 1619 } 1620 1621 // golang.org/issue/5323 1622 func TestStmtCloseDeps(t *testing.T) { 1623 if testing.Short() { 1624 t.Skip("skipping in short mode") 1625 } 1626 defer setHookpostCloseConn(nil) 1627 setHookpostCloseConn(func(_ *fakeConn, err error) { 1628 if err != nil { 1629 t.Errorf("Error closing fakeConn: %v", err) 1630 } 1631 }) 1632 1633 db := newTestDB(t, "magicquery") 1634 defer closeDB(t, db) 1635 1636 driver := db.driver.(*fakeDriver) 1637 1638 driver.mu.Lock() 1639 opens0 := driver.openCount 1640 closes0 := driver.closeCount 1641 driver.mu.Unlock() 1642 openDelta0 := opens0 - closes0 1643 1644 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?") 1645 if err != nil { 1646 t.Fatal(err) 1647 } 1648 1649 // Start 50 parallel slow queries. 1650 const ( 1651 nquery = 50 1652 sleepMillis = 25 1653 nbatch = 2 1654 ) 1655 var wg sync.WaitGroup 1656 for batch := 0; batch < nbatch; batch++ { 1657 for i := 0; i < nquery; i++ { 1658 wg.Add(1) 1659 go func() { 1660 defer wg.Done() 1661 var op string 1662 if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows { 1663 t.Error(err) 1664 } 1665 }() 1666 } 1667 // Sleep for twice the expected length of time for the 1668 // batch of 50 queries above to finish before starting 1669 // the next round. 1670 time.Sleep(2 * sleepMillis * time.Millisecond) 1671 } 1672 wg.Wait() 1673 1674 if g, w := db.numFreeConns(), 2; g != w { 1675 t.Errorf("free conns = %d; want %d", g, w) 1676 } 1677 1678 if n := db.numDepsPollUntil(4, time.Second); n > 4 { 1679 t.Errorf("number of dependencies = %d; expected <= 4", n) 1680 db.dumpDeps(t) 1681 } 1682 1683 driver.mu.Lock() 1684 opens := driver.openCount - opens0 1685 closes := driver.closeCount - closes0 1686 openDelta := (driver.openCount - driver.closeCount) - openDelta0 1687 driver.mu.Unlock() 1688 1689 if openDelta > 2 { 1690 t.Logf("open calls = %d", opens) 1691 t.Logf("close calls = %d", closes) 1692 t.Logf("open delta = %d", openDelta) 1693 t.Errorf("db connections opened = %d; want <= 2", openDelta) 1694 db.dumpDeps(t) 1695 } 1696 1697 if len(stmt.css) > nquery { 1698 t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery) 1699 } 1700 1701 if err := stmt.Close(); err != nil { 1702 t.Fatal(err) 1703 } 1704 1705 if g, w := db.numFreeConns(), 2; g != w { 1706 t.Errorf("free conns = %d; want %d", g, w) 1707 } 1708 1709 if n := db.numDepsPollUntil(2, time.Second); n > 2 { 1710 t.Errorf("number of dependencies = %d; expected <= 2", n) 1711 db.dumpDeps(t) 1712 } 1713 1714 db.clearAllConns(t) 1715 } 1716 1717 // golang.org/issue/5046 1718 func TestCloseConnBeforeStmts(t *testing.T) { 1719 db := newTestDB(t, "people") 1720 defer closeDB(t, db) 1721 1722 defer setHookpostCloseConn(nil) 1723 setHookpostCloseConn(func(_ *fakeConn, err error) { 1724 if err != nil { 1725 t.Errorf("Error closing fakeConn: %v; from %s", err, stack()) 1726 db.dumpDeps(t) 1727 t.Errorf("DB = %#v", db) 1728 } 1729 }) 1730 1731 stmt, err := db.Prepare("SELECT|people|name|") 1732 if err != nil { 1733 t.Fatal(err) 1734 } 1735 1736 if len(db.freeConn) != 1 { 1737 t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn)) 1738 } 1739 dc := db.freeConn[0] 1740 if dc.closed { 1741 t.Errorf("conn shouldn't be closed") 1742 } 1743 1744 if n := len(dc.openStmt); n != 1 { 1745 t.Errorf("driverConn num openStmt = %d; want 1", n) 1746 } 1747 err = db.Close() 1748 if err != nil { 1749 t.Errorf("db Close = %v", err) 1750 } 1751 if !dc.closed { 1752 t.Errorf("after db.Close, driverConn should be closed") 1753 } 1754 if n := len(dc.openStmt); n != 0 { 1755 t.Errorf("driverConn num openStmt = %d; want 0", n) 1756 } 1757 1758 err = stmt.Close() 1759 if err != nil { 1760 t.Errorf("Stmt close = %v", err) 1761 } 1762 1763 if !dc.closed { 1764 t.Errorf("conn should be closed") 1765 } 1766 if dc.ci != nil { 1767 t.Errorf("after Stmt Close, driverConn's Conn interface should be nil") 1768 } 1769 } 1770 1771 // golang.org/issue/5283: don't release the Rows' connection in Close 1772 // before calling Stmt.Close. 1773 func TestRowsCloseOrder(t *testing.T) { 1774 db := newTestDB(t, "people") 1775 defer closeDB(t, db) 1776 1777 db.SetMaxIdleConns(0) 1778 setStrictFakeConnClose(t) 1779 defer setStrictFakeConnClose(nil) 1780 1781 rows, err := db.Query("SELECT|people|age,name|") 1782 if err != nil { 1783 t.Fatal(err) 1784 } 1785 err = rows.Close() 1786 if err != nil { 1787 t.Fatal(err) 1788 } 1789 } 1790 1791 func TestRowsImplicitClose(t *testing.T) { 1792 db := newTestDB(t, "people") 1793 defer closeDB(t, db) 1794 1795 rows, err := db.Query("SELECT|people|age,name|") 1796 if err != nil { 1797 t.Fatal(err) 1798 } 1799 1800 want, fail := 2, errors.New("fail") 1801 r := rows.rowsi.(*rowsCursor) 1802 r.errPos, r.err = want, fail 1803 1804 got := 0 1805 for rows.Next() { 1806 got++ 1807 } 1808 if got != want { 1809 t.Errorf("got %d rows, want %d", got, want) 1810 } 1811 if err := rows.Err(); err != fail { 1812 t.Errorf("got error %v, want %v", err, fail) 1813 } 1814 if !r.closed { 1815 t.Errorf("r.closed is false, want true") 1816 } 1817 } 1818 1819 func TestStmtCloseOrder(t *testing.T) { 1820 db := newTestDB(t, "people") 1821 defer closeDB(t, db) 1822 1823 db.SetMaxIdleConns(0) 1824 setStrictFakeConnClose(t) 1825 defer setStrictFakeConnClose(nil) 1826 1827 _, err := db.Query("SELECT|non_existent|name|") 1828 if err == nil { 1829 t.Fatal("Querying non-existent table should fail") 1830 } 1831 } 1832 1833 // Test cases where there's more than maxBadConnRetries bad connections in the 1834 // pool (issue 8834) 1835 func TestManyErrBadConn(t *testing.T) { 1836 manyErrBadConnSetup := func() *DB { 1837 db := newTestDB(t, "people") 1838 1839 nconn := maxBadConnRetries + 1 1840 db.SetMaxIdleConns(nconn) 1841 db.SetMaxOpenConns(nconn) 1842 // open enough connections 1843 func() { 1844 for i := 0; i < nconn; i++ { 1845 rows, err := db.Query("SELECT|people|age,name|") 1846 if err != nil { 1847 t.Fatal(err) 1848 } 1849 defer rows.Close() 1850 } 1851 }() 1852 1853 db.mu.Lock() 1854 defer db.mu.Unlock() 1855 if db.numOpen != nconn { 1856 t.Fatalf("unexpected numOpen %d (was expecting %d)", db.numOpen, nconn) 1857 } else if len(db.freeConn) != nconn { 1858 t.Fatalf("unexpected len(db.freeConn) %d (was expecting %d)", len(db.freeConn), nconn) 1859 } 1860 for _, conn := range db.freeConn { 1861 conn.ci.(*fakeConn).stickyBad = true 1862 } 1863 return db 1864 } 1865 1866 // Query 1867 db := manyErrBadConnSetup() 1868 defer closeDB(t, db) 1869 rows, err := db.Query("SELECT|people|age,name|") 1870 if err != nil { 1871 t.Fatal(err) 1872 } 1873 if err = rows.Close(); err != nil { 1874 t.Fatal(err) 1875 } 1876 1877 // Exec 1878 db = manyErrBadConnSetup() 1879 defer closeDB(t, db) 1880 _, err = db.Exec("INSERT|people|name=Julia,age=19") 1881 if err != nil { 1882 t.Fatal(err) 1883 } 1884 1885 // Begin 1886 db = manyErrBadConnSetup() 1887 defer closeDB(t, db) 1888 tx, err := db.Begin() 1889 if err != nil { 1890 t.Fatal(err) 1891 } 1892 if err = tx.Rollback(); err != nil { 1893 t.Fatal(err) 1894 } 1895 1896 // Prepare 1897 db = manyErrBadConnSetup() 1898 defer closeDB(t, db) 1899 stmt, err := db.Prepare("SELECT|people|age,name|") 1900 if err != nil { 1901 t.Fatal(err) 1902 } 1903 if err = stmt.Close(); err != nil { 1904 t.Fatal(err) 1905 } 1906 } 1907 1908 // golang.org/issue/5718 1909 func TestErrBadConnReconnect(t *testing.T) { 1910 db := newTestDB(t, "foo") 1911 defer closeDB(t, db) 1912 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 1913 1914 simulateBadConn := func(name string, hook *func() bool, op func() error) { 1915 broken, retried := false, false 1916 numOpen := db.numOpen 1917 1918 // simulate a broken connection on the first try 1919 *hook = func() bool { 1920 if !broken { 1921 broken = true 1922 return true 1923 } 1924 retried = true 1925 return false 1926 } 1927 1928 if err := op(); err != nil { 1929 t.Errorf(name+": %v", err) 1930 return 1931 } 1932 1933 if !broken || !retried { 1934 t.Error(name + ": Failed to simulate broken connection") 1935 } 1936 *hook = nil 1937 1938 if numOpen != db.numOpen { 1939 t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen) 1940 numOpen = db.numOpen 1941 } 1942 } 1943 1944 // db.Exec 1945 dbExec := func() error { 1946 _, err := db.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true) 1947 return err 1948 } 1949 simulateBadConn("db.Exec prepare", &hookPrepareBadConn, dbExec) 1950 simulateBadConn("db.Exec exec", &hookExecBadConn, dbExec) 1951 1952 // db.Query 1953 dbQuery := func() error { 1954 rows, err := db.Query("SELECT|t1|age,name|") 1955 if err == nil { 1956 err = rows.Close() 1957 } 1958 return err 1959 } 1960 simulateBadConn("db.Query prepare", &hookPrepareBadConn, dbQuery) 1961 simulateBadConn("db.Query query", &hookQueryBadConn, dbQuery) 1962 1963 // db.Prepare 1964 simulateBadConn("db.Prepare", &hookPrepareBadConn, func() error { 1965 stmt, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?") 1966 if err != nil { 1967 return err 1968 } 1969 stmt.Close() 1970 return nil 1971 }) 1972 1973 // Provide a way to force a re-prepare of a statement on next execution 1974 forcePrepare := func(stmt *Stmt) { 1975 stmt.css = nil 1976 } 1977 1978 // stmt.Exec 1979 stmt1, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?") 1980 if err != nil { 1981 t.Fatalf("prepare: %v", err) 1982 } 1983 defer stmt1.Close() 1984 // make sure we must prepare the stmt first 1985 forcePrepare(stmt1) 1986 1987 stmtExec := func() error { 1988 _, err := stmt1.Exec("Gopher", 3, false) 1989 return err 1990 } 1991 simulateBadConn("stmt.Exec prepare", &hookPrepareBadConn, stmtExec) 1992 simulateBadConn("stmt.Exec exec", &hookExecBadConn, stmtExec) 1993 1994 // stmt.Query 1995 stmt2, err := db.Prepare("SELECT|t1|age,name|") 1996 if err != nil { 1997 t.Fatalf("prepare: %v", err) 1998 } 1999 defer stmt2.Close() 2000 // make sure we must prepare the stmt first 2001 forcePrepare(stmt2) 2002 2003 stmtQuery := func() error { 2004 rows, err := stmt2.Query() 2005 if err == nil { 2006 err = rows.Close() 2007 } 2008 return err 2009 } 2010 simulateBadConn("stmt.Query prepare", &hookPrepareBadConn, stmtQuery) 2011 simulateBadConn("stmt.Query exec", &hookQueryBadConn, stmtQuery) 2012 } 2013 2014 // golang.org/issue/11264 2015 func TestTxEndBadConn(t *testing.T) { 2016 db := newTestDB(t, "foo") 2017 defer closeDB(t, db) 2018 db.SetMaxIdleConns(0) 2019 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 2020 db.SetMaxIdleConns(1) 2021 2022 simulateBadConn := func(name string, hook *func() bool, op func() error) { 2023 broken := false 2024 numOpen := db.numOpen 2025 2026 *hook = func() bool { 2027 if !broken { 2028 broken = true 2029 } 2030 return broken 2031 } 2032 2033 if err := op(); err != driver.ErrBadConn { 2034 t.Errorf(name+": %v", err) 2035 return 2036 } 2037 2038 if !broken { 2039 t.Error(name + ": Failed to simulate broken connection") 2040 } 2041 *hook = nil 2042 2043 if numOpen != db.numOpen { 2044 t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen) 2045 } 2046 } 2047 2048 // db.Exec 2049 dbExec := func(endTx func(tx *Tx) error) func() error { 2050 return func() error { 2051 tx, err := db.Begin() 2052 if err != nil { 2053 return err 2054 } 2055 _, err = tx.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true) 2056 if err != nil { 2057 return err 2058 } 2059 return endTx(tx) 2060 } 2061 } 2062 simulateBadConn("db.Tx.Exec commit", &hookCommitBadConn, dbExec((*Tx).Commit)) 2063 simulateBadConn("db.Tx.Exec rollback", &hookRollbackBadConn, dbExec((*Tx).Rollback)) 2064 2065 // db.Query 2066 dbQuery := func(endTx func(tx *Tx) error) func() error { 2067 return func() error { 2068 tx, err := db.Begin() 2069 if err != nil { 2070 return err 2071 } 2072 rows, err := tx.Query("SELECT|t1|age,name|") 2073 if err == nil { 2074 err = rows.Close() 2075 } else { 2076 return err 2077 } 2078 return endTx(tx) 2079 } 2080 } 2081 simulateBadConn("db.Tx.Query commit", &hookCommitBadConn, dbQuery((*Tx).Commit)) 2082 simulateBadConn("db.Tx.Query rollback", &hookRollbackBadConn, dbQuery((*Tx).Rollback)) 2083 } 2084 2085 type concurrentTest interface { 2086 init(t testing.TB, db *DB) 2087 finish(t testing.TB) 2088 test(t testing.TB) error 2089 } 2090 2091 type concurrentDBQueryTest struct { 2092 db *DB 2093 } 2094 2095 func (c *concurrentDBQueryTest) init(t testing.TB, db *DB) { 2096 c.db = db 2097 } 2098 2099 func (c *concurrentDBQueryTest) finish(t testing.TB) { 2100 c.db = nil 2101 } 2102 2103 func (c *concurrentDBQueryTest) test(t testing.TB) error { 2104 rows, err := c.db.Query("SELECT|people|name|") 2105 if err != nil { 2106 t.Error(err) 2107 return err 2108 } 2109 var name string 2110 for rows.Next() { 2111 rows.Scan(&name) 2112 } 2113 rows.Close() 2114 return nil 2115 } 2116 2117 type concurrentDBExecTest struct { 2118 db *DB 2119 } 2120 2121 func (c *concurrentDBExecTest) init(t testing.TB, db *DB) { 2122 c.db = db 2123 } 2124 2125 func (c *concurrentDBExecTest) finish(t testing.TB) { 2126 c.db = nil 2127 } 2128 2129 func (c *concurrentDBExecTest) test(t testing.TB) error { 2130 _, err := c.db.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday) 2131 if err != nil { 2132 t.Error(err) 2133 return err 2134 } 2135 return nil 2136 } 2137 2138 type concurrentStmtQueryTest struct { 2139 db *DB 2140 stmt *Stmt 2141 } 2142 2143 func (c *concurrentStmtQueryTest) init(t testing.TB, db *DB) { 2144 c.db = db 2145 var err error 2146 c.stmt, err = db.Prepare("SELECT|people|name|") 2147 if err != nil { 2148 t.Fatal(err) 2149 } 2150 } 2151 2152 func (c *concurrentStmtQueryTest) finish(t testing.TB) { 2153 if c.stmt != nil { 2154 c.stmt.Close() 2155 c.stmt = nil 2156 } 2157 c.db = nil 2158 } 2159 2160 func (c *concurrentStmtQueryTest) test(t testing.TB) error { 2161 rows, err := c.stmt.Query() 2162 if err != nil { 2163 t.Errorf("error on query: %v", err) 2164 return err 2165 } 2166 2167 var name string 2168 for rows.Next() { 2169 rows.Scan(&name) 2170 } 2171 rows.Close() 2172 return nil 2173 } 2174 2175 type concurrentStmtExecTest struct { 2176 db *DB 2177 stmt *Stmt 2178 } 2179 2180 func (c *concurrentStmtExecTest) init(t testing.TB, db *DB) { 2181 c.db = db 2182 var err error 2183 c.stmt, err = db.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?") 2184 if err != nil { 2185 t.Fatal(err) 2186 } 2187 } 2188 2189 func (c *concurrentStmtExecTest) finish(t testing.TB) { 2190 if c.stmt != nil { 2191 c.stmt.Close() 2192 c.stmt = nil 2193 } 2194 c.db = nil 2195 } 2196 2197 func (c *concurrentStmtExecTest) test(t testing.TB) error { 2198 _, err := c.stmt.Exec(3, chrisBirthday) 2199 if err != nil { 2200 t.Errorf("error on exec: %v", err) 2201 return err 2202 } 2203 return nil 2204 } 2205 2206 type concurrentTxQueryTest struct { 2207 db *DB 2208 tx *Tx 2209 } 2210 2211 func (c *concurrentTxQueryTest) init(t testing.TB, db *DB) { 2212 c.db = db 2213 var err error 2214 c.tx, err = c.db.Begin() 2215 if err != nil { 2216 t.Fatal(err) 2217 } 2218 } 2219 2220 func (c *concurrentTxQueryTest) finish(t testing.TB) { 2221 if c.tx != nil { 2222 c.tx.Rollback() 2223 c.tx = nil 2224 } 2225 c.db = nil 2226 } 2227 2228 func (c *concurrentTxQueryTest) test(t testing.TB) error { 2229 rows, err := c.db.Query("SELECT|people|name|") 2230 if err != nil { 2231 t.Error(err) 2232 return err 2233 } 2234 var name string 2235 for rows.Next() { 2236 rows.Scan(&name) 2237 } 2238 rows.Close() 2239 return nil 2240 } 2241 2242 type concurrentTxExecTest struct { 2243 db *DB 2244 tx *Tx 2245 } 2246 2247 func (c *concurrentTxExecTest) init(t testing.TB, db *DB) { 2248 c.db = db 2249 var err error 2250 c.tx, err = c.db.Begin() 2251 if err != nil { 2252 t.Fatal(err) 2253 } 2254 } 2255 2256 func (c *concurrentTxExecTest) finish(t testing.TB) { 2257 if c.tx != nil { 2258 c.tx.Rollback() 2259 c.tx = nil 2260 } 2261 c.db = nil 2262 } 2263 2264 func (c *concurrentTxExecTest) test(t testing.TB) error { 2265 _, err := c.tx.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday) 2266 if err != nil { 2267 t.Error(err) 2268 return err 2269 } 2270 return nil 2271 } 2272 2273 type concurrentTxStmtQueryTest struct { 2274 db *DB 2275 tx *Tx 2276 stmt *Stmt 2277 } 2278 2279 func (c *concurrentTxStmtQueryTest) init(t testing.TB, db *DB) { 2280 c.db = db 2281 var err error 2282 c.tx, err = c.db.Begin() 2283 if err != nil { 2284 t.Fatal(err) 2285 } 2286 c.stmt, err = c.tx.Prepare("SELECT|people|name|") 2287 if err != nil { 2288 t.Fatal(err) 2289 } 2290 } 2291 2292 func (c *concurrentTxStmtQueryTest) finish(t testing.TB) { 2293 if c.stmt != nil { 2294 c.stmt.Close() 2295 c.stmt = nil 2296 } 2297 if c.tx != nil { 2298 c.tx.Rollback() 2299 c.tx = nil 2300 } 2301 c.db = nil 2302 } 2303 2304 func (c *concurrentTxStmtQueryTest) test(t testing.TB) error { 2305 rows, err := c.stmt.Query() 2306 if err != nil { 2307 t.Errorf("error on query: %v", err) 2308 return err 2309 } 2310 2311 var name string 2312 for rows.Next() { 2313 rows.Scan(&name) 2314 } 2315 rows.Close() 2316 return nil 2317 } 2318 2319 type concurrentTxStmtExecTest struct { 2320 db *DB 2321 tx *Tx 2322 stmt *Stmt 2323 } 2324 2325 func (c *concurrentTxStmtExecTest) init(t testing.TB, db *DB) { 2326 c.db = db 2327 var err error 2328 c.tx, err = c.db.Begin() 2329 if err != nil { 2330 t.Fatal(err) 2331 } 2332 c.stmt, err = c.tx.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?") 2333 if err != nil { 2334 t.Fatal(err) 2335 } 2336 } 2337 2338 func (c *concurrentTxStmtExecTest) finish(t testing.TB) { 2339 if c.stmt != nil { 2340 c.stmt.Close() 2341 c.stmt = nil 2342 } 2343 if c.tx != nil { 2344 c.tx.Rollback() 2345 c.tx = nil 2346 } 2347 c.db = nil 2348 } 2349 2350 func (c *concurrentTxStmtExecTest) test(t testing.TB) error { 2351 _, err := c.stmt.Exec(3, chrisBirthday) 2352 if err != nil { 2353 t.Errorf("error on exec: %v", err) 2354 return err 2355 } 2356 return nil 2357 } 2358 2359 type concurrentRandomTest struct { 2360 tests []concurrentTest 2361 } 2362 2363 func (c *concurrentRandomTest) init(t testing.TB, db *DB) { 2364 c.tests = []concurrentTest{ 2365 new(concurrentDBQueryTest), 2366 new(concurrentDBExecTest), 2367 new(concurrentStmtQueryTest), 2368 new(concurrentStmtExecTest), 2369 new(concurrentTxQueryTest), 2370 new(concurrentTxExecTest), 2371 new(concurrentTxStmtQueryTest), 2372 new(concurrentTxStmtExecTest), 2373 } 2374 for _, ct := range c.tests { 2375 ct.init(t, db) 2376 } 2377 } 2378 2379 func (c *concurrentRandomTest) finish(t testing.TB) { 2380 for _, ct := range c.tests { 2381 ct.finish(t) 2382 } 2383 } 2384 2385 func (c *concurrentRandomTest) test(t testing.TB) error { 2386 ct := c.tests[rand.Intn(len(c.tests))] 2387 return ct.test(t) 2388 } 2389 2390 func doConcurrentTest(t testing.TB, ct concurrentTest) { 2391 maxProcs, numReqs := 1, 500 2392 if testing.Short() { 2393 maxProcs, numReqs = 4, 50 2394 } 2395 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) 2396 2397 db := newTestDB(t, "people") 2398 defer closeDB(t, db) 2399 2400 ct.init(t, db) 2401 defer ct.finish(t) 2402 2403 var wg sync.WaitGroup 2404 wg.Add(numReqs) 2405 2406 reqs := make(chan bool) 2407 defer close(reqs) 2408 2409 for i := 0; i < maxProcs*2; i++ { 2410 go func() { 2411 for range reqs { 2412 err := ct.test(t) 2413 if err != nil { 2414 wg.Done() 2415 continue 2416 } 2417 wg.Done() 2418 } 2419 }() 2420 } 2421 2422 for i := 0; i < numReqs; i++ { 2423 reqs <- true 2424 } 2425 2426 wg.Wait() 2427 } 2428 2429 func TestIssue6081(t *testing.T) { 2430 db := newTestDB(t, "people") 2431 defer closeDB(t, db) 2432 2433 drv := db.driver.(*fakeDriver) 2434 drv.mu.Lock() 2435 opens0 := drv.openCount 2436 closes0 := drv.closeCount 2437 drv.mu.Unlock() 2438 2439 stmt, err := db.Prepare("SELECT|people|name|") 2440 if err != nil { 2441 t.Fatal(err) 2442 } 2443 rowsCloseHook = func(rows *Rows, err *error) { 2444 *err = driver.ErrBadConn 2445 } 2446 defer func() { rowsCloseHook = nil }() 2447 for i := 0; i < 10; i++ { 2448 rows, err := stmt.Query() 2449 if err != nil { 2450 t.Fatal(err) 2451 } 2452 rows.Close() 2453 } 2454 if n := len(stmt.css); n > 1 { 2455 t.Errorf("len(css slice) = %d; want <= 1", n) 2456 } 2457 stmt.Close() 2458 if n := len(stmt.css); n != 0 { 2459 t.Errorf("len(css slice) after Close = %d; want 0", n) 2460 } 2461 2462 drv.mu.Lock() 2463 opens := drv.openCount - opens0 2464 closes := drv.closeCount - closes0 2465 drv.mu.Unlock() 2466 if opens < 9 { 2467 t.Errorf("opens = %d; want >= 9", opens) 2468 } 2469 if closes < 9 { 2470 t.Errorf("closes = %d; want >= 9", closes) 2471 } 2472 } 2473 2474 func TestConcurrency(t *testing.T) { 2475 doConcurrentTest(t, new(concurrentDBQueryTest)) 2476 doConcurrentTest(t, new(concurrentDBExecTest)) 2477 doConcurrentTest(t, new(concurrentStmtQueryTest)) 2478 doConcurrentTest(t, new(concurrentStmtExecTest)) 2479 doConcurrentTest(t, new(concurrentTxQueryTest)) 2480 doConcurrentTest(t, new(concurrentTxExecTest)) 2481 doConcurrentTest(t, new(concurrentTxStmtQueryTest)) 2482 doConcurrentTest(t, new(concurrentTxStmtExecTest)) 2483 doConcurrentTest(t, new(concurrentRandomTest)) 2484 } 2485 2486 func TestConnectionLeak(t *testing.T) { 2487 db := newTestDB(t, "people") 2488 defer closeDB(t, db) 2489 // Start by opening defaultMaxIdleConns 2490 rows := make([]*Rows, defaultMaxIdleConns) 2491 // We need to SetMaxOpenConns > MaxIdleConns, so the DB can open 2492 // a new connection and we can fill the idle queue with the released 2493 // connections. 2494 db.SetMaxOpenConns(len(rows) + 1) 2495 for ii := range rows { 2496 r, err := db.Query("SELECT|people|name|") 2497 if err != nil { 2498 t.Fatal(err) 2499 } 2500 r.Next() 2501 if err := r.Err(); err != nil { 2502 t.Fatal(err) 2503 } 2504 rows[ii] = r 2505 } 2506 // Now we have defaultMaxIdleConns busy connections. Open 2507 // a new one, but wait until the busy connections are released 2508 // before returning control to DB. 2509 drv := db.driver.(*fakeDriver) 2510 drv.waitCh = make(chan struct{}, 1) 2511 drv.waitingCh = make(chan struct{}, 1) 2512 var wg sync.WaitGroup 2513 wg.Add(1) 2514 go func() { 2515 r, err := db.Query("SELECT|people|name|") 2516 if err != nil { 2517 t.Fatal(err) 2518 } 2519 r.Close() 2520 wg.Done() 2521 }() 2522 // Wait until the goroutine we've just created has started waiting. 2523 <-drv.waitingCh 2524 // Now close the busy connections. This provides a connection for 2525 // the blocked goroutine and then fills up the idle queue. 2526 for _, v := range rows { 2527 v.Close() 2528 } 2529 // At this point we give the new connection to DB. This connection is 2530 // now useless, since the idle queue is full and there are no pending 2531 // requests. DB should deal with this situation without leaking the 2532 // connection. 2533 drv.waitCh <- struct{}{} 2534 wg.Wait() 2535 } 2536 2537 // badConn implements a bad driver.Conn, for TestBadDriver. 2538 // The Exec method panics. 2539 type badConn struct{} 2540 2541 func (bc badConn) Prepare(query string) (driver.Stmt, error) { 2542 return nil, errors.New("badConn Prepare") 2543 } 2544 2545 func (bc badConn) Close() error { 2546 return nil 2547 } 2548 2549 func (bc badConn) Begin() (driver.Tx, error) { 2550 return nil, errors.New("badConn Begin") 2551 } 2552 2553 func (bc badConn) Exec(query string, args []driver.Value) (driver.Result, error) { 2554 panic("badConn.Exec") 2555 } 2556 2557 // badDriver is a driver.Driver that uses badConn. 2558 type badDriver struct{} 2559 2560 func (bd badDriver) Open(name string) (driver.Conn, error) { 2561 return badConn{}, nil 2562 } 2563 2564 // Issue 15901. 2565 func TestBadDriver(t *testing.T) { 2566 Register("bad", badDriver{}) 2567 db, err := Open("bad", "ignored") 2568 if err != nil { 2569 t.Fatal(err) 2570 } 2571 defer func() { 2572 if r := recover(); r == nil { 2573 t.Error("expected panic") 2574 } else { 2575 if want := "badConn.Exec"; r.(string) != want { 2576 t.Errorf("panic was %v, expected %v", r, want) 2577 } 2578 } 2579 }() 2580 defer db.Close() 2581 db.Exec("ignored") 2582 } 2583 2584 type pingDriver struct { 2585 fails bool 2586 } 2587 2588 type pingConn struct { 2589 badConn 2590 driver *pingDriver 2591 } 2592 2593 var pingError = errors.New("Ping failed") 2594 2595 func (pc pingConn) Ping(ctx context.Context) error { 2596 if pc.driver.fails { 2597 return pingError 2598 } 2599 return nil 2600 } 2601 2602 var _ driver.Pinger = pingConn{} 2603 2604 func (pd *pingDriver) Open(name string) (driver.Conn, error) { 2605 return pingConn{driver: pd}, nil 2606 } 2607 2608 func TestPing(t *testing.T) { 2609 driver := &pingDriver{} 2610 Register("ping", driver) 2611 2612 db, err := Open("ping", "ignored") 2613 if err != nil { 2614 t.Fatal(err) 2615 } 2616 2617 if err := db.Ping(); err != nil { 2618 t.Errorf("err was %#v, expected nil", err) 2619 return 2620 } 2621 2622 driver.fails = true 2623 if err := db.Ping(); err != pingError { 2624 t.Errorf("err was %#v, expected pingError", err) 2625 } 2626 } 2627 2628 func BenchmarkConcurrentDBExec(b *testing.B) { 2629 b.ReportAllocs() 2630 ct := new(concurrentDBExecTest) 2631 for i := 0; i < b.N; i++ { 2632 doConcurrentTest(b, ct) 2633 } 2634 } 2635 2636 func BenchmarkConcurrentStmtQuery(b *testing.B) { 2637 b.ReportAllocs() 2638 ct := new(concurrentStmtQueryTest) 2639 for i := 0; i < b.N; i++ { 2640 doConcurrentTest(b, ct) 2641 } 2642 } 2643 2644 func BenchmarkConcurrentStmtExec(b *testing.B) { 2645 b.ReportAllocs() 2646 ct := new(concurrentStmtExecTest) 2647 for i := 0; i < b.N; i++ { 2648 doConcurrentTest(b, ct) 2649 } 2650 } 2651 2652 func BenchmarkConcurrentTxQuery(b *testing.B) { 2653 b.ReportAllocs() 2654 ct := new(concurrentTxQueryTest) 2655 for i := 0; i < b.N; i++ { 2656 doConcurrentTest(b, ct) 2657 } 2658 } 2659 2660 func BenchmarkConcurrentTxExec(b *testing.B) { 2661 b.ReportAllocs() 2662 ct := new(concurrentTxExecTest) 2663 for i := 0; i < b.N; i++ { 2664 doConcurrentTest(b, ct) 2665 } 2666 } 2667 2668 func BenchmarkConcurrentTxStmtQuery(b *testing.B) { 2669 b.ReportAllocs() 2670 ct := new(concurrentTxStmtQueryTest) 2671 for i := 0; i < b.N; i++ { 2672 doConcurrentTest(b, ct) 2673 } 2674 } 2675 2676 func BenchmarkConcurrentTxStmtExec(b *testing.B) { 2677 b.ReportAllocs() 2678 ct := new(concurrentTxStmtExecTest) 2679 for i := 0; i < b.N; i++ { 2680 doConcurrentTest(b, ct) 2681 } 2682 } 2683 2684 func BenchmarkConcurrentRandom(b *testing.B) { 2685 b.ReportAllocs() 2686 ct := new(concurrentRandomTest) 2687 for i := 0; i < b.N; i++ { 2688 doConcurrentTest(b, ct) 2689 } 2690 } 2691 2692 func BenchmarkManyConcurrentQueries(b *testing.B) { 2693 b.ReportAllocs() 2694 // To see lock contention in Go 1.4, 16~ cores and 128~ goroutines are required. 2695 const parallelism = 16 2696 2697 db := newTestDB(b, "magicquery") 2698 defer closeDB(b, db) 2699 db.SetMaxIdleConns(runtime.GOMAXPROCS(0) * parallelism) 2700 2701 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?") 2702 if err != nil { 2703 b.Fatal(err) 2704 } 2705 defer stmt.Close() 2706 2707 b.SetParallelism(parallelism) 2708 b.RunParallel(func(pb *testing.PB) { 2709 for pb.Next() { 2710 rows, err := stmt.Query("sleep", 1) 2711 if err != nil { 2712 b.Error(err) 2713 return 2714 } 2715 rows.Close() 2716 } 2717 }) 2718 }