diff --git a/awx/main/models/unified_jobs.py b/awx/main/models/unified_jobs.py index 0a34e18bca..3b96735bdb 100644 --- a/awx/main/models/unified_jobs.py +++ b/awx/main/models/unified_jobs.py @@ -610,11 +610,15 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique """Return a file-like object containing the standard out of the job's result. """ + msg = { + 'pending': 'stdout capture pending', + 'missing': 'stdout capture is missing', + } if self.result_stdout_text: return StringIO(self.result_stdout_text) else: if not os.path.exists(self.result_stdout_file): - return StringIO("stdout capture is missing") + return StringIO(msg['missing' if self.finished else 'pending']) # There is a potential timing issue here, because another # process may be deleting the stdout file after it is written @@ -631,7 +635,7 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique self.result_stdout_text = type(self).objects.get(id=self.id).result_stdout_text return self.result_stdout_raw_handle(attempt=attempt + 1) else: - return StringIO("stdout capture is missing") + return StringIO(msg['missing' if self.finished else 'pending']) def _escape_ascii(self, content): ansi_escape = re.compile(r'\x1b[^m]*m') diff --git a/awx/main/tests/__init__.py b/awx/main/tests/__init__.py index 3b5e1fcf12..de61f95cf1 100644 --- a/awx/main/tests/__init__.py +++ b/awx/main/tests/__init__.py @@ -17,3 +17,4 @@ from awx.main.tests.redact import * # noqa from awx.main.tests.views import * # noqa from awx.main.tests.commands import * # noqa from awx.main.tests.fact import * # noqa +from awx.main.tests.unified_jobs import * # noqa diff --git a/awx/main/tests/unified_jobs.py b/awx/main/tests/unified_jobs.py new file mode 100644 index 0000000000..719bc45165 --- /dev/null +++ b/awx/main/tests/unified_jobs.py @@ -0,0 +1,53 @@ +# Copyright (c) 2015 Ansible, Inc. +# All Rights Reserved + +# Python +import mock +from StringIO import StringIO +from django.utils.timezone import now + +# Django +from django.test import SimpleTestCase + +# AWX +from awx.main.models import * # noqa + +__all__ = ['UnifiedJobsUnitTest',] + +class UnifiedJobsUnitTest(SimpleTestCase): + + # stdout file present + @mock.patch('os.path.exists', return_value=True) + @mock.patch('codecs.open', return_value='my_file_handler') + def test_result_stdout_raw_handle_file__found(self, exists, open): + unified_job = UnifiedJob() + unified_job.result_stdout_file = 'dummy' + + result = unified_job.result_stdout_raw_handle() + + self.assertEqual(result, 'my_file_handler') + + # stdout file missing, job finished + @mock.patch('os.path.exists', return_value=False) + def test_result_stdout_raw_handle__missing(self, exists): + unified_job = UnifiedJob() + unified_job.result_stdout_file = 'dummy' + unified_job.finished = now() + + result = unified_job.result_stdout_raw_handle() + + self.assertIsInstance(result, StringIO) + self.assertEqual(result.read(), 'stdout capture is missing') + + # stdout file missing, job not finished + @mock.patch('os.path.exists', return_value=False) + def test_result_stdout_raw_handle__pending(self, exists): + unified_job = UnifiedJob() + unified_job.result_stdout_file = 'dummy' + unified_job.finished = None + + result = unified_job.result_stdout_raw_handle() + + self.assertIsInstance(result, StringIO) + self.assertEqual(result.read(), 'stdout capture pending') +