mirror of
https://github.com/ansible/awx.git
synced 2026-01-14 11:20:39 -03:30
Fix IntegrityError deleting job splitting JT
misc: *show sharded jobs in recent_jobs *test updates
This commit is contained in:
parent
f9bdb1da15
commit
7ff04dafd3
@ -2976,12 +2976,9 @@ class JobTemplateMixin(object):
|
||||
'''
|
||||
|
||||
def _recent_jobs(self, obj):
|
||||
if hasattr(obj, 'workflow_jobs'):
|
||||
job_mgr = obj.workflow_jobs
|
||||
else:
|
||||
job_mgr = obj.jobs
|
||||
job_mgr = obj.unifiedjob_unified_jobs.non_polymorphic().only('id', 'status', 'finished')
|
||||
return [{'id': x.id, 'status': x.status, 'finished': x.finished}
|
||||
for x in job_mgr.all().order_by('-created')[:10]]
|
||||
for x in job_mgr.order_by('-created')[:10]]
|
||||
|
||||
def get_summary_fields(self, obj):
|
||||
d = super(JobTemplateMixin, self).get_summary_fields(obj)
|
||||
|
||||
21
awx/main/migrations/0050_v340_unified_jt_set_null.py
Normal file
21
awx/main/migrations/0050_v340_unified_jt_set_null.py
Normal file
@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.11 on 2018-09-10 17:41
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import awx.main.utils.polymorphic
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0049_v340_add_job_template'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='unifiedjob',
|
||||
name='unified_job_template',
|
||||
field=models.ForeignKey(default=None, editable=False, null=True, on_delete=awx.main.utils.polymorphic.SET_NULL, related_name='unifiedjob_unified_jobs', to='main.UnifiedJobTemplate'),
|
||||
),
|
||||
]
|
||||
@ -320,10 +320,13 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour
|
||||
def resources_needed_to_start(self):
|
||||
return [fd for fd in ['project', 'inventory'] if not getattr(self, '{}_id'.format(fd))]
|
||||
|
||||
def create_unified_job(self, **kwargs):
|
||||
def create_job(self, **kwargs):
|
||||
'''
|
||||
Create a new job based on this template.
|
||||
'''
|
||||
return self.create_unified_job(**kwargs)
|
||||
|
||||
def create_unified_job(self, **kwargs):
|
||||
split_event = bool(
|
||||
self.job_shard_count > 1 and
|
||||
not kwargs.pop('_prevent_sharding', False)
|
||||
@ -345,7 +348,7 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour
|
||||
create_kwargs = dict(workflow_job=job,
|
||||
unified_job_template=self,
|
||||
ancestor_artifacts=dict(job_shard=idx))
|
||||
wfjn = WorkflowJobNode.objects.create(**create_kwargs)
|
||||
WorkflowJobNode.objects.create(**create_kwargs)
|
||||
return job
|
||||
|
||||
def get_absolute_url(self, request=None):
|
||||
@ -480,7 +483,7 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour
|
||||
RelatedJobsMixin
|
||||
'''
|
||||
def _get_related_jobs(self):
|
||||
return Job.objects.filter(job_template=self)
|
||||
return UnifiedJob.objects.filter(unified_job_template=self)
|
||||
|
||||
|
||||
class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskManagerJobMixin):
|
||||
|
||||
@ -321,8 +321,6 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, Notificatio
|
||||
'''
|
||||
Create a new unified job based on this unified job template.
|
||||
'''
|
||||
from awx.main.models import JobTemplate, WorkflowJob
|
||||
|
||||
new_job_passwords = kwargs.pop('survey_passwords', {})
|
||||
eager_fields = kwargs.pop('_eager_fields', None)
|
||||
|
||||
@ -553,7 +551,7 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
|
||||
default=None,
|
||||
editable=False,
|
||||
related_name='%(class)s_unified_jobs',
|
||||
on_delete=models.SET_NULL,
|
||||
on_delete=polymorphic.SET_NULL,
|
||||
)
|
||||
launch_type = models.CharField(
|
||||
max_length=20,
|
||||
@ -834,7 +832,7 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
|
||||
'''
|
||||
unified_job_class = self.__class__
|
||||
unified_jt_class = self._get_unified_job_template_class()
|
||||
parent_field_name = unified_job_class._get_parent_field_name()
|
||||
parent_field_name = self._get_parent_field_name()
|
||||
fields = unified_jt_class._get_unified_job_field_names() | set([parent_field_name])
|
||||
|
||||
create_data = {}
|
||||
@ -881,6 +879,8 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
|
||||
config = JobLaunchConfig(job=self)
|
||||
if parent is None:
|
||||
parent = getattr(self, self._get_parent_field_name())
|
||||
if parent is None:
|
||||
return
|
||||
valid_fields = parent.get_ask_mapping().keys()
|
||||
# Special cases allowed for workflows
|
||||
if hasattr(self, 'extra_vars'):
|
||||
|
||||
@ -122,6 +122,22 @@ def test_job_relaunch_on_failed_hosts(post, inventory, project, machine_credenti
|
||||
assert r.data.get('limit') == hosts
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_shard_jt_recent_jobs(shard_job_factory, admin_user, get):
|
||||
workflow_job = shard_job_factory(3, spawn=True)
|
||||
shard_jt = workflow_job.job_template
|
||||
r = get(
|
||||
url=shard_jt.get_absolute_url(),
|
||||
user=admin_user,
|
||||
expect=200
|
||||
)
|
||||
job_ids = [entry['id'] for entry in r.data['summary_fields']['recent_jobs']]
|
||||
assert workflow_job.pk in job_ids
|
||||
for node in workflow_job.workflow_nodes.all():
|
||||
job = node.job
|
||||
assert job.pk in job_ids
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_block_unprocessed_events(delete, admin_user, mocker):
|
||||
time_of_finish = parse("Thu Feb 28 09:10:20 2013 -0500")
|
||||
|
||||
@ -82,6 +82,7 @@ def test_job_host_summary_representation(host):
|
||||
host.delete()
|
||||
assert 'N/A changed=1 dark=2 failures=3 ok=4 processed=5 skipped=6' == six.text_type(jhs)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestShardingModels:
|
||||
|
||||
@ -97,6 +98,6 @@ class TestShardingModels:
|
||||
job = shard_job_factory(3, jt_kwargs={'ask_limit_on_launch': True}, prompts={'limit': 'foobar'}, spawn=True)
|
||||
assert job.launch_config.prompts_dict() == {'limit': 'foobar'}
|
||||
for node in job.workflow_nodes.all():
|
||||
assert node.limit == None # data not saved in node prompts
|
||||
assert node.limit is None # data not saved in node prompts
|
||||
job = node.job
|
||||
assert job.limit == 'foobar'
|
||||
|
||||
@ -58,9 +58,7 @@ class TestCreateUnifiedJob:
|
||||
job_with_links.save()
|
||||
job_with_links.credentials.add(machine_credential)
|
||||
job_with_links.credentials.add(net_credential)
|
||||
with mocker.patch('awx.main.models.unified_jobs.UnifiedJobTemplate._get_unified_job_field_names',
|
||||
return_value=['inventory', 'credential', 'limit']):
|
||||
second_job = job_with_links.copy_unified_job()
|
||||
second_job = job_with_links.copy_unified_job()
|
||||
|
||||
# Check that job data matches the original variables
|
||||
assert second_job.credential == job_with_links.credential
|
||||
|
||||
@ -71,14 +71,19 @@ class TestJobTemplateSerializerGetRelated():
|
||||
class TestJobTemplateSerializerGetSummaryFields():
|
||||
def test__recent_jobs(self, mocker, job_template, jobs):
|
||||
|
||||
job_template.jobs.all = mocker.MagicMock(**{'order_by.return_value': jobs})
|
||||
job_template.jobs.all.return_value = job_template.jobs.all
|
||||
job_template.unifiedjob_unified_jobs = mocker.MagicMock(**{
|
||||
'non_polymorphic.return_value': mocker.MagicMock(**{
|
||||
'only.return_value': mocker.MagicMock(**{
|
||||
'order_by.return_value': jobs
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
serializer = JobTemplateSerializer()
|
||||
recent_jobs = serializer._recent_jobs(job_template)
|
||||
|
||||
job_template.jobs.all.assert_called_once_with()
|
||||
job_template.jobs.all.order_by.assert_called_once_with('-created')
|
||||
job_template.unifiedjob_unified_jobs.non_polymorphic.assert_called_once_with()
|
||||
job_template.unifiedjob_unified_jobs.non_polymorphic().only().order_by.assert_called_once_with('-created')
|
||||
assert len(recent_jobs) == 10
|
||||
for x in jobs[:10]:
|
||||
assert recent_jobs == [{'id': x.id, 'status': x.status, 'finished': x.finished} for x in jobs[:10]]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user