Properly handle non native strings under py2 and py3

This commit is contained in:
Pedro Algarvio 2017-04-18 16:10:55 +01:00
parent 5ed3d8d98c
commit 9a3f6d1350
No known key found for this signature in database
GPG Key ID: BB36BF6584A298FF
2 changed files with 113 additions and 2 deletions

View File

@ -125,7 +125,6 @@ def output(data, **kwargs): # pylint: disable=unused-argument
The HighState Outputter is only meant to be used with the state.highstate
function, or a function that returns highstate return data.
'''
# Discard retcode in dictionary as present in orchestrate data
local_masters = [key for key in data.keys() if key.endswith('.local_master')]
orchestrator_output = 'retcode' in data.keys() and len(local_masters) == 1
@ -319,7 +318,10 @@ def _format_host(host, data):
# be sure that ret['comment'] is utf-8 friendly
try:
if not isinstance(ret['comment'], six.text_type):
ret['comment'] = str(ret['comment']).decode('utf-8')
if six.PY2:
ret['comment'] = str(ret['comment']).decode('utf-8')
else:
ret['comment'] = salt.utils.to_str(ret['comment'])
except UnicodeDecodeError:
# but try to continue on errors
pass

View File

@ -0,0 +1,109 @@
# -*- coding: utf-8 -*-
'''
unittests for highstate outputter
'''
# Import Python Libs
from __future__ import absolute_import
# Import Salt Testing Libs
from tests.support.mixins import LoaderModuleMockMixin
from tests.support.unit import TestCase
# Import Salt Libs
import salt.utils
import salt.output.highstate as highstate
# Import 3rd-party libs
import salt.ext.six as six
class JsonTestCase(TestCase, LoaderModuleMockMixin):
'''
Test cases for salt.output.highstate
'''
def setup_loader_modules(self):
return {
highstate: {
'__opts__': {
'extension_modules': '',
'color': False,
}
}
}
def setUp(self):
self.data = {
'data': {
'master': {
'salt_|-call_sleep_state_|-call_sleep_state_|-state': {
'__id__': 'call_sleep_state',
'__jid__': '20170418153529810135',
'__run_num__': 0,
'__sls__': 'orch.simple',
'changes': {
'out': 'highstate',
'ret': {
'minion': {
'module_|-simple-ping_|-test.ping_|-run': {
'__id__': 'simple-ping',
'__run_num__': 0,
'__sls__': 'simple-ping',
'changes': {'ret': True},
'comment': 'Module function test.ping executed',
'duration': 56.179,
'name': 'test.ping',
'result': True,
'start_time': '15:35:31.282099'
}
},
'sub_minion': {
'module_|-simple-ping_|-test.ping_|-run': {
'__id__': 'simple-ping',
'__run_num__': 0,
'__sls__': 'simple-ping',
'changes': {'ret': True},
'comment': 'Module function test.ping executed',
'duration': 54.103,
'name': 'test.ping',
'result': True,
'start_time': '15:35:31.005606'
}
}
}
},
'comment': 'States ran successfully. Updating sub_minion, minion.',
'duration': 1638.047,
'name': 'call_sleep_state',
'result': True,
'start_time': '15:35:29.762657'
}
}
},
'outputter': 'highstate',
'retcode': 0
}
self.addCleanup(delattr, self, 'data')
def test_default_output(self):
ret = highstate.output(self.data)
self.assertIn('Succeeded: 1 (changed=1)', ret)
self.assertIn('Failed: 0', ret)
self.assertIn('Total states run: 1', ret)
def test_output_comment_is_not_unicode(self):
entry = None
for key in ('data', 'master', 'salt_|-call_sleep_state_|-call_sleep_state_|-state',
'changes', 'ret', 'minion', 'module_|-simple-ping_|-test.ping_|-run'):
if entry is None:
entry = self.data[key]
continue
entry = entry[key]
if six.PY2:
entry['comment'] = salt.utils.to_unicode(entry['comment'])
else:
entry['comment'] = salt.utils.to_bytes(entry['comment'])
ret = highstate.output(self.data)
self.assertIn('Succeeded: 1 (changed=1)', ret)
self.assertIn('Failed: 0', ret)
self.assertIn('Total states run: 1', ret)