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