Giter Site home page Giter Site logo

ruby-jmeter's Introduction

Ruby-JMeter Build Status Code Climate Gem Version

Ruby-JMeter is built and maintained by Flood IO, an easy to use load testing platform for any scale of testing.

Tired of using the JMeter GUI or looking at hairy XML files?

This gem lets you write test plans for JMeter in your favourite text editor, and optionally run them on flood.io.

Installation

Install it yourself as:

$ gem install ruby-jmeter

Basic Usage

RubyJmeter exposes easy-to-use domain specific language for fluent communication with JMeter.It also includes API integration with flood.io, a cloud based load testing service.

To use the DSL, first let's require the gem:

require 'ruby-jmeter'

Basic Example

Let's create a test and save the related jmx testplan to file, so we can edit/view it in JMeter.

test do
  threads count: 10 do
    visit name: 'Google Search', url: 'http://google.com'
  end
end.jmx

So in this example, we just created a test plan, with 10 threads, each of which visited the search page at Google.

Generating a JMeter Test Plan (JMX)

Note also how we called the jmx method of the test. Calling this method will write the contents of the JMeter test plan to file like this.

$ ruby testplan.rb
[2013-04-23T10:29:03.275743 #42060]  INFO -- : Test plan saved to: jmeter.jmx
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="2.1">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
      ...
    </TestPlan>
  </hashTree>
</jmeterTestPlan>
JMX saved to: jmeter.jmx

The file that is created can then be executed in the JMeter GUI. If you want to create the file with a different filename and/or path, just add the file parameter to the jmx method call like this.

test do
  threads count: 10 do
    visit name: 'Google Search', url: 'http://google.com'
  end
end.jmx(file: "/tmp/my_testplan.jmx")

Windows users should specify a path like this.

.jmx(file: "C:\\TEMP\\MyTestplan.jmx")

Running a JMeter Test Plan locally

You can execute the JMeter test plan by calling the run method of the test like this.

test do
  threads count: 10 do
    visit name: 'Google Search', url: 'http://google.com'
  end
end.run

This will launch JMeter in headless (non-GUI mode) and execute the test plan. This is useful for shaking out the script before you push it to the Grid. There are a few parameters that you can set such as the path to the JMeter binary, the file path/name for the JMX file, the log path/name to output JMeter logs, the jtl path/name for JMeter results like this, and the properties path/name for the additional JMeter property file.

test do
  threads count: 10 do
    visit name: 'Google Search', url: 'http://google.com'
  end
end.run(
  path: '/usr/share/jmeter/bin/',
  file: 'jmeter.jmx',
  log: 'jmeter.log',
  jtl: 'results.jtl',
  properties: 'jmeter.properties')

Running a JMeter Test Plan on Flood IO

You can also execute JMeter test plans on Flood IO using our API. To do so, you require an account and API token. If you don't know your token, sign in to flood.io and check your account settings.

To execute the test on Flood IO, call the flood method on the test and pass it the API token like this.

test do
  threads count: 10 do
    visit name: 'Google Search', url: 'http://google.com'
  end
end.flood(
  ENV['FLOOD_API_TOKEN'],
  name: 'Demo',
  privacy: 'public',
  ## Select a grid or region to distribute this flood to
  # grid: 'pmmi24XaSMnKjGVEtutroQ',
  # region: 'ap-southeast-2'
)

This will then provide you with a link to the live test results on Flood IO like this.

I, [2015-02-24T11:15:25.669029 #14010]  INFO -- : Flood results at: https://flood.io/AbRWkFl7VODYCkQuy3ffvA

Note you will need to provide a grid or region parameter to the .flood method to describe which grid to distribute the flood test to. Otherwise it will default to the shared grid. You can find the Grid ID from the URL of the target grid in your grids dashboard e.g.:

Flood IO provides a shared grid for free, suitable for 5 minute tests, check your dashboard for the latest grid:

Alternatively upgrade to a paid subscription on Flood IO and start your own grids on demand.

Advanced Usage

Blocks

Each of the methods take an optional block delimited by do and end or braces {}

Blocks let you nest methods within methods, so you can scope the execution of methods as you would in a normal JMeter test plan. For example.

test do
  threads count: 100 do
    visit name: 'Home', url: 'http://altentee.com' do
      extract regex: "content='(.+?)' name='csrf-token'", name: 'csrf-token'
    end
  end
end

This would create a new test plan, with a 100 user thread group, each user visiting the "Home" page and extracting the CSRF token from the response of each visit.

All methods are nestable, but you should only have one test method, and typically only one threads method. For example, it wouldn't make sense to have a test plan within a test plan, or a thread group within a thread group. You can have multiple thread groups per test plan though. This implies some knowlege of how JMeter works.

All methods take a parameter hash to configure related options.

Threads

You can use the threads method to define a group of users:

threads count: 100
threads count: 100, continue_forever: true
threads count: 100, loops: 10
threads count: 100, rampup: 30, duration: 60
threads count: 100, scheduler: true,
  start_time: Time.now.to_i * 1000,
  end_time:   (Time.now.to_i * 1000) + (3600 * 1000)

Cookies

You can use the cookies method to define a Cookie Manager:

test do
  cookies
end

This methods takes an optional parameters hash. This is based on the HTTP Cookie Manager.

test do
  cookies clear_each_iteration: false
end

test do
  cookies policy: 'rfc2109', clear_each_iteration: true
end

User-Defined Cookies

The cookies method parameters hash supports user_defined_cookies:

test do
  cookie1 = { value: 'foo', name: 'bar', domain: 'google.co.uk', path: '/' }
  cookie2 = { value: 'hello', name: 'world', domain: 'google.co.uk', secure: true }

  cookies user_defined_cookies: [ cookie1, cookie2 ]
end

name and value are required. domain and path are optional and default to blank. secure is optional and defaults to false.

Cache

You can use the cache method to define a Cache Manager:

test do
  cache
end

This methods takes an optional parameters hash. This is based on the HTTP Cache Manager.

test do
  cache clear_each_iteration: false
end

test do
  cache use_expires: true, clear_each_iteration: true
end

Authorization

You can use the auth method to define an Authorization Manager:

test do
  auth
end

This methods takes an optional parameters hash. This is based on the HTTP Authorization Manager.

test do
  auth url: '/', username: 'tim', password: 'secret', domain: 'altentee.com'
end

Navigating

You can use the visit method to navigate to pages:

visit name: 'Google Search', url: 'http://google.com'
visit name: 'Google Search', url: 'http://google.com'
visit name: 'Google Search', url: 'http://google.com',
  method: 'POST',
  'DO_MULTIPART_POST': 'true'
visit name: 'Google Search', url: 'http://google.com',
  use_keepalive: 'false'
visit name: 'Google Search', url: 'http://google.com',
  connect_timeout: '1000',
  response_timeout: '60000'
visit name: 'View Login', url: '/login',
  protocol: "https",
  port: 443

Submitting a Form

You can use the submit method to POST a HTTP form:

submit name: 'Submit Form', url: 'http://altentee.com/',
  fill_in: {
    username: 'tim',
    password: 'password',
    'csrf-token' => '${csrf-token}'
  }

This method makes a single request. The fill_in parameter lets you specify key/value pairs for form field parameters. You can also use the built in JMeter ${expression} language to access run time variables extracted from previous responses.

POST JSON

  header [
    { name: 'Content-Type', value: 'application/json' }
  ]

  person = { name: "Tom" }

  post name: 'Create Person',
        url: "https://example.com/people.json",
        raw_body: person.to_json do
        with_xhr
      end

Think Time

You can use the think_time method to insert pauses into the simulation. This method is aliased as random_timer.

think_time 3000

This method takes 2 parameters: the constant delay, and an optional variable delay. Both are specified in milliseconds. This is based on the Gaussian Random Timer. This timer pauses each thread request for a random amount of time, with most of the time intervals ocurring near a particular value. The total delay is the sum of the Gaussian distributed value (with mean 0.0 and standard deviation 1.0) times the deviation value you specify, and the offset value.

# constant delay of 3 seconds
think_time 3000
# constant delay of 1 seconds with variance up to 6 seconds.
random_timer 1000, 6000

Response Extractor

You can use the extract method to extract values from a server response using a regular expression. This is aliased as the web_reg_save_param method. This method is typically used inside a visit or submit block.

extract regex: "content='(.+?)' name='csrf-token'", name: 'csrf-token'

visit name: 'Google', url: "http://google.com/" do
  extract regex: 'aria-label="(.+?)"', name: 'button_text'
  extract xpath: '//button', name: 'button'
end

This is based on the Regular Expression Extractor and XPath Extractor

visit name: "Altentee", url: "http://altentee.com" do
  extract regex: "content='(.+?)' name='csrf-token'", name: 'csrf-token'
  extract regex: 'value="(.+?)" name="JESSIONSID"', name: 'JSESSIONID'
  web_reg_save_param regex: 'value="(.+?)" name="VIEWSTATE"', name: 'VIEWSTATE'
  extract name: 'username', regex: 'value="(.+?)", name="username"',
    default: 'Tim Koopmans',
    match_number: 1
  extract name: 'shopping_item', regex: 'id="(.+?)" name="book"',
    match_number: 0 # random
end

You can later use the extracted values with subsequent requests:

post name: 'Authenticate', url: 'http://example.com/api/authentication/facebook', raw_body: '{"auth_token": "FB_TOKEN"}' do
  extract name: 'auth_token', regex: %q{.*"token":"([^"]+)".*}
  extract name: 'user_id', regex: %q{.*"user_id":([^,]+),.*}
end

header({name: 'X-Auth-Token', value: '${auth_token}'})
visit name: 'User profile', url: 'http://example.com/api/users/${user_id}'

Response Assertion

You can use the assert method to extract values from a server response using a regular expression. This is aliased as the web_reg_find method. This method is typically used inside a visit or submit block.

visit "Altentee", "http://altentee.com" do
  assert contains: "We test, tune and secure your site"
end

This method takes 3 parameters: the matching rule, the test string, and an optional parameters hash. This is based on the Response Assertion.

visit "Altentee", "http://altentee.com" do
  assert "contains": "We test, tune and secure your site"
  assert "not-contains": "We price gouge on cloud services"
  assert "matches": "genius"
  assert "not-matches": "fakers"
  assert "contains": "magic"
  assert "not-contains": "unicorns", scope: 'all'
end

Roadmap

This work is being sponsored by Flood IO. Get in touch with us if you'd like to be involved.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Create some specs, make them pass
  4. Commit your changes (git commit -am 'Add some feature')
  5. Push to the branch (git push origin my-new-feature)
  6. Create new Pull Request

IDL

We use an interface description language (IDL) as a bridge between JMeter's components expressed as XML in a .jmx test plan to Ruby's DSL objects in this repository.

To automate this lib/ruby-jmeter/idl.rb can be executed from the command line which will read from lib/ruby-jmeter/idl.xml and output to lib/ruby-jmeter/dsl

For example:

flood/ruby-jmeter - [masterโ—] ยป ruby lib/ruby-jmeter/idl.rb
flood/ruby-jmeter - [masterโ—] ยป git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

  modified:   lib/ruby-jmeter/DSL.md
  modified:   lib/ruby-jmeter/dsl/foreach_controller.rb
  modified:   lib/ruby-jmeter/dsl/http_request.rb
  modified:   lib/ruby-jmeter/dsl/http_request_defaults.rb
  modified:   lib/ruby-jmeter/dsl/regular_expression_extractor.rb
  modified:   lib/ruby-jmeter/dsl/response_assertion.rb
  modified:   lib/ruby-jmeter/dsl/test_fragment.rb
  modified:   lib/ruby-jmeter/dsl/user_parameters.rb

You should never manually update code in lib/ruby-jmeter/dsl as this is automatically overwritten whenever we run the IDL script. As new components / plugins are added, or major versions of JMeter are updated, we open lib/ruby-jmeter/idl.xml in the JMeter UI with those updates prior to running the IDL script. This makes updating between versions more easy.

DSL

Much of the behaviour of the gem is defined in lib/ruby-jmeter/dsl.rb which is where you should be updating code. You can extend individual DSL component behaviour in live/ruby-jmeter/extend/**/*.rb

Plugins

Some custom code has been contributed particularly for support of JMeter plugins. These are not included in the IDL and as such should be added to lib/ruby-jmeter/plugins. Please follow some of the other examples.

Bundler

We recommend using the Ruby gem bundle to manage your dependencies. Typical setup would be:

gem install bundler
cd <your local clone>
bundle install

Then you can run any rake / test tasks with the prefix bundle exec

Tests

If contributing please add an appropriate test. See spec/*_spec.rb for examples. Tests can be run from the command line as follows:

$ bundle exec rspec

Examples

It is often useful to add an appropriate example for other users and for testing your changes locally with the JMeter UI. See examples for different types of examples. To let your examples work locally from your own changes / commits simply prefix the examples with:

$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
$ flood/ruby-jmeter - [masterโ—] ยป ruby examples/basic_assertion.rb
  W, [2015-10-17T19:31:12.021004 #33216]  WARN -- : Test executing locally ...

Note: most of the examples assume the JMeter binary is installed in /usr/share/jmeter/bin/ however you can modify this in your example to something that suits your installation e.g.:

...
end.run(path: 'C/Program Files/JMeter/bin/', gui: true)

ruby-jmeter's People

Contributors

304 avatar benhutchison avatar brki avatar dansingerman avatar dizzy42 avatar honsq90 avatar ivanvanderbyl avatar jdutil avatar jmaeso avatar mikeknep avatar oriolgual avatar pgilad avatar pikeit avatar rpocklin avatar sworisbreathing avatar tilln avatar timkoopmans avatar tspacek avatar victorb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ruby-jmeter's Issues

`assert contains` always fails

I'm trying out ruby-jmeter with Ruby 2.1.5, and assert contains: 'foo' seems always to fail. To rule out issues with my own test plan, I'm using a simplified version of the Etsy test in the examples directory:

require 'ruby-jmeter'

test do
  defaults :domain => 'www.etsy.com'
  cache :clear_each_iteration => true
  cookies
  threads :count => 1, :loops => 1 do
    transaction '01_etsy_home' do
      visit :name => 'home', :url => 'http://www.etsy.com/' do
        assert 'contains' => 'Etsy'
      end
    end
    view_results_tree
  end
end.jmx
ruby

When running the generated .jmx in JMeter, the ResponseAssertion fails, even though I can clearly see the text "Etsy" appears in the response:

screen shot 2014-12-10 at 9 30 27 am

Here's what JMeter has to say:

screen shot 2014-12-10 at 9 30 37 am

Create a unique file for each thread

I need to test a feature of the web app where user uploads XML file for processing. I cant use single XML as duplicate files generate error in the app. I have external script that randomizes some aspects of the XML and I need a way to assign those files to each worker thread.

Is this possible to do with this DSL ?

BTW, unrelated, do you have somewhere status of jmeter features supported so far ?

BTW2, thanks for the great work, I hate GUIs.

Unable to do multiple entries in HTTP Header or User Defined Variables

Hi,

As mentioned on the depreciated repository, I am unable to insert multiple entries into the HTTP Header Manager or User Defined Variables config elements.

Only the last values are used on multiple entries and "fill_in" has no effect. Attached is two screenshots of what I am trying to achieve.

httpheadermanager

userdefinedvariables

Not sure if this is just a missing feature, a bug or if I am simply doing it wrong. An example or any help would be appreciated.

Thanks.

Simplify module controller

#24 introduced some changes to the module controller so that it can properly reference other test components. Currently, this is done by passing the node path as an array of test elements (which is how JMeter resolves the node path).

This isn't exactly intuitive, and it makes the tests somewhat brittle - if you rename your test plan (or any other part of the hierarchy), you will have to update all the module controllers which reference that node. For example:

-test do
+test name: 'foo' do
   threads 1 do
     Simple name: 'foo'
   end
   threads 1 do
     module_controller name: 'Call Simple', node_path: [
       'WorkBench',
       'TestPlan', # This won't work anymore because the node was renamed.
       'ThreadGroup',
       'foo' ]
 end

I haven't opened a pull request for this one because I'm still trying to figure out what's the best approach. Off the top of my head, I'm wondering if we could optionally store test items in a hash, so they could be referenced later by a module controller. Something to the effect of:

-test do
+test name: 'foo' do
   threads 1 do
     simple name: 'foo',
       unique_id: 'foo_1' #this should be unique
   end
   threads 1 do
     module_controller name: 'Call Simple',
       node_ref: 'foo_1' # this should match another node's unique_id
   end
 end

Thoughts?

installation problem

Building native extensions. This could take a while...
ERROR: Error installing ruby-jmeter:
ERROR: Failed to build gem native extension.

    /usr/bin/ruby1.9.1 extconf.rb

checking for main() in -lstdc++... no
creating Makefile

make
compiling unf.cc
make: g++: Command not found
make: *** [unf.o] Error 127

Gem files will remain installed in /var/lib/gems/1.9.1/gems/unf_ext-0.0.7.2 for inspection.
Results logged to /var/lib/gems/1.9.1/gems/unf_ext-0.0.7.2/ext/unf_ext/gem_make.out

Generated DSL source out of date / does not match idl.xml

In the course of investigating an issue in the DSL source under lib/ruby-jmeter/dsl, I found that it looks like it's out of date. I understand the source is auto-generated. However, simply running ruby lib/ruby-jmeter/idl.rb in a fresh copy of the repository results in a number of source files in lib/ruby-jmeter/dsl changing. Looking at the git history shows that lib/ruby-jmeter/idl.xml is newer than most of the files inlib/ruby-jmeter/dsl`. It is older than 1 or 2 though.

This implies that the generated source is not all up to date, but has also in a couple of cases been tweaked by hand and/or auto-generated changes have been selectively committed since most recent idl.xml commit.

There are cases where the XML has changed, but this isn't reflected in the auto-generated file in the repo (e.g. embedded_url_re disapeared from the idl.xml c14caf3#diff-2391882be85be2c7f559dfaa99483e3fL94 but not from the autogenerated

<stringProp name="HTTPSampler.embedded_url_re"/>
). There are also cases where things have been manually tweaked (e.g. the conditional creation of start/end indexes at
#{'<stringProp name="ForeachController.startIndex"/>' if params[:startIndex]}
#{'<stringProp name="ForeachController.endIndex"/>' if params[:endIndex]}

This makes it a bit tricky to decide which route to take when fixing a bug in the DSL code. Should it be fixed by changing the DSL generation code, or should it be fixed by tweaking the generated code by hand, after which the file joins the list of existing (originally-autogenerated) files which aren't simply the result of running the DSL generation? My concern with the latter route is that it adds to the special cases. I would think this should be avoided, because the more special cases there are, the less relevant/use the autogeneration becomes and the more overhead with jmeter updates in the long run. Any thoughts?

Fails to generate tests with unicode URLs

Performing a test of the form
get url: "http://example.com?unicode=รฅรŸโˆ‚ห™โˆ†ยฌยฌ"
returns the following error:

/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/ruby-jmeter-2.13.3/lib/ruby-jmeter/helpers/parser.rb:14:in `split': invalid byte sequence in US-ASCII (ArgumentError)
    from /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/ruby-jmeter-2.13.3/lib/ruby-jmeter/helpers/parser.rb:14:in `parse_http_request'
    from /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/ruby-jmeter-2.13.3/lib/ruby-jmeter/dsl.rb:108:in `get'

This could be due to the fact that URI::decode (called in Parser::parse_url) returns a string without specific encoding information, thereby defaulting to US-ASCII, which split (Called in parse_http_request then complains about. A possible solution would be to switch to CGI::unescape which allows the specification of encoding information.

Typo in README code example

You've got a typo in the Threads section of the README (under Advanced Usage).

threads count: 100, ramup: 30, duration: 60

should be:

threads count: 100, rampup: 30, duration: 60

Defaults download_resources does not turn flag off

I've omitted download_resources or set it to false, both do not unflag Retrieve All Embedded Resources in HttpRequestDefaults. Something I'm missing?

test do
    defaults download_resources: false
end.run(gui: true)

Your docs/examples don't reflect your greatness.

I just looked into this Friday/Monday because I wanted the utility of JMeter but we're a Ruby shop and . . . well . . . JMeter is a hard sell once people try to use it. So I found this wrapper and everything seemed to just work.

But I wanted to use the random order controller and wasn't sure if it was supported. Nothing in the docs. No example. A quick grep through the code and I realized it was there. I tried it and it worked exactly as expected.

You should really have better docs/examples. I'm incredibly happy with what you've put together. I want to chip in. Are you more interested in me giving you example/doc PRs or fixing some of the bugs in the Issues bucket?

jsr223_assertion mix up script with scriptLanguage

The generated JMX has the script and scriptLanguage parameters mixed up when using the jsr223_assertion component :

            <stringProp name="script">javascript</stringProp>
            <stringProp name="scriptLanguage">//My Javascript code ends up here</stringProp>

Of course this gives error in JMeter ( JSR223 script Assert state javax.script.ScriptException: Cannot find engine named: '//My Javascript... ). This happens with JRuby 9.0.1.0.

Looking at the source it seems that the order of these fields in the XML template is significant (!) in the file ruby-jmeter/dsl/jsr223_assertion.rb.

So changing to the following helps:

<JSR223Assertion guiclass="TestBeanGUI" testclass="JSR223Assertion" testname="#{testname}" enabled="true">
  <stringProp name="parameters"/>
  <stringProp name="filename"/>
  <stringProp name="cacheKey"/>
  <stringProp name="script"/>
  <stringProp name="scriptLanguage"/>
</JSR223Assertion>)

which is also similar to the other JSR223 components in the same directory.

I should be able to make a PR if you need.

Send files with request

Hi,

Is it currently possible to set the "Send files with request" on the HTTP Request with ruby-jmeter?

Please see screenshot for an example.

sendfileswithrequest

Regards

Cannot run basic test against OOTB Rails application

I'm trying to use ruby-jmeter against a Rails app locally. I run the following:

require 'rubygems'
require 'ruby-jmeter'

test do
  threads count: 1 do
    visit name: 'Localhost', url: 'http://localhost:3000'
  end
end.run(
  path: '/opt/jmeter/bin/'
)

using

$ ruby load-test.rb
W, [2014-04-12T10:44:41.420638 #89118]  WARN -- : Test executing locally ...
I, [2014-04-12T10:46:33.925950 #89245]  INFO -- : Local Results at: jmeter.jtl

But there are no requests logged by Rails (although they are logged when I visit http://localhost:3000 with a browser), and the jmeter.jtl log file seems to show that it isn't doing anything:

$ less jmeter.jtl
1397313933747|72|Localhost|200|ThreadGroup 1-1|true|9829|1|1|72|1|0|null
1397313933827|6|Localhost|200|ThreadGroup 1-1|true|9829|1|1|6|1|0|null
1397313933833|5|Localhost|200|ThreadGroup 1-1|true|9829|1|1|5|1|0|null
1397313933839|4|Localhost|200|ThreadGroup 1-1|true|9829|1|1|4|1|0|null
....

Test runner and test suite structure for large ruby-jmeter suite?

Hi. Could you offer guidance on how best to organize a large test suite made completely in ruby-jmeter? Testing multiple APIs with several scenarios.

I would like to utilize BDD libraries like Spinach to wrap ruby-jmeter tests, but I'm having a hard time imagining a non-invasive way to do it.

Setting boolean properties to false requires passing strings

It looks like some of the logic around setting boolean properties to false doesn't work. For example:

transaction parent: false

produces

<TransactionController guiclass="TransactionControllerGui" testclass="TransactionController" testname="TransactionController" enabled="true">
  <boolProp name="TransactionController.parent">true</boolProp>
  <boolProp name="TransactionController.includeTimers">false</boolProp>
</TransactionController>

This appears to be due to the way default values are handled the transaction_controller method in dsl.rb (line 195):

      params[:parent] ||= true

As a workaround, you can pass the value as a string:

transaction parent: 'false'

Non-standard interface for jmeter-plugins

def initialize(name, params={})
instead of
def initialize(params={}).

This is really confusing at times, because it is totally valid ruby to use the normal syntax in a test plan, but that results in having a hash in the variable name, and nil in parameters :-/

Can we change this? Or was there a good reason to have it this way?

trouble

/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in require': cannot load such file -- ruby-jmeter (LoadError) from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:inrequire'
from mytest.rb:2:in `

'

Support of external libraries

I have REST client for my API build on top of rest-client and ruby-oauth gems, which I use for testing etc. Is there any possibility to use it for jmeter test creation?

Unable to set global properties on to jmeter

We are using a number of JMeter servers in Kuberneties as a grid to generate the load in NFTs.
As part of running the tests, we need to set some properties, which should be set/sent across all the grid servers. These properties can only be decided after starting up the grid and before kicking of the tests (i.e. before calling run method). The way to achieve this as per JMeter documentation is to set global properties with -G option while executing the command line on controller (example below). (for details. http://jmeter.apache.org/usermanual/get-started.html#options)

Example.

jmeter -n -t pipeline_test.jmx -j pipeline_test.log -Gsome_property_1=1 -Gsome_property_2=2000000001 -Gsome_property_3=2000000000 -l pipeline_test.jtl -q user.properties -R 192.168.99.100,192.168.99.101

As per current implementation of the DSL, we are not able to set these properties.
Looking at above link which is detailing various options available on JMeter command line, what we would like to propose is to have open option like for e.g. 'otherJmeterOptions' which can be used to set any extra params that should be passed on to JMeter executable directly. This will also cater for future releases where JMeter provides any new command line options.

end.run(
        file: scenario.project_filename,
        log: scenario.log_filename,
        jtl: scenario.results_filename,
        remote_hosts: File.readlines(ips.txt', __FILE__)[0],
        properties: scenario.resource_filename('user.properties'),
        debug: true,
        otherJmeterOptions: "-Gsome_property_1=1 -Gsome_property_2=2000000001 -Gsome_property_3=2000000000"
    )

Generating plan does not work on Mac OSX 10.6.8

Hello,

Used https://github.com/flood-io/ruby-jmeter

macbook:/ xxx$ sudo gem install ruby-jmeter
Password:
Successfully installed ruby-jmeter-2.1.0
1 gem installed
Installing ri documentation for ruby-jmeter-2.1.0...
Installing RDoc documentation for ruby-jmeter-2.1.0...

macbook:/ philippemouawad$ ruby /simple.rb
/jmeter_wordpress.rb:5: syntax error, unexpected ':', expecting kEND
threads count: 10 do
^
/jmeter_wordpress.rb:6: syntax error, unexpected ',', expecting kEND
visit name: 'Google Search', url: 'http://google.com'
^
/jmeter_wordpress.rb:8: syntax error, unexpected kEND, expecting $end
end.jmx
^

where simple.rb is:

test do
threads count: 10 do
visit name: 'Google Search', url: 'http://google.com'
end
end.jmx

Note I have this:
macbook-pro-de-philippe-mouawad:/ philippemouawad$ ruby -version
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin10.0]
-e:1: undefined local variable or method `rsion' for main:Object (NameError)

Is there a mandatory system requirement ?

Thanks

Output variables from extracted html response to JTL?

Is it possible to extract data from an HTML response of GET request and output this value to JTL file?

extract css: "div#global-footer-system-info", name: 'Test123', variable: 'Test123'

Also from the response header of GET request?
extract regex: "CustomHeaderName: '(.+?)'", name: 'Test123', variable: 'Test123'

URLs Generated by ruby-jmeter's flood integration don't work

The URL's that are generated by the ruby-jmeter flood integration don't seem to point at anything. They all say "Flood not found" when used. I can still see running floods if I go in through the UI so it's not the end of the world, just an annoyance.

Support for User Defined Cookies in HTTP Cache Manager

Right now, it's not possible to send custom cookies with the requests. It would be really helpful to be able to do it. It's limiting our capability to run some specific load tests via flood.io on apps whose main functionality depends on certain cookies existing.

error on opening created jtl file

On running tests, the jtl file is created. Here is the content of the jtl file

1431002449675|807|Home Page|200|Home Page Users 1-1|true|20531|1|1|311|1|0|null

On opening the jtl file from JMeter UI, the following error is thrown:
2015/05/07 16:54:09 WARN - jmeter.save.CSVSaveService: Error parsing field 'timeStamp' at line 1 java.text.ParseException: No date-time format found matching 1431002449675|807|Home Page|200|Home Page Users 1-1|true|20531|1|1|311|1|0|null

How to circumvent this error?

can't use

/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in require': cannot load such file -- ruby-jmeter (LoadError) from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:inrequire'
from mytest.rb:2:in `

'

Thread Group: Action to be taken after a Sampler error

I couldn't find a way to set this option in a thread group using the ruby DSL.

Use case, if an assertion fails I want the thread to stop and this behavior can be configured in the Action to be taken after a Sampler error option in a thread group manually in the JMeter UI.

Image of Action to be taken after a Sampler error

This could be a good enhancement candidate or please help me by pointing out how can this be done using a properties file option that I'm probably missing.

Thanks

Support for "Match No." within Extractors

I often write tests (in jMeter) that select a random element from a list, using the Match No. properly set to 0. This might actually be default behavior if the value is not populated. However its still a valid request in the event you needed to select the 1st element for example.

From what I can tell, the DSL does not currently support this.

How can I set simple_data_writer properties?

Hello,

I wrote configuration for simple_data_writer like following.

simple_data_writer name: "Result", fieldNames: true, xml: false, saveAssertionResultsFailureMessage: true, responseDataOnError: true, filename:"file_name"

But configuration under "SampleSaveConfiguration" element was not changed.
How can I change those values?

Regards,
Masanori Takahashi

Use Array of URLs to visit

Is there a way to use an array of paths to have Ruby-Jmeter to visit? I have an array of thousands of URLs. Same host, just different paths.

[
  'foo.com',
  'foo.com/bar',
  'foo.com/bar/main-results',
  ....
]

Using a User Defined Variable as Server Name

Hi,

Would it be possible to include the functionality to use variables for Server Name in an HTTP Request?

Please see screenshots for the desired result and current result.

Desired:
desiredresult

Currently:
currentresult

Regards

User Parameters per-iteration setting is ignored

It seems this is because of invalid XML in dsl/user_parameters.rb.

I've developed a fix plus unit test for this.

Actually, I've developed 3 fixes, but I'm not sure which to use, otherwise I'd have also submitted a PR!

  1. The first thing I did was to tweak the XML by hand. However, when I started thinking about contributing the fix, I realised that the code in dsl/ is autogenerated.
  2. I decided a safer option was to use the update_at_xpath(params) route. I added code to that helper to deal with Builder objects and tweaked user_parameters() in dsl.rb to use this route.
  3. I tweaked update(params) in dsl.rb so that instead of appending a child << it replaced the children.

Option 1 adds to the DSL files which are tweaked by hand, which doesn't seem ideal (see also #87). Option 2 shouldn't affect existing code, but seems messier than option 3. Option 3 is tidier than 2, but has the potential to affect existing code and test plans, so I'm wary of it despite all tests passing because I'm don't feel familiar enough with the rest of the code and the ins-and-outs of the jmeter XML (idl.xml).

Any of the 3 routes fixes the problem. Any thoughts on which is preferred? Once decided, I can submit a PR for any of them.

Options to overwrite jmeter properties (or the whole jmeter.properties file)

Hi,

I was playing with ruby-jmeter and Jenkins and I noticed that the latest version of the performance plugin can't parse the JMeter results if they are in CSV format instead of XML. See https://issues.jenkins-ci.org/browse/JENKINS-16627

I couldn't find a way to programmatically overwrite the jmeter.save.saveservice.output_format property so I edited it straight on the jruby-jmeter/helpers/jmeter.properties file.

Did I miss something on the documentation to overwrite the properties?

Thanks!

Felipe

Using different headers per thread

I'm currently testing an API that uses a special header to authenticate the user. I'd like to run a test with multiple threads and each one using a different authentication. Is that possible?

I've been digging into the code but since I'm quite new to jmeter I don't see how to proceed.

Using Ruby 2.1, ruby-jmeter seg faults when trying to require ruby files in the lib/ruby-jmeter/plugins directory

I am using ruby-jmeter from a rake task that I've developed, that lives within a Rails project.

Following an upgrade from Ruby 2.0 to Ruby 2.1, ruby-jmeter would consistently seg fault when the environment was loaded. I first suspected a load order issue, as I was able to use ruby-jmeter successfully when I placed the ruby-jmeter dependency at the top of my Gemfile, but received a seg fault when the dependency was placed at the bottom of the Gemfile.

Through some debugging, I narrowed the issue down to two lines of code within lib/ruby-jmeter.rb.

The following code, which is the current code the gem is using, as of version 2.11.2, gives me a seg fault:

Dir.glob(lib + '/ruby-jmeter/dsl/*', &method(:require))
Dir.glob(lib + '/ruby-jmeter/plugins/*', &method(:require))

However, when I change the code as follows, I do not receive a seg fault, and am able to successfully generate my JMeter test plan:

Dir.glob(lib + '/ruby-jmeter/dsl/*').each do |file|
  require file
end
Dir.glob(lib + '/ruby-jmeter/plugins/*').each do |file|
  require file
end

My first reaction is that this seems like a bug in the ruby interpreter in version 2.1, but I thought posting this issue might help others that are running into the same problem as myself. I'll submit a PR for the issue.

How to run with jvmargs?

When hitting a particular server I am getting an SSL handshake error. The same one as described in this stack overflow. In trying to diagnose my problem I am hoping to be able to tun jmeter via ruby-jmeter with a jvmarg configured for debugging the ssl handshake: -Djavax.net.debug=ssl:handshake:verbose. Is there a way to do this?

Note: I differ from the stack overflow in that I am not hitting a TomCat server, my ssl tests are clean at ssllabs.com, it is not an RC4 issue, and I attempted to replace my Java 8 Cryptography Extension with the latest from Oracle, as in one of the SO comments, to no avail.

Dump extraction values

I'm attempting to do a simple dump of an extract for debugging. How can this be done? It simply outputs "${apdex}"

  threads count: 1 do
    visit 'https://flood.io/d384673f64e3a3/result.json' do
      extract json: '.apdex.score', name: 'apdex'
     end
     puts '${apdex}'
  end

Aggregate Report vs. Standard Plugins

I did some digging and found that Aggregate Report format available in the GUI is only obtainable from the command line through post processing. The Standard Plugins library contains a method of doing this. Would you be willing to support a true Aggregate Report?

./JMeterPluginsCMD.sh --generate-csv new.csv --input-jtl existing.jtl --plugin-type AggregateReport

http://stackoverflow.com/a/7992846

http://www.quora.com/How-do-we-analyze-reports-in-JMeter/answers/9712920

https://code.google.com/p/gisgraphy/source/browse/trunk/gisgraphy/src/bench/bin/aggregate_sample.sh?r=111&spec=svn362

Can't pass arguments to a OS process sampler

When using os_process_sampler, I can't seem to generate jmeter xml containing the correct arguments to a command.

I should get:

<collectionProp name="Arguments.arguments">
             <elementProp name="" elementType="Argument">
                <stringProp name="Argument.name"></stringProp>
                <stringProp name="Argument.value">push</stringProp#>
                <stringProp name="Argument.metadata">=</stringProp>
              </elementProp>
             <elementProp name="" elementType="Argument">
                <stringProp name="Argument.name"></stringProp>
                <stringProp name="Argument.value">origin</stringProp#>
                <stringProp name="Argument.metadata">=</stringProp>
              </elementProp>
             <elementProp name="" elementType="Argument">
                <stringProp name="Argument.name"></stringProp>
                <stringProp name="Argument.value">master</stringProp#>
                <stringProp name="Argument.metadata">=</stringProp>
              </elementProp>
</collectionProp>

What I get

<collectionProp name="Arguments.arguments">["push", "origin", "master"]</collectionProp>

My jmeter dsl code:

 os_process_sampler  'SystemSampler.command'   => 'git', 
                        'Arguments.arguments' => ['push', 'origin', 'master']

Any ideas what we're doing wrong?

Open3 unsupported spawn option when using JRuby

jruby/lib/jruby.jar!/jruby/kernel19/process.rb:4 warning: unsupported spawn option: in
TypeError: wrong exec option: [:out, :err]
_spawn_internal at org/jruby/RubyProcess.java:1091
any ideas
e.g. test do
threads count: 10 do
visit name: 'Pet Shop Home', url: 'http://54.252.57.49/MSPetShop'
end
end.run(
path: 'C:\apache-jmeter-2.9\bin',
file: 'jmeter.jmx',
log: 'jmeter.log',
jtl: 'results.jtl')

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.