From 23ccbde4ff176ce9cb32f1b6524793b3f256c3a2 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 20 May 2023 15:48:35 -0400 Subject: [PATCH 01/69] Initial nox configuration file Signed-off-by: Chirag Aggarwal --- noxfile.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 noxfile.py diff --git a/noxfile.py b/noxfile.py new file mode 100644 index 000000000..d937cdc1d --- /dev/null +++ b/noxfile.py @@ -0,0 +1,26 @@ +import re +import nox + +@nox.session +@nox.parametrize("borgbackup", ["2.0.0b5", "2.0.0b4"]) +def run_tests(session, borgbackup): + # install borgbackup + session.install(f"borgbackup=={borgbackup}") + + # install dependencies + session.install("-r", "requirements.d/dev.txt") + session.install("-e", ".") + + # check versions + cli_version = session.run("borg", "--version", silent=True).strip() + cli_version = re.search(r"borg (\S+)", cli_version).group(1) + python_version = session.run("python", "-c", "import borg; print(borg.__version__)", silent=True).strip() + + session.log(f"CLI version: {cli_version}") + session.log(f"Python version: {python_version}") + + assert cli_version == borgbackup + assert python_version == borgbackup + + # run tests + session.run("pytest") \ No newline at end of file From 70a9db9da53adb5a98748e84ad17dc8da8d5bf87 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 20 May 2023 15:57:43 -0400 Subject: [PATCH 02/69] Formatting Signed-off-by: Chirag Aggarwal --- noxfile.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/noxfile.py b/noxfile.py index d937cdc1d..9cd4f107f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,6 +1,8 @@ import re + import nox + @nox.session @nox.parametrize("borgbackup", ["2.0.0b5", "2.0.0b4"]) def run_tests(session, borgbackup): @@ -18,9 +20,9 @@ def run_tests(session, borgbackup): session.log(f"CLI version: {cli_version}") session.log(f"Python version: {python_version}") - + assert cli_version == borgbackup assert python_version == borgbackup # run tests - session.run("pytest") \ No newline at end of file + session.run("pytest") From 2a46274f6d15328bf7e9dd522521f5077421ec68 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 24 May 2023 19:56:12 -0400 Subject: [PATCH 03/69] Added several tests for test_archives Signed-off-by: Chirag Aggarwal --- noxfile.py | 5 +- .../__init__.py} | 0 tests/integration/conftest.py | 176 ++++++++++++++++++ tests/integration/test_archives.py | 121 ++++++++++++ .../__init__.py} | 0 .../borg_json_output/check_stderr.json | 0 .../borg_json_output/check_stdout.json | 0 .../borg_json_output/compact_stderr.json | 0 .../borg_json_output/compact_stdout.json} | 0 .../create_break_stderr.json} | 0 .../create_break_stdout.json} | 0 .../borg_json_output/create_lock_stderr.json | 0 .../borg_json_output/create_lock_stdout.json} | 0 .../borg_json_output/create_perm_stderr.json | 0 .../borg_json_output/create_perm_stdout.json} | 0 .../borg_json_output/create_stderr.json | 0 .../borg_json_output/create_stdout.json | 0 .../borg_json_output/delete_stderr.json | 0 .../borg_json_output/delete_stdout.json} | 0 .../diff_archives_dict_issue_stderr.json} | 0 .../diff_archives_dict_issue_stdout.json | 0 .../diff_archives_stderr.json} | 0 .../diff_archives_stdout.json | 0 .../borg_json_output/info_stderr.json | 0 .../borg_json_output/info_stdout.json | 0 .../borg_json_output/list_archive_stderr.json | 0 .../borg_json_output/list_archive_stdout.json | 0 .../borg_json_output/list_stderr.json | 0 .../borg_json_output/list_stdout.json | 0 .../borg_json_output/prune_stderr.json | 0 .../borg_json_output/prune_stdout.json | 0 .../unit/borg_json_output/rename_stderr.json | 0 .../unit/borg_json_output/rename_stdout.json | 0 tests/{ => unit}/conftest.py | 4 +- .../profile_exports/invalid_no_json.json | 0 tests/{ => unit}/profile_exports/valid.json | 0 tests/{ => unit}/test_archives.py | 0 tests/{ => unit}/test_borg.py | 0 tests/{ => unit}/test_create.py | 0 tests/{ => unit}/test_diff.py | 0 tests/{ => unit}/test_extract.py | 0 tests/{ => unit}/test_import_export.py | 0 tests/{ => unit}/test_lock.py | 0 tests/{ => unit}/test_misc.py | 0 tests/{ => unit}/test_notifications.py | 0 tests/{ => unit}/test_profile.py | 0 tests/{ => unit}/test_repo.py | 0 tests/{ => unit}/test_schedule.py | 0 tests/{ => unit}/test_scheduler.py | 0 tests/{ => unit}/test_source.py | 0 tests/{ => unit}/test_treemodel.py | 0 tests/{ => unit}/test_utils.py | 0 52 files changed, 302 insertions(+), 4 deletions(-) rename tests/{borg_json_output/compact_stdout.json => integration/__init__.py} (100%) create mode 100644 tests/integration/conftest.py create mode 100644 tests/integration/test_archives.py rename tests/{borg_json_output/create_break_stderr.json => unit/__init__.py} (100%) rename tests/{ => unit}/borg_json_output/check_stderr.json (100%) rename tests/{ => unit}/borg_json_output/check_stdout.json (100%) rename tests/{ => unit}/borg_json_output/compact_stderr.json (100%) rename tests/{borg_json_output/create_break_stdout.json => unit/borg_json_output/compact_stdout.json} (100%) rename tests/{borg_json_output/create_lock_stdout.json => unit/borg_json_output/create_break_stderr.json} (100%) rename tests/{borg_json_output/create_perm_stdout.json => unit/borg_json_output/create_break_stdout.json} (100%) rename tests/{ => unit}/borg_json_output/create_lock_stderr.json (100%) rename tests/{borg_json_output/delete_stdout.json => unit/borg_json_output/create_lock_stdout.json} (100%) rename tests/{ => unit}/borg_json_output/create_perm_stderr.json (100%) rename tests/{borg_json_output/diff_archives_dict_issue_stderr.json => unit/borg_json_output/create_perm_stdout.json} (100%) rename tests/{ => unit}/borg_json_output/create_stderr.json (100%) rename tests/{ => unit}/borg_json_output/create_stdout.json (100%) rename tests/{ => unit}/borg_json_output/delete_stderr.json (100%) rename tests/{borg_json_output/diff_archives_stderr.json => unit/borg_json_output/delete_stdout.json} (100%) rename tests/{borg_json_output/rename_stderr.json => unit/borg_json_output/diff_archives_dict_issue_stderr.json} (100%) rename tests/{ => unit}/borg_json_output/diff_archives_dict_issue_stdout.json (100%) rename tests/{borg_json_output/rename_stdout.json => unit/borg_json_output/diff_archives_stderr.json} (100%) rename tests/{ => unit}/borg_json_output/diff_archives_stdout.json (100%) rename tests/{ => unit}/borg_json_output/info_stderr.json (100%) rename tests/{ => unit}/borg_json_output/info_stdout.json (100%) rename tests/{ => unit}/borg_json_output/list_archive_stderr.json (100%) rename tests/{ => unit}/borg_json_output/list_archive_stdout.json (100%) rename tests/{ => unit}/borg_json_output/list_stderr.json (100%) rename tests/{ => unit}/borg_json_output/list_stdout.json (100%) rename tests/{ => unit}/borg_json_output/prune_stderr.json (100%) rename tests/{ => unit}/borg_json_output/prune_stdout.json (100%) create mode 100644 tests/unit/borg_json_output/rename_stderr.json create mode 100644 tests/unit/borg_json_output/rename_stdout.json rename tests/{ => unit}/conftest.py (95%) rename tests/{ => unit}/profile_exports/invalid_no_json.json (100%) rename tests/{ => unit}/profile_exports/valid.json (100%) rename tests/{ => unit}/test_archives.py (100%) rename tests/{ => unit}/test_borg.py (100%) rename tests/{ => unit}/test_create.py (100%) rename tests/{ => unit}/test_diff.py (100%) rename tests/{ => unit}/test_extract.py (100%) rename tests/{ => unit}/test_import_export.py (100%) rename tests/{ => unit}/test_lock.py (100%) rename tests/{ => unit}/test_misc.py (100%) rename tests/{ => unit}/test_notifications.py (100%) rename tests/{ => unit}/test_profile.py (100%) rename tests/{ => unit}/test_repo.py (100%) rename tests/{ => unit}/test_schedule.py (100%) rename tests/{ => unit}/test_scheduler.py (100%) rename tests/{ => unit}/test_source.py (100%) rename tests/{ => unit}/test_treemodel.py (100%) rename tests/{ => unit}/test_utils.py (100%) diff --git a/noxfile.py b/noxfile.py index 9cd4f107f..9a4696542 100644 --- a/noxfile.py +++ b/noxfile.py @@ -4,7 +4,8 @@ @nox.session -@nox.parametrize("borgbackup", ["2.0.0b5", "2.0.0b4"]) +# @nox.parametrize("borgbackup", ["2.0.0b5", "2.0.0b4"]) +@nox.parametrize("borgbackup", ["1.2.4"]) def run_tests(session, borgbackup): # install borgbackup session.install(f"borgbackup=={borgbackup}") @@ -25,4 +26,4 @@ def run_tests(session, borgbackup): assert python_version == borgbackup # run tests - session.run("pytest") + session.run("pytest", *session.posargs) diff --git a/tests/borg_json_output/compact_stdout.json b/tests/integration/__init__.py similarity index 100% rename from tests/borg_json_output/compact_stdout.json rename to tests/integration/__init__.py diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py new file mode 100644 index 000000000..6d220e192 --- /dev/null +++ b/tests/integration/conftest.py @@ -0,0 +1,176 @@ +import atexit +import os +import shutil +import subprocess +import sys + +import pytest +import vorta +import vorta.application +import vorta.borg.jobs_manager +from peewee import SqliteDatabase +from vorta.store.models import ( + ArchiveModel, + BackupProfileModel, + EventLogModel, + RepoModel, + RepoPassword, + SchemaVersion, + SettingsModel, + SourceFileModel, + WifiSettingModel, +) +from vorta.views.main_window import MainWindow + +models = [ + RepoModel, + RepoPassword, + BackupProfileModel, + SourceFileModel, + SettingsModel, + ArchiveModel, + WifiSettingModel, + EventLogModel, + SchemaVersion, +] + + +def pytest_configure(config): + sys._called_from_test = True + pytest._wait_defaults = {'timeout': 20000} + os.environ['LANG'] = 'en' # Ensure we test an English UI + + +@pytest.fixture(scope='session') +def qapp(tmpdir_factory): + # DB is required to init QApplication. New DB used for every test. + tmp_db = tmpdir_factory.mktemp('Vorta').join('settings.sqlite') + mock_db = SqliteDatabase(str(tmp_db)) + vorta.store.connection.init_db(mock_db) + + # Needs to be disabled before calling VortaApp() + if sys.platform == 'darwin': + cfg = vorta.store.models.SettingsModel.get(key='check_full_disk_access') + cfg.value = False + cfg.save() + + from vorta.application import VortaApp + + qapp = VortaApp([]) # Only init QApplication once to avoid segfaults while testing. + + yield qapp + mock_db.close() + qapp.quit() + + +@pytest.fixture(scope='function', autouse=True) +def create_test_repo(tmpdir_factory): + temp_dir = tmpdir_factory.mktemp('repo') + repo_path = str(temp_dir) + + subprocess.run(['borg', 'init', '--encryption=none', repo_path], check=True) + + # create source files dir + source_files_dir = os.path.join(temp_dir, 'src') + os.mkdir(source_files_dir) + + file_path = os.path.join(source_files_dir, 'file') + with open(file_path, 'w') as f: + f.write('test') + + subprocess.run(['borg', 'create', f'{repo_path}::test-archive', source_files_dir], cwd=temp_dir, check=True) + + dir_path = os.path.join(source_files_dir, 'dir') + os.mkdir(dir_path) + + file_path = os.path.join(dir_path, 'file') + with open(file_path, 'w') as f: + f.write('test') + + subprocess.run(['borg', 'create', f'{repo_path}::test-archive1', source_files_dir], cwd=temp_dir, check=True) + + symlink_path = os.path.join(source_files_dir, 'symlink') + os.symlink(file_path, symlink_path) + + subprocess.run(['borg', 'create', f'{repo_path}::test-archive2', source_files_dir], cwd=temp_dir, check=True) + + # TODO: More file types and more archives required for testing + + def cleanup(): + shutil.rmtree(temp_dir) + + atexit.register(cleanup) + + return repo_path, source_files_dir + + +@pytest.fixture(scope='function', autouse=True) +def init_db(qapp, qtbot, tmpdir_factory, create_test_repo): + tmp_db = tmpdir_factory.mktemp('Vorta').join('settings.sqlite') + mock_db = SqliteDatabase( + str(tmp_db), + pragmas={ + 'journal_mode': 'wal', + }, + ) + vorta.store.connection.init_db(mock_db) + + default_profile = BackupProfileModel(name='Default') + default_profile.save() + + repo_path, source_dir = create_test_repo + + new_repo = RepoModel(url=repo_path) + new_repo.encryption = 'none' + new_repo.save() + + default_profile.repo = new_repo.id + default_profile.dont_run_on_metered_networks = False + default_profile.validation_on = False + default_profile.save() + + source_dir = SourceFileModel(dir=source_dir, repo=new_repo, dir_size=12, dir_files_count=3, 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 + + qapp.scheduler.schedule_changed.disconnect() + + yield + + qapp.jobs_manager.cancel_all_jobs() + qapp.backup_finished_event.disconnect() + qtbot.waitUntil(lambda: not qapp.jobs_manager.is_worker_running(), **pytest._wait_defaults) + mock_db.close() + + +@pytest.fixture +def choose_file_dialog(tmpdir): + class MockFileDialog: + def __init__(self, *args, **kwargs): + pass + + def open(self, func): + func() + + def selectedFiles(self): + return [str(tmpdir)] + + return MockFileDialog + + +@pytest.fixture +def borg_json_output(): + def _read_json(subcommand): + stdout = open(f'tests/borg_json_output/{subcommand}_stdout.json') + stderr = open(f'tests/borg_json_output/{subcommand}_stderr.json') + return stdout, stderr + + return _read_json + + +@pytest.fixture +def rootdir(): + return os.path.dirname(os.path.abspath(__file__)) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py new file mode 100644 index 000000000..a1c71fd3a --- /dev/null +++ b/tests/integration/test_archives.py @@ -0,0 +1,121 @@ +from collections import namedtuple + +import psutil +import pytest +import vorta.borg +import vorta.utils +import vorta.views.archive_tab +from PyQt6 import QtCore +from vorta.store.models import ArchiveModel + + +def test_repo_list(qapp, qtbot): + main = qapp.main_window + tab = main.archiveTab + main.show() + + main.tabWidget.setCurrentIndex(3) + tab.refresh_archive_list() + qtbot.waitUntil(lambda: not tab.bCheck.isEnabled(), **pytest._wait_defaults) + + assert not tab.bCheck.isEnabled() + + qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults) + assert ArchiveModel.select().count() == 3 + qtbot.wait(5000) + assert 'Refreshing archives done.' in main.progressText.text() + assert tab.bCheck.isEnabled() + + +def test_repo_prune(qapp, qtbot): + main = qapp.main_window + main.show() + tab = main.archiveTab + main.tabWidget.setCurrentIndex(3) + tab.populate_from_profile() + + qtbot.mouseClick(tab.bPrune, QtCore.Qt.MouseButton.LeftButton) + + qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults) + + +def test_repo_compact(qapp, qtbot): + main = qapp.main_window + main.show() + tab = main.archiveTab + main.tabWidget.setCurrentIndex(3) + tab.refresh_archive_list() + + qtbot.mouseClick(tab.compactButton, QtCore.Qt.MouseButton.LeftButton) + + qtbot.waitUntil(lambda: 'compaction freed about' in main.logText.text(), **pytest._wait_defaults) + + +def test_check(qapp, qtbot): + main = qapp.main_window + main.show() + tab = main.archiveTab + main.tabWidget.setCurrentIndex(3) + tab.refresh_archive_list() + + qtbot.mouseClick(tab.bCheck, QtCore.Qt.MouseButton.LeftButton) + success_text = 'INFO: Archive consistency check complete' + qtbot.waitUntil(lambda: success_text in main.logText.text(), **pytest._wait_defaults) + + qtbot.wait(4000) + + +# TODO: Fix this test and nox config to support fuse mounts. +@pytest.mark.skip(reason="TODO: Fix this test and nox config to support fuse mounts.") +def test_mount(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): + def psutil_disk_partitions(**kwargs): + DiskPartitions = namedtuple('DiskPartitions', ['device', 'mountpoint']) + return [DiskPartitions('borgfs', str(tmpdir))] + + monkeypatch.setattr(psutil, "disk_partitions", psutil_disk_partitions) + + main = qapp.main_window + tab = main.archiveTab + main.show() + main.tabWidget.setCurrentIndex(3) + tab.refresh_archive_list() + tab.archiveTable.selectRow(0) + + monkeypatch.setattr(vorta.views.archive_tab, "choose_file_dialog", choose_file_dialog) + + tab.bmountarchive_clicked() + qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Mounted'), **pytest._wait_defaults) + + 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() + qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Un-mounted successfully.'), **pytest._wait_defaults) + + +def test_archive_extract(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): + main = qapp.main_window + tab = main.archiveTab + main.show() + main.tabWidget.setCurrentIndex(3) + + tab.refresh_archive_list() + qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) + + tab.archiveTable.selectRow(2) + tab.extract_action() + + qtbot.waitUntil(lambda: hasattr(tab, '_window'), **pytest._wait_defaults) + + # Select all files + tree_view = tab._window.treeView.model() + tree_view.setData(tree_view.index(0, 0), QtCore.Qt.CheckState.Checked, QtCore.Qt.ItemDataRole.CheckStateRole) + monkeypatch.setattr(vorta.views.archive_tab, "choose_file_dialog", choose_file_dialog) + qtbot.mouseClick(tab._window.extractButton, QtCore.Qt.MouseButton.LeftButton) + + qtbot.waitUntil(lambda: 'Restored files from archive.' in main.progressText.text(), **pytest._wait_defaults) + + assert [item.basename for item in tmpdir.listdir()] == ['tmp'] diff --git a/tests/borg_json_output/create_break_stderr.json b/tests/unit/__init__.py similarity index 100% rename from tests/borg_json_output/create_break_stderr.json rename to tests/unit/__init__.py diff --git a/tests/borg_json_output/check_stderr.json b/tests/unit/borg_json_output/check_stderr.json similarity index 100% rename from tests/borg_json_output/check_stderr.json rename to tests/unit/borg_json_output/check_stderr.json diff --git a/tests/borg_json_output/check_stdout.json b/tests/unit/borg_json_output/check_stdout.json similarity index 100% rename from tests/borg_json_output/check_stdout.json rename to tests/unit/borg_json_output/check_stdout.json diff --git a/tests/borg_json_output/compact_stderr.json b/tests/unit/borg_json_output/compact_stderr.json similarity index 100% rename from tests/borg_json_output/compact_stderr.json rename to tests/unit/borg_json_output/compact_stderr.json diff --git a/tests/borg_json_output/create_break_stdout.json b/tests/unit/borg_json_output/compact_stdout.json similarity index 100% rename from tests/borg_json_output/create_break_stdout.json rename to tests/unit/borg_json_output/compact_stdout.json diff --git a/tests/borg_json_output/create_lock_stdout.json b/tests/unit/borg_json_output/create_break_stderr.json similarity index 100% rename from tests/borg_json_output/create_lock_stdout.json rename to tests/unit/borg_json_output/create_break_stderr.json diff --git a/tests/borg_json_output/create_perm_stdout.json b/tests/unit/borg_json_output/create_break_stdout.json similarity index 100% rename from tests/borg_json_output/create_perm_stdout.json rename to tests/unit/borg_json_output/create_break_stdout.json diff --git a/tests/borg_json_output/create_lock_stderr.json b/tests/unit/borg_json_output/create_lock_stderr.json similarity index 100% rename from tests/borg_json_output/create_lock_stderr.json rename to tests/unit/borg_json_output/create_lock_stderr.json diff --git a/tests/borg_json_output/delete_stdout.json b/tests/unit/borg_json_output/create_lock_stdout.json similarity index 100% rename from tests/borg_json_output/delete_stdout.json rename to tests/unit/borg_json_output/create_lock_stdout.json diff --git a/tests/borg_json_output/create_perm_stderr.json b/tests/unit/borg_json_output/create_perm_stderr.json similarity index 100% rename from tests/borg_json_output/create_perm_stderr.json rename to tests/unit/borg_json_output/create_perm_stderr.json diff --git a/tests/borg_json_output/diff_archives_dict_issue_stderr.json b/tests/unit/borg_json_output/create_perm_stdout.json similarity index 100% rename from tests/borg_json_output/diff_archives_dict_issue_stderr.json rename to tests/unit/borg_json_output/create_perm_stdout.json diff --git a/tests/borg_json_output/create_stderr.json b/tests/unit/borg_json_output/create_stderr.json similarity index 100% rename from tests/borg_json_output/create_stderr.json rename to tests/unit/borg_json_output/create_stderr.json diff --git a/tests/borg_json_output/create_stdout.json b/tests/unit/borg_json_output/create_stdout.json similarity index 100% rename from tests/borg_json_output/create_stdout.json rename to tests/unit/borg_json_output/create_stdout.json diff --git a/tests/borg_json_output/delete_stderr.json b/tests/unit/borg_json_output/delete_stderr.json similarity index 100% rename from tests/borg_json_output/delete_stderr.json rename to tests/unit/borg_json_output/delete_stderr.json diff --git a/tests/borg_json_output/diff_archives_stderr.json b/tests/unit/borg_json_output/delete_stdout.json similarity index 100% rename from tests/borg_json_output/diff_archives_stderr.json rename to tests/unit/borg_json_output/delete_stdout.json diff --git a/tests/borg_json_output/rename_stderr.json b/tests/unit/borg_json_output/diff_archives_dict_issue_stderr.json similarity index 100% rename from tests/borg_json_output/rename_stderr.json rename to tests/unit/borg_json_output/diff_archives_dict_issue_stderr.json diff --git a/tests/borg_json_output/diff_archives_dict_issue_stdout.json b/tests/unit/borg_json_output/diff_archives_dict_issue_stdout.json similarity index 100% rename from tests/borg_json_output/diff_archives_dict_issue_stdout.json rename to tests/unit/borg_json_output/diff_archives_dict_issue_stdout.json diff --git a/tests/borg_json_output/rename_stdout.json b/tests/unit/borg_json_output/diff_archives_stderr.json similarity index 100% rename from tests/borg_json_output/rename_stdout.json rename to tests/unit/borg_json_output/diff_archives_stderr.json diff --git a/tests/borg_json_output/diff_archives_stdout.json b/tests/unit/borg_json_output/diff_archives_stdout.json similarity index 100% rename from tests/borg_json_output/diff_archives_stdout.json rename to tests/unit/borg_json_output/diff_archives_stdout.json diff --git a/tests/borg_json_output/info_stderr.json b/tests/unit/borg_json_output/info_stderr.json similarity index 100% rename from tests/borg_json_output/info_stderr.json rename to tests/unit/borg_json_output/info_stderr.json diff --git a/tests/borg_json_output/info_stdout.json b/tests/unit/borg_json_output/info_stdout.json similarity index 100% rename from tests/borg_json_output/info_stdout.json rename to tests/unit/borg_json_output/info_stdout.json diff --git a/tests/borg_json_output/list_archive_stderr.json b/tests/unit/borg_json_output/list_archive_stderr.json similarity index 100% rename from tests/borg_json_output/list_archive_stderr.json rename to tests/unit/borg_json_output/list_archive_stderr.json diff --git a/tests/borg_json_output/list_archive_stdout.json b/tests/unit/borg_json_output/list_archive_stdout.json similarity index 100% rename from tests/borg_json_output/list_archive_stdout.json rename to tests/unit/borg_json_output/list_archive_stdout.json diff --git a/tests/borg_json_output/list_stderr.json b/tests/unit/borg_json_output/list_stderr.json similarity index 100% rename from tests/borg_json_output/list_stderr.json rename to tests/unit/borg_json_output/list_stderr.json diff --git a/tests/borg_json_output/list_stdout.json b/tests/unit/borg_json_output/list_stdout.json similarity index 100% rename from tests/borg_json_output/list_stdout.json rename to tests/unit/borg_json_output/list_stdout.json diff --git a/tests/borg_json_output/prune_stderr.json b/tests/unit/borg_json_output/prune_stderr.json similarity index 100% rename from tests/borg_json_output/prune_stderr.json rename to tests/unit/borg_json_output/prune_stderr.json diff --git a/tests/borg_json_output/prune_stdout.json b/tests/unit/borg_json_output/prune_stdout.json similarity index 100% rename from tests/borg_json_output/prune_stdout.json rename to tests/unit/borg_json_output/prune_stdout.json diff --git a/tests/unit/borg_json_output/rename_stderr.json b/tests/unit/borg_json_output/rename_stderr.json new file mode 100644 index 000000000..e69de29bb diff --git a/tests/unit/borg_json_output/rename_stdout.json b/tests/unit/borg_json_output/rename_stdout.json new file mode 100644 index 000000000..e69de29bb diff --git a/tests/conftest.py b/tests/unit/conftest.py similarity index 95% rename from tests/conftest.py rename to tests/unit/conftest.py index 03a8d22b3..d6cbb8864 100644 --- a/tests/conftest.py +++ b/tests/unit/conftest.py @@ -128,8 +128,8 @@ def selectedFiles(self): @pytest.fixture def borg_json_output(): def _read_json(subcommand): - stdout = open(f'tests/borg_json_output/{subcommand}_stdout.json') - stderr = open(f'tests/borg_json_output/{subcommand}_stderr.json') + stdout = open(f'tests/unit/borg_json_output/{subcommand}_stdout.json') + stderr = open(f'tests/unit/borg_json_output/{subcommand}_stderr.json') return stdout, stderr return _read_json diff --git a/tests/profile_exports/invalid_no_json.json b/tests/unit/profile_exports/invalid_no_json.json similarity index 100% rename from tests/profile_exports/invalid_no_json.json rename to tests/unit/profile_exports/invalid_no_json.json diff --git a/tests/profile_exports/valid.json b/tests/unit/profile_exports/valid.json similarity index 100% rename from tests/profile_exports/valid.json rename to tests/unit/profile_exports/valid.json diff --git a/tests/test_archives.py b/tests/unit/test_archives.py similarity index 100% rename from tests/test_archives.py rename to tests/unit/test_archives.py diff --git a/tests/test_borg.py b/tests/unit/test_borg.py similarity index 100% rename from tests/test_borg.py rename to tests/unit/test_borg.py diff --git a/tests/test_create.py b/tests/unit/test_create.py similarity index 100% rename from tests/test_create.py rename to tests/unit/test_create.py diff --git a/tests/test_diff.py b/tests/unit/test_diff.py similarity index 100% rename from tests/test_diff.py rename to tests/unit/test_diff.py diff --git a/tests/test_extract.py b/tests/unit/test_extract.py similarity index 100% rename from tests/test_extract.py rename to tests/unit/test_extract.py diff --git a/tests/test_import_export.py b/tests/unit/test_import_export.py similarity index 100% rename from tests/test_import_export.py rename to tests/unit/test_import_export.py diff --git a/tests/test_lock.py b/tests/unit/test_lock.py similarity index 100% rename from tests/test_lock.py rename to tests/unit/test_lock.py diff --git a/tests/test_misc.py b/tests/unit/test_misc.py similarity index 100% rename from tests/test_misc.py rename to tests/unit/test_misc.py diff --git a/tests/test_notifications.py b/tests/unit/test_notifications.py similarity index 100% rename from tests/test_notifications.py rename to tests/unit/test_notifications.py diff --git a/tests/test_profile.py b/tests/unit/test_profile.py similarity index 100% rename from tests/test_profile.py rename to tests/unit/test_profile.py diff --git a/tests/test_repo.py b/tests/unit/test_repo.py similarity index 100% rename from tests/test_repo.py rename to tests/unit/test_repo.py diff --git a/tests/test_schedule.py b/tests/unit/test_schedule.py similarity index 100% rename from tests/test_schedule.py rename to tests/unit/test_schedule.py diff --git a/tests/test_scheduler.py b/tests/unit/test_scheduler.py similarity index 100% rename from tests/test_scheduler.py rename to tests/unit/test_scheduler.py diff --git a/tests/test_source.py b/tests/unit/test_source.py similarity index 100% rename from tests/test_source.py rename to tests/unit/test_source.py diff --git a/tests/test_treemodel.py b/tests/unit/test_treemodel.py similarity index 100% rename from tests/test_treemodel.py rename to tests/unit/test_treemodel.py diff --git a/tests/test_utils.py b/tests/unit/test_utils.py similarity index 100% rename from tests/test_utils.py rename to tests/unit/test_utils.py From 6cd2658bc753638879cb73f6c0794818f76ebcac Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 28 May 2023 18:39:58 -0400 Subject: [PATCH 04/69] added more tests to archives tests Signed-off-by: Chirag Aggarwal --- tests/integration/conftest.py | 1 - tests/integration/test_archives.py | 66 +++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 6d220e192..4c024d95c 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -170,7 +170,6 @@ def _read_json(subcommand): return _read_json - @pytest.fixture def rootdir(): return os.path.dirname(os.path.abspath(__file__)) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index a1c71fd3a..e67fd71c2 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -12,7 +12,6 @@ def test_repo_list(qapp, qtbot): main = qapp.main_window tab = main.archiveTab - main.show() main.tabWidget.setCurrentIndex(3) tab.refresh_archive_list() @@ -22,48 +21,49 @@ def test_repo_list(qapp, qtbot): qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults) assert ArchiveModel.select().count() == 3 - qtbot.wait(5000) assert 'Refreshing archives done.' in main.progressText.text() assert tab.bCheck.isEnabled() def test_repo_prune(qapp, qtbot): main = qapp.main_window - main.show() tab = main.archiveTab + main.tabWidget.setCurrentIndex(3) - tab.populate_from_profile() + tab.refresh_archive_list() + qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) qtbot.mouseClick(tab.bPrune, QtCore.Qt.MouseButton.LeftButton) - qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults) def test_repo_compact(qapp, qtbot): main = qapp.main_window - main.show() tab = main.archiveTab + main.tabWidget.setCurrentIndex(3) tab.refresh_archive_list() + qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) + qtbot.waitUntil(lambda: tab.compactButton.isEnabled(), **pytest._wait_defaults) - qtbot.mouseClick(tab.compactButton, QtCore.Qt.MouseButton.LeftButton) + assert tab.compactButton.isEnabled() + + qtbot.mouseClick(tab.compactButton, QtCore.Qt.MouseButton.LeftButton) qtbot.waitUntil(lambda: 'compaction freed about' in main.logText.text(), **pytest._wait_defaults) def test_check(qapp, qtbot): main = qapp.main_window - main.show() tab = main.archiveTab main.tabWidget.setCurrentIndex(3) tab.refresh_archive_list() + qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) qtbot.mouseClick(tab.bCheck, QtCore.Qt.MouseButton.LeftButton) success_text = 'INFO: Archive consistency check complete' qtbot.waitUntil(lambda: success_text in main.logText.text(), **pytest._wait_defaults) - qtbot.wait(4000) - # TODO: Fix this test and nox config to support fuse mounts. @pytest.mark.skip(reason="TODO: Fix this test and nox config to support fuse mounts.") @@ -99,7 +99,7 @@ def psutil_disk_partitions(**kwargs): def test_archive_extract(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): main = qapp.main_window tab = main.archiveTab - main.show() + main.tabWidget.setCurrentIndex(3) tab.refresh_archive_list() @@ -119,3 +119,47 @@ def test_archive_extract(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): qtbot.waitUntil(lambda: 'Restored files from archive.' in main.progressText.text(), **pytest._wait_defaults) assert [item.basename for item in tmpdir.listdir()] == ['tmp'] + + +def test_archive_delete(qapp, qtbot, mocker): + main = qapp.main_window + tab = main.archiveTab + + main.tabWidget.setCurrentIndex(3) + + tab.refresh_archive_list() + qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) + + archivesCount = tab.archiveTable.rowCount() + + mocker.patch.object(vorta.views.archive_tab.ArchiveTab, 'confirm_dialog', lambda x, y, z: True) + + tab.archiveTable.selectRow(0) + tab.delete_action() + qtbot.waitUntil(lambda: 'Archive deleted.' in main.progressText.text(), **pytest._wait_defaults) + + assert ArchiveModel.select().count() == archivesCount - 1 + assert tab.archiveTable.rowCount() == archivesCount - 1 + +def test_archive_rename(qapp, qtbot, mocker, borg_json_output): + main = qapp.main_window + tab = main.archiveTab + main.tabWidget.setCurrentIndex(3) + + tab.refresh_archive_list() + qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) + + tab.archiveTable.selectRow(0) + new_archive_name = 'idf89d8f9d8fd98' + 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 + tab.archiveTable.selectRow(0) + exp_text = 'An archive with this name already exists.' + tab.rename_action() + qtbot.waitUntil(lambda: tab.mountErrors.text() == exp_text, **pytest._wait_defaults) \ No newline at end of file From 077f993d561828b0709ce43c78d1f7f8073c420f Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 28 May 2023 19:16:26 -0400 Subject: [PATCH 05/69] Archive more supported file types Signed-off-by: Chirag Aggarwal --- tests/integration/conftest.py | 47 +++++++++++++++++++++++++++--- tests/integration/test_archives.py | 10 ++++++- tests/integration/test_borg.py | 16 ++++++++++ 3 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 tests/integration/test_borg.py diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 4c024d95c..e78ab62f8 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -74,27 +74,66 @@ def create_test_repo(tmpdir_factory): source_files_dir = os.path.join(temp_dir, 'src') os.mkdir(source_files_dir) + # /src/file file_path = os.path.join(source_files_dir, 'file') with open(file_path, 'w') as f: f.write('test') - subprocess.run(['borg', 'create', f'{repo_path}::test-archive', source_files_dir], cwd=temp_dir, check=True) - + # /src/dir/ dir_path = os.path.join(source_files_dir, 'dir') os.mkdir(dir_path) + # /src/dir/file file_path = os.path.join(dir_path, 'file') with open(file_path, 'w') as f: f.write('test') + # Create first archive subprocess.run(['borg', 'create', f'{repo_path}::test-archive1', source_files_dir], cwd=temp_dir, check=True) - symlink_path = os.path.join(source_files_dir, 'symlink') + # /src/dir/symlink + symlink_path = os.path.join(dir_path, 'symlink') os.symlink(file_path, symlink_path) + # /src/dir/hardlink + hardlink_path = os.path.join(dir_path, 'hardlink') + os.link(file_path, hardlink_path) + + # /src/dir/fifo + fifo_path = os.path.join(dir_path, 'fifo') + os.mkfifo(fifo_path) + + # /src/dir/socket + socket_path = os.path.join(dir_path, 'socket') + os.mknod(socket_path, mode=0o600 | 0o140000) + + # /src/dir/chrdev + chrdev_path = os.path.join(dir_path, 'chrdev') + os.mknod(chrdev_path, mode=0o600 | 0o020000) + + # /src/dir/blkdev + # blkdev_path = os.path.join(dir_path, 'blkdev') + # os.mknod(blkdev_path, mode=0o600 | 0o060000) + + # Create second archive subprocess.run(['borg', 'create', f'{repo_path}::test-archive2', source_files_dir], cwd=temp_dir, check=True) - # TODO: More file types and more archives required for testing + # Rename dir to dir1 + os.rename(dir_path, os.path.join(source_files_dir, 'dir1')) + + subprocess.run(['borg', 'create', f'{repo_path}::test-archive3', source_files_dir], cwd=temp_dir, check=True) + + # Rename all files under dir1 + for file in os.listdir(os.path.join(source_files_dir, 'dir1')): + os.rename(os.path.join(source_files_dir, 'dir1', file), os.path.join(source_files_dir, 'dir1', file + '1')) + + subprocess.run(['borg', 'create', f'{repo_path}::test-archive4', source_files_dir], cwd=temp_dir, check=True) + + # Delete all file under dir1 + for file in os.listdir(os.path.join(source_files_dir, 'dir1')): + os.remove(os.path.join(source_files_dir, 'dir1', file)) + + subprocess.run(['borg', 'create', f'{repo_path}::test-archive5', source_files_dir], cwd=temp_dir, check=True) def cleanup(): shutil.rmtree(temp_dir) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index e67fd71c2..51c2d9c0a 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -8,6 +8,14 @@ from PyQt6 import QtCore from vorta.store.models import ArchiveModel +# def test_test(qapp, qtbot): +# main = qapp.main_window +# tab = main.archiveTab +# main.tabWidget.setCurrentIndex(3) +# tab.refresh_archive_list() +# main.show() +# # wait until window close with no timeout +# qtbot.wait(1000000) def test_repo_list(qapp, qtbot): main = qapp.main_window @@ -20,7 +28,7 @@ def test_repo_list(qapp, qtbot): assert not tab.bCheck.isEnabled() qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults) - assert ArchiveModel.select().count() == 3 + assert ArchiveModel.select().count() == 5 assert 'Refreshing archives done.' in main.progressText.text() assert tab.bCheck.isEnabled() diff --git a/tests/integration/test_borg.py b/tests/integration/test_borg.py new file mode 100644 index 000000000..6a8f55b8f --- /dev/null +++ b/tests/integration/test_borg.py @@ -0,0 +1,16 @@ +import pytest +import vorta.borg +import vorta.store.models +from vorta.borg.prune import BorgPruneJob + + +def test_borg_prune(qapp, qtbot): + + params = BorgPruneJob.prepare(vorta.store.models.BackupProfileModel.select().first()) + thread = BorgPruneJob(params['cmd'], params, qapp) + + with qtbot.waitSignal(thread.result, **pytest._wait_defaults) as blocker: + blocker.connect(thread.updated) + thread.run() + + assert blocker.args[0]['returncode'] == 0 From 5b3b6c6b44f03524c58f4b1a96b0aa0f06290e0b Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 28 May 2023 19:17:46 -0400 Subject: [PATCH 06/69] Revert "Archive more supported file types" This reverts commit 077f993d561828b0709ce43c78d1f7f8073c420f. --- tests/integration/conftest.py | 47 +++--------------------------- tests/integration/test_archives.py | 10 +------ tests/integration/test_borg.py | 16 ---------- 3 files changed, 5 insertions(+), 68 deletions(-) delete mode 100644 tests/integration/test_borg.py diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index e78ab62f8..4c024d95c 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -74,66 +74,27 @@ def create_test_repo(tmpdir_factory): source_files_dir = os.path.join(temp_dir, 'src') os.mkdir(source_files_dir) - # /src/file file_path = os.path.join(source_files_dir, 'file') with open(file_path, 'w') as f: f.write('test') - # /src/dir/ + subprocess.run(['borg', 'create', f'{repo_path}::test-archive', source_files_dir], cwd=temp_dir, check=True) + dir_path = os.path.join(source_files_dir, 'dir') os.mkdir(dir_path) - # /src/dir/file file_path = os.path.join(dir_path, 'file') with open(file_path, 'w') as f: f.write('test') - # Create first archive subprocess.run(['borg', 'create', f'{repo_path}::test-archive1', source_files_dir], cwd=temp_dir, check=True) - # /src/dir/symlink - symlink_path = os.path.join(dir_path, 'symlink') + symlink_path = os.path.join(source_files_dir, 'symlink') os.symlink(file_path, symlink_path) - # /src/dir/hardlink - hardlink_path = os.path.join(dir_path, 'hardlink') - os.link(file_path, hardlink_path) - - # /src/dir/fifo - fifo_path = os.path.join(dir_path, 'fifo') - os.mkfifo(fifo_path) - - # /src/dir/socket - socket_path = os.path.join(dir_path, 'socket') - os.mknod(socket_path, mode=0o600 | 0o140000) - - # /src/dir/chrdev - chrdev_path = os.path.join(dir_path, 'chrdev') - os.mknod(chrdev_path, mode=0o600 | 0o020000) - - # /src/dir/blkdev - # blkdev_path = os.path.join(dir_path, 'blkdev') - # os.mknod(blkdev_path, mode=0o600 | 0o060000) - - # Create second archive subprocess.run(['borg', 'create', f'{repo_path}::test-archive2', source_files_dir], cwd=temp_dir, check=True) - # Rename dir to dir1 - os.rename(dir_path, os.path.join(source_files_dir, 'dir1')) - - subprocess.run(['borg', 'create', f'{repo_path}::test-archive3', source_files_dir], cwd=temp_dir, check=True) - - # Rename all files under dir1 - for file in os.listdir(os.path.join(source_files_dir, 'dir1')): - os.rename(os.path.join(source_files_dir, 'dir1', file), os.path.join(source_files_dir, 'dir1', file + '1')) - - subprocess.run(['borg', 'create', f'{repo_path}::test-archive4', source_files_dir], cwd=temp_dir, check=True) - - # Delete all file under dir1 - for file in os.listdir(os.path.join(source_files_dir, 'dir1')): - os.remove(os.path.join(source_files_dir, 'dir1', file)) - - subprocess.run(['borg', 'create', f'{repo_path}::test-archive5', source_files_dir], cwd=temp_dir, check=True) + # TODO: More file types and more archives required for testing def cleanup(): shutil.rmtree(temp_dir) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 51c2d9c0a..e67fd71c2 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -8,14 +8,6 @@ from PyQt6 import QtCore from vorta.store.models import ArchiveModel -# def test_test(qapp, qtbot): -# main = qapp.main_window -# tab = main.archiveTab -# main.tabWidget.setCurrentIndex(3) -# tab.refresh_archive_list() -# main.show() -# # wait until window close with no timeout -# qtbot.wait(1000000) def test_repo_list(qapp, qtbot): main = qapp.main_window @@ -28,7 +20,7 @@ def test_repo_list(qapp, qtbot): assert not tab.bCheck.isEnabled() qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults) - assert ArchiveModel.select().count() == 5 + assert ArchiveModel.select().count() == 3 assert 'Refreshing archives done.' in main.progressText.text() assert tab.bCheck.isEnabled() diff --git a/tests/integration/test_borg.py b/tests/integration/test_borg.py deleted file mode 100644 index 6a8f55b8f..000000000 --- a/tests/integration/test_borg.py +++ /dev/null @@ -1,16 +0,0 @@ -import pytest -import vorta.borg -import vorta.store.models -from vorta.borg.prune import BorgPruneJob - - -def test_borg_prune(qapp, qtbot): - - params = BorgPruneJob.prepare(vorta.store.models.BackupProfileModel.select().first()) - thread = BorgPruneJob(params['cmd'], params, qapp) - - with qtbot.waitSignal(thread.result, **pytest._wait_defaults) as blocker: - blocker.connect(thread.updated) - thread.run() - - assert blocker.args[0]['returncode'] == 0 From e243f683f924e684a3578738cfe741195e790359 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 28 May 2023 19:19:26 -0400 Subject: [PATCH 07/69] Archive more supported file types Signed-off-by: Chirag Aggarwal --- tests/integration/conftest.py | 46 +++++++++++++++++++++++++++--- tests/integration/test_archives.py | 2 +- tests/integration/test_borg.py | 16 +++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 tests/integration/test_borg.py diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 4c024d95c..de1d7a82b 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -74,27 +74,65 @@ def create_test_repo(tmpdir_factory): source_files_dir = os.path.join(temp_dir, 'src') os.mkdir(source_files_dir) + # /src/file file_path = os.path.join(source_files_dir, 'file') with open(file_path, 'w') as f: f.write('test') - subprocess.run(['borg', 'create', f'{repo_path}::test-archive', source_files_dir], cwd=temp_dir, check=True) - + # /src/dir/ dir_path = os.path.join(source_files_dir, 'dir') os.mkdir(dir_path) + # /src/dir/file file_path = os.path.join(dir_path, 'file') with open(file_path, 'w') as f: f.write('test') + # Create first archive subprocess.run(['borg', 'create', f'{repo_path}::test-archive1', source_files_dir], cwd=temp_dir, check=True) - symlink_path = os.path.join(source_files_dir, 'symlink') + # /src/dir/symlink + symlink_path = os.path.join(dir_path, 'symlink') os.symlink(file_path, symlink_path) + # /src/dir/hardlink + hardlink_path = os.path.join(dir_path, 'hardlink') + os.link(file_path, hardlink_path) + + # /src/dir/fifo + fifo_path = os.path.join(dir_path, 'fifo') + os.mkfifo(fifo_path) + + # /src/dir/socket + socket_path = os.path.join(dir_path, 'socket') + os.mknod(socket_path, mode=0o600 | 0o140000) + + # /src/dir/chrdev + chrdev_path = os.path.join(dir_path, 'chrdev') + os.mknod(chrdev_path, mode=0o600 | 0o020000) + + # /src/dir/blkdev + # blkdev_path = os.path.join(dir_path, 'blkdev') + # os.mknod(blkdev_path, mode=0o600 | 0o060000) + subprocess.run(['borg', 'create', f'{repo_path}::test-archive2', source_files_dir], cwd=temp_dir, check=True) - # TODO: More file types and more archives required for testing + # Rename dir to dir1 + os.rename(dir_path, os.path.join(source_files_dir, 'dir1')) + + subprocess.run(['borg', 'create', f'{repo_path}::test-archive3', source_files_dir], cwd=temp_dir, check=True) + + # Rename all files under dir1 + for file in os.listdir(os.path.join(source_files_dir, 'dir1')): + os.rename(os.path.join(source_files_dir, 'dir1', file), os.path.join(source_files_dir, 'dir1', file + '1')) + + subprocess.run(['borg', 'create', f'{repo_path}::test-archive4', source_files_dir], cwd=temp_dir, check=True) + + # Delete all file under dir1 + for file in os.listdir(os.path.join(source_files_dir, 'dir1')): + os.remove(os.path.join(source_files_dir, 'dir1', file)) + + subprocess.run(['borg', 'create', f'{repo_path}::test-archive5', source_files_dir], cwd=temp_dir, check=True) def cleanup(): shutil.rmtree(temp_dir) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index e67fd71c2..f25155ab9 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -20,7 +20,7 @@ def test_repo_list(qapp, qtbot): assert not tab.bCheck.isEnabled() qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults) - assert ArchiveModel.select().count() == 3 + assert ArchiveModel.select().count() == 5 assert 'Refreshing archives done.' in main.progressText.text() assert tab.bCheck.isEnabled() diff --git a/tests/integration/test_borg.py b/tests/integration/test_borg.py new file mode 100644 index 000000000..6a8f55b8f --- /dev/null +++ b/tests/integration/test_borg.py @@ -0,0 +1,16 @@ +import pytest +import vorta.borg +import vorta.store.models +from vorta.borg.prune import BorgPruneJob + + +def test_borg_prune(qapp, qtbot): + + params = BorgPruneJob.prepare(vorta.store.models.BackupProfileModel.select().first()) + thread = BorgPruneJob(params['cmd'], params, qapp) + + with qtbot.waitSignal(thread.result, **pytest._wait_defaults) as blocker: + blocker.connect(thread.updated) + thread.run() + + assert blocker.args[0]['returncode'] == 0 From 14cab4a40b988026a4db4c6b5bf12aad16b36ad0 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Thu, 1 Jun 2023 15:38:50 -0400 Subject: [PATCH 08/69] Added test for creating / adding repo Signed-off-by: Chirag Aggarwal --- tests/integration/test_init.py | 77 ++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 tests/integration/test_init.py diff --git a/tests/integration/test_init.py b/tests/integration/test_init.py new file mode 100644 index 000000000..178c76c07 --- /dev/null +++ b/tests/integration/test_init.py @@ -0,0 +1,77 @@ +import os +from pathlib import PurePath + +import pytest +import vorta.borg +import vorta.utils +import vorta.views.repo_add_dialog +from PyQt6.QtCore import Qt +from PyQt6.QtWidgets import QMessageBox + +LONG_PASSWORD = 'long-password-long' + + +def test_create_repo(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): + main = qapp.main_window + main.show() + main.repoTab.new_repo() + add_repo_window = main.repoTab._window + + # create new folder in tmpdir + new_repo_path = tmpdir.join('new_repo') + new_repo_path.mkdir() + + monkeypatch.setattr( + vorta.views.repo_add_dialog, + "choose_file_dialog", + lambda *args, **kwargs: choose_file_dialog(*args, **kwargs, subdirectory=new_repo_path.basename), + ) + qtbot.mouseClick(add_repo_window.chooseLocalFolderButton, Qt.MouseButton.LeftButton) + + qtbot.keyClicks(add_repo_window.passwordLineEdit, LONG_PASSWORD) + qtbot.keyClicks(add_repo_window.confirmLineEdit, LONG_PASSWORD) + + add_repo_window.run() + + qtbot.waitUntil(lambda: main.repoTab.repoSelector.count() == 2, **pytest._wait_defaults) + + # Check if repo was created in tmpdir + assert PurePath(main.repoTab.repoSelector.currentText()).parent == tmpdir + assert PurePath(main.repoTab.repoSelector.currentText()).name == 'new_repo' + + # check that new_repo_path contains folder data + assert os.path.exists(new_repo_path.join('data')) + assert os.path.exists(new_repo_path.join('config')) + assert os.path.exists(new_repo_path.join('README')) + + +def test_add_existing_repo(qapp, qtbot, monkeypatch, choose_file_dialog): + main = qapp.main_window + main.show() + tab = main.repoTab + + main.tabWidget.setCurrentIndex(0) + current_repo_path = PurePath(main.repoTab.repoSelector.currentText()) + + monkeypatch.setattr(QMessageBox, "show", lambda *args: True) + qtbot.mouseClick(main.repoTab.repoRemoveToolbutton, Qt.MouseButton.LeftButton) + qtbot.waitUntil( + lambda: tab.repoSelector.count() == 1 and tab.repoSelector.currentText() == "No repository selected", + **pytest._wait_defaults, + ) + + # add existing repo again + main.repoTab.add_existing_repo() + add_repo_window = main.repoTab._window + + monkeypatch.setattr( + vorta.views.repo_add_dialog, + "choose_file_dialog", + lambda *args, **kwargs: choose_file_dialog(*args, **kwargs, directory=current_repo_path), + ) + qtbot.mouseClick(add_repo_window.chooseLocalFolderButton, Qt.MouseButton.LeftButton) + add_repo_window.run() + + # check that repo was added + qtbot.waitUntil(lambda: tab.repoSelector.count() == 1, **pytest._wait_defaults) + assert tab.repoSelector.currentText() == str(current_repo_path) From 05ecaf2e8ece437d9f9e710099722944c84c49a6 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Thu, 1 Jun 2023 15:41:12 -0400 Subject: [PATCH 09/69] Push changes for conftest.py Signed-off-by: Chirag Aggarwal --- tests/integration/conftest.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index de1d7a82b..2bd9f0cd2 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -90,6 +90,7 @@ def create_test_repo(tmpdir_factory): # Create first archive subprocess.run(['borg', 'create', f'{repo_path}::test-archive1', source_files_dir], cwd=temp_dir, check=True) + # time.sleep(1) # /src/dir/symlink symlink_path = os.path.join(dir_path, 'symlink') @@ -116,23 +117,33 @@ def create_test_repo(tmpdir_factory): # os.mknod(blkdev_path, mode=0o600 | 0o060000) subprocess.run(['borg', 'create', f'{repo_path}::test-archive2', source_files_dir], cwd=temp_dir, check=True) + # time.sleep(1) # Rename dir to dir1 os.rename(dir_path, os.path.join(source_files_dir, 'dir1')) subprocess.run(['borg', 'create', f'{repo_path}::test-archive3', source_files_dir], cwd=temp_dir, check=True) + # time.sleep(1) - # Rename all files under dir1 + # Rename all files under dir1 for file in os.listdir(os.path.join(source_files_dir, 'dir1')): os.rename(os.path.join(source_files_dir, 'dir1', file), os.path.join(source_files_dir, 'dir1', file + '1')) subprocess.run(['borg', 'create', f'{repo_path}::test-archive4', source_files_dir], cwd=temp_dir, check=True) + # time.sleep(1) # Delete all file under dir1 for file in os.listdir(os.path.join(source_files_dir, 'dir1')): os.remove(os.path.join(source_files_dir, 'dir1', file)) subprocess.run(['borg', 'create', f'{repo_path}::test-archive5', source_files_dir], cwd=temp_dir, check=True) + # time.sleep(1) + + # change permission of dir1 + os.chmod(os.path.join(source_files_dir, 'dir1'), 0o700) + + subprocess.run(['borg', 'create', f'{repo_path}::test-archive6', source_files_dir], cwd=temp_dir, check=True) + # time.sleep(1) def cleanup(): shutil.rmtree(temp_dir) @@ -188,13 +199,19 @@ def init_db(qapp, qtbot, tmpdir_factory, create_test_repo): def choose_file_dialog(tmpdir): class MockFileDialog: def __init__(self, *args, **kwargs): - pass + self.directory = kwargs.get('directory', None) + self.subdirectory = kwargs.get('subdirectory', None) def open(self, func): func() def selectedFiles(self): - return [str(tmpdir)] + if self.subdirectory: + return [str(tmpdir.join(self.subdirectory))] + elif self.directory: + return [str(self.directory)] + else: + return [str(tmpdir)] return MockFileDialog @@ -208,6 +225,7 @@ def _read_json(subcommand): return _read_json + @pytest.fixture def rootdir(): return os.path.dirname(os.path.abspath(__file__)) From 0ca561304ee0c49b5d11d6dce0178b1ab6f0da8f Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 5 Jun 2023 23:02:27 -0400 Subject: [PATCH 10/69] Added tests for borg info Signed-off-by: Chirag Aggarwal --- tests/integration/test_borg.py | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/integration/test_borg.py b/tests/integration/test_borg.py index 6a8f55b8f..d474e0794 100644 --- a/tests/integration/test_borg.py +++ b/tests/integration/test_borg.py @@ -1,6 +1,10 @@ +from pathlib import Path + import pytest import vorta.borg import vorta.store.models +from vorta.borg.info_archive import BorgInfoArchiveJob +from vorta.borg.info_repo import BorgInfoRepoJob from vorta.borg.prune import BorgPruneJob @@ -14,3 +18,39 @@ def test_borg_prune(qapp, qtbot): thread.run() assert blocker.args[0]['returncode'] == 0 + + +# test borg info +def test_borg_repo_info(qapp, qtbot, tmpdir): + repo_info = { + 'repo_url': str(Path(tmpdir).parent / 'repo'), + 'extra_borg_arguments': '', + 'ssh_key': '', + 'password': '', + } + + params = BorgInfoRepoJob.prepare(repo_info) + thread = BorgInfoRepoJob(params['cmd'], params, qapp) + + with qtbot.waitSignal(thread.result, **pytest._wait_defaults) as blocker: + blocker.connect(thread.result) + thread.run() + + assert blocker.args[0]['returncode'] == 0 + + +def test_borg_archive_info(qapp, qtbot, tmpdir): + main = qapp.main_window + tab = main.archiveTab + main.tabWidget.setCurrentIndex(3) + tab.refresh_archive_list() + qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) + + params = BorgInfoArchiveJob.prepare(vorta.store.models.BackupProfileModel.select().first(), "test-archive1") + thread = BorgInfoArchiveJob(params['cmd'], params, qapp) + + with qtbot.waitSignal(thread.result, **pytest._wait_defaults) as blocker: + blocker.connect(thread.result) + thread.run() + + assert blocker.args[0]['returncode'] == 0 From c6418e8604d1ab0ef260186fa6f53064001060b5 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Thu, 8 Jun 2023 05:04:15 -0400 Subject: [PATCH 11/69] Test configuration improvements and bug fixes Signed-off-by: Chirag Aggarwal --- noxfile.py | 4 +-- tests/integration/conftest.py | 46 ++++++++++++++++-------------- tests/integration/test_archives.py | 30 ++++++++++++------- 3 files changed, 45 insertions(+), 35 deletions(-) diff --git a/noxfile.py b/noxfile.py index 9a4696542..886c40e81 100644 --- a/noxfile.py +++ b/noxfile.py @@ -5,10 +5,10 @@ @nox.session # @nox.parametrize("borgbackup", ["2.0.0b5", "2.0.0b4"]) -@nox.parametrize("borgbackup", ["1.2.4"]) +@nox.parametrize("borgbackup", ["1.1.18", "1.2.2", "1.2.3", "1.2.4"]) def run_tests(session, borgbackup): # install borgbackup - session.install(f"borgbackup=={borgbackup}") + session.install(f"borgbackup[pyfuse3]=={borgbackup}") # install dependencies session.install("-r", "requirements.d/dev.txt") diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 2bd9f0cd2..86b67e9de 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -3,6 +3,7 @@ import shutil import subprocess import sys +import time import pytest import vorta @@ -65,14 +66,17 @@ def qapp(tmpdir_factory): @pytest.fixture(scope='function', autouse=True) def create_test_repo(tmpdir_factory): - temp_dir = tmpdir_factory.mktemp('repo') - repo_path = str(temp_dir) + # temp_dir = tmpdir_factory.mktemp('repo') + # repo_path = os.path.join(tmpdir_factory.getbasetemp(), 'repo') + # os.mkdir(repo_path) + repo_path = tmpdir_factory.mktemp('repo') - subprocess.run(['borg', 'init', '--encryption=none', repo_path], check=True) + subprocess.run(['borg', 'init', '--encryption=none', str(repo_path)], check=True) # create source files dir - source_files_dir = os.path.join(temp_dir, 'src') - os.mkdir(source_files_dir) + # source_files_dir = os.path.join(tmpdir_factory.getbasetemp(), 'borg_src') + # os.mkdir(source_files_dir) + source_files_dir = tmpdir_factory.mktemp('borg_src') # /src/file file_path = os.path.join(source_files_dir, 'file') @@ -89,8 +93,8 @@ def create_test_repo(tmpdir_factory): f.write('test') # Create first archive - subprocess.run(['borg', 'create', f'{repo_path}::test-archive1', source_files_dir], cwd=temp_dir, check=True) - # time.sleep(1) + subprocess.run(['borg', 'create', f'{repo_path}::test-archive1', source_files_dir], cwd=str(repo_path), check=True) + time.sleep(1) # /src/dir/symlink symlink_path = os.path.join(dir_path, 'symlink') @@ -112,41 +116,39 @@ def create_test_repo(tmpdir_factory): chrdev_path = os.path.join(dir_path, 'chrdev') os.mknod(chrdev_path, mode=0o600 | 0o020000) - # /src/dir/blkdev - # blkdev_path = os.path.join(dir_path, 'blkdev') - # os.mknod(blkdev_path, mode=0o600 | 0o060000) - - subprocess.run(['borg', 'create', f'{repo_path}::test-archive2', source_files_dir], cwd=temp_dir, check=True) - # time.sleep(1) + subprocess.run(['borg', 'create', f'{repo_path}::test-archive2', source_files_dir], cwd=str(repo_path), check=True) + time.sleep(1) # Rename dir to dir1 os.rename(dir_path, os.path.join(source_files_dir, 'dir1')) - subprocess.run(['borg', 'create', f'{repo_path}::test-archive3', source_files_dir], cwd=temp_dir, check=True) - # time.sleep(1) + subprocess.run(['borg', 'create', f'{repo_path}::test-archive3', source_files_dir], cwd=str(repo_path), check=True) + time.sleep(1) # Rename all files under dir1 for file in os.listdir(os.path.join(source_files_dir, 'dir1')): os.rename(os.path.join(source_files_dir, 'dir1', file), os.path.join(source_files_dir, 'dir1', file + '1')) - subprocess.run(['borg', 'create', f'{repo_path}::test-archive4', source_files_dir], cwd=temp_dir, check=True) - # time.sleep(1) + subprocess.run(['borg', 'create', f'{repo_path}::test-archive4', source_files_dir], cwd=str(repo_path), check=True) + time.sleep(1) # Delete all file under dir1 for file in os.listdir(os.path.join(source_files_dir, 'dir1')): os.remove(os.path.join(source_files_dir, 'dir1', file)) - subprocess.run(['borg', 'create', f'{repo_path}::test-archive5', source_files_dir], cwd=temp_dir, check=True) - # time.sleep(1) + subprocess.run(['borg', 'create', f'{repo_path}::test-archive5', source_files_dir], cwd=str(repo_path), check=True) + time.sleep(1) # change permission of dir1 os.chmod(os.path.join(source_files_dir, 'dir1'), 0o700) - subprocess.run(['borg', 'create', f'{repo_path}::test-archive6', source_files_dir], cwd=temp_dir, check=True) - # time.sleep(1) + subprocess.run(['borg', 'create', f'{repo_path}::test-archive6', source_files_dir], cwd=str(repo_path), check=True) + time.sleep(1) + # Cleanup def cleanup(): - shutil.rmtree(temp_dir) + shutil.rmtree(repo_path) + shutil.rmtree(source_files_dir) atexit.register(cleanup) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index f25155ab9..9452bca15 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -20,7 +20,7 @@ def test_repo_list(qapp, qtbot): assert not tab.bCheck.isEnabled() qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults) - assert ArchiveModel.select().count() == 5 + assert ArchiveModel.select().count() == 6 assert 'Refreshing archives done.' in main.progressText.text() assert tab.bCheck.isEnabled() @@ -37,6 +37,9 @@ def test_repo_prune(qapp, qtbot): qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults) +@pytest.mark.skipif( + not vorta.utils.borg_compat.check('COMPACT_SUBCOMMAND'), reason="Borg version does not support compact" +) def test_repo_compact(qapp, qtbot): main = qapp.main_window tab = main.archiveTab @@ -44,10 +47,9 @@ def test_repo_compact(qapp, qtbot): main.tabWidget.setCurrentIndex(3) tab.refresh_archive_list() qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) - qtbot.waitUntil(lambda: tab.compactButton.isEnabled(), **pytest._wait_defaults) + qtbot.waitUntil(lambda: tab.compactButton.isEnabled(), **pytest._wait_defaults) assert tab.compactButton.isEnabled() - qtbot.mouseClick(tab.compactButton, QtCore.Qt.MouseButton.LeftButton) qtbot.waitUntil(lambda: 'compaction freed about' in main.logText.text(), **pytest._wait_defaults) @@ -56,34 +58,41 @@ def test_repo_compact(qapp, qtbot): def test_check(qapp, qtbot): main = qapp.main_window tab = main.archiveTab + main.show() + main.tabWidget.setCurrentIndex(3) tab.refresh_archive_list() qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) + qapp.check_failed_event.disconnect() + + qtbot.waitUntil(lambda: tab.bCheck.isEnabled(), **pytest._wait_defaults) qtbot.mouseClick(tab.bCheck, QtCore.Qt.MouseButton.LeftButton) success_text = 'INFO: Archive consistency check complete' + qtbot.waitUntil(lambda: success_text in main.logText.text(), **pytest._wait_defaults) -# TODO: Fix this test and nox config to support fuse mounts. -@pytest.mark.skip(reason="TODO: Fix this test and nox config to support fuse mounts.") def test_mount(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): def psutil_disk_partitions(**kwargs): DiskPartitions = namedtuple('DiskPartitions', ['device', 'mountpoint']) return [DiskPartitions('borgfs', str(tmpdir))] monkeypatch.setattr(psutil, "disk_partitions", psutil_disk_partitions) + monkeypatch.setattr(vorta.views.archive_tab, "choose_file_dialog", choose_file_dialog) main = qapp.main_window tab = main.archiveTab main.show() + main.tabWidget.setCurrentIndex(3) tab.refresh_archive_list() + qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) tab.archiveTable.selectRow(0) - monkeypatch.setattr(vorta.views.archive_tab, "choose_file_dialog", choose_file_dialog) + qtbot.waitUntil(lambda: tab.bMountRepo.isEnabled(), **pytest._wait_defaults) - tab.bmountarchive_clicked() + qtbot.mouseClick(tab.bMountArchive, QtCore.Qt.MouseButton.LeftButton) qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Mounted'), **pytest._wait_defaults) tab.bmountarchive_clicked() @@ -101,7 +110,6 @@ def test_archive_extract(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): tab = main.archiveTab main.tabWidget.setCurrentIndex(3) - tab.refresh_archive_list() qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) @@ -126,7 +134,6 @@ def test_archive_delete(qapp, qtbot, mocker): tab = main.archiveTab main.tabWidget.setCurrentIndex(3) - tab.refresh_archive_list() qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) @@ -141,11 +148,12 @@ def test_archive_delete(qapp, qtbot, mocker): assert ArchiveModel.select().count() == archivesCount - 1 assert tab.archiveTable.rowCount() == archivesCount - 1 + def test_archive_rename(qapp, qtbot, mocker, borg_json_output): main = qapp.main_window tab = main.archiveTab - main.tabWidget.setCurrentIndex(3) + main.tabWidget.setCurrentIndex(3) tab.refresh_archive_list() qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) @@ -162,4 +170,4 @@ def test_archive_rename(qapp, qtbot, mocker, borg_json_output): tab.archiveTable.selectRow(0) exp_text = 'An archive with this name already exists.' tab.rename_action() - qtbot.waitUntil(lambda: tab.mountErrors.text() == exp_text, **pytest._wait_defaults) \ No newline at end of file + qtbot.waitUntil(lambda: tab.mountErrors.text() == exp_text, **pytest._wait_defaults) From a68cb65ade0fad231e885e837be906a3b01acaec Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Thu, 8 Jun 2023 05:09:07 -0400 Subject: [PATCH 12/69] conftest.py cleanup Signed-off-by: Chirag Aggarwal --- tests/integration/conftest.py | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 86b67e9de..702815136 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -1,6 +1,4 @@ -import atexit import os -import shutil import subprocess import sys import time @@ -66,18 +64,11 @@ def qapp(tmpdir_factory): @pytest.fixture(scope='function', autouse=True) def create_test_repo(tmpdir_factory): - # temp_dir = tmpdir_factory.mktemp('repo') - # repo_path = os.path.join(tmpdir_factory.getbasetemp(), 'repo') - # os.mkdir(repo_path) repo_path = tmpdir_factory.mktemp('repo') + source_files_dir = tmpdir_factory.mktemp('borg_src') subprocess.run(['borg', 'init', '--encryption=none', str(repo_path)], check=True) - # create source files dir - # source_files_dir = os.path.join(tmpdir_factory.getbasetemp(), 'borg_src') - # os.mkdir(source_files_dir) - source_files_dir = tmpdir_factory.mktemp('borg_src') - # /src/file file_path = os.path.join(source_files_dir, 'file') with open(file_path, 'w') as f: @@ -94,6 +85,7 @@ def create_test_repo(tmpdir_factory): # Create first archive subprocess.run(['borg', 'create', f'{repo_path}::test-archive1', source_files_dir], cwd=str(repo_path), check=True) + # Sleep 1 second to prevent timestamp issue where both archives have the same timestamp causing issue with diff time.sleep(1) # /src/dir/symlink @@ -145,13 +137,6 @@ def create_test_repo(tmpdir_factory): subprocess.run(['borg', 'create', f'{repo_path}::test-archive6', source_files_dir], cwd=str(repo_path), check=True) time.sleep(1) - # Cleanup - def cleanup(): - shutil.rmtree(repo_path) - shutil.rmtree(source_files_dir) - - atexit.register(cleanup) - return repo_path, source_files_dir From e456f1009a2f37fd1a5c515b6477d9a027747c5b Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 9 Jun 2023 01:21:39 -0400 Subject: [PATCH 13/69] Test for creating new archive Signed-off-by: Chirag Aggarwal --- tests/integration/test_repo.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/integration/test_repo.py diff --git a/tests/integration/test_repo.py b/tests/integration/test_repo.py new file mode 100644 index 000000000..67bd05da6 --- /dev/null +++ b/tests/integration/test_repo.py @@ -0,0 +1,20 @@ +import pytest +from PyQt6 import QtCore +from vorta.store.models import ArchiveModel, EventLogModel + + +def test_create(qapp, qtbot): + main = qapp.main_window + main.show() + main.archiveTab.refresh_archive_list() + qtbot.waitUntil(lambda: main.archiveTab.archiveTable.rowCount() > 0, **pytest._wait_defaults) + + qtbot.mouseClick(main.createStartBtn, QtCore.Qt.MouseButton.LeftButton) + qtbot.waitUntil(lambda: 'Backup finished.' in main.progressText.text(), **pytest._wait_defaults) + qtbot.waitUntil(lambda: main.createStartBtn.isEnabled(), **pytest._wait_defaults) + + assert EventLogModel.select().count() == 2 + assert ArchiveModel.select().count() == 7 + assert main.createStartBtn.isEnabled() + assert main.archiveTab.archiveTable.rowCount() == 7 + assert main.scheduleTab.logTableWidget.rowCount() == 2 From 854ee602eb4de483e1ae5cf76f6c4ebeedcf5370 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 9 Jun 2023 02:33:58 -0400 Subject: [PATCH 14/69] Fixed prune test Signed-off-by: Chirag Aggarwal --- tests/integration/test_archives.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 9452bca15..b16352de5 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -34,6 +34,7 @@ def test_repo_prune(qapp, qtbot): qtbot.waitUntil(lambda: tab.archiveTable.rowCount() > 0, **pytest._wait_defaults) qtbot.mouseClick(tab.bPrune, QtCore.Qt.MouseButton.LeftButton) + qtbot.waitUntil(lambda: 'Pruning old archives' in main.progressText.text(), **pytest._wait_defaults) qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults) From 72215dc3b634a5ea11ef3319eaa30a3b3246f306 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 9 Jun 2023 02:53:50 -0400 Subject: [PATCH 15/69] Group common fixtures of conftest.py Signed-off-by: Chirag Aggarwal --- noxfile.py | 3 ++- tests/conftest.py | 36 ++++++++++++++++++++++++++++++++ tests/integration/conftest.py | 39 ----------------------------------- tests/unit/conftest.py | 33 ----------------------------- 4 files changed, 38 insertions(+), 73 deletions(-) create mode 100644 tests/conftest.py diff --git a/noxfile.py b/noxfile.py index 886c40e81..1f8b1cec3 100644 --- a/noxfile.py +++ b/noxfile.py @@ -5,7 +5,8 @@ @nox.session # @nox.parametrize("borgbackup", ["2.0.0b5", "2.0.0b4"]) -@nox.parametrize("borgbackup", ["1.1.18", "1.2.2", "1.2.3", "1.2.4"]) +# @nox.parametrize("borgbackup", ["1.1.18", "1.2.2", "1.2.3", "1.2.4"]) +@nox.parametrize("borgbackup", ["1.2.4"]) def run_tests(session, borgbackup): # install borgbackup session.install(f"borgbackup[pyfuse3]=={borgbackup}") diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..0f7810265 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,36 @@ +import os +import sys + +import pytest +import vorta +import vorta.application +import vorta.borg.jobs_manager +from peewee import SqliteDatabase + + +def pytest_configure(config): + sys._called_from_test = True + pytest._wait_defaults = {'timeout': 20000} + os.environ['LANG'] = 'en' # Ensure we test an English UI + + +@pytest.fixture(scope='session') +def qapp(tmpdir_factory): + # DB is required to init QApplication. New DB used for every test. + tmp_db = tmpdir_factory.mktemp('Vorta').join('settings.sqlite') + mock_db = SqliteDatabase(str(tmp_db)) + vorta.store.connection.init_db(mock_db) + + # Needs to be disabled before calling VortaApp() + if sys.platform == 'darwin': + cfg = vorta.store.models.SettingsModel.get(key='check_full_disk_access') + cfg.value = False + cfg.save() + + from vorta.application import VortaApp + + qapp = VortaApp([]) # Only init QApplication once to avoid segfaults while testing. + + yield qapp + mock_db.close() + qapp.quit() diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 702815136..6c3bd8f58 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -1,6 +1,5 @@ import os import subprocess -import sys import time import pytest @@ -34,34 +33,6 @@ ] -def pytest_configure(config): - sys._called_from_test = True - pytest._wait_defaults = {'timeout': 20000} - os.environ['LANG'] = 'en' # Ensure we test an English UI - - -@pytest.fixture(scope='session') -def qapp(tmpdir_factory): - # DB is required to init QApplication. New DB used for every test. - tmp_db = tmpdir_factory.mktemp('Vorta').join('settings.sqlite') - mock_db = SqliteDatabase(str(tmp_db)) - vorta.store.connection.init_db(mock_db) - - # Needs to be disabled before calling VortaApp() - if sys.platform == 'darwin': - cfg = vorta.store.models.SettingsModel.get(key='check_full_disk_access') - cfg.value = False - cfg.save() - - from vorta.application import VortaApp - - qapp = VortaApp([]) # Only init QApplication once to avoid segfaults while testing. - - yield qapp - mock_db.close() - qapp.quit() - - @pytest.fixture(scope='function', autouse=True) def create_test_repo(tmpdir_factory): repo_path = tmpdir_factory.mktemp('repo') @@ -203,16 +174,6 @@ def selectedFiles(self): return MockFileDialog -@pytest.fixture -def borg_json_output(): - def _read_json(subcommand): - stdout = open(f'tests/borg_json_output/{subcommand}_stdout.json') - stderr = open(f'tests/borg_json_output/{subcommand}_stderr.json') - return stdout, stderr - - return _read_json - - @pytest.fixture def rootdir(): return os.path.dirname(os.path.abspath(__file__)) diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index d6cbb8864..e2ac7d4f0 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -1,7 +1,5 @@ import os -import sys from datetime import datetime as dt -from unittest.mock import MagicMock import pytest import vorta @@ -34,37 +32,6 @@ ] -def pytest_configure(config): - sys._called_from_test = True - pytest._wait_defaults = {'timeout': 20000} - os.environ['LANG'] = 'en' # Ensure we test an English UI - - -@pytest.fixture(scope='session') -def qapp(tmpdir_factory): - # DB is required to init QApplication. New DB used for every test. - tmp_db = tmpdir_factory.mktemp('Vorta').join('settings.sqlite') - mock_db = SqliteDatabase(str(tmp_db)) - vorta.store.connection.init_db(mock_db) - - # Needs to be disabled before calling VortaApp() - if sys.platform == 'darwin': - cfg = vorta.store.models.SettingsModel.get(key='check_full_disk_access') - cfg.value = False - cfg.save() - - from vorta.application import VortaApp - - VortaApp.set_borg_details_action = MagicMock() # Can't use pytest-mock in session scope - VortaApp.scheduler = MagicMock() - - qapp = VortaApp([]) # Only init QApplication once to avoid segfaults while testing. - - yield qapp - mock_db.close() - qapp.quit() - - @pytest.fixture(scope='function', autouse=True) def init_db(qapp, qtbot, tmpdir_factory): tmp_db = tmpdir_factory.mktemp('Vorta').join('settings.sqlite') From ce942138b3be9720ee4bc89afb0ddee7872c777f Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 9 Jun 2023 03:03:33 -0400 Subject: [PATCH 16/69] Added nox to dev requirements and adjusted Makefile for nox and unit/integration tests Signed-off-by: Chirag Aggarwal --- Makefile | 8 +++++++- requirements.d/dev.txt | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7b6307b9a..5696346dd 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,13 @@ lint: pre-commit run --all-files --show-diff-on-failure test: - pytest --cov=vorta + nox -- --cov=vorta + +test-unit: + nox -- tests/unit + +test-integration: + nox -- tests/integration help: @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/requirements.d/dev.txt b/requirements.d/dev.txt index 239dfbff6..995bf2cb1 100644 --- a/requirements.d/dev.txt +++ b/requirements.d/dev.txt @@ -2,6 +2,7 @@ black==22.* coverage flake8 macholib +nox pre-commit pyinstaller pylint From 9067939d2ca6642287601885075efade9ca01e7b Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 9 Jun 2023 03:24:24 -0400 Subject: [PATCH 17/69] Added docstrings to test_archive.py Signed-off-by: Chirag Aggarwal --- tests/integration/test_archives.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index b16352de5..d8440145c 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -8,8 +8,13 @@ from PyQt6 import QtCore from vorta.store.models import ArchiveModel +""" +This file contains tests for the Archive tab to test the various archive related borg commands. +""" + def test_repo_list(qapp, qtbot): + """Test that the archives are created and repo list is populated correctly""" main = qapp.main_window tab = main.archiveTab @@ -26,6 +31,7 @@ def test_repo_list(qapp, qtbot): def test_repo_prune(qapp, qtbot): + """Test for archive pruning""" main = qapp.main_window tab = main.archiveTab @@ -42,6 +48,7 @@ def test_repo_prune(qapp, qtbot): not vorta.utils.borg_compat.check('COMPACT_SUBCOMMAND'), reason="Borg version does not support compact" ) def test_repo_compact(qapp, qtbot): + """Test for archive compaction""" main = qapp.main_window tab = main.archiveTab @@ -57,6 +64,7 @@ def test_repo_compact(qapp, qtbot): def test_check(qapp, qtbot): + """Test for archive consistency check""" main = qapp.main_window tab = main.archiveTab main.show() @@ -75,6 +83,8 @@ def test_check(qapp, qtbot): def test_mount(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): + """Test for archive mounting and unmounting""" + def psutil_disk_partitions(**kwargs): DiskPartitions = namedtuple('DiskPartitions', ['device', 'mountpoint']) return [DiskPartitions('borgfs', str(tmpdir))] @@ -107,6 +117,7 @@ def psutil_disk_partitions(**kwargs): def test_archive_extract(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): + """Test for archive extraction""" main = qapp.main_window tab = main.archiveTab @@ -131,6 +142,7 @@ def test_archive_extract(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): def test_archive_delete(qapp, qtbot, mocker): + """Test for archive deletion""" main = qapp.main_window tab = main.archiveTab @@ -151,6 +163,7 @@ def test_archive_delete(qapp, qtbot, mocker): def test_archive_rename(qapp, qtbot, mocker, borg_json_output): + """Test for archive renaming""" main = qapp.main_window tab = main.archiveTab From d19b83435aff0f033e1045953f015553598fdb72 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 9 Jun 2023 03:28:42 -0400 Subject: [PATCH 18/69] Added coverage to pytests Signed-off-by: Chirag Aggarwal --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5696346dd..9ca3e385f 100644 --- a/Makefile +++ b/Makefile @@ -63,10 +63,10 @@ test: nox -- --cov=vorta test-unit: - nox -- tests/unit + nox -- --cov=vorta tests/unit test-integration: - nox -- tests/integration + nox -- --cov=vorta tests/integration help: @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' From bb7c2f6c0bbdf4a8c331dd90aea6583e5ee6a09a Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 11 Jun 2023 12:10:07 -0400 Subject: [PATCH 19/69] Added all supported versions to nox Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 4 ++-- noxfile.py | 24 ++++++++++++++++++++---- tests/integration/conftest.py | 4 ++-- tests/integration/test_archives.py | 1 + 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 59ee4914e..39bfe0fb7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -43,10 +43,10 @@ jobs: if: runner.os == 'Linux' run: | sudo apt update && sudo apt install -y \ - xvfb libssl-dev openssl libacl1-dev libacl1 build-essential borgbackup \ + xvfb libssl-dev openssl libacl1-dev libacl1 fuse3 build-essential borgbackup \ libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \ - libegl1 libxcb-cursor0 + libegl1 libxcb-cursor0 libfuse-dev - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: | diff --git a/noxfile.py b/noxfile.py index 1f8b1cec3..6c2151f9d 100644 --- a/noxfile.py +++ b/noxfile.py @@ -4,12 +4,28 @@ @nox.session -# @nox.parametrize("borgbackup", ["2.0.0b5", "2.0.0b4"]) -# @nox.parametrize("borgbackup", ["1.1.18", "1.2.2", "1.2.3", "1.2.4"]) -@nox.parametrize("borgbackup", ["1.2.4"]) +# @nox.parametrize("borgbackup", ["1.1.18", "1.2.2", "1.2.3", "1.2.4", "2.0.0b5"]) +@nox.parametrize( + "python, borgbackup", + [ + (python, borgbackup) + # All supported Python and BorgBackup versions + for python in ("3.8", "3.9", "3.10", "3.11") + for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b5") + + # Python version requirements for borgbackup versions + if (borgbackup == "1.1.18" and python >= "3.5") + or (borgbackup == "1.2.2" and python >= "3.8") + or (borgbackup == "1.2.4" and python >= "3.8") + or (borgbackup == "2.0.0b5" and python >= "3.9") + ] +) def run_tests(session, borgbackup): # install borgbackup - session.install(f"borgbackup[pyfuse3]=={borgbackup}") + if (borgbackup == "1.1.18"): + session.install(f"borgbackup=={borgbackup}") + else: + session.install(f"borgbackup[pyfuse3]=={borgbackup}") # install dependencies session.install("-r", "requirements.d/dev.txt") diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 6c3bd8f58..57837dd01 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -56,8 +56,7 @@ def create_test_repo(tmpdir_factory): # Create first archive subprocess.run(['borg', 'create', f'{repo_path}::test-archive1', source_files_dir], cwd=str(repo_path), check=True) - # Sleep 1 second to prevent timestamp issue where both archives have the same timestamp causing issue with diff - time.sleep(1) + # time.sleep(1) # /src/dir/symlink symlink_path = os.path.join(dir_path, 'symlink') @@ -80,6 +79,7 @@ def create_test_repo(tmpdir_factory): os.mknod(chrdev_path, mode=0o600 | 0o020000) subprocess.run(['borg', 'create', f'{repo_path}::test-archive2', source_files_dir], cwd=str(repo_path), check=True) + time.sleep(1) # Rename dir to dir1 diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index d8440145c..e40acf141 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -82,6 +82,7 @@ def test_check(qapp, qtbot): qtbot.waitUntil(lambda: success_text in main.logText.text(), **pytest._wait_defaults) +# TODO: Skip on borg version less than 1.2.0 def test_mount(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): """Test for archive mounting and unmounting""" From a9c3da3d7374b8e1c457d5212dc8b88d8ff72f8b Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 11 Jun 2023 12:24:41 -0400 Subject: [PATCH 20/69] Changed GH action flow to install all required py versions Signed-off-by: Chirag Aggarwal --- .github/actions/setup/action.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 633ee06cf..14ad31fcf 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -11,18 +11,18 @@ inputs: description: Whether pre-commit shall be setup, too required: false default: "" # == false - python-version: - description: The python version to install - required: true - default: "3.10" runs: using: "composite" steps: - - name: Set up Python ${{ inputs.python-version }} + - name: Set up Python versions uses: actions/setup-python@v4 with: - python-version: ${{ inputs.python-version }} + python-version: | + 3.8 + 3.9 + 3.10 + 3.11 - name: Get pip cache dir shell: bash @@ -37,11 +37,11 @@ runs: restore-keys: | ${{ runner.os }}-pip- - - name: Install Vorta - shell: bash - run: | - pip install -e . - pip install -r requirements.d/dev.txt + # - name: Install Vorta + # shell: bash + # run: | + # pip install -e . + # pip install -r requirements.d/dev.txt - name: Hash python version if: ${{ inputs.setup-pre-commit }} From 7f8d1a308642aea1d7d2437a74a9d5d415dfa98b Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 14 Jun 2023 08:05:05 -0400 Subject: [PATCH 21/69] Completed borg diff testing Signed-off-by: Chirag Aggarwal --- tests/integration/conftest.py | 48 +++-- tests/integration/test_diff.py | 360 +++++++++++++++++++++++++++++++++ 2 files changed, 390 insertions(+), 18 deletions(-) create mode 100644 tests/integration/test_diff.py diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 57837dd01..1d9381e4b 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -1,6 +1,5 @@ import os import subprocess -import time import pytest import vorta @@ -55,8 +54,11 @@ def create_test_repo(tmpdir_factory): f.write('test') # Create first archive - subprocess.run(['borg', 'create', f'{repo_path}::test-archive1', source_files_dir], cwd=str(repo_path), check=True) - # time.sleep(1) + subprocess.run( + ['borg', 'create', '--timestamp', '2023-06-14T01:00:00', f'{repo_path}::test-archive1', source_files_dir], + cwd=str(repo_path), + check=True, + ) # /src/dir/symlink symlink_path = os.path.join(dir_path, 'symlink') @@ -70,43 +72,53 @@ def create_test_repo(tmpdir_factory): fifo_path = os.path.join(dir_path, 'fifo') os.mkfifo(fifo_path) - # /src/dir/socket - socket_path = os.path.join(dir_path, 'socket') - os.mknod(socket_path, mode=0o600 | 0o140000) - # /src/dir/chrdev chrdev_path = os.path.join(dir_path, 'chrdev') os.mknod(chrdev_path, mode=0o600 | 0o020000) - subprocess.run(['borg', 'create', f'{repo_path}::test-archive2', source_files_dir], cwd=str(repo_path), check=True) - - time.sleep(1) + subprocess.run( + ['borg', 'create', '--timestamp', '2023-06-14T02:00:00', f'{repo_path}::test-archive2', source_files_dir], + cwd=str(repo_path), + check=True, + ) # Rename dir to dir1 os.rename(dir_path, os.path.join(source_files_dir, 'dir1')) - subprocess.run(['borg', 'create', f'{repo_path}::test-archive3', source_files_dir], cwd=str(repo_path), check=True) - time.sleep(1) + subprocess.run( + ['borg', 'create', '--timestamp', '2023-06-14T03:00:00', f'{repo_path}::test-archive3', source_files_dir], + cwd=str(repo_path), + check=True, + ) # Rename all files under dir1 for file in os.listdir(os.path.join(source_files_dir, 'dir1')): os.rename(os.path.join(source_files_dir, 'dir1', file), os.path.join(source_files_dir, 'dir1', file + '1')) - subprocess.run(['borg', 'create', f'{repo_path}::test-archive4', source_files_dir], cwd=str(repo_path), check=True) - time.sleep(1) + subprocess.run( + ['borg', 'create', '--timestamp', '2023-06-14T04:00:00', f'{repo_path}::test-archive4', source_files_dir], + cwd=str(repo_path), + check=True, + ) # Delete all file under dir1 for file in os.listdir(os.path.join(source_files_dir, 'dir1')): os.remove(os.path.join(source_files_dir, 'dir1', file)) - subprocess.run(['borg', 'create', f'{repo_path}::test-archive5', source_files_dir], cwd=str(repo_path), check=True) - time.sleep(1) + subprocess.run( + ['borg', 'create', '--timestamp', '2023-06-14T05:00:00', f'{repo_path}::test-archive5', source_files_dir], + cwd=str(repo_path), + check=True, + ) # change permission of dir1 os.chmod(os.path.join(source_files_dir, 'dir1'), 0o700) - subprocess.run(['borg', 'create', f'{repo_path}::test-archive6', source_files_dir], cwd=str(repo_path), check=True) - time.sleep(1) + subprocess.run( + ['borg', 'create', '--timestamp', '2023-06-14T06:00:00', f'{repo_path}::test-archive6', source_files_dir], + cwd=str(repo_path), + check=True, + ) return repo_path, source_files_dir diff --git a/tests/integration/test_diff.py b/tests/integration/test_diff.py new file mode 100644 index 000000000..32d9a568e --- /dev/null +++ b/tests/integration/test_diff.py @@ -0,0 +1,360 @@ +import pytest +import vorta.borg +import vorta.utils +import vorta.views.archive_tab +from vorta.borg.diff import BorgDiffJob +from vorta.views.diff_result import ( + ChangeType, + DiffTree, + FileType, + ParseThread, +) + + +@pytest.mark.parametrize( + 'archive_name_1, archive_name_2, expected', + [ + ( + 'test-archive1', + 'test-archive2', + [ + { + 'subpath': 'dir', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.MODIFIED, + # 'changed_size': 0, + # 'size': 0, + # 'mode_change': None, + # 'owner_change': None, + # 'ctime_change': None, + # 'mtime_change': None, + 'modified': None, + }, + }, + { + 'subpath': 'file', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.MODIFIED, + 'modified': (0, 0), + }, + }, + { + 'subpath': 'chrdev', + 'data': { + 'file_type': FileType.CHRDEV, + 'change_type': ChangeType.ADDED, + 'modified': None, + }, + }, + { + 'subpath': 'fifo', + 'data': { + 'file_type': FileType.FIFO, + 'change_type': ChangeType.ADDED, + 'modified': None, + }, + }, + { + 'subpath': 'hardlink', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.ADDED, + 'modified': None, + }, + }, + { + 'subpath': 'symlink', + 'data': { + 'file_type': FileType.LINK, + 'change_type': ChangeType.ADDED, + 'modified': None, + }, + }, + ], + ), + ( + 'test-archive2', + 'test-archive3', + [ + { + 'subpath': 'borg_src1', + 'data': { + # TODO: Check/Review why file_type is FILE instead of DIRECTORY + 'file_type': FileType.FILE, + 'change_type': ChangeType.MODIFIED, + 'modified': None, + }, + }, + { + 'subpath': 'dir', + 'data': { + 'file_type': FileType.DIRECTORY, + 'change_type': ChangeType.REMOVED, + 'modified': None, + }, + }, + { + 'subpath': 'chrdev', + 'data': { + 'file_type': FileType.CHRDEV, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'fifo', + 'data': { + 'file_type': FileType.FIFO, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'file', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'hardlink', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'symlink', + 'data': { + 'file_type': FileType.LINK, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'dir1', + 'data': { + 'file_type': FileType.DIRECTORY, + 'change_type': ChangeType.ADDED, + }, + }, + { + 'subpath': 'chrdev', + 'data': { + 'file_type': FileType.CHRDEV, + 'change_type': ChangeType.ADDED, + }, + }, + { + 'subpath': 'fifo', + 'data': { + 'file_type': FileType.FIFO, + 'change_type': ChangeType.ADDED, + }, + }, + { + 'subpath': 'file', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.ADDED, + }, + }, + { + 'subpath': 'hardlink', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.ADDED, + }, + }, + { + 'subpath': 'symlink', + 'data': { + 'file_type': FileType.LINK, + 'change_type': ChangeType.ADDED, + }, + }, + ], + ), + ( + 'test-archive3', + 'test-archive4', + [ + { + 'subpath': 'dir1', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.MODIFIED, + }, + }, + { + 'subpath': 'chrdev', + 'data': { + 'file_type': FileType.CHRDEV, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'chrdev1', + 'data': { + 'file_type': FileType.CHRDEV, + 'change_type': ChangeType.ADDED, + }, + }, + { + 'subpath': 'fifo', + 'data': { + 'file_type': FileType.FIFO, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'fifo1', + 'data': { + 'file_type': FileType.FIFO, + 'change_type': ChangeType.ADDED, + }, + }, + { + 'subpath': 'file', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'file1', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.ADDED, + }, + }, + { + 'subpath': 'hardlink', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'hardlink1', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.ADDED, + }, + }, + { + 'subpath': 'symlink', + 'data': { + 'file_type': FileType.LINK, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'symlink1', + 'data': { + 'file_type': FileType.LINK, + 'change_type': ChangeType.ADDED, + }, + }, + ], + ), + ( + 'test-archive4', + 'test-archive5', + [ + { + 'subpath': 'dir1', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.MODIFIED, + }, + }, + { + 'subpath': 'chrdev1', + 'data': { + 'file_type': FileType.CHRDEV, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'fifo1', + 'data': { + 'file_type': FileType.FIFO, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'file1', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'hardlink1', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.REMOVED, + }, + }, + { + 'subpath': 'symlink1', + 'data': { + 'file_type': FileType.LINK, + 'change_type': ChangeType.REMOVED, + }, + }, + ], + ), + ( + 'test-archive5', + 'test-archive6', + [ + { + 'subpath': 'dir1', + 'data': { + 'file_type': FileType.FILE, + 'change_type': ChangeType.MODIFIED, + }, + }, + ], + ), + ], +) +def test_archive_diff_lines(qapp, qtbot, archive_name_1, archive_name_2, expected): + main = qapp.main_window + tab = main.archiveTab + + main.tabWidget.setCurrentIndex(3) + tab.refresh_archive_list() + qtbot.waitUntil(lambda: not tab.bCheck.isEnabled(), **pytest._wait_defaults) + + params = BorgDiffJob.prepare(vorta.store.models.BackupProfileModel.select().first(), archive_name_1, archive_name_2) + thread = BorgDiffJob(params['cmd'], params, qapp) + + with qtbot.waitSignal(thread.result, **pytest._wait_defaults) as blocker: + blocker.connect(thread.updated) + thread.run() + + diff_lines = blocker.args[0]['data'] + json_lines = blocker.args[0]['params']['json_lines'] + + model = DiffTree() + model.setMode(model.DisplayMode.FLAT) + + # Use ParseThread to parse the diff lines + parse_thread = ParseThread(diff_lines, json_lines, model) + parse_thread.start() + qtbot.waitUntil(lambda: parse_thread.isFinished(), **pytest._wait_defaults) + + assert model.rowCount() == len(expected) + + for index, item in enumerate(expected): + assert model.index(index, 0).internalPointer().subpath == item['subpath'] + + # Checking all attributes for every line will produce very large testing output and will be difficult to debug + # So we will check only the attributes we are interested in + # TODO: Remove below line above code review + # assert model.index(index, 0).internalPointer().data == DiffData(**item['data']) + + for key, value in item['data'].items(): + assert getattr(model.index(index, 0).internalPointer().data, key) == value From 56827da8c9bb081f942421f37998d607ee61275a Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 14 Jun 2023 08:10:10 -0400 Subject: [PATCH 22/69] Removed unnecessary code from diff test Signed-off-by: Chirag Aggarwal --- tests/integration/test_diff.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/integration/test_diff.py b/tests/integration/test_diff.py index 32d9a568e..d48067b01 100644 --- a/tests/integration/test_diff.py +++ b/tests/integration/test_diff.py @@ -321,13 +321,6 @@ ], ) def test_archive_diff_lines(qapp, qtbot, archive_name_1, archive_name_2, expected): - main = qapp.main_window - tab = main.archiveTab - - main.tabWidget.setCurrentIndex(3) - tab.refresh_archive_list() - qtbot.waitUntil(lambda: not tab.bCheck.isEnabled(), **pytest._wait_defaults) - params = BorgDiffJob.prepare(vorta.store.models.BackupProfileModel.select().first(), archive_name_1, archive_name_2) thread = BorgDiffJob(params['cmd'], params, qapp) From 3e4a462e706ab77dc6a3f8a18b5b6b73875333e1 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 14 Jun 2023 09:17:04 -0400 Subject: [PATCH 23/69] Added a min borg version fixture Signed-off-by: Chirag Aggarwal --- .github/actions/setup/action.yml | 4 ++++ .github/workflows/test.yml | 2 +- noxfile.py | 5 ++++- tests/integration/conftest.py | 26 ++++++++++++++++++++++++++ tests/integration/test_archives.py | 6 ++---- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 14ad31fcf..1b4aa33a3 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -43,6 +43,10 @@ runs: # pip install -e . # pip install -r requirements.d/dev.txt + - name: Install Nox + shell: bash + run: pip install nox + - name: Hash python version if: ${{ inputs.setup-pre-commit }} shell: bash diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 39bfe0fb7..7bd2c7af5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,7 +46,7 @@ jobs: xvfb libssl-dev openssl libacl1-dev libacl1 fuse3 build-essential borgbackup \ libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \ - libegl1 libxcb-cursor0 libfuse-dev + libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: | diff --git a/noxfile.py b/noxfile.py index 6c2151f9d..4e99353c3 100644 --- a/noxfile.py +++ b/noxfile.py @@ -22,6 +22,7 @@ ) def run_tests(session, borgbackup): # install borgbackup + pass if (borgbackup == "1.1.18"): session.install(f"borgbackup=={borgbackup}") else: @@ -43,4 +44,6 @@ def run_tests(session, borgbackup): assert python_version == borgbackup # run tests - session.run("pytest", *session.posargs) + # session.run("pytest", *session.posargs) + # pass borgbackup version as environment variable + session.run("pytest", *session.posargs, env={"BORG_VERSION": borgbackup}) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 1d9381e4b..3ae1f7a59 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -6,6 +6,7 @@ import vorta.application import vorta.borg.jobs_manager from peewee import SqliteDatabase +from pkg_resources import parse_version from vorta.store.models import ( ArchiveModel, BackupProfileModel, @@ -189,3 +190,28 @@ def selectedFiles(self): @pytest.fixture def rootdir(): return os.path.dirname(os.path.abspath(__file__)) + + +@pytest.fixture(autouse=True) +def min_borg_version(qapp, request): + if request.node.get_closest_marker('min_borg_version'): + borg_version = os.getenv('BORG_VERSION') + if not borg_version: + borg_version = subprocess.run(['borg', '--version'], stdout=subprocess.PIPE).stdout.decode('utf-8') + borg_version = borg_version.split(' ')[1] + + parsed_borg_version = parse_version(borg_version) + + if parsed_borg_version < parse_version(request.node.get_closest_marker('min_borg_version').args[0]): + pytest.skip( + 'skipped due to borg version requirement for test: {}'.format( + request.node.get_closest_marker('min_borg_version').args[0] + ) + ) + + +def pytest_configure(config): + config.addinivalue_line( + "markers", + "min_borg_version(): set minimum required borg version for a test", + ) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index e40acf141..922e08ca1 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -44,9 +44,7 @@ def test_repo_prune(qapp, qtbot): qtbot.waitUntil(lambda: 'Refreshing archives done.' in main.progressText.text(), **pytest._wait_defaults) -@pytest.mark.skipif( - not vorta.utils.borg_compat.check('COMPACT_SUBCOMMAND'), reason="Borg version does not support compact" -) +@pytest.mark.min_borg_version('1.2.0a1') def test_repo_compact(qapp, qtbot): """Test for archive compaction""" main = qapp.main_window @@ -82,7 +80,7 @@ def test_check(qapp, qtbot): qtbot.waitUntil(lambda: success_text in main.logText.text(), **pytest._wait_defaults) -# TODO: Skip on borg version less than 1.2.0 +@pytest.mark.min_borg_version('1.2.0') def test_mount(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): """Test for archive mounting and unmounting""" From d12dd086d11802876df51d03bf9ca7c2a6fed9e5 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 14 Jun 2023 09:24:18 -0400 Subject: [PATCH 24/69] Added libfuse3-dev to linux requirement for fuse3 Signed-off-by: Chirag Aggarwal --- .github/actions/setup/action.yml | 5 +++++ .github/workflows/test.yml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 1b4aa33a3..16ae4b4ad 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -47,6 +47,11 @@ runs: shell: bash run: pip install nox + - name: Install pre-commit + if: ${{ inputs.setup-pre-commit }} + shell: bash + run: pip install pre-commit + - name: Hash python version if: ${{ inputs.setup-pre-commit }} shell: bash diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7bd2c7af5..7c11f5a0b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,7 +46,7 @@ jobs: xvfb libssl-dev openssl libacl1-dev libacl1 fuse3 build-essential borgbackup \ libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \ - libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev + libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev libfuse3-dev - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: | From 725b6b024b6703acb9f1a2598e4f22a0cedb9698 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 20 Jun 2023 13:18:17 -0400 Subject: [PATCH 25/69] Added various compatibility check for platform and borg versions Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 19 ++++++-- tests/integration/conftest.py | 89 ++++++++++++++++++---------------- tests/integration/test_diff.py | 56 +++++++++++++++------ 3 files changed, 104 insertions(+), 60 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7c11f5a0b..7f95a24c9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -61,14 +61,25 @@ jobs: uses: mxschmitt/action-tmate@v3 if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} - - name: Test with pytest (Linux) + - name: Run Unit Tests with pytest (Linux) if: runner.os == 'Linux' run: | xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test - - name: Test with pytest (macOS) + -a dbus-run-session -- make test-unit + + - name: Run Unit Tests with pytest (macOS) + if: runner.os == 'macOS' + run: make test-unit + + - name: Run Integration Tests with pytest (Linux) + if: runner.os == 'Linux' + run: | + xvfb-run --server-args="-screen 0 1024x768x24+32" \ + -a dbus-run-session -- make test-integration + + - name: Run Integration Tests with pytest (macOS) if: runner.os == 'macOS' - run: make test + run: make test-integration - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 3ae1f7a59..45fb04510 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -1,5 +1,6 @@ import os import subprocess +import sys import pytest import vorta @@ -18,6 +19,7 @@ SourceFileModel, WifiSettingModel, ) +from vorta.utils import borg_compat from vorta.views.main_window import MainWindow models = [ @@ -33,12 +35,45 @@ ] +@pytest.fixture +def borg_version(): + borg_version = os.getenv('BORG_VERSION') + if not borg_version: + borg_version = subprocess.run(['borg', '--version'], stdout=subprocess.PIPE).stdout.decode('utf-8') + borg_version = borg_version.split(' ')[1] + + # test window does not automatically set borg version + borg_compat.set_version(borg_version, borg_compat.path) + + parsed_borg_version = parse_version(borg_version) + return borg_version, parsed_borg_version + + @pytest.fixture(scope='function', autouse=True) -def create_test_repo(tmpdir_factory): +def create_test_repo(tmpdir_factory, borg_version): repo_path = tmpdir_factory.mktemp('repo') source_files_dir = tmpdir_factory.mktemp('borg_src') - subprocess.run(['borg', 'init', '--encryption=none', str(repo_path)], check=True) + is_borg_v2 = borg_version[1] >= parse_version('2.0.0b1') + + if is_borg_v2: + subprocess.run(['borg', '-r', str(repo_path), 'rcreate', '--encryption=none'], check=True) + else: + subprocess.run(['borg', 'init', '--encryption=none', str(repo_path)], check=True) + + def create_archive(timestamp, name): + if is_borg_v2: + subprocess.run( + ['borg', '-r', str(repo_path), 'create', '--timestamp', timestamp, name, str(source_files_dir)], + cwd=str(repo_path), + check=True, + ) + else: + subprocess.run( + ['borg', 'create', '--timestamp', timestamp, f'{repo_path}::{name}', str(source_files_dir)], + cwd=str(repo_path), + check=True, + ) # /src/file file_path = os.path.join(source_files_dir, 'file') @@ -55,11 +90,7 @@ def create_test_repo(tmpdir_factory): f.write('test') # Create first archive - subprocess.run( - ['borg', 'create', '--timestamp', '2023-06-14T01:00:00', f'{repo_path}::test-archive1', source_files_dir], - cwd=str(repo_path), - check=True, - ) + create_archive('2023-06-14T01:00:00', 'test-archive1') # /src/dir/symlink symlink_path = os.path.join(dir_path, 'symlink') @@ -74,52 +105,33 @@ def create_test_repo(tmpdir_factory): os.mkfifo(fifo_path) # /src/dir/chrdev - chrdev_path = os.path.join(dir_path, 'chrdev') - os.mknod(chrdev_path, mode=0o600 | 0o020000) + if sys.platform.startswith('linux'): + chrdev_path = os.path.join(dir_path, 'chrdev') + os.mknod(chrdev_path, mode=0o600 | 0o020000) - subprocess.run( - ['borg', 'create', '--timestamp', '2023-06-14T02:00:00', f'{repo_path}::test-archive2', source_files_dir], - cwd=str(repo_path), - check=True, - ) + create_archive('2023-06-14T02:00:00', 'test-archive2') # Rename dir to dir1 os.rename(dir_path, os.path.join(source_files_dir, 'dir1')) - subprocess.run( - ['borg', 'create', '--timestamp', '2023-06-14T03:00:00', f'{repo_path}::test-archive3', source_files_dir], - cwd=str(repo_path), - check=True, - ) + create_archive('2023-06-14T03:00:00', 'test-archive3') # Rename all files under dir1 for file in os.listdir(os.path.join(source_files_dir, 'dir1')): os.rename(os.path.join(source_files_dir, 'dir1', file), os.path.join(source_files_dir, 'dir1', file + '1')) - subprocess.run( - ['borg', 'create', '--timestamp', '2023-06-14T04:00:00', f'{repo_path}::test-archive4', source_files_dir], - cwd=str(repo_path), - check=True, - ) + create_archive('2023-06-14T04:00:00', 'test-archive4') # Delete all file under dir1 for file in os.listdir(os.path.join(source_files_dir, 'dir1')): os.remove(os.path.join(source_files_dir, 'dir1', file)) - subprocess.run( - ['borg', 'create', '--timestamp', '2023-06-14T05:00:00', f'{repo_path}::test-archive5', source_files_dir], - cwd=str(repo_path), - check=True, - ) + create_archive('2023-06-14T05:00:00', 'test-archive5') # change permission of dir1 os.chmod(os.path.join(source_files_dir, 'dir1'), 0o700) - subprocess.run( - ['borg', 'create', '--timestamp', '2023-06-14T06:00:00', f'{repo_path}::test-archive6', source_files_dir], - cwd=str(repo_path), - check=True, - ) + create_archive('2023-06-14T06:00:00', 'test-archive6') return repo_path, source_files_dir @@ -193,14 +205,9 @@ def rootdir(): @pytest.fixture(autouse=True) -def min_borg_version(qapp, request): +def min_borg_version(borg_version, request): if request.node.get_closest_marker('min_borg_version'): - borg_version = os.getenv('BORG_VERSION') - if not borg_version: - borg_version = subprocess.run(['borg', '--version'], stdout=subprocess.PIPE).stdout.decode('utf-8') - borg_version = borg_version.split(' ')[1] - - parsed_borg_version = parse_version(borg_version) + parsed_borg_version = borg_version[1] if parsed_borg_version < parse_version(request.node.get_closest_marker('min_borg_version').args[0]): pytest.skip( diff --git a/tests/integration/test_diff.py b/tests/integration/test_diff.py index d48067b01..628290984 100644 --- a/tests/integration/test_diff.py +++ b/tests/integration/test_diff.py @@ -1,7 +1,10 @@ +import sys + import pytest import vorta.borg import vorta.utils import vorta.views.archive_tab +from pkg_resources import parse_version from vorta.borg.diff import BorgDiffJob from vorta.views.diff_result import ( ChangeType, @@ -23,14 +26,10 @@ 'data': { 'file_type': FileType.FILE, 'change_type': ChangeType.MODIFIED, - # 'changed_size': 0, - # 'size': 0, - # 'mode_change': None, - # 'owner_change': None, - # 'ctime_change': None, - # 'mtime_change': None, 'modified': None, }, + 'min_version': '1.2.4', + 'max_version': '1.2.4', }, { 'subpath': 'file', @@ -39,6 +38,8 @@ 'change_type': ChangeType.MODIFIED, 'modified': (0, 0), }, + 'min_version': '1.2.4', + 'max_version': '1.2.4', }, { 'subpath': 'chrdev', @@ -86,6 +87,8 @@ 'change_type': ChangeType.MODIFIED, 'modified': None, }, + 'min_version': '1.2.4', + 'max_version': '1.2.4', }, { 'subpath': 'dir', @@ -184,6 +187,8 @@ 'file_type': FileType.FILE, 'change_type': ChangeType.MODIFIED, }, + 'min_version': '1.2.4', + 'max_version': '1.2.4', }, { 'subpath': 'chrdev', @@ -267,6 +272,8 @@ 'file_type': FileType.FILE, 'change_type': ChangeType.MODIFIED, }, + 'min_version': '1.2.4', + 'max_version': '1.2.4', }, { 'subpath': 'chrdev1', @@ -315,12 +322,18 @@ 'file_type': FileType.FILE, 'change_type': ChangeType.MODIFIED, }, + 'min_version': '1.2.4', + 'max_version': '1.2.4', }, ], ), ], ) -def test_archive_diff_lines(qapp, qtbot, archive_name_1, archive_name_2, expected): +def test_archive_diff_lines(qapp, qtbot, borg_version, archive_name_1, archive_name_2, expected): + parsed_borg_version = borg_version[1] + supports_fifo = parsed_borg_version > parse_version('1.1.18') + supports_chrdev = sys.platform.startswith('linux') + params = BorgDiffJob.prepare(vorta.store.models.BackupProfileModel.select().first(), archive_name_1, archive_name_2) thread = BorgDiffJob(params['cmd'], params, qapp) @@ -339,15 +352,28 @@ def test_archive_diff_lines(qapp, qtbot, archive_name_1, archive_name_2, expecte parse_thread.start() qtbot.waitUntil(lambda: parse_thread.isFinished(), **pytest._wait_defaults) - assert model.rowCount() == len(expected) + expected = [ + item + for item in expected + if ( + ('min_version' not in item or parse_version(item['min_version']) <= parsed_borg_version) + and ('max_version' not in item or parse_version(item['max_version']) >= parsed_borg_version) + and (item['data']['file_type'] != FileType.FIFO or supports_fifo) + and (item['data']['file_type'] != FileType.CHRDEV or supports_chrdev) + ) + ] - for index, item in enumerate(expected): - assert model.index(index, 0).internalPointer().subpath == item['subpath'] + # diff versions of borg produce inconsistent ordering of diff lines so we sort the expected and model + expected = sorted(expected, key=lambda item: item['subpath']) + sorted_model = sorted( + [model.index(index, 0).internalPointer() for index in range(model.rowCount())], + key=lambda item: item.subpath, + ) - # Checking all attributes for every line will produce very large testing output and will be difficult to debug - # So we will check only the attributes we are interested in - # TODO: Remove below line above code review - # assert model.index(index, 0).internalPointer().data == DiffData(**item['data']) + assert len(sorted_model) == len(expected) + + for index, item in enumerate(expected): + assert sorted_model[index].subpath == item['subpath'] for key, value in item['data'].items(): - assert getattr(model.index(index, 0).internalPointer().data, key) == value + assert getattr(sorted_model[index].data, key) == value From 9a0c1c9e41f27da76d4a66a9e4d1c16157c53f9c Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 20 Jun 2023 13:26:33 -0400 Subject: [PATCH 26/69] GH CI temp speedup Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7f95a24c9..5a0e1dce4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -61,15 +61,17 @@ jobs: uses: mxschmitt/action-tmate@v3 if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} - - name: Run Unit Tests with pytest (Linux) - if: runner.os == 'Linux' - run: | - xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test-unit + # TODO: Re-enable unit tests (currently disabled for quick) + # TODO: Merge unit tests back to integration to speed up CI + # - name: Run Unit Tests with pytest (Linux) + # if: runner.os == 'Linux' + # run: | + # xvfb-run --server-args="-screen 0 1024x768x24+32" \ + # -a dbus-run-session -- make test-unit - - name: Run Unit Tests with pytest (macOS) - if: runner.os == 'macOS' - run: make test-unit + # - name: Run Unit Tests with pytest (macOS) + # if: runner.os == 'macOS' + # run: make test-unit - name: Run Integration Tests with pytest (Linux) if: runner.os == 'Linux' From ce33f9ec2ce5c7e50973c5414282a44ffc4a307d Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 20 Jun 2023 13:32:58 -0400 Subject: [PATCH 27/69] Solve borg_json_output not found error on archive rename test Signed-off-by: Chirag Aggarwal --- noxfile.py | 4 +--- tests/integration/conftest.py | 2 +- tests/integration/test_archives.py | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/noxfile.py b/noxfile.py index 4e99353c3..1a9a0edf9 100644 --- a/noxfile.py +++ b/noxfile.py @@ -43,7 +43,5 @@ def run_tests(session, borgbackup): assert cli_version == borgbackup assert python_version == borgbackup - # run tests - # session.run("pytest", *session.posargs) - # pass borgbackup version as environment variable + session.log(f"Running tests with BorgBackup {borgbackup} and Python {python_version}") session.run("pytest", *session.posargs, env={"BORG_VERSION": borgbackup}) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 45fb04510..8b4aab4db 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -35,7 +35,7 @@ ] -@pytest.fixture +@pytest.fixture(scope='function', autouse=True) def borg_version(): borg_version = os.getenv('BORG_VERSION') if not borg_version: diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 922e08ca1..414ff0895 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -161,7 +161,7 @@ def test_archive_delete(qapp, qtbot, mocker): assert tab.archiveTable.rowCount() == archivesCount - 1 -def test_archive_rename(qapp, qtbot, mocker, borg_json_output): +def test_archive_rename(qapp, qtbot, mocker): """Test for archive renaming""" main = qapp.main_window tab = main.archiveTab From 4a6c778d7db8fa5db22885d4c52b27ff08a08609 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 20 Jun 2023 13:40:05 -0400 Subject: [PATCH 28/69] Fixed test_borg_repo_info error with invalid repo path Signed-off-by: Chirag Aggarwal --- tests/integration/test_borg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_borg.py b/tests/integration/test_borg.py index d474e0794..e9ae9bb57 100644 --- a/tests/integration/test_borg.py +++ b/tests/integration/test_borg.py @@ -23,7 +23,7 @@ def test_borg_prune(qapp, qtbot): # test borg info def test_borg_repo_info(qapp, qtbot, tmpdir): repo_info = { - 'repo_url': str(Path(tmpdir).parent / 'repo'), + 'repo_url': str(Path(tmpdir).parent / 'repo0'), 'extra_borg_arguments': '', 'ssh_key': '', 'password': '', From db5d6bbf14e64b7e6ddcdf917c0f5c81151e9462 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 20 Jun 2023 13:47:37 -0400 Subject: [PATCH 29/69] Macos does not use tmp for tmpdir, fix Signed-off-by: Chirag Aggarwal --- tests/integration/test_archives.py | 3 ++- tests/integration/test_borg.py | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 414ff0895..7883a2c81 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -1,3 +1,4 @@ +import sys from collections import namedtuple import psutil @@ -137,7 +138,7 @@ def test_archive_extract(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): qtbot.waitUntil(lambda: 'Restored files from archive.' in main.progressText.text(), **pytest._wait_defaults) - assert [item.basename for item in tmpdir.listdir()] == ['tmp'] + assert [item.basename for item in tmpdir.listdir()] == ['private' if sys.platform == 'darwin' else 'tmp'] def test_archive_delete(qapp, qtbot, mocker): diff --git a/tests/integration/test_borg.py b/tests/integration/test_borg.py index e9ae9bb57..2e93f29bb 100644 --- a/tests/integration/test_borg.py +++ b/tests/integration/test_borg.py @@ -9,7 +9,6 @@ def test_borg_prune(qapp, qtbot): - params = BorgPruneJob.prepare(vorta.store.models.BackupProfileModel.select().first()) thread = BorgPruneJob(params['cmd'], params, qapp) From 6ecdec47fc2645e1e922fac8411fc708225e3fbd Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 20 Jun 2023 13:53:49 -0400 Subject: [PATCH 30/69] Require pkgconfig to install borg 1.2.0 and above using pip Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 2 +- requirements.d/dev.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5a0e1dce4..ef2604dc3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,7 +46,7 @@ jobs: xvfb libssl-dev openssl libacl1-dev libacl1 fuse3 build-essential borgbackup \ libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \ - libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev libfuse3-dev + libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev libfuse3-dev pkg-config python3-pkgconfig - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: | diff --git a/requirements.d/dev.txt b/requirements.d/dev.txt index 995bf2cb1..8db4a0304 100644 --- a/requirements.d/dev.txt +++ b/requirements.d/dev.txt @@ -3,6 +3,7 @@ coverage flake8 macholib nox +pkg-config pre-commit pyinstaller pylint From da05507a7227192711f36f79f3e710ae316832c1 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 20 Jun 2023 13:57:33 -0400 Subject: [PATCH 31/69] pkg-config -> pkgconfig Signed-off-by: Chirag Aggarwal --- requirements.d/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.d/dev.txt b/requirements.d/dev.txt index 8db4a0304..5391c54a0 100644 --- a/requirements.d/dev.txt +++ b/requirements.d/dev.txt @@ -3,7 +3,7 @@ coverage flake8 macholib nox -pkg-config +pkgconfig pre-commit pyinstaller pylint From a1c71901b88e4e4f59284b9629c1469e7f49456b Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 23 Jun 2023 07:57:00 -0400 Subject: [PATCH 32/69] tmpdir appends integer to generate unique directory for diff tests run, use startsWith to match them Signed-off-by: Chirag Aggarwal --- noxfile.py | 2 -- tests/integration/test_diff.py | 8 ++++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/noxfile.py b/noxfile.py index 1a9a0edf9..ad54093ba 100644 --- a/noxfile.py +++ b/noxfile.py @@ -22,7 +22,6 @@ ) def run_tests(session, borgbackup): # install borgbackup - pass if (borgbackup == "1.1.18"): session.install(f"borgbackup=={borgbackup}") else: @@ -43,5 +42,4 @@ def run_tests(session, borgbackup): assert cli_version == borgbackup assert python_version == borgbackup - session.log(f"Running tests with BorgBackup {borgbackup} and Python {python_version}") session.run("pytest", *session.posargs, env={"BORG_VERSION": borgbackup}) diff --git a/tests/integration/test_diff.py b/tests/integration/test_diff.py index 628290984..7fa89e185 100644 --- a/tests/integration/test_diff.py +++ b/tests/integration/test_diff.py @@ -80,7 +80,8 @@ 'test-archive3', [ { - 'subpath': 'borg_src1', + 'subpath': 'borg_src', + 'match_startsWith': True, 'data': { # TODO: Check/Review why file_type is FILE instead of DIRECTORY 'file_type': FileType.FILE, @@ -373,7 +374,10 @@ def test_archive_diff_lines(qapp, qtbot, borg_version, archive_name_1, archive_n assert len(sorted_model) == len(expected) for index, item in enumerate(expected): - assert sorted_model[index].subpath == item['subpath'] + if 'match_startsWith' in item and item['match_startsWith']: + assert sorted_model[index].subpath.startswith(item['subpath']) + else: + assert sorted_model[index].subpath == item['subpath'] for key, value in item['data'].items(): assert getattr(sorted_model[index].data, key) == value From 914a35abd1aa9f3ce15a19edeb316581324232a6 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 23 Jun 2023 08:11:17 -0400 Subject: [PATCH 33/69] Always install pre-commit Signed-off-by: Chirag Aggarwal --- .github/actions/setup/action.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 16ae4b4ad..f80a77679 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -37,25 +37,22 @@ runs: restore-keys: | ${{ runner.os }}-pip- + # TODO: # - name: Install Vorta # shell: bash # run: | # pip install -e . # pip install -r requirements.d/dev.txt - - name: Install Nox + - name: Install Nox and pre-commit shell: bash - run: pip install nox - - - name: Install pre-commit - if: ${{ inputs.setup-pre-commit }} - shell: bash - run: pip install pre-commit + run: pip install nox pre-commit - name: Hash python version if: ${{ inputs.setup-pre-commit }} shell: bash run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV + - name: Caching for Pre-Commit if: ${{ inputs.setup-pre-commit }} uses: actions/cache@v3 From 79d247e35487f39722306ed086389a2b467c6cdf Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 23 Jun 2023 08:47:37 -0400 Subject: [PATCH 34/69] Install libxxhash-dev for linux Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ef2604dc3..de8c6b497 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,7 +19,7 @@ jobs: - name: Setup python, vorta and dev deps uses: ./.github/actions/setup with: - python-version: 3.11 + # python-version: 3.11 pre-commit: true - name: Test formatting with Flake8, ruff and Black @@ -46,7 +46,7 @@ jobs: xvfb libssl-dev openssl libacl1-dev libacl1 fuse3 build-essential borgbackup \ libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \ - libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev libfuse3-dev pkg-config python3-pkgconfig + libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev libfuse3-dev pkg-config python3-pkgconfig libxxhash-dev - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: | From 9a19d90ab740c4865bc698bb2a84f04b585a3e37 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 23 Jun 2023 09:05:48 -0400 Subject: [PATCH 35/69] Set PKG_CONFIG_PATH for macos Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 4 +++- tests/integration/test_archives.py | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index de8c6b497..45d68c71a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -47,10 +47,12 @@ jobs: libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \ libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev libfuse3-dev pkg-config python3-pkgconfig libxxhash-dev + - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: | - brew install openssl readline xz borgbackup + brew install openssl readline xz borgbackup \ + && echo "PKG_CONFIG_PATH=/usr/local/opt/openssl@3/lib/pkgconfig" >> $GITHUB_ENV - name: Setup python, vorta and dev deps uses: ./.github/actions/setup diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 7883a2c81..119813299 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -1,3 +1,7 @@ +""" +This file contains tests for the Archive tab to test the various archive related borg commands. +""" + import sys from collections import namedtuple @@ -9,10 +13,6 @@ from PyQt6 import QtCore from vorta.store.models import ArchiveModel -""" -This file contains tests for the Archive tab to test the various archive related borg commands. -""" - def test_repo_list(qapp, qtbot): """Test that the archives are created and repo list is populated correctly""" From ec8710442f699bf6df264d802cb19a7d8d78e6a7 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 24 Jun 2023 10:10:33 -0400 Subject: [PATCH 36/69] Remove python parameterization from nox Signed-off-by: Chirag Aggarwal --- .github/actions/setup/action.yml | 13 ++++++------- .github/workflows/test.yml | 13 +------------ noxfile.py | 31 +++++++++++++++---------------- 3 files changed, 22 insertions(+), 35 deletions(-) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index f80a77679..bd0ecd9ba 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -11,18 +11,17 @@ inputs: description: Whether pre-commit shall be setup, too required: false default: "" # == false - + python-version: + description: The python version to install + required: true + default: "3.10" runs: using: "composite" steps: - - name: Set up Python versions + - name: Set up Python ${{ inputs.python-version }} uses: actions/setup-python@v4 with: - python-version: | - 3.8 - 3.9 - 3.10 - 3.11 + python-version: ${{ inputs.python-version }} - name: Get pip cache dir shell: bash diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 45d68c71a..c90ef6946 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -63,18 +63,6 @@ jobs: uses: mxschmitt/action-tmate@v3 if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} - # TODO: Re-enable unit tests (currently disabled for quick) - # TODO: Merge unit tests back to integration to speed up CI - # - name: Run Unit Tests with pytest (Linux) - # if: runner.os == 'Linux' - # run: | - # xvfb-run --server-args="-screen 0 1024x768x24+32" \ - # -a dbus-run-session -- make test-unit - - # - name: Run Unit Tests with pytest (macOS) - # if: runner.os == 'macOS' - # run: make test-unit - - name: Run Integration Tests with pytest (Linux) if: runner.os == 'Linux' run: | @@ -83,6 +71,7 @@ jobs: - name: Run Integration Tests with pytest (macOS) if: runner.os == 'macOS' + # TODO: Change integration to all tests run: make test-integration - name: Upload coverage to Codecov diff --git a/noxfile.py b/noxfile.py index ad54093ba..b5f278c82 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,25 +1,24 @@ +import platform import re import nox +system_python_version = platform.python_version_tuple() +system_python_version = tuple(int(part) for part in system_python_version) + +supported_borgbackup_versions = [ + borgbackup + for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b5") + # Python version requirements for borgbackup versions + if (borgbackup == "1.1.18" and system_python_version >= (3, 5, 0)) + or (borgbackup == "1.2.2" and system_python_version >= (3, 8, 0)) + or (borgbackup == "1.2.4" and system_python_version >= (3, 8, 0)) + or (borgbackup == "2.0.0b5" and system_python_version >= (3, 9, 0)) +] + @nox.session -# @nox.parametrize("borgbackup", ["1.1.18", "1.2.2", "1.2.3", "1.2.4", "2.0.0b5"]) -@nox.parametrize( - "python, borgbackup", - [ - (python, borgbackup) - # All supported Python and BorgBackup versions - for python in ("3.8", "3.9", "3.10", "3.11") - for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b5") - - # Python version requirements for borgbackup versions - if (borgbackup == "1.1.18" and python >= "3.5") - or (borgbackup == "1.2.2" and python >= "3.8") - or (borgbackup == "1.2.4" and python >= "3.8") - or (borgbackup == "2.0.0b5" and python >= "3.9") - ] -) +@nox.parametrize("borgbackup", supported_borgbackup_versions) def run_tests(session, borgbackup): # install borgbackup if (borgbackup == "1.1.18"): From 282c119788bfd1cf037946f0c854814d794f5960 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 24 Jun 2023 10:16:53 -0400 Subject: [PATCH 37/69] Trial | Restore nox python parameterization with increased timeout Signed-off-by: Chirag Aggarwal --- .github/actions/setup/action.yml | 8 ++++++-- .github/workflows/test.yml | 2 +- noxfile.py | 31 ++++++++++++++++--------------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index bd0ecd9ba..d4b2e7051 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -18,10 +18,14 @@ inputs: runs: using: "composite" steps: - - name: Set up Python ${{ inputs.python-version }} + - name: Set up Python versions uses: actions/setup-python@v4 with: - python-version: ${{ inputs.python-version }} + python-version: | + 3.8 + 3.9 + 3.10 + 3.11 - name: Get pip cache dir shell: bash diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c90ef6946..dbb43cbd1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,7 +27,7 @@ jobs: run: make lint test: - timeout-minutes: 20 + timeout-minutes: 60 runs-on: ${{ matrix.os }} strategy: fail-fast: false diff --git a/noxfile.py b/noxfile.py index b5f278c82..ad54093ba 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,24 +1,25 @@ -import platform import re import nox -system_python_version = platform.python_version_tuple() -system_python_version = tuple(int(part) for part in system_python_version) - -supported_borgbackup_versions = [ - borgbackup - for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b5") - # Python version requirements for borgbackup versions - if (borgbackup == "1.1.18" and system_python_version >= (3, 5, 0)) - or (borgbackup == "1.2.2" and system_python_version >= (3, 8, 0)) - or (borgbackup == "1.2.4" and system_python_version >= (3, 8, 0)) - or (borgbackup == "2.0.0b5" and system_python_version >= (3, 9, 0)) -] - @nox.session -@nox.parametrize("borgbackup", supported_borgbackup_versions) +# @nox.parametrize("borgbackup", ["1.1.18", "1.2.2", "1.2.3", "1.2.4", "2.0.0b5"]) +@nox.parametrize( + "python, borgbackup", + [ + (python, borgbackup) + # All supported Python and BorgBackup versions + for python in ("3.8", "3.9", "3.10", "3.11") + for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b5") + + # Python version requirements for borgbackup versions + if (borgbackup == "1.1.18" and python >= "3.5") + or (borgbackup == "1.2.2" and python >= "3.8") + or (borgbackup == "1.2.4" and python >= "3.8") + or (borgbackup == "2.0.0b5" and python >= "3.9") + ] +) def run_tests(session, borgbackup): # install borgbackup if (borgbackup == "1.1.18"): From 1bc222a23c502310d5d1e3eff820ea61bb1aae48 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 24 Jun 2023 10:48:08 -0400 Subject: [PATCH 38/69] Borg 2 have compact message case change Signed-off-by: Chirag Aggarwal --- tests/integration/test_archives.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 119813299..9ff817da0 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -59,7 +59,7 @@ def test_repo_compact(qapp, qtbot): assert tab.compactButton.isEnabled() qtbot.mouseClick(tab.compactButton, QtCore.Qt.MouseButton.LeftButton) - qtbot.waitUntil(lambda: 'compaction freed about' in main.logText.text(), **pytest._wait_defaults) + qtbot.waitUntil(lambda: 'compaction freed about' in main.logText.text().lower(), **pytest._wait_defaults) def test_check(qapp, qtbot): From 83695fd9649db460721dc483d7acb2756bb616bc Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 24 Jun 2023 11:30:28 -0400 Subject: [PATCH 39/69] Added docstrings to tests Signed-off-by: Chirag Aggarwal --- .github/actions/setup/action.yml | 15 ++------------- .github/workflows/test.yml | 11 ++++++----- noxfile.py | 31 +++++++++++++++---------------- tests/integration/test_borg.py | 4 ++++ tests/integration/test_diff.py | 4 ++++ 5 files changed, 31 insertions(+), 34 deletions(-) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index d4b2e7051..27fe0ea05 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -18,14 +18,10 @@ inputs: runs: using: "composite" steps: - - name: Set up Python versions + - name: Set up Python ${{ inputs.python-version }} uses: actions/setup-python@v4 with: - python-version: | - 3.8 - 3.9 - 3.10 - 3.11 + python-version: ${{ inputs.python-version }} - name: Get pip cache dir shell: bash @@ -40,13 +36,6 @@ runs: restore-keys: | ${{ runner.os }}-pip- - # TODO: - # - name: Install Vorta - # shell: bash - # run: | - # pip install -e . - # pip install -r requirements.d/dev.txt - - name: Install Nox and pre-commit shell: bash run: pip install nox pre-commit diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dbb43cbd1..b0086da63 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,7 +19,7 @@ jobs: - name: Setup python, vorta and dev deps uses: ./.github/actions/setup with: - # python-version: 3.11 + python-version: 3.11 pre-commit: true - name: Test formatting with Flake8, ruff and Black @@ -50,9 +50,10 @@ jobs: - name: Install system dependencies (macOS) if: runner.os == 'macOS' + env: + PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig run: | - brew install openssl readline xz borgbackup \ - && echo "PKG_CONFIG_PATH=/usr/local/opt/openssl@3/lib/pkgconfig" >> $GITHUB_ENV + brew install openssl readline xz borgbackup - name: Setup python, vorta and dev deps uses: ./.github/actions/setup @@ -67,12 +68,12 @@ jobs: if: runner.os == 'Linux' run: | xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test-integration + -a dbus-run-session -- make test - name: Run Integration Tests with pytest (macOS) if: runner.os == 'macOS' # TODO: Change integration to all tests - run: make test-integration + run: echo $PKG_CONFIG_PATH && make test - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 diff --git a/noxfile.py b/noxfile.py index ad54093ba..b5f278c82 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,25 +1,24 @@ +import platform import re import nox +system_python_version = platform.python_version_tuple() +system_python_version = tuple(int(part) for part in system_python_version) + +supported_borgbackup_versions = [ + borgbackup + for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b5") + # Python version requirements for borgbackup versions + if (borgbackup == "1.1.18" and system_python_version >= (3, 5, 0)) + or (borgbackup == "1.2.2" and system_python_version >= (3, 8, 0)) + or (borgbackup == "1.2.4" and system_python_version >= (3, 8, 0)) + or (borgbackup == "2.0.0b5" and system_python_version >= (3, 9, 0)) +] + @nox.session -# @nox.parametrize("borgbackup", ["1.1.18", "1.2.2", "1.2.3", "1.2.4", "2.0.0b5"]) -@nox.parametrize( - "python, borgbackup", - [ - (python, borgbackup) - # All supported Python and BorgBackup versions - for python in ("3.8", "3.9", "3.10", "3.11") - for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b5") - - # Python version requirements for borgbackup versions - if (borgbackup == "1.1.18" and python >= "3.5") - or (borgbackup == "1.2.2" and python >= "3.8") - or (borgbackup == "1.2.4" and python >= "3.8") - or (borgbackup == "2.0.0b5" and python >= "3.9") - ] -) +@nox.parametrize("borgbackup", supported_borgbackup_versions) def run_tests(session, borgbackup): # install borgbackup if (borgbackup == "1.1.18"): diff --git a/tests/integration/test_borg.py b/tests/integration/test_borg.py index 2e93f29bb..409779d59 100644 --- a/tests/integration/test_borg.py +++ b/tests/integration/test_borg.py @@ -1,3 +1,7 @@ +""" +This file contains tests that directly call borg commands and the ouput without UI. +""" + from pathlib import Path import pytest diff --git a/tests/integration/test_diff.py b/tests/integration/test_diff.py index 7fa89e185..876115c0c 100644 --- a/tests/integration/test_diff.py +++ b/tests/integration/test_diff.py @@ -1,3 +1,7 @@ +""" +These tests compare the output of the diff command with the expected output. +""" + import sys import pytest From ede422c5446d96edc29028f7e7fb497f14480795 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 24 Jun 2023 11:30:45 -0400 Subject: [PATCH 40/69] Added docstrings to tests_2 Signed-off-by: Chirag Aggarwal --- tests/integration/test_borg.py | 5 ++++- tests/integration/test_diff.py | 1 + tests/integration/test_init.py | 6 ++++++ tests/integration/test_repo.py | 5 +++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/integration/test_borg.py b/tests/integration/test_borg.py index 409779d59..19cb84018 100644 --- a/tests/integration/test_borg.py +++ b/tests/integration/test_borg.py @@ -1,5 +1,5 @@ """ -This file contains tests that directly call borg commands and the ouput without UI. +This file contains tests that directly call borg commands and verify the exit code. """ from pathlib import Path @@ -13,6 +13,7 @@ def test_borg_prune(qapp, qtbot): + """This test runs borg prune on a test repo directly without UI""" params = BorgPruneJob.prepare(vorta.store.models.BackupProfileModel.select().first()) thread = BorgPruneJob(params['cmd'], params, qapp) @@ -25,6 +26,7 @@ def test_borg_prune(qapp, qtbot): # test borg info def test_borg_repo_info(qapp, qtbot, tmpdir): + """This test runs borg info on a test repo directly without UI""" repo_info = { 'repo_url': str(Path(tmpdir).parent / 'repo0'), 'extra_borg_arguments': '', @@ -43,6 +45,7 @@ def test_borg_repo_info(qapp, qtbot, tmpdir): def test_borg_archive_info(qapp, qtbot, tmpdir): + """Check that archive info command works""" main = qapp.main_window tab = main.archiveTab main.tabWidget.setCurrentIndex(3) diff --git a/tests/integration/test_diff.py b/tests/integration/test_diff.py index 876115c0c..2c9fb62e9 100644 --- a/tests/integration/test_diff.py +++ b/tests/integration/test_diff.py @@ -335,6 +335,7 @@ ], ) def test_archive_diff_lines(qapp, qtbot, borg_version, archive_name_1, archive_name_2, expected): + """Test that the diff lines are parsed correctly for supported borg versions""" parsed_borg_version = borg_version[1] supports_fifo = parsed_borg_version > parse_version('1.1.18') supports_chrdev = sys.platform.startswith('linux') diff --git a/tests/integration/test_init.py b/tests/integration/test_init.py index 178c76c07..db5882a67 100644 --- a/tests/integration/test_init.py +++ b/tests/integration/test_init.py @@ -1,3 +1,7 @@ +""" +Test initialization of new repositories and adding existing ones. +""" + import os from pathlib import PurePath @@ -12,6 +16,7 @@ def test_create_repo(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): + """Test initializing a new repository""" main = qapp.main_window main.show() main.repoTab.new_repo() @@ -46,6 +51,7 @@ def test_create_repo(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): def test_add_existing_repo(qapp, qtbot, monkeypatch, choose_file_dialog): + """Test adding an existing repository""" main = qapp.main_window main.show() tab = main.repoTab diff --git a/tests/integration/test_repo.py b/tests/integration/test_repo.py index 67bd05da6..3f3b4b57c 100644 --- a/tests/integration/test_repo.py +++ b/tests/integration/test_repo.py @@ -1,9 +1,14 @@ +""" +Test backup creation +""" + import pytest from PyQt6 import QtCore from vorta.store.models import ArchiveModel, EventLogModel def test_create(qapp, qtbot): + """Test for manual archive creation""" main = qapp.main_window main.show() main.archiveTab.refresh_archive_list() From 86da9e9154751b3cd7b4b0b838259601ca19ec56 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 24 Jun 2023 11:39:17 -0400 Subject: [PATCH 41/69] Added pkg config path to env for macos Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b0086da63..e5d29f302 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -50,8 +50,6 @@ jobs: - name: Install system dependencies (macOS) if: runner.os == 'macOS' - env: - PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig run: | brew install openssl readline xz borgbackup @@ -72,7 +70,8 @@ jobs: - name: Run Integration Tests with pytest (macOS) if: runner.os == 'macOS' - # TODO: Change integration to all tests + env: + PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig run: echo $PKG_CONFIG_PATH && make test - name: Upload coverage to Codecov From b95d245f2aca08265113b7568570fefb02d672a6 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 24 Jun 2023 12:02:28 -0400 Subject: [PATCH 42/69] Macos install macfuse Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e5d29f302..5efd7b27a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,7 +51,8 @@ jobs: - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: | - brew install openssl readline xz borgbackup + brew install openssl readline xz xxhash pkg-config borgbackup \ + && brew install --cask macfuse - name: Setup python, vorta and dev deps uses: ./.github/actions/setup From 101c70982ddb562224f6c90cba3eb5c9930497bd Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 24 Jun 2023 12:58:49 -0400 Subject: [PATCH 43/69] Attempt at installing borg via github test Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 27 ++++++++++++++++++++++++--- noxfile.py | 13 +++++++------ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5efd7b27a..d6b916e18 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,6 +35,7 @@ jobs: matrix: python-version: ["3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest, macos-latest] + borg-version: ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"] steps: - uses: actions/checkout@v3 @@ -43,7 +44,7 @@ jobs: if: runner.os == 'Linux' run: | sudo apt update && sudo apt install -y \ - xvfb libssl-dev openssl libacl1-dev libacl1 fuse3 build-essential borgbackup \ + xvfb libssl-dev openssl libacl1-dev libacl1 fuse3 build-essential \ libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \ libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev libfuse3-dev pkg-config python3-pkgconfig libxxhash-dev @@ -51,8 +52,25 @@ jobs: - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: | - brew install openssl readline xz xxhash pkg-config borgbackup \ - && brew install --cask macfuse + brew install openssl readline xz xxhash pkg-config + + + - name: Install borgbackup (macOS) + if: runner.os == 'macOS' + run: | + borg_version="${{ matrix.borg-version }}" + pip install borgbackup + + - name: Install borgbackup (Linux) + if: runner.os == 'Linux' + run: | + borg_version="${{ matrix.borg-version }}" + if [[ "$borg_version" == "1.1.18" ]]; then + pip install borgbackup + else + pip install borgbackup[pyfuse3] + fi + - name: Setup python, vorta and dev deps uses: ./.github/actions/setup @@ -65,6 +83,8 @@ jobs: - name: Run Integration Tests with pytest (Linux) if: runner.os == 'Linux' + env: + borg_version: ${{ matrix.borg-version }} run: | xvfb-run --server-args="-screen 0 1024x768x24+32" \ -a dbus-run-session -- make test @@ -72,6 +92,7 @@ jobs: - name: Run Integration Tests with pytest (macOS) if: runner.os == 'macOS' env: + borg_version: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig run: echo $PKG_CONFIG_PATH && make test diff --git a/noxfile.py b/noxfile.py index b5f278c82..cd652b53e 100644 --- a/noxfile.py +++ b/noxfile.py @@ -18,13 +18,14 @@ @nox.session -@nox.parametrize("borgbackup", supported_borgbackup_versions) +# @nox.parametrize("borgbackup", supported_borgbackup_versions) def run_tests(session, borgbackup): - # install borgbackup - if (borgbackup == "1.1.18"): - session.install(f"borgbackup=={borgbackup}") - else: - session.install(f"borgbackup[pyfuse3]=={borgbackup}") + + # # install borgbackup + # if (borgbackup == "1.1.18"): + # session.install(f"borgbackup=={borgbackup}") + # else: + # session.install(f"borgbackup[pyfuse3]=={borgbackup}") # install dependencies session.install("-r", "requirements.d/dev.txt") From 6e1c70c62ca0e4879d1478850da4f6440c80c40b Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 24 Jun 2023 13:17:24 -0400 Subject: [PATCH 44/69] Nox config to use env specified borg version when set Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 25 +++++----------------- noxfile.py | 43 +++++++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 37 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d6b916e18..90d77fd78 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,6 +36,9 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest, macos-latest] borg-version: ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"] + exclude: + - borg-version: "2.0.0b5" + python-version: "3.8" steps: - uses: actions/checkout@v3 @@ -54,24 +57,6 @@ jobs: run: | brew install openssl readline xz xxhash pkg-config - - - name: Install borgbackup (macOS) - if: runner.os == 'macOS' - run: | - borg_version="${{ matrix.borg-version }}" - pip install borgbackup - - - name: Install borgbackup (Linux) - if: runner.os == 'Linux' - run: | - borg_version="${{ matrix.borg-version }}" - if [[ "$borg_version" == "1.1.18" ]]; then - pip install borgbackup - else - pip install borgbackup[pyfuse3] - fi - - - name: Setup python, vorta and dev deps uses: ./.github/actions/setup with: @@ -84,7 +69,7 @@ jobs: - name: Run Integration Tests with pytest (Linux) if: runner.os == 'Linux' env: - borg_version: ${{ matrix.borg-version }} + BORG_VERSION: ${{ matrix.borg-version }} run: | xvfb-run --server-args="-screen 0 1024x768x24+32" \ -a dbus-run-session -- make test @@ -92,7 +77,7 @@ jobs: - name: Run Integration Tests with pytest (macOS) if: runner.os == 'macOS' env: - borg_version: ${{ matrix.borg-version }} + BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig run: echo $PKG_CONFIG_PATH && make test diff --git a/noxfile.py b/noxfile.py index cd652b53e..81eb9599e 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,31 +1,40 @@ +import os import platform import re +import sys import nox -system_python_version = platform.python_version_tuple() -system_python_version = tuple(int(part) for part in system_python_version) +borg_version = os.getenv("BORG_VERSION") -supported_borgbackup_versions = [ - borgbackup - for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b5") - # Python version requirements for borgbackup versions - if (borgbackup == "1.1.18" and system_python_version >= (3, 5, 0)) - or (borgbackup == "1.2.2" and system_python_version >= (3, 8, 0)) - or (borgbackup == "1.2.4" and system_python_version >= (3, 8, 0)) - or (borgbackup == "2.0.0b5" and system_python_version >= (3, 9, 0)) -] +if borg_version: + # Use specified borg version + supported_borgbackup_versions = [borg_version] +else: + # Generate a list of borg versions compatible with system installed python version + system_python_version = platform.python_version_tuple() + system_python_version = tuple(int(part) for part in system_python_version) + + supported_borgbackup_versions = [ + borgbackup + for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b5") + # Python version requirements for borgbackup versions + if (borgbackup == "1.1.18" and system_python_version >= (3, 5, 0)) + or (borgbackup == "1.2.2" and system_python_version >= (3, 8, 0)) + or (borgbackup == "1.2.4" and system_python_version >= (3, 8, 0)) + or (borgbackup == "2.0.0b5" and system_python_version >= (3, 9, 0)) + ] @nox.session -# @nox.parametrize("borgbackup", supported_borgbackup_versions) +@nox.parametrize("borgbackup", supported_borgbackup_versions) def run_tests(session, borgbackup): - # # install borgbackup - # if (borgbackup == "1.1.18"): - # session.install(f"borgbackup=={borgbackup}") - # else: - # session.install(f"borgbackup[pyfuse3]=={borgbackup}") + # install borgbackup + if (borgbackup == "1.1.18" or sys.platform == 'darwin'): + session.install(f"borgbackup=={borgbackup}") + else: + session.install(f"borgbackup[pyfuse3]=={borgbackup}") # install dependencies session.install("-r", "requirements.d/dev.txt") From 23ce04c21b1f594c3f5d3fc72ae535e324dde59e Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 24 Jun 2023 13:32:02 -0400 Subject: [PATCH 45/69] Skip borg mount test on macos (atleast for now) Signed-off-by: Chirag Aggarwal --- noxfile.py | 5 ++--- tests/integration/test_archives.py | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/noxfile.py b/noxfile.py index 81eb9599e..fcf40f863 100644 --- a/noxfile.py +++ b/noxfile.py @@ -29,7 +29,6 @@ @nox.session @nox.parametrize("borgbackup", supported_borgbackup_versions) def run_tests(session, borgbackup): - # install borgbackup if (borgbackup == "1.1.18" or sys.platform == 'darwin'): session.install(f"borgbackup=={borgbackup}") @@ -45,8 +44,8 @@ def run_tests(session, borgbackup): cli_version = re.search(r"borg (\S+)", cli_version).group(1) python_version = session.run("python", "-c", "import borg; print(borg.__version__)", silent=True).strip() - session.log(f"CLI version: {cli_version}") - session.log(f"Python version: {python_version}") + session.log(f"Borg CLI version: {cli_version}") + session.log(f"Borg Python version: {python_version}") assert cli_version == borgbackup assert python_version == borgbackup diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 9ff817da0..c273ad7df 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -82,6 +82,7 @@ def test_check(qapp, qtbot): @pytest.mark.min_borg_version('1.2.0') +@pytest.mark.skipif(sys.platform == 'darwin', reason="Macos fuse support is uncertain") def test_mount(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): """Test for archive mounting and unmounting""" From 1db9d4b084acc5665819059b8b7dfdef12cba6b2 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 24 Jun 2023 14:59:53 -0400 Subject: [PATCH 46/69] Cleanup | remove main.show() statements Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 2 +- tests/integration/test_archives.py | 2 -- tests/integration/test_init.py | 2 -- tests/integration/test_repo.py | 1 - 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 90d77fd78..b63101a90 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,7 +27,7 @@ jobs: run: make lint test: - timeout-minutes: 60 + timeout-minutes: 20 runs-on: ${{ matrix.os }} strategy: fail-fast: false diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index c273ad7df..d987c45d1 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -66,7 +66,6 @@ def test_check(qapp, qtbot): """Test for archive consistency check""" main = qapp.main_window tab = main.archiveTab - main.show() main.tabWidget.setCurrentIndex(3) tab.refresh_archive_list() @@ -95,7 +94,6 @@ def psutil_disk_partitions(**kwargs): main = qapp.main_window tab = main.archiveTab - main.show() main.tabWidget.setCurrentIndex(3) tab.refresh_archive_list() diff --git a/tests/integration/test_init.py b/tests/integration/test_init.py index db5882a67..4bf4562f8 100644 --- a/tests/integration/test_init.py +++ b/tests/integration/test_init.py @@ -18,7 +18,6 @@ def test_create_repo(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): """Test initializing a new repository""" main = qapp.main_window - main.show() main.repoTab.new_repo() add_repo_window = main.repoTab._window @@ -53,7 +52,6 @@ def test_create_repo(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): def test_add_existing_repo(qapp, qtbot, monkeypatch, choose_file_dialog): """Test adding an existing repository""" main = qapp.main_window - main.show() tab = main.repoTab main.tabWidget.setCurrentIndex(0) diff --git a/tests/integration/test_repo.py b/tests/integration/test_repo.py index 3f3b4b57c..5fb4e972a 100644 --- a/tests/integration/test_repo.py +++ b/tests/integration/test_repo.py @@ -10,7 +10,6 @@ def test_create(qapp, qtbot): """Test for manual archive creation""" main = qapp.main_window - main.show() main.archiveTab.refresh_archive_list() qtbot.waitUntil(lambda: main.archiveTab.archiveTable.rowCount() > 0, **pytest._wait_defaults) From cf0dfaab15c00853ca5b83f882950f52359dfd44 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 11:28:49 -0400 Subject: [PATCH 47/69] Run unit test seperately Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b63101a90..596152db6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,6 +36,9 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest, macos-latest] borg-version: ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"] + include: + - test-type: "unit" + borg-version: "1.2.4" exclude: - borg-version: "2.0.0b5" python-version: "3.8" @@ -66,20 +69,35 @@ jobs: uses: mxschmitt/action-tmate@v3 if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} + - name: Run Unit Tests with pytest (Linux) + if: ${{ runner.os == 'Linux' && matrix.test-type == 'unit' }} + env: + BORG_VERSION: ${{ matrix.borg-version }} + run: | + xvfb-run --server-args="-screen 0 1024x768x24+32" \ + -a dbus-run-session -- make test-unit + + - name: Run Unit Tests with pytest (macOS) + if: ${{ runner.os == 'macOS' && matrix.test-type == 'unit' }} + env: + BORG_VERSION: ${{ matrix.borg-version }} + PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig + run: echo $PKG_CONFIG_PATH && make test-unit + - name: Run Integration Tests with pytest (Linux) - if: runner.os == 'Linux' + if: ${{ runner.os == 'Linux' && matrix.test-type != 'unit' }} env: BORG_VERSION: ${{ matrix.borg-version }} run: | xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test + -a dbus-run-session -- make test-integration - name: Run Integration Tests with pytest (macOS) - if: runner.os == 'macOS' + if: ${{ runner.os == 'macOS' && matrix.test-type != 'unit' }} env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig - run: echo $PKG_CONFIG_PATH && make test + run: echo $PKG_CONFIG_PATH && make test-integration - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 From 770ecbff72b51b2a469d7823688aa8d1bb09dc48 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 11:42:57 -0400 Subject: [PATCH 48/69] Unit job as include Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 596152db6..ccb1962d4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,9 +36,10 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest, macos-latest] borg-version: ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"] + test-type: ["integration"] include: - - test-type: "unit" - borg-version: "1.2.4" + - borg-version: "1.2.4" + test-type: "unit" exclude: - borg-version: "2.0.0b5" python-version: "3.8" @@ -70,7 +71,7 @@ jobs: if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} - name: Run Unit Tests with pytest (Linux) - if: ${{ runner.os == 'Linux' && matrix.test-type == 'unit' }} + if: runner.os == 'Linux' env: BORG_VERSION: ${{ matrix.borg-version }} run: | @@ -78,14 +79,14 @@ jobs: -a dbus-run-session -- make test-unit - name: Run Unit Tests with pytest (macOS) - if: ${{ runner.os == 'macOS' && matrix.test-type == 'unit' }} + if: runner.os == 'macOS' env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig run: echo $PKG_CONFIG_PATH && make test-unit - name: Run Integration Tests with pytest (Linux) - if: ${{ runner.os == 'Linux' && matrix.test-type != 'unit' }} + if: runner.os == 'Linux' env: BORG_VERSION: ${{ matrix.borg-version }} run: | @@ -93,7 +94,7 @@ jobs: -a dbus-run-session -- make test-integration - name: Run Integration Tests with pytest (macOS) - if: ${{ runner.os == 'macOS' && matrix.test-type != 'unit' }} + if: runner.os == 'macOS' env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig From 71f1ef6600bad44aa97e3e06f0d9647c1a606750 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 11:48:05 -0400 Subject: [PATCH 49/69] Revert unit test config Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ccb1962d4..3feb53ec2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -70,35 +70,20 @@ jobs: uses: mxschmitt/action-tmate@v3 if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} - - name: Run Unit Tests with pytest (Linux) - if: runner.os == 'Linux' - env: - BORG_VERSION: ${{ matrix.borg-version }} - run: | - xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test-unit - - - name: Run Unit Tests with pytest (macOS) - if: runner.os == 'macOS' - env: - BORG_VERSION: ${{ matrix.borg-version }} - PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig - run: echo $PKG_CONFIG_PATH && make test-unit - - name: Run Integration Tests with pytest (Linux) if: runner.os == 'Linux' env: BORG_VERSION: ${{ matrix.borg-version }} run: | xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test-integration + -a dbus-run-session -- make test - name: Run Integration Tests with pytest (macOS) if: runner.os == 'macOS' env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig - run: echo $PKG_CONFIG_PATH && make test-integration + run: echo $PKG_CONFIG_PATH && make test - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 From cd023716861982761cfb7d78eb98d52ac8c75bca Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 11:53:58 -0400 Subject: [PATCH 50/69] Revert "Revert unit test config" This reverts commit 71f1ef6600bad44aa97e3e06f0d9647c1a606750. --- .github/workflows/test.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3feb53ec2..ccb1962d4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -70,20 +70,35 @@ jobs: uses: mxschmitt/action-tmate@v3 if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} + - name: Run Unit Tests with pytest (Linux) + if: runner.os == 'Linux' + env: + BORG_VERSION: ${{ matrix.borg-version }} + run: | + xvfb-run --server-args="-screen 0 1024x768x24+32" \ + -a dbus-run-session -- make test-unit + + - name: Run Unit Tests with pytest (macOS) + if: runner.os == 'macOS' + env: + BORG_VERSION: ${{ matrix.borg-version }} + PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig + run: echo $PKG_CONFIG_PATH && make test-unit + - name: Run Integration Tests with pytest (Linux) if: runner.os == 'Linux' env: BORG_VERSION: ${{ matrix.borg-version }} run: | xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test + -a dbus-run-session -- make test-integration - name: Run Integration Tests with pytest (macOS) if: runner.os == 'macOS' env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig - run: echo $PKG_CONFIG_PATH && make test + run: echo $PKG_CONFIG_PATH && make test-integration - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 From 1e484f1a1bddbf58faa89dcffabe18c43ec09960 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 11:54:05 -0400 Subject: [PATCH 51/69] Revert "Unit job as include" This reverts commit 770ecbff72b51b2a469d7823688aa8d1bb09dc48. --- .github/workflows/test.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ccb1962d4..596152db6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,10 +36,9 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest, macos-latest] borg-version: ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"] - test-type: ["integration"] include: - - borg-version: "1.2.4" - test-type: "unit" + - test-type: "unit" + borg-version: "1.2.4" exclude: - borg-version: "2.0.0b5" python-version: "3.8" @@ -71,7 +70,7 @@ jobs: if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} - name: Run Unit Tests with pytest (Linux) - if: runner.os == 'Linux' + if: ${{ runner.os == 'Linux' && matrix.test-type == 'unit' }} env: BORG_VERSION: ${{ matrix.borg-version }} run: | @@ -79,14 +78,14 @@ jobs: -a dbus-run-session -- make test-unit - name: Run Unit Tests with pytest (macOS) - if: runner.os == 'macOS' + if: ${{ runner.os == 'macOS' && matrix.test-type == 'unit' }} env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig run: echo $PKG_CONFIG_PATH && make test-unit - name: Run Integration Tests with pytest (Linux) - if: runner.os == 'Linux' + if: ${{ runner.os == 'Linux' && matrix.test-type != 'unit' }} env: BORG_VERSION: ${{ matrix.borg-version }} run: | @@ -94,7 +93,7 @@ jobs: -a dbus-run-session -- make test-integration - name: Run Integration Tests with pytest (macOS) - if: runner.os == 'macOS' + if: ${{ runner.os == 'macOS' && matrix.test-type != 'unit' }} env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig From ba61d9e9535131caab6789c931640bd70c3ad71a Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 11:54:06 -0400 Subject: [PATCH 52/69] Revert "Run unit test seperately" This reverts commit cf0dfaab15c00853ca5b83f882950f52359dfd44. --- .github/workflows/test.yml | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 596152db6..b63101a90 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,9 +36,6 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest, macos-latest] borg-version: ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"] - include: - - test-type: "unit" - borg-version: "1.2.4" exclude: - borg-version: "2.0.0b5" python-version: "3.8" @@ -69,35 +66,20 @@ jobs: uses: mxschmitt/action-tmate@v3 if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} - - name: Run Unit Tests with pytest (Linux) - if: ${{ runner.os == 'Linux' && matrix.test-type == 'unit' }} - env: - BORG_VERSION: ${{ matrix.borg-version }} - run: | - xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test-unit - - - name: Run Unit Tests with pytest (macOS) - if: ${{ runner.os == 'macOS' && matrix.test-type == 'unit' }} - env: - BORG_VERSION: ${{ matrix.borg-version }} - PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig - run: echo $PKG_CONFIG_PATH && make test-unit - - name: Run Integration Tests with pytest (Linux) - if: ${{ runner.os == 'Linux' && matrix.test-type != 'unit' }} + if: runner.os == 'Linux' env: BORG_VERSION: ${{ matrix.borg-version }} run: | xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test-integration + -a dbus-run-session -- make test - name: Run Integration Tests with pytest (macOS) - if: ${{ runner.os == 'macOS' && matrix.test-type != 'unit' }} + if: runner.os == 'macOS' env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig - run: echo $PKG_CONFIG_PATH && make test-integration + run: echo $PKG_CONFIG_PATH && make test - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 From 26772e5ccb2434d9b39449338fa1670143b9635b Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 12:04:35 -0400 Subject: [PATCH 53/69] Restore unit test job --- .github/workflows/test.yml | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b63101a90..e989c877f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,6 +36,10 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest, macos-latest] borg-version: ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"] + test-type: ["integration"] + include: + - borg-version: "1.2.4" + test-type: "unit" exclude: - borg-version: "2.0.0b5" python-version: "3.8" @@ -66,20 +70,35 @@ jobs: uses: mxschmitt/action-tmate@v3 if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} + - name: Run Unit Tests with pytest (Linux) + if: ${{ runner.os == 'Linux' && matrix.test-type == 'unit' }} + env: + BORG_VERSION: ${{ matrix.borg-version }} + run: | + xvfb-run --server-args="-screen 0 1024x768x24+32" \ + -a dbus-run-session -- make test-unit + + - name: Run Unit Tests with pytest (macOS) + if: ${{ runner.os == 'macOS' && matrix.test-type == 'unit' }} + env: + BORG_VERSION: ${{ matrix.borg-version }} + PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig + run: echo $PKG_CONFIG_PATH && make test-unit + - name: Run Integration Tests with pytest (Linux) - if: runner.os == 'Linux' + if: ${{ runner.os == 'Linux' && matrix.test-type == 'integration' }} env: BORG_VERSION: ${{ matrix.borg-version }} run: | xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test + -a dbus-run-session -- make test-integration - name: Run Integration Tests with pytest (macOS) - if: runner.os == 'macOS' + if: ${{ runner.os == 'macOS' && matrix.test-type == 'integration' }} env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig - run: echo $PKG_CONFIG_PATH && make test + run: echo $PKG_CONFIG_PATH && make test-integration - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 From 2c514351a0101d43e2dc6b90d6a6f9a50b43d2d2 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 12:39:29 -0400 Subject: [PATCH 54/69] New composite action for installation Signed-off-by: Chirag Aggarwal --- .../actions/install-dependencies/action.yml | 24 +++++++++++ .github/workflows/test.yml | 40 +++---------------- 2 files changed, 30 insertions(+), 34 deletions(-) create mode 100644 .github/actions/install-dependencies/action.yml diff --git a/.github/actions/install-dependencies/action.yml b/.github/actions/install-dependencies/action.yml new file mode 100644 index 000000000..7c4b3f178 --- /dev/null +++ b/.github/actions/install-dependencies/action.yml @@ -0,0 +1,24 @@ +name: Install Dependencies +description: Installs system dependencies + +inputs: + os: + description: Supports Linux and macOS + required: true + +runs: + using: "composite" + steps: + - name: Install system dependencies (Linux) + if: inputs.os == 'Linux' + run: | + sudo apt update && sudo apt install -y \ + xvfb libssl-dev openssl libacl1-dev libacl1 build-essential borgbackup \ + libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ + libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \ + libegl1 libxcb-cursor0 + + - name: Install system dependencies (macOS) + if: inputs.os == 'macOS' + run: | + brew install openssl readline xz borgbackup diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e989c877f..6806783b1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,10 +36,6 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest, macos-latest] borg-version: ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"] - test-type: ["integration"] - include: - - borg-version: "1.2.4" - test-type: "unit" exclude: - borg-version: "2.0.0b5" python-version: "3.8" @@ -47,19 +43,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Install system dependencies (Linux) - if: runner.os == 'Linux' - run: | - sudo apt update && sudo apt install -y \ - xvfb libssl-dev openssl libacl1-dev libacl1 fuse3 build-essential \ - libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ - libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \ - libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev libfuse3-dev pkg-config python3-pkgconfig libxxhash-dev - - - name: Install system dependencies (macOS) - if: runner.os == 'macOS' - run: | - brew install openssl readline xz xxhash pkg-config + - name: Install system dependencies + uses: ./.github/actions/install-dependencies + with: + os: ${{ runner.os }} - name: Setup python, vorta and dev deps uses: ./.github/actions/setup @@ -70,23 +57,8 @@ jobs: uses: mxschmitt/action-tmate@v3 if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} - - name: Run Unit Tests with pytest (Linux) - if: ${{ runner.os == 'Linux' && matrix.test-type == 'unit' }} - env: - BORG_VERSION: ${{ matrix.borg-version }} - run: | - xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test-unit - - - name: Run Unit Tests with pytest (macOS) - if: ${{ runner.os == 'macOS' && matrix.test-type == 'unit' }} - env: - BORG_VERSION: ${{ matrix.borg-version }} - PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig - run: echo $PKG_CONFIG_PATH && make test-unit - - name: Run Integration Tests with pytest (Linux) - if: ${{ runner.os == 'Linux' && matrix.test-type == 'integration' }} + if: runner.os == 'Linux' env: BORG_VERSION: ${{ matrix.borg-version }} run: | @@ -94,7 +66,7 @@ jobs: -a dbus-run-session -- make test-integration - name: Run Integration Tests with pytest (macOS) - if: ${{ runner.os == 'macOS' && matrix.test-type == 'integration' }} + if: runner.os == 'macOS' env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig From 1b33e378a723f2e6fa4565e9066c114c3609c148 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 12:40:59 -0400 Subject: [PATCH 55/69] Composite action require shell property Signed-off-by: Chirag Aggarwal --- .github/actions/install-dependencies/action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/install-dependencies/action.yml b/.github/actions/install-dependencies/action.yml index 7c4b3f178..f28b94a5d 100644 --- a/.github/actions/install-dependencies/action.yml +++ b/.github/actions/install-dependencies/action.yml @@ -11,6 +11,7 @@ runs: steps: - name: Install system dependencies (Linux) if: inputs.os == 'Linux' + shell: bash run: | sudo apt update && sudo apt install -y \ xvfb libssl-dev openssl libacl1-dev libacl1 build-essential borgbackup \ @@ -20,5 +21,6 @@ runs: - name: Install system dependencies (macOS) if: inputs.os == 'macOS' + shell: bash run: | brew install openssl readline xz borgbackup From 48afd4b9eb7c0c514114c4e28ae30a8765ec3a97 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 12:47:52 -0400 Subject: [PATCH 56/69] Unit tests as another job Signed-off-by: Chirag Aggarwal --- .../actions/install-dependencies/action.yml | 11 ++-- .github/workflows/test.yml | 54 ++++++++++++++++++- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/.github/actions/install-dependencies/action.yml b/.github/actions/install-dependencies/action.yml index f28b94a5d..141e2f3db 100644 --- a/.github/actions/install-dependencies/action.yml +++ b/.github/actions/install-dependencies/action.yml @@ -14,13 +14,14 @@ runs: shell: bash run: | sudo apt update && sudo apt install -y \ - xvfb libssl-dev openssl libacl1-dev libacl1 build-essential borgbackup \ - libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ - libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \ - libegl1 libxcb-cursor0 + xvfb libssl-dev openssl libacl1-dev libacl1 fuse3 build-essential \ + libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ + libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \ + libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev libfuse3-dev pkg-config \ + python3-pkgconfig libxxhash-dev borgbackup - name: Install system dependencies (macOS) if: inputs.os == 'macOS' shell: bash run: | - brew install openssl readline xz borgbackup + brew install openssl readline xz xxhash pkg-config borgbackup diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6806783b1..48c9d1ac8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: shell: bash run: make lint - test: + test-integration: timeout-minutes: 20 runs-on: ${{ matrix.os }} strategy: @@ -80,3 +80,55 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} env_vars: OS, python + + test-unit: + timeout-minutes: 20 + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + + matrix: + python-version: ["3.8", "3.9", "3.10", "3.11"] + os: [ubuntu-latest, macos-latest] + borg-version: ["1.2.4"] + + steps: + - uses: actions/checkout@v3 + + - name: Install system dependencies + uses: ./.github/actions/install-dependencies + with: + os: ${{ runner.os }} + + - name: Setup python, vorta and dev deps + uses: ./.github/actions/setup + with: + python-version: ${{ matrix.python-version }} + + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} + + - name: Run Unit Tests with pytest (Linux) + if: runner.os == 'Linux' + env: + BORG_VERSION: ${{ matrix.borg-version }} + run: | + xvfb-run --server-args="-screen 0 1024x768x24+32" \ + -a dbus-run-session -- make test-unit + + - name: Run Unit Tests with pytest (macOS) + if: runner.os == 'macOS' + env: + BORG_VERSION: ${{ matrix.borg-version }} + PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig + run: echo $PKG_CONFIG_PATH && make test-unit + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + env: + OS: ${{ runner.os }} + python: ${{ matrix.python-version }} + with: + token: ${{ secrets.CODECOV_TOKEN }} + env_vars: OS, python From f1302f4bf0128dd26a0b7eb6585eede7a71ceaf1 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 13:22:05 -0400 Subject: [PATCH 57/69] Fixed breaking of some tests due to introduction of repo name Signed-off-by: Chirag Aggarwal --- .github/workflows/test.yml | 30 +++++++++++++++--------------- tests/integration/test_borg.py | 1 + tests/integration/test_init.py | 26 ++++++++++++++++++++++---- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 48c9d1ac8..481c76c89 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: shell: bash run: make lint - test-integration: + test-unit: timeout-minutes: 20 runs-on: ${{ matrix.os }} strategy: @@ -35,10 +35,7 @@ jobs: matrix: python-version: ["3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest, macos-latest] - borg-version: ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"] - exclude: - - borg-version: "2.0.0b5" - python-version: "3.8" + borg-version: ["1.2.4"] steps: - uses: actions/checkout@v3 @@ -57,20 +54,20 @@ jobs: uses: mxschmitt/action-tmate@v3 if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} - - name: Run Integration Tests with pytest (Linux) + - name: Run Unit Tests with pytest (Linux) if: runner.os == 'Linux' env: BORG_VERSION: ${{ matrix.borg-version }} run: | xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test-integration + -a dbus-run-session -- make test-unit - - name: Run Integration Tests with pytest (macOS) + - name: Run Unit Tests with pytest (macOS) if: runner.os == 'macOS' env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig - run: echo $PKG_CONFIG_PATH && make test-integration + run: echo $PKG_CONFIG_PATH && make test-unit - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 @@ -81,7 +78,7 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} env_vars: OS, python - test-unit: + test-integration: timeout-minutes: 20 runs-on: ${{ matrix.os }} strategy: @@ -90,7 +87,10 @@ jobs: matrix: python-version: ["3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest, macos-latest] - borg-version: ["1.2.4"] + borg-version: ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"] + exclude: + - borg-version: "2.0.0b5" + python-version: "3.8" steps: - uses: actions/checkout@v3 @@ -109,20 +109,20 @@ jobs: uses: mxschmitt/action-tmate@v3 if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} - - name: Run Unit Tests with pytest (Linux) + - name: Run Integration Tests with pytest (Linux) if: runner.os == 'Linux' env: BORG_VERSION: ${{ matrix.borg-version }} run: | xvfb-run --server-args="-screen 0 1024x768x24+32" \ - -a dbus-run-session -- make test-unit + -a dbus-run-session -- make test-integration - - name: Run Unit Tests with pytest (macOS) + - name: Run Integration Tests with pytest (macOS) if: runner.os == 'macOS' env: BORG_VERSION: ${{ matrix.borg-version }} PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig - run: echo $PKG_CONFIG_PATH && make test-unit + run: echo $PKG_CONFIG_PATH && make test-integration - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 diff --git a/tests/integration/test_borg.py b/tests/integration/test_borg.py index 19cb84018..2a4817109 100644 --- a/tests/integration/test_borg.py +++ b/tests/integration/test_borg.py @@ -29,6 +29,7 @@ def test_borg_repo_info(qapp, qtbot, tmpdir): """This test runs borg info on a test repo directly without UI""" repo_info = { 'repo_url': str(Path(tmpdir).parent / 'repo0'), + 'repo_name': 'repo0', 'extra_borg_arguments': '', 'ssh_key': '', 'password': '', diff --git a/tests/integration/test_init.py b/tests/integration/test_init.py index 4bf4562f8..a4d651029 100644 --- a/tests/integration/test_init.py +++ b/tests/integration/test_init.py @@ -13,6 +13,7 @@ from PyQt6.QtWidgets import QMessageBox LONG_PASSWORD = 'long-password-long' +TEST_REPO_NAME = 'TEST - REPONAME' def test_create_repo(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): @@ -20,6 +21,7 @@ def test_create_repo(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): main = qapp.main_window main.repoTab.new_repo() add_repo_window = main.repoTab._window + main.show() # create new folder in tmpdir new_repo_path = tmpdir.join('new_repo') @@ -32,6 +34,11 @@ def test_create_repo(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): ) qtbot.mouseClick(add_repo_window.chooseLocalFolderButton, Qt.MouseButton.LeftButton) + # clear auto input of repo name from url + add_repo_window.repoName.selectAll() + add_repo_window.repoName.del_() + qtbot.keyClicks(add_repo_window.repoName, TEST_REPO_NAME) + qtbot.keyClicks(add_repo_window.passwordLineEdit, LONG_PASSWORD) qtbot.keyClicks(add_repo_window.confirmLineEdit, LONG_PASSWORD) @@ -40,8 +47,11 @@ def test_create_repo(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): qtbot.waitUntil(lambda: main.repoTab.repoSelector.count() == 2, **pytest._wait_defaults) # Check if repo was created in tmpdir - assert PurePath(main.repoTab.repoSelector.currentText()).parent == tmpdir - assert PurePath(main.repoTab.repoSelector.currentText()).name == 'new_repo' + repo_url = ( + vorta.store.models.RepoModel.select().where(vorta.store.models.RepoModel.name == TEST_REPO_NAME).get().url + ) + assert PurePath(repo_url).parent == tmpdir + assert PurePath(repo_url).name == 'new_repo' # check that new_repo_path contains folder data assert os.path.exists(new_repo_path.join('data')) @@ -55,7 +65,8 @@ def test_add_existing_repo(qapp, qtbot, monkeypatch, choose_file_dialog): tab = main.repoTab main.tabWidget.setCurrentIndex(0) - current_repo_path = PurePath(main.repoTab.repoSelector.currentText()) + current_repo_path = vorta.store.models.RepoModel.select().first().url + current_repo_name = vorta.store.models.RepoModel.select().first().name monkeypatch.setattr(QMessageBox, "show", lambda *args: True) qtbot.mouseClick(main.repoTab.repoRemoveToolbutton, Qt.MouseButton.LeftButton) @@ -74,8 +85,15 @@ def test_add_existing_repo(qapp, qtbot, monkeypatch, choose_file_dialog): lambda *args, **kwargs: choose_file_dialog(*args, **kwargs, directory=current_repo_path), ) qtbot.mouseClick(add_repo_window.chooseLocalFolderButton, Qt.MouseButton.LeftButton) + + # clear auto input of repo name from url + add_repo_window.repoName.selectAll() + add_repo_window.repoName.del_() + qtbot.keyClicks(add_repo_window.repoName, TEST_REPO_NAME) + add_repo_window.run() # check that repo was added qtbot.waitUntil(lambda: tab.repoSelector.count() == 1, **pytest._wait_defaults) - assert tab.repoSelector.currentText() == str(current_repo_path) + assert vorta.store.models.RepoModel.select().first().url == str(current_repo_path) + assert vorta.store.models.RepoModel.select().first().name == current_repo_name From c0ca6163383f2e1ee135da7bb33e2be27f67c433 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 25 Jun 2023 13:29:10 -0400 Subject: [PATCH 58/69] Minor bug fix, incorrect variable used in asssertion Signed-off-by: Chirag Aggarwal --- tests/integration/test_init.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/integration/test_init.py b/tests/integration/test_init.py index a4d651029..00cba53a3 100644 --- a/tests/integration/test_init.py +++ b/tests/integration/test_init.py @@ -66,7 +66,6 @@ def test_add_existing_repo(qapp, qtbot, monkeypatch, choose_file_dialog): main.tabWidget.setCurrentIndex(0) current_repo_path = vorta.store.models.RepoModel.select().first().url - current_repo_name = vorta.store.models.RepoModel.select().first().name monkeypatch.setattr(QMessageBox, "show", lambda *args: True) qtbot.mouseClick(main.repoTab.repoRemoveToolbutton, Qt.MouseButton.LeftButton) @@ -96,4 +95,4 @@ def test_add_existing_repo(qapp, qtbot, monkeypatch, choose_file_dialog): # check that repo was added qtbot.waitUntil(lambda: tab.repoSelector.count() == 1, **pytest._wait_defaults) assert vorta.store.models.RepoModel.select().first().url == str(current_repo_path) - assert vorta.store.models.RepoModel.select().first().name == current_repo_name + assert vorta.store.models.RepoModel.select().first().name == TEST_REPO_NAME From 211dec16794bc13bbfd8fe4c328d6b64d05b3920 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 27 Jun 2023 13:56:37 -0400 Subject: [PATCH 59/69] Use llfuse for borg 1.1.18, minor GH action changes Signed-off-by: Chirag Aggarwal --- .github/actions/install-dependencies/action.yml | 9 ++------- .github/actions/setup/action.yml | 13 +++++++++++-- .github/workflows/test.yml | 6 ++---- noxfile.py | 10 ++++++---- tests/integration/test_archives.py | 2 +- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/.github/actions/install-dependencies/action.yml b/.github/actions/install-dependencies/action.yml index 141e2f3db..e888476ae 100644 --- a/.github/actions/install-dependencies/action.yml +++ b/.github/actions/install-dependencies/action.yml @@ -1,16 +1,11 @@ name: Install Dependencies description: Installs system dependencies -inputs: - os: - description: Supports Linux and macOS - required: true - runs: using: "composite" steps: - name: Install system dependencies (Linux) - if: inputs.os == 'Linux' + if: runner.os == 'Linux' shell: bash run: | sudo apt update && sudo apt install -y \ @@ -21,7 +16,7 @@ runs: python3-pkgconfig libxxhash-dev borgbackup - name: Install system dependencies (macOS) - if: inputs.os == 'macOS' + if: runner.os == 'macOS' shell: bash run: | brew install openssl readline xz xxhash pkg-config borgbackup diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 27fe0ea05..1057ddb9e 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -15,6 +15,10 @@ inputs: description: The python version to install required: true default: "3.10" + install-nox: + description: Whether nox shall be installed + required: false + default: "" # == false runs: using: "composite" steps: @@ -36,9 +40,14 @@ runs: restore-keys: | ${{ runner.os }}-pip- - - name: Install Nox and pre-commit + - name: Install pre-commit + shell: bash + run: pip install pre-commit + + - name: Install nox + if: ${{ inputs.install-nox }} shell: bash - run: pip install nox pre-commit + run: pip install nox - name: Hash python version if: ${{ inputs.setup-pre-commit }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 481c76c89..19175959a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,13 +42,12 @@ jobs: - name: Install system dependencies uses: ./.github/actions/install-dependencies - with: - os: ${{ runner.os }} - name: Setup python, vorta and dev deps uses: ./.github/actions/setup with: python-version: ${{ matrix.python-version }} + install-nox: true - name: Setup tmate session uses: mxschmitt/action-tmate@v3 @@ -97,13 +96,12 @@ jobs: - name: Install system dependencies uses: ./.github/actions/install-dependencies - with: - os: ${{ runner.os }} - name: Setup python, vorta and dev deps uses: ./.github/actions/setup with: python-version: ${{ matrix.python-version }} + install-nox: true - name: Setup tmate session uses: mxschmitt/action-tmate@v3 diff --git a/noxfile.py b/noxfile.py index fcf40f863..5cbdea596 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,5 +1,4 @@ import os -import platform import re import sys @@ -12,8 +11,7 @@ supported_borgbackup_versions = [borg_version] else: # Generate a list of borg versions compatible with system installed python version - system_python_version = platform.python_version_tuple() - system_python_version = tuple(int(part) for part in system_python_version) + system_python_version = tuple(sys.version_info[:3]) supported_borgbackup_versions = [ borgbackup @@ -30,8 +28,12 @@ @nox.parametrize("borgbackup", supported_borgbackup_versions) def run_tests(session, borgbackup): # install borgbackup - if (borgbackup == "1.1.18" or sys.platform == 'darwin'): + if (sys.platform == 'darwin'): + # in macOS there's currently no fuse package which works with borgbackup directly session.install(f"borgbackup=={borgbackup}") + elif (borgbackup == "1.1.18"): + # borgbackup 1.1.18 doesn't support pyfuse3 + session.install(f"borgbackup[llfuse]=={borgbackup}") else: session.install(f"borgbackup[pyfuse3]=={borgbackup}") diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index d987c45d1..59a677d0f 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -80,7 +80,7 @@ def test_check(qapp, qtbot): qtbot.waitUntil(lambda: success_text in main.logText.text(), **pytest._wait_defaults) -@pytest.mark.min_borg_version('1.2.0') +# @pytest.mark.min_borg_version('1.2.0') @pytest.mark.skipif(sys.platform == 'darwin', reason="Macos fuse support is uncertain") def test_mount(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): """Test for archive mounting and unmounting""" From 4152103d05f50f5e7f202266341b3d6689ea5293 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 27 Jun 2023 14:09:09 -0400 Subject: [PATCH 60/69] Debug mount error Signed-off-by: Chirag Aggarwal --- noxfile.py | 1 + tests/integration/test_archives.py | 1 + 2 files changed, 2 insertions(+) diff --git a/noxfile.py b/noxfile.py index 5cbdea596..3539d3f8e 100644 --- a/noxfile.py +++ b/noxfile.py @@ -33,6 +33,7 @@ def run_tests(session, borgbackup): session.install(f"borgbackup=={borgbackup}") elif (borgbackup == "1.1.18"): # borgbackup 1.1.18 doesn't support pyfuse3 + session.install("llfuse") session.install(f"borgbackup[llfuse]=={borgbackup}") else: session.install(f"borgbackup[pyfuse3]=={borgbackup}") diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 59a677d0f..93fc3c7ee 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -103,6 +103,7 @@ def psutil_disk_partitions(**kwargs): qtbot.waitUntil(lambda: tab.bMountRepo.isEnabled(), **pytest._wait_defaults) qtbot.mouseClick(tab.bMountArchive, QtCore.Qt.MouseButton.LeftButton) + raise Exception(tab.mountErrors.text()) # TODO: remove qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Mounted'), **pytest._wait_defaults) tab.bmountarchive_clicked() From 55c8a8457bdb2b3cea3a59d41c1062a97fbd2cc4 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 27 Jun 2023 14:17:16 -0400 Subject: [PATCH 61/69] Debug mount error 2 Signed-off-by: Chirag Aggarwal --- tests/integration/test_archives.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 93fc3c7ee..9ac98b08d 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -103,6 +103,7 @@ def psutil_disk_partitions(**kwargs): qtbot.waitUntil(lambda: tab.bMountRepo.isEnabled(), **pytest._wait_defaults) qtbot.mouseClick(tab.bMountArchive, QtCore.Qt.MouseButton.LeftButton) + qtbot.wait(500) raise Exception(tab.mountErrors.text()) # TODO: remove qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Mounted'), **pytest._wait_defaults) From 99a3c111db3bc26b836a8ffe27bbb0acb8aff5cf Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 27 Jun 2023 14:25:48 -0400 Subject: [PATCH 62/69] raise exception if not mounted Signed-off-by: Chirag Aggarwal --- tests/integration/test_archives.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 9ac98b08d..4d403c39f 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -103,8 +103,9 @@ def psutil_disk_partitions(**kwargs): qtbot.waitUntil(lambda: tab.bMountRepo.isEnabled(), **pytest._wait_defaults) qtbot.mouseClick(tab.bMountArchive, QtCore.Qt.MouseButton.LeftButton) - qtbot.wait(500) - raise Exception(tab.mountErrors.text()) # TODO: remove + qtbot.wait(2000) + if not tab.mountErrors.text().startswith('Mounted'): + raise Exception(tab.mountErrors.text()) qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Mounted'), **pytest._wait_defaults) tab.bmountarchive_clicked() From f64d7d31d1c34130bd3b2f33809a3f4e9b7058a1 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 27 Jun 2023 14:33:38 -0400 Subject: [PATCH 63/69] Revert exception Signed-off-by: Chirag Aggarwal --- tests/integration/test_archives.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 4d403c39f..59a677d0f 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -103,9 +103,6 @@ def psutil_disk_partitions(**kwargs): qtbot.waitUntil(lambda: tab.bMountRepo.isEnabled(), **pytest._wait_defaults) qtbot.mouseClick(tab.bMountArchive, QtCore.Qt.MouseButton.LeftButton) - qtbot.wait(2000) - if not tab.mountErrors.text().startswith('Mounted'): - raise Exception(tab.mountErrors.text()) qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Mounted'), **pytest._wait_defaults) tab.bmountarchive_clicked() From c8757f21abd2d42d8889469cf127c88d327936aa Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 19 Jul 2023 04:26:37 -0400 Subject: [PATCH 64/69] Minor changes; removed a comment Signed-off-by: Chirag Aggarwal --- tests/integration/test_archives.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/test_archives.py b/tests/integration/test_archives.py index 59a677d0f..98d653fbc 100644 --- a/tests/integration/test_archives.py +++ b/tests/integration/test_archives.py @@ -80,7 +80,6 @@ def test_check(qapp, qtbot): qtbot.waitUntil(lambda: success_text in main.logText.text(), **pytest._wait_defaults) -# @pytest.mark.min_borg_version('1.2.0') @pytest.mark.skipif(sys.platform == 'darwin', reason="Macos fuse support is uncertain") def test_mount(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): """Test for archive mounting and unmounting""" From 0cdb4f8ed2b400d0fe59c014fe2ca3c97197d1e0 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 19 Jul 2023 04:32:01 -0400 Subject: [PATCH 65/69] Minor changes; removed a comment Signed-off-by: Chirag Aggarwal --- tests/integration/test_diff.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/test_diff.py b/tests/integration/test_diff.py index 2c9fb62e9..3621e1410 100644 --- a/tests/integration/test_diff.py +++ b/tests/integration/test_diff.py @@ -87,7 +87,6 @@ 'subpath': 'borg_src', 'match_startsWith': True, 'data': { - # TODO: Check/Review why file_type is FILE instead of DIRECTORY 'file_type': FileType.FILE, 'change_type': ChangeType.MODIFIED, 'modified': None, From 956eebd6da7e64e339abe8d077259a6babeca73d Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 24 Jul 2023 18:35:39 -0400 Subject: [PATCH 66/69] Check for chrdev support Signed-off-by: Chirag Aggarwal --- tests/integration/conftest.py | 10 ++++++---- tests/integration/test_diff.py | 6 ++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 8b4aab4db..3d67fc648 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -1,6 +1,5 @@ import os import subprocess -import sys import pytest import vorta @@ -105,9 +104,12 @@ def create_archive(timestamp, name): os.mkfifo(fifo_path) # /src/dir/chrdev - if sys.platform.startswith('linux'): + supports_chrdev = True + try: chrdev_path = os.path.join(dir_path, 'chrdev') os.mknod(chrdev_path, mode=0o600 | 0o020000) + except PermissionError: + supports_chrdev = False create_archive('2023-06-14T02:00:00', 'test-archive2') @@ -133,7 +135,7 @@ def create_archive(timestamp, name): create_archive('2023-06-14T06:00:00', 'test-archive6') - return repo_path, source_files_dir + return repo_path, source_files_dir, supports_chrdev @pytest.fixture(scope='function', autouse=True) @@ -150,7 +152,7 @@ def init_db(qapp, qtbot, tmpdir_factory, create_test_repo): default_profile = BackupProfileModel(name='Default') default_profile.save() - repo_path, source_dir = create_test_repo + repo_path, source_dir, _ = create_test_repo new_repo = RepoModel(url=repo_path) new_repo.encryption = 'none' diff --git a/tests/integration/test_diff.py b/tests/integration/test_diff.py index 3621e1410..28e8037b5 100644 --- a/tests/integration/test_diff.py +++ b/tests/integration/test_diff.py @@ -2,8 +2,6 @@ These tests compare the output of the diff command with the expected output. """ -import sys - import pytest import vorta.borg import vorta.utils @@ -333,11 +331,11 @@ ), ], ) -def test_archive_diff_lines(qapp, qtbot, borg_version, archive_name_1, archive_name_2, expected): +def test_archive_diff_lines(qapp, qtbot, borg_version, create_test_repo, archive_name_1, archive_name_2, expected): """Test that the diff lines are parsed correctly for supported borg versions""" parsed_borg_version = borg_version[1] supports_fifo = parsed_borg_version > parse_version('1.1.18') - supports_chrdev = sys.platform.startswith('linux') + supports_chrdev = create_test_repo[2] params = BorgDiffJob.prepare(vorta.store.models.BackupProfileModel.select().first(), archive_name_1, archive_name_2) thread = BorgDiffJob(params['cmd'], params, qapp) From 37f91ea96d981db13d97723f60788499ede71f19 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 24 Jul 2023 18:39:14 -0400 Subject: [PATCH 67/69] Update to Borg 2.0.0b6 Signed-off-by: Chirag Aggarwal --- noxfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noxfile.py b/noxfile.py index 3539d3f8e..804b8d60c 100644 --- a/noxfile.py +++ b/noxfile.py @@ -15,12 +15,12 @@ supported_borgbackup_versions = [ borgbackup - for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b5") + for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b6") # Python version requirements for borgbackup versions if (borgbackup == "1.1.18" and system_python_version >= (3, 5, 0)) or (borgbackup == "1.2.2" and system_python_version >= (3, 8, 0)) or (borgbackup == "1.2.4" and system_python_version >= (3, 8, 0)) - or (borgbackup == "2.0.0b5" and system_python_version >= (3, 9, 0)) + or (borgbackup == "2.0.0b6" and system_python_version >= (3, 9, 0)) ] From 1b2f272f63886fa70c2b6816d0a95ed28c4697c3 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Thu, 3 Aug 2023 19:07:30 -0400 Subject: [PATCH 68/69] Merge Master Signed-off-by: Chirag Aggarwal --- tests/{ => unit}/test_password_input.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{ => unit}/test_password_input.py (100%) diff --git a/tests/test_password_input.py b/tests/unit/test_password_input.py similarity index 100% rename from tests/test_password_input.py rename to tests/unit/test_password_input.py From 0532cd9d7171eeccf29e95eb9cb40ac9fdd3a692 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Thu, 3 Aug 2023 19:49:06 -0400 Subject: [PATCH 69/69] Switch to new password widget for test_init Signed-off-by: Chirag Aggarwal --- tests/integration/test_init.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/test_init.py b/tests/integration/test_init.py index 00cba53a3..7312a4202 100644 --- a/tests/integration/test_init.py +++ b/tests/integration/test_init.py @@ -39,8 +39,8 @@ def test_create_repo(qapp, qtbot, monkeypatch, choose_file_dialog, tmpdir): add_repo_window.repoName.del_() qtbot.keyClicks(add_repo_window.repoName, TEST_REPO_NAME) - qtbot.keyClicks(add_repo_window.passwordLineEdit, LONG_PASSWORD) - qtbot.keyClicks(add_repo_window.confirmLineEdit, LONG_PASSWORD) + qtbot.keyClicks(add_repo_window.passwordInput.passwordLineEdit, LONG_PASSWORD) + qtbot.keyClicks(add_repo_window.passwordInput.confirmLineEdit, LONG_PASSWORD) add_repo_window.run()