mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-14 11:03:09 +02:00
Merge remote-tracking branch 'github/master' into HEAD
This commit is contained in:
commit
14d1027323
@ -1,5 +1,7 @@
|
|||||||
package com.sap.piper
|
package com.sap.piper
|
||||||
|
|
||||||
|
import com.cloudbees.groovy.cps.NonCPS
|
||||||
|
|
||||||
class ConfigurationHelper implements Serializable {
|
class ConfigurationHelper implements Serializable {
|
||||||
static ConfigurationHelper loadStepDefaults(Script step){
|
static ConfigurationHelper loadStepDefaults(Script step){
|
||||||
return new ConfigurationHelper(step)
|
return new ConfigurationHelper(step)
|
||||||
@ -96,13 +98,19 @@ class ConfigurationHelper implements Serializable {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
Map use(){ return config }
|
@NonCPS // required because we have a closure in the
|
||||||
|
// method body that cannot be CPS transformed
|
||||||
|
Map use(){
|
||||||
|
MapUtils.traverse(config, { v -> (v instanceof GString) ? v.toString() : v })
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
ConfigurationHelper(Map config = [:]){
|
ConfigurationHelper(Map config = [:]){
|
||||||
this.config = config
|
this.config = config
|
||||||
}
|
}
|
||||||
|
|
||||||
def getConfigProperty(key) {
|
def getConfigProperty(key) {
|
||||||
|
use()
|
||||||
return getConfigPropertyNested(config, key)
|
return getConfigPropertyNested(config, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,4 +38,28 @@ class MapUtils implements Serializable {
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param m The map to which the changed denoted by closure <code>strategy</code>
|
||||||
|
* should be applied.
|
||||||
|
* The strategy is also applied to all sub-maps contained as values
|
||||||
|
* in <code>m</code> in a recursive manner.
|
||||||
|
* @param strategy Strategy applied to all non-map entries
|
||||||
|
*/
|
||||||
|
@NonCPS
|
||||||
|
static void traverse(Map m, Closure strategy) {
|
||||||
|
|
||||||
|
def updates = [:]
|
||||||
|
for(def e : m.entrySet()) {
|
||||||
|
if(isMap(e.value)) {
|
||||||
|
traverse(e.getValue(), strategy)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// do not update the map while it is traversed. Depending
|
||||||
|
// on the map implementation the behavior is undefined.
|
||||||
|
updates.put(e.getKey(), strategy(e.getValue()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.putAll(updates)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import org.junit.rules.ExpectedException
|
|||||||
import org.junit.rules.RuleChain
|
import org.junit.rules.RuleChain
|
||||||
import org.yaml.snakeyaml.Yaml
|
import org.yaml.snakeyaml.Yaml
|
||||||
import util.BasePiperTest
|
import util.BasePiperTest
|
||||||
|
import util.JenkinsCredentialsRule
|
||||||
import util.JenkinsEnvironmentRule
|
import util.JenkinsEnvironmentRule
|
||||||
import util.JenkinsDockerExecuteRule
|
import util.JenkinsDockerExecuteRule
|
||||||
import util.JenkinsLoggingRule
|
import util.JenkinsLoggingRule
|
||||||
@ -42,28 +43,9 @@ class CloudFoundryDeployTest extends BasePiperTest {
|
|||||||
.around(jwfr)
|
.around(jwfr)
|
||||||
.around(jedr)
|
.around(jedr)
|
||||||
.around(jer)
|
.around(jer)
|
||||||
|
.around(new JenkinsCredentialsRule(this).withCredentials('test_cfCredentialsId', 'test_cf', '********'))
|
||||||
.around(jsr) // needs to be activated after jedr, otherwise executeDocker is not mocked
|
.around(jsr) // needs to be activated after jedr, otherwise executeDocker is not mocked
|
||||||
|
|
||||||
@Before
|
|
||||||
void init() throws Throwable {
|
|
||||||
helper.registerAllowedMethod('usernamePassword', [Map], { m -> return m })
|
|
||||||
helper.registerAllowedMethod('withCredentials', [List, Closure], { l, c ->
|
|
||||||
if(l[0].credentialsId == 'test_cfCredentialsId') {
|
|
||||||
binding.setProperty('username', 'test_cf')
|
|
||||||
binding.setProperty('password', '********')
|
|
||||||
} else if(l[0].credentialsId == 'test_camCredentialsId') {
|
|
||||||
binding.setProperty('username', 'test_cam')
|
|
||||||
binding.setProperty('password', '********')
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
c()
|
|
||||||
} finally {
|
|
||||||
binding.setProperty('username', null)
|
|
||||||
binding.setProperty('password', null)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testNoTool() throws Exception {
|
void testNoTool() throws Exception {
|
||||||
nullScript.commonPipelineEnvironment.configuration = [
|
nullScript.commonPipelineEnvironment.configuration = [
|
||||||
|
@ -5,8 +5,10 @@ import org.junit.rules.TemporaryFolder
|
|||||||
import org.junit.BeforeClass
|
import org.junit.BeforeClass
|
||||||
import org.junit.ClassRule
|
import org.junit.ClassRule
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
|
|
||||||
import org.hamcrest.BaseMatcher
|
import org.hamcrest.BaseMatcher
|
||||||
import org.hamcrest.Description
|
import org.hamcrest.Description
|
||||||
|
import org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
@ -15,6 +17,7 @@ import org.junit.rules.ExpectedException
|
|||||||
import org.junit.rules.RuleChain
|
import org.junit.rules.RuleChain
|
||||||
|
|
||||||
import util.BasePiperTest
|
import util.BasePiperTest
|
||||||
|
import util.JenkinsCredentialsRule
|
||||||
import util.JenkinsLoggingRule
|
import util.JenkinsLoggingRule
|
||||||
import util.JenkinsReadYamlRule
|
import util.JenkinsReadYamlRule
|
||||||
import util.JenkinsShellCallRule
|
import util.JenkinsShellCallRule
|
||||||
@ -40,6 +43,9 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
.around(thrown)
|
.around(thrown)
|
||||||
.around(jlr)
|
.around(jlr)
|
||||||
.around(jscr)
|
.around(jscr)
|
||||||
|
.around(new JenkinsCredentialsRule(this)
|
||||||
|
.withCredentials('myCredentialsId', 'anonymous', '********')
|
||||||
|
.withCredentials('CI_CREDENTIALS_ID', 'defaultUser', '********'))
|
||||||
.around(jsr)
|
.around(jsr)
|
||||||
|
|
||||||
private static workspacePath
|
private static workspacePath
|
||||||
@ -66,24 +72,6 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
|
|
||||||
helper.registerAllowedMethod('dockerExecute', [Map, Closure], null)
|
helper.registerAllowedMethod('dockerExecute', [Map, Closure], null)
|
||||||
helper.registerAllowedMethod('fileExists', [String], { s -> return new File(workspacePath, s).exists() })
|
helper.registerAllowedMethod('fileExists', [String], { s -> return new File(workspacePath, s).exists() })
|
||||||
helper.registerAllowedMethod('usernamePassword', [Map], { m -> return m })
|
|
||||||
helper.registerAllowedMethod('withCredentials', [List, Closure], { l, c ->
|
|
||||||
if(l[0].credentialsId == 'myCredentialsId') {
|
|
||||||
binding.setProperty('username', 'anonymous')
|
|
||||||
binding.setProperty('password', '********')
|
|
||||||
} else if(l[0].credentialsId == 'CI_CREDENTIALS_ID') {
|
|
||||||
binding.setProperty('username', 'defaultUser')
|
|
||||||
binding.setProperty('password', '********')
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
c()
|
|
||||||
} finally {
|
|
||||||
binding.setProperty('username', null)
|
|
||||||
binding.setProperty('password', null)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
helper.registerAllowedMethod('sh', [Map], { Map m -> getVersionWithEnvVars(m) })
|
helper.registerAllowedMethod('sh', [Map], { Map m -> getVersionWithEnvVars(m) })
|
||||||
|
|
||||||
nullScript.commonPipelineEnvironment.configuration = [steps:[neoDeploy: [host: 'test.deploy.host.com', account: 'trialuser123']]]
|
nullScript.commonPipelineEnvironment.configuration = [steps:[neoDeploy: [host: 'test.deploy.host.com', account: 'trialuser123']]]
|
||||||
@ -179,8 +167,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
@Test
|
@Test
|
||||||
void badCredentialsIdTest() {
|
void badCredentialsIdTest() {
|
||||||
|
|
||||||
thrown.expect(MissingPropertyException)
|
thrown.expect(CredentialNotFoundException)
|
||||||
thrown.expectMessage('No such property: username')
|
|
||||||
|
|
||||||
jsr.step.call(script: nullScript,
|
jsr.step.call(script: nullScript,
|
||||||
archivePath: archiveName,
|
archivePath: archiveName,
|
||||||
|
@ -30,16 +30,14 @@ public class PrepareDefaultValuesTest extends BasePiperTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
|
||||||
helper.registerAllowedMethod("libraryResource", [String], { fileName-> return fileName })
|
helper.registerAllowedMethod("libraryResource", [String], { fileName ->
|
||||||
helper.registerAllowedMethod("readYaml", [Map], { m ->
|
switch(fileName) {
|
||||||
switch(m.text) {
|
case 'default_pipeline_environment.yml': return "default: 'config'"
|
||||||
case 'default_pipeline_environment.yml': return [default: 'config']
|
case 'custom.yml': return "custom: 'myConfig'"
|
||||||
case 'custom.yml': return [custom: 'myConfig']
|
|
||||||
case 'not_found': throw new hudson.AbortException('No such library resource not_found could be found')
|
case 'not_found': throw new hudson.AbortException('No such library resource not_found could be found')
|
||||||
default: return [the:'end']
|
default: return "the:'end'"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -54,11 +52,16 @@ public class PrepareDefaultValuesTest extends BasePiperTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testReInitializeOnCustomConfig() {
|
public void testReInitializeOnCustomConfig() {
|
||||||
|
|
||||||
DefaultValueCache.createInstance([key:'value'])
|
def instance = DefaultValueCache.createInstance([key:'value'])
|
||||||
|
|
||||||
// existing instance is dropped in case a custom config is provided.
|
// existing instance is dropped in case a custom config is provided.
|
||||||
jsr.step.call(script: nullScript, customDefaults: 'custom.yml')
|
jsr.step.call(script: nullScript, customDefaults: 'custom.yml')
|
||||||
|
|
||||||
|
// this check is for checking we have another instance
|
||||||
|
assert ! instance.is(DefaultValueCache.getInstance())
|
||||||
|
|
||||||
|
// some additional checks that the configuration represented by the new
|
||||||
|
// config is fine
|
||||||
assert DefaultValueCache.getInstance().getDefaultValues().size() == 2
|
assert DefaultValueCache.getInstance().getDefaultValues().size() == 2
|
||||||
assert DefaultValueCache.getInstance().getDefaultValues().default == 'config'
|
assert DefaultValueCache.getInstance().getDefaultValues().default == 'config'
|
||||||
assert DefaultValueCache.getInstance().getDefaultValues().custom == 'myConfig'
|
assert DefaultValueCache.getInstance().getDefaultValues().custom == 'myConfig'
|
||||||
@ -67,10 +70,11 @@ public class PrepareDefaultValuesTest extends BasePiperTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testNoReInitializeWithoutCustomConfig() {
|
public void testNoReInitializeWithoutCustomConfig() {
|
||||||
|
|
||||||
DefaultValueCache.createInstance([key:'value'])
|
def instance = DefaultValueCache.createInstance([key:'value'])
|
||||||
|
|
||||||
jsr.step.call(script: nullScript)
|
jsr.step.call(script: nullScript)
|
||||||
|
|
||||||
|
assert instance.is(DefaultValueCache.getInstance())
|
||||||
assert DefaultValueCache.getInstance().getDefaultValues().size() == 1
|
assert DefaultValueCache.getInstance().getDefaultValues().size() == 1
|
||||||
assert DefaultValueCache.getInstance().getDefaultValues().key == 'value'
|
assert DefaultValueCache.getInstance().getDefaultValues().key == 'value'
|
||||||
}
|
}
|
||||||
|
@ -279,4 +279,32 @@ class ConfigurationHelperTest {
|
|||||||
|
|
||||||
Assert.assertThat(configuration, hasEntry('collectTelemetryData', false))
|
Assert.assertThat(configuration, hasEntry('collectTelemetryData', false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGStringsAreReplacedByJavaLangStrings() {
|
||||||
|
//
|
||||||
|
// needed in order to ensure we have real GStrings.
|
||||||
|
// a GString not containing variables might be optimized to
|
||||||
|
// a java.lang.String from the very beginning.
|
||||||
|
def dummy = 'Dummy',
|
||||||
|
aGString = "a${dummy}",
|
||||||
|
bGString = "b${dummy}",
|
||||||
|
cGString = "c${dummy}"
|
||||||
|
|
||||||
|
assert aGString instanceof GString
|
||||||
|
assert bGString instanceof GString
|
||||||
|
assert cGString instanceof GString
|
||||||
|
|
||||||
|
def config = new ConfigurationHelper([a: aGString,
|
||||||
|
nextLevel: [b: bGString]])
|
||||||
|
.mixin([c : cGString])
|
||||||
|
.use()
|
||||||
|
|
||||||
|
assert config == [a: 'aDummy',
|
||||||
|
c: 'cDummy',
|
||||||
|
nextLevel: [b: 'bDummy']]
|
||||||
|
assert config.a instanceof java.lang.String
|
||||||
|
assert config.c instanceof java.lang.String
|
||||||
|
assert config.nextLevel.b instanceof java.lang.String
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,4 +43,11 @@ class MapUtilsTest {
|
|||||||
c: [ d: 'abc',
|
c: [ d: 'abc',
|
||||||
e: '']]
|
e: '']]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTraverse() {
|
||||||
|
Map m = [a: 'x1', m:[b: 'x2', c: 'otherString']]
|
||||||
|
MapUtils.traverse(m, { s -> (s.startsWith('x')) ? "replaced" : s})
|
||||||
|
assert m == [a: 'replaced', m: [b: 'replaced', c: 'otherString']]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import static org.hamcrest.Matchers.nullValue
|
|||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import org.hamcrest.Matchers
|
import org.hamcrest.Matchers
|
||||||
|
import org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* By default a user "anonymous" with password "********"
|
* By default a user "anonymous" with password "********"
|
||||||
@ -47,16 +48,19 @@ class JenkinsCredentialsRule implements TestRule {
|
|||||||
@Override
|
@Override
|
||||||
void evaluate() throws Throwable {
|
void evaluate() throws Throwable {
|
||||||
|
|
||||||
testInstance.helper.registerAllowedMethod('usernamePassword', [Map.class], {m -> return m})
|
testInstance.helper.registerAllowedMethod('usernamePassword', [Map.class],
|
||||||
|
{ m -> if (credentials.keySet().contains(m.credentialsId)) return m;
|
||||||
|
// this is what really happens in case of an unknown credentials id,
|
||||||
|
// checked with reality using credentials plugin 2.1.18.
|
||||||
|
throw new CredentialNotFoundException(
|
||||||
|
"Could not find credentials entry with ID '${m.credentialsId}'")
|
||||||
|
})
|
||||||
|
|
||||||
testInstance.helper.registerAllowedMethod('withCredentials', [List, Closure], { l, c ->
|
testInstance.helper.registerAllowedMethod('withCredentials', [List, Closure], { l, c ->
|
||||||
|
|
||||||
def credsId = l[0].credentialsId
|
def credsId = l[0].credentialsId
|
||||||
def creds = credentials.get(credsId)
|
def creds = credentials.get(credsId)
|
||||||
|
|
||||||
assertThat("Unexpected credentialsId received: '${credsId}'.",
|
|
||||||
creds, is(not(nullValue())))
|
|
||||||
|
|
||||||
binding.setProperty('username', creds?.user)
|
binding.setProperty('username', creds?.user)
|
||||||
binding.setProperty('password', creds?.passwd)
|
binding.setProperty('password', creds?.passwd)
|
||||||
try {
|
try {
|
||||||
|
Loading…
Reference in New Issue
Block a user