fix(python/robomp): corrected issue classification updates on rename-fail

- Moved issue classification updates to run only after branch rename succeeds, preventing partial labeling or DB writes when rename fails.
- Adjusted workspace ownership normalization to chown workspaces to the active slot or, when slotless, to the current euid/egid, then apply shared permissions.
- Added tests for classify_issue rename-failure rollback and chown_workspace normalization in non-slot mode.
This commit is contained in:
can1357
2026-05-25 19:54:19 +02:00
parent 2ad7124e25
commit d55b7d51df
4 changed files with 99 additions and 38 deletions
+37
View File
@@ -849,6 +849,43 @@ def test_classify_issue_rejects_invalid_branch_slug(db: Database, tmp_path: Path
assert bindings.workspace.branch == "farm/abc12345/some-issue"
def test_classify_issue_rename_failure_does_not_apply_labels_or_classification(
db: Database, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
requests: list[str] = []
def handler(request: httpx.Request) -> httpx.Response:
requests.append(str(request.url))
return httpx.Response(200, json=[])
def fail_rename(*_args: object, **_kwargs: object) -> str:
raise host_tools.GitCommandError(["git", "branch", "-m"], 128, "", "fatal: detected dubious ownership")
bindings, loop, t = _bindings(db, tmp_path, httpx.MockTransport(handler))
monkeypatch.setattr(host_tools, "rename_workspace_branch", fail_rename)
try:
tool = next(x for x in build(bindings) if x.name == "classify_issue")
with pytest.raises(RpcCommandError):
tool.execute(
{
"primary": "bug",
"priority": "prio:p1",
"rationale": "x",
"branch_slug": "fix-orphan-tool-output",
},
_ctx(),
)
finally:
_stop_loop(loop, t)
assert requests == []
row = db.get_issue(bindings.issue_key)
assert row is not None
assert row.classification is None
assert row.branch == "farm/abc12345/some-issue"
assert bindings.workspace.branch == "farm/abc12345/some-issue"
def test_classify_issue_omitting_branch_slug_is_a_noop(db: Database, tmp_path: Path) -> None:
"""Existing callers that don't pass branch_slug must keep the original branch."""
bindings, loop, t = _bindings(
+22
View File
@@ -616,6 +616,28 @@ def test_slot_subprocess_kwargs_run_as_slot_on_linux_root(monkeypatch: pytest.Mo
}
def test_chown_workspace_normalizes_to_root_when_slots_disabled(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
calls: list[tuple[list[str], bool | None]] = []
def fake_run(cmd: list[str], **kwargs: object) -> subprocess.CompletedProcess[str]:
calls.append((cmd, kwargs.get("check") if isinstance(kwargs.get("check"), bool) else None))
return subprocess.CompletedProcess(cmd, 0, "", "")
monkeypatch.setattr("robomp.sandbox.platform.system", lambda: "Linux")
monkeypatch.setattr("robomp.sandbox.os.geteuid", lambda: 0)
monkeypatch.setattr("robomp.sandbox.os.getegid", lambda: 0)
monkeypatch.setattr("robomp.sandbox.subprocess.run", fake_run)
_chown_workspace(tmp_path, None)
assert calls == [
(["chown", "-R", "0:0", str(tmp_path)], True),
(["chmod", "-R", "u=rwX,g=rwX,o=", str(tmp_path)], True),
]
def test_prepare_slot_runtime_env_returns_workspace_private_paths_without_chown(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None: