scripts/e2e.sh ran only test_end_to_end_loop.py, and the integration step excludes e2e-marked tests, so test_review_live.py (M7.3) never ran in CI. The script now runs every e2e-marked test under tests/integration, and the review test is a smoke test: about a minute on the local model, and the only check that the review account, its token and its read-only refusal work. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
98 lines
3.6 KiB
Python
98 lines
3.6 KiB
Python
"""nisse-review against the real services (Part R, M7.3): a PR in a fresh
|
|
test repository gets one COMMENT review from the review account, by the
|
|
local model; an account that could write to a repository is refused.
|
|
|
|
Needs NISSE_REVIEW_GITEA_TOKEN, the review account's token (CI secret; .env
|
|
locally), besides what every live test needs.
|
|
"""
|
|
|
|
import io
|
|
import os
|
|
import uuid
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from e2e_support import e2e_roles, fresh_repo, operator_gitea
|
|
|
|
from nisse_core.gitea import GiteaClient
|
|
from nisse_core.oplog import OpLog
|
|
from nisse_dev.config import AgentConfig
|
|
from nisse_review.build import StartupError, build
|
|
from nisse_review.config import ReviewConfig
|
|
from nisse_review.review import marker
|
|
|
|
# Smoke: every PR runs it (about a minute on the local model), the only
|
|
# check that the review account, its token and its read-only refusal work.
|
|
pytestmark = [pytest.mark.integration, pytest.mark.e2e, pytest.mark.smoke]
|
|
|
|
|
|
def review_gitea(url: str) -> GiteaClient:
|
|
token = os.environ.get("NISSE_REVIEW_GITEA_TOKEN", "")
|
|
assert token.strip(), "NISSE_REVIEW_GITEA_TOKEN is not set: the review account's"
|
|
return GiteaClient(url, token)
|
|
|
|
|
|
def test_a_ready_pr_gets_one_comment_review(
|
|
live_config: AgentConfig, tmp_path: Path
|
|
) -> None:
|
|
run = uuid.uuid4().hex[:8]
|
|
operator = operator_gitea(live_config.gitea_url)
|
|
reviewer = review_gitea(live_config.gitea_url)
|
|
account = reviewer.whoami()
|
|
roles = e2e_roles()
|
|
with fresh_repo(
|
|
operator, f"review-{run}", tmp_path / "keys", agent=account
|
|
) as repo:
|
|
tree = {
|
|
"state_db": str(tmp_path / "review" / "state.db"),
|
|
"llm": {
|
|
"base_url": live_config.llm_base_url,
|
|
"token": live_config.llm_token,
|
|
},
|
|
"roles": {"reviewer": roles.driver, "expert": roles.expert},
|
|
"gitea": {
|
|
"url": live_config.gitea_url,
|
|
"token": os.environ["NISSE_REVIEW_GITEA_TOKEN"],
|
|
"operators": ["nisse-testing-operator"],
|
|
},
|
|
"repositories": [repo.name],
|
|
"tuning": {"review": {"max_turns": 25}},
|
|
}
|
|
config = ReviewConfig.from_tree(tree, {})
|
|
# make_repo gives the agent write access: the reviewer refuses that.
|
|
with pytest.raises(StartupError, match="read access only"):
|
|
build(config, gitea=reviewer, oplog=OpLog("t", io.StringIO()))
|
|
operator._request(
|
|
"PUT",
|
|
f"/repos/{repo.name}/collaborators/{account}",
|
|
json={"permission": "read"},
|
|
)
|
|
operator.branch_with_file(
|
|
repo.name,
|
|
base="main",
|
|
branch="shout",
|
|
path="sandbox/shout.py",
|
|
text='def shout(text):\n return text.upper() + "!"\n',
|
|
message="Add shout",
|
|
)
|
|
pr = operator.open_pull_request(
|
|
repo.name,
|
|
head="shout",
|
|
base="main",
|
|
title="Add shout",
|
|
body="Adds shout(text): the text in capitals, with an exclamation mark.",
|
|
)
|
|
built = build(config, gitea=reviewer, oplog=OpLog("t", io.StringIO()))
|
|
try:
|
|
assert built.scheduler.round() is True
|
|
assert built.scheduler.round() is False # reviewed once, not again
|
|
finally:
|
|
built.store.close()
|
|
head = operator.pull_request(repo.name, pr.number).head_sha
|
|
mine = [
|
|
r for r in operator.reviews(repo.name, pr.number) if r.author == account
|
|
]
|
|
assert len(mine) == 1
|
|
assert mine[0].state == "COMMENT" and mine[0].commit == head
|
|
assert marker(head) in mine[0].body
|