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