Files
spinifex/tests/integration/volume_daemon_lite.go
T
joshsiv-mulga f17e93aedf refactor: split the Viperblock EBS adapter out of services/viperblockd
Move the EBS provider adapter (volume lease, fence, dirty marker,
nbdkit recovery, provider handlers, encryption key loading) to
providers/ebs/viperblock. services/viperblockd keeps only process
lifecycle and the NATS subscription wiring that starts and stops it.

The dirty-bucket read path moves to providers/ebs/viperblock/dirty as
a read-only ListUnsealedVolumes capability; the adapter's write, clear
and purge logic stays unexported in the adapter package. Delete
services/viperblockd/vbwire now that its vocabulary lives in
contracts/viperblockd/legacy/v1 and its I/O helpers live in dirty.

Update operator/cli, the runtime service registry, qemunbdd's config
comment and the integration test harness to the new import paths, and
drop the now-stale architecture/layering allowlist and frozen-package
entries for the deleted package. Behaviour, persisted keys and NATS
subjects are unchanged.
2026-10-09 15:52:29 +10:00

94 lines
3.8 KiB
Go

//go:build integration
package integration
import (
"context"
"testing"
"time"
"github.com/mulgadc/spinifex/spinifex/bootstrap/config"
ec2volume "github.com/mulgadc/spinifex/spinifex/domains/ec2/volume"
"github.com/mulgadc/spinifex/spinifex/providers/ebs"
"github.com/mulgadc/spinifex/spinifex/providers/ebs/viperblock"
"github.com/mulgadc/spinifex/spinifex/providers/objectstore"
testpredastore "github.com/mulgadc/spinifex/tests/fixtures/predastore"
"github.com/stretchr/testify/require"
)
// testVolumeBucket is the real predastore bucket StartVolumeDaemonLite's
// VolumeServiceImpl is wired against. Unlike testPredastoreBucket
// (memory-backed, name never resolved — see StartDaemonLite), this bucket
// genuinely exists on the shared predastore fixture: viperblock's S3 backend
// dials it for real, so chunk uploads and config.json persistence are real.
const testVolumeBucket = "integration-test-volumes"
// testProviderNodeName names the node the in-process provider answers as. Only
// publish and unpublish are node-addressed, and nothing here publishes, but an
// empty name makes the provider log a warning about attachments it cannot serve.
const testProviderNodeName = "integration-node"
// providerRequestTimeout bounds a control-plane call to the provider. Generous
// because the first CreateVolume pays the real predastore's cold start.
const providerRequestTimeout = 60 * time.Second
// StartVolumeDaemonLite subscribes a real ec2volume.VolumeServiceImpl
// — the same production code a live daemon runs (daemon/daemon_handlers_volume.go)
// — to its ec2.* subjects, backed by a
// real predastore daemon (testpredastore.Start) rather than the memory-backed
// stores DaemonLite's other resources use.
//
// This is deliberately a separate opt-in wiring rather than part of
// StartDaemonLite: CreateVolume constructs viperblock.New and calls
// Backend.Init() unconditionally (domains/ec2/volume/service_impl.go), so it
// needs a reachable Predastore to do anything beyond input validation, while
// every other DaemonLite-wired resource is happy with an in-memory stand-in.
// Only a test that actually exercises volume storage should pay the shared
// predastore daemon's startup cost.
//
// Must be called before a test issues a volume request; like
// StartECRDaemonLite it wires its own subjects independent of StartDaemonLite.
func StartVolumeDaemonLite(t *testing.T, gw *Gateway) *ec2volume.VolumeServiceImpl {
t.Helper()
fixture := testpredastore.Start(t)
store := objectstore.NewS3ObjectStoreFromConfig(fixture.Host, fixture.Region, fixture.AccessKey, fixture.SecretKey)
require.NoError(t, store.EnsureBucket(context.Background(), testVolumeBucket), "ensure volume test bucket")
cfg := &config.Config{
AZ: testAZ,
Predastore: config.PredastoreConfig{
Host: fixture.Host,
Bucket: testVolumeBucket,
Region: fixture.Region,
AccessKey: fixture.AccessKey,
SecretKey: fixture.SecretKey,
},
// Real WAL/chunk files land here (viperblock.VB.BaseDir); a per-test
// dir is safe since only the predastore daemon itself is shared.
WalDir: t.TempDir(),
}
nc := gw.NATSConn
svc := ec2volume.NewVolumeServiceImplWithStore(cfg, store, nc)
// The control plane no longer builds volumes itself; it asks a provider.
// Serve the provider contract from viperblockd against the same fixture,
// so the blocks are still written by real viperblock to real predastore.
require.NoError(t, viperblock.RegisterProviderSubjects(&viperblock.Config{
S3Host: "https://" + fixture.Host,
Bucket: testVolumeBucket,
Region: fixture.Region,
AccessKey: fixture.AccessKey,
SecretKey: fixture.SecretKey,
BaseDir: cfg.WalDir,
NodeName: testProviderNodeName,
}, nc), "register provider subjects")
svc.SetEBSProvider(ebsprovider.NewNATSProvider(nc, providerRequestTimeout))
subscribeServiceMethods(t, nc, "ec2", svc)
return svc
}