Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use external imgutil library #125

Merged
merged 6 commits into from
Apr 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"log"
"os"

"github.com/buildpack/imgutil"
"github.com/pkg/errors"

"github.com/buildpack/lifecycle/image"
"github.com/buildpack/lifecycle/metadata"
)

Expand All @@ -20,7 +20,7 @@ type Analyzer struct {
GID int
}

func (a *Analyzer) Analyze(image image.Image) error {
func (a *Analyzer) Analyze(image imgutil.Image) error {
data, err := metadata.GetAppMetadata(image)
if err != nil {
return err
Expand Down
38 changes: 14 additions & 24 deletions analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package lifecycle_test

import (
"bytes"
"errors"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"testing"

"github.com/buildpack/imgutil/fakes"
"github.com/golang/mock/gomock"
"github.com/sclevine/spec"
"github.com/sclevine/spec/report"
Expand All @@ -25,7 +25,6 @@ func TestAnalyzer(t *testing.T) {

//go:generate mockgen -mock_names Image=GGCRImage -package testmock -destination testmock/image.go github.com/google/go-containerregistry/pkg/v1 Image
//go:generate mockgen -package testmock -destination testmock/ref.go github.com/google/go-containerregistry/pkg/name Reference
//go:generate mockgen -package testmock -destination testmock/image.go github.com/buildpack/lifecycle/image Image

func testAnalyzer(t *testing.T, when spec.G, it spec.S) {
var (
Expand Down Expand Up @@ -64,21 +63,25 @@ func testAnalyzer(t *testing.T, when spec.G, it spec.S) {

when("Analyze", func() {
var (
image *testmock.MockImage
image *fakes.Image
ref *testmock.MockReference
)

it.Before(func() {
image = testmock.NewMockImage(mockCtrl)
image = fakes.NewImage(t, "image-repo-name", "", "")

ref = testmock.NewMockReference(mockCtrl)
ref.EXPECT().Name().AnyTimes()
image.EXPECT().Name().AnyTimes().Return("image-repo-name")
})

it.After(func() {
image.Cleanup()
})

when("image exists", func() {
when("image label has compatible metadata", func() {
it.Before(func() {
image.EXPECT().Found().Return(true, nil)
image.EXPECT().Label("io.buildpacks.lifecycle.metadata").Return(`{
image.SetLabel("io.buildpacks.lifecycle.metadata", `{
"buildpacks": [
{
"key": "metdata.buildpack",
Expand Down Expand Up @@ -136,7 +139,7 @@ func testAnalyzer(t *testing.T, when spec.G, it spec.S) {
}
}
]
}`, nil)
}`)
})

it("should use labels to populate the layer dir", func() {
Expand Down Expand Up @@ -473,7 +476,7 @@ func testAnalyzer(t *testing.T, when spec.G, it spec.S) {

when("the image cannot found", func() {
it.Before(func() {
image.EXPECT().Found().Return(false, nil)
h.AssertNil(t, image.Delete())
})

it("clears the cached launch layers", func() {
Expand All @@ -493,21 +496,9 @@ func testAnalyzer(t *testing.T, when spec.G, it spec.S) {
})
})

when("there is an error while trying to find the image", func() {
it.Before(func() {
image.EXPECT().Found().Return(false, errors.New("some-error"))
})

it("returns the error", func() {
err := analyzer.Analyze(image)
h.AssertError(t, err, "some-error")
})
})

when("the image does not have the required label", func() {
it.Before(func() {
image.EXPECT().Found().Return(true, nil)
image.EXPECT().Label("io.buildpacks.lifecycle.metadata").Return("", nil)
h.AssertNil(t, image.SetLabel("io.buildpacks.lifecycle.metadata", ""))
})

it("returns", func() {
Expand All @@ -530,8 +521,7 @@ func testAnalyzer(t *testing.T, when spec.G, it spec.S) {

when("the image label has incompatible metadata", func() {
it.Before(func() {
image.EXPECT().Found().Return(true, nil)
image.EXPECT().Label("io.buildpacks.lifecycle.metadata").Return(`{["bad", "metadata"]}`, nil)
h.AssertNil(t, image.SetLabel("io.buildpacks.lifecycle.metadata", `{["bad", "metadata"]}`))
})

it("returns", func() {
Expand Down
32 changes: 19 additions & 13 deletions cache/image_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,20 @@ import (
"encoding/json"
"io"

"github.com/buildpack/imgutil"
"github.com/pkg/errors"

"github.com/buildpack/lifecycle/image"
"github.com/buildpack/lifecycle/metadata"
)

//go:generate mockgen -package testmock -destination testmock/image_factory.go github.com/buildpack/lifecycle/cache ImageFactory
type ImageFactory interface {
NewEmptyLocal(string) image.Image
}

type ImageCache struct {
factory ImageFactory
origImage image.Image
newImage image.Image
committed bool
origImage imgutil.Image
newImage imgutil.Image
}

func NewImageCache(factory ImageFactory, origImage image.Image) *ImageCache {
newImage := factory.NewEmptyLocal(origImage.Name())
func NewImageCache(origImage imgutil.Image, newImage imgutil.Image) *ImageCache {
return &ImageCache{
factory: factory,
origImage: origImage,
newImage: newImage,
}
Expand All @@ -35,6 +28,9 @@ func (c *ImageCache) Name() string {
}

func (c *ImageCache) SetMetadata(metadata Metadata) error {
if c.committed {
return errCacheCommitted
}
data, err := json.Marshal(metadata)
if err != nil {
return errors.Wrap(err, "serializing metadata")
Expand All @@ -56,10 +52,16 @@ func (c *ImageCache) RetrieveMetadata() (Metadata, error) {
}

func (c *ImageCache) AddLayer(identifier string, sha string, tarPath string) error {
if c.committed {
return errCacheCommitted
}
return c.newImage.AddLayer(tarPath)
}

func (c *ImageCache) ReuseLayer(identifier string, sha string) error {
if c.committed {
return errCacheCommitted
}
return c.newImage.ReuseLayer(sha)
}

Expand All @@ -68,6 +70,11 @@ func (c *ImageCache) RetrieveLayer(sha string) (io.ReadCloser, error) {
}

func (c *ImageCache) Commit() error {
if c.committed {
return errCacheCommitted
}
c.committed = true

_, err := c.newImage.Save()
if err != nil {
return errors.Wrapf(err, "saving image '%s'", c.newImage.Name())
Expand All @@ -78,7 +85,6 @@ func (c *ImageCache) Commit() error {
}

c.origImage = c.newImage
c.newImage = c.factory.NewEmptyLocal(c.origImage.Name())

return nil
}
56 changes: 41 additions & 15 deletions cache/image_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ import (
"testing"
"time"

"github.com/golang/mock/gomock"
"github.com/buildpack/imgutil/fakes"
"github.com/sclevine/spec"
"github.com/sclevine/spec/report"

"github.com/buildpack/lifecycle/cache"
"github.com/buildpack/lifecycle/cache/testmock"
"github.com/buildpack/lifecycle/image/fakes"
"github.com/buildpack/lifecycle/metadata"
h "github.com/buildpack/lifecycle/testhelpers"
)
Expand All @@ -30,8 +28,6 @@ func testImageCache(t *testing.T, when spec.G, it spec.S) {
tmpDir string
fakeOriginalImage *fakes.Image
fakeNewImage *fakes.Image
mockController *gomock.Controller
mockImageFactory *testmock.MockImageFactory
subject *cache.ImageCache
testLayerTarPath string
testLayerSHA string
Expand All @@ -46,24 +42,17 @@ func testImageCache(t *testing.T, when spec.G, it spec.S) {
fakeOriginalImage = fakes.NewImage(t, "fake-image", "", "")
fakeNewImage = fakes.NewImage(t, "fake-image", "", "")

mockController = gomock.NewController(t)
mockImageFactory = testmock.NewMockImageFactory(mockController)
mockImageFactory.EXPECT().NewEmptyLocal("fake-image").Return(fakeNewImage).AnyTimes()

subject = cache.NewImageCache(
mockImageFactory,
fakeOriginalImage,
)
subject = cache.NewImageCache(fakeOriginalImage, fakeNewImage)

testLayerTarPath = filepath.Join(tmpDir, "some-layer.tar")
h.AssertNil(t, ioutil.WriteFile(testLayerTarPath, []byte("dummy data"), 0666))
testLayerSHA = "sha256:" + h.ComputeSHA256ForFile(t, testLayerTarPath)
})

it.After(func() {
mockController.Finish()

os.RemoveAll(tmpDir)
fakeOriginalImage.Cleanup()
fakeNewImage.Cleanup()
})

when("#Name", func() {
Expand Down Expand Up @@ -176,6 +165,15 @@ func testImageCache(t *testing.T, when spec.G, it spec.S) {
})
})

when("set after commit", func() {
it("retrieve returns the newly set metadata", func() {
err := subject.Commit()
h.AssertNil(t, err)

h.AssertError(t, subject.SetMetadata(newMetadata), "cache cannot be modified after commit")
})
})

when("set without commit", func() {
it("retrieve returns the previous metadata", func() {
previousMetadata := cache.Metadata{
Expand Down Expand Up @@ -210,6 +208,15 @@ func testImageCache(t *testing.T, when spec.G, it spec.S) {
})
})

when("add after commit", func() {
it("retrieve returns the newly set metadata", func() {
err := subject.Commit()
h.AssertNil(t, err)

h.AssertError(t, subject.AddLayer("some_identifier", testLayerSHA, testLayerTarPath), "cache cannot be modified after commit")
})
})

when("add without commit", func() {
it("retrieve returns not found error", func() {
h.AssertNil(t, subject.AddLayer("some_identifier", testLayerSHA, testLayerTarPath))
Expand Down Expand Up @@ -242,6 +249,15 @@ func testImageCache(t *testing.T, when spec.G, it spec.S) {
})
})

when("reuse after commit", func() {
it("retrieve returns the newly set metadata", func() {
err := subject.Commit()
h.AssertNil(t, err)

h.AssertError(t, subject.ReuseLayer("some_identifier", testLayerSHA), "cache cannot be modified after commit")
})
})

when("reuse without commit", func() {
it("retrieve returns the previous layer", func() {
h.AssertNil(t, subject.ReuseLayer("some_identifier", testLayerSHA))
Expand All @@ -256,5 +272,15 @@ func testImageCache(t *testing.T, when spec.G, it spec.S) {
})

})

when("attempting to commit more than once", func() {
it("should fail", func() {
err := subject.Commit()
h.AssertNil(t, err)

err = subject.Commit()
h.AssertError(t, err, "cache cannot be modified after commit")
})
})
})
}
6 changes: 6 additions & 0 deletions cache/metadata.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package cache

import (
"errors"

"github.com/buildpack/lifecycle/metadata"
)

const MetadataLabel = "io.buildpacks.lifecycle.cache.metadata"

var (
errCacheCommitted = errors.New("cache cannot be modified after commit")
)

type Metadata struct {
Buildpacks []metadata.BuildpackMetadata `json:"buildpacks"`
}
Expand Down
46 changes: 0 additions & 46 deletions cache/testmock/image_factory.go

This file was deleted.

Loading