hippoload 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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