Repository: open-telemetry/opentelemetry-python

Issue:
Celery Instrumentation with apply_async function
I have a basic django application which uses celery to call a method using apply_async and delay functions. I am trying to integrate Otel into my django application. I am using  0.10b0 version of all Otel libraries. I have used celery-auto instrumentation for produce the spans/traces. But I see that the celery-auto instrumentation isnt working. 

**Steps to reproduce**
I have attached my code in order to reproduce the issue. 
1. Run the python application using 
`python manage.py runserver`
<img width="684" alt="Screen Shot 2020-07-01 at 1 54 05 PM" src="https://user-images.githubusercontent.com/11060386/86276134-5bf37780-bba2-11ea-951e-75cca763ee55.png">

2. Then also start the celery worker using
celery -A django_email_celery worker --loglevel=info
<img width="1352" alt="Screen Shot 2020-07-01 at 1 55 11 PM" src="https://user-images.githubusercontent.com/11060386/86276219-82b1ae00-bba2-11ea-9a8d-96454683a694.png">


**What is the expected behavior?**
Once you hit the `localhost` url, I see the trace and spans created by the Otel. But I was expecting the `traceid` to continue from method `index()` in `views.py` to `send_log` in `tasks.py`. 

**What is the actual behavior?**
But then the a new trace is being created at the `send_log`. 
<img width="748" alt="Screen Shot 2020-07-01 at 1 59 29 PM" src="https://user-images.githubusercontent.com/11060386/86276630-331fb200-bba3-11ea-9eab-5df16112a275.png">
<img width="1336" alt="Screen Shot 2020-07-01 at 2 01 44 PM" src="https://user-images.githubusercontent.com/11060386/86276746-737f3000-bba3-11ea-8750-be0e416399f0.png">

**Other Info**
I have added celery instrumentation in `celery.py` file

[django_email_celery.zip](https://github.com/open-telemetry/opentelemetry-python/files/4859611/django_email_celery.zip)

@ocelotl @codeboten 


Discussion:

Resolving patch:
diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py
--- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py
+++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py
@@ -30,11 +30,20 @@
 
 .. code:: python
 
+    from opentelemetry import trace
+    from opentelemetry.sdk.trace import TracerProvider
+    from opentelemetry.sdk.trace.export import BatchExportSpanProcessor
     from opentelemetry.instrumentation.celery import CeleryInstrumentor
 
-    CeleryInstrumentor().instrument()
-
     from celery import Celery
+    from celery.signals import worker_process_init
+
+    @worker_process_init.connect(weak=False)
+    def init_celery_tracing(*args, **kwargs):
+        trace.set_tracer_provider(TracerProvider())
+        span_processor = BatchExportSpanProcessor(ConsoleSpanExporter())
+        trace.get_tracer_provider().add_span_processor(span_processor)
+        CeleryInstrumentor().instrument()
 
     app = Celery("tasks", broker="amqp://localhost")
 
@@ -50,13 +59,15 @@ def add(x, y):
 
 import logging
 import signal
+from collections.abc import Iterable
 
 from celery import signals  # pylint: disable=no-name-in-module
 
-from opentelemetry import trace
+from opentelemetry import propagators, trace
 from opentelemetry.instrumentation.celery import utils
 from opentelemetry.instrumentation.celery.version import __version__
 from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
+from opentelemetry.trace.propagation import get_current_span
 from opentelemetry.trace.status import Status, StatusCanonicalCode
 
 logger = logging.getLogger(__name__)
@@ -106,9 +117,16 @@ def _trace_prerun(self, *args, **kwargs):
         if task is None or task_id is None:
             return
 
+        request = task.request
+        tracectx = propagators.extract(carrier_extractor, request) or {}
+        parent = get_current_span(tracectx)
+
         logger.debug("prerun signal start task_id=%s", task_id)
 
-        span = self._tracer.start_span(task.name, kind=trace.SpanKind.CONSUMER)
+        operation_name = "{0}/{1}".format(_TASK_RUN, task.name)
+        span = self._tracer.start_span(
+            operation_name, parent=parent, kind=trace.SpanKind.CONSUMER
+        )
 
         activation = self._tracer.use_span(span, end_on_exit=True)
         activation.__enter__()
@@ -146,7 +164,10 @@ def _trace_before_publish(self, *args, **kwargs):
         if task is None or task_id is None:
             return
 
-        span = self._tracer.start_span(task.name, kind=trace.SpanKind.PRODUCER)
+        operation_name = "{0}/{1}".format(_TASK_APPLY_ASYNC, task.name)
+        span = self._tracer.start_span(
+            operation_name, kind=trace.SpanKind.PRODUCER
+        )
 
         # apply some attributes here because most of the data is not available
         span.set_attribute(_TASK_TAG_KEY, _TASK_APPLY_ASYNC)
@@ -158,6 +179,10 @@ def _trace_before_publish(self, *args, **kwargs):
         activation.__enter__()
         utils.attach_span(task, task_id, (span, activation), is_publish=True)
 
+        headers = kwargs.get("headers")
+        if headers:
+            propagators.inject(type(headers).__setitem__, headers)
+
     @staticmethod
     def _trace_after_publish(*args, **kwargs):
         task = utils.retrieve_task_from_sender(kwargs)
@@ -221,3 +246,10 @@ def _trace_retry(*args, **kwargs):
         # Use `str(reason)` instead of `reason.message` in case we get
         # something that isn't an `Exception`
         span.set_attribute(_TASK_RETRY_REASON_KEY, str(reason))
+
+
+def carrier_extractor(carrier, key):
+    value = getattr(carrier, key, [])
+    if isinstance(value, str) or not isinstance(value, Iterable):
+        value = (value,)
+    return value


Test patch:
diff --git a/instrumentation/opentelemetry-instrumentation-celery/tests/celery_test_tasks.py b/instrumentation/opentelemetry-instrumentation-celery/tests/celery_test_tasks.py
new file mode 100644
--- /dev/null
+++ b/instrumentation/opentelemetry-instrumentation-celery/tests/celery_test_tasks.py
@@ -0,0 +1,29 @@
+# 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 celery import Celery
+
+
+class Config:
+    result_backend = "rpc"
+    broker_backend = "memory"
+
+
+app = Celery(broker="memory:///")
+app.config_from_object(Config)
+
+
+@app.task
+def task_add(num_a, num_b):
+    return num_a + num_b
diff --git a/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py b/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py
new file mode 100644
--- /dev/null
+++ b/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py
@@ -0,0 +1,78 @@
+# 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.
+
+import threading
+import time
+
+from opentelemetry.instrumentation.celery import CeleryInstrumentor
+from opentelemetry.test.test_base import TestBase
+from opentelemetry.trace import SpanKind
+
+from .celery_test_tasks import app, task_add
+
+
+class TestCeleryInstrumentation(TestBase):
+    def setUp(self):
+        super().setUp()
+        self._worker = app.Worker(app=app, pool="solo", concurrency=1)
+        self._thread = threading.Thread(target=self._worker.start)
+        self._thread.daemon = True
+        self._thread.start()
+
+    def tearDown(self):
+        super().tearDown()
+        self._worker.stop()
+        self._thread.join()
+
+    def test_task(self):
+        CeleryInstrumentor().instrument()
+
+        result = task_add.delay(1, 2)
+        while not result.ready():
+            time.sleep(0.05)
+
+        spans = self.sorted_spans(self.memory_exporter.get_finished_spans())
+        self.assertEqual(len(spans), 2)
+
+        consumer, producer = spans
+
+        self.assertEqual(consumer.name, "run/tests.celery_test_tasks.task_add")
+        self.assertEqual(consumer.kind, SpanKind.CONSUMER)
+        self.assert_span_has_attributes(
+            consumer,
+            {
+                "celery.action": "run",
+                "celery.state": "SUCCESS",
+                "messaging.destination": "celery",
+                "celery.task_name": "tests.celery_test_tasks.task_add",
+            },
+        )
+
+        self.assertEqual(
+            producer.name, "apply_async/tests.celery_test_tasks.task_add"
+        )
+        self.assertEqual(producer.kind, SpanKind.PRODUCER)
+        self.assert_span_has_attributes(
+            producer,
+            {
+                "celery.action": "apply_async",
+                "celery.task_name": "tests.celery_test_tasks.task_add",
+                "messaging.destination_kind": "queue",
+                "messaging.destination": "celery",
+            },
+        )
+
+        self.assertNotEqual(consumer.parent, producer.context)
+        self.assertEqual(consumer.parent.span_id, producer.context.span_id)
+        self.assertEqual(consumer.context.trace_id, producer.context.trace_id)
diff --git a/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py b/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py
--- a/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py
+++ b/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py
@@ -46,21 +46,21 @@ def fn_task():
 
     async_span, run_span = spans
 
-    assert (
-        async_span.instrumentation_info.name
-        == opentelemetry.instrumentation.celery.__name__
+    assert run_span.parent == async_span.context
+    assert run_span.parent.span_id == async_span.context.span_id
+    assert run_span.context.trace_id == async_span.context.trace_id
+
+    assert async_span.instrumentation_info.name == "apply_async/{0}".format(
+        opentelemetry.instrumentation.celery.__name__
     )
-    assert (
-        async_span.instrumentation_info.version
-        == opentelemetry.instrumentation.celery.__version__
+    assert async_span.instrumentation_info.version == "apply_async/{0}".format(
+        opentelemetry.instrumentation.celery.__version__
     )
-    assert (
-        run_span.instrumentation_info.name
-        == opentelemetry.instrumentation.celery.__name__
+    assert run_span.instrumentation_info.name == "run/{0}".format(
+        opentelemetry.instrumentation.celery.__name__
     )
-    assert (
-        run_span.instrumentation_info.version
-        == opentelemetry.instrumentation.celery.__version__
+    assert run_span.instrumentation_info.version == "run/{0}".format(
+        opentelemetry.instrumentation.celery.__version__
     )
 
 
@@ -103,7 +103,7 @@ def fn_task():
     span = spans[0]
 
     assert span.status.is_ok is True
-    assert span.name == "test_celery_functional.fn_task"
+    assert span.name == "run/test_celery_functional.fn_task"
     assert span.attributes.get("messaging.message_id") == t.task_id
     assert (
         span.attributes.get("celery.task_name")
@@ -128,7 +128,7 @@ def fn_task(self):
     span = spans[0]
 
     assert span.status.is_ok is True
-    assert span.name == "test_celery_functional.fn_task"
+    assert span.name == "run/test_celery_functional.fn_task"
     assert span.attributes.get("messaging.message_id") == t.task_id
     assert (
         span.attributes.get("celery.task_name")
@@ -157,7 +157,10 @@ def fn_task_parameters(user, force_logout=False):
     assert run_span.context.trace_id != async_span.context.trace_id
 
     assert async_span.status.is_ok is True
-    assert async_span.name == "test_celery_functional.fn_task_parameters"
+    assert (
+        async_span.name
+        == "apply_async/test_celery_functional.fn_task_parameters"
+    )
     assert async_span.attributes.get("celery.action") == "apply_async"
     assert async_span.attributes.get("messaging.message_id") == result.task_id
     assert (
@@ -209,7 +212,10 @@ def fn_task_parameters(user, force_logout=False):
     assert run_span.context.trace_id != async_span.context.trace_id
 
     assert async_span.status.is_ok is True
-    assert async_span.name == "test_celery_functional.fn_task_parameters"
+    assert (
+        async_span.name
+        == "apply_async/test_celery_functional.fn_task_parameters"
+    )
     assert async_span.attributes.get("celery.action") == "apply_async"
     assert async_span.attributes.get("messaging.message_id") == result.task_id
     assert (
@@ -218,7 +224,7 @@ def fn_task_parameters(user, force_logout=False):
     )
 
     assert run_span.status.is_ok is True
-    assert run_span.name == "test_celery_functional.fn_task_parameters"
+    assert run_span.name == "run/test_celery_functional.fn_task_parameters"
     assert run_span.attributes.get("celery.action") == "run"
     assert run_span.attributes.get("celery.state") == "SUCCESS"
     assert run_span.attributes.get("messaging.message_id") == result.task_id
@@ -244,7 +250,7 @@ def fn_exception():
     span = spans[0]
 
     assert span.status.is_ok is False
-    assert span.name == "test_celery_functional.fn_exception"
+    assert span.name == "run/test_celery_functional.fn_exception"
     assert span.attributes.get("celery.action") == "run"
     assert span.attributes.get("celery.state") == "FAILURE"
     assert (
@@ -273,7 +279,7 @@ def fn_exception():
 
     assert span.status.is_ok is True
     assert span.status.canonical_code == StatusCanonicalCode.OK
-    assert span.name == "test_celery_functional.fn_exception"
+    assert span.name == "run/test_celery_functional.fn_exception"
     assert span.attributes.get("celery.action") == "run"
     assert span.attributes.get("celery.state") == "FAILURE"
     assert (
@@ -300,7 +306,7 @@ def fn_exception():
 
     assert span.status.is_ok is True
     assert span.status.canonical_code == StatusCanonicalCode.OK
-    assert span.name == "test_celery_functional.fn_exception"
+    assert span.name == "run/test_celery_functional.fn_exception"
     assert span.attributes.get("celery.action") == "run"
     assert span.attributes.get("celery.state") == "RETRY"
     assert (
@@ -332,7 +338,7 @@ def run(self):
     span = spans[0]
 
     assert span.status.is_ok is True
-    assert span.name == "test_celery_functional.BaseTask"
+    assert span.name == "run/test_celery_functional.BaseTask"
     assert (
         span.attributes.get("celery.task_name")
         == "test_celery_functional.BaseTask"
@@ -364,7 +370,7 @@ def run(self):
     span = spans[0]
 
     assert span.status.is_ok is False
-    assert span.name == "test_celery_functional.BaseTask"
+    assert span.name == "run/test_celery_functional.BaseTask"
     assert (
         span.attributes.get("celery.task_name")
         == "test_celery_functional.BaseTask"
@@ -401,7 +407,7 @@ def run(self):
 
     assert span.status.is_ok is True
     assert span.status.canonical_code == StatusCanonicalCode.OK
-    assert span.name == "test_celery_functional.BaseTask"
+    assert span.name == "run/test_celery_functional.BaseTask"
     assert span.attributes.get("celery.action") == "run"
     assert span.attributes.get("celery.state") == "FAILURE"
     assert span.attributes.get("messaging.message_id") == result.task_id
@@ -423,7 +429,7 @@ def add(x, y):
     span = spans[0]
 
     assert span.status.is_ok is True
-    assert span.name == "test_celery_functional.add"
+    assert span.name == "run/test_celery_functional.add"
     assert (
         span.attributes.get("celery.task_name") == "test_celery_functional.add"
     )
@@ -471,7 +477,7 @@ class CelerySubClass(CelerySuperClass):
     async_span, async_run_span, run_span = spans
 
     assert run_span.status.is_ok is True
-    assert run_span.name == "test_celery_functional.CelerySubClass"
+    assert run_span.name == "run/test_celery_functional.CelerySubClass"
     assert (
         run_span.attributes.get("celery.task_name")
         == "test_celery_functional.CelerySubClass"
@@ -481,7 +487,7 @@ class CelerySubClass(CelerySuperClass):
     assert run_span.attributes.get("messaging.message_id") == result.task_id
 
     assert async_run_span.status.is_ok is True
-    assert async_run_span.name == "test_celery_functional.CelerySubClass"
+    assert async_run_span.name == "run/test_celery_functional.CelerySubClass"
     assert (
         async_run_span.attributes.get("celery.task_name")
         == "test_celery_functional.CelerySubClass"
@@ -493,7 +499,9 @@ class CelerySubClass(CelerySuperClass):
     )
 
     assert async_span.status.is_ok is True
-    assert async_span.name == "test_celery_functional.CelerySubClass"
+    assert (
+        async_span.name == "apply_async/test_celery_functional.CelerySubClass"
+    )
     assert (
         async_span.attributes.get("celery.task_name")
         == "test_celery_functional.CelerySubClass"
diff --git a/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py b/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py
--- a/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py
+++ b/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py
@@ -75,15 +75,13 @@ def validate_spans(self):
         self.assertEqual(db_span.attributes["net.peer.port"], MYSQL_PORT)
 
     def test_execute(self):
-        """Should create a child span for execute
-        """
+        """Should create a child span for execute"""
         with self._tracer.start_as_current_span("rootSpan"):
             self._cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)")
         self.validate_spans()
 
     def test_execute_with_connection_context_manager(self):
-        """Should create a child span for execute with connection context
-        """
+        """Should create a child span for execute with connection context"""
         with self._tracer.start_as_current_span("rootSpan"):
             with self._connection as conn:
                 cursor = conn.cursor()
@@ -91,16 +89,14 @@ def test_execute_with_connection_context_manager(self):
         self.validate_spans()
 
     def test_execute_with_cursor_context_manager(self):
-        """Should create a child span for execute with cursor context
-        """
+        """Should create a child span for execute with cursor context"""
         with self._tracer.start_as_current_span("rootSpan"):
             with self._connection.cursor() as cursor:
                 cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)")
         self.validate_spans()
 
     def test_executemany(self):
-        """Should create a child span for executemany
-        """
+        """Should create a child span for executemany"""
         with self._tracer.start_as_current_span("rootSpan"):
             data = (("1",), ("2",), ("3",))
             stmt = "INSERT INTO test (id) VALUES (%s)"
@@ -108,8 +104,7 @@ def test_executemany(self):
         self.validate_spans()
 
     def test_callproc(self):
-        """Should create a child span for callproc
-        """
+        """Should create a child span for callproc"""
         with self._tracer.start_as_current_span("rootSpan"), self.assertRaises(
             Exception
         ):
diff --git a/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py b/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py
--- a/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py
+++ b/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py
@@ -85,8 +85,7 @@ def validate_spans(self):
         self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT)
 
     def test_execute(self):
-        """Should create a child span for execute method
-        """
+        """Should create a child span for execute method"""
         with self._tracer.start_as_current_span("rootSpan"):
             async_call(
                 self._cursor.execute(
@@ -96,8 +95,7 @@ def test_execute(self):
         self.validate_spans()
 
     def test_executemany(self):
-        """Should create a child span for executemany
-        """
+        """Should create a child span for executemany"""
         with pytest.raises(psycopg2.ProgrammingError):
             with self._tracer.start_as_current_span("rootSpan"):
                 data = (("1",), ("2",), ("3",))
@@ -106,8 +104,7 @@ def test_executemany(self):
             self.validate_spans()
 
     def test_callproc(self):
-        """Should create a child span for callproc
-        """
+        """Should create a child span for callproc"""
         with self._tracer.start_as_current_span("rootSpan"), self.assertRaises(
             Exception
         ):
@@ -169,8 +166,7 @@ def validate_spans(self):
         self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT)
 
     def test_execute(self):
-        """Should create a child span for execute method
-        """
+        """Should create a child span for execute method"""
         with self._tracer.start_as_current_span("rootSpan"):
             async_call(
                 self._cursor.execute(
@@ -180,8 +176,7 @@ def test_execute(self):
         self.validate_spans()
 
     def test_executemany(self):
-        """Should create a child span for executemany
-        """
+        """Should create a child span for executemany"""
         with pytest.raises(psycopg2.ProgrammingError):
             with self._tracer.start_as_current_span("rootSpan"):
                 data = (("1",), ("2",), ("3",))
@@ -190,8 +185,7 @@ def test_executemany(self):
             self.validate_spans()
 
     def test_callproc(self):
-        """Should create a child span for callproc
-        """
+        """Should create a child span for callproc"""
         with self._tracer.start_as_current_span("rootSpan"), self.assertRaises(
             Exception
         ):
diff --git a/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py b/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py
--- a/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py
+++ b/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py
@@ -77,8 +77,7 @@ def validate_spans(self):
         self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT)
 
     def test_execute(self):
-        """Should create a child span for execute method
-        """
+        """Should create a child span for execute method"""
         with self._tracer.start_as_current_span("rootSpan"):
             self._cursor.execute(
                 "CREATE TABLE IF NOT EXISTS test (id integer)"
@@ -86,8 +85,7 @@ def test_execute(self):
         self.validate_spans()
 
     def test_execute_with_connection_context_manager(self):
-        """Should create a child span for execute with connection context
-        """
+        """Should create a child span for execute with connection context"""
         with self._tracer.start_as_current_span("rootSpan"):
             with self._connection as conn:
                 cursor = conn.cursor()
@@ -95,8 +93,7 @@ def test_execute_with_connection_context_manager(self):
         self.validate_spans()
 
     def test_execute_with_cursor_context_manager(self):
-        """Should create a child span for execute with cursor context
-        """
+        """Should create a child span for execute with cursor context"""
         with self._tracer.start_as_current_span("rootSpan"):
             with self._connection.cursor() as cursor:
                 cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)")
@@ -104,8 +101,7 @@ def test_execute_with_cursor_context_manager(self):
         self.assertTrue(cursor.closed)
 
     def test_executemany(self):
-        """Should create a child span for executemany
-        """
+        """Should create a child span for executemany"""
         with self._tracer.start_as_current_span("rootSpan"):
             data = (("1",), ("2",), ("3",))
             stmt = "INSERT INTO test (id) VALUES (%s)"
@@ -113,8 +109,7 @@ def test_executemany(self):
         self.validate_spans()
 
     def test_callproc(self):
-        """Should create a child span for callproc
-        """
+        """Should create a child span for callproc"""
         with self._tracer.start_as_current_span("rootSpan"), self.assertRaises(
             Exception
         ):
diff --git a/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py b/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py
--- a/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py
+++ b/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py
@@ -64,8 +64,7 @@ def validate_spans(self):
         )
 
     def test_insert(self):
-        """Should create a child span for insert
-        """
+        """Should create a child span for insert"""
         with self._tracer.start_as_current_span("rootSpan"):
             self._collection.insert_one(
                 {"name": "testName", "value": "testValue"}
@@ -73,8 +72,7 @@ def test_insert(self):
         self.validate_spans()
 
     def test_update(self):
-        """Should create a child span for update
-        """
+        """Should create a child span for update"""
         with self._tracer.start_as_current_span("rootSpan"):
             self._collection.update_one(
                 {"name": "testName"}, {"$set": {"value": "someOtherValue"}}
@@ -82,15 +80,13 @@ def test_update(self):
         self.validate_spans()
 
     def test_find(self):
-        """Should create a child span for find
-        """
+        """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
-        """
+        """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/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py b/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py
--- a/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py
+++ b/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py
@@ -72,23 +72,20 @@ def validate_spans(self):
         self.assertEqual(db_span.attributes["net.peer.port"], MYSQL_PORT)
 
     def test_execute(self):
-        """Should create a child span for execute
-        """
+        """Should create a child span for execute"""
         with self._tracer.start_as_current_span("rootSpan"):
             self._cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)")
         self.validate_spans()
 
     def test_execute_with_cursor_context_manager(self):
-        """Should create a child span for execute with cursor context
-        """
+        """Should create a child span for execute with cursor context"""
         with self._tracer.start_as_current_span("rootSpan"):
             with self._connection.cursor() as cursor:
                 cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)")
         self.validate_spans()
 
     def test_executemany(self):
-        """Should create a child span for executemany
-        """
+        """Should create a child span for executemany"""
         with self._tracer.start_as_current_span("rootSpan"):
             data = (("1",), ("2",), ("3",))
             stmt = "INSERT INTO test (id) VALUES (%s)"
@@ -96,8 +93,7 @@ def test_executemany(self):
         self.validate_spans()
 
     def test_callproc(self):
-        """Should create a child span for callproc
-        """
+        """Should create a child span for callproc"""
         with self._tracer.start_as_current_span("rootSpan"), self.assertRaises(
             Exception
         ):