fix: make messages say what was verified (source questions from the Italian review)

This commit is contained in:
MacRimi
2026-10-06 17:08:18 +02:00
parent 12632c027e
commit 85b88f709a
21 changed files with 166 additions and 50 deletions
+20 -2
View File
@@ -171,7 +171,8 @@ class RevertTests(unittest.TestCase):
patch.object(recognition, "stop", side_effect=lambda vmid: calls.append(("stop", vmid))), \
patch.object(recognition, "apply", side_effect=lambda *arguments: calls.append(("apply",) + arguments[2:])), \
patch.object(recognition.subprocess, "run", side_effect=lambda command, **_: calls.append(tuple(command[:3]))):
recognition.revert(Path("/nonexistent"), 100, 101, {"cpu": "image"}, ("cpu", None, None), True)
kept = recognition.revert(Path("/nonexistent"), 100, 101, {"cpu": "image"}, ("cpu", None, None), True)
self.assertTrue(kept)
self.assertEqual(calls, [("stop", 101), ("apply", 101, {"cpu": "image"}, "cpu", None, None),
("pct", "start", "101")])
@@ -180,9 +181,26 @@ class RevertTests(unittest.TestCase):
patch.object(recognition, "apply", side_effect=RuntimeError("pct set: locked")), \
patch.object(recognition, "msg_warn") as warned, \
patch.object(recognition.subprocess, "run") as started:
recognition.revert(Path("/nonexistent"), 100, 101, {}, ("cpu", None, None), True)
kept = recognition.revert(Path("/nonexistent"), 100, 101, {}, ("cpu", None, None), True)
self.assertIn("pct set: locked", warned.call_args[0][0])
started.assert_not_called()
self.assertFalse(kept)
def test_the_error_only_says_nothing_changed_when_the_choice_was_kept(self):
def reported(error):
with patch.object(recognition.os, "geteuid", return_value=0), \
patch.object(recognition.sys, "argv", ["x", "100", "--acceleration", "cpu"]), \
patch.object(recognition, "change", side_effect=error), \
patch.object(recognition, "translate", side_effect=lambda text: text), \
patch.object(recognition, "msg_error") as shown:
self.assertEqual(recognition.main(), 1)
return shown.call_args[0][0]
self.assertIn("was not changed", reported(ValueError("already on that choice")))
put_back = RuntimeError("update failed"); put_back.recognition_kept = True
self.assertIn("was not changed", reported(put_back))
left = RuntimeError("update failed"); left.recognition_kept = False
self.assertIn("did not complete", reported(left))
self.assertNotIn("was not changed", reported(left))
class RocmProbeTests(unittest.TestCase):
+50
View File
@@ -546,5 +546,55 @@ class RegistrationTests(unittest.TestCase):
self.assertNotIn("deployment", services[2])
class FirewallConsentTests(unittest.TestCase):
"""A host firewall rule is added only for the container it was confirmed for."""
def recover(self, confirmed):
rule = lambda vmid, port: {"vmid": vmid, "port": port, "source": "192.0.2.0/24"}
plan = {"bridges": {}, "renumbered": {}, "hold": False, "notes": [],
"restored": [{"vmid": 120, "firewall": rule(120, 61208)}, {"vmid": 121, "firewall": rule(121, 19999)}]}
added = []
with patch.object(recovery, "restore_host_files"), patch.object(recovery, "clean_format_directories"), \
patch.object(recovery, "register", return_value=[120, 121]), patch.object(recovery.carried, "carry"), \
patch.object(recovery, "add_firewall_rule", side_effect=lambda rule: added.append(rule["vmid"]) or True), \
patch.object(recovery, "msg_info"), patch.object(recovery, "msg_ok"):
recovery.recover(Path("/nonexistent"), plan, host_firewall=confirmed)
return added, plan["notes"]
def test_one_confirmed_rule_does_not_add_the_others(self):
added, notes = self.recover([121])
self.assertEqual(added, [121])
self.assertEqual([note[:7] for note in notes], ["CT 120:"])
def test_without_an_answer_no_rule_is_added(self):
added, notes = self.recover([])
self.assertEqual(added, [])
self.assertEqual(len(notes), 2)
def test_the_menu_asks_for_each_rule_and_passes_only_the_confirmed_ones(self):
sys.path.insert(0, str(ROOT / "src"))
from proxmenux_oci import management
rules = [{"vmid": 120, "port": 61208, "source": "192.0.2.0/24"},
{"vmid": 121, "port": 19999, "source": "192.0.2.0/24"}]
answers = iter([True, False, True, False]) # recover, rule of 120, rule of 121, start
class Ui:
asked = []
def confirm(self, text, default=False):
self.asked.append(text)
return next(answers)
ui = Ui()
with patch.object(management, "restored_applications", return_value=[{"vmid": 120, "hostname": "glances"},
{"vmid": 121, "hostname": "netdata"}]), \
patch.object(management, "_restored_firewall_rules", return_value=rules), \
patch.object(management, "_run_lifecycle") as run:
management.offer_recovery(ROOT, ui)
command = run.call_args[0][0]
self.assertEqual(len(ui.asked), 4)
self.assertEqual(command[command.index("--host-firewall"):], ["--host-firewall", "121"])
if __name__ == "__main__":
unittest.main()
+17 -1
View File
@@ -54,8 +54,24 @@ class StageReleaseTests(unittest.TestCase):
patch.object(transaction, "stop"), \
patch.object(transaction, "run", side_effect=RuntimeError("pct failed with exit code 255")), \
patch.object(transaction, "log") as logged:
transaction.discard_stage(STATE)
removed = transaction.discard_stage(STATE)
self.assertIn("pct failed", logged.call_args[0][0])
self.assertFalse(removed)
def test_the_result_says_whether_the_container_was_removed(self):
with patch.object(transaction, "owned", return_value=HOLDING), patch.object(transaction, "stop"), \
patch.object(transaction, "run"):
self.assertTrue(transaction.discard_stage(STATE))
self.assertFalse(transaction.release_stage(STATE))
with patch.object(transaction, "owned", side_effect=ValueError("not ours")):
self.assertFalse(transaction.discard_stage(STATE))
self.assertFalse(transaction.discard_stage({"id": "x"}))
def test_the_recovery_only_says_the_disks_were_removed_when_they_were(self):
source = (ROOT / "remote/oci_instance_transaction.py").read_text()
claim = source.index("The disks of the failed attempt were removed")
self.assertIn("if discard_stage(state):", source[source.rindex("\n", 0, claim - 80):claim])
self.assertIn("could not be removed and stay in the temporary container", source)
if __name__ == "__main__":