test_stats.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. from functools import cached_property
  2. from unittest.mock import patch
  3. from django.test import RequestFactory, override_settings
  4. from rest_framework.permissions import AllowAny
  5. from rest_framework.response import Response
  6. from sentry.api.base import Endpoint
  7. from sentry.middleware.ratelimit import RatelimitMiddleware
  8. from sentry.middleware.stats import RequestTimingMiddleware, add_request_metric_tags
  9. from sentry.testutils import TestCase
  10. from sentry.testutils.helpers.faux import Mock
  11. from sentry.types.ratelimit import RateLimit, RateLimitCategory
  12. class RateLimitedEndpoint(Endpoint):
  13. permission_classes = (AllowAny,)
  14. enforce_rate_limit = True
  15. rate_limits = {"GET": {RateLimitCategory.IP: RateLimit(0, 10)}}
  16. def get(self):
  17. return Response({"ok": True})
  18. class RequestTimingMiddlewareTest(TestCase):
  19. middleware = cached_property(RequestTimingMiddleware)
  20. @cached_property
  21. def factory(self):
  22. return RequestFactory()
  23. @patch("sentry.utils.metrics.incr")
  24. def test_records_default_api_metrics(self, incr):
  25. request = self.factory.get("/")
  26. request._view_path = "/"
  27. response = Mock(status_code=200)
  28. self.middleware.process_response(request, response)
  29. incr.assert_called_with(
  30. "view.response",
  31. instance=request._view_path,
  32. tags={
  33. "method": "GET",
  34. "status_code": 200,
  35. "ui_request": False,
  36. "rate_limit_type": None,
  37. },
  38. skip_internal=False,
  39. )
  40. @patch("sentry.utils.metrics.incr")
  41. @override_settings(SENTRY_SELF_HOSTED=False)
  42. def test_records_default_api_metrics_with_rate_limit_type(self, incr):
  43. rate_limit_middleware = RatelimitMiddleware(None)
  44. test_endpoint = RateLimitedEndpoint.as_view()
  45. request = self.factory.get("/")
  46. request._view_path = "/"
  47. response = Mock(status_code=429)
  48. rate_limit_middleware.process_view(request, test_endpoint, [], {})
  49. self.middleware.process_response(request, response)
  50. incr.assert_called_with(
  51. "view.response",
  52. instance=request._view_path,
  53. tags={
  54. "method": "GET",
  55. "status_code": 429,
  56. "ui_request": False,
  57. "rate_limit_type": "fixed_window",
  58. },
  59. skip_internal=False,
  60. )
  61. @patch("sentry.utils.metrics.incr")
  62. def test_records_ui_request(self, incr):
  63. request = self.factory.get("/")
  64. request._view_path = "/"
  65. response = Mock(status_code=200)
  66. request.COOKIES = {"foo": "bar"}
  67. self.middleware.process_response(request, response)
  68. incr.assert_called_with(
  69. "view.response",
  70. instance=request._view_path,
  71. tags={"method": "GET", "status_code": 200, "ui_request": True, "rate_limit_type": None},
  72. skip_internal=False,
  73. )
  74. @patch("sentry.utils.metrics.incr")
  75. def test_records_endpoint_specific_metrics(self, incr):
  76. request = self.factory.get("/")
  77. request._view_path = "/"
  78. request._metric_tags = {"a": "b"}
  79. response = Mock(status_code=200)
  80. self.middleware.process_response(request, response)
  81. incr.assert_called_with(
  82. "view.response",
  83. instance=request._view_path,
  84. tags={
  85. "method": "GET",
  86. "status_code": 200,
  87. "ui_request": False,
  88. "a": "b",
  89. "rate_limit_type": None,
  90. },
  91. skip_internal=False,
  92. )
  93. @patch("sentry.utils.metrics.incr")
  94. def test_add_request_metric_tags(self, incr):
  95. request = self.factory.get("/")
  96. request._view_path = "/"
  97. add_request_metric_tags(request, foo="bar")
  98. response = Mock(status_code=200)
  99. self.middleware.process_response(request, response)
  100. incr.assert_called_with(
  101. "view.response",
  102. instance=request._view_path,
  103. tags={
  104. "method": "GET",
  105. "status_code": 200,
  106. "ui_request": False,
  107. "foo": "bar",
  108. "rate_limit_type": None,
  109. },
  110. skip_internal=False,
  111. )