Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 08b100f

Browse files
authored
Adding functional tests for psycopg2 integration (open-telemetry#528)
End to end verification for span creation using psycopg2 and dbapi integrations
1 parent cbe1cba commit 08b100f

File tree

4 files changed

+210
-2
lines changed

4 files changed

+210
-2
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Copyright 2020, OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import os
15+
import time
16+
import traceback
17+
18+
import psycopg2
19+
import pymongo
20+
21+
MONGODB_COLLECTION_NAME = "test"
22+
MONGODB_DB_NAME = os.getenv("MONGODB_DB_NAME", "opentelemetry-tests")
23+
MONGODB_HOST = os.getenv("MONGODB_HOST", "localhost")
24+
MONGODB_PORT = int(os.getenv("MONGODB_PORT", "27017"))
25+
POSTGRES_DB_NAME = os.getenv("POSTGRESQL_DB_NAME", "opentelemetry-tests")
26+
POSTGRES_HOST = os.getenv("POSTGRESQL_HOST", "localhost")
27+
POSTGRES_PASSWORD = os.getenv("POSTGRESQL_HOST", "testpassword")
28+
POSTGRES_PORT = int(os.getenv("POSTGRESQL_PORT", "5432"))
29+
POSTGRES_USER = os.getenv("POSTGRESQL_HOST", "testuser")
30+
RETRY_COUNT = 5
31+
RETRY_INTERVAL = 5 # Seconds
32+
33+
34+
def check_pymongo_connection():
35+
# Try to connect to DB
36+
for i in range(RETRY_COUNT):
37+
try:
38+
client = pymongo.MongoClient(
39+
MONGODB_HOST, MONGODB_PORT, serverSelectionTimeoutMS=2000
40+
)
41+
db = client[MONGODB_DB_NAME]
42+
collection = db[MONGODB_COLLECTION_NAME]
43+
collection.find_one()
44+
client.close()
45+
break
46+
except Exception as ex:
47+
if i == RETRY_COUNT - 1:
48+
raise (ex)
49+
traceback.print_exc()
50+
time.sleep(RETRY_INTERVAL)
51+
52+
53+
def check_postgres_connection():
54+
# Try to connect to DB
55+
for i in range(RETRY_COUNT):
56+
try:
57+
connection = psycopg2.connect(
58+
dbname=POSTGRES_DB_NAME,
59+
user=POSTGRES_USER,
60+
password=POSTGRES_PASSWORD,
61+
host=POSTGRES_HOST,
62+
port=POSTGRES_PORT,
63+
)
64+
connection.close()
65+
break
66+
except Exception as ex:
67+
if i == RETRY_COUNT - 1:
68+
raise (ex)
69+
traceback.print_exc()
70+
time.sleep(RETRY_INTERVAL)
71+
72+
73+
def check_docker_services_availability():
74+
# Check if Docker services accept connections
75+
check_pymongo_connection()
76+
check_postgres_connection()
77+
78+
79+
check_docker_services_availability()

ext/opentelemetry-ext-docker-tests/tests/docker-compose.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,14 @@ services:
44
otmongo:
55
ports:
66
- "27017:27017"
7-
image: mongo:latest
7+
image: mongo:latest
8+
9+
otpostgres:
10+
image: postgres
11+
ports:
12+
- "5432:5432"
13+
environment:
14+
POSTGRES_USER: testuser
15+
POSTGRES_PASSWORD: testpassword
16+
POSTGRES_DB: opentelemetry-tests
17+
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Copyright 2020, OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
import time
17+
import unittest
18+
19+
import psycopg2
20+
21+
from opentelemetry import trace as trace_api
22+
from opentelemetry.ext.psycopg2 import trace_integration
23+
from opentelemetry.sdk.trace import Tracer, TracerProvider
24+
from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor
25+
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
26+
InMemorySpanExporter,
27+
)
28+
29+
POSTGRES_HOST = os.getenv("POSTGRESQL_HOST ", "localhost")
30+
POSTGRES_PORT = int(os.getenv("POSTGRESQL_PORT ", "5432"))
31+
POSTGRES_DB_NAME = os.getenv("POSTGRESQL_DB_NAME ", "opentelemetry-tests")
32+
POSTGRES_PASSWORD = os.getenv("POSTGRESQL_HOST ", "testpassword")
33+
POSTGRES_USER = os.getenv("POSTGRESQL_HOST ", "testuser")
34+
35+
36+
class TestFunctionalPsycopg(unittest.TestCase):
37+
@classmethod
38+
def setUpClass(cls):
39+
cls._connection = None
40+
cls._cursor = None
41+
cls._tracer_provider = TracerProvider()
42+
cls._tracer = Tracer(cls._tracer_provider, None)
43+
cls._span_exporter = InMemorySpanExporter()
44+
cls._span_processor = SimpleExportSpanProcessor(cls._span_exporter)
45+
cls._tracer_provider.add_span_processor(cls._span_processor)
46+
trace_integration(cls._tracer)
47+
cls._connection = psycopg2.connect(
48+
dbname=POSTGRES_DB_NAME,
49+
user=POSTGRES_USER,
50+
password=POSTGRES_PASSWORD,
51+
host=POSTGRES_HOST,
52+
port=POSTGRES_PORT,
53+
)
54+
cls._connection.set_session(autocommit=True)
55+
cls._cursor = cls._connection.cursor()
56+
57+
@classmethod
58+
def tearDownClass(cls):
59+
if cls._cursor:
60+
cls._cursor.close()
61+
if cls._connection:
62+
cls._connection.close()
63+
64+
def setUp(self):
65+
self._span_exporter.clear()
66+
67+
def validate_spans(self):
68+
spans = self._span_exporter.get_finished_spans()
69+
self.assertEqual(len(spans), 2)
70+
for span in spans:
71+
if span.name == "rootSpan":
72+
root_span = span
73+
else:
74+
child_span = span
75+
self.assertIsInstance(span.start_time, int)
76+
self.assertIsInstance(span.end_time, int)
77+
self.assertIsNotNone(root_span)
78+
self.assertIsNotNone(child_span)
79+
self.assertEqual(root_span.name, "rootSpan")
80+
self.assertEqual(child_span.name, "postgresql.opentelemetry-tests")
81+
self.assertIsNotNone(child_span.parent)
82+
self.assertEqual(child_span.parent.name, root_span.name)
83+
self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT)
84+
self.assertEqual(
85+
child_span.attributes["db.instance"], POSTGRES_DB_NAME
86+
)
87+
self.assertEqual(child_span.attributes["net.peer.name"], POSTGRES_HOST)
88+
self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT)
89+
90+
def test_execute(self):
91+
"""Should create a child span for execute method
92+
"""
93+
with self._tracer.start_as_current_span("rootSpan"):
94+
self._cursor.execute(
95+
"CREATE TABLE IF NOT EXISTS test (id integer)"
96+
)
97+
self.validate_spans()
98+
99+
def test_executemany(self):
100+
"""Should create a child span for executemany
101+
"""
102+
with self._tracer.start_as_current_span("rootSpan"):
103+
data = ("1", "2", "3")
104+
stmt = "INSERT INTO test (id) VALUES (%s)"
105+
self._cursor.executemany(stmt, data)
106+
self.validate_spans()
107+
108+
def test_callproc(self):
109+
"""Should create a child span for callproc
110+
"""
111+
with self._tracer.start_as_current_span("rootSpan"), self.assertRaises(
112+
Exception
113+
):
114+
self._cursor.callproc("test", ())
115+
self.validate_spans()

tox.ini

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,19 @@ deps =
260260
pytest
261261
docker-compose >= 1.25.2
262262
pymongo ~= 3.1
263+
psycopg2 ~= 2.8.4
263264

264265
changedir =
265266
ext/opentelemetry-ext-docker-tests/tests
266267

267268
commands_pre =
268269
pip install -e {toxinidir}/opentelemetry-api \
269270
-e {toxinidir}/opentelemetry-sdk \
271+
-e {toxinidir}/ext/opentelemetry-ext-dbapi \
272+
-e {toxinidir}/ext/opentelemetry-ext-psycopg2 \
270273
-e {toxinidir}/ext/opentelemetry-ext-pymongo
271-
- docker-compose up -d
274+
docker-compose up -d
275+
python check_availability.py
272276
commands =
273277
pytest {posargs}
274278

0 commit comments

Comments
 (0)