Skip to content

Commit

Permalink
add filters to /job and /program (#1466)
Browse files Browse the repository at this point in the history
  • Loading branch information
akihikokuroda committed Aug 26, 2024
1 parent 0e14adf commit 48ac9dd
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 6 deletions.
45 changes: 41 additions & 4 deletions gateway/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,13 @@ def get_queryset(self):
author = self.request.user
title = self.request.query_params.get("title")
provider_name = self.request.query_params.get("provider")
type_filter = self.request.query_params.get("filter")

author_programs = self._get_program_queryset_for_title_and_provider(
author=author, title=title, provider_name=provider_name
author=author,
title=title,
provider_name=provider_name,
type_filter=type_filter,
).distinct()

author_programs_count = author_programs.count()
Expand Down Expand Up @@ -305,7 +309,7 @@ def get_by_title(self, request, title):
provider_name = self.request.query_params.get("provider")

result_program = self._get_program_queryset_for_title_and_provider(
author=author, title=title, provider_name=provider_name
author=author, title=title, provider_name=provider_name, type_filter=None
).first()

if result_program:
Expand All @@ -314,14 +318,38 @@ def get_by_title(self, request, title):
return Response(status=404)

def _get_program_queryset_for_title_and_provider(
self, author, title: str, provider_name: Optional[str]
self,
author,
title: str,
provider_name: Optional[str],
type_filter: Optional[str],
):
"""Returns queryset for program for gived request, title and provider."""
view_program_permission = Permission.objects.get(
codename=VIEW_PROGRAM_PERMISSION
)

# Groups logic
if type_filter:
if type_filter == "catalog":
view_permission_criteria = Q(permissions=view_program_permission)
groups_with_view_permissions = Group.objects.filter(
view_permission_criteria
)
groups_with_view_permissions_criteria = Q(
instances__in=groups_with_view_permissions
)
provider_exists_criteria = ~Q(provider=None)
result_queryset = Program.objects.filter(
groups_with_view_permissions_criteria & provider_exists_criteria
)
return result_queryset
if type_filter == "serverless":
result_queryset = Program.objects.filter(
Q(author=author) & Q(provider=None)
)
return result_queryset

user_criteria = Q(user=author)
view_permission_criteria = Q(permissions=view_program_permission)
author_groups_with_view_permissions = Group.objects.filter(
Expand Down Expand Up @@ -357,7 +385,6 @@ def _get_program_queryset_for_title_and_provider(
result_queryset = Program.objects.filter(
author_criteria | author_groups_with_view_permissions_criteria
)

return result_queryset

@action(methods=["GET"], detail=True)
Expand Down Expand Up @@ -405,6 +432,16 @@ def get_serializer_class(self):
return self.serializer_class

def get_queryset(self):
type_filter = self.request.query_params.get("filter")
if type_filter:
if type_filter == "catalog":
user_criteria = Q(author=self.request.user)
provider_exists_criteria = ~Q(program__provider=None)
return Job.objects.filter(user_criteria & provider_exists_criteria)
if type_filter == "serverless":
user_criteria = Q(author=self.request.user)
provider_not_exists_criteria = Q(program__provider=None)
return Job.objects.filter(user_criteria & provider_not_exists_criteria)
return Job.objects.filter(author=self.request.user).order_by("-created")

def retrieve(self, request, pk=None): # pylint: disable=unused-argument
Expand Down
33 changes: 33 additions & 0 deletions gateway/tests/api/test_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,39 @@ def test_job_list(self):
jobs_response.data.get("results")[0].get("result"), '{"somekey":1}'
)

def test_job_catalog_list(self):
"""Tests job list authorized."""
self._authorize()

jobs_response = self.client.get(
reverse("v1:jobs-list"), {"filter": "catalog"}, format="json"
)
self.assertEqual(jobs_response.status_code, status.HTTP_200_OK)
self.assertEqual(jobs_response.data.get("count"), 1)
self.assertEqual(jobs_response.data.get("results")[0].get("status"), "QUEUED")
self.assertEqual(
jobs_response.data.get("results")[0].get("result"), '{"somekey":1}'
)

def test_job_serverless_list(self):
"""Tests job list authorized."""
self._authorize()

jobs_response = self.client.get(
reverse("v1:jobs-list"), {"filter": "serverless"}, format="json"
)
self.assertEqual(jobs_response.status_code, status.HTTP_200_OK)
self.assertEqual(jobs_response.data.get("count"), 2)
job_status = jobs_response.data.get("results")[0].get("status")
if job_status == "SUCCEEDED":
self.assertEqual(
jobs_response.data.get("results")[0].get("result"), '{"somekey":1}'
)
elif job_status == "QUEUED":
self.assertEqual(
jobs_response.data.get("results")[0].get("result"), '{"somekey":2}'
)

def test_job_detail(self):
"""Tests job detail authorized."""
self._authorize()
Expand Down
38 changes: 38 additions & 0 deletions gateway/tests/api/test_v1_program.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,44 @@ def test_provider_programs_list(self):
"Docker-Image-Program",
)

def test_provider_programs_catalog_list(self):
"""Tests programs list authorized."""

user = models.User.objects.get(username="test_user_4")
self.client.force_authenticate(user=user)

programs_response = self.client.get(
reverse("v1:programs-list"), {"filter": "catalog"}, format="json"
)

self.assertEqual(programs_response.status_code, status.HTTP_200_OK)
self.assertEqual(len(programs_response.data), 1)
self.assertEqual(
programs_response.data[0].get("provider"),
"ibm",
)
self.assertEqual(
programs_response.data[0].get("title"),
"Docker-Image-Program-2",
)

def test_provider_programs_serverless_list(self):
"""Tests programs list authorized."""

user = models.User.objects.get(username="test_user_3")
self.client.force_authenticate(user=user)

programs_response = self.client.get(
reverse("v1:programs-list"), {"filter": "serverless"}, format="json"
)

self.assertEqual(programs_response.status_code, status.HTTP_200_OK)
self.assertEqual(len(programs_response.data), 1)
self.assertEqual(
programs_response.data[0].get("title"),
"Program",
)

def test_program_list_with_title_query_parameter(self):
"""Tests program list filtered with title."""
user = models.User.objects.get(username="test_user")
Expand Down
49 changes: 47 additions & 2 deletions gateway/tests/fixtures/fixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,21 @@
"password": "pbkdf2_sha256$390000$kcex1rxhZg6VVJYkx71cBX$e4ns0xDykbO6Dz6j4nZ4uNusqkB9GVpojyegPv5/9KM=",
"is_active": true,
"groups": [
100
100,
101
]
}
},
{
"model": "auth.user",
"pk": 4,
"fields": {
"email": "test_user_4@email.com",
"username": "test_user_4",
"password": "pbkdf2_sha256$390000$kcex1rxhZg6VVJYkx71cBX$e4ns0xDykbO6Dz6j4nZ4uNusqkB9GVpojyegPv5/9KM=",
"is_active": true,
"groups": [
101
]
}
},
Expand Down Expand Up @@ -67,6 +81,37 @@
"provider": "bfe8aa6a-2127-4123-bf57-5b547293cbea"
}
},
{
"model": "api.program",
"pk": "6160a2ff-e482-443d-af23-15110b646ae3",
"fields": {
"created": "2023-02-01T15:30:43.281796Z",
"title": "Docker-Image-Program-2",
"image": "icr.io/awesome-namespace/awesome-title",
"author": 3,
"env_vars": "{\"PROGRAM_ENV1\": \"VALUE1\", \"PROGRAM_ENV2\": \"VALUE2\"}",
"provider": "bfe8aa6a-2127-4123-bf57-5b547293cbeb",
"instances": [
100,
101
]
}
},
{
"model": "api.program",
"pk": "1a7947f9-6ae8-4e3d-ac1e-e7d608deec83",
"fields": {
"created": "2023-02-01T15:30:43.281796Z",
"title": "Program",
"entrypoint": "program.py",
"artifact": "path",
"author": 3,
"env_vars": "{\"PROGRAM_ENV1\": \"VALUE1\", \"PROGRAM_ENV2\": \"VALUE2\"}",
"instances": [
100
]
}
},
{
"model": "api.job",
"pk": "1a7947f9-6ae8-4e3d-ac1e-e7d608deec82",
Expand All @@ -85,7 +130,7 @@
"fields": {
"program": "1a7947f9-6ae8-4e3d-ac1e-e7d608deec82",
"created": "2023-02-01T15:30:43.281796Z",
"result": "{\"somekey\":1}",
"result": "{\"somekey\":2}",
"status": "QUEUED",
"author": 1
}
Expand Down

0 comments on commit 48ac9dd

Please sign in to comment.