metrics_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package metrics
  2. import (
  3. "bytes"
  4. "io/ioutil"
  5. "runtime"
  6. "sync"
  7. "testing"
  8. "time"
  9. "net/http"
  10. "net/http/httptest"
  11. "github.com/grafana/grafana/pkg/bus"
  12. "github.com/grafana/grafana/pkg/components/simplejson"
  13. "github.com/grafana/grafana/pkg/models"
  14. "github.com/grafana/grafana/pkg/plugins"
  15. "github.com/grafana/grafana/pkg/setting"
  16. . "github.com/smartystreets/goconvey/convey"
  17. )
  18. func TestMetrics(t *testing.T) {
  19. Convey("Test send usage stats", t, func() {
  20. var getSystemStatsQuery *models.GetSystemStatsQuery
  21. bus.AddHandler("test", func(query *models.GetSystemStatsQuery) error {
  22. query.Result = &models.SystemStats{
  23. Dashboards: 1,
  24. Datasources: 2,
  25. Users: 3,
  26. ActiveUsers: 4,
  27. Orgs: 5,
  28. Playlists: 6,
  29. Alerts: 7,
  30. Stars: 8,
  31. Folders: 9,
  32. DashboardPermissions: 10,
  33. FolderPermissions: 11,
  34. ProvisionedDashboards: 12,
  35. Snapshots: 13,
  36. Teams: 14,
  37. }
  38. getSystemStatsQuery = query
  39. return nil
  40. })
  41. var getDataSourceStatsQuery *models.GetDataSourceStatsQuery
  42. bus.AddHandler("test", func(query *models.GetDataSourceStatsQuery) error {
  43. query.Result = []*models.DataSourceStats{
  44. {
  45. Type: models.DS_ES,
  46. Count: 9,
  47. },
  48. {
  49. Type: models.DS_PROMETHEUS,
  50. Count: 10,
  51. },
  52. {
  53. Type: "unknown_ds",
  54. Count: 11,
  55. },
  56. {
  57. Type: "unknown_ds2",
  58. Count: 12,
  59. },
  60. }
  61. getDataSourceStatsQuery = query
  62. return nil
  63. })
  64. var wg sync.WaitGroup
  65. var responseBuffer *bytes.Buffer
  66. var req *http.Request
  67. ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
  68. req = r
  69. buf, err := ioutil.ReadAll(r.Body)
  70. if err != nil {
  71. t.Fatalf("Failed to read response body, err=%v", err)
  72. }
  73. responseBuffer = bytes.NewBuffer(buf)
  74. wg.Done()
  75. }))
  76. usageStatsURL = ts.URL
  77. sendUsageStats()
  78. Convey("Given reporting not enabled and sending usage stats", func() {
  79. setting.ReportingEnabled = false
  80. sendUsageStats()
  81. Convey("Should not gather stats or call http endpoint", func() {
  82. So(getSystemStatsQuery, ShouldBeNil)
  83. So(getDataSourceStatsQuery, ShouldBeNil)
  84. So(req, ShouldBeNil)
  85. })
  86. })
  87. Convey("Given reporting enabled and sending usage stats", func() {
  88. setting.ReportingEnabled = true
  89. setting.BuildVersion = "5.0.0"
  90. wg.Add(1)
  91. sendUsageStats()
  92. Convey("Should gather stats and call http endpoint", func() {
  93. if waitTimeout(&wg, 2*time.Second) {
  94. t.Fatalf("Timed out waiting for http request")
  95. }
  96. So(getSystemStatsQuery, ShouldNotBeNil)
  97. So(getDataSourceStatsQuery, ShouldNotBeNil)
  98. So(req, ShouldNotBeNil)
  99. So(req.Method, ShouldEqual, http.MethodPost)
  100. So(req.Header.Get("Content-Type"), ShouldEqual, "application/json")
  101. So(responseBuffer, ShouldNotBeNil)
  102. j, err := simplejson.NewFromReader(responseBuffer)
  103. So(err, ShouldBeNil)
  104. So(j.Get("version").MustString(), ShouldEqual, "5_0_0")
  105. So(j.Get("os").MustString(), ShouldEqual, runtime.GOOS)
  106. So(j.Get("arch").MustString(), ShouldEqual, runtime.GOARCH)
  107. metrics := j.Get("metrics")
  108. So(metrics.Get("stats.dashboards.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Dashboards)
  109. So(metrics.Get("stats.users.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Users)
  110. So(metrics.Get("stats.orgs.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Orgs)
  111. So(metrics.Get("stats.playlist.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Playlists)
  112. So(metrics.Get("stats.plugins.apps.count").MustInt(), ShouldEqual, len(plugins.Apps))
  113. So(metrics.Get("stats.plugins.panels.count").MustInt(), ShouldEqual, len(plugins.Panels))
  114. So(metrics.Get("stats.plugins.datasources.count").MustInt(), ShouldEqual, len(plugins.DataSources))
  115. So(metrics.Get("stats.alerts.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Alerts)
  116. So(metrics.Get("stats.active_users.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.ActiveUsers)
  117. So(metrics.Get("stats.datasources.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Datasources)
  118. So(metrics.Get("stats.stars.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Stars)
  119. So(metrics.Get("stats.folders.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Folders)
  120. So(metrics.Get("stats.dashboard_permissions.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.DashboardPermissions)
  121. So(metrics.Get("stats.folder_permissions.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.FolderPermissions)
  122. So(metrics.Get("stats.provisioned_dashboards.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.ProvisionedDashboards)
  123. So(metrics.Get("stats.snapshots.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Snapshots)
  124. So(metrics.Get("stats.teams.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Teams)
  125. So(metrics.Get("stats.ds."+models.DS_ES+".count").MustInt(), ShouldEqual, 9)
  126. So(metrics.Get("stats.ds."+models.DS_PROMETHEUS+".count").MustInt(), ShouldEqual, 10)
  127. So(metrics.Get("stats.ds.other.count").MustInt(), ShouldEqual, 11+12)
  128. })
  129. })
  130. Reset(func() {
  131. ts.Close()
  132. })
  133. })
  134. }
  135. func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
  136. c := make(chan struct{})
  137. go func() {
  138. defer close(c)
  139. wg.Wait()
  140. }()
  141. select {
  142. case <-c:
  143. return false // completed normally
  144. case <-time.After(timeout):
  145. return true // timed out
  146. }
  147. }