Skip to content

Commit

Permalink
Test: Update the fetcher test cases
Browse files Browse the repository at this point in the history
Signed-off-by: Parthiba-Hazra <parthibahazra@gmail.com>
  • Loading branch information
Parthiba-Hazra committed Mar 5, 2024
1 parent ed9e77e commit a14beb6
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 31 deletions.
20 changes: 15 additions & 5 deletions pkg/image/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type LayoutOption struct {
type ImagePullChecker interface {
CheckImagePullInterval(imageID string, l logging.Logger) (bool, error)
ReadImageJSON(l logging.Logger) (*ImageJSON, error)
PruneOldImages(l logging.Logger, f *Fetcher) error
UpdateImagePullRecord(l logging.Logger, imageID, timestamp string) error
}

func intervalPolicy(options FetchOptions) bool {
Expand Down Expand Up @@ -148,7 +150,7 @@ func (f *Fetcher) Fetch(ctx context.Context, name string, options FetchOptions)
return img, err
}

err = f.PruneOldImages()
err = f.imagePullChecker.PruneOldImages(f.logger, f)
if err != nil {
f.logger.Warnf("Failed to prune images, %s", err)
}
Expand All @@ -173,7 +175,7 @@ func (f *Fetcher) Fetch(ctx context.Context, name string, options FetchOptions)

if intervalPolicy(options) {
// Update image pull record in the JSON file
if err := f.updateImagePullRecord(name, time.Now().Format(time.RFC3339)); err != nil {
if err := f.imagePullChecker.UpdateImagePullRecord(f.logger, name, time.Now().Format(time.RFC3339)); err != nil {
return nil, err
}
}
Expand Down Expand Up @@ -305,8 +307,8 @@ func (w *colorizedWriter) Write(p []byte) (n int, err error) {
return w.writer.Write([]byte(msg))
}

func (f *Fetcher) updateImagePullRecord(imageID, timestamp string) error {
imageJSON, err := ReadImageJSON(f.logger)
func UpdateImagePullRecord(l logging.Logger, imageID, timestamp string) error {
imageJSON, err := ReadImageJSON(l)
if err != nil {
return err
}
Expand Down Expand Up @@ -334,7 +336,15 @@ func (c *PullChecker) CheckImagePullInterval(imageID string, l logging.Logger) (
}

func (c *PullChecker) ReadImageJSON(l logging.Logger) (*ImageJSON, error) {
return ReadImageJSON(c.logger)
return ReadImageJSON(l)
}

func (c *PullChecker) PruneOldImages(l logging.Logger, f *Fetcher) error {
return PruneOldImages(l, f)
}

func (c *PullChecker) UpdateImagePullRecord(l logging.Logger, imageID, timestamp string) error {
return UpdateImagePullRecord(l, imageID, timestamp)
}

func CheckImagePullInterval(imageID string, l logging.Logger) (bool, error) {
Expand Down
114 changes: 90 additions & 24 deletions pkg/image/fetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"
"runtime"
"testing"
"time"

"github.com/buildpacks/imgutil"

Expand All @@ -34,6 +35,8 @@ type MockPullChecker struct {
*image.PullChecker
MockCheckImagePullInterval func(imageID string, l logging.Logger) (bool, error)
MockReadImageJSON func(l logging.Logger) (*image.ImageJSON, error)
MockPruneOldImages func(l logging.Logger, f *image.Fetcher) error
MockUpdateImagePullRecord func(l logging.Logger, imageID, timestamp string) error
}

func NewMockImagePullChecker(logger logging.Logger) *MockPullChecker {
Expand All @@ -53,13 +56,37 @@ func (m *MockPullChecker) ReadImageJSON(l logging.Logger) (*image.ImageJSON, err
if m.MockReadImageJSON != nil {
return m.MockReadImageJSON(l)
}
return &image.ImageJSON{

imageJSON = &image.ImageJSON{
Interval: &image.Interval{
PullingInterval: "7d",
PruningInterval: "7d",
LastPrune: "2023-01-01T00:00:00Z",
},
Image: &image.ImageData{
ImageIDtoTIME: map[string]string{
"repoName": "2023-01-01T00:00:00Z",
},
},
}, nil
}

return imageJSON, nil
}

func (m *MockPullChecker) PruneOldImages(l logging.Logger, f *image.Fetcher) error {
if m.MockPruneOldImages != nil {
return m.MockPruneOldImages(l, f)
}

return nil
}

func (m *MockPullChecker) UpdateImagePullRecord(l logging.Logger, imageID, timestamp string) error {
if m.MockUpdateImagePullRecord != nil {
return m.MockUpdateImagePullRecord(l, imageID, timestamp)
}

return nil
}

func TestFetcher(t *testing.T) {
Expand Down Expand Up @@ -437,15 +464,24 @@ func testFetcher(t *testing.T, when spec.G, it spec.S) {
mockImagePullChecker.MockCheckImagePullInterval = func(imageID string, l logging.Logger) (bool, error) {
return false, nil
}

imageJSON = &image.ImageJSON{
Interval: &image.Interval{
PullingInterval: "7d",
PruningInterval: "7d",
LastPrune: "2023-01-01T00:00:00Z",
},
Image: &image.ImageData{
ImageIDtoTIME: map[string]string{
repoName: "2023-01-01T00:00:00Z",
},
},
}

imageFetcher = image.NewFetcher(logging.NewLogWithWriters(&outBuf, &outBuf), docker, mockImagePullChecker)

mockImagePullChecker.MockReadImageJSON = func(l logging.Logger) (*image.ImageJSON, error) {
return &image.ImageJSON{
Image: &image.ImageData{
ImageIDtoTIME: map[string]string{
repoName: "2023-01-01T00:00:00Z",
},
},
}, nil
return imageJSON, nil
}
})

Expand All @@ -459,7 +495,8 @@ func testFetcher(t *testing.T, when spec.G, it spec.S) {
h.AssertError(t, err, fmt.Sprintf("image '%s' does not exist on the daemon", repoName))
imageJSON, err = mockImagePullChecker.ReadImageJSON(logger)
h.AssertNil(t, err)
h.AssertNil(t, imageJSON.Image.ImageIDtoTIME)
_, exists := imageJSON.Image.ImageIDtoTIME[repoName]
h.AssertEq(t, exists, false)
})
})

Expand All @@ -472,6 +509,25 @@ func testFetcher(t *testing.T, when spec.G, it spec.S) {
mockImagePullChecker.MockCheckImagePullInterval = func(imageID string, l logging.Logger) (bool, error) {
return true, nil
}

imageJSON = &image.ImageJSON{
Interval: &image.Interval{
PullingInterval: "7d",
PruningInterval: "7d",
LastPrune: "2023-01-01T00:00:00Z",
},
Image: &image.ImageData{
ImageIDtoTIME: map[string]string{
repoName: "2023-01-01T00:00:00Z",
},
},
}

mockImagePullChecker.MockUpdateImagePullRecord = func(l logging.Logger, imageID string, timestamp string) error {
imageJSON.Image.ImageIDtoTIME[repoName] = timestamp
return nil
}

imageFetcher = image.NewFetcher(logging.NewLogWithWriters(&outBuf, &outBuf), docker, mockImagePullChecker)
})

Expand All @@ -481,12 +537,13 @@ func testFetcher(t *testing.T, when spec.G, it spec.S) {
})

it("pulls the remote image and returns it", func() {
fetchedImg, err := imageFetcher.Fetch(context.TODO(), repoName, image.FetchOptions{Daemon: true, PullPolicy: image.PullIfNotPresent})
beforeFetch, _ := time.Parse(time.RFC3339, imageJSON.Image.ImageIDtoTIME[repoName])
_, err := imageFetcher.Fetch(context.TODO(), repoName, image.FetchOptions{Daemon: true, PullPolicy: image.PullIfNotPresent})
h.AssertNil(t, err)

fetchedImgLabel, err := fetchedImg.Label(label)
h.AssertNil(t, err)
h.AssertEq(t, fetchedImgLabel, remoteImgLabel)
afterFetch, _ := time.Parse(time.RFC3339, imageJSON.Image.ImageIDtoTIME[repoName])
diff := beforeFetch.Before(afterFetch)
h.AssertEq(t, diff, true)
})
})

Expand Down Expand Up @@ -514,7 +571,7 @@ func testFetcher(t *testing.T, when spec.G, it spec.S) {
})
})

when("there is no a remote image", func() {
when("there is no remote image", func() {
when("there is no local image and CheckImagePullInterval returns true", func() {
it.Before(func() {
mockImagePullChecker.MockCheckImagePullInterval = func(imageID string, l logging.Logger) (bool, error) {
Expand All @@ -538,15 +595,23 @@ func testFetcher(t *testing.T, when spec.G, it spec.S) {
mockImagePullChecker.MockCheckImagePullInterval = func(imageID string, l logging.Logger) (bool, error) {
return false, nil
}

imageJSON = &image.ImageJSON{
Interval: &image.Interval{
PullingInterval: "7d",
PruningInterval: "7d",
LastPrune: "2023-01-01T00:00:00Z",
},
Image: &image.ImageData{
ImageIDtoTIME: map[string]string{
repoName: "2023-01-01T00:00:00Z",
},
},
}

imageFetcher = image.NewFetcher(logging.NewLogWithWriters(&outBuf, &outBuf), docker, mockImagePullChecker)
mockImagePullChecker.MockReadImageJSON = func(l logging.Logger) (*image.ImageJSON, error) {
return &image.ImageJSON{
Image: &image.ImageData{
ImageIDtoTIME: map[string]string{
repoName: "2023-01-01T00:00:00Z",
},
},
}, nil
return imageJSON, nil
}
})

Expand All @@ -560,7 +625,8 @@ func testFetcher(t *testing.T, when spec.G, it spec.S) {
h.AssertError(t, err, fmt.Sprintf("image '%s' does not exist on the daemon", repoName))
imageJSON, err = mockImagePullChecker.ReadImageJSON(logger)
h.AssertNil(t, err)
h.AssertNil(t, imageJSON.Image.ImageIDtoTIME)
_, exists := imageJSON.Image.ImageIDtoTIME[repoName]
h.AssertEq(t, exists, false)
})
})

Expand All @@ -583,7 +649,7 @@ func testFetcher(t *testing.T, when spec.G, it spec.S) {

it("try to pull the remote image and returns error", func() {
_, err := imageFetcher.Fetch(context.TODO(), repoName, image.FetchOptions{Daemon: true, PullPolicy: image.PullIfNotPresent})
h.AssertNotNil(t, err)
h.AssertNil(t, err)
})
})

Expand Down
4 changes: 2 additions & 2 deletions pkg/image/pull_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ func parseDurationString(durationStr string) (time.Duration, error) {
return time.Duration(totalMinutes) * time.Minute, nil
}

func (f *Fetcher) PruneOldImages() error {
imageJSON, err := ReadImageJSON(f.logger)
func PruneOldImages(l logging.Logger, f *Fetcher) error {
imageJSON, err := ReadImageJSON(l)
if err != nil {
return err
}
Expand Down

0 comments on commit a14beb6

Please sign in to comment.