mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
f9858d4e5d
* test(e2e): add ECR end-to-end suite (control plane + docker/crane/skopeo) New tests/e2e/ecr/ suite plus harness support: - harness: ECR SDK client, control-plane helpers (repo CRUD, get-login-password, describe-images), and docker/crane/skopeo CLI wrappers that skip when the binary or registry-host resolution is absent. - suite: control-plane CRUD + policy + lifecycle round-trip; docker login/push/ pull; crane append/pull and skopeo copy exercising the Bearer /v2/token flow. - registered e2e-ecr in the Makefile + service manifest. Predastore capacity/load leg is a skipped placeholder pending mulga-siv-359/356. * test(e2e): carry awsgw port in ECR registry host for dev clusters Dev clusters bind awsgw on a non-standard port (e.g. 9999); production uses :443. ECRRegistryHost now appends SPINIFEX_ECR_PORT when set so docker/crane/ skopeo address the right endpoint, and RequireRegistryResolves strips the port before DNS lookup.
81 lines
2.6 KiB
Go
81 lines
2.6 KiB
Go
//go:build e2e
|
|
|
|
package ecr
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/mulgadc/spinifex/tests/e2e/harness"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const dockerCmdTimeout = 2 * time.Minute
|
|
|
|
// buildScratchContext writes a hermetic FROM-scratch build context (no network
|
|
// pulls) with a random payload layer, returning the context dir.
|
|
func buildScratchContext(t *testing.T, dir string) string {
|
|
t.Helper()
|
|
payload := make([]byte, 4096)
|
|
_, err := rand.Read(payload)
|
|
require.NoError(t, err)
|
|
require.NoError(t, os.WriteFile(filepath.Join(dir, "payload"), payload, 0o600))
|
|
require.NoError(t, os.WriteFile(filepath.Join(dir, "Dockerfile"),
|
|
[]byte("FROM scratch\nCOPY payload /payload\n"), 0o600))
|
|
return dir
|
|
}
|
|
|
|
// TestDockerPushPull drives the canonical workflow: aws ecr get-login-password
|
|
// -> docker login -> docker push -> DescribeImages -> docker pull (clean daemon)
|
|
// against the cluster registry.
|
|
func TestDockerPushPull(t *testing.T) {
|
|
f := requireECRFixture(t)
|
|
host := harness.ECRRegistryHost(f.Account)
|
|
harness.RequireRegistryResolves(t, host)
|
|
|
|
dockerConfig := filepath.Join(f.TmpDir, "docker")
|
|
require.NoError(t, os.MkdirAll(dockerConfig, 0o700))
|
|
docker := harness.NewDocker(t, dockerConfig)
|
|
|
|
repo := uniqueRepo("docker")
|
|
harness.CreateECRRepository(t, f.AWS, repo)
|
|
ref := harness.ECRRepositoryURI(f.Account, repo) + ":v1"
|
|
|
|
t.Run("docker login", func(t *testing.T) {
|
|
pass := harness.ECRGetLoginPassword(t, f.AWS)
|
|
out, err := docker.RunStdin(dockerCmdTimeout, pass,
|
|
"login", host, "-u", "AWS", "--password-stdin")
|
|
require.NoErrorf(t, err, "docker login: %s", out)
|
|
assert.Contains(t, out, "Login Succeeded")
|
|
})
|
|
|
|
t.Run("docker build + push", func(t *testing.T) {
|
|
buildDir := filepath.Join(f.TmpDir, "build")
|
|
require.NoError(t, os.MkdirAll(buildDir, 0o700))
|
|
ctxDir := buildScratchContext(t, buildDir)
|
|
|
|
out, err := docker.Run(dockerCmdTimeout, "build", "-t", ref, ctxDir)
|
|
require.NoErrorf(t, err, "docker build: %s", out)
|
|
|
|
out, err = docker.Run(dockerCmdTimeout, "push", ref)
|
|
require.NoErrorf(t, err, "docker push: %s", out)
|
|
})
|
|
|
|
t.Run("DescribeImages shows the pushed tag", func(t *testing.T) {
|
|
require.True(t, harness.ECRWaitImageTag(t, f.AWS, repo, "v1", 30*time.Second),
|
|
"pushed tag v1 not visible via DescribeImages")
|
|
})
|
|
|
|
t.Run("docker pull round-trips from a clean daemon", func(t *testing.T) {
|
|
out, err := docker.Run(dockerCmdTimeout, "rmi", "-f", ref)
|
|
require.NoErrorf(t, err, "docker rmi: %s", out)
|
|
|
|
out, err = docker.Run(dockerCmdTimeout, "pull", ref)
|
|
require.NoErrorf(t, err, "docker pull: %s", out)
|
|
})
|
|
}
|