diff --git a/.gitignore b/.gitignore index 283b7ddd..9786d53c 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/ShadowsocksX-NG2/README.md b/ShadowsocksX-NG2/README.md index 06d47b8d..1c9ec201 100644 --- a/ShadowsocksX-NG2/README.md +++ b/ShadowsocksX-NG2/README.md @@ -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 ``` diff --git a/ShadowsocksX-NG2/Taskfile.dist.yml b/ShadowsocksX-NG2/Taskfile.dist.yml index 50d01313..738b6195 100644 --- a/ShadowsocksX-NG2/Taskfile.dist.yml +++ b/ShadowsocksX-NG2/Taskfile.dist.yml @@ -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 }} \ No newline at end of file diff --git a/ShadowsocksX-NG2/Tests/ProxyRuntimeControllerTests.swift b/ShadowsocksX-NG2/Tests/ProxyRuntimeControllerTests.swift index 271690d6..e8844019 100644 --- a/ShadowsocksX-NG2/Tests/ProxyRuntimeControllerTests.swift +++ b/ShadowsocksX-NG2/Tests/ProxyRuntimeControllerTests.swift @@ -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 } } diff --git a/ShadowsocksX-NG2/Tests/RealSslocalSmokeTests+ACLRouting.swift b/ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests+ACLRouting.swift similarity index 100% rename from ShadowsocksX-NG2/Tests/RealSslocalSmokeTests+ACLRouting.swift rename to ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests+ACLRouting.swift diff --git a/ShadowsocksX-NG2/Tests/RealSslocalSmokeTests+CustomRules.swift b/ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests+CustomRules.swift similarity index 100% rename from ShadowsocksX-NG2/Tests/RealSslocalSmokeTests+CustomRules.swift rename to ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests+CustomRules.swift diff --git a/ShadowsocksX-NG2/Tests/RealSslocalSmokeTests+GFWListACL.swift b/ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests+GFWListACL.swift similarity index 100% rename from ShadowsocksX-NG2/Tests/RealSslocalSmokeTests+GFWListACL.swift rename to ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests+GFWListACL.swift diff --git a/ShadowsocksX-NG2/Tests/RealSslocalSmokeTests+Loopback.swift b/ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests+Loopback.swift similarity index 100% rename from ShadowsocksX-NG2/Tests/RealSslocalSmokeTests+Loopback.swift rename to ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests+Loopback.swift diff --git a/ShadowsocksX-NG2/Tests/RealSslocalSmokeTests+Plugin.swift b/ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests+Plugin.swift similarity index 100% rename from ShadowsocksX-NG2/Tests/RealSslocalSmokeTests+Plugin.swift rename to ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests+Plugin.swift diff --git a/ShadowsocksX-NG2/Tests/RealSslocalSmokeTests.swift b/ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests.swift similarity index 100% rename from ShadowsocksX-NG2/Tests/RealSslocalSmokeTests.swift rename to ShadowsocksX-NG2/Tests/Smoke/RealSslocalSmokeTests.swift diff --git a/ShadowsocksX-NG2/project.yml b/ShadowsocksX-NG2/project.yml index 2bab6ac2..1020a799 100644 --- a/ShadowsocksX-NG2/project.yml +++ b/ShadowsocksX-NG2/project.yml @@ -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