Strategy (layered proof, coverage ratchets, ProdStyle-first): Testing strategy pivot v1 · Tracking checklist · Review guide
Nexo uses multiple mechanisms to prevent tests from hanging indefinitely and keep CI/dev loops responsive.
| Scope | blame-hang-timeout | Per-test timeout | Notes |
|---|---|---|---|
| prime-time | 300s | varies | Nexo.PrimeTime.slnf — ProdStyle then full (make test-prime-time / make test-prime-time-full) |
| prod-style | 120s | varies | Category=ProdStyle — Infrastructure-only (make test-prod-style) |
| smoke | 30s | — | BaseFrameworkSmokeTests; local make test |
| integration | 60s | 15s (Integration tests) | Category=Integration |
| persistence | 60s | — | InMemoryPersistenceTests |
| adaptation | 90s | — | Category=Adaptation (LiteDB, Roslyn, MSBuild) |
| e2e | 90s | — | Category=E2E |
| trust | 60s | — | Trust tests (Infrastructure + BackgroundAgents) |
| full | 120s | — | All Nexo.Tests.Infrastructure tests |
- Makefile
make test:--blame-hang-timeout 30s --blame-hang-dump-type none(avoids 6GB+ hang dumps) - Makefile
test-all-platforms: Local 30s; Docker runs 60s - CI (cross-platform-tests.yml): Per-scope as above
- TestCommandRunner: 10 min global timeout for
nexo test local - TestRunnerAdapter: 60s per-test for TestBase-based tests
- MultiPlatformTestCommand: 5 min for native platform runs
- WorkflowExecutorIntegrationTests:
[Fact(Timeout = 15000)]on each test
- Add
[Collection("Integration")]and[Trait("Category", "Integration")]to the test class when appropriate. - For suites that exercise production DI graphs or
Hostwiring, also add[Trait("Category", "ProdStyle")]so they participate inmake test-prod-style/nexo ci verifyordering. - Add
[Fact(Timeout = 15000)](or appropriate value) to async/I/O tests - Integration tests run sequentially (DisableParallelization) to avoid file watcher and temp dir contention
Run before building product features on top of the kernel. Builds Nexo.Runtime.sln, runs hosting phase/profile resolution tests, and pipeline tests.
make kernel-gate # Tier A: runtime build + hosting matrix + pipeline lifecycle
make kernel-gate-tier-b # Tier B: CLI validate/run/fallback + LiteDB cross-process resume
make kernel-gate-tier-c # Tier C: ProdStyle + workflow + gRPC transport + air-gapped profile
make kernel-gate-tier-d # Tier D: pack graph alignment + NuGet consumer sample
make kernel-gate-full # Tier A + B + C + D
make bootstrap-mesh-lab-env # create .env.mesh-lab from example (gitignored)
KERNEL_GATE_MESH_E2E=1 make kernel-gate-tier-c # adds ~2min Docker mesh E2E
make mesh-lab-e2e .env.mesh-lab # or run mesh E2E directly
# Skip tiers on full run:
make kernel-gate-tier-e # Tier E: OpenTelemetry + perf tests + prod Compose dry run
KERNEL_GATE_CHAOS_LITE=1 make kernel-gate-tier-e # optional mesh network-negative
KERNEL_GATE_SKIP_TIER_E=1 make kernel-gate-full # skip Docker prod dry runSee docs/production-readiness/KernelHardeningPlan-v1.md, docs/architecture/KernelPhaseMatrix.md, and track sign-off in docs/production-readiness/KernelReadiness-v1.md.
Validates application/Nexo.Application.sln (CLI, API, optional agent-server Compose). Assumes make kernel-gate-full has passed (or set APPLICATION_GATE_REQUIRE_KERNEL=1 on full run).
make application-gate-tier-a # build product sln + CLI smoke (runs kernel-gate unless APPLICATION_GATE_SKIP_KERNEL=1)
make application-gate-tier-b # focused CLI tests + doctor --json
make application-gate-tier-c # in-process API WebApplicationFactory tests
make application-gate-tier-d # agent-server prod dry run (Docker)
make application-gate-full # A–D (skips re-running kernel by default)
APPLICATION_GATE_SKIP_TIER_D=1 make application-gate-full # skip Docker agent-server
APPLICATION_GATE_GAMEDOMAIN=1 make application-gate-tier-d # include GameDomain testsSee docs/production-readiness/ApplicationHardeningPlan-v1.md and docs/production-readiness/ApplicationReadiness-v1.md.
Pipeline composition (fan-out/fan-in, agentic stages) and async clustered mesh tasks:
make composition-mesh-gate-tier-a # pipeline validator/decomposer/orchestrator/lifecycle
make composition-mesh-gate-tier-b # CLI pipeline + mesh command suites
make composition-mesh-gate-tier-c # mesh fleet placement/execution (in-process)
make composition-mesh-gate-tier-d # Docker mesh lab with workers (schedule→placement)
make composition-mesh-gate-full
COMPOSITION_MESH_GATE_SKIP_TIER_D=1 make composition-mesh-gate-full # in-process only
COMPOSITION_MESH_GATE_STRESS=1 make composition-mesh-gate-full # workers + stress rampSee docs/production-readiness/CompositionMeshHardeningPlan-v1.md.
Production CLI flows, ci verify, release preflight, release bundle:
make ship-gate-full
SHIP_GATE_SKIP_TIER_B=1 make ship-gate-full # skip heavy ProdStyle ci verifySee docs/production-readiness/ShipHardeningPlan-v1.md.
Self-improvement dogfood blocks, optional mesh chaos, oh-shit demo:
make ops-gate-full
OPS_GATE_MESH_DEEP=1 make ops-gate-tier-d # mesh checkpoint/migrate E2E
make nexo-ready-gate # full stack
NEXO_READY_SKIP_DOCKER=1 make nexo-ready-gate # skip Docker tiers (~faster)See docs/production-readiness/OpsHardeningPlan-v1.md.
Trust boundary, API auth, mesh security, supply chain, air-gapped:
make security-gate-tier-a # trust core + audit + policy packs
make security-gate-tier-b # API security middleware
make security-gate-tier-c # trust CLI surfaces
make security-gate-tier-d # dotnet list package --vulnerable / --deprecated (artifacts in .nexo/security-gate/)
make security-gate-tier-e # air-gapped + safety
make security-gate-full
SECURITY_GATE_STRICT_SUPPLY_CHAIN=1 make security-gate-tier-d
SECURITY_GATE_AIRGAPPED_CONTAINER=1 make security-gate-tier-eSee docs/production-readiness/SecurityHardeningPlan-v1.md.
Prime-time (whole automated framework slice):
make test-prime-time # Category=ProdStyle across Nexo.PrimeTime.slnf (nine test projects)
make test-prime-time-full # ProdStyle gate then full slice excluding Category=ProdStyleFaster Infrastructure-only ProdStyle: make test-prod-style
Production-shaped containers (Linux dry run): make prod-dry-run or make prod-dry-run-agent-server — see docs/prod-dry-run.md (Compose + published API image, /health + /api/status).
Multi-node mesh (Docker bridge): make mesh-lab-e2e or make mesh-lab-e2e-workers — see docs/MeshVirtualLab.md (peer-a / peer-b / optional worker, scripted HTTP + mesh API checks). Deep checkpoint/migrate: make mesh-lab-verify-deep or MESH_LAB_VERIFY_DEEP=1 make mesh-lab-e2e-workers. Network failure modes: mesh-lab-verify-network-negative.sh (included in standard verify); see docs/MeshPhase11NetworkNegative.md.
Same checks via dotnet (optional): make test-mesh-lab or NEXO_RUN_MESH_LAB=1 dotnet test … --filter Category=MeshLab — runs MeshLabDockerE2ETests (Compose + mesh-lab-verify.sh / deep script). Skipped by default; set NEXO_MESH_LAB_SKIP_DEEP=1 for standard verify only.
Stress (workers scale + health bursts): make mesh-lab-e2e-stress locally (verify + deep + ramp + post-stress director checks); CI weekly via mesh-lab-stress-gate.yml (workflow_dispatch also available). See docs/MeshPhase10LabStressHardening.md.
Entitlements (CopilotScoped + hourly quota): included in make mesh-lab-verify when workers are up; standalone make mesh-lab-verify-entitlements (requires Nexo__Security__CopilotScopedApiKey in .env.mesh-lab).
nexo command note:
- Commands shown as
nexo ...assume the CLI tool is installed on your PATH. - If you have not installed the global tool, use the equivalent project invocation:
dotnet run --project application/src/Nexo.CLI -- <subcommand>
- Example:
nexo validatedotnet run --project application/src/Nexo.CLI -- validate
# Local (all tests, 30s blame-hang)
make test
# Or directly (add --blame-hang-dump-type none to avoid 6GB dumps on hangs)
dotnet test --blame-hang-timeout 30s --blame-hang-dump-type none
# nexo validate: high-signal check, but can fail in some host environments
# due to platform-specific test/runtime constraints.
# Prefer running after setup scripts and initial CLI smoke checks.
nexo validate
# equivalent:
dotnet run --project application/src/Nexo.CLI -- validate
# nexo dogfood: add --verbose to stream build/test output
nexo dogfood block2 --verbose
nexo dogfood all --verbose
# equivalent:
dotnet run --project application/src/Nexo.CLI -- dogfood block2 --verbose
dotnet run --project application/src/Nexo.CLI -- dogfood all --verbose
# Integration tests only
dotnet test src/Nexo.Tests.Infrastructure/Nexo.Tests.Infrastructure.csproj \
--filter "Category=Integration" --blame-hang-timeout 60s --blame-hang-dump-type none
# Adaptation tests only (local)
dotnet test src/Nexo.Tests.Infrastructure/Nexo.Tests.Infrastructure.csproj \
--filter "Category=Adaptation" --blame-hang-timeout 90s --blame-hang-dump-type none
# Adaptation tests across all Docker environments (linear)
make test-adaptation-all-envs
# Or: nexo test multi-env --suite adaptation --all
# equivalent:
dotnet run --project application/src/Nexo.CLI -- test multi-env --suite adaptation --all
# Cross-platform (CI)
make test-cross-platform SCOPE=integration
# Adaptation scope in CI
gh workflow run "Cross-Platform Tests" -f scope=adaptation
# Dogfood (North Star gates)
make dogfood-allThe routing stack (NCR local + peer network + RunPod cloud) has targeted smoke coverage in:
CapabilityRoutingBrickTestsPeerToPeerRoutingSmokeTests
Run them with:
# Peer smoke + stress scenarios (fallback, timeout, outage, burst concurrency)
dotnet test src/Nexo.Tests.Infrastructure/Nexo.Tests.Infrastructure.csproj \
-f net8.0 --filter "FullyQualifiedName~PeerToPeerRoutingSmokeTests"
# Routing regression (peer smoke + core capability router)
dotnet test src/Nexo.Tests.Infrastructure/Nexo.Tests.Infrastructure.csproj \
--filter "FullyQualifiedName~PeerToPeerRoutingSmokeTests|FullyQualifiedName~CapabilityRoutingBrickTests"What these stress tests simulate:
- concurrent burst traffic to peers
- intermittent HTTP failures and socket resets
- latency spikes that trigger per-peer timeout and failover
- recovery with success-rate thresholds under degraded network conditions
Note: src/Nexo.Tests.Infrastructure/scripts/copy-assemblies.cs is lock-tolerant for transient file-copy races during test builds (retry/backoff + safe lock skips when outputs already exist), so transient assembly lock contention should not surface as MSB3073 copy-script warnings.
Running multiple validation commands in parallel (e.g. from Cursor's integrated terminal) can cause severe memory pressure and freeze the machine. Each dotnet test run buffers output and spawns test hosts; running 5+ in parallel can exceed 100GB RAM.
Never run make ci-verify, nexo dogfood all, and multiple dotnet test commands in parallel from Cursor's integrated terminal.
Prefer:
- Run validation in an external terminal (iTerm, Terminal.app) or CI
- If using Cursor, run one command at a time and wait for completion before starting the next
Quick sanity check: make ci-verify alone (sequential: build → smoke → validate) is the minimal gate. Run it first; if it passes, consider running nexo dogfood all in a separate terminal.
Lightweight alternative: make validate-safe or bash scripts/validate-safe.sh — equivalent to ci-verify but via shell script; use when ci-verify causes high memory usage. Run dogfood separately: make dogfood-all.
Test projects use xunit.runner.json to limit parallelism and reduce memory usage:
- maxParallelThreads: 2 — limits concurrent test execution (default: CPU count)
- parallelAlgorithm: conservative — starts fewer tests at once, lower memory pressure
- parallelizeAssembly: false — prevents cross-assembly parallelism
To further reduce memory (e.g. on very constrained machines), set parallelizeTestCollections: false in xunit.runner.json to run all tests sequentially within each assembly.
Tests can leave artifacts that consume disk space:
| Artifact | Size | Location |
|---|---|---|
Hang dumps (.dmp) |
~6 GB each | src/*/TestResults/*/ |
| Sequence XML | ~88 KB | src/*/TestResults/*/ |
TRX results (.trx) |
~20 KB each | TestResults/, test-results/ |
Coverage (.coverage) |
varies | TestResults/ |
To prevent accumulation: Local make test and CLI use --blame-hang-dump-type none so hang dumps are not written.
To clean existing artifacts:
# Via CLI (programmatic)
nexo maintenance clean --strategy test-artifacts
# Or via Makefile
make clean-test-artifactsRemoves all TestResults/ dirs under src/ and the root test-results/ folder.
Procedural cleanup (before/after test runs): Set NEXO_CLEAN_BEFORE_TEST=1 or NEXO_CLEAN_AFTER_TEST=1 to run test-artifacts cleanup automatically when using nexo test local.
The full-platform-readiness-gate.yml workflow runs setup → discovery → dry-run on all target platforms:
- Native: Ubuntu, macOS, Windows (setup scripts, CLI build,
nexo doctor,nexo bootstrap check,ci verify, smoke tests) - Container: Ubuntu, Alpine, Debian (Docker test images with CLI + test projects pre-built)
- Docker CLI image: build from
Dockerfile.cli+ smoke + discover - SDK sample:
docs/samples/StableSdkHostSample/built as compatibility smoke check
Trigger manually: make test-readiness-gate or gh workflow run "Full Platform Readiness Gate" --ref <branch>. Most repo workflows are manual-first; see .github/workflows/README.md.
Three Docker test images are maintained under .docker/:
| Image | Base | Purpose |
|---|---|---|
Dockerfile.test-caching |
Ubuntu + .NET 9 SDK | Framework, trust, and smoke tests |
Dockerfile.test-caching-alpine |
Alpine + .NET 9 SDK | Alpine-specific portability tests |
Dockerfile.test-caching-debian |
Debian + .NET 9 SDK | Debian-specific portability tests |
All three include the .NET 8 runtime (for CLI net8.0 target) and pre-build test projects + CLI during image build.
E2E tests are tagged with [Trait("Category", "E2E")] and must have explicit [Fact(Timeout = N)] (enforced by TimeoutConventionTests).
Key E2E test files:
| File | Tests | Coverage |
|---|---|---|
StrictModeE2ETests |
8 | Strict mode flags, DI, config fail-fast |
NexoDefaultsTests |
13 | Golden tests for all centralized constants |
ConfigurationAdapterEdgeCaseTests |
8 | NEXO_CONFIG_PATH, malformed JSON, strict/permissive |
ProviderFactoryEdgeCaseTests |
11 | Provider selection, mock gating, concurrency |
PipelineLifecycleE2ETests |
9 | Pipeline lifecycle, resume, fan-in, concurrency |
HostingDeploymentProfileTests |
10 | All deployment profiles, env var resolution |
BackgroundAgentLifecycleE2ETests |
10 | Mode transitions, approval gates, audit bounds |
HostingE2ESmokeTests |
8 | AddNexo kernel resolution, validation, observation |