feat: --smart-resume 智能断点续传 (校验最新N个文件, 损坏即重传)
This commit is contained in:
1 parent
15ed4330ae
commit
0f9866a031
3 files changed
+142
-2
No files matched your search
@@ -370,3 +370,61 @@ def test_count_files_only_files(tmp_path):
|
||||
def test_parse_args_retry_infinite():
|
||||
args = transfer.parse_args(["--retry", "-1", "s", "d"])
|
||||
assert args.retry == -1 # 无限重试
|
||||
|
||||
# ---------- 智能断点续传 (校验最新N个文件) ----------
|
||||
|
||||
def test_verify_recent_all_ok(tmp_path):
|
||||
src = tmp_path / "s"; dst = tmp_path / "d"
|
||||
src.mkdir(); dst.mkdir()
|
||||
(src / "a.bin").write_bytes(b"x" * 1000)
|
||||
(dst / "a.bin").write_bytes(b"x" * 1000)
|
||||
assert transfer.verify_recent_files(str(src), str(dst)) == []
|
||||
|
||||
def test_verify_recent_detects_corrupt_and_deletes(tmp_path):
|
||||
src = tmp_path / "s"; dst = tmp_path / "d"
|
||||
src.mkdir(); dst.mkdir()
|
||||
(src / "a.bin").write_bytes(b"hello world")
|
||||
(dst / "a.bin").write_bytes(b"hello worlX") # 内容损坏
|
||||
bad = transfer.verify_recent_files(str(src), str(dst))
|
||||
assert bad == ["a.bin"]
|
||||
assert not (dst / "a.bin").exists() # 坏副本已删除
|
||||
|
||||
def test_verify_recent_empty_dst_no_check(tmp_path):
|
||||
"""目标无已传文件时无可校验 (缺失文件由 rsync 正常补传)"""
|
||||
src = tmp_path / "s"; dst = tmp_path / "d"
|
||||
src.mkdir(); dst.mkdir()
|
||||
(src / "a.bin").write_bytes(b"data")
|
||||
assert transfer.verify_recent_files(str(src), str(dst)) == []
|
||||
|
||||
def test_verify_recent_large_file_checks_size_only(tmp_path):
|
||||
""">100MB 只查大小, 不做内容 hash"""
|
||||
src = tmp_path / "s"; dst = tmp_path / "d"
|
||||
src.mkdir(); dst.mkdir()
|
||||
big = b"a" * (101 * 1024 * 1024) # 101MB
|
||||
(src / "big.bin").write_bytes(big)
|
||||
(dst / "big.bin").write_bytes(b"b" * len(big)) # 同大小不同内容
|
||||
assert transfer.verify_recent_files(str(src), str(dst)) == [] # 只查大小, 不报
|
||||
|
||||
def test_verify_recent_count_limit(tmp_path):
|
||||
"""只校验最新 N 个, 更早的损坏不报"""
|
||||
src = tmp_path / "s"; dst = tmp_path / "d"
|
||||
src.mkdir(); dst.mkdir()
|
||||
for i in range(3):
|
||||
(src / f"f{i}.txt").write_text("ok" * 100)
|
||||
(dst / f"f{i}.txt").write_text("ok" * 100)
|
||||
import time
|
||||
# 让 f0 是最早的
|
||||
old = time.time() - 100
|
||||
os.utime(str(dst / "f0.txt"), (old, old))
|
||||
os.utime(str(src / "f0.txt"), (old, old))
|
||||
# 损坏最早的文件 (不在最新2个内)
|
||||
(src / "f0.txt").write_text("changed")
|
||||
(dst / "f0.txt").write_text("changed-too")
|
||||
bad = transfer.verify_recent_files(str(src), str(dst), check_count=2)
|
||||
assert "f0.txt" not in bad # 只查最新2个
|
||||
|
||||
def test_parse_smart_resume():
|
||||
assert transfer.parse_args(["s", "d"]).smart_resume is False
|
||||
assert transfer.parse_args(["--smart-resume", "s", "d"]).smart_resume is True
|
||||
assert transfer.parse_args(["--smart-check", "3", "s", "d"]).smart_check == 3
|
||||
assert transfer.parse_args(["s", "d"]).smart_check == 5
|
||||
Reference in new issue
Block a user