blazemeter 0.5.0

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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
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
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in blazemeter.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Tamer Zoubi
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,122 @@
1
+ # Blazemeter
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'blazemeter'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install blazemeter
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions
22
+
23
+ You can use BlazeMeter either from command line or from your Ruby code.
24
+
25
+ ### Command line usage
26
+
27
+ First you must initialize your Blazemeter instance:
28
+ blazemeter api:init
29
+
30
+ or
31
+
32
+ blazemeter api:init -a XXXYYY
33
+
34
+ This will prompt you to enter your user key which will be saved so you don't need to do it again.
35
+ However if you want to change your user key you can do it by removing the current key using api:reset command:
36
+
37
+ blazemeter api:reset
38
+
39
+ To create a new test:
40
+
41
+ blazemeter test:create
42
+
43
+ -this will prompt you to enter test name, max users (or max users per load engine if -en is set), location, jmeter version, ramp up, iterations, duration and number of engines for the test.
44
+ -you can also prefil those values in command line:
45
+
46
+ blazemeter test:create -u 1000 -n mytestname -l us-west-1 -j 2.9 -r 300 -i 100 -d 100 -en 2
47
+
48
+ To start a test:
49
+
50
+ blazemeter test:start
51
+
52
+ or
53
+
54
+ blazemeter test:start -id 123
55
+
56
+ To stop a test:
57
+
58
+ blazemeter test:stop
59
+
60
+ or
61
+
62
+ blazemeter test:start -id 123
63
+
64
+ To update a test:
65
+
66
+ blazemeter test:update
67
+
68
+ -this will prompt you to enter test id, max users (or max users per load engine if -en is set), location, jmeter version, ramp up, iterations, duration and number of engines for the test
69
+ -you can also prefil those values
70
+
71
+ blazemeter test:update -id 123 -u 500 -l us-east-1 -j 2.9 -r 300 -i 100 -d 100 -en 2
72
+
73
+ To get test status:
74
+
75
+ blazemeter test:status
76
+
77
+ or
78
+
79
+ blazemeter test:status -id 123
80
+
81
+ To get test options:
82
+
83
+ blazemeter test:options
84
+
85
+ or
86
+
87
+ blazemeter test:options -id 123
88
+
89
+ To get list of valid locations:
90
+
91
+ blazemeter help:locations
92
+
93
+ ### Usage from the Ruby code
94
+
95
+ To use BlazeMeter in your ruby code, first you must include it:
96
+
97
+ require "blazemeter"
98
+
99
+ Then you can instantiate BlazeMeter class with your user key:
100
+
101
+ blaze = BlazemeterApi.new('12345678')
102
+
103
+ To create a new test:
104
+
105
+ test_id = blaze.testCreate(test_name, options)
106
+
107
+ To start a test:
108
+
109
+ blaze.testStart(test_id)
110
+
111
+ To stop a test:
112
+
113
+ blaze.testStop(test_id)
114
+
115
+ To update a test:
116
+
117
+ blaze.testUpdate(test_id, options)
118
+
119
+ To get test status:
120
+
121
+ blaze.testGetStatus(test_id)
122
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/blazemeter ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require 'blazemeter'
7
+
8
+ argv = ARGV.dup
9
+ ARGV.clear
10
+ cmd = argv.shift.strip rescue 'help'
11
+ Blazemeter.run cmd, argv
12
+
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'blazemeter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "blazemeter"
8
+ spec.version = Blazemeter::VERSION
9
+ spec.authors = ["Tamer Zoubi"]
10
+ spec.email = ["tamer.zoubi@blazemeter.com"]
11
+ spec.homepage = "http://blazemeter.com/"
12
+ spec.description = %q{Provide BlazeMeter functions as CLI}
13
+ spec.summary = %q{Provide BlazeMeter integration with Ruby}
14
+ spec.homepage = ""
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ end
@@ -0,0 +1,91 @@
1
+ class Blazemeter
2
+ class Command
3
+ class API < Command # :nodoc:
4
+ attr_accessor :user_key
5
+
6
+ def cmd_init argv
7
+ @user_key = user_key
8
+ #ENV['BLAZEMETER_APIKEY'] = '123'
9
+ #get apikey stored on this computer
10
+ if !@user_key
11
+ @user_key = read_credentials[0]
12
+ end
13
+
14
+ if !@user_key
15
+ #First get apikey from cmd line
16
+ vars = Blazemeter::Command::Test.parse argv
17
+ @user_key = vars["apikey"]
18
+
19
+ #Secondly get apikey from heroku
20
+ if !@user_key && ENV['BLAZEMETER_APIKEY']
21
+ puts "Heroku BlazeMeter APIKEY found. Use it? [y/n]"
22
+ use = gets.chomp.downcase
23
+ if use[0..0] == 'y'
24
+ @user_key = ENV['BLAZEMETER_APIKEY']
25
+ end
26
+ end
27
+ #Thirdly get apikey by prompting user
28
+ if !@user_key
29
+ @user_key = ask_for_credentials
30
+ end
31
+
32
+ if @user_key
33
+ write_credentials
34
+ puts "Blazemeter API KEY stored."
35
+ end
36
+ else
37
+ puts "BlazeMeter already initialized. Use blazemeter api:reset to change API KEY"
38
+ end
39
+ end
40
+
41
+ def cmd_reset argv
42
+ @user_key = nil
43
+ write_credentials
44
+ puts "BlazeMeter is reset."
45
+ end
46
+
47
+ def cmd_validoptions argv
48
+ user_key = Blazemeter::Common.get_user_key
49
+ if !user_key
50
+ puts "You must enter API Key. Use blazemeter api:init"
51
+ return
52
+ end
53
+ blaze = BlazemeterApi.new(user_key)
54
+ puts "Valid options for your account: "
55
+ puts blaze.getOptions()
56
+ end
57
+
58
+ def credentials_file
59
+ Blazemeter::Common.credentials_file
60
+ end
61
+
62
+ def read_credentials
63
+ Blazemeter::Common.read_credentials
64
+ end
65
+
66
+ def ask_for_credentials
67
+ puts "Enter your BlazeMeter credentials. You can find this in https://a.blazemeter.com/user"
68
+ print "API-Key: "
69
+ apik = gets
70
+ return apik.chomp.strip
71
+ end
72
+
73
+
74
+
75
+ def write_credentials
76
+ FileUtils.mkdir_p(File.dirname(credentials_file))
77
+ File.open(credentials_file, 'w') do |f|
78
+ f.puts @user_key
79
+ end
80
+ set_credentials_permissions
81
+ end
82
+
83
+ def set_credentials_permissions
84
+ FileUtils.chmod 0700, File.dirname(credentials_file)
85
+ FileUtils.chmod 0600, credentials_file
86
+ end
87
+
88
+ end
89
+ Api = API
90
+ end # Command
91
+ end # Blazemeter
@@ -0,0 +1,48 @@
1
+ class Blazemeter
2
+ class Command
3
+ class Help < Command # :nodoc:
4
+ def cmd_default argv
5
+
6
+ puts "Usage: blazemeter <command> <options>"
7
+ helps = [
8
+ { :cmd => 'help', :help => 'Display this help' },
9
+ { :cmd => 'help:locations', :help => 'Display list of available test geo locations' },
10
+ { :cmd => 'api:init', :help => 'Store your API key' },
11
+ { :cmd => 'api:reset', :help => 'Remove your API key' },
12
+ { :cmd => 'api:validoptions', :help => 'Returns a list of available options that can be used for test creation or modification.' },
13
+ { :cmd => 'test:create', :help => 'generate blazemeter test' },
14
+ { :cmd => 'test:start', :help => 'starts blazemeter test' },
15
+ { :cmd => 'test:stop', :help => 'stops blazemeter test' },
16
+ { :cmd => 'test:update', :help => 'updates blazemeter test' },
17
+ { :cmd => 'test:status', :help => 'show blazemeter test status' },
18
+ { :cmd => 'test:options', :help => 'show blazemeter test options' },
19
+ { :cmd => 'test:query', :help => 'returns the report (a zip file)' }
20
+ ]
21
+
22
+ max_cmd_size = helps.inject(0) { |memo, obj| [ obj[:cmd].size, memo ].max } + 4
23
+ helps.each do |h|
24
+ puts "%*s - %s" % [max_cmd_size, h[:cmd], h[:help]]
25
+ end
26
+ puts
27
+ end
28
+ def cmd_locations argv
29
+ helps = [
30
+ { :cmd => 'eu-west-1', :help => 'EU West (Ireland)' },
31
+ { :cmd => 'us-east-1', :help => 'US East (Virginia)' },
32
+ { :cmd => 'us-west-1', :help => 'US West (N.California)' },
33
+ { :cmd => 'us-west-2', :help => 'US West (Oregon)' },
34
+ { :cmd => 'sa-east-1', :help => 'South America(Sao Paulo)' },
35
+ { :cmd => 'ap-southeast-1', :help => 'Asia Pacific (Singapore)' },
36
+ { :cmd => 'ap-southeast-2', :help => 'Australia (Sydney)' },
37
+ { :cmd => 'ap-northeast-1', :help => 'Japan (Tokyo)' }
38
+ ]
39
+
40
+ max_cmd_size = helps.inject(0) { |memo, obj| [ obj[:cmd].size, memo ].max } + 4
41
+ helps.each do |h|
42
+ puts "%*s - %s" % [max_cmd_size, h[:cmd], h[:help]]
43
+ end
44
+ puts
45
+ end
46
+ end
47
+ end # Command
48
+ end # Blitz
@@ -0,0 +1,532 @@
1
+ require 'blazemeter/utils'
2
+
3
+ class Blazemeter
4
+ class Command
5
+ class Test < Command # :nodoc:
6
+ extend Blazemeter::Utils
7
+
8
+
9
+ def cmd_create argv
10
+ options = Hash.new
11
+ options["options"] = Hash.new
12
+
13
+ begin
14
+ user_key = Blazemeter::Common.get_user_key
15
+ if !user_key
16
+ puts "You must enter API Key. Use blazemeter api:init"
17
+ return
18
+ end
19
+ vars = Blazemeter::Command::Test.parse argv
20
+
21
+ vars["options"]["TEST_TYPE"] = "jmeter" #hardcoded until next version
22
+ #todo: check if this can be on even if we don't override anything
23
+ #todo: move to blazemeter.rb
24
+ vars["options"]["OVERRIDE"] = 1 #turn on overriding
25
+
26
+ if !vars["test_name"]
27
+ puts "Enter name for the test: "
28
+ user_input = gets
29
+ if user_input.chomp != ""
30
+ vars["test_name"] = user_input.chomp
31
+ end
32
+ end
33
+
34
+ if !vars["options"]["LOCATION"]
35
+ puts "Enter location(Default - Virginia, California, Oregon, Ireland, Sydney, Tokyo, Singapore, Sao Paulo): "
36
+ user_input = gets
37
+ if user_input.chomp != ""
38
+ vars["options"]["LOCATION"] = user_input.chomp
39
+ end
40
+ end
41
+
42
+ if !vars["jmx_filepath"]
43
+ puts "Enter a path to a JMX file:* "
44
+ user_input = gets.chomp
45
+ while user_input.empty? || !File.exist?(user_input) do
46
+ if !user_input.empty? && !File.exist?(user_input)
47
+ puts "File doesn't exist. Please enter absolute path, or relative to the "+Dir.pwd
48
+ end
49
+ puts "* mandatory field."
50
+ puts "Enter a path to a JMX file:* "
51
+ user_input = gets.chomp
52
+ end
53
+ vars["jmx_filepath"] = user_input
54
+ end
55
+
56
+ if !vars["options"]["JMETER_VERSION"]
57
+ puts "Enter Jmeter version(Default - 2.9, 2.8, 2.7, 2.6, 2.5, 2.4, 2.3.2): "
58
+ user_input = gets
59
+ if user_input.chomp != ""
60
+ vars["options"]["JMETER_VERSION"] = user_input.chomp.to_f
61
+ end
62
+ end
63
+
64
+ if !vars["options"]["OVERRIDE_RAMP_UP"]
65
+ puts "Enter ramp up(300sec): "
66
+ user_input = gets
67
+ if user_input.chomp != ""
68
+ vars["options"]["OVERRIDE_RAMP_UP"] = user_input.chomp.to_i
69
+ end
70
+ end
71
+
72
+ if !vars["options"]["OVERRIDE_ITERATIONS"]
73
+ puts "Enter iterations(forever): "
74
+ user_input = gets
75
+ if user_input.chomp != ""
76
+ vars["options"]["OVERRIDE_ITERATIONS"] = user_input.chomp.to_i
77
+ end
78
+ end
79
+
80
+ if !vars["options"]["OVERRIDE_DURATION"]
81
+ puts "Enter duration(forever): "
82
+ user_input = gets
83
+ if user_input.chomp != ""
84
+ vars["options"]["OVERRIDE_DURATION"] = user_input.chomp.to_i
85
+ end
86
+ end
87
+
88
+ if vars["options"]["TEST_TYPE"] == "jmeter"
89
+ # NUMBER_OF_ENGINES only available if JMeter test was selected in TEST_TYPE
90
+ if !vars["options"]["NUMBER_OF_ENGINES"]
91
+ #todo: get the limits
92
+ puts "Enter number of engines(Default- auto, [1-60]): "
93
+ user_input = gets.chomp
94
+ while user_input != "" && (user_input.to_i < 1 || user_input.to_i > 60)
95
+ if(user_input.to_i < 1 || user_input.to_i > 60)
96
+ puts "Value must be between 1-60"
97
+ end
98
+ puts "Enter number of engines(Default- auto, [1-60]): "
99
+ user_input = gets.chomp
100
+ end
101
+
102
+ if user_input != ""
103
+ vars["options"]["NUMBER_OF_ENGINES"] = user_input.to_i
104
+ end
105
+ end
106
+ else
107
+ #make sure this option isn't passed in case of other test_types
108
+ vars["options"].delete("NUMBER_OF_ENGINES")
109
+ end
110
+
111
+ if vars["options"]["NUMBER_OF_ENGINES"]
112
+ #[Auto] wasn't selected in NUMBER_OF_ENGINES
113
+ user_text = "Maximum number of concurrent users per load engine[20-36000]"
114
+ else
115
+ #[Auto] Was selected in NUMBER_OF_ENGINES
116
+ user_text = "Maximum number of concurrent users[20-36000]"
117
+ end
118
+
119
+ if !vars["options"]["USERS"]
120
+ #mandatory field
121
+ puts "Enter "+user_text+":"
122
+ user_input = gets.chomp
123
+ while user_input.empty? || (user_input.to_i < 20 || user_input.to_i > 36000) do
124
+ if !user_input.empty? && (user_input.to_i < 20 || user_input.to_i > 36000)
125
+ puts "Incorrect value. "
126
+ end
127
+ puts "* mandatory field."
128
+ puts "Enter "+user_text+":*"
129
+ user_input = gets.chomp
130
+ end
131
+ vars["options"]["USERS"] = user_input
132
+ end
133
+
134
+ if vars["options"]["NUMBER_OF_ENGINES"] && vars["options"]["USERS"]
135
+ #[Auto] wasn't selected in NUMBER_OF_ENGINES
136
+ vars["options"]["OVERRIDE_THREADS"] = vars["options"]["USERS"]
137
+ vars["options"].delete("USERS")
138
+ end
139
+
140
+ if vars["test_name"]
141
+ test_name = vars["test_name"]
142
+ end
143
+
144
+ options["options"] = vars["options"]
145
+
146
+ blaze = BlazemeterApi.new(user_key)
147
+ test_id = blaze.testCreate(test_name, options)
148
+ if test_id
149
+ #Upload JMX script
150
+ filename = File.basename(vars["jmx_filepath"])
151
+ blaze.testScriptUpload(test_id, vars["jmx_filepath"], filename)
152
+ end
153
+ rescue "help"
154
+ return help
155
+ end
156
+ end
157
+
158
+ def cmd_start argv
159
+ begin
160
+ user_key = Blazemeter::Common.get_user_key
161
+ if !user_key
162
+ puts "You must enter API Key. Use blazemeter api:init"
163
+ return
164
+ end
165
+ vars = Blazemeter::Command::Test.parse argv
166
+ if !vars["test_id"]
167
+ puts "Enter test id: "
168
+ user_input = gets
169
+ vars["test_id"] = user_input.chomp
170
+ end
171
+
172
+ if vars["test_id"] == ''
173
+ puts "Test id is required"
174
+ exit
175
+ end
176
+ blaze = BlazemeterApi.new(user_key)
177
+ blaze.testStart(vars["test_id"])
178
+ rescue "help"
179
+ return help
180
+ end
181
+ end
182
+
183
+ def cmd_stop argv
184
+ begin
185
+ user_key = Blazemeter::Common.get_user_key
186
+ if !user_key
187
+ puts "You must enter API Key. Use blazemeter api:init"
188
+ return
189
+ end
190
+ vars = Blazemeter::Command::Test.parse argv
191
+ if !vars["test_id"]
192
+ puts "Enter test id: "
193
+ user_input = gets
194
+ vars["test_id"] = user_input.chomp
195
+ end
196
+
197
+ if vars["test_id"] == ''
198
+ puts "Test id is required"
199
+ exit
200
+ end
201
+ blaze = BlazemeterApi.new(user_key)
202
+ blaze.testStop(vars["test_id"])
203
+ rescue "help"
204
+ return help
205
+ end
206
+ end
207
+
208
+ def cmd_update argv
209
+ options = Hash.new
210
+ options["options"] = Hash.new
211
+ begin
212
+ user_key = Blazemeter::Common.get_user_key
213
+ if !user_key
214
+ puts "You must enter API Key. Use blazemeter api:init"
215
+ return
216
+ end
217
+ blaze = BlazemeterApi.new(user_key)
218
+ vars = Blazemeter::Command::Test.parse argv
219
+
220
+ #todo: we need to check test type from existing test
221
+ test_type = "jmeter" #hardcoded until next version
222
+
223
+ #todo: check if this can be on even if we don't override anything
224
+ vars["options"]["OVERRIDE"] = 1 #turn on overriding
225
+
226
+ if !vars["test_id"]
227
+ puts "Enter test id: "
228
+ user_input = gets
229
+ if user_input.chomp != ""
230
+ test_id = user_input.chomp
231
+ else
232
+ puts "Test id is required"
233
+ exit
234
+ end
235
+ else
236
+ test_id = vars["test_id"]
237
+ end
238
+
239
+ old_vars = blaze.testGetStatus(test_id, true)
240
+
241
+ if !vars["options"]["LOCATION"]
242
+ puts "Enter location(Default - don't change, California, Oregon, Ireland, Sydney, Tokyo, Singapore, Sao Paulo): "
243
+ user_input = gets
244
+ if user_input.chomp != ""
245
+ vars["options"]["LOCATION"] = user_input.chomp
246
+ end
247
+ end
248
+
249
+ if !vars["jmx_filepath"]
250
+ puts "Enter a path to a JMX file(don't change): "
251
+ user_input = gets.chomp
252
+ while !user_input.empty? && !File.exist?(user_input) do
253
+ puts "File doesn't exist. Please enter absolute path, or relative to the "+Dir.pwd
254
+ puts "Enter a path to a JMX file(don't change): "
255
+ user_input = gets.chomp
256
+ end
257
+ if !user_input.empty?
258
+ vars["jmx_filepath"] = user_input
259
+ end
260
+ end
261
+
262
+ if !vars["options"]["JMETER_VERSION"]
263
+ puts "Enter Jmeter version(Default - don't change, 2.9, 2.8, 2.7, 2.6, 2.5, 2.4, 2.3.2): "
264
+ user_input = gets
265
+ if user_input.chomp != ""
266
+ vars["options"]["JMETER_VERSION"] = user_input.chomp.to_f
267
+ end
268
+ end
269
+
270
+ if !vars["options"]["OVERRIDE_RAMP_UP"]
271
+ puts "Enter ramp up(don't change): "
272
+ user_input = gets
273
+ if user_input.chomp != ""
274
+ vars["options"]["OVERRIDE_RAMP_UP"] = user_input.chomp.to_i
275
+ end
276
+ end
277
+
278
+ if !vars["options"]["OVERRIDE_ITERATIONS"]
279
+ puts "Enter iterations(don't change): "
280
+ user_input = gets
281
+ if user_input.chomp != ""
282
+ vars["options"]["OVERRIDE_ITERATIONS"] = user_input.chomp.to_i
283
+ end
284
+ end
285
+
286
+ if !vars["options"]["OVERRIDE_DURATION"]
287
+ puts "Enter duration(don't change): "
288
+ user_input = gets
289
+ if user_input.chomp != ""
290
+ vars["options"]["OVERRIDE_DURATION"] = user_input.chomp.to_i
291
+ end
292
+ end
293
+
294
+ if test_type == "jmeter"
295
+ # NUMBER_OF_ENGINES only available if JMeter test was selected in TEST_TYPE
296
+ if !vars["options"]["NUMBER_OF_ENGINES"]
297
+ puts "Enter number of engines(Default- don't change, [1-60]): "
298
+ user_input = gets.chomp
299
+ while user_input != "" && (user_input.to_i < 1 || user_input.to_i > 60)
300
+ if(user_input.to_i < 1 || user_input.to_i > 60)
301
+ puts "Value must be between 1-60"
302
+ end
303
+ puts "Enter number of engines(Default- auto, [1-60]): "
304
+ user_input = gets.chomp
305
+ end
306
+ if user_input != ""
307
+ vars["options"]["NUMBER_OF_ENGINES"] = user_input.to_i
308
+ end
309
+ end
310
+ else
311
+ #make sure this option isn't passed in case of other test_types
312
+ vars["options"].delete("NUMBER_OF_ENGINES")
313
+ end
314
+
315
+ #todo: check number_of_engines value from original test
316
+
317
+ if vars["options"]["NUMBER_OF_ENGINES"] || old_vars["options"]["NUMBER_OF_ENGINES"] != "0"
318
+ #[Auto] wasn't selected in NUMBER_OF_ENGINES
319
+ user_text = "Maximum number of concurrent users per load engine(Default- don't change, [20-36000])"
320
+ else
321
+ #[Auto] Was selected in NUMBER_OF_ENGINES
322
+ user_text = "Maximum number of concurrent users(Default- don't change, [20-36000])"
323
+ end
324
+
325
+ if !vars["options"]["USERS"]
326
+ puts "Enter "+user_text+":"
327
+ user_input = gets.chomp
328
+
329
+ while !user_input.empty? && (user_input.to_i < 20 || user_input.to_i > 36000) do
330
+ puts "Incorrect value. "
331
+ puts "Enter "+user_text+":"
332
+ user_input = gets.chomp
333
+ end
334
+
335
+ if user_input != ""
336
+ vars["options"]["USERS"] = user_input
337
+ end
338
+ end
339
+
340
+ if (vars["options"]["NUMBER_OF_ENGINES"] || old_vars["options"]["NUMBER_OF_ENGINES"] != "0")&& vars["options"]["USERS"]
341
+ #[Auto] wasn't selected in NUMBER_OF_ENGINES
342
+ vars["options"]["OVERRIDE_THREADS"] = vars["options"]["USERS"]
343
+ vars["options"].delete("USERS")
344
+ end
345
+
346
+ options["options"] = vars["options"]
347
+
348
+ blaze.testUpdate(test_id, options)
349
+ if vars["jmx_filepath"]
350
+ filename = File.basename(vars["jmx_filepath"])
351
+ blaze.testScriptUpload(test_id, vars["jmx_filepath"], filename)
352
+ end
353
+
354
+ rescue "help"
355
+ return help
356
+ end
357
+ end
358
+
359
+ def cmd_status argv
360
+ begin
361
+ user_key = Blazemeter::Common.get_user_key
362
+ if !user_key
363
+ puts "You must enter API Key. Use blazemeter api:init"
364
+ return
365
+ end
366
+ vars = Blazemeter::Command::Test.parse argv
367
+
368
+ if !vars["test_id"]
369
+ puts "Enter test id: "
370
+ user_input = gets
371
+ vars["test_id"] = user_input.chomp
372
+ end
373
+
374
+ if vars["test_id"] == ''
375
+ puts "Test id is required"
376
+ exit
377
+ end
378
+
379
+ blaze = BlazemeterApi.new(user_key)
380
+ status = blaze.testGetStatus(vars["test_id"])
381
+ if !status["error"] and status["response_code"] == 200
382
+ puts "BlazeMeter status: " + status["status"]
383
+ else
384
+ puts "Error retrieving status: " + status["error"]
385
+ end
386
+
387
+ rescue "help"
388
+ return help
389
+ end
390
+ end
391
+
392
+ def cmd_options argv
393
+ begin
394
+ user_key = Blazemeter::Common.get_user_key
395
+ if !user_key
396
+ puts "You must enter API Key. Use blazemeter api:init"
397
+ return
398
+ end
399
+ vars = Blazemeter::Command::Test.parse argv
400
+
401
+ if !vars["test_id"]
402
+ puts "Enter test id: "
403
+ user_input = gets
404
+ vars["test_id"] = user_input.chomp
405
+ end
406
+
407
+ if vars["test_id"] == ''
408
+ puts "Test id is required"
409
+ exit
410
+ end
411
+
412
+ blaze = BlazemeterApi.new(user_key)
413
+ status = blaze.testGetStatus(vars["test_id"], true)
414
+ if !status["error"] and status["response_code"] == 200
415
+ puts "BlazeMeter options: "
416
+ puts status
417
+ else
418
+ puts "Error retrieving status: " + status["error"]
419
+ end
420
+
421
+ rescue "help"
422
+ return help
423
+ end
424
+ end
425
+
426
+ def cmd_query argv
427
+ begin
428
+ user_key = Blazemeter::Common.get_user_key
429
+ vars = Blazemeter::Command::Test.parse argv
430
+
431
+ if !vars["test_id"]
432
+ puts "Enter test id: "
433
+ user_input = gets
434
+ if user_input.chomp != ""
435
+ test_id = user_input.chomp
436
+ else
437
+ puts "Test id is required"
438
+ exit
439
+ end
440
+ else
441
+ test_id = vars["test_id"]
442
+ end
443
+
444
+ blaze = BlazemeterApi.new(user_key)
445
+ blaze.testGetArchive(test_id)
446
+ rescue "help"
447
+ return help
448
+ end
449
+ end
450
+
451
+ def self.parse arguments
452
+ argv = arguments.is_a?(Array) ? arguments : ''
453
+ args = parse_cli argv
454
+ raise "help" if args['help']
455
+
456
+ args
457
+ end
458
+
459
+ def self.parse_cli argv
460
+ hash = { 'steps' => [] }
461
+ hash["options"] = Hash.new
462
+
463
+ while not argv.empty?
464
+ hash['steps'] << Hash.new
465
+ step = hash['steps'].last
466
+
467
+ while not argv.empty?
468
+ break if argv.first[0,1] != '-'
469
+
470
+ k = argv.shift
471
+ if ['-u'].member? k
472
+ hash['options']['USERS'] = shift(k, argv)
473
+ next
474
+ end
475
+ if ['-n'].member? k
476
+ hash['test_name'] = shift(k, argv)
477
+ next
478
+ end
479
+ if ['-l'].member? k
480
+ hash['options']['LOCATION'] = shift(k, argv)
481
+ next
482
+ end
483
+ if ['-id'].member? k
484
+ hash['test_id'] = shift(k, argv)
485
+ next
486
+ end
487
+ if ['-j'].member? k
488
+ hash['options']['JMETER_VERSION'] = shift(k, argv).to_f
489
+ next
490
+ end
491
+ if ['-r'].member? k
492
+ hash['options']['OVERRIDE_RAMP_UP'] = shift(k, argv).to_i
493
+ next
494
+ end
495
+ if ['-i'].member? k
496
+ hash['options']['OVERRIDE_ITERATIONS'] = shift(k, argv).to_i
497
+ next
498
+ end
499
+ if ['-d'].member? k
500
+ hash['options']['OVERRIDE_DURATION'] = shift(k, argv).to_i
501
+ next
502
+ end
503
+ if ['-en'].member? k
504
+ hash['options']['NUMBER_OF_ENGINES'] = shift(k, argv).to_i
505
+ next
506
+ end
507
+ if ['-jmx'].member? k
508
+ hash['jmx_filepath'] = shift(k, argv).to_i
509
+ next
510
+ end
511
+ if ['-a'].member? k
512
+ hash['apikey'] = shift(k, argv).to_i
513
+ next
514
+ end
515
+
516
+
517
+ raise ArgumentError, "Unknown option #{k}"
518
+ end
519
+ break if hash['help']
520
+ end
521
+ if not hash['help']
522
+ #if hash['steps'].empty?
523
+ # raise ArgumentError, "no options specified!"
524
+ #end
525
+ end
526
+
527
+ hash
528
+ end
529
+
530
+ end
531
+ end # Command
532
+ end # Blazemeter
@@ -0,0 +1,8 @@
1
+ require 'blazemeter/utils'
2
+ class Blazemeter
3
+ class Command # :nodoc:
4
+ include Blazemeter::Utils
5
+ end
6
+ end # Blazemeter
7
+
8
+ Dir["#{File.dirname(__FILE__)}/command/*.rb"].each { |c| require c }
@@ -0,0 +1,35 @@
1
+ class Blazemeter
2
+ class Common # :nodoc:
3
+ def self.read_credentials
4
+ File.exists?(credentials_file) and File.read(credentials_file).split("\n")
5
+ end
6
+ def self.credentials_file
7
+ ENV['HOME'] + '/.blazemeter/credentials'
8
+ end
9
+ def self.get_user_key
10
+ read_credentials[0]
11
+ end
12
+
13
+ def self.locations_hash
14
+ locations = Hash.new
15
+ locations['ireland'] = 'eu-west-1'
16
+ locations['virginia'] = 'us-east-1'
17
+ locations['california'] = 'us-west-1'
18
+ locations['oregon'] = 'us-west-2'
19
+ locations['sao paulo'] = 'sa-east-1'
20
+ locations['singapore'] = 'ap-southeast-1'
21
+ locations['sydney'] = 'ap-southeast-2'
22
+ locations['tokyo'] = 'ap-northeast-1'
23
+ return locations
24
+ end
25
+ def self.get_location(location)
26
+ locations = locations_hash
27
+ if locations[location]
28
+ return locations[location]
29
+ else
30
+ return location
31
+ end
32
+
33
+ end
34
+ end
35
+ end # Blazemeter
@@ -0,0 +1,39 @@
1
+ require 'test/unit/assertions'
2
+
3
+ # The default template string contains what was sent and received. Strip
4
+ # these out since we don't need them
5
+ unless RUBY_VERSION =~ /^1.9/
6
+ module Test # :nodoc:
7
+ module Unit # :nodoc:
8
+ module Assertions # :nodoc:
9
+ class AssertionMessage # :nodoc:
10
+ alias :old_template :template
11
+
12
+ def template
13
+ @template_string = ''
14
+ @parameters = []
15
+ old_template
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ else
22
+ module ::Test::Unit # :nodoc:
23
+ AssertionFailedError = MiniTest::Assertion
24
+ end
25
+ end
26
+
27
+ class Blazemeter
28
+ module Utils
29
+ include Test::Unit::Assertions
30
+ def shift key, argv
31
+ val = argv.shift
32
+ assert_not_nil(val, "missing value for #{key}")
33
+ assert_no_match(/^-.*$/, val, "missing value for #{key}")
34
+ val
35
+ end
36
+
37
+
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module Blazemeter
2
+ VERSION = "0.5.0"
3
+ end
data/lib/blazemeter.rb ADDED
@@ -0,0 +1,270 @@
1
+ require "rubygems"
2
+ require "json"
3
+ require "net/https"
4
+ require "uri"
5
+ require "fileutils"
6
+ require "base64"
7
+ require 'blazemeter/command'
8
+ require 'blazemeter/utils'
9
+ require 'blazemeter/common'
10
+
11
+ class Blazemeter # :nodoc:
12
+ def self.run cmd, argv
13
+
14
+ kname, mname = cmd.split(':', 2)
15
+ klass = Blazemeter::Command.const_get kname.capitalize rescue nil
16
+ mname ||= 'default'
17
+ mname = "cmd_#{mname}".to_sym
18
+ if klass and klass < Blazemeter::Command and klass.method_defined? mname
19
+ command = klass.new
20
+ begin
21
+ command.send mname, argv
22
+ rescue Test::Unit::AssertionFailedError, ArgumentError => e
23
+ $stderr.puts "!! #{e.message.chomp('.')}"
24
+ end
25
+ else
26
+ puts "Unknown command #{cmd}"
27
+ end
28
+ end
29
+ end
30
+
31
+ class BlazemeterApi
32
+ @@url = 'https://a.blazemeter.com'
33
+ #@@url = 'http://vitali.a.blazemeter.com'
34
+ #@@url = 'http://localhost/ablazemetercom'
35
+
36
+ def initialize(user_key)
37
+ @user_key = user_key
38
+ end
39
+
40
+ def get_https(uri)
41
+ https = Net::HTTP.new(uri.host,uri.port)
42
+ https.use_ssl = true
43
+ https.verify_mode = OpenSSL::SSL::VERIFY_NONE
44
+ return https
45
+ end
46
+
47
+ def post(path, options=nil)
48
+ uri = URI.parse(@@url+path)
49
+ options = options.to_json
50
+ https = get_https(uri)
51
+ req = Net::HTTP::Post.new(uri.request_uri, initheader = {'Content-Type' =>'application/json'})
52
+ req.body = options
53
+ response = https.request(req)
54
+ return response
55
+ end
56
+
57
+ def postData(path, filepath)
58
+ uri = URI.parse(@@url+path)
59
+ postdata = Hash.new
60
+ file = File.open(filepath, "rb")
61
+ f = file.read
62
+ postdata['data'] = f.to_s
63
+ https = get_https(uri)
64
+ req = Net::HTTP::Post.new(uri.request_uri, initheader = {'Content-Type' =>'application/json'})
65
+ req.body = postdata.to_json
66
+ response = https.request(req)
67
+ return response
68
+ end
69
+
70
+ def get(path)
71
+ uri = URI.parse(@@url+path)
72
+ https = get_https(uri)
73
+ req = Net::HTTP::Get.new(uri.request_uri)
74
+ response = https.request(req)
75
+ return response
76
+ end
77
+
78
+ def getFile(url, filepath)
79
+ uri = URI.parse(url)
80
+ https = get_https(uri)
81
+ resp = https.get(uri.request_uri)
82
+ File.open(filepath, "w") do |file|
83
+ file.binmode #windows
84
+ file.write resp.body
85
+ file.close
86
+ end
87
+ end
88
+
89
+ def normalizeOptions(options)
90
+ options['options'].each do |index, item|
91
+ case index
92
+ when "LOCATION"
93
+ options["options"]["LOCATION"] = Blazemeter::Common.get_location(item.downcase)
94
+ end
95
+ end
96
+ return options
97
+ end
98
+
99
+ def testCreate(test_name=nil, options=nil)
100
+ if !test_name
101
+ test_name = "Automatic Ruby Test "+Time.new.inspect
102
+ end
103
+
104
+ path = '/api/rest/blazemeter/testCreate.json?user_key=' + @user_key + '&test_name=' + URI.escape(test_name)
105
+ options = normalizeOptions(options)
106
+ response = post(path, options)
107
+
108
+ if response.body == ''
109
+ puts "BlazeMeter server not responding"
110
+ return nil
111
+ end
112
+
113
+ ret = JSON.parse(response.body)
114
+
115
+ if ret["error"]
116
+ puts "BlazeMeter returned error: "+ret["error"]
117
+ else
118
+ if ret["response_code"] == 200
119
+ puts "BlazeMeter test created with id "+ret["test_id"].to_s
120
+ puts "Access test online at "+@@url+"/node/"+ret["test_id"].to_s
121
+ return ret["test_id"]
122
+ else
123
+ puts "BlazeMeter server response error:"+ret["response_code"].to_s
124
+ end
125
+ end
126
+
127
+ end
128
+
129
+ def testStart(test_id)
130
+ path = '/api/rest/blazemeter/testStart.json?user_key=' + @user_key + '&test_id=' + test_id.to_s
131
+ response = get(path)
132
+ ret = JSON.parse(response.body)
133
+ if !ret["error"] and ret["response_code"] == 200
134
+ puts "BlazeMeter test started"
135
+ return true
136
+ else
137
+ #todo: what to do with error? log? throw exception?
138
+ puts "Test not started. Error: "+ret["error"]
139
+ return false
140
+ end
141
+ end
142
+
143
+ def testStop(test_id)
144
+ path = '/api/rest/blazemeter/testStop.json?user_key=' + @user_key + '&test_id=' + test_id.to_s
145
+ response = get(path)
146
+
147
+ ret = JSON.parse(response.body)
148
+ if !ret["error"] and ret["response_code"] == 200
149
+ puts "BlazeMeter test stopped"
150
+ return true
151
+ else
152
+ #todo: what to do with error? log? throw exception?
153
+ puts "Test not stopped. Error: "+ret["error"]
154
+ return false
155
+ end
156
+ end
157
+
158
+ def testUpdate(test_id, options=nil)
159
+ path = '/api/rest/blazemeter/testUpdate.json?user_key=' + @user_key + '&test_id=' + test_id.to_s
160
+ options = normalizeOptions(options)
161
+ response = post(path, options)
162
+
163
+ if response.body == ''
164
+ puts "BlazeMeter server not responding"
165
+ return nil
166
+ end
167
+
168
+ ret = JSON.parse(response.body)
169
+
170
+ if ret["error"]
171
+ puts "BlazeMeter returned error: "+ret["error"]
172
+ else
173
+ if ret["response_code"] == 200
174
+ puts "BlazeMeter test updated sucessfully"
175
+ return true
176
+ else
177
+ puts "BlazeMeter test not updated. Error:"+ret["error"].to_s
178
+ end
179
+ end
180
+ return false
181
+
182
+ end
183
+
184
+ def testGetStatus(test_id, detailed = false)
185
+ path = '/api/rest/blazemeter/testGetStatus.json?user_key=' + @user_key + '&test_id=' + test_id.to_s
186
+ if detailed
187
+ path = path + '&detailed=true'
188
+ end
189
+
190
+ response = get(path)
191
+ ret = JSON.parse(response.body)
192
+ return ret
193
+ end
194
+
195
+ def getOptions()
196
+ path = '/api/rest/blazemeter/getAvailableOptions.json?user_key=' + @user_key
197
+ response = get(path)
198
+ ret = JSON.parse(response.body)
199
+ return ret["options"]
200
+ end
201
+
202
+ def testLoad(test_id)
203
+ path = '/api/rest/blazemeter/testUpdate.json?user_key=' + @user_key + '&test_id=' + test_id.to_s
204
+ response = post(path)
205
+ ret = JSON.parse(response.body)
206
+ if !ret["error"] and ret["response_code"] == 200
207
+ return ret["options"]
208
+ else
209
+ puts "Error loading test: " + ret["error"]
210
+ return nil
211
+ end
212
+ end
213
+
214
+ def testGetArchive(test_id)
215
+ path = '/api/rest/blazemeter/testGetArchive.json?user_key=' + @user_key + '&test_id=' + test_id.to_s
216
+ has_report = false
217
+ response = get(path)
218
+ ret = JSON.parse(response.body)
219
+ if !ret["error"] and ret["response_code"] == 200
220
+ ret["reports"].each_with_index {|val, index|
221
+ if ret["reports"][index]["zip_url"]
222
+ zip_url = ret["reports"][index]["zip_url"]
223
+ filename = File.basename zip_url
224
+ filepath = Dir.home+"/"+ filename
225
+ zip_url = zip_url + '?api_key=' + @user_key #we need api_key to access report
226
+ getFile(zip_url,filepath)
227
+ #todo: check that its downloaded
228
+ puts "Zip report downloaded to "+filepath
229
+ has_report = true
230
+ end
231
+ }
232
+ if !has_report
233
+ puts "No reports found for test "+test_id
234
+ end
235
+ else
236
+ puts "Error retrieving archive: " + ret["error"]
237
+ end
238
+ end
239
+
240
+ def testScriptUpload(test_id, filepath, filename = nil)
241
+ path = '/api/rest/blazemeter/testScriptUpload.json?user_key=' + @user_key + '&test_id=' + test_id.to_s
242
+ if (filename)
243
+ path = path + "&file_name=" + URI.escape(filename)
244
+ end
245
+
246
+ response = postData(path, filepath)
247
+
248
+ if response.body == ''
249
+ puts "BlazeMeter server not responding"
250
+ return nil
251
+ end
252
+
253
+ ret = JSON.parse(response.body)
254
+
255
+ if ret["error"]
256
+ puts "BlazeMeter returned error: "+ret["error"]
257
+ else
258
+ if ret["response_code"] == 200
259
+ puts "JMX script uploaded sucessfully to BlazeMeter"
260
+ return true
261
+ else
262
+ puts "JMX script couldn't be uploaded. Error:"+ret["error"].to_s
263
+ end
264
+ end
265
+ return false
266
+
267
+ end
268
+
269
+ end
270
+
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: blazemeter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tamer Zoubi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Provide BlazeMeter functions as CLI
47
+ email:
48
+ - tamer.zoubi@blazemeter.com
49
+ executables:
50
+ - blazemeter
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - bin/blazemeter
60
+ - blazemeter.gemspec
61
+ - lib/blazemeter.rb
62
+ - lib/blazemeter/command.rb
63
+ - lib/blazemeter/command/api.rb
64
+ - lib/blazemeter/command/help.rb
65
+ - lib/blazemeter/command/test.rb
66
+ - lib/blazemeter/common.rb
67
+ - lib/blazemeter/utils.rb
68
+ - lib/blazemeter/version.rb
69
+ homepage: ''
70
+ licenses:
71
+ - MIT
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 1.8.24
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Provide BlazeMeter integration with Ruby
94
+ test_files: []