test_strings.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import pytest
  2. from django.test import override_settings
  3. from sentry.sentry_metrics.indexer.mock import MockIndexer
  4. from sentry.sentry_metrics.indexer.strings import PREFIX, SHARED_STRINGS, StaticStringIndexer
  5. from sentry.sentry_metrics.use_case_id_registry import UseCaseID
  6. from sentry.snuba.metrics.naming_layer.mri import parse_mri
  7. use_case_id = UseCaseID.SESSIONS
  8. def test_static_strings_only() -> None:
  9. indexer = StaticStringIndexer(MockIndexer())
  10. org_strings = {2: {"release"}, 3: {"production", "environment", "release"}}
  11. results = indexer.bulk_record({use_case_id: org_strings})
  12. assert results[use_case_id][2]["release"] == SHARED_STRINGS["release"]
  13. assert results[use_case_id][3]["production"] == SHARED_STRINGS["production"]
  14. assert results[use_case_id][3]["environment"] == SHARED_STRINGS["environment"]
  15. assert results[use_case_id][3]["release"] == SHARED_STRINGS["release"]
  16. def test_resolve_shared_org_existing_entry() -> None:
  17. """
  18. Tests it is able to resolve shared strings
  19. """
  20. indexer = StaticStringIndexer(MockIndexer())
  21. actual = indexer.resolve_shared_org("release")
  22. expected = SHARED_STRINGS["release"]
  23. assert actual == expected
  24. def test_reverse_resolve_shared_org_existing_entry() -> None:
  25. """
  26. Tests it is able to return correct strings for known
  27. shared string ids
  28. """
  29. indexer = StaticStringIndexer(MockIndexer())
  30. release_idx = indexer.resolve_shared_org("release")
  31. assert release_idx is not None
  32. actual = indexer.reverse_shared_org_resolve(release_idx)
  33. assert actual == "release"
  34. def test_resolve_shared_org_no_entry() -> None:
  35. """
  36. Tests that it returns None for unknown strings
  37. """
  38. indexer = StaticStringIndexer(MockIndexer())
  39. actual = indexer.resolve_shared_org("SOME_MADE_UP_STRING")
  40. assert actual is None
  41. def test_reverse_resolve_shared_org_no_entry() -> None:
  42. indexer = StaticStringIndexer(MockIndexer())
  43. # shared string start quite high 2^63 so anything smaller should return None
  44. actual = indexer.reverse_shared_org_resolve(5)
  45. assert actual is None
  46. REINDEXED_INTS = {12345678: "release"}
  47. @override_settings(SENTRY_METRICS_INDEXER_REINDEXED_INTS=REINDEXED_INTS)
  48. def test_reverse_resolve_reindexed():
  49. """
  50. If we have deleted a record accidentally and whose id still lives in
  51. ClickHouse, then we need to account for the re-indexed id. Since the
  52. indexer table has a unique contraint on the org and string, we have a
  53. hardcoded setting that let's us patch reverse_resolve so that we don't
  54. get MetricIndexNotFound and return a 500.
  55. """
  56. indexer = StaticStringIndexer(MockIndexer())
  57. id = indexer.record(use_case_id, 2, "release")
  58. # for mypy
  59. assert id
  60. assert indexer.reverse_resolve(UseCaseID.SESSIONS, 1, id) == "release"
  61. assert indexer.reverse_resolve(UseCaseID.SESSIONS, 1, 12345678) == "release"
  62. @pytest.mark.parametrize(
  63. ["mri", "id"],
  64. [
  65. pytest.param(
  66. string,
  67. id,
  68. marks=pytest.mark.skipif(
  69. string
  70. in {
  71. "s:transactions/span.user@none",
  72. "d:transactions/span.duration@millisecond",
  73. "d:transactions/span.exclusive_time@millisecond",
  74. },
  75. reason="deprecated MRI",
  76. ),
  77. id=string,
  78. )
  79. for string, id in SHARED_STRINGS.items()
  80. if parse_mri(string) is not None
  81. ],
  82. )
  83. def test_shared_mri_string_range(mri, id):
  84. parsed_mri = parse_mri(mri)
  85. assert parsed_mri is not None, mri
  86. try:
  87. start, end = {
  88. "sessions": (1, 99),
  89. "transactions": (100, 199),
  90. "spans": (400, 499),
  91. "escalating_issues": (500, 599),
  92. "profiles": (600, 699),
  93. "bundle_analysis": (700, 799),
  94. "metric_stats": (800, 899),
  95. }[parsed_mri.namespace]
  96. except KeyError:
  97. raise Exception(f"Unknown namespace: {parsed_mri.namespace}")
  98. start += PREFIX
  99. end += PREFIX
  100. assert (
  101. start <= id <= end
  102. ), f"id for MRI: {mri} fall outside of expected range. Expected {start} - {end}, got {id}"