// // ProtocolFlowTests.swift — T-iOS-16 测试 1-2:基本协议流程(吸收 spike②) // // 1. attach(null) → attached → input "echo hi\r" → output 含 "hi" // (附加强断言 RUN:42:证明命令确被 shell 执行,而不是只看到输入回显) // 2. resize(120,40) → `stty size` 输出 "40 120";边界 resize 1/1000 各一发, // 以 stty 实测尺寸生效证明"被接受"(服务器对非法 resize 是静默丢弃, // src/protocol.ts:113-115 —— 只有尺寸真变了才证明帧被采纳),且连接存活。 // // 客户端帧一律 MessageCodec 编码、服务器帧一律 MessageCodec 解码 —— 本 suite // 同时是冻结契约与真服务器之间的防漂移闸门(plan §9)。 import Foundation import Testing import WireProtocol @Suite("T-iOS-16 协议流程(真服务器)", .serialized, .timeLimit(.minutes(5))) struct ProtocolFlowTests { @Test("attach(null)→attached(101);echo hi → output 含 hi 且命令确被执行") func attachEchoRoundtrip() async throws { // Arrange let server = try await ServerHarness.shared.server() let client = WSTestClient(server: server, origin: server.origin) defer { client.close() } // Act: attach(null) → attached(spike② 阳性对照:自定义 Origin 升级 101) let sessionId = try await attachAndAwaitAttached(client: client, sessionId: nil) #expect(client.handshakeStatusCode == 101, "升级应 101,实际 \(String(describing: client.handshakeStatusCode))") var reader = TranscriptReader(client: client) try await client.send(shellCommand("echo hi")) try await reader.awaitContains("hi") // 强断言:$((6*7)) 只有 shell 真执行才会变成 42(回显里只有字面量表达式)。 try await client.send(shellCommand("echo \"RUN:$((6*7))\"")) try await reader.awaitContains("RUN:42") // Cleanup client.close() await killSessionBestEffort(server: server, id: sessionId) } @Test("resize(120,40) → stty size = 40 120;边界 1/1000 均被采纳且连接存活") func resizeTakesEffectIncludingBoundaries() async throws { // Arrange let server = try await ServerHarness.shared.server() let client = WSTestClient(server: server, origin: server.origin) defer { client.close() } let sessionId = try await attachAndAwaitAttached(client: client, sessionId: nil) var reader = TranscriptReader(client: client) // Act + Assert: 常规尺寸(任务字面用例)。SZ: 哨兵防止把输入回显误判成输出 //(回显里是字面量 $(stty size),只有命令执行结果才含 "SZ: ")。 try await client.send(.resize(cols: 120, rows: 40)) try await client.send(shellCommand("echo \"SZ:$(stty size)\"")) try await reader.awaitContains("SZ:40 120") // 边界下限:1×1 被采纳(stty 实测 1 1),连接未断。 try await client.send(.resize(cols: 1, rows: 1)) try await client.send(shellCommand("echo \"SZ:$(stty size)\"")) try await reader.awaitContains("SZ:1 1") // 边界上限:1000×1000 被采纳,连接未断。 try await client.send(.resize(cols: 1000, rows: 1000)) try await client.send(shellCommand("echo \"SZ:$(stty size)\"")) try await reader.awaitContains("SZ:1000 1000") // Cleanup client.close() await killSessionBestEffort(server: server, id: sessionId) } }