1
0
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:
Marcus Holl 2018-09-21 13:44:54 +02:00
commit 14d1027323
8 changed files with 98 additions and 54 deletions

View File

@ -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)
} }

View File

@ -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)
}
} }

View File

@ -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 = [

View File

@ -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,

View File

@ -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'
} }

View File

@ -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
}
} }

View File

@ -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']]
}
} }

View File

@ -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 &quot;anonymous&quot; with password &quot;********&quot; * By default a user &quot;anonymous&quot; with password &quot;********&quot;
@ -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 {