Skip to content

Commit 4330b67

Browse files
isaachierblack-adder
authored andcommitted
Fix wrapper for psycopg2 connection so type check does not fail (#55)
1 parent f5826d9 commit 4330b67

6 files changed

Lines changed: 150 additions & 7 deletions

File tree

.travis.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,22 @@ matrix:
66
include:
77
- python: '2.7'
88
env: COVER=1
9-
- python: '3.3'
9+
# For some reason not working.
10+
# - python: '3.3'
1011
- python: '3.4'
1112
- python: '3.5'
1213
- python: '3.6'
1314

14-
before_install:
15-
- bash travis/install-redis.sh
16-
1715
install:
1816
- make install-ci
1917

18+
services:
19+
- postgresql
20+
- redis
21+
22+
before_script:
23+
- psql -c 'create database travis_ci_test;' -U postgres
24+
2025
script:
2126
- make test lint
2227

opentracing_instrumentation/client_hooks/_dbapi2.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ def __init__(self, connection, module_name, connect_params):
161161
connect_params=connect_params
162162
)
163163

164+
def __getattr__(self, name):
165+
# Tip suggested here:
166+
# https://gist.github.com/mjallday/3d4c92e7e6805af1e024.
167+
if name == '_sqla_unwrap':
168+
return self.__wrapped__
169+
164170
def __enter__(self):
165171
with func_span('%s:begin_transaction' % self._module_name):
166172
cursor = self.__wrapped__.__enter__()

setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
'flake8<3', # see https://github.com/zheller/flake8-quotes/issues/29
4242
'flake8-quotes',
4343
'mock<1.1.0',
44+
'psycopg2>=2.4.0',
45+
'sqlalchemy>=1.2.0',
4446
'pytest>=3.0.0',
4547
'pytest-cov',
4648
'pytest-localserver',
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Copyright (c) 2018 Uber Technologies, Inc.
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in
11+
# all copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
# THE SOFTWARE.
20+
21+
from builtins import object
22+
import random
23+
24+
import psycopg2 as psycopg2_client
25+
26+
from basictracer import BasicTracer
27+
from basictracer.recorder import InMemoryRecorder
28+
import opentracing
29+
from opentracing.ext import tags
30+
31+
from opentracing_instrumentation.client_hooks import _dbapi2
32+
from opentracing_instrumentation.client_hooks import psycopg2
33+
34+
from sqlalchemy import (
35+
Column,
36+
ForeignKey,
37+
Integer,
38+
MetaData,
39+
String,
40+
Table,
41+
create_engine,
42+
)
43+
from sqlalchemy.orm import mapper, sessionmaker
44+
45+
import pytest
46+
47+
48+
POSTGRES_CONNECTION_STRING = 'postgresql://localhost/travis_ci_test'
49+
50+
51+
@pytest.fixture
52+
def engine():
53+
try:
54+
yield create_engine(POSTGRES_CONNECTION_STRING)
55+
except:
56+
pass
57+
58+
59+
@pytest.fixture
60+
def session():
61+
Session = sessionmaker()
62+
Session.configure(bind=engine)
63+
try:
64+
yield Session()
65+
except:
66+
pass
67+
68+
69+
@pytest.fixture(autouse=True)
70+
def patch_postgres():
71+
psycopg2.install_patches()
72+
73+
74+
@pytest.fixture()
75+
def tracer():
76+
t = BasicTracer(recorder=InMemoryRecorder())
77+
old_tracer = opentracing.tracer
78+
opentracing.tracer = t
79+
80+
try:
81+
yield t
82+
except:
83+
opentracing.tracer = old_tracer
84+
85+
86+
metadata = MetaData()
87+
user = Table('user', metadata,
88+
Column('id', Integer, primary_key=True),
89+
Column('name', String(50)),
90+
Column('fullname', String(50)),
91+
Column('password', String(12)))
92+
93+
94+
class User(object):
95+
96+
def __init__(self, name, fullname, password):
97+
self.name = name
98+
self.fullname = fullname
99+
self.password = password
100+
101+
102+
mapper(User, user)
103+
104+
105+
def is_postgres_running():
106+
try:
107+
with psycopg2_client.connect(POSTGRES_CONNECTION_STRING) as conn:
108+
pass
109+
return True
110+
except:
111+
return False
112+
113+
114+
@pytest.mark.skipif(not is_postgres_running(), reason='Postgres is not running or cannot connect')
115+
def test_db(tracer, engine, session):
116+
metadata.create_all(engine)
117+
user1 = User(name='user1', fullname='User 1', password='password')
118+
user2 = User(name='user2', fullname='User 2', password='password')
119+
session.add(user1)
120+
session.add(user2)
121+
# If the test does not raised an error, it is passing

tests/opentracing_instrumentation/test_redis.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ def check_span(span, key):
9393
assert span.tags[tags.PEER_SERVICE] == 'redis'
9494

9595

96+
def is_redis_running():
97+
try:
98+
return client().ping()
99+
except:
100+
return False
101+
102+
103+
@pytest.mark.skipif(not is_redis_running(), reason='Redis is not running')
96104
def test_get(monkeypatch, client, key):
97105
span, start_span = spans(monkeypatch)
98106
client.get(key)
@@ -101,6 +109,7 @@ def test_get(monkeypatch, client, key):
101109
client.get(name=key)
102110

103111

112+
@pytest.mark.skipif(not is_redis_running(), reason='Redis is not running')
104113
def test_set(monkeypatch, client, key):
105114
span, start_span = spans(monkeypatch)
106115
client.set(key, VAL)
@@ -111,6 +120,7 @@ def test_set(monkeypatch, client, key):
111120
client.set(key, VAL, 1)
112121

113122

123+
@pytest.mark.skipif(not is_redis_running(), reason='Redis is not running')
114124
def test_setex(monkeypatch, client, key):
115125
span, start_span = spans(monkeypatch)
116126
client.setex(key, 60, VAL)
@@ -120,6 +130,7 @@ def test_setex(monkeypatch, client, key):
120130
client.setex(name=key, time=60, value=VAL)
121131

122132

133+
@pytest.mark.skipif(not is_redis_running(), reason='Redis is not running')
123134
def test_setnx(monkeypatch, client, key):
124135
span, start_span = spans(monkeypatch)
125136
client.setnx(key, VAL)
@@ -129,6 +140,7 @@ def test_setnx(monkeypatch, client, key):
129140
client.setnx(name=key, value=VAL)
130141

131142

143+
@pytest.mark.skipif(not is_redis_running(), reason='Redis is not running')
132144
def test_key_is_cleared(monkeypatch, client, key):
133145
# first do a GET that sets the key
134146
span, start_span = spans(monkeypatch)

travis/install-redis.sh

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)