ruby-jmeter 2.13.7 → 2.13.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|