elasticsearch-transport 0.0.2
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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +13 -0
- data/README.md +276 -0
- data/Rakefile +67 -0
- data/elasticsearch-transport.gemspec +52 -0
- data/lib/elasticsearch-transport.rb +1 -0
- data/lib/elasticsearch/transport.rb +29 -0
- data/lib/elasticsearch/transport/client.rb +123 -0
- data/lib/elasticsearch/transport/extensions/test_cluster.rb +163 -0
- data/lib/elasticsearch/transport/transport/base.rb +236 -0
- data/lib/elasticsearch/transport/transport/connections/collection.rb +93 -0
- data/lib/elasticsearch/transport/transport/connections/connection.rb +117 -0
- data/lib/elasticsearch/transport/transport/connections/selector.rb +63 -0
- data/lib/elasticsearch/transport/transport/errors.rb +73 -0
- data/lib/elasticsearch/transport/transport/http/curb.rb +70 -0
- data/lib/elasticsearch/transport/transport/http/faraday.rb +59 -0
- data/lib/elasticsearch/transport/transport/response.rb +20 -0
- data/lib/elasticsearch/transport/transport/serializer/multi_json.rb +36 -0
- data/lib/elasticsearch/transport/transport/sniffer.rb +46 -0
- data/lib/elasticsearch/transport/version.rb +5 -0
- data/test/integration/client_test.rb +117 -0
- data/test/integration/transport_test.rb +37 -0
- data/test/profile/client_benchmark_test.rb +107 -0
- data/test/test_extensions.rb +139 -0
- data/test/test_helper.rb +58 -0
- data/test/unit/client_test.rb +109 -0
- data/test/unit/connection_collection_test.rb +83 -0
- data/test/unit/connection_selector_test.rb +64 -0
- data/test/unit/connection_test.rb +90 -0
- data/test/unit/serializer_test.rb +16 -0
- data/test/unit/sniffer_test.rb +146 -0
- data/test/unit/transport_base_test.rb +402 -0
- data/test/unit/transport_curb_test.rb +59 -0
- data/test/unit/transport_faraday_test.rb +73 -0
- metadata +342 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Transport
|
3
|
+
module Transport
|
4
|
+
|
5
|
+
# Wraps the response from Elasticsearch.
|
6
|
+
#
|
7
|
+
class Response
|
8
|
+
attr_reader :status, :body, :headers
|
9
|
+
|
10
|
+
# @param status [Integer] Response status code
|
11
|
+
# @param body [String] Response body
|
12
|
+
# @param headers [Hash] Response headers
|
13
|
+
def initialize(status, body, headers={})
|
14
|
+
@status, @body, @headers = status, body, headers
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Transport
|
3
|
+
module Transport
|
4
|
+
module Serializer
|
5
|
+
|
6
|
+
# An abstract class for implementing serializer implementations
|
7
|
+
#
|
8
|
+
module Base
|
9
|
+
# @param transport [Object] The instance of transport which uses this serializer
|
10
|
+
#
|
11
|
+
def initialize(transport=nil)
|
12
|
+
@transport = transport
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# A default JSON serializer (using [MultiJSON](http://rubygems.org/gems/multi_json))
|
17
|
+
#
|
18
|
+
class MultiJson
|
19
|
+
include Base
|
20
|
+
|
21
|
+
# De-serialize a Hash from JSON string
|
22
|
+
#
|
23
|
+
def load(string, options={})
|
24
|
+
::MultiJson.load(string, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Serialize a Hash to JSON string
|
28
|
+
#
|
29
|
+
def dump(object, options={})
|
30
|
+
::MultiJson.dump(object, options)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Transport
|
3
|
+
module Transport
|
4
|
+
|
5
|
+
# Handles node discovery ("sniffing").
|
6
|
+
#
|
7
|
+
class Sniffer
|
8
|
+
RE_URL = /\/([^:]*):([0-9]+)\]/ # Use named groups on Ruby 1.9: /\/(?<host>[^:]*):(?<port>[0-9]+)\]/
|
9
|
+
|
10
|
+
attr_reader :transport
|
11
|
+
attr_accessor :timeout
|
12
|
+
|
13
|
+
# @param transport [Object] A transport instance.
|
14
|
+
#
|
15
|
+
def initialize(transport)
|
16
|
+
@transport = transport
|
17
|
+
@timeout = transport.options[:sniffer_timeout] || 1
|
18
|
+
end
|
19
|
+
|
20
|
+
# Retrieves the node list from the Elasticsearch's
|
21
|
+
# [_Nodes Info API_](http://www.elasticsearch.org/guide/reference/api/admin-cluster-nodes-info/)
|
22
|
+
# and returns a normalized Array of information suitable for passing to transport.
|
23
|
+
#
|
24
|
+
# Shuffles the collection before returning it when the `randomize_hosts` option is set for transport.
|
25
|
+
#
|
26
|
+
# @return [Array<Hash>]
|
27
|
+
# @raise [SnifferTimeoutError]
|
28
|
+
#
|
29
|
+
def hosts
|
30
|
+
Timeout::timeout(timeout, SnifferTimeoutError) do
|
31
|
+
nodes = transport.perform_request('GET', '_cluster/nodes').body
|
32
|
+
hosts = nodes['nodes'].map do |id,info|
|
33
|
+
if matches = info["#{transport.protocol}_address"].to_s.match(RE_URL)
|
34
|
+
# TODO: Implement lightweight "indifferent access" here
|
35
|
+
info.merge :host => matches[1], :port => matches[2], :id => id
|
36
|
+
end
|
37
|
+
end.compact
|
38
|
+
|
39
|
+
hosts.shuffle! if transport.options[:randomize_hosts]
|
40
|
+
hosts
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::IntegrationTestCase
|
4
|
+
startup do
|
5
|
+
Elasticsearch::TestCluster.start if ENV['SERVER'] and not Elasticsearch::TestCluster.running?
|
6
|
+
end
|
7
|
+
|
8
|
+
context "Elasticsearch client" do
|
9
|
+
setup do
|
10
|
+
system "curl -X DELETE http://localhost:9250/_all > /dev/null 2>&1"
|
11
|
+
|
12
|
+
@logger = Logger.new(STDERR)
|
13
|
+
@logger.formatter = proc do |severity, datetime, progname, msg|
|
14
|
+
color = case severity
|
15
|
+
when /INFO/ then :green
|
16
|
+
when /ERROR|WARN|FATAL/ then :red
|
17
|
+
when /DEBUG/ then :cyan
|
18
|
+
else :white
|
19
|
+
end
|
20
|
+
ANSI.ansi(severity[0] + ' ', color, :faint) + ANSI.ansi(msg, :white, :faint) + "\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
@client = Elasticsearch::Client.new host: 'localhost:9250'
|
24
|
+
end
|
25
|
+
|
26
|
+
should "connect to the cluster" do
|
27
|
+
assert_nothing_raised do
|
28
|
+
response = @client.perform_request 'GET', '_cluster/health'
|
29
|
+
assert_equal 2, response.body['number_of_nodes']
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
should "handle paths and URL parameters" do
|
34
|
+
@client.perform_request 'PUT', 'myindex/mydoc/1', {routing: 'XYZ'}, {foo: 'bar'}
|
35
|
+
response = @client.perform_request 'GET', 'myindex/mydoc/1?routing=XYZ'
|
36
|
+
assert_equal true, response.body['exists']
|
37
|
+
assert_equal 'bar', response.body['_source']['foo']
|
38
|
+
assert_raise Elasticsearch::Transport::Transport::Errors::NotFound do
|
39
|
+
response = @client.perform_request 'GET', 'myindex/mydoc/1?routing=ABC'
|
40
|
+
assert_nil response.body['_source']
|
41
|
+
assert_equal false, response.body['exists']
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "with round robin selector" do
|
46
|
+
setup do
|
47
|
+
@client = Elasticsearch::Client.new \
|
48
|
+
hosts: %w| localhost:9250 localhost:9251 |,
|
49
|
+
logger: @logger
|
50
|
+
end
|
51
|
+
|
52
|
+
should "rotate nodes" do
|
53
|
+
# Hit node 1
|
54
|
+
response = @client.perform_request 'GET', '_cluster/nodes/_local'
|
55
|
+
assert_equal 'node-1', response.body['nodes'].to_a[0][1]['name']
|
56
|
+
|
57
|
+
# Hit node 2
|
58
|
+
response = @client.perform_request 'GET', '_cluster/nodes/_local'
|
59
|
+
assert_equal 'node-2', response.body['nodes'].to_a[0][1]['name']
|
60
|
+
|
61
|
+
# Hit node 1
|
62
|
+
response = @client.perform_request 'GET', '_cluster/nodes/_local'
|
63
|
+
assert_equal 'node-1', response.body['nodes'].to_a[0][1]['name']
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "with a sick node and retry on failure" do
|
68
|
+
setup do
|
69
|
+
@client = Elasticsearch::Client.new \
|
70
|
+
hosts: %w| localhost:9250 foobar1 |,
|
71
|
+
logger: @logger,
|
72
|
+
retry_on_failure: true
|
73
|
+
end
|
74
|
+
|
75
|
+
should "retry the request with next server" do
|
76
|
+
assert_nothing_raised do
|
77
|
+
5.times { @client.perform_request 'GET', '_cluster/nodes/_local' }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
should "raise exception when it cannot get any healthy server" do
|
82
|
+
@client = Elasticsearch::Client.new \
|
83
|
+
hosts: %w| localhost:9250 foobar1 foobar2 foobar3 |,
|
84
|
+
logger: @logger,
|
85
|
+
retry_on_failure: 1
|
86
|
+
|
87
|
+
assert_nothing_raised do
|
88
|
+
# First hit is OK
|
89
|
+
@client.perform_request 'GET', '_cluster/nodes/_local'
|
90
|
+
end
|
91
|
+
|
92
|
+
assert_raise Faraday::Error::ConnectionFailed do
|
93
|
+
# Second hit fails
|
94
|
+
@client.perform_request 'GET', '_cluster/nodes/_local'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "with a sick node and reloading on failure" do
|
100
|
+
setup do
|
101
|
+
@client = Elasticsearch::Client.new \
|
102
|
+
hosts: %w| localhost:9250 foobar1 foobar2 |,
|
103
|
+
logger: @logger,
|
104
|
+
reload_on_failure: true
|
105
|
+
end
|
106
|
+
|
107
|
+
should "reload the connections" do
|
108
|
+
assert_equal 3, @client.transport.connections.size
|
109
|
+
assert_nothing_raised do
|
110
|
+
5.times { @client.perform_request 'GET', '_cluster/nodes/_local' }
|
111
|
+
end
|
112
|
+
assert_equal 2, @client.transport.connections.size
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::IntegrationTestCase
|
4
|
+
startup do
|
5
|
+
Elasticsearch::TestCluster.start if ENV['SERVER'] and not Elasticsearch::TestCluster.running?
|
6
|
+
end
|
7
|
+
|
8
|
+
context "Transport" do
|
9
|
+
should "allow to customize the Faraday adapter" do
|
10
|
+
require 'typhoeus'
|
11
|
+
require 'typhoeus/adapters/faraday'
|
12
|
+
|
13
|
+
transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new \
|
14
|
+
:hosts => [ { :host => 'localhost', :port => '9250' } ] do |f|
|
15
|
+
f.response :logger
|
16
|
+
f.adapter :typhoeus
|
17
|
+
end
|
18
|
+
|
19
|
+
client = Elasticsearch::Transport::Client.new transport: transport
|
20
|
+
client.perform_request 'GET', ''
|
21
|
+
end
|
22
|
+
|
23
|
+
should "use the Curb client" do
|
24
|
+
require 'curb'
|
25
|
+
require 'elasticsearch/transport/transport/http/curb'
|
26
|
+
|
27
|
+
transport = Elasticsearch::Transport::Transport::HTTP::Curb.new \
|
28
|
+
:hosts => [ { :host => 'localhost', :port => '9250' } ] do |curl|
|
29
|
+
curl.verbose = true
|
30
|
+
end
|
31
|
+
|
32
|
+
client = Elasticsearch::Transport::Client.new transport: transport
|
33
|
+
client.perform_request 'GET', ''
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::ProfilingTest
|
4
|
+
startup do
|
5
|
+
Elasticsearch::TestCluster.start if ENV['SERVER'] and not Elasticsearch::TestCluster.running?
|
6
|
+
end
|
7
|
+
|
8
|
+
context "Elasticsearch client benchmark" do
|
9
|
+
setup do
|
10
|
+
client = Elasticsearch::Client.new host: 'localhost:9250'
|
11
|
+
client.perform_request 'DELETE', '/ruby_test_benchmark/' rescue nil
|
12
|
+
client.perform_request 'POST', '/ruby_test_benchmark/', {index: {number_of_shards: 1, number_of_replicas: 0}}
|
13
|
+
100.times do client.perform_request 'POST', '/ruby_test_benchmark_search/test/', {}, {foo: 'bar'}; end
|
14
|
+
client.perform_request 'POST', '/ruby_test_benchmark_search/_refresh'
|
15
|
+
end
|
16
|
+
teardown do
|
17
|
+
client = Elasticsearch::Client.new host: 'localhost:9250'
|
18
|
+
client.perform_request 'DELETE', '/ruby_test_benchmark/'
|
19
|
+
client.perform_request 'DELETE', '/ruby_test_benchmark_search/'
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with a single-node cluster" do
|
23
|
+
setup do
|
24
|
+
@client = Elasticsearch::Client.new hosts: 'localhost:9250'
|
25
|
+
end
|
26
|
+
|
27
|
+
measure "get the cluster info", count: 1_000 do
|
28
|
+
@client.perform_request 'GET', ''
|
29
|
+
end
|
30
|
+
|
31
|
+
measure "index a document" do
|
32
|
+
@client.perform_request 'POST', '/ruby_test_benchmark/test/', {}, {foo: 'bar'}
|
33
|
+
end
|
34
|
+
|
35
|
+
measure "search" do
|
36
|
+
@client.perform_request 'POST', '/ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with a two-node cluster" do
|
41
|
+
setup do
|
42
|
+
@client = Elasticsearch::Client.new hosts: ['localhost:9250', 'localhost:9251']
|
43
|
+
end
|
44
|
+
|
45
|
+
measure "get the cluster info", count: 1_000 do
|
46
|
+
@client.perform_request 'GET', ''
|
47
|
+
end
|
48
|
+
|
49
|
+
measure "index a document"do
|
50
|
+
@client.perform_request 'POST', '/ruby_test_benchmark/test/', {}, {foo: 'bar'}
|
51
|
+
end
|
52
|
+
|
53
|
+
measure "search" do
|
54
|
+
@client.perform_request 'POST', '/ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "with a single-node cluster and the Curb client" do
|
59
|
+
setup do
|
60
|
+
require 'curb'
|
61
|
+
require 'elasticsearch/transport/transport/http/curb'
|
62
|
+
@client = Elasticsearch::Client.new host: 'localhost:9250',
|
63
|
+
transport_class: Elasticsearch::Transport::Transport::HTTP::Curb
|
64
|
+
end
|
65
|
+
|
66
|
+
measure "get the cluster info", count: 1_000 do
|
67
|
+
@client.perform_request 'GET', ''
|
68
|
+
end
|
69
|
+
|
70
|
+
measure "index a document" do
|
71
|
+
@client.perform_request 'POST', '/ruby_test_benchmark/test/', {}, {foo: 'bar'}
|
72
|
+
end
|
73
|
+
|
74
|
+
measure "search" do
|
75
|
+
@client.perform_request 'POST', '/ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "with a single-node cluster and the Typhoeus client" do
|
80
|
+
setup do
|
81
|
+
require 'typhoeus'
|
82
|
+
require 'typhoeus/adapters/faraday'
|
83
|
+
|
84
|
+
transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new \
|
85
|
+
:hosts => [ { :host => 'localhost', :port => '9250' } ] do |f|
|
86
|
+
f.adapter :typhoeus
|
87
|
+
end
|
88
|
+
|
89
|
+
@client = Elasticsearch::Client.new transport: transport
|
90
|
+
end
|
91
|
+
|
92
|
+
measure "get the cluster info", count: 1_000 do
|
93
|
+
@client.perform_request 'GET', ''
|
94
|
+
end
|
95
|
+
|
96
|
+
measure "index a document" do
|
97
|
+
@client.perform_request 'POST', '/ruby_test_benchmark/test/', {}, {foo: 'bar'}
|
98
|
+
end
|
99
|
+
|
100
|
+
measure "search" do
|
101
|
+
@client.perform_request 'POST', '/ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}}
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'ruby-prof'
|
3
|
+
require 'ansi/code'
|
4
|
+
require 'ansi/terminal'
|
5
|
+
|
6
|
+
module Elasticsearch
|
7
|
+
module Test
|
8
|
+
|
9
|
+
# Startup/shutdown support for test suites
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# class MyTest < Test::Unit::TestCase
|
14
|
+
# extend IntegrationTestStartupShutdown
|
15
|
+
#
|
16
|
+
# startup { puts "Suite starting up..." }
|
17
|
+
# shutdown { puts "Suite shutting down..." }
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# *** IMPORTANT NOTE: **********************************************************
|
21
|
+
#
|
22
|
+
# You have to register the handler for shutdown before requiring 'test/unit':
|
23
|
+
#
|
24
|
+
# # File: test_helper.rb
|
25
|
+
# at_exit { MyTest.__run_at_exit_hooks }
|
26
|
+
# require 'test/unit'
|
27
|
+
#
|
28
|
+
# The API follows Test::Unit 2.0
|
29
|
+
# <https://github.com/test-unit/test-unit/blob/master/lib/test/unit/testcase.rb>
|
30
|
+
#
|
31
|
+
module IntegrationTestStartupShutdown
|
32
|
+
@@started = false
|
33
|
+
@@shutdown_blocks ||= []
|
34
|
+
|
35
|
+
def startup &block
|
36
|
+
return if started?
|
37
|
+
@@started = true
|
38
|
+
yield block if block_given?
|
39
|
+
end
|
40
|
+
|
41
|
+
def shutdown &block
|
42
|
+
@@shutdown_blocks << block if block_given?
|
43
|
+
end
|
44
|
+
|
45
|
+
def started?
|
46
|
+
!! @@started
|
47
|
+
end
|
48
|
+
|
49
|
+
def __run_at_exit_hooks
|
50
|
+
return unless started?
|
51
|
+
STDERR.puts ANSI.faint("Running at_exit hooks...")
|
52
|
+
puts ANSI.faint('-'*80)
|
53
|
+
@@shutdown_blocks.each { |b| b.call }
|
54
|
+
puts ANSI.faint('-'*80)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Profiling support for tests with [ruby-prof](https://github.com/ruby-prof/ruby-prof)
|
59
|
+
#
|
60
|
+
# Example:
|
61
|
+
#
|
62
|
+
# measure "divide numbers", count: 10_000 do
|
63
|
+
# assert_nothing_raised { 1/2 }
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# Will print out something like this along your test output:
|
67
|
+
#
|
68
|
+
# ---------------------------------------------------------------------
|
69
|
+
# Context: My benchmark should divide numbers (10000x)
|
70
|
+
# mean: 0.01ms | avg: 0.01ms | max: 6.19ms
|
71
|
+
# ---------------------------------------------------------------------
|
72
|
+
# ...
|
73
|
+
# Total: 0.313283
|
74
|
+
#
|
75
|
+
# %self total self wait child calls name
|
76
|
+
# 25.38 0.313 0.079 0.000 0.234 1 <Object::MyTets>#__bind_1368638677_723101
|
77
|
+
# 14.42 0.118 0.045 0.000 0.073 20000 <Class::Time>#now
|
78
|
+
# 7.57 0.088 0.033 0.000 0.055 10000 Time#-
|
79
|
+
# ...
|
80
|
+
#
|
81
|
+
# PASS (0:00:00.322) test: My benchmark should divide numbers (10000x).
|
82
|
+
#
|
83
|
+
#
|
84
|
+
module ProfilingTestSupport
|
85
|
+
|
86
|
+
# Profiles the passed block of code.
|
87
|
+
#
|
88
|
+
# measure "divide numbers", count: 10_000 do
|
89
|
+
# assert_nothing_raised { 1/2 }
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# @todo Try to make progress bar not interfere with tests
|
93
|
+
#
|
94
|
+
def measure(name, options={}, &block)
|
95
|
+
# require 'pry'; binding.pry
|
96
|
+
___ = '-'*ANSI::Terminal.terminal_width
|
97
|
+
test_name = self.name.split('::').last
|
98
|
+
context_name = self.context(nil) {}.first.parent.name
|
99
|
+
count = Integer(ENV['COUNT'] || options[:count] || 1_000)
|
100
|
+
ticks = []
|
101
|
+
# progress = ANSI::Progressbar.new("#{name} (#{count}x)", count)
|
102
|
+
|
103
|
+
should "#{name} (#{count}x)" do
|
104
|
+
RubyProf.start
|
105
|
+
|
106
|
+
count.times do
|
107
|
+
ticks << Benchmark.realtime { self.instance_eval(&block) }
|
108
|
+
# RubyProf.pause
|
109
|
+
# progress.inc
|
110
|
+
# RubyProf.resume
|
111
|
+
end
|
112
|
+
|
113
|
+
result = RubyProf.stop
|
114
|
+
# progress.finish
|
115
|
+
|
116
|
+
total = result.threads.reduce(0) { |total,info| total += info.total_time; total }
|
117
|
+
mean = (ticks.sort[(ticks.size/2).round-1])*1000
|
118
|
+
avg = (ticks.inject {|sum,el| sum += el; sum}.to_f/ticks.size)*1000
|
119
|
+
max = ticks.max*1000
|
120
|
+
|
121
|
+
|
122
|
+
result.eliminate_methods!([/Integer#times|Benchmark.realtime|ANSI::Code#.*|ANSI::ProgressBar#.*/])
|
123
|
+
printer = RubyProf::FlatPrinter.new(result)
|
124
|
+
# printer = RubyProf::GraphPrinter.new(result)
|
125
|
+
|
126
|
+
puts "\n",
|
127
|
+
___,
|
128
|
+
'Context: ' + ANSI.bold(context_name) + ' should ' + ANSI.bold(name) + " (#{count}x)",
|
129
|
+
"mean: #{sprintf('%.2f', mean)}ms | " +
|
130
|
+
"avg: #{sprintf('%.2f', avg)}ms | " +
|
131
|
+
"max: #{sprintf('%.2f', max)}ms",
|
132
|
+
___
|
133
|
+
printer.print(STDOUT, {}) unless ENV['QUIET'] || options[:quiet]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|