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