hippoload 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,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 hippoload.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Santosh Wadghule
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.
@@ -0,0 +1,57 @@
1
+ # Hippoload
2
+
3
+ Basic Ruby wrapper/parser for Httperf
4
+
5
+ Currently it supports 'get' method of httperf.
6
+
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'hippoload'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install hippoload
21
+
22
+ ## Usage
23
+ ``` Ruby
24
+
25
+ require "hippoload"
26
+
27
+ # for single connections and rate
28
+
29
+ conf = {:connections => 100, :rate => 10, :uri => "/api/v1/entities?app_token=ef6baaed0d294f8f54eef80aeb8a4ee1" }
30
+
31
+ hippo = Hippoload::Hippo.new(conf)
32
+
33
+ hippo_parser = Hippoload::HippoParser.new
34
+
35
+ raw_output = hippo.attack # for single connections and rate
36
+
37
+ hippo_parser.parse(raw_output)
38
+
39
+ # Parsed data => {:total_conenctions=>"100", :duration=>"9.948", :connections_per_second=>"10.1", :min_ms_per_connection=>"33.8", :avg_ms_per_connection=>"61.5", :max_ms_per_connection=>"164.2", :median_ms_per_connection=>"49.5", :stddev_ms_per_connection=>"22.0", :request_rate_per_second=>"10.1", :min_replies_per_second=>"10.0", :avg_replies_per_second=>"10.0", :max_replies_per_second=>"10.0", :stddev_replies_per_second=>"0.0", :samples=>"1", :client_timeout_errors=>"0", :connections_reset_errors=>"0"}
40
+
41
+ # for connections and rates list
42
+
43
+ conf = {:connections_and_rates => [{:connections => 100, :rate => 10}, {:connections => 200, :rate => 20}], :uri => "/api/v1/entities?app_token=ef6baaed0d294f8f54eef
44
+
45
+ hippo = Hippoload::Hippo.new(conf)
46
+
47
+ hippo.becomes_crazy
48
+
49
+ # connections list wise => {"100-10-/api/v1/entities?app_token=ef6baaed0d294f8f54eef80aeb8a4ee1"=>"httperf --client=0/1 --server=localhost --port=3000 --uri=/api/v1/entities?app_token=ef6baaed0d294f8f54eef80aeb8a4ee1 --rate=10 --send-buffer=4096 --recv-buffer=16384 --num-conns=100 --num-calls=1\nMaximum connect burst length: 1\n\nTotal: connections 100 requests 100 replies 100 test-duration 9.951 s\n\nConnection rate: 10.0 conn/s (99.5 ms/conn, <=5 concurrent connections)\nConnection time [ms]: min 34.3 avg 69.5 max 400.1 median 50.5 stddev 57.6\nConnection time [ms]: connect 0.1\nConnection length [replies/conn]: 1.000\n\nRequest rate: 10.0 req/s (99.5 ms/req)\nRequest size [B]: 120.0\n\nReply rate [replies/s]: min 10.0 avg 10.0 max 10.0 stddev 0.0 (1 samples)\nReply time [ms]: response 68.9 transfer 0.5\nReply size [B]: header 642.0 content 4901.0 footer 0.0 (total 5543.0)\nReply status: 1xx=0 2xx=100 3xx=0 4xx=0 5xx=0\n\nCPU time [s]: user 2.14 system 7.81 (user 21.5% system 78.5% total 99.9%)\nNet I/O: 55.6 KB/s (0.5*10^6 bps)\n\nErrors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0\nErrors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0\n", "150-15-/api/v1/entities?app_token=ef6baaed0d294f8f54eef80aeb8a4ee1"=>"httperf --client=0/1 --server=localhost --port=3000 --uri=/api/v1/entities?app_token=ef6baaed0d294f8f54eef80aeb8a4ee1 --rate=15 --send-buffer=4096 --recv-buffer=16384 --num-conns=150 --num-calls=1\nMaximum connect burst length: 1\n\nTotal: connections 150 requests 150 replies 150 test-duration 9.988 s\n\nConnection rate: 15.0 conn/s (66.6 ms/conn, <=7 concurrent connections)\nConnection time [ms]: min 34.3 avg 92.1 max 415.4 median 71.5 stddev 68.8\nConnection time [ms]: connect 0.1\nConnection length [replies/conn]: 1.000\n\nRequest rate: 15.0 req/s (66.6 ms/req)\nRequest size [B]: 120.0\n\nReply rate [replies/s]: min 15.0 avg 15.0 max 15.0 stddev 0.0 (1 samples)\nReply time [ms]: response 91.9 transfer 0.0\nReply size [B]: header 642.0 content 4901.0 footer 0.0 (total 5543.0)\nReply status: 1xx=0 2xx=150 3xx=0 4xx=0 5xx=0\n\nCPU time [s]: user 1.76 system 8.21 (user 17.6% system 82.2% total 99.9%)\nNet I/O: 83.1 KB/s (0.7*10^6 bps)\n\nErrors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0\nErrors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0\n"}
50
+ ```
51
+ ## Contributing
52
+
53
+ 1. Fork it
54
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
55
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
56
+ 4. Push to the branch (`git push origin my-new-feature`)
57
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hippoload/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "hippoload"
8
+ gem.version = Hippoload::VERSION
9
+ gem.authors = ["Santosh Wadghule"]
10
+ gem.email = ["santosh.wadghule@gmail.com"]
11
+ gem.description = %q{Basic Ruby wrapper for httperf}
12
+ gem.summary = %q{Ruby wrapper/parser for httperf}
13
+ gem.homepage = "https://github.com/mechanicles/hippoload"
14
+
15
+ gem.add_development_dependency "rspec"
16
+ gem.add_dependency "activesupport"
17
+
18
+ gem.files = `git ls-files`.split($/)
19
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
20
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
21
+ gem.require_paths = ["lib"]
22
+ end
@@ -0,0 +1,7 @@
1
+ require "hippoload/version"
2
+ require "hippoload/hippo"
3
+ require "hippoload/hippo_parser"
4
+
5
+ module Hippoload
6
+ # Your code goes here...
7
+ end
@@ -0,0 +1,71 @@
1
+ module Hippoload
2
+ class Hippo # Hippo acts as httperf but with hippo style :)
3
+
4
+ # Currently Hippoload supports only -----------------------------
5
+ # 'get' method of Httperf
6
+ # --num-conns
7
+ # --rate
8
+ # --server
9
+ # --port
10
+ # --uri
11
+
12
+ attr_reader :connections, :rate, :server, :port, :uri, :connections_and_rates
13
+
14
+ def initialize(conf)
15
+ @connections = conf[:connections]
16
+ @rate = conf[:rate]
17
+ @server = conf[:server] || 'localhost'
18
+ @port = conf[:port] || '3000'
19
+ @uri = conf[:uri]
20
+ @connections_and_rates = conf[:connections_and_rates] || default_connections_and_rates
21
+
22
+ raise_error_if_wrong_conf
23
+ end
24
+
25
+ def attack
26
+ set_connections if !@connections.nil?
27
+ set_rate if !@rate.nil?
28
+ %x(httperf --num-conns=#{@connections} --rate=#{@rate} --server=#{@server} --port=#{@port} --uri="#{@uri}")
29
+ end
30
+
31
+ def becomes_crazy
32
+ return nil if @connections_and_rates.nil?
33
+ raw_outputs = {}
34
+ @connections_and_rates.each do |cr|
35
+ @connections = cr[:connections]
36
+ @rate = cr[:rate]
37
+ raw_outputs["#{@connections}-#{@rate}-#{uri}"] = attack
38
+ end
39
+
40
+ raw_outputs
41
+ end
42
+
43
+ private
44
+
45
+ def default_connections_and_rates
46
+ [
47
+ { :connections => 100, :rate => 10 },
48
+ { :connections => 200, :rate => 20 },
49
+ { :connections => 300, :rate => 30 },
50
+ { :connections => 500, :rate => 50 },
51
+ { :connections => 700, :rate => 70 },
52
+ { :connections => 1000, :rate => 100 }
53
+ ] if (!@connections.nil? or !@rate.nil?) && !@connections_and_rates.nil?
54
+ end
55
+
56
+ def set_connections
57
+ @connections = @connections || default_connections_and_rates.first[:connections]
58
+ end
59
+
60
+ def set_rate
61
+ @rate = @rate || default_connections_and_rates.first[:rate]
62
+ end
63
+
64
+ def raise_error_if_wrong_conf
65
+ if (!@connections.nil? || !@rate.nil?) && !@connections_and_rates.nil?
66
+ raise "You can not assign (:connections, :rate) at same with :connections_and_rates attributes. Either assign (:connections, :rate) or assign :connections_and_rates attribute"
67
+ end
68
+ end
69
+ end
70
+ end
71
+
@@ -0,0 +1,43 @@
1
+ module Hippoload
2
+ class HippoParser
3
+
4
+ DATATYPES = %w(
5
+ total_conenctions
6
+ duration
7
+ connections_per_second
8
+ min_ms_per_connection
9
+ avg_ms_per_connection
10
+ max_ms_per_connection
11
+ median_ms_per_connection
12
+ stddev_ms_per_connection
13
+ request_rate_per_second
14
+ min_replies_per_second
15
+ avg_replies_per_second
16
+ max_replies_per_second
17
+ stddev_replies_per_second
18
+ samples
19
+ client_timeout_errors
20
+ connections_reset_errors
21
+ )
22
+
23
+ def parse(httperf_raw_output)
24
+ return nil if httperf_raw_output.nil?
25
+
26
+ formatted_output = formatted_output(httperf_raw_output)
27
+ matched_data = formatted_output.match(/Total: connections (\d+).+test-duration ([\d.]+).+Connection rate: ([\d.]+).+Connection time \[ms\]: min ([\d.]+).+avg ([\d.]+).+max ([\d.]+).+median ([\d.]+).+stddev ([\d.]+).+Request rate: ([\d.]+).+min ([\d.]+).+avg ([\d.]+).+max ([\d.]+).+stddev ([\d.]+).+(\d+) samples.+client-timo (\d+).+connreset (\d+)/)
28
+
29
+ parsed_data = {}
30
+ DATATYPES.size.times do |i|
31
+ parsed_data[DATATYPES[i].to_sym] = matched_data[i+1]
32
+ end
33
+
34
+ parsed_data
35
+ end
36
+
37
+ private
38
+
39
+ def formatted_output(httperf_raw_output)
40
+ httperf_raw_output.inspect.split('\n').join(' ')
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ module Hippoload
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,16 @@
1
+ require 'hippoload'
2
+
3
+ describe Hippoload::Hippo do
4
+ let(:httperf_raw_output) { "httperf --client=0/1 --server=localhost --port=3000 --uri=/api/v1/entities?app_token=ef6baaed0d294f8f54eef80aeb8a4ee1 --rate=10 --send-buffer=4096 --recv-buffer=16384 --num-conns=100 --num-calls=1\nMaximum connect burst length: 1\n\nTotal: connections 100 requests 100 replies 100 test-duration 9.966 s\n\nConnection rate: 10.0 conn/s (99.7 ms/conn, <=1 concurrent connections)\nConnection time [ms]: min 32.1 avg 55.7 max 94.4 median 46.5 stddev 17.6\nConnection time [ms]: connect 0.1\nConnection length [replies/conn]: 1.000\n\nRequest rate: 10.0 req/s (99.7 ms/req)\nRequest size [B]: 120.0\n\nReply rate [replies/s]: min 10.0 avg 10.0 max 10.0 stddev 0.0 (1 samples)\nReply time [ms]: response 55.5 transfer 0.0\nReply size [B]: header 642.0 content 4901.0 footer 0.0 (total 5543.0)\nReply status: 1xx=0 2xx=100 3xx=0 4xx=0 5xx=0\n\nCPU time [s]: user 2.18 system 7.78 (user 21.9% system 78.0% total 99.9%)\nNet I/O: 55.5 KB/s (0.5*10^6 bps)\n\nErrors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0\nErrors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0\n" }
5
+
6
+ it "should have DATATYPES constant" do
7
+ Hippoload::HippoParser::DATATYPES.should_not be_nil
8
+ end
9
+
10
+ describe "HippoParser#parse" do
11
+ it "should parse for raw input" do
12
+ parser = Hippoload::HippoParser.new
13
+ parser.parse(httperf_raw_output).size.should > 0
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,62 @@
1
+ require 'hippoload'
2
+
3
+ describe Hippoload::Hippo do
4
+
5
+ let(:basic_conf) { { :connections => 100, :rate => 10, :uri => "/posts" } }
6
+ let(:advanced_conf) { { :uri => "/posts", :connections_and_rates => [{ :connections => 100, :rate => 10 }] } }
7
+ let(:wrong_conf) do
8
+ {
9
+ :connections => 100,
10
+ :rate => 10,
11
+ :uri => "/posts",
12
+ :connections_and_rates => [{ :connections => 100, :rate => 10 }]
13
+ }
14
+ end
15
+
16
+ describe "Hippo#attributes_methods" do
17
+
18
+ it "should have attributes reader" do
19
+ hippo = Hippoload::Hippo.new(basic_conf)
20
+ hippo.connections.should eql(100)
21
+ hippo.rate.should eql(10)
22
+ hippo.server.should eql('localhost')
23
+ hippo.port.should eql('3000')
24
+ hippo.uri.should eql('/posts')
25
+ hippo.connections_and_rates.should nil
26
+ end
27
+
28
+ it "should raise error if wrong conf passed" do
29
+ expect { Hippoload::Hippo.new(wrong_conf) }.to raise_error
30
+ end
31
+
32
+ it "should not raise error if correct conf passed" do
33
+ expect { Hippoload::Hippo.new(basic_conf) }.to_not raise_error
34
+ end
35
+
36
+ it "should have connections_and_rates attribute if we passed advanced_conf" do
37
+ hippo = Hippoload::Hippo.new(advanced_conf)
38
+ hippo.connections_and_rates.should eql(advanced_conf[:connections_and_rates])
39
+ end
40
+
41
+ it "should have default connections and rates if passed advanced_conf without connections_and_rates attribute" do
42
+ advanced_conf.delete(:connections_and_rates)
43
+ hippo = Hippoload::Hippo.new(advanced_conf)
44
+ hippo.connections_and_rates.should eql(hippo.send(:default_connections_and_rates))
45
+ end
46
+ end
47
+
48
+ describe "Hippo#attack" do
49
+ it "should return httperf raw output" do
50
+ hippo = Hippoload::Hippo.new(basic_conf)
51
+ hippo.attack.inspect.should include('httperf')
52
+ end
53
+ end
54
+
55
+ describe "Hippo#becomes_crazy" do
56
+ it "should return httperf raw output" do
57
+ hippo = Hippoload::Hippo.new(advanced_conf)
58
+ hippo.becomes_crazy
59
+ hippo.becomes_crazy.inspect.should include('httperf')
60
+ end
61
+ end
62
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hippoload
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Santosh Wadghule
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
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: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
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: Basic Ruby wrapper for httperf
47
+ email:
48
+ - santosh.wadghule@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE.txt
56
+ - README.md
57
+ - Rakefile
58
+ - hippoload.gemspec
59
+ - lib/hippoload.rb
60
+ - lib/hippoload/hippo.rb
61
+ - lib/hippoload/hippo_parser.rb
62
+ - lib/hippoload/version.rb
63
+ - spec/hippo_parser_spec.rb
64
+ - spec/hippo_spec.rb
65
+ homepage: https://github.com/mechanicles/hippoload
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.24
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Ruby wrapper/parser for httperf
89
+ test_files:
90
+ - spec/hippo_parser_spec.rb
91
+ - spec/hippo_spec.rb