Skip to content

Commit b7d3038

Browse files
committed
test(core): stabilize post-rebase regression checks
1 parent 981e6d3 commit b7d3038

4 files changed

Lines changed: 159 additions & 44 deletions

File tree

codex-rs/.cargo/config.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
[env]
2+
RUST_MIN_STACK = "8388608"
3+
14
[target.'cfg(all(windows, target_env = "msvc"))']
25
rustflags = ["-C", "link-arg=/STACK:8388608"]
36

codex-rs/core/src/agent/control_tests.rs

Lines changed: 97 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,31 @@ async fn wait_for_live_thread_spawn_children(
239239
.expect("expected persisted child tree");
240240
}
241241

242+
fn run_agent_control_test_with_large_stack<Fut>(
243+
test_name: &'static str,
244+
test: impl FnOnce() -> Fut + Send + 'static,
245+
) where
246+
Fut: std::future::Future<Output = ()> + 'static,
247+
{
248+
const TEST_STACK_SIZE_BYTES: usize = 8 * 1024 * 1024;
249+
250+
let handle = std::thread::Builder::new()
251+
.name(test_name.to_string())
252+
.stack_size(TEST_STACK_SIZE_BYTES)
253+
.spawn(move || {
254+
let runtime = tokio::runtime::Builder::new_current_thread()
255+
.enable_all()
256+
.build()
257+
.expect("build test runtime");
258+
runtime.block_on(test());
259+
})
260+
.expect("spawn large-stack test thread");
261+
262+
handle
263+
.join()
264+
.expect("large-stack test thread should finish");
265+
}
266+
242267
#[tokio::test]
243268
async fn send_input_errors_when_manager_dropped() {
244269
let control = AgentControl::default();
@@ -1729,8 +1754,15 @@ async fn resume_agent_from_rollout_reads_archived_rollout_path() {
17291754
.expect("resumed child shutdown should succeed");
17301755
}
17311756

1732-
#[tokio::test]
1733-
async fn list_agent_subtree_thread_ids_includes_anonymous_and_closed_descendants() {
1757+
#[test]
1758+
fn list_agent_subtree_thread_ids_includes_anonymous_and_closed_descendants() {
1759+
run_agent_control_test_with_large_stack(
1760+
"list_agent_subtree_thread_ids_includes_anonymous_and_closed_descendants",
1761+
list_agent_subtree_thread_ids_includes_anonymous_and_closed_descendants_impl,
1762+
);
1763+
}
1764+
1765+
async fn list_agent_subtree_thread_ids_includes_anonymous_and_closed_descendants_impl() {
17341766
let harness = AgentControlHarness::new().await;
17351767
let (parent_thread_id, _parent_thread) = harness.start_thread().await;
17361768
let worker_path = AgentPath::root().join("worker").expect("worker path");
@@ -1855,8 +1887,15 @@ async fn list_agent_subtree_thread_ids_includes_anonymous_and_closed_descendants
18551887
);
18561888
}
18571889

1858-
#[tokio::test]
1859-
async fn shutdown_agent_tree_closes_live_descendants() {
1890+
#[test]
1891+
fn shutdown_agent_tree_closes_live_descendants() {
1892+
run_agent_control_test_with_large_stack(
1893+
"shutdown_agent_tree_closes_live_descendants",
1894+
shutdown_agent_tree_closes_live_descendants_impl,
1895+
);
1896+
}
1897+
1898+
async fn shutdown_agent_tree_closes_live_descendants_impl() {
18601899
let harness = AgentControlHarness::new().await;
18611900
let (parent_thread_id, _parent_thread) = harness.start_thread().await;
18621901

@@ -1940,8 +1979,15 @@ async fn shutdown_agent_tree_closes_live_descendants() {
19401979
assert_eq!(shutdown_ids, expected_shutdown_ids);
19411980
}
19421981

1943-
#[tokio::test]
1944-
async fn shutdown_agent_tree_closes_descendants_when_started_at_child() {
1982+
#[test]
1983+
fn shutdown_agent_tree_closes_descendants_when_started_at_child() {
1984+
run_agent_control_test_with_large_stack(
1985+
"shutdown_agent_tree_closes_descendants_when_started_at_child",
1986+
shutdown_agent_tree_closes_descendants_when_started_at_child_impl,
1987+
);
1988+
}
1989+
1990+
async fn shutdown_agent_tree_closes_descendants_when_started_at_child_impl() {
19451991
let harness = AgentControlHarness::new().await;
19461992
let (parent_thread_id, _parent_thread) = harness.start_thread().await;
19471993

@@ -2031,8 +2077,15 @@ async fn shutdown_agent_tree_closes_descendants_when_started_at_child() {
20312077
assert_eq!(shutdown_ids, expected_shutdown_ids);
20322078
}
20332079

2034-
#[tokio::test]
2035-
async fn resume_agent_from_rollout_does_not_reopen_closed_descendants() {
2080+
#[test]
2081+
fn resume_agent_from_rollout_does_not_reopen_closed_descendants() {
2082+
run_agent_control_test_with_large_stack(
2083+
"resume_agent_from_rollout_does_not_reopen_closed_descendants",
2084+
resume_agent_from_rollout_does_not_reopen_closed_descendants_impl,
2085+
);
2086+
}
2087+
2088+
async fn resume_agent_from_rollout_does_not_reopen_closed_descendants_impl() {
20362089
let harness = AgentControlHarness::new().await;
20372090
let (parent_thread_id, parent_thread) = harness.start_thread().await;
20382091

@@ -2126,8 +2179,15 @@ async fn resume_agent_from_rollout_does_not_reopen_closed_descendants() {
21262179
.expect("tree shutdown after resume should succeed");
21272180
}
21282181

2129-
#[tokio::test]
2130-
async fn resume_closed_child_reopens_open_descendants() {
2182+
#[test]
2183+
fn resume_closed_child_reopens_open_descendants() {
2184+
run_agent_control_test_with_large_stack(
2185+
"resume_closed_child_reopens_open_descendants",
2186+
resume_closed_child_reopens_open_descendants_impl,
2187+
);
2188+
}
2189+
2190+
async fn resume_closed_child_reopens_open_descendants_impl() {
21312191
let harness = AgentControlHarness::new().await;
21322192
let (parent_thread_id, parent_thread) = harness.start_thread().await;
21332193

@@ -2223,8 +2283,15 @@ async fn resume_closed_child_reopens_open_descendants() {
22232283
.expect("parent shutdown should succeed");
22242284
}
22252285

2226-
#[tokio::test]
2227-
async fn resume_agent_from_rollout_reopens_open_descendants_after_manager_shutdown() {
2286+
#[test]
2287+
fn resume_agent_from_rollout_reopens_open_descendants_after_manager_shutdown() {
2288+
run_agent_control_test_with_large_stack(
2289+
"resume_agent_from_rollout_reopens_open_descendants_after_manager_shutdown",
2290+
resume_agent_from_rollout_reopens_open_descendants_after_manager_shutdown_impl,
2291+
);
2292+
}
2293+
2294+
async fn resume_agent_from_rollout_reopens_open_descendants_after_manager_shutdown_impl() {
22282295
let harness = AgentControlHarness::new().await;
22292296
let (parent_thread_id, parent_thread) = harness.start_thread().await;
22302297

@@ -2314,8 +2381,15 @@ async fn resume_agent_from_rollout_reopens_open_descendants_after_manager_shutdo
23142381
.expect("tree shutdown after subtree resume should succeed");
23152382
}
23162383

2317-
#[tokio::test]
2318-
async fn resume_agent_from_rollout_uses_edge_data_when_descendant_metadata_source_is_stale() {
2384+
#[test]
2385+
fn resume_agent_from_rollout_uses_edge_data_when_descendant_metadata_source_is_stale() {
2386+
run_agent_control_test_with_large_stack(
2387+
"resume_agent_from_rollout_uses_edge_data_when_descendant_metadata_source_is_stale",
2388+
resume_agent_from_rollout_uses_edge_data_when_descendant_metadata_source_is_stale_impl,
2389+
);
2390+
}
2391+
2392+
async fn resume_agent_from_rollout_uses_edge_data_when_descendant_metadata_source_is_stale_impl() {
23192393
let harness = AgentControlHarness::new().await;
23202394
let (parent_thread_id, parent_thread) = harness.start_thread().await;
23212395

@@ -2445,8 +2519,15 @@ async fn resume_agent_from_rollout_uses_edge_data_when_descendant_metadata_sourc
24452519
.expect("tree shutdown after subtree resume should succeed");
24462520
}
24472521

2448-
#[tokio::test]
2449-
async fn resume_agent_from_rollout_skips_descendants_when_parent_resume_fails() {
2522+
#[test]
2523+
fn resume_agent_from_rollout_skips_descendants_when_parent_resume_fails() {
2524+
run_agent_control_test_with_large_stack(
2525+
"resume_agent_from_rollout_skips_descendants_when_parent_resume_fails",
2526+
resume_agent_from_rollout_skips_descendants_when_parent_resume_fails_impl,
2527+
);
2528+
}
2529+
2530+
async fn resume_agent_from_rollout_skips_descendants_when_parent_resume_fails_impl() {
24502531
let harness = AgentControlHarness::new().await;
24512532
let (parent_thread_id, parent_thread) = harness.start_thread().await;
24522533

codex-rs/core/src/tools/spec_plan_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2388,7 +2388,7 @@ fn code_mode_only_exec_description_omits_deferred_tools() {
23882388

23892389
assert!(!description.contains("mcp__rmcp__echo"));
23902390
assert!(!description.contains("Deferred RMCP tool."));
2391-
assert!(registry.has_handler(&ToolName::namespaced("mcp__rmcp__", "echo")));
2391+
assert!(registry.has_tool(&ToolName::namespaced("mcp__rmcp__", "echo")));
23922392
}
23932393

23942394
#[test]

codex-rs/core/tests/suite/compact_remote_parity.rs

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::fs;
44
use std::path::Path;
55
use std::path::PathBuf;
6+
use std::time::Duration;
67

78
use anyhow::Result;
89
use codex_features::Feature;
@@ -20,6 +21,7 @@ use core_test_support::skip_if_no_network;
2021
use core_test_support::test_codex::TestCodexHarness;
2122
use core_test_support::test_codex::test_codex;
2223
use core_test_support::wait_for_event;
24+
use core_test_support::wait_for_event_with_timeout;
2325
use pretty_assertions::assert_eq;
2426
use serde_json::Value;
2527
use serde_json::json;
@@ -115,34 +117,56 @@ const FULL_MIX: &[Step] = &[
115117
Step::Assistant,
116118
];
117119

118-
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
119-
async fn remote_compaction_parity_manual_transcripts() -> Result<()> {
120-
skip_if_no_network!(Ok(()));
120+
#[test]
121+
fn remote_compaction_parity_manual_transcripts() -> Result<()> {
122+
const TEST_STACK_SIZE_BYTES: usize = 8 * 1024 * 1024;
123+
const WORKER_THREADS: usize = 2;
124+
125+
let handle = std::thread::Builder::new()
126+
.name("remote_compaction_parity_manual_transcripts".to_string())
127+
.stack_size(TEST_STACK_SIZE_BYTES)
128+
.spawn(|| -> Result<()> {
129+
let runtime = tokio::runtime::Builder::new_multi_thread()
130+
.worker_threads(WORKER_THREADS)
131+
.thread_stack_size(TEST_STACK_SIZE_BYTES)
132+
.enable_all()
133+
.build()?;
134+
runtime.block_on(async {
135+
skip_if_no_network!(Ok(()));
136+
137+
let scenarios = [
138+
Scenario {
139+
name: "assistant_only",
140+
steps: ASSISTANT_ONLY,
141+
},
142+
Scenario {
143+
name: "reasoning_image",
144+
steps: REASONING_IMAGE,
145+
},
146+
Scenario {
147+
name: "tool_mix",
148+
steps: TOOL_MIX,
149+
},
150+
Scenario {
151+
name: "full_mix",
152+
steps: FULL_MIX,
153+
},
154+
];
155+
156+
for scenario in scenarios {
157+
compare_manual_scenario(&scenario, RunSettings::default()).await?;
158+
}
121159

122-
let scenarios = [
123-
Scenario {
124-
name: "assistant_only",
125-
steps: ASSISTANT_ONLY,
126-
},
127-
Scenario {
128-
name: "reasoning_image",
129-
steps: REASONING_IMAGE,
130-
},
131-
Scenario {
132-
name: "tool_mix",
133-
steps: TOOL_MIX,
134-
},
135-
Scenario {
136-
name: "full_mix",
137-
steps: FULL_MIX,
138-
},
139-
];
140-
141-
for scenario in scenarios {
142-
compare_manual_scenario(&scenario, RunSettings::default()).await?;
143-
}
160+
Ok(())
161+
})
162+
})?;
144163

145-
Ok(())
164+
match handle.join() {
165+
Ok(result) => result,
166+
Err(_) => Err(anyhow::anyhow!(
167+
"remote_compaction_parity_manual_transcripts thread panicked"
168+
)),
169+
}
146170
}
147171

148172
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
@@ -613,7 +637,14 @@ async fn submit_user_input(codex: &codex_core::CodexThread, items: Vec<UserInput
613637
}
614638

615639
async fn wait_for_turn_complete(codex: &codex_core::CodexThread) {
616-
wait_for_event(codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await;
640+
const PARITY_EVENT_TIMEOUT_SECS: u64 = 30;
641+
642+
wait_for_event_with_timeout(
643+
codex,
644+
|ev| matches!(ev, EventMsg::TurnComplete(_)),
645+
Duration::from_secs(PARITY_EVENT_TIMEOUT_SECS),
646+
)
647+
.await;
617648
}
618649

619650
fn user_input_for_step(scenario_name: &str, idx: usize, step: Step) -> Vec<UserInput> {

0 commit comments

Comments
 (0)