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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2fad51ef27a7e3737b320fbb418db4772ffe6300
4
- data.tar.gz: 6b266bfbd9507a0b8f08259d80a110923ef74e0d
3
+ metadata.gz: 01ab5cb50b02e20695b64b2e420a551117a9af6b
4
+ data.tar.gz: 4a844acbf379fd95132e773fd46b5dbdb2d317d3
5
5
  SHA512:
6
- metadata.gz: 590dadd09d7a91119e24acb35af182950e127f4f47be0c4207c8b5b9a2af0655ad00b51ffaab2fa8035f4b034dc021c4666b96d861c941f100c141018aa3a386
7
- data.tar.gz: 4b8110856c259925912c3b471f629656000539295ad0d6e137f79ab37419ab6a40d9798ae6144605c2d590cd429706e381c5f27c5ec454d00defa85fbad00ad8
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,5000
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)
@@ -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,
@@ -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 = RubyJmeter::ResponseAssertion.new(params)
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(name, params = {}, filename="perfMon.jtl", &block)
515
- node = RubyJmeter::Plugins::PerfmonCollector.new(name, params, filename)
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>true</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
- #{metricConnections.root.to_s}
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
@@ -1,3 +1,3 @@
1
1
  module RubyJmeter
2
- VERSION = '2.13.7'
2
+ VERSION = '2.13.8'
3
3
  end
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.7
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 00:00:00.000000000 Z
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