Process output is supposed to be represented with lines, so we should
put Python strings in the queue (not bytes). Just in case, we do it only
for Python 3 environment.
To fix that, we reuse code from utils.execute() linux/windows
implementations.
This fixes the TestAsyncProcess.test_async_process_respawns functional
test for Python 3 environment.
Related-Bug: #
1515118
Change-Id: I9efec2290003add44909aab33a0026372a580016
from neutron.agent.linux import ip_lib
from neutron.agent.linux import utils
+from neutron.common import utils as common_utils
from neutron.i18n import _LE
def _read(self, stream, queue):
data = stream.readline()
if data:
- data = data.strip()
+ data = common_utils.safe_decode_utf8(data.strip())
queue.put(data)
return data
_stdout, _stderr = obj.communicate(_process_input)
returncode = obj.returncode
obj.stdin.close()
- if six.PY3:
- if isinstance(_stdout, bytes):
- _stdout = _stdout.decode('utf-8', 'surrogateescape')
- if isinstance(_stderr, bytes):
- _stderr = _stderr.decode('utf-8', 'surrogateescape')
+ _stdout = utils.safe_decode_utf8(_stdout)
+ _stderr = utils.safe_decode_utf8(_stderr)
command_str = {
'cmd': cmd,
obj, cmd = create_process(cmd, addl_env=addl_env)
_stdout, _stderr = obj.communicate(_process_input)
obj.stdin.close()
- if six.PY3:
- if isinstance(_stdout, bytes):
- _stdout = _stdout.decode('utf-8', 'surrogateescape')
- if isinstance(_stderr, bytes):
- _stderr = _stderr.decode('utf-8', 'surrogateescape')
+ _stdout = utils.safe_decode_utf8(_stdout)
+ _stderr = utils.safe_decode_utf8(_stderr)
m = _("\nCommand: %(cmd)s\nExit code: %(code)s\nStdin: %(stdin)s\n"
"Stdout: %(stdout)s\nStderr: %(stderr)s") % \
exc_info=True)
raise ImportError(_("Class not found."))
return class_to_load
+
+
+def safe_decode_utf8(s):
+ if six.PY3 and isinstance(s, bytes):
+ return s.decode('utf-8', 'surrogateescape')
+ return s
import os
from oslo_utils import timeutils
+import six
+import testtools
import neutron
from neutron.common import constants
tunneling_ip, interface_mappings,
l2pop_network_types)
return _register_agent(agent)
+
+
+def requires_py2(testcase):
+ return testtools.skipUnless(six.PY2, "requires python 2.x")(testcase)
+
+
+def requires_py3(testcase):
+ return testtools.skipUnless(six.PY3, "requires python 3.x")(testcase)
# under the License.
import eventlet
+import six
from neutron.agent.linux import async_process
from neutron.agent.linux import utils
def setUp(self):
super(AsyncProcessTestFramework, self).setUp()
self.test_file_path = self.get_temp_file_path('test_async_process.tmp')
- self.data = [str(x) for x in range(4)]
+ self.data = [six.text_type(x) for x in range(4)]
with open(self.test_file_path, 'w') as f:
f.writelines('%s\n' % item for item in self.data)
from neutron.agent.linux import utils
from neutron.tests import base
+from neutron.tests.common import helpers
_marker = object()
result = utils.execute(['ls', self.test_file], return_stderr=True)
self.assertEqual((str_data, ''), result)
- @testtools.skipUnless(six.PY3, 'This test makes sense only in Python 3')
+ @helpers.requires_py3
def test_surrogateescape_in_decoding_out_data(self):
bytes_err_data = b'\xed\xa0\xbd'
err_data = bytes_err_data.decode('utf-8', 'surrogateescape')
import eventlet
import mock
import netaddr
+import six
import testtools
from neutron.common import constants
from neutron.plugins.common import constants as p_const
from neutron.plugins.common import utils as plugin_utils
from neutron.tests import base
+from neutron.tests.common import helpers
from oslo_log import log as logging
self.assertEqual(length, len(random_string))
regex = re.compile('^[0-9a-fA-F]+$')
self.assertIsNotNone(regex.match(random_string))
+
+
+class TestSafeDecodeUtf8(base.BaseTestCase):
+
+ @helpers.requires_py2
+ def test_py2_does_nothing(self):
+ s = 'test-py2'
+ self.assertIs(s, utils.safe_decode_utf8(s))
+
+ @helpers.requires_py3
+ def test_py3_decoded_valid_bytes(self):
+ s = bytes('test-py2', 'utf-8')
+ decoded_str = utils.safe_decode_utf8(s)
+ self.assertIsInstance(decoded_str, six.text_type)
+ self.assertEqual(s, decoded_str.encode('utf-8'))
+
+ @helpers.requires_py3
+ def test_py3_decoded_invalid_bytes(self):
+ s = bytes('test-py2', 'utf_16')
+ decoded_str = utils.safe_decode_utf8(s)
+ self.assertIsInstance(decoded_str, six.text_type)
import mock
from oslo_config import cfg
-import six
import six.moves.urllib.request as urlrequest
import testtools
import webob
from neutron.common import exceptions as exception
from neutron.db import api
from neutron.tests import base
+from neutron.tests.common import helpers
from neutron import wsgi
CONF = cfg.CONF
# The tested behaviour is only meant to be witnessed in Python 2, so it is
# OK to skip this test with Python 3.
- @testtools.skipIf(six.PY3, "This test does not make sense in Python 3")
+ @helpers.requires_py2
def test_json_with_utf8(self):
input_dict = dict(servers=dict(a=(2, '\xe7\xbd\x91\xe7\xbb\x9c')))
expected_json = b'{"servers":{"a":[2,"\\u7f51\\u7edc"]}}'