فهرست منبع

improve borg check --repair healing tests, see #8302

test the healing more thoroughly:
- preservation of correct chunks list in .chunks_healthy
- check that .chunks_healthy is removed after healing
- check that doing another borg check --repair run does not find
  something to heal, again.

also did a datatype consistency fix for item.chunks_healthy list
members: they are now post processed in the same way as item.chunks,
so they have type ChunkListEntry rather than simple tuple.
Thomas Waldmann 10 ماه پیش
والد
کامیت
c6f95de492
2فایلهای تغییر یافته به همراه18 افزوده شده و 3 حذف شده
  1. 2 0
      src/borg/archive.py
  2. 16 3
      src/borg/testsuite/archiver/check_cmd.py

+ 2 - 0
src/borg/archive.py

@@ -282,6 +282,8 @@ class DownloadPipeline:
                 item = Item(internal_dict=_item)
                 if "chunks" in item:
                     item.chunks = [ChunkListEntry(*e) for e in item.chunks]
+                if "chunks_healthy" in item:
+                    item.chunks_healthy = [ChunkListEntry(*e) for e in item.chunks_healthy]
                 if filter and not filter(item):
                     continue
                 if preload and "chunks" in item:

+ 16 - 3
src/borg/testsuite/archiver/check_cmd.py

@@ -115,14 +115,20 @@ def test_missing_file_chunk(archivers, request):
     output = cmd(archiver, "list", "archive1", "--format={health}#{path}{NL}", exit_code=0)
     assert "broken#" in output
 
-    # check that the file in the old archives has now a different chunk list without the killed chunk
+    # check that the file in the old archives has now a different chunk list without the killed chunk.
+    # also check that the correct original chunks list is preserved in item.chunks_healthy.
     for archive_name in ("archive1", "archive2"):
         archive, repository = open_archive(archiver.repository_path, archive_name)
         with repository:
             for item in archive.iter_items():
                 if item.path.endswith(src_file):
-                    assert valid_chunks != item.chunks
+                    assert len(valid_chunks) == len(item.chunks)
                     assert killed_chunk not in item.chunks
+                    assert valid_chunks != item.chunks
+                    assert "chunks_healthy" in item
+                    assert len(valid_chunks) == len(item.chunks_healthy)
+                    assert killed_chunk in item.chunks_healthy
+                    assert valid_chunks == item.chunks_healthy
                     break
             else:
                 pytest.fail("should not happen")  # convert 'fail'
@@ -136,13 +142,15 @@ def test_missing_file_chunk(archivers, request):
     assert "Healed previously missing file chunk" in output
     assert f"{src_file}: Completely healed previously damaged file!" in output
 
-    # check that the file in the old archives has the correct chunks again
+    # check that the file in the old archives has the correct chunks again.
+    # also check that chunks_healthy list is removed as it is not needed any more.
     for archive_name in ("archive1", "archive2"):
         archive, repository = open_archive(archiver.repository_path, archive_name)
         with repository:
             for item in archive.iter_items():
                 if item.path.endswith(src_file):
                     assert valid_chunks == item.chunks
+                    assert "chunks_healthy" not in item
                     break
             else:
                 pytest.fail("should not happen")
@@ -151,6 +159,11 @@ def test_missing_file_chunk(archivers, request):
     output = cmd(archiver, "list", "archive1", "--format={health}#{path}{NL}", exit_code=0)
     assert "broken#" not in output
 
+    # check should be fine now (and not show it has healed anything).
+    output = cmd(archiver, "check", "-v", "--repair", exit_code=0)
+    assert "Healed previously missing file chunk" not in output
+    assert "testsuite/archiver.py: Completely healed previously damaged file!" not in output
+
 
 def test_missing_archive_item_chunk(archivers, request):
     archiver = request.getfixturevalue(archivers)