diff --git a/scripts/slots.py b/scripts/slots.py index 8e336db7..18c4ba49 100644 --- a/scripts/slots.py +++ b/scripts/slots.py @@ -355,14 +355,17 @@ def format_decision(decision: Decision) -> str: conflict = decision.conflict if decision.serves_both: winner = decision.winner.local_path - served = sorted({ - c.emulator for c in conflict.profile_claims - if c.emulator and c.local_path == winner - }) - others = sorted({ + # A claim that only matched a path is answered by whatever file sits + # there; only one that pins content can be left wanting. + pinned_elsewhere = { c.emulator for c in conflict.profile_claims if c.emulator and c.local_path != winner - }) + and resolution_is_hash_exact(c.status) + } + served = sorted({ + c.emulator for c in conflict.profile_claims if c.emulator + } - pinned_elsewhere) + others = sorted(pinned_elsewhere) line = ( f"{conflict.destination}: serve {winner} " f"({', '.join(served) or 'profile'}); the frontend only " diff --git a/tests/test_slots.py b/tests/test_slots.py index 11878bc2..752c28af 100644 --- a/tests/test_slots.py +++ b/tests/test_slots.py @@ -573,7 +573,22 @@ class StrongestProfileClaimWins(unittest.TestCase): ) decision = arbitrate(conflict, "existence") self.assertEqual(decision.winner.emulator, "yaps2") - self.assertIn("armsx2 expected another file", format_decision(decision)) + # armsx2 names no content: the file at the path answers it too. + line = format_decision(decision) + self.assertIn("(armsx2, yaps2)", line) + self.assertNotIn("expected another file", line) + + pinned = Conflict( + conflict.destination, + conflict.platform_claim, + [claim("armsx2", "a", "md5_exact"), claim("yaps2", "y", "sha1_exact")], + ) + # Both pin content: the tie goes to the first, the other is named. + self.assertIn( + "yaps2 expected another file", + format_decision(arbitrate(pinned, "existence")), + ) + if __name__ == "__main__": unittest.main()