TEST MATRIX
Chimera test matrix
Use this matrix as the acceptance suite for Chimera personas. Sections 1–74 focus on Transiva's vSphere provider; sections 75–87 cover Nutanix and Hyper-V; sections 88–98 cover AWS and Azure protocol personas.
Authentication and session¶
- Valid username/password logs in.
- Wrong password returns
InvalidLogin. - Empty username is rejected.
- Empty password is rejected.
- Session cookie is reused across property calls.
- Logout invalidates the session.
- A request without a session to a protected VIM method returns
NotAuthenticated. - Multiple concurrent Transiva clients can log in independently.
Discovery and inventory¶
- Default datacenter discovery succeeds.
- Datacenter wildcard list returns all seeded datacenters.
- VM wildcard list returns all seeded VMs.
- Exact VM name lookup succeeds.
- Full inventory path lookup succeeds.
- Missing VM lookup returns a non-retryable not-found condition.
- 100-VM inventory remains responsive.
- 500-VM inventory can be used as a scale/latency test.
- Powered-on and powered-off VM metadata can be queried.
- Datastore and host references resolve through the property collector.
OVF and export lease¶
OvfManager.CreateDescriptorreturns a descriptor, including when called on a real authenticated session beforeVirtualMachine.Export(Transiva's actual sequence) —integration/chimera_test.go'sTestCreateDescriptorThenExportVm.VirtualMachine.Exportreturns an HTTP NFC lease.- Lease is observable in ready state through the property collector.
- Lease contains at least one downloadable item.
- Lease download URL is rewritten to the public Chimera endpoint.
- Lease completion succeeds after download.
- Lease abort succeeds when the client cancels.
- Two VM exports can run concurrently.
NFC transfer¶
- Full GET returns the complete fixture stream.
- Parallel GETs work.
Range: bytes=0-returns HTTP 206.Range: bytes=N-returns data beginning at offset N.- Invalid ranges return HTTP 416.
- Bandwidth limiting slows a download deterministically.
- A one-shot configured connection drop interrupts exactly the selected stream.
- Retry after an injected NFC 503 succeeds.
- A partial local file can be resumed with a correct Content-Range and without duplicated bytes.
Retry/failure behavior¶
- Inject one SOAP 503 and verify retry.
- Inject two SOAP 503 responses and verify backoff.
- Inject more failures than
retry_attemptsand verify terminal failure. - Add 750 ms latency and verify timeout handling.
- Combine latency and 503 faults.
- Clear the scenario and verify the next run is clean.
Transiva-specific regression¶
NewVSphereClientconnects using the generated Transiva config.find.Finder.DefaultDatacenterworks.finder.VirtualMachineresolvesDC0_C0_RP0_VM0.ExportOVFwrites the OVF descriptor.downloadFilesParalleldownloads all lease items.- Existing partial file causes a Range request.
- Checkpoint save/restore resumes the file.
- HTTP 403/404 remains non-retryable.
- Successful export calls lease Complete and removes its checkpoint.
Commands¶
make run
./bin/chimera selftest -url http://127.0.0.1:8989/sdk -user administrator@vsphere.local -pass vmware
go test ./integration/ -run 'Persona|AWS|Azure'
./scripts/scenario.sh flaky
./scripts/scenario.sh resume
./scripts/scenario.sh clean
Fixture modes¶
- Generated transport fixture is deterministic and has the configured byte size.
- Supplied real VMDK (
fixture_vmdk, single-file mode) is served read-only through the lease alias. - Multiple leases can reference the same single-file real fixture independently (
fixture_vmdkmode only). - Completing/aborting a lease removes only that lease mapping.
- Conversion pipeline is run only with a valid VMDK fixture.
Directory-matched fixtures (fixture_vmdk_dir)¶
- A directory file whose sanitized basename matches a VM's sanitized name is assigned to that VM (
name-match). - Leftover files and leftover VMs are paired off in sorted order (
round-robin). - A VM with no directory-mode match still gets the existing generated synthetic fixture, unchanged.
- Setting
fixture_vmdkandfixture_vmdk_dirtogether is rejected at config validation. - Non-
.vmdkfiles in the configured directory are ignored. /__chimera/api/inventoryVM entries reflect the real simulator model's names/power states — the same namesExportVmoperates on — not a fabricated count./__chimera/api/vmdkslists every.vmdkfile in the configured directory with its assignment method, including files that matched no VM.- A real fixture image fetched via
make fixturesround-trips throughqemu-img infoas a valid disk image, confirmed viascripts/verify-real-fixture.sh(downloads the complete export viachimera selftest -vm <name> -save <path>, not just the default 4KB probe). fixture_vmdk_diris re-scanned automatically (every 5s) — a VMDK added after startup is picked up and assigned without restarting the server.- Scanning recurses into subdirectories; name-match keys off the file's own basename, not its full relative path, so nesting doesn't break matching.
fixture_vmdk_dirs(additional read-only roots) are scanned and matched the same way asfixture_vmdk_dir; browser uploads always land only in the primary directory.- A file with the same relative name in two different fixture roots doesn't collide — override keys are unique per root.
SetOverride/ClearOverride(manual assignment) take priority over name-match/round-robin, are reported as methodmanual, and reject an unknown VM name.
Dashboard upload/browse/assign and login (internal/gateway)¶
- Unauthenticated
POST /__chimera/api/vmdks/uploadis rejected (401); a valid upload with an explicitvm_namelands on disk and is reportedmanual; a non-.vmdkfilename is rejected (400). GET /__chimera/api/vmdks/browselists files/subdirectories under a configured fixture root; a..-path-traversal attempt is rejected (400) — the browser can never reveal a path outside the configured roots, even via a symlink.POST /__chimera/api/vmdks/assignpins a file already on disk to a VM without re-uploading it, and is rejected unauthenticated.POST /__chimera/loginaccepts the configured username/password (defaultadmin/admin) and returns the same bearer token every other protected endpoint expects; wrong credentials return 401.POST /__chimera/admin/credentials(authenticated) changes the live admin login; the old credentials then fail/loginand the new ones succeed. Unauthenticated calls are rejected.GET /redirects (302) to/__chimera/.
Nutanix Prism persona (CHIMERA_PERSONA=nutanix)¶
- Basic auth rejects missing/wrong credentials with 401 +
WWW-Authenticate. GET /api/nutanix/v3/clusterreturns cluster identity.POST /api/nutanix/v3/vms/listreturns seeded VM entities (vms_per_pool).GET /api/nutanix/v3/vms/{id}returns VM detail with disk list.POST /api/nutanix/v3/vms/{id}/set_power_statecreates a task and updates power state.GET /api/nutanix/v3/tasks/{id}returns task status.GET /api/nutanix/v3/vms/{id}/disks/{disk}/datareturns deterministic export bytes.- Covered by
integration/personas_e2e_test.go(TestNutanixDiscoveryPowerAndDiskExportE2E).
Hyper-V WS-Man persona (CHIMERA_PERSONA=hyperv)¶
- Basic auth rejects missing/wrong credentials with 401.
- WS-Man Identify returns Chimera product identity.
- Enumerate returns an enumeration context; Pull returns
Msvm_ComputerSysteminventory. RequestStateChangereturns asyncReturnValue4096 and updates VM power.- Covered by
integration/personas_e2e_test.go(TestHyperVWSManIdentifyEnumeratePullAndPowerE2E).
AWS EC2/EBS persona (CHIMERA_PERSONA=aws)¶
- SigV4 rejects missing/wrong credentials with
AuthFailure. DescribeInstancesreturns seeded instances and attached volumes.StartInstances/StopInstancestransition instance state.CreateSnapshotreturns asnap-chimera*id;DescribeSnapshotslists it.GET /snapshots/{id}/blocksreturns block index/token list with 512 KiB block size.GET /snapshots/{id}/blocks/{index}returns deterministic block bytes with SHA256 checksum headers.- Covered by
integration/cloud_personas_e2e_test.go(TestAWSEC2DiscoveryPowerSnapshotAndBlockExportE2E).
Azure ARM persona (CHIMERA_PERSONA=azure)¶
- Bearer auth rejects missing/wrong tokens; subscription mismatch returns not found.
- VM list/get/instanceView and
start/powerOffwithAzure-AsyncOperationpolling. beginGetAccessyields SAS URL; ranged GET returns 206 PageBlob bytes.- Covered by
integration/cloud_personas_e2e_test.go(TestAzureARMDiscoveryPowerAndManagedDiskAccessE2E).