70 lines
3.1 KiB
Python
70 lines
3.1 KiB
Python
import unittest
|
|
|
|
from tests.fakes import BOT, FakeGitea, FakeModel, config, diff_for, gitea_file
|
|
from tests.test_flow import run
|
|
from tests.test_open_questions import DOC, doc_bytes
|
|
from werkrevisor.verdict import Verdict
|
|
|
|
GATE = {"yellow_gate": "approval", "human_reviewers": ["alice"], "max_red_rounds": 3}
|
|
|
|
|
|
def result_comment(sha, verdict):
|
|
return {"id": hash(sha) % 10000, "user": {"login": BOT},
|
|
"body": f"<!-- werkrevisor:{sha} -->\n<!-- werkrevisor-verdict:{verdict} -->\n## werkrevisor: {verdict}"}
|
|
|
|
|
|
def red_run(earlier):
|
|
"""The new head has an open question in its PR document, so its review is RED."""
|
|
comments = [result_comment(f"{i:040x}", v) for i, v in enumerate(earlier, 1)]
|
|
gitea = FakeGitea(files=[gitea_file(DOC)], diff=diff_for(DOC, added=["x"]), comments=comments)
|
|
gitea.raw_files[DOC] = doc_bytes(1)
|
|
outcome, _ = run(gitea, FakeModel(prompt_files=[DOC]), cfg=config(gate=GATE))
|
|
return outcome, gitea
|
|
|
|
|
|
def codes(outcome):
|
|
return [r.code for r in outcome.result.reasons]
|
|
|
|
|
|
class RedRoundsTest(unittest.TestCase):
|
|
def test_the_fourth_red_in_a_row_asks_a_human(self):
|
|
"""Scenario#62.01"""
|
|
outcome, gitea = red_run(["RED", "RED", "RED"])
|
|
self.assertIs(outcome.result.verdict, Verdict.RED)
|
|
reason = next(r for r in outcome.result.reasons if r.code == "red_escalated")
|
|
self.assertEqual(reason.text, "RED after 3 rounds of new commits: the automatic rounds end, "
|
|
"and a human decides how to go on")
|
|
self.assertEqual(gitea.requested, ["alice"])
|
|
|
|
def test_fewer_rounds_give_red_as_before(self):
|
|
"""Scenario#62.02"""
|
|
outcome, gitea = red_run(["RED", "RED"])
|
|
self.assertIs(outcome.result.verdict, Verdict.RED)
|
|
self.assertNotIn("red_escalated", codes(outcome))
|
|
self.assertEqual(gitea.requested, [])
|
|
|
|
def test_a_head_without_red_starts_the_count_anew(self):
|
|
"""Scenario#62.03"""
|
|
outcome, gitea = red_run(["RED", "RED", "RED", "GREEN"])
|
|
self.assertNotIn("red_escalated", codes(outcome))
|
|
self.assertEqual(gitea.requested, [])
|
|
|
|
def test_without_the_approval_gate_the_escalation_is_named_too(self):
|
|
comments = [result_comment(f"{i:040x}", "RED") for i in range(1, 4)]
|
|
gitea = FakeGitea(files=[gitea_file(DOC)], diff=diff_for(DOC, added=["x"]), comments=comments)
|
|
gitea.raw_files[DOC] = doc_bytes(1)
|
|
outcome, _ = run(gitea, FakeModel(prompt_files=[DOC]), cfg=config(gate={**GATE, "yellow_gate": "block"}))
|
|
self.assertEqual(gitea.requested, ["alice"])
|
|
self.assertEqual(outcome.result.gate_note, "escalated to alice")
|
|
|
|
def test_zero_never_escalates(self):
|
|
comments = [result_comment(f"{i:040x}", "RED") for i in range(1, 6)]
|
|
gitea = FakeGitea(files=[gitea_file(DOC)], diff=diff_for(DOC, added=["x"]), comments=comments)
|
|
gitea.raw_files[DOC] = doc_bytes(1)
|
|
outcome, _ = run(gitea, FakeModel(prompt_files=[DOC]), cfg=config(gate={**GATE, "max_red_rounds": 0}))
|
|
self.assertNotIn("red_escalated", codes(outcome))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|