From a14beb6048d7a707b26d1e2e3535cbd58b84901c Mon Sep 17 00:00:00 2001 From: Parthiba-Hazra Date: Tue, 5 Mar 2024 13:56:28 +0530 Subject: [PATCH] Test: Update the fetcher test cases Signed-off-by: Parthiba-Hazra --- pkg/image/fetcher.go | 20 +++++-- pkg/image/fetcher_test.go | 114 ++++++++++++++++++++++++++++++-------- pkg/image/pull_policy.go | 4 +- 3 files changed, 107 insertions(+), 31 deletions(-) diff --git a/pkg/image/fetcher.go b/pkg/image/fetcher.go index 363669bae..3bd965d03 100644 --- a/pkg/image/fetcher.go +++ b/pkg/image/fetcher.go @@ -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 { @@ -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) } @@ -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 } } @@ -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 } @@ -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) { diff --git a/pkg/image/fetcher_test.go b/pkg/image/fetcher_test.go index d1ea37e35..87b5c0e2e 100644 --- a/pkg/image/fetcher_test.go +++ b/pkg/image/fetcher_test.go @@ -8,6 +8,7 @@ import ( "path/filepath" "runtime" "testing" + "time" "github.com/buildpacks/imgutil" @@ -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 { @@ -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) { @@ -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 } }) @@ -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) }) }) @@ -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) }) @@ -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) }) }) @@ -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) { @@ -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 } }) @@ -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) }) }) @@ -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) }) }) diff --git a/pkg/image/pull_policy.go b/pkg/image/pull_policy.go index 1ba08303f..0322ee0e7 100644 --- a/pkg/image/pull_policy.go +++ b/pkg/image/pull_policy.go @@ -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 }