Skip to content

Commit

Permalink
Adds task groups status API endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
dkliban committed Nov 13, 2015
1 parent 416fcff commit 3530a85
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 1 deletion.
56 changes: 56 additions & 0 deletions docs/dev-guide/integration/rest-api/tasks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Example Task Report::
}



Polling Task Progress
---------------------

Expand Down Expand Up @@ -120,6 +121,7 @@ All currently running and waiting tasks may be listed. This returns an array of
| :return:`array of` :ref:`task_report`


Deleting Completed Tasks
------------------------

Expand Down Expand Up @@ -174,3 +176,57 @@ For example::
| :response_list:`_`
* :response_code:`200,containing the array of tasks.`

.. _task_group_management:

Task Group Management
=====================

.. _task_group_summary:

Task Group Summary
------------------

Task Group Summary object summarizes the state of all the tasks belonging to a task group.

* **accepted** *(int)* - number of tasks in 'accepted' state
* **finished** *(int)* - number of tasks in 'finished' state
* **running** *(int)* - number of tasks in 'running' state
* **canceled** *(int)* - number of tasks in 'canceled' state
* **waiting** *(int)* - number of tasks in 'waiting' state
* **skipped** *(int)* - number of tasks in 'skipped' state
* **suspended** *(int)* - number of tasks in 'suspended' state
* **error** *(int)* - number of tasks in 'error' state
* **total** *(int)* - total number of tasks in the task group

Example task group summary::

{
"accepted": 0,
"finished": 100,
"running": 4,
"canceled": 0,
"waiting": 2,
"skipped": 0,
"suspended": 0,
"error": 0,
"total": 106
}


Polling Task Group Progress
----------------------------

Poll a group of tasks for progress summary. Polling returns a :ref:`task_group_summary`

| :method:`get`
| :path:`/v2/task_groups/<task_group_id>/state_summary/`
| :permission:`read`
| :response_list:`_`
* :response_code:`200, if the task group is found`
* :response_code:`404, if the task group id is not found`

| :return:`a` :ref:`task_group_summary` summarizing the state of all tasks belonging to
queried task group id
4 changes: 3 additions & 1 deletion server/pulp/server/webservices/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
UnitUpdateSchedulesView,
UnitUpdateScheduleResourceView)

from pulp.server.webservices.views import tasks, users
from pulp.server.webservices.views import tasks, users, task_groups
from pulp.server.webservices.views.consumer_groups import (ConsumerGroupAssociateActionView,
ConsumerGroupBindingView,
ConsumerGroupBindingsView,
Expand Down Expand Up @@ -244,6 +244,8 @@
url(r'^v2/tasks/$', tasks.TaskCollectionView.as_view(), name='task_collection'),
url(r'^v2/tasks/search/$', tasks.TaskSearchView.as_view(), name='task_search'),
url(r'^v2/tasks/(?P<task_id>[^/]+)/$', tasks.TaskResourceView.as_view(), name='task_resource'),
url(r'^v2/task_groups/(?P<group_id>[^/]+)/state_summary/$',
task_groups.TaskGroupSummaryView.as_view(), name='task_group_summary'),
url(r'^v2/users/$', users.UsersView.as_view(), name='users'),
url(r'^v2/users/search/$', users.UserSearchView.as_view(),
name='user_search'),
Expand Down
43 changes: 43 additions & 0 deletions server/pulp/server/webservices/views/task_groups.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
This module contains views related to Pulp's task groups.
"""
from django.views.generic import View

from pulp.common.constants import CALL_STATES
from pulp.server.auth import authorization
from pulp.server.db.model import TaskStatus
from pulp.server.exceptions import MissingResource
from pulp.server.webservices.views.decorators import auth_required
from pulp.server.webservices.views.util import generate_json_response_with_pulp_encoder


class TaskGroupSummaryView(View):
"""
View for a task group summary.
"""

@auth_required(authorization.READ)
def get(self, request, group_id):
"""
Return a response containing a summary of task states for task group.
:param request: WSGI request object
:type request: django.core.handlers.wsgi.WSGIRequest
:param group_id: The ID of the task group you wish to summarize
:type group_id: basestring
:return: Response containing a serialized dict of the task group summary
:rtype : django.http.HttpResponse
:raises MissingResource: if group id is not found
"""
tasks = TaskStatus.objects(group_id=group_id)
task_group_total = tasks.count()

if task_group_total == 0:
raise MissingResource(group_id)

summary = {'total': task_group_total}
for state in CALL_STATES:
summary[state] = tasks.filter(state=state).count()

return generate_json_response_with_pulp_encoder(summary)
71 changes: 71 additions & 0 deletions server/test/unit/server/webservices/views/test_task_groups.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""
This module contains tests for the pulp.server.webservices.views.task_groups module.
"""
import mock

from .base import assert_auth_READ
from pulp.common.compat import unittest

from pulp.server.exceptions import MissingResource
from pulp.server.webservices.views.task_groups import TaskGroupSummaryView


class TestTaskGroupSummary(unittest.TestCase):
"""
Tests for TaskGroupSummaryView
"""

@mock.patch('pulp.server.webservices.views.decorators._verify_auth',
new=assert_auth_READ())
@mock.patch('pulp.server.webservices.views.task_groups.TaskStatus.objects')
def test_get_task_group_summary_nonexistant(self, mock_objects):
"""
Test get task_group_summary with no tasks
"""

mock_request = mock.MagicMock()
mock_objects.return_value.count.return_value = 0
task_group_summary = TaskGroupSummaryView()
self.assertRaises(MissingResource, task_group_summary.get, mock_request, 'mock_task')

@mock.patch('pulp.server.webservices.views.decorators._verify_auth',
new=assert_auth_READ())
@mock.patch('pulp.server.webservices.views.task_groups.TaskStatus.objects')
@mock.patch(
'pulp.server.webservices.views.task_groups.generate_json_response_with_pulp_encoder')
def test_get_task_group_summary(self, mock_resp, mock_objects):
"""
Test get task_group_summary with multiple tasks
"""
class MockQuerySet(object):

def __init__(self, list_of_objects):
self.items = list_of_objects
self.i = 0
self.n = len(self.items)

def count(self):
return len(self.items)

def filter(self, state=None):
filtered_list = []
for item in self.items:
if item['state'] == state:
filtered_list.append(item)
return MockQuerySet(filtered_list)

mock_request = mock.MagicMock()
mock_objects.return_value = MockQuerySet([{'id': 'mock_task', 'worker_name': 'mock',
'state': 'running'},
{'id': 'mock_task', 'worker_name': 'mock',
'state': 'finished'},
{'id': 'mock_task', 'worker_name': 'mock',
'state': 'waiting'}])

task_group_summary = TaskGroupSummaryView()
response = task_group_summary.get(mock_request, 'mock_task')

expected_content = {'accepted': 0, 'finished': 1, 'running': 1, 'canceled': 0,
'waiting': 1, 'skipped': 0, 'suspended': 0, 'error': 0, 'total': 3}
mock_resp.assert_called_with(expected_content)
self.assertTrue(response is mock_resp.return_value)

0 comments on commit 3530a85

Please sign in to comment.