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