Skip to content

Commit

Permalink
removing blobs from test data, after testing on pack we don't want to…
Browse files Browse the repository at this point in the history
… save the image information. Reimplement the getters/setters to read the information from the index. Adding more test coverage

Signed-off-by: Juan Bustamante <[email protected]>
  • Loading branch information
jjbustamante committed Apr 25, 2024
1 parent cbecaa8 commit f00946b
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 190 deletions.
155 changes: 78 additions & 77 deletions cnb_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,161 +35,144 @@ type CNBIndex struct {
RepoName string
}

func (h *CNBIndex) getConfigFileFrom(digest name.Digest) (v1.ConfigFile, error) {
hash, err := v1.NewHash(digest.Identifier())
if err != nil {
return v1.ConfigFile{}, err
}
image, err := h.Image(hash)
if err != nil {
return v1.ConfigFile{}, err
}
configFile, err := GetConfigFile(image)
if err != nil {
return v1.ConfigFile{}, err
}
return *configFile, nil
}

func (h *CNBIndex) getManifestFileFrom(digest name.Digest) (v1.Manifest, error) {
hash, err := v1.NewHash(digest.Identifier())
if err != nil {
return v1.Manifest{}, err
}
image, err := h.Image(hash)
func (h *CNBIndex) getDescriptorFrom(digest name.Digest) (v1.Descriptor, error) {
indexManifest, err := getIndexManifest(h.ImageIndex)
if err != nil {
return v1.Manifest{}, err
return v1.Descriptor{}, err

Check warning on line 41 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L38-L41

Added lines #L38 - L41 were not covered by tests
}
manifestFile, err := GetManifest(image)
if err != nil {
return v1.Manifest{}, err
for _, current := range indexManifest.Manifests {
if current.Digest.String() == digest.Identifier() {
return current, nil

Check warning on line 45 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L43-L45

Added lines #L43 - L45 were not covered by tests
}
}
return *manifestFile, nil
return v1.Descriptor{}, fmt.Errorf("failed to find image with digest %s in index", digest.Identifier())

Check warning on line 48 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L48

Added line #L48 was not covered by tests
}

// OS returns `OS` of an existing Image.
func (h *CNBIndex) OS(digest name.Digest) (os string, err error) {
configFile, err := h.getConfigFileFrom(digest)
desc, err := h.getDescriptorFrom(digest)
if err != nil {
return "", err

Check warning on line 55 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L52-L55

Added lines #L52 - L55 were not covered by tests
}
return configFile.OS, nil
if desc.Platform != nil {
return desc.Platform.OS, nil

Check warning on line 58 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L57-L58

Added lines #L57 - L58 were not covered by tests
}
return "", nil

Check warning on line 60 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L60

Added line #L60 was not covered by tests
}

// Architecture return the Architecture of an Image/Index based on given Digest.
// Returns an error if no Image/Index found with given Digest.
func (h *CNBIndex) Architecture(digest name.Digest) (arch string, err error) {
configFile, err := h.getConfigFileFrom(digest)
desc, err := h.getDescriptorFrom(digest)
if err != nil {
return "", err

Check warning on line 68 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L65-L68

Added lines #L65 - L68 were not covered by tests
}
return configFile.Architecture, nil
if desc.Platform != nil {
return desc.Platform.Architecture, nil

Check warning on line 71 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L70-L71

Added lines #L70 - L71 were not covered by tests
}
return "", nil

Check warning on line 73 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L73

Added line #L73 was not covered by tests
}

// Variant return the `Variant` of an Image.
// Returns an error if no Image/Index found with given Digest.
func (h *CNBIndex) Variant(digest name.Digest) (osVariant string, err error) {
configFile, err := h.getConfigFileFrom(digest)
desc, err := h.getDescriptorFrom(digest)
if err != nil {
return "", err

Check warning on line 81 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L78-L81

Added lines #L78 - L81 were not covered by tests
}
return configFile.Variant, nil
if desc.Platform != nil {
return desc.Platform.Variant, nil

Check warning on line 84 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L83-L84

Added lines #L83 - L84 were not covered by tests
}
return "", nil

Check warning on line 86 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L86

Added line #L86 was not covered by tests
}

// OSVersion returns the `OSVersion` of an Image with given Digest.
// Returns an error if no Image/Index found with given Digest.
func (h *CNBIndex) OSVersion(digest name.Digest) (osVersion string, err error) {
configFile, err := h.getConfigFileFrom(digest)
desc, err := h.getDescriptorFrom(digest)
if err != nil {
return "", err

Check warning on line 94 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L91-L94

Added lines #L91 - L94 were not covered by tests
}
return configFile.OSVersion, nil
if desc.Platform != nil {
return desc.Platform.OSVersion, nil

Check warning on line 97 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L96-L97

Added lines #L96 - L97 were not covered by tests
}
return "", nil

Check warning on line 99 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L99

Added line #L99 was not covered by tests
}

// OSFeatures returns the `OSFeatures` of an Image with given Digest.
// Returns an error if no Image/Index found with given Digest.
func (h *CNBIndex) OSFeatures(digest name.Digest) (osFeatures []string, err error) {
configFile, err := h.getConfigFileFrom(digest)
desc, err := h.getDescriptorFrom(digest)
if err != nil {
return nil, err

Check warning on line 107 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L104-L107

Added lines #L104 - L107 were not covered by tests
}
return configFile.OSFeatures, nil
if desc.Platform != nil {
return desc.Platform.OSFeatures, nil

Check warning on line 110 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L109-L110

Added lines #L109 - L110 were not covered by tests
}
return []string{}, nil

Check warning on line 112 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L112

Added line #L112 was not covered by tests
}

// Annotations return the `Annotations` of an Image with given Digest.
// Returns an error if no Image/Index found with given Digest.
// For Docker images and Indexes it returns an error.
func (h *CNBIndex) Annotations(digest name.Digest) (annotations map[string]string, err error) {
manifestFile, err := h.getManifestFileFrom(digest)
desc, err := h.getDescriptorFrom(digest)
if err != nil {
return nil, err

Check warning on line 121 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L118-L121

Added lines #L118 - L121 were not covered by tests
}
return manifestFile.Annotations, nil
return desc.Annotations, nil

Check warning on line 123 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L123

Added line #L123 was not covered by tests
}

// setters

func (h *CNBIndex) SetAnnotations(digest name.Digest, annotations map[string]string) (err error) {
return h.mutateExistingImage(digest, func(image v1.Image) (v1.Image, error) {
partial := mutate.Annotations(image, annotations)
annotatedImage, ok := partial.(v1.Image)
if !ok {
return nil, fmt.Errorf("failed to annotate image")
return h.replaceDescriptor(digest, func(descriptor v1.Descriptor) (v1.Descriptor, error) {
if len(descriptor.Annotations) == 0 {
descriptor.Annotations = make(map[string]string)

Check warning on line 131 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L128-L131

Added lines #L128 - L131 were not covered by tests
}
return annotatedImage, nil

for k, v := range annotations {
descriptor.Annotations[k] = v

Check warning on line 135 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L134-L135

Added lines #L134 - L135 were not covered by tests
}
return descriptor, nil

Check warning on line 137 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L137

Added line #L137 was not covered by tests
})
}

func (h *CNBIndex) SetArchitecture(digest name.Digest, arch string) (err error) {
return h.mutateExistingImage(digest, func(image v1.Image) (v1.Image, error) {
configFile, err := image.ConfigFile()
if err != nil {
return nil, err
}
configFile.Architecture = arch
return mutate.ConfigFile(image, configFile)
return h.replaceDescriptor(digest, func(descriptor v1.Descriptor) (v1.Descriptor, error) {
descriptor.Platform.Architecture = arch
return descriptor, nil
})

Check warning on line 145 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L141-L145

Added lines #L141 - L145 were not covered by tests
}

func (h *CNBIndex) SetOS(digest name.Digest, os string) (err error) {
return h.mutateExistingImage(digest, func(image v1.Image) (v1.Image, error) {
configFile, err := image.ConfigFile()
if err != nil {
return nil, err
}
configFile.OS = os
return mutate.ConfigFile(image, configFile)
return h.replaceDescriptor(digest, func(descriptor v1.Descriptor) (v1.Descriptor, error) {
descriptor.Platform.OS = os
return descriptor, nil
})

Check warning on line 152 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L148-L152

Added lines #L148 - L152 were not covered by tests
}

func (h *CNBIndex) SetVariant(digest name.Digest, osVariant string) (err error) {
return h.mutateExistingImage(digest, func(image v1.Image) (v1.Image, error) {
configFile, err := image.ConfigFile()
if err != nil {
return nil, err
}
configFile.Variant = osVariant
return mutate.ConfigFile(image, configFile)
return h.replaceDescriptor(digest, func(descriptor v1.Descriptor) (v1.Descriptor, error) {
descriptor.Platform.Variant = osVariant
return descriptor, nil
})

Check warning on line 159 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L155-L159

Added lines #L155 - L159 were not covered by tests
}

func (h *CNBIndex) mutateExistingImage(digest name.Digest, withFunc func(image v1.Image) (v1.Image, error)) (err error) {
hash, err := v1.NewHash(digest.Identifier())
func (h *CNBIndex) replaceDescriptor(digest name.Digest, withFun func(descriptor v1.Descriptor) (v1.Descriptor, error)) (err error) {
desc, err := h.getDescriptorFrom(digest)
if err != nil {
return err

Check warning on line 165 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L162-L165

Added lines #L162 - L165 were not covered by tests
}
image, err := h.Image(hash)
desc, err = withFun(desc)
if err != nil {
return err

Check warning on line 169 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L167-L169

Added lines #L167 - L169 were not covered by tests
}
if err = h.RemoveManifest(digest); err != nil {
return err
}
newImage, err := withFunc(image)
if err != nil {
return err
add := mutate.IndexAddendum{
Add: h.ImageIndex,
Descriptor: desc,

Check warning on line 173 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L171-L173

Added lines #L171 - L173 were not covered by tests
}
h.AddManifest(newImage)
h.ImageIndex = mutate.AppendManifests(mutate.RemoveManifests(h.ImageIndex, match.Digests(desc.Digest)), add)
return nil

Check warning on line 176 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L175-L176

Added lines #L175 - L176 were not covered by tests
}

Expand All @@ -215,8 +198,10 @@ func indexContains(manifests []v1.Descriptor, hash v1.Hash) bool {

// AddManifest adds an image to the index.
func (h *CNBIndex) AddManifest(image v1.Image) {
desc, _ := descriptor(image)
h.ImageIndex = mutate.AppendManifests(h.ImageIndex, mutate.IndexAddendum{
Add: image,
Add: image,
Descriptor: desc,
})

Check warning on line 205 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L200-L205

Added lines #L200 - L205 were not covered by tests
}

Expand Down Expand Up @@ -378,3 +363,19 @@ func getIndexManifest(ii v1.ImageIndex) (mfest *v1.IndexManifest, err error) {
}
return mfest, err

Check warning on line 364 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L364

Added line #L364 was not covered by tests
}

// descriptor returns a v1.Descriptor filled with a v1.Platform created from reading
// the image config file.
func descriptor(image v1.Image) (v1.Descriptor, error) {

Check warning on line 369 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L369

Added line #L369 was not covered by tests
// Get the image configuration file
cfg, _ := GetConfigFile(image)
platform := v1.Platform{}
platform.Architecture = cfg.Architecture
platform.OS = cfg.OS
platform.OSVersion = cfg.OSVersion
platform.Variant = cfg.Variant
platform.OSFeatures = cfg.OSFeatures
return v1.Descriptor{
Platform: &platform,
}, nil

Check warning on line 380 in cnb_index.go

View check run for this annotation

Codecov / codecov/patch

cnb_index.go#L371-L380

Added lines #L371 - L380 were not covered by tests
}
109 changes: 108 additions & 1 deletion layout/layout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -1267,6 +1268,112 @@ func testIndex(t *testing.T, when spec.G, it spec.S) {
})
})

when("#Setters", func() {
var (
descriptor1 v1.Descriptor
digest1 name.Digest
)

when("index is created from scratch", func() {
it.Before(func() {
repoName := newRepoName()
idx = setupIndex(t, repoName, imgutil.WithXDGRuntimePath(tmpDir))
localPath = filepath.Join(tmpDir, repoName)
})

when("digest is provided", func() {
it.Before(func() {
image1, err := random.Image(1024, 1)
h.AssertNil(t, err)
idx.AddManifest(image1)

h.AssertNil(t, idx.SaveDir())

index := h.ReadIndexManifest(t, localPath)
h.AssertEq(t, len(index.Manifests), 1)
descriptor1 = index.Manifests[0]

digest1, err = name.NewDigest(fmt.Sprintf("%s@%s", "random", descriptor1.Digest.String()))
h.AssertNil(t, err)
})

it("platform attributes are written on disk", func() {
h.AssertNil(t, idx.SetOS(digest1, "linux"))
h.AssertNil(t, idx.SetArchitecture(digest1, "arm"))
h.AssertNil(t, idx.SetVariant(digest1, "v6"))
h.AssertNil(t, idx.SaveDir())

index := h.ReadIndexManifest(t, localPath)
h.AssertEq(t, len(index.Manifests), 1)
h.AssertEq(t, index.Manifests[0].Digest.String(), descriptor1.Digest.String())
h.AssertEq(t, index.Manifests[0].Platform.OS, "linux")
h.AssertEq(t, index.Manifests[0].Platform.Architecture, "arm")
h.AssertEq(t, index.Manifests[0].Platform.Variant, "v6")
})

it("annotations are written on disk", func() {
annotations := map[string]string{
"some-key": "some-value",
}
h.AssertNil(t, idx.SetAnnotations(digest1, annotations))
h.AssertNil(t, idx.SaveDir())

index := h.ReadIndexManifest(t, localPath)
h.AssertEq(t, len(index.Manifests), 1)
h.AssertEq(t, index.Manifests[0].Digest.String(), descriptor1.Digest.String())
h.AssertEq(t, reflect.DeepEqual(index.Manifests[0].Annotations, annotations), true)
})
})
})

when("index exists on disk", func() {
when("#FromBaseIndex", func() {
it.Before(func() {
idx = setupIndex(t, "busybox-multi-platform", imgutil.WithXDGRuntimePath(tmpDir), imgutil.FromBaseIndex(baseIndexPath))
localPath = filepath.Join(tmpDir, "busybox-multi-platform")
digest1, err = name.NewDigest("busybox@sha256:e18f2c12bb4ea582045415243370a3d9cf3874265aa2867f21a35e630ebe45a7")
h.AssertNil(t, err)
})

when("digest is provided", func() {
when("attributes already exists", func() {
it("platform attributes are updated on disk", func() {
h.AssertNil(t, idx.SetOS(digest1, "linux-2"))
h.AssertNil(t, idx.SetArchitecture(digest1, "arm-2"))
h.AssertNil(t, idx.SetVariant(digest1, "v6-2"))
h.AssertNil(t, idx.SaveDir())

index := h.ReadIndexManifest(t, localPath)
h.AssertEq(t, len(index.Manifests), 2)
h.AssertEq(t, index.Manifests[1].Digest.String(), "sha256:e18f2c12bb4ea582045415243370a3d9cf3874265aa2867f21a35e630ebe45a7")
h.AssertEq(t, index.Manifests[1].Platform.OS, "linux-2")
h.AssertEq(t, index.Manifests[1].Platform.Architecture, "arm-2")
h.AssertEq(t, index.Manifests[1].Platform.Variant, "v6-2")
})

it("new annotation are appended on disk", func() {
annotations := map[string]string{
"some-key": "some-value",
}
h.AssertNil(t, idx.SetAnnotations(digest1, annotations))
h.AssertNil(t, idx.SaveDir())

index := h.ReadIndexManifest(t, localPath)
h.AssertEq(t, len(index.Manifests), 2)

// When updating a digest, it will be appended at the end
h.AssertEq(t, index.Manifests[1].Digest.String(), "sha256:e18f2c12bb4ea582045415243370a3d9cf3874265aa2867f21a35e630ebe45a7")

// in testdata we have 7 annotations + 1 new
h.AssertEq(t, len(index.Manifests[1].Annotations), 8)
h.AssertEq(t, index.Manifests[1].Annotations["some-key"], "some-value")
})
})
})
})
})
})

when("#Save", func() {
when("index exists on disk", func() {
when("#FromBaseIndex", func() {
Expand Down Expand Up @@ -1348,7 +1455,7 @@ func testIndex(t *testing.T, when spec.G, it spec.S) {
h.AssertEq(t, len(index.Manifests), 1)
})

it.Focus("add more than one manifest to the index", func() {
it("add more than one manifest to the index", func() {
image1, err := random.Image(1024, 1)
h.AssertNil(t, err)
idx.AddManifest(image1)
Expand Down
Loading

0 comments on commit f00946b

Please sign in to comment.