Skip to content

Commit c947c34

Browse files
committed
added test helpers and tests for go-sql-driver#314
1 parent a197e5d commit c947c34

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed

Diff for: helpers_test.go

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package mysql
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"runtime"
7+
"strings"
8+
"testing"
9+
"time"
10+
)
11+
12+
// Printer is a function that can be used as a Logger.
13+
type Printer func(v ...interface{})
14+
15+
func (p Printer) Print(v ...interface{}) {
16+
p(v...)
17+
}
18+
19+
// useLogger sets the logger and returns a function resetting it to the old one.
20+
// Use it as
21+
// defer useLogger(LOGGER)()
22+
func useLogger(p Printer) func() {
23+
var logger = errLog
24+
SetLogger(p)
25+
return func() {
26+
SetLogger(logger)
27+
}
28+
}
29+
30+
// testTimebound runs a test and fails if it takes longer than allowed.
31+
func testTimebound(t *testing.T, timeout time.Duration, f func(*testing.T)) {
32+
timer := time.After(timeout)
33+
done := make(chan struct{})
34+
defer close(done)
35+
go func() {
36+
f(t)
37+
done <- struct{}{}
38+
}()
39+
select {
40+
case <-timer:
41+
t.Fatal("TIMEOUT")
42+
case <-done:
43+
}
44+
}
45+
46+
// tracer is useable as a Logger, prints full stacktrace of all package internal calls
47+
type tracer struct{}
48+
49+
func (t tracer) Print(v ...interface{}) {
50+
trace := []string{}
51+
var (
52+
dstPkg string
53+
file string
54+
line int
55+
)
56+
ok := true
57+
for i := 0; ok; i++ {
58+
_, file, line, ok = runtime.Caller(i)
59+
if !ok {
60+
break
61+
}
62+
pkg := ""
63+
pEnd := 0
64+
for j := len(file) - 2; j > 0; j-- {
65+
if file[j] == '/' {
66+
if pEnd != 0 {
67+
pkg = file[j+1 : pEnd]
68+
if i == 0 {
69+
dstPkg = pkg
70+
}
71+
file = file[j+1:]
72+
break
73+
}
74+
pEnd = j
75+
}
76+
}
77+
if pkg == dstPkg && i > 0 {
78+
trace = append(trace, fmt.Sprintf("%s:%d", file, line))
79+
}
80+
}
81+
fmt.Fprintln(
82+
os.Stderr,
83+
append([]interface{}{"[" + strings.Join(trace, ", ") + "]: "}, v...),
84+
)
85+
}

Diff for: issue314_test.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package mysql
2+
3+
import (
4+
"database/sql"
5+
"database/sql/driver"
6+
"testing"
7+
"time"
8+
)
9+
10+
// test for issue #314:
11+
// Busy buffer. Commands out of sync. Did you run multiple statements at once?
12+
13+
func test314Text(t *testing.T) {
14+
dsts := []driver.Value{sql.NullInt64{}}
15+
db, err := MySQLDriver{}.Open(dsn)
16+
if err != nil {
17+
t.Fatal(err)
18+
}
19+
defer db.Close()
20+
conn, _ := db.(*mysqlConn)
21+
rows, err := conn.Query("SELECT 1", nil)
22+
if err != nil {
23+
t.Fatal(err)
24+
}
25+
conn.Close()
26+
rows.Next(dsts) // busy buffer
27+
rows.Close()
28+
}
29+
30+
func test314Binary(t *testing.T) {
31+
dsts := []driver.Value{sql.NullInt64{}}
32+
conn, err := MySQLDriver{}.Open(dsn)
33+
if err != nil {
34+
t.Fatal(err)
35+
}
36+
defer conn.Close()
37+
stmt, err := conn.Prepare("SELECT 1")
38+
if err != nil {
39+
t.Fatal(err)
40+
}
41+
rows, err := stmt.Query(nil)
42+
if err != nil {
43+
t.Fatal(err)
44+
}
45+
stmt.Close() // busy buffer
46+
rows.Next(dsts)
47+
rows.Close() // freeze
48+
conn.Close()
49+
}
50+
51+
func Test314Text(t *testing.T) {
52+
if !available {
53+
t.Skipf("MySQL-Server not running on %s", netAddr)
54+
}
55+
defer useLogger(t.Error)()
56+
testTimebound(t, 1*time.Second, test314Text)
57+
}
58+
59+
func Test314Binary(t *testing.T) {
60+
if !available {
61+
t.Skipf("MySQL-Server not running on %s", netAddr)
62+
}
63+
defer useLogger(t.Error)()
64+
testTimebound(t, 1*time.Second, test314Binary)
65+
}

0 commit comments

Comments
 (0)