def _fixture(self, dialect_name, exception, is_disconnect=False): def do_execute(self, cursor, statement, parameters, **kw): raise exception engine = self.engine # ensure the engine has done its initial checks against the # DB as we are going to be removing its ability to execute a # statement self.engine.connect().close() with test_utils.nested( mock.patch.object(engine.dialect, "do_execute", do_execute), # replace the whole DBAPI rather than patching "Error" # as some DBAPIs might not be patchable (?) mock.patch.object(engine.dialect, "dbapi", mock.Mock(Error=self.Error)), mock.patch.object(engine.dialect, "name", dialect_name), mock.patch.object(engine.dialect, "is_disconnect", lambda *args: is_disconnect) ): yield
def _fixture( self, dialect_name, exception, num_disconnects, is_disconnect=True): engine = self.engine event.listen(engine, "engine_connect", engines._connect_ping_listener) real_do_execute = engine.dialect.do_execute counter = itertools.count(1) def fake_do_execute(self, *arg, **kw): if next(counter) > num_disconnects: return real_do_execute(self, *arg, **kw) else: raise exception with self._dbapi_fixture(dialect_name): with test_utils.nested( mock.patch.object(engine.dialect, "do_execute", fake_do_execute), mock.patch.object(engine.dialect, "is_disconnect", mock.Mock(return_value=is_disconnect)) ): yield
def _fixture(self, dialect_name, exception, num_disconnects, is_disconnect=True): engine = self.engine event.listen(engine, "engine_connect", engines._connect_ping_listener) real_do_execute = engine.dialect.do_execute counter = itertools.count(1) def fake_do_execute(self, *arg, **kw): if next(counter) > num_disconnects: return real_do_execute(self, *arg, **kw) else: raise exception with self._dbapi_fixture(dialect_name): with test_utils.nested( mock.patch.object(engine.dialect, "do_execute", fake_do_execute), mock.patch.object(engine.dialect, "is_disconnect", mock.Mock(return_value=is_disconnect))): yield
def _dbapi_fixture(self, dialect_name, is_disconnect=False): engine = self.engine with test_utils.nested( mock.patch.object(engine.dialect.dbapi, "Error", self.Error), mock.patch.object(engine.dialect, "name", dialect_name), mock.patch.object(engine.dialect, "is_disconnect", lambda *args: is_disconnect), ): yield
def _dbapi_fixture(self, dialect_name, is_disconnect=False): engine = self.engine with test_utils.nested( mock.patch.object(engine.dialect.dbapi, "Error", self.Error), mock.patch.object(engine.dialect, "name", dialect_name), mock.patch.object(engine.dialect, "is_disconnect", lambda *args: is_disconnect)): yield
def test_db_sync_sanity_called(self): with test_utils.nested( mock.patch.object(migration, '_find_migrate_repo'), mock.patch.object(migration, '_db_schema_sanity_check'), mock.patch.object(versioning_api, 'downgrade') ) as (mock_find_repo, mock_sanity, mock_downgrade): mock_find_repo.return_value = self.return_value migration.db_sync(self.engine, self.path, self.test_version) mock_sanity.assert_called_once_with(self.engine)
def test_db_sync_sanity_skipped(self): with test_utils.nested( mock.patch.object(migration, '_find_migrate_repo'), mock.patch.object(migration, '_db_schema_sanity_check'), mock.patch.object(versioning_api, 'downgrade') ) as (mock_find_repo, mock_sanity, mock_downgrade): mock_find_repo.return_value = self.return_value migration.db_sync(self.engine, self.path, self.test_version, sanity_check=False) self.assertFalse(mock_sanity.called)
def test_db_sync_sanity_called(self): with test_utils.nested( mock.patch.object(migration, '_find_migrate_repo'), mock.patch.object(migration, '_db_schema_sanity_check'), mock.patch.object(versioning_api, 'downgrade') ) as (mock_find_repo, mock_sanity, mock_downgrade): mock_find_repo.return_value = self.return_value migration.db_sync(self.engine, self.path, self.test_version) self.assertEqual([mock.call(self.engine), mock.call(self.engine)], mock_sanity.call_args_list)
def test_db_version_control(self): with test_utils.nested( mock.patch.object(migration, '_find_migrate_repo'), mock.patch.object(versioning_api, 'version_control'), ) as (mock_find_repo, mock_version_control): mock_find_repo.return_value = self.return_value version = migration.db_version_control( self.engine, self.path, self.test_version) self.assertEqual(self.test_version, version) mock_version_control.assert_called_once_with( self.engine, self.return_value, self.test_version)
def test_db_sync_downgrade(self): with test_utils.nested( mock.patch.object(migration, '_find_migrate_repo'), mock.patch.object(versioning_api, 'downgrade') ) as (mock_find_repo, mock_downgrade): mock_find_repo.return_value = self.return_value self.mock_api_db_version.return_value = self.test_version + 1 migration.db_sync(self.engine, self.path, self.test_version) mock_downgrade.assert_called_once_with( self.engine, self.return_value, self.test_version)
def test_no_is_disconnect_not_invalidated(self): self._fixture() with test_utils.nested( mock.patch.object(self.engine.dialect.execution_ctx_cls, "handle_dbapi_exception"), mock.patch.object( self.engine.dialect, "is_disconnect", lambda *args: False)) as (handle_dbapi_exception, is_disconnect): with self.engine.connect() as conn: self.assertRaises(MyException, conn.execute, "SELECT 'ERROR ONE' FROM I_DONT_EXIST") self.assertEqual(1, handle_dbapi_exception.call_count) self.assertFalse(conn.invalidated)
def test_no_is_disconnect_not_invalidated(self): self._fixture() with test_utils.nested( mock.patch.object( self.engine.dialect.execution_ctx_cls, "handle_dbapi_exception" ), mock.patch.object( self.engine.dialect, "is_disconnect", lambda *args: False ) ) as (handle_dbapi_exception, is_disconnect): with self.engine.connect() as conn: self.assertRaises( MyException, conn.execute, "SELECT 'ERROR ONE' FROM I_DONT_EXIST" ) self.assertEqual(1, handle_dbapi_exception.call_count) self.assertFalse(conn.invalidated)
def _fixture(self, dialect_name, exception, is_disconnect=False): def do_execute(self, cursor, statement, parameters, **kw): raise exception engine = self.engine # ensure the engine has done its initial checks against the # DB as we are going to be removing its ability to execute a # statement self.engine.connect().close() with test_utils.nested( mock.patch.object(engine.dialect, "do_execute", do_execute), # replace the whole DBAPI rather than patching "Error" # as some DBAPIs might not be patchable (?) mock.patch.object(engine.dialect, "dbapi", mock.Mock(Error=self.Error)), mock.patch.object(engine.dialect, "name", dialect_name), mock.patch.object(engine.dialect, "is_disconnect", lambda *args: is_disconnect)): yield