test: split real-process smoke into opt-in target

Real sslocal smoke (11 tests, ~27s) sat on every task test as the
slow tail. Tests/Smoke now builds as a separate target behind the
ShadowsocksX-NG2Smoke scheme; task test:smoke runs it on demand and
the README release gate requires it green next to packaging-gate.

SignalRecorder also gains kill(_, 0) semantics (stale pids report
ESRCH): the GUI-restart test burned the 5s waitForWrapperExit
ceiling on pid 99999, now 0.18s. Default lane: 617 tests ~40s.
This commit is contained in:
Qiu Yuzhou
2026-09-27 01:11:48 +08:00
parent e25e211165
commit 851660f1c6
11 changed files with 55 additions and 3 deletions
+1
View File
@@ -99,6 +99,7 @@ ShadowsocksX-NG2/*.xcodeproj
ShadowsocksX-NG2/App/Info.plist
ShadowsocksX-NG2/App/ShadowsocksX-NG2.entitlements
ShadowsocksX-NG2/Tests/Info.plist
ShadowsocksX-NG2/Tests/Smoke/Info.plist
####
# NG2 external binary cache (fetched & hash-verified by
+8 -3
View File
@@ -47,7 +47,8 @@ task lint
task lint:fix # 需要自动修复 SwiftLint 违规时使用;执行后再运行 task lint
task gen:prj # 生成 Xcode 工程
task build # 构建 Debug 版本 app
task test # 运行单元测试
task test # 运行单元测试(不含真实进程冒烟)
task test:smoke # 运行真实进程冒烟测试(拉起真实 sslocal,见下节发布门槛)
```
`task format` 会格式化 `App/`、`Tests/`、`Domain/` 和 `Agent/` 下的 Swift 文件;`task lint:fix` 会修改源文件,执行后检查并复核 diff。
@@ -59,10 +60,14 @@ Scripts/fetch-external-binaries.sh
task gen:prj
```
发布前对构建产物运行打包门槛检查:
`Tests/Smoke/` 是真实进程冒烟(经 wrapper 拉起真实 sslocal 验证启动、握手、
ACL 路由与插件监管),不在默认 `task test` 内,由独立 scheme 按需运行。
发布前运行发布门槛检查:
```bash
# 打包门槛(对构建产物;发布前必须全绿)
# 发布门槛(必须全绿):真实进程冒烟 + 打包门槛
task test:smoke
Scripts/packaging-gate.sh \
.build/derivedData/Build/Products/Debug/ShadowsocksX-NG2.app
```
+11
View File
@@ -50,6 +50,17 @@ tasks:
-derivedDataPath {{ .DERIVED_DATA_DIR }}
test
test:smoke:
desc: 'Run real-process smoke tests (real sslocal; release gate)'
cmds:
- >-
xcodebuild
-project ShadowsocksX-NG2.xcodeproj
-scheme ShadowsocksX-NG2Smoke
-destination 'platform=macOS,arch=arm64'
-derivedDataPath {{ .DERIVED_DATA_DIR }}
test
clean:
cmds:
- rm -rf {{ .BUILD_DIR }}
@@ -40,6 +40,12 @@ final class ProxyRuntimeControllerTests: XCTestCase {
if signal == SIGUSR1 {
reloadReceipt?()
}
// kill(_, 0) 判活语义:只对夹具约定的存活 pid(42 与本测试进程)报告
// 在跑;陈旧残留 pid 返回 ESRCH,停止协议才不必空等退出超时上限。
if signal == 0 {
return pid == 42 || pid == ProcessInfo.processInfo.processIdentifier
? 0 : Int32(ESRCH)
}
return 0
}
}
+29
View File
@@ -129,6 +129,9 @@ targets:
platform: macOS
sources:
- path: Tests
# 真实进程冒烟归 SmokeTests target,不进默认 task test 快车道。
excludes:
- "Smoke"
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.qiuyuzhou.ShadowsocksX-NG2.Tests
@@ -140,3 +143,29 @@ targets:
properties: {}
dependencies:
- target: ShadowsocksX-NG2
ShadowsocksX-NG2SmokeTests:
type: bundle.unit-test
platform: macOS
sources:
- path: Tests/Smoke
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.qiuyuzhou.ShadowsocksX-NG2.SmokeTests
# 同 Team 签名理由同 ShadowsocksX-NG2Tests。
CODE_SIGN_IDENTITY: "Apple Development"
info:
path: Tests/Smoke/Info.plist
properties: {}
dependencies:
- target: ShadowsocksX-NG2
schemes:
# 真实进程冒烟独立 scheme(task test:smoke):拉起真实 sslocal,按需执行;
# 发布门槛要求与 packaging-gate 一起全绿。
ShadowsocksX-NG2Smoke:
build:
targets:
ShadowsocksX-NG2: [build]
ShadowsocksX-NG2SmokeTests: [test]
test:
targets:
- ShadowsocksX-NG2SmokeTests