diff --git a/opencensus/trace/propagation/binary_format.py b/opencensus/trace/propagation/binary_format.py index b73492bad..3d078ab6b 100644 --- a/opencensus/trace/propagation/binary_format.py +++ b/opencensus/trace/propagation/binary_format.py @@ -17,7 +17,7 @@ import logging import struct -from opencensus.trace.span_context import SpanContext +from opencensus.trace import span_context as span_context_module from opencensus.trace.trace_options import TraceOptions # Used for decoding hex bytes to hex string. @@ -54,7 +54,7 @@ trace_id_field_id=UNSIGNED_CHAR, trace_id='{}{}'.format(TRACE_ID_SIZE, CHAR_ARRAY_FORMAT), span_id_field_id=UNSIGNED_CHAR, - span_id=UNSIGNED_LONG_LONG, + span_id='{}{}'.format(SPAN_ID_SIZE, CHAR_ARRAY_FORMAT), trace_option_field_id=UNSIGNED_CHAR, trace_option=UNSIGNED_CHAR) @@ -80,15 +80,15 @@ class BinaryFormatPropagator(object): [SpanContext] trace_id: hex string with length 32. e.g. 'a0b72ca15c1a4bd18962d0ac59dc90b9' - span_id: 64 bits integer. - e.g. 7433567179112518326 + span_id: hex string with length 16. + e.g. 'a0b72ca15c1a4bd1' enabled (trace option): bool. e.g. True [Binary Format] trace_id: Bytes with length 16. e.g. b'\xa0\xb7,\xa1\\\x1aK\xd1\x89b\xd0\xacY\xdc\x90\xb9' span_id: Bytes with length 8. - e.g. b'\xb6\x12\x01\xf5\xf6U)g' + e.g. b'\x00\xf0g\xaa\x0b\xa9\x02\xb7' trace_option: Byte with length 1. e.g. b'\x01' """ @@ -106,25 +106,28 @@ def from_header(self, binary): """ # If no binary provided, generate a new SpanContext if binary is None: - return SpanContext(from_header=False) + return span_context_module.SpanContext(from_header=False) # If cannot parse, return a new SpanContext and ignore the context # from binary. try: data = Header._make(struct.unpack(BINARY_FORMAT, binary)) except struct.error: - logging.warn('Cannot parse the incoming binary data {}, ' - 'wrong format. Total bytes length should be {}.' - .format(binary, FORMAT_LENGTH)) - return SpanContext(from_header=False) + logging.warning( + 'Cannot parse the incoming binary data {}, ' + 'wrong format. Total bytes length should be {}.'.format( + binary, FORMAT_LENGTH + ) + ) + return span_context_module.SpanContext(from_header=False) # data.trace_id is in bytes with length 16, hexlify it to hex bytes # with length 32, then decode it to hex string using utf-8. trace_id = str(binascii.hexlify(data.trace_id).decode(UTF8)) - span_id = data.span_id + span_id = str(binascii.hexlify(data.span_id).decode(UTF8)) trace_options = TraceOptions(data.trace_option) - span_context = SpanContext( + span_context = span_context_module.SpanContext( trace_id=trace_id, span_id=span_id, trace_options=trace_options, @@ -149,7 +152,7 @@ def to_header(self, span_context): # If there is no span_id in this context, set it to 0, which is # considered invalid and won't be set as the downstream parent span_id. if span_id is None: - span_id = 0 + span_id = span_context_module.INVALID_SPAN_ID # Convert trace_id to bytes with length 16, treat span_id as 64 bit # integer which is unsigned long long type and convert it to bytes with @@ -160,6 +163,6 @@ def to_header(self, span_context): TRACE_ID_FIELD_ID, binascii.unhexlify(trace_id), SPAN_ID_FIELD_ID, - span_id, + binascii.unhexlify(span_id), TRACE_OPTION_FIELD_ID, trace_options) diff --git a/opencensus/trace/propagation/google_cloud_format.py b/opencensus/trace/propagation/google_cloud_format.py index 1c1b607e8..8c635dd73 100644 --- a/opencensus/trace/propagation/google_cloud_format.py +++ b/opencensus/trace/propagation/google_cloud_format.py @@ -18,7 +18,7 @@ from opencensus.trace.span_context import SpanContext from opencensus.trace.trace_options import TraceOptions -_TRACE_CONTEXT_HEADER_FORMAT = '([0-9a-f]{32})(\/(\d+))?(;o=(\d+))?' +_TRACE_CONTEXT_HEADER_FORMAT = '([0-9a-f]{32})(\/([0-9a-f]{16}))?(;o=(\d+))?' _TRACE_CONTEXT_HEADER_RE = re.compile(_TRACE_CONTEXT_HEADER_FORMAT) _TRACE_ID_DELIMETER = '/' _SPAN_ID_DELIMETER = ';' diff --git a/opencensus/trace/propagation/trace_context_http_header_format.py b/opencensus/trace/propagation/trace_context_http_header_format.py index 1098ffba2..3ac3301f6 100644 --- a/opencensus/trace/propagation/trace_context_http_header_format.py +++ b/opencensus/trace/propagation/trace_context_http_header_format.py @@ -61,7 +61,7 @@ def from_header(self, header): # Need to convert span_id from hex string to int span_context = SpanContext( trace_id=trace_id, - span_id=int(span_id, 16), + span_id=span_id, trace_options=TraceOptions(trace_options), from_header=True) return span_context @@ -90,10 +90,6 @@ def to_header(self, span_context): span_id = span_context.span_id trace_options = span_context.trace_options.enabled - # Need to convert span_id from int to hex string - span_id_hex = hex(span_id) - span_id = span_id_hex[2:].zfill(16) - # Convert the trace options trace_options = '01' if trace_options else '00' diff --git a/opencensus/trace/span_context.py b/opencensus/trace/span_context.py index 97c02d961..e01c425e9 100644 --- a/opencensus/trace/span_context.py +++ b/opencensus/trace/span_context.py @@ -15,16 +15,17 @@ """SpanContext encapsulates the current context within the request's trace.""" import logging -import random import re import uuid from opencensus.trace import trace_options _INVALID_TRACE_ID = '0' * 32 -_INVALID_SPAN_ID = 0 +INVALID_SPAN_ID = '0' * 16 _TRACE_HEADER_KEY = 'X_CLOUD_TRACE_CONTEXT' -_TRACE_ID_FORMAT = '[0-9a-f]{32}?' + +TRACE_ID_PATTERN = re.compile('[0-9a-f]{32}?') +SPAN_ID_PATTERN = re.compile('[0-9a-f]{16}?') # Default options, enable tracing DEFAULT_OPTIONS = 1 @@ -42,8 +43,9 @@ class SpanContext(object): :param trace_id: (Optional) Trace_id is a 32 digits uuid for the trace. If not given, will generate one automatically. - :type span_id: int + :type span_id: str :param span_id: (Optional) Identifier for the span, unique within a trace. + If not given, will generate one automatically. :type trace_options: :class: `~opencensus.trace.trace_options.TraceOptions` :param trace_options: (Optional) TraceOptions indicates 8 trace options. @@ -64,10 +66,10 @@ def __init__( if trace_options is None: trace_options = DEFAULT - self.trace_id = self.check_trace_id(trace_id) - self.span_id = self.check_span_id(span_id) - self.trace_options = trace_options self.from_header = from_header + self.trace_id = self._check_trace_id(trace_id) + self.span_id = self._check_span_id(span_id) + self.trace_options = trace_options def __str__(self): """Returns a string form of the SpanContext. This is the format of @@ -84,41 +86,42 @@ def __str__(self): int(enabled)) return header - def check_span_id(self, span_id): - """Check the type of span_id to ensure it is int. If it is not int, - first try to convert it to int, if failed to convert, then log a - warning message and set the span_id to None. + def _check_span_id(self, span_id): + """Check the format of the span_id to ensure it is 16-character hex + value representing a 64-bit number. If span_id is invalid, logs a + warning message and returns None - :type span_id: int - :param span_id: Identifier for the span, unique within a trace. + :type span_id: str + :param span_id: Identifier for the span, unique within a span. - :rtype: int + :rtype: str :returns: Span_id for the current span. """ if span_id is None: return None + assert isinstance(span_id, str) - if span_id == 0: + if span_id is INVALID_SPAN_ID: logging.warning( - 'Span_id {} is invalid, cannot be zero.'.format(span_id)) + 'Span_id {} is invalid (cannot be all zero)'.format(span_id)) self.from_header = False return None - if not isinstance(span_id, int): - try: - span_id = int(span_id) - except (TypeError, ValueError): - logging.warning( - 'The type of span_id should be int, got {}.'.format( - span_id.__class__.__name__)) - self.from_header = False - span_id = None + match = SPAN_ID_PATTERN.match(span_id) - return span_id + if match: + return span_id + else: + logging.warning( + 'Span_id {} does not the match the ' + 'required format'.format(span_id)) + self.from_header = False + return None - def check_trace_id(self, trace_id): + def _check_trace_id(self, trace_id): """Check the format of the trace_id to ensure it is 32-character hex - value representing a 128-bit number. Also the trace_id cannot be zero. + value representing a 128-bit number. If trace_id is invalid, returns a + randomly generated trace id :type trace_id: str :param trace_id: @@ -131,41 +134,39 @@ def check_trace_id(self, trace_id): if trace_id is _INVALID_TRACE_ID: logging.warning( 'Trace_id {} is invalid (cannot be all zero), ' - 'generate a new one.'.format(trace_id)) + 'generating a new one.'.format(trace_id)) self.from_header = False return generate_trace_id() - trace_id_pattern = re.compile(_TRACE_ID_FORMAT) - - match = trace_id_pattern.match(trace_id) + match = TRACE_ID_PATTERN.match(trace_id) if match: return trace_id else: logging.warning( 'Trace_id {} does not the match the required format,' - 'generate a new one instead.'.format(trace_id)) + 'generating a new one instead.'.format(trace_id)) self.from_header = False return generate_trace_id() def generate_span_id(): - """Return the random generated span ID for a span. Must be 16 digits - as Stackdriver Trace V2 API only accepts 16 digits span ID. + """Return the random generated span ID for a span. Must be a 16 character + hexadecimal encoded string - :rtype: int - :returns: Identifier for the span. Must be a 64-bit integer other - than 0 and unique within a trace. + :rtype: str + :returns: 16 digit randomly generated hex trace id. """ - span_id = random.randint(10**15, 10**16 - 1) + span_id = uuid.uuid4().hex[:16] return span_id def generate_trace_id(): - """Generate a trace_id randomly. + """Generate a trace_id randomly. Must be a 32 character + hexadecimal encoded string :rtype: str - :returns: 32 digit randomly generated trace ID. + :returns: 32 digit randomly generated hex trace id. """ trace_id = uuid.uuid4().hex return trace_id diff --git a/tests/system/trace/basic_trace/basic_trace_system_test.py b/tests/system/trace/basic_trace/basic_trace_system_test.py index 2ba3803d7..d919249ba 100644 --- a/tests/system/trace/basic_trace/basic_trace_system_test.py +++ b/tests/system/trace/basic_trace/basic_trace_system_test.py @@ -32,7 +32,7 @@ def test_tracer(self): from opencensus.trace.propagation import google_cloud_format trace_id = 'f8739df974a4481f98748cd92b27177d' - span_id = '16971691944144156899' + span_id = '6e0c63257de34c92' trace_option = 1 trace_header = '{}/{};o={}'.format(trace_id, span_id, trace_option) diff --git a/tests/system/trace/django/django_system_test.py b/tests/system/trace/django/django_system_test.py index 9871037df..5462c2260 100644 --- a/tests/system/trace/django/django_system_test.py +++ b/tests/system/trace/django/django_system_test.py @@ -43,7 +43,7 @@ def wait_app_to_start(): def generate_header(): """Generate a trace header.""" trace_id = uuid.uuid4().hex - span_id = random.randint(10**15, 10**16 - 1) + span_id = uuid.uuid4().hex[:16] trace_option = 1 header = '{}/{};o={}'.format(trace_id, span_id, trace_option) diff --git a/tests/system/trace/flask/flask_system_test.py b/tests/system/trace/flask/flask_system_test.py index 3ca0bc4e6..f7c20ae1f 100644 --- a/tests/system/trace/flask/flask_system_test.py +++ b/tests/system/trace/flask/flask_system_test.py @@ -42,7 +42,7 @@ def wait_app_to_start(): def generate_header(): """Generate a trace header.""" trace_id = uuid.uuid4().hex - span_id = random.randint(10**15, 10**16 - 1) + span_id = uuid.uuid4().hex[:16] trace_option = 1 header = '{}/{};o={}'.format(trace_id, span_id, trace_option) diff --git a/tests/unit/trace/exporters/test_stackdriver_exporter.py b/tests/unit/trace/exporters/test_stackdriver_exporter.py index 8cc989619..dfce4eb4e 100644 --- a/tests/unit/trace/exporters/test_stackdriver_exporter.py +++ b/tests/unit/trace/exporters/test_stackdriver_exporter.py @@ -144,7 +144,7 @@ def test_translate_to_stackdriver(self): project_id = 'PROJECT' trace_id = '6e0c63257de34c92bf9efcd03927272e' span_name = 'test span' - span_id = 1234 + span_id = '6e0c63257de34c92' attributes = { 'attributeMap': { 'key': { @@ -155,7 +155,7 @@ def test_translate_to_stackdriver(self): } } } - parent_span_id = 1111 + parent_span_id = '6e0c63257de34c93' start_time = 'test start time' end_time = 'test end time' trace = { diff --git a/tests/unit/trace/exporters/test_zipkin_exporter.py b/tests/unit/trace/exporters/test_zipkin_exporter.py index 69035c939..34715da8e 100644 --- a/tests/unit/trace/exporters/test_zipkin_exporter.py +++ b/tests/unit/trace/exporters/test_zipkin_exporter.py @@ -98,8 +98,8 @@ def test_translate_to_zipkin_span_kind_none(self): span_data_module.SpanData( name='child_span', context=span_context.SpanContext(trace_id=trace_id), - span_id=1234567890, - parent_span_id=1111111111, + span_id='6e0c63257de34c92', + parent_span_id='6e0c63257de34c93', attributes={'test_key': 'test_value'}, start_time='2017-08-15T18:02:26.071158Z', end_time='2017-08-15T18:02:36.071158Z', @@ -114,8 +114,8 @@ def test_translate_to_zipkin_span_kind_none(self): span_data_module.SpanData( name='child_span', context=span_context.SpanContext(trace_id=trace_id), - span_id=1234567890, - parent_span_id=1111111111, + span_id='6e0c63257de34c92', + parent_span_id='6e0c63257de34c93', attributes={'test_key': 1}, start_time='2017-08-15T18:02:26.071158Z', end_time='2017-08-15T18:02:36.071158Z', @@ -134,7 +134,7 @@ def test_translate_to_zipkin_span_kind_none(self): span_data_module.SpanData( name='child_span', context=span_context.SpanContext(trace_id=trace_id), - span_id=1234567890, + span_id='6e0c63257de34c92', parent_span_id=None, attributes={ 'test_key': False, @@ -172,8 +172,8 @@ def test_translate_to_zipkin_span_kind_none(self): expected_zipkin_spans_ipv4 = [ { 'traceId': '6e0c63257de34c92bf9efcd03927272e', - 'id': '1234567890', - 'parentId': '1111111111', + 'id': '6e0c63257de34c92', + 'parentId': '6e0c63257de34c93', 'name': 'child_span', 'timestamp': 1502820146000000, 'duration': 10000000, @@ -182,8 +182,8 @@ def test_translate_to_zipkin_span_kind_none(self): }, { 'traceId': '6e0c63257de34c92bf9efcd03927272e', - 'id': '1234567890', - 'parentId': '1111111111', + 'id': '6e0c63257de34c92', + 'parentId': '6e0c63257de34c93', 'name': 'child_span', 'timestamp': 1502820146000000, 'duration': 10000000, @@ -195,7 +195,7 @@ def test_translate_to_zipkin_span_kind_none(self): expected_zipkin_spans_ipv6 = [ { 'traceId': '6e0c63257de34c92bf9efcd03927272e', - 'id': '1234567890', + 'id': '6e0c63257de34c92', 'name': 'child_span', 'timestamp': 1502820146000000, 'duration': 10000000, diff --git a/tests/unit/trace/ext/django/test_middleware.py b/tests/unit/trace/ext/django/test_middleware.py index fd44eff0c..53ddcf959 100644 --- a/tests/unit/trace/ext/django/test_middleware.py +++ b/tests/unit/trace/ext/django/test_middleware.py @@ -12,9 +12,21 @@ # See the License for the specific language governing permissions and # limitations under the License. +import unittest + import mock +from django.test import RequestFactory +from django.test.utils import teardown_test_environment -import unittest +from opencensus.trace import execution_context +from opencensus.trace.exporters import print_exporter +from opencensus.trace.exporters import zipkin_exporter +from opencensus.trace.exporters.transports import sync +from opencensus.trace.ext import utils +from opencensus.trace.propagation import google_cloud_format +from opencensus.trace.samplers import always_on +from opencensus.trace.samplers import probability +from opencensus.trace.tracers import base class TestOpencensusMiddleware(unittest.TestCase): @@ -28,18 +40,11 @@ def setUp(self): setup_test_environment() def tearDown(self): - from django.test.utils import teardown_test_environment - from opencensus.trace import execution_context - execution_context.clear() - teardown_test_environment() def test_constructor_cloud(self): from opencensus.trace.ext.django import middleware - from opencensus.trace.samplers import always_on - from opencensus.trace.propagation import google_cloud_format - from opencensus.trace.exporters.transports import sync class MockCloudExporter(object): def __init__(self, project_id, transport): @@ -83,9 +88,6 @@ def __init__(self, project_id, transport): def test_constructor_zipkin(self): from opencensus.trace.ext.django import middleware - from opencensus.trace.samplers import always_on - from opencensus.trace.exporters import zipkin_exporter - from opencensus.trace.propagation import google_cloud_format service_name = 'test_service' host_name = 'test_hostname' @@ -129,9 +131,6 @@ def test_constructor_zipkin(self): def test_constructor_probability_sampler(self): from opencensus.trace.ext.django import middleware - from opencensus.trace.samplers import probability - from opencensus.trace.exporters import print_exporter - from opencensus.trace.propagation import google_cloud_format rate = 0.8 params = { @@ -171,12 +170,10 @@ def test_constructor_probability_sampler(self): self.assertEqual(middleware.sampler.rate, rate) def test_process_request(self): - from django.test import RequestFactory - from opencensus.trace.ext.django import middleware trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 123 + span_id = '6e0c63257de34c92' django_trace_id = '{}/{}'.format(trace_id, span_id) django_request = RequestFactory().get('/', **{ @@ -208,21 +205,15 @@ def test_process_request(self): self.assertEqual(span.name, 'mock.mock.Mock') def test_blacklist_path(self): - from django.test import RequestFactory - from opencensus.trace.ext.django import middleware - from opencensus.trace.tracers import base - from opencensus.trace.tracers import noop_tracer - from opencensus.trace.ext import utils - from opencensus.trace import execution_context execution_context.clear() - blacklist_paths = ['test_blacklist_path',] + blacklist_paths = ['test_blacklist_path', ] params = { - 'BLACKLIST_PATHS': ['test_blacklist_path',], + 'BLACKLIST_PATHS': ['test_blacklist_path', ], 'TRANSPORT': - 'opencensus.trace.exporters.transports.sync.SyncTransport',} + 'opencensus.trace.exporters.transports.sync.SyncTransport', } patch_params = mock.patch( 'opencensus.trace.ext.django.middleware.settings.params', params) @@ -262,12 +253,10 @@ def test_blacklist_path(self): assert isinstance(span, base.NullContextManager) def test_process_response(self): - from django.test import RequestFactory - from opencensus.trace.ext.django import middleware trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 123 + span_id = '6e0c63257de34c92' django_trace_id = '{}/{}'.format(trace_id, span_id) django_request = RequestFactory().get('/', **{ @@ -304,7 +293,6 @@ def test_process_response(self): class Test__set_django_attributes(unittest.TestCase): - class Tracer(object): def __init__(self): self.attributes = {} @@ -313,8 +301,8 @@ def add_attribute_to_current_span(self, key, value): self.attributes[key] = value def test__set_django_attributes_no_user(self): - from opencensus.trace.ext.django.middleware import _set_django_attributes - + from opencensus.trace.ext.django.middleware import \ + _set_django_attributes tracer = self.Tracer() request = mock.Mock() @@ -327,8 +315,8 @@ def test__set_django_attributes_no_user(self): self.assertEqual(tracer.attributes, expected_attributes) def test__set_django_attributes_no_user_info(self): - from opencensus.trace.ext.django.middleware import _set_django_attributes - + from opencensus.trace.ext.django.middleware import \ + _set_django_attributes tracer = self.Tracer() request = mock.Mock() django_user = mock.Mock() @@ -344,8 +332,8 @@ def test__set_django_attributes_no_user_info(self): self.assertEqual(tracer.attributes, expected_attributes) def test__set_django_attributes_with_user_info(self): - from opencensus.trace.ext.django.middleware import _set_django_attributes - + from opencensus.trace.ext.django.middleware import \ + _set_django_attributes tracer = self.Tracer() request = mock.Mock() django_user = mock.Mock() diff --git a/tests/unit/trace/ext/flask/test_flask_middleware.py b/tests/unit/trace/ext/flask/test_flask_middleware.py index 1f7e7d598..0c172fe0b 100644 --- a/tests/unit/trace/ext/flask/test_flask_middleware.py +++ b/tests/unit/trace/ext/flask/test_flask_middleware.py @@ -17,17 +17,23 @@ import unittest +import flask import mock +from opencensus.trace import execution_context +from opencensus.trace.exporters import print_exporter from opencensus.trace.ext.flask import flask_middleware +from opencensus.trace.propagation import google_cloud_format +from opencensus.trace.samplers import always_off +from opencensus.trace.samplers import always_on +from opencensus.trace.tracers import base +from opencensus.trace.tracers import noop_tracer class TestFlaskMiddleware(unittest.TestCase): @staticmethod def create_app(): - import flask - app = flask.Flask(__name__) @app.route('/') @@ -46,10 +52,6 @@ def tearDown(self): execution_context.clear() def test_constructor_default(self): - from opencensus.trace.exporters import print_exporter - from opencensus.trace.samplers import always_on - from opencensus.trace.propagation import google_cloud_format - app = mock.Mock() middleware = flask_middleware.FlaskMiddleware(app=app) @@ -86,7 +88,7 @@ def test__before_request(self): flask_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 1234 + span_id = '6e0c63257de34c92' flask_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() @@ -114,13 +116,9 @@ def test__before_request(self): self.assertEqual(span_context.trace_id, trace_id) def test__before_request_blacklist(self): - from opencensus.trace import execution_context - from opencensus.trace.tracers import base - from opencensus.trace.tracers import noop_tracer - flask_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 1234 + span_id = '6e0c63257de34c92' flask_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() @@ -144,12 +142,10 @@ def test_header_encoding(self): # This test case is expected to fail at the check_trace_id method # in SpanContext because it cannot match the pattern for trace_id, # And a new trace_id will generate for the context. - from opencensus.trace import execution_context - from opencensus.trace.tracers import base flask_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = "你好" - span_id = 1234 + span_id = '6e0c63257de34c92' flask_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() @@ -177,9 +173,6 @@ def test_header_encoding(self): self.assertNotEqual(span_context.trace_id, trace_id) def test_header_is_none(self): - from opencensus.trace import execution_context - from opencensus.trace.tracers import base - app = self.create_app() flask_middleware.FlaskMiddleware(app=app) context = app.test_request_context( @@ -201,11 +194,9 @@ def test_header_is_none(self): assert isinstance(span.parent_span, base.NullContextManager) def test__after_request_not_sampled(self): - from opencensus.trace.samplers import always_off - flask_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 1234 + span_id = '6e0c63257de34c92' flask_trace_id = '{}/{}'.format(trace_id, span_id) sampler = always_off.AlwaysOffSampler() @@ -221,7 +212,7 @@ def test__after_request_not_sampled(self): def test__after_request_sampled(self): flask_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 1234 + span_id = '6e0c63257de34c92' flask_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() @@ -234,12 +225,9 @@ def test__after_request_sampled(self): self.assertEqual(response.status_code, 200) def test__after_request_blacklist(self): - from opencensus.trace import execution_context - from opencensus.trace.tracers import noop_tracer - flask_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 1234 + span_id = '6e0c63257de34c92' flask_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() diff --git a/tests/unit/trace/ext/pyramid/test_pyramid_middleware.py b/tests/unit/trace/ext/pyramid/test_pyramid_middleware.py index 0dbb21cbd..d12ab47f4 100644 --- a/tests/unit/trace/ext/pyramid/test_pyramid_middleware.py +++ b/tests/unit/trace/ext/pyramid/test_pyramid_middleware.py @@ -15,13 +15,23 @@ # See the License for the specific language governing permissions and # limitations under the License. -import mock import unittest +import mock from pyramid.registry import Registry from pyramid.response import Response from pyramid.testing import DummyRequest +from opencensus.trace import execution_context +from opencensus.trace.exporters import print_exporter +from opencensus.trace.exporters import zipkin_exporter +from opencensus.trace.exporters.transports import sync +from opencensus.trace.ext.pyramid import pyramid_middleware +from opencensus.trace.propagation import google_cloud_format +from opencensus.trace.samplers import always_on +from opencensus.trace.tracers import base +from opencensus.trace.tracers import noop_tracer + class TestPyramidMiddleware(unittest.TestCase): def tearDown(self): @@ -30,24 +40,20 @@ def tearDown(self): execution_context.clear() def test_constructor(self): - from opencensus.trace.ext.pyramid import pyramid_middleware - from opencensus.trace.samplers import always_on - from opencensus.trace.propagation import google_cloud_format - from opencensus.trace.exporters.transports import sync - from opencensus.trace.exporters import print_exporter - pyramid_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 1234 + span_id = '6e0c63257de34c92' pyramid_trace_id = '{}/{}'.format(trace_id, span_id) response = Response() + def dummy_handler(request): return response mock_registry = mock.Mock(spec=Registry) mock_registry.settings = {} - mock_registry.settings['OPENCENSUS_TRACE'] = {'EXPORTER': print_exporter.PrintExporter()} + mock_registry.settings['OPENCENSUS_TRACE'] = { + 'EXPORTER': print_exporter.PrintExporter()} middleware = pyramid_middleware.OpenCensusTweenFactory( dummy_handler, @@ -71,17 +77,12 @@ def dummy_handler(request): assert middleware(request) == response def test_constructor_zipkin(self): - from opencensus.trace.ext.pyramid import pyramid_middleware - from opencensus.trace.samplers import always_on - from opencensus.trace.exporters import zipkin_exporter - from opencensus.trace.propagation import google_cloud_format - from opencensus.trace.exporters.transports import sync - service_name = 'test_service' host_name = 'test_hostname' port = 2333 response = Response() + def dummy_handler(request): return response @@ -115,15 +116,13 @@ def dummy_handler(request): self.assertEqual(middleware.exporter.port, port) def test__before_request(self): - from opencensus.trace import execution_context - from opencensus.trace.ext.pyramid import pyramid_middleware - pyramid_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 1234 + span_id = '6e0c63257de34c92' pyramid_trace_id = '{}/{}'.format(trace_id, span_id) response = Response() + def dummy_handler(request): return response @@ -159,17 +158,13 @@ def dummy_handler(request): self.assertEqual(span_context.trace_id, trace_id) def test__before_request_blacklist(self): - from opencensus.trace import execution_context - from opencensus.trace.tracers import base - from opencensus.trace.tracers import noop_tracer - from opencensus.trace.ext.pyramid import pyramid_middleware - pyramid_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 1234 + span_id = '6e0c63257de34c92' pyramid_trace_id = '{}/{}'.format(trace_id, span_id) response = Response() + def dummy_handler(request): return response @@ -197,16 +192,13 @@ def dummy_handler(request): assert isinstance(span, base.NullContextManager) def test__after_request(self): - from opencensus.trace import execution_context - from opencensus.trace.ext.pyramid import pyramid_middleware - from opencensus.trace.samplers import always_off - pyramid_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 1234 + span_id = '6e0c63257de34c92' pyramid_trace_id = '{}/{}'.format(trace_id, span_id) response = Response(status=200) + def dummy_handler(request): return response @@ -244,17 +236,13 @@ def dummy_handler(request): self.assertEqual(span.attributes, expected_attributes) def test__after_request_blacklist(self): - from opencensus.trace import execution_context - from opencensus.trace.tracers import base - from opencensus.trace.tracers import noop_tracer - from opencensus.trace.ext.pyramid import pyramid_middleware - pyramid_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' - span_id = 1234 + span_id = '6e0c63257de34c92' pyramid_trace_id = '{}/{}'.format(trace_id, span_id) response = Response() + def dummy_handler(request): return response diff --git a/tests/unit/trace/propagation/test_binary_format.py b/tests/unit/trace/propagation/test_binary_format.py index 769639a3e..8fd3e148e 100644 --- a/tests/unit/trace/propagation/test_binary_format.py +++ b/tests/unit/trace/propagation/test_binary_format.py @@ -39,12 +39,11 @@ def test_from_header_none(self): self.assertFalse(span_context.from_header) def test_from_header(self): - binary_header = b'\x00\x00\xa0\xb7,\xa1\\\x1aK\xd1\x89b\xd0' \ - b'\xacY\xdc\x90\xb9\x01g)U\xf6\xf5\x01\x12' \ - b'\xb6\x02\x01' + binary_header = b'\x00\x00\xa0\xb7,\xa1\\\x1aK\xd1\x89b\xd0\xacY\xdc' \ + b'\x90\xb9\x01\xa0\xb7,\xa1\\\x1aK\xd1\x02\x01' expected_trace_id = 'a0b72ca15c1a4bd18962d0ac59dc90b9' - expected_span_id = 7433567179112518326 + expected_span_id = 'a0b72ca15c1a4bd1' expected_trace_option = True propagator = binary_format.BinaryFormatPropagator() @@ -74,8 +73,8 @@ def test_to_header_span_id_zero(self): binary_header = propagator.to_header(span_context) expected_binary_header = b'\x00\x00\xa0\xb7,\xa1\\\x1aK\xd1\x89b\xd0' \ - b'\xacY\xdc\x90\xb9\x01\x00\x00\x00\x00\x00' \ - b'\x00\x00\x00\x02\x01' + b'\xacY\xdc\x90\xb9\x01\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x02\x01' self.assertEqual(expected_binary_header, binary_header) @@ -85,7 +84,7 @@ def test_to_header(self): span_context = mock.Mock(spec=SpanContext) trace_id = 'a0b72ca15c1a4bd18962d0ac59dc90b9' - span_id = 7433567179112518326 + span_id = 'a0b72ca15c1a4bd1' trace_options = '1' span_context.trace_id = trace_id span_context.span_id = span_id @@ -95,8 +94,8 @@ def test_to_header(self): binary_header = propagator.to_header(span_context) - expected_binary_header = b'\x00\x00\xa0\xb7,\xa1\\\x1aK\xd1\x89b\xd0' \ - b'\xacY\xdc\x90\xb9\x01g)U\xf6\xf5\x01\x12' \ - b'\xb6\x02\x01' + expected_binary_header = b'\x00\x00\xa0\xb7,\xa1\\\x1aK' \ + b'\xd1\x89b\xd0\xacY\xdc' \ + b'\x90\xb9\x01\xa0\xb7,\xa1\\\x1aK\xd1\x02\x01' self.assertEqual(expected_binary_header, binary_header) diff --git a/tests/unit/trace/propagation/test_google_cloud_format.py b/tests/unit/trace/propagation/test_google_cloud_format.py index 3124f4a3d..b18e7d4aa 100644 --- a/tests/unit/trace/propagation/test_google_cloud_format.py +++ b/tests/unit/trace/propagation/test_google_cloud_format.py @@ -37,9 +37,9 @@ def test_header_type_error(self): def test_header_match(self): # Trace option is not enabled. - header = '6e0c63257de34c92bf9efcd03927272e/1234;o=0' + header = '6e0c63257de34c92bf9efcd03927272e/00f067aa0ba902b7;o=0' expected_trace_id = '6e0c63257de34c92bf9efcd03927272e' - expected_span_id = 1234 + expected_span_id = '00f067aa0ba902b7' propagator = google_cloud_format.GoogleCloudFormatPropagator() span_context = propagator.from_header(header) @@ -49,9 +49,9 @@ def test_header_match(self): self.assertFalse(span_context.trace_options.enabled) # Trace option is enabled. - header = '6e0c63257de34c92bf9efcd03927272e/1234;o=1' + header = '6e0c63257de34c92bf9efcd03927272e/00f067aa0ba902b7;o=1' expected_trace_id = '6e0c63257de34c92bf9efcd03927272e' - expected_span_id = 1234 + expected_span_id = '00f067aa0ba902b7' propagator = google_cloud_format.GoogleCloudFormatPropagator() span_context = propagator.from_header(header) @@ -61,9 +61,9 @@ def test_header_match(self): self.assertTrue(span_context.trace_options.enabled) def test_header_match_no_option(self): - header = '6e0c63257de34c92bf9efcd03927272e/1234' + header = '6e0c63257de34c92bf9efcd03927272e/00f067aa0ba902b7' expected_trace_id = '6e0c63257de34c92bf9efcd03927272e' - expected_span_id = 1234 + expected_span_id = '00f067aa0ba902b7' propagator = google_cloud_format.GoogleCloudFormatPropagator() span_context = propagator.from_header(header) @@ -86,7 +86,7 @@ def test_to_header(self): from opencensus.trace import trace_options trace_id = '6e0c63257de34c92bf9efcd03927272e' - span_id = 1234 + span_id = '00f067aa0ba902b7' span_context = span_context.SpanContext( trace_id=trace_id, span_id=span_id, diff --git a/tests/unit/trace/propagation/test_text_format.py b/tests/unit/trace/propagation/test_text_format.py index 260b4e8a0..2b6fbf0e2 100644 --- a/tests/unit/trace/propagation/test_text_format.py +++ b/tests/unit/trace/propagation/test_text_format.py @@ -18,11 +18,12 @@ from opencensus.trace.propagation import text_format + class Test_from_carrier(unittest.TestCase): def test_from_carrier_keys_exist(self): test_trace_id = '6e0c63257de34c92bf9efcd03927272e' - test_span_id = 1234 + test_span_id = '00f067aa0ba902b7' test_options = 1 carrier = { @@ -53,7 +54,7 @@ def test_from_carrier_keys_not_exist(self): def test_to_carrier_has_span_id(self): test_trace_id = '6e0c63257de34c92bf9efcd03927272e' - test_span_id = 1234 + test_span_id = '00f067aa0ba902b7' test_options = '2' span_context = mock.Mock() diff --git a/tests/unit/trace/propagation/test_trace_context_http_header_format.py b/tests/unit/trace/propagation/test_trace_context_http_header_format.py index 4989cde70..dc75694f9 100644 --- a/tests/unit/trace/propagation/test_trace_context_http_header_format.py +++ b/tests/unit/trace/propagation/test_trace_context_http_header_format.py @@ -51,7 +51,7 @@ def test_header_match(self): # Trace option is not enabled. header = '00-6e0c63257de34c92bf9efcd03927272e-00f067aa0ba902b7-00' expected_trace_id = '6e0c63257de34c92bf9efcd03927272e' - expected_span_id = 67667974448284343 + expected_span_id = '00f067aa0ba902b7' propagator = trace_context_http_header_format.\ TraceContextPropagator() @@ -64,7 +64,7 @@ def test_header_match(self): # Trace option is enabled. header = '00-6e0c63257de34c92bf9efcd03927272e-00f067aa0ba902b7-01' expected_trace_id = '6e0c63257de34c92bf9efcd03927272e' - expected_span_id = 67667974448284343 + expected_span_id = '00f067aa0ba902b7' propagator = trace_context_http_header_format.\ TraceContextPropagator() @@ -77,7 +77,7 @@ def test_header_match(self): def test_header_match_no_option(self): header = '00-6e0c63257de34c92bf9efcd03927272e-00f067aa0ba902b7' expected_trace_id = '6e0c63257de34c92bf9efcd03927272e' - expected_span_id = 67667974448284343 + expected_span_id = '00f067aa0ba902b7' propagator = trace_context_http_header_format.\ TraceContextPropagator() @@ -102,11 +102,10 @@ def test_to_header(self): from opencensus.trace import trace_options trace_id = '6e0c63257de34c92bf9efcd03927272e' - span_id = 67667974448284343 span_id_hex = '00f067aa0ba902b7' span_context = span_context.SpanContext( trace_id=trace_id, - span_id=span_id, + span_id=span_id_hex, trace_options=trace_options.TraceOptions('1')) propagator = trace_context_http_header_format.\ diff --git a/tests/unit/trace/test_span_context.py b/tests/unit/trace/test_span_context.py index 9011937f7..f137081e1 100644 --- a/tests/unit/trace/test_span_context.py +++ b/tests/unit/trace/test_span_context.py @@ -13,93 +13,114 @@ # limitations under the License. import unittest +from opencensus.trace import span_context as span_context_module +from opencensus.trace.trace_options import TraceOptions class TestSpanContext(unittest.TestCase): - project = 'PROJECT' + trace_id = '6e0c63257de34c92bf9efcd03927272e' + span_id = '6e0c63257de34c92' @staticmethod def _get_target_class(): - from opencensus.trace.span_context import SpanContext - - return SpanContext + return span_context_module.SpanContext def _make_one(self, *args, **kw): return self._get_target_class()(*args, **kw) def test_constructor(self): - trace_id = '6e0c63257de34c92bf9efcd03927272e' - span_id = 1234 - - span_context = self._make_one(trace_id=trace_id, span_id=span_id) + span_context = self._make_one( + trace_id=self.trace_id, + span_id=self.span_id + ) - self.assertEqual(span_context.trace_id, trace_id) - self.assertEqual(span_context.span_id, span_id) + self.assertEqual(span_context.trace_id, self.trace_id) + self.assertEqual(span_context.span_id, self.span_id) def test__str__(self): - from opencensus.trace.trace_options import TraceOptions - trace_id = '6e0c63257de34c92bf9efcd03927272e' - span_id = 1234 - span_context = self._make_one( - trace_id=trace_id, - span_id=span_id, + trace_id=self.trace_id, + span_id=self.span_id, trace_options=TraceOptions('1')) - header_expected = '6e0c63257de34c92bf9efcd03927272e/1234;o=1' + header_expected = '6e0c63257de34c92bf9efcd03927272e' \ + '/6e0c63257de34c92;o=1' header = span_context.__str__() self.assertEqual(header_expected, header) def test_check_span_id_none(self): - span_context = self._make_one(from_header=True) - span_id = span_context.check_span_id(None) - self.assertIsNone(span_id) + span_context = self._make_one( + trace_id=self.trace_id, + from_header=True) + self.assertIsNone(span_context.span_id) def test_check_span_id_zero(self): - span_context = self._make_one(from_header=True) - span_id = span_context.check_span_id(0) + span_context = self._make_one( + from_header=True, + trace_id=self.trace_id, + span_id=span_context_module.INVALID_SPAN_ID + ) self.assertFalse(span_context.from_header) - self.assertIsNone(span_id) + self.assertIsNone(span_context.span_id) - def test_check_span_id_not_int(self): - span_id = {} - span_context = self._make_one() - span_id_checked = span_context.check_span_id(span_id) - self.assertIsNone(span_id_checked) - self.assertFalse(span_context.from_header) + def test_check_span_id_not_str(self): + with self.assertRaises(AssertionError): + self._make_one( + from_header=True, + trace_id=self.trace_id, + span_id={} + ) def test_check_span_id_valid(self): - span_id = 1234 - span_context = self._make_one(from_header=True) - span_id_checked = span_context.check_span_id(span_id) - self.assertEqual(span_id, span_id_checked) + span_context = self._make_one( + from_header=True, + trace_id=self.trace_id, + span_id=self.span_id + ) + self.assertEqual(span_context.span_id, self.span_id) def test_check_trace_id_invalid(self): - from opencensus.trace.span_context import _INVALID_TRACE_ID - - span_context = self._make_one(from_header=True) - - trace_id_checked = span_context.check_trace_id(_INVALID_TRACE_ID) + span_context = self._make_one( + from_header=True, + trace_id=span_context_module._INVALID_TRACE_ID, + span_id=self.span_id + ) self.assertFalse(span_context.from_header) - self.assertNotEqual(trace_id_checked, _INVALID_TRACE_ID) + self.assertNotEqual( + span_context.trace_id, span_context_module._INVALID_TRACE_ID + ) - def test_check_trace_id_not_match(self): + def test_check_trace_id_invalid_format(self): trace_id_test = 'test_trace_id' - - span_context = self._make_one(from_header=True) - trace_id_checked = span_context.check_trace_id(trace_id_test) + span_context = self._make_one( + from_header=True, + trace_id=trace_id_test, + span_id=self.span_id + ) self.assertFalse(span_context.from_header) - self.assertNotEqual(trace_id_checked, trace_id_test) - - def test_check_trace_id_match(self): - trace_id = '6e0c63257de34c92bf9efcd03927272e' + self.assertNotEqual(span_context.trace_id, trace_id_test) - span_context = self._make_one(from_header=True) - trace_id_checked = span_context.check_trace_id(trace_id) + def test_check_trace_id_valid_format(self): + span_context = self._make_one( + from_header=True, + trace_id=self.trace_id, + span_id=self.span_id + ) - self.assertEqual(trace_id, trace_id_checked) + self.assertEqual(span_context.trace_id, self.trace_id) self.assertTrue(span_context.from_header) + + def test_check_span_id_invalid_format(self): + span_id_test = 'test_trace_id' + span_context = self._make_one( + from_header=True, + trace_id=self.trace_id, + span_id=span_id_test + ) + + self.assertFalse(span_context.from_header) + self.assertIsNone(span_context.span_id) diff --git a/tests/unit/trace/test_span_data.py b/tests/unit/trace/test_span_data.py index e7dc85dad..8d50843e4 100644 --- a/tests/unit/trace/test_span_data.py +++ b/tests/unit/trace/test_span_data.py @@ -28,8 +28,8 @@ def test_create_span_data(self): span_data_module.SpanData( name='root', context=None, - span_id=2, - parent_span_id=1, + span_id='6e0c63257de34c92', + parent_span_id='6e0c63257de34c93', attributes={'key1': 'value1'}, start_time=datetime.datetime.utcnow().isoformat() + 'Z', end_time=datetime.datetime.utcnow().isoformat() + 'Z', @@ -46,8 +46,8 @@ def test_span_data_immutable(self): span_data = span_data_module.SpanData( name='root', context=None, - span_id=2, - parent_span_id=1, + span_id='6e0c63257de34c92', + parent_span_id='6e0c63257de34c93', attributes={'key1': 'value1'}, start_time=datetime.datetime.utcnow().isoformat() + 'Z', end_time=datetime.datetime.utcnow().isoformat() + 'Z', @@ -71,15 +71,15 @@ def test_format_legacy_trace_json(self): name='root', context=span_context.SpanContext( trace_id=trace_id, - span_id=1111 + span_id='6e0c63257de34c92' ), - span_id=2, - parent_span_id=1, + span_id='6e0c63257de34c92', + parent_span_id='6e0c63257de34c93', attributes={'key1': 'value1'}, start_time=datetime.datetime.utcnow().isoformat() + 'Z', end_time=datetime.datetime.utcnow().isoformat() + 'Z', stack_trace=stack_trace.StackTrace(stack_trace_hash_id='111'), - links=[link.Link('1111', span_id='111')], + links=[link.Link('1111', span_id='6e0c63257de34c92')], status=status.Status(code=0, message='pok'), time_events=[ time_event.TimeEvent( diff --git a/tests/unit/trace/tracers/test_context_tracer.py b/tests/unit/trace/tracers/test_context_tracer.py index 2a2c2c5ee..69588ea37 100644 --- a/tests/unit/trace/tracers/test_context_tracer.py +++ b/tests/unit/trace/tracers/test_context_tracer.py @@ -20,7 +20,6 @@ class TestContextTracer(unittest.TestCase): - def test_constructor_defaults(self): from opencensus.trace import span_context from opencensus.trace.exporters import print_exporter @@ -68,7 +67,7 @@ def test_finish_with_spans(self): def test_start_span(self, current_span_mock): from opencensus.trace import span_context - span_id = 1234 + span_id = '6e0c63257de34c92' span_name = 'test_span' mock_span = mock.Mock() mock_span.span_id = span_id @@ -87,7 +86,7 @@ def test_start_span(self, current_span_mock): def test_span(self, current_span_mock): from opencensus.trace import span_context - span_id = 1234 + span_id = '6e0c63257de34c92' span_name = 'test_span' mock_span = mock.Mock() mock_span.span_id = span_id @@ -126,7 +125,7 @@ def test_end_span_active(self, mock_current_span): mock_span.attributes = {} mock_span.__iter__ = mock.Mock( return_value=iter([mock_span])) - parent_span_id = 1234 + parent_span_id = '6e0c63257de34c92' mock_span.parent_span.span_id = parent_span_id mock_current_span.return_value = mock_span tracer.end_span() @@ -174,7 +173,7 @@ def test_end_span_batch_export(self, mock_current_span): mock_span.attributes = {} mock_span.__iter__ = mock.Mock( return_value=iter([mock_span])) - parent_span_id = 1234 + parent_span_id = '6e0c63257de34c92' mock_span.parent_span.span_id = parent_span_id mock_current_span.return_value = mock_span tracer.end_span()