diff options
author | Sergey Shepelev <temotor@gmail.com> | 2017-02-16 14:12:00 +0300 |
---|---|---|
committer | Sergey Shepelev <temotor@gmail.com> | 2017-02-25 23:02:19 +0300 |
commit | 885482b57691bd19e8b403e43a035546705da21e (patch) | |
tree | ccd3c182c67a23439c9f2cf08343a117fcf9e3fb | |
parent | 4e775e23f312c386929e0c5e9a9c952c1ec80c45 (diff) | |
download | eventlet-885482b57691bd19e8b403e43a035546705da21e.tar.gz |
db_pool: proxy Connection.set_isolation_level()
https://github.com/eventlet/eventlet/issues/389
-rw-r--r-- | eventlet/db_pool.py | 139 | ||||
-rw-r--r-- | tests/db_pool_test.py | 105 |
2 files changed, 100 insertions, 144 deletions
diff --git a/eventlet/db_pool.py b/eventlet/db_pool.py index 31cd7cf..301c28c 100644 --- a/eventlet/db_pool.py +++ b/eventlet/db_pool.py @@ -327,98 +327,53 @@ class GenericConnectionWrapper(object): def __repr__(self): return self._base.__repr__() - def affected_rows(self): - return self._base.affected_rows() - - def autocommit(self, *args, **kwargs): - return self._base.autocommit(*args, **kwargs) - - def begin(self): - return self._base.begin() - - def change_user(self, *args, **kwargs): - return self._base.change_user(*args, **kwargs) - - def character_set_name(self, *args, **kwargs): - return self._base.character_set_name(*args, **kwargs) - - def close(self, *args, **kwargs): - return self._base.close(*args, **kwargs) - - def commit(self, *args, **kwargs): - return self._base.commit(*args, **kwargs) - - def cursor(self, *args, **kwargs): - return self._base.cursor(*args, **kwargs) - - def dump_debug_info(self, *args, **kwargs): - return self._base.dump_debug_info(*args, **kwargs) - - def errno(self, *args, **kwargs): - return self._base.errno(*args, **kwargs) - - def error(self, *args, **kwargs): - return self._base.error(*args, **kwargs) - - def errorhandler(self, *args, **kwargs): - return self._base.errorhandler(*args, **kwargs) - - def insert_id(self, *args, **kwargs): - return self._base.insert_id(*args, **kwargs) - - def literal(self, *args, **kwargs): - return self._base.literal(*args, **kwargs) - - def set_character_set(self, *args, **kwargs): - return self._base.set_character_set(*args, **kwargs) - - def set_sql_mode(self, *args, **kwargs): - return self._base.set_sql_mode(*args, **kwargs) - - def show_warnings(self): - return self._base.show_warnings() - - def warning_count(self): - return self._base.warning_count() - - def ping(self, *args, **kwargs): - return self._base.ping(*args, **kwargs) - - def query(self, *args, **kwargs): - return self._base.query(*args, **kwargs) - - def rollback(self, *args, **kwargs): - return self._base.rollback(*args, **kwargs) - - def select_db(self, *args, **kwargs): - return self._base.select_db(*args, **kwargs) - - def set_server_option(self, *args, **kwargs): - return self._base.set_server_option(*args, **kwargs) - - def server_capabilities(self, *args, **kwargs): - return self._base.server_capabilities(*args, **kwargs) - - def shutdown(self, *args, **kwargs): - return self._base.shutdown(*args, **kwargs) - - def sqlstate(self, *args, **kwargs): - return self._base.sqlstate(*args, **kwargs) - - def stat(self, *args, **kwargs): - return self._base.stat(*args, **kwargs) - - def store_result(self, *args, **kwargs): - return self._base.store_result(*args, **kwargs) - - def string_literal(self, *args, **kwargs): - return self._base.string_literal(*args, **kwargs) - - def thread_id(self, *args, **kwargs): - return self._base.thread_id(*args, **kwargs) - - def use_result(self, *args, **kwargs): - return self._base.use_result(*args, **kwargs) + _proxy_funcs = ( + 'affected_rows', + 'autocommit', + 'begin', + 'change_user', + 'character_set_name', + 'close', + 'commit', + 'cursor', + 'dump_debug_info', + 'errno', + 'error', + 'errorhandler', + 'insert_id', + 'literal', + 'ping', + 'query', + 'rollback', + 'select_db', + 'server_capabilities', + 'set_character_set', + 'set_isolation_level', + 'set_server_option', + 'set_sql_mode', + 'show_warnings', + 'shutdown', + 'sqlstate', + 'stat', + 'store_result', + 'string_literal', + 'thread_id', + 'use_result', + 'warning_count', + ) +for _proxy_fun in GenericConnectionWrapper._proxy_funcs: + # excess wrapper for early binding (closure by value) + def _wrapper(_proxy_fun=_proxy_fun): + def _proxy_method(self, *args, **kwargs): + return getattr(self._base, _proxy_fun)(*args, **kwargs) + _proxy_method.func_name = _proxy_fun + _proxy_method.__name__ = _proxy_fun + _proxy_method.__qualname__ = 'GenericConnectionWrapper.' + _proxy_fun + return _proxy_method + setattr(GenericConnectionWrapper, _proxy_fun, _wrapper(_proxy_fun)) +del GenericConnectionWrapper._proxy_funcs +del _proxy_fun +del _wrapper class PooledConnectionWrapper(GenericConnectionWrapper): diff --git a/tests/db_pool_test.py b/tests/db_pool_test.py index da72be4..6dbacdc 100644 --- a/tests/db_pool_test.py +++ b/tests/db_pool_test.py @@ -1,17 +1,27 @@ -'''Test cases for db_pool -''' from __future__ import print_function - -import sys import os +import sys import traceback -from unittest import TestCase, main -from tests import mock, skip_unless, skip_with_pyevent, get_database_auth -from eventlet import event from eventlet import db_pool from eventlet.support import six import eventlet +import eventlet.tpool +import tests +import tests.mock + +psycopg2 = None +try: + import psycopg2 + import psycopg2.extensions +except ImportError: + pass + +MySQLdb = None +try: + import MySQLdb +except ImportError: + pass class DBTester(object): @@ -141,7 +151,7 @@ class DBConnectionPool(DBTester): curs = conn.cursor() results = [] SHORT_QUERY = "select * from test_table" - evt = event.Event() + evt = eventlet.Event() def a_query(): self.assert_cursor_works(curs) @@ -282,7 +292,7 @@ class DBConnectionPool(DBTester): self.connection = self.pool.get() self.assertEqual(self.pool.free(), 0) self.assertEqual(self.pool.waiting(), 0) - e = event.Event() + e = eventlet.Event() def retrieve(pool, ev): c = pool.get() @@ -337,14 +347,13 @@ class TpoolConnectionPool(DBConnectionPool): connect_timeout=connect_timeout, **self._auth) - @skip_with_pyevent + @tests.skip_with_pyevent def setUp(self): super(TpoolConnectionPool, self).setUp() def tearDown(self): super(TpoolConnectionPool, self).tearDown() - from eventlet import tpool - tpool.killall() + eventlet.tpool.killall() class RawConnectionPool(DBConnectionPool): @@ -373,7 +382,7 @@ def test_raw_pool_issue_125(): def test_raw_pool_custom_cleanup_ok(): - cleanup_mock = mock.Mock() + cleanup_mock = tests.mock.Mock() pool = db_pool.RawConnectionPool(DummyDBModule(), cleanup=cleanup_mock) conn = pool.get() pool.put(conn) @@ -385,7 +394,7 @@ def test_raw_pool_custom_cleanup_ok(): def test_raw_pool_custom_cleanup_arg_error(): - cleanup_mock = mock.Mock(side_effect=NotImplementedError) + cleanup_mock = tests.mock.Mock(side_effect=NotImplementedError) pool = db_pool.RawConnectionPool(DummyDBModule()) conn = pool.get() pool.put(conn, cleanup=cleanup_mock) @@ -427,27 +436,23 @@ def test_raw_pool_clear_update_current_size(): assert len(pool.free_items) == 0 -get_auth = get_database_auth - - def mysql_requirement(_f): verbose = os.environ.get('eventlet_test_mysql_verbose') - try: - import MySQLdb - try: - auth = get_auth()['MySQLdb'].copy() - MySQLdb.connect(**auth) - return True - except MySQLdb.OperationalError: - if verbose: - print(">> Skipping mysql tests, error when connecting:", file=sys.stderr) - traceback.print_exc() - return False - except ImportError: + if MySQLdb is None: if verbose: print(">> Skipping mysql tests, MySQLdb not importable", file=sys.stderr) return False + try: + auth = tests.get_database_auth()['MySQLdb'].copy() + MySQLdb.connect(**auth) + return True + except MySQLdb.OperationalError: + if verbose: + print(">> Skipping mysql tests, error when connecting:", file=sys.stderr) + traceback.print_exc() + return False + class MysqlConnectionPool(object): dummy_table_sql = """CREATE TEMPORARY TABLE test_table @@ -463,11 +468,10 @@ class MysqlConnectionPool(object): created TIMESTAMP ) ENGINE=InnoDB;""" - @skip_unless(mysql_requirement) + @tests.skip_unless(mysql_requirement) def setUp(self): - import MySQLdb self._dbmodule = MySQLdb - self._auth = get_auth()['MySQLdb'] + self._auth = tests.get_database_auth()['MySQLdb'] super(MysqlConnectionPool, self).setUp() def tearDown(self): @@ -493,28 +497,27 @@ class MysqlConnectionPool(object): del db -class Test01MysqlTpool(MysqlConnectionPool, TpoolConnectionPool, TestCase): +class Test01MysqlTpool(MysqlConnectionPool, TpoolConnectionPool, tests.LimitedTestCase): __test__ = True -class Test02MysqlRaw(MysqlConnectionPool, RawConnectionPool, TestCase): +class Test02MysqlRaw(MysqlConnectionPool, RawConnectionPool, tests.LimitedTestCase): __test__ = True def postgres_requirement(_f): - try: - import psycopg2 - try: - auth = get_auth()['psycopg2'].copy() - psycopg2.connect(**auth) - return True - except psycopg2.OperationalError: - print("Skipping postgres tests, error when connecting") - return False - except ImportError: + if psycopg2 is None: print("Skipping postgres tests, psycopg2 not importable") return False + try: + auth = tests.get_database_auth()['psycopg2'].copy() + psycopg2.connect(**auth) + return True + except psycopg2.OperationalError: + print("Skipping postgres tests, error when connecting") + return False + class Psycopg2ConnectionPool(object): dummy_table_sql = """CREATE TEMPORARY TABLE test_table @@ -529,11 +532,10 @@ class Psycopg2ConnectionPool(object): created TIMESTAMP );""" - @skip_unless(postgres_requirement) + @tests.skip_unless(postgres_requirement) def setUp(self): - import psycopg2 self._dbmodule = psycopg2 - self._auth = get_auth()['psycopg2'] + self._auth = tests.get_database_auth()['psycopg2'] super(Psycopg2ConnectionPool, self).setUp() def tearDown(self): @@ -566,7 +568,7 @@ class Psycopg2ConnectionPool(object): conn.close() -class TestPsycopg2Base(TestCase): +class TestPsycopg2Base(tests.LimitedTestCase): __test__ = False def test_cursor_works_as_context_manager(self): @@ -575,6 +577,9 @@ class TestPsycopg2Base(TestCase): row = c.fetchone() assert row == (1,) + def test_set_isolation_level(self): + self.connection.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) + class Test01Psycopg2Tpool(Psycopg2ConnectionPool, TpoolConnectionPool, TestPsycopg2Base): __test__ = True @@ -582,7 +587,3 @@ class Test01Psycopg2Tpool(Psycopg2ConnectionPool, TpoolConnectionPool, TestPsyco class Test02Psycopg2Raw(Psycopg2ConnectionPool, RawConnectionPool, TestPsycopg2Base): __test__ = True - - -if __name__ == '__main__': - main() |