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