mysql_test.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package mysql
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/go-xorm/xorm"
  6. "github.com/grafana/grafana/pkg/components/simplejson"
  7. "github.com/grafana/grafana/pkg/log"
  8. "github.com/grafana/grafana/pkg/services/sqlstore/sqlutil"
  9. "github.com/grafana/grafana/pkg/tsdb"
  10. . "github.com/smartystreets/goconvey/convey"
  11. )
  12. // To run this test, remove the Skip from SkipConvey
  13. // and set up a MySQL db named grafana_tests and a user/password grafana/password
  14. func TestMySQL(t *testing.T) {
  15. SkipConvey("MySQL", t, func() {
  16. x := InitMySQLTestDB(t)
  17. endpoint := &MysqlQueryEndpoint{
  18. sqlEngine: &tsdb.DefaultSqlEngine{
  19. MacroEngine: NewMysqlMacroEngine(),
  20. XormEngine: x,
  21. },
  22. log: log.New("tsdb.mysql"),
  23. }
  24. sess := x.NewSession()
  25. defer sess.Close()
  26. sql := "CREATE TABLE `mysql_types` ("
  27. sql += "`atinyint` tinyint(1) NOT NULL,"
  28. sql += "`avarchar` varchar(3) NOT NULL,"
  29. sql += "`achar` char(3),"
  30. sql += "`amediumint` mediumint NOT NULL,"
  31. sql += "`asmallint` smallint NOT NULL,"
  32. sql += "`abigint` bigint NOT NULL,"
  33. sql += "`aint` int(11) NOT NULL,"
  34. sql += "`adouble` double(10,2),"
  35. sql += "`anewdecimal` decimal(10,2),"
  36. sql += "`afloat` float(10,2) NOT NULL,"
  37. sql += "`atimestamp` timestamp NOT NULL,"
  38. sql += "`adatetime` datetime NOT NULL,"
  39. sql += "`atime` time NOT NULL,"
  40. // sql += "`ayear` year," // Crashes xorm when running cleandb
  41. sql += "`abit` bit(1),"
  42. sql += "`atinytext` tinytext,"
  43. sql += "`atinyblob` tinyblob,"
  44. sql += "`atext` text,"
  45. sql += "`ablob` blob,"
  46. sql += "`amediumtext` mediumtext,"
  47. sql += "`amediumblob` mediumblob,"
  48. sql += "`alongtext` longtext,"
  49. sql += "`alongblob` longblob,"
  50. sql += "`aenum` enum('val1', 'val2'),"
  51. sql += "`aset` set('a', 'b', 'c', 'd'),"
  52. sql += "`adate` date,"
  53. sql += "`time_sec` datetime(6),"
  54. sql += "`aintnull` int(11),"
  55. sql += "`afloatnull` float(10,2),"
  56. sql += "`avarcharnull` varchar(3),"
  57. sql += "`adecimalnull` decimal(10,2)"
  58. sql += ") ENGINE=InnoDB DEFAULT CHARSET=latin1;"
  59. _, err := sess.Exec(sql)
  60. So(err, ShouldBeNil)
  61. sql = "INSERT INTO `mysql_types` "
  62. sql += "(`atinyint`, `avarchar`, `achar`, `amediumint`, `asmallint`, `abigint`, `aint`, `adouble`, "
  63. sql += "`anewdecimal`, `afloat`, `adatetime`, `atimestamp`, `atime`, `abit`, `atinytext`, "
  64. sql += "`atinyblob`, `atext`, `ablob`, `amediumtext`, `amediumblob`, `alongtext`, `alongblob`, "
  65. sql += "`aenum`, `aset`, `adate`, `time_sec`) "
  66. sql += "VALUES(1, 'abc', 'def', 1, 10, 100, 1420070400, 1.11, "
  67. sql += "2.22, 3.33, now(), current_timestamp(), '11:11:11', 1, 'tinytext', "
  68. sql += "'tinyblob', 'text', 'blob', 'mediumtext', 'mediumblob', 'longtext', 'longblob', "
  69. sql += "'val2', 'a,b', curdate(), '2018-01-01 00:01:01.123456');"
  70. _, err = sess.Exec(sql)
  71. So(err, ShouldBeNil)
  72. Convey("Query with Table format should map MySQL column types to Go types", func() {
  73. query := &tsdb.TsdbQuery{
  74. Queries: []*tsdb.Query{
  75. {
  76. Model: simplejson.NewFromAny(map[string]interface{}{
  77. "rawSql": "SELECT * FROM mysql_types",
  78. "format": "table",
  79. }),
  80. RefId: "A",
  81. },
  82. },
  83. }
  84. resp, err := endpoint.Query(nil, nil, query)
  85. queryResult := resp.Results["A"]
  86. So(err, ShouldBeNil)
  87. column := queryResult.Tables[0].Rows[0]
  88. So(*column[0].(*int8), ShouldEqual, 1)
  89. So(column[1].(string), ShouldEqual, "abc")
  90. So(column[2].(string), ShouldEqual, "def")
  91. So(*column[3].(*int32), ShouldEqual, 1)
  92. So(*column[4].(*int16), ShouldEqual, 10)
  93. So(*column[5].(*int64), ShouldEqual, 100)
  94. So(*column[6].(*int32), ShouldEqual, 1420070400)
  95. So(column[7].(float64), ShouldEqual, 1.11)
  96. So(column[8].(float64), ShouldEqual, 2.22)
  97. So(*column[9].(*float32), ShouldEqual, 3.33)
  98. _, offset := time.Now().Zone()
  99. So(column[10].(time.Time), ShouldHappenWithin, time.Duration(10*time.Second), time.Now().Add(time.Duration(offset)*time.Second))
  100. So(column[11].(time.Time), ShouldHappenWithin, time.Duration(10*time.Second), time.Now().Add(time.Duration(offset)*time.Second))
  101. So(column[12].(string), ShouldEqual, "11:11:11")
  102. So(*column[13].(*[]byte), ShouldHaveSameTypeAs, []byte{1})
  103. So(column[14].(string), ShouldEqual, "tinytext")
  104. So(column[15].(string), ShouldEqual, "tinyblob")
  105. So(column[16].(string), ShouldEqual, "text")
  106. So(column[17].(string), ShouldEqual, "blob")
  107. So(column[18].(string), ShouldEqual, "mediumtext")
  108. So(column[19].(string), ShouldEqual, "mediumblob")
  109. So(column[20].(string), ShouldEqual, "longtext")
  110. So(column[21].(string), ShouldEqual, "longblob")
  111. So(column[22].(string), ShouldEqual, "val2")
  112. So(column[23].(string), ShouldEqual, "a,b")
  113. So(column[24].(time.Time).Format("2006-01-02T00:00:00Z"), ShouldEqual, time.Now().Format("2006-01-02T00:00:00Z"))
  114. So(column[25].(float64), ShouldEqual, 1514764861)
  115. So(column[26], ShouldEqual, nil)
  116. So(column[27], ShouldEqual, nil)
  117. So(column[28], ShouldEqual, "")
  118. So(column[29], ShouldEqual, nil)
  119. })
  120. })
  121. }
  122. func InitMySQLTestDB(t *testing.T) *xorm.Engine {
  123. x, err := xorm.NewEngine(sqlutil.TestDB_Mysql.DriverName, sqlutil.TestDB_Mysql.ConnStr+"&parseTime=true")
  124. // x.ShowSQL()
  125. if err != nil {
  126. t.Fatalf("Failed to init mysql db %v", err)
  127. }
  128. sqlutil.CleanDB(x)
  129. return x
  130. }