def setUp(self): super().setUp() self.client_error_patcher = mock.patch.object( self.storage, "bump_and_store_timestamp", side_effect=exceptions.BackendError("Segmentation fault."), )
def test_ping_returns_false_if_unavailable_in_readonly_mode(self): self.request.registry.settings['readonly'] = 'true' ping = heartbeat(self.permission) with mock.patch.object(self.permission, 'get_user_principals', side_effect=exceptions.BackendError("Boom!")): self.assertFalse(ping(self.request))
def connect(self, readonly=False, force_commit=False): """ Pulls a connection from the pool when context is entered and returns it when context is exited. A COMMIT is performed on the current transaction if everything went well. Otherwise transaction is ROLLBACK, and everything cleaned up. """ with_transaction = not readonly and self.commit_manually session = None try: # Pull connection from pool. session = self.session_factory() # Start context yield session if not readonly and not self.commit_manually: # Mark session as dirty. self.invalidate(session) # Success if with_transaction: session.commit() elif force_commit: # Commit like would do a succesful request. zope_transaction.commit() except sqlalchemy.exc.SQLAlchemyError as e: logger.error(e) if session and with_transaction: session.rollback() raise exceptions.BackendError(original=e) from e finally: if session and self.commit_manually: # Give back to pool if commit done manually. session.close()
def setUp(self): super(BackendErrorTest, self).setUp() self.patcher = mock.patch.object( self.storage, 'create', side_effect=storage_exceptions.BackendError()) self.addCleanup(self.patcher.stop)
def collection_timestamp(self, collection_id, parent_id, auth=None): ts = self._timestamps[parent_id].get(collection_id) if ts is not None: return ts if self.readonly: error_msg = "Cannot initialize empty collection timestamp when running in readonly." raise exceptions.BackendError(message=error_msg) return self.bump_and_store_timestamp(collection_id, parent_id)
def resource_timestamp(self, resource_name, parent_id, auth=None): ts = self._timestamps[parent_id].get(resource_name) if ts is not None: return ts if self.readonly: error_msg = "Cannot initialize empty resource timestamp when running in readonly." raise exceptions.BackendError(message=error_msg) return self.bump_and_store_timestamp(resource_name, parent_id)
def test_ping_returns_false_if_unavailable_in_readonly_mode(self): request = DummyRequest() request.headers['Authorization'] = 'Basic bWF0OjI=' request.registry.settings = {'readonly': 'true'} ping = heartbeat(self.storage) with mock.patch.object(self.storage, 'get_all', side_effect=exceptions.BackendError("Boom!")): self.assertFalse(ping(request))
def wrapped(*args, **kwargs): try: return func(*args, **kwargs) except TypeError: raise except (memcache.Client.MemcachedKeyError, memcache.Client.MemcachedStringEncodingError) as e: logger.exception(e) raise exceptions.BackendError(original=e)
def resource_timestamp(self, resource_name, parent_id): query_existing = """ WITH existing_timestamps AS ( -- Timestamp of latest object. ( SELECT last_modified, as_epoch(last_modified) AS last_epoch FROM objects WHERE parent_id = :parent_id AND resource_name = :resource_name ORDER BY last_modified DESC LIMIT 1 ) -- Timestamp of empty resource. UNION ( SELECT last_modified, as_epoch(last_modified) AS last_epoch FROM timestamps WHERE parent_id = :parent_id AND resource_name = :resource_name ) ) SELECT MAX(last_modified) AS last_modified, MAX(last_epoch) AS last_epoch FROM existing_timestamps """ create_if_missing = """ INSERT INTO timestamps (parent_id, resource_name, last_modified) VALUES (:parent_id, :resource_name, COALESCE(:last_modified, clock_timestamp()::timestamp)) ON CONFLICT (parent_id, resource_name) DO NOTHING RETURNING as_epoch(last_modified) AS last_epoch """ placeholders = dict(parent_id=parent_id, resource_name=resource_name) with self.client.connect(readonly=False) as conn: existing_ts = None ts_result = conn.execute(query_existing, placeholders) row = ts_result.fetchone() # Will return (None, None) when empty. existing_ts = row["last_modified"] # If the backend is readonly, we should not try to create the timestamp. if self.readonly: if existing_ts is None: error_msg = ( "Cannot initialize empty resource timestamp " "when running in readonly." ) raise exceptions.BackendError(message=error_msg) obj = row else: create_result = conn.execute( create_if_missing, dict(last_modified=existing_ts, **placeholders) ) obj = create_result.fetchone() or row return obj["last_epoch"]
def collection_timestamp(self, collection_id, parent_id, auth=None): query_existing = """ WITH existing_timestamps AS ( -- Timestamp of latest record. ( SELECT last_modified, as_epoch(last_modified) AS last_epoch FROM records WHERE parent_id = :parent_id AND collection_id = :collection_id ORDER BY last_modified DESC LIMIT 1 ) -- Timestamp of empty collection. UNION ( SELECT last_modified, as_epoch(last_modified) AS last_epoch FROM timestamps WHERE parent_id = :parent_id AND collection_id = :collection_id ) ) SELECT MAX(last_modified) AS last_modified, MAX(last_epoch) AS last_epoch FROM existing_timestamps """ create_if_missing = """ INSERT INTO timestamps (parent_id, collection_id, last_modified) VALUES (:parent_id, :collection_id, COALESCE(:last_modified, clock_timestamp()::timestamp)) ON CONFLICT (parent_id, collection_id) DO NOTHING RETURNING as_epoch(last_modified) AS last_epoch """ placeholders = dict(parent_id=parent_id, collection_id=collection_id) with self.client.connect(readonly=False) as conn: existing_ts = None ts_result = conn.execute(query_existing, placeholders) row = ts_result.fetchone() # Will return (None, None) when empty. existing_ts = row['last_modified'] # If the backend is readonly, we should not try to create the timestamp. if self.readonly: if existing_ts is None: error_msg = ( 'Cannot initialize empty collection timestamp ' 'when running in readonly.') raise exceptions.BackendError(message=error_msg) record = row else: create_result = conn.execute( create_if_missing, dict(last_modified=existing_ts, **placeholders)) record = create_result.fetchone() or row return record['last_epoch']
def __init__(self, *args, **kwargs): super(StorageErrorTest, self).__init__(*args, **kwargs) self.error = storage_exceptions.BackendError(ValueError()) self.storage_error_patcher = mock.patch( 'kinto.core.storage.memory.Storage.create', side_effect=self.error)
def wrapped(*args, **kwargs): try: return func(*args, **kwargs) except redis.RedisError as e: logger.exception(e) raise exceptions.BackendError(original=e)
def test_backenderror_message_default_to_original_exception_message(self): error = exceptions.BackendError(ValueError("Pool Error")) self.assertEqual(str(error), "ValueError: Pool Error")
def test_backend_error_message_provides_given_message_if_defined(self): error = exceptions.BackendError(message="Connection Error") self.assertEqual(str(error), "Connection Error")
def setUp(self): super(MemoryStorageTest, self).setUp() self.client_error_patcher = mock.patch.object( self.storage, '_bump_timestamp', side_effect=exceptions.BackendError("Segmentation fault."))