@@ -16,6 +16,7 @@ package proxy
1616
1717import (
1818 "context"
19+ "fmt"
1920 "io"
2021 "testing"
2122
@@ -31,6 +32,8 @@ import (
3132 "github.com/goharbor/harbor/src/lib/errors"
3233 proModels "github.com/goharbor/harbor/src/pkg/project/models"
3334 testproxy "github.com/goharbor/harbor/src/testing/controller/proxy"
35+ "github.com/goharbor/harbor/src/testing/lib/cache"
36+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
3437)
3538
3639type localInterfaceMock struct {
@@ -64,6 +67,17 @@ func (l *localInterfaceMock) PushBlob(localRepo string, desc distribution.Descri
6467 panic ("implement me" )
6568}
6669
70+ func (l * localInterfaceMock ) PullManifest (repo string , ref string ) (distribution.Manifest , string , error ) {
71+ args := l .Called (repo , ref )
72+
73+ var d distribution.Manifest
74+ if arg := args .Get (0 ); arg != nil {
75+ d = arg .(distribution.Manifest )
76+ }
77+
78+ return d , args .String (1 ), args .Error (2 )
79+ }
80+
6781func (l * localInterfaceMock ) PushManifest (repo string , tag string , manifest distribution.Manifest ) error {
6882 args := l .Called (repo , tag , manifest )
6983 return args .Error (0 )
@@ -84,7 +98,7 @@ type proxyControllerTestSuite struct {
8498 suite.Suite
8599 local * localInterfaceMock
86100 remote * testproxy.RemoteInterface
87- ctr Controller
101+ ctr * controller
88102 proj * proModels.Project
89103}
90104
@@ -114,12 +128,15 @@ func (p *proxyControllerTestSuite) TestUseLocalManifest_False() {
114128 ctx := context .Background ()
115129 dig := "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b"
116130 desc := & distribution.Descriptor {Digest : digest .Digest (dig )}
117- art := lib.ArtifactInfo {Repository : "library/hello-world" , Digest : dig }
131+ repo := "library/hello-world"
132+ art := lib.ArtifactInfo {Repository : repo , Digest : dig }
118133 p .remote .On ("ManifestExist" , mock .Anything , mock .Anything ).Return (true , desc , nil )
119134 p .local .On ("GetManifest" , mock .Anything , mock .Anything ).Return (nil , nil )
135+ p .local .On ("PullManifest" , repo , string (desc .Digest )).Times (1 ).Return (nil , "" , fmt .Errorf ("could not pull manifest" ))
120136 result , _ , err := p .ctr .UseLocalManifest (ctx , art , p .remote )
121137 p .Assert ().Nil (err )
122138 p .Assert ().False (result )
139+ p .local .AssertExpectations (p .T ())
123140}
124141
125142func (p * proxyControllerTestSuite ) TestUseLocalManifest_429 () {
@@ -157,6 +174,93 @@ func (p *proxyControllerTestSuite) TestUseLocalManifestWithTag_False() {
157174 p .Assert ().False (result )
158175}
159176
177+ func (p * proxyControllerTestSuite ) TestUseLocalManifestWithTag_LocalRepoTrueManifest () {
178+ manifest := `{
179+ "schemaVersion": 2,
180+ "mediaType": "application/vnd.oci.image.manifest.v1+json",
181+ "config": {
182+ "mediaType": "application/vnd.example.config.v1+json",
183+ "digest": "sha256:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03",
184+ "size": 123
185+ },
186+ "layers": [
187+ {
188+ "mediaType": "application/vnd.example.data.v1.tar+gzip",
189+ "digest": "sha256:e258d248fda94c63753607f7c4494ee0fcbe92f1a76bfdac795c9d84101eb317",
190+ "size": 1234
191+ }
192+ ],
193+ "annotations": {
194+ "com.example.key1": "value1"
195+ }
196+ }`
197+ man , desc , err := distribution .UnmarshalManifest (v1 .MediaTypeImageManifest , []byte (manifest ))
198+ p .Require ().NoError (err )
199+ mediaType , payload , err := man .Payload ()
200+ p .Require ().NoError (err )
201+
202+ ctx := context .Background ()
203+ repo := "library/hello-world"
204+ art := lib.ArtifactInfo {Repository : repo , Tag : "latest" }
205+ p .local .On ("GetManifest" , mock .Anything , mock .Anything ).Return (& artifact.Artifact {}, nil )
206+ p .remote .On ("ManifestExist" , mock .Anything , mock .Anything ).Return (true , & desc , nil )
207+ p .local .On ("PullManifest" , repo , string (desc .Digest )).Times (1 ).Return (man , string (desc .Digest ), nil )
208+
209+ result , manifests , err := p .ctr .UseLocalManifest (ctx , art , p .remote )
210+
211+ p .Assert ().NoError (err )
212+ p .Assert ().True (result )
213+ p .Assert ().NotNil (manifests )
214+ p .Assert ().Equal (mediaType , manifests .ContentType ())
215+ p .Assert ().Equal (string (desc .Digest ), manifests .Digest ())
216+ p .Assert ().Equal (payload , manifests .Content ())
217+
218+ p .local .AssertExpectations (p .T ())
219+ }
220+
221+ func (p * proxyControllerTestSuite ) TestUseLocalManifestWithTag_CacheTrueManifestList () {
222+ c := cache .NewCache (p .T ())
223+ p .ctr .cache = c
224+
225+ ctx := context .Background ()
226+ repo := "library/hello-world"
227+ art := lib.ArtifactInfo {Repository : repo , Tag : "latest" }
228+ dig := "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b"
229+ desc := & distribution.Descriptor {Digest : digest .Digest (dig )}
230+ content := "some content"
231+ contentType := "some content type"
232+ p .local .On ("GetManifest" , mock .Anything , mock .Anything ).Return (& artifact.Artifact {}, nil )
233+ p .remote .On ("ManifestExist" , mock .Anything , mock .Anything ).Return (true , desc , nil )
234+ p .local .On ("PullManifest" , repo , string (desc .Digest )).Times (1 ).Return (nil , "" , fmt .Errorf ("could not pull manifest" ))
235+ artInfoWithDigest := art
236+ artInfoWithDigest .Digest = dig
237+ c .On ("Fetch" , mock .Anything , manifestListKey (art .Repository , artInfoWithDigest ), mock .Anything ).
238+ Times (1 ).
239+ Run (func (args mock.Arguments ) {
240+ ct := args .Get (2 ).(* []byte )
241+ * ct = []byte (content )
242+ }).
243+ Return (nil )
244+ c .On ("Fetch" , mock .Anything , manifestListContentTypeKey (art .Repository , artInfoWithDigest ), mock .Anything ).
245+ Times (1 ).
246+ Run (func (args mock.Arguments ) {
247+ ct := args .Get (2 ).(* string )
248+ * ct = contentType
249+ }).
250+ Return (nil )
251+
252+ result , manifests , err := p .ctr .UseLocalManifest (ctx , art , p .remote )
253+
254+ p .Assert ().NoError (err )
255+ p .Assert ().True (result )
256+ p .Assert ().NotNil (manifests )
257+ p .Assert ().Equal (contentType , manifests .ContentType ())
258+ p .Assert ().Equal (string (desc .Digest ), manifests .Digest ())
259+ p .Assert ().Equal ([]byte (content ), manifests .Content ())
260+
261+ p .local .AssertExpectations (p .T ())
262+ }
263+
160264func (p * proxyControllerTestSuite ) TestUseLocalBlob_True () {
161265 ctx := context .Background ()
162266 dig := "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b"
0 commit comments