jmeter - user defined variables and groovy - groovy

this is my objective:
keep the Test Plan more flexible and usable both on win and mac (since some people use mac and other use win).
I created this simple script in groovy:
import org.apache.jmeter.services.FileServer;
import groovy.json.JsonSlurper;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
String winPath;
String macPath;
String winSlash;
String macSlash;
String userPath;
String userSlash;
if (System.properties['os.name'].toLowerCase().contains('windows')) {
winPath="C:\\QA\\";
winSlash="\\";
vars.put("userPath",winPath.toString());
}
if (System.properties['os.name'].toLowerCase().contains('mac')) {
macPath="/Users/macUser/QA/";
macSlash="/";
vars.put("userPath",macPath.toString());
}
and add it into a "JSR223 Sampler" object under my Thread Group object
Then I've added a "User Defined Variables" object with the following var:
Name value
projectDir myProjectDir
rootPath ${__groovy(props.getProperty("userPath"))}${projectDir}
Then I tried to used the rootPath variable for setting the path of my csv files, so I've added ${projectDir}/AUTH.csv to FileName in "CSV Data Set Config" object, but I got this message:
2018-11-23 16:36:40,634 DEBUG o.a.j.t.TestBeanHelper: Ignoring property 'property' in org.apache.jmeter.config.CSVDataSet
2018-11-23 16:36:40,634 DEBUG o.a.j.t.TestBeanHelper: Setting filename=myProjectPath/AUTH.csv
2018-11-23 16:36:40,634 DEBUG o.a.j.t.TestCompiler: Subtracting node, stack size = 2
2018-11-23 16:36:40,634 DEBUG o.a.j.t.TestCompiler: Subtracting node, stack size = 1
2018-11-23 16:36:40,634 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-1
2018-11-23 16:36:40,634 INFO o.a.j.s.FileServer: Stored: myProjectPath/AUTH.csv
2018-11-23 16:36:40,635 ERROR o.a.j.t.JMeterThread: Test failed!
java.lang.IllegalArgumentException: Could not read file header line for file myProjectPath/AUTH.csv
as you can see it trying to read myProjectPath/AUTH.csv and then off course it get an exception..
why it doesn't "read" the variable rootPath ?
any suggestions?

According to the User Defined Variables documentation:
Note that all the UDV elements in a test plan - no matter where they are - are processed at the start.
Additionally be aware of JMeter Test Elements Execution Order
0. Configuration elements
1. Pre-Processors
2. Timers
3. Sampler
4. Post-Processors (unless SampleResult is null)
5. Assertions (unless SampleResult is null)
6. Listeners (unless SampleResult is null)
Assuming above points your Groovy code is being executed after User Defined Variables therefore you cannot access the value. So the only way to define dynamic value depending on the operating system in the User Defined Variables is using __groovy() function directly in the Value section like:
${__groovy(if(System.getProperty('os.name').toLowerCase().contains('windows')){return 'C:\\\QA\\\' } else { return '/Users/macUser/QA/' },)}
Make sure to escape commas and backslashes with another backslash as in JMeter Functions comma acts as parameters separator and backslash is an escape character. Check out Apache JMeter Functions - An Introduction guide to learn more about JMeter Functions contept.

The issue is that you try to add it to the properties and try to read it from the variables.
Also, don't bother the \ or / in Java. Java handles both on every platform. (Difference between File.separator and slash in paths)
For me this works fine:
def path;
if (System.properties['os.name'].toLowerCase().contains('windows')) {
path="C:\\QA\\";
} else if (System.properties['os.name'].toLowerCase().contains('mac')) {
path="/Users/macUser/QA/";
}
vars.put("userPath",path);
vars.put("rootPath", path+vars.get("projectDir"));
And to use it: log.info(vars.get("rootPath"))

Related

How to use Ansible Python API to run ansible task

I would like to use Ansible 2.9.9 Python API to get config file and parse it to json format from servers in hosts file.
I don't know how to call an existing ansible task using Python API.
Through the Ansible API document, how to integrate ansible task with the sample code.
Sample.py
#!/usr/bin/env python
import json
import shutil
from ansible.module_utils.common.collections import ImmutableDict
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.plugins.callback import CallbackBase
from ansible import context
import ansible.constants as C
class ResultCallback(CallbackBase):
"""A sample callback plugin used for performing an action as results come in
If you want to collect all results into a single object for processing at
the end of the execution, look into utilizing the ``json`` callback plugin
or writing your own custom callback plugin
"""
def v2_runner_on_ok(self, result, **kwargs):
"""Print a json representation of the result
This method could store the result in an instance attribute for retrieval later
"""
host = result._host
print(json.dumps({host.name: result._result}, indent=4))
# since the API is constructed for CLI it expects certain options to always be set in the context object
context.CLIARGS = ImmutableDict(connection='local', module_path=['/to/mymodules'], forks=10, become=None,
become_method=None, become_user=None, check=False, diff=False)
# initialize needed objects
loader = DataLoader() # Takes care of finding and reading yaml, json and ini files
passwords = dict(vault_pass='secret')
# Instantiate our ResultCallback for handling results as they come in. Ansible expects this to be one of its main display outlets
results_callback = ResultCallback()
# create inventory, use path to host config file as source or hosts in a comma separated string
inventory = InventoryManager(loader=loader, sources='localhost,')
# variable manager takes care of merging all the different sources to give you a unified view of variables available in each context
variable_manager = VariableManager(loader=loader, inventory=inventory)
# create data structure that represents our play, including tasks, this is basically what our YAML loader does internally.
play_source = dict(
name = "Ansible Play",
hosts = 'localhost',
gather_facts = 'no',
tasks = [
dict(action=dict(module='shell', args='ls'), register='shell_out'),
dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}')))
]
)
# Create play object, playbook objects use .load instead of init or new methods,
# this will also automatically create the task objects from the info provided in play_source
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
# Run it - instantiate task queue manager, which takes care of forking and setting up all objects to iterate over host list and tasks
tqm = None
try:
tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
passwords=passwords,
stdout_callback=results_callback, # Use our custom callback instead of the ``default`` callback plugin, which prints to stdout
)
result = tqm.run(play) # most interesting data for a play is actually sent to the callback's methods
finally:
# we always need to cleanup child procs and the structures we use to communicate with them
if tqm is not None:
tqm.cleanup()
# Remove ansible tmpdir
shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
sum.yml : generated summary file for each host
- hosts: staging
tasks:
- name: pt_mysql_sum
shell: PTDEST=/tmp/collected;mkdir -p $PTDEST;cd /tmp;wget percona.com/get/pt-mysql-summary;chmod +x pt*;./pt-mysql-summary -- --user=adm --password=***** > $PTDEST/pt-mysql-summary.txt;cat $PTDEST/pt-mysql-summary.out;
register: result
environment:
http_proxy: http://proxy.example.com:8080
https_proxy: https://proxy.example.com:8080
- name: ansible_result
debug: var=result.stdout_lines
- name: fetch_log
fetch:
src: /tmp/collected/pt-mysql-summary.txt
dest: /tmp/collected/pt-mysql-summary-{{ inventory_hostname }}.txt
flat: yes
hosts file
[staging]
vm1 ansible_ssh_host=10.40.50.41 ansible_ssh_user=testuser ansible_ssh_pass=*****

Java Application taking long time to execute Groovy scripts which are precomplied

I have my groovy script precomplied on server start (I have stored groovy scripts as varchar in DB) up like below in Map ,
final Binding sharedData = new Binding();
final GroovyShell shell = new GroovyShell(sharedData);
script= shell.parse(rs.getString("VALIDATION_SCRIPT"));
Now when checking the validation on input records based on specified validation id i try to execute the precompiled script as below.
Script scrpt = Validation.getScript(); //getting from cache
scrpt.getBinding().setVariable("attributes", objects);
scrpt.getBinding().setVariable("tools", scrpt);
GroovyResponse gr = scrpt.evaluate("tools.valid(attributes)");
but here my application takes long time to evaluate..i guess heap size also gets increase and GC takes place. Can any one help me if there are better way to do it. with out impacting the performance.
one of My groovy script :
import com.fis.derivatives.utility.generic.model.GroovyResponse;
def valid(Map mapInput){
GroovyResponse obj = new GroovyResponse()
if(mapInput.inputVal.equals("1")){
obj.setStatus(true) ;
obj.setResultValue("B") ;
} else if(mapInput.inputVal.equals("2")){
obj.setStatus(true) ;
obj.setResultValue("S") ;
}else{
obj.setStatus(false);
obj.setComment("Error : Unable to extract BUY_SELL. Please check BS value "+mapInput.inputVal+".")
}
return obj;
}
1 - I have doubts about your cache. getting from cache without any key is strange...
Script scrpt = Validation.getScript(); //getting from cache
2 - rework a little the call of groovy:
Script scrpt = Validation.getScript(); //getting from cache
//we will pass attributes as a parameter to method
//scrpt.getBinding().setVariable("attributes", objects);
//not necessary to pass to script link to itself
//scrpt.getBinding().setVariable("tools", scrpt);
GroovyResponse gr = scrpt.invokeMethod​("valid", objects);

SoapUI + Groovy + Get 3 test data from 3 different environment respectively

In SoapUI, We have 3 different environment and 3 different test data property files.
So my problems are:
How to set 3 different end points in SoapUI?
How to get test data as per the environment using Groovy?
I try to answer your questions
1.- How to set 3 different end points in SoapUI.
Set your test steps URL with a property like:
http://${#Project#endpoint}
And add the endpoint property in your test data file.
2.- How to get test data as per the environment using Groovy.
If you have a typical property file with key=value you can use the code shown below:
// read property file
def properties = new java.util.Properties();
properties.load( new java.io.FileInputStream( "/tmp/sample.properties" ));
proj = testRunner.testCase.testSuite.project;
def names = [];
names = properties.propertyNames();
while( names.hasMoreElements() )
{
def name = names.nextElement();
log.info name + " " + properties.getProperty(name);
proj.setPropertyValue(name, properties.getProperty(name)) ;
}
With this you save all properties in the project level, if you prefer to save in testCase or testSuite use testRunner.testCase or testRunner.testCase.testSuite instead of testRunner.testCase.testSuite.project.
Hope this helps,

Memory-issue with instance of "ReteooStatefulSession"

I'm using jBoss Rules.But I run in to memory issues after using JBoss rules. Using a profiling tool I collected heap dump
and I got the result as :
One instance of "org.drools.reteoo.ReteooStatefulSession" loaded by
"sun.misc.Launcher$AppClassLoader # 0x7f899fdb6d88" occupies 657,328,888 (78.91%) bytes.
The memory is accumulated in one instance of "org.drools.reteoo.ReteooStatefulSession"
loaded by "sun.misc.Launcher$AppClassLoader # 0x7f899fdb6d88".
Keywords
sun.misc.Launcher$AppClassLoader # 0x7f899fdb6d88
org.drools.reteoo.ReteooStatefulSession
The code I used for JBoss rules is given below.
kbase= KnowledgeBaseFactory.newKnowledgeBase();
ksession= kbase.newStatefulKnowledgeSession();
final String str = CISMSRemotingUtils.getFullConfigFilePath("change-set.xml") ;
final String filePath = str.replaceAll(" ", "%20");
aconf = KnowledgeAgentFactory .newKnowledgeAgentConfiguration();
aconf.setProperty("drools.agent.newInstance", "false");
kagent = KnowledgeAgentFactory.newKnowledgeAgent( "Agent", aconf);
kagent.applyChangeSet( ResourceFactory.newFileResource(filePath) );
kbase = kagent.getKnowledgeBase();
ksession= kbase.newStatefulKnowledgeSession();
sconf =ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
sconf.setProperty( "drools.resource.scanner.interval", "3600");
ResourceFactory.getResourceChangeScannerService().configure( sconf );
ResourceFactory.getResourceChangeNotifierService().start();
ResourceFactory.getResourceChangeScannerService().start();
This piece of code is given in the class constructor and rules are fired inside this class
ksession.insert(data);
ksession.fireAllRules();
I'm using drools 5.4.0
Can anyone help me to identify the problem?

Groovy CliBuilder: only last LongOpt is taken in account

I'm trying to use the groovy CliBuilder to parse command line options. I'm trying to use multiple long options without a short option.
I have the following processor:
def cli = new CliBuilder(usage: 'Generate.groovy [options]')
cli.with {
h longOpt: "help", "Usage information"
r longOpt: "root", args: 1, type: GString, "Root directory for code generation"
x args: 1, type: GString, "Type of processor (all, schema, beans, docs)"
_ longOpt: "dir-beans", args: 1, argName: "directory", type: GString, "Custom location for grails bean classes"
_ longOpt: "dir-orm", args: 1, argName: "directory", type: GString, "Custom location for grails domain classes"
}
options = cli.parse(args)
println "BEANS=${options.'dir-beans'}"
println "ORM=${options.'dir-orm'}"
if (options.h || options == null) {
cli.usage()
System.exit(0)
}
According to the groovy documentation I should be able to use multiple "_" values for an option when I want it to ignore the short option name and use a long option name only. According to the groovy documentation:
Another example showing long options (partial emulation of arg
processing for 'curl' command line):
def cli = new CliBuilder(usage:'curl [options] <url>')
cli._(longOpt:'basic', 'Use HTTP Basic Authentication')
cli.d(longOpt:'data', args:1, argName:'data', 'HTTP POST data')
cli.G(longOpt:'get', 'Send the -d data with a HTTP GET')
cli.q('If used as the first parameter disables .curlrc')
cli._(longOpt:'url', args:1, argName:'URL', 'Set URL to work with')
Which has the following usage message:
usage: curl [options] <url>
--basic Use HTTP Basic Authentication
-d,--data <data> HTTP POST data
-G,--get Send the -d data with a HTTP GET
-q If used as the first parameter disables .curlrc
--url <URL> Set URL to work with
This example shows a common convention. When mixing short and long
names, the short names are often one
character in size. One character
options with arguments don't require a
space between the option and the
argument, e.g. -Ddebug=true. The
example also shows the use of '_' when
no short option is applicable.
Also note that '_' was used multiple times. This is supported but
if any other shortOpt or any longOpt is repeated, then the behavior is undefined.
http://groovy.codehaus.org/gapi/groovy/util/CliBuilder.html
When I use the "_" it only accepts the last one in the list (last one encountered). Am I doing something wrong or is there a way around this issue?
Thanks.
not sure what you mean it only accepts the last one. but this should work...
def cli = new CliBuilder().with {
x 'something', args:1
_ 'something', args:1, longOpt:'dir-beans'
_ 'something', args:1, longOpt:'dir-orm'
parse "-x param --dir-beans beans --dir-orm orm".split(' ')
}
assert cli.x == 'param'
assert cli.'dir-beans' == 'beans'
assert cli.'dir-orm' == 'orm'
I learned that my original code works correctly. What is not working is the function that takes all of the options built in the with enclosure and prints a detailed usage. The function call built into CliBuilder that prints the usage is:
cli.usage()
The original code above prints the following usage line:
usage: Generate.groovy [options]
--dir-orm <directory> Custom location for grails domain classes
-h,--help Usage information
-r,--root Root directory for code generation
-x Type of processor (all, schema, beans, docs)
This usage line makes it look like I'm missing options. I made the mistake of not printing each individual item separate from this usage function call. That's what made this look like it only cared about the last _ item in the with enclosure. I added this code to prove that it was passing values:
println "BEANS=${options.'dir-beans'}"
println "ORM=${options.'dir-orm'}"
I also discovered that you must use = between a long option and it's value or it will not parse the command line options correctly (--long-option=some_value)

Resources