From 7dd8d6b7890e8f403cb8606c96def6d2c8e34278 Mon Sep 17 00:00:00 2001 From: rahmukhe Date: Mon, 28 Nov 2022 16:28:37 +0530 Subject: [PATCH 1/4] added new testcases related to basic rest api calls and spans check for instrumentation --- .../README.rst | 40 +++ .../tests/__init__.py | 0 .../tests/test_cherrypy.py | 227 ++++++++++++++++++ 3 files changed, 267 insertions(+) create mode 100644 instrumentation/opentelemetry-instrumentation-cherrypy/tests/__init__.py create mode 100644 instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py diff --git a/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst b/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst index e69de29bb2..3be2d61eff 100644 --- a/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst +++ b/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst @@ -0,0 +1,40 @@ +OpenTelemetry CherryPy Tracing +============================ + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-cherrypy.svg + :target: https://pypi.org/project/opentelemetry-instrumentation-cherrypy/ + +This library builds on the OpenTelemetry WSGI middleware to track web requests +in CherryPy applications. + +Installation +------------ + +:: + + pip install opentelemetry-instrumentation-cherrypy + +Configuration +------------- + +Exclude lists +************* +To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_CHERRYPY_EXCLUDED_URLS`` +(or ``OTEL_PYTHON_CHERRYPY_URLS`` as fallback) with comma delimited regexes representing which URLs to exclude. + +For example, + +:: + + export OTEL_PYTHON_CHERRYPY_EXCLUDED_URLS="client/.*/info,healthcheck" + +will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. + +References +---------- + +* `OpenTelemetry CherryPy Instrumentation `_ +* `OpenTelemetry Project `_ +* `OpenTelemetry Python Examples `_ diff --git a/instrumentation/opentelemetry-instrumentation-cherrypy/tests/__init__.py b/instrumentation/opentelemetry-instrumentation-cherrypy/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py b/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py new file mode 100644 index 0000000000..293108e9a8 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py @@ -0,0 +1,227 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from timeit import default_timer +from unittest.mock import Mock, patch + +import pytest +from cherrypy import __version__ as _cherrypy_verison +import cherrypy +from cherrypy.test import helper +from packaging import version as package_version + +from opentelemetry import trace +from opentelemetry.instrumentation.cherrypy import CherryPyInstrumentor +from opentelemetry.instrumentation.propagators import ( + TraceResponsePropagator, + get_global_response_propagator, + set_global_response_propagator, +) +from opentelemetry.instrumentation.wsgi import ( + _active_requests_count_attrs, + _duration_attrs, +) +from opentelemetry.sdk.metrics.export import ( + HistogramDataPoint, + NumberDataPoint, +) +from opentelemetry.sdk.resources import Resource +from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.test.test_base import TestBase +from opentelemetry.test.wsgitestutil import WsgiTestBase +from opentelemetry.trace import StatusCode +from opentelemetry.util.http import ( + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, +) + + +_expected_metric_names = [ + "http.server.active_requests", + "http.server.duration", +] +_recommended_attrs = { + "http.server.active_requests": _active_requests_count_attrs, + "http.server.duration": _duration_attrs, +} + +class TestCherryPyBase(TestBase, helper.CPWebCase): + def setUp(self): + super().setUp() + self.env_patch = patch.dict( + "os.environ", + { + "OTEL_PYTHON_CHERRYPY_EXCLUDED_URLS": "ping", + "OTEL_PYTHON_CHERRYPY_TRACED_REQUEST_ATTRS": "query_string", + }, + ) + self.env_patch.start() + + CherryPyInstrumentor().instrument( + request_hook=getattr(self, "request_hook", None), + response_hook=getattr(self, "response_hook", None), + ) + + + def call(self, *args, **kwargs): + self.setup_server() + return self.getPage(*args, **kwargs) + + + def setup_server(): + class CherryPyApp(object): + @cherrypy.expose + def hello(self): + return {"message": "hello world"} + + @cherrypy.expose + def user(self, username): + return {"user": username} + + @cherrypy.expose + def exclude(self, param): + return {"message": param} + + @cherrypy.expose + def healthzz(self): + return {"message": "ok"} + + @cherrypy.expose + def error(self): + raise cherrypy.HTTPError(500, 'error') + + return cherrypy.tree.mount(CherryPyApp()) + + setup_server = staticmethod(setup_server) + + def tearDown(self): + super().tearDown() + with self.disable_logging(): + CherryPyInstrumentor().uninstrument() + self.env_patch.stop() + + +class TestCherryPyInstrumentation(TestCherryPyBase, WsgiTestBase): + def test_get(self): + self._test_method("GET") + + def test_post(self): + self._test_method("POST") + + def test_patch(self): + self._test_method("PATCH") + + def test_put(self): + self._test_method("PUT") + + def test_delete(self): + self._test_method("DELETE") + + def test_head(self): + self._test_method("HEAD") + + def _test_method(self, method): + res = self.call(method=method, url="/hello") + self.assertEqual(res[0],'200 OK') + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + span = spans[0] + self.assertEqual(span.name, f"HTTP {method.upper()}") + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual( + span.status.description, + None, + ) + self.assertSpanHasAttributes( + span, + { + SpanAttributes.HTTP_METHOD: method, + SpanAttributes.HTTP_SERVER_NAME: "127.0.0.1", + SpanAttributes.HTTP_SCHEME: "http", + SpanAttributes.NET_HOST_PORT: 54583, + SpanAttributes.HTTP_HOST: "127.0.0.1:54583", + SpanAttributes.HTTP_TARGET: "/hello", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_STATUS_CODE: 200, + }, + ) + self.memory_exporter.clear() + + def test_404(self): + res = self.call(method="GET", url="/does-not-exit") + self.assertEqual(res[0],'404 Not Found') + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + span = spans[0] + self.assertEqual(span.name, f"HTTP GET") + self.assertEqual(span.status.status_code, StatusCode.UNSET) + self.assertEqual( + span.status.description, + None, + ) + self.assertSpanHasAttributes( + span, + { + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_SERVER_NAME: "127.0.0.1", + SpanAttributes.HTTP_SCHEME: "http", + SpanAttributes.NET_HOST_PORT: 54583, + SpanAttributes.HTTP_HOST: "127.0.0.1:54583", + SpanAttributes.HTTP_TARGET: "/does-not-exit", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_STATUS_CODE: 404, + }, + ) + self.memory_exporter.clear() + + def test_500(self): + res = self.call(method="GET", url="/error") + self.assertEqual(res[0],'500 Internal Server Error') + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + span = spans[0] + self.assertEqual(span.name, f"HTTP GET") + self.assertEqual(span.status.status_code, StatusCode.ERROR) + self.assertEqual( + span.status.description, + None, + ) + self.assertSpanHasAttributes( + span, + { + SpanAttributes.HTTP_METHOD: "GET", + SpanAttributes.HTTP_SERVER_NAME: "127.0.0.1", + SpanAttributes.HTTP_SCHEME: "http", + SpanAttributes.NET_HOST_PORT: 54583, + SpanAttributes.HTTP_HOST: "127.0.0.1:54583", + SpanAttributes.HTTP_TARGET: "/error", + SpanAttributes.HTTP_FLAVOR: "1.1", + SpanAttributes.HTTP_STATUS_CODE: 500, + }, + ) + self.memory_exporter.clear() + + def test_uninstrument(self): + self.call(method="GET", url="/healthzz") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + self.memory_exporter.clear() + + CherryPyInstrumentor().uninstrument() + self.setup_server() + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 0) + \ No newline at end of file From 065a16acf4259fd82074088a0ae69f194ee6919f Mon Sep 17 00:00:00 2001 From: rahmukhe Date: Tue, 29 Nov 2022 14:40:23 +0530 Subject: [PATCH 2/4] added tox changes and metrices testcases and fixed review comments --- .../tests/test_cherrypy.py | 87 ++++++++++++++ tox.ini | 110 ++++++++++-------- 2 files changed, 151 insertions(+), 46 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py b/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py index 293108e9a8..12ca10be39 100644 --- a/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py +++ b/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py @@ -224,4 +224,91 @@ def test_uninstrument(self): self.setup_server() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 0) + + def test_cherrypy_metrics(self): + self.setup_server() + self.call(url="/hello") + self.call(url="/hello") + self.call(url="/hello") + metrics_list = self.memory_metrics_reader.get_metrics_data() + number_data_point_seen = False + histogram_data_point_seen = False + self.assertTrue(len(metrics_list.resource_metrics) == 1) + for resource_metric in metrics_list.resource_metrics: + self.assertTrue(len(resource_metric.scope_metrics) == 1) + for scope_metric in resource_metric.scope_metrics: + self.assertTrue(len(scope_metric.metrics) == 2) + for metric in scope_metric.metrics: + self.assertIn(metric.name, _expected_metric_names) + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) + for point in data_points: + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 3) + histogram_data_point_seen = True + if isinstance(point, NumberDataPoint): + number_data_point_seen = True + for attr in point.attributes: + self.assertIn( + attr, _recommended_attrs[metric.name] + ) + self.assertTrue(number_data_point_seen and histogram_data_point_seen) + + def test_basic_metric_success(self): + start = default_timer() + self.setup_server() + self.call(url="/hello") + duration = max(round((default_timer() - start) * 1000), 0) + expected_duration_attributes = { + "http.method": "GET", + "http.host": "127.0.0.1:54583", + "http.scheme": "http", + "http.flavor": "1.1", + "http.server_name": "127.0.0.1", + "net.host.port": 54583, + "http.status_code": 200, + } + expected_requests_count_attributes = { + "http.method": "GET", + "http.host": "127.0.0.1:54583", + "http.scheme": "http", + "http.flavor": "1.1", + "http.server_name": "127.0.0.1", + } + metrics_list = self.memory_metrics_reader.get_metrics_data() + for metric in ( + metrics_list.resource_metrics[0].scope_metrics[0].metrics + ): + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertDictEqual( + expected_duration_attributes, + dict(point.attributes), + ) + self.assertEqual(point.count, 1) + self.assertAlmostEqual(duration, point.sum, delta=30) + if isinstance(point, NumberDataPoint): + print(expected_requests_count_attributes) + print(dict(point.attributes)) + self.assertDictEqual( + expected_requests_count_attributes, + dict(point.attributes), + ) + self.assertEqual(point.value, 0) + + def test_basic_post_request_metric_success(self): + start = default_timer() + self.setup_server() + self.call(url="/hello") + duration = max(round((default_timer() - start) * 1000), 0) + metrics_list = self.memory_metrics_reader.get_metrics_data() + for metric in ( + metrics_list.resource_metrics[0].scope_metrics[0].metrics + ): + for point in list(metric.data.data_points): + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 1) + self.assertAlmostEqual(duration, point.sum, delta=30) + if isinstance(point, NumberDataPoint): + self.assertEqual(point.value, 0) \ No newline at end of file diff --git a/tox.ini b/tox.ini index 4c028e2ccc..3f8fb59b17 100644 --- a/tox.ini +++ b/tox.ini @@ -7,34 +7,34 @@ envlist = ; for specifying supported Python versions per package. ; opentelemetry-sdk-extension-aws - py3{7,8,9,10}-test-sdkextension-aws + py3{7,8,9,10,11}-test-sdkextension-aws pypy3-test-sdkextension-aws ; opentelemetry-distro - py3{7,8,9,10}-test-distro + py3{7,8,9,10,11}-test-distro pypy3-test-distro ; opentelemetry-instrumentation - py3{7,8,9,10}-test-opentelemetry-instrumentation + py3{7,8,9,10,11}-test-opentelemetry-instrumentation pypy3-test-opentelemetry-instrumentation ; opentelemetry-instrumentation-aiohttp-client - py3{7,8,9,10}-test-instrumentation-aiohttp-client + py3{7,8,9,10,11}-test-instrumentation-aiohttp-client pypy3-test-instrumentation-aiohttp-client ; opentelemetry-instrumentation-aiopg - py3{7,8,9,10}-test-instrumentation-aiopg + py3{7,8,9,10,11}-test-instrumentation-aiopg ; instrumentation-aiopg intentionally excluded from pypy3 ; opentelemetry-instrumentation-aws-lambda py3{7,8,9}-test-instrumentation-aws-lambda ; opentelemetry-instrumentation-botocore - py3{7,8,9,10}-test-instrumentation-botocore + py3{7,8,9,10,11}-test-instrumentation-botocore pypy3-test-instrumentation-botocore ; opentelemetry-instrumentation-boto3sqs - py3{6,7,8,9,10}-test-instrumentation-boto3sqs + py3{6,7,8,9,10,11}-test-instrumentation-boto3sqs pypy3-test-instrumentation-boto3sqs ; opentelemetry-instrumentation-django @@ -43,20 +43,24 @@ envlist = ; https://docs.djangoproject.com/en/dev/faq/install/#what-python-version-can-i-use-with-django py3{7}-test-instrumentation-django1 py3{7,8,9}-test-instrumentation-django2 - py3{7,8,9,10}-test-instrumentation-django3 - py3{8,9,10}-test-instrumentation-django4 + py3{7,8,9,10,11}-test-instrumentation-django3 + py3{8,9,10,11}-test-instrumentation-django4 pypy3-test-instrumentation-django{1,2,3} ; opentelemetry-instrumentation-dbapi - py3{7,8,9,10}-test-instrumentation-dbapi + py3{7,8,9,10,11}-test-instrumentation-dbapi pypy3-test-instrumentation-dbapi ; opentelemetry-instrumentation-boto - py3{7,8,9,10}-test-instrumentation-boto + py3{7,8,9,10,11}-test-instrumentation-boto pypy3-test-instrumentation-boto + ; opentelemetry-instrumentation-cherrypy + py3{7,8,9,10}-test-instrumentation-cherrypy + pypy3-test-instrumentation-cherrypy + ; opentelemetry-instrumentation-elasticsearch - py3{7,8,9,10}-test-instrumentation-elasticsearch{2,6} + py3{7,8,9,10,11}-test-instrumentation-elasticsearch{2,6} pypy3-test-instrumentation-elasticsearch{2,6} ; opentelemetry-instrumentation-elasticsearch5 @@ -66,138 +70,141 @@ envlist = ; opentelemetry-instrumentation-falcon ; py310 does not work with falcon 1 py3{7,8,9}-test-instrumentation-falcon1 - py3{7,8,9,10}-test-instrumentation-falcon{2,3} + py3{7,8,9,10,11}-test-instrumentation-falcon{2,3} pypy3-test-instrumentation-falcon{1,2,3} ; opentelemetry-instrumentation-fastapi - py3{7,8,9,10}-test-instrumentation-fastapi + py3{7,8,9,10,11}-test-instrumentation-fastapi pypy3-test-instrumentation-fastapi ; opentelemetry-instrumentation-flask - py3{7,8,9,10}-test-instrumentation-flask + py3{7,8,9,10,11}-test-instrumentation-flask pypy3-test-instrumentation-flask ; opentelemetry-instrumentation-urllib - py3{7,8,9,10}-test-instrumentation-urllib + py3{7,8,9,10,11}-test-instrumentation-urllib pypy3-test-instrumentation-urllib ; opentelemetry-instrumentation-urllib3 - py3{7,8,9,10}-test-instrumentation-urllib3 + py3{7,8,9,10,11}-test-instrumentation-urllib3 pypy3-test-instrumentation-urllib3 ; opentelemetry-instrumentation-requests - py3{7,8,9,10}-test-instrumentation-requests + py3{7,8,9,10,11}-test-instrumentation-requests pypy3-test-instrumentation-requests ; opentelemetry-instrumentation-starlette. - py3{7,8,9,10}-test-instrumentation-starlette + py3{7,8,9,10,11}-test-instrumentation-starlette pypy3-test-instrumentation-starlette ; opentelemetry-instrumentation-jinja2 - py3{7,8,9,10}-test-instrumentation-jinja2 + py3{7,8,9,10,11}-test-instrumentation-jinja2 pypy3-test-instrumentation-jinja2 ; opentelemetry-instrumentation-logging - py3{7,8,9,10}-test-instrumentation-logging + py3{7,8,9,10,11}-test-instrumentation-logging pypy3-test-instrumentation-logging ; opentelemetry-exporter-richconsole - py3{7,8,9,10}-test-exporter-richconsole + py3{7,8,9,10,11}-test-exporter-richconsole + + ; opentelemetry-exporter-prometheus-remote-write + py3{6,7,8,9,10}-test-exporter-prometheus-remote-write ; opentelemetry-instrumentation-mysql - py3{7,8,9,10}-test-instrumentation-mysql + py3{7,8,9,10,11}-test-instrumentation-mysql pypy3-test-instrumentation-mysql ; opentelemetry-instrumentation-psycopg2 - py3{7,8,9,10}-test-instrumentation-psycopg2 + py3{7,8,9,10,11}-test-instrumentation-psycopg2 ; ext-psycopg2 intentionally excluded from pypy3 ; opentelemetry-instrumentation-pymemcache - py3{7,8,9,10}-test-instrumentation-pymemcache{135,200,300,342} + py3{7,8,9,10,11}-test-instrumentation-pymemcache{135,200,300,342} pypy3-test-instrumentation-pymemcache{135,200,300,342} ; opentelemetry-instrumentation-pymongo - py3{7,8,9,10}-test-instrumentation-pymongo + py3{7,8,9,10,11}-test-instrumentation-pymongo pypy3-test-instrumentation-pymongo ; opentelemetry-instrumentation-pymysql - py3{7,8,9,10}-test-instrumentation-pymysql + py3{7,8,9,10,11}-test-instrumentation-pymysql pypy3-test-instrumentation-pymysql ; opentelemetry-instrumentation-pyramid - py3{7,8,9,10}-test-instrumentation-pyramid + py3{7,8,9,10,11}-test-instrumentation-pyramid pypy3-test-instrumentation-pyramid ; opentelemetry-instrumentation-asgi - py3{7,8,9,10}-test-instrumentation-asgi + py3{7,8,9,10,11}-test-instrumentation-asgi pypy3-test-instrumentation-asgi ; opentelemetry-instrumentation-asyncpg - py3{7,8,9,10}-test-instrumentation-asyncpg + py3{7,8,9,10,11}-test-instrumentation-asyncpg ; ext-asyncpg intentionally excluded from pypy3 ; opentelemetry-instrumentation-sqlite3 - py3{7,8,9,10}-test-instrumentation-sqlite3 + py3{7,8,9,10,11}-test-instrumentation-sqlite3 pypy3-test-instrumentation-sqlite3 ; opentelemetry-instrumentation-wsgi - py3{7,8,9,10}-test-instrumentation-wsgi + py3{7,8,9,10,11}-test-instrumentation-wsgi pypy3-test-instrumentation-wsgi ; opentelemetry-instrumentation-grpc - py3{7,8,9,10}-test-instrumentation-grpc + py3{7,8,9,10,11}-test-instrumentation-grpc ; opentelemetry-instrumentation-sqlalchemy py3{7}-test-instrumentation-sqlalchemy{11} - py3{7,8,9,10}-test-instrumentation-sqlalchemy{14} + py3{7,8,9,10,11}-test-instrumentation-sqlalchemy{14} pypy3-test-instrumentation-sqlalchemy{11,14} ; opentelemetry-instrumentation-redis - py3{7,8,9,10}-test-instrumentation-redis + py3{7,8,9,10,11}-test-instrumentation-redis pypy3-test-instrumentation-redis ; opentelemetry-instrumentation-remoulade ; remoulade only supports 3.7 and above - py3{7,8,9,10}-test-instrumentation-remoulade + py3{7,8,9,10,11}-test-instrumentation-remoulade ; instrumentation-remoulade intentionally excluded from pypy3 ; opentelemetry-instrumentation-celery - py3{7,8,9,10}-test-instrumentation-celery + py3{7,8,9,10,11}-test-instrumentation-celery pypy3-test-instrumentation-celery ; opentelemetry-instrumentation-sklearn py3{7,8}-test-instrumentation-sklearn ; opentelemetry-instrumentation-system-metrics - py3{6,7,8,9,10}-test-instrumentation-system-metrics + py3{6,7,8,9,10,11}-test-instrumentation-system-metrics ; instrumentation-system-metrics intentionally excluded from pypy3 ; opentelemetry-instrumentation-tornado - py3{7,8,9,10}-test-instrumentation-tornado + py3{7,8,9,10,11}-test-instrumentation-tornado pypy3-test-instrumentation-tornado ; opentelemetry-instrumentation-httpx - py3{7,8,9,10}-test-instrumentation-httpx{18,21} + py3{7,8,9,10,11}-test-instrumentation-httpx{18,21} pypy3-test-instrumentation-httpx{18,21} ; opentelemetry-util-http - py3{7,8,9,10}-test-util-http + py3{7,8,9,10,11}-test-util-http pypy3-test-util-http ; opentelemetry-propagator-aws-xray - py3{7,8,9,10}-test-propagator-aws-xray + py3{7,8,9,10,11}-test-propagator-aws-xray pypy3-test-propagator-aws-xray ; opentelemetry-propagator-ot-trace - py3{7,8,9,10}-test-propagator-ot-trace + py3{7,8,9,10,11}-test-propagator-ot-trace pypy3-test-propagator-ot-trace ; opentelemetry-instrumentation-pika - py3{7,8,9,10}-test-instrumentation-pika{0,1} + py3{7,8,9,10,11}-test-instrumentation-pika{0,1} pypy3-test-instrumentation-pika{0,1} ; opentelemetry-instrumentation-kafka-python - py3{7,8,9,10}-test-instrumentation-kafka-python + py3{7,8,9,10,11}-test-instrumentation-kafka-python pypy3-test-instrumentation-kafka-python lint @@ -214,6 +221,7 @@ deps = test: pytest-benchmark coverage: pytest coverage: pytest-cov + cherrypy: CherryPy~=18.8.0 django1: django~=1.0 django2: django~=2.0 django3: django~=3.0 @@ -230,6 +238,7 @@ deps = falcon1: falcon ==1.4.1 falcon2: falcon >=2.0.0,<3.0.0 falcon3: falcon >=3.0.0,<4.0.0 + grpc: pytest-asyncio sqlalchemy11: sqlalchemy>=1.1,<1.2 sqlalchemy14: aiosqlite sqlalchemy14: sqlalchemy~=1.4 @@ -265,6 +274,7 @@ changedir = test-instrumentation-botocore: instrumentation/opentelemetry-instrumentation-botocore/tests test-instrumentation-boto3sqs: instrumentation/opentelemetry-instrumentation-boto3sqs/tests test-instrumentation-celery: instrumentation/opentelemetry-instrumentation-celery/tests + test-instrumentation-cherrypy: instrumentation/opentelemetry-instrumentation-cherrypy/tests test-instrumentation-dbapi: instrumentation/opentelemetry-instrumentation-dbapi/tests test-instrumentation-django{1,2,3,4}: instrumentation/opentelemetry-instrumentation-django/tests test-instrumentation-elasticsearch{2,5,6}: instrumentation/opentelemetry-instrumentation-elasticsearch/tests @@ -300,10 +310,11 @@ changedir = test-propagator-aws: propagator/opentelemetry-propagator-aws-xray/tests test-propagator-ot-trace: propagator/opentelemetry-propagator-ot-trace/tests test-exporter-richconsole: exporter/opentelemetry-exporter-richconsole/tests + test-exporter-prometheus-remote-write: exporter/opentelemetry-exporter-prometheus-remote-write/tests commands_pre = ; Install without -e to test the actual installation - py3{7,8,9,10}: python -m pip install -U pip setuptools wheel + py3{7,8,9,10,11}: python -m pip install -U pip setuptools wheel ; Install common packages for all the tests. These are not needed in all the ; cases but it saves a lot of boilerplate in this file. test: pip install "opentelemetry-api[test] @ {env:CORE_REPO}#egg=opentelemetry-api&subdirectory=opentelemetry-api" @@ -316,6 +327,8 @@ commands_pre = celery: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-celery[test] + cherrypy: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-cherrypy[test] + pika{0,1}: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-pika[test] kafka-python: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python[test] @@ -387,6 +400,8 @@ commands_pre = richconsole: pip install flaky {toxinidir}/exporter/opentelemetry-exporter-richconsole[test] + prometheus: pip install {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write[test] + sklearn: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn[test] sqlalchemy{11,14}: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy[test] @@ -470,6 +485,7 @@ commands_pre = python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-flask[test] python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy[test] python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-celery[test] + python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-cherrypy[test] python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-pika[test] python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika[test] python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn[test] @@ -498,6 +514,7 @@ commands_pre = python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda[test] python -m pip install -e {toxinidir}/instrumentation/opentelemetry-instrumentation-system-metrics[test] python -m pip install -e {toxinidir}/exporter/opentelemetry-exporter-richconsole[test] + python -m pip install -e {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write[test] python -m pip install -e {toxinidir}/sdk-extension/opentelemetry-sdk-extension-aws[test] python -m pip install -e {toxinidir}/propagator/opentelemetry-propagator-aws-xray[test] python -m pip install -e {toxinidir}/propagator/opentelemetry-propagator-ot-trace[test] @@ -507,6 +524,7 @@ commands = python scripts/eachdist.py lint --check-only [testenv:docker-tests] +basepython: python3.9 deps = pip >= 20.3.3 pytest From 358af8644af27a9f83cf7d425453dff0982324b6 Mon Sep 17 00:00:00 2001 From: rahmukhe Date: Tue, 29 Nov 2022 14:43:54 +0530 Subject: [PATCH 3/4] added metrices testcases and review comments fixed --- .../opentelemetry-instrumentation-cherrypy/README.rst | 6 +++--- .../tests/test_cherrypy.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst b/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst index 3be2d61eff..145245edae 100644 --- a/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst +++ b/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst @@ -3,8 +3,8 @@ OpenTelemetry CherryPy Tracing |pypi| -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-cherrypy.svg - :target: https://pypi.org/project/opentelemetry-instrumentation-cherrypy/ +.. |pypi| image:: todo + :target: todo This library builds on the OpenTelemetry WSGI middleware to track web requests in CherryPy applications. @@ -22,7 +22,7 @@ Configuration Exclude lists ************* To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_CHERRYPY_EXCLUDED_URLS`` -(or ``OTEL_PYTHON_CHERRYPY_URLS`` as fallback) with comma delimited regexes representing which URLs to exclude. +(or ``OTEL_PYTHON_EXCLUDED_URLS`` as fallback) with comma delimited regexes representing which URLs to exclude. For example, diff --git a/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py b/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py index 12ca10be39..56020e5f62 100644 --- a/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py +++ b/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py @@ -78,7 +78,7 @@ def call(self, *args, **kwargs): self.setup_server() return self.getPage(*args, **kwargs) - + @staticmethod def setup_server(): class CherryPyApp(object): @cherrypy.expose @@ -103,7 +103,7 @@ def error(self): return cherrypy.tree.mount(CherryPyApp()) - setup_server = staticmethod(setup_server) + # setup_server = staticmethod(setup_server) def tearDown(self): super().tearDown() @@ -295,7 +295,7 @@ def test_basic_metric_success(self): dict(point.attributes), ) self.assertEqual(point.value, 0) - + def test_basic_post_request_metric_success(self): start = default_timer() self.setup_server() From b0d3410c119f8d60c0335c881f9f210ab8a91052 Mon Sep 17 00:00:00 2001 From: rahmukhe Date: Tue, 29 Nov 2022 16:25:47 +0530 Subject: [PATCH 4/4] added fixes for review comments --- .../opentelemetry-instrumentation-cherrypy/README.rst | 4 ++-- .../tests/test_cherrypy.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst b/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst index 145245edae..5cd5e43035 100644 --- a/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst +++ b/instrumentation/opentelemetry-instrumentation-cherrypy/README.rst @@ -3,8 +3,8 @@ OpenTelemetry CherryPy Tracing |pypi| -.. |pypi| image:: todo - :target: todo +.. |pypi| image:: TODO + :target: TODO This library builds on the OpenTelemetry WSGI middleware to track web requests in CherryPy applications. diff --git a/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py b/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py index 56020e5f62..d1f32ad543 100644 --- a/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py +++ b/instrumentation/opentelemetry-instrumentation-cherrypy/tests/test_cherrypy.py @@ -103,8 +103,6 @@ def error(self): return cherrypy.tree.mount(CherryPyApp()) - # setup_server = staticmethod(setup_server) - def tearDown(self): super().tearDown() with self.disable_logging(): @@ -311,4 +309,6 @@ def test_basic_post_request_metric_success(self): self.assertAlmostEqual(duration, point.sum, delta=30) if isinstance(point, NumberDataPoint): self.assertEqual(point.value, 0) + + \ No newline at end of file