Exemple #1
0
def app(tmpdir, qtbot, mocker):
    tmp_db = tmpdir.join('settings.sqlite')
    mock_db = peewee.SqliteDatabase(str(tmp_db))
    vorta.models.init_db(mock_db)
    mocker.patch.object(vorta.application.VortaApp,
                        'set_borg_details_action',
                        return_value=None)

    new_repo = RepoModel(url='[email protected]:repo')
    new_repo.save()

    profile = BackupProfileModel.get(id=1)
    profile.repo = new_repo.id
    profile.save()

    test_archive = ArchiveModel(snapshot_id='99999',
                                name='test-archive',
                                time=dt(2000, 1, 1, 0, 0),
                                repo=1)
    test_archive.save()

    source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo)
    source_dir.save()

    app = VortaApp([])
    app.open_main_window_action()
    qtbot.addWidget(app.main_window)
    app.main_window.tests_running = True
    return app
Exemple #2
0
    def process_result(self, result):
        if result['returncode'] == 0:
            repo, created = RepoModel.get_or_create(url=result['cmd'][-1])
            if not result['data']:
                result['data'] = {
                }  # TODO: Workaround for tests. Can't read mock results 2x.
            remote_archives = result['data'].get('archives', [])

            # Delete archives that don't exist on the remote side
            for archive in ArchiveModel.select().where(
                    ArchiveModel.repo == repo.id):
                if not list(
                        filter(lambda s: s['id'] == archive.snapshot_id,
                               remote_archives)):
                    archive.delete_instance()

            # Add remote archives we don't have locally.
            for archive in result['data'].get('archives', []):
                new_archive, _ = ArchiveModel.get_or_create(
                    snapshot_id=archive['id'],
                    repo=repo.id,
                    defaults={
                        'name': archive['name'],
                        'time': parser.parse(archive['time'])
                    })
                new_archive.save()
Exemple #3
0
def app(tmpdir, qtbot):
    tmp_db = tmpdir.join('settings.sqlite')
    mock_db = peewee.SqliteDatabase(str(tmp_db))
    vorta.models.init_db(mock_db)

    new_repo = RepoModel(url='[email protected]:repo')
    new_repo.save()

    profile = BackupProfileModel.get(id=1)
    profile.repo = new_repo.id
    profile.save()

    test_archive = ArchiveModel(snapshot_id='99999',
                                name='test-archive',
                                time=dt(2000, 1, 1, 0, 0),
                                repo=1)
    test_archive.save()

    source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo)
    source_dir.save()

    app = VortaApp([])
    app.main_window.show()
    qtbot.addWidget(app.main_window)
    return app
Exemple #4
0
 def delete_result(self, result):
     if result['returncode'] == 0:
         self._set_status(self.tr('Archive deleted.'))
         deleted_row = self.archiveTable.findItems(
             self.archive_name, QtCore.Qt.MatchExactly)[0].row()
         self.archiveTable.removeRow(deleted_row)
         ArchiveModel.get(name=self.archive_name).delete_instance()
         del self.archive_name
     else:
         self._toggle_all_buttons(True)
Exemple #5
0
 def list_diff_result(self, result):
     self._set_status('')
     if result['returncode'] == 0:
         archive_newer = ArchiveModel.get(
             name=result['params']['archive_name_newer'])
         archive_older = ArchiveModel.get(
             name=result['params']['archive_name_older'])
         window = DiffResult(result['data'], archive_newer, archive_older)
         self._toggle_all_buttons(True)
         window.setParent(self, QtCore.Qt.Sheet)
         self._resultwindow = window  # for testing
         window.show()
Exemple #6
0
def init_db(qapp):
    vorta.models.db.drop_tables(models)
    vorta.models.init_db()

    new_repo = RepoModel(url='[email protected]:repo')
    new_repo.save()

    profile = BackupProfileModel.get(id=1)
    profile.repo = new_repo.id
    profile.save()

    test_archive = ArchiveModel(snapshot_id='99999',
                                name='test-archive',
                                time=dt(2000, 1, 1, 0, 0),
                                repo=1)
    test_archive.save()

    test_archive1 = ArchiveModel(snapshot_id='99998',
                                 name='test-archive1',
                                 time=dt(2000, 1, 1, 0, 0),
                                 repo=1)
    test_archive1.save()

    source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo)
    source_dir.save()

    qapp.open_main_window_action()
Exemple #7
0
def init_db(qapp):
    vorta.models.db.drop_tables(models)
    vorta.models.init_db()

    new_repo = RepoModel(url='[email protected]:repo')
    new_repo.encryption = 'none'
    new_repo.save()

    profile = BackupProfileModel.get(id=1)
    profile.repo = new_repo.id
    profile.dont_run_on_metered_networks = False
    profile.save()

    test_archive = ArchiveModel(snapshot_id='99999',
                                name='test-archive',
                                time=dt(2000, 1, 1, 0, 0),
                                repo=1)
    test_archive.save()

    test_archive1 = ArchiveModel(snapshot_id='99998',
                                 name='test-archive1',
                                 time=dt(2000, 1, 1, 0, 0),
                                 repo=1)
    test_archive1.save()

    source_dir = SourceFileModel(dir='/tmp/another',
                                 repo=new_repo,
                                 dir_size=100,
                                 dir_files_count=18,
                                 path_isdir=True)
    source_dir.save()

    qapp.main_window = MainWindow(
        qapp)  # Re-open main window to apply mock data in UI
Exemple #8
0
    def list_archive_result(self, result):
        self._set_status('')
        if result['returncode'] == 0:

            def process_result():
                def receive():
                    extraction_folder = dialog.selectedFiles()
                    if extraction_folder:
                        params = BorgExtractThread.prepare(
                            self.profile(), archive.name, window.selected,
                            extraction_folder[0])
                        if params['ok']:
                            self._toggle_all_buttons(False)
                            thread = BorgExtractThread(params['cmd'],
                                                       params,
                                                       parent=self.app)
                            thread.updated.connect(self.mountErrors.setText)
                            thread.result.connect(self.extract_archive_result)
                            thread.start()
                        else:
                            self._set_status(params['message'])

                dialog = choose_file_dialog(self,
                                            self.tr("Choose Extraction Point"),
                                            want_folder=True)
                dialog.open(receive)

            archive = ArchiveModel.get(name=result['params']['archive_name'])
            window = ExtractDialog(result['data'], archive)
            self._toggle_all_buttons(True)
            window.setParent(self, QtCore.Qt.Sheet)
            self._window = window  # for testing
            window.show()
            window.accepted.connect(process_result)
Exemple #9
0
def test_archive_rename(qapp, qtbot, mocker, borg_json_output):
    main = qapp.main_window
    tab = main.archiveTab
    main.tabWidget.setCurrentIndex(3)

    tab.populate_from_profile()
    qtbot.waitUntil(lambda: tab.archiveTable.rowCount() == 2)

    tab.archiveTable.selectRow(0)
    new_archive_name = 'idf89d8f9d8fd98'
    stdout, stderr = borg_json_output('rename')
    popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
    mocker.patch.object(vorta.borg.borg_thread,
                        'Popen',
                        return_value=popen_result)
    mocker.patch.object(vorta.views.archive_tab.QInputDialog,
                        'getText',
                        return_value=(new_archive_name, True))
    tab.rename_action()

    # Successful rename case
    qtbot.waitUntil(lambda: tab.mountErrors.text() == 'Archive renamed.',
                    **pytest._wait_defaults)
    assert ArchiveModel.select().filter(name=new_archive_name).count() == 1

    # Duplicate name case
    exp_text = 'An archive with this name already exists.'
    mocker.patch.object(vorta.views.archive_tab.QInputDialog,
                        'getText',
                        return_value=(new_archive_name, True))
    tab.rename_action()
    qtbot.waitUntil(lambda: tab.mountErrors.text() == exp_text,
                    **pytest._wait_defaults)
Exemple #10
0
    def process_result(self, result):
        if result['returncode'] in [0, 1] and 'archive' in result['data']:
            new_archive, created = ArchiveModel.get_or_create(
                snapshot_id=result['data']['archive']['id'],
                defaults={
                    'name': result['data']['archive']['name'],
                    'time': parser.parse(result['data']['archive']['start']),
                    'repo': result['params']['repo_id'],
                    'duration': result['data']['archive']['duration'],
                    'size':
                    result['data']['archive']['stats']['deduplicated_size']
                })
            new_archive.save()
            if 'cache' in result['data'] and created:
                stats = result['data']['cache']['stats']
                repo = RepoModel.get(id=result['params']['repo_id'])
                repo.total_size = stats['total_size']
                repo.unique_csize = stats['unique_csize']
                repo.unique_size = stats['unique_size']
                repo.total_unique_chunks = stats['total_unique_chunks']
                repo.save()

            if result['returncode'] == 1:
                self.app.backup_progress_event.emit(
                    self.
                    tr('Backup finished with warnings. See logs for details.'))
            else:
                self.app.backup_progress_event.emit(
                    self.tr('Backup finished.'))
Exemple #11
0
    def process_result(self, result):
        if result['returncode'] == 0:
            remote_archives = result['data'].get('archives', [])

            # get info stored during BorgThread.prepare()
            # repo_id = self.params['repo_id']
            repo_id = result['params']['repo_id']

            # Update remote archives.
            for remote_archive in remote_archives:
                archive = ArchiveModel.get_or_none(
                    snapshot_id=remote_archive['id'], repo=repo_id)
                archive.name = remote_archive['name']  # incase name changed
                # archive.time = parser.parse(remote_archive['time'])
                archive.duration = remote_archive['duration']
                archive.size = remote_archive['stats']['deduplicated_size']

                archive.save()

            if 'cache' in result['data']:
                stats = result['data']['cache']['stats']
                repo = RepoModel.get(id=result['params']['repo_id'])
                repo.total_size = stats['total_size']
                repo.unique_csize = stats['unique_csize']
                repo.unique_size = stats['unique_size']
                repo.total_unique_chunks = stats['total_unique_chunks']
                repo.save()
Exemple #12
0
 def process_result(self, result):
     if result['returncode'] == 0:
         repo_url, old_name = result['cmd'][-2].split('::')
         new_name = result['cmd'][-1]
         repo = RepoModel.get(url=repo_url)
         renamed_archive = ArchiveModel.get(name=old_name, repo=repo)
         renamed_archive.name = new_name
         renamed_archive.save()
Exemple #13
0
    def process_result(self, result):
        if result['returncode'] == 0:
            repo, created = RepoModel.get_or_create(url=result['cmd'][-1])
            remote_snapshots = result['data'].get('archives', [])

            # Delete snapshots that don't exist on the remote side
            for snapshot in ArchiveModel.select().where(ArchiveModel.repo == repo.id):
                if not list(filter(lambda s: s['id'] == snapshot.snapshot_id, remote_snapshots)):
                    snapshot.delete_instance()

            # Add remote snapshots we don't have locally.
            for snapshot in result['data'].get('archives', []):
                new_snapshot, _ = ArchiveModel.get_or_create(
                    snapshot_id=snapshot['id'],
                    defaults={
                        'repo': repo.id,
                        'name': snapshot['name'],
                        'time': parser.parse(snapshot['time'])
                    }
                )
                new_snapshot.save()
Exemple #14
0
    def repo_unlink_action(self):
        profile = self.profile()
        self.init_repo_stats()
        msg = QMessageBox()
        msg.setStandardButtons(QMessageBox.Ok)
        msg.setParent(self, QtCore.Qt.Sheet)
        selected_repo_id = self.repoSelector.currentData()
        selected_repo_index = self.repoSelector.currentIndex()
        if selected_repo_index > 2:
            repo = RepoModel.get(id=selected_repo_id)
            ArchiveModel.delete().where(ArchiveModel.repo_id == repo.id).execute()
            profile.repo = None
            profile.save()
            repo.delete_instance(recursive=True)  # This also deletes archives.
            self.repoSelector.setCurrentIndex(0)
            self.repoSelector.removeItem(selected_repo_index)
            msg.setText(self.tr('Repository was Unlinked'))
            msg.setInformativeText(self.tr('You can always connect it again later.'))
            msg.exec_()

            self.repo_changed.emit()
            self.init_repo_stats()
Exemple #15
0
def init_db(qapp, qtbot, tmpdir_factory):
    tmp_db = tmpdir_factory.mktemp('Vorta').join('settings.sqlite')
    mock_db = peewee.SqliteDatabase(str(tmp_db),
                                    pragmas={
                                        'journal_mode': 'wal',
                                    })
    vorta.models.init_db(mock_db)

    default_profile = BackupProfileModel(name='Default')
    default_profile.save()

    new_repo = RepoModel(url='[email protected]:repo')
    new_repo.encryption = 'none'
    new_repo.save()

    default_profile.repo = new_repo.id
    default_profile.dont_run_on_metered_networks = False
    default_profile.save()

    test_archive = ArchiveModel(snapshot_id='99999',
                                name='test-archive',
                                time=dt(2000, 1, 1, 0, 0),
                                repo=1)
    test_archive.save()

    test_archive1 = ArchiveModel(snapshot_id='99998',
                                 name='test-archive1',
                                 time=dt(2000, 1, 1, 0, 0),
                                 repo=1)
    test_archive1.save()

    source_dir = SourceFileModel(dir='/tmp/another',
                                 repo=new_repo,
                                 dir_size=100,
                                 dir_files_count=18,
                                 path_isdir=True)
    source_dir.save()

    qapp.main_window.deleteLater()
    del qapp.main_window
    qapp.main_window = MainWindow(
        qapp)  # Re-open main window to apply mock data in UI

    yield
    qapp.backup_cancelled_event.emit()
    qtbot.waitUntil(lambda: not vorta.borg.borg_thread.BorgThread.is_running())
    mock_db.close()
Exemple #16
0
def test_create(qapp, borg_json_output, mocker, qtbot):
    main = qapp.main_window
    stdout, stderr = borg_json_output('create')
    popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
    mocker.patch.object(vorta.borg.borg_thread, 'Popen', return_value=popen_result)

    qtbot.mouseClick(main.createStartBtn, QtCore.Qt.LeftButton)
    qtbot.waitUntil(lambda: main.progressText.text().startswith('Backup finished.'), timeout=3000)
    qtbot.waitUntil(lambda: main.createStartBtn.isEnabled(), timeout=3000)
    assert EventLogModel.select().count() == 1
    assert ArchiveModel.select().count() == 3
    assert RepoModel.get(id=1).unique_size == 15520474
    assert main.createStartBtn.isEnabled()
    assert main.archiveTab.archiveTable.rowCount() == 3
    assert main.scheduleTab.logTableWidget.rowCount() == 1
Exemple #17
0
def test_repo_list(app, qtbot, mocker, borg_json_output):
    main = app.main_window
    tab = main.archiveTab
    main.tabWidget.setCurrentIndex(3)
    tab.list_action()
    assert not tab.checkButton.isEnabled()

    stdout, stderr = borg_json_output('list')
    popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
    mocker.patch.object(vorta.borg.borg_thread, 'Popen', return_value=popen_result)

    qtbot.waitUntil(lambda: main.createProgressText.text() == 'Refreshing archives done.', timeout=3000)
    assert ArchiveModel.select().count() == 6
    assert main.createProgressText.text() == 'Refreshing archives done.'
    assert tab.checkButton.isEnabled()
Exemple #18
0
    def rename_action(self):
        profile = self.profile()
        params = BorgRenameThread.prepare(profile)
        if not params['ok']:
            self._set_status(params['message'])
            return

        archive_name = self.selected_archive_name()
        if archive_name is not None:
            new_name, finished = QInputDialog.getText(
                self,
                self.tr("Change name"),
                self.tr("New archive name:"),
                text=archive_name)

            if not finished:
                return

            if not new_name:
                self._set_status(self.tr('Archive name cannot be blank.'))
                return

            new_name_exists = ArchiveModel.get_or_none(name=new_name,
                                                       repo=profile.repo)
            if new_name_exists is not None:
                self._set_status(
                    self.tr('An archive with this name already exists.'))
                return

            params['cmd'][-1] += f'::{archive_name}'
            params['cmd'].append(new_name)

            thread = BorgRenameThread(params['cmd'], params, parent=self)
            thread.updated.connect(self._set_status)
            thread.result.connect(self.rename_result)
            self._toggle_all_buttons(False)
            thread.start()
        else:
            self._set_status(self.tr("No archive selected"))
Exemple #19
0
def test_archive_delete(qapp, qtbot, mocker, borg_json_output):
    main = qapp.main_window
    tab = main.archiveTab
    main.tabWidget.setCurrentIndex(3)

    tab.populate_from_profile()
    qtbot.waitUntil(lambda: tab.archiveTable.rowCount() == 2)

    tab.archiveTable.selectRow(0)
    stdout, stderr = borg_json_output('delete')
    popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
    mocker.patch.object(vorta.borg.borg_thread,
                        'Popen',
                        return_value=popen_result)
    mocker.patch.object(vorta.views.archive_tab.ArchiveTab, 'confirm_dialog',
                        lambda x, y, z: True)
    qtbot.mouseClick(tab.deleteButton, QtCore.Qt.LeftButton)

    qtbot.waitUntil(lambda: main.progressText.text() == 'Archive deleted.',
                    timeout=3000)
    assert ArchiveModel.select().count() == 1
    assert tab.archiveTable.rowCount() == 1