@@ -179,6 +179,39 @@ func runPushTest(containerManager container.ContainerManagerType, imageName, mod
179
179
validateContainerBuild (tests .DockerBuildName , buildNumber , imagePath , module , 7 , 5 , 7 , t )
180
180
}
181
181
182
+ func loginToArtifactory (t * testing.T , container * tests.TestContainer ) {
183
+ password := * tests .JfrogPassword
184
+ user := * tests .JfrogUser
185
+ if * tests .JfrogAccessToken != "" {
186
+ user = auth .ExtractUsernameFromAccessToken (* tests .JfrogAccessToken )
187
+ password = * tests .JfrogAccessToken
188
+ }
189
+ assert .NoError (t , container .Exec (
190
+ context .Background (),
191
+ "docker" ,
192
+ "login" ,
193
+ tests .RtContainerHostName ,
194
+ "--username=" + user ,
195
+ "--password=" + password ,
196
+ ))
197
+ }
198
+
199
+ func buildBuilderImage (t * testing.T , workspace , dockerfile , containerName string ) * tests.TestContainer {
200
+ ctx := context .Background ()
201
+ testContainer , err := tests .NewContainerRequest ().
202
+ SetDockerfile (workspace , dockerfile , nil ).
203
+ Privileged ().
204
+ Networks (rtNetwork ).
205
+ Name (containerName ).
206
+ Mount (mount.Mount {Type : mount .TypeBind , Source : workspace , Target : "/workspace" , ReadOnly : false }).
207
+ Cmd ("--insecure-registry" , tests .RtContainerHostName ).
208
+ WaitFor (wait .ForLog ("API listen on /var/run/docker.sock" ).WithStartupTimeout (5 * time .Minute )).
209
+ Remove ().
210
+ Build (ctx , true )
211
+ assert .NoError (t , err , "Couldn't create builder image." )
212
+ return testContainer
213
+ }
214
+
182
215
// This test validate the collect build-info flow for fat-manifest images.
183
216
// The way we build the fat manifest and push it to Artifactory is not important.
184
217
// Therefore, this test runs only with docker.
@@ -194,53 +227,30 @@ func TestPushFatManifestImage(t *testing.T) {
194
227
assert .NoError (t , fileutils .CreateDirIfNotExist (workspace ))
195
228
testDataDir := filepath .Join (filepath .FromSlash (tests .GetTestResourcesPath ()), "docker" )
196
229
files , err := os .ReadDir (testDataDir )
197
-
198
230
assert .NoError (t , err )
199
231
for _ , file := range files {
200
232
if ! file .IsDir () {
201
233
_ , err := tests .ReplaceTemplateVariables (filepath .Join (testDataDir , file .Name ()), tests .Out )
202
234
assert .NoError (t , err )
203
235
}
204
236
}
237
+
205
238
// Build the builder image locally.
206
- ctx := context .Background ()
207
- testContainer , err := tests .NewContainerRequest ().
208
- SetDockerfile (workspace , "Dockerfile.Buildx.Fatmanifest" , nil ).
209
- Privileged ().
210
- Networks (rtNetwork ).
211
- Name ("buildx_container" ).
212
- Mount (mount.Mount {Type : mount .TypeBind , Source : workspace , Target : "/workspace" , ReadOnly : false }).
213
- Cmd ("--insecure-registry" , tests .RtContainerHostName ).
214
- // Docker daemon take times to load. In order to check if it's available we wait for a log message to indications that the Docker daemon has finished initializing.
215
- WaitFor (wait .ForLog ("API listen on /var/run/docker.sock" ).WithStartupTimeout (5 * time .Minute )).
216
- Remove ().
217
- Build (ctx , true )
218
- assert .NoError (t , err , "Couldn't run create buildx image." )
219
- defer func () { assert .NoError (t , testContainer .Terminate (ctx )) }()
239
+ testContainer := buildBuilderImage (t , workspace , "Dockerfile.Buildx.Fatmanifest" , "buildx_container" )
240
+ defer func () { assert .NoError (t , testContainer .Terminate (context .Background ())) }()
220
241
221
242
// Enable the builder util in the container.
222
- err = testContainer .Exec (ctx , "sh" , "script.sh" )
243
+ err = testContainer .Exec (context . Background () , "sh" , "script.sh" )
223
244
assert .NoError (t , err )
224
245
225
- // login from the builder container toward the Artifactory.
226
- password := * tests .JfrogPassword
227
- user := * tests .JfrogUser
228
- if * tests .JfrogAccessToken != "" {
229
- user = auth .ExtractUsernameFromAccessToken (* tests .JfrogAccessToken )
230
- password = * tests .JfrogAccessToken
231
- }
232
- assert .NoError (t , testContainer .Exec (
233
- ctx ,
234
- "docker" ,
235
- "login" ,
236
- tests .RtContainerHostName ,
237
- "--username=" + user ,
238
- "--password=" + password ))
246
+ // Login to Artifactory
247
+ loginToArtifactory (t , testContainer )
248
+
239
249
buildxOutputFile := "buildmetadata"
240
250
241
- // Run the builder in the container and push the fat-manifest image to artifactory
251
+ // Run the builder in the container and push the fat-manifest image to Artifactory
242
252
assert .NoError (t , testContainer .Exec (
243
- ctx ,
253
+ context . Background () ,
244
254
"docker" ,
245
255
"buildx" ,
246
256
"build" ,
@@ -263,20 +273,83 @@ func TestPushFatManifestImage(t *testing.T) {
263
273
assert .NoError (t , artifactoryCli .Exec ("build-docker-create" , tests .DockerLocalRepo , "--image-file=" + buildxOutput , "--build-name=" + buildName , "--build-number=" + buildNumber ))
264
274
assert .NoError (t , artifactoryCli .Exec ("build-publish" , buildName , buildNumber ))
265
275
266
- // Validate the published build-info exits
276
+ // Validate the published build-info exists
267
277
publishedBuildInfo , found , err := tests .GetBuildInfo (serverDetails , buildName , buildNumber )
268
- if err != nil {
269
- assert .NoError (t , err )
270
- return
278
+ assert .NoError (t , err )
279
+ assert .True (t , found , "build info was expected to be found" )
280
+ assert .True (t , len (publishedBuildInfo .BuildInfo .Modules ) > 1 )
281
+
282
+ // Validate build-name & build-number properties in all image layers
283
+ searchSpec := spec .NewBuilder ().Pattern (tests .DockerLocalRepo + "/*" ).Build (buildName ).Recursive (true ).BuildSpec ()
284
+ searchCmd := generic .NewSearchCommand ()
285
+ searchCmd .SetServerDetails (serverDetails ).SetSpec (searchSpec )
286
+ reader , err := searchCmd .Search ()
287
+ assert .NoError (t , err )
288
+ totalResults , err := reader .Length ()
289
+ assert .NoError (t , err )
290
+ assert .True (t , totalResults > 1 )
291
+ }
292
+
293
+ func TestPushMultiTaggedImage (t * testing.T ) {
294
+ if ! * tests .TestDocker {
295
+ t .Skip ("Skipping test. To run it, add the '-test.docker=true' option." )
271
296
}
272
- if ! found {
273
- assert .True (t , found , "build info was expected to be found" )
274
- return
297
+
298
+ buildName := "push-multi-tagged" + tests .DockerBuildName
299
+ buildNumber := "1"
300
+
301
+ // Setup workspace
302
+ workspace , err := filepath .Abs (tests .Out )
303
+ assert .NoError (t , err )
304
+ assert .NoError (t , fileutils .CreateDirIfNotExist (workspace ))
305
+ testDataDir := filepath .Join (filepath .FromSlash (tests .GetTestResourcesPath ()), "docker" )
306
+ files , err := os .ReadDir (testDataDir )
307
+ assert .NoError (t , err )
308
+ for _ , file := range files {
309
+ if ! file .IsDir () {
310
+ _ , err := tests .ReplaceTemplateVariables (filepath .Join (testDataDir , file .Name ()), tests .Out )
311
+ assert .NoError (t , err )
312
+ }
275
313
}
276
314
277
- assert .True (t , len (publishedBuildInfo .BuildInfo .Modules ) > 1 )
315
+ // Build the builder image locally
316
+ testContainer := buildBuilderImage (t , workspace , "Dockerfile.Buildx.Fatmanifest" , "buildx_multi_tag_container" )
317
+ defer func () { assert .NoError (t , testContainer .Terminate (context .Background ())) }()
278
318
279
- // Validate build-name & build-number properties in all image layers
319
+ // Enable builder
320
+ assert .NoError (t , testContainer .Exec (context .Background (), "sh" , "script.sh" ))
321
+
322
+ // Login to Artifactory
323
+ loginToArtifactory (t , testContainer )
324
+
325
+ // Build & push image with multiple tags
326
+ imageName1 := path .Join (tests .RtContainerHostName , tests .DockerLocalRepo , tests .DockerImageName + "-multi:v1" )
327
+ imageName2 := path .Join (tests .RtContainerHostName , tests .DockerLocalRepo , tests .DockerImageName + "-multi:latest" )
328
+ buildxOutputFile := "multi-build-metadata"
329
+
330
+ assert .NoError (t , testContainer .Exec (
331
+ context .Background (),
332
+ "docker" , "buildx" , "build" ,
333
+ "--platform" , "linux/amd64,linux/arm64" ,
334
+ "-t" , imageName1 ,
335
+ "-t" , imageName2 ,
336
+ "-f" , "Dockerfile.Fatmanifest" ,
337
+ "--metadata-file" , "/workspace/" + buildxOutputFile ,
338
+ "--push" , "." ,
339
+ ))
340
+
341
+ // Run build-docker-create & publish
342
+ buildxOutput := filepath .Join (workspace , buildxOutputFile )
343
+ assert .NoError (t , artifactoryCli .Exec ("build-docker-create" , tests .DockerLocalRepo , "--image-file=" + buildxOutput , "--build-name=" + buildName , "--build-number=" + buildNumber ))
344
+ assert .NoError (t , artifactoryCli .Exec ("build-publish" , buildName , buildNumber ))
345
+
346
+ // Validate build-info is published
347
+ publishedBuildInfo , found , err := tests .GetBuildInfo (serverDetails , buildName , buildNumber )
348
+ assert .NoError (t , err )
349
+ assert .True (t , found , "build info was expected to be found" )
350
+ assert .True (t , len (publishedBuildInfo .BuildInfo .Modules ) >= 1 )
351
+
352
+ // Validate build-name & build-number properties in all layers
280
353
searchSpec := spec .NewBuilder ().Pattern (tests .DockerLocalRepo + "/*" ).Build (buildName ).Recursive (true ).BuildSpec ()
281
354
searchCmd := generic .NewSearchCommand ()
282
355
searchCmd .SetServerDetails (serverDetails ).SetSpec (searchSpec )
0 commit comments