gridinit-jmeter 0.0.1

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.
@@ -0,0 +1,44 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'gridinit-jmeter'
3
+
4
+ base_url = 'http://localhost:4567'
5
+ endpoint = 'localhost:3000'
6
+
7
+ test do
8
+
9
+ cache clear_each_iteration: true
10
+ cookies
11
+
12
+ threads 100 do
13
+
14
+ random_timer 3000, 3000
15
+
16
+ transaction 'First Visit', {parent: true} do
17
+ visit 'Home Page', "#{base_url}/" do
18
+ extract 'csrf-token', "content='(.+?)' name='csrf-token'"
19
+ end
20
+ end
21
+
22
+ transaction 'Login' do
23
+ submit 'Submit Form', "#{base_url}/login", {
24
+ fill_in: {
25
+ username: 'tim',
26
+ password: 'password',
27
+ 'csrf-token' => '${csrf-token}'
28
+ }
29
+ }
30
+ think_time 1000
31
+ end
32
+
33
+ transaction 'Check Mana' do
34
+ visit 'Rails Camp' , "#{base_url}/magic" do
35
+ assert "contains", "magic"
36
+ assert "not-contains", "unicorns"
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ # end.jmx
43
+ # end.run(path: '/usr/share/jmeter/bin/')
44
+ end.grid '4dy-zJLEIgpYkKe6p6JhSQ', { endpoint: endpoint }
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'gridinit-jmeter'
3
+
4
+ test do
5
+ threads 100 do
6
+ think_time 5000,5000
7
+ transaction 'Google Search' do
8
+ visit 'Home Page', 'http://google.com/'
9
+ random_timer 3000
10
+ end
11
+ end
12
+ end.jmx
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gridinit-jmeter/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "gridinit-jmeter"
8
+ gem.version = Gridinit::Jmeter::VERSION
9
+ gem.authors = ["Tim Koopmans"]
10
+ gem.email = ["support@gridinit.com"]
11
+ gem.description = %q{This is a Ruby based DSL for writing JMeter test plans}
12
+ gem.summary = %q{This is a Ruby based DSL for writing JMeter test plans}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,28 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class AuthManager
5
+ attr_accessor :doc
6
+ def initialize(params={})
7
+ @doc = Nokogiri::XML(<<-EOF.strip_heredoc)
8
+ <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true">
9
+ <collectionProp name="AuthManager.auth_list">
10
+ <elementProp name="" elementType="Authorization">
11
+ <stringProp name="Authorization.url">/</stringProp>
12
+ <stringProp name="Authorization.username"></stringProp>
13
+ <stringProp name="Authorization.password"></stringProp>
14
+ <stringProp name="Authorization.domain"></stringProp>
15
+ <stringProp name="Authorization.realm"></stringProp>
16
+ </elementProp>
17
+ </collectionProp>
18
+ </AuthManager>
19
+ EOF
20
+ params.each do |name, value|
21
+ node = @doc.children.xpath("//*[contains(@name,\"#{name.to_s}\")]")
22
+ node.first.content = value unless node.empty?
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class CacheManager
5
+ attr_accessor :doc
6
+ def initialize(params={})
7
+ @doc = Nokogiri::XML(<<-EOF.strip_heredoc)
8
+ <CacheManager guiclass="CacheManagerGui" testclass="CacheManager" testname="HTTP Cache Manager" enabled="true">
9
+ <boolProp name="clearEachIteration">#{params[:clear_each_iteration] ? 'true' : 'false'}</boolProp>
10
+ <boolProp name="useExpires">#{params[:use_expires] ? 'true' : 'false'}</boolProp>
11
+ </CacheManager>
12
+ EOF
13
+ params.delete :clear_each_iteration
14
+ params.each do |name, value|
15
+ node = @doc.children.xpath("//*[contains(@name,\"#{name.to_s}\")]")
16
+ node.first.content = value unless node.empty?
17
+ end
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class CookieManager
5
+ attr_accessor :doc
6
+ def initialize(params={})
7
+ @doc = Nokogiri::XML(<<-EOF.strip_heredoc)
8
+ <CookieManager guiclass="CookiePanel" testclass="CookieManager" testname="HTTP Cookie Manager" enabled="true">
9
+ <collectionProp name="CookieManager.cookies"/>
10
+ <boolProp name="CookieManager.clearEachIteration">#{params[:clear_each_iteration] ? 'true' : 'false'}</boolProp>
11
+ <stringProp name="CookieManager.policy">default</stringProp>
12
+ </CookieManager>
13
+ EOF
14
+ params.delete :clear_each_iteration
15
+ params.each do |name, value|
16
+ node = @doc.children.xpath("//*[contains(@name,\"#{name.to_s}\")]")
17
+ node.first.content = value unless node.empty?
18
+ end
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,177 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class DSL
5
+ attr_accessor :root
6
+
7
+ def initialize
8
+ @root = Nokogiri::XML(<<-EOF.strip_heredoc)
9
+ <?xml version="1.0" encoding="UTF-8"?>
10
+ <jmeterTestPlan version="1.2" properties="2.1">
11
+ <hashTree>
12
+ </hashTree>
13
+ </jmeterTestPlan>
14
+ EOF
15
+ node = Gridinit::Jmeter::TestPlan.new
16
+ @root.at_xpath("//jmeterTestPlan/hashTree") << node.doc.children << hash_tree
17
+
18
+ variables(
19
+ name: 'testguid',
20
+ value: '${__P(testguid,${__time(,)})}',
21
+ comments: 'The testguid variable is mandatory when running on the Grid.') {}
22
+ end
23
+
24
+ def variables(params={}, &block)
25
+ node = Gridinit::Jmeter::UserDefinedVariable.new(params)
26
+ @root.at_xpath(xpath_from(caller)) << node.doc.children << hash_tree
27
+ self.instance_exec(&block) if block
28
+ end
29
+
30
+ def cookies(params={}, &block)
31
+ node = Gridinit::Jmeter::CookieManager.new(params)
32
+ @root.at_xpath(xpath_from(caller)) << node.doc.children << hash_tree
33
+ self.instance_exec(&block) if block
34
+ end
35
+
36
+ def cache(params={}, &block)
37
+ node = Gridinit::Jmeter::CacheManager.new(params)
38
+ @root.at_xpath(xpath_from(caller)) << node.doc.children << hash_tree
39
+ self.instance_exec(&block) if block
40
+ end
41
+
42
+ def auth(params={}, &block)
43
+ node = Gridinit::Jmeter::AuthManager.new(params)
44
+ @root.at_xpath(xpath_from(caller)) << node.doc.children << hash_tree
45
+ self.instance_exec(&block) if block
46
+ end
47
+
48
+ def threads(num_threads=1, params={}, &block)
49
+ node = Gridinit::Jmeter::ThreadGroup.new(num_threads, params)
50
+ @root.at_xpath(xpath_from(caller)) << node.doc.children << hash_tree
51
+ self.instance_exec(&block) if block
52
+ end
53
+
54
+ def transaction(name="Transaction Contoller", params={}, &block)
55
+ node = Gridinit::Jmeter::Transaction.new(name, params)
56
+ @root.at_xpath(xpath_from(caller)) << node.doc.children << hash_tree
57
+ self.instance_exec(&block) if block
58
+ end
59
+
60
+ def visit(name="HTTP Request", url="", params={}, &block)
61
+ params[:method] = 'GET'
62
+ node = Gridinit::Jmeter::HttpSampler.new(name, url, params)
63
+ @root.at_xpath(xpath_from(caller)) << node.doc.children << hash_tree
64
+ self.instance_exec(&block) if block
65
+ end
66
+
67
+ def submit(name="HTTP Request", url="", params={}, &block)
68
+ params[:method] = 'POST'
69
+ node = Gridinit::Jmeter::HttpSampler.new(name, url, params)
70
+ @root.at_xpath(xpath_from(caller)) << node.doc.children << hash_tree
71
+ self.instance_exec(&block) if block
72
+ end
73
+
74
+ alias_method :post, :submit
75
+
76
+ def extract(name="", regex="", params={}, &block)
77
+ node = Gridinit::Jmeter::RegexExtractor.new(name, regex, params)
78
+ @root.at_xpath(xpath_from(caller)) << node.doc.children << hash_tree
79
+ self.instance_exec(&block) if block
80
+ end
81
+
82
+ alias_method :web_reg_save_param, :extract
83
+
84
+ def random_timer(delay=0, range=0, &block)
85
+ node = Gridinit::Jmeter::GaussianRandomTimer.new(delay, range)
86
+ @root.at_xpath(xpath_from(caller)) << node.doc.children << hash_tree
87
+ self.instance_exec(&block) if block
88
+ end
89
+
90
+ alias_method :think_time, :random_timer
91
+
92
+ def assert(match="contains", pattern="", params={}, &block)
93
+ node = Gridinit::Jmeter::ResponseAssertion.new(match, pattern, params)
94
+ @root.at_xpath(xpath_from(caller)) << node.doc.children << hash_tree
95
+ self.instance_exec(&block) if block
96
+ end
97
+
98
+ alias_method :web_reg_find, :assert
99
+
100
+ def jmx(params={})
101
+ file(params)
102
+ puts doc.to_xml(:indent => 2)
103
+ logger.info "JMX saved to: #{params[:file]}"
104
+ end
105
+
106
+ def run(params={})
107
+ file(params)
108
+ logger.warn "Test executing locally ..."
109
+ cmd = "#{params[:path]}jmeter -n -t #{params[:file]} -j #{params[:log] ? params[:log] : 'jmeter.log' } -l #{params[:jtl] ? params[:jtl] : 'jmeter.jtl' }"
110
+ logger.info cmd
111
+ `#{cmd}`
112
+ logger.info "Results at: #{params[:jtl] ? params[:jtl] : 'jmeter.jtl'}"
113
+ end
114
+
115
+ def grid(token, params={})
116
+ file(params)
117
+ begin
118
+ response = RestClient.post "http://#{params[:endpoint] ? params[:endpoint] : 'gridinit.com'}/api?token=#{token}", {
119
+ :name => 'attachment',
120
+ :attachment => File.new("#{params[:file]}", 'rb'),
121
+ :multipart => true,
122
+ :content_type => 'application/octet-stream'
123
+ }
124
+ logger.info "Results at: #{JSON.parse(response)["results"]}" if response.code == 200
125
+ rescue => e
126
+ logger.fatal "There was an error: #{e.message}"
127
+ end
128
+ end
129
+
130
+ private
131
+
132
+ def hash_tree
133
+ Nokogiri::XML::Node.new("hashTree", @root)
134
+ end
135
+
136
+ def xpath_from(calling_method)
137
+ case calling_method.grep(/dsl/)[1][/`.*'/][1..-2]
138
+ when 'threads'
139
+ '//ThreadGroup[last()]/following-sibling::hashTree'
140
+ when 'transaction'
141
+ '//TransactionController[last()]/following-sibling::hashTree'
142
+ when 'visit'
143
+ '//HTTPSamplerProxy[last()]/following-sibling::hashTree'
144
+ when 'submit'
145
+ '//HTTPSamplerProxy[last()]/following-sibling::hashTree'
146
+ when 'extract'
147
+ '//RegexExtractor[last()]/following-sibling::hashTree'
148
+ when 'random_timer'
149
+ '//GaussianRandomTimer[last()]/following-sibling::hashTree'
150
+ else
151
+ '//TestPlan/following-sibling::hashTree'
152
+ end
153
+ end
154
+
155
+ def file(params={})
156
+ params[:file] ||= 'jmeter.jmx'
157
+ File.open(params[:file], 'w') { |file| file.write(doc.to_xml(:indent => 2)) }
158
+ end
159
+
160
+ def doc
161
+ Nokogiri::XML(@root.to_s,&:noblanks)
162
+ end
163
+
164
+ def logger
165
+ @log ||= Logger.new(STDOUT)
166
+ @log.level = Logger::DEBUG
167
+ @log
168
+ end
169
+
170
+ end
171
+
172
+ end
173
+ end
174
+
175
+ def test(&block)
176
+ Docile.dsl_eval(Gridinit::Jmeter::DSL.new, &block)
177
+ end
@@ -0,0 +1,17 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class GaussianRandomTimer
5
+ attr_accessor :doc
6
+ def initialize(delay, range)
7
+ @doc = Nokogiri::XML(<<-EOF.strip_heredoc)
8
+ <GaussianRandomTimer guiclass="GaussianRandomTimerGui" testclass="GaussianRandomTimer" testname="Think Time" enabled="true">
9
+ <stringProp name="ConstantTimer.delay">#{delay}</stringProp>
10
+ <stringProp name="RandomTimer.range">#{range}</stringProp>
11
+ </GaussianRandomTimer>
12
+ EOF
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,68 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class HttpSampler
5
+ attr_accessor :doc
6
+ def initialize(name, url, params={})
7
+ @doc = Nokogiri::XML(<<-EOF.strip_heredoc)
8
+ <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="#{name}" enabled="true">
9
+ <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
10
+ <collectionProp name="Arguments.arguments"/>
11
+ </elementProp>
12
+ <stringProp name="HTTPSampler.domain"></stringProp>
13
+ <stringProp name="HTTPSampler.port"></stringProp>
14
+ <stringProp name="HTTPSampler.connect_timeout"></stringProp>
15
+ <stringProp name="HTTPSampler.response_timeout"></stringProp>
16
+ <stringProp name="HTTPSampler.protocol"></stringProp>
17
+ <stringProp name="HTTPSampler.contentEncoding"></stringProp>
18
+ <stringProp name="HTTPSampler.path">/</stringProp>
19
+ <stringProp name="HTTPSampler.method">GET</stringProp>
20
+ <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
21
+ <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
22
+ <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
23
+ <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
24
+ <boolProp name="HTTPSampler.monitor">false</boolProp>
25
+ <boolProp name="HTTPSampler.image_parser">true</boolProp>
26
+ <boolProp name="HTTPSampler.concurrentDwn">true</boolProp>
27
+ <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
28
+ </HTTPSamplerProxy>
29
+ EOF
30
+ parse_url(url, params) unless url.empty?
31
+ fill_in(params) if params[:fill_in]
32
+ params.each do |name, value|
33
+ node = @doc.children.xpath("//*[contains(@name,\"#{name.to_s}\")]")
34
+ node.first.content = value unless node.empty?
35
+ end
36
+ end
37
+
38
+ def parse_uri(url)
39
+ URI.parse(url).scheme.nil? ? URI.parse("http://#{url}") : URI.parse(url)
40
+ end
41
+
42
+ def parse_url(url, params)
43
+ uri = parse_uri(url)
44
+ params[:domain] = uri.host
45
+ params[:port] = uri.port
46
+ params[:path] = uri.path
47
+ end
48
+
49
+ def fill_in(params)
50
+ params[:fill_in].each do |name, value|
51
+ @doc.at_xpath('//collectionProp') <<
52
+ Nokogiri::XML(<<-EOF.strip_heredoc).children
53
+ <elementProp name="username" elementType="HTTPArgument">
54
+ <boolProp name="HTTPArgument.always_encode">false</boolProp>
55
+ <stringProp name="Argument.value">#{value}</stringProp>
56
+ <stringProp name="Argument.metadata">=</stringProp>
57
+ <boolProp name="HTTPArgument.use_equals">true</boolProp>
58
+ <stringProp name="Argument.name">#{name}</stringProp>
59
+ </elementProp>
60
+ EOF
61
+ end
62
+ params.delete :fill_in
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,25 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class RegexExtractor
5
+ attr_accessor :doc
6
+ def initialize(name, regex, params={})
7
+ @doc = Nokogiri::XML(<<-EOF.strip_heredoc)
8
+ <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor" enabled="true">
9
+ <stringProp name="RegexExtractor.useHeaders">false</stringProp>
10
+ <stringProp name="RegexExtractor.refname">#{name}</stringProp>
11
+ <stringProp name="RegexExtractor.regex">#{CGI.escapeHTML regex}</stringProp>
12
+ <stringProp name="RegexExtractor.template">$1$</stringProp>
13
+ <stringProp name="RegexExtractor.default"></stringProp>
14
+ <stringProp name="RegexExtractor.match_number">0</stringProp>
15
+ </RegexExtractor>
16
+ EOF
17
+ params.each do |name, value|
18
+ node = @doc.children.xpath("//*[contains(@name,\"#{name.to_s}\")]")
19
+ node.first.content = value unless node.empty?
20
+ end
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,58 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class ResponseAssertion
5
+ attr_accessor :doc
6
+ def initialize(match, pattern, params={})
7
+ @doc = Nokogiri::XML(<<-EOF.strip_heredoc)
8
+ <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
9
+ <collectionProp name="Asserion.test_strings">
10
+ <stringProp name="#{Time.now.to_i}">#{pattern}</stringProp>
11
+ </collectionProp>
12
+ <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
13
+ <boolProp name="Assertion.assume_success">false</boolProp>
14
+ <intProp name="Assertion.test_type">#{test_type(match)}</intProp>
15
+ </ResponseAssertion>
16
+ EOF
17
+ if params[:scope]
18
+ @doc.at_xpath('//ResponseAssertion') <<
19
+ Nokogiri::XML(<<-EOF.strip_heredoc).children
20
+ <stringProp name="Assertion.scope">#{params[:scope]}</stringProp>
21
+ EOF
22
+ params.delete [:scope]
23
+ end
24
+ params.each do |name, value|
25
+ node = @doc.children.xpath("//*[contains(@name,\"#{name.to_s}\")]")
26
+ node.first.content = value unless node.empty?
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def test_type(match)
33
+ case match
34
+ when 'contains'
35
+ 2
36
+ when 'not-contains'
37
+ 6
38
+ when 'matches'
39
+ 1
40
+ when 'not-matches'
41
+ 5
42
+ when 'equals'
43
+ 8
44
+ when 'not-equals'
45
+ 12
46
+ when 'substring'
47
+ 16
48
+ when 'not-substring'
49
+ 20
50
+ else
51
+ 2
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,22 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class TestPlan
5
+ attr_accessor :doc
6
+ def initialize
7
+ @doc = Nokogiri::XML(<<-EOF.strip_heredoc)
8
+ <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
9
+ <stringProp name="TestPlan.comments"></stringProp>
10
+ <boolProp name="TestPlan.functional_mode">false</boolProp>
11
+ <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
12
+ <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
13
+ <collectionProp name="Arguments.arguments"/>
14
+ </elementProp>
15
+ <stringProp name="TestPlan.user_define_classpath"></stringProp>
16
+ </TestPlan>
17
+ EOF
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class ThreadGroup
5
+ attr_accessor :doc
6
+ def initialize(num_threads, params={})
7
+ @doc = Nokogiri::XML(<<-EOF.strip_heredoc)
8
+ <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
9
+ <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
10
+ <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
11
+ <boolProp name="LoopController.continue_forever">false</boolProp>
12
+ <stringProp name="LoopController.loops">1</stringProp>
13
+ </elementProp>
14
+ <stringProp name="ThreadGroup.num_threads">#{num_threads}</stringProp>
15
+ <stringProp name="ThreadGroup.ramp_time">1</stringProp>
16
+ <longProp name="ThreadGroup.start_time">1352677419000</longProp>
17
+ <longProp name="ThreadGroup.end_time">1352677419000</longProp>
18
+ <boolProp name="ThreadGroup.scheduler">false</boolProp>
19
+ <stringProp name="ThreadGroup.duration"></stringProp>
20
+ <stringProp name="ThreadGroup.delay"></stringProp>
21
+ </ThreadGroup>
22
+ EOF
23
+ params.each do |name, value|
24
+ node = @doc.children.xpath("//*[contains(@name,\"#{name.to_s}\")]")
25
+ node.first.content = value unless node.empty?
26
+ end
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class Transaction
5
+ attr_accessor :doc
6
+ def initialize(name, params={})
7
+ @doc = Nokogiri::XML(<<-EOF.strip_heredoc)
8
+ <TransactionController guiclass="TransactionControllerGui" testclass="TransactionController" testname="#{name}" enabled="true">
9
+ <boolProp name="TransactionController.parent">false</boolProp>
10
+ </TransactionController>
11
+ EOF
12
+ params.each do |name, value|
13
+ node = @doc.children.xpath("//*[contains(@name,\"#{name.to_s}\")]")
14
+ node.first.content = value unless node.empty?
15
+ end
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ module Gridinit
2
+ module Jmeter
3
+
4
+ class UserDefinedVariable
5
+ attr_accessor :doc
6
+ def initialize(params={})
7
+ @doc = Nokogiri::XML(<<-EOF.strip_heredoc)
8
+ <Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
9
+ <collectionProp name="Arguments.arguments">
10
+ <elementProp name="testguid" elementType="Argument">
11
+ <stringProp name="Argument.name"></stringProp>
12
+ <stringProp name="Argument.value"></stringProp>
13
+ <stringProp name="Argument.metadata">=</stringProp>
14
+ </elementProp>
15
+ </collectionProp>
16
+ <stringProp name="TestPlan.comments"></stringProp>
17
+ </Arguments>
18
+ EOF
19
+ params.each do |name, value|
20
+ node = @doc.children.xpath("//*[contains(@name,\"#{name.to_s}\")]")
21
+ node.first.content = value unless node.empty?
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ module Gridinit
2
+ module Jmeter
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ require 'nokogiri'
2
+ require 'docile'
3
+ require 'active_support/core_ext'
4
+ require 'logger/colors'
5
+ require 'rest_client'
6
+ require 'cgi'
7
+
8
+ require 'gridinit-jmeter/dsl'
9
+ require 'gridinit-jmeter/version'
10
+ require 'gridinit-jmeter/test_plan'
11
+ require 'gridinit-jmeter/auth_manager'
12
+ require 'gridinit-jmeter/cookie_manager'
13
+ require 'gridinit-jmeter/cache_manager'
14
+ require 'gridinit-jmeter/thread_group'
15
+ require 'gridinit-jmeter/transaction'
16
+ require 'gridinit-jmeter/http_sampler'
17
+ require 'gridinit-jmeter/regex_extractor'
18
+ require 'gridinit-jmeter/user_defined_variable'
19
+ require 'gridinit-jmeter/gaussian_random_timer'
20
+ require 'gridinit-jmeter/response_assertion'
data/spec/dsl_spec.rb ADDED
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+
3
+ describe "DSL" do
4
+
5
+ it "test plan should respond to thread groups" do
6
+ test {}.should respond_to :threads
7
+ end
8
+
9
+ it "test plan should respond to transactions" do
10
+ test {}.should respond_to :transaction
11
+ end
12
+
13
+ it "test plan should respond to visit" do
14
+ test {}.should respond_to :visit
15
+ end
16
+
17
+ it "test plan should respond to submit" do
18
+ test {}.should respond_to :submit
19
+ end
20
+
21
+ it "should output a test plan to stdout" do
22
+ $stdout.should_receive(:puts).with(/jmeterTestPlan/i)
23
+ test do
24
+ end.jmx
25
+ end
26
+
27
+ it "should output a test plan to jmx file" do
28
+ file = mock('file')
29
+ File.should_receive(:open).with("/tmp/jmeter.jmx", "w").and_yield(file)
30
+ file.should_receive(:write).with(/jmeterTestPlan/i)
31
+ test do
32
+ end.jmx
33
+ end
34
+
35
+ end