github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/server/server_test.go (about) 1 // Copyright 2015 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package server 15 16 import ( 17 "database/sql" 18 "encoding/json" 19 "net/http" 20 "testing" 21 22 "github.com/insionng/yougam/libraries/go-sql-driver/mysql" 23 . "github.com/insionng/yougam/libraries/pingcap/check" 24 tmysql "github.com/insionng/yougam/libraries/pingcap/tidb/mysql" 25 ) 26 27 func TestT(t *testing.T) { 28 TestingT(t) 29 } 30 31 var regression = true 32 33 var dsn = "root@tcp(localhost:4001)/test?strict=true" 34 35 func runTests(c *C, dsn string, tests ...func(dbt *DBTest)) { 36 db, err := sql.Open("mysql", dsn) 37 c.Assert(err, IsNil, Commentf("Error connecting")) 38 defer db.Close() 39 40 db.Exec("DROP TABLE IF EXISTS test") 41 42 dbt := &DBTest{c, db} 43 for _, test := range tests { 44 test(dbt) 45 dbt.db.Exec("DROP TABLE IF EXISTS test") 46 } 47 } 48 49 type DBTest struct { 50 *C 51 db *sql.DB 52 } 53 54 func (dbt *DBTest) fail(method, query string, err error) { 55 if len(query) > 300 { 56 query = "[query too large to print]" 57 } 58 dbt.Fatalf("Error on %s %s: %s", method, query, err.Error()) 59 } 60 61 func (dbt *DBTest) mustExec(query string, args ...interface{}) (res sql.Result) { 62 res, err := dbt.db.Exec(query, args...) 63 dbt.Assert(err, IsNil, Commentf("Exec %s", query)) 64 return res 65 } 66 67 func (dbt *DBTest) mustQuery(query string, args ...interface{}) (rows *sql.Rows) { 68 rows, err := dbt.db.Query(query, args...) 69 dbt.Assert(err, IsNil, Commentf("Query %s", query)) 70 return rows 71 } 72 73 func (dbt *DBTest) mustQueryRows(query string, args ...interface{}) { 74 rows := dbt.mustQuery(query, args...) 75 dbt.Assert(rows.Next(), IsTrue) 76 rows.Close() 77 } 78 79 func runTestRegression(c *C) { 80 runTests(c, dsn, func(dbt *DBTest) { 81 // Create Table 82 dbt.mustExec("CREATE TABLE test (val TINYINT)") 83 84 // Test for unexpected data 85 var out bool 86 rows := dbt.mustQuery("SELECT * FROM test") 87 dbt.Assert(rows.Next(), IsFalse, Commentf("unexpected data in empty table")) 88 89 // Create Data 90 res := dbt.mustExec("INSERT INTO test VALUES (1)") 91 // res := dbt.mustExec("INSERT INTO test VALUES (?)", 1) 92 count, err := res.RowsAffected() 93 dbt.Assert(err, IsNil) 94 dbt.Check(count, Equals, int64(1)) 95 id, err := res.LastInsertId() 96 dbt.Assert(err, IsNil) 97 dbt.Check(id, Equals, int64(0)) 98 99 // Read 100 rows = dbt.mustQuery("SELECT val FROM test") 101 if rows.Next() { 102 rows.Scan(&out) 103 dbt.Check(out, IsTrue) 104 dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data")) 105 } else { 106 dbt.Error("no data") 107 } 108 rows.Close() 109 110 // Update 111 res = dbt.mustExec("UPDATE test SET val = 0 WHERE val = ?", 1) 112 count, err = res.RowsAffected() 113 dbt.Assert(err, IsNil) 114 dbt.Check(count, Equals, int64(1)) 115 116 // Check Update 117 rows = dbt.mustQuery("SELECT val FROM test") 118 if rows.Next() { 119 rows.Scan(&out) 120 dbt.Check(out, IsFalse) 121 dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data")) 122 } else { 123 dbt.Error("no data") 124 } 125 rows.Close() 126 127 // Delete 128 res = dbt.mustExec("DELETE FROM test WHERE val = 0") 129 // res = dbt.mustExec("DELETE FROM test WHERE val = ?", 0) 130 count, err = res.RowsAffected() 131 dbt.Assert(err, IsNil) 132 dbt.Check(count, Equals, int64(1)) 133 134 // Check for unexpected rows 135 res = dbt.mustExec("DELETE FROM test") 136 count, err = res.RowsAffected() 137 dbt.Assert(err, IsNil) 138 dbt.Check(count, Equals, int64(0)) 139 140 dbt.mustQueryRows("SELECT 1") 141 142 b := []byte{} 143 if err := dbt.db.QueryRow("SELECT ?", b).Scan(&b); err != nil { 144 dbt.Fatal(err) 145 } 146 if b == nil { 147 dbt.Error("nil echo from non-nil input") 148 } 149 }) 150 } 151 152 func runTestPrepareResultFieldType(t *C) { 153 var param int64 = 83 154 runTests(t, dsn, func(dbt *DBTest) { 155 stmt, err := dbt.db.Prepare(`SELECT ?`) 156 if err != nil { 157 dbt.Fatal(err) 158 } 159 defer stmt.Close() 160 row := stmt.QueryRow(param) 161 var result int64 162 err = row.Scan(&result) 163 if err != nil { 164 dbt.Fatal(err) 165 } 166 switch { 167 case result != param: 168 dbt.Fatal("Unexpected result value") 169 } 170 }) 171 } 172 173 func runTestSpecialType(t *C) { 174 runTests(t, dsn, func(dbt *DBTest) { 175 dbt.mustExec("create table test (a decimal(10, 5), b datetime, c time)") 176 dbt.mustExec("insert test values (1.4, '2012-12-21 12:12:12', '4:23:34')") 177 rows := dbt.mustQuery("select * from test where a > ?", 0) 178 t.Assert(rows.Next(), IsTrue) 179 var outA float64 180 var outB, outC string 181 err := rows.Scan(&outA, &outB, &outC) 182 t.Assert(err, IsNil) 183 t.Assert(outA, Equals, 1.4) 184 t.Assert(outB, Equals, "2012-12-21 12:12:12") 185 t.Assert(outC, Equals, "04:23:34") 186 }) 187 } 188 189 func runTestPreparedString(t *C) { 190 runTests(t, dsn, func(dbt *DBTest) { 191 dbt.mustExec("create table test (a char(10), b char(10))") 192 dbt.mustExec("insert test values (?, ?)", "abcdeabcde", "abcde") 193 rows := dbt.mustQuery("select * from test where 1 = ?", 1) 194 t.Assert(rows.Next(), IsTrue) 195 var outA, outB string 196 err := rows.Scan(&outA, &outB) 197 t.Assert(err, IsNil) 198 t.Assert(outA, Equals, "abcdeabcde") 199 t.Assert(outB, Equals, "abcde") 200 }) 201 } 202 203 func runTestConcurrentUpdate(c *C) { 204 runTests(c, dsn, func(dbt *DBTest) { 205 dbt.mustExec("create table test (a int, b int)") 206 dbt.mustExec("insert test values (1, 1)") 207 txn1, err := dbt.db.Begin() 208 c.Assert(err, IsNil) 209 210 txn2, err := dbt.db.Begin() 211 c.Assert(err, IsNil) 212 213 _, err = txn2.Exec("update test set a = a + 1 where b = 1") 214 c.Assert(err, IsNil) 215 err = txn2.Commit() 216 c.Assert(err, IsNil) 217 218 _, err = txn1.Exec("update test set a = a + 1 where b = 1") 219 c.Assert(err, IsNil) 220 221 err = txn1.Commit() 222 c.Assert(err, IsNil) 223 }) 224 } 225 226 func runTestErrorCode(c *C) { 227 runTests(c, dsn, func(dbt *DBTest) { 228 dbt.mustExec("create table test (c int PRIMARY KEY);") 229 dbt.mustExec("insert into test values (1);") 230 txn1, err := dbt.db.Begin() 231 c.Assert(err, IsNil) 232 _, err = txn1.Exec("insert into test values(1)") 233 c.Assert(err, IsNil) 234 err = txn1.Commit() 235 checkErrorCode(c, err, tmysql.ErrDupEntry) 236 237 // Schema errors 238 txn2, err := dbt.db.Begin() 239 c.Assert(err, IsNil) 240 _, err = txn2.Exec("use db_not_exists;") 241 checkErrorCode(c, err, tmysql.ErrBadDB) 242 _, err = txn2.Exec("select * from tbl_not_exists;") 243 checkErrorCode(c, err, tmysql.ErrNoSuchTable) 244 _, err = txn2.Exec("create database test;") 245 checkErrorCode(c, err, tmysql.ErrDBCreateExists) 246 _, err = txn2.Exec("create table test (c int);") 247 checkErrorCode(c, err, tmysql.ErrTableExists) 248 _, err = txn2.Exec("drop table unknown_table;") 249 checkErrorCode(c, err, tmysql.ErrBadTable) 250 _, err = txn2.Exec("drop database unknown_db;") 251 checkErrorCode(c, err, tmysql.ErrDBDropExists) 252 253 // Optimizer errors 254 _, err = txn2.Exec("select *, * from test;") 255 checkErrorCode(c, err, tmysql.ErrParse) 256 _, err = txn2.Exec("select row(1, 2) > 1;") 257 checkErrorCode(c, err, tmysql.ErrOperandColumns) 258 _, err = txn2.Exec("select * from test order by row(c, c);") 259 checkErrorCode(c, err, tmysql.ErrOperandColumns) 260 261 // Variable errors 262 _, err = txn2.Exec("select @@unknown_sys_var;") 263 checkErrorCode(c, err, tmysql.ErrUnknownSystemVariable) 264 _, err = txn2.Exec("set @@unknown_sys_var='1';") 265 checkErrorCode(c, err, tmysql.ErrUnknownSystemVariable) 266 }) 267 } 268 269 func checkErrorCode(c *C, e error, code uint16) { 270 me, ok := e.(*mysql.MySQLError) 271 c.Assert(ok, IsTrue) 272 c.Assert(me.Number, Equals, code) 273 } 274 275 func runTestAuth(c *C) { 276 runTests(c, dsn, func(dbt *DBTest) { 277 dbt.mustExec(`CREATE USER 'test'@'%' IDENTIFIED BY '123';`) 278 }) 279 newDsn := "test:123@tcp(localhost:4001)/test?strict=true" 280 runTests(c, newDsn, func(dbt *DBTest) { 281 dbt.mustExec(`USE mysql;`) 282 }) 283 284 db, err := sql.Open("mysql", "test:456@tcp(localhost:4001)/test?strict=true") 285 _, err = db.Query("USE mysql;") 286 c.Assert(err, NotNil, Commentf("Wrong password should be failed")) 287 db.Close() 288 } 289 290 func runTestIssues(c *C) { 291 // For issue #263 292 unExistsSchemaDsn := "root@tcp(localhost:4001)/unexists_schema?strict=true" 293 db, err := sql.Open("mysql", unExistsSchemaDsn) 294 c.Assert(db, NotNil) 295 c.Assert(err, IsNil) 296 // Open may just validate its arguments without creating a connection to the database. To verify that the data source name is valid, call Ping. 297 err = db.Ping() 298 c.Assert(err, NotNil, Commentf("Connecting to an unexists schema should be error")) 299 db.Close() 300 } 301 302 func runTestResultFieldTableIsNull(c *C) { 303 runTests(c, dsn, func(dbt *DBTest) { 304 dbt.mustExec("drop table if exists test;") 305 dbt.mustExec("create table test (c int);") 306 dbt.mustExec("explain select * from test;") 307 }) 308 } 309 310 func runTestStatusAPI(c *C) { 311 resp, err := http.Get("http://127.0.0.1:10090/status") 312 c.Assert(err, IsNil) 313 defer resp.Body.Close() 314 decoder := json.NewDecoder(resp.Body) 315 var data status 316 err = decoder.Decode(&data) 317 c.Assert(err, IsNil) 318 c.Assert(data.Version, Equals, tmysql.ServerVersion) 319 }