Skip to content

testsuite: fix flaky byte-corruption in check_cmd tests#9771

Merged
ThomasWaldmann merged 1 commit into
borgbackup:masterfrom
ThomasWaldmann:fix-spoofed-archive-flaky
Jun 13, 2026
Merged

testsuite: fix flaky byte-corruption in check_cmd tests#9771
ThomasWaldmann merged 1 commit into
borgbackup:masterfrom
ThomasWaldmann:fix-spoofed-archive-flaky

Conversation

@ThomasWaldmann

@ThomasWaldmann ThomasWaldmann commented Jun 13, 2026

Copy link
Copy Markdown
Member

What

Several tests in archiver/check_cmd_test.py intermittently failed (e.g. test_spoofed_archive with assert 0 == 1 on the first check).

Why

They corrupted a repo object by overwriting a byte at a fixed position with a fixed value:

corrupted_manifest = manifest[:250] + b"x" + manifest[251:]

Manifests and chunks are stored as AEAD-encrypted repo objects (repokey-aes-ocb), so their bytes are essentially random and differ every run. Whenever the targeted byte already happened to hold the overwrite value (~1 in 256), the "corruption" was a no-op: the object stayed valid, check found nothing wrong and returned 0, and the exit_code=1 assertion failed — hence the flakiness.

Fix

Introduce a small helper that flips the byte (XOR 0xFF), so the result is guaranteed to differ:

def corrupt(data, position):
    if position < 0:
        position += len(data)
    return data[:position] + bytes([data[position] ^ 0xFF]) + data[position + 1 :]

and use it at all the byte-overwrite corruption sites: test_corrupted_manifest, test_spoofed_manifest, test_manifest_rebuild_corrupted_chunk, test_spoofed_archive, test_verify_data, test_corrupted_file_chunk.

The crypto unit tests (crypto_test.py) do a similar overwrite but with fixed keys/IVs and deterministic output (they assert exact MAC hex), so they are not affected and are left unchanged.

Test

Ran the affected tests locally: 14 passed, 10 skipped (skips are the remote/binary variants).

🤖 Generated with Claude Code

Several check_cmd tests corrupted a repo object by overwriting a byte at
a fixed position with a fixed value, e.g.:

    manifest[:250] + b"x" + manifest[251:]

Manifests/chunks are stored as AEAD-encrypted repo objects, so their
bytes are ~random. When the target byte already happened to hold the
overwrite value (~1/256), the "corruption" was a no-op: the object
stayed valid, "check" returned 0 instead of 1, and the test failed
intermittently (observed in test_spoofed_archive).

Introduce a corrupt(data, position) helper that flips the byte (XOR
0xFF), so the result is guaranteed to differ, and use it in all the
byte-overwrite corruption sites: test_corrupted_manifest,
test_spoofed_manifest, test_manifest_rebuild_corrupted_chunk,
test_spoofed_archive, test_verify_data and test_corrupted_file_chunk.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ThomasWaldmann ThomasWaldmann force-pushed the fix-spoofed-archive-flaky branch from 8ccdddf to 27401aa Compare June 13, 2026 21:14
@ThomasWaldmann ThomasWaldmann changed the title testsuite: fix flaky test_spoofed_archive manifest corruption testsuite: fix flaky byte-corruption in check_cmd tests Jun 13, 2026
@codecov

codecov Bot commented Jun 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.90%. Comparing base (e0a040a) to head (27401aa).
⚠️ Report is 6 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9771      +/-   ##
==========================================
+ Coverage   84.86%   84.90%   +0.04%     
==========================================
  Files          92       92              
  Lines       15172    15107      -65     
  Branches     2273     2260      -13     
==========================================
- Hits        12875    12826      -49     
+ Misses       1593     1581      -12     
+ Partials      704      700       -4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@ThomasWaldmann ThomasWaldmann merged commit ff3133e into borgbackup:master Jun 13, 2026
19 checks passed
@ThomasWaldmann ThomasWaldmann deleted the fix-spoofed-archive-flaky branch June 13, 2026 22:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant