Stanislav Ovchar
stchar
pipeline
Jenkins
pipeline
JobDSL
Configuration
Seeder
Jenkins
pipeline
JobDSL
E2E Test
Configuration
Seeder
Jenkins
pipeline
JobDSL
Unit-Test
E2E Test
Configuration
Seeder
Jenkins
E2E Tests
Unit tests
Integration
Tests
Sandbox project
Split big pipeline in small pieces
load'em, test'em one by one
E2E Tests
Unit tests
Integration
Tests
@JenkinsRule
@DockerRule
Verify jobDsl configuration and your seeder factory
Test Release mail
Test input step
E2E Tests
Unit tests
Integration
Tests
Mock (sh, git, parallel, shared lib)
Check pipeline "business-logic"
Demo Pipeline Test (gradle)
stchar/pipeline-dsl-seed
#> ./gradlew test
#> git clone https://github.com/stchar/pipeline-dsl-seed.git
.
├── jobs
│ ├── config.groovy # contains a configuration of jobs to deploy
│ │
│ ├── seeder.groovy # Groovy script to seed jobs with provided configuration
│ │
│ ├── seed # A project to test and publish
│ │ │ # your Jenkins jobs
│ │ │
│ │ ├── dsl
│ │ │ └── job-publisher.groovy # default input arguments
│ │ │ # configuration to call seeder script
| │ │ # and is used to sand-boxing the projects
│ │ └── pipeline
│ │ └── job-publisher.groovy # Contains pipeline script to read the
| │ # configuration, and to call seeder script
│ │
│ └── template # project with examples of scripts
│ ├── dsl
│ │ └── template.groovy
│ ├── pipeline
│ │ └── template.groovy
│ └── test
│ └── template_SUITE.groovy # e2e test
└── src
└── test
└── groovy
├── JobSriptsSpec.groovy # Reads the configuration
│ # runs deployment in a test environment
│
├── TestJobPublisher.groovy # Test job deployment script
│
└── TestTemplateJob.groovy # Example of junit tests written using JenkinsPipelineUnit
# to test template job
// file: jobs/template/pipeline/template.groovy
node() {
echo "Hello World!"
}
// file: jobs/template/dsl/template.groovy
def pipeline(dslFactory,seed_ref,job) {
if (seed_ref =~ /master/) {
_quietPeriod = 10
} else {
_quietPeriod = 1
}
dslFactory.with {
quietPeriod(_quietPeriod)
concurrentBuild(true)
}
}
// file: src/test/groovy/TestTemplateJob.groovy
import org.junit.Before
import org.junit.Test
import static org.junit.Assert.assertTrue
import com.lesfurets.jenkins.unit.BasePipelineTest
import static com.lesfurets.jenkins.unit.MethodCall.callArgsToString
class TestTemplateJob extends BasePipelineTest {
@Override
@Before
void setUp() throws Exception {
scriptRoots += 'jobs'
super.setUp()
}
// ...
}
// file: src/test/groovy/TestTemplateJob.groovy
import static com.lesfurets.jenkins.unit.MethodCall.callArgsToString
...
@Test
void should_print_property_value() {
def script = runScript('template/pipeline/template.groovy')
def expectedValue = 'Hello World!'
assertTrue(helper.callStack.findAll { call ->
call.methodName == 'echo'
}.any { call ->
callArgsToString(call).contains(expectedValue)
})
}
Demo Pipeline Test (docker)
stchar/pipeline-dsl-seed
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3c943db4: defining beans [authenticationManager]; root of factory hierarchy
Jul 27, 2017 4:23:10 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.web.context.support.StaticWebApplicationContext@57615d2e: display name [Root WebApplicationContext]; startup date [Thu Jul 27 16:23:10 UTC 2017]; root of context hierarchy
Jul 27, 2017 4:23:10 PM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
INFO: Bean factory for application context [org.springframework.web.context.support.StaticWebApplicationContext@57615d2e]: org.springframework.beans.factory.support.DefaultListableBeanFactory@6e050b6c
Jul 27, 2017 4:23:10 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6e050b6c: defining beans [filter,legacy]; root of factory hierarchy
Jul 27, 2017 4:23:10 PM jenkins.install.SetupWizard init
INFO:
*************************************************************
*************************************************************
*************************************************************
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
a7290d982c39456e81c2be180e4301ef
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
*************************************************************
*************************************************************
*************************************************************
Jul 27, 2017 4:23:18 PM hudson.model.UpdateSite updateData
INFO: Obtained the latest update center data file for UpdateSource default
Jul 27, 2017 4:23:18 PM hudson.model.UpdateSite updateData
INFO: Obtained the latest update center data file for UpdateSource d
Ctrl+C
#> docker run -p 8080:8080 -p 50000:50000 jenkins
Ctrl+V
jobs/seed/pipeline/job-publisher.groovy
gradle downloads the entire internet)))
script approval
Install jobDsl plugin
pipeline-template
Unit-Tests
src, vars
Integration
Tests
Demo Shared Lib Test (gradle)
stchar/pipeline-sharedlib-testharness
#> gradle check
#> git clone https://github.com/stchar/pipeline-sharedlib-testharness.git
.
│
├── build.gradle
│
├── build
│ │
│ └── libs
│ └── jenkins-commons@master
│ └── jenkins-commons@feature
│
├── jobs
│ └── template
│ └── pipeline
│ └── template.groovy
│
├── src
│ ├── org
│ │ └── hcm
│ │ └── libjenkins
│ │ └── Gitlab.groovy
│ └── test
│ └── groovy
│ └── TestJenkinsCommonLib.groovy
└── vars
└── gitlab_stage.groovy
// file: src/test/groovy/TestJenkinsCommonLib.groovy
@Library('jenkins-commons')
import org.hcm.libjenkins.Gitlab
gitlab_lib = new Gitlab(this)
gl_stages = ['hello']
gitlabBuild(gl_stages) {
gitlab_stage(gl_stages,'hello','master',10) {
echo "Hello World!"
}
}
return this
// file: src/test/groovy/TestJenkinsCommonLib.groovy
...
class TestJenkinsCommonLib extends BasePipelineTest {
String sharedLibs = ''
@Override
@Before
void setUp() throws Exception {
scriptRoots += 'jobs'
super.setUp()
def library = library().name('jenkins-commons')
.defaultVersion("master")
.allowOverride(true)
.implicit(true)
.targetPath('build/libs')
.retriever(localSource('build/libs'))
.build()
helper.registerSharedLibrary(library)
}
}
// file: src/test/groovy/TestJenkinsCommonLib.groovy
...
@Test
void should_execute_without_errors() throws Exception {
def script = runScript("template/pipeline/template.groovy")
//printCallStack()
}
@Test
void verify_is_upstream() throws Exception {
def script = runScript("template/pipeline/template.groovy")
assertEquals('Verify is_upstream ', false, script.gitlab_lib.is_upstream('feature'))
assertEquals('Verify is_upstream ', true, script.gitlab_lib.is_upstream('master'))
assertEquals('Verify is_upstream ', true, script.gitlab_lib.is_upstream('rel-1.2.3'))
//printCallStack()
}