Files
spinifex/tests/e2e/single/createimage_test.go
T
joshsiv-mulga 162d840cf1 test(e2e-single): port run-e2e.sh phases 5-5e to Go
Stage C of mulga-siv-89 — the instance/volume/snapshot/image lifecycle
that everything else hangs off:

- Phase 5: run-instances (default VPC + default SG with tcp/22 opened
  via idempotent harness.AuthorizeSSHIngress), wait running, resolve
  root volume from BlockDeviceMappings.
- Phase 5a-pre: spx get vms now contains the running instance.
- Phase 5a: describe-instances metadata round-trip (type/key/AMI/BDMs).
- Phase 5a-ii: TCP wait, ssh id, lsblk cross-check vs API root volume
  size (±1 GiB tolerance — lsblk rounds down), soft hostname check.
- Phase 5a-iii: get-console-output round-trip on InstanceId.
- Phase 5b: create-volume (10 GiB) → modify-volume (20 GiB) →
  attach-volume → detach-volume → delete-volume, polling each state
  transition through harness.WaitForVolumeState.
- Phase 5b-ii: describe-volume-status on the root volume.
- Phase 5c: create-snapshot → wait completed → copy-snapshot → both
  visible → delete original → copy survives → delete copy.
- Phase 5d: AMI snapshot-backed launch verification via
  DescribeImages.BlockDeviceMappings[].Ebs.SnapshotId. Predastore-side
  config.json reads are TODO (no S3 client in harness yet).
- Phase 5e: create-image --no-reboot, wait available, capture backing
  snapshot ID for Phase 9 cleanup.

Phase 7a (attach to stopped → error) stubbed in volume_test.go for
Stage D to fill once the lifecycle stop/start lands.
2026-05-18 20:31:27 +10:00

75 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//go:build e2e
package single
import (
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/mulgadc/spinifex/tests/e2e/harness"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// phase5e_CreateImage builds a custom AMI from the running instance and
// records the backing snapshot ID so Phase 9 cleanup can delete the
// snapshot before terminating the instance (otherwise DeleteOnTermination
// trips over the still-referenced snapshot). Maps to run-e2e.sh ~805–844.
func phase5e_CreateImage(t *testing.T, fix *Fixture) {
harness.Phase(t, "Phase 5e — CreateImage Lifecycle")
require.NotEmpty(t, fix.InstanceID, "Phase 5 must populate fix.InstanceID")
const customName = "e2e-custom-ami"
const customDesc = "E2E test custom image"
harness.Step(t, "create-image instance=%s name=%s (no-reboot)", fix.InstanceID, customName)
create, err := fix.AWS.EC2.CreateImage(&ec2.CreateImageInput{
InstanceId: aws.String(fix.InstanceID),
Name: aws.String(customName),
Description: aws.String(customDesc),
NoReboot: aws.Bool(true),
})
require.NoError(t, err, "create-image")
fix.CustomAMIID = aws.StringValue(create.ImageId)
require.NotEmpty(t, fix.CustomAMIID, "create-image returned empty ImageId")
harness.Detail(t, "custom_ami", fix.CustomAMIID)
harness.WaitForImageState(t, fix.AWS, fix.CustomAMIID, "available")
harness.Step(t, "describe-images %s", fix.CustomAMIID)
out, err := fix.AWS.EC2.DescribeImages(&ec2.DescribeImagesInput{
ImageIds: []*string{aws.String(fix.CustomAMIID)},
})
require.NoError(t, err, "describe-images %s", fix.CustomAMIID)
require.NotEmpty(t, out.Images, "no image for %s", fix.CustomAMIID)
img := out.Images[0]
assert.Equal(t, customName, aws.StringValue(img.Name), "custom AMI Name mismatch")
assert.Equal(t, "available", aws.StringValue(img.State), "custom AMI State should be available")
// Capture the backing snapshot — needed by Phase 9 cleanup (Stage G).
for _, bdm := range img.BlockDeviceMappings {
if bdm.Ebs == nil {
continue
}
if id := aws.StringValue(bdm.Ebs.SnapshotId); id != "" {
fix.CustomAMISnapID = id
break
}
}
if fix.CustomAMISnapID == "" {
// Bash treats this as a non-fatal warning — replicate so a transient
// CreateImage path that omits the snapshot ref doesn't fail the suite.
t.Logf("WARNING: custom AMI %s has no backing snapshot ID — Stage G cleanup may be incomplete",
fix.CustomAMIID)
} else {
harness.Detail(t, "custom_ami_snapshot", fix.CustomAMISnapID)
}
// TODO(stage-?): bash mentions verifying the predastore-side snapshot
// config exists for the custom AMI. The actual bash doesn't do that —
// the EC2 API check above is the sole assertion. Wire up an S3 client
// in the harness if we ever want to enforce the predastore-side state.
}