Port swift.common.utils.StatsdClient to Python 3

* StatsdClient._send(): on Python 3, encode parts to UTF-8 and
  replace '|' with b'|' to join parts.
* timing_stats(): replace func.func_name with func.__name__. The
  func_name attribute of functions was removed on Python 3, whereas
  the __name__ attribute is available on Python 2 and Python 3.
* Fix unit tests to use bytes

Change-Id: Ic279c9b54e91aabcc52587eed7758e268ffb155e
This commit is contained in:
Victor Stinner 2015-10-19 16:19:28 +02:00
parent 6830f6f33e
commit 88c9aed7c8
2 changed files with 20 additions and 9 deletions
swift/common
test/unit/common

@ -1166,11 +1166,13 @@ class StatsdClient(object):
parts.append('@%s' % (sample_rate,))
else:
return
if six.PY3:
parts = [part.encode('utf-8') for part in parts]
# Ideally, we'd cache a sending socket in self, but that
# results in a socket getting shared by multiple green threads.
with closing(self._open_socket()) as sock:
try:
return sock.sendto('|'.join(parts), self._target)
return sock.sendto(b'|'.join(parts), self._target)
except IOError as err:
if self.logger:
self.logger.warn(
@ -1227,7 +1229,7 @@ def timing_stats(**dec_kwargs):
swift's wsgi server controllers, based on response code.
"""
def decorating_func(func):
method = func.func_name
method = func.__name__
@functools.wraps(func)
def _timing_stats(ctrl, *args, **kwargs):

@ -34,6 +34,7 @@ import sys
import json
import math
import six
from six import BytesIO, StringIO
from six.moves.queue import Queue, Empty
from six.moves import range
@ -3650,7 +3651,7 @@ class TestStatsdLogging(unittest.TestCase):
self.assertEqual(len(mock_socket.sent), 1)
payload = mock_socket.sent[0][0]
self.assertTrue(payload.endswith("|@0.5"))
self.assertTrue(payload.endswith(b"|@0.5"))
def test_sample_rates_with_sample_rate_factor(self):
logger = utils.get_logger({
@ -3676,8 +3677,10 @@ class TestStatsdLogging(unittest.TestCase):
self.assertEqual(len(mock_socket.sent), 1)
payload = mock_socket.sent[0][0]
self.assertTrue(payload.endswith("|@%s" % effective_sample_rate),
payload)
suffix = "|@%s" % effective_sample_rate
if six.PY3:
suffix = suffix.encode('utf-8')
self.assertTrue(payload.endswith(suffix), payload)
effective_sample_rate = 0.587 * 0.91
statsd_client.random = lambda: effective_sample_rate - 0.001
@ -3685,8 +3688,10 @@ class TestStatsdLogging(unittest.TestCase):
self.assertEqual(len(mock_socket.sent), 2)
payload = mock_socket.sent[1][0]
self.assertTrue(payload.endswith("|@%s" % effective_sample_rate),
payload)
suffix = "|@%s" % effective_sample_rate
if six.PY3:
suffix = suffix.encode('utf-8')
self.assertTrue(payload.endswith(suffix), payload)
def test_timing_stats(self):
class MockController(object):
@ -3983,7 +3988,7 @@ class TestStatsdLoggingDelegation(unittest.TestCase):
while True:
try:
payload = self.sock.recv(4096)
if payload and 'STOP' in payload:
if payload and b'STOP' in payload:
return 42
self.queue.put(payload)
except Exception as e:
@ -4006,10 +4011,14 @@ class TestStatsdLoggingDelegation(unittest.TestCase):
def assertStat(self, expected, sender_fn, *args, **kwargs):
got = self._send_and_get(sender_fn, *args, **kwargs)
if six.PY3:
got = got.decode('utf-8')
return self.assertEqual(expected, got)
def assertStatMatches(self, expected_regexp, sender_fn, *args, **kwargs):
got = self._send_and_get(sender_fn, *args, **kwargs)
if six.PY3:
got = got.decode('utf-8')
return self.assertTrue(re.search(expected_regexp, got),
[got, expected_regexp])
@ -4178,7 +4187,7 @@ class TestStatsdLoggingDelegation(unittest.TestCase):
utils.get_valid_utf8_str(valid_utf8_str))
self.assertEqual(valid_utf8_str,
utils.get_valid_utf8_str(unicode_sample))
self.assertEqual('\xef\xbf\xbd\xef\xbf\xbd\xec\xbc\x9d\xef\xbf\xbd',
self.assertEqual(b'\xef\xbf\xbd\xef\xbf\xbd\xec\xbc\x9d\xef\xbf\xbd',
utils.get_valid_utf8_str(invalid_utf8_str))
@reset_logger_state