gridinit-jmeter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitattributes ADDED
@@ -0,0 +1,22 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+
4
+ # Custom for Visual Studio
5
+ *.cs diff=csharp
6
+ *.sln merge=union
7
+ *.csproj merge=union
8
+ *.vbproj merge=union
9
+ *.fsproj merge=union
10
+ *.dbproj merge=union
11
+
12
+ # Standard to msysgit
13
+ *.doc diff=astextplain
14
+ *.DOC diff=astextplain
15
+ *.docx diff=astextplain
16
+ *.DOCX diff=astextplain
17
+ *.dot diff=astextplain
18
+ *.DOT diff=astextplain
19
+ *.pdf diff=astextplain
20
+ *.PDF diff=astextplain
21
+ *.rtf diff=astextplain
22
+ *.RTF diff=astextplain
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.log
19
+ *.jmx
20
+ *.jtl
data/.rbenv-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p194
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format nested
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - jruby-19mode # JRuby in 1.9 mode
5
+ # uncomment this line if your project needs to run something other than `rake`:
6
+ # script: bundle exec rspec spec
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gridinit-jmeter.gemspec
4
+ gemspec
5
+
6
+ gem 'docile'
7
+ gem 'nokogiri'
8
+ gem 'active_attr'
9
+ gem 'activesupport'
10
+ gem 'logger-colors'
11
+ gem 'rest-client'
12
+
13
+ group :test do
14
+ gem 'rake'
15
+ gem 'rspec'
16
+ gem 'sinatra'
17
+ gem 'haml'
18
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,335 @@
1
+ # Gridinit::Jmeter
2
+
3
+ Tired of using the JMeter GUI or looking at hairy XML files?
4
+
5
+ This gem lets you write test plans for JMeter in your favourite text editor, and optionally run them on [Gridinit.com](http://gridinit.com). Here's some background on [why we think](http://www.slideshare.net/90kts/gridinit-jmeter) a DSL is necessary.
6
+
7
+ ## Installation
8
+
9
+ Install it yourself as:
10
+
11
+ $ gem install gridinit-jmeter
12
+
13
+ ## Basic Usage
14
+
15
+ *Gridinit::Jmeter* exposes easy-to-use domain specific language for fluent communication with [JMeter](http://jmeter.apache.org/). As the name of the gem suggests, it also includes API integration with [Gridinit](http://gridinit.com), a cloud based load testing service.
16
+
17
+ To use the DSL, first let's require the gem:
18
+
19
+ ```ruby
20
+ require 'rubygems'
21
+ require 'gridinit-jmeter'
22
+ ```
23
+
24
+ ### Basic Example
25
+ Let's create a `test` and save the related `jmx` testplan to file, so we can edit/view it in JMeter.
26
+
27
+ ```ruby
28
+ test do
29
+ threads 10 do
30
+ visit 'Google Search', 'http://google.com'
31
+ end
32
+ end.jmx
33
+ ```
34
+
35
+ So in this example, we just created a test plan, with 10 threads, each of which visited the search page at Google.
36
+
37
+ ### Generating a JMeter Test Plan (JMX)
38
+ Note also how we called the `jmx` method of the test. Calling this method will write the contents of the JMeter test plan to screen (stdout) and also to a file like this.
39
+
40
+ ```xml
41
+ <?xml version="1.0" encoding="UTF-8"?>
42
+ <jmeterTestPlan version="1.2" properties="2.1">
43
+ <hashTree>
44
+ <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
45
+ ...
46
+ </TestPlan>
47
+ </hashTree>
48
+ </jmeterTestPlan>
49
+ JMX saved to: jmeter.jmx
50
+ ```
51
+
52
+ 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.
53
+
54
+ ```ruby
55
+ test do
56
+ threads 10 do
57
+ visit 'Google Search', 'http://altentee.com'
58
+ end
59
+ end.jmx(file: "/tmp/my_testplan.jmx")
60
+ ```
61
+
62
+ Windows users should specify a path like this.
63
+
64
+ ```ruby
65
+ .jmx(file: "C:\\TEMP\\MyTestplan.jmx")
66
+ ```
67
+
68
+ ### Running a JMeter Test Plan locally
69
+ You can execute the JMeter test plan by calling the `run` method of the test like this.
70
+
71
+ ```ruby
72
+ test do
73
+ threads 10 do
74
+ visit 'Google Search', 'http://altentee.com'
75
+ end
76
+ end.run
77
+ ```
78
+
79
+ 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 and the `jtl` path/name for JMeter results like this.
80
+
81
+ ```ruby
82
+ test do
83
+ threads 10 do
84
+ visit 'Google Search', 'http://altentee.com'
85
+ end
86
+ end.run(
87
+ path: '/usr/share/jmeter/bin/',
88
+ file: 'jmeter.jmx',
89
+ log: 'jmeter.log',
90
+ jtl: 'results.jtl')
91
+ ```
92
+
93
+ ### Running a JMeter Test Plan on Gridinit.com
94
+
95
+ As the gem name implies, you can also execute JMeter test plans on Gridinit.com using our API. To do so, you require an account and API token. If you don't know your token, sign in to the Grid and [generate a new token](http://gridinit.com/api).
96
+
97
+ To execute the test on the Grid, call the `grid` method on the test and pass it the API token like this.
98
+
99
+ ```ruby
100
+ test do
101
+ threads 10 do
102
+ visit 'Google Search', 'http://altentee.com'
103
+ end
104
+ end.grid('OxtZ-4v-v0koSz5Y0enEQQ')
105
+ ```
106
+
107
+ This will then provide you with a link to the live test results on the Grid like this.
108
+
109
+ ```
110
+ Results at: http://prod.gridinit.com/shared?testguid=73608030311611e2962f123141011033&run_id=339&tags=jmeter&domain=altentee.com&cluster=54.251.48.129&status=running&view=
111
+ ```
112
+
113
+ ## Advanced Usage
114
+
115
+ ### Blocks
116
+
117
+ Each of the methods take an optional block delimited by `do` and `end` or braces `{}`
118
+
119
+ 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.
120
+
121
+ ```ruby
122
+ test do
123
+ threads 100 do
124
+ visit 'Home', 'http://altentee.com' do
125
+ extract 'csrf-token', "content='(.+?)' name='csrf-token'"
126
+ end
127
+ end
128
+ end
129
+ ```
130
+
131
+ 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.
132
+
133
+ 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.
134
+
135
+ ### Threads
136
+
137
+ You can use the `threads` method to define a group of users:
138
+
139
+ ```ruby
140
+ threads 100
141
+ ```
142
+
143
+ This methods takes 2 parameters: the number of threads and an optional parameters hash.
144
+
145
+ ```ruby
146
+ threads 100
147
+ threads 100, {continue_forever: 'true'}
148
+ threads 100, {loops: 10}
149
+ threads 100, {ramp_time: 30, duration: 60}
150
+ threads 100, {
151
+ scheduler: 'true',
152
+ start_time: Time.now.to_i * 1000,
153
+ end_time: (Time.now.to_i * 1000) + (3600 * 1000)
154
+ }
155
+ ```
156
+
157
+ ### Cookies
158
+
159
+ You can use the `cookies` method to define a Cookie Manager:
160
+
161
+ ```ruby
162
+ test do
163
+ cookies
164
+ end
165
+ ```
166
+
167
+ This methods takes an optional parameters hash. This is based on the [HTTP Cookie Manager](http://jmeter.apache.org/usermanual/component_reference.html#HTTP_Cookie_Manager).
168
+
169
+ ```ruby
170
+ test do
171
+ cookies clear_each_iteration: false
172
+ end
173
+
174
+ test do
175
+ cookies policy: 'rfc2109', clear_each_iteration: true
176
+ end
177
+ ```
178
+
179
+ ### Cache
180
+
181
+ You can use the `cache` method to define a Cache Manager:
182
+
183
+ ```ruby
184
+ test do
185
+ cache
186
+ end
187
+ ```
188
+
189
+ This methods takes an optional parameters hash. This is based on the [HTTP Cache Manager](http://jmeter.apache.org/usermanual/component_reference.html#HTTP_Cache_Manager).
190
+
191
+ ```ruby
192
+ test do
193
+ cache clear_each_iteration: false
194
+ end
195
+
196
+ test do
197
+ cache use_expires: true, clear_each_iteration: true
198
+ end
199
+ ```
200
+
201
+ ### Authorization
202
+
203
+ You can use the `auth` method to define an Authorization Manager:
204
+
205
+ ```ruby
206
+ test do
207
+ auth
208
+ end
209
+ ```
210
+
211
+ This methods takes an optional parameters hash. This is based on the [HTTP Authorization Manager](http://jmeter.apache.org/usermanual/component_reference.html#HTTP_Authorization_Manager).
212
+
213
+ ```ruby
214
+ test do
215
+ auth url: '/', username: 'tim', password: 'secret', domain: 'altentee.com'
216
+ end
217
+ ```
218
+
219
+ ### Navigating
220
+
221
+ You can use the `visit` method to navigate to pages:
222
+
223
+ ```ruby
224
+ visit 'Google Search', 'http://altentee.com'
225
+ ```
226
+
227
+ This method makes a single request and takes 3 parameters: the label, the URL and an optional parameters hash.
228
+
229
+ ```ruby
230
+ visit 'Google Search', 'http://altentee.com'
231
+ visit 'Google Search', 'http://altentee.com', {
232
+ method: 'POST',
233
+ DO_MULTIPART_POST: 'true'
234
+ }
235
+ visit 'Google Search', 'http://altentee.com', {
236
+ use_keepalive: 'false'
237
+ }
238
+ visit 'Google Search', 'http://altentee.com', {
239
+ connect_timeout: '1000',
240
+ response_timeout: '60000',
241
+ }
242
+ ```
243
+
244
+ ### Submitting a Form
245
+
246
+ You can use the `submit` method to POST a HTTP form:
247
+
248
+ ```ruby
249
+ submit 'Submit Form', 'http://altentee.com/', {
250
+ fill_in: {
251
+ username: 'tim',
252
+ password: 'password',
253
+ 'csrf-token' => '${csrf-token}'
254
+ }
255
+ ```
256
+
257
+ This method makes a single request and takes 3 parameters: the label, the URL and an optional parameters hash. 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.
258
+
259
+ ### Think Time
260
+
261
+ You can use the `think_time` method to insert pauses into the simulation. This method is aliased as `random_timer`.
262
+
263
+ ```ruby
264
+ think_time 3000
265
+ ```
266
+
267
+ 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](http://jmeter.apache.org/usermanual/component_reference.html#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.
268
+
269
+ ```ruby
270
+ # constant delay of 3 seconds
271
+ think_time 3000
272
+ # constant delay of 1 seconds with variance up to 6 seconds.
273
+ random_timer 1000,5000
274
+ ```
275
+
276
+ ### Response Extractor
277
+
278
+ 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.
279
+
280
+ ```ruby
281
+ extract 'csrf-token', "content='(.+?)' name='csrf-token'"
282
+ ```
283
+
284
+ This method takes 3 parameters: the extracted value name, the PCRE regular expression and an optional parameters hash. This is based on the [Regular Expression Extractor](http://jmeter.apache.org/usermanual/component_reference.html#Regular_Expression_Extractor).
285
+
286
+ ```ruby
287
+ visit "Altentee", "http://altentee.com" do
288
+ extract 'csrf-token', "content='(.+?)' name='csrf-token'"
289
+ extract 'JSESSIONID', 'value="(.+?)" name="JESSIONSID"'
290
+ web_reg_save_param 'VIEWSTATE', 'value="(.+?)" name="VIEWSTATE"'
291
+ extract 'username', 'value="(.+?)" name="username"', {
292
+ default: 'Tim Koopmans',
293
+ match_number: 1
294
+ }
295
+ extract 'shopping_item', 'id="(.+?)" name="book"', {
296
+ match_number: 0 # random
297
+ }
298
+ end
299
+ ```
300
+
301
+ ### Response Assertion
302
+
303
+ 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.
304
+
305
+ ```ruby
306
+ visit "Altentee", "http://altentee.com" do
307
+ assert "contains", "We test, tune and secure your site"
308
+ end
309
+ ```
310
+
311
+
312
+ This method takes 3 parameters: the matching rule, the test string, and an optional parameters hash. This is based on the [Response Assertion](http://jmeter.apache.org/usermanual/component_reference.html#Response_Assertion).
313
+
314
+ ```ruby
315
+ visit "Altentee", "http://altentee.com" do
316
+ assert "contains", "We test, tune and secure your site"
317
+ assert "not-contains", "We price gouge on cloud services"
318
+ assert "matches", "genius"
319
+ assert "not-matches", "fakers"
320
+ assert "contains", "magic"
321
+ assert "not-contains", "unicorns", {scope: 'all'}
322
+ end
323
+ ```
324
+
325
+ ## Roadmap
326
+
327
+ This is very much a work-in-progress. Future work is being sponsored by Gridinit.com. Get in touch with us if you'd like to be involved.
328
+
329
+ ## Contributing
330
+
331
+ 1. Fork it
332
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
333
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
334
+ 4. Push to the branch (`git push origin my-new-feature`)
335
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => [:spec]
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'gridinit-jmeter'
3
+
4
+ test do
5
+ threads 2 do
6
+ transaction 'Assertions' do
7
+ visit 'Altentee', 'http://altentee.com/' do
8
+ assert "contains", "We test, tune and secure your site"
9
+ assert "not-contains", "Something in frames", {scope: 'all'}
10
+ end
11
+ end
12
+ end
13
+ end.jmx
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'gridinit-jmeter'
3
+
4
+ test do
5
+ auth url: '/', username: 'tim', password: 'secret', domain: 'altentee.com'
6
+ threads 1 do
7
+ transaction 'Google Search' do
8
+ visit 'Home Page', 'http://google.com/'
9
+ end
10
+ end
11
+ end.jmx
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'gridinit-jmeter'
3
+
4
+ test do
5
+ cache clear_each_iteration: true
6
+ threads 1 do
7
+ transaction 'Google Search' do
8
+ visit 'Home Page', 'http://google.com/'
9
+ end
10
+ end
11
+ end.jmx
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'gridinit-jmeter'
3
+
4
+ test do
5
+ cookies clear_each_iteration: false
6
+ threads 1 do
7
+ transaction 'Google Search' do
8
+ visit 'Home Page', 'http://google.com/'
9
+ end
10
+ end
11
+ end.jmx
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'gridinit-jmeter'
3
+
4
+ test do
5
+ threads 10 do
6
+ visit 'Google Search', 'http://google.com'
7
+ end
8
+ end.jmx
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'gridinit-jmeter'
3
+
4
+ test do
5
+ think_time 100
6
+ threads 100, {ramp_time: 10, loops: 10} do
7
+ transaction 'Home Page' do
8
+ visit 'Altentee', 'http://127.0.0.1:9200/'
9
+ end
10
+ end
11
+ end.grid('4dy-zJLEIgpYkKe6p6JhSQ', {endpoint: '127.0.0.1:3000'})
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'gridinit-jmeter'
3
+
4
+ test do
5
+ threads 10 do
6
+ visit 'Google Search', 'http://google.com'
7
+ end
8
+ end.run(
9
+ path: '/usr/share/jmeter/bin/',
10
+ file: 'jmeter.jmx',
11
+ log: 'jmeter.log',
12
+ jtl: 'results.jtl')
@@ -0,0 +1,138 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <jmeterTestPlan version="1.2" properties="2.3" jmeter="2.8 r1393162">
3
+ <hashTree>
4
+ <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
5
+ <stringProp name="TestPlan.comments"></stringProp>
6
+ <boolProp name="TestPlan.functional_mode">false</boolProp>
7
+ <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
8
+ <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
9
+ <collectionProp name="Arguments.arguments"/>
10
+ </elementProp>
11
+ <stringProp name="TestPlan.user_define_classpath"></stringProp>
12
+ </TestPlan>
13
+ <hashTree>
14
+ <CookieManager guiclass="CookiePanel" testclass="CookieManager" testname="HTTP Cookie Manager" enabled="true">
15
+ <collectionProp name="CookieManager.cookies"/>
16
+ <boolProp name="CookieManager.clearEachIteration">true</boolProp>
17
+ <stringProp name="CookieManager.policy">rfc2109</stringProp>
18
+ </CookieManager>
19
+ <hashTree/>
20
+ <CacheManager guiclass="CacheManagerGui" testclass="CacheManager" testname="HTTP Cache Manager" enabled="true">
21
+ <boolProp name="clearEachIteration">true</boolProp>
22
+ <boolProp name="useExpires">false</boolProp>
23
+ </CacheManager>
24
+ <hashTree/>
25
+ <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true">
26
+ <collectionProp name="AuthManager.auth_list">
27
+ <elementProp name="" elementType="Authorization">
28
+ <stringProp name="Authorization.url">/</stringProp>
29
+ <stringProp name="Authorization.username">tim</stringProp>
30
+ <stringProp name="Authorization.password">password</stringProp>
31
+ <stringProp name="Authorization.domain">altentee.com</stringProp>
32
+ <stringProp name="Authorization.realm"></stringProp>
33
+ </elementProp>
34
+ </collectionProp>
35
+ </AuthManager>
36
+ <hashTree/>
37
+ <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
38
+ <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
39
+ <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
40
+ <boolProp name="LoopController.continue_forever">false</boolProp>
41
+ <stringProp name="LoopController.loops">1</stringProp>
42
+ </elementProp>
43
+ <stringProp name="ThreadGroup.num_threads">10</stringProp>
44
+ <stringProp name="ThreadGroup.ramp_time">1</stringProp>
45
+ <longProp name="ThreadGroup.start_time">1352677419000</longProp>
46
+ <longProp name="ThreadGroup.end_time">1352677419000</longProp>
47
+ <boolProp name="ThreadGroup.scheduler">false</boolProp>
48
+ <stringProp name="ThreadGroup.duration"></stringProp>
49
+ <stringProp name="ThreadGroup.delay"></stringProp>
50
+ </ThreadGroup>
51
+ <hashTree>
52
+ <TransactionController guiclass="TransactionControllerGui" testclass="TransactionController" testname="Transaction Controller" enabled="true">
53
+ <boolProp name="TransactionController.parent">false</boolProp>
54
+ </TransactionController>
55
+ <hashTree>
56
+ <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP Request" enabled="true">
57
+ <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
58
+ <collectionProp name="Arguments.arguments"/>
59
+ </elementProp>
60
+ <stringProp name="HTTPSampler.domain">127.0.0.1</stringProp>
61
+ <stringProp name="HTTPSampler.port">4567</stringProp>
62
+ <stringProp name="HTTPSampler.connect_timeout"></stringProp>
63
+ <stringProp name="HTTPSampler.response_timeout"></stringProp>
64
+ <stringProp name="HTTPSampler.protocol"></stringProp>
65
+ <stringProp name="HTTPSampler.contentEncoding"></stringProp>
66
+ <stringProp name="HTTPSampler.path">/</stringProp>
67
+ <stringProp name="HTTPSampler.method">GET</stringProp>
68
+ <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
69
+ <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
70
+ <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
71
+ <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
72
+ <boolProp name="HTTPSampler.monitor">false</boolProp>
73
+ <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
74
+ </HTTPSamplerProxy>
75
+ <hashTree>
76
+ <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor" enabled="true">
77
+ <stringProp name="RegexExtractor.useHeaders">false</stringProp>
78
+ <stringProp name="RegexExtractor.refname">csrf_token</stringProp>
79
+ <stringProp name="RegexExtractor.regex">content=&quot;(.+?)&quot; name=&quot;csrf-token&quot;</stringProp>
80
+ <stringProp name="RegexExtractor.template">$1$</stringProp>
81
+ <stringProp name="RegexExtractor.default">authenticity_token</stringProp>
82
+ <stringProp name="RegexExtractor.match_number">0</stringProp>
83
+ </RegexExtractor>
84
+ <hashTree/>
85
+ </hashTree>
86
+ <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP Request" enabled="true">
87
+ <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
88
+ <collectionProp name="Arguments.arguments">
89
+ <elementProp name="username" elementType="HTTPArgument">
90
+ <boolProp name="HTTPArgument.always_encode">false</boolProp>
91
+ <stringProp name="Argument.value">Tim</stringProp>
92
+ <stringProp name="Argument.metadata">=</stringProp>
93
+ <boolProp name="HTTPArgument.use_equals">true</boolProp>
94
+ <stringProp name="Argument.name">username</stringProp>
95
+ </elementProp>
96
+ <elementProp name="password" elementType="HTTPArgument">
97
+ <boolProp name="HTTPArgument.always_encode">false</boolProp>
98
+ <stringProp name="Argument.value">Password</stringProp>
99
+ <stringProp name="Argument.metadata">=</stringProp>
100
+ <boolProp name="HTTPArgument.use_equals">true</boolProp>
101
+ <stringProp name="Argument.name">password</stringProp>
102
+ </elementProp>
103
+ </collectionProp>
104
+ </elementProp>
105
+ <stringProp name="HTTPSampler.domain">127.0.0.1</stringProp>
106
+ <stringProp name="HTTPSampler.port">4567</stringProp>
107
+ <stringProp name="HTTPSampler.connect_timeout"></stringProp>
108
+ <stringProp name="HTTPSampler.response_timeout"></stringProp>
109
+ <stringProp name="HTTPSampler.protocol"></stringProp>
110
+ <stringProp name="HTTPSampler.contentEncoding"></stringProp>
111
+ <stringProp name="HTTPSampler.path">/</stringProp>
112
+ <stringProp name="HTTPSampler.method">POST</stringProp>
113
+ <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
114
+ <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
115
+ <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
116
+ <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
117
+ <boolProp name="HTTPSampler.image_parser">true</boolProp>
118
+ <boolProp name="HTTPSampler.concurrentDwn">true</boolProp>
119
+ <stringProp name="HTTPSampler.concurrentPool">8</stringProp>
120
+ <boolProp name="HTTPSampler.monitor">false</boolProp>
121
+ <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
122
+ </HTTPSamplerProxy>
123
+ <hashTree>
124
+ <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
125
+ <collectionProp name="Asserion.test_strings">
126
+ <stringProp name="2603186">Test</stringProp>
127
+ </collectionProp>
128
+ <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
129
+ <boolProp name="Assertion.assume_success">false</boolProp>
130
+ <intProp name="Assertion.test_type">20</intProp>
131
+ </ResponseAssertion>
132
+ <hashTree/>
133
+ </hashTree>
134
+ </hashTree>
135
+ </hashTree>
136
+ </hashTree>
137
+ </hashTree>
138
+ </jmeterTestPlan>