How can I do this in Spock/groovy?
package org.jenkinsci.plugins
import hudson.matrix.*
import spock.lang.*
import org.junit.Rule
import org.jvnet.hudson.test.JenkinsRule
class xxxx extends Specification {
#Rule JenkinsRule rule = new JenkinsRule()
def 'matrix'() {
given:
def matrixProject = rule.createMatrixProject()
AxisList axl = new AxisList();
def axis = new TextAxis('TEST', "1", "2", "3")
axl.add(axis)
matrixProject.setAxes(axl)
expect: matrixProject.scheduleBuild2(0).get().logFile.text.contains("Some String!")
matrixProject.scheduleBuild2(0).get().getRuns().each(){
expect: it.logFile.text.contains("Another String")
}
}
}
specifically, how can I run a closure with a nested test? The "Another String" test doesn't work
Does this work?
def 'matrix'() {
given:
def matrixProject = rule.createMatrixProject()
def axis = new TextAxis('TEST', "1", "2", "3")
matrixProject.axes.add(axis)
expect:
with( matrixProject.scheduleBuild2(0).get() ) {
logFile.text.contains("Some String!")
runs.every { it.logFile.text.contains("Another String") }
}
}
}
Either use every instead of each, or use a nested assert.
I'm not sure if I understand your question well. However if by nested test you mean evaluating statement inside of each closure, why not just use assert
expect:
matrixProject.scheduleBuild2(0).get().logFile.text.contains("Some String!")
matrixProject.scheduleBuild2(0).get().getRuns().each() {
assert it.logFile.text.contains("Another String")
}
#tim_yates's approach also seems fine and it's more like Spock's way. I haven't tested it though.
EDIT
If you want be sure that all logFiles contain test string then use 'every' method as Peter suggested.
expect:
...
matrixProject.scheduleBuild2(0).get().getRuns().every {
it.text.contains('Another String')
}
Other approach, if you prefer to know how many logFiles don't contain test string on test fail count them and compare result size to zero:
expect:
...
matrixProject.scheduleBuild2(0).get().getRuns().count {
!it.text.contains('Another String')
} == 0
Yet another, if you like to know which files caused test to fail, get names of those which don't contain test string and compare that to an empty list:
expect:
...
matrixProject.scheduleBuild2(0).get().getRuns().findAll {
!it.text.contains('Another String')
}*.name == []
Related
Very basic question but I cannot find an answer:
I have the below code in a file g.groovy, and it functions in printing output:
#! /usr/env/groovy
def matchFiles = { match ->
new File(".").eachFile() {
if (it.name =~ match) {
println it
}
}
}
matchFiles('.groovy') prints ./g.groovy to screen.
But I want to capture the output of the closure in a variable and use it elsewhere, e.g.
def fileMatches = matchFiles('.groovy')
but cannot figure this out.
Tried changing println it to return it and then running
def fileMatches = matchFiles('.groovy')
fileMatches.println { it }
but this prints something like g$_run_closure2#4b168fa9
Any help is much appreciated, sorry for any incorrect nomenclature, very new to Groovy
according to the name matchFiles I assume you want to return all matched files
so, you have to define an array result variable where you are going to store each matched file
and then return this result variable after eachFile{...} closure
def matchFiles = { match ->
def result=[]
new File(".").eachFile {
if (it.name =~ match) {
result.add(it)
}
}
return result
}
println matchFiles(/.*/)
I've got a switch case like this:
def someString = 'hello1234bla'
// ...
switch (someString) {
case {it.contains('1234')}:
doSomething()
break
case {it.contains('2468')}:
doSomethingElse()
break
default:
throw new Exception("ERROR: Number not found")
break
}
This seems to be quite a lot of code for something so seemingly simple. All I want is to have different functions be executed when someString contains a specific substring. Is there no simpler way to do this, apart from maybe an if-else cascade?
This is pretty close to what the comments above suggest, but I'll write out a working example with indentation etc and perhaps it will be a bit more readable:
def someString = "hello1234bla"
def found = [
'1234': { println "do something" },
'2468': { println "do something else" }
].find { pattern, action ->
if (someString.contains(pattern)) { action(); true }
else false
}
if (!found) throw new Exception("ERROR: Number not found")
this executes the first matching action and throws an exception if no matches were found. If you need to execute an action for every match, replace the find call with a findAll call.
Another way of executing code based on a pattern in the string is the groovy String eachMatch method:
def someString = "hello1234blae"
someString.eachMatch(/1234/) { println "do something" }
someString.eachMatch(/2468/) { println "do something else" }
which uses regular expressions and runs the closure (the block in the curlies after the eachMatch call) once for every match. Thus:
someString.eachMatch(/e/) { println "runs twice" }
on the above string would execute twice as there are two 'e' characters in the string.
I would like to write a system groovy script which inspects the queued jobs in Jenkins, and extracts the build parameters (and build cause as a bonus) supplied as the job was scheduled. Ideas?
Specifically:
def q = Jenkins.instance.queue
q.items.each { println it.task.name }
retrieves the queued items. I can't for the life of me figure out where the build parameters live.
The closest I am getting is this:
def q = Jenkins.instance.queue
q.items.each {
println("${it.task.name}:")
it.task.properties.each { key, val ->
println(" ${key}=${val}")
}
}
This gets me this:
4.1.next-build-launcher:
com.sonyericsson.jenkins.plugins.bfa.model.ScannerJobProperty$ScannerJobPropertyDescriptor#b299407=com.sonyericsson.jenkins.plugins.bfa.model.ScannerJobProperty#5e04bfd7
com.chikli.hudson.plugin.naginator.NaginatorOptOutProperty$DescriptorImpl#40d04eaa=com.chikli.hudson.plugin.naginator.NaginatorOptOutProperty#16b308db
hudson.model.ParametersDefinitionProperty$DescriptorImpl#b744c43=hudson.mod el.ParametersDefinitionProperty#440a6d81
...
The params property of the queue element itself contains a string with the parameters in a property file format -- key=value with multiple parameters separated by newlines.
def q = Jenkins.instance.queue
q.items.each {
println("${it.task.name}:")
println("Parameters: ${it.params}")
}
yields:
dbacher params:
Parameters:
MyParameter=Hello world
BoolParameter=true
I'm no Groovy expert, but when exploring the Jenkins scripting interface, I've found the following functions to be very helpful:
def showProps(inst, prefix="Properties:") {
println prefix
for (prop in inst.properties) {
def pc = ""
if (prop.value != null) {
pc = prop.value.class
}
println(" $prop.key : $prop.value ($pc)")
}
}
def showMethods(inst, prefix="Methods:") {
println prefix
inst.metaClass.methods.name.unique().each {
println " $it"
}
}
The showProps function reveals that the queue element has another property named causes that you'll need to do some more decoding on:
causes : [hudson.model.Cause$UserIdCause#56af8f1c] (class java.util.Collections$UnmodifiableRandomAccessList)
I am developing a DSL with Groovy and I have run into the following problem. I have a method which performs some action on an object with the given parameters.
def run(x) {
[with:{ y -> foo(x,y) }]
}
run "thing" with "param" // evaluates to foo("thing","param")
Now, assume I want to add a default functionality to my DSL:
def runDefault(x) {
foo(x)
}
runDefault "thing" // evaluates to foo("thing")
Is there a way to combine the two into a single function, such that the with "param" part becomes an optional clause? I want to be able to use the DSL as shown below:
run "thing" with "param" // should do foo("thing","param")
run "thing" // should do foo("thing")
if you are able to distinguish both calls in the run-method, you could do something like this:
def run(x) {
switch (x) {
case 'foo':
println "foo($x)"; break;
case 'bar':
[with:{ y -> println "bar($x,$y)" }]; break;
}
}
run "bar" with "param"
run "foo"
In my work, I have methods to return closures as inputs for markup builders. So, for testing purposes, can we make an expected closure and assert the expected one equal to the one returned by one method? I tried the following code, but the assert failed.
a = {
foo {
bar {
input( type : 'int', name : 'dum', 'hello world' )
}
}
}
b = {
foo {
bar {
input( type : 'int', name : 'dum', 'hello world' )
}
}
}
assert a == b
I do not think it will be feasible to assert the closures even after calling them.
//Since you have Markup elements in closure
//it would not even execute the below assertion.
//Would fail with error on foo()
assert a() != b()
Using ConfigSlurper will give the error about input() since the closure does not represent a config script (because it is a Markup)
One way you can assert the behavior is by asserting the payload (since you have mentioned MarkupBuilder). That can be easily done by using XmlUnit as below(mainly Diff).
#Grab('xmlunit:xmlunit:1.4')
import groovy.xml.MarkupBuilder
import org.custommonkey.xmlunit.*
//Stub out XML in test case
def expected = new StringWriter()
def mkp = new MarkupBuilder(expected)
mkp.foo {
bar {
input( type : 'int', name : 'dum', 'hello world' )
}
}
/**The below setup will not be required because the application will
* be returning an XML as below. Used here only to showcase the feature.
* <foo>
* <bar>
* <input type='float' name='dum'>Another hello world</input>
* </bar>
* </foo>
**/
def real = new StringWriter()
def mkp1 = new MarkupBuilder(real)
mkp1.foo {
bar {
input( type : 'float', name : 'dum', 'Another hello world' )
}
}
//Use XmlUnit API to compare xmls
def xmlDiff = new Diff(expected.toString(), real.toString())
assert !xmlDiff.identical()
assert !xmlDiff.similar()
Above looks like a functional test, but I would go with this test unless otherwise there is an appropriate unit test to assert two markup closures.