github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/test/groovy/DockerExecuteOnKubernetesTest.groovy (about) 1 import com.sap.piper.JenkinsUtils 2 import com.sap.piper.Utils 3 4 import org.junit.After 5 import org.junit.Before 6 import org.junit.Rule 7 import org.junit.Test 8 import org.junit.rules.ExpectedException 9 import org.junit.rules.RuleChain 10 11 import groovy.json.JsonSlurper 12 import util.BasePiperTest 13 import util.JenkinsDockerExecuteRule 14 import util.JenkinsLoggingRule 15 import util.JenkinsReadYamlRule 16 import util.JenkinsShellCallRule 17 import util.JenkinsStepRule 18 import util.PluginMock 19 import util.Rules 20 21 import hudson.AbortException 22 23 import static org.hamcrest.Matchers.* 24 import static org.junit.Assert.assertThat 25 import static org.junit.Assert.assertTrue 26 import static org.junit.Assert.assertEquals 27 import static org.junit.Assert.assertFalse 28 import static org.junit.Assert.assertNotNull 29 import static org.junit.Assert.assertNull 30 31 class DockerExecuteOnKubernetesTest extends BasePiperTest { 32 private ExpectedException exception = ExpectedException.none() 33 private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this) 34 private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this) 35 private JenkinsStepRule stepRule = new JenkinsStepRule(this) 36 private ExpectedException thrown = new ExpectedException() 37 38 @Rule 39 public RuleChain ruleChain = Rules 40 .getCommonRules(this) 41 .around(new JenkinsReadYamlRule(this)) 42 .around(exception) 43 .around(shellRule) 44 .around(loggingRule) 45 .around(stepRule) 46 .around(thrown) 47 int whichDockerReturnValue = 0 48 def bodyExecuted 49 def dockerImage 50 def containerMap 51 def dockerEnvVars 52 def dockerWorkspace 53 def podName = '' 54 def podLabel = '' 55 def podNodeSelector = '' 56 def containersList = [] 57 def imageList = [] 58 def containerName = '' 59 def containerShell = '' 60 def envList = [] 61 def portList = [] 62 def containerCommands = [] 63 def pullImageMap = [:] 64 def namespace 65 def securityContext 66 def inheritFrom 67 def yamlMergeStrategy 68 def podSpec 69 Map resources = [:] 70 List stashList = [] 71 List unstashList = [] 72 def utilsMock = newUtilsMock() 73 74 Utils newUtilsMock() { 75 def utilsMock = new Utils() 76 utilsMock.steps = [ 77 stash : { m -> stashList.add(m) }, 78 unstash : { m -> unstashList.add(m) } 79 ] 80 utilsMock.echo = { def m -> } 81 return utilsMock 82 } 83 84 @Before 85 void init() { 86 containersList = [] 87 imageList = [] 88 envList = [] 89 portList = [] 90 containerCommands = [] 91 resources = [:] 92 bodyExecuted = false 93 podSpec = null 94 JenkinsUtils.metaClass.static.isPluginActive = { def s -> new PluginMock(s).isActive() } 95 helper.registerAllowedMethod('sh', [Map.class], { return whichDockerReturnValue }) 96 helper.registerAllowedMethod('container', [Map.class, Closure.class], { Map config, Closure body -> 97 container(config) { 98 body() 99 } 100 }) 101 helper.registerAllowedMethod('merge', [], { 102 return 'merge' 103 }) 104 helper.registerAllowedMethod('podTemplate', [Map.class, Closure.class], { Map options, Closure body -> 105 podName = options.name 106 podLabel = options.label 107 namespace = options.namespace 108 inheritFrom = options.inheritFrom 109 yamlMergeStrategy = options.yamlMergeStrategy 110 podNodeSelector = options.nodeSelector 111 podSpec = new JsonSlurper().parseText(options.yaml) // this yaml is actually json 112 def containers = podSpec.spec.containers 113 securityContext = podSpec.spec.securityContext 114 115 containers.each { container -> 116 containersList.add(container.name) 117 imageList.add(container.image.toString()) 118 envList.add(container.env) 119 if (container.ports) { 120 portList.add(container.ports) 121 } 122 if (container.command) { 123 containerCommands.add(container.command) 124 } 125 pullImageMap.put(container.image.toString(), container.imagePullPolicy == "Always") 126 resources.put(container.name, container.resources) 127 } 128 body() 129 }) 130 } 131 132 @Test 133 void testRunOnPodNoContainerMapOnlyDockerImage() throws Exception { 134 stepRule.step.dockerExecuteOnKubernetes( 135 script: nullScript, 136 juStabUtils: utilsMock, 137 dockerImage: 'maven:3.5-jdk-8-alpine', 138 dockerOptions: '-it', 139 dockerVolumeBind: ['my_vol': '/my_vol'], 140 dockerEnvVars: ['http_proxy': 'http://proxy:8000'], dockerWorkspace: '/home/piper' 141 ) { 142 bodyExecuted = true 143 } 144 assertThat(containersList, hasItem('container-exec')) 145 assertThat(imageList, hasItem('maven:3.5-jdk-8-alpine')) 146 assertThat(envList.toString(), containsString('http_proxy')) 147 assertThat(envList.toString(), containsString('http://proxy:8000')) 148 assertThat(envList.toString(), containsString('/home/piper')) 149 assertThat(bodyExecuted, is(true)) 150 assertThat(containerCommands.size(), is(1)) 151 } 152 153 @Test 154 void testDockerExecuteOnKubernetesEmptyContainerMapNoDockerImage() throws Exception { 155 stepRule.step.dockerExecuteOnKubernetes( 156 script: nullScript, 157 juStabUtils: utilsMock, 158 containerMap: [:], 159 dockerEnvVars: ['customEnvKey': 'customEnvValue']) { 160 bodyExecuted = true 161 } 162 assertTrue(bodyExecuted) 163 } 164 165 @Test 166 void testDockerExecuteOnKubernetesWithCustomContainerMap() throws Exception { 167 stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, 168 containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute']) { 169 container(name: 'mavenexecute') { 170 bodyExecuted = true 171 } 172 } 173 assertEquals('mavenexecute', containerName) 174 assertTrue(containersList.contains('mavenexecute')) 175 assertTrue(imageList.contains('maven:3.5-jdk-8-alpine')) 176 assertTrue(bodyExecuted) 177 assertThat(containerCommands.size(), is(1)) 178 } 179 180 @Test 181 void testInheritFromPodTemplate() throws Exception { 182 nullScript.commonPipelineEnvironment.configuration = ['general': ['jenkinsKubernetes': ['inheritFrom': 'default']]] 183 stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, 184 containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute']) { 185 container(name: 'mavenexecute') { 186 bodyExecuted = true 187 } 188 } 189 assertEquals(inheritFrom, 'default') 190 assertEquals(yamlMergeStrategy, 'merge') 191 assertTrue(bodyExecuted) 192 } 193 194 @Test 195 void testDockerExecuteOnKubernetesWithCustomJnlpWithContainerMap() throws Exception { 196 nullScript.commonPipelineEnvironment.configuration = ['general': ['jenkinsKubernetes': ['jnlpAgent': 'myJnalpAgent']]] 197 stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, 198 containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute']) { 199 container(name: 'mavenexecute') { 200 bodyExecuted = true 201 } 202 } 203 assertEquals('mavenexecute', containerName) 204 assertTrue(containersList.contains('mavenexecute')) 205 assertTrue(imageList.contains('maven:3.5-jdk-8-alpine')) 206 assertTrue(containersList.contains('jnlp')) 207 assertTrue(imageList.contains('myJnalpAgent')) 208 assertTrue(bodyExecuted) 209 } 210 211 212 @Test 213 void testDockerExecuteOnKubernetesWithCustomJnlpWithDockerImage() throws Exception { 214 nullScript.commonPipelineEnvironment.configuration = ['general': ['jenkinsKubernetes': ['jnlpAgent': 'myJnalpAgent']]] 215 stepRule.step.dockerExecuteOnKubernetes( 216 script: nullScript, 217 juStabUtils: utilsMock, 218 dockerImage: 'maven:3.5-jdk-8-alpine') { 219 bodyExecuted = true 220 } 221 assertEquals('container-exec', containerName) 222 assertTrue(containersList.contains('jnlp')) 223 assertTrue(containersList.contains('container-exec')) 224 assertTrue(imageList.contains('myJnalpAgent')) 225 assertTrue(imageList.contains('maven:3.5-jdk-8-alpine')) 226 assertTrue(bodyExecuted) 227 } 228 229 @Test 230 void testDockerExecuteOnKubernetesWithCustomWorkspace() throws Exception { 231 stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, 232 containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], 233 dockerWorkspace: '/home/piper') { 234 container(name: 'mavenexecute') { 235 bodyExecuted = true 236 } 237 } 238 assertTrue(envList.toString().contains('/home/piper')) 239 assertTrue(bodyExecuted) 240 } 241 242 @Test 243 void testDockerExecuteOnKubernetesWithCustomEnv() throws Exception { 244 stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, 245 containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], 246 dockerEnvVars: ['customEnvKey': 'customEnvValue']) { 247 container(name: 'mavenexecute') { 248 bodyExecuted = true 249 } 250 } 251 assertTrue(envList.toString().contains('customEnvKey') && envList.toString().contains('customEnvValue')) 252 assertTrue(bodyExecuted) 253 } 254 255 @Test 256 void testDockerExecuteOnKubernetesNoResourceLimitsOnEmptyResourcesMap() throws Exception { 257 258 nullScript.commonPipelineEnvironment.configuration = [general: 259 [jenkinsKubernetes: [ 260 resources: [ 261 DEFAULT: [ 262 requests: [ 263 memory: '1Gi', 264 cpu: '0.25' 265 ], 266 limits: [ 267 memory: '2Gi', 268 cpu: '1' 269 ] 270 ], 271 mavenexecute: [:] 272 ] 273 ] 274 ]] 275 stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, 276 containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], { 277 bodyExecuted = true 278 }) 279 280 assertNull(resources.mavenexecute) 281 assertTrue(bodyExecuted) 282 } 283 284 @Test 285 void testDockerExecuteOnKubernetesWithDefaultResourceLimits() throws Exception { 286 287 nullScript.commonPipelineEnvironment.configuration = [general: 288 [jenkinsKubernetes: [ 289 resources: [DEFAULT: [ 290 requests: [ 291 memory: '1Gi', 292 cpu: '0.25' 293 ], 294 limits: [ 295 memory: '2Gi', 296 cpu: '1' 297 ] 298 ] 299 ] 300 ]]] 301 stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, 302 containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], { 303 bodyExecuted = true 304 }) 305 306 assertEquals(requests: [memory: '1Gi',cpu: '0.25'],limits: [memory: '2Gi',cpu: '1'], resources.jnlp) 307 assertEquals(requests: [memory: '1Gi',cpu: '0.25'],limits: [memory: '2Gi',cpu: '1'], resources.mavenexecute) 308 assertTrue(bodyExecuted) 309 } 310 311 @Test 312 void testDockerExecuteOnKubernetesWithSpecificResourcLimitsParametersAreTakingPrecendence() throws Exception { 313 314 // the settings here are expected to be overwritten by the parameters provided via signature 315 nullScript.commonPipelineEnvironment.configuration = [general: 316 [jenkinsKubernetes: [ 317 resources: [ 318 mavenexecute: [ 319 requests: [ 320 memory: '2Gi', 321 cpu: '0.75' 322 ], 323 limits: [ 324 memory: '4Gi', 325 cpu: '2' 326 ] 327 ] 328 ] 329 ]]] 330 stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, 331 containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], 332 resources: [ 333 mavenexecute: [ 334 requests: [ 335 memory: '8Gi', 336 cpu: '2' 337 ], 338 limits: [ 339 memory: '16Gi', 340 cpu: '4' 341 ] 342 ] 343 ]) { 344 bodyExecuted = true 345 } 346 347 assertEquals(requests: [memory: '8Gi',cpu: '2'],limits: [memory: '16Gi',cpu: '4'], resources.mavenexecute) 348 assertTrue(bodyExecuted) 349 } 350 351 @Test 352 void testDockerExecuteOnKubernetesWithSpecificResourceLimits() throws Exception { 353 354 nullScript.commonPipelineEnvironment.configuration = [general: 355 [jenkinsKubernetes: [ 356 resources: [ 357 DEFAULT: [ 358 requests: [ 359 memory: '1Gi', 360 cpu: '0.25' 361 ], 362 limits: [ 363 memory: '2Gi', 364 cpu: '1' 365 ] 366 ], 367 mavenexecute: [ 368 requests: [ 369 memory: '2Gi', 370 cpu: '0.75' 371 ], 372 limits: [ 373 memory: '4Gi', 374 cpu: '2' 375 ] 376 ], 377 jnlp: [ 378 requests: [ 379 memory: '3Gi', 380 cpu: '0.33' 381 ], 382 limits: [ 383 memory: '6Gi', 384 cpu: '3' 385 ] 386 ], 387 mysidecar: [ 388 requests: [ 389 memory: '10Gi', 390 cpu: '5.00' 391 ], 392 limits: [ 393 memory: '20Gi', 394 cpu: '10' 395 ] 396 ] 397 ] 398 ] 399 ]] 400 stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, 401 containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], 402 sidecarImage: 'ubuntu', 403 sidecarName: 'mysidecar') { 404 bodyExecuted = true 405 } 406 407 assertEquals(requests: [memory: '10Gi',cpu: '5.00'],limits: [memory: '20Gi',cpu: '10'], resources.mysidecar) 408 assertEquals(requests: [memory: '3Gi',cpu: '0.33'],limits: [memory: '6Gi',cpu: '3'], resources.jnlp) 409 assertEquals(requests: [memory: '2Gi',cpu: '0.75'],limits: [memory: '4Gi',cpu: '2'], resources.mavenexecute) 410 assertTrue(bodyExecuted) 411 } 412 413 @Test 414 void testDockerExecuteOnKubernetesUpperCaseContainerName() throws Exception { 415 stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, 416 containerMap: ['maven:3.5-jdk-8-alpine': 'MAVENEXECUTE'], 417 dockerEnvVars: ['customEnvKey': 'customEnvValue']) { 418 container(name: 'mavenexecute') { 419 bodyExecuted = true 420 } 421 } 422 assertEquals('mavenexecute', containerName) 423 assertTrue(containersList.contains('mavenexecute')) 424 assertTrue(imageList.contains('maven:3.5-jdk-8-alpine')) 425 assertTrue(bodyExecuted) 426 } 427 428 @Test 429 void testSidecarDefaultWithContainerMap() { 430 List portMapping = [] 431 helper.registerAllowedMethod('portMapping', [Map.class], { m -> 432 portMapping.add(m) 433 return m 434 }) 435 stepRule.step.dockerExecuteOnKubernetes( 436 script: nullScript, 437 juStabUtils: utilsMock, 438 containerCommands: ['selenium/standalone-chrome': ''], 439 containerEnvVars: [ 440 'selenium/standalone-chrome': ['customEnvKey': 'customEnvValue'] 441 ], 442 containerMap: [ 443 'maven:3.5-jdk-8-alpine' : 'mavenexecute', 444 'selenium/standalone-chrome': 'selenium' 445 ], 446 containerName: 'mavenexecute', 447 containerPortMappings: [ 448 'selenium/standalone-chrome': [[containerPort: 4444]] 449 ], 450 containerWorkspaces: [ 451 'selenium/standalone-chrome': '' 452 ], 453 dockerWorkspace: '/home/piper' 454 ) { 455 bodyExecuted = true 456 } 457 458 assertThat(bodyExecuted, is(true)) 459 assertThat(containerName, is('mavenexecute')) 460 461 assertThat(containersList, allOf( 462 hasItem('mavenexecute'), 463 hasItem('selenium'), 464 )) 465 assertThat(imageList, allOf( 466 hasItem('maven:3.5-jdk-8-alpine'), 467 hasItem('selenium/standalone-chrome'), 468 )) 469 assertThat(portList, hasItem([[name: 'selenium0', containerPort: 4444]])) 470 assertThat(containerCommands.size(), is(1)) 471 assertThat(envList, hasItem(hasItem(allOf(hasEntry('name', 'customEnvKey'), hasEntry('value', 'customEnvValue'))))) 472 } 473 474 @Test 475 void testSidecarDefaultWithParameters() { 476 List portMapping = [] 477 helper.registerAllowedMethod('portMapping', [Map.class], { m -> 478 portMapping.add(m) 479 return m 480 }) 481 stepRule.step.dockerExecuteOnKubernetes( 482 script: nullScript, 483 juStabUtils: utilsMock, 484 containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], 485 containerName: 'mavenexecute', 486 dockerOptions: '-it', 487 dockerVolumeBind: ['my_vol': '/my_vol'], 488 dockerEnvVars: ['http_proxy': 'http://proxy:8000'], 489 dockerWorkspace: '/home/piper', 490 sidecarEnvVars: ['testEnv': 'testVal'], 491 sidecarWorkspace: '/home/piper/sidecar', 492 sidecarImage: 'postgres', 493 sidecarName: 'postgres', 494 sidecarReadyCommand: 'pg_isready' 495 ) { 496 bodyExecuted = true 497 } 498 499 assertThat(bodyExecuted, is(true)) 500 501 assertThat(containersList, allOf(hasItem('postgres'), hasItem('mavenexecute'))) 502 assertThat(imageList, allOf(hasItem('maven:3.5-jdk-8-alpine'), hasItem('postgres'))) 503 504 assertThat(envList, hasItem(hasItem(allOf(hasEntry('name', 'testEnv'), hasEntry('value', 'testVal'))))) 505 assertThat(envList, hasItem(hasItem(allOf(hasEntry('name', 'HOME'), hasEntry('value', '/home/piper/sidecar'))))) 506 } 507 508 @Test 509 void testDockerExecuteOnKubernetesWithCustomShell() { 510 stepRule.step.dockerExecuteOnKubernetes( 511 script: nullScript, 512 juStabUtils: utilsMock, 513 dockerImage: 'maven:3.5-jdk-8-alpine', 514 containerShell: '/busybox/sh' 515 ) { 516 //nothing to exeute 517 } 518 assertThat(containerShell, is('/busybox/sh')) 519 } 520 521 @Test 522 void testDockerExecuteOnKubernetesWithCustomContainerCommand() { 523 stepRule.step.dockerExecuteOnKubernetes( 524 script: nullScript, 525 juStabUtils: utilsMock, 526 dockerImage: 'maven:3.5-jdk-8-alpine', 527 containerCommand: '/busybox/tail -f /dev/null' 528 ) { 529 //nothing to exeute 530 } 531 assertThat(containerCommands, hasItem(['/bin/sh', '-c', '/busybox/tail -f /dev/null'])) 532 } 533 534 @Test 535 void testSkipDockerImagePull() throws Exception { 536 stepRule.step.dockerExecuteOnKubernetes( 537 script: nullScript, 538 juStabUtils: utilsMock, 539 dockerPullImage: false, 540 containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'] 541 ) { 542 container(name: 'mavenexecute') { 543 bodyExecuted = true 544 } 545 } 546 assertEquals(false, pullImageMap.get('maven:3.5-jdk-8-alpine')) 547 assertTrue(bodyExecuted) 548 } 549 550 @Test 551 void testSkipSidecarImagePull() throws Exception { 552 stepRule.step.dockerExecuteOnKubernetes( 553 script: nullScript, 554 juStabUtils: utilsMock, 555 containerCommands: ['selenium/standalone-chrome': ''], 556 containerEnvVars: [ 557 'selenium/standalone-chrome': ['customEnvKey': 'customEnvValue'] 558 ], 559 containerMap: [ 560 'maven:3.5-jdk-8-alpine' : 'mavenexecute', 561 'selenium/standalone-chrome': 'selenium' 562 ], 563 containerName: 'mavenexecute', 564 containerWorkspaces: [ 565 'selenium/standalone-chrome': '' 566 ], 567 containerPullImageFlags: [ 568 'maven:3.5-jdk-8-alpine' : true, 569 'selenium/standalone-chrome': false 570 ], 571 dockerWorkspace: '/home/piper' 572 ) { 573 bodyExecuted = true 574 } 575 assertEquals(true, pullImageMap.get('maven:3.5-jdk-8-alpine')) 576 assertEquals(false, pullImageMap.get('selenium/standalone-chrome')) 577 assertTrue(bodyExecuted) 578 } 579 580 @Test 581 void testDockerExecuteOnKubernetesWithCustomNamespace() { 582 def expectedNamespace = "sandbox" 583 nullScript.commonPipelineEnvironment.configuration = [general: [jenkinsKubernetes: [namespace: expectedNamespace]]] 584 585 stepRule.step.dockerExecuteOnKubernetes( 586 script: nullScript, 587 juStabUtils: utilsMock, 588 dockerImage: 'maven:3.5-jdk-8-alpine', 589 ) { bodyExecuted = true } 590 assertTrue(bodyExecuted) 591 assertThat(namespace, is(equalTo(expectedNamespace))) 592 } 593 594 @Test 595 void testDockerExecuteWithAdditionalPodProperties() { 596 nullScript.commonPipelineEnvironment.configuration = [general: [jenkinsKubernetes: [ 597 additionalPodProperties: [ 598 tolerations:[ 599 [ 600 key: "key1", 601 operator: "Equal", 602 value: "value1", 603 effect: "NoSchedule", 604 ], 605 [ 606 key: "key2", 607 operator: "Equal", 608 value: "value2", 609 effect: "NoExecute", 610 ], 611 ], 612 subdomain: 'foo', 613 shareProcessNamespace: false 614 ] 615 ]]] 616 617 stepRule.step.dockerExecuteOnKubernetes( 618 script: nullScript, 619 juStabUtils: utilsMock, 620 dockerImage: 'maven:3.5-jdk-8-alpine', 621 ) { bodyExecuted = true } 622 assertTrue(bodyExecuted) 623 assertEquals( 624 [ 625 [ 626 "key": "key1", 627 "operator": "Equal", 628 "value": "value1", 629 "effect": "NoSchedule" 630 ], 631 [ 632 "key": "key2", 633 "operator": "Equal", 634 "value": "value2", 635 "effect": "NoExecute" 636 ] 637 ], podSpec.spec.tolerations) 638 assertEquals('foo', podSpec.spec.subdomain) 639 assertFalse(podSpec.spec.shareProcessNamespace) 640 assertThat(loggingRule.log, containsString('Additional pod properties found ([tolerations, subdomain, shareProcessNamespace]). Providing additional pod properties is some kind of expert mode. In case of any problems caused by these additional properties only limited support can be provided.')) 641 642 } 643 644 @Test 645 void testDockerExecuteWithAdditionalPodPropertiesContainerPropertyIsNotOverwritten() { 646 nullScript.commonPipelineEnvironment.configuration = [general: [jenkinsKubernetes: [ 647 additionalPodProperties: [ 648 containers:[ 649 [ 650 some: "stupid", 651 stuff: "here", 652 ] 653 ], 654 subdomain: 'foo', 655 shareProcessNamespace: false, 656 ] 657 ]]] 658 659 stepRule.step.dockerExecuteOnKubernetes( 660 script: nullScript, 661 juStabUtils: utilsMock, 662 dockerImage: 'maven:3.5-jdk-8-alpine', 663 ) { bodyExecuted = true } 664 assertTrue(bodyExecuted) 665 666 // This is not contained in the configuration above. 667 assertNotNull(podSpec.spec.containers[0].name) 668 669 // This is contained in the config above. 670 assertNull(podSpec.spec.some) 671 assertNull(podSpec.spec.stuff) 672 673 assertEquals('foo', podSpec.spec.subdomain) 674 assertFalse(podSpec.spec.shareProcessNamespace) 675 } 676 677 @Test 678 void testDockerExecuteOnKubernetesWithSecurityContext() { 679 def expectedSecurityContext = [runAsUser: 1000, fsGroup: 1000] 680 nullScript.commonPipelineEnvironment.configuration = [general: [jenkinsKubernetes: [ 681 securityContext: expectedSecurityContext]]] 682 stepRule.step.dockerExecuteOnKubernetes( 683 script: nullScript, 684 juStabUtils: utilsMock, 685 dockerImage: 'maven:3.5-jdk-8-alpine', 686 ) { bodyExecuted = true } 687 assertTrue(bodyExecuted) 688 assertThat(securityContext, is(equalTo(expectedSecurityContext))) 689 } 690 691 @Test 692 void testDockerExecuteOnKubernetesCustomNode() { 693 694 stepRule.step.dockerExecuteOnKubernetes( 695 script: nullScript, 696 juStabUtils: utilsMock, 697 dockerImage: 'maven:3.5-jdk-8-alpine', 698 nodeSelector: 'size:big' 699 ) { bodyExecuted = true } 700 assertTrue(bodyExecuted) 701 assertThat(podNodeSelector, is('size:big')) 702 } 703 704 @Test 705 void testDockerExecuteOnKubernetesCustomJnlpViaEnv() { 706 707 nullScript.commonPipelineEnvironment.configuration = [ 708 general: [jenkinsKubernetes: [jnlpAgent: 'config/jnlp:latest']] 709 ] 710 binding.variables.env.JENKINS_JNLP_IMAGE = 'env/jnlp:latest' 711 stepRule.step.dockerExecuteOnKubernetes( 712 script: nullScript, 713 juStabUtils: utilsMock, 714 dockerImage: 'maven:3.5-jdk-8-alpine', 715 ) { bodyExecuted = true } 716 assertTrue(bodyExecuted) 717 718 assertThat(containersList, allOf( 719 hasItem('jnlp'), 720 hasItem('container-exec') 721 )) 722 assertThat(imageList, allOf( 723 hasItem('env/jnlp:latest'), 724 hasItem('maven:3.5-jdk-8-alpine'), 725 )) 726 } 727 728 @Test 729 void testDockerExecuteOnKubernetesCustomJnlpViaConfig() { 730 731 nullScript.commonPipelineEnvironment.configuration = [ 732 general: [jenkinsKubernetes: [jnlpAgent: 'config/jnlp:latest']] 733 ] 734 //binding.variables.env.JENKINS_JNLP_IMAGE = 'config/jnlp:latest' 735 stepRule.step.dockerExecuteOnKubernetes( 736 script: nullScript, 737 juStabUtils: utilsMock, 738 dockerImage: 'maven:3.5-jdk-8-alpine', 739 ) { bodyExecuted = true } 740 assertTrue(bodyExecuted) 741 742 assertThat(containersList, allOf( 743 hasItem('jnlp'), 744 hasItem('container-exec') 745 )) 746 assertThat(imageList, allOf( 747 hasItem('config/jnlp:latest'), 748 hasItem('maven:3.5-jdk-8-alpine'), 749 )) 750 } 751 752 @Test 753 void testDockerExecuteOnKubernetesExecutionFails() { 754 755 thrown.expect(AbortException) 756 thrown.expectMessage('Execution failed.') 757 758 nullScript.commonPipelineEnvironment.configuration = [ 759 general: [jenkinsKubernetes: [jnlpAgent: 'config/jnlp:latest']] 760 ] 761 //binding.variables.env.JENKINS_JNLP_IMAGE = 'config/jnlp:latest' 762 stepRule.step.dockerExecuteOnKubernetes( 763 script: nullScript, 764 juStabUtils: utilsMock, 765 dockerImage: 'maven:3.5-jdk-8-alpine', 766 ) { throw new AbortException('Execution failed.') } 767 } 768 769 @Test 770 void testDockerExecuteOnKubernetesAnnotations(){ 771 stepRule.step.dockerExecuteOnKubernetes( 772 script: nullScript, 773 juStabUtils: utilsMock, 774 annotations: ['testAnnotation':'testValue'] 775 ) 776 { 777 bodyExecuted = true 778 } 779 assertEquals(['testAnnotation':'testValue'], podSpec.metadata.annotations) 780 } 781 782 @Test 783 void testStashIncludesAndExcludes() { 784 nullScript.commonPipelineEnvironment.configuration = [ 785 steps: [ 786 dockerExecuteOnKubernetes: [ 787 stashExcludes: [ 788 workspace: 'workspace/exclude.test', 789 stashBack: 'container/exclude.test' 790 ], 791 stashIncludes: [ 792 workspace: 'workspace/include.test', 793 stashBack: 'container/include.test' 794 ] 795 ] 796 ] 797 ] 798 stepRule.step.dockerExecuteOnKubernetes( 799 script: nullScript, 800 juStabUtils: utilsMock, 801 dockerImage: 'maven:3.5-jdk-8-alpine', 802 ) { 803 bodyExecuted = true 804 } 805 assertThat(stashList, hasItem(allOf( 806 hasEntry('allowEmpty', true), 807 hasEntry('includes', 'workspace/include.test'), 808 hasEntry('excludes', 'workspace/exclude.test')))) 809 assertThat(stashList, hasItem(allOf( 810 hasEntry('allowEmpty', true), 811 hasEntry('includes', 'container/include.test'), 812 hasEntry('excludes', 'container/exclude.test')))) 813 } 814 815 @Test 816 void testUnstash() { 817 stepRule.step.dockerExecuteOnKubernetes( 818 script: nullScript, 819 juStabUtils: utilsMock, 820 dockerImage: 'maven:3.5-jdk-8-alpine', 821 ) {} 822 assertEquals(2, unstashList.size()) 823 assertTrue(unstashList[0].startsWith('workspace-')) 824 assertTrue(unstashList[1].startsWith('container-')) 825 } 826 827 @Test 828 void testDockerExecuteWithVolumeProperties() { 829 stepRule.step.dockerExecuteOnKubernetes( 830 script: nullScript, 831 juStabUtils: utilsMock, 832 containerName: 'mycontainer', 833 initContainerImage: 'ppiper/cf-cli', 834 dockerImage: 'maven:3.5-jdk-8-alpine', 835 containerMountPath: '/opt', 836 ) { bodyExecuted = true } 837 def containerSpec = podSpec.spec.containers.find{it.image == "maven:3.5-jdk-8-alpine"} 838 def initContainerSpec = podSpec.spec.initContainers[0] 839 assertTrue(bodyExecuted) 840 assertEquals( 841 [[ 842 "name" : "volume", 843 "emptyDir": [:] 844 ]], podSpec.spec.volumes) 845 assertEquals( 846 [[ 847 "name" : "volume", 848 "mountPath": "/opt" 849 ]], containerSpec.volumeMounts) 850 assertEquals( 851 [[ 852 "name" : "volume", 853 "mountPath": "/opt" 854 ]], initContainerSpec.volumeMounts) 855 } 856 857 @Test 858 void testInitContainerDefaultWithParameters() { 859 stepRule.step.dockerExecuteOnKubernetes( 860 script: nullScript, 861 juStabUtils: utilsMock, 862 containerName: 'mycontainer', 863 initContainerImage: 'ppiper/cf-cli@sha256:latest', 864 initContainerCommand: 'cp /usr/local/bin/cf7 /opt/bin/cf', 865 dockerImage: 'maven:3.5-jdk-8-alpine', 866 containerMountPath: '/opt', 867 ) { bodyExecuted = true } 868 def initContainer = podSpec.spec.initContainers[0] 869 def expectedCommandOutput = ["sh", "-c", "cp /usr/local/bin/cf7 /opt/bin/cf"] 870 assertTrue(bodyExecuted) 871 assertEquals("ppiper-cf-cli-sha256-latest", initContainer.name) 872 assertEquals("ppiper/cf-cli@sha256:latest", initContainer.image) 873 assertThat(initContainer.command, is(equalTo(expectedCommandOutput))) 874 } 875 876 @Test 877 void testInitContainerWithoutContainerCommand() { 878 stepRule.step.dockerExecuteOnKubernetes( 879 script: nullScript, 880 juStabUtils: utilsMock, 881 containerName: 'mycontainer', 882 initContainerImage: 'ppiper/cf-cli@sha256:latest', 883 dockerImage: 'maven:3.5-jdk-8-alpine', 884 containerMountPath: '/opt', 885 ) { bodyExecuted = true } 886 def initContainer = podSpec.spec.initContainers[0] 887 def expectedCommandOutput = ["/usr/bin/tail", "-f", "/dev/null"] 888 assertTrue(bodyExecuted) 889 assertThat(initContainer.command, is(equalTo(expectedCommandOutput))) 890 } 891 892 893 private container(options, body) { 894 containerName = options.name 895 containerShell = options.shell 896 body() 897 } 898 }