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