Skip to content

Commit 6dc7d0f

Browse files
authored
Merge pull request #148 from dotindustries/fix/integration-tests
fix: resolve all failing integration tests and flaky CI
2 parents 5ffa778 + da7eff9 commit 6dc7d0f

File tree

93 files changed

+8778
-391
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+8778
-391
lines changed

.beads/issues.jsonl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{"id":"warpgrid-5fj","title":"Serve warpgrid.dev via WarpGrid Cloud (dogfooding)","description":"Migrate warpgrid.dev from include_str\\!() in warpd to a standalone website deployed as a WarpGrid Wasm component. Currently the landing page is baked into the warpd binary, which: (1) couples frontend to backend releases, (2) bloats the customer-downloadable binary, (3) requires 3-min Rust rebuilds for page edits, (4) is dishonest — we claim WarpGrid is great but don't use it ourselves. The website repo (warpgrid-website) gets compiled to Wasm via warp pack and deployed via warp deploy. The site itself becomes a showcase: 'This page runs on WarpGrid.' Dependencies: warpgrid-website repo must be created first.","status":"open","priority":1,"issue_type":"feature","owner":"janos@dot.industries","created_at":"2026-03-17T18:23:13.222459+01:00","created_by":"János Veres","updated_at":"2026-03-17T18:23:13.222459+01:00"}
12
{"id":"warpgrid-agm","title":"WarpGrid SDK — Fork Engineering Implementation","description":"Curated, tested distribution of WebAssembly toolchain components that enables WarpGrid (a Wasm-native cluster orchestrator) to run real-world backend services. Pushes WASI workload compatibility from ~25-35% to 60-70% through 6 coordinated engineering domains:\n\n1. Wasmtime host functions (shim layer foundation)\n2. wasi-libc patches (socket/filesystem compat)\n3. TinyGo WASI overlay (Go workload support)\n4. ComponentizeJS extensions (TypeScript/Node.js support)\n5. WASI 0.3 async pre-integration (async I/O)\n6. Bun WASI runtime (Bun/TypeScript support)\n\n85 user stories across 7 sections with explicit dependency chains.\n\nQuality Gates (per domain):\n- Rust: cargo check \u0026\u0026 cargo test \u0026\u0026 cargo clippy -- -D warnings\n- C/libc: make + scripts/test-libc.sh\n- Go: tinygo build -target=wasip2 + go test ./...\n- TypeScript: npm run typecheck + npm test\n- Bun: bun run typecheck + bun test\n- All: TDD (tests written BEFORE implementation)","status":"open","priority":1,"issue_type":"epic","owner":"janos@dot.industries","created_at":"2026-02-22T11:47:49.620679+01:00","created_by":"János Veres","updated_at":"2026-02-22T11:47:49.620679+01:00","external_ref":"prd:./tasks/prd-warpgrid-sdk.md"}
23
{"id":"warpgrid-agm.1","title":"US-101: Scaffold the warpgrid-host crate with dependencies","description":"Milestone: M1.1 | Depends on: none\n\nAs a SDK developer, I want a properly structured warpgrid-host crate with all required dependencies so that I have a compilable foundation for implementing host function shims.\n\n## Acceptance Criteria\n- [ ] crates/warpgrid-host/ directory exists with Cargo.toml and src/lib.rs\n- [ ] Cargo.toml declares dependencies on wasmtime, wasmtime-wasi, tokio (with rt-multi-thread, macros, net, time features), tracing, and anyhow\n- [ ] Dev-dependencies include tokio (with test-util), tracing-subscriber, and wasmtime (with component-model feature)\n- [ ] src/lib.rs contains public crate-level module structure (empty modules for filesystem, dns, signals, db_proxy, threading, config, engine)\n- [ ] cargo check -p warpgrid-host passes with zero errors\n\n## Quality Gates\n- [ ] cargo check passes\n- [ ] cargo test passes\n- [ ] cargo clippy -- -D warnings passes\n- [ ] Tests written before implementation (TDD)","status":"closed","priority":1,"issue_type":"task","owner":"janos@dot.industries","created_at":"2026-02-22T11:50:04.860934+01:00","created_by":"János Veres","updated_at":"2026-02-22T12:41:08.207798+01:00","closed_at":"2026-02-22T12:41:08.207798+01:00","close_reason":"Scaffolded crate with all modules, workspace integration, and quality gates passing","dependencies":[{"issue_id":"warpgrid-agm.1","depends_on_id":"warpgrid-agm","type":"parent-child","created_at":"2026-02-22T11:50:04.862488+01:00","created_by":"János Veres"}]}
34
{"id":"warpgrid-agm.10","title":"US-110: Signal handling integration tests","description":"Milestone: M1.4 | Depends on: US-109\n\nAs a SDK developer, I want integration tests proving Wasm modules can register for and receive signals.\n\n## Acceptance Criteria\n- [ ] Test: Wasm component registers for terminate, host delivers it, poll-signal returns it\n- [ ] Test: poll-signal on empty queue returns None\n- [ ] Test: queue bounding — 20 signals delivered, only 16 most recent retrievable\n- [ ] Test: signal filtering — register hangup only, deliver terminate, poll returns None\n- [ ] All integration tests against real Wasmtime engine instance\n\n## Quality Gates\n- [ ] cargo check passes\n- [ ] cargo test passes\n- [ ] cargo clippy -- -D warnings passes\n- [ ] Tests written before implementation (TDD)","status":"in_progress","priority":2,"issue_type":"task","owner":"janos@dot.industries","created_at":"2026-02-22T11:51:12.007536+01:00","created_by":"János Veres","updated_at":"2026-02-24T04:31:30.971434+01:00","dependencies":[{"issue_id":"warpgrid-agm.10","depends_on_id":"warpgrid-agm","type":"parent-child","created_at":"2026-02-22T11:51:12.008255+01:00","created_by":"János Veres"},{"issue_id":"warpgrid-agm.10","depends_on_id":"warpgrid-agm.9","type":"blocks","created_at":"2026-02-22T12:08:17.148497+01:00","created_by":"János Veres"}]}

.github/workflows/integration-tests.yml

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,18 @@ jobs:
5757
version: "v41.0.0"
5858

5959
- name: Build T1
60-
run: cargo build -p t1-rust-http-postgres 2>&1 || echo "BUILD_FAILED"
60+
run: cd test-apps/t1-rust-http-postgres && cargo build 2>&1 || echo "BUILD_FAILED"
6161
continue-on-error: true
6262
id: build
63+
env:
64+
RUSTFLAGS: ""
6365

6466
- name: Test T1
6567
if: steps.build.outcome == 'success'
66-
run: cargo test -p t1-rust-http-postgres
68+
run: cd test-apps/t1-rust-http-postgres && cargo test
6769
env:
6870
DATABASE_URL: "postgres://testuser:testpass@localhost:5432/testdb"
71+
RUSTFLAGS: ""
6972

7073
- name: Upload test results
7174
if: always()
@@ -123,16 +126,19 @@ jobs:
123126
version: "v41.0.0"
124127

125128
- name: Build T2
126-
run: cargo build -p t2-rust-http-redis-postgres 2>&1 || echo "BUILD_FAILED"
129+
run: cd test-apps/t2-rust-http-redis-postgres && cargo build 2>&1 || echo "BUILD_FAILED"
127130
continue-on-error: true
128131
id: build
132+
env:
133+
RUSTFLAGS: ""
129134

130135
- name: Test T2
131136
if: steps.build.outcome == 'success'
132-
run: cargo test -p t2-rust-http-redis-postgres
137+
run: cd test-apps/t2-rust-http-redis-postgres && cargo test
133138
env:
134139
DATABASE_URL: "postgres://testuser:testpass@localhost:5432/testdb"
135140
REDIS_URL: "redis://localhost:6379"
141+
RUSTFLAGS: ""
136142

137143
- name: Upload test results
138144
if: always()
@@ -171,6 +177,7 @@ jobs:
171177
- uses: actions/setup-go@v5
172178
with:
173179
go-version: '1.22'
180+
cache-dependency-path: test-apps/t3-go-http-postgres/go.sum
174181

175182
- name: Build & Test T3
176183
run: test-apps/t3-go-http-postgres/test.sh
@@ -189,8 +196,8 @@ jobs:
189196
# ── T4: TypeScript HTTP + Postgres ─────────────────────────────────
190197
t4-ts-http-postgres:
191198
name: "T4: TypeScript HTTP + Postgres"
192-
runs-on: blacksmith-4vcpu-ubuntu-2404
193-
timeout-minutes: 15
199+
runs-on: blacksmith-8vcpu-ubuntu-2404
200+
timeout-minutes: 45
194201

195202
steps:
196203
- uses: actions/checkout@v4
@@ -224,6 +231,17 @@ jobs:
224231
- name: Install T4 dependencies
225232
run: npm ci --prefix test-apps/t4-ts-http-postgres
226233

234+
- name: Cache T4 standalone WASM
235+
id: t4-wasm-cache
236+
uses: actions/cache@v4
237+
with:
238+
path: test-apps/t4-ts-http-postgres/dist/handler.wasm
239+
key: t4-wasm-${{ hashFiles('test-apps/t4-ts-http-postgres/src/handler-standalone.js', 'test-apps/t4-ts-http-postgres/wit-standalone/**') }}
240+
241+
- name: Build T4 standalone WASM
242+
if: steps.t4-wasm-cache.outputs.cache-hit != 'true'
243+
run: test-apps/t4-ts-http-postgres/build.sh --standalone
244+
227245
- name: Build & Test T4
228246
run: test-apps/t4-ts-http-postgres/test.sh
229247

@@ -239,8 +257,8 @@ jobs:
239257
# ── T5: Bun HTTP + Postgres ────────────────────────────────────────
240258
t5-bun-http-postgres:
241259
name: "T5: Bun HTTP + Postgres"
242-
runs-on: blacksmith-4vcpu-ubuntu-2404
243-
timeout-minutes: 15
260+
runs-on: blacksmith-8vcpu-ubuntu-2404
261+
timeout-minutes: 45
244262

245263
steps:
246264
- uses: actions/checkout@v4
@@ -278,6 +296,17 @@ jobs:
278296
- name: Install T5 dependencies
279297
run: bun install --frozen-lockfile --cwd test-apps/t5-bun-http-postgres
280298

299+
- name: Cache T5 standalone WASM
300+
id: t5-wasm-cache
301+
uses: actions/cache@v4
302+
with:
303+
path: test-apps/t5-bun-http-postgres/dist/handler.wasm
304+
key: t5-wasm-${{ hashFiles('test-apps/t5-bun-http-postgres/src/handler-standalone.js', 'test-apps/t5-bun-http-postgres/wit-standalone/**') }}
305+
306+
- name: Build T5 standalone WASM
307+
if: steps.t5-wasm-cache.outputs.cache-hit != 'true'
308+
run: test-apps/t5-bun-http-postgres/build.sh --standalone
309+
281310
- name: Build & Test T5
282311
run: test-apps/t5-bun-http-postgres/test.sh
283312

@@ -327,7 +356,7 @@ jobs:
327356

328357
- uses: dtolnay/rust-toolchain@stable
329358
with:
330-
targets: wasm32-wasip2
359+
targets: wasm32-wasip2,wasm32-unknown-unknown
331360

332361
- uses: Swatinem/rust-cache@v2
333362

@@ -369,18 +398,20 @@ jobs:
369398
run: scripts/build-componentize-js.sh --npm
370399

371400
- name: Build all T6 services
401+
env:
402+
RUSTFLAGS: ""
372403
run: |
373-
echo "Building gateway (Rust)..."
374-
cargo build -p t6-gateway-svc
404+
echo "Building gateway-svc (Rust WASM component)..."
405+
cd test-apps/t6-multi-service/gateway-svc && cargo build --target wasm32-unknown-unknown --release && cd "$GITHUB_WORKSPACE"
375406
376-
echo "Building user-svc (Go)..."
377-
test-apps/t6-multi-service/user-svc/build.sh --standalone
407+
echo "Building user-svc (Rust WASM component)..."
408+
cd test-apps/t6-multi-service/user-svc && cargo build --target wasm32-unknown-unknown --release && cd "$GITHUB_WORKSPACE"
378409
379-
echo "Building notification-svc (TypeScript)..."
380-
test-apps/t6-multi-service/notification-svc/build.sh --standalone
410+
echo "Building notification-svc (Rust WASM component)..."
411+
cd test-apps/t6-multi-service/notification-svc && cargo build --target wasm32-unknown-unknown --release && cd "$GITHUB_WORKSPACE"
381412
382-
echo "Building analytics-svc (Bun)..."
383-
test-apps/t6-multi-service/analytics-svc/build.sh --standalone
413+
echo "Building analytics-svc (Rust WASM component)..."
414+
cd test-apps/t6-multi-service/analytics-svc && cargo build --target wasm32-unknown-unknown --release && cd "$GITHUB_WORKSPACE"
384415
385416
- name: Test T6 multi-service integration
386417
run: scripts/test-all.sh --only t6

.gitignore

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
/vendor/tinygo
1111
/vendor/componentize-js
1212
/vendor/wasmtime-async
13-
tests/fixtures/fs-shim-guest/target/
13+
tests/fixtures/**/target/
14+
tests/fixtures/**/Cargo.lock
1415
test-apps/**/target/
1516
test-apps/**/Cargo.lock
1617
__pycache__/
1718
/test-results
1819
docs/GTM-BETA-LAUNCH-PLAN.md
1920
docs/IMPLEMENTATION-PLAN-PHASE2.md
2021
warpgrid.toml
21-
tests/fixtures/rust-sqlx-postgres-guest/target/
22+
.beads/daemon-error
23+
.gstack/
24+
.context/

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/warp-pack/src/bun.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,10 @@ pub fn pack_bun(project_path: &Path, config: &WarpConfig) -> Result<PackResult>
474474
mod tests {
475475
use super::*;
476476
use std::fs;
477+
use std::sync::Mutex;
478+
479+
/// Serialize tests that mutate process-wide environment variables.
480+
static ENV_MUTEX: Mutex<()> = Mutex::new(());
477481

478482
// ── Helper: Create a minimal Bun project in a temp dir ──────────────────
479483

@@ -569,10 +573,10 @@ entry = "src/index.ts"
569573
#[test]
570574
fn test_resolve_jco_env_var_missing_file() {
571575
// WARPGRID_JCO_PATH pointing to nonexistent file should error.
572-
// In Rust 2024 edition, set_var/remove_var are unsafe due to
573-
// potential data races in multi-threaded test execution.
574-
// SAFETY: This test is not using threads and the env var is
575-
// restored before the test returns.
576+
// Hold ENV_MUTEX to prevent races with other env-var-mutating tests.
577+
let _lock = ENV_MUTEX.lock().unwrap();
578+
579+
// SAFETY: serialized by ENV_MUTEX; env var is restored before the lock drops.
576580
unsafe { std::env::set_var("WARPGRID_JCO_PATH", "/nonexistent/jco") };
577581
let result = resolve_jco(Path::new("."));
578582
unsafe { std::env::remove_var("WARPGRID_JCO_PATH") };
@@ -820,11 +824,14 @@ entry = "src/index.ts"
820824
#[test]
821825
fn test_resolve_jco_env_var_valid_file() {
822826
// WARPGRID_JCO_PATH pointing to a real file should succeed.
827+
// Hold ENV_MUTEX to prevent races with other env-var-mutating tests.
828+
let _lock = ENV_MUTEX.lock().unwrap();
829+
823830
let dir = tempfile::tempdir().unwrap();
824831
let fake_jco = dir.path().join("jco");
825832
fs::write(&fake_jco, "#!/bin/sh\n").unwrap();
826833

827-
// SAFETY: test is single-threaded for this env var; restored before return.
834+
// SAFETY: serialized by ENV_MUTEX; env var is restored before the lock drops.
828835
unsafe { std::env::set_var("WARPGRID_JCO_PATH", fake_jco.to_str().unwrap()) };
829836
let result = resolve_jco(Path::new("."));
830837
unsafe { std::env::remove_var("WARPGRID_JCO_PATH") };

crates/warpd/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ path = "src/main.rs"
1111

1212
[dependencies]
1313
warp-core.workspace = true
14+
warp-analyzer = { path = "../warp-analyzer" }
1415
warp-runtime = { path = "../warp-runtime" }
1516
warpgrid-state = { path = "../warpgrid-state" }
1617
warpgrid-scheduler = { path = "../warpgrid-scheduler" }
@@ -43,9 +44,9 @@ hex = "0.4"
4344
chrono = { version = "0.4", features = ["serde"] }
4445
toml = "0.8"
4546
libsql = "0.9"
47+
tempfile = "3"
4648

4749
[dev-dependencies]
4850
tower = { version = "0.5", features = ["util"] }
4951
axum = { version = "0.8", features = ["tokio"] }
5052
warpgrid-placement = { path = "../warpgrid-placement" }
51-
tempfile = "3"
18.6 KB
Binary file not shown.

crates/warpd/src/cloud/admin.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,8 @@ mod tests {
832832
usage: UsageTracker::new(),
833833
logs: crate::cloud::routes::new_log_buffer(),
834834
admin_key: None,
835+
playground_rate_limit: crate::cloud::routes::new_playground_rate_limit(),
836+
analyze_rate_limit: crate::cloud::routes::new_playground_rate_limit(),
835837
}
836838
}
837839

crates/warpd/src/cloud/auth.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ fn generate_api_key() -> String {
242242
}
243243

244244
/// Generate a random user ID.
245-
fn generate_user_id() -> String {
245+
pub fn generate_user_id() -> String {
246246
let mut rng = rand::thread_rng();
247247
let bytes: [u8; 8] = rng.r#gen();
248248
format!("usr_{}", hex::encode(bytes))

crates/warpd/src/cloud/console.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,8 @@ mod tests {
10311031
usage: UsageTracker::new(),
10321032
logs: crate::cloud::routes::new_log_buffer(),
10331033
admin_key: None,
1034+
playground_rate_limit: crate::cloud::routes::new_playground_rate_limit(),
1035+
analyze_rate_limit: crate::cloud::routes::new_playground_rate_limit(),
10341036
}
10351037
}
10361038

0 commit comments

Comments
 (0)