diff --git a/.github/scripts/generate-matrix.sh b/.github/scripts/generate-matrix.sh index c797abb5..9b8e2d39 100644 --- a/.github/scripts/generate-matrix.sh +++ b/.github/scripts/generate-matrix.sh @@ -3,28 +3,28 @@ branch_name="$2" if [[ "$event_name" == "workflow_dispatch" ]] || [[ "$branch_name" == "master" ]]; then echo '{ - "python-version": ["3.8", "3.9", "3.10", "3.11"], - "os": ["ubuntu-22.04", "macos-12"], - "borg-version": ["1.2.4"] + "python-version": ["3.9", "3.10", "3.11"], + "os": ["ubuntu-22.04", "macos-14"], + "borg-version": ["1.4.0"] }' | jq -c . > matrix-unit.json echo '{ - "python-version": ["3.8", "3.9", "3.10", "3.11"], - "os": ["ubuntu-22.04", "macos-12"], - "borg-version": ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"], - "exclude": [{"borg-version": "2.0.0b5", "python-version": "3.8"}] + "python-version": ["3.9", "3.10", "3.11"], + "os": ["ubuntu-22.04", "macos-14"], + "borg-version": ["1.1.18", "1.2.8", "1.4.0", "2.0.0b12"], + "exclude": [{"borg-version": "2.0.0b12", "python-version": "3.8"}] }' | jq -c . > matrix-integration.json elif [[ "$event_name" == "push" ]] || [[ "$event_name" == "pull_request" ]]; then echo '{ - "python-version": ["3.8", "3.9", "3.10", "3.11"], - "os": ["ubuntu-22.04", "macos-12"], - "borg-version": ["1.2.4"] + "python-version": ["3.9", "3.11"], + "os": ["ubuntu-22.04", "macos-14"], + "borg-version": ["1.2.8"] }' | jq -c . > matrix-unit.json echo '{ - "python-version": ["3.10"], + "python-version": ["3.11"], "os": ["ubuntu-22.04"], - "borg-version": ["1.2.4"] + "borg-version": ["1.2.8"] }' | jq -c . > matrix-integration.json fi diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index c1c19aa2..6a6b162c 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -31,12 +31,12 @@ jobs: run: | brew install --cask sparkle brew install create-dmg - pip3 install --upgrade pip - pip3 install -r dev.txt + pip3 install --break-system-packages --upgrade pip + pip3 install --break-system-packages -r dev.txt working-directory: requirements.d - name: Install Vorta run: | - pip3 install . + pip3 install --break-system-packages . - name: Package with PyInstaller run: | pyinstaller --clean --noconfirm package/vorta.spec diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 40156ba5..5d78041a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,7 +51,7 @@ jobs: test-unit: needs: prepare-matrix - timeout-minutes: 20 + timeout-minutes: 60 # macos tests are very slow runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -137,10 +137,11 @@ jobs: run: echo $PKG_CONFIG_PATH && make test-integration - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 env: OS: ${{ runner.os }} python: ${{ matrix.python-version }} with: token: ${{ secrets.CODECOV_TOKEN }} env_vars: OS, python + version: v0.7.3 # workaround on Intel macs (GH Actions) diff --git a/tests/integration/test_diff.py b/tests/integration/test_diff.py index d2a4dacf..97ca6fb7 100644 --- a/tests/integration/test_diff.py +++ b/tests/integration/test_diff.py @@ -18,335 +18,347 @@ @pytest.mark.parametrize( - 'archive_name_1, archive_name_2, expected', + "archive_name_1, archive_name_2, expected", [ ( - 'test-archive1', - 'test-archive2', + "test-archive1", + "test-archive2", [ { - 'subpath': 'dir', - 'data': { - 'file_type': FileType.FILE, - 'change_type': ChangeType.MODIFIED, - 'modified': None, + "subpath": "dir", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.MODIFIED, + "modified": None, }, - 'min_version': '1.2.4', - 'max_version': '1.2.4', + "min_version": "1.2.4", + "max_version": "1.2.8", }, { - 'subpath': 'file', - 'data': { - 'file_type': FileType.FILE, - 'change_type': ChangeType.MODIFIED, - 'modified': (0, 0), + "subpath": "file", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.MODIFIED, + "modified": (0, 0), }, - 'min_version': '1.2.4', - 'max_version': '1.2.4', + "min_version": "1.2.4", + "max_version": "1.2.8", }, { - 'subpath': 'chrdev', - 'data': { - 'file_type': FileType.CHRDEV, - 'change_type': ChangeType.ADDED, - 'modified': None, + "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": "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": "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, + "subpath": "symlink", + "data": { + "file_type": FileType.LINK, + "change_type": ChangeType.ADDED, + "modified": None, }, }, ], ), ( - 'test-archive2', - 'test-archive3', + "test-archive2", + "test-archive3", [ { - 'subpath': 'borg_src', - 'match_startsWith': True, - 'data': { - 'file_type': FileType.FILE, - 'change_type': ChangeType.MODIFIED, - 'modified': None, + "subpath": "borg_src", + "match_startsWith": True, + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.MODIFIED, + "modified": None, }, - 'min_version': '1.2.4', - 'max_version': '1.2.4', + "min_version": "1.2.4", + "max_version": "1.2.8", }, { - 'subpath': 'dir', - 'data': { - 'file_type': FileType.DIRECTORY, - 'change_type': ChangeType.REMOVED, - '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": "chrdev", + "data": { + "file_type": FileType.CHRDEV, + "change_type": ChangeType.REMOVED, }, }, { - 'subpath': 'fifo', - 'data': { - 'file_type': FileType.FIFO, - '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": "file", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.REMOVED, }, }, { - 'subpath': 'hardlink', - '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": "symlink", + "data": { + "file_type": FileType.LINK, + "change_type": ChangeType.REMOVED, }, }, { - 'subpath': 'dir1', - 'data': { - 'file_type': FileType.DIRECTORY, - 'change_type': ChangeType.ADDED, + "subpath": "dir1", + "data": { + "file_type": FileType.DIRECTORY, + "change_type": ChangeType.ADDED, }, }, { - 'subpath': 'chrdev', - 'data': { - 'file_type': FileType.CHRDEV, - '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": "fifo", + "data": { + "file_type": FileType.FIFO, + "change_type": ChangeType.ADDED, }, }, { - 'subpath': 'file', - 'data': { - 'file_type': FileType.FILE, - '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": "hardlink", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.ADDED, }, }, { - 'subpath': 'symlink', - 'data': { - 'file_type': FileType.LINK, - 'change_type': ChangeType.ADDED, + "subpath": "symlink", + "data": { + "file_type": FileType.LINK, + "change_type": ChangeType.ADDED, }, }, ], ), ( - 'test-archive3', - 'test-archive4', + "test-archive3", + "test-archive4", [ { - 'subpath': 'dir1', - 'data': { - 'file_type': FileType.FILE, - 'change_type': ChangeType.MODIFIED, + "subpath": "dir1", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.MODIFIED, }, - 'min_version': '1.2.4', - 'max_version': '1.2.4', + "min_version": "1.2.4", + "max_version": "1.2.8", }, { - 'subpath': 'chrdev', - 'data': { - 'file_type': FileType.CHRDEV, - 'change_type': ChangeType.REMOVED, + "subpath": "chrdev", + "data": { + "file_type": FileType.CHRDEV, + "change_type": ChangeType.REMOVED, }, }, { - 'subpath': 'chrdev1', - 'data': { - 'file_type': FileType.CHRDEV, - 'change_type': ChangeType.ADDED, + "subpath": "chrdev1", + "data": { + "file_type": FileType.CHRDEV, + "change_type": ChangeType.ADDED, }, }, { - 'subpath': 'fifo', - 'data': { - 'file_type': FileType.FIFO, - 'change_type': ChangeType.REMOVED, + "subpath": "fifo", + "data": { + "file_type": FileType.FIFO, + "change_type": ChangeType.REMOVED, }, }, { - 'subpath': 'fifo1', - 'data': { - 'file_type': FileType.FIFO, - 'change_type': ChangeType.ADDED, + "subpath": "fifo1", + "data": { + "file_type": FileType.FIFO, + "change_type": ChangeType.ADDED, }, }, { - 'subpath': 'file', - 'data': { - 'file_type': FileType.FILE, - 'change_type': ChangeType.REMOVED, + "subpath": "file", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.REMOVED, }, }, { - 'subpath': 'file1', - 'data': { - 'file_type': FileType.FILE, - 'change_type': ChangeType.ADDED, + "subpath": "file1", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.ADDED, }, }, { - 'subpath': 'hardlink', - 'data': { - 'file_type': FileType.FILE, - 'change_type': ChangeType.REMOVED, + "subpath": "hardlink", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.REMOVED, }, }, { - 'subpath': 'hardlink1', - 'data': { - 'file_type': FileType.FILE, - 'change_type': ChangeType.ADDED, + "subpath": "hardlink1", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.ADDED, }, }, { - 'subpath': 'symlink', - 'data': { - 'file_type': FileType.LINK, - 'change_type': ChangeType.REMOVED, + "subpath": "symlink", + "data": { + "file_type": FileType.LINK, + "change_type": ChangeType.REMOVED, }, }, { - 'subpath': 'symlink1', - 'data': { - 'file_type': FileType.LINK, - 'change_type': ChangeType.ADDED, + "subpath": "symlink1", + "data": { + "file_type": FileType.LINK, + "change_type": ChangeType.ADDED, }, }, ], ), ( - 'test-archive4', - 'test-archive5', + "test-archive4", + "test-archive5", [ { - 'subpath': 'dir1', - 'data': { - 'file_type': FileType.FILE, - 'change_type': ChangeType.MODIFIED, + "subpath": "dir1", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.MODIFIED, }, - 'min_version': '1.2.4', - 'max_version': '1.2.4', + "min_version": "1.2.4", + "max_version": "1.2.8", }, { - 'subpath': 'chrdev1', - 'data': { - 'file_type': FileType.CHRDEV, - 'change_type': ChangeType.REMOVED, + "subpath": "chrdev1", + "data": { + "file_type": FileType.CHRDEV, + "change_type": ChangeType.REMOVED, }, }, { - 'subpath': 'fifo1', - 'data': { - 'file_type': FileType.FIFO, - '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": "file1", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.REMOVED, }, }, { - 'subpath': 'hardlink1', - '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, + "subpath": "symlink1", + "data": { + "file_type": FileType.LINK, + "change_type": ChangeType.REMOVED, }, }, ], ), ( - 'test-archive5', - 'test-archive6', + "test-archive5", + "test-archive6", [ { - 'subpath': 'dir1', - 'data': { - 'file_type': FileType.FILE, - 'change_type': ChangeType.MODIFIED, + "subpath": "dir1", + "data": { + "file_type": FileType.FILE, + "change_type": ChangeType.MODIFIED, }, - 'min_version': '1.2.4', - 'max_version': '1.2.4', + "min_version": "1.2.4", + "max_version": "1.2.8", }, ], ), ], ) -def test_archive_diff_lines(qapp, qtbot, borg_version, create_test_repo, 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_fifo = parsed_borg_version > parse_version("1.1.18") 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) + 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'] + diff_lines = blocker.args[0]["data"] + json_lines = blocker.args[0]["params"]["json_lines"] model = DiffTree() model.setMode(model.DisplayMode.FLAT) @@ -360,15 +372,15 @@ def test_archive_diff_lines(qapp, qtbot, borg_version, create_test_repo, archive 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) + ("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) ) ] # 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']) + 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, @@ -377,10 +389,10 @@ def test_archive_diff_lines(qapp, qtbot, borg_version, create_test_repo, archive assert len(sorted_model) == len(expected) for index, item in enumerate(expected): - if 'match_startsWith' in item and item['match_startsWith']: - assert sorted_model[index].subpath.startswith(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'] + assert sorted_model[index].subpath == item["subpath"] - for key, value in item['data'].items(): + for key, value in item["data"].items(): assert getattr(sorted_model[index].data, key) == value