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
2 changes: 1 addition & 1 deletion .github/workflows/rust-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
working-directory: runner

# zone_server's integration tests talk to real backing services: Postgres
# via tests/common::create_test_pool, and Valkey via cache_tests. Without
# via tests/integration/common::create_test_pool, and Valkey via cache::. Without
# both, coverage fails before it can measure anything.
services:
postgres:
Expand Down
2 changes: 1 addition & 1 deletion docs/SYSTEM-PROMPT-RESEARCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ GK 29 allows disclosure on explicit request. Recommend the same: an operator-own

## 5. Suggested PR sequence

1. **Prompt builder, P0 text, and the two media tool descriptions** (A1, A2, A4, B1, B4, C1 to C8, D1, D4, F1 text, F4, F5, G2, G3, H3, H5, J1, K1, K3, L2, L3, N1 to N4). One PR that restructures `agent::system_prompt`, `session::system_prompt` and `task::guidance` into named sections with snapshot tests and adds every prompt-only item. Add scripted-completion tests using the wiremock LiteLLM stub that `runner/zone_server/tests/chat_agent_tests.rs` and its siblings already use, for the behaviours that matter most: a failure reported first, no "Done." reply, no invented citation.
1. **Prompt builder, P0 text, and the two media tool descriptions** (A1, A2, A4, B1, B4, C1 to C8, D1, D4, F1 text, F4, F5, G2, G3, H3, H5, J1, K1, K3, L2, L3, N1 to N4). One PR that restructures `agent::system_prompt`, `session::system_prompt` and `task::guidance` into named sections with snapshot tests and adds every prompt-only item. Add scripted-completion tests using the wiremock LiteLLM stub that `runner/zone_server/tests/integration/chat_agent.rs` and its siblings already use, for the behaviours that matter most: a failure reported first, no "Done." reply, no invented citation.
2. **Repository instruction files and effort dial** (A3, A4 wiring).
3. **Tool schema pass** (E1, E3, F1 `time_range`, F2, F3, E2 output cap). Approval card and receipts show the `description`.
4. **Action tiers and approval preview** (B2, B3, D3 watchdog, J2 commit and PR content).
Expand Down
2 changes: 1 addition & 1 deletion runner/zone_installer/src/migration/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ async fn apply(
/// row is written. Those six cannot be edited to fix it -- both runners key a migration by
/// a hash of its bytes and refuse to start when a recorded one changes -- so what makes the
/// window survivable is that all six are idempotent and the re-run is a no-op. That property
/// is held by `zone_server/tests/migration_atomicity_tests.rs`, which also stops a seventh
/// is held by `zone_server/tests/integration/migration_atomicity.rs`, which also stops a seventh
/// joining the set.
async fn execute(
connection: &mut PgConnection,
Expand Down
5 changes: 5 additions & 0 deletions runner/zone_server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
autotests = false

[features]
default = ["local-embeddings", "saliency"]
Expand All @@ -24,6 +25,10 @@ path = "src/lib.rs"
name = "zone-server"
path = "src/main.rs"

[[test]]
name = "integration"
path = "tests/integration/main.rs"

[dependencies]
tokio = { workspace = true }
serde = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion runner/zone_server/src/workers/gathering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,4 +418,4 @@ pub(crate) fn core_source_from_row(
})
}

// Integration tests are in zone_server/tests/gathering_worker_tests.rs
// Integration tests are in zone_server/tests/integration/gathering_worker.rs
2 changes: 1 addition & 1 deletion runner/zone_server/src/workers/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3572,7 +3572,7 @@ mod tests {
.unwrap();
}

// Integration tests are in zone_server/tests/task_execution_tests.rs
// Integration tests are in zone_server/tests/integration/task_execution.rs

#[tokio::test]
async fn task_loop_persists_workspace_receipt_before_returning() {
Expand Down
10 changes: 6 additions & 4 deletions runner/zone_server/src/ws/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ enum Routing {
Video(crate::config::ComfyUiConfig),
Audio(crate::config::ComfyUiConfig),
Upscale(crate::config::ComfyUiConfig),
Chat(chats::ChatRow, Route),
Chat(chats::ChatRow, Box<Route>),
}

/// What a provider reported when a turn failed, remedied for a coding agent's
Expand Down Expand Up @@ -2495,7 +2495,7 @@ async fn handle_send_message(
return Ok(());
}
_ = session.guard.lost() => { return Err(OWNERSHIP_LOST.into()); }
result = prepare_chat(state, stream, chat_id, workspace_id, user_id, content, metadata.as_ref(), chat, route, web_search_requested) => result?,
result = prepare_chat(state, stream, chat_id, workspace_id, user_id, content, metadata.as_ref(), chat, *route, web_search_requested) => result?,
};
handle_chat_generation(state, stream, chat_id, workspace_id, user_id, preparation, &mut request, &mut session, &mut jobs).await
}
Expand Down Expand Up @@ -2666,7 +2666,9 @@ async fn prepare_message(
}
crate::services::image_intent::GenerationIntent::Audio => Routing::Audio(image_config),
crate::services::image_intent::GenerationIntent::Upscale => Routing::Upscale(image_config),
crate::services::image_intent::GenerationIntent::Chat => Routing::Chat(chat, route),
crate::services::image_intent::GenerationIntent::Chat => {
Routing::Chat(chat, Box::new(route))
}
})
}

Expand Down Expand Up @@ -4569,7 +4571,7 @@ mod tests {
QUESTION,
None,
chat,
route,
*route,
false,
)
.await
Expand Down
5 changes: 4 additions & 1 deletion runner/zone_server/tests/CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ Run against a disposable PostgreSQL database with migrations 001 through 015 app
```sh
TEST_DATABASE_URL=postgres://postgres:postgres@127.0.0.1:49755/zone_context_test \
DATABASE_URL=postgres://postgres:postgres@127.0.0.1:49755/zone_context_test \
cargo test -p zone_server --test chat_context_tests --test chat_replay_tests --test chat_context_store_tests --test chat_lifecycle_tests --no-default-features --features zone_context/test-utils
cargo nextest run -p zone_server --test integration --no-default-features --features zone_context/test-utils \
-E 'test(/^(chat_context|chat_replay|chat_context_store|chat_lifecycle)::/)'
```

The fixtures serve the real router on an ephemeral local port, authenticate through its public API, and replace inference and model metadata with deterministic Wiremock responses. They disable MCP startup and external web/image services. Tool mutations are confined to per-test temporary directories. Tests retain rows only in the disposable database; remove the database when finished.

Every file under `integration/` is a module of the one `integration` test binary (`autotests = false` in `Cargo.toml`), so a new test file must be declared in `integration/main.rs`; `integration/layout.rs` fails when one is not. Shared helpers live in `integration/common/`, reached as `crate::common`. All modules share one process under plain `cargo test` and `cargo llvm-cov`, while nextest runs each test in its own.

`fixtures/context.json` is checked against Rust `ContextUsage` serialization and shared with frontend E2E tests.

## Library tests that need the same database
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
//! migrated database:
//!
//! `CLAUDE_CONFIG_DIR=/tmp/empty cargo test -p zone_server --no-default-features
//! --features zone_context/test-utils --test agent_host_login_tests -- --ignored`
//! --features zone_context/test-utils --test integration -- --ignored agent_host_login::`
//!
//! `CLAUDE_CONFIG_DIR` points at an empty directory on purpose: the server's own
//! environment must not reach the agent, so claude still finds the host login.

mod common;

use std::path::PathBuf;

use axum::http::StatusCode;
Expand All @@ -23,7 +21,7 @@ use zone_server::config::{AgentConfig, Config};
use zone_server::services::route::Route;
use zone_server::services::stages::AUTO;

use common::{TestClient, test_config, test_email, test_password};
use crate::common::{TestClient, test_config, test_email, test_password};

const PROVIDER: &str = "claude_code";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! real one printed, so no test here signs in to anything real. The one test that asks the host's
//! own claude is ignored.

mod common;
use crate::common;

use std::fs;
use std::net::{Ipv4Addr, SocketAddr};
Expand Down Expand Up @@ -35,7 +35,7 @@ use zone_server::config::{AgentConfig, Callback, Config, ModelBackend};
use zone_server::services::login::claude::{AUTHORIZE_URL, CLIENT_ID, REDIRECT_URL, Tokens};
use zone_server::services::login::{callback, devices};

use common::{TestClient, test_email, test_password};
use crate::common::{TestClient, test_email, test_password};

const FIXTURES: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/login");
const TOKEN_PATH: &str = "/v1/oauth/token";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
//! for itself. Run by hand, from `runner/`:
//!
//! `CLAUDE_CODE_OAUTH_TOKEN=<token from claude setup-token> cargo test -p zone_server
//! --no-default-features --features zone_context/test-utils --test agent_session_resume_tests
//! -- --ignored --exact claude_session_resume_across_homes`
//! --no-default-features --features zone_context/test-utils --test integration
//! -- --ignored --exact agent_session_resume::claude_session_resume_across_homes`
//!
//! `ZONE_SPIKE_CODEX_HOMES=<home a>:<home b> cargo test -p zone_server --no-default-features
//! --features zone_context/test-utils --test agent_session_resume_tests -- --ignored --exact
//! codex_session_resume_across_homes`, where each home was signed in with
//! --features zone_context/test-utils --test integration -- --ignored --exact
//! agent_session_resume::codex_session_resume_across_homes`, where each home was signed in with
//! `CODEX_HOME=<home> codex login`.

use std::env;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//! AI Settings integration tests

mod common;
use crate::common;

use abnegate_secret::OptionalSecretExtension;
use axum::http::StatusCode;
use serde_json::json;
use uuid::Uuid;
use zone_server::db::ai_settings;

use common::{TestClient, test_email, test_password};
use crate::common::{TestClient, test_email, test_password};

const AGENT_PROVIDERS: [&str; 2] = ["claude_code", "codex"];
const MODEL_FIELDS: [&str; 3] = ["model_fast", "model_reasoning", "model_embedding"];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
//! settings are written straight into the tables, so what is under test is the
//! read side alone: which host a completion reaches and which key rides with it.

mod common;

use common::{
use crate::common::{
TestClient, TestResponse, create_test_pool, create_test_router, create_test_state, discard,
next_frame, seed_chat, serve, setup_test_data, setup_workspace_member, test_config, test_email,
test_password,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! Regression coverage for AI settings and workspace theme authorization.

mod common;

use std::time::Duration;

use axum::http::StatusCode;
Expand All @@ -10,7 +8,7 @@ use sqlx::{PgPool, postgres::PgPoolOptions, postgres::PgQueryResult};
use uuid::Uuid;
use zone_server::db::{organization_members, workspace_members};

use common::{
use crate::common::{
TestClient, create_test_pool, create_test_router, create_test_state, test_config, test_password,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//! gauges went empty on the busiest workspaces -- the ones anyone would be
//! watching.

mod common;
use crate::common;

use chrono::{Duration, Utc};
use sqlx::PgPool;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
//! Integration tests for the Zone Server API
//!
//! These tests exercise the HTTP endpoints with a real database.
//! Run with: SQLX_OFFLINE=true cargo test --test api_tests
//! Run with: SQLX_OFFLINE=true cargo nextest run -p zone_server --test integration -E 'test(/^api::/)'

#![allow(unused_variables)]

mod common;
use crate::common;

use axum::http::StatusCode;
use serde_json::json;

use common::{TestClient, test_email, test_password};
use crate::common::{TestClient, test_email, test_password};

// Health Check Tests

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
//! Byte-range serving for generated media through the real authenticated router.
mod common;

use common::context::Harness;
use common::{test_email, test_password};
use crate::common::context::Harness;
use crate::common::{test_email, test_password};
use serde_json::json;
use std::path::PathBuf;
use uuid::Uuid;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
//! Integration tests for audit logging functionality

mod common;

use crate::common::{create_test_pool, setup_test_data};
use chrono::{Duration, Utc};
use common::{create_test_pool, setup_test_data};
use uuid::Uuid;

#[tokio::test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
//! and the current session, and revoking the other sessions kills their
//! refresh tokens while keeping the caller's own.

mod common;

use axum::http::StatusCode;
use serde_json::{Value, json};
use uuid::Uuid;

use common::{TestClient, test_email, test_password};
use crate::common::{TestClient, test_email, test_password};
use zone_server::db::{email_verification, password_reset};

struct Login {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod common;
use crate::common;

use axum::{Router, http::StatusCode, middleware, routing::get};
use uuid::Uuid;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@
//! admins and owners included -- while the organization's own credential stayed
//! in effect and travelled to the host they chose.
//!
//! `cross_tenant_authorization_tests` already pins that a stranger cannot
//! `cross_tenant_authorization` already pins that a stranger cannot
//! repoint another tenant's model host. This pins that a member of the tenant
//! cannot either.

mod common;

use axum::http::StatusCode;
use serde_json::json;

use common::{TestClient, test_email, test_password};
use crate::common::{TestClient, test_email, test_password};

struct Account {
token: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
//! gather asked only whether the caller was a member at all, so the read-only
//! role could start the same work.

mod common;

use axum::http::StatusCode;
use serde_json::json;

use common::{TestClient, test_email, test_password};
use crate::common::{TestClient, test_email, test_password};

struct Account {
token: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
//! `cross_tenant_authorization_tests` covers tasks, task runs, AI settings and
//! `cross_tenant_authorization` covers tasks, task runs, AI settings and
//! branding. These are the id-addressed routes it does not: chats and their
//! messages, sources, knowledge, audit logs, billing, and session revocation.
//! Each one takes a resource id straight from the request, so each one is
//! driven here with a stranger's id to pin that the binding holds.

mod common;
use crate::common;

use axum::http::StatusCode;
use serde_json::json;

use common::{TestClient, test_email, test_password};
use crate::common::{TestClient, test_email, test_password};

struct Tenant {
token: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
//! Written from the attacker's side: an organization the attacker owns outright
//! is used as a lever to seat an accomplice inside a stranger's workspace.

mod common;

use axum::http::StatusCode;
use serde_json::json;

use common::{TestClient, test_email, test_password};
use crate::common::{TestClient, test_email, test_password};

struct Account {
token: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@
//! workspace` for a stranger's project and `404` for one that does not exist,
//! so the pair separated real project ids from invented ones.

mod common;

use axum::http::StatusCode;
use serde_json::json;

use common::{TestClient, test_email, test_password};
use crate::common::{TestClient, test_email, test_password};

struct Tenant {
token: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
//! Written from the attacker's side: an admin the owner seated deletes the
//! workspace out from under them.

mod common;

use axum::http::StatusCode;
use serde_json::json;

use common::{TestClient, test_email, test_password};
use crate::common::{TestClient, test_email, test_password};

struct Account {
token: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! checkout it runs in, and who kills the child when the session that started
//! the job ends.

mod common;
use crate::common;

use std::collections::HashMap;
use std::path::{Path, PathBuf};
Expand Down
Loading
Loading