From 79edaf000525e8b5eb83d19e3a800e8760131a08 Mon Sep 17 00:00:00 2001 From: Aliaksei Urbanski Date: Thu, 22 Aug 2019 15:35:23 +0300 Subject: [PATCH] Improve testing I believe it would be nice to have tests on CI not only for Python 3.7, but for all supported Python versions. These changes: - fix compatibility with Python 3.5 and 3.4 - add tests for various Python versions on CI - allow running tests for any branches --- .travis.yml | 13 +++++++++---- .../tests/test_wsgi_middleware.py | 6 ++++-- .../src/opentelemetry/context/__init__.py | 4 +++- .../src/opentelemetry/context/async_context.py | 9 +++++---- .../src/opentelemetry/context/base_context.py | 4 ++-- .../context/thread_local_context.py | 9 +++++---- opentelemetry-api/src/opentelemetry/loader.py | 2 +- .../src/opentelemetry/trace/__init__.py | 17 +++++++++++------ tox.ini | 7 +++++-- 9 files changed, 45 insertions(+), 26 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4f9cb871ea1..64eebc36213 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,14 +3,19 @@ dist: xenial language: python python: + - '3.4' + - '3.5' + - '3.6' - '3.7' + - 'pypy3.5' + - '3.8-dev' + +matrix: + allow_failures: + - python: '3.8-dev' install: - pip install tox-travis script: - tox - -branches: - only: - - master diff --git a/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py b/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py index 70b7e8fcf63..0e86a871f45 100644 --- a/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py +++ b/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py @@ -94,7 +94,7 @@ def tearDown(self): def start_response(self, status, response_headers, exc_info=None): # The span should have started already - self.span_context_manager.__enter__.assert_called() + self.span_context_manager.__enter__.assert_called_with() self.status = status self.response_headers = response_headers @@ -108,7 +108,9 @@ def validate_response(self, response, error=None): self.span_context_manager.__exit__.assert_not_called() self.assertEqual(value, b"*") except StopIteration: - self.span_context_manager.__exit__.assert_called() + self.span_context_manager.__exit__.assert_called_with( + None, None, None + ) break self.assertEqual(self.status, "200 OK") diff --git a/opentelemetry-api/src/opentelemetry/context/__init__.py b/opentelemetry-api/src/opentelemetry/context/__init__.py index 4edbf2bd048..1495f8828e3 100644 --- a/opentelemetry-api/src/opentelemetry/context/__init__.py +++ b/opentelemetry-api/src/opentelemetry/context/__init__.py @@ -145,7 +145,9 @@ async def main(): __all__ = ['Context'] -Context: typing.Optional[BaseRuntimeContext] +Context = ( # pylint: disable=invalid-name + None +) # type: typing.Optional[BaseRuntimeContext] try: from .async_context import AsyncRuntimeContext diff --git a/opentelemetry-api/src/opentelemetry/context/async_context.py b/opentelemetry-api/src/opentelemetry/context/async_context.py index 413e7b2543f..559d36234be 100644 --- a/opentelemetry-api/src/opentelemetry/context/async_context.py +++ b/opentelemetry-api/src/opentelemetry/context/async_context.py @@ -13,7 +13,7 @@ # limitations under the License. from contextvars import ContextVar -import typing +import typing # pylint: disable=unused-import from . import base_context @@ -23,9 +23,10 @@ class Slot(base_context.BaseRuntimeContext.Slot): def __init__(self, name: str, default: 'object'): # pylint: disable=super-init-not-called self.name = name - self.contextvar: 'ContextVar[object]' = ContextVar(name) - self.default: typing.Callable[..., object] - self.default = base_context.wrap_callable(default) + self.contextvar = ContextVar(name) # type: ContextVar[object] + self.default = base_context.wrap_callable( + default + ) # type: typing.Callable[..., object] def clear(self) -> None: self.contextvar.set(self.default()) diff --git a/opentelemetry-api/src/opentelemetry/context/base_context.py b/opentelemetry-api/src/opentelemetry/context/base_context.py index c750d993ad1..5c1ffb4a8e4 100644 --- a/opentelemetry-api/src/opentelemetry/context/base_context.py +++ b/opentelemetry-api/src/opentelemetry/context/base_context.py @@ -37,7 +37,7 @@ def set(self, value: 'object') -> None: raise NotImplementedError _lock = threading.Lock() - _slots: typing.Dict[str, 'BaseRuntimeContext.Slot'] = {} + _slots = {} # type: typing.Dict[str, 'BaseRuntimeContext.Slot'] @classmethod def clear(cls) -> None: @@ -112,7 +112,7 @@ def with_current_context( def call_with_current_context( *args: 'object', - **kwargs: 'object', + **kwargs: 'object' ) -> 'object': try: backup_context = self.snapshot() diff --git a/opentelemetry-api/src/opentelemetry/context/thread_local_context.py b/opentelemetry-api/src/opentelemetry/context/thread_local_context.py index dd11128b7ac..8313fb57e89 100644 --- a/opentelemetry-api/src/opentelemetry/context/thread_local_context.py +++ b/opentelemetry-api/src/opentelemetry/context/thread_local_context.py @@ -13,7 +13,7 @@ # limitations under the License. import threading -import typing +import typing # pylint: disable=unused-import from . import base_context @@ -25,15 +25,16 @@ class Slot(base_context.BaseRuntimeContext.Slot): def __init__(self, name: str, default: 'object'): # pylint: disable=super-init-not-called self.name = name - self.default: typing.Callable[..., object] - self.default = base_context.wrap_callable(default) + self.default = base_context.wrap_callable( + default + ) # type: typing.Callable[..., object] def clear(self) -> None: setattr(self._thread_local, self.name, self.default()) def get(self) -> 'object': try: - got: object = getattr(self._thread_local, self.name) + got = getattr(self._thread_local, self.name) # type: object return got except AttributeError: value = self.default() diff --git a/opentelemetry-api/src/opentelemetry/loader.py b/opentelemetry-api/src/opentelemetry/loader.py index 9e28846b8c5..78b7cc4f321 100644 --- a/opentelemetry-api/src/opentelemetry/loader.py +++ b/opentelemetry-api/src/opentelemetry/loader.py @@ -83,7 +83,7 @@ def my_factory_for_t(api_type: typing.Type[T]) -> typing.Optional[T]: # code. # ImplementationFactory = Callable[[Type[_T]], Optional[_T]] -_DEFAULT_FACTORY: Optional[_UntrustedImplFactory[object]] = None +_DEFAULT_FACTORY = None # type: Optional[_UntrustedImplFactory[object]] def _try_load_impl_from_modname( diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index aed421307ee..0ff3039bcd6 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -378,9 +378,15 @@ def use_span(self, span: 'Span') -> typing.Iterator[None]: yield -_TRACER: typing.Optional[Tracer] = None -_TRACER_FACTORY: typing.Optional[ - typing.Callable[[typing.Type[Tracer]], typing.Optional[Tracer]]] = None +# Once https://github.com/python/mypy/issues/7092 is resolved, +# the following type definition should be replaced with +# from opentelemetry.loader import ImplementationFactory +ImplementationFactory = typing.Callable[ + [typing.Type[Tracer]], typing.Optional[Tracer] +] + +_TRACER = None # type: typing.Optional[Tracer] +_TRACER_FACTORY = None # type: typing.Optional[ImplementationFactory] def tracer() -> Tracer: @@ -399,9 +405,8 @@ def tracer() -> Tracer: def set_preferred_tracer_implementation( - factory: typing.Callable[ - [typing.Type[Tracer]], typing.Optional[Tracer]] - ) -> None: + factory: ImplementationFactory +) -> None: """Set the factory to be used to create the tracer. See :mod:`opentelemetry.loader` for details. diff --git a/tox.ini b/tox.ini index 82178115c09..71bc408a397 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,9 @@ [tox] skipsdist = True +skip_missing_interpreters = True envlist = - py{34,35,36,37}-test-{api,sdk} - py{34,35,36,37}-test-ext-wsgi + py3{4,5,6,7,8}-test-{api,sdk,ext-wsgi} + pypy35-test-{api,sdk,ext-wsgi} lint py37-mypy docs @@ -24,6 +25,7 @@ changedir = test-ext-wsgi: ext/opentelemetry-ext-wsgi/tests commands_pre = + pip install -U pip setuptools wheel test: pip install -e {toxinidir}/opentelemetry-api test-sdk: pip install -e {toxinidir}/opentelemetry-sdk ext: pip install -e {toxinidir}/opentelemetry-api @@ -36,6 +38,7 @@ commands = test: python -m unittest discover [testenv:lint] +basepython: python3.7 deps = pylint~=2.3 flake8~=3.7