watch: Avoid double-decoding in python3
Both iter_content and the first line of the loop in the etcd3gw watch code were decoding the chunk received. In python2, this works fine: ``` $ python2 -c "print(b'hello_world'.decode().decode('utf-8'))" hello_world ``` In python3, it raises an AttributeError: ``` $ python3 -c "print(b'hello_world'.decode().decode('utf-8'))" Traceback (most recent call last): File "<string>", line 1, in <module> AttributeError: 'str' object has no attribute 'decode' ``` Thus, etcd3gw's watch is broken in python3. This commit fixes it by only decoding the line once. Signed-off-by: Tyler J. Stachecki <tstachecki@bloomberg.net> Change-Id: I203574a1ef4996a43860350be59fbe208457562d Closes-Bug: 1950517
This commit is contained in:
parent
9d50411b6f
commit
ed899b34e4
etcd3gw
@ -17,12 +17,16 @@ test_etcd3-gateway
|
||||
Tests for `etcd3gw` module.
|
||||
"""
|
||||
|
||||
import base64
|
||||
import json
|
||||
import requests
|
||||
import six
|
||||
import threading
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from testtools.testcase import unittest
|
||||
from unittest import mock
|
||||
import urllib3
|
||||
|
||||
from etcd3gw.client import Etcd3Client
|
||||
@ -404,3 +408,30 @@ class TestEtcd3Gateway(base.TestCase):
|
||||
keys = lease.keys()
|
||||
self.assertEqual(1, len(keys))
|
||||
self.assertIn(six.b(key), keys)
|
||||
|
||||
def my_iter_content(self, *args, **kwargs):
|
||||
payload = json.dumps({
|
||||
'result': {
|
||||
'events': [{
|
||||
'kv': {'key': base64.b64encode(b'value').decode('utf-8')},
|
||||
}]
|
||||
}
|
||||
})
|
||||
|
||||
if not kwargs.get('decode_unicode', False):
|
||||
payload = payload.encode()
|
||||
return [payload]
|
||||
|
||||
@mock.patch.object(requests.Response, 'iter_content', new=my_iter_content)
|
||||
@mock.patch.object(requests.sessions.Session, 'post')
|
||||
def test_watch_unicode(self, mock_post):
|
||||
mocked_response = requests.Response()
|
||||
mocked_response.connection = mock.Mock()
|
||||
mock_post.return_value = mocked_response
|
||||
|
||||
try:
|
||||
res = self.client.watch_once('/some/key', timeout=1)
|
||||
except exceptions.WatchTimedOut:
|
||||
self.fail("watch timed out when server responded with unicode")
|
||||
|
||||
self.assertEqual(res, {'kv': {'key': b'value'}})
|
||||
|
@ -19,7 +19,7 @@ from etcd3gw.utils import _get_threadpool_executor
|
||||
|
||||
|
||||
def _watch(resp, callback):
|
||||
for line in resp.iter_content(chunk_size=None, decode_unicode=True):
|
||||
for line in resp.iter_content(chunk_size=None, decode_unicode=False):
|
||||
decoded_line = line.decode('utf-8')
|
||||
payload = json.loads(decoded_line)
|
||||
if 'created' in payload['result']:
|
||||
|
Loading…
x
Reference in New Issue
Block a user