mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-19 10:52:04 +00:00
test(integration): migrate DescribeImages round-trip off live guests
runImage's AMI describe round-trip needs no real cluster: it registers an AMI against a hand-seeded snapshot via the real ImageServiceImpl, backed by a new StartImageDaemonLite helper wiring RegisterImage/DescribeImages onto an in-memory object store.
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
//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/require"
|
||||
)
|
||||
|
||||
// runImage rediscovers the architecture-appropriate Ubuntu AMI that
|
||||
// bootstrap-install.sh imported from the pre-staged gold-image file
|
||||
// (~/images/ubuntu-{26,24}.04.img → `spx admin images import --file`) and
|
||||
// stashes the ID on the fixture for Phase 5+. Maps to run-e2e.sh ~233–255.
|
||||
func runImage(t *testing.T, fix *Fixture) {
|
||||
harness.Phase(t, "Single — Image Management")
|
||||
|
||||
// Resolve the gold-image AMI via the cluster discovery helper. The first
|
||||
// caller pays the DescribeImages + state-poll cost; this and every other
|
||||
// AMI consumer hit the memoized ID.
|
||||
amiID := needAMI(t, fix)
|
||||
require.NotEmpty(t, amiID, "needAMI returned empty AMI ID")
|
||||
_, arch := needInstanceTypeArch(t, fix)
|
||||
harness.Detail(t, "ami", amiID, "arch", arch)
|
||||
|
||||
harness.Step(t, "describe-images by AMI ID (verify round-trip)")
|
||||
byID, err := fix.AWS.EC2.DescribeImages(&ec2.DescribeImagesInput{
|
||||
ImageIds: []*string{aws.String(amiID)},
|
||||
})
|
||||
require.NoErrorf(t, err, "describe-images %s", amiID)
|
||||
require.Lenf(t, byID.Images, 1, "expected exactly 1 image for %s, got %d", amiID, len(byID.Images))
|
||||
require.Equal(t, amiID, aws.StringValue(byID.Images[0].ImageId), "round-trip AMI ID mismatch")
|
||||
require.NotEmpty(t, aws.StringValue(byID.Images[0].Name), "lookup-by-ID returned empty Name")
|
||||
}
|
||||
@@ -25,11 +25,6 @@ func TestDiscovery(t *testing.T) {
|
||||
runDiscovery(t, requireSingleNodeFixture(t))
|
||||
}
|
||||
|
||||
func TestImage(t *testing.T) {
|
||||
t.Parallel()
|
||||
runImage(t, requireSingleNodeFixture(t))
|
||||
}
|
||||
|
||||
func TestAccountScoping(t *testing.T) {
|
||||
t.Parallel()
|
||||
runAccountScoping(t, requireSingleNodeFixture(t))
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
//go:build integration
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
handlers_ec2_image "github.com/mulgadc/spinifex/spinifex/handlers/ec2/image"
|
||||
"github.com/mulgadc/spinifex/spinifex/objectstore"
|
||||
"github.com/nats-io/nats.go"
|
||||
)
|
||||
|
||||
// testImageBucket is the bucket name StartImageDaemonLite's ImageServiceImpl
|
||||
// stores AMI config.json objects under. Backed by a MemoryObjectStore (see
|
||||
// below), so — like testPredastoreBucket in daemon_lite.go — the name is
|
||||
// never resolved against a real Predastore.
|
||||
const testImageBucket = "integration-test-images"
|
||||
|
||||
// StartImageDaemonLite subscribes a real handlers_ec2_image.ImageServiceImpl
|
||||
// — the same production code a live daemon runs (daemon/daemon_handlers_image.go)
|
||||
// — to the ec2.DescribeImages/ec2.RegisterImage subjects, backed by a memory
|
||||
// object store rather than a real Predastore. The store itself is returned
|
||||
// too, so a test can seed fixture data (e.g. snapshot metadata RegisterImage
|
||||
// requires) directly, without a round-trip through NATS.
|
||||
//
|
||||
// Deliberately separate from StartDaemonLite (like StartVolumeDaemonLite):
|
||||
// only a test that actually exercises image registration/lookup should wire
|
||||
// it. CreateImage/CopyImage/DeregisterImage/*ImageAttribute are not wired —
|
||||
// no ported test needs them yet.
|
||||
func StartImageDaemonLite(t *testing.T, gw *Gateway) (*handlers_ec2_image.ImageServiceImpl, objectstore.ObjectStore) {
|
||||
t.Helper()
|
||||
|
||||
store := objectstore.NewMemoryObjectStore()
|
||||
svc := handlers_ec2_image.NewImageServiceImplWithStore(store, testImageBucket)
|
||||
|
||||
nc := gw.NATSConn
|
||||
sub(t, nc, "ec2.DescribeImages", func(m *nats.Msg) { dispatch(m, svc.DescribeImages) })
|
||||
sub(t, nc, "ec2.RegisterImage", func(m *nats.Msg) { dispatch(m, svc.RegisterImage) })
|
||||
|
||||
return svc, store
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
//go:build integration
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
handlers_ec2_snapshot "github.com/mulgadc/spinifex/spinifex/handlers/ec2/snapshot"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestImage ports tests/e2e/single/image_test.go's runImage describe-images
|
||||
// round-trip. The live test resolved a pre-staged gold-image AMI via
|
||||
// needAMI (bootstrap-install.sh's `spx admin images import`); this tier has
|
||||
// no such bootstrap, so it registers its own AMI against a hand-seeded
|
||||
// snapshot via the real RegisterImage path instead — same production
|
||||
// ImageServiceImpl.DescribeImages contract, without depending on a live
|
||||
// cluster's pre-imported gold image.
|
||||
func TestImage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
gw := StartGateway(t)
|
||||
_, store := StartImageDaemonLite(t, gw)
|
||||
ec2Cli := gw.EC2Client(t)
|
||||
|
||||
const snapshotID = "snap-integration-test-image"
|
||||
require.NoError(t, handlers_ec2_snapshot.WriteSnapshotConfig(store, testImageBucket, snapshotID, &handlers_ec2_snapshot.SnapshotConfig{
|
||||
SnapshotID: snapshotID,
|
||||
VolumeID: "vol-integration-test-image",
|
||||
VolumeSize: 8,
|
||||
State: "completed",
|
||||
OwnerID: gw.AccountID,
|
||||
}), "seed snapshot metadata")
|
||||
|
||||
registerOut, err := ec2Cli.RegisterImage(&ec2.RegisterImageInput{
|
||||
Name: aws.String("integration-test-ami"),
|
||||
RootDeviceName: aws.String("/dev/sda1"),
|
||||
BlockDeviceMappings: []*ec2.BlockDeviceMapping{{
|
||||
DeviceName: aws.String("/dev/sda1"),
|
||||
Ebs: &ec2.EbsBlockDevice{SnapshotId: aws.String(snapshotID)},
|
||||
}},
|
||||
})
|
||||
require.NoError(t, err, "register-image")
|
||||
amiID := aws.StringValue(registerOut.ImageId)
|
||||
require.NotEmpty(t, amiID, "register-image returned empty ImageId")
|
||||
|
||||
byID, err := ec2Cli.DescribeImages(&ec2.DescribeImagesInput{
|
||||
ImageIds: []*string{aws.String(amiID)},
|
||||
})
|
||||
require.NoErrorf(t, err, "describe-images %s", amiID)
|
||||
require.Lenf(t, byID.Images, 1, "expected exactly 1 image for %s, got %d", amiID, len(byID.Images))
|
||||
require.Equal(t, amiID, aws.StringValue(byID.Images[0].ImageId), "round-trip AMI ID mismatch")
|
||||
require.NotEmpty(t, aws.StringValue(byID.Images[0].Name), "lookup-by-ID returned empty Name")
|
||||
}
|
||||
Reference in New Issue
Block a user