Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .agents/skills/maintain-dynamic-plugins/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Use this skill for `plugin.kind = "rust_dynamic"`, `plugin.kind = "worker"`,
## Validation

```bash
just build-test-plugin-fixtures
cargo test -p nemo-relay-types
cargo test -p nemo-relay-plugin
cargo test -p nemo-relay-worker-proto
Expand All @@ -70,6 +71,11 @@ just test-python
just docs
```

The canonical `just test-rust`, `just test-python`, and `just test-go` recipes
prepare plugin fixtures automatically. Run `just build-test-plugin-fixtures`
before raw focused native or worker plugin tests; fixture compilation must not
happen inside an individual test case.

For broad runtime or public API changes, run the full `validate-change` matrix.

## References
Expand Down
4 changes: 4 additions & 0 deletions .agents/skills/test-python-binding/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ docs/examples.
# Focused test loop
uv run pytest -k "<pattern>"

# Required first for focused dynamic-plugin host tests
just build-test-plugin-fixtures
uv run pytest python/tests/test_dynamic_plugin_host.py

# Focused Python worker plugin SDK suite
just test-python-plugin

Expand Down
1 change: 1 addition & 0 deletions .agents/skills/test-rust-core/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ cargo test -p nemo-relay
cargo test -p nemo-relay-adaptive

# Dynamic plugin crates when touched
just build-test-plugin-fixtures
cargo test -p nemo-relay-types
cargo test -p nemo-relay-plugin
cargo test -p nemo-relay-worker-proto
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci_go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
Test:
name: Test (${{ matrix.platform }})
runs-on: ${{ matrix.runner }}
timeout-minutes: 120
timeout-minutes: 30
continue-on-error: ${{ startsWith(matrix.platform, 'windows') }}
permissions:
contents: read
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci_node.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
Test:
name: Test (${{ matrix.platform }})
runs-on: ${{ matrix.runner }}
timeout-minutes: 120
timeout-minutes: 30
continue-on-error: ${{ startsWith(matrix.platform, 'windows') }}
permissions:
contents: read
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci_python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
Test:
name: Test (${{ matrix.platform }})
runs-on: ${{ matrix.runner }}
timeout-minutes: 120
timeout-minutes: 30
continue-on-error: ${{ startsWith(matrix.platform, 'windows') }}
permissions:
contents: read
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci_rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
Test:
name: Test (${{ matrix.platform }})
runs-on: ${{ matrix.runner }}
timeout-minutes: 120
timeout-minutes: 30
continue-on-error: ${{ startsWith(matrix.platform, 'windows') }}
permissions:
contents: read
Expand Down
22 changes: 16 additions & 6 deletions crates/adaptive/tests/integration/redis_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,7 @@ fn enable_operational_logs() {
/// Redis tests were not explicitly enabled or Redis is unavailable.
async fn get_test_redis() -> Option<RedisBackend> {
enable_operational_logs();
let redis_test_env =
std::env::var_os(REDIS_TEST_ENV).map(|value| value.to_string_lossy().into_owned());
if !env_value_is_truthy(redis_test_env.as_deref()) {
eprintln!(
"SKIP: set {REDIS_TEST_ENV} to a truthy value (for example, {REDIS_TEST_ENV}=1) to run Redis-backed tests"
);
if !redis_tests_enabled() {
return None;
}

Expand All @@ -75,8 +70,23 @@ async fn get_test_redis() -> Option<RedisBackend> {
}
}

fn redis_tests_enabled() -> bool {
let redis_test_env =
std::env::var_os(REDIS_TEST_ENV).map(|value| value.to_string_lossy().into_owned());
if !env_value_is_truthy(redis_test_env.as_deref()) {
eprintln!(
"SKIP: set {REDIS_TEST_ENV} to a truthy value (for example, {REDIS_TEST_ENV}=1) to run Redis-backed tests"
);
return false;
}
true
}

async fn get_test_redis_with_prefix() -> Option<(RedisBackend, String)> {
enable_operational_logs();
if !redis_tests_enabled() {
return None;
}
let prefix = format!("test:{}:", Uuid::now_v7());
match RedisBackend::new("redis://127.0.0.1/", prefix.clone()).await {
Ok(backend) => Some((backend, prefix)),
Expand Down
17 changes: 9 additions & 8 deletions crates/cli/tests/cli_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ fn gateway_bin() -> &'static str {

const ACTIVE_GENERATION_TOKEN: &str = "active-generation";
const BOOTSTRAP_PROTOCOL_VERSION: u64 = 3;
const SIDECAR_PUBLICATION_TIMEOUT: Duration = Duration::from_secs(30);
const CHILD_PROCESS_TIMEOUT_SECONDS: u64 = 5;
const SIDECAR_PUBLICATION_TIMEOUT: Duration = Duration::from_secs(5);

fn write_active_generation(temp: &std::path::Path) -> std::path::PathBuf {
let generation = temp.join("plugin/.nemo-relay-generation");
Expand Down Expand Up @@ -1466,15 +1467,15 @@ fn find_runtime_files_matching(
}

fn wait_child(child: &mut Child) -> ExitStatus {
let deadline = Instant::now() + Duration::from_secs(10);
let deadline = Instant::now() + Duration::from_secs(CHILD_PROCESS_TIMEOUT_SECONDS);
loop {
if let Some(status) = child.try_wait().unwrap() {
return status;
}
if Instant::now() >= deadline {
let _ = child.kill();
let _ = child.wait();
panic!("child process did not exit within 10 seconds");
panic!("child process did not exit within {CHILD_PROCESS_TIMEOUT_SECONDS} seconds");
}
thread::sleep(Duration::from_millis(20));
}
Expand Down Expand Up @@ -1523,15 +1524,15 @@ fn wait_child_with_output(mut child: Child) -> Output {

let stdout = read_pipe(child.stdout.take());
let stderr = read_pipe(child.stderr.take());
let deadline = Instant::now() + Duration::from_secs(10);
let deadline = Instant::now() + Duration::from_secs(CHILD_PROCESS_TIMEOUT_SECONDS);
let status = loop {
if let Some(status) = child.try_wait().unwrap() {
break status;
}
if Instant::now() >= deadline {
let _ = child.kill();
let _ = child.wait();
panic!("child process did not exit within 10 seconds");
panic!("child process did not exit within {CHILD_PROCESS_TIMEOUT_SECONDS} seconds");
Comment thread
willkill07 marked this conversation as resolved.
}
thread::sleep(Duration::from_millis(20));
};
Expand Down Expand Up @@ -1607,7 +1608,7 @@ fn run_persistent_hook_with_token(
}

fn wait_for_port_closed(address: SocketAddr) {
let deadline = Instant::now() + Duration::from_secs(10);
let deadline = Instant::now() + Duration::from_secs(5);
loop {
if TcpStream::connect_timeout(&address, Duration::from_millis(100)).is_err() {
return;
Expand Down Expand Up @@ -4340,7 +4341,7 @@ fn assert_non_tty_signal_forwarding(

#[cfg(unix)]
fn wait_for_agent_pid_file(relay: &mut std::process::Child, pids: &Path, signal_name: &str) {
let deadline = Instant::now() + Duration::from_secs(10);
let deadline = Instant::now() + Duration::from_secs(5);
while !pids.is_file() {
if Instant::now() >= deadline {
// SAFETY: Relay's PID is live and owned by this test; SIGTERM exercises its registered
Expand Down Expand Up @@ -4592,7 +4593,7 @@ fn collect_replacement_requests(
stopped: &AtomicBool,
requests: &Mutex<Vec<String>>,
) {
let deadline = Instant::now() + Duration::from_secs(12);
let deadline = Instant::now() + Duration::from_secs(5);
while !stopped.load(Ordering::Relaxed) && Instant::now() < deadline {
match listener.accept() {
Ok((mut stream, _)) => {
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/tests/coverage/agents/plugin_install_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,7 @@ fn cross_process_lock_holder() {
return;
}
std::fs::write(ready, b"ready").unwrap();
let deadline = Instant::now() + Duration::from_secs(10);
let deadline = Instant::now() + Duration::from_secs(5);
while !release.exists() {
assert!(Instant::now() < deadline, "lock holder release timed out");
thread::sleep(Duration::from_millis(10));
Expand Down
3 changes: 1 addition & 2 deletions crates/cli/tests/coverage/shared/agent_process_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,7 @@ while (-not (Test-Path -LiteralPath $args[1])) {
};
std::fs::write(release_path, b"ready").unwrap();

let status = match tokio::time::timeout(std::time::Duration::from_secs(15), child.wait()).await
{
let status = match tokio::time::timeout(std::time::Duration::from_secs(5), child.wait()).await {
Ok(status) => status.unwrap(),
Err(_) => {
let _ = child.terminate().await;
Expand Down
Loading
Loading