refactor: extract minimal pure helpers from _continue_task, _task_wait, _task_thread_read and _metrics

_continue_task 226->168 via _validate_continue_options;
_task_wait 158->139 via _validate_wait_params;
_task_thread_read 187->152 via _summarize_trace_entries;
_metrics 123->104 via _summarize_metrics_tasks.
No behaviour, message, status or route change; error strings verbatim.
New tests: test_longfunc_extra (9). Cloud full suite: 1439 OK, skipped=4.
Follows #229 pattern; must merge after #229 and be rebased/checked then.
This commit is contained in:
host committed 2026-11-03 02:48:55 +00:00
1 parent f96960c9c5
commit 1accfac844
2 files changed
+380 -154

No files matched your search

+177
View File
@@ -0,0 +1,177 @@
"""长函数小提取第二轨(#229 之后):四处纯函数钉住测试。
只钉住本轨抽出的四个纯函数(成功路径与错误串),不改原有
断言语义;原路由行为不变由 test_task_continue /
test_thread_wait_ops / test_thread_ops 等定向套件覆盖。
"""
import sys
import unittest
from pathlib import Path
try:
from cloud.server import (
TASK_STATUS_KEYS,
_summarize_metrics_tasks,
_summarize_trace_entries,
_validate_continue_options,
_validate_wait_params,
)
except ImportError: # discover -s cloud/tests 时把项目根目录补进 sys.path
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
from cloud.server import (
TASK_STATUS_KEYS,
_summarize_metrics_tasks,
_summarize_trace_entries,
_validate_continue_options,
_validate_wait_params,
)
def _task(**over):
task = {"plan": 0, "goal_mode": 0, "approval": "ask"}
task.update(over)
return task
class ValidateContinueOptionsTestCase(unittest.TestCase):
def test_success_defaults_from_task(self):
opts, err = _validate_continue_options({}, _task(), None)
self.assertIsNone(err)
self.assertIsNone(opts["model"])
self.assertIsNone(opts["effort"])
self.assertFalse(opts["child_model_present"])
self.assertFalse(opts["child_effort_present"])
self.assertIsNone(opts["approval"])
self.assertIsNone(opts["plan"])
self.assertIsNone(opts["goal_mode"])
def test_success_explicit_and_empty_child_clears(self):
opts, err = _validate_continue_options(
{"model": " m ", "effort": "low", "child_model": "",
"child_effort": "", "approval": "auto", "plan": True,
"goal_mode": 0},
_task(), None)
self.assertIsNone(err)
self.assertEqual(opts["model"], "m")
self.assertEqual(opts["effort"], "low")
self.assertIsNone(opts["child_model"])
self.assertTrue(opts["child_model_present"])
self.assertIsNone(opts["child_effort"])
self.assertTrue(opts["child_effort_present"])
self.assertEqual(opts["plan"], 1)
self.assertEqual(opts["goal_mode"], 0)
def test_goal_command_forces_goal_mode(self):
opts, err = _validate_continue_options(
{"goal_mode": 0}, _task(), "do X")
self.assertIsNone(err)
self.assertEqual(opts["goal_mode"], 1)
def test_error_strings_verbatim(self):
cases = [
({"model": 1}, "model must be a string"),
({"effort": "huge"},
"effort must be low, medium, high, xhigh or max"),
({"child_model": 1}, "child_model must be a string"),
({"child_effort": "huge"},
"child_effort must be low, medium, high, xhigh or max"),
({"approval": "all"}, "approval must be ask, auto or full"),
({"plan": True, "approval": "full"},
"plan 模式与 approval=full 冲突(只读 vs 完全访问)"),
({"plan": True, "goal_mode": 1}, "plan 模式与 goal 模式冲突"),
]
for body, want in cases:
with self.subTest(body=body):
opts, err = _validate_continue_options(body, _task(), None)
self.assertIsNone(opts)
self.assertEqual(err, want)
class ValidateWaitParamsTestCase(unittest.TestCase):
def test_default_and_valid(self):
timeout, requested, err = _validate_wait_params({})
self.assertEqual(timeout, 30)
self.assertIsNone(requested)
self.assertIsNone(err)
timeout, requested, err = _validate_wait_params(
{"timeout_seconds": 5, "task_ids": ["a"]})
self.assertEqual((timeout, requested, err), (5, ["a"], None))
def test_error_payloads_verbatim(self):
cases = [
({"timeout_seconds": True},
{"error": "timeout_seconds must be a number"}),
({"timeout_seconds": 121},
{"error": "timeout_seconds must be between 0 and 120"}),
({"task_ids": "a"}, {"error": "task_ids must be a list"}),
({"task_ids": [1]}, {"error": "task_ids must be a list"}),
({"task_ids": []}, {"error": "task_ids must not be empty"}),
({"task_ids": ["a"] * 9},
{"error": "at most 8 threads per wait", "count": 9}),
]
for body, want in cases:
with self.subTest(body=body):
_, _, err = _validate_wait_params(body)
self.assertEqual(err, want)
class SummarizeTraceEntriesTestCase(unittest.TestCase):
def test_changed_commands_activity(self):
entries = [
{"kind": "file", "path": "a.py", "change": "mod",
"status": "ok"},
{"kind": "file", "path": "a.py", "change": "mod2",
"status": "ok2"},
{"kind": "exec", "command": "pytest", "exitCode": 0,
"durationMs": 7},
{"kind": "tool", "server": "s", "tool": "t",
"status": "done", "id": "x"},
{"kind": "message", "text": "hi", "id": "y"},
"not-a-dict",
]
changed, commands, activity = _summarize_trace_entries(entries)
self.assertEqual(changed, [{"path": "a.py", "change": "mod2",
"status": "ok2"}])
self.assertEqual(commands, [{"command": "pytest", "exit_code": 0,
"duration_ms": 7}])
self.assertEqual(activity[3],
{"kind": "tool", "id": "x", "text": "s/t: done"})
self.assertEqual(activity[4],
{"kind": "message", "id": "y", "text": "hi"})
self.assertEqual(activity[5], {"kind": "unknown"})
def test_truncation_windows(self):
entries = [{"kind": "message", "text": "t%d" % i, "id": i}
for i in range(15)]
_, _, activity = _summarize_trace_entries(entries)
self.assertEqual(len(activity), 10)
self.assertEqual(activity[0]["text"], "t5")
class SummarizeMetricsTasksTestCase(unittest.TestCase):
def test_aggregation_and_member_filter(self):
now = 1000000.0
rows = [
{"project_id": "p1", "status": "completed",
"started_at": 100.0, "finished_at": 160.0},
{"project_id": "p1", "status": "failed",
"started_at": None, "finished_at": now - 100},
{"project_id": "p1", "status": "running",
"started_at": now - 400, "finished_at": None},
{"project_id": "p2", "status": "completed",
"started_at": 0.0, "finished_at": 10.0},
]
by_status, durations, failures, over = _summarize_metrics_tasks(
rows, {"p1"}, now)
self.assertEqual(set(by_status), set(TASK_STATUS_KEYS))
self.assertEqual(by_status["completed"], 1)
self.assertEqual(by_status["failed"], 1)
self.assertEqual(by_status["running"], 1)
self.assertEqual(durations, [60.0])
self.assertEqual(failures, 1)
self.assertEqual(over, 1)
if __name__ == "__main__":
unittest.main()