httperfrb 0.3.8 → 0.3.10

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.
Files changed (5) hide show
  1. data/Gemfile +2 -1
  2. data/README.md +1 -137
  3. data/lib/httperf.rb +75 -48
  4. data/lib/httperf/version.rb +1 -1
  5. metadata +3 -3
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
+ gemspec
2
3
  gem 'open4'
3
4
  group :development do
4
5
  gem 'rspec'
data/README.md CHANGED
@@ -1,137 +1 @@
1
- HTTPerf.rb
2
- ==========
3
-
4
- ### [Documentation](http://rubyops.github.com/httperfrb/doc/) | [Coverage](http://rubyops.github.com/httperfrb/coverage/) | [RSpec Out](https://github.com/rubyops/httperfrb/blob/master/RSPECOUT.md)
5
-
6
- Simple Ruby interface for httperf.
7
-
8
- ## Installing 'httperf'
9
-
10
- Requires httperf, of course...
11
-
12
- #### Mac
13
-
14
- sudo port install httperf
15
-
16
- #### Debian / Ubuntu
17
-
18
- sudo apt-get install httperf
19
-
20
- #### Redhat / CentOS
21
-
22
- sudo yum install httperf
23
-
24
- #### My 'httperf'
25
-
26
- See: [httperf-0.9.1 with individual connection times](http://www.rubyops.net/2012/08/13/httperf-0_9_1_with_individual_connection_times).
27
-
28
- ## Install
29
-
30
- gem install httperfrb
31
-
32
- ## Usage - HTTPerf
33
-
34
- Some basic usage examples.
35
-
36
- require 'httperf'
37
- perf = HTTPerf.new( "server" => "host", "port" => 8080, "uri" => "/foo" )
38
- puts perf.run
39
-
40
- perf.update_option("uri", "/foo/bar")
41
- thread = perf.fork
42
- while((thread.alive?))
43
- sleep 0.01
44
- print "#"
45
- end
46
- unless perf.fork_err.nil?
47
- puts perf.fork_out
48
- end
49
-
50
- ### With HTTPerf::Parser
51
-
52
- require 'httperf'
53
- perf = HTTPerf.new( "server" => "host", "port" => 8080, "uri" => "/foo" )
54
- puts perf.parse = true
55
- puts perf.run
56
-
57
- # or directly
58
-
59
- puts HTTPerf::Parser.parse( HTTPerf.new( "server" => "host", "port" => 8080, "uri" => "/foo" ).run )
60
-
61
- ## Useage - HTTPerf::Parser
62
-
63
- require 'httperf/parser'
64
-
65
- # read result from a file, for example
66
- puts HTTPerf::Parser.parse( File.open("httperf.out", "r").read )
67
-
68
- # or verbose output
69
- puts HTTPerf::Parser.parse( File.open("httperf_verbose.out", "r").read, true )
70
-
71
- #### From the command line:
72
-
73
- Something I've been playing around with, it's more of hack really. But it works well for seralizing output to YAML or JSON:
74
-
75
- ##### To JSON file:
76
-
77
- httperf --num-conns=10 --verbose | ruby -e 'require "httperf/parser"; require "json"; puts HTTPerf::Parser.parse(ARGF.read).to_json' > httperf.json
78
-
79
- ##### To YAML file:
80
-
81
- httperf --num-conns=10 --verbose | ruby -e 'require "httperf/parser"; require "yaml"; puts HTTPerf::Parser.parse(ARGF.read).to_yaml' > httperf.yml
82
-
83
-
84
-
85
- ##### Parser Keys:
86
-
87
- :command
88
- :max_connect_burst_length
89
- :total_connections
90
- :total_requests
91
- :total_replies
92
- :total_test_duration
93
- :connection_rate_per_sec
94
- :connection_rate_ms_conn
95
- :connection_time_min
96
- :connection_time_avg
97
- :connection_time_max
98
- :connection_time_median
99
- :connection_time_stddev
100
- :connection_time_connect
101
- :connection_length
102
- :request_rate_per_sec
103
- :request_rate_ms_request
104
- :request_size
105
- :reply_rate_min
106
- :reply_rate_avg
107
- :reply_rate_max
108
- :reply_rate_stddev
109
- :reply_rate_samples
110
- :reply_time_response
111
- :reply_time_transfer
112
- :reply_size_header
113
- :reply_size_content
114
- :reply_size_footer
115
- :reply_size_total
116
- :reply_status_1xx
117
- :reply_status_2xx
118
- :reply_status_3xx
119
- :reply_status_4xx
120
- :reply_status_5xx
121
- :cpu_time_user_sec
122
- :cpu_time_system_sec
123
- :cpu_time_user_pct
124
- :cpu_time_system_pct
125
- :cpu_time_total_pct
126
- :net_io_kb_sec
127
- :net_io_bps
128
- :errors_total
129
- :errors_client_timeout
130
- :errors_socket_timeout
131
- :errors_conn_refused
132
- :errors_conn_reset
133
- :errors_fd_unavail
134
- :errors_addr_unavail
135
- :errors_ftab_full
136
- :errors_other
137
-
1
+ ## See: [www.rubyops.net/gems/httperfrb](http://www.rubyops.net/gems/httperfrb)
data/lib/httperf.rb CHANGED
@@ -3,7 +3,7 @@ $:.unshift File.dirname(__FILE__)
3
3
  require 'httperf/parser'
4
4
  require 'httperf/version'
5
5
 
6
- autoload :Open3, 'open3'
6
+ autoload :PTY, 'pty'
7
7
  autoload :Open4, 'open4'
8
8
 
9
9
  begin
@@ -14,11 +14,12 @@ end
14
14
  class HTTPerf
15
15
 
16
16
  # @return [Boolean] parse flag
17
- attr_accessor :parse
17
+ attr_accessor :parse, :tee
18
18
 
19
19
  # availbe instance methods
20
20
  @fork_out, @fork_err = ''
21
21
  @fork_thr, @options, @command = nil
22
+ @tee = false
22
23
 
23
24
  # initialize with (optional):
24
25
  # - options: see below for options
@@ -66,40 +67,13 @@ class HTTPerf
66
67
  # - wset
67
68
  def initialize options={}, path=nil
68
69
  self.parse = options.delete("parse")
69
- if options.has_key?("command")
70
- command = options.delete("command")
71
- raise "Option command must not be passed with other options" unless options.empty?
70
+ self.tee = options.delete("tee")
71
+ options = parse_command_option(options) if options.has_key?("command")
72
72
 
73
- valid_command = !!(command.match(/([a-z\/]*)httperf /))
74
- raise "Invalid httperf command" unless valid_command
73
+ validate_options(options)
74
+ set_command_from_path(path) unless @command
75
75
 
76
- command.gsub!("--hog", "--hog=true")
77
- command.gsub!("--verbose", "--verbose=true")
78
-
79
- cli_options = command.split(" --")
80
- path = cli_options.delete_at(0)
81
- path = nil unless path.start_with?("/")
82
-
83
- cli_options.each do |clio|
84
- kvp = clio.split("=")
85
- kvp = clio.split(" ") unless kvp.size == 2
86
- raise "Error parsing command params" unless kvp.size == 2
87
- options[kvp.first] = kvp.last
88
- end
89
- end
90
-
91
- options.each_key do |k|
92
- raise "'#{k}' is an invalid httperf param" unless params.keys.include?(k)
93
- end
94
- @options = params.merge(options)
95
- if path.nil?
96
- @command = %x{ which httperf }.chomp
97
- raise "httperf not found" unless @command =~ /httperf/
98
- else
99
- path = path.chomp
100
- @command = (path =~ /httperf$/ ? path : File.join(path, "httperf"))
101
- raise "#{@command} not found" unless %x{ test -x "#{@command}" && echo "true" }.chomp == "true"
102
- end
76
+ @options = params.merge(options)
103
77
  end
104
78
 
105
79
  # update a given option
@@ -111,21 +85,26 @@ class HTTPerf
111
85
  # return errors if any, otherwise return
112
86
  # results
113
87
  def run
114
- status, out, err = nil
115
- Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
116
- pid = wait_thr.pid
117
- out = stdout.readlines
118
- err = stderr.readlines
119
- status = wait_thr.value
120
- end
121
- if status == 0
122
- if @parse
123
- return Parser.parse(out.join)
124
- else
125
- return out.join
88
+ out = ""
89
+
90
+ begin
91
+ PTY.spawn(command) do |stdout, stdin, pid|
92
+ begin
93
+ stdout.each do |line|
94
+ out << line.strip+"\n"
95
+ print line if @tee
96
+ end
97
+ rescue Errno::EIO
98
+ #Errno:EIO error probably just means that the process has finished giving output
99
+ end
126
100
  end
127
- else
128
- return err.join
101
+ rescue PTY::ChildExited
102
+ # The child process has exited.
103
+ end
104
+
105
+ if $?.exitstatus == 0
106
+ return Parser.parse(out) if @parse
107
+ return out
129
108
  end
130
109
  end
131
110
 
@@ -214,5 +193,53 @@ class HTTPerf
214
193
  }
215
194
  end
216
195
 
196
+ def parse_command_option options
197
+ command = options.delete("command")
198
+ raise "Option command must not be passed with other options" unless options.empty?
199
+
200
+ raise "Invalid httperf command" unless !!(command.match(/([a-z\/]*)httperf /))
201
+
202
+ command.gsub!("--hog", "--hog=true")
203
+ command.gsub!("--verbose", "--verbose=true")
204
+
205
+ cli_options(command).each { |clio| options.merge!(split_cli_option(clio)) }
206
+
207
+ options
208
+ end
209
+
210
+ def cli_options command
211
+ opts = command.split(" --")
212
+ set_command_from_path(opts.delete_at(0))
213
+ opts
214
+ end
215
+
216
+ def set_command_from_path(path)
217
+ if path && path.start_with?("/")
218
+ path = path.chomp
219
+ @command = (path =~ /httperf$/ ? path : File.join(path, "httperf"))
220
+ raise "#{@command} not found" unless %x{ test -x "#{@command}" && echo "true" }.chomp == "true"
221
+ else
222
+ set_command_without_path
223
+ end
224
+ end
225
+
226
+ def set_command_without_path
227
+ @command = %x{ which httperf }.chomp
228
+ raise "httperf not found" unless @command =~ /httperf/
229
+ end
230
+
231
+ def split_cli_option(clio)
232
+ kvp = clio.split("=")
233
+ kvp = clio.split(" ") unless kvp.size == 2
234
+ raise "Error parsing command params" unless kvp.size == 2
235
+ return { kvp.first => kvp.last }
236
+ end
237
+
238
+ def validate_options options
239
+ options.each_key do |k|
240
+ raise "'#{k}' is an invalid httperf param" unless params.keys.include?(k)
241
+ end
242
+ end
243
+
217
244
  end
218
245
 
@@ -1,4 +1,4 @@
1
1
  class HTTPerf
2
- VERSION = "0.3.8"
2
+ VERSION = "0.3.10"
3
3
  end
4
4
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httperfrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.8
4
+ version: 0.3.10
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: 2013-03-01 00:00:00.000000000 Z
12
+ date: 2013-04-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -88,7 +88,7 @@ files:
88
88
  - README.md
89
89
  - HISTORY.md
90
90
  - Gemfile
91
- homepage: http://github.com/rubyops/httperfrb
91
+ homepage: http://www.rubyops.net/gems/httperfrb
92
92
  licenses: []
93
93
  post_install_message:
94
94
  rdoc_options: []