Skip to content
This repository was archived by the owner on Jul 11, 2022. It is now read-only.

Commit 4200bdb

Browse files
authored
Remove support for non-ascii baggage keys; enable testing with Py 3.6 (#154)
* enable testing with Python 3.6 * some fixes to the codec to handle unicode strings with Py3 * a fix for thrift converter that broke Py3 compatibility in 3.8.0 release * skip crossdock unit tests when on Py3 * remove tests for non-ascii characters in baggage keys - while those tests were passing with Py2, they didn't actually confirm that such baggage was readable on the receiving side, and it didn't really work. It's very hard to make it work because there's no way of knowing which encoding the strings are coming in from inbound request. This change **officially removes support for non-ascii characters in baggage keys.** Signed-off-by: Yuri Shkuro <[email protected]>
1 parent ca16098 commit 4200bdb

File tree

6 files changed

+42
-36
lines changed

6 files changed

+42
-36
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ matrix:
1010
env: COVER=1
1111
- python: '2.7'
1212
env: CROSSDOCK=1
13+
- python: '3.6'
1314

1415
services:
1516
- docker

jaeger_client/codecs.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,14 @@ def inject(self, span_context, carrier):
7474
if six.PY2 and isinstance(key, six.text_type):
7575
encoded_key = key.encode('utf-8')
7676
else:
77-
encoded_value = value
77+
if six.PY3 and isinstance(value, six.binary_type):
78+
encoded_value = str(value, 'utf-8')
79+
else:
80+
encoded_value = value
81+
if six.PY3 and isinstance(key, six.binary_type):
82+
encoded_key = str(key, 'utf-8')
83+
# Leave the below print(), you will thank me next time you debug unicode strings
84+
# print('adding baggage', key, '=>', value, 'as', encoded_key, '=>', encoded_value)
7885
header_key = '%s%s' % (self.baggage_prefix, encoded_key)
7986
carrier[header_key] = encoded_value
8087

jaeger_client/thrift.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ def id_to_int(big_id):
5151

5252
def _to_string(s):
5353
try:
54-
if isinstance(s, six.text_type): # This is unicode() in Python 2 and str in Python 3.
54+
# Thrift in PY2 likes strings as bytes
55+
if six.PY2 and isinstance(s, six.text_type):
5556
return s.encode('utf-8')
5657
else:
5758
return str(s)

tests/test_codecs.py

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@
3535
)
3636

3737

38-
byte255 = bytes(chr(255)) if six.PY2 else bytes([255])
39-
40-
4138
class TestCodecs(unittest.TestCase):
4239

4340

@@ -117,12 +114,11 @@ def test_context_to_readable_headers(self):
117114
assert carrier == {'trace-id': '100:7f:0:1'}
118115

119116
ctx._baggage = {
120-
'fry': u'Leela',
121117
'bender': 'Countess de la Roca',
122-
b'key1': byte255,
123-
u'key2-caf\xe9': 'caf\xc3\xa9',
124-
u'key3': u'caf\xe9',
125-
'key4-caf\xc3\xa9': 'value',
118+
'fry': u'Leela',
119+
b'key1': bytes(chr(75)) if six.PY2 else bytes([75]),
120+
u'key2': 'cafe',
121+
u'key3': u'\U0001F47E',
126122
}
127123
carrier = {}
128124
codec.inject(ctx, carrier)
@@ -134,10 +130,9 @@ def test_context_to_readable_headers(self):
134130
'trace-id': '100:7f:0:1',
135131
'trace-attr-bender': 'Countess%20de%20la%20Roca',
136132
'trace-attr-fry': 'Leela',
137-
'trace-attr-key1': '%FF',
138-
'trace-attr-key2-caf\xc3\xa9': 'caf%C3%A9',
139-
'trace-attr-key3': 'caf%C3%A9',
140-
'trace-attr-key4-caf\xc3\xa9': 'value',
133+
'trace-attr-key1': 'K',
134+
'trace-attr-key2': 'cafe',
135+
'trace-attr-key3': '%F0%9F%91%BE',
141136
}, 'with url_encoding = %s' % url_encoding
142137
for key, val in six.iteritems(carrier):
143138
assert isinstance(key, str)
@@ -147,10 +142,9 @@ def test_context_to_readable_headers(self):
147142
'trace-id': '100:7f:0:1',
148143
'trace-attr-bender': 'Countess de la Roca',
149144
'trace-attr-fry': 'Leela',
150-
'trace-attr-key1': '\xff',
151-
u'trace-attr-key2-caf\xe9': 'caf\xc3\xa9',
152-
u'trace-attr-key3': u'caf\xe9',
153-
'trace-attr-key4-caf\xc3\xa9': 'value',
145+
'trace-attr-key1': 'K',
146+
u'trace-attr-key2': 'cafe',
147+
'trace-attr-key3': u'\U0001F47E',
154148
}, 'with url_encoding = %s' % url_encoding
155149

156150
def test_context_from_bad_readable_headers(self):
@@ -401,14 +395,14 @@ def test_debug_id():
401395
assert tags[0].vStr == 'Coraline'
402396

403397

404-
def test_non_ascii_baggage_with_httplib(httpserver):
405-
# TODO this test requires `futurize`. Unfortunately, that also changes
406-
# how the test works under Py2.
407-
# Some observation:
408-
# - In Py2, the httplib does not like unicode strings, maybe we need to convert everything to bytes.
409-
# - Not sure yet what's the story with httplib in Py3, it seems not to like raw bytes.
410-
if six.PY3:
411-
raise ValueError('this test does not work with Py3')
398+
def test_baggage_as_unicode_strings_with_httplib(httpserver):
399+
if six.PY2:
400+
import urllib2
401+
urllib_under_test = urllib2
402+
else:
403+
import urllib.request
404+
urllib_under_test = urllib.request
405+
412406
# httpserver is provided by pytest-localserver
413407
httpserver.serve_content(content='Hello', code=200, headers=None)
414408

@@ -421,11 +415,11 @@ def test_non_ascii_baggage_with_httplib(httpserver):
421415
tracer.codecs[Format.TEXT_MAP] = TextCodec(url_encoding=True)
422416

423417
baggage = [
424-
(b'key', b'value'),
425-
(u'key', b'value'),
426-
(b'key', byte255),
427-
(u'caf\xe9', 'caf\xc3\xa9'),
428-
('caf\xc3\xa9', 'value'),
418+
(b'key1', b'value'),
419+
(u'key2', b'value'),
420+
('key3', u'value'),
421+
(b'key4', bytes(chr(255)) if six.PY2 else bytes([255])),
422+
(u'key5', u'\U0001F47E')
429423
]
430424
for b in baggage:
431425
span = tracer.start_span('test')
@@ -436,8 +430,7 @@ def test_non_ascii_baggage_with_httplib(httpserver):
436430
span_context=span.context, format=Format.TEXT_MAP, carrier=headers
437431
)
438432
# make sure httplib doesn't blow up
439-
import urllib2
440-
request = urllib2.Request(httpserver.url, None, headers)
441-
response = urllib2.urlopen(request)
433+
request = urllib_under_test.Request(httpserver.url, None, headers)
434+
response = urllib_under_test.urlopen(request)
442435
assert response.read() == b'Hello'
443436
response.close()

tests/test_crossdock.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414

1515
from __future__ import absolute_import
1616

17+
import six
1718
import mock
1819
import json
1920
import pytest
2021
import opentracing
2122
from mock import MagicMock
22-
from crossdock.server import server
23+
if six.PY2:
24+
from crossdock.server import server
2325
from tornado.httpclient import HTTPRequest
2426
from jaeger_client import Tracer, ConstSampler
2527
from jaeger_client.reporter import InMemoryReporter
@@ -60,6 +62,7 @@ def tracer():
6062
# noinspection PyShadowingNames
6163
@pytest.mark.parametrize('s2_transport,s3_transport,sampled', PERMUTATIONS)
6264
@pytest.mark.gen_test
65+
@pytest.mark.skipif(six.PY3, reason="crossdock tests need tchannel that only works with Python 2.7")
6366
def test_trace_propagation(
6467
s2_transport, s3_transport, sampled, tracer,
6568
base_url, http_port, http_client):
@@ -122,6 +125,7 @@ def test_trace_propagation(
122125

123126
# noinspection PyShadowingNames
124127
@pytest.mark.gen_test
128+
@pytest.mark.skipif(six.PY3, reason="crossdock tests need tchannel that only works with Python 2.7")
125129
def test_endtoend_handler(tracer):
126130
payload = dict()
127131
payload["operation"] = "Zoidberg"

tests/test_local_agent_net.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ def test_request_sampling_strategy(http_client, base_url):
5151
reporting_port=DEFAULT_REPORTING_PORT
5252
)
5353
response = yield sender.request_sampling_strategy(service_name='svc', timeout=15)
54-
assert response.body == test_strategy
54+
assert response.body == test_strategy.encode('utf-8')

0 commit comments

Comments
 (0)