Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JMeter setting user defined variable in beanshell not working

I want to overwrite user defined variable in Jmeter in a beanshell. I triead beanshell preprocessor, postprecessor or sample, but nothing worked.

My code:

vars.put("box_user", "mybox");
log.info(vars.get("box_user"));

The output is correct, mybox. But when I use the variable in a sampler later with ${box_user}, the username is not correct. It has the value of the beginning initalization.

What is wrong?

Here is the xml of my jmeter project, tried another variable name, but it is not working:

<?xml version="1.0" encoding="UTF-8"?>
    <jmeterTestPlan version="1.2" properties="2.8" jmeter="2.13 r1665067">
     <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
      <stringProp name="TestPlan.comments"></stringProp>
      <boolProp name="TestPlan.functional_mode">false</boolProp>
      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
        <collectionProp name="Arguments.arguments"/>
      </elementProp>
      <stringProp name="TestPlan.user_define_classpath"></stringProp>
    </TestPlan>
    <hashTree>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
          <boolProp name="LoopController.continue_forever">false</boolProp>
          <stringProp name="LoopController.loops">1</stringProp>
        </elementProp>
        <stringProp name="ThreadGroup.num_threads">1</stringProp>
        <stringProp name="ThreadGroup.ramp_time">1</stringProp>
        <longProp name="ThreadGroup.start_time">1441359197000</longProp>
        <longProp name="ThreadGroup.end_time">1441359197000</longProp>
        <boolProp name="ThreadGroup.scheduler">false</boolProp>
        <stringProp name="ThreadGroup.duration"></stringProp>
        <stringProp name="ThreadGroup.delay"></stringProp>
      </ThreadGroup>
      <hashTree>
        <BeanShellSampler guiclass="BeanShellSamplerGui" testclass="BeanShellSampler" testname="BeanShell Sampler" enabled="true">
          <stringProp name="BeanShellSampler.query">vars.put(&quot;user&quot;, &quot;one&quot;);
vars.put(&quot;host&quot;, &quot;localhost&quot;);</stringProp>
          <stringProp name="BeanShellSampler.filename"></stringProp>
          <stringProp name="BeanShellSampler.parameters"></stringProp>
          <boolProp name="BeanShellSampler.resetInterpreter">false</boolProp>
        </BeanShellSampler>
        <hashTree/>
        <JDBCDataSource guiclass="TestBeanGUI" testclass="JDBCDataSource" testname="JDBC Connection Configuration" enabled="true">
          <stringProp name="dataSource">dbcon</stringProp>
          <stringProp name="poolMax">10</stringProp>
          <stringProp name="timeout">10000</stringProp>
          <stringProp name="trimInterval">60000</stringProp>
          <boolProp name="autocommit">true</boolProp>
          <stringProp name="transactionIsolation">DEFAULT</stringProp>
          <boolProp name="keepAlive">true</boolProp>
          <stringProp name="connectionAge">5000</stringProp>
          <stringProp name="checkQuery">Select 1</stringProp>
          <stringProp name="dbUrl">jdbc:postgresql://localhost:5432/box</stringProp>
          <stringProp name="driver">org.postgresql.Driver</stringProp>
          <stringProp name="username">${user}</stringProp>
          <stringProp name="password">pwd</stringProp>
        </JDBCDataSource>
        <hashTree/>
        <JDBCSampler guiclass="TestBeanGUI" testclass="JDBCSampler" testname="JDBC Request" enabled="true">
          <stringProp name="dataSource">dbcon</stringProp>
          <stringProp name="queryType">Select Statement</stringProp>
          <stringProp name="query">SELECT 1</stringProp>
          <stringProp name="queryArguments"></stringProp>
          <stringProp name="queryArgumentsTypes"></stringProp>
          <stringProp name="variableNames"></stringProp>
          <stringProp name="resultVariable"></stringProp>
          <stringProp name="queryTimeout"></stringProp>
          <stringProp name="resultSetHandler">Store as String</stringProp>
        </JDBCSampler>
        <hashTree/>
        <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
          <boolProp name="ResultCollector.error_logging">false</boolProp>
          <objProp>
            <name>saveConfig</name>
            <value class="SampleSaveConfiguration">
              <time>true</time>
              <latency>true</latency>
              <timestamp>true</timestamp>
              <success>true</success>
              <label>true</label>
              <code>true</code>
              <message>true</message>
              <threadName>true</threadName>
              <dataType>true</dataType>
              <encoding>false</encoding>
              <assertions>true</assertions>
              <subresults>true</subresults>
              <responseData>false</responseData>
              <samplerData>false</samplerData>
              <xml>false</xml>
              <fieldNames>false</fieldNames>
              <responseHeaders>false</responseHeaders>
              <requestHeaders>false</requestHeaders>
              <responseDataOnError>false</responseDataOnError>
              <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
              <assertionsResultsToSave>0</assertionsResultsToSave>
              <bytes>true</bytes>
              <threadCounts>true</threadCounts>
            </value>
          </objProp>
          <stringProp name="filename"></stringProp>
        </ResultCollector>
        <hashTree/>
      </hashTree>
    </hashTree>
  </hashTree>
</jmeterTestPlan>

Error is: FATAL: role "${user}" does not exist -> so my variable ist not replace, I dont know why

like image 988
Peter Avatar asked Aug 31 '15 10:08

Peter


2 Answers

Any chance that you referring variable in the different Thread Group? If yes, you need to use JMeter Properties instead like:

props.put("box_user", "mybox");

and later use ${__P(box_user,)} to access the value.

It is due to JMeter Variables visibility scope limited to the current Thread Group, as per Functions and Variables chapter:

Properties are not the same as variables. Variables are local to a thread; properties are common to all threads, and need to be referenced using the __P or __property function.

See How to Use Variables in Different Thread Groups. guide for more details.

like image 155
Dmitri T Avatar answered Nov 20 '22 09:11

Dmitri T


The issue is timing, not whether the beanshell is properly saving the variable. See section 3.9: Execution order for the order in which JMeter elements are processed. It clearly states that Configuration elements are processed before everything else. This is why ${user} (defined in your beanshell preprocessor) is not defined at the time the JDBC Connection Configuration is processed.

I've tried using a CSV Data Set to populate a database configuration element, but it appears that the database configuration is processed before the CSV Data Set element since that never worked for me.

There are two ways I know will work for passing variables to your database configuration.

  1. The simpler method is with the User Defined Variables configuration element (located before the database configuration in all my tests).
  2. The other method is by passing properties to JMeter on launch, which can be done in multiple ways, then accessing the variable as ${__P(box_user,)} (or as props.get("box_user"); from inside beanshell). To pass the property on startup, you can add it on the commandline with -Jbox_user=one. Alternatively you can add it to user.properties (or jmeter.properties, but don't do that) in the bin directory of your jmeter installation, with a new line box_user=one. Alternatively you can specify an additional properties file on the commandline with --addprop pathToFile, where the referenced file is read with the same format as jmeter.properties and user.properties.
like image 1
Erik Avatar answered Nov 20 '22 09:11

Erik