From da0b8ad2ffa64b0aad227176ecbd3161bab2d24a Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 2 Aug 2016 10:39:02 -0400 Subject: [PATCH 1/3] moving from old to unit folder --- awx/main/tests/{old => unit}/api/decorator_paginated.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename awx/main/tests/{old => unit}/api/decorator_paginated.py (100%) diff --git a/awx/main/tests/old/api/decorator_paginated.py b/awx/main/tests/unit/api/decorator_paginated.py similarity index 100% rename from awx/main/tests/old/api/decorator_paginated.py rename to awx/main/tests/unit/api/decorator_paginated.py From 720eb8d6fb98f4e3dfe4387ca8db7594807b12e1 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 2 Aug 2016 10:39:16 -0400 Subject: [PATCH 2/3] adding more credential parsing coverage --- .../tests/unit/test_network_credential.py | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/awx/main/tests/unit/test_network_credential.py b/awx/main/tests/unit/test_network_credential.py index 6393bd64d1..9ca8c6693a 100644 --- a/awx/main/tests/unit/test_network_credential.py +++ b/awx/main/tests/unit/test_network_credential.py @@ -1,26 +1,42 @@ -import pytest - from awx.main.models.credential import Credential from awx.main.models.jobs import Job from awx.main.models.inventory import Inventory from awx.main.tasks import RunJob -@pytest.fixture -def options(): - return { - 'username':'test', - 'password':'test', - 'ssh_key_data': """-----BEGIN PRIVATE KEY-----\nstuff==\n-----END PRIVATE KEY-----""", - 'authorize': True, - 'authorize_password': 'passwd', - } - - -def test_net_cred_parse(mocker, options): +def test_aws_cred_parse(mocker): with mocker.patch('django.db.ConnectionRouter.db_for_write'): job = Job(id=1) job.inventory = mocker.MagicMock(spec=Inventory, id=2) + + options = { + 'kind': 'aws', + 'username': 'aws_user', + 'password': 'aws_passwd', + 'security_token': 'token', + } + job.cloud_credential = Credential(**options) + + run_job = RunJob() + mocker.patch.object(run_job, 'should_use_proot', return_value=False) + + env = run_job.build_env(job, private_data_dir='/tmp') + assert env['AWS_ACCESS_KEY'] == options['username'] + assert env['AWS_SECRET_KEY'] == options['password'] + assert env['AWS_SECURITY_TOKEN'] == options['security_token'] + + +def test_net_cred_parse(mocker): + with mocker.patch('django.db.ConnectionRouter.db_for_write'): + job = Job(id=1) + job.inventory = mocker.MagicMock(spec=Inventory, id=2) + + options = { + 'username':'test', + 'password':'test', + 'authorize': True, + 'authorize_password': 'passwd', + } job.network_credential = Credential(**options) run_job = RunJob() @@ -33,10 +49,17 @@ def test_net_cred_parse(mocker, options): assert env['ANSIBLE_NET_AUTHORIZE_PASSWORD'] == options['authorize_password'] -def test_net_cred_ssh_agent(mocker, options, get_ssh_version): +def test_net_cred_ssh_agent(mocker, get_ssh_version): with mocker.patch('django.db.ConnectionRouter.db_for_write'): run_job = RunJob() + options = { + 'username':'test', + 'password':'test', + 'ssh_key_data': """-----BEGIN PRIVATE KEY-----\nstuff==\n-----END PRIVATE KEY-----""", + 'authorize': True, + 'authorize_password': 'passwd', + } mock_job_attrs = {'forks': False, 'id': 1, 'cancel_flag': False, 'status': 'running', 'job_type': 'normal', 'credential': None, 'cloud_credential': None, 'network_credential': Credential(**options), 'become_enabled': False, 'become_method': None, 'become_username': None, From c5b005fd35940e69d68c5f3c6fb3a63148d3e530 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Wed, 3 Aug 2016 15:37:40 -0400 Subject: [PATCH 3/3] refactor start_event_queryset into model --- awx/api/views.py | 16 +--------------- awx/main/models/jobs.py | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/awx/api/views.py b/awx/api/views.py index 7d1a855ed7..57f46189ba 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -2967,21 +2967,7 @@ class JobJobTasksList(BaseJobEventsList): return ({'detail': 'Parent event not found.'}, -1, status.HTTP_404_NOT_FOUND) parent_task = parent_task[0] - # Some events correspond to a playbook or task starting up, - # and these are what we're interested in here. - STARTING_EVENTS = ('playbook_on_task_start', 'playbook_on_setup') - - # We need to pull information about each start event. - # - # This is super tricky, because this table has a one-to-many - # relationship with itself (parent-child), and we're getting - # information for an arbitrary number of children. This means we - # need stats on grandchildren, sorted by child. - queryset = (JobEvent.objects.filter(parent__parent=parent_task, - parent__event__in=STARTING_EVENTS) - .values('parent__id', 'event', 'changed') - .annotate(num=Count('event')) - .order_by('parent__id')) + queryset = JobEvent.start_event_queryset(parent_task) # The data above will come back in a list, but we are going to # want to access it based on the parent id, so map it into a diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index ac67bf8d67..552a30a285 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -1206,6 +1206,30 @@ class JobEvent(CreatedModifiedModel): job.inventory.update_computed_fields() emit_websocket_notification('/socket.io/jobs', 'summary_complete', dict(unified_job_id=job.id)) + @property + def STARTING_EVENTS(): + return ('playbook_on_task_start', 'playbook_on_setup') + + @classmethod + def get_startevent_queryset(cls, parent_task, ordering=None): + ''' + We need to pull information about each start event. + + This is super tricky, because this table has a one-to-many + relationship with itself (parent-child), and we're getting + information for an arbitrary number of children. This means we + need stats on grandchildren, sorted by child. + ''' + qs = (JobEvent.objects.filter(parent__parent=parent_task, + parent__event__in=STARTING_EVENTS) + .values('parent__id', 'event', 'changed') + .annotate(num=Count('event')) + .order_by('parent__id')) + if ordering is not None: + qs = qs.order_by(ordering) + return qs + + class SystemJobOptions(BaseModel): ''' Common fields for SystemJobTemplate and SystemJob.