I have used context in groovy in and as:
def gu = new com.eviware.soapui.support.GroovyUtils(context)
What does it refer to?
Context holds information about the environment and is required to freely navigate in the mentioned environment.
#dmahapatro:
context available in groovy scripts in SoapUI is the context of executions of a test case/test suit.
From the documentation:
When scripting inside some kind of "run", there is always a context variable available for getting/setting context-specific variables. The contexts are:
SubmitContext - available within one submit of a request
TestRunContext - available from within all scripts in a TestCase run
LoadTestRunContext - available in LoadTest setup/tearDown scripts and
from the exectued TestCase context via the LoadTestContext context
variable
MockRunContext - available in MockService startup/shutdown scripts
and MockOperation/MockResponse dispatch scripts
All these inherit from the PropertyExpansionContext interface which
has methods for setting/getting properties and an expand method which
can be used to expand arbitrary strings containing
Property-Expansions, read more on this in the soapUI User-Guide.
Related
Is there any way to call mule "flow" instance using groovy ? like When I use the groovy script and it will call the another flow, that means ( calls the another flow -- > sets the variable value and get back with the results). = Expected Behaviour.
Requirement :
Like, Mule Flow A is running independently and keep on incrementing variable value.
Mule flow B wants to access the Flow A variable (Incremental value) ( only variable ) using groovy or python Script.
Note: Script should not execute flow A for getting variable value.
Is there method like to get instance of variable in groovy ? like
flow=registry.lookupByName('A-flow').getInstance(VariableName) ?
// Need to get only variable value.
Groovy Script to call a Mule flow:
import org.mule.runtime.api.message.Message;
import org.mule.runtime.core.api.event.CoreEvent;
import org.mule.runtime.core.api.event.EventContextFactory;
flow=registry.lookupByName('A-flow').grep();
msg = Message.builder().value(payload).build();
event =CoreEvent.builder(EventContextFactory.create(flow, org.mule.runtime.dsl.api.component.config.
DefaultComponentLocation.fromSingleComponent("add-location"))).message(msg).build();
result =flow.process(event);
Mule flow B wants to access the Flow A variable with out deploying or
starting the flow A (as it is running independently ) using groovy or
python Script.
Variables live inside a Mule Event, which is really what contains the status of an execution triggered from a flow. However even if you get a list of all active events you may not know which one is the one you are interested. It is also a bad practice trying to use Mule internals inside an application.
Instead you should share the value of the variable you are interested using a standard method for Mule, like an object store, a queue or database. It really depends on what you are trying to do and the design of your application what is the method that will fit best.
I want to structure my code well to use in JMeter, so I plan to have the groovy scripts in separate groovy files. The JSR223 script can load the script file and execute it. So far so good.
The groovy scripts will get complex, so I want to split the files into multiple files and use them. For e.g. have a file utils.groovy with content
public class SharedStore {
// Initializes the store to store all information about all the data being worked upon
def initializeStore() {
HashMap allStore = new HashMap();
// def props = org.apache.jmeter.util.JMeterUtils.getJMeterProperties()
props.put("${storeHashSet}", allStore);
}
This class will grow with more methods and will be used by all scripts invoked from JMeter. There will be other similar classes.
One JMeter sampler called InitializeEnvironment.groovy wants to use this method thus:
evaluate(new File("<<path>>/Utils.groovy")); // This line is an attempt to include utils.groovy
var shr = new SharedStore().initializeStore();
The above attempt to include groovy file is based on this discussion - https://stackoverflow.com/a/9154553 (and I have tried other options from that discussion to no avail)
Using the above option throws the error:
Script70.groovy: 2: unable to resolve class SharedStore
# line 2, column 11.
var shr = new SharedStore().initializeStore();
I would prefer to wrap things utility methods a class but I can live with having keep methods in global space.
If I do manage to load the additional file like in this - https://stackoverflow.com/a/15904699 - suggestion, without using "class" and have groovy wrap it up in a class for me, props are not available in utils.groovy unless I include the line def props = org.apache.jmeter.util.JMeterUtils.getJMeterProperties() and even then ${storeHashSet} cannot be used
No such property: storeHashSet for class: SharedStore
I want to be able to decompose the scripts into more manageable files, and be able to access JMeter variables and structures in these files.
Any advise on how I can do that in JMeter?
The most straightforward solution would be:
Compiling these individual files into classes
Packaging them into .jar (this one you can skip)
Putting the .jar or (class files if you skipped step 2) in the JMeter Classpath
Using the .jar file in your JSR223 Test Elements
TestPlan Thread Group HTTP Request1 ->Regular Expression Extractor - Return 10 Results - URLs -- Single Thread
ForEach Controller - Using variable from extractor - Successfully Loops through above results HTTP Request2 ->Regular Expression Extractor - Return 10 Results
This above is under 1 thread
I want to have ForEach Controller under different thread --run multiple therads and use the URLs extracted from 1 thread HTTP Sampler -- I tried to use these two approaches
https://www.blazemeter.com/blog/knit-one-pearl-two-how-use-variables-different-thread-groups
How do I pass a variable from one Thread Group to another in JMeter
but somehow now managed it to work
Please help
ForEach Controller will not work with JMeter Properties, it is designed to work only with JMeter Variables so if you want to pass them between different Thread Groups you will need to do some scripting.
Add JSR223 PostProcessor after the Regular Expression Extractor and put the following code into "Script" area
vars.entrySet().each { var ->
if (var.getKey().startsWith('foo')) {
props.put(var.getKey(), var.getValue())
}
}
replace foo with what you have as a Reference Name in the Regular Expression Extractor. The above code will convert all variables which names start with foo into the relevant JMeter Properties
Add Test Action sampler to the second Thread Group (you don't need to measure time of properties to variables conversion, do you)
Add JSR223 PreProcessor as a child of the Test Action sampler
Put the following code into "Script" area
props.entrySet().each {prop ->
if (prop.getKey().startsWith('foo')){
vars.put(prop.getKey(),prop.getValue())
}
}
the above code convert JMeter Properties into JMeter Variables so you will be able to use them in the ForEach Controller in the second Thread Group. Again, replace this foo with the reference name of your own variable.
See Apache Groovy - Why and How You Should Use It article for more information on using Groovy scripting in JMeter tests
Is there a possibility to have variables that depend on the listener where there lay in?
So I want to execute two samplers which are working with a JSR223 Assertion. I use a groovy code which asks for the value of the variable "name". If I execute Sampler A it should say "Tom" and if i execute Sampler B it should say "Paul".
It has to be possible to execute both at the same time.
You have sampler shorthand in the JSR223 Assertion which stands for this or that Sampler. So you can check its name by calling sampler.getName() function which will basically execute underlying AbstractTestElement.getName() method. The relevant code would look like:
if (sampler.getName().equals('Sampler A')) {
log.info('Tom')
}
else if (sampler.getName().equals('Sampler B')) {
log.info('Paul')
}
You can set a JMeter Variable from Groovy code using vars shorthand which in its turn stands for JMeterVariables class instance like:
vars.put('foo', 'bar')
Once done you will be able to refer created variable as ${foo} where required - it will have the value of bar
Check out Scripting JMeter Assertions in Groovy - A Tutorial article for more details.
Problem:
Create GroovyClassLoader GCLA with explicitly set CompilerConfiguration
Create another GroovyClassLoader GCLB with different CompilerConfiguration that sets the BaseScriptClass and uses GCLA as parent
-> a script loaded in GCLB will not have the BaseScriptClass set correctly (but uses the potentially set basescript of GCLA)
Long Story:
My application uses four Groovy scripts to allow customization of certain actions. Each script provides a small DSL, where the DLSs are different for each script. When the action is excecuted in the application, the corresponding script will be called. Additionally some common groovy scripts can be loaded at application startup for storing of common data or definition of helper functions.
The scripts are heavily typechecked at the start of the application.
My first approach was to have one GroovyClassLoader which first loads the common groovy scripts and then does a loadClass for each of the scripts. The DSL is created by simply adding corresponding elements to the binding of each script befor the script is run. The GroovyClassLoader uses a CompilerConfiguration with TypeCheck-Extensions to typecheck the scripts.
This works quite well but has two severe limitations:
the typechecking has to be performed based on the name of the script (because the DSLs for each script is different)
the typechecking script gets quite complicated because it has to handle all four DSLs
To get rid of the named limitations I tried to use a distinct GroovyClassLoader (with my actual ClassLoader as parent) for each of the script (i. e. one per DSL) and set a corresponding ScriptBaseClass which provides the functionality for the DSL. This works very well: the typechecking code is reduced drastically, I can have distinct typechecking scripts for each DSL and I don't have to mess with the name of the script.
But I don't get this to work with the common groovy scripts. As soon as I try to use the GroovyClassLoader of the common scripts as parent for the GroovyClassLoader of the DSL scripts, the DSL no longer gets the correct BaseScriptClass although it's explictly set in the CompilerConfiguration. It seems that the child GroovyClassLoader uses the BaseScriptClass of the parent GroovyClassLoader.
Any ideas of how to get this working?
UPDATE
In my original post I did not mention that I'm using scala. Actually I tried the following code snippet:
val rootConfig = {
val cf = new CompilerConfiguration(CompilerConfiguration.DEFAULT)
cf.setSourceEncoding("UTF-8")
cf.addCompilationCustomizers(new ASTTransformationCustomizer(classOf[CompileStatic]))
cf
}
val childConfig = {
val cfg = new CompilerConfiguration(CompilerConfiguration.DEFAULT)
cfg.setSourceEncoding("UTF-8")
cfg.setScriptBaseClass("NonExisting")
cfg.addCompilationCustomizers(new ASTTransformationCustomizer(classOf[CompileStatic]))
cfg
}
val rootGCL = new GroovyClassLoader(getClass.getClassLoader, rootConfig, false)
val childGCL = new GroovyClassLoader(rootGCL, childConfig, false)
This does not work and the child ClassLoader seems to ignore the CompilerConfiguration completely: it does not complain about the non-exiting BaseScriptClass and if I switch off the static-compilation in the rootConfig it will not even perform the static checks.
If I move the ClassLoader creation to a Java file everything works as expected
GroovyClassLoader has several constructor. For example one for ClassLoader and one for GroovyClassLoader. The GroovyClassLoader version will take the configuration from it. But if you do for example new GroovyClassLoader((ClassLoader) parent) or go with giving the configuration yourself. And for that it is even enough to give null as configuration. The constructor logic will take CompilerConfiguration.DEFAULT then to configure the GroovyClassLoader: new GroovyClassLoader(parent,null) and if you want to be very sure no strange paths are added to the GroovyClassLoader, use the variant with a boolean new GroovyClassLoader(parent,null,false)