2018-11-30 00:40:18 +00:00
|
|
|
from collections import namedtuple
|
2023-05-01 08:28:11 +00:00
|
|
|
|
2022-03-24 06:27:07 +00:00
|
|
|
import psutil
|
2020-06-16 16:21:24 +00:00
|
|
|
import pytest
|
2018-11-06 06:47:04 +00:00
|
|
|
import vorta.borg
|
2018-11-30 00:40:18 +00:00
|
|
|
import vorta.utils
|
2022-03-24 06:27:07 +00:00
|
|
|
import vorta.views.archive_tab
|
2023-05-01 08:28:11 +00:00
|
|
|
from PyQt6 import QtCore
|
2022-03-24 06:27:07 +00:00
|
|
|
from vorta.store.models import ArchiveModel, BackupProfileModel
|
2018-11-30 00:40:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
class MockFileDialog:
|
|
|
|
def open(self, func):
|
|
|
|
func()
|
|
|
|
|
|
|
|
def selectedFiles(self):
|
|
|
|
return ['/tmp']
|
2018-11-06 06:47:04 +00:00
|
|
|
|
|
|
|
|
2020-03-03 05:19:36 +00:00
|
|
|
def test_prune_intervals(qapp, qtbot):
|
2018-11-06 06:47:04 +00:00
|
|
|
prune_intervals = ['hour', 'day', 'week', 'month', 'year']
|
2020-03-03 05:19:36 +00:00
|
|
|
main = qapp.main_window
|
2018-11-22 01:18:12 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
|
2023-08-17 10:05:52 +00:00
|
|
|
def test_repo_list(qapp, qtbot, mocker, borg_json_output, archive_env):
|
|
|
|
main, tab = archive_env
|
2018-11-06 06:47:04 +00:00
|
|
|
|
|
|
|
stdout, stderr = borg_json_output('list')
|
2018-11-22 00:43:37 +00:00
|
|
|
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
2021-10-04 11:31:41 +00:00
|
|
|
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
2018-11-06 06:47:04 +00:00
|
|
|
|
2022-03-24 06:27:07 +00:00
|
|
|
tab.refresh_archive_list()
|
|
|
|
qtbot.waitUntil(lambda: not tab.bCheck.isEnabled(), **pytest._wait_defaults)
|
|
|
|
assert not tab.bCheck.isEnabled()
|
2020-03-03 05:19:36 +00:00
|
|
|
|
2023-03-22 11:16:46 +00:00
|
|
|
qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults)
|
2018-11-22 01:35:59 +00:00
|
|
|
assert ArchiveModel.select().count() == 6
|
2023-03-22 11:16:46 +00:00
|
|
|
assert 'Refreshing archives done.' in main.progressText.text()
|
2022-03-24 06:27:07 +00:00
|
|
|
assert tab.bCheck.isEnabled()
|
2018-11-30 00:40:18 +00:00
|
|
|
|
|
|
|
|
2023-08-17 10:05:52 +00:00
|
|
|
def test_repo_prune(qapp, qtbot, mocker, borg_json_output, archive_env):
|
|
|
|
main, tab = archive_env
|
|
|
|
|
2018-11-30 00:40:18 +00:00
|
|
|
stdout, stderr = borg_json_output('prune')
|
|
|
|
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
2021-10-04 11:31:41 +00:00
|
|
|
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
2018-11-30 00:40:18 +00:00
|
|
|
|
2023-04-17 10:17:01 +00:00
|
|
|
qtbot.mouseClick(tab.bPrune, QtCore.Qt.MouseButton.LeftButton)
|
2018-11-30 00:40:18 +00:00
|
|
|
|
2023-03-22 11:16:46 +00:00
|
|
|
qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults)
|
2018-11-30 00:40:18 +00:00
|
|
|
|
|
|
|
|
2023-08-17 10:05:52 +00:00
|
|
|
def test_repo_compact(qapp, qtbot, mocker, borg_json_output, archive_env):
|
2022-02-21 17:23:56 +00:00
|
|
|
vorta.utils.borg_compat.version = '1.2.0'
|
2023-08-17 10:05:52 +00:00
|
|
|
main, tab = archive_env
|
|
|
|
|
2022-02-21 17:23:56 +00:00
|
|
|
stdout, stderr = borg_json_output('compact')
|
|
|
|
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
|
|
|
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
|
|
|
|
2023-04-17 10:17:01 +00:00
|
|
|
qtbot.mouseClick(tab.compactButton, QtCore.Qt.MouseButton.LeftButton)
|
2022-02-21 17:23:56 +00:00
|
|
|
|
|
|
|
qtbot.waitUntil(
|
2022-08-15 17:02:40 +00:00
|
|
|
lambda: 'compaction freed about 56.00 kB repository space' in main.logText.text(), **pytest._wait_defaults
|
2022-02-21 17:23:56 +00:00
|
|
|
)
|
|
|
|
vorta.utils.borg_compat.version = '1.1.0'
|
|
|
|
|
|
|
|
|
2023-08-17 10:05:52 +00:00
|
|
|
def test_check(qapp, mocker, borg_json_output, qtbot, archive_env):
|
|
|
|
main, tab = archive_env
|
2018-11-30 00:40:18 +00:00
|
|
|
|
|
|
|
stdout, stderr = borg_json_output('check')
|
|
|
|
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
2021-10-04 11:31:41 +00:00
|
|
|
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
2018-11-30 00:40:18 +00:00
|
|
|
|
2023-04-17 10:17:01 +00:00
|
|
|
qtbot.mouseClick(tab.bCheck, QtCore.Qt.MouseButton.LeftButton)
|
2018-11-30 00:40:18 +00:00
|
|
|
success_text = 'INFO: Archive consistency check complete'
|
2023-03-22 11:16:46 +00:00
|
|
|
qtbot.waitUntil(lambda: success_text in main.logText.text(), **pytest._wait_defaults)
|
2018-11-30 00:40:18 +00:00
|
|
|
|
|
|
|
|
2023-08-17 10:05:52 +00:00
|
|
|
def test_mount(qapp, qtbot, mocker, borg_json_output, monkeypatch, choose_file_dialog, archive_env):
|
2018-11-30 00:40:18 +00:00
|
|
|
def psutil_disk_partitions(**kwargs):
|
|
|
|
DiskPartitions = namedtuple('DiskPartitions', ['device', 'mountpoint'])
|
|
|
|
return [DiskPartitions('borgfs', '/tmp')]
|
|
|
|
|
2022-08-15 17:02:40 +00:00
|
|
|
monkeypatch.setattr(psutil, "disk_partitions", psutil_disk_partitions)
|
2023-08-17 10:05:52 +00:00
|
|
|
main, tab = archive_env
|
2018-11-30 00:40:18 +00:00
|
|
|
tab.archiveTable.selectRow(0)
|
|
|
|
|
2021-02-18 01:44:10 +00:00
|
|
|
stdout, stderr = borg_json_output('prune') # TODO: fully mock mount command?
|
2018-11-30 00:40:18 +00:00
|
|
|
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
2021-10-04 11:31:41 +00:00
|
|
|
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
2018-11-30 00:40:18 +00:00
|
|
|
|
2022-08-15 17:02:40 +00:00
|
|
|
monkeypatch.setattr(vorta.views.archive_tab, "choose_file_dialog", choose_file_dialog)
|
2018-11-30 00:40:18 +00:00
|
|
|
|
2022-04-16 05:30:31 +00:00
|
|
|
tab.bmountarchive_clicked()
|
2021-02-17 02:14:58 +00:00
|
|
|
qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Mounted'), **pytest._wait_defaults)
|
2018-11-30 00:40:18 +00:00
|
|
|
|
2022-04-16 05:30:31 +00:00
|
|
|
tab.bmountarchive_clicked()
|
|
|
|
qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Un-mounted successfully.'), **pytest._wait_defaults)
|
|
|
|
|
|
|
|
tab.bmountrepo_clicked()
|
|
|
|
qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Mounted'), **pytest._wait_defaults)
|
|
|
|
|
|
|
|
tab.bmountrepo_clicked()
|
2021-02-17 02:14:58 +00:00
|
|
|
qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Un-mounted successfully.'), **pytest._wait_defaults)
|
2018-11-30 00:40:18 +00:00
|
|
|
|
|
|
|
|
2023-08-17 10:05:52 +00:00
|
|
|
def test_archive_extract(qapp, qtbot, mocker, borg_json_output, archive_env):
|
|
|
|
main, tab = archive_env
|
2018-11-30 00:40:18 +00:00
|
|
|
tab.archiveTable.selectRow(0)
|
|
|
|
stdout, stderr = borg_json_output('list_archive')
|
|
|
|
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
2021-10-04 11:31:41 +00:00
|
|
|
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
2022-03-24 06:27:07 +00:00
|
|
|
tab.extract_action()
|
2018-11-30 00:40:18 +00:00
|
|
|
|
2021-02-17 02:14:58 +00:00
|
|
|
qtbot.waitUntil(lambda: hasattr(tab, '_window'), **pytest._wait_defaults)
|
2018-11-30 00:40:18 +00:00
|
|
|
|
2022-05-07 10:04:35 +00:00
|
|
|
model = tab._window.model
|
|
|
|
assert model.root.children[0].subpath == 'home'
|
2023-03-22 11:16:46 +00:00
|
|
|
assert 'test-archive, 2000' in tab._window.archiveNameLabel.text()
|
2020-03-23 06:20:09 +00:00
|
|
|
|
|
|
|
|
2023-08-17 10:05:52 +00:00
|
|
|
def test_archive_delete(qapp, qtbot, mocker, borg_json_output, archive_env):
|
|
|
|
main, tab = archive_env
|
2020-03-23 06:20:09 +00:00
|
|
|
|
2020-11-20 00:46:09 +00:00
|
|
|
tab.archiveTable.selectRow(0)
|
|
|
|
stdout, stderr = borg_json_output('delete')
|
|
|
|
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
2021-10-04 11:31:41 +00:00
|
|
|
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
2020-11-20 00:46:09 +00:00
|
|
|
mocker.patch.object(vorta.views.archive_tab.ArchiveTab, 'confirm_dialog', lambda x, y, z: True)
|
2021-02-18 01:44:10 +00:00
|
|
|
tab.delete_action()
|
2023-03-22 11:16:46 +00:00
|
|
|
qtbot.waitUntil(lambda: 'Archive deleted.' in main.progressText.text(), **pytest._wait_defaults)
|
2020-11-20 00:46:09 +00:00
|
|
|
assert ArchiveModel.select().count() == 1
|
|
|
|
assert tab.archiveTable.rowCount() == 1
|
|
|
|
|
|
|
|
|
2023-08-17 10:05:52 +00:00
|
|
|
def test_archive_copy(qapp, qtbot, monkeypatch, mocker, archive_env):
|
|
|
|
main, tab = archive_env
|
|
|
|
|
|
|
|
# mock the clipboard to ensure no changes are made to it during testing
|
|
|
|
mocker.patch.object(qapp.clipboard(), "setMimeData")
|
|
|
|
clipboard_spy = mocker.spy(qapp.clipboard(), "setMimeData")
|
|
|
|
|
|
|
|
# test 'archive_copy()' by passing it an index to copy
|
|
|
|
index = tab.archiveTable.model().index(0, 0)
|
|
|
|
tab.archive_copy(index)
|
|
|
|
assert clipboard_spy.call_count == 1
|
|
|
|
actual_data = clipboard_spy.call_args[0][0] # retrieves the QMimeData() object used in method call
|
|
|
|
assert actual_data.text() == "test-archive"
|
|
|
|
|
|
|
|
# test 'archive_copy()' by selecting a row to copy
|
|
|
|
tab.archiveTable.selectRow(1)
|
|
|
|
tab.archive_copy()
|
|
|
|
assert clipboard_spy.call_count == 2
|
|
|
|
actual_data = clipboard_spy.call_args[0][0] # retrieves the QMimeData() object used in method call
|
|
|
|
assert actual_data.text() == "test-archive1"
|
|
|
|
|
|
|
|
|
|
|
|
def test_refresh_archive_info(qapp, qtbot, mocker, borg_json_output, archive_env):
|
|
|
|
main, tab = archive_env
|
|
|
|
tab.archiveTable.selectRow(0)
|
|
|
|
stdout, stderr = borg_json_output('info')
|
|
|
|
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
|
|
|
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
|
|
|
|
|
|
|
with qtbot.waitSignal(tab.bRefreshArchive.clicked, timeout=5000):
|
|
|
|
qtbot.mouseClick(tab.bRefreshArchive, QtCore.Qt.MouseButton.LeftButton)
|
|
|
|
|
|
|
|
qtbot.waitUntil(lambda: tab.mountErrors.text() == 'Refreshed archives.', **pytest._wait_defaults)
|
|
|
|
|
2021-02-18 01:44:10 +00:00
|
|
|
|
2023-08-17 10:05:52 +00:00
|
|
|
def test_archive_rename(qapp, qtbot, mocker, borg_json_output, archive_env):
|
|
|
|
main, tab = archive_env
|
2021-02-18 01:44:10 +00:00
|
|
|
|
|
|
|
tab.archiveTable.selectRow(0)
|
|
|
|
new_archive_name = 'idf89d8f9d8fd98'
|
|
|
|
stdout, stderr = borg_json_output('rename')
|
|
|
|
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
2021-10-04 11:31:41 +00:00
|
|
|
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
2021-02-18 01:44:10 +00:00
|
|
|
|
2023-08-15 11:38:51 +00:00
|
|
|
pos = tab.archiveTable.visualRect(tab.archiveTable.model().index(0, 4)).center()
|
|
|
|
qtbot.mouseClick(tab.archiveTable.viewport(), QtCore.Qt.MouseButton.LeftButton, pos=pos)
|
|
|
|
qtbot.mouseDClick(tab.archiveTable.viewport(), QtCore.Qt.MouseButton.LeftButton, pos=pos)
|
|
|
|
qtbot.keyClicks(tab.archiveTable.viewport().focusWidget(), new_archive_name)
|
|
|
|
qtbot.keyClick(tab.archiveTable.viewport().focusWidget(), QtCore.Qt.Key.Key_Return)
|
2021-02-18 01:44:10 +00:00
|
|
|
|
2023-08-15 11:38:51 +00:00
|
|
|
# Successful rename case
|
|
|
|
qtbot.waitUntil(lambda: tab.archiveTable.model().index(0, 4).data() == new_archive_name, **pytest._wait_defaults)
|