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