github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/test/groovy/ContainerPushToRegistryTest.groovy (about) 1 #!groovy 2 import org.junit.After 3 import org.junit.Before 4 import org.junit.Rule 5 import org.junit.Test 6 import org.junit.rules.ExpectedException 7 import org.junit.rules.RuleChain 8 import util.BasePiperTest 9 import util.JenkinsCredentialsRule 10 import util.JenkinsDockerExecuteRule 11 import util.JenkinsReadYamlRule 12 import util.JenkinsShellCallRule 13 import util.JenkinsStepRule 14 import util.Rules 15 16 import com.sap.piper.Utils 17 18 import static org.hamcrest.CoreMatchers.containsString 19 import static org.hamcrest.CoreMatchers.hasItem 20 import static org.hamcrest.CoreMatchers.is 21 import static org.hamcrest.CoreMatchers.not 22 import static org.junit.Assert.assertThat 23 24 class ContainerPushToRegistryTest extends BasePiperTest { 25 private ExpectedException exception = ExpectedException.none() 26 private JenkinsStepRule stepRule = new JenkinsStepRule(this) 27 private JenkinsDockerExecuteRule dockerRule = new JenkinsDockerExecuteRule(this) 28 private JenkinsShellCallRule shellCallRule = new JenkinsShellCallRule(this) 29 30 @Rule 31 public RuleChain rules = Rules 32 .getCommonRules(this) 33 .around(new JenkinsReadYamlRule(this)) 34 .around(exception) 35 .around(shellCallRule) 36 .around(dockerRule) 37 .around(new JenkinsCredentialsRule(this) 38 .withCredentials('testCredentialsId', 'registryUser', '********') 39 ) 40 .around(stepRule) 41 42 def dockerMock = new DockerMock('test') 43 44 class DockerMock { 45 46 LinkedList<DockerRegistry> registries 47 String image 48 49 DockerMock(name){ 50 this.image = name 51 this.registries = [] as LinkedList 52 } 53 def withRegistry(paramRegistry, paramCredentials, paramClosure){ 54 this.registries.add(new DockerRegistry(paramRegistry, paramCredentials, paramCredentials? false : true)) 55 return paramClosure() 56 } 57 def withRegistry(paramRegistry, paramClosure){ 58 return withRegistry(paramRegistry, null, paramClosure) 59 } 60 61 def image(name) { 62 this.image = name 63 return new ContainerImageMock() 64 } 65 66 protected DockerRegistry getSourceRegistry() { 67 if (registries.size() == 1) { 68 return null; 69 } 70 return registries.first 71 } 72 protected DockerRegistry getTargetRegistry() { 73 if (registries.size() == 1) { 74 return registries.first 75 } 76 return registries.last 77 } 78 } 79 80 class DockerRegistry { 81 final boolean isAnonymous 82 final String credentials 83 final String url 84 85 DockerRegistry(url, credentials, isAnonymous) { 86 this.url = url 87 this.credentials = credentials 88 this.isAnonymous = isAnonymous 89 } 90 } 91 92 def dockerMockPushes = [] 93 def dockerMockPull = false 94 class ContainerImageMock { 95 ContainerImageMock(){} 96 def push(tag){ 97 dockerMockPushes.add(tag) 98 } 99 def push(){ 100 push('default') 101 } 102 103 def pull(){ 104 dockerMockPull = true 105 } 106 } 107 108 @Before 109 void init() { 110 binding.setVariable('docker', dockerMock) 111 Utils.metaClass.echo = { def m -> } 112 } 113 114 @After 115 public void tearDown() { 116 Utils.metaClass = null 117 } 118 119 @Test 120 void testNoImageProvided() { 121 exception.expectMessage(containsString('Please provide a dockerImage')) 122 stepRule.step.containerPushToRegistry( 123 script: nullScript, 124 dockerRegistryUrl: 'https://testRegistry', 125 dockerCredentialsId: 'testCredentialsId', 126 ) 127 } 128 129 @Test 130 void testDefault() { 131 stepRule.step.containerPushToRegistry( 132 script: nullScript, 133 dockerRegistryUrl: 'https://testRegistry', 134 dockerCredentialsId: 'testCredentialsId', 135 dockerImage: 'testImage:tag', 136 ) 137 138 assertThat(dockerMock.targetRegistry.url, is('https://testRegistry')) 139 assertThat(dockerMock.targetRegistry.credentials, is('testCredentialsId')) 140 assertThat(dockerMock.image, is('testImage:tag')) 141 assertThat(dockerMockPushes, hasItem('default')) 142 assertThat(dockerMockPushes, not(hasItem('latest'))) 143 } 144 145 @Test 146 void testBuildImagePushLatest() { 147 def dockerBuildImage = new ContainerImageMock() 148 stepRule.step.containerPushToRegistry( 149 script: nullScript, 150 dockerRegistryUrl: 'https://testRegistry', 151 dockerCredentialsId: 'testCredentialsId', 152 dockerBuildImage: dockerBuildImage, 153 tagLatest: true 154 ) 155 156 assertThat(dockerMock.targetRegistry.url, is('https://testRegistry')) 157 assertThat(dockerMock.targetRegistry.credentials, is('testCredentialsId')) 158 assertThat(dockerMock.sourceRegistry, is (null)) 159 assertThat(dockerMock.image, is('test')) 160 assertThat(dockerMockPushes, hasItem('default')) 161 assertThat(dockerMockPushes, hasItem('latest')) 162 } 163 164 @Test 165 void testBuildImagePushArtifactVersion() throws Exception { 166 nullScript.commonPipelineEnvironment.setArtifactVersion('1.0.0') 167 def dockerBuildImage = new ContainerImageMock() 168 stepRule.step.containerPushToRegistry( 169 script: nullScript, 170 dockerRegistryUrl: 'https://testRegistry', 171 dockerCredentialsId: 'testCredentialsId', 172 dockerBuildImage: dockerBuildImage, 173 tagArtifactVersion: true 174 ) 175 176 assertThat(dockerMock.targetRegistry.url, is('https://testRegistry')) 177 assertThat(dockerMock.targetRegistry.credentials, is('testCredentialsId')) 178 assertThat(dockerMock.sourceRegistry, is (null)) 179 assertThat(dockerMock.image, is('test')) 180 assertThat(dockerMockPushes, hasItem('default')) 181 assertThat(dockerMockPushes, not(hasItem('latest'))) 182 assertThat(dockerMockPushes, hasItem('1.0.0')) 183 } 184 185 @Test 186 void testBuildImagePushLatestAndArtifactVersion() throws Exception { 187 nullScript.commonPipelineEnvironment.setArtifactVersion('1.0.0') 188 def dockerBuildImage = new ContainerImageMock() 189 stepRule.step.containerPushToRegistry( 190 script: nullScript, 191 dockerRegistryUrl: 'https://testRegistry', 192 dockerCredentialsId: 'testCredentialsId', 193 dockerBuildImage: dockerBuildImage, 194 tagArtifactVersion: true, 195 tagLatest: true 196 ) 197 198 assertThat(dockerMock.targetRegistry.url, is('https://testRegistry')) 199 assertThat(dockerMock.targetRegistry.credentials, is('testCredentialsId')) 200 assertThat(dockerMock.sourceRegistry, is (null)) 201 assertThat(dockerMock.image, is('test')) 202 assertThat(dockerMockPushes, hasItem('default')) 203 assertThat(dockerMockPushes, hasItem('latest')) 204 assertThat(dockerMockPushes, hasItem('1.0.0')) 205 } 206 207 @Test 208 void testFromEnv() { 209 nullScript.commonPipelineEnvironment.setValue('containerImage', 'path/testImage:tag') 210 nullScript.commonPipelineEnvironment.setValue('containerRegistryUrl', 'https://testRegistry:55555') 211 212 stepRule.step.containerPushToRegistry( 213 script: nullScript, 214 dockerRegistryUrl: 'https://testRegistry', 215 dockerCredentialsId: 'testCredentialsId', 216 ) 217 218 assertThat(dockerMock.sourceRegistry.url, is('https://testRegistry:55555')) 219 assertThat(dockerMock.sourceRegistry.isAnonymous, is(true)) 220 assertThat(dockerMock.targetRegistry.url, is('https://testRegistry')) 221 assertThat(dockerMock.targetRegistry.credentials, is('testCredentialsId')) 222 assertThat(dockerMock.targetRegistry.isAnonymous, is(false)) 223 assertThat(dockerMock.image, is('path/testImage:tag')) 224 assertThat(shellCallRule.shell, hasItem('docker tag testRegistry:55555/path/testImage:tag path/testImage:tag')) 225 assertThat(dockerMockPull, is(true)) 226 } 227 228 @Test 229 void testWithSourceImageAndRegistry() { 230 stepRule.step.containerPushToRegistry( 231 script: nullScript, 232 dockerCredentialsId: 'testCredentialsId', 233 dockerRegistryUrl: 'https://testRegistry', 234 sourceImage: 'testSourceName:testSourceTag', 235 sourceRegistryUrl: 'http://testSourceRegistry' 236 ) 237 238 assertThat(dockerMock.sourceRegistry.url, is('http://testSourceRegistry')) 239 assertThat(dockerMock.image, is('testSourceName:testSourceTag')) 240 assertThat(dockerMock.sourceRegistry.isAnonymous, is(true)) 241 assertThat(shellCallRule.shell, hasItem('docker tag testSourceRegistry/testSourceName:testSourceTag testSourceName:testSourceTag')) 242 assertThat(dockerMockPull, is(true)) 243 } 244 245 @Test 246 void testWithSourceAndTarget() { 247 stepRule.step.containerPushToRegistry( 248 script: nullScript, 249 dockerCredentialsId: 'testCredentialsId', 250 dockerImage: 'testImage:tag', 251 dockerRegistryUrl: 'https://testRegistry', 252 sourceImage: 'testSourceName:testSourceTag', 253 sourceRegistryUrl: 'http://testSourceRegistry' 254 ) 255 256 assertThat(dockerMock.sourceRegistry.url, is('http://testSourceRegistry')) 257 assertThat(dockerMock.sourceRegistry.isAnonymous, is(true)) 258 assertThat(dockerMock.image, is('testSourceName:testSourceTag')) 259 assertThat(shellCallRule.shell, hasItem('docker tag testSourceRegistry/testSourceName:testSourceTag testImage:tag')) 260 assertThat(dockerMockPull, is(true)) 261 } 262 263 @Test 264 void testWithAuthenticatedSourceAndTarget() { 265 stepRule.step.containerPushToRegistry( 266 script: nullScript, 267 dockerCredentialsId: 'testCredentialsId', 268 dockerImage: 'testImage:tag', 269 dockerRegistryUrl: 'https://testRegistry', 270 sourceCredentialsId: 'testSourceCredentialsId', 271 sourceImage: 'testSourceName:testSourceTag', 272 sourceRegistryUrl: 'http://testSourceRegistry' 273 ) 274 275 assertThat(dockerMock.sourceRegistry.url, is('http://testSourceRegistry')) 276 assertThat(dockerMock.sourceRegistry.credentials, is('testSourceCredentialsId')) 277 assertThat(dockerMock.targetRegistry.url, is('https://testRegistry')) 278 assertThat(dockerMock.targetRegistry.credentials, is('testCredentialsId')) 279 assertThat(dockerMock.image, is('testSourceName:testSourceTag')) 280 assertThat(shellCallRule.shell, hasItem('docker tag testSourceRegistry/testSourceName:testSourceTag testImage:tag')) 281 assertThat(dockerMockPull, is(true)) 282 } 283 284 @Test 285 void testKubernetesMove() { 286 binding.setVariable('docker', null) 287 shellCallRule.setReturnValue('docker ps -q > /dev/null', 1) 288 289 stepRule.step.containerPushToRegistry( 290 script: nullScript, 291 dockerCredentialsId: 'testCredentialsId', 292 dockerImage: 'testImage:tag', 293 dockerRegistryUrl: 'https://my.registry:55555', 294 skopeoImage: 'skopeo:latest', 295 sourceImage: 'sourceImage:sourceTag', 296 sourceRegistryUrl: 'https://my.source.registry:44444', 297 ) 298 299 assertThat(shellCallRule.shell, hasItem('skopeo copy --multi-arch=all --src-tls-verify=false --dest-tls-verify=false --dest-creds=\'registryUser\':\'********\' docker://my.source.registry:44444/sourceImage:sourceTag docker://my.registry:55555/testImage:tag')) 300 assertThat(dockerRule.dockerParams.dockerImage, is('skopeo:latest')) 301 } 302 303 @Test 304 void testKubernetesMoveTagLatest() { 305 binding.setVariable('docker', null) 306 shellCallRule.setReturnValue('docker ps -q > /dev/null', 1) 307 308 stepRule.step.containerPushToRegistry( 309 script: nullScript, 310 dockerCredentialsId: 'testCredentialsId', 311 dockerImage: 'testImage:tag', 312 dockerRegistryUrl: 'https://my.registry:55555', 313 sourceImage: 'sourceImage:sourceTag', 314 sourceRegistryUrl: 'https://my.source.registry:44444', 315 sourceCredentialsId: 'testCredentialsId', 316 tagLatest: true 317 ) 318 319 assertThat(shellCallRule.shell, hasItem('skopeo copy --multi-arch=all --src-tls-verify=false --src-creds=\'registryUser\':\'********\' --dest-tls-verify=false --dest-creds=\'registryUser\':\'********\' docker://my.source.registry:44444/sourceImage:sourceTag docker://my.registry:55555/testImage:tag')) 320 assertThat(shellCallRule.shell, hasItem('skopeo copy --multi-arch=all --src-tls-verify=false --src-creds=\'registryUser\':\'********\' --dest-tls-verify=false --dest-creds=\'registryUser\':\'********\' docker://my.source.registry:44444/sourceImage:sourceTag docker://my.registry:55555/testImage:latest')) 321 } 322 323 @Test 324 void testKubernetesMoveTagArtifactVersion() { 325 nullScript.commonPipelineEnvironment.setArtifactVersion('1.0.0') 326 binding.setVariable('docker', null) 327 shellCallRule.setReturnValue('docker ps -q > /dev/null', 1) 328 329 stepRule.step.containerPushToRegistry( 330 script: nullScript, 331 dockerCredentialsId: 'testCredentialsId', 332 dockerImage: 'testImage:tag', 333 dockerRegistryUrl: 'https://my.registry:55555', 334 sourceImage: 'sourceImage:sourceTag', 335 sourceRegistryUrl: 'https://my.source.registry:44444', 336 sourceCredentialsId: 'testCredentialsId', 337 tagArtifactVersion: true 338 ) 339 340 assertThat(shellCallRule.shell, hasItem('skopeo copy --multi-arch=all --src-tls-verify=false --src-creds=\'registryUser\':\'********\' --dest-tls-verify=false --dest-creds=\'registryUser\':\'********\' docker://my.source.registry:44444/sourceImage:sourceTag docker://my.registry:55555/testImage:tag')) 341 assertThat(shellCallRule.shell, hasItem('skopeo copy --multi-arch=all --src-tls-verify=false --src-creds=\'registryUser\':\'********\' --dest-tls-verify=false --dest-creds=\'registryUser\':\'********\' docker://my.source.registry:44444/sourceImage:sourceTag docker://my.registry:55555/testImage:1.0.0')) 342 } 343 344 @Test 345 void testKubernetesMoveTagLatestAndArtifactVersion() { 346 nullScript.commonPipelineEnvironment.setArtifactVersion('1.0.0') 347 binding.setVariable('docker', null) 348 shellCallRule.setReturnValue('docker ps -q > /dev/null', 1) 349 350 stepRule.step.containerPushToRegistry( 351 script: nullScript, 352 dockerCredentialsId: 'testCredentialsId', 353 dockerImage: 'testImage:tag', 354 dockerRegistryUrl: 'https://my.registry:55555', 355 sourceImage: 'sourceImage:sourceTag', 356 sourceRegistryUrl: 'https://my.source.registry:44444', 357 sourceCredentialsId: 'testCredentialsId', 358 tagLatest: true, 359 tagArtifactVersion: true 360 ) 361 362 assertThat(shellCallRule.shell, hasItem('skopeo copy --multi-arch=all --src-tls-verify=false --src-creds=\'registryUser\':\'********\' --dest-tls-verify=false --dest-creds=\'registryUser\':\'********\' docker://my.source.registry:44444/sourceImage:sourceTag docker://my.registry:55555/testImage:tag')) 363 assertThat(shellCallRule.shell, hasItem('skopeo copy --multi-arch=all --src-tls-verify=false --src-creds=\'registryUser\':\'********\' --dest-tls-verify=false --dest-creds=\'registryUser\':\'********\' docker://my.source.registry:44444/sourceImage:sourceTag docker://my.registry:55555/testImage:latest')) 364 assertThat(shellCallRule.shell, hasItem('skopeo copy --multi-arch=all --src-tls-verify=false --src-creds=\'registryUser\':\'********\' --dest-tls-verify=false --dest-creds=\'registryUser\':\'********\' docker://my.source.registry:44444/sourceImage:sourceTag docker://my.registry:55555/testImage:1.0.0')) 365 } 366 367 @Test 368 void testKubernetesSourceOnly() { 369 binding.setVariable('docker', null) 370 shellCallRule.setReturnValue('docker ps -q > /dev/null', 1) 371 372 stepRule.step.containerPushToRegistry( 373 script: nullScript, 374 dockerCredentialsId: 'testCredentialsId', 375 dockerRegistryUrl: 'https://my.registry:55555', 376 sourceImage: 'sourceImage:sourceTag', 377 sourceRegistryUrl: 'https://my.source.registry:44444', 378 ) 379 380 assertThat(shellCallRule.shell, hasItem('skopeo copy --multi-arch=all --src-tls-verify=false --dest-tls-verify=false --dest-creds=\'registryUser\':\'********\' docker://my.source.registry:44444/sourceImage:sourceTag docker://my.registry:55555/sourceImage:sourceTag')) 381 } 382 383 @Test 384 void testKubernetesSourceRegistryFromEnv() { 385 binding.setVariable('docker', null) 386 shellCallRule.setReturnValue('docker ps -q > /dev/null', 1) 387 388 nullScript.commonPipelineEnvironment.setValue('containerImage', 'sourceImage:sourceTag') 389 nullScript.commonPipelineEnvironment.setValue('containerRegistryUrl', 'https://my.source.registry:44444') 390 391 stepRule.step.containerPushToRegistry( 392 script: nullScript, 393 dockerCredentialsId: 'testCredentialsId', 394 dockerRegistryUrl: 'https://my.registry:55555', 395 sourceImage: 'sourceImage:sourceTag', 396 sourceCredentialsId: 'testCredentialsId' 397 ) 398 399 assertThat(shellCallRule.shell, hasItem('skopeo copy --multi-arch=all --src-tls-verify=false --src-creds=\'registryUser\':\'********\' --dest-tls-verify=false --dest-creds=\'registryUser\':\'********\' docker://my.source.registry:44444/sourceImage:sourceTag docker://my.registry:55555/sourceImage:sourceTag')) 400 } 401 402 @Test 403 void testKubernetesPushTar() { 404 binding.setVariable('docker', null) 405 shellCallRule.setReturnValue('docker ps -q > /dev/null', 1) 406 407 exception.expectMessage('Only moving images') 408 stepRule.step.containerPushToRegistry( 409 script: nullScript, 410 dockerCredentialsId: 'testCredentialsId', 411 dockerArchive: 'myImage.tar', 412 dockerImage: 'testImage:tag', 413 dockerRegistryUrl: 'https://my.registry:55555', 414 ) 415 } 416 }