Name lookup of the local variable - groovy

I have a question about name lookup in Groovy. Consider the following build script:
apply([plugin: 'java'])
def dependenciesClosure = {
delegate.ext.name = "DelegateName"
println name
println delegate.toString()
project(':api')
}
dependenciesClosure();
dependencies(dependenciesClosure)
The gradle check command produces the output
webapp
project ':webapp'
DelegateName
org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler_Decorated#397ef2
Taking that into account, nonlocal variable name lookup is performed on a delegate object first an, if the name's not found, performed on the global project object. Is that correct?

Correct, Gradle uses a delegate first resolve strategy within configuration closures. In this case, the delegate is an instance of DependencyHandler. You can see what any given block delegates to by looking at the Gradle DSL documentation.
Edit: To confirm your last point, yes, the build script itself delegates to an instance of Project.

Related

Using Groovy create Project properties in SoapUI

I have 50+ tests in my current SoapUI workspace. I need to add a new project level parameter on all of these tests. Is there a way I can do this using the groovy console within SoapUI?
For example :
testRunner.testCase.testSuite.project.setPropertyValue( "SuperMan",("SuperMan"));
I can run this to create a property within the current working project.
Is there a way I can create this under all projects on my current workspace?
Thanks in advance.
Yes, We can do this but it's little tricky.
Way to do this:
Create a empty generic project in soapui, Add empty testsuite, add Empty testcase
In test case Add a groovy script step
Now paste this groovy code
for(project in com.eviware.soapui.SoapUI.workspace.projectList) {
if(project.open && project.name != testRunner.testCase.testSuite.project.name){
project.setPropertyValue( "TestProperty","TestValue");
}
}
Run the groovy step, you will get property added at Project level.
Please mark this as correct response if this solve your problem.
Using your testRunner access you simply need one level more workspace. From here you can access projects map and iterate over each project adding the property:
testRunner.testCase.testSuite.project.workspace.projects.each{ key, proj ->
proj.setPropertyValue('superman','superman')
}
This code doesn't add the property on closed projects in workspace but not fails accessing it.
Alternatively as #Rao suggest on his comment it's possible to use default it object iterator and access the value instead of defining key, proj -> on each:
testRunner.testCase.testSuite.project.workspace.projects.each{
it.value.setPropertyValue('superman','superman')
}
I prefer the first approach for clarity.
Hope it helps,

Jenkins Workflow Error When Accessing Variable Inside a Closure

I'm using some groovy inside a Jenkins Workflow script that includes a closure.
def newMarkup = new StreamingMarkupBuilder().bind {
mkp.yield(xml)
}.toString()
As I understand it mkp should be a variable made available inside closures when using StreamMarkupBuilder, however when I try and run this I get the error,
groovy.lang.MissingPropertyException: No such property: mkp for class: WorkflowScript
So my question is why doesn't Jenkins recognise that mkp is a property of the StreamMarkupBuilder class and not the workflow script?
Sounds like a bug in groovy-cps. Try encapsulating your logic inside a method marked with the #NonCPS annotation. If it starts working, then groovy-cps is to blame, and you can file a bug in the Jenkins JIRA in the workflow-plugin component with steps to reproduce, although I suspect even with the MissingPropertyException fixed the code would still not run due to JENKINS-26481.

Add a map into jenkins build flow plugin as a parameters

I have a question about jenkins build flow plugin.
There is a default value called params in build flow dsl which looks like a map.
What I want to do is pass this map to the jobs I want to build later, however, build flow dont accept a map as a parameters.
For example:
build("test_job", params)
The most stupid way I know is just paste all of them one by one, like, build("test_job", "Key1":params[1], "key2":"params[2]")
Any better idea for this case?
Br,
Tim
The order is the key here!
You can do this (at least it works for me), use the map of parameters as the first argument :
job_params = [:]
job_params['BRANCH'] = 'The Branch Name'
build( job_params, 'pipelinetester' )
And it works!
Try this method
build("jobname", parameter_name:"your parameter value")
Example :
In your case if you are using name as parameter and your value "abc"
then use
build ("job-name", name:"abc")
You can do this by archiving your map from project 1 and copy it using this plugin:
https://wiki.jenkins-ci.org/display/JENKINS/Copy+Artifact+Plugin
Or you can use shared folder using the plugin:
https://wiki.jenkins-ci.org/display/JENKINS/CopyArchiver+Plugin

Pass variables between step definitions in Cucumber groovy

I am wondering how we can pass variables between two step definitions files.
I found this How to share variables across multiple cucumber step definition files with groovy but their structure is different from mine, because I am not using classes in step definition.
The following is my two step definition files.
Feature File 1
Scenario: Consumer registration
When I try to register with my details with "memberNo" mem no.
Then I should be able to get success response
stepDef1
When(~'^I try to register with my details with "([^"]*)" mem no.$') { String memdNo ->
sMemdNo = memNo + getRanNo()
// more code here
}
Feature File 2
Scenario: Event Generation
When I activate my account
Then I can see the file having "logName" event
stepDef2
Then(~'^I can see the file having "([^"]*)" event$') { String logName ->
eventFile = GetLogtData(logName , sMemdNo )
// more code here
}
So, as per the above I want to get the value of sMemdNo from stepDef1 and use it in stepDef2.
I will recommend that you use the World, to store global variables needed across step definitions.
You can see an example here: cucumber-jvm-groovy-example.
You can combine the World with a Factory and/or dependency injection pattern.
To use variables between steps you can add the variable at the top of the steps file (groovy or java), and the variable used in one step will have the value available for other variable.
Example
Result

SoapUi: Transferring a response value to a temporary property (missing a non persisting target scope)

Using SoapUI Pro 5.0
I know how to transfer response values to any scoped property (test suite, test case, etc.).
My problem is, that such scoped properties:
must already exist in the target scope
are persisted at the end in the project configuration file. So after each run this configuration file is changed, what is a nightmare for source control.
I need this value only one or two step(s) later for doing complex verifications (usingg a Script-TestStep).
The "Property Transfer"-TestStep is very powerful for extracting from known sources and transferring to known targets. As target one even can choose a Script-TestStep from the same TestCase. But I did not find any hint how to bind the value to be transferred to - let's say - a declared variable within the target script.
Using the context (e.g. context.getProperties().put( 'MY_PROP_NAME', transferValue ) would be nice but the context is not available within the "Property Transfer"-TestStep. The only possibility I figured out is following script code in a Script-TestStep:
def xmlResponse = XMLNamespaceRemover.removeNamespaces(context.expand( '${mySoapTestStep#Response}' ));
def node = new groovy.util.XmlParser(false,false).parseText(xmlResponse);
def transferValue = node["Body"]["tag1"]["tag2"].text();
context.getProperties().put( 'MY_PROP_NAME', transferValue )
Any ideas how to solve this using the "Property Transfer" TestStep?
In your script, you can just use:
def MY_PROP_NAME = context.expand( '${mySoapTestStep#Response//*:Body/*:tag1/*:tag2}' )
Alternatively, you can use a Property Transfer step to transfer your value to a TestCase Property - which, as you pointed out, must already exist. In order to get around the problem you mentioned of persisting and thereby messing around with source control, you can create a TearDown script:
testRunner.testCase.setPropertyValue("MY_PROP_NAME", "default")

Resources