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  }