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