An upstream copy kept by the artifact store is named by the holder, upstream/<host>/<path>@<digest>, in the seat form (container-image-registry/upstream/...) and the older one (artifact-store://upstream/...). InRegistrySeat reads it, InUpstream reads its host and path, and referenceProblem accepts it for an upstream artifact, so readers stop reading it on their own. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
71 lines
3.8 KiB
Go
71 lines
3.8 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// A build is recorded by what it is; where it is pushed is composed where it is used (novox/hq
|
|
// 04-ISSUES/102).
|
|
|
|
var digest = "sha256:" + strings.Repeat("d", 64)
|
|
|
|
func TestAReferenceIsRecordedWithoutTheStoresAddress(t *testing.T) {
|
|
cases := map[string]string{
|
|
"anchor.internal:5100/gitea/server@" + digest: ArtifactStoreScheme + "gitea/server@" + digest,
|
|
"localhost:5000/gitea/server@" + digest: ArtifactStoreScheme + "gitea/server@" + digest,
|
|
"http://anchor.internal:5100/v2/gitea/config/blobs/" + digest: ArtifactStoreScheme + "gitea/config/blobs/" + digest,
|
|
ArtifactStoreScheme + "gitea/server@" + digest: ArtifactStoreScheme + "gitea/server@" + digest,
|
|
digest: digest,
|
|
"@novox/sdk@1.2.3": "@novox/sdk@1.2.3",
|
|
"gitea/gitea@" + digest: "gitea/gitea@" + digest,
|
|
"https://registry.example/v2/gitea/config/blobs/" + digest: "https://registry.example/v2/gitea/config/blobs/" + digest,
|
|
// The form a registry seat answers is recorded as it is (ADR 0605 §9).
|
|
"container-image-registry/gitea/server@" + digest: "container-image-registry/gitea/server@" + digest,
|
|
"oci-artifact-registry/gitea/config@" + digest: "oci-artifact-registry/gitea/config@" + digest,
|
|
}
|
|
for announced, want := range cases {
|
|
if got := Recorded(announced); got != want {
|
|
t.Errorf("Recorded(%q) = %q, want %q", announced, got, want)
|
|
}
|
|
}
|
|
// And every reader reads both forms: a kept reference and the seat's are fetched from the same place.
|
|
for reference, want := range map[string]string{
|
|
ArtifactStoreScheme + "gitea/server@" + digest: "10.0.0.1:5000/gitea/server@" + digest,
|
|
"container-image-registry/gitea/server@" + digest: "10.0.0.1:5000/gitea/server@" + digest,
|
|
ArtifactStoreScheme + "gitea/config/blobs/" + digest: "http://10.0.0.1:5000/v2/gitea/config/blobs/" + digest,
|
|
"oci-artifact-registry/gitea/config@" + digest: "http://10.0.0.1:5000/v2/gitea/config/blobs/" + digest,
|
|
"registry.example/gitea/server@" + digest: "registry.example/gitea/server@" + digest,
|
|
"mesh-artifact-store/gitea/server@" + digest: "mesh-artifact-store/gitea/server@" + digest,
|
|
// An upstream copy under the holder's own naming, in both forms.
|
|
"container-image-registry/upstream/quay.io:443/org/app@" + digest: "10.0.0.1:5000/upstream/quay.io:443/org/app@" + digest,
|
|
ArtifactStoreScheme + "upstream/quay.io:443/org/app@" + digest: "10.0.0.1:5000/upstream/quay.io:443/org/app@" + digest,
|
|
} {
|
|
if got := Routed(reference, "10.0.0.1:5000"); got != want {
|
|
t.Errorf("Routed(%q) = %q, want %q", reference, got, want)
|
|
}
|
|
}
|
|
// A build module names what it published in the seat's form, and reads it back as the seat it came through.
|
|
for _, seat := range RegistrySeats {
|
|
ref := SeatReference(seat, "gitea", "config", digest)
|
|
if got, path, ok := InRegistrySeat(ref); !ok || got != seat || path != "gitea/config@"+digest {
|
|
t.Errorf("SeatReference(%s) = %q, read back as %q %q %v", seat, ref, got, path, ok)
|
|
}
|
|
}
|
|
// The holder's naming of an upstream copy reads through the image seat only, and InUpstream reads its host and path.
|
|
for reference, want := range map[string]bool{
|
|
"container-image-registry/upstream/quay.io:443/org/app@" + digest: true,
|
|
"oci-artifact-registry/upstream/quay.io:443/org/app@" + digest: false,
|
|
"container-image-registry/upstream/org/app@" + digest: false,
|
|
"container-image-registry/upstream/quay.io/app": false,
|
|
} {
|
|
_, path, ok := InRegistrySeat(reference)
|
|
if ok != want {
|
|
t.Errorf("InRegistrySeat(%q) read %v, want %v", reference, ok, want)
|
|
}
|
|
if host, image, up := InUpstream(path); ok && (!up || host != "quay.io:443" || image != "org/app@"+digest) {
|
|
t.Errorf("InUpstream(%q) = %q %q %v", path, host, image, up)
|
|
}
|
|
}
|
|
}
|