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 +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +122 -0
- data/Rakefile +1 -0
- data/bin/blazemeter +12 -0
- data/blazemeter.gemspec +24 -0
- data/lib/blazemeter/command/api.rb +91 -0
- data/lib/blazemeter/command/help.rb +48 -0
- data/lib/blazemeter/command/test.rb +532 -0
- data/lib/blazemeter/command.rb +8 -0
- data/lib/blazemeter/common.rb +35 -0
- data/lib/blazemeter/utils.rb +39 -0
- data/lib/blazemeter/version.rb +3 -0
- data/lib/blazemeter.rb +270 -0
- metadata +94 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
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
|
+
|
data/blazemeter.gemspec
ADDED
|
@@ -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,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
|
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: []
|