diff --git a/.travis.yml b/.travis.yml index 223cfbb587f..e8133bbb85d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,9 @@ python: # allow_failures: # - python: '3.8-dev' +services: + - docker + install: - pip install tox-travis diff --git a/ext/opentelemetry-ext-docker-tests/tests/docker-compose.yml b/ext/opentelemetry-ext-docker-tests/tests/docker-compose.yml new file mode 100644 index 00000000000..1dab842f898 --- /dev/null +++ b/ext/opentelemetry-ext-docker-tests/tests/docker-compose.yml @@ -0,0 +1,7 @@ +version: '3' + +services: + otmongo: + ports: + - "27017:27017" + image: mongo:latest \ No newline at end of file diff --git a/ext/opentelemetry-ext-docker-tests/tests/pymongo/test_pymongo_functional.py b/ext/opentelemetry-ext-docker-tests/tests/pymongo/test_pymongo_functional.py new file mode 100644 index 00000000000..4ef14fd789b --- /dev/null +++ b/ext/opentelemetry-ext-docker-tests/tests/pymongo/test_pymongo_functional.py @@ -0,0 +1,108 @@ +# Copyright 2020, 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. + +import os +import typing +import unittest + +from pymongo import MongoClient + +from opentelemetry import trace as trace_api +from opentelemetry.ext.pymongo import trace_integration +from opentelemetry.sdk.trace import Span, Tracer, TracerSource +from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( + InMemorySpanExporter, +) + +MONGODB_HOST = os.getenv("MONGODB_HOST ", "localhost") +MONGODB_PORT = int(os.getenv("MONGODB_PORT ", "27017")) +MONGODB_DB_NAME = os.getenv("MONGODB_DB_NAME ", "opentelemetry-tests") +MONGODB_COLLECTION_NAME = "test" + + +class TestFunctionalPymongo(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls._tracer_source = TracerSource() + cls._tracer = Tracer(cls._tracer_source, None) + cls._span_exporter = InMemorySpanExporter() + cls._span_processor = SimpleExportSpanProcessor(cls._span_exporter) + cls._tracer_source.add_span_processor(cls._span_processor) + trace_integration(cls._tracer) + client = MongoClient( + MONGODB_HOST, MONGODB_PORT, serverSelectionTimeoutMS=2000 + ) + db = client[MONGODB_DB_NAME] + cls._collection = db[MONGODB_COLLECTION_NAME] + + def setUp(self): + self._span_exporter.clear() + + def validate_spans(self): + spans = self._span_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + for span in spans: + if span.name == "rootSpan": + root_span = span + else: + pymongo_span = span + self.assertIsInstance(span.start_time, int) + self.assertIsInstance(span.end_time, int) + self.assertIsNot(root_span, None) + self.assertIsNot(pymongo_span, None) + self.assertIsNotNone(pymongo_span.parent) + self.assertEqual(pymongo_span.parent.name, root_span.name) + self.assertIs(pymongo_span.kind, trace_api.SpanKind.CLIENT) + self.assertEqual( + pymongo_span.attributes["db.instance"], MONGODB_DB_NAME + ) + self.assertEqual( + pymongo_span.attributes["net.peer.name"], MONGODB_HOST + ) + self.assertEqual( + pymongo_span.attributes["net.peer.port"], MONGODB_PORT + ) + + def test_insert(self): + """Should create a child span for insert + """ + with self._tracer.start_as_current_span("rootSpan"): + self._collection.insert_one( + {"name": "testName", "value": "testValue"} + ) + self.validate_spans() + + def test_update(self): + """Should create a child span for update + """ + with self._tracer.start_as_current_span("rootSpan"): + self._collection.update_one( + {"name": "testName"}, {"$set": {"value": "someOtherValue"}} + ) + self.validate_spans() + + def test_find(self): + """Should create a child span for find + """ + with self._tracer.start_as_current_span("rootSpan"): + self._collection.find_one() + self.validate_spans() + + def test_delete(self): + """Should create a child span for delete + """ + with self._tracer.start_as_current_span("rootSpan"): + self._collection.delete_one({"name": "testName"}) + self.validate_spans() diff --git a/ext/opentelemetry-ext-pymongo/tests/test_pymongo_integration.py b/ext/opentelemetry-ext-pymongo/tests/test_pymongo.py similarity index 99% rename from ext/opentelemetry-ext-pymongo/tests/test_pymongo_integration.py rename to ext/opentelemetry-ext-pymongo/tests/test_pymongo.py index 6c99e09e711..0889d9d994b 100644 --- a/ext/opentelemetry-ext-pymongo/tests/test_pymongo_integration.py +++ b/ext/opentelemetry-ext-pymongo/tests/test_pymongo.py @@ -20,7 +20,7 @@ from opentelemetry.util import time_ns -class TestPymongoIntegration(unittest.TestCase): +class TestPymongo(unittest.TestCase): def test_trace_integration(self): mock_register = mock.Mock() patch = mock.patch( diff --git a/tox.ini b/tox.ini index 642a8a556b3..7042fe71cad 100644 --- a/tox.ini +++ b/tox.ini @@ -15,10 +15,11 @@ envlist = py37-tracecontext py37-{mypy,mypyinstalled} docs + docker-tests [travis] python = - 3.7: py37, lint, docs + 3.7: py37, lint, docs, docker-tests [testenv] deps = @@ -152,3 +153,23 @@ commands_pre = commands = {toxinidir}/scripts/tracecontext-integration-test.sh + +[testenv:docker-tests] +deps = + pytest + docker-compose >= 1.25.2 + pymongo ~= 3.1 + +changedir = + ext/opentelemetry-ext-docker-tests/tests + +commands_pre = + pip install -e {toxinidir}/opentelemetry-api \ + -e {toxinidir}/opentelemetry-sdk \ + -e {toxinidir}/ext/opentelemetry-ext-pymongo + - docker-compose up -d +commands = + pytest {posargs} + +commands_post = + docker-compose down \ No newline at end of file