mssql_test.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. package mssql
  2. import (
  3. "strings"
  4. "testing"
  5. "time"
  6. "github.com/go-xorm/xorm"
  7. "github.com/grafana/grafana/pkg/components/simplejson"
  8. "github.com/grafana/grafana/pkg/log"
  9. "github.com/grafana/grafana/pkg/services/sqlstore/sqlutil"
  10. "github.com/grafana/grafana/pkg/tsdb"
  11. . "github.com/smartystreets/goconvey/convey"
  12. )
  13. // To run this test, remove the Skip from SkipConvey
  14. // and set up a MSSQL db named grafana_tests and a user/password grafana/Password!
  15. // and set the variable below to the IP address of the database
  16. var serverIP string = "172.18.0.1"
  17. func TestMSSQL(t *testing.T) {
  18. SkipConvey("MSSQL", t, func() {
  19. x := InitMSSQLTestDB(t)
  20. endpoint := &MssqlQueryEndpoint{
  21. sqlEngine: &tsdb.DefaultSqlEngine{
  22. MacroEngine: NewMssqlMacroEngine(),
  23. XormEngine: x,
  24. },
  25. log: log.New("tsdb.mssql"),
  26. }
  27. sess := x.NewSession()
  28. defer sess.Close()
  29. sql := `
  30. IF OBJECT_ID('dbo.[mssql_types]', 'U') IS NOT NULL
  31. DROP TABLE dbo.[mssql_types]
  32. CREATE TABLE [mssql_types] (
  33. c_bit bit,
  34. c_tinyint tinyint,
  35. c_smallint smallint,
  36. c_int int,
  37. c_bigint bigint,
  38. c_money money,
  39. c_smallmoney smallmoney,
  40. c_numeric numeric(10,5),
  41. c_real real,
  42. c_decimal decimal(10,2),
  43. c_float float,
  44. c_char char(10),
  45. c_varchar varchar(10),
  46. c_text text,
  47. c_nchar nchar(12),
  48. c_nvarchar nvarchar(12),
  49. c_ntext ntext,
  50. c_datetime datetime,
  51. c_datetime2 datetime2,
  52. c_smalldatetime smalldatetime,
  53. c_date date,
  54. c_time time,
  55. c_datetimeoffset datetimeoffset
  56. )
  57. `
  58. _, err := sess.Exec(sql)
  59. So(err, ShouldBeNil)
  60. sql = `
  61. INSERT INTO [mssql_types]
  62. SELECT
  63. 1, 5, 20020, 980300, 1420070400, '$20000.15', '£2.15', 12345.12,
  64. 1.11, 2.22, 3.33,
  65. 'char10', 'varchar10', 'text',
  66. N'☺nchar12☺', N'☺nvarchar12☺', N'☺text☺',
  67. GETUTCDATE(), GETUTCDATE(), GETUTCDATE(), CAST(GETUTCDATE() AS DATE), CAST(GETUTCDATE() AS TIME), SWITCHOFFSET(SYSDATETIMEOFFSET(), '-07:00')
  68. `
  69. _, err = sess.Exec(sql)
  70. So(err, ShouldBeNil)
  71. Convey("Query with Table format should map MSSQL column types to Go types", func() {
  72. query := &tsdb.TsdbQuery{
  73. Queries: []*tsdb.Query{
  74. {
  75. Model: simplejson.NewFromAny(map[string]interface{}{
  76. "rawSql": "SELECT * FROM mssql_types",
  77. "format": "table",
  78. }),
  79. RefId: "A",
  80. },
  81. },
  82. }
  83. resp, err := endpoint.Query(nil, nil, query)
  84. queryResult := resp.Results["A"]
  85. So(err, ShouldBeNil)
  86. column := queryResult.Tables[0].Rows[0]
  87. So(column[0].(bool), ShouldEqual, true)
  88. So(column[1].(int64), ShouldEqual, 5)
  89. So(column[2].(int64), ShouldEqual, 20020)
  90. So(column[3].(int64), ShouldEqual, 980300)
  91. So(column[4].(int64), ShouldEqual, 1420070400)
  92. // So(column[5].(float64), ShouldEqual, 20000.15)
  93. // So(column[6].(float64), ShouldEqual, 2.15)
  94. //So(column[7].(float64), ShouldEqual, 12345.12)
  95. So(column[8].(float64), ShouldEqual, 1.1100000143051147) // MSSQL dose not have precision for "real" datatype
  96. // fix me: MSSQL driver puts the decimal inside an array of chars. and the test fails despite the values are correct.
  97. //So(column[9].([]uint8), ShouldEqual, []uint8{'2', '.', '2', '2'})
  98. So(column[10].(float64), ShouldEqual, 3.33)
  99. So(column[11].(string), ShouldEqual, "char10 ")
  100. So(column[12].(string), ShouldEqual, "varchar10")
  101. So(column[13].(string), ShouldEqual, "text")
  102. So(column[14].(string), ShouldEqual, "☺nchar12☺ ")
  103. So(column[15].(string), ShouldEqual, "☺nvarchar12☺")
  104. So(column[16].(string), ShouldEqual, "☺text☺")
  105. So(column[17].(time.Time), ShouldHappenWithin, time.Duration(10*time.Second), time.Now().UTC())
  106. So(column[18].(time.Time), ShouldHappenWithin, time.Duration(10*time.Millisecond), time.Now().UTC())
  107. So(column[19].(time.Time), ShouldHappenWithin, time.Duration(10*time.Second), time.Now().UTC().Truncate(time.Minute))
  108. So(column[20].(time.Time), ShouldHappenWithin, time.Duration(10*time.Second), time.Now().UTC().Truncate(24*time.Hour)) // ShouldEqual dose not work here !!?
  109. So(column[21].(time.Time), ShouldHappenWithin, time.Duration(10*time.Second), time.Date(1, time.January, 1, time.Now().UTC().Hour(), time.Now().UTC().Minute(), time.Now().UTC().Second(), 0, time.UTC))
  110. So(column[22].(time.Time), ShouldHappenWithin, time.Duration(10*time.Second), time.Now().UTC())
  111. })
  112. })
  113. }
  114. func InitMSSQLTestDB(t *testing.T) *xorm.Engine {
  115. x, err := xorm.NewEngine(sqlutil.TestDB_Mssql.DriverName, strings.Replace(sqlutil.TestDB_Mssql.ConnStr, "localhost", serverIP, 1))
  116. // x.ShowSQL()
  117. if err != nil {
  118. t.Fatalf("Failed to init mssql db %v", err)
  119. }
  120. sqlutil.CleanDB(x)
  121. return x
  122. }