ruby-jmeter 2.13.7 → 2.13.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +76 -1
- data/examples/basic_json_path_assertion.rb +10 -0
- data/examples/basic_perfmon.rb +2 -1
- data/lib/ruby-jmeter/dsl.rb +22 -9
- data/lib/ruby-jmeter/plugins/json_path_assertion.rb +18 -0
- data/lib/ruby-jmeter/plugins/perfmon_collector.rb +28 -21
- data/lib/ruby-jmeter/version.rb +1 -1
- data/spec/dsl_spec.rb +56 -2
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01ab5cb50b02e20695b64b2e420a551117a9af6b
|
4
|
+
data.tar.gz: 4a844acbf379fd95132e773fd46b5dbdb2d317d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e242b7f6a1f74a4c0adbff263ff5a2d5ef7950aaee5218085bca02e632f6c8bae13ee62cdb2347a6b1a8a8495f09e65c604c26ff9b25c0faf07da6e10a6d01e6
|
7
|
+
data.tar.gz: 0dc1ce59b26da2c80fa14de8db4ad5db04a57cd2fb52104a1cf5e5230904bb5a08303924154e5d491ca1b4cf9b5cfbf2bd18a4c2077a48e4c99e018fffb91b06
|
data/README.md
CHANGED
@@ -303,7 +303,7 @@ This method takes 2 parameters: the constant delay, and an optional variable del
|
|
303
303
|
# constant delay of 3 seconds
|
304
304
|
think_time 3000
|
305
305
|
# constant delay of 1 seconds with variance up to 6 seconds.
|
306
|
-
random_timer 1000,
|
306
|
+
random_timer 1000, 6000
|
307
307
|
```
|
308
308
|
|
309
309
|
### Response Extractor
|
@@ -381,3 +381,78 @@ This work is being sponsored by Flood IO. Get in touch with us if you'd like to
|
|
381
381
|
4. Commit your changes (`git commit -am 'Add some feature'`)
|
382
382
|
5. Push to the branch (`git push origin my-new-feature`)
|
383
383
|
6. Create new Pull Request
|
384
|
+
|
385
|
+
### IDL
|
386
|
+
|
387
|
+
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.
|
388
|
+
|
389
|
+
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`
|
390
|
+
|
391
|
+
For example:
|
392
|
+
|
393
|
+
```sh
|
394
|
+
flood/ruby-jmeter - [master●] » ruby lib/ruby-jmeter/idl.rb
|
395
|
+
flood/ruby-jmeter - [master●] » git status
|
396
|
+
On branch master
|
397
|
+
Your branch is up-to-date with 'origin/master'.
|
398
|
+
Changes not staged for commit:
|
399
|
+
(use "git add <file>..." to update what will be committed)
|
400
|
+
(use "git checkout -- <file>..." to discard changes in working directory)
|
401
|
+
|
402
|
+
modified: lib/ruby-jmeter/DSL.md
|
403
|
+
modified: lib/ruby-jmeter/dsl/foreach_controller.rb
|
404
|
+
modified: lib/ruby-jmeter/dsl/http_request.rb
|
405
|
+
modified: lib/ruby-jmeter/dsl/http_request_defaults.rb
|
406
|
+
modified: lib/ruby-jmeter/dsl/regular_expression_extractor.rb
|
407
|
+
modified: lib/ruby-jmeter/dsl/response_assertion.rb
|
408
|
+
modified: lib/ruby-jmeter/dsl/test_fragment.rb
|
409
|
+
modified: lib/ruby-jmeter/dsl/user_parameters.rb
|
410
|
+
```
|
411
|
+
|
412
|
+
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.
|
413
|
+
|
414
|
+
### DSL
|
415
|
+
|
416
|
+
Much of the behaviour of the gem is defined in `lib/ruby-jmeter/dsl.rb` which is where you should be updating code. This is now a very long module and in much need of refactoring. PR's are welcomed.
|
417
|
+
|
418
|
+
### Plugins
|
419
|
+
|
420
|
+
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.
|
421
|
+
|
422
|
+
### Bundler
|
423
|
+
|
424
|
+
We recommend using the Ruby gem bundle to manage your dependencies. Typical setup would be:
|
425
|
+
|
426
|
+
|
427
|
+
```sh
|
428
|
+
gem install bundler
|
429
|
+
cd <your local clone>
|
430
|
+
bundle install
|
431
|
+
```
|
432
|
+
|
433
|
+
Then you can run any rake / test tasks with the prefix `bundle exec`
|
434
|
+
|
435
|
+
### Tests
|
436
|
+
|
437
|
+
If contributing please add an appropriate test. See `spec/dsl_spec.rb` for examples. Tests can be run from the command line as follows:
|
438
|
+
|
439
|
+
$ bundle exec rspec
|
440
|
+
|
441
|
+
### Examples
|
442
|
+
|
443
|
+
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:
|
444
|
+
|
445
|
+
```ruby
|
446
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
447
|
+
```
|
448
|
+
|
449
|
+
$ flood/ruby-jmeter - [master●] » ruby examples/basic_assertion.rb
|
450
|
+
W, [2015-10-17T19:31:12.021004 #33216] WARN -- : Test executing locally ...
|
451
|
+
|
452
|
+
Note: most of the examples assume the JMeter binary is installed in `/usr/share/jmeter-2.13/bin/` however you can modify this in your example to something that suits your installation e.g.:
|
453
|
+
|
454
|
+
|
455
|
+
```ruby
|
456
|
+
...
|
457
|
+
end.run(path: 'C/Program Files/JMeter-2.13/bin/', gui: true)
|
458
|
+
```
|
@@ -0,0 +1,10 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'ruby-jmeter'
|
3
|
+
|
4
|
+
test do
|
5
|
+
threads count: 1, loop: 1 do
|
6
|
+
visit 'https://api.github.com/orgs/flood-io/repos' do
|
7
|
+
assert json: '.name', value: 'ruby-jmeter'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end.run(path: '/usr/share/jmeter-2.13/bin/', gui: true)
|
data/examples/basic_perfmon.rb
CHANGED
@@ -20,7 +20,8 @@ test do
|
|
20
20
|
# You need perfmon agent running
|
21
21
|
# http://jmeter-plugins.org/wiki/PerfMonAgent/
|
22
22
|
#
|
23
|
-
perfmon_collector 'Perfmon Metrics Collector',
|
23
|
+
perfmon_collector name: 'Perfmon Metrics Collector',
|
24
|
+
nodes: [
|
24
25
|
{
|
25
26
|
server: 'localhost',
|
26
27
|
port: 4444,
|
data/lib/ruby-jmeter/dsl.rb
CHANGED
@@ -401,13 +401,7 @@ module RubyJmeter
|
|
401
401
|
def response_assertion(params = {}, &block)
|
402
402
|
params[:test_type] = parse_test_type(params)
|
403
403
|
params['0'] = params.values.first
|
404
|
-
node =
|
405
|
-
if params[:variable] then
|
406
|
-
params['Scope.variable'] = params[:variable]
|
407
|
-
node.doc.xpath("//stringProp[@name='Assertion.scope']").first.content = 'variable'
|
408
|
-
end
|
409
|
-
node.doc.xpath("//stringProp[@name='Assertion.scope']").remove if
|
410
|
-
params[:scope] == 'main' || params['scope'] == 'main'
|
404
|
+
node = params[:json] ? json_path_assertion(params) : assertion(params)
|
411
405
|
attach_node(node, &block)
|
412
406
|
end
|
413
407
|
|
@@ -511,8 +505,8 @@ module RubyJmeter
|
|
511
505
|
|
512
506
|
alias_method :active_threads, :active_threads_over_time
|
513
507
|
|
514
|
-
def perfmon_collector(
|
515
|
-
node = RubyJmeter::Plugins::PerfmonCollector.new(
|
508
|
+
def perfmon_collector(params = {}, &block)
|
509
|
+
node = RubyJmeter::Plugins::PerfmonCollector.new(params)
|
516
510
|
attach_node(node, &block)
|
517
511
|
end
|
518
512
|
|
@@ -672,6 +666,25 @@ module RubyJmeter
|
|
672
666
|
@log.level = Logger::DEBUG
|
673
667
|
@log
|
674
668
|
end
|
669
|
+
|
670
|
+
def json_path_assertion(params)
|
671
|
+
params[:EXPECTED_VALUE] = params[:value]
|
672
|
+
params[:JSON_PATH] = params[:json]
|
673
|
+
RubyJmeter::Plugins::JsonPathAssertion.new(params)
|
674
|
+
end
|
675
|
+
|
676
|
+
def assertion(params)
|
677
|
+
RubyJmeter::ResponseAssertion.new(params).tap do |node|
|
678
|
+
if params[:variable]
|
679
|
+
params['Scope.variable'] = params[:variable]
|
680
|
+
node.doc.xpath("//stringProp[@name='Assertion.scope']").first.content = 'variable'
|
681
|
+
end
|
682
|
+
|
683
|
+
if params[:scope] == 'main' || params['scope'] == 'main'
|
684
|
+
node.doc.xpath("//stringProp[@name='Assertion.scope']").remove
|
685
|
+
end
|
686
|
+
end
|
687
|
+
end
|
675
688
|
end
|
676
689
|
end
|
677
690
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RubyJmeter
|
2
|
+
module Plugins
|
3
|
+
class JsonPathAssertion
|
4
|
+
attr_accessor :doc
|
5
|
+
include Helper
|
6
|
+
def initialize(params={})
|
7
|
+
@doc = Nokogiri::XML(<<-EOF.strip_heredoc)
|
8
|
+
<com.atlantbh.jmeter.plugins.jsonutils.jsonpathassertion.JSONPathAssertion guiclass="com.atlantbh.jmeter.plugins.jsonutils.jsonpathassertion.gui.JSONPathAssertionGui" testclass="com.atlantbh.jmeter.plugins.jsonutils.jsonpathassertion.JSONPathAssertion" testname="jp@gc - JSON Path Assertion" enabled="true">
|
9
|
+
<stringProp name="EXPECTED_VALUE"></stringProp>
|
10
|
+
<stringProp name="JSON_PATH"></stringProp>
|
11
|
+
<boolProp name="JSONVALIDATION">true</boolProp>
|
12
|
+
</com.atlantbh.jmeter.plugins.jsonutils.jsonpathassertion.JSONPathAssertion>
|
13
|
+
EOF
|
14
|
+
update params
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -3,26 +3,10 @@ module RubyJmeter
|
|
3
3
|
class PerfmonCollector
|
4
4
|
attr_accessor :doc
|
5
5
|
include Helper
|
6
|
-
def initialize(name, params={}, filename="perfMon.jtl")
|
7
|
-
metricNodes = params.collect do |m|
|
8
|
-
"
|
9
|
-
<collectionProp name=\"\">
|
10
|
-
<stringProp name=\"\">#{m[:server]}</stringProp>
|
11
|
-
<stringProp name=\"\">#{m[:port]}</stringProp>
|
12
|
-
<stringProp name=\"\">#{m[:metric]}</stringProp>
|
13
|
-
<stringProp name=\"\">#{m[:parameters]}</stringProp>
|
14
|
-
</collectionProp>
|
15
|
-
"
|
16
|
-
end
|
17
|
-
|
18
|
-
metricConnections = Nokogiri::XML(<<-XML.strip_heredoc)
|
19
|
-
<collectionProp name="metricConnections">
|
20
|
-
#{metricNodes.join "\n"}
|
21
|
-
</collectionProp>
|
22
|
-
XML
|
23
6
|
|
7
|
+
def initialize(params = {})
|
24
8
|
@doc = Nokogiri::XML(<<-XML.strip_heredoc)
|
25
|
-
<kg.apc.jmeter.perfmon.PerfMonCollector guiclass="kg.apc.jmeter.vizualizers.PerfMonGui" testclass="kg.apc.jmeter.perfmon.PerfMonCollector" testname="#{name}" enabled="true">
|
9
|
+
<kg.apc.jmeter.perfmon.PerfMonCollector guiclass="kg.apc.jmeter.vizualizers.PerfMonGui" testclass="kg.apc.jmeter.perfmon.PerfMonCollector" testname="#{params[:name] || 'PerfmonCollector'}" enabled="true">
|
26
10
|
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
27
11
|
<objProp>
|
28
12
|
<name>saveConfig</name>
|
@@ -41,7 +25,7 @@ module RubyJmeter
|
|
41
25
|
<subresults>false</subresults>
|
42
26
|
<responseData>false</responseData>
|
43
27
|
<samplerData>false</samplerData>
|
44
|
-
<xml
|
28
|
+
<xml>#{(params[:xml] || false).to_s}</xml>
|
45
29
|
<fieldNames>false</fieldNames>
|
46
30
|
<responseHeaders>false</responseHeaders>
|
47
31
|
<requestHeaders>false</requestHeaders>
|
@@ -53,7 +37,7 @@ module RubyJmeter
|
|
53
37
|
<sampleCount>true</sampleCount>
|
54
38
|
</value>
|
55
39
|
</objProp>
|
56
|
-
<stringProp name="filename">#{filename}</stringProp>
|
40
|
+
<stringProp name="filename">#{params[:filename] || 'perfmon.jtl'}</stringProp>
|
57
41
|
<longProp name="interval_grouping">1000</longProp>
|
58
42
|
<boolProp name="graph_aggregated">false</boolProp>
|
59
43
|
<stringProp name="include_sample_labels"></stringProp>
|
@@ -62,11 +46,34 @@ module RubyJmeter
|
|
62
46
|
<stringProp name="end_offset"></stringProp>
|
63
47
|
<boolProp name="include_checkbox_state">false</boolProp>
|
64
48
|
<boolProp name="exclude_checkbox_state">false</boolProp>
|
65
|
-
#{
|
49
|
+
#{metric_connections(params).root.to_s}
|
66
50
|
</kg.apc.jmeter.perfmon.PerfMonCollector>
|
67
51
|
XML
|
68
52
|
update params
|
69
53
|
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def metric_connections(params)
|
58
|
+
Nokogiri::XML(<<-XML.strip_heredoc)
|
59
|
+
<collectionProp name="metricConnections">
|
60
|
+
#{metric_nodes(params[:nodes]).join "\n"}
|
61
|
+
</collectionProp>
|
62
|
+
XML
|
63
|
+
end
|
64
|
+
|
65
|
+
def metric_nodes(nodes)
|
66
|
+
nodes.collect do |node|
|
67
|
+
%(
|
68
|
+
<collectionProp name="">
|
69
|
+
<stringProp name="">#{node[:server]}</stringProp>
|
70
|
+
<stringProp name="">#{node[:port]}</stringProp>
|
71
|
+
<stringProp name="">#{node[:metric]}</stringProp>
|
72
|
+
<stringProp name="">#{node[:parameters]}</stringProp>
|
73
|
+
</collectionProp>
|
74
|
+
)
|
75
|
+
end
|
76
|
+
end
|
70
77
|
end
|
71
78
|
end
|
72
79
|
end
|
data/lib/ruby-jmeter/version.rb
CHANGED
data/spec/dsl_spec.rb
CHANGED
@@ -225,7 +225,6 @@ describe 'DSL' do
|
|
225
225
|
|
226
226
|
let(:fragment) { doc.search("//kg.apc.jmeter.threads.SteppingThreadGroup").first }
|
227
227
|
it 'should match on on_sample_error' do
|
228
|
-
puts fragment
|
229
228
|
fragment.search(".//stringProp[@name='ThreadGroup.on_sample_error']").text.should == 'startnextloop'
|
230
229
|
end
|
231
230
|
|
@@ -794,6 +793,30 @@ describe 'DSL' do
|
|
794
793
|
end
|
795
794
|
end
|
796
795
|
|
796
|
+
describe 'json assertion' do
|
797
|
+
let(:doc) do
|
798
|
+
test do
|
799
|
+
visit '/' do
|
800
|
+
assert json: '.key', value: 'value'
|
801
|
+
end
|
802
|
+
end.to_doc
|
803
|
+
end
|
804
|
+
|
805
|
+
let(:fragment) { doc.search('//com.atlantbh.jmeter.plugins.jsonutils.jsonpathassertion.JSONPathAssertion').first }
|
806
|
+
|
807
|
+
it 'should match on expected value' do
|
808
|
+
fragment.search(".//stringProp[@name='EXPECTED_VALUE']").text.should == "value"
|
809
|
+
end
|
810
|
+
|
811
|
+
it 'should match on json path' do
|
812
|
+
fragment.search(".//stringProp[@name='JSON_PATH']").text.should == ".key"
|
813
|
+
end
|
814
|
+
|
815
|
+
it 'should have json validation by default' do
|
816
|
+
fragment.search(".//boolProp[@name='JSONVALIDATION']").text.should == "true"
|
817
|
+
end
|
818
|
+
end
|
819
|
+
|
797
820
|
describe 'scope main' do
|
798
821
|
let(:doc) do
|
799
822
|
test do
|
@@ -1045,6 +1068,37 @@ describe 'DSL' do
|
|
1045
1068
|
it 'should match on response data' do
|
1046
1069
|
fragment.search("//stringProp[@name='RESPONSE_DATA']").text.should == 'Some response data'
|
1047
1070
|
end
|
1048
|
-
|
1049
1071
|
end
|
1072
|
+
|
1073
|
+
describe 'perfmon collector' do
|
1074
|
+
let(:doc) do
|
1075
|
+
test do
|
1076
|
+
threads do
|
1077
|
+
perfmon_collector name: 'perfmon collector name',
|
1078
|
+
nodes:
|
1079
|
+
[
|
1080
|
+
{server: '1.1.1.1', port: 4444, metric: 'CPU', parameters: ''},
|
1081
|
+
{server: '2.2.2.2', port: 4444, metric: 'CPU', parameters: ''}
|
1082
|
+
],
|
1083
|
+
filename: 'perf.jtl',
|
1084
|
+
xml: false
|
1085
|
+
end
|
1086
|
+
end.to_doc
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
let(:fragment) { doc.search("//kg.apc.jmeter.perfmon.PerfMonCollector").first }
|
1090
|
+
let(:metric_connections) { fragment.search("//collectionProp[@name='metricConnections']").first }
|
1091
|
+
|
1092
|
+
it 'should match on name' do
|
1093
|
+
fragment.attributes['testname'].value.should == 'perfmon collector name'
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
it 'should match on xml flag' do
|
1097
|
+
fragment.search(".//xml").first.text.should == 'false'
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
it 'should match on first server ip' do
|
1101
|
+
metric_connections.search("//stringProp[@name='']").first.text.should == '1.1.1.1'
|
1102
|
+
end
|
1103
|
+
end
|
1050
1104
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-jmeter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.13.
|
4
|
+
version: 2.13.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Koopmans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -79,6 +79,7 @@ files:
|
|
79
79
|
- examples/basic_header.rb
|
80
80
|
- examples/basic_http_request_defaults.rb
|
81
81
|
- examples/basic_http_request_with_files.rb
|
82
|
+
- examples/basic_json_path_assertion.rb
|
82
83
|
- examples/basic_json_path_extractor.rb
|
83
84
|
- examples/basic_ldap_ext.rb
|
84
85
|
- examples/basic_loadosophia.rb
|
@@ -242,6 +243,7 @@ files:
|
|
242
243
|
- lib/ruby-jmeter/plugins/composite_graph.rb
|
243
244
|
- lib/ruby-jmeter/plugins/console_status_logger.rb
|
244
245
|
- lib/ruby-jmeter/plugins/dummy_sampler.rb
|
246
|
+
- lib/ruby-jmeter/plugins/json_path_assertion.rb
|
245
247
|
- lib/ruby-jmeter/plugins/json_path_extractor.rb
|
246
248
|
- lib/ruby-jmeter/plugins/latencies_over_time.rb
|
247
249
|
- lib/ruby-jmeter/plugins/loadosophia_uploader.rb
|