refactor(apple-runner): encapsulate XCTest-channel penalty state
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 35/100
- Issue 类型
- 重构
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- swift
- 领域
- mobile-dev, testing-qa
调研方向
First read the deletion gate and inspect RunnerTests+SnapshotCapturePlan.swift:133–162, RunnerTests.swift:118–122, and SnapshotTiming.swift:119–154 under apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/. Confirm a concrete deletion or correctness case before starting, since the issue is currently deferred. If resumed, use the owner-matched tests and consuming suites named in the issue; done means penalty behavior and effective-plan outputs remain unchanged and the required focused checks pass.
由索引模型根据 Issue 内容生成。
描述
Encapsulate the runner's XCTest-channel penalty state with its existing operations
Deletion-first acceptance
This is part of #2803's simplify-and-shrink initiative. Before production simplification, name the production mechanism, duplicated decision, state, fallback, forwarding layer, or public/internal interface this change removes. Compare deletion and inlining against extraction. Moving the same state into another file is not a deletion case.
Every PR reports baseline/final SHAs; added, deleted and net production lines; test/fixture/documentation changes separately; and the exact mechanisms removed. Use a rename-aware diff (git diff --numstat -M BASE...HEAD) and account for all affected production paths, including destination packages. Moving tests out of production files, generated output, formatting churn, and moving code elsewhere are not production-code deletion. Preserve readable code; no compressed formatting to hit a number.
Default for simplification work: net production reduction. A required behavior-preserving size split may be line-neutral. Growth needs an explicit, quantified explanation of the correctness or type guarantee it buys, why deletion/inlining cannot achieve it, and what old mechanism is removed; it is not automatically acceptable because ownership looks cleaner. If the only benefit is relocating fields or adding a wrapper, defer the change. Required regression tests and a minimal correctness fix are allowed to grow without inventing unrelated deletion to offset them.
Priority and scope gate
Readiness: deferred; remove ready-for-agent. Existing operations are already collocated and no penalty-state defect has been demonstrated. Resume only for a named deletion of duplicate state/coordination or a concrete correctness need. A new class with the same fields plus forwarding methods does not meet this initiative's goal. Preserve the distinct penalty, warmup and depth lifetimes. Run shared Swift work one issue at a time.
Parent: #2803. Readiness: deferred pending a concrete deletion or correctness case. Evidence baseline: 5712a3552e209c9c853bc1f42cb3e007f1213139; recheck current main. If resumed after its deletion/correctness gate, coordinate edits with target-transition characterization and ownership work; the current penalty operations are already explicit. #2911 has merged and #2882 owns additional actor source guards.
Problem and evidence
RunnerTests+SnapshotCapturePlan.swift:133–162 already colocates arm, clear and lookup functions. The missing piece is concrete ownership: their lock, bundle identity, deadline and duration remain writable on the entire XCTest case (RunnerTests.swift:118–122). This extraction should close that seam, not claim to discover a missing state machine or rewrite capture-plan policy.
The current penalty is a single retained record, not a per-app map. SnapshotTiming.swift:119–154 decides whether an XCTest-backed attempt deserves it from acquisition timing, typed timeout and deadline exhaustion. Main-thread abandonment can also arm it. Lifecycle explicitly clears it for process replacement/external relaunch; ordinary invalidation does not mean the same thing.
Small interface and ownership
Create one concrete SnapshotXCTestChannelPenalty module owning its private lock, optional bundle and expiration. Expose arm, clear and isActive(for:). Preserve the 120-second duration, existing log markers, and strict now < expiresAt lookup. Accept the current instant as an explicit operation input, or reuse an existing production clock seam, so expiry tests advance time without production-length sleeps. Do not add test-only setters or a scheduler framework.
Place the instance on RunnerTests, replace direct accesses, and delete superseded fields/functions. The existing acquisition classifier, capture-plan reordering and presentation-quality decisions retain their owners. The new module must not know backend capabilities, app activation or snapshot node shapes.
Keep SnapshotXCTestPenaltyWarmupExemption separate: it already has lock-protected ownership and a different contract (one pending exemption consumed by an actual plan). Keep private-AX accepted-depth memory separate: its positive-PID matching and non-renewing successful reuse are not this penalty's semantics. Shared duration values today do not justify a combined cache or lifetime abstraction.
Required preservation and completion checks
- Arming replaces the single previous penalty; it does not accumulate one entry per app. A nil-bundle penalty applies to any requested bundle; a named penalty only matches that bundle.
- Re-arming retains current deadline renewal behavior. Expiry itself need not mutate storage. Clearing emits its existing marker only when the old penalty was still active.
- An independently recovered capture must still avoid occupied XCTest work; physical-device plans retain bounded XCTest probes while eligible simulator plans can defer to independent acquisition.
- Slow presentation alone never arms the penalty; acquisition timeout or an exhausted XCTest tier can arm it without crossing the slow-duration threshold. Preserve warmup suppression at its current decision point.
- Before: lock/state exposed across all runner extensions. After: only the owner accesses penalty state, with exactly the same effective-plan and quality outputs for the same observations.
Validation and exclusions
Move penalty-specific cases into the owner-matched test file; retain the consuming assertions in SnapshotCapturePlanTests, SnapshotTimingTests, LifecycleCacheTests, SnapshotCaptureTargetTests and SnapshotCapturePlanOccupancyTests. Cover nil/named bundle, replacement, exact expiry, clear, renewal and concurrent arm/read through the public interface. Plant a nil-bundle mismatch and a presentation-only penalty mutation to prove the nearest negative cases fail.
Run pnpm check:xctest-selection, unit-enabled iOS/macOS builds and selected XCTest cases, pnpm check:packaged-runner-swift, and pnpm check:affected --run. Preserve source-guard lane ownership. No claim of hostile-screen recovery improvement follows from extraction alone; report live evidence separately. No new retry strategy, clock-domain migration, penalty duration change, actor rewrite or host-side bridge-cache change belongs here.
Source paths in this issue are rooted at apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/; extension names abbreviate the RunnerTests+ prefix where stated. Tests live in its UnitTests/ directory. For a fresh worktree, run pnpm install --frozen-lockfile && pnpm build before the focused checks. Read docs/agents/testing.md and docs/agents/device-verification.md for native lane selection and build freshness.
- 主要语言
- TypeScript
- 星标
- 4.7k
- 派生
- 304
- 平均合并
- 11 小时 6 分钟
- 30 天内合并 PR
- 521
环境准备
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
callstack/agent-device 的其他 Issue
-
ready-for-agent
难度 2/5 1-3 小时 新手友好度 84/100
callstack/agent-device#2995 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 68/100
callstack/agent-device#1869 ·
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 75/100
callstack/agent-device#3047 ·
维护者通常 1 天内回复
-
难度 5/5 一周以上 新手友好度 45/100
callstack/agent-device#3021 ·
维护者通常 1 天内回复
-
ready-for-agent
难度 3/5 1-2 天 新手友好度 68/100
callstack/agent-device#3004 ·
维护者通常 1 天内回复
查看 callstack/agent-device 的全部 Issue
相似的 Issue
-
documentation
难度 2/5 1-3 小时 新手友好度 88/100
inu-appcenter/memorIN-frontend#106 ·
维护者通常 1 天内回复
-
kind/bug
难度 1/5 1 小时以内 新手友好度 88/100
维护者通常 7 天内回复
-
[Bug] @deck.gl/arcgis dist import resolves to unpublished @deck.gl/core source path (9.3.11, 9.4.0)未关闭
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 82/100
CSCfi/sd-search-ui#145 ·
维护者通常 1 天内回复
-
check:passed streams:add
难度 2/5 1-3 小时 新手友好度 62/100
维护者通常 1 天内回复