magicciv/infra/terraform/test-fleet/tests/fleet.tftest.hcl
Natalie f5c5d1a410 feat(infra): distributed test/train fleet on DigitalOcean (Terraform + Packer + dispatch)
Ephemeral CPU Droplet fleet that horizontally scales the iteration loop:
- infra/terraform/test-fleet: cattle Droplets from a golden image (auto-discovered
  by name via digitalocean_images), grouped under the mc:dev DO project, with a
  mocked-provider test suite (no token/spend).
- infra/packer: golden-image builder reusing scripts/dev-setup/linux.sh.
- scripts/run/dist.sh: ./run dist:{check,up,sim,train,down} — shard sim/test
  batches across workers via autoplay-batch AUTOPLAY_HOST+SEED_OFFSET.
GPU intentionally absent (workload is CPU-bound per docs/ai-production.md).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 08:51:09 -04:00

88 lines
2.3 KiB
HCL

# No-spend test harness for the fleet module.
# terraform test (from the module dir)
# Uses a MOCKED digitalocean provider — no API token, no API calls, no Droplets,
# no cost. Exercises count expansion, the golden-image branch toggle, and the
# workers guardrail.
mock_provider "digitalocean" {
# The golden-image data source is computed; give it a non-empty result so the
# base_image == "" branch (images[0].id) resolves under mocking.
mock_data "digitalocean_images" {
defaults = {
images = [{ id = 123456789 }]
}
}
}
variables {
do_token = "mock-token-unused"
git_remote = "https://example.com/magic-civilization.git"
ssh_public_key_path = "./tests/fixtures/id_test.pub"
}
# base_image set -> golden data source is skipped (count 0); fleet expands to N.
run "fleet_expands_and_skips_golden_when_base_image_set" {
command = plan
variables {
workers = 3
base_image = "ubuntu-24-04-x64"
}
assert {
condition = length(digitalocean_droplet.worker) == 3
error_message = "expected 3 workers when workers=3"
}
assert {
condition = length(data.digitalocean_images.golden) == 0
error_message = "golden data source must be skipped when base_image is set"
}
}
# base_image empty -> golden image is resolved via the name-substring filter.
run "golden_image_branch_active_when_base_image_empty" {
command = plan
variables {
workers = 2
base_image = ""
}
assert {
condition = length(data.digitalocean_images.golden) == 1
error_message = "golden data source must be queried when base_image is empty"
}
assert {
condition = length(digitalocean_droplet.worker) == 2
error_message = "expected 2 workers when workers=2"
}
}
# workers = 0 -> zero Droplets (idle / torn-down state).
run "zero_workers_is_empty_fleet" {
command = plan
variables {
workers = 0
base_image = "ubuntu-24-04-x64"
}
assert {
condition = length(digitalocean_droplet.worker) == 0
error_message = "workers=0 must produce no Droplets"
}
}
# The validation guardrail rejects an oversize fleet — proven without provisioning.
run "rejects_oversize_fleet" {
command = plan
variables {
workers = 99
base_image = "ubuntu-24-04-x64"
}
expect_failures = [var.workers]
}