Skip to content

Commit

Permalink
Merge pull request jenkinsci#65 from jabbrwcky/JENKINS-18491
Browse files Browse the repository at this point in the history
JENKINS-18491: Top level DSL extensions
  • Loading branch information
quidryan committed Jul 5, 2013
2 parents 6ceb624 + 62390c1 commit 92a0469
Show file tree
Hide file tree
Showing 2 changed files with 288 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import com.google.common.base.Preconditions
import javaposse.jobdsl.dsl.JobType
import javaposse.jobdsl.dsl.WithXmlAction

import static javaposse.jobdsl.dsl.helpers.TopLevelHelper.Timeout.absolute

class TopLevelHelper extends AbstractHelper {

TopLevelHelper(List<WithXmlAction> withXmlActions, JobType jobType) {
Expand All @@ -24,6 +26,7 @@ class TopLevelHelper extends AbstractHelper {
* @return
*/
boolean labelAlreadyAdded = false

def label(String labelExpression = null) {
Preconditions.checkState(!labelAlreadyAdded, "Label can only be appplied once")
labelAlreadyAdded = true
Expand Down Expand Up @@ -51,7 +54,6 @@ class TopLevelHelper extends AbstractHelper {
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
</buildWrappers>
*/

def timeout(Integer timeoutInMinutes, Boolean shouldFailBuild = true) {
execute {
def pluginNode = it / buildWrappers / 'hudson.plugins.build__timeout.BuildTimeoutWrapper'
Expand All @@ -60,6 +62,77 @@ class TopLevelHelper extends AbstractHelper {
}
}

/** Enumeration of timeout types for parsing and error reporting*/
def static enum Timeout {
absolute,
elastic,
likelyStuck
}

/** Context to configure timeout */
def static class TimeoutContext implements Context {

Timeout type
def limit = 3
def failBuild = false
def writeDescription = false
def percentage = 0

TimeoutContext(Timeout type) {
this.type = type
}

def limit(int limit) {
this.limit = limit
}

def failBuild(boolean fail) {
this.failBuild = fail
}

def writeDescription(boolean writeDesc) {
this.writeDescription = writeDesc
}

def percentage(int percentage) {
this.percentage = percentage
}

}

/**
* Add a timeout to the build job.
*
* May be an absolute, elastic or likely Stuck timeout.
*
* @param type type of timeout defaults to absolute
*
* @param timeoutClosure optional closure for configuring the timeout
*/
def timeout(String type = absolute.toString(), Closure timeoutClosure = null) {
Timeout ttype
try {
ttype = Timeout.valueOf(type)
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("Timeout type must be one of: ${Timeout.values()}")
}

TimeoutContext ctx = new TimeoutContext(ttype)
AbstractContextHelper.executeInContext(timeoutClosure, ctx)

execute {
it / buildWrappers / 'hudson.plugins.build__timeout.BuildTimeoutWrapper' {
timeoutMinutes ctx.limit
failBuild ctx.failBuild
writingDescription ctx.writeDescription
timeoutPercentage ctx.percentage
timeoutType ctx.type
timeoutMinutesElasticDefault ctx.limit
}
}
}


/**
* Add environment variables to the build.
*
Expand All @@ -80,7 +153,7 @@ class TopLevelHelper extends AbstractHelper {
environmentVariables(null, envClosure)
}

def environmentVariables(Map<Object,Object> vars, Closure envClosure = null) {
def environmentVariables(Map<Object, Object> vars, Closure envClosure = null) {
EnvironmentVariableContext envContext = new EnvironmentVariableContext()
if (vars) {
envContext.envs(vars)
Expand Down Expand Up @@ -126,13 +199,13 @@ class TopLevelHelper extends AbstractHelper {
/*
<disabled>true</disabled>
*/

def disabled(boolean shouldDisable = true) {
execute {
it / disabled(shouldDisable?'true':'false')
}
}


/**
<logRotator>
<daysToKeep>14</daysToKeep>
Expand Down Expand Up @@ -165,7 +238,7 @@ class TopLevelHelper extends AbstractHelper {
</properties>
*/
def blockOn(Iterable<String> projectNames) {
blockOn( projectNames.join('\n'))
blockOn(projectNames.join('\n'))
}

/**
Expand All @@ -175,7 +248,7 @@ class TopLevelHelper extends AbstractHelper {
*/
def blockOn(String projectName) {
execute {
it / 'properties'/ 'hudson.plugins.buildblocker.BuildBlockerProperty' {
it / 'properties' / 'hudson.plugins.buildblocker.BuildBlockerProperty' {
useBuildBlocker 'true'
blockingJobs projectName
}
Expand Down Expand Up @@ -210,4 +283,78 @@ class TopLevelHelper extends AbstractHelper {
node.appendNode('priority', value)
}
}

/**
* Adds a quiet period to the project.
*
* @param seconds number of seconds to wait
*/
def quietPeriod(int seconds = 5) {
execute {
def node = methodMissing('quietPeriod', seconds)
it / node
}
}

/**
* Sets the number of times the SCM checkout is retried on errors.
*
* @param times number of attempts
*/
def checkoutRetryCount(int times = 3) {
execute {
def node = methodMissing('scmCheckoutRetryCount', times)
it / node
}
}

/**
* Sets a display name for the project.
*
* @param displayName name to display
*/
def displayName(String displayName) {
def name = Preconditions.checkNotNull(displayName, 'Display name must not be null.')
execute {
def node = methodMissing('displayName', name)
it / node
}

}

/**
* Configures a custom workspace for the project.
*
* @param workspacePath workspace path to use
*/
def customWorkspace(String workspacePath) {
def workspace = Preconditions.checkNotNull(workspacePath,"Workspace path must not be null")
execute {
def node = methodMissing('customWorkspace', workspace)
it / node
}

}

/**
* Configures the job to block when upstream projects are building.
*
* @return
*/
def blockOnUpstreamProjects() {
execute {
it / blockBuildWhenDownstreamBuilding(true)
}
}

/**
* Configures the job to block when downstream projects are building.
* @return
*/
def blockOnDownstreamProjects() {
execute {
it / blockBuildWhenUpstreamBuilding(true)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import javaposse.jobdsl.dsl.WithXmlAction
import javaposse.jobdsl.dsl.WithXmlActionSpec
import spock.lang.Specification

import static javaposse.jobdsl.dsl.helpers.TopLevelHelper.Timeout.absolute
import static javaposse.jobdsl.dsl.helpers.TopLevelHelper.Timeout.elastic
import static javaposse.jobdsl.dsl.helpers.TopLevelHelper.Timeout.likelyStuck

public class TopLevelHelperSpec extends Specification {

List<WithXmlAction> mockActions = Mock()
Expand Down Expand Up @@ -56,6 +60,72 @@ public class TopLevelHelperSpec extends Specification {
root.buildWrappers[0].'hudson.plugins.build__timeout.BuildTimeoutWrapper'[0].failBuild[0].value() == 'false'
}

def 'default timeout works' () {
when:
def action = helper.timeout()
action.execute(root)

then:
def timeout = root.buildWrappers[0].'hudson.plugins.build__timeout.BuildTimeoutWrapper'
timeout.timeoutMinutes[0].value() == 3
timeout.failBuild[0].value() == false
timeout.writingDescription[0].value() == false
timeout.timeoutPercentage[0].value() == 0
timeout.timeoutType[0].value() == absolute
timeout.timeoutMinutesElasticDefault[0].value() == 3
}

def 'absolute timeout configuration working' () {
when:
def action = helper.timeout('absolute') {
limit 5
}
action.execute(root)

then:
def timeout = root.buildWrappers[0].'hudson.plugins.build__timeout.BuildTimeoutWrapper'
timeout.timeoutMinutes[0].value() == 5
timeout.failBuild[0].value() == false
timeout.writingDescription[0].value() == false
timeout.timeoutPercentage[0].value() == 0
timeout.timeoutType[0].value() == absolute
timeout.timeoutMinutesElasticDefault[0].value() == 5
}


def 'elastic timeout configuration working' () {
when:
def action = helper.timeout('elastic') {
limit 15
percentage 200
}
action.execute(root)

then:
def timeout = root.buildWrappers[0].'hudson.plugins.build__timeout.BuildTimeoutWrapper'
timeout.timeoutMinutes[0].value() == 15
timeout.failBuild[0].value() == false
timeout.writingDescription[0].value() == false
timeout.timeoutPercentage[0].value() == 200
timeout.timeoutType[0].value() == elastic
timeout.timeoutMinutesElasticDefault[0].value() == 15
}

def 'likelyStuck timeout configuration working' () {
when:
def action = helper.timeout('likelyStuck')
action.execute(root)

then:
def timeout = root.buildWrappers[0].'hudson.plugins.build__timeout.BuildTimeoutWrapper'
timeout.timeoutMinutes[0].value() == 3
timeout.failBuild[0].value() == false
timeout.writingDescription[0].value() == false
timeout.timeoutPercentage[0].value() == 0
timeout.timeoutType[0].value() == likelyStuck
timeout.timeoutMinutesElasticDefault[0].value() == 3
}

def 'environments work with map arg'() {
when:
def action = helper.environmentVariables([
Expand Down Expand Up @@ -83,7 +153,6 @@ public class TopLevelHelperSpec extends Specification {
root.properties[0].'EnvInjectJobProperty'[0].info[0].propertiesContent[0].value().contains('key3=val3')
}


def 'environments work with combination'() {
when:
def action = helper.environmentVariables([key4: 'val4']) {
Expand Down Expand Up @@ -220,4 +289,70 @@ public class TopLevelHelperSpec extends Specification {
then:
root.properties.'hudson.queueSorter.PrioritySorterJobProperty'.priority[0].value() == 99
}

def 'add a quiet period'() {
when:
def action = helper.quietPeriod()
action.execute(root)

then:
root.quietPeriod[0].value() == 5

when:
action = helper.quietPeriod(10)
action.execute(root)

then:
root.quietPeriod[0].value() == 10
}

def 'add SCM retry count' () {
when:
def action = helper.checkoutRetryCount()
action.execute(root)

then:
root.scmCheckoutRetryCount[0].value() == 3

when:
action = helper.checkoutRetryCount(6)
action.execute(root)

then:
root.scmCheckoutRetryCount[0].value() == 6
}

def 'add display name' () {
when:
def action = helper.displayName('FooBar')
action.execute(root)

then:
root.displayName[0].value() == 'FooBar'
}

def 'add custom workspace' () {
when:
def action = helper.customWorkspace('/var/lib/jenkins/foobar')
action.execute(root)

then:
root.customWorkspace[0].value() == '/var/lib/jenkins/foobar'
}

def 'add block for up and downstream projects' () {
when:
def action = helper.blockOnUpstreamProjects()
action.execute(root)

then:
root.blockBuildWhenDownstreamBuilding[0].value() == true

when:
action = helper.blockOnDownstreamProjects()
action.execute(root)

then:
root.blockBuildWhenUpstreamBuilding[0].value() == true
}
}

0 comments on commit 92a0469

Please sign in to comment.