recovery_test.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package middleware
  2. import (
  3. "path/filepath"
  4. "testing"
  5. "github.com/grafana/grafana/pkg/bus"
  6. "github.com/grafana/grafana/pkg/infra/remotecache"
  7. m "github.com/grafana/grafana/pkg/models"
  8. "github.com/grafana/grafana/pkg/services/auth"
  9. "github.com/grafana/grafana/pkg/setting"
  10. . "github.com/smartystreets/goconvey/convey"
  11. macaron "gopkg.in/macaron.v1"
  12. )
  13. func TestRecoveryMiddleware(t *testing.T) {
  14. setting.ERR_TEMPLATE_NAME = "error-template"
  15. Convey("Given an api route that panics", t, func() {
  16. apiURL := "/api/whatever"
  17. recoveryScenario(t, "recovery middleware should return json", apiURL, func(sc *scenarioContext) {
  18. sc.handlerFunc = PanicHandler
  19. sc.fakeReq("GET", apiURL).exec()
  20. sc.req.Header.Add("content-type", "application/json")
  21. So(sc.resp.Code, ShouldEqual, 500)
  22. So(sc.respJson["message"], ShouldStartWith, "Internal Server Error - Check the Grafana server logs for the detailed error message.")
  23. So(sc.respJson["error"], ShouldStartWith, "Server Error")
  24. })
  25. })
  26. Convey("Given a non-api route that panics", t, func() {
  27. apiURL := "/whatever"
  28. recoveryScenario(t, "recovery middleware should return html", apiURL, func(sc *scenarioContext) {
  29. sc.handlerFunc = PanicHandler
  30. sc.fakeReq("GET", apiURL).exec()
  31. So(sc.resp.Code, ShouldEqual, 500)
  32. So(sc.resp.Header().Get("content-type"), ShouldEqual, "text/html; charset=UTF-8")
  33. So(sc.resp.Body.String(), ShouldContainSubstring, "<title>Grafana - Error</title>")
  34. })
  35. })
  36. }
  37. func PanicHandler(c *m.ReqContext) {
  38. panic("Handler has panicked")
  39. }
  40. func recoveryScenario(t *testing.T, desc string, url string, fn scenarioFunc) {
  41. Convey(desc, func() {
  42. defer bus.ClearBusHandlers()
  43. sc := &scenarioContext{
  44. url: url,
  45. }
  46. viewsPath, _ := filepath.Abs("../../public/views")
  47. sc.m = macaron.New()
  48. sc.m.Use(Recovery())
  49. sc.m.Use(macaron.Renderer(macaron.RenderOptions{
  50. Directory: viewsPath,
  51. Delims: macaron.Delims{Left: "[[", Right: "]]"},
  52. }))
  53. sc.userAuthTokenService = auth.NewFakeUserAuthTokenService()
  54. sc.remoteCacheService = remotecache.NewFakeStore(t)
  55. sc.m.Use(GetContextHandler(sc.userAuthTokenService, sc.remoteCacheService))
  56. // mock out gc goroutine
  57. sc.m.Use(OrgRedirect())
  58. sc.m.Use(AddDefaultResponseHeaders())
  59. sc.defaultHandler = func(c *m.ReqContext) {
  60. sc.context = c
  61. if sc.handlerFunc != nil {
  62. sc.handlerFunc(sc.context)
  63. }
  64. }
  65. sc.m.Get(url, sc.defaultHandler)
  66. fn(sc)
  67. })
  68. }