From c9ddd6544a06048318da21fdadd21c0684ef22e0 Mon Sep 17 00:00:00 2001 From: Aliaksei Urbanski Date: Wed, 30 Oct 2019 12:38:34 +0300 Subject: [PATCH 1/5] Add test coverage collecting I believe that we should be able to see the test coverage. These changes: - make tests use pytest - add displaying of the test coverage - add sending of collected coverage data to https://codecov.io --- .coveragerc | 4 ++ .gitignore | 1 + .travis.yml | 4 ++ .../ext/jaeger/gen/agent/Agent.py | 8 +-- .../ext/jaeger/gen/agent/ttypes.py | 9 ++-- .../opentelemetry/context/async_context.py | 52 ++++++++++--------- pytest-cov.ini | 6 +++ pytest.ini | 2 + scripts/coverage.sh | 30 +++++++++++ tox.ini | 21 +++++++- 10 files changed, 103 insertions(+), 34 deletions(-) create mode 100644 .coveragerc create mode 100644 pytest-cov.ini create mode 100644 pytest.ini create mode 100755 scripts/coverage.sh diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000000..a00b3844ca --- /dev/null +++ b/.coveragerc @@ -0,0 +1,4 @@ +[run] +omit = + */tests/* + */setup.py diff --git a/.gitignore b/.gitignore index c9acc31940..473ef20a4a 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ venv*/ pip-log.txt # Unit test / coverage reports +coverage.xml .coverage .nox .tox diff --git a/.travis.yml b/.travis.yml index 64eebc3621..f8c01c80be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,3 +19,7 @@ install: script: - tox + +after_success: + - pip install codecov + - codecov -v diff --git a/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/Agent.py b/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/Agent.py index e8e0fe662e..b8fac11a5c 100644 --- a/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/Agent.py +++ b/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/Agent.py @@ -124,7 +124,7 @@ class emitZipkinBatch_args(object): thrift_spec = ( None, # 0 - (1, TType.LIST, 'spans', (TType.STRUCT, (zipkincore.ttypes.Span, zipkincore.ttypes.Span.thrift_spec), False), None, ), # 1 + (1, TType.LIST, 'spans', (TType.STRUCT, (zipkincore_ttypes.Span, zipkincore_ttypes.Span.thrift_spec), False), None, ), # 1 ) def __init__(self, spans=None,): @@ -144,7 +144,7 @@ def read(self, iprot): self.spans = [] (_etype3, _size0) = iprot.readListBegin() for _i4 in range(_size0): - _elem5 = zipkincore.ttypes.Span() + _elem5 = zipkincore_ttypes.Span() _elem5.read(iprot) self.spans.append(_elem5) iprot.readListEnd() @@ -193,7 +193,7 @@ class emitBatch_args(object): thrift_spec = ( None, # 0 - (1, TType.STRUCT, 'batch', (jaeger.ttypes.Batch, jaeger.ttypes.Batch.thrift_spec), None, ), # 1 + (1, TType.STRUCT, 'batch', (jaeger_ttypes.Batch, jaeger_ttypes.Batch.thrift_spec), None, ), # 1 ) def __init__(self, batch=None,): @@ -210,7 +210,7 @@ def read(self, iprot): break if fid == 1: if ftype == TType.STRUCT: - self.batch = jaeger.ttypes.Batch() + self.batch = jaeger_ttypes.Batch() self.batch.read(iprot) else: iprot.skip(ftype) diff --git a/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/ttypes.py b/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/ttypes.py index fc8743cba9..461c414f53 100644 --- a/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/ttypes.py +++ b/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/ttypes.py @@ -6,10 +6,11 @@ # options string: py # -from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException -from thrift.protocol.TProtocol import TProtocolException import sys -import jaeger.ttypes -import zipkincore.ttypes +from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException +from thrift.protocol.TProtocol import TProtocolException from thrift.transport import TTransport + +from ..jaeger import ttypes as jaeger_ttypes +from ..zipkincore import ttypes as zipkincore_ttypes diff --git a/opentelemetry-api/src/opentelemetry/context/async_context.py b/opentelemetry-api/src/opentelemetry/context/async_context.py index e7337d103f..267059fb31 100644 --- a/opentelemetry-api/src/opentelemetry/context/async_context.py +++ b/opentelemetry-api/src/opentelemetry/context/async_context.py @@ -12,32 +12,34 @@ # See the License for the specific language governing permissions and # limitations under the License. -import typing # pylint: disable=unused-import -from contextvars import ContextVar +try: + from contextvars import ContextVar +except ImportError: + pass +else: + import typing # pylint: disable=unused-import + from . import base_context -from . import base_context + class AsyncRuntimeContext(base_context.BaseRuntimeContext): + 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(name) # type: ContextVar[object] + self.default = base_context.wrap_callable( + default + ) # type: typing.Callable[..., object] + def clear(self) -> None: + self.contextvar.set(self.default()) -class AsyncRuntimeContext(base_context.BaseRuntimeContext): - 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(name) # type: ContextVar[object] - self.default = base_context.wrap_callable( - default - ) # type: typing.Callable[..., object] + def get(self) -> object: + try: + return self.contextvar.get() + except LookupError: + value = self.default() + self.set(value) + return value - def clear(self) -> None: - self.contextvar.set(self.default()) - - def get(self) -> "object": - try: - return self.contextvar.get() - except LookupError: - value = self.default() - self.set(value) - return value - - def set(self, value: "object") -> None: - self.contextvar.set(value) + def set(self, value: object) -> None: + self.contextvar.set(value) diff --git a/pytest-cov.ini b/pytest-cov.ini new file mode 100644 index 0000000000..d34438e8c3 --- /dev/null +++ b/pytest-cov.ini @@ -0,0 +1,6 @@ +[pytest] +addopts = -rs -v + +# We need this to make pytest "touch" every python file +# in order to include them into the coverage report. +python_files = *.py diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000000..a71d000b56 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = -rs -v diff --git a/scripts/coverage.sh b/scripts/coverage.sh new file mode 100755 index 0000000000..43aee56325 --- /dev/null +++ b/scripts/coverage.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +set -e + +function cov { + pytest ${1} \ + -c pytest-cov.ini \ + --ignore-glob=*/setup.py \ + --cov opentelemetry-api \ + --cov opentelemetry-sdk \ + --cov ext \ + --cov examples \ + --cov-append \ + --cov-branch \ + --cov-report= +} + + +coverage erase + +cov opentelemetry-api +cov opentelemetry-sdk +cov ext/opentelemetry-ext-http-requests +cov ext/opentelemetry-ext-jaeger +cov ext/opentelemetry-ext-opentracing-shim +cov ext/opentelemetry-ext-wsgi +cov examples/opentelemetry-example-app + +coverage report +coverage xml diff --git a/tox.ini b/tox.ini index e30cb1a14b..1791978227 100644 --- a/tox.ini +++ b/tox.ini @@ -4,6 +4,11 @@ skip_missing_interpreters = True envlist = py3{4,5,6,7,8}-test-{api,sdk,example-app,ext-wsgi,ext-http-requests,ext-jaeger,opentracing-shim} pypy3-test-{api,sdk,example-app,ext-wsgi,ext-http-requests,ext-jaeger,opentracing-shim} + py3{4,5,6,7,8}-coverage + + ; Coverage is temporarily disabled for pypy3 due to the pytest bug. + ; pypy3-coverage + lint py37-tracecontext py37-{mypy,mypyinstalled} @@ -15,6 +20,8 @@ python = [testenv] deps = + test: pytest + coverage: pytest-cov mypy,mypyinstalled: mypy~=0.740 setenv = @@ -45,12 +52,24 @@ commands_pre = jaeger: pip install {toxinidir}/ext/opentelemetry-ext-jaeger opentracing-shim: pip install {toxinidir}/opentelemetry-sdk {toxinidir}/ext/opentelemetry-ext-opentracing-shim +; In order to get a healthy coverage report, +; we have to install packages in editable mode. + coverage: pip install -e {toxinidir}/opentelemetry-api + coverage: pip install -e {toxinidir}/opentelemetry-sdk + coverage: pip install -e {toxinidir}/ext/opentelemetry-ext-azure-monitor + coverage: pip install -e {toxinidir}/ext/opentelemetry-ext-http-requests + coverage: pip install -e {toxinidir}/ext/opentelemetry-ext-jaeger + coverage: pip install -e {toxinidir}/ext/opentelemetry-ext-opentracing-shim + coverage: pip install -e {toxinidir}/ext/opentelemetry-ext-wsgi + coverage: pip install -e {toxinidir}/examples/opentelemetry-example-app + ; Using file:// here because otherwise tox invokes just "pip install ; opentelemetry-api", leading to an error mypyinstalled: pip install file://{toxinidir}/opentelemetry-api/ commands = - test: python -m unittest discover + test: pytest + coverage: {toxinidir}/scripts/coverage.sh mypy: mypy --namespace-packages opentelemetry-api/src/opentelemetry/ ; For test code, we don't want to enforce the full mypy strictness From c012914be1d4e05ac375b745dc54555158fe216a Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Tue, 5 Nov 2019 12:06:53 -0800 Subject: [PATCH 2/5] Revert changes to generated jaeger modules --- .../src/opentelemetry/ext/jaeger/gen/agent/Agent.py | 8 ++++---- .../src/opentelemetry/ext/jaeger/gen/agent/ttypes.py | 9 ++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/Agent.py b/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/Agent.py index b8fac11a5c..e8e0fe662e 100644 --- a/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/Agent.py +++ b/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/Agent.py @@ -124,7 +124,7 @@ class emitZipkinBatch_args(object): thrift_spec = ( None, # 0 - (1, TType.LIST, 'spans', (TType.STRUCT, (zipkincore_ttypes.Span, zipkincore_ttypes.Span.thrift_spec), False), None, ), # 1 + (1, TType.LIST, 'spans', (TType.STRUCT, (zipkincore.ttypes.Span, zipkincore.ttypes.Span.thrift_spec), False), None, ), # 1 ) def __init__(self, spans=None,): @@ -144,7 +144,7 @@ def read(self, iprot): self.spans = [] (_etype3, _size0) = iprot.readListBegin() for _i4 in range(_size0): - _elem5 = zipkincore_ttypes.Span() + _elem5 = zipkincore.ttypes.Span() _elem5.read(iprot) self.spans.append(_elem5) iprot.readListEnd() @@ -193,7 +193,7 @@ class emitBatch_args(object): thrift_spec = ( None, # 0 - (1, TType.STRUCT, 'batch', (jaeger_ttypes.Batch, jaeger_ttypes.Batch.thrift_spec), None, ), # 1 + (1, TType.STRUCT, 'batch', (jaeger.ttypes.Batch, jaeger.ttypes.Batch.thrift_spec), None, ), # 1 ) def __init__(self, batch=None,): @@ -210,7 +210,7 @@ def read(self, iprot): break if fid == 1: if ftype == TType.STRUCT: - self.batch = jaeger_ttypes.Batch() + self.batch = jaeger.ttypes.Batch() self.batch.read(iprot) else: iprot.skip(ftype) diff --git a/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/ttypes.py b/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/ttypes.py index 461c414f53..fc8743cba9 100644 --- a/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/ttypes.py +++ b/ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/agent/ttypes.py @@ -6,11 +6,10 @@ # options string: py # -import sys - from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException from thrift.protocol.TProtocol import TProtocolException -from thrift.transport import TTransport +import sys +import jaeger.ttypes +import zipkincore.ttypes -from ..jaeger import ttypes as jaeger_ttypes -from ..zipkincore import ttypes as zipkincore_ttypes +from thrift.transport import TTransport From cdc64f55da84fd2408a0087b670be0540ffce945 Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Tue, 5 Nov 2019 13:16:16 -0800 Subject: [PATCH 3/5] Only report coverage for package being tested --- pytest-cov.ini | 4 ---- scripts/coverage.sh | 10 ++++------ 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/pytest-cov.ini b/pytest-cov.ini index d34438e8c3..a71d000b56 100644 --- a/pytest-cov.ini +++ b/pytest-cov.ini @@ -1,6 +1,2 @@ [pytest] addopts = -rs -v - -# We need this to make pytest "touch" every python file -# in order to include them into the coverage report. -python_files = *.py diff --git a/scripts/coverage.sh b/scripts/coverage.sh index 43aee56325..3ff3a2d8d1 100755 --- a/scripts/coverage.sh +++ b/scripts/coverage.sh @@ -3,16 +3,14 @@ set -e function cov { - pytest ${1} \ + pytest \ -c pytest-cov.ini \ --ignore-glob=*/setup.py \ - --cov opentelemetry-api \ - --cov opentelemetry-sdk \ - --cov ext \ - --cov examples \ + --cov ${1} \ --cov-append \ --cov-branch \ - --cov-report= + --cov-report='' \ + ${1} } From 3da192d5ba7d648bba3172ee109db35e6beb775c Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Tue, 5 Nov 2019 13:16:39 -0800 Subject: [PATCH 4/5] Ignore generated files in coverage --- .coveragerc | 1 + 1 file changed, 1 insertion(+) diff --git a/.coveragerc b/.coveragerc index a00b3844ca..6f2257aba5 100644 --- a/.coveragerc +++ b/.coveragerc @@ -2,3 +2,4 @@ omit = */tests/* */setup.py + */gen/* From 89c4f0107a4581e927f9e4c87346b91563a03557 Mon Sep 17 00:00:00 2001 From: Aliaksei Urbanski Date: Wed, 6 Nov 2019 16:11:46 +0300 Subject: [PATCH 5/5] Remove pytest-cov.ini --- pytest-cov.ini | 2 -- scripts/coverage.sh | 1 - 2 files changed, 3 deletions(-) delete mode 100644 pytest-cov.ini diff --git a/pytest-cov.ini b/pytest-cov.ini deleted file mode 100644 index a71d000b56..0000000000 --- a/pytest-cov.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -addopts = -rs -v diff --git a/scripts/coverage.sh b/scripts/coverage.sh index 3ff3a2d8d1..bddf39a90c 100755 --- a/scripts/coverage.sh +++ b/scripts/coverage.sh @@ -4,7 +4,6 @@ set -e function cov { pytest \ - -c pytest-cov.ini \ --ignore-glob=*/setup.py \ --cov ${1} \ --cov-append \