Skip to content

Commit

Permalink
feat: add filtering for flags and testsuites
Browse files Browse the repository at this point in the history
we want to be able to filter test results by a list of flags and by a
list of testsuite names so this adds that functionality.

this is done by adding testsuites and flags fields to the
TestResultsFilteringParameter GQL model

to filter by flags this uses the TestFlagBridge database model
  • Loading branch information
joseph-sentry committed Oct 4, 2024
1 parent f73c190 commit 4d9ff63
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 2 deletions.
60 changes: 59 additions & 1 deletion graphql_api/tests/test_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@
RepositoryFactory,
RepositoryTokenFactory,
)
from reports.tests.factories import DailyTestRollupFactory, TestFactory
from reports.tests.factories import (
DailyTestRollupFactory,
RepositoryFlagFactory,
TestFactory,
TestFlagBridgeFactory,
)
from services.profiling import CriticalFile

from .helper import GraphQLTestHelper
Expand Down Expand Up @@ -1018,6 +1023,59 @@ def test_slowest_filter_on_test_results(self) -> None:
)
assert res["testResults"] == {"edges": [{"node": {"name": test2.name}}]}

def test_flags_filter_on_test_results(self) -> None:
repo = RepositoryFactory(author=self.owner, active=True, private=True)
test = TestFactory(repository=repo)
test2 = TestFactory(repository=repo)

repo_flag = RepositoryFlagFactory(repository=repo, flag_name="hello_world")

bridge = TestFlagBridgeFactory(flag=repo_flag, test=test)
_ = DailyTestRollupFactory(
test=test,
created_at=datetime.datetime.now(),
repoid=repo.repoid,
branch="main",
avg_duration_seconds=0.1,
)
_ = DailyTestRollupFactory(
test=test2,
created_at=datetime.datetime.now(),
repoid=repo.repoid,
branch="main",
avg_duration_seconds=20.0,
)
res = self.fetch_repository(
repo.name,
"""testResults(filters: { flags: ["hello_world"] }) { edges { node { name } } }""",
)
assert res["testResults"] == {"edges": [{"node": {"name": test.name}}]}

def test_testsuites_filter_on_test_results(self) -> None:
repo = RepositoryFactory(author=self.owner, active=True, private=True)
test = TestFactory(repository=repo, testsuite="hello")
test2 = TestFactory(repository=repo, testsuite="world")

_ = DailyTestRollupFactory(
test=test,
created_at=datetime.datetime.now(),
repoid=repo.repoid,
branch="main",
avg_duration_seconds=0.1,
)
_ = DailyTestRollupFactory(
test=test2,
created_at=datetime.datetime.now(),
repoid=repo.repoid,
branch="main",
avg_duration_seconds=20.0,
)
res = self.fetch_repository(
repo.name,
"""testResults(filters: { testsuites: ["hello"] }) { edges { node { name } } }""",
)
assert res["testResults"] == {"edges": [{"node": {"name": test.name}}]}

def test_commits_failed_ordering_on_test_results(self) -> None:
repo = RepositoryFactory(author=self.owner, active=True, private=True)
test = TestFactory(repository=repo)
Expand Down
25 changes: 24 additions & 1 deletion graphql_api/tests/test_test_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@

from codecov_auth.tests.factories import OwnerFactory
from core.tests.factories import RepositoryFactory
from reports.tests.factories import DailyTestRollupFactory, TestFactory
from reports.tests.factories import (
DailyTestRollupFactory,
TestFactory,
TestFlagBridgeFactory,
)

from .helper import GraphQLTestHelper

Expand All @@ -22,6 +26,17 @@ def setUp(self):
repository=self.repository,
)

self.test_with_flag = TestFactory(
name="Other Test",
repository=self.repository,
)

flag = RepositoryFlagFactory(
repository=self.repository, flag_name="test_flag_name"
)

bridge = TestFlagBridgeFactory(repository=self.repository, flag=flag)

_ = DailyTestRollupFactory(
test=self.test,
commits_where_fail=["123"],
Expand All @@ -44,6 +59,14 @@ def setUp(self):
avg_duration_seconds=3,
latest_run=datetime.now(),
)
_ = DailyTestRollupFactory(
test=self.test_with_flag,
commits_where_fail=["456"],
date=date.today(),
last_duration_seconds=10.0,
avg_duration_seconds=5,
latest_run=datetime.now(),
)

def test_fetch_test_result_name(self) -> None:
query = """
Expand Down
2 changes: 2 additions & 0 deletions graphql_api/types/inputs/test_results_filters.graphql
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
input TestResultsFilters {
branch: String
parameter: TestResultsFilterParameter
testsuites: [String!]
flags: [String!]
}

input TestResultsOrdering {
Expand Down
2 changes: 2 additions & 0 deletions graphql_api/types/repository/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,8 @@ async def resolve_test_results(
repoid=repository.repoid,
branch=filters.get("branch") if filters else None,
parameter=generate_test_results_param,
testsuites=filters.get("testsuites") if filters else None,
flags=filters.get("flags") if filters else None,
)

return await queryset_to_connection(
Expand Down
8 changes: 8 additions & 0 deletions reports/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,11 @@ class Meta:
date = date.today()

commits_where_fail = ["123", "456", "789"]


class TestFlagBridgeFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.TestFlagBridge

test = factory.SubFactory(TestFactory)
flag = factory.SubFactory(RepositoryFlagFactory)
16 changes: 16 additions & 0 deletions utils/test_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from shared.django_apps.reports.models import (
DailyTestRollup,
Flake,
TestFlagBridge,
)

thirty_days_ago = dt.datetime.now(dt.UTC) - dt.timedelta(days=30)
Expand Down Expand Up @@ -63,6 +64,8 @@ def generate_test_results(
branch: str | None = None,
history: dt.timedelta = dt.timedelta(days=30),
parameter: GENERATE_TEST_RESULT_PARAM | None = None,
testsuites: list[str] | None = None,
flags: list[str] | None = None,
) -> QuerySet:
"""
Function that retrieves aggregated information about all tests in a given repository, for a given time range, optionally filtered by branch name.
Expand All @@ -81,6 +84,19 @@ def generate_test_results(
if branch is not None:
totals = totals.filter(branch=branch)

if testsuites is not None:
totals = totals.filter(test__testsuite__in=testsuites)

if flags is not None:
# we're going to have to do the filtering in python somehow
bridges = TestFlagBridge.objects.select_related("flag").filter(
flag__flag_name__in=flags
)

test_ids = [bridge.test_id for bridge in bridges]

totals = totals.filter(test_id__in=test_ids)

match parameter:
case GENERATE_TEST_RESULT_PARAM.FLAKY:
flakes = Flake.objects.filter(
Expand Down

0 comments on commit 4d9ff63

Please sign in to comment.