From c2c37cb018d7a29915be8bbd1279741709da03fb Mon Sep 17 00:00:00 2001 From: oanatmaria Date: Tue, 21 Mar 2023 12:19:52 +0200 Subject: [PATCH] OCI store resolve returns full descriptor Signed-off-by: oanatmaria --- content/oci/oci.go | 7 ++- content/oci/oci_test.go | 82 ++++++++++++++++++++++++++++++++- content/oci/readonlyoci.go | 7 ++- content/oci/readonlyoci_test.go | 16 +++++-- 4 files changed, 105 insertions(+), 7 deletions(-) diff --git a/content/oci/oci.go b/content/oci/oci.go index 17f1515de..012f860de 100644 --- a/content/oci/oci.go +++ b/content/oci/oci.go @@ -180,7 +180,12 @@ func (s *Store) Resolve(ctx context.Context, reference string) (ocispec.Descript } return ocispec.Descriptor{}, err } - return descriptor.Plain(desc), nil + + if reference == desc.Digest.String() { + return descriptor.Plain(desc), nil + } + + return desc, nil } // Predecessors returns the nodes directly pointing to the current node. diff --git a/content/oci/oci_test.go b/content/oci/oci_test.go index 79198eaac..bcc2c20a8 100644 --- a/content/oci/oci_test.go +++ b/content/oci/oci_test.go @@ -452,6 +452,86 @@ func TestStore_ContentBadPush(t *testing.T) { } } +func TestStore_ResolveByTagReturnsFullDescriptor(t *testing.T) { + content := []byte("hello world") + ref := "hello-world:0.0.1" + annotations := map[string]string{"name": "Hello"} + desc := ocispec.Descriptor{ + MediaType: "test", + Digest: digest.FromBytes(content), + Size: int64(len(content)), + Annotations: annotations, + } + + tempDir := t.TempDir() + s, err := New(tempDir) + if err != nil { + t.Fatal("New() error =", err) + } + ctx := context.Background() + + err = s.Push(ctx, desc, bytes.NewReader(content)) + if err != nil { + t.Errorf("Store.Push() error = %v, wantErr %v", err, false) + } + + err = s.Tag(ctx, desc, ref) + if err != nil { + t.Errorf("error tagging descriptor error = %v, wantErr %v", err, false) + } + + resolvedDescr, err := s.Resolve(ctx, ref) + if err != nil { + t.Errorf("error resolving descriptor error = %v, wantErr %v", err, false) + } + + if !reflect.DeepEqual(resolvedDescr, desc) { + t.Errorf("Store.Resolve() = %v, want %v", resolvedDescr, desc) + } + + // descriptor resolved by tag should have annotations + if resolvedDescr.Annotations["name"] != annotations["name"] { + t.Errorf("Store.Resolve() returned descriptor without annotations %v, want %v", resolvedDescr.Annotations, annotations) + } +} + +func TestStore_ResolveByDigestReturnsPlainDescriptor(t *testing.T) { + content := []byte("hello world") + ref := "hello-world:0.0.1" + desc := ocispec.Descriptor{ + MediaType: "test", + Digest: digest.FromBytes(content), + Size: int64(len(content)), + Annotations: map[string]string{"name": "Hello"}, + } + + tempDir := t.TempDir() + s, err := New(tempDir) + if err != nil { + t.Fatal("New() error =", err) + } + ctx := context.Background() + + err = s.Push(ctx, desc, bytes.NewReader(content)) + if err != nil { + t.Errorf("Store.Push() error = %v, wantErr %v", err, false) + } + + err = s.Tag(ctx, desc, ref) + if err != nil { + t.Errorf("error tagging descriptor error = %v, wantErr %v", err, false) + } + + resolvedDescr, err := s.Resolve(ctx, string(desc.Digest)) + if err != nil { + t.Errorf("error resolving descriptor error = %v, wantErr %v", err, false) + } + + if reflect.DeepEqual(resolvedDescr, desc) { + t.Errorf("Store.Resolve() = %v, want %v", resolvedDescr, desc) + } +} + func TestStore_TagNotFound(t *testing.T) { ref := "foobar" @@ -1092,7 +1172,7 @@ func TestStore_ExistingStore(t *testing.T) { if err != nil { t.Fatal("Store: Resolve() error =", err) } - if !reflect.DeepEqual(gotDesc, indexRoot) { + if !content.Equal(gotDesc, indexRoot) { t.Errorf("Store.Resolve() = %v, want %v", gotDesc, indexRoot) } diff --git a/content/oci/readonlyoci.go b/content/oci/readonlyoci.go index cf36e6bd8..04e02d912 100644 --- a/content/oci/readonlyoci.go +++ b/content/oci/readonlyoci.go @@ -98,7 +98,12 @@ func (s *ReadOnlyStore) Resolve(ctx context.Context, reference string) (ocispec. } return ocispec.Descriptor{}, err } - return descriptor.Plain(desc), nil + + if reference == desc.Digest.String() { + return descriptor.Plain(desc), nil + } + + return desc, nil } // Predecessors returns the nodes directly pointing to the current node. diff --git a/content/oci/readonlyoci_test.go b/content/oci/readonlyoci_test.go index 5c4ab344d..ca15e5ca6 100644 --- a/content/oci/readonlyoci_test.go +++ b/content/oci/readonlyoci_test.go @@ -34,6 +34,7 @@ import ( ocispec "github.com/opencontainers/image-spec/specs-go/v1" "golang.org/x/sync/errgroup" "oras.land/oras-go/v2" + "oras.land/oras-go/v2/content" "oras.land/oras-go/v2/content/memory" "oras.land/oras-go/v2/internal/docker" "oras.land/oras-go/v2/registry" @@ -148,10 +149,17 @@ func TestReadOnlyStore(t *testing.T) { if err != nil { t.Error("ReadOnlyStore.Resolve() error =", err) } - if want := descs[2]; !reflect.DeepEqual(gotDesc, want) { + if want := descs[2]; !content.Equal(gotDesc, want) { t.Errorf("ReadOnlyStore.Resolve() = %v, want %v", gotDesc, want) } + // descriptor resolved by tag should have annotations + if gotDesc.Annotations[ocispec.AnnotationRefName] != subjectTag { + t.Errorf("ReadOnlyStore.Resolve() returned descriptor without annotations %v, want %v", + gotDesc.Annotations, + map[string]string{ocispec.AnnotationRefName: subjectTag}) + } + // test resolving artifact by digest gotDesc, err = s.Resolve(ctx, descs[3].Digest.String()) if err != nil { @@ -318,7 +326,7 @@ func TestReadOnlyStore_DirFS(t *testing.T) { if err != nil { t.Fatal("ReadOnlyStore: Resolve() error =", err) } - if !reflect.DeepEqual(gotDesc, indexRoot) { + if !content.Equal(gotDesc, indexRoot) { t.Errorf("ReadOnlyStore.Resolve() = %v, want %v", gotDesc, indexRoot) } @@ -613,7 +621,7 @@ func TestReadOnlyStore_Copy_OCIToMemory(t *testing.T) { if err != nil { t.Fatalf("Copy() error = %v, wantErr %v", err, false) } - if !reflect.DeepEqual(gotDesc, root) { + if !content.Equal(gotDesc, root) { t.Errorf("Copy() = %v, want %v", gotDesc, root) } @@ -633,7 +641,7 @@ func TestReadOnlyStore_Copy_OCIToMemory(t *testing.T) { if err != nil { t.Fatal("dst.Resolve() error =", err) } - if !reflect.DeepEqual(gotDesc, root) { + if !content.Equal(gotDesc, root) { t.Errorf("dst.Resolve() = %v, want %v", gotDesc, root) } }