Skip to content

Testing and Benchmarking

github-actions[bot] edited this page Aug 5, 2026 · 4 revisions

Testing and Benchmarking

This page explains how GridForge validates behavior and performance.

The short version is:

  • use the xUnit suite to protect correctness
  • use the benchmark project when changing performance-sensitive or allocation-sensitive code
  • treat GridWorld boundaries as part of the validation story

The Two Validation Tracks

Track Project Best for
Tests tests/GridForge.Tests Behavioral correctness, regressions, edge cases, and event semantics
Benchmarks tests/GridForge.Benchmarks Allocation trends, warm-vs-cold pool effects, and throughput-sensitive changes

Test Harness Shape

The test suite uses xUnit v3 and a shared collection fixture:

  • GridForgeFixture sets GridForgeLogger.MinimumLevel to Error
  • GridForgeFixture does not create a runtime world
  • [Collection("GridForgeCollection")] is used where tests share the fixture-managed logger configuration

New tests should prefer explicit GridWorld creation. The test project includes helpers such as GridWorldTestFactory to keep that setup small and consistent.

What The Tests Cover

The test folders mirror the main subsystem boundaries:

  • tests/GridForge.Tests/Grids covers world behavior, manager behavior, voxel/grid state, scan cells, and neighbor logic
  • tests/GridForge.Tests/Blockers covers blocker application, stacking, removal, and reapply behavior
  • tests/GridForge.Tests/Diagnostics covers diagnostic contracts, geometry, physical queries, and dirty sessions
  • tests/GridForge.Tests/Utility covers tracing and logging
  • tests/GridForge.Tests/Spatial covers index and provider semantics

Isolation coverage includes:

  • multiple worlds loaded simultaneously with overlapping local coordinates
  • stale identity rejection after world teardown
  • blockers, occupants, tracing, and scans staying inside their owning world

Sparse storage coverage includes:

  • dense storage behavior after storage extraction
  • sparse construction from configured indices and masks
  • sparse hex construction from topology-local axial (q, layer, r) indices
  • missing in-bounds sparse voxel lookup
  • storage-neutral tracing, blockers, occupants, partitions, scans, and neighbor lookup
  • explicit runtime sparse voxel add/remove safety rules

Hex-prism topology coverage includes:

  • flat-top and pointy-top projection and inverse projection
  • exact cube-coordinate rounding at hex boundaries
  • mixed rectangular/hex world lookup
  • unified voxel contact queries across source-grid, same-topology, and mixed-topology scopes
  • exact topology-specific directed neighbor overloads for rectangular and hex grids
  • mixed-topology voxel contact queries for pointy-top and flat-top hex grids
  • hex line tracing and conservative bounds coverage
  • hex blocker apply/remove behavior
  • hex occupant registration and radius scans
  • sparse hex tracing, scan-cell coverage, blockers, occupants, scans, and runtime mutation

Standard Test Commands

dotnet restore GridForge.slnx
dotnet build GridForge.slnx --configuration Debug
dotnet test GridForge.slnx --configuration Debug --no-build

Coverage Notes

dotnet test tests/GridForge.Tests/GridForge.Tests.csproj --configuration Release --collect:"XPlat Code Coverage" --settings tests/GridForge.Tests/coverlet.runsettings --results-directory artifacts/coverage

The main-branch coverage workflow enforces full line, branch, and method coverage and publishes the report at GridForge coverage.

Test Design Expectations

Good GridForge tests usually:

  • create their own GridWorld
  • use deterministic positions and explicit expectations
  • assert exact snapped values instead of fuzzy tolerances
  • dispose or reset the world when the scenario finishes

Benchmark Runner Basics

dotnet run --project tests/GridForge.Benchmarks/GridForge.Benchmarks.csproj -c Release -f net8.0 -- list
dotnet run --project tests/GridForge.Benchmarks/GridForge.Benchmarks.csproj -c Release -f net8.0 -- all
dotnet run --project tests/GridForge.Benchmarks/GridForge.Benchmarks.csproj -c Release -f net8.0 -- sparse-voxel-grid --filter '*SparseVoxelGridBenchmarks*'
dotnet run --project tests/GridForge.Benchmarks/GridForge.Benchmarks.csproj -c Release -f net8.0 -- hex-prism-topology --filter '*HexPrismTopologyBenchmarks*'
dotnet run --project tests/GridForge.Benchmarks/GridForge.Benchmarks.csproj -c Release -f net8.0 -- grid-diagnostics --filter '*GridDiagnosticsBenchmarks*'
dotnet run --project tests/GridForge.Benchmarks/GridForge.Benchmarks.csproj -c Release -f net8.0 -- neighbor-lookup --filter '*NeighborLookupBenchmarks*'
dotnet run --project tests/GridForge.Benchmarks/GridForge.Benchmarks.csproj -c Release -f net8.0 -- grid-spatial-index --filter '*GridSpatialIndex*'

The sparse-voxel-grid alias covers sparse construction density, configured and missing lookup, empty and clustered coverage, blocker apply/remove, occupant registration, radius scans, neighbor lookup, and dense comparison scenarios.

The hex-prism-topology alias covers rectangular baseline lookup, pointy/flat hex lookup, projection, construction, line tracing, bounds coverage, blockers, occupants, radius scans, and mixed rectangular/hex world lookup.

The grid-diagnostics alias covers dense and sparse rectangular physical queries, dense and sparse hex physical queries, bounded sparse missing-address queries, and GetCellsInto versus VisitCells traversal paths. See Grid Diagnostics and Geometry for the API surface those benchmarks protect.

The neighbor-lookup alias covers stateless directed boundary lookup plus the unified neighbor resolver matrix: source-grid contacts, same-topology conjoined contacts, no mixed candidates nearby, pointy-top and flat-top mixed contacts, many nearby candidate grids, sparse targets with mostly missing candidate cells, and rectangular/hex direction-labeled caller-owned result paths.

The grid-spatial-index alias covers threshold selection, grid-footprint scaling, mixed ordinary/oversized lookup, and many-oversized-grid scaling. For matched evidence, build once and run the compiled Release/net8.0 benchmark DLL with the same aliases and filters, changing only --artifacts between the baseline, after, and confirmation roots.

Benchmark Environment Behavior

BenchmarkEnvironment:

  • suppresses logging by setting GridForgeLogger.MinimumLevel to None
  • creates or resets an explicit GridWorld between iterations
  • optionally clears GridForge and shared SwiftCollections pools
  • configures the world with the benchmark's requested voxel and ordinary-lookup settings

Clone this wiki locally