//go:build integration // Package integration runs an in-process smoke test of the full ATCR stack: // fake PDS, gofakes3 (S3), hold, appview — all wired together in goroutines // with no docker, no compose, no external network. Confirms that the happy // path of "push an image and pull it back" works before deploy. // // Run with: go test -tags=integration -v ./test/integration/... package integration import ( "fmt" "testing" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1/random" "atcr.io/internal/testharness" // distribution registers its drivers and auth providers via init() side // effects; cmd/appview pulls these in too. Without these blank imports // distribution panics with "StorageDriver not registered: inmemory". _ "github.com/distribution/distribution/v3/registry/auth/token" _ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" ) func TestPushPullHappyPath(t *testing.T) { h := testharness.New(t) alice := h.AddSailor("alice.test") img, err := random.Image(1<<20, 3) // 1MB, 3 layers if err != nil { t.Fatalf("build random image: %v", err) } pushedDigest, err := img.Digest() if err != nil { t.Fatalf("pushed digest: %v", err) } for _, c := range Clients { t.Run(c.Name(), func(t *testing.T) { // Per-client repo path so concurrent / matrixed runs don't // collide on shared blob digests at the registry. ref, err := name.ParseReference( fmt.Sprintf("%s/%s/repo-%s:tag", h.AppViewHostPort(), alice.Handle(), c.Name()), name.Insecure, ) if err != nil { t.Fatalf("parse ref: %v", err) } creds := h.RegistryCreds(alice) if err := c.Push(t.Context(), t, ref.String(), img, creds); err != nil { t.Fatalf("push: %v", err) } pulledDigest, err := c.Pull(t.Context(), ref.String(), creds) if err != nil { t.Fatalf("pull: %v", err) } if pushedDigest != pulledDigest { t.Fatalf("digest mismatch: pushed=%s pulled=%s", pushedDigest, pulledDigest) } }) } }