github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/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 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: http://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 func TestSingleOpenConn(t *testing.T) { 1074 db := newTestDB(t, "people") 1075 defer closeDB(t, db) 1076 1077 db.SetMaxOpenConns(1) 1078 1079 rows, err := db.Query("SELECT|people|name|") 1080 if err != nil { 1081 t.Fatal(err) 1082 } 1083 if err = rows.Close(); err != nil { 1084 t.Fatal(err) 1085 } 1086 // shouldn't deadlock 1087 rows, err = db.Query("SELECT|people|name|") 1088 if err != nil { 1089 t.Fatal(err) 1090 } 1091 if err = rows.Close(); err != nil { 1092 t.Fatal(err) 1093 } 1094 } 1095 1096 // golang.org/issue/5323 1097 func TestStmtCloseDeps(t *testing.T) { 1098 if testing.Short() { 1099 t.Skip("skipping in short mode") 1100 } 1101 defer setHookpostCloseConn(nil) 1102 setHookpostCloseConn(func(_ *fakeConn, err error) { 1103 if err != nil { 1104 t.Errorf("Error closing fakeConn: %v", err) 1105 } 1106 }) 1107 1108 db := newTestDB(t, "magicquery") 1109 defer closeDB(t, db) 1110 1111 driver := db.driver.(*fakeDriver) 1112 1113 driver.mu.Lock() 1114 opens0 := driver.openCount 1115 closes0 := driver.closeCount 1116 driver.mu.Unlock() 1117 openDelta0 := opens0 - closes0 1118 1119 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?") 1120 if err != nil { 1121 t.Fatal(err) 1122 } 1123 1124 // Start 50 parallel slow queries. 1125 const ( 1126 nquery = 50 1127 sleepMillis = 25 1128 nbatch = 2 1129 ) 1130 var wg sync.WaitGroup 1131 for batch := 0; batch < nbatch; batch++ { 1132 for i := 0; i < nquery; i++ { 1133 wg.Add(1) 1134 go func() { 1135 defer wg.Done() 1136 var op string 1137 if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows { 1138 t.Error(err) 1139 } 1140 }() 1141 } 1142 // Sleep for twice the expected length of time for the 1143 // batch of 50 queries above to finish before starting 1144 // the next round. 1145 time.Sleep(2 * sleepMillis * time.Millisecond) 1146 } 1147 wg.Wait() 1148 1149 if g, w := db.numFreeConns(), 2; g != w { 1150 t.Errorf("free conns = %d; want %d", g, w) 1151 } 1152 1153 if n := db.numDepsPollUntil(4, time.Second); n > 4 { 1154 t.Errorf("number of dependencies = %d; expected <= 4", n) 1155 db.dumpDeps(t) 1156 } 1157 1158 driver.mu.Lock() 1159 opens := driver.openCount - opens0 1160 closes := driver.closeCount - closes0 1161 openDelta := (driver.openCount - driver.closeCount) - openDelta0 1162 driver.mu.Unlock() 1163 1164 if openDelta > 2 { 1165 t.Logf("open calls = %d", opens) 1166 t.Logf("close calls = %d", closes) 1167 t.Logf("open delta = %d", openDelta) 1168 t.Errorf("db connections opened = %d; want <= 2", openDelta) 1169 db.dumpDeps(t) 1170 } 1171 1172 if len(stmt.css) > nquery { 1173 t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery) 1174 } 1175 1176 if err := stmt.Close(); err != nil { 1177 t.Fatal(err) 1178 } 1179 1180 if g, w := db.numFreeConns(), 2; g != w { 1181 t.Errorf("free conns = %d; want %d", g, w) 1182 } 1183 1184 if n := db.numDepsPollUntil(2, time.Second); n > 2 { 1185 t.Errorf("number of dependencies = %d; expected <= 2", n) 1186 db.dumpDeps(t) 1187 } 1188 1189 db.SetMaxIdleConns(0) 1190 1191 if g, w := db.numFreeConns(), 0; g != w { 1192 t.Errorf("free conns = %d; want %d", g, w) 1193 } 1194 1195 if n := db.numDepsPollUntil(0, time.Second); n > 0 { 1196 t.Errorf("number of dependencies = %d; expected 0", n) 1197 db.dumpDeps(t) 1198 } 1199 } 1200 1201 // golang.org/issue/5046 1202 func TestCloseConnBeforeStmts(t *testing.T) { 1203 db := newTestDB(t, "people") 1204 defer closeDB(t, db) 1205 1206 defer setHookpostCloseConn(nil) 1207 setHookpostCloseConn(func(_ *fakeConn, err error) { 1208 if err != nil { 1209 t.Errorf("Error closing fakeConn: %v; from %s", err, stack()) 1210 db.dumpDeps(t) 1211 t.Errorf("DB = %#v", db) 1212 } 1213 }) 1214 1215 stmt, err := db.Prepare("SELECT|people|name|") 1216 if err != nil { 1217 t.Fatal(err) 1218 } 1219 1220 if len(db.freeConn) != 1 { 1221 t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn)) 1222 } 1223 dc := db.freeConn[0] 1224 if dc.closed { 1225 t.Errorf("conn shouldn't be closed") 1226 } 1227 1228 if n := len(dc.openStmt); n != 1 { 1229 t.Errorf("driverConn num openStmt = %d; want 1", n) 1230 } 1231 err = db.Close() 1232 if err != nil { 1233 t.Errorf("db Close = %v", err) 1234 } 1235 if !dc.closed { 1236 t.Errorf("after db.Close, driverConn should be closed") 1237 } 1238 if n := len(dc.openStmt); n != 0 { 1239 t.Errorf("driverConn num openStmt = %d; want 0", n) 1240 } 1241 1242 err = stmt.Close() 1243 if err != nil { 1244 t.Errorf("Stmt close = %v", err) 1245 } 1246 1247 if !dc.closed { 1248 t.Errorf("conn should be closed") 1249 } 1250 if dc.ci != nil { 1251 t.Errorf("after Stmt Close, driverConn's Conn interface should be nil") 1252 } 1253 } 1254 1255 // golang.org/issue/5283: don't release the Rows' connection in Close 1256 // before calling Stmt.Close. 1257 func TestRowsCloseOrder(t *testing.T) { 1258 db := newTestDB(t, "people") 1259 defer closeDB(t, db) 1260 1261 db.SetMaxIdleConns(0) 1262 setStrictFakeConnClose(t) 1263 defer setStrictFakeConnClose(nil) 1264 1265 rows, err := db.Query("SELECT|people|age,name|") 1266 if err != nil { 1267 t.Fatal(err) 1268 } 1269 err = rows.Close() 1270 if err != nil { 1271 t.Fatal(err) 1272 } 1273 } 1274 1275 func TestRowsImplicitClose(t *testing.T) { 1276 db := newTestDB(t, "people") 1277 defer closeDB(t, db) 1278 1279 rows, err := db.Query("SELECT|people|age,name|") 1280 if err != nil { 1281 t.Fatal(err) 1282 } 1283 1284 want, fail := 2, errors.New("fail") 1285 r := rows.rowsi.(*rowsCursor) 1286 r.errPos, r.err = want, fail 1287 1288 got := 0 1289 for rows.Next() { 1290 got++ 1291 } 1292 if got != want { 1293 t.Errorf("got %d rows, want %d", got, want) 1294 } 1295 if err := rows.Err(); err != fail { 1296 t.Errorf("got error %v, want %v", err, fail) 1297 } 1298 if !r.closed { 1299 t.Errorf("r.closed is false, want true") 1300 } 1301 } 1302 1303 func TestStmtCloseOrder(t *testing.T) { 1304 db := newTestDB(t, "people") 1305 defer closeDB(t, db) 1306 1307 db.SetMaxIdleConns(0) 1308 setStrictFakeConnClose(t) 1309 defer setStrictFakeConnClose(nil) 1310 1311 _, err := db.Query("SELECT|non_existent|name|") 1312 if err == nil { 1313 t.Fatal("Quering non-existent table should fail") 1314 } 1315 } 1316 1317 // golang.org/issue/5781 1318 func TestErrBadConnReconnect(t *testing.T) { 1319 db := newTestDB(t, "foo") 1320 defer closeDB(t, db) 1321 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 1322 1323 simulateBadConn := func(name string, hook *func() bool, op func() error) { 1324 broken, retried := false, false 1325 numOpen := db.numOpen 1326 1327 // simulate a broken connection on the first try 1328 *hook = func() bool { 1329 if !broken { 1330 broken = true 1331 return true 1332 } 1333 retried = true 1334 return false 1335 } 1336 1337 if err := op(); err != nil { 1338 t.Errorf(name+": %v", err) 1339 return 1340 } 1341 1342 if !broken || !retried { 1343 t.Error(name + ": Failed to simulate broken connection") 1344 } 1345 *hook = nil 1346 1347 if numOpen != db.numOpen { 1348 t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen) 1349 numOpen = db.numOpen 1350 } 1351 } 1352 1353 // db.Exec 1354 dbExec := func() error { 1355 _, err := db.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true) 1356 return err 1357 } 1358 simulateBadConn("db.Exec prepare", &hookPrepareBadConn, dbExec) 1359 simulateBadConn("db.Exec exec", &hookExecBadConn, dbExec) 1360 1361 // db.Query 1362 dbQuery := func() error { 1363 rows, err := db.Query("SELECT|t1|age,name|") 1364 if err == nil { 1365 err = rows.Close() 1366 } 1367 return err 1368 } 1369 simulateBadConn("db.Query prepare", &hookPrepareBadConn, dbQuery) 1370 simulateBadConn("db.Query query", &hookQueryBadConn, dbQuery) 1371 1372 // db.Prepare 1373 simulateBadConn("db.Prepare", &hookPrepareBadConn, func() error { 1374 stmt, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?") 1375 if err != nil { 1376 return err 1377 } 1378 stmt.Close() 1379 return nil 1380 }) 1381 1382 // Provide a way to force a re-prepare of a statement on next execution 1383 forcePrepare := func(stmt *Stmt) { 1384 stmt.css = nil 1385 } 1386 1387 // stmt.Exec 1388 stmt1, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?") 1389 if err != nil { 1390 t.Fatalf("prepare: %v", err) 1391 } 1392 defer stmt1.Close() 1393 // make sure we must prepare the stmt first 1394 forcePrepare(stmt1) 1395 1396 stmtExec := func() error { 1397 _, err := stmt1.Exec("Gopher", 3, false) 1398 return err 1399 } 1400 simulateBadConn("stmt.Exec prepare", &hookPrepareBadConn, stmtExec) 1401 simulateBadConn("stmt.Exec exec", &hookExecBadConn, stmtExec) 1402 1403 // stmt.Query 1404 stmt2, err := db.Prepare("SELECT|t1|age,name|") 1405 if err != nil { 1406 t.Fatalf("prepare: %v", err) 1407 } 1408 defer stmt2.Close() 1409 // make sure we must prepare the stmt first 1410 forcePrepare(stmt2) 1411 1412 stmtQuery := func() error { 1413 rows, err := stmt2.Query() 1414 if err == nil { 1415 err = rows.Close() 1416 } 1417 return err 1418 } 1419 simulateBadConn("stmt.Query prepare", &hookPrepareBadConn, stmtQuery) 1420 simulateBadConn("stmt.Query exec", &hookQueryBadConn, stmtQuery) 1421 } 1422 1423 type concurrentTest interface { 1424 init(t testing.TB, db *DB) 1425 finish(t testing.TB) 1426 test(t testing.TB) error 1427 } 1428 1429 type concurrentDBQueryTest struct { 1430 db *DB 1431 } 1432 1433 func (c *concurrentDBQueryTest) init(t testing.TB, db *DB) { 1434 c.db = db 1435 } 1436 1437 func (c *concurrentDBQueryTest) finish(t testing.TB) { 1438 c.db = nil 1439 } 1440 1441 func (c *concurrentDBQueryTest) test(t testing.TB) error { 1442 rows, err := c.db.Query("SELECT|people|name|") 1443 if err != nil { 1444 t.Error(err) 1445 return err 1446 } 1447 var name string 1448 for rows.Next() { 1449 rows.Scan(&name) 1450 } 1451 rows.Close() 1452 return nil 1453 } 1454 1455 type concurrentDBExecTest struct { 1456 db *DB 1457 } 1458 1459 func (c *concurrentDBExecTest) init(t testing.TB, db *DB) { 1460 c.db = db 1461 } 1462 1463 func (c *concurrentDBExecTest) finish(t testing.TB) { 1464 c.db = nil 1465 } 1466 1467 func (c *concurrentDBExecTest) test(t testing.TB) error { 1468 _, err := c.db.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday) 1469 if err != nil { 1470 t.Error(err) 1471 return err 1472 } 1473 return nil 1474 } 1475 1476 type concurrentStmtQueryTest struct { 1477 db *DB 1478 stmt *Stmt 1479 } 1480 1481 func (c *concurrentStmtQueryTest) init(t testing.TB, db *DB) { 1482 c.db = db 1483 var err error 1484 c.stmt, err = db.Prepare("SELECT|people|name|") 1485 if err != nil { 1486 t.Fatal(err) 1487 } 1488 } 1489 1490 func (c *concurrentStmtQueryTest) finish(t testing.TB) { 1491 if c.stmt != nil { 1492 c.stmt.Close() 1493 c.stmt = nil 1494 } 1495 c.db = nil 1496 } 1497 1498 func (c *concurrentStmtQueryTest) test(t testing.TB) error { 1499 rows, err := c.stmt.Query() 1500 if err != nil { 1501 t.Errorf("error on query: %v", err) 1502 return err 1503 } 1504 1505 var name string 1506 for rows.Next() { 1507 rows.Scan(&name) 1508 } 1509 rows.Close() 1510 return nil 1511 } 1512 1513 type concurrentStmtExecTest struct { 1514 db *DB 1515 stmt *Stmt 1516 } 1517 1518 func (c *concurrentStmtExecTest) init(t testing.TB, db *DB) { 1519 c.db = db 1520 var err error 1521 c.stmt, err = db.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?") 1522 if err != nil { 1523 t.Fatal(err) 1524 } 1525 } 1526 1527 func (c *concurrentStmtExecTest) finish(t testing.TB) { 1528 if c.stmt != nil { 1529 c.stmt.Close() 1530 c.stmt = nil 1531 } 1532 c.db = nil 1533 } 1534 1535 func (c *concurrentStmtExecTest) test(t testing.TB) error { 1536 _, err := c.stmt.Exec(3, chrisBirthday) 1537 if err != nil { 1538 t.Errorf("error on exec: %v", err) 1539 return err 1540 } 1541 return nil 1542 } 1543 1544 type concurrentTxQueryTest struct { 1545 db *DB 1546 tx *Tx 1547 } 1548 1549 func (c *concurrentTxQueryTest) init(t testing.TB, db *DB) { 1550 c.db = db 1551 var err error 1552 c.tx, err = c.db.Begin() 1553 if err != nil { 1554 t.Fatal(err) 1555 } 1556 } 1557 1558 func (c *concurrentTxQueryTest) finish(t testing.TB) { 1559 if c.tx != nil { 1560 c.tx.Rollback() 1561 c.tx = nil 1562 } 1563 c.db = nil 1564 } 1565 1566 func (c *concurrentTxQueryTest) test(t testing.TB) error { 1567 rows, err := c.db.Query("SELECT|people|name|") 1568 if err != nil { 1569 t.Error(err) 1570 return err 1571 } 1572 var name string 1573 for rows.Next() { 1574 rows.Scan(&name) 1575 } 1576 rows.Close() 1577 return nil 1578 } 1579 1580 type concurrentTxExecTest struct { 1581 db *DB 1582 tx *Tx 1583 } 1584 1585 func (c *concurrentTxExecTest) init(t testing.TB, db *DB) { 1586 c.db = db 1587 var err error 1588 c.tx, err = c.db.Begin() 1589 if err != nil { 1590 t.Fatal(err) 1591 } 1592 } 1593 1594 func (c *concurrentTxExecTest) finish(t testing.TB) { 1595 if c.tx != nil { 1596 c.tx.Rollback() 1597 c.tx = nil 1598 } 1599 c.db = nil 1600 } 1601 1602 func (c *concurrentTxExecTest) test(t testing.TB) error { 1603 _, err := c.tx.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday) 1604 if err != nil { 1605 t.Error(err) 1606 return err 1607 } 1608 return nil 1609 } 1610 1611 type concurrentTxStmtQueryTest struct { 1612 db *DB 1613 tx *Tx 1614 stmt *Stmt 1615 } 1616 1617 func (c *concurrentTxStmtQueryTest) init(t testing.TB, db *DB) { 1618 c.db = db 1619 var err error 1620 c.tx, err = c.db.Begin() 1621 if err != nil { 1622 t.Fatal(err) 1623 } 1624 c.stmt, err = c.tx.Prepare("SELECT|people|name|") 1625 if err != nil { 1626 t.Fatal(err) 1627 } 1628 } 1629 1630 func (c *concurrentTxStmtQueryTest) finish(t testing.TB) { 1631 if c.stmt != nil { 1632 c.stmt.Close() 1633 c.stmt = nil 1634 } 1635 if c.tx != nil { 1636 c.tx.Rollback() 1637 c.tx = nil 1638 } 1639 c.db = nil 1640 } 1641 1642 func (c *concurrentTxStmtQueryTest) 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 concurrentTxStmtExecTest struct { 1658 db *DB 1659 tx *Tx 1660 stmt *Stmt 1661 } 1662 1663 func (c *concurrentTxStmtExecTest) init(t testing.TB, db *DB) { 1664 c.db = db 1665 var err error 1666 c.tx, err = c.db.Begin() 1667 if err != nil { 1668 t.Fatal(err) 1669 } 1670 c.stmt, err = c.tx.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?") 1671 if err != nil { 1672 t.Fatal(err) 1673 } 1674 } 1675 1676 func (c *concurrentTxStmtExecTest) finish(t testing.TB) { 1677 if c.stmt != nil { 1678 c.stmt.Close() 1679 c.stmt = nil 1680 } 1681 if c.tx != nil { 1682 c.tx.Rollback() 1683 c.tx = nil 1684 } 1685 c.db = nil 1686 } 1687 1688 func (c *concurrentTxStmtExecTest) test(t testing.TB) error { 1689 _, err := c.stmt.Exec(3, chrisBirthday) 1690 if err != nil { 1691 t.Errorf("error on exec: %v", err) 1692 return err 1693 } 1694 return nil 1695 } 1696 1697 type concurrentRandomTest struct { 1698 tests []concurrentTest 1699 } 1700 1701 func (c *concurrentRandomTest) init(t testing.TB, db *DB) { 1702 c.tests = []concurrentTest{ 1703 new(concurrentDBQueryTest), 1704 new(concurrentDBExecTest), 1705 new(concurrentStmtQueryTest), 1706 new(concurrentStmtExecTest), 1707 new(concurrentTxQueryTest), 1708 new(concurrentTxExecTest), 1709 new(concurrentTxStmtQueryTest), 1710 new(concurrentTxStmtExecTest), 1711 } 1712 for _, ct := range c.tests { 1713 ct.init(t, db) 1714 } 1715 } 1716 1717 func (c *concurrentRandomTest) finish(t testing.TB) { 1718 for _, ct := range c.tests { 1719 ct.finish(t) 1720 } 1721 } 1722 1723 func (c *concurrentRandomTest) test(t testing.TB) error { 1724 ct := c.tests[rand.Intn(len(c.tests))] 1725 return ct.test(t) 1726 } 1727 1728 func doConcurrentTest(t testing.TB, ct concurrentTest) { 1729 maxProcs, numReqs := 1, 500 1730 if testing.Short() { 1731 maxProcs, numReqs = 4, 50 1732 } 1733 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) 1734 1735 db := newTestDB(t, "people") 1736 defer closeDB(t, db) 1737 1738 ct.init(t, db) 1739 defer ct.finish(t) 1740 1741 var wg sync.WaitGroup 1742 wg.Add(numReqs) 1743 1744 reqs := make(chan bool) 1745 defer close(reqs) 1746 1747 for i := 0; i < maxProcs*2; i++ { 1748 go func() { 1749 for range reqs { 1750 err := ct.test(t) 1751 if err != nil { 1752 wg.Done() 1753 continue 1754 } 1755 wg.Done() 1756 } 1757 }() 1758 } 1759 1760 for i := 0; i < numReqs; i++ { 1761 reqs <- true 1762 } 1763 1764 wg.Wait() 1765 } 1766 1767 func manyConcurrentQueries(t testing.TB) { 1768 maxProcs, numReqs := 16, 500 1769 if testing.Short() { 1770 maxProcs, numReqs = 4, 50 1771 } 1772 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) 1773 1774 db := newTestDB(t, "people") 1775 defer closeDB(t, db) 1776 1777 stmt, err := db.Prepare("SELECT|people|name|") 1778 if err != nil { 1779 t.Fatal(err) 1780 } 1781 defer stmt.Close() 1782 1783 var wg sync.WaitGroup 1784 wg.Add(numReqs) 1785 1786 reqs := make(chan bool) 1787 defer close(reqs) 1788 1789 for i := 0; i < maxProcs*2; i++ { 1790 go func() { 1791 for range reqs { 1792 rows, err := stmt.Query() 1793 if err != nil { 1794 t.Errorf("error on query: %v", err) 1795 wg.Done() 1796 continue 1797 } 1798 1799 var name string 1800 for rows.Next() { 1801 rows.Scan(&name) 1802 } 1803 rows.Close() 1804 1805 wg.Done() 1806 } 1807 }() 1808 } 1809 1810 for i := 0; i < numReqs; i++ { 1811 reqs <- true 1812 } 1813 1814 wg.Wait() 1815 } 1816 1817 func TestIssue6081(t *testing.T) { 1818 db := newTestDB(t, "people") 1819 defer closeDB(t, db) 1820 1821 drv := db.driver.(*fakeDriver) 1822 drv.mu.Lock() 1823 opens0 := drv.openCount 1824 closes0 := drv.closeCount 1825 drv.mu.Unlock() 1826 1827 stmt, err := db.Prepare("SELECT|people|name|") 1828 if err != nil { 1829 t.Fatal(err) 1830 } 1831 rowsCloseHook = func(rows *Rows, err *error) { 1832 *err = driver.ErrBadConn 1833 } 1834 defer func() { rowsCloseHook = nil }() 1835 for i := 0; i < 10; i++ { 1836 rows, err := stmt.Query() 1837 if err != nil { 1838 t.Fatal(err) 1839 } 1840 rows.Close() 1841 } 1842 if n := len(stmt.css); n > 1 { 1843 t.Errorf("len(css slice) = %d; want <= 1", n) 1844 } 1845 stmt.Close() 1846 if n := len(stmt.css); n != 0 { 1847 t.Errorf("len(css slice) after Close = %d; want 0", n) 1848 } 1849 1850 drv.mu.Lock() 1851 opens := drv.openCount - opens0 1852 closes := drv.closeCount - closes0 1853 drv.mu.Unlock() 1854 if opens < 9 { 1855 t.Errorf("opens = %d; want >= 9", opens) 1856 } 1857 if closes < 9 { 1858 t.Errorf("closes = %d; want >= 9", closes) 1859 } 1860 } 1861 1862 func TestConcurrency(t *testing.T) { 1863 doConcurrentTest(t, new(concurrentDBQueryTest)) 1864 doConcurrentTest(t, new(concurrentDBExecTest)) 1865 doConcurrentTest(t, new(concurrentStmtQueryTest)) 1866 doConcurrentTest(t, new(concurrentStmtExecTest)) 1867 doConcurrentTest(t, new(concurrentTxQueryTest)) 1868 doConcurrentTest(t, new(concurrentTxExecTest)) 1869 doConcurrentTest(t, new(concurrentTxStmtQueryTest)) 1870 doConcurrentTest(t, new(concurrentTxStmtExecTest)) 1871 doConcurrentTest(t, new(concurrentRandomTest)) 1872 } 1873 1874 func TestConnectionLeak(t *testing.T) { 1875 db := newTestDB(t, "people") 1876 defer closeDB(t, db) 1877 // Start by opening defaultMaxIdleConns 1878 rows := make([]*Rows, defaultMaxIdleConns) 1879 // We need to SetMaxOpenConns > MaxIdleConns, so the DB can open 1880 // a new connection and we can fill the idle queue with the released 1881 // connections. 1882 db.SetMaxOpenConns(len(rows) + 1) 1883 for ii := range rows { 1884 r, err := db.Query("SELECT|people|name|") 1885 if err != nil { 1886 t.Fatal(err) 1887 } 1888 r.Next() 1889 if err := r.Err(); err != nil { 1890 t.Fatal(err) 1891 } 1892 rows[ii] = r 1893 } 1894 // Now we have defaultMaxIdleConns busy connections. Open 1895 // a new one, but wait until the busy connections are released 1896 // before returning control to DB. 1897 drv := db.driver.(*fakeDriver) 1898 drv.waitCh = make(chan struct{}, 1) 1899 drv.waitingCh = make(chan struct{}, 1) 1900 var wg sync.WaitGroup 1901 wg.Add(1) 1902 go func() { 1903 r, err := db.Query("SELECT|people|name|") 1904 if err != nil { 1905 t.Fatal(err) 1906 } 1907 r.Close() 1908 wg.Done() 1909 }() 1910 // Wait until the goroutine we've just created has started waiting. 1911 <-drv.waitingCh 1912 // Now close the busy connections. This provides a connection for 1913 // the blocked goroutine and then fills up the idle queue. 1914 for _, v := range rows { 1915 v.Close() 1916 } 1917 // At this point we give the new connection to DB. This connection is 1918 // now useless, since the idle queue is full and there are no pending 1919 // requests. DB should deal with this situation without leaking the 1920 // connection. 1921 drv.waitCh <- struct{}{} 1922 wg.Wait() 1923 } 1924 1925 func BenchmarkConcurrentDBExec(b *testing.B) { 1926 b.ReportAllocs() 1927 ct := new(concurrentDBExecTest) 1928 for i := 0; i < b.N; i++ { 1929 doConcurrentTest(b, ct) 1930 } 1931 } 1932 1933 func BenchmarkConcurrentStmtQuery(b *testing.B) { 1934 b.ReportAllocs() 1935 ct := new(concurrentStmtQueryTest) 1936 for i := 0; i < b.N; i++ { 1937 doConcurrentTest(b, ct) 1938 } 1939 } 1940 1941 func BenchmarkConcurrentStmtExec(b *testing.B) { 1942 b.ReportAllocs() 1943 ct := new(concurrentStmtExecTest) 1944 for i := 0; i < b.N; i++ { 1945 doConcurrentTest(b, ct) 1946 } 1947 } 1948 1949 func BenchmarkConcurrentTxQuery(b *testing.B) { 1950 b.ReportAllocs() 1951 ct := new(concurrentTxQueryTest) 1952 for i := 0; i < b.N; i++ { 1953 doConcurrentTest(b, ct) 1954 } 1955 } 1956 1957 func BenchmarkConcurrentTxExec(b *testing.B) { 1958 b.ReportAllocs() 1959 ct := new(concurrentTxExecTest) 1960 for i := 0; i < b.N; i++ { 1961 doConcurrentTest(b, ct) 1962 } 1963 } 1964 1965 func BenchmarkConcurrentTxStmtQuery(b *testing.B) { 1966 b.ReportAllocs() 1967 ct := new(concurrentTxStmtQueryTest) 1968 for i := 0; i < b.N; i++ { 1969 doConcurrentTest(b, ct) 1970 } 1971 } 1972 1973 func BenchmarkConcurrentTxStmtExec(b *testing.B) { 1974 b.ReportAllocs() 1975 ct := new(concurrentTxStmtExecTest) 1976 for i := 0; i < b.N; i++ { 1977 doConcurrentTest(b, ct) 1978 } 1979 } 1980 1981 func BenchmarkConcurrentRandom(b *testing.B) { 1982 b.ReportAllocs() 1983 ct := new(concurrentRandomTest) 1984 for i := 0; i < b.N; i++ { 1985 doConcurrentTest(b, ct) 1986 } 1987 }