Skip to content

Commit c1b4db5

Browse files
authored
test for integrity remove (#17628)
* test for integrity remove * manifest and conaninfo.txt corruptions * more checks in tests
1 parent 2cb50a2 commit c1b4db5

File tree

3 files changed

+96
-6
lines changed

3 files changed

+96
-6
lines changed

conan/api/subapi/list.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,10 +394,12 @@ def _get_cache_packages_binary_info(cache, prefs) -> Dict[PkgReference, dict]:
394394
# Read conaninfo
395395
info_path = os.path.join(pkg_layout.package(), CONANINFO)
396396
if not os.path.exists(info_path):
397-
raise ConanException(f"Corrupted package '{pkg_layout.reference}' "
398-
f"without conaninfo.txt in: {info_path}")
399-
conan_info_content = load(info_path)
400-
info = load_binary_info(conan_info_content)
397+
ConanOutput().error(f"Corrupted package '{pkg_layout.reference}' "
398+
f"without conaninfo.txt in: {info_path}")
399+
info = {}
400+
else:
401+
conan_info_content = load(info_path)
402+
info = load_binary_info(conan_info_content)
401403
pref = pkg_layout.reference
402404
# The key shoudln't have the latest package revision, we are asking for package configs
403405
pref.revision = None

conan/internal/cache/integrity_check.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ def check(self, upload_data):
3232
def _recipe_corrupted(self, ref: RecipeReference):
3333
layout = self._cache.recipe_layout(ref)
3434
output = ConanOutput()
35-
read_manifest, expected_manifest = layout.recipe_manifests()
35+
try:
36+
read_manifest, expected_manifest = layout.recipe_manifests()
37+
except FileNotFoundError:
38+
output.error(f"{ref.repr_notime()}: Manifest missing", error_type="exception")
39+
return True
3640
# Filter exports_sources from read manifest if there are no exports_sources locally
3741
# This happens when recipe is downloaded without sources (not built from source)
3842
export_sources_folder = layout.export_sources()
@@ -52,7 +56,11 @@ def _recipe_corrupted(self, ref: RecipeReference):
5256
def _package_corrupted(self, ref: PkgReference):
5357
layout = self._cache.pkg_layout(ref)
5458
output = ConanOutput()
55-
read_manifest, expected_manifest = layout.package_manifests()
59+
try:
60+
read_manifest, expected_manifest = layout.package_manifests()
61+
except FileNotFoundError:
62+
output.error(f"{ref.repr_notime()}: Manifest missing", error_type="exception")
63+
return True
5664

5765
if read_manifest != expected_manifest:
5866
output.error(f"{ref}: Manifest mismatch", error_type="exception")

test/integration/command_v2/test_cache_integrity.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,92 @@ def test_cache_integrity():
1717
layout = t.created_layout()
1818
conaninfo = os.path.join(layout.package(), "conaninfo.txt")
1919
save(conaninfo, "[settings]")
20+
t.run("create . --name pkg4 --version=4.0")
21+
layout = t.created_layout()
22+
conaninfo = os.path.join(layout.package(), "conaninfo.txt")
23+
save(conaninfo, "[settings]")
2024

2125
t.run("cache check-integrity *", assert_error=True)
2226
assert "pkg1/1.0: Integrity checked: ok" in t.out
2327
assert "pkg1/1.0:da39a3ee5e6b4b0d3255bfef95601890afd80709: Integrity checked: ok" in t.out
2428
assert "ERROR: pkg2/2.0:da39a3ee5e6b4b0d3255bfef95601890afd80709: Manifest mismatch" in t.out
2529
assert "ERROR: pkg3/3.0:da39a3ee5e6b4b0d3255bfef95601890afd80709: Manifest mismatch" in t.out
30+
assert "ERROR: pkg4/4.0:da39a3ee5e6b4b0d3255bfef95601890afd80709: Manifest mismatch" in t.out
31+
32+
t.run("remove pkg2/2.0:da39a3ee5e6b4b0d3255bfef95601890afd80709 -c")
33+
t.run("remove pkg3/3.0:da39a3ee5e6b4b0d3255bfef95601890afd80709 -c")
34+
t.run("remove pkg4/4.0:da39a3ee5e6b4b0d3255bfef95601890afd80709 -c")
35+
t.run("cache check-integrity *")
36+
assert "pkg1/1.0: Integrity checked: ok" in t.out
37+
assert "pkg2/2.0: Integrity checked: ok" in t.out
38+
assert "pkg3/3.0: Integrity checked: ok" in t.out
39+
assert "pkg4/4.0: Integrity checked: ok" in t.out
40+
41+
42+
def test_cache_integrity_missing_recipe_manifest():
43+
t = TestClient()
44+
t.save({"conanfile.py": GenConanfile()})
45+
t.run("create . --name pkg1 --version 1.0")
46+
t.run("create . --name pkg2 --version=2.0")
47+
layout = t.exported_layout()
48+
manifest = os.path.join(layout.export(), "conanmanifest.txt")
49+
os.remove(manifest)
50+
t.run("create . --name pkg3 --version=3.0")
51+
52+
t.run("cache check-integrity *", assert_error=True)
53+
assert "pkg1/1.0: Integrity checked: ok" in t.out
54+
assert "ERROR: pkg2/2.0#4d670581ccb765839f2239cc8dff8fbd: Manifest missing" in t.out
55+
assert "pkg3/3.0: Integrity checked: ok" in t.out
56+
assert "ERROR: There are corrupted artifacts, check the error logs" in t.out
57+
58+
t.run("remove pkg2* -c")
59+
t.run("cache check-integrity *")
60+
assert "pkg1/1.0:da39a3ee5e6b4b0d3255bfef95601890afd80709: Integrity checked: ok" in t.out
61+
assert "pkg3/3.0: Integrity checked: ok" in t.out
62+
assert "Integrity check: ok" in t.out
63+
64+
65+
def test_cache_integrity_missing_package_manifest():
66+
t = TestClient()
67+
t.save({"conanfile.py": GenConanfile()})
68+
t.run("create . --name pkg1 --version 1.0")
69+
t.run("create . --name pkg2 --version=2.0")
70+
layout = t.created_layout()
71+
manifest = os.path.join(layout.package(), "conanmanifest.txt")
72+
os.remove(manifest)
73+
t.run("create . --name pkg3 --version=3.0")
74+
75+
t.run("cache check-integrity *", assert_error=True)
76+
assert "pkg1/1.0: Integrity checked: ok" in t.out
77+
assert "ERROR: pkg2/2.0#4d670581ccb765839f2239cc8dff8fbd" \
78+
":da39a3ee5e6b4b0d3255bfef95601890afd80709" \
79+
"#0ba8627bd47edc3a501e8f0eb9a79e5e: Manifest missing" in t.out
80+
assert "pkg3/3.0: Integrity checked: ok" in t.out
81+
assert "ERROR: There are corrupted artifacts, check the error logs" in t.out
82+
83+
t.run("remove pkg2* -c")
84+
t.run("cache check-integrity *")
85+
assert "pkg1/1.0:da39a3ee5e6b4b0d3255bfef95601890afd80709: Integrity checked: ok" in t.out
86+
assert "pkg3/3.0: Integrity checked: ok" in t.out
87+
assert "Integrity check: ok" in t.out
88+
89+
90+
def test_cache_integrity_missing_package_conaninfo():
91+
t = TestClient()
92+
t.save({"conanfile.py": GenConanfile()})
93+
t.run("create . --name pkg1 --version 1.0")
94+
t.run("create . --name pkg2 --version=2.0")
95+
layout = t.created_layout()
96+
conaninfo = os.path.join(layout.package(), "conaninfo.txt")
97+
os.remove(conaninfo)
98+
99+
t.run("cache check-integrity *", assert_error=True)
100+
assert "pkg1/1.0: Integrity checked: ok" in t.out
101+
assert "ERROR: pkg2/2.0:da39a3ee5e6b4b0d3255bfef95601890afd80709: Manifest mismatch" in t.out
102+
103+
t.run("remove pkg2* -c")
104+
t.run("cache check-integrity *")
105+
assert "pkg1/1.0:da39a3ee5e6b4b0d3255bfef95601890afd80709: Integrity checked: ok" in t.out
26106

27107

28108
def test_cache_integrity_export_sources():

0 commit comments

Comments
 (0)