forked from go-sql-driver/mysql
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdriver_go110_test.go
137 lines (111 loc) · 3.01 KB
/
driver_go110_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
//
// Copyright 2018 The Go-MySQL-Driver Authors. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
// +build go1.10
package mysql
import (
"context"
"database/sql"
"database/sql/driver"
"fmt"
"net"
"testing"
"time"
)
var _ driver.DriverContext = &MySQLDriver{}
type dialCtxKey struct{}
func TestConnectorObeysDialTimeouts(t *testing.T) {
if !available {
t.Skipf("MySQL server not running on %s", netAddr)
}
RegisterDialContext("dialctxtest", func(ctx context.Context, addr string) (net.Conn, error) {
var d net.Dialer
if !ctx.Value(dialCtxKey{}).(bool) {
return nil, fmt.Errorf("test error: query context is not propagated to our dialer")
}
return d.DialContext(ctx, prot, addr)
})
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@dialctxtest(%s)/%s?timeout=30s", user, pass, addr, dbname))
if err != nil {
t.Fatalf("error connecting: %s", err.Error())
}
defer db.Close()
ctx := context.WithValue(context.Background(), dialCtxKey{}, true)
_, err = db.ExecContext(ctx, "DO 1")
if err != nil {
t.Fatal(err)
}
}
func configForTests(t *testing.T) *Config {
if !available {
t.Skipf("MySQL server not running on %s", netAddr)
}
mycnf := NewConfig()
mycnf.User = user
mycnf.Passwd = pass
mycnf.Addr = addr
mycnf.Net = prot
mycnf.DBName = dbname
return mycnf
}
func TestNewConnector(t *testing.T) {
mycnf := configForTests(t)
conn, err := NewConnector(mycnf)
if err != nil {
t.Fatal(err)
}
db := sql.OpenDB(conn)
defer db.Close()
if err := db.Ping(); err != nil {
t.Fatal(err)
}
}
type slowConnection struct {
net.Conn
slowdown time.Duration
}
func (sc *slowConnection) Read(b []byte) (int, error) {
time.Sleep(sc.slowdown)
return sc.Conn.Read(b)
}
type connectorHijack struct {
driver.Connector
connErr error
}
func (cw *connectorHijack) Connect(ctx context.Context) (driver.Conn, error) {
var conn driver.Conn
conn, cw.connErr = cw.Connector.Connect(ctx)
return conn, cw.connErr
}
func TestConnectorTimeoutsDuringOpen(t *testing.T) {
RegisterDialContext("slowconn", func(ctx context.Context, addr string) (net.Conn, error) {
var d net.Dialer
conn, err := d.DialContext(ctx, prot, addr)
if err != nil {
return nil, err
}
return &slowConnection{Conn: conn, slowdown: 100 * time.Millisecond}, nil
})
mycnf := configForTests(t)
mycnf.Net = "slowconn"
conn, err := NewConnector(mycnf)
if err != nil {
t.Fatal(err)
}
hijack := &connectorHijack{Connector: conn}
db := sql.OpenDB(hijack)
defer db.Close()
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
defer cancel()
_, err = db.ExecContext(ctx, "DO 1")
if err != context.DeadlineExceeded {
t.Fatalf("ExecContext should have timed out")
}
if hijack.connErr != context.DeadlineExceeded {
t.Fatalf("(*Connector).Connect should have timed out")
}
}