vorta/tests/test_archives.py

237 lines
9.1 KiB
Python
Raw Normal View History

import psutil
from collections import namedtuple
import pytest
from PyQt5 import QtCore
from vorta.models import BackupProfileModel, ArchiveModel
2018-11-06 06:47:04 +00:00
import vorta.borg
import vorta.views.archive_tab
import vorta.utils
class MockFileDialog:
def open(self, func):
func()
def selectedFiles(self):
return ['/tmp']
2018-11-06 06:47:04 +00:00
def test_prune_intervals(qapp, qtbot):
2018-11-06 06:47:04 +00:00
prune_intervals = ['hour', 'day', 'week', 'month', 'year']
main = qapp.main_window
tab = main.archiveTab
2018-11-06 06:47:04 +00:00
profile = BackupProfileModel.get(id=1)
for i in prune_intervals:
getattr(tab, f'prune_{i}').setValue(9)
tab.save_prune_setting(None)
profile = profile.refresh()
assert getattr(profile, f'prune_{i}') == 9
def test_repo_list(qapp, qtbot, mocker, borg_json_output):
main = qapp.main_window
tab = main.archiveTab
2018-11-06 06:47:04 +00:00
stdout, stderr = borg_json_output('list')
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
2018-11-06 06:47:04 +00:00
mocker.patch.object(vorta.borg.borg_thread, 'Popen', return_value=popen_result)
main.tabWidget.setCurrentIndex(3)
tab.list_action()
qtbot.waitUntil(lambda: not tab.checkButton.isEnabled(), **pytest._wait_defaults)
assert not tab.checkButton.isEnabled()
qtbot.waitUntil(lambda: main.progressText.text() == 'Refreshing archives done.', **pytest._wait_defaults)
assert ArchiveModel.select().count() == 6
assert main.progressText.text() == 'Refreshing archives done.'
2018-11-06 06:47:04 +00:00
assert tab.checkButton.isEnabled()
def test_repo_prune(qapp, qtbot, mocker, borg_json_output):
main = qapp.main_window
tab = main.archiveTab
main.tabWidget.setCurrentIndex(3)
tab.populate_from_profile()
stdout, stderr = borg_json_output('prune')
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
mocker.patch.object(vorta.borg.borg_thread, 'Popen', return_value=popen_result)
qtbot.mouseClick(tab.pruneButton, QtCore.Qt.LeftButton)
qtbot.waitUntil(lambda: main.progressText.text().startswith('Refreshing archives done.'), **pytest._wait_defaults)
def test_check(qapp, mocker, borg_json_output, qtbot):
main = qapp.main_window
tab = main.archiveTab
main.tabWidget.setCurrentIndex(3)
tab.populate_from_profile()
stdout, stderr = borg_json_output('check')
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
mocker.patch.object(vorta.borg.borg_thread, 'Popen', return_value=popen_result)
qtbot.mouseClick(tab.checkButton, QtCore.Qt.LeftButton)
success_text = 'INFO: Archive consistency check complete'
qtbot.waitUntil(lambda: main.logText.text().startswith(success_text), **pytest._wait_defaults)
def test_archive_mount(qapp, qtbot, mocker, borg_json_output, monkeypatch, choose_file_dialog):
def psutil_disk_partitions(**kwargs):
DiskPartitions = namedtuple('DiskPartitions', ['device', 'mountpoint'])
return [DiskPartitions('borgfs', '/tmp')]
monkeypatch.setattr(
psutil, "disk_partitions", psutil_disk_partitions
)
main = qapp.main_window
tab = main.archiveTab
main.tabWidget.setCurrentIndex(3)
tab.populate_from_profile()
tab.archiveTable.selectRow(0)
stdout, stderr = borg_json_output('prune') # TODO: fully mock mount command?
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
mocker.patch.object(vorta.borg.borg_thread, 'Popen', return_value=popen_result)
monkeypatch.setattr(
vorta.views.archive_tab, "choose_file_dialog", choose_file_dialog
)
tab.mount_action()
qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Mounted'), **pytest._wait_defaults)
tab.umount_action()
qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Un-mounted successfully.'), **pytest._wait_defaults)
def test_archive_extract(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('list_archive')
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
mocker.patch.object(vorta.borg.borg_thread, 'Popen', return_value=popen_result)
tab.list_archive_action()
qtbot.waitUntil(lambda: hasattr(tab, '_window'), **pytest._wait_defaults)
# qtbot.waitUntil(lambda: tab._window == qapp.activeWindow(), **pytest._wait_defaults)
assert tab._window.treeView.model().rootItem.childItems[0].data(0) == 'Users'
tab._window.treeView.model().rootItem.childItems[0].load_children()
assert tab._window.archiveNameLabel.text().startswith('test-archive, 2000')
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)
tab.delete_action()
qtbot.waitUntil(lambda: main.progressText.text() == 'Archive deleted.', **pytest._wait_defaults)
assert ArchiveModel.select().count() == 1
assert tab.archiveTable.rowCount() == 1
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)
def test_archive_diff(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)
stdout, stderr = borg_json_output('diff_archives')
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
mocker.patch.object(vorta.borg.borg_thread, 'Popen', return_value=popen_result)
tab.diff_action()
qtbot.waitUntil(lambda: hasattr(tab, '_window'), **pytest._wait_defaults)
tab._window.archiveTable.selectRow(0)
tab._window.archiveTable.selectRow(1)
tab._window.diff_action()
qtbot.waitUntil(lambda: hasattr(tab, '_resultwindow'), **pytest._wait_defaults)
assert tab._resultwindow.treeView.model().rootItem.childItems[0].data(0) == 'test'
tab._resultwindow.treeView.model().rootItem.childItems[0].load_children()
assert tab._resultwindow.archiveNameLabel_1.text() == 'test-archive'
tab._resultwindow.accept()
@pytest.mark.parametrize('line, expected', [
('changed link some/changed/link',
(0, 'changed', 'link', 'some/changed')),
(' +77.8 kB -77.8 kB some/changed/file',
(77800, 'modified', 'file', 'some/changed')),
(' +77.8 kB -77.8 kB [-rw-rw-rw- -> -rw-r--r--] some/changed/file',
(77800, '[-rw-rw-rw- -> -rw-r--r--]', 'file', 'some/changed')),
('[-rw-rw-rw- -> -rw-r--r--] some/changed/file',
(0, '[-rw-rw-rw- -> -rw-r--r--]', 'file', 'some/changed')),
('added directory some/changed/dir',
(0, 'added', 'dir', 'some/changed')),
('removed directory some/changed/dir',
(0, 'removed', 'dir', 'some/changed')),
# Example from https://github.com/borgbase/vorta/issues/521
('[user:user -> nfsnobody:nfsnobody] home/user/arrays/test.txt',
(0, 'modified', 'test.txt', 'home/user/arrays')),
# Very short owner change, to check stripping whitespace from file path
('[a:a -> b:b] home/user/arrays/test.txt',
(0, 'modified', 'test.txt', 'home/user/arrays')),
# All file-related changes in one test
(' +77.8 kB -77.8 kB [user:user -> nfsnobody:nfsnobody] [-rw-rw-rw- -> -rw-r--r--] home/user/arrays/test.txt',
(77800, '[-rw-rw-rw- -> -rw-r--r--]', 'test.txt', 'home/user/arrays')),
])
def test_archive_diff_parser(line, expected):
files_with_attributes, nested_file_list = vorta.views.diff_result.parse_diff_lines([line])
assert files_with_attributes == [expected]