Repository navigation
#633 [test] TUI profile 昇格のポート fixture を test transport に移す - #640
Merged
Kewton merged 2 commits intoOct 9, 2026
Merged
Conversation
Move the profile-promotion body out of tests/tui_integration.rs into the required library test tui::profile_transport_tests, driving the fake dev child through the Issue #608 OS-assigned port transport instead of a freed-and-rebound local port. The logical port, profile promotion, stage, terminal summary, and evidence assertions are preserved one-to-one. Extract the shared Config builder, FakeClient, FakeUi, and command-event helper into tests/support/tui_profile_fixture.rs and include the same file from both the integration test and the library test. The fake child is owned by the test module and speaks only the transport's file contract (the workspace marker, the generation file, the {"generation","port"} ready file, and the browser probe's mock-port file); it binds an OS-assigned port and announces it, so no product code or visibility change is needed. Mirrors the Issue #622/#448 test transports. Process isolation (PM 案 A): the required #[test] keeps its name but no longer runs the flow in the lib test process. It re-execs this binary with `--ignored --exact <inner> --nocapture --test-threads=1` and the entry env variable COMMANDAGENT_TUI_PROFILE_TRANSPORT_INNER=1, so the moved body (an #[ignore]d inner test gated by that variable, like the fake dev child) runs in its own process. The outer waits a bounded 120s, kills and reaps on timeout, drains stdout/stderr on reader threads, and requires: child exit status 0, child stdout containing "1 passed" (so --exact matching zero tests cannot pass), and the inner completion marker file the inner writes after its final assertion (path passed from outside the tempdir). On failure it panics with the child's stdout and stderr. The test itself binds 127.0.0.1:0, keeps the listener alive to the end, and uses that number as the logical port in the goal, package.json (`-p`), and the requested_port assertions. The child's announced port (read from browser-probe-mock-port.txt) is asserted non-zero and different from the logical port. assertion 対応 (旧 tests/tui_integration.rs == 新 inner body, 1 対 1): 1 output.contains("ultra-plan-run complete") 2 events contains "event":"profile_reinferred" 3 events contains "profile":"nextjs" 4 events contains "requested_port":"<port> (goal)" 5 tui_command_stop.profile == "nextjs" 6 tui_command_stop.effective_profile == "nextjs" 7 tui_command_stop.contract_origin == "promoted_union" 8 tui_command_stop.assurance_level == "full" 9 tui_command_stop.requested_port == "<port> (goal)" 10 summary contains "Profile promoted: generic -> nextjs" 11 summary contains "Profile: nextjs" 12 summary contains "Requested port: <port> (goal)" 追加(旧 body に無い証跡 assertion、既存は弱めていない): browser_probe event の status=="ready" / ok==true / http_status==200 / port==<logical> / requested_port=="<logical> (goal)" / output_excerpt 非空 子が browser-probe-mock-port.txt に告知した実ポート != 0 かつ != logical 外側: 子の exit status 0 / 子の stdout に "1 passed" / inner の完了マーカー 読み替え: 「モジュール配線は tui の親へ置く」は新 test file の親モジュール src/tui/mod.rs への mod 宣言と読んだ 判断: dev child は本 test module が所有し、#622/#448 と同じ file 契約だけを使う。test_transport の enable/bind は runner test module の pub(super) で scope 内から呼べないため、製品側を変えず契約経由にした 判断: 移した body は #[ignore] の内側に置き、外側の必須 #[test] が current_exe を再実行して内側だけを走らせる。lib の同一プロセスで共有状態を取り合わないため(案 A、案 B は採らない) 判断: 論理ポートはテスト内で bind(0) した listener を終了まで保持して決め、その番号を goal/package.json/assert に使う。固定番号を使わず、占有したままでも同一の昇格・summary になることを test 自身が確認し、2 プロセス同時でも衝突しない 判断: generality_guardrails の nextjs literal 監査は scope 外のため編集せず、lib test module 全体を #[cfg(test)] mod tests で包み test 行として分類させた 本文に無い指摘: この TUI flow の readiness は minimal_loop::browser_probe で、acceptance.rs の dev_server_lifecycle(start/wait/probe/cleanup) は出ない。よって実子起動と HTTP 観測は browser_probe event の status/ok/http_status/output_excerpt で assert した 本文に無い指摘: browser_probe の dynamic_port には .anvil/evidence/browser-probe-command.json の上書きが要る(無いと論理ポートを poll して 30s timeout) 本文に無い指摘: lib の filter `tui::` 反復で 13/20 落ちた原因は (1) tui::repl が cli_pack の lock 下で COMMANDAGENT_PACK_* を一時設定すること、(2) 新テストの flow が presentation の共有状態を書き換えること。内側の別プロセス化で回避した Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
…issue-633-test-tui-profile-fixture-test-transport
4 tasks
Kewton
deleted the
feature/issue-633-test-tui-profile-fixture-test-transport
branch
October 9, 2026 10:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
TUI の profile 昇格のテスト(
tui_slash_promoted_profile_reflected_in_terminal_summary)は、integration test で一度 bind して解放した番号のポートを dev server の子に bind し直させていたため、その番号をほかのプロセスに取られると落ちることがありました(#541 の分割 N)。この PR は、テストを lib のテストに移し、#608 の test transport(子が OS の割り当てたポートに bind し、実ポートを ready ファイルで知らせる)を使います。変更(対象 4 ファイル、+761/−479)
src/tui/profile_transport_tests.rs(新規、全体が#[cfg(test)] mod tests):#[ignore]の内側のテスト)。旧 body の assertion 12 個を 1 対 1 でそのまま持つ。加えて、readiness の probe が実の子の HTTP を観測した証跡(browser_probeのstatus=="ready"・ok・http_status==200・port・requested_port・子の出力)と、子が告知した実ポートが 0 でなく論理ポートと違うことを assert。127.0.0.1:0に bind した listener を最後まで握り、その番号を論理ポートにする(番号を解放しない。論理ポートを占有したままで同じ昇格・summary になる)。#[ignore]なし)は、自分のテストバイナリを子プロセスとして起動し、内側だけを走らせる。lib の同じプロセスのほかのテストと、pack の環境変数や TUI の共有の状態を取り合わないため。120 秒の上限(超えたら kill・回収して失敗)、exit 0・1 passed・内側の完了の印を確かめ、失敗のときは子の出力を表示する。pub(super)で tui から呼べないため。[test] issue475 observer の transport を動的ポート通知へ分離する #622・issue448 と同じ形)。tests/support/tui_profile_fixture.rs(新規):config・FakeClient・FakeUi・tui_command_stop_eventsを、integration と lib の両方からinclude!する共通の fixture にした。tests/tui_integration.rs:移した body、共通の fixture、使わなくなった番号解放の helper と#[ignore]の子を削除。src/tui/mod.rs:#[cfg(test)] mod profile_transport_tests;の 3 行だけ(製品側の唯一の差分)。テスト用の環境変数を読むのはこのテストの module の中だけで、通常の library や release binary には入口が無い。acceptance.rs・runner.rs・cli_pack.rs・presentation.rsは変えていません。#[ignore]でない実のテストは 22 本のまま(integration 23 → 21 は、移した body と使わなくなった#[ignore]の子)。検証
commandmate verifyの 15 ゲート:developddcb8022を取り込んだ HEAD で 15/15 pass(075bca1a、scope 4 本、違反 0)。cargo test --test tui_integration:取り込んだ HEAD で exit 0、21 passed・0 failed。cargo test --lib tui:: を 20 回:落ちた回 0/20(新しいテストは 20/20 回 pass)cargo test --lib tui::を 20 回で 13 回落ちました(presentation の snapshot のテストと、このテスト)。隔離した後は 0/20 です。レビュー
テストだけの変更です(製品側は cfg(test) の module の宣言だけ)。merge 前レビューは行いません(利用者承認済み)。
Refs #633
Refs #541
🤖 Generated with Claude Code