hulk_smash 1.1.0 → 1.2.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.
@@ -0,0 +1,62 @@
1
+ require_relative 'smasher'
2
+ require_relative 'url_data_converter'
3
+
4
+ module HulkSmash
5
+ class Request
6
+ attr_reader :url, :concurrent_users, :method, :url_data
7
+ attr_accessor :benchmark, :duration
8
+
9
+ def initialize(url, options={})
10
+ @url = url
11
+ @concurrent_users = options[:concurrent_users]
12
+ @duration = options[:duration]
13
+ @method = options[:method] || :get
14
+ @url_data = UrlDataConverter.from_hash(options[:data]) if options[:data]
15
+ self.benchmark = options[:benchmark]
16
+ end
17
+
18
+ def command
19
+ if post?
20
+ write_to_urls_file("#{url} POST #{url_data}")
21
+ "siege #{cmd_options} -f #{urls_file}"
22
+ elsif put?
23
+ write_to_urls_file("#{url} POST _method=put&#{url_data}")
24
+ "siege #{cmd_options} -f #{urls_file}"
25
+ else
26
+ "siege #{cmd_options} #{url}"
27
+ end
28
+ end
29
+
30
+ def cmd_options
31
+ ary = []
32
+ ary << '-b' if benchmark
33
+ ary << "-c#{concurrent_users}" if concurrent_users
34
+ ary << "-t#{duration}" if duration
35
+ ary.join(" ")
36
+ end
37
+
38
+ def post?
39
+ method == :post
40
+ end
41
+
42
+ def put?
43
+ method == :put
44
+ end
45
+
46
+ def urls_file
47
+ File.expand_path("urls_file.txt", Smasher.cache_dir)
48
+ end
49
+
50
+ private
51
+
52
+ def urls_file_base_path
53
+ File.expand_path("../../../cache", __FILE__)
54
+ end
55
+
56
+ def write_to_urls_file(content)
57
+ file = File.open(urls_file, "w+")
58
+ file.write(content)
59
+ file.close
60
+ end
61
+ end
62
+ end
@@ -2,11 +2,14 @@ require_relative 'validator'
2
2
 
3
3
  module HulkSmash
4
4
  class Result
5
- attr_reader :avg_response_time, :requests_per_second, :validator
5
+ attr_reader :avg_response_time, :requests_per_second, :validator, :availability
6
6
 
7
7
  def initialize(siege_result)
8
8
  @siege_result = siege_result
9
9
  @validator = Validator.new siege_result
10
+ @avg_response_time = 'N/A'
11
+ @requests_per_second = 'N/A'
12
+ @availability = 'N/A'
10
13
  parse_result
11
14
  end
12
15
 
@@ -28,9 +31,15 @@ module HulkSmash
28
31
  if valid?
29
32
  parse_avg_response_time
30
33
  parse_requests_per_second
34
+ parse_availability
31
35
  end
32
36
  end
33
37
 
38
+ def parse_availability
39
+ regex = /Availability:\s*([\d\.]*) %/
40
+ @availability = regex.match(siege_result)[1] + " %"
41
+ end
42
+
34
43
  def parse_avg_response_time
35
44
  regex = /Response time:\s*([\d\.]*) secs/
36
45
  @avg_response_time = regex.match(siege_result)[1].to_f*1000
@@ -1,34 +1,37 @@
1
1
  require_relative 'result'
2
- require 'stringio'
2
+ require_relative 'request'
3
3
 
4
4
  module HulkSmash
5
5
  class Smasher
6
- attr_reader :url, :duration, :concurrent_users, :result
6
+ attr_reader :request, :result
7
7
 
8
8
  def initialize(url='http://localhost', options={})
9
- @duration = options[:duration] || self.class.default_duration
10
- @concurrent_users = options[:concurrent_users] || self.class.default_concurrent_users
11
- @url = url
9
+ options = default_options.merge(options)
10
+ options[:method] = options[:method].downcase.to_sym if options[:method]
11
+ @request = Request.new url, options
12
+ setup_cache_dir
12
13
  end
13
14
 
14
- def run_load_test
15
- @result = execute_siege_command "siege -b -t#{duration} -c#{concurrent_users} #{url}"
15
+ def setup_cache_dir
16
+ Dir.mkdir self.class.cache_dir unless Dir.exists?(self.class.cache_dir)
16
17
  end
17
18
 
18
- def run_scalability_test
19
- @result = execute_siege_command "siege -t#{duration} -c#{concurrent_users} #{url}"
19
+ def load_test=(val)
20
+ request.benchmark = val
20
21
  end
21
22
 
22
- private
23
+ def run_load_test
24
+ self.load_test = true
25
+ run
26
+ end
23
27
 
24
- def execute_siege_command(command)
25
- `#{command} > #{results_file} 2>&1`
26
- results = File.read(results_file)
27
- HulkSmash::Result.new(results)
28
+ def run_scalability_test
29
+ run
28
30
  end
29
31
 
30
- def results_file
31
- @results_file ||= File.expand_path('../../../log/results.log', __FILE__)
32
+ def run
33
+ `#{request.command} > #{self.class.results_file} 2>&1`
34
+ @result = HulkSmash::Result.new(self.class.results_file_contents)
32
35
  end
33
36
 
34
37
  def self.default_duration
@@ -38,5 +41,23 @@ module HulkSmash
38
41
  def self.default_concurrent_users
39
42
  15
40
43
  end
44
+
45
+ def self.cache_dir
46
+ File.expand_path('../../../cache', __FILE__)
47
+ end
48
+
49
+ def self.results_file
50
+ File.expand_path('results.txt', cache_dir)
51
+ end
52
+
53
+ def self.results_file_contents
54
+ File.read(results_file)
55
+ end
56
+
57
+ private
58
+
59
+ def default_options
60
+ { duration: '5s', concurrent_users: 15 }
61
+ end
41
62
  end
42
63
  end
@@ -0,0 +1,28 @@
1
+ module HulkSmash
2
+ class UrlDataConverter
3
+ def self.from_hash(hash)
4
+ encode(hash)
5
+ end
6
+
7
+ def self.encode(value, key = nil, out_hash = {})
8
+ case value
9
+ when Hash then
10
+ value.each { |k,v| encode(v, append_key(key,k), out_hash) }
11
+ out_hash
12
+ when Array then
13
+ value.each { |v| encode(v, "#{key}[]", out_hash) }
14
+ out_hash
15
+ when nil then ''
16
+ else
17
+ out_hash[key] = value
18
+ end
19
+ out_hash.map{|k,v| "#{k}=#{v}" }.join("&")
20
+ end
21
+
22
+ private
23
+
24
+ def self.append_key(root_key, key)
25
+ root_key.nil? ? "#{key}" : "#{root_key}[#{key.to_s}]"
26
+ end
27
+ end
28
+ end
@@ -9,6 +9,7 @@ module HulkSmash
9
9
 
10
10
  def valid?
11
11
  validate_version_is_supported
12
+ validate_successful_siege
12
13
  reasons_for_failure.empty?
13
14
  end
14
15
 
@@ -19,6 +20,14 @@ module HulkSmash
19
20
  @version ||= regex.match(siege_result)[1].to_f
20
21
  end
21
22
 
23
+ def unsuccessful_siege?
24
+ siege_result.include?('error') && !siege_result.include?('Shortest transaction')
25
+ end
26
+
27
+ def validate_successful_siege
28
+ @reasons_for_failure << "Unable to connect" if unsuccessful_siege?
29
+ end
30
+
22
31
  def validate_version_is_supported
23
32
  @reasons_for_failure << "Siege version must be 2.x" if version < 2 || version >= 3
24
33
  end
@@ -5,7 +5,7 @@ module HulkSmash
5
5
  end
6
6
 
7
7
  def self.minor
8
- 1
8
+ 2
9
9
  end
10
10
 
11
11
  def self.patch
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hulk_smash
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-02 00:00:00.000000000 Z
12
+ date: 2012-08-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -81,12 +81,13 @@ executables: []
81
81
  extensions: []
82
82
  extra_rdoc_files: []
83
83
  files:
84
- - lib/hulk_smash/version.rb
85
84
  - lib/hulk_smash.rb
85
+ - lib/hulk_smash/version.rb
86
86
  - lib/hulk_smash/smasher.rb
87
87
  - lib/hulk_smash/result.rb
88
88
  - lib/hulk_smash/validator.rb
89
- - log/.gitkeep
89
+ - lib/hulk_smash/request.rb
90
+ - lib/hulk_smash/url_data_converter.rb
90
91
  homepage: http://asynchrony.com
91
92
  licenses: []
92
93
  post_install_message:
data/log/.gitkeep DELETED
File without changes