Ejemplo n.º 1
0
def test_mutable_json_type(db, config, default_account, folder):
    """
    Test that FolderSync._sync_status which is a mutable JSON column is
    updated as expected.

    """
    from inbox.models.backends.imap import ImapFolderSyncStatus

    sync_status = ImapFolderSyncStatus(account_id=default_account.id, folder=folder)
    db.session.add(sync_status)
    db.session.commit()

    original_metrics = sync_status.metrics

    metrics = dict(download_uid_count=10, queue_checked_at=datetime.utcnow())
    sync_status.update_metrics(metrics)

    updated_metrics = sync_status.metrics

    metrics.update(original_metrics)
    assert updated_metrics != original_metrics and updated_metrics == metrics, "metrics not updated correctly"

    # Reupdate status
    new_metrics = dict(delete_uid_count=50, download_uid_count=100, queue_checked_at=datetime.utcnow())
    sync_status.update_metrics(new_metrics)

    latest_metrics = sync_status.metrics

    metrics.update(new_metrics)
    assert latest_metrics == metrics, "metrics not re-updated correctly"
Ejemplo n.º 2
0
    def _load_state(self):
        with mailsync_session_scope() as db_session:
            try:
                state = ImapFolderSyncStatus.state
                saved_folder_status = db_session.query(ImapFolderSyncStatus)\
                    .filter_by(account_id=self.account_id,
                               folder_id=self.folder_id).options(
                        load_only(state)).one()
            except NoResultFound:
                saved_folder_status = ImapFolderSyncStatus(
                    account_id=self.account_id, folder_id=self.folder_id)
                db_session.add(saved_folder_status)

            saved_folder_status.start_sync()
            db_session.commit()
            self.state = saved_folder_status.state
            return saved_folder_status
Ejemplo n.º 3
0
    def _load_state(self):
        with session_scope(self.namespace_id) as db_session:
            try:
                state = ImapFolderSyncStatus.state
                saved_folder_status = db_session.query(ImapFolderSyncStatus)\
                    .filter_by(account_id=self.account_id,
                               folder_id=self.folder_id).options(
                        load_only(state)).one()
            except NoResultFound:
                saved_folder_status = ImapFolderSyncStatus(
                    account_id=self.account_id, folder_id=self.folder_id)
                db_session.add(saved_folder_status)

            saved_folder_status.start_sync()
            db_session.commit()
            self.state = saved_folder_status.state
            return saved_folder_status
Ejemplo n.º 4
0
    def _run_impl(self):
        # We do NOT ignore soft deletes in the mail sync because it gets real
        # complicated handling e.g. when backends reuse imapids. ImapUid
        # objects are the only objects deleted by the mail sync backends
        # anyway.
        with session_scope(ignore_soft_deletes=False) as db_session:
            try:
                state = ImapFolderSyncStatus.state
                saved_folder_status = db_session.query(ImapFolderSyncStatus)\
                    .filter_by(account_id=self.account_id,
                               folder_id=self.folder_id).options(
                        load_only(state)).one()
            except NoResultFound:
                saved_folder_status = ImapFolderSyncStatus(
                    account_id=self.account_id, folder_id=self.folder_id)
                db_session.add(saved_folder_status)

            saved_folder_status.start_sync()

            db_session.commit()

            self.state = saved_folder_status.state

        # NOTE: The parent ImapSyncMonitor handler could kill us at any
        # time if it receives a shutdown command. The shutdown command is
        # equivalent to ctrl-c.
        while True:
            old_state = self.state
            try:
                self.state = self.state_handlers[old_state](self.conn_pool,
                                                            self.log,
                                                            self.folder_name,
                                                            self.shared_state)
            except UidInvalid:
                self.state = self.state + ' uidinvalid'
            # State handlers are idempotent, so it's okay if we're
            # killed between the end of the handler and the commit.
            if self.state != old_state:
                # Don't need to re-query, will auto refresh on re-associate.
                with session_scope(ignore_soft_deletes=False) as db_session:
                    db_session.add(saved_folder_status)
                    saved_folder_status.state = self.state
                    db_session.commit()
            if self.state == 'finish':
                return
Ejemplo n.º 5
0
    def _run_impl(self):
        # We do NOT ignore soft deletes in the mail sync because it gets real
        # complicated handling e.g. when backends reuse imapids. ImapUid
        # objects are the only objects deleted by the mail sync backends
        # anyway.
        with session_scope(ignore_soft_deletes=False) as db_session:
            try:
                state = ImapFolderSyncStatus.state
                saved_folder_status = db_session.query(ImapFolderSyncStatus)\
                    .filter_by(account_id=self.account_id,
                               folder_id=self.folder_id).options(
                        load_only(state)).one()
            except NoResultFound:
                saved_folder_status = ImapFolderSyncStatus(
                    account_id=self.account_id, folder_id=self.folder_id)
                db_session.add(saved_folder_status)

            saved_folder_status.start_sync()

            db_session.commit()

            self.state = saved_folder_status.state

        # NOTE: The parent ImapSyncMonitor handler could kill us at any
        # time if it receives a shutdown command. The shutdown command is
        # equivalent to ctrl-c.
        while True:
            old_state = self.state
            try:
                self.state = self.state_handlers[old_state](
                    self.conn_pool, self.log, self.folder_name,
                    self.shared_state)
            except UidInvalid:
                self.state = self.state + ' uidinvalid'
            # State handlers are idempotent, so it's okay if we're
            # killed between the end of the handler and the commit.
            if self.state != old_state:
                # Don't need to re-query, will auto refresh on re-associate.
                with session_scope(ignore_soft_deletes=False) as db_session:
                    db_session.add(saved_folder_status)
                    saved_folder_status.state = self.state
                    db_session.commit()
            if self.state == 'finish':
                return
Ejemplo n.º 6
0
    def _run_impl(self):
        # We do NOT ignore soft deletes in the mail sync because it gets real
        # complicated handling e.g. when backends reuse imapids. ImapUid
        # objects are the only objects deleted by the mail sync backends
        # anyway.
        with session_scope(ignore_soft_deletes=False) as db_session:
            try:
                saved_folder_status = db_session.query(ImapFolderSyncStatus)\
                    .filter_by(account_id=self.account_id,
                               folder_id=self.folder_id).one()
            except NoResultFound:
                saved_folder_status = ImapFolderSyncStatus(
                    account_id=self.account_id, folder_id=self.folder_id)
                db_session.add(saved_folder_status)

            saved_folder_status.update_metrics(
                dict(run_state='running',
                     sync_start_time=datetime.utcnow(),
                     sync_end_time=None,
                     sync_error=None))

            db_session.commit()

            self.state = saved_folder_status.state
            # NOTE: The parent ImapSyncMonitor handler could kill us at any
            # time if it receives a shutdown command. The shutdown command is
            # equivalent to ctrl-c.
            while True:
                try:
                    self.state = saved_folder_status.state = \
                        self.state_handlers[saved_folder_status.state](
                            self.conn_pool, db_session, self.log,
                            self.folder_name, self.shared_state)
                except UidInvalid:
                    self.state = saved_folder_status.state = \
                        self.state + ' uidinvalid'
                # State handlers are idempotent, so it's okay if we're
                # killed between the end of the handler and the commit.
                db_session.commit()
                if self.state == 'finish':
                    return
def test_mutable_json_type(db, config, default_account, folder):
    """
    Test that FolderSync._sync_status which is a mutable JSON column is
    updated as expected.

    """
    from inbox.models.backends.imap import ImapFolderSyncStatus

    sync_status = ImapFolderSyncStatus(account_id=default_account.id,
                                       folder=folder)
    db.session.add(sync_status)
    db.session.commit()

    original_metrics = sync_status.metrics

    metrics = dict(download_uid_count=10, queue_checked_at=datetime.utcnow())
    sync_status.update_metrics(metrics)

    updated_metrics = sync_status.metrics

    metrics.update(original_metrics)
    assert updated_metrics != original_metrics and updated_metrics == metrics,\
        'metrics not updated correctly'

    # Reupdate status
    new_metrics = dict(delete_uid_count=50,
                       download_uid_count=100,
                       queue_checked_at=datetime.utcnow())
    sync_status.update_metrics(new_metrics)

    latest_metrics = sync_status.metrics

    metrics.update(new_metrics)
    assert latest_metrics == metrics, 'metrics not re-updated correctly'
Ejemplo n.º 8
0
def add_imap_status_info_rows(folder_id, account_id, db_session):
    """Add placeholder ImapFolderSyncStatus and ImapFolderInfo rows for this
    folder_id if none exist."""
    if not db_session.query(ImapFolderSyncStatus).filter_by(
            account_id=account_id, folder_id=folder_id).all():
        db_session.add(
            ImapFolderSyncStatus(account_id=ACCOUNT_ID,
                                 folder_id=folder_id,
                                 state='initial'))

    if not db_session.query(ImapFolderInfo).filter_by(
            account_id=account_id, folder_id=folder_id).all():
        db_session.add(
            ImapFolderInfo(account_id=account_id,
                           folder_id=folder_id,
                           uidvalidity=1,
                           highestmodseq=22))
Ejemplo n.º 9
0
    def update_folder_sync_status(self, cb):
        # Loads the folder sync status and invokes the provided callback to
        # modify it. Commits any changes and updates `self.state` to ensure
        # they are never out of sync.
        with session_scope(self.namespace_id) as db_session:
            try:
                state = ImapFolderSyncStatus.state
                saved_folder_status = db_session.query(ImapFolderSyncStatus)\
                    .filter_by(account_id=self.account_id, folder_id=self.folder_id)\
                    .options(load_only(state)).one()
            except NoResultFound:
                saved_folder_status = ImapFolderSyncStatus(
                    account_id=self.account_id, folder_id=self.folder_id)
                db_session.add(saved_folder_status)

            cb(saved_folder_status)
            db_session.commit()

            self.state = saved_folder_status.state
Ejemplo n.º 10
0
def create_folder_with_syncstatus(account, name, canonical_name, db_session):
    folder = Folder.find_or_create(db_session, account, name, canonical_name)
    folder.imapsyncstatus = ImapFolderSyncStatus(account=account)
    db_session.commit()
    return folder