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