From 20d76bfc91f408e1cefb42c81fa0914400fd5f2b Mon Sep 17 00:00:00 2001 From: Chris Church Date: Wed, 23 Jul 2014 20:03:47 -0400 Subject: [PATCH] Fix UnicodeDecodeError from pexpect when ansible-playbook output contains unicode. --- awx/main/models/unified_jobs.py | 5 +++-- awx/main/tasks.py | 3 ++- awx/main/tests/base.py | 2 +- awx/main/tests/tasks.py | 18 +++++++++--------- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/awx/main/models/unified_jobs.py b/awx/main/models/unified_jobs.py index 1ce189ea3f..c9e69f9840 100644 --- a/awx/main/models/unified_jobs.py +++ b/awx/main/models/unified_jobs.py @@ -2,6 +2,7 @@ # All Rights Reserved. # Python +import codecs import json import logging import re @@ -506,7 +507,7 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique if self.result_stdout_file != "": if not os.path.exists(self.result_stdout_file): return StringIO("stdout capture is missing") - return open(self.result_stdout_file, "r") + return codecs.open(self.result_stdout_file, "r", encoding='utf-8') else: return StringIO(self.result_stdout_text) @@ -520,7 +521,7 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique return ansi_escape.sub('', self.result_stdout_raw) def result_stdout_raw_limited(self, start_line=0, end_line=None): - return_buffer = "" + return_buffer = u"" if end_line is not None: end_line = int(end_line) stdout_lines = self.result_stdout_raw_handle().readlines() diff --git a/awx/main/tasks.py b/awx/main/tasks.py index c2a5d93682..9a947bb5d4 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -2,6 +2,7 @@ # All Rights Reserved. # Python +import codecs import ConfigParser import cStringIO from distutils.version import StrictVersion as Version @@ -388,7 +389,7 @@ class BaseTask(Task): if not os.path.exists(settings.JOBOUTPUT_ROOT): os.makedirs(settings.JOBOUTPUT_ROOT) stdout_filename = os.path.join(settings.JOBOUTPUT_ROOT, str(uuid.uuid1()) + ".out") - stdout_handle = open(stdout_filename, 'w') + stdout_handle = codecs.open(stdout_filename, 'w', encoding='utf-8') instance = self.update_model(pk, job_args=json.dumps(safe_args), job_cwd=cwd, job_env=safe_env, result_stdout_file=stdout_filename) status = self.run_pexpect(instance, args, cwd, env, kwargs['passwords'], stdout_handle) diff --git a/awx/main/tests/base.py b/awx/main/tests/base.py index df04a16d77..2722b53309 100644 --- a/awx/main/tests/base.py +++ b/awx/main/tests/base.py @@ -180,7 +180,7 @@ class BaseTestMixin(object): handle, playbook_path = tempfile.mkstemp(suffix='.yml', dir=project_dir) test_playbook_file = os.fdopen(handle, 'w') - test_playbook_file.write(playbook_content) + test_playbook_file.write(playbook_content.encode('utf-8')) test_playbook_file.close() # Role playbooks are specified as a dict of role name and the # content of tasks/main.yml playbook. diff --git a/awx/main/tests/tasks.py b/awx/main/tests/tasks.py index 873d0dcdf0..9b92adc19a 100644 --- a/awx/main/tests/tasks.py +++ b/awx/main/tests/tasks.py @@ -20,12 +20,12 @@ from awx.main.models import * from awx.main.tests.base import BaseLiveServerTest from awx.main.tasks import RunJob -TEST_PLAYBOOK = ''' +TEST_PLAYBOOK = u''' - name: test success hosts: test-group gather_facts: False tasks: - - name: should pass + - name: should pass \u2623 command: test 1 = 1 - name: should also pass command: test 2 = 2 @@ -329,13 +329,13 @@ class RunJobTest(BaseCeleryTest): def check_job_result(self, job, expected='successful', expect_stdout=True, expect_traceback=False): - msg = 'job status is %s, expected %s' % (job.status, expected) - msg = '%s\nargs:\n%s' % (msg, job.job_args) - msg = '%s\nenv:\n%s' % (msg, job.job_env) + msg = u'job status is %s, expected %s' % (job.status, expected) + msg = u'%s\nargs:\n%s' % (msg, job.job_args) + msg = u'%s\nenv:\n%s' % (msg, job.job_env) if job.result_traceback: - msg = '%s\ngot traceback:\n%s' % (msg, job.result_traceback) + msg = u'%s\ngot traceback:\n%s' % (msg, job.result_traceback) if job.result_stdout: - msg = '%s\ngot stdout:\n%s' % (msg, job.result_stdout) + msg = u'%s\ngot stdout:\n%s' % (msg, job.result_stdout) if isinstance(expected, (list, tuple)): self.assertTrue(job.status in expected) else: @@ -344,13 +344,13 @@ class RunJobTest(BaseCeleryTest): self.assertTrue(job.result_stdout) else: self.assertFalse(job.result_stdout, - 'expected no stdout, got:\n%s' % + u'expected no stdout, got:\n%s' % job.result_stdout) if expect_traceback: self.assertTrue(job.result_traceback) else: self.assertFalse(job.result_traceback, - 'expected no traceback, got:\n%s' % + u'expected no traceback, got:\n%s' % job.result_traceback) def check_job_events(self, job, runner_status='ok', plays=1, tasks=1,