forked from adamlaska/boulder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase_test.go
More file actions
156 lines (141 loc) · 4.88 KB
/
database_test.go
File metadata and controls
156 lines (141 loc) · 4.88 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package sa
import (
"database/sql"
"errors"
"strings"
"testing"
"time"
"github.com/letsencrypt/boulder/test"
"github.com/letsencrypt/boulder/test/vars"
)
func TestInvalidDSN(t *testing.T) {
_, err := NewDbMap("invalid", DbSettings{})
test.AssertError(t, err, "DB connect string missing the slash separating the database name")
}
var errExpected = errors.New("expected")
func TestDbSettings(t *testing.T) {
// TODO(#5248): Add a full db.mockWrappedMap to sa/database tests
oldSetMaxOpenConns := setMaxOpenConns
oldSetMaxIdleConns := setMaxIdleConns
oldSetConnMaxLifetime := setConnMaxLifetime
oldSetConnMaxIdleTime := setConnMaxIdleTime
defer func() {
setMaxOpenConns = oldSetMaxOpenConns
setMaxIdleConns = oldSetMaxIdleConns
setConnMaxLifetime = oldSetConnMaxLifetime
setConnMaxIdleTime = oldSetConnMaxIdleTime
}()
maxOpenConns := -1
maxIdleConns := -1
connMaxLifetime := time.Second * 1
connMaxIdleTime := time.Second * 1
setMaxOpenConns = func(db *sql.DB, m int) {
maxOpenConns = m
oldSetMaxOpenConns(db, maxOpenConns)
}
setMaxIdleConns = func(db *sql.DB, m int) {
maxIdleConns = m
oldSetMaxIdleConns(db, maxIdleConns)
}
setConnMaxLifetime = func(db *sql.DB, c time.Duration) {
connMaxLifetime = c
oldSetConnMaxLifetime(db, connMaxLifetime)
}
setConnMaxIdleTime = func(db *sql.DB, c time.Duration) {
connMaxIdleTime = c
oldSetConnMaxIdleTime(db, connMaxIdleTime)
}
dbSettings := DbSettings{
MaxOpenConns: 100,
MaxIdleConns: 100,
ConnMaxLifetime: 100,
ConnMaxIdleTime: 100,
}
_, err := NewDbMap("sa@tcp(boulder-mysql:3306)/boulder_sa_integration", dbSettings)
if err != nil {
t.Errorf("connecting to DB: %s", err)
}
if maxOpenConns != 100 {
t.Errorf("maxOpenConns was not set: expected %d, got %d", 100, maxOpenConns)
}
if maxIdleConns != 100 {
t.Errorf("maxIdleConns was not set: expected %d, got %d", 100, maxIdleConns)
}
if connMaxLifetime != 100 {
t.Errorf("connMaxLifetime was not set: expected %d, got %d", 100, connMaxLifetime)
}
if connMaxIdleTime != 100 {
t.Errorf("connMaxIdleTime was not set: expected %d, got %d", 100, connMaxIdleTime)
}
}
func TestNewDbMap(t *testing.T) {
const mysqlConnectURL = "policy:password@tcp(boulder-mysql:3306)/boulder_policy_integration?readTimeout=800ms&writeTimeout=800ms"
const expected = "policy:password@tcp(boulder-mysql:3306)/boulder_policy_integration?clientFoundRows=true&parseTime=true&readTimeout=800ms&writeTimeout=800ms&long_query_time=0.6400000000000001&max_statement_time=0.76&sql_mode=STRICT_ALL_TABLES"
oldSQLOpen := sqlOpen
defer func() {
sqlOpen = oldSQLOpen
}()
sqlOpen = func(dbType, connectString string) (*sql.DB, error) {
if connectString != expected {
t.Errorf("incorrect connection string mangling, want %#v, got %#v", expected, connectString)
}
return nil, errExpected
}
dbMap, err := NewDbMap(mysqlConnectURL, DbSettings{})
if err != errExpected {
t.Errorf("got incorrect error. Got %v, expected %v", err, errExpected)
}
if dbMap != nil {
t.Errorf("expected nil, got %v", dbMap)
}
}
func TestStrictness(t *testing.T) {
dbMap, err := NewDbMap(vars.DBConnSA, DbSettings{1, 0, 0, 0})
if err != nil {
t.Fatal(err)
}
_, err = dbMap.Exec(`insert into orderToAuthz2 set
orderID=999999999999999999999999999,
authzID=999999999999999999999999999;`)
if err == nil {
t.Fatal("Expected error when providing out of range value, got none.")
}
if !strings.Contains(err.Error(), "Out of range value for column") {
t.Fatalf("Got wrong type of error: %s", err)
}
}
func TestTimeouts(t *testing.T) {
dbMap, err := NewDbMap(vars.DBConnSA+"?readTimeout=1s", DbSettings{1, 0, 0, 0})
if err != nil {
t.Fatal("Error setting up DB:", err)
}
// SLEEP is defined to return 1 if it was interrupted, but we want to actually
// get an error to simulate what would happen with a slow query. So we wrap
// the SLEEP in a subselect.
_, err = dbMap.Exec(`SELECT 1 FROM (SELECT SLEEP(5)) as subselect;`)
if err == nil {
t.Fatal("Expected error when running slow query, got none.")
}
// We expect to get:
// Error 1969: Query execution was interrupted (max_statement_time exceeded)
// https://mariadb.com/kb/en/mariadb/mariadb-error-codes/
if !strings.Contains(err.Error(), "Error 1969") {
t.Fatalf("Got wrong type of error: %s", err)
}
}
// TestAutoIncrementSchema tests that all of the tables in the boulder_*
// databases that have auto_increment columns use BIGINT for the data type. Our
// data is too big for INT.
func TestAutoIncrementSchema(t *testing.T) {
dbMap, err := NewDbMap(vars.DBInfoSchemaRoot, DbSettings{1, 0, 0, 0})
test.AssertNotError(t, err, "unexpected err making NewDbMap")
var count int64
err = dbMap.SelectOne(
&count,
`SELECT COUNT(1) FROM columns WHERE
table_schema LIKE 'boulder%' AND
extra LIKE '%auto_increment%' AND
data_type != "bigint"`)
test.AssertNotError(t, err, "unexpected err querying columns")
test.AssertEquals(t, count, int64(0))
}