Skip to content

Commit

Permalink
Add more fields to /tasks endpoint (#526)
Browse files Browse the repository at this point in the history
* Add more fields to /tasks endpoint

- Added 7 more fields to /tasks endpoint
- Added information about worker and errors
- Added progress_reports from pulp api
- Add progress_reports from pulpcore
- Adding ProgressReportSerializer to exception list
 - temporary solution until pulp/pulpcore#982 is
   merged
- Add unittests
- Adding a Detail view for tasks
- Add Summary Serializer and href field

Issue: AAH-16
  • Loading branch information
rochacbruno authored Jan 11, 2021
1 parent 288c1bb commit 7901955
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 5 deletions.
3 changes: 2 additions & 1 deletion .travis/check_pulpcore_imports.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ set -uv
MATCHES=$(grep -n -r --include \*.py "from pulpcore.*import" . \
| grep -v "tests\|plugin" \
| grep -v "pulpcore.app.*viewsets" \
| grep -v "pulpcore\.app.*admin")
| grep -v "pulpcore\.app.*admin" \
| grep -v "ProgressReportSerializer")

if [ $? -ne 1 ]; then
printf "\nERROR: Detected bad imports from pulpcore:\n"
Expand Down
1 change: 1 addition & 0 deletions CHANGES/16.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add more fields to /tasks endpoint
2 changes: 2 additions & 0 deletions galaxy_ng/app/api/v3/serializers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from .task import (
TaskSerializer,
TaskSummarySerializer,
)


Expand All @@ -28,4 +29,5 @@
'NamespaceSerializer',
'NamespaceSummarySerializer',
'TaskSerializer',
'TaskSummarySerializer',
)
73 changes: 70 additions & 3 deletions galaxy_ng/app/api/v3/serializers/task.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,82 @@
import logging

from typing import Any, Dict, Optional
from rest_framework import serializers
from rest_framework.reverse import reverse
from drf_spectacular.utils import extend_schema_field
from pulpcore.app.serializers import ProgressReportSerializer
from pulpcore.plugin.models import Task
from galaxy_ng.app.models import CollectionSyncTask

from galaxy_ng.app.api.ui.serializers.base import Serializer

log = logging.getLogger(__name__)


class TaskSerializer(Serializer):
class TaskSerializer(serializers.ModelSerializer):
created_at = serializers.DateTimeField(source='pulp_created')
updated_at = serializers.DateTimeField(source='pulp_last_updated')
worker = serializers.SerializerMethodField()
repository = serializers.SerializerMethodField()
progress_reports = ProgressReportSerializer(many=True, read_only=True)
pulp_id = serializers.UUIDField(source='pk')
name = serializers.CharField()
state = serializers.CharField()
started_at = serializers.DateTimeField()
finished_at = serializers.DateTimeField()

@extend_schema_field(Optional[Dict[str, Any]])
def get_worker(self, obj):
if obj.worker:
return {
'name': obj.worker.name,
'missing': obj.worker.missing,
'last_heartbeat': obj.worker.last_heartbeat,
}

@extend_schema_field(Optional[str])
def get_repository(self, obj):
sync_task = CollectionSyncTask.objects.filter(task=obj).first()
if sync_task:
return sync_task.repository.name

class Meta:
model = Task
fields = (
'pulp_id',
'name',
'created_at',
'updated_at',
'finished_at',
'started_at',
'state',
'error',
'worker',
'parent_task',
'child_tasks',
'repository',
'progress_reports',
)


class TaskSummarySerializer(TaskSerializer):
"""TaskSerializer but without detail fields.
For use in /tasks/<str:pk>/ detail views."""
href = serializers.SerializerMethodField()

def get_href(self, obj):
return reverse(
'galaxy:api:v3:default-content:tasks-detail',
kwargs={"pk": str(obj.pulp_id)}
)

class Meta:
model = Task
fields = (
'pulp_id',
'name',
'repository',
'state',
'started_at',
'finished_at',
'href',
)
8 changes: 7 additions & 1 deletion galaxy_ng/app/api/v3/viewsets/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from pulpcore.plugin import viewsets as pulp_core_viewsets

from galaxy_ng.app.api.base import LocalSettingsMixin
from galaxy_ng.app.api.v3.serializers import TaskSerializer
from galaxy_ng.app.api.v3.serializers import TaskSerializer, TaskSummarySerializer
from galaxy_ng.app.access_control import access_policy

log = logging.getLogger(__name__)
Expand All @@ -12,3 +12,9 @@
class TaskViewSet(LocalSettingsMixin, pulp_core_viewsets.TaskViewSet):
permission_classes = [access_policy.TaskAccessPolicy]
serializer_class = TaskSerializer

def get_serializer_class(self):
if self.action == 'list':
return TaskSummarySerializer
else:
return self.serializer_class
103 changes: 103 additions & 0 deletions galaxy_ng/tests/unit/api/test_api_v3_tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import logging
from rest_framework import status
from django.urls import reverse
from django.test import override_settings
from pulp_ansible.app.models import (
AnsibleDistribution,
AnsibleRepository,
CollectionRemote
)
from galaxy_ng.app.constants import DeploymentMode
from .base import BaseTestCase

log = logging.getLogger(__name__)


def _create_repo(name, **kwargs):
repo = AnsibleRepository.objects.create(name=name, **kwargs)
AnsibleDistribution.objects.create(name=name, base_path=name, repository=repo)
return repo


def _create_remote(name, url, **kwargs):
return CollectionRemote.objects.create(
name=name, url=url, **kwargs
)


@override_settings(GALAXY_DEPLOYMENT_MODE=DeploymentMode.STANDALONE.value)
class TestUiTaskListViewSet(BaseTestCase):
def setUp(self):
super().setUp()

self.admin_user = self._create_user("admin")
self.pe_group = self._create_partner_engineer_group()
self.admin_user.groups.add(self.pe_group)
self.admin_user.save()

self.certified_remote = _create_remote(
name='rh-certified',
url='https://a.certified.url.com/api/v2/collections',
requirements_file=None
)
_create_repo(name='rh-certified', remote=self.certified_remote)

def build_sync_url(self, path):
return reverse('galaxy:api:content:v3:sync', kwargs={'path': path})

def build_task_url(self):
return reverse('galaxy:api:v3:default-content:tasks-list')

def build_task_detail_url(self, pk):
return reverse('galaxy:api:v3:default-content:tasks-detail', kwargs={"pk": pk})

def test_tasks_required_fields(self):
# Spawn a task
self.client.force_authenticate(user=self.admin_user)
response = self.client.post(self.build_sync_url(self.certified_remote.name))
log.debug('Spawn a task for testing tasks/ endpoint')
log.debug('response: %s', response)
log.debug('response.data: %s', response.data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertIn('task', response.data)

# Ensure all required fields are present in list URL
response = self.client.get(self.build_task_url())
log.debug('response: %s', response)
log.debug('response.data: %s', response.data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertGreater(response.data['meta']['count'], 0)
required_fields = (
'pulp_id',
'name',
'finished_at',
'started_at',
'state',
'repository',
'href',
)
for field in required_fields:
self.assertIn(field, response.data['data'][0])

# Test Detail URL
task_pk = response.data['data'][0]['pulp_id']
response = self.client.get(self.build_task_detail_url(task_pk))
log.debug('response: %s', response)
log.debug('response.data: %s', response.data)
required_fields = (
'pulp_id',
'name',
'created_at',
'updated_at',
'finished_at',
'started_at',
'state',
'error',
'worker',
'parent_task',
'child_tasks',
'repository',
'progress_reports',
)
for field in required_fields:
self.assertIn(field, response.data)

0 comments on commit 7901955

Please sign in to comment.