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