Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/sentry/sentry_metrics/indexer/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,19 @@ def reverse_resolve(self, use_case_id: UseCaseKey, org_id: int, id: int) -> Opti
Returns None if the entry cannot be found.
"""
raise NotImplementedError()

def resolve_shared_org(self, string: str) -> Optional[int]:
"""
Look up the index for a shared (cross organisation) string.

Typically, this function will only lookup strings that are statically defined but
regardless of the mechanism these are strings that are not organisation or use-case specific.
"""
raise NotImplementedError()

def reverse_shared_org_resolve(self, id: int) -> Optional[str]:
"""Lookup the stored string given integer for a shared (cross organisation) ID.

Returns None if the entry cannot be found.
"""
raise NotImplementedError()
10 changes: 10 additions & 0 deletions src/sentry/sentry_metrics/indexer/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,13 @@ def resolve(self, use_case_id: UseCaseKey, org_id: int, string: str) -> Optional

def reverse_resolve(self, use_case_id: UseCaseKey, org_id: int, id: int) -> Optional[str]:
return self.indexer.reverse_resolve(use_case_id, org_id, id)

def resolve_shared_org(self, string: str) -> Optional[int]:
raise NotImplementedError(
"This class should not be used directly, use a wrapping class that derives from StaticStringIndexer"
)

def reverse_shared_org_resolve(self, id: int) -> Optional[str]:
raise NotImplementedError(
"This class should not be used directly, use a wrapping class that derives from StaticStringIndexer"
)
10 changes: 10 additions & 0 deletions src/sentry/sentry_metrics/indexer/cloudspanner/cloudspanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,16 @@ def reverse_resolve(self, use_case_id: UseCaseKey, org_id: int, id: int) -> Opti
else:
return str(results_list[0][0])

def resolve_shared_org(self, string: str) -> Optional[int]:
raise NotImplementedError(
"This class should not be used directly, use the wrapping class CloudSpannerIndexer"
)

def reverse_shared_org_resolve(self, id: int) -> Optional[str]:
raise NotImplementedError(
"This class should not be used directly, use the wrapping class CloudSpannerIndexer"
)


class CloudSpannerIndexer(StaticStringIndexer):
def __init__(self, **kwargs: Any) -> None:
Expand Down
10 changes: 10 additions & 0 deletions src/sentry/sentry_metrics/indexer/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ def _record(self, org_id: int, string: str) -> Optional[int]:
self._reverse[index] = string
return index

def resolve_shared_org(self, string: str) -> Optional[int]:
raise NotImplementedError(
"This class should not be used directly, use the wrapping class SimpleIndexer"
)

def reverse_shared_org_resolve(self, id: int) -> Optional[str]:
raise NotImplementedError(
"This class should not be used directly, use the wrapping class SimpleIndexer"
)


class SimpleIndexer(StaticStringIndexer):
def __init__(self) -> None:
Expand Down
10 changes: 10 additions & 0 deletions src/sentry/sentry_metrics/indexer/postgres/postgres_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,16 @@ def reverse_resolve(self, use_case_id: UseCaseKey, org_id: int, id: int) -> Opti
def _table(self, use_case_id: UseCaseKey) -> IndexerTable:
return TABLE_MAPPING[use_case_id]

def resolve_shared_org(self, string: str) -> Optional[int]:
raise NotImplementedError(
"This class should not be used directly, use the wrapping class PostgresIndexer"
)

def reverse_shared_org_resolve(self, id: int) -> Optional[str]:
raise NotImplementedError(
"This class should not be used directly, use the wrapping class PostgresIndexer"
)


class PostgresIndexer(StaticStringIndexer):
def __init__(self) -> None:
Expand Down
10 changes: 10 additions & 0 deletions src/sentry/sentry_metrics/indexer/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,13 @@ def reverse_resolve(self, use_case_id: UseCaseKey, org_id: int, id: int) -> Opti
if id in REVERSE_SHARED_STRINGS:
return REVERSE_SHARED_STRINGS[id]
return self.indexer.reverse_resolve(use_case_id=use_case_id, org_id=org_id, id=id)

def resolve_shared_org(self, string: str) -> Optional[int]:
if string in SHARED_STRINGS:
return SHARED_STRINGS[string]
return None

def reverse_shared_org_resolve(self, id: int) -> Optional[str]:
if id in REVERSE_SHARED_STRINGS:
return REVERSE_SHARED_STRINGS[id]
return None
42 changes: 42 additions & 0 deletions tests/sentry/sentry_metrics/test_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,45 @@ def test_static_strings_only() -> None:
assert results[3]["production"] == SHARED_STRINGS["production"]
assert results[3]["environment"] == SHARED_STRINGS["environment"]
assert results[3]["release"] == SHARED_STRINGS["release"]


def test_resolve_shared_org_existing_entry() -> None:
"""
Tests it is able to resolve shared strings
"""
indexer = StaticStringIndexer(MockIndexer())

actual = indexer.resolve_shared_org("release")
expected = SHARED_STRINGS["release"]

assert actual == expected


def test_reverse_resolve_shared_org_existing_entry() -> None:
"""
Tests it is able to return correct strings for known
shared string ids
"""
indexer = StaticStringIndexer(MockIndexer())

release_idx = indexer.resolve_shared_org("release")
actual = indexer.reverse_shared_org_resolve(release_idx)

assert actual == "release"


def test_resolve_shared_org_no_entry() -> None:
"""
Tests that it returns None for unknown strings
"""
indexer = StaticStringIndexer(MockIndexer())
actual = indexer.resolve_shared_org("SOME_MADE_UP_STRING")
assert actual is None


def test_reverse_resolve_shared_org_no_entry() -> None:
indexer = StaticStringIndexer(MockIndexer())

# shared string start quite high 2^63 so anything smaller should return None
actual = indexer.reverse_shared_org_resolve(5)
assert actual is None