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