Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshFerge committed Sep 11, 2024
1 parent 4c5a138 commit a6e3bef
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/sentry/models/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def filter_by_semver_build(
self,
organization_id: int,
operator: str,
build: str,
build: str | Sequence[str],
project_ids: Sequence[int] | None = None,
negated: bool = False,
) -> models.QuerySet:
Expand Down
49 changes: 41 additions & 8 deletions src/sentry/models/releases/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def filter_by_semver_build(
self,
organization_id: int,
operator: str,
build: str,
build: str | Sequence[str],
project_ids: Sequence[int] | None = None,
negated: bool = False,
) -> Self:
Expand All @@ -80,16 +80,49 @@ def filter_by_semver_build(
"release_id", flat=True
)
)
if isinstance(build, str):
if build.isdecimal() and validate_bigint(int(build)):
qs = getattr(qs, query_func)(**{f"build_number__{operator}": int(build)})
else:
if not build or build.endswith("*"):
qs = getattr(qs, query_func)(build_code__startswith=build[:-1])
else:
qs = getattr(qs, query_func)(build_code=build)

if build.isdecimal() and validate_bigint(int(build)):
qs = getattr(qs, query_func)(**{f"build_number__{operator}": int(build)})
return qs
else:
if not build or build.endswith("*"):
qs = getattr(qs, query_func)(build_code__startswith=build[:-1])
build_number_filters = Q()
build_code_filters = Q()
for b in build:
if b.isdecimal() and validate_bigint(int(b)):
build_number_filters |= Q(**{f"build_number__{operator}": [int(b)]})
else:
if not b or b.endswith("*"):
build_code_filters |= Q(build_code__startswith=b[:-1])
else:
build_code_filters |= Q(build_code=b)

if build_number_filters:
qs = getattr(qs, query_func)(build_number_filters)
if build_code_filters:
qs = getattr(qs, query_func)(build_code_filters)

# Handle the case where operator is 'in' separately
if operator == "in":
return qs.filter(
Q(
build_number__in=[
int(b) for b in build if b.isdecimal() and validate_bigint(int(b))
]
)
| Q(
build_code__in=[
b for b in build if not b.isdecimal() or not validate_bigint(int(b))
]
)
)
else:
qs = getattr(qs, query_func)(build_code=build)

return qs
return qs

def filter_by_semver(
self,
Expand Down
3 changes: 2 additions & 1 deletion src/sentry/search/events/datasets/filter_aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from collections.abc import Mapping
from functools import reduce
from typing import Sequence

from snuba_sdk import Column, Condition, Function, Op

Expand Down Expand Up @@ -280,7 +281,7 @@ def semver_build_filter_converter(
"""
if builder.params.organization is None:
raise ValueError("organization is a required param")
build: str = search_filter.value.raw_value
build: str | Sequence[str] = search_filter.value.raw_value

operator, negated = handle_operator_negation(search_filter.operator)
try:
Expand Down
3 changes: 3 additions & 0 deletions src/sentry/search/events/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,9 @@ def parse_semver(version, operator) -> SemverFilter:
- 1.2.3.4-alpha
- 1.*
"""
import traceback

traceback.print_stack()
(operator, negated) = handle_operator_negation(operator)
try:
operator = OPERATOR_TO_DJANGO[operator]
Expand Down
56 changes: 54 additions & 2 deletions tests/sentry/issues/endpoints/test_organization_group_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,7 @@ def test_semver(self, _: MagicMock) -> None:
release_1 = self.create_release(version="[email protected]")
release_2 = self.create_release(version="[email protected]")
release_3 = self.create_release(version="[email protected]")
release_4 = self.create_release(version="[email protected]")

release_1_g_1 = self.store_event(
data={
Expand Down Expand Up @@ -1425,6 +1426,14 @@ def test_semver(self, _: MagicMock) -> None:
},
project_id=self.project.id,
).group.id
release_4_g_1 = self.store_event(
data={
"timestamp": iso_format(before_now(minutes=7)),
"fingerprint": ["group-7"],
"release": release_4.version,
},
project_id=self.project.id,
).group.id
self.login_as(user=self.user)
response = self.get_response(sort_by="date", limit=10, query=f"{SEMVER_ALIAS}:>1.2.3")
assert response.status_code == 200, response.content
Expand All @@ -1433,6 +1442,7 @@ def test_semver(self, _: MagicMock) -> None:
release_2_g_2,
release_3_g_1,
release_3_g_2,
release_4_g_1,
]

response = self.get_response(sort_by="date", limit=10, query=f"{SEMVER_ALIAS}:>=1.2.3")
Expand All @@ -1444,6 +1454,7 @@ def test_semver(self, _: MagicMock) -> None:
release_2_g_2,
release_3_g_1,
release_3_g_2,
release_4_g_1,
]

response = self.get_response(sort_by="date", limit=10, query=f"{SEMVER_ALIAS}:<1.2.4")
Expand All @@ -1461,6 +1472,40 @@ def test_semver(self, _: MagicMock) -> None:
release_1_g_2,
release_3_g_1,
release_3_g_2,
release_4_g_1,
]

# Test multiple semver in same filter
response = self.get_response(sort_by="date", limit=10, query=f"{SEMVER_ALIAS}:[1.2.3,1.2.5]")
assert response.status_code == 200, response.content
assert [int(r["id"]) for r in response.json()] == [
release_1_g_1,
release_1_g_2,
release_2_g_1,
release_2_g_2,
release_3_g_1,
release_3_g_2,
]

response = self.get_response(sort_by="date", limit=10, query=f"{SEMVER_ALIAS}:[>1.2.3,<2.0.0]")
assert response.status_code == 200, response.content
assert [int(r["id"]) for r in response.json()] == [
release_2_g_1,
release_2_g_2,
release_3_g_1,
release_3_g_2,
]

response = self.get_response(sort_by="date", limit=10, query=f"{SEMVER_ALIAS}:[1.2.3,>2.0.0]")
assert response.status_code == 200, response.content
assert [int(r["id"]) for r in response.json()] == [
release_1_g_1,
release_1_g_2,
release_2_g_1,
release_2_g_2,
release_3_g_1,
release_3_g_2,
release_4_g_1,
]

def test_release_stage(self, _: MagicMock) -> None:
Expand Down Expand Up @@ -1653,8 +1698,15 @@ def test_semver_build(self, _: MagicMock) -> None:
release_2_g_1,
]

response = self.get_response(sort_by="date", limit=10, query=f"{SEMVER_BUILD_ALIAS}:[124]")
assert response.status_code == 400, response.content
response = self.get_response(
sort_by="date", limit=10, query=f"{SEMVER_BUILD_ALIAS}:[123,124]"
)
assert response.status_code == 200, response.content
assert [int(r["id"]) for r in response.json()] == [
release_1_g_1,
release_1_g_2,
release_2_g_1,
]

def test_aggregate_stats_regression_test(self, _: MagicMock) -> None:
self.store_event(
Expand Down

0 comments on commit a6e3bef

Please sign in to comment.