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