diff --git a/scripts/common.py b/scripts/common.py index 3d3d6baa..f2e98204 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -1938,13 +1938,17 @@ def group_identical_platforms( inherits[platform] = False continue - entries = [] - for sys_id, system in sorted(config.get("systems", {}).items()): - for fe in system.get("files", []): - dest = fe.get("destination", fe.get("name", "")) - sha1 = fe.get("sha1", "") - md5 = fe.get("md5", "") - entries.append(f"{dest}|{sha1}|{md5}") + # Every field of every entry: the builder reads required, zipped_file, + # size and crc32 too, so two lists that differ only there are two + # packs. So is the way the frontend checks a file. + entries = [ + json.dumps(fe, sort_keys=True, default=str) + for _sys_id, system in sorted(config.get("systems", {}).items()) + for fe in system.get("files", []) + ] + entries.append( + f"mode={config.get('verification_mode', '')}|rule={config.get('hash_rule', '')}" + ) fp = hashlib.sha1("|".join(sorted(entries)).encode()).hexdigest() cores = config.get("cores") diff --git a/tests/test_pack_grouping.py b/tests/test_pack_grouping.py index e60125fd..d24674c4 100644 --- a/tests/test_pack_grouping.py +++ b/tests/test_pack_grouping.py @@ -75,5 +75,33 @@ class VariantGroupSpansSystems(unittest.TestCase): self.assertNotIn(name, names) +class AFrontendCheckSeparatesPacks(unittest.TestCase): + """Two lists of the same files under different checks are two packs: a + hash platform drops a file whose hash disagrees, an existence one ships + it. The fingerprint read destination, sha1 and md5 only.""" + + def test_verification_mode_and_entry_fields_split_groups(self): + import tempfile + + import yaml + + import common + + files = [{"name": "a.bin", "destination": "a.bin", "md5": "0" * 32}] + with tempfile.TemporaryDirectory() as tmp: + for name, mode, extra in (("one", "existence", {}), ("two", "md5", {}), + ("three", "existence", {"required": False})): + entry = {**files[0], **extra} + Path(tmp, f"{name}.yml").write_text(yaml.dump({ + "platform": name, "verification_mode": mode, + "systems": {"s": {"files": [entry]}}, + })) + Path(tmp, "_registry.yml").write_text(yaml.dump({"platforms": {}})) + common._platform_config_cache.clear() + self.addCleanup(common._platform_config_cache.clear) + groups = common.group_identical_platforms(["one", "two", "three"], tmp) + self.assertEqual(sorted(g for g, _ in groups), [["one"], ["three"], ["two"]]) + + if __name__ == "__main__": unittest.main()