def delayed_update_messages(remote_submissions, local_submissions, session,
                                data_dir):
        assert source_exists(session, source.uuid)
        deleter.start()
        time.sleep(1)

        # This next assert should fail if transactions are working, as
        # the source should still be visible in this session -- it's
        # only been deleted in the Deleter's session. If transactions
        # are *not* working, the deletion will be visible here.
        assert source_exists(session, source.uuid) is False
        update_messages(remote_submissions, local_submissions, session,
                        data_dir)
def test_source_exists_true(homedir, mocker):
    """
    Check that method returns True if a source is return from the query.
    """
    session = mocker.MagicMock()
    source = factory.RemoteSource()
    source.uuid = "test-source-uuid"
    session.query().filter_by().one.return_value = source
    assert source_exists(session, "test-source-uuid")
Exemple #3
0
def test_source_exists_true(homedir, mocker):
    '''
    Check that method returns True if a source is return from the query.
    '''
    session = mocker.MagicMock()
    source = make_remote_source()
    source.uuid = 'test-source-uuid'
    session.query().filter_by().one.return_value = source
    assert source_exists(session, 'test-source-uuid')
def test_source_exists_false(homedir, mocker):
    """
    Check that method returns False if NoResultFound is thrown when we try to query the source.
    """
    session = mocker.MagicMock()
    source = mocker.MagicMock()
    source.uuid = "test-source-uuid"
    session.query().filter_by().one.side_effect = NoResultFound()

    assert not source_exists(session, "test-source-uuid")
def test_sync_delete_race(homedir, mocker, session_maker, session):
    """
    Test a race between sync and source deletion (#797).

    The original failure scenario:
      0. New source submits message 1.
      1. Sync occurs in client. Journalist sees message 1.
      2. Source submits message 2.
      3. Journalist simultaneously deletes the source while the sync
         begins. Deletion completes as it occurs independently of the
         sync, but by this time the sync has collected the list of new
         messages, which includes message 2.
      4. Source is gone, yet the logic in the sync will attempt to add
         message 2 which corresponds to a source that is deleted.
    """

    source = factory.RemoteSource()
    message1 = make_remote_message(source.uuid)

    sources = [source]
    submissions = [message1]
    replies = []

    update_local_storage(session, sources, submissions, replies, homedir)

    assert source_exists(session, source.uuid)
    get_message(session, message1.uuid)

    message2 = make_remote_message(source.uuid, file_counter=2)
    submissions = [message1, message2]

    class Deleter(QThread):
        def __init__(self, source_uuid):
            super().__init__()
            self.source_uuid = source_uuid

        def run(self):
            session = db.make_session_maker(homedir)()
            session.begin(subtransactions=True)
            delete_local_source_by_uuid(session, self.source_uuid, homedir)
            session.commit()
            self.exit()

    deleter = Deleter(source.uuid)

    def delayed_update_messages(remote_submissions, local_submissions, session,
                                data_dir):
        assert source_exists(session, source.uuid)
        deleter.start()
        time.sleep(1)

        # This next assert should fail if transactions are working, as
        # the source should still be visible in this session -- it's
        # only been deleted in the Deleter's session. If transactions
        # are *not* working, the deletion will be visible here.
        assert source_exists(session, source.uuid) is False
        update_messages(remote_submissions, local_submissions, session,
                        data_dir)

    mocker.patch("securedrop_client.storage.update_messages",
                 delayed_update_messages)

    # simulate update_local_storage being called as part of the sync operation
    update_local_storage(session, sources, [message1, message2], [], homedir)

    assert source_exists(session, source.uuid) is False
    with pytest.raises(NoResultFound):
        get_message(session, message1.uuid)

    assert source_exists(session, source.uuid) is False
    with pytest.raises(NoResultFound):
        get_message(session, message1.uuid)
        get_message(session, message2.uuid)
 def get_current_source(self):
     source_item = self.currentItem()
     source_widget = self.itemWidget(source_item)
     if source_widget and source_exists(self.controller.session,
                                        source_widget.source.uuid):
         return source_widget.source