Skip to content

Commit 2a64ebf

Browse files
kardianosbradfitz
authored andcommitted
database/sql: deflake query cancel tests
Rather then using a sleep in the fake DB, go to a channel select and wait for the context to be done. Fixes #18115 Change-Id: I6bc3a29db58c568d0a7ea06c2a354c18c9e798b2 Reviewed-on: https://go-review.googlesource.com/33712 Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent f6bff1d commit 2a64ebf

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

src/database/sql/fakedb_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,10 @@ func (c *fakeConn) prepareInsert(stmt *fakeStmt, parts []string) (*fakeStmt, err
511511
var hookPrepareBadConn func() bool
512512

513513
func (c *fakeConn) Prepare(query string) (driver.Stmt, error) {
514+
panic("use PrepareContext")
515+
}
516+
517+
func (c *fakeConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
514518
c.numPrepare++
515519
if c.db == nil {
516520
panic("nil c.db; conn = " + fmt.Sprintf("%#v", c))
@@ -549,7 +553,13 @@ func (c *fakeConn) Prepare(query string) (driver.Stmt, error) {
549553
parts = parts[1:]
550554

551555
if stmt.wait > 0 {
552-
time.Sleep(stmt.wait)
556+
wait := time.NewTimer(stmt.wait)
557+
select {
558+
case <-wait.C:
559+
case <-ctx.Done():
560+
wait.Stop()
561+
return nil, ctx.Err()
562+
}
553563
}
554564

555565
c.incrStat(&c.stmtsMade)

src/database/sql/sql_test.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ func init() {
2424
c *driverConn
2525
}
2626
freedFrom := make(map[dbConn]string)
27+
var mu sync.Mutex
28+
getFreedFrom := func(c dbConn) string {
29+
mu.Lock()
30+
defer mu.Unlock()
31+
return freedFrom[c]
32+
}
33+
setFreedFrom := func(c dbConn, s string) {
34+
mu.Lock()
35+
defer mu.Unlock()
36+
freedFrom[c] = s
37+
}
2738
putConnHook = func(db *DB, c *driverConn) {
2839
idx := -1
2940
for i, v := range db.freeConn {
@@ -36,10 +47,10 @@ func init() {
3647
// print before panic, as panic may get lost due to conflicting panic
3748
// (all goroutines asleep) elsewhere, since we might not unlock
3849
// the mutex in freeConn here.
39-
println("double free of conn. conflicts are:\nA) " + freedFrom[dbConn{db, c}] + "\n\nand\nB) " + stack())
50+
println("double free of conn. conflicts are:\nA) " + getFreedFrom(dbConn{db, c}) + "\n\nand\nB) " + stack())
4051
panic("double free of conn.")
4152
}
42-
freedFrom[dbConn{db, c}] = stack()
53+
setFreedFrom(dbConn{db, c}, stack())
4354
}
4455
}
4556

@@ -344,7 +355,7 @@ func TestQueryContextWait(t *testing.T) {
344355
// This will trigger the *fakeConn.Prepare method which will take time
345356
// performing the query. The ctxDriverPrepare func will check the context
346357
// after this and close the rows and return an error.
347-
_, err := db.QueryContext(ctx, "WAIT|30ms|SELECT|people|age,name|")
358+
_, err := db.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|")
348359
if err != context.DeadlineExceeded {
349360
t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
350361
}
@@ -372,7 +383,7 @@ func TestTxContextWait(t *testing.T) {
372383
// This will trigger the *fakeConn.Prepare method which will take time
373384
// performing the query. The ctxDriverPrepare func will check the context
374385
// after this and close the rows and return an error.
375-
_, err = tx.QueryContext(ctx, "WAIT|30ms|SELECT|people|age,name|")
386+
_, err = tx.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|")
376387
if err != context.DeadlineExceeded {
377388
t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
378389
}

0 commit comments

Comments
 (0)