1 // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
3 // Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this file,
7 // You can obtain one at http://mozilla.org/MPL/2.0/.
20 func TestScanNullTime(t *testing.T) {
21 var scanTests = []struct {
27 {tDate, false, true, tDate},
28 {sDate, false, true, tDate},
29 {[]byte(sDate), false, true, tDate},
30 {tDateTime, false, true, tDateTime},
31 {sDateTime, false, true, tDateTime},
32 {[]byte(sDateTime), false, true, tDateTime},
33 {tDate0, false, true, tDate0},
34 {sDate0, false, true, tDate0},
35 {[]byte(sDate0), false, true, tDate0},
36 {sDateTime0, false, true, tDate0},
37 {[]byte(sDateTime0), false, true, tDate0},
38 {"", true, false, tDate0},
39 {"1234", true, false, tDate0},
40 {0, true, false, tDate0},
46 for _, tst := range scanTests {
48 if (err != nil) != tst.error {
49 t.Errorf("%v: expected error status %t, got %t", tst.in, tst.error, (err != nil))
51 if nt.Valid != tst.valid {
52 t.Errorf("%v: expected valid status %t, got %t", tst.in, tst.valid, nt.Valid)
54 if nt.Time != tst.time {
55 t.Errorf("%v: expected time %v, got %v", tst.in, tst.time, nt.Time)
60 func TestLengthEncodedInteger(t *testing.T) {
61 var integerTests = []struct {
65 {0x0000000000000000, []byte{0x00}},
66 {0x0000000000000012, []byte{0x12}},
67 {0x00000000000000fa, []byte{0xfa}},
68 {0x0000000000000100, []byte{0xfc, 0x00, 0x01}},
69 {0x0000000000001234, []byte{0xfc, 0x34, 0x12}},
70 {0x000000000000ffff, []byte{0xfc, 0xff, 0xff}},
71 {0x0000000000010000, []byte{0xfd, 0x00, 0x00, 0x01}},
72 {0x0000000000123456, []byte{0xfd, 0x56, 0x34, 0x12}},
73 {0x0000000000ffffff, []byte{0xfd, 0xff, 0xff, 0xff}},
74 {0x0000000001000000, []byte{0xfe, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}},
75 {0x123456789abcdef0, []byte{0xfe, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12}},
76 {0xffffffffffffffff, []byte{0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
79 for _, tst := range integerTests {
80 num, isNull, numLen := readLengthEncodedInteger(tst.encoded)
82 t.Errorf("%x: expected %d, got NULL", tst.encoded, tst.num)
85 t.Errorf("%x: expected %d, got %d", tst.encoded, tst.num, num)
87 if numLen != len(tst.encoded) {
88 t.Errorf("%x: expected size %d, got %d", tst.encoded, len(tst.encoded), numLen)
90 encoded := appendLengthEncodedInteger(nil, num)
91 if !bytes.Equal(encoded, tst.encoded) {
92 t.Errorf("%v: expected %x, got %x", num, tst.encoded, encoded)
97 func TestFormatBinaryDateTime(t *testing.T) {
99 binary.LittleEndian.PutUint16(rawDate[:2], 1978) // years
100 rawDate[2] = 12 // months
101 rawDate[3] = 30 // days
102 rawDate[4] = 15 // hours
103 rawDate[5] = 46 // minutes
104 rawDate[6] = 23 // seconds
105 binary.LittleEndian.PutUint32(rawDate[7:], 987654) // microseconds
106 expect := func(expected string, inlen, outlen uint8) {
107 actual, _ := formatBinaryDateTime(rawDate[:inlen], outlen)
108 bytes, ok := actual.([]byte)
110 t.Errorf("formatBinaryDateTime must return []byte, was %T", actual)
112 if string(bytes) != expected {
114 "expected %q, got %q for length in %d, out %d",
115 expected, actual, inlen, outlen,
119 expect("0000-00-00", 0, 10)
120 expect("0000-00-00 00:00:00", 0, 19)
121 expect("1978-12-30", 4, 10)
122 expect("1978-12-30 15:46:23", 7, 19)
123 expect("1978-12-30 15:46:23.987654", 11, 26)
126 func TestFormatBinaryTime(t *testing.T) {
127 expect := func(expected string, src []byte, outlen uint8) {
128 actual, _ := formatBinaryTime(src, outlen)
129 bytes, ok := actual.([]byte)
131 t.Errorf("formatBinaryDateTime must return []byte, was %T", actual)
133 if string(bytes) != expected {
135 "expected %q, got %q for src=%q and outlen=%d",
136 expected, actual, src, outlen)
141 // sign (0: positive, 1: negative), days(4), hours, minutes, seconds, micro(4)
144 expect("00:00:00", []byte{}, 8)
145 expect("00:00:00.0", []byte{}, 10)
146 expect("00:00:00.000000", []byte{}, 15)
149 expect("12:34:56", []byte{0, 0, 0, 0, 0, 12, 34, 56}, 8)
150 expect("-12:34:56", []byte{1, 0, 0, 0, 0, 12, 34, 56}, 8)
151 expect("12:34:56.00", []byte{0, 0, 0, 0, 0, 12, 34, 56}, 11)
152 expect("24:34:56", []byte{0, 1, 0, 0, 0, 0, 34, 56}, 8)
153 expect("-99:34:56", []byte{1, 4, 0, 0, 0, 3, 34, 56}, 8)
154 expect("103079215103:34:56", []byte{0, 255, 255, 255, 255, 23, 34, 56}, 8)
157 expect("12:34:56.00", []byte{0, 0, 0, 0, 0, 12, 34, 56, 99, 0, 0, 0}, 11)
158 expect("12:34:56.000099", []byte{0, 0, 0, 0, 0, 12, 34, 56, 99, 0, 0, 0}, 15)
161 func TestEscapeBackslash(t *testing.T) {
162 expect := func(expected, value string) {
163 actual := string(escapeBytesBackslash([]byte{}, []byte(value)))
164 if actual != expected {
166 "expected %s, got %s",
171 actual = string(escapeStringBackslash([]byte{}, value))
172 if actual != expected {
174 "expected %s, got %s",
180 expect("foo\\0bar", "foo\x00bar")
181 expect("foo\\nbar", "foo\nbar")
182 expect("foo\\rbar", "foo\rbar")
183 expect("foo\\Zbar", "foo\x1abar")
184 expect("foo\\\"bar", "foo\"bar")
185 expect("foo\\\\bar", "foo\\bar")
186 expect("foo\\'bar", "foo'bar")
189 func TestEscapeQuotes(t *testing.T) {
190 expect := func(expected, value string) {
191 actual := string(escapeBytesQuotes([]byte{}, []byte(value)))
192 if actual != expected {
194 "expected %s, got %s",
199 actual = string(escapeStringQuotes([]byte{}, value))
200 if actual != expected {
202 "expected %s, got %s",
208 expect("foo\x00bar", "foo\x00bar") // not affected
209 expect("foo\nbar", "foo\nbar") // not affected
210 expect("foo\rbar", "foo\rbar") // not affected
211 expect("foo\x1abar", "foo\x1abar") // not affected
212 expect("foo''bar", "foo'bar") // affected
213 expect("foo\"bar", "foo\"bar") // not affected
216 func TestAtomicBool(t *testing.T) {
219 t.Fatal("Expected value to be false")
224 t.Fatal("Set(true) did not set value to 1")
227 t.Fatal("Expected value to be true")
232 t.Fatal("Expected value to be true")
237 t.Fatal("Set(false) did not set value to 0")
240 t.Fatal("Expected value to be false")
245 t.Fatal("Expected value to be false")
247 if ab.TrySet(false) {
248 t.Fatal("Expected TrySet(false) to fail")
250 if !ab.TrySet(true) {
251 t.Fatal("Expected TrySet(true) to succeed")
254 t.Fatal("Expected value to be true")
259 t.Fatal("Expected value to be true")
262 t.Fatal("Expected TrySet(true) to fail")
264 if !ab.TrySet(false) {
265 t.Fatal("Expected TrySet(false) to succeed")
268 t.Fatal("Expected value to be false")
271 ab._noCopy.Lock() // we've "tested" it ¯\_(ツ)_/¯
274 func TestAtomicError(t *testing.T) {
276 if ae.Value() != nil {
277 t.Fatal("Expected value to be nil")
280 ae.Set(ErrMalformPkt)
281 if v := ae.Value(); v != ErrMalformPkt {
283 t.Fatal("Value is still nil")
285 t.Fatal("Error did not match")
288 if ae.Value() == ErrMalformPkt {
289 t.Fatal("Error still matches old error")
291 if v := ae.Value(); v != ErrPktSync {
292 t.Fatal("Error did not match")
296 func TestIsolationLevelMapping(t *testing.T) {
298 level driver.IsolationLevel
302 level: driver.IsolationLevel(sql.LevelReadCommitted),
303 expected: "READ COMMITTED",
306 level: driver.IsolationLevel(sql.LevelRepeatableRead),
307 expected: "REPEATABLE READ",
310 level: driver.IsolationLevel(sql.LevelReadUncommitted),
311 expected: "READ UNCOMMITTED",
314 level: driver.IsolationLevel(sql.LevelSerializable),
315 expected: "SERIALIZABLE",
319 for i, td := range data {
320 if actual, err := mapIsolationLevel(td.level); actual != td.expected || err != nil {
321 t.Fatal(i, td.expected, actual, err)
325 // check unsupported mapping
326 expectedErr := "mysql: unsupported isolation level: 7"
327 actual, err := mapIsolationLevel(driver.IsolationLevel(sql.LevelLinearizable))
328 if actual != "" || err == nil {
329 t.Fatal("Expected error on unsupported isolation level")
331 if err.Error() != expectedErr {
332 t.Fatalf("Expected error to be %q, got %q", expectedErr, err)