Skip to content

Commit baa89d3

Browse files
author
wandl
committed
test(appserver): 新增真实 app-server 集成测试(-Dcodex.real.base-url 门控)
对 codex 0.154.0 真容器实测 2/2 通过:initialize 握手 + 嵌套 thread.id 解析 + turn 越过 thread/start。默认不执行,与仓库 RealIntegrationTest 惯例一致。
1 parent 9ed4855 commit baa89d3

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (c) 2018-present, easy-4-java (https://github.com/easy-4-java).
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.github.easy4j.codex.appserver;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
20+
21+
import static org.junit.jupiter.api.Assertions.assertFalse;
22+
import static org.junit.jupiter.api.Assertions.assertNotNull;
23+
import static org.junit.jupiter.api.Assertions.assertTrue;
24+
25+
/**
26+
* 显式真实集成测试:默认不执行,仅当同时传入
27+
* {@code -Dcodex.real.base-url=http://host:port}(token 可选
28+
* {@code -Dcodex.real.token=...})时对真实 codex app-server 执行。
29+
*
30+
* <p>协议层验收点(2026-09-17 对 codex 0.154.0 实测提炼):</p>
31+
* <ol>
32+
* <li>initialize → notifications/initialized 握手必须先行,否则 -32600 Not initialized;</li>
33+
* <li>thread id 嵌套在 {@code result.thread.id},顶层 {@code threadId} 为空;</li>
34+
* <li>turn 阶段失败必须来自模型/凭证层,而不是 {@code no threadId}
35+
* 这类协议层错误。</li>
36+
* </ol>
37+
*
38+
* @since 2.0.x
39+
*/
40+
@EnabledIfSystemProperty(named = "codex.real.base-url", matches = "https?://.+")
41+
class CodexAppServerRealIntegrationTest {
42+
43+
@Test
44+
void listThreadsShouldPassProtocolHandshake() {
45+
CodexAppServerClient client = client();
46+
try {
47+
// 走通用 RPC 通道(tolerant initialize);能返回列表即证明握手与帧解析可用
48+
client.listThreads(5);
49+
} finally {
50+
client.close();
51+
}
52+
}
53+
54+
@Test
55+
void runTurnMustGetPastThreadStartEvenWithoutModelCredentials() {
56+
CodexAppServerClient client = client();
57+
try {
58+
try {
59+
client.runTurn(AppServerTurnRequest.builder()
60+
.prompt("只回复两个字母:OK")
61+
.sessionKey("real-wire-smoke")
62+
.build());
63+
// 有凭证时直接完成,也算通过
64+
} catch (CodexAppServerException ex) {
65+
String message = String.valueOf(ex.getMessage());
66+
assertFalse(message.contains("no threadId"),
67+
"threadId 解析回退到了旧协议: " + message);
68+
assertFalse(message.contains("Not initialized"),
69+
"initialize 握手缺失: " + message);
70+
// 无模型凭证的真实环境在此收到 turn/failed 类错误——协议层已通过
71+
}
72+
} finally {
73+
client.close();
74+
}
75+
}
76+
77+
private CodexAppServerClient client() {
78+
CodexAppServerConfig config = new CodexAppServerConfig();
79+
config.setBaseUrl(System.getProperty("codex.real.base-url").trim());
80+
String token = System.getProperty("codex.real.token");
81+
if (token != null && !token.isBlank()) {
82+
config.setToken(token.trim());
83+
}
84+
assertNotNull(config.getBaseUrl());
85+
assertTrue(config.getConnectTimeoutMillis() > 0);
86+
return new CodexAppServerClient(config);
87+
}
88+
}

0 commit comments

Comments
 (0)