benchmark-http 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a7198efc6883b1ab033fabd79461782dc4a283d7a8643b962f13fc6ec9d8b630
4
- data.tar.gz: ae74b4d5cfb6d5407c600d46af92817897556fdd246b68591c23b3d40b3a8602
3
+ metadata.gz: de65883bfb494a1d1da97429666bd4a590361632cc008d1292e11003a00a8acc
4
+ data.tar.gz: 2b0a8c9f5d9d59799203e6030669a576c4802d0d95c1c1dd4dcf23bba7a875ce
5
5
  SHA512:
6
- metadata.gz: d930b61aec7683e5162fb0b6f4776b960562473506c574162861eefe91d07d898b3aa9efa755ee5e8464938d358efb34f2f0198dc8bb05907578109e6c7bae19
7
- data.tar.gz: 176349eac7a9b287dd60f85f1d2c97c78a3580cd6ec235533b4f81380e2060e82ace5c3bfa3fc9fed322d8d26e9f0f6e0876d9362a7930caeca52c1163b28171
6
+ metadata.gz: '039a873b982321ada9fcfd8cb3f848e46df8786ee2590a075a68580ad4aa5b3bcee638eb47f28a24e88faabf1349215193a02b65d25f377abe3ad091a36f594f'
7
+ data.tar.gz: 584cea3731b38082c4a1fb078d883c7eb8d61edc5b626d0ef5dc0ead41e9fe5338edbcfc6535f6b9a66e9187580fbcd25b73d68336e76502a3c5f8bb9a6b6e72
@@ -8,9 +8,9 @@ before_script:
8
8
 
9
9
  matrix:
10
10
  include:
11
- - rvm: 2.3
12
11
  - rvm: 2.4
13
12
  - rvm: 2.5
13
+ - rvm: 2.6
14
14
  - rvm: jruby-head
15
15
  env: JRUBY_OPTS="--debug -X+O"
16
16
  - rvm: ruby-head
data/Gemfile CHANGED
@@ -1,6 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
-
5
- # Specify your gem's dependencies in benchmark-http.gemspec
6
3
  gemspec
4
+
5
+ group :development do
6
+ gem 'pry'
7
+ end
data/README.md CHANGED
@@ -20,6 +20,85 @@ Install it yourself:
20
20
 
21
21
  You can run `benchmark-http` is a top level tool for invoking specific benchmarks.
22
22
 
23
+ ### Spider
24
+
25
+ This benchmark spiders a website and generates some statistics on general access time.
26
+
27
+ ```shell
28
+ $ benchmark-http spider https://www.oriontransfer.co.nz/welcome/index
29
+ HEAD https://www.oriontransfer.co.nz/welcome/index -> HTTP/2.0 404 (unspecified bytes)
30
+ GET https://www.oriontransfer.co.nz/welcome/index (depth = 10)
31
+ GET https://www.oriontransfer.co.nz/welcome/index -> HTTP/2.0 404 (2263 bytes)
32
+ HEAD https://www.oriontransfer.co.nz/products/index -> HTTP/2.0 200 (unspecified bytes)
33
+ GET https://www.oriontransfer.co.nz/products/index (depth = 9)
34
+ HEAD https://www.oriontransfer.co.nz/services/index -> HTTP/2.0 200 (unspecified bytes)
35
+ GET https://www.oriontransfer.co.nz/services/index (depth = 9)
36
+ HEAD https://www.oriontransfer.co.nz/support/index -> HTTP/2.0 200 (unspecified bytes)
37
+ GET https://www.oriontransfer.co.nz/support/index (depth = 9)
38
+ HEAD https://www.oriontransfer.co.nz/support/contact-us -> HTTP/2.0 307 (unspecified bytes)
39
+ Following redirect to https://www.oriontransfer.co.nz/support/contact-us/index...
40
+ HEAD https://www.oriontransfer.co.nz/support/terms-of-service -> HTTP/2.0 200 (unspecified bytes)
41
+ GET https://www.oriontransfer.co.nz/support/terms-of-service (depth = 9)
42
+ GET https://www.oriontransfer.co.nz/products/index -> HTTP/2.0 200 (3469 bytes)
43
+ GET https://www.oriontransfer.co.nz/services/index -> HTTP/2.0 200 (2488 bytes)
44
+ GET https://www.oriontransfer.co.nz/support/index -> HTTP/2.0 200 (2246 bytes)
45
+ HEAD https://www.oriontransfer.co.nz/support/contact-us/index -> HTTP/2.0 200 (unspecified bytes)
46
+ GET https://www.oriontransfer.co.nz/support/contact-us/index (depth = 8)
47
+ GET https://www.oriontransfer.co.nz/support/terms-of-service -> HTTP/2.0 200 (8466 bytes)
48
+ HEAD https://www.oriontransfer.co.nz/products/library-inspector/index -> HTTP/2.0 200 (unspecified bytes)
49
+ GET https://www.oriontransfer.co.nz/products/library-inspector/index (depth = 8)
50
+ HEAD https://www.oriontransfer.co.nz/products/truth-tables/index -> HTTP/2.0 200 (unspecified bytes)
51
+ GET https://www.oriontransfer.co.nz/products/truth-tables/index (depth = 8)
52
+ HEAD https://www.oriontransfer.co.nz/products/fingerprint/index -> HTTP/2.0 200 (unspecified bytes)
53
+ GET https://www.oriontransfer.co.nz/products/fingerprint/index (depth = 8)
54
+ HEAD https://www.oriontransfer.co.nz/services/internet-services -> HTTP/2.0 200 (unspecified bytes)
55
+ GET https://www.oriontransfer.co.nz/services/internet-services (depth = 8)
56
+ HEAD https://www.oriontransfer.co.nz/services/software-development -> HTTP/2.0 200 (unspecified bytes)
57
+ GET https://www.oriontransfer.co.nz/services/software-development (depth = 8)
58
+ HEAD https://www.oriontransfer.co.nz/services/systems-administration -> HTTP/2.0 200 (unspecified bytes)
59
+ GET https://www.oriontransfer.co.nz/services/systems-administration (depth = 8)
60
+ HEAD https://www.oriontransfer.co.nz/services/website-development -> HTTP/2.0 200 (unspecified bytes)
61
+ GET https://www.oriontransfer.co.nz/services/website-development (depth = 8)
62
+ HEAD https://www.oriontransfer.co.nz/support/contact-us/ -> HTTP/2.0 307 (unspecified bytes)
63
+ Following redirect to https://www.oriontransfer.co.nz/support/contact-us/index...
64
+ GET https://www.oriontransfer.co.nz/support/contact-us/index -> HTTP/2.0 200 (3094 bytes)
65
+ GET https://www.oriontransfer.co.nz/products/library-inspector/index -> HTTP/2.0 200 (5592 bytes)
66
+ GET https://www.oriontransfer.co.nz/products/truth-tables/index -> HTTP/2.0 200 (4160 bytes)
67
+ GET https://www.oriontransfer.co.nz/products/fingerprint/index -> HTTP/2.0 200 (4414 bytes)
68
+ GET https://www.oriontransfer.co.nz/services/internet-services -> HTTP/2.0 200 (3362 bytes)
69
+ GET https://www.oriontransfer.co.nz/services/software-development -> HTTP/2.0 200 (3521 bytes)
70
+ GET https://www.oriontransfer.co.nz/services/systems-administration -> HTTP/2.0 200 (2979 bytes)
71
+ GET https://www.oriontransfer.co.nz/services/website-development -> HTTP/2.0 200 (3943 bytes)
72
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/library-inspector/_screenshots/large/Library%20Inspector%20(Libraries).png -> HTTP/2.0 200 (unspecified bytes)
73
+ Unsupported content type: image/png
74
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/library-inspector/_screenshots/large/Library%20Inspector%20(Libraries%20Disassembly).png -> HTTP/2.0 200 (unspecified bytes)
75
+ Unsupported content type: image/png
76
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/library-inspector/_screenshots/large/Library%20Inspector%20(Libraries%20QuickLook).png -> HTTP/2.0 200 (unspecified bytes)
77
+ Unsupported content type: image/png
78
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/library-inspector/_screenshots/large/Library%20Inspector%20(App).png -> HTTP/2.0 200 (unspecified bytes)
79
+ Unsupported content type: image/png
80
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/library-inspector/_screenshots/large/Library%20Inspector%20(App%20Headers).png -> HTTP/2.0 200 (unspecified bytes)
81
+ Unsupported content type: image/png
82
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/truth-tables/_screenshots/large/Reformat%20Expression.png -> HTTP/2.0 200 (unspecified bytes)
83
+ Unsupported content type: image/png
84
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/truth-tables/_screenshots/large/Large%20Tables.png -> HTTP/2.0 200 (unspecified bytes)
85
+ Unsupported content type: image/png
86
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/truth-tables/_screenshots/large/Tutor.png -> HTTP/2.0 200 (unspecified bytes)
87
+ Unsupported content type: image/png
88
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/truth-tables/_screenshots/large/Informative%20Text.png -> HTTP/2.0 200 (unspecified bytes)
89
+ Unsupported content type: image/png
90
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/fingerprint/_screenshots/large/Fingerprint%20(3).png -> HTTP/2.0 200 (unspecified bytes)
91
+ Unsupported content type: image/png
92
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/fingerprint/_screenshots/large/Fingerprint%20(2).png -> HTTP/2.0 200 (unspecified bytes)
93
+ Unsupported content type: image/png
94
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/fingerprint/_screenshots/large/Fingerprint%20(1).png -> HTTP/2.0 200 (unspecified bytes)
95
+ Unsupported content type: image/png
96
+ HEAD https://www.oriontransfer.co.nz/services/training -> HTTP/2.0 200 (unspecified bytes)
97
+ GET https://www.oriontransfer.co.nz/services/training (depth = 7)
98
+ GET https://www.oriontransfer.co.nz/services/training -> HTTP/2.0 200 (2994 bytes)
99
+ 14 samples: 13x 200; 1x 404. 15.124294695167547 requests per second. S/D: 35.69ms.
100
+ ```
101
+
23
102
  ### Concurrency
24
103
 
25
104
  This benchmark determines the optimal level of concurrency (maximise throughput while keeping latency to a minimum).
@@ -16,7 +16,10 @@ Gem::Specification.new do |spec|
16
16
  spec.require_paths = ["lib"]
17
17
 
18
18
  spec.add_dependency("async-io", "~> 1.5")
19
- spec.add_dependency("async-http", "~> 0.9")
19
+ spec.add_dependency("async-http", "~> 0.27.0")
20
+ spec.add_dependency("async-await")
21
+
22
+ spec.add_dependency("trenni-sanitize")
20
23
 
21
24
  spec.add_dependency('samovar', "~> 1.3")
22
25
 
@@ -19,6 +19,8 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  require_relative 'command/concurrency'
22
+ require_relative 'command/spider'
23
+
22
24
  require_relative 'version'
23
25
  require 'samovar'
24
26
 
@@ -39,7 +41,8 @@ module Benchmark
39
41
  end
40
42
 
41
43
  nested '<command>',
42
- 'concurrency' => Concurrency
44
+ 'concurrency' => Concurrency,
45
+ 'spider' => Spider
43
46
 
44
47
  def verbose?
45
48
  @options[:logging] == :verbose
@@ -0,0 +1,150 @@
1
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative '../seconds'
22
+ require_relative '../statistics'
23
+ require_relative '../links_filter'
24
+
25
+ require 'async'
26
+ require 'async/http/client'
27
+ require 'async/http/url_endpoint'
28
+ require 'async/await'
29
+
30
+ require 'samovar'
31
+ require 'uri'
32
+
33
+ module Benchmark
34
+ module HTTP
35
+ module Command
36
+ class Spider < Samovar::Command
37
+ include Async::Await
38
+
39
+ self.description = "Spider a website and report on performance."
40
+
41
+ options do
42
+ option '-d/--depth <count>', "The number of nested URLs to traverse.", default: 10, type: Integer
43
+ option '-h/--headers', "Print out the response headers", default: false
44
+ end
45
+
46
+ many :urls, "One or more hosts to benchmark"
47
+
48
+ def log(method, url, response)
49
+ puts "#{method} #{url} -> #{response.version} #{response.status} (#{response.body&.length || 'unspecified'} bytes)"
50
+
51
+ response.headers.each do |key, value|
52
+ puts "\t#{key}: #{value}"
53
+ end if @options[:headers]
54
+ end
55
+
56
+ def extract_links(url, response)
57
+ base = url
58
+
59
+ body = response.read
60
+
61
+ begin
62
+ filter = LinksFilter.parse(body)
63
+ rescue
64
+ Async.logger.error($!)
65
+ return []
66
+ end
67
+
68
+ if filter.base
69
+ base = base + filter.base
70
+ end
71
+
72
+ filter.links.collect do |href|
73
+ begin
74
+ full_url = base + href
75
+
76
+ if full_url.host == url.host && full_url.kind_of?(URI::HTTP)
77
+ yield full_url
78
+ end
79
+ rescue ArgumentError, URI::InvalidURIError
80
+ puts "Could not fetch #{href}, relative to #{base}."
81
+ end
82
+ end.compact
83
+ end
84
+
85
+ async def fetch(statistics, client, url, depth = @options[:depth], fetched = Set.new)
86
+ return if fetched.include?(url) or depth == 0
87
+
88
+ fetched << url
89
+
90
+ request_uri = url.request_uri
91
+
92
+ response = timeout(10) do
93
+ client.head(request_uri)
94
+ end
95
+
96
+ log("HEAD", url, response)
97
+
98
+ if response.redirection?
99
+ location = url + response.headers['location']
100
+ if location.host == url.host
101
+ puts "Following redirect to #{location}..."
102
+ return fetch(statistics, client, location, depth-1, fetched).wait
103
+ else
104
+ puts "Ignoring redirect to #{location}."
105
+ return
106
+ end
107
+ end
108
+
109
+ content_type = response.headers['content-type']
110
+ unless content_type&.start_with? 'text/html'
111
+ puts "Unsupported content type: #{content_type}"
112
+ return
113
+ end
114
+
115
+ response = timeout(20) do
116
+ statistics.measure do
117
+ client.get(request_uri)
118
+ end
119
+ end
120
+
121
+ log("GET", url, response)
122
+
123
+ extract_links(url, response) do |href|
124
+ fetch(statistics, client, href, depth - 1, fetched)
125
+ end.each(&:wait)
126
+ rescue Async::TimeoutError
127
+ Async.logger.error("Timeout while fetching #{url}")
128
+ rescue StandardError
129
+ Async.logger.error($!)
130
+ end
131
+
132
+ async def invoke(parent)
133
+ statistics = Statistics.new
134
+
135
+ @urls.each do |url|
136
+ endpoint = Async::HTTP::URLEndpoint.parse(url)
137
+
138
+ Async::HTTP::Client.open(endpoint, endpoint.protocol, connection_limit: 4) do |client|
139
+ fetch(statistics, client, endpoint.url).wait
140
+ end
141
+ end
142
+
143
+ statistics.print
144
+
145
+ return statistics
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,47 @@
1
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'trenni/sanitize'
22
+
23
+ module Benchmark
24
+ module HTTP
25
+ class LinksFilter < Trenni::Sanitize::Filter
26
+ def initialize(*)
27
+ super
28
+
29
+ @base = nil
30
+ @links = []
31
+ end
32
+
33
+ attr :base
34
+ attr :links
35
+
36
+ def filter(node)
37
+ if node.name == 'base'
38
+ @base = node['href']
39
+ elsif node.name == 'a'
40
+ @links << node['href']
41
+ end
42
+
43
+ node.skip!(TAG)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -18,23 +18,38 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
+ require 'async/clock'
22
+
21
23
  module Benchmark
22
24
  module HTTP
23
- class Statistics
24
- def initialize(concurrency)
25
+ class Stopwatch
26
+ def initialize(concurrency = 0)
25
27
  @samples = []
26
- @duration = 0
28
+
29
+ @total_time = 0
30
+
31
+ # The number of currently executing measurements:
32
+ @count = 0
27
33
 
28
34
  @concurrency = concurrency
35
+ @start_time = nil
29
36
  end
30
37
 
38
+ # The individual samples' durations.
31
39
  attr :samples
32
- attr :duration
33
40
 
41
+ # The sequential time of all samples.
42
+ attr :total_time
43
+
44
+ # The maximum number of executing measurements at any one time.
34
45
  attr :concurrency
35
46
 
47
+ def duration
48
+ @samples.sum
49
+ end
50
+
36
51
  def sequential_duration
37
- @duration / @concurrency
52
+ duration / @concurrency
38
53
  end
39
54
 
40
55
  def count
@@ -42,11 +57,11 @@ module Benchmark
42
57
  end
43
58
 
44
59
  def per_second
45
- @samples.count.to_f / sequential_duration.to_f
60
+ @samples.count.to_f / total_time.to_f
46
61
  end
47
62
 
48
63
  def latency
49
- @duration.to_f / @samples.count.to_f
64
+ duration.to_f / count.to_f
50
65
  end
51
66
 
52
67
  def similar?(other, difference = 2.0)
@@ -61,13 +76,17 @@ module Benchmark
61
76
  end
62
77
  end
63
78
 
79
+ def valid?
80
+ @samples.count > 1
81
+ end
82
+
64
83
  # Computes Population Variance, σ^2.
65
84
  def variance
66
- return nil if @samples.count < 2
67
-
68
- average = self.average
69
-
70
- return @samples.map{|n| (n - average)**2}.sum / @samples.count
85
+ if valid?
86
+ average = self.average
87
+
88
+ return @samples.map{|n| (n - average)**2}.sum / @samples.count
89
+ end
71
90
  end
72
91
 
73
92
  # Population Standard Deviation, σ
@@ -83,16 +102,37 @@ module Benchmark
83
102
  end
84
103
  end
85
104
 
105
+ def add(duration, result = nil)
106
+ @samples << duration
107
+ end
108
+
86
109
  def measure
87
- start_time = Time.now
110
+ @count += 1
111
+
112
+ if @count > @concurrency
113
+ @concurrency = @count
114
+ end
115
+
116
+ start_time = Async::Clock.now
117
+
118
+ unless @start_time
119
+ @start_time = start_time
120
+ end
88
121
 
89
122
  result = yield
90
123
 
91
- duration = Time.now - start_time
92
- @samples << duration
93
- @duration += duration
124
+ end_time = Async::Clock.now
125
+
126
+ self.add(end_time - start_time, result)
94
127
 
95
128
  return result
129
+ ensure
130
+ @count -= 1
131
+
132
+ if @count == 0
133
+ @total_time += end_time - @start_time
134
+ @start_time = nil
135
+ end
96
136
  end
97
137
 
98
138
  def sample(confidence_factor, &block)
@@ -105,13 +145,46 @@ module Benchmark
105
145
  end
106
146
 
107
147
  def print(out = STDOUT)
108
- out.puts "#{@samples.count} samples. #{1.0 / self.average} per second. S/D: #{standard_deviation}."
148
+ if self.valid?
149
+ out.puts "#{@samples.count} samples. #{per_second} requests per second. S/D: #{Seconds[standard_deviation]}."
150
+ else
151
+ out.puts "Not enough samples."
152
+ end
109
153
  end
110
154
 
111
155
  private
112
156
 
113
157
  def confident?(factor)
114
- (@samples.count > @concurrency) && self.standard_error < (self.average * factor)
158
+ if @samples.count > @concurrency
159
+ return self.standard_error < (self.average * factor)
160
+ end
161
+
162
+ return false
163
+ end
164
+ end
165
+
166
+ class Statistics < Stopwatch
167
+ def initialize(*)
168
+ super
169
+
170
+ # The count of the status codes seen in the responses:
171
+ @responses = Hash.new{|h,k| 0}
172
+ end
173
+
174
+ def add(duration, result)
175
+ super
176
+
177
+ @responses[result.status] += 1
178
+ end
179
+
180
+ def print(out = STDOUT)
181
+ if valid?
182
+ counts = @responses.sort.collect{|status, count| "#{count}x #{status}"}.join("; ")
183
+
184
+ out.puts "#{@samples.count} samples: #{counts}. #{per_second.round(2)} requests per second. S/D: #{Seconds[standard_deviation]}."
185
+ else
186
+ out.puts "Not enough samples."
187
+ end
115
188
  end
116
189
  end
117
190
  end
@@ -20,6 +20,6 @@
20
20
 
21
21
  module Benchmark
22
22
  module HTTP
23
- VERSION = "0.2.0"
23
+ VERSION = "0.3.0"
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: benchmark-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-27 00:00:00.000000000 Z
11
+ date: 2018-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-io
@@ -30,14 +30,42 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.9'
33
+ version: 0.27.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.9'
40
+ version: 0.27.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: async-await
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: trenni-sanitize
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: samovar
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -113,6 +141,8 @@ files:
113
141
  - lib/benchmark/http.rb
114
142
  - lib/benchmark/http/command.rb
115
143
  - lib/benchmark/http/command/concurrency.rb
144
+ - lib/benchmark/http/command/spider.rb
145
+ - lib/benchmark/http/links_filter.rb
116
146
  - lib/benchmark/http/seconds.rb
117
147
  - lib/benchmark/http/statistics.rb
118
148
  - lib/benchmark/http/version.rb