Ejemplo n.º 1
0
 def setUp(self):
     super().setUp()
     self.client_error_patcher = mock.patch.object(
         self.storage,
         "bump_and_store_timestamp",
         side_effect=exceptions.BackendError("Segmentation fault."),
     )
Ejemplo n.º 2
0
 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))
Ejemplo n.º 3
0
    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()
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
 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)
Ejemplo n.º 7
0
 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))
Ejemplo n.º 8
0
 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)
Ejemplo n.º 9
0
    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"]
Ejemplo n.º 10
0
    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']
Ejemplo n.º 11
0
 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)
Ejemplo n.º 12
0
 def wrapped(*args, **kwargs):
     try:
         return func(*args, **kwargs)
     except redis.RedisError as e:
         logger.exception(e)
         raise exceptions.BackendError(original=e)
Ejemplo n.º 13
0
 def test_backenderror_message_default_to_original_exception_message(self):
     error = exceptions.BackendError(ValueError("Pool Error"))
     self.assertEqual(str(error), "ValueError: Pool Error")
Ejemplo n.º 14
0
 def test_backend_error_message_provides_given_message_if_defined(self):
     error = exceptions.BackendError(message="Connection Error")
     self.assertEqual(str(error), "Connection Error")
Ejemplo n.º 15
0
 def setUp(self):
     super(MemoryStorageTest, self).setUp()
     self.client_error_patcher = mock.patch.object(
         self.storage,
         '_bump_timestamp',
         side_effect=exceptions.BackendError("Segmentation fault."))