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