elasticsearch-transport 0.4.0 → 0.4.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/README.md +30 -11
- data/Rakefile +19 -6
- data/elasticsearch-transport.gemspec +11 -1
- data/lib/elasticsearch/transport/client.rb +10 -4
- data/lib/elasticsearch/transport/transport/base.rb +13 -0
- data/lib/elasticsearch/transport/transport/connections/connection.rb +5 -1
- data/lib/elasticsearch/transport/transport/http/curb.rb +14 -9
- data/lib/elasticsearch/transport/transport/http/faraday.rb +2 -2
- data/lib/elasticsearch/transport/version.rb +1 -1
- data/test/integration/client_test.rb +11 -7
- data/test/integration/transport_test.rb +7 -3
- data/test/profile/client_benchmark_test.rb +8 -7
- data/test/test_helper.rb +10 -9
- data/test/unit/client_test.rb +66 -10
- data/test/unit/connection_test.rb +10 -0
- data/test/unit/sniffer_test.rb +2 -3
- data/test/unit/transport_base_test.rb +22 -1
- data/test/unit/transport_curb_test.rb +26 -7
- data/test/unit/transport_faraday_test.rb +6 -1
- metadata +68 -7
- data/lib/elasticsearch/transport/extensions/test_cluster.rb +0 -163
- data/test/test_extensions.rb +0 -139
data/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# Elasticsearch::
|
|
1
|
+
# Elasticsearch::Transport
|
|
2
2
|
|
|
3
3
|
**This library is part of the [`elasticsearch-ruby`](https://github.com/elasticsearch/elasticsearch-ruby/) package;
|
|
4
4
|
please refer to it, unless you want to use this library standalone.**
|
|
5
5
|
|
|
6
6
|
----
|
|
7
7
|
|
|
8
|
-
The `elasticsearch-
|
|
8
|
+
The `elasticsearch-transport` library provides a low-level Ruby client for connecting
|
|
9
9
|
to an [Elasticsearch](http://elasticsearch.org) cluster.
|
|
10
10
|
|
|
11
11
|
It handles connecting to multiple nodes in the cluster, rotating across connections,
|
|
@@ -31,16 +31,16 @@ Features overview:
|
|
|
31
31
|
|
|
32
32
|
Install the package from [Rubygems](https://rubygems.org):
|
|
33
33
|
|
|
34
|
-
gem install elasticsearch-
|
|
34
|
+
gem install elasticsearch-transport
|
|
35
35
|
|
|
36
36
|
To use an unreleased version, either add it to your `Gemfile` for [Bundler](http://gembundler.com):
|
|
37
37
|
|
|
38
|
-
gem 'elasticsearch-
|
|
38
|
+
gem 'elasticsearch-transport', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git'
|
|
39
39
|
|
|
40
40
|
or install it from a source code checkout:
|
|
41
41
|
|
|
42
42
|
git clone https://github.com/elasticsearch/elasticsearch-ruby.git
|
|
43
|
-
cd elasticsearch-ruby/elasticsearch-
|
|
43
|
+
cd elasticsearch-ruby/elasticsearch-transport
|
|
44
44
|
bundle install
|
|
45
45
|
rake install
|
|
46
46
|
|
|
@@ -49,12 +49,14 @@ or install it from a source code checkout:
|
|
|
49
49
|
In the simplest form, connect to Elasticsearch running on <http://localhost:9200>
|
|
50
50
|
without any configuration:
|
|
51
51
|
|
|
52
|
-
require 'elasticsearch/
|
|
52
|
+
require 'elasticsearch/transport'
|
|
53
53
|
|
|
54
54
|
client = Elasticsearch::Client.new
|
|
55
55
|
response = client.perform_request 'GET', '_cluster/health'
|
|
56
56
|
# => #<Elasticsearch::Transport::Transport::Response:0x007fc5d506ce38 @status=200, @body={ ... } >
|
|
57
57
|
|
|
58
|
+
Full documentation is available at <http://rubydoc.info/gems/elasticsearch-transport>.
|
|
59
|
+
|
|
58
60
|
## Configuration
|
|
59
61
|
|
|
60
62
|
The client supports many configurations options for setting up and managing connections,
|
|
@@ -78,9 +80,13 @@ Instead of Strings, you can pass host information as an array of Hashes:
|
|
|
78
80
|
|
|
79
81
|
Elasticsearch::Client.new hosts: [ { host: 'myhost1', port: 8080 }, { host: 'myhost2', port: 8080 } ]
|
|
80
82
|
|
|
83
|
+
Scheme, HTTP authentication credentials and URL prefixes are handled automatically:
|
|
84
|
+
|
|
85
|
+
Elasticsearch::Client.new url: 'https://username:password@api.server.org:4430/search'
|
|
86
|
+
|
|
81
87
|
### Logging
|
|
82
88
|
|
|
83
|
-
To log requests and responses to standard output with the default logger (an instance of Ruby's {::Logger}
|
|
89
|
+
To log requests and responses to standard output with the default logger (an instance of Ruby's {::Logger} class):
|
|
84
90
|
|
|
85
91
|
Elasticsearch::Client.new log: true
|
|
86
92
|
|
|
@@ -163,7 +169,7 @@ and only when these are not be available, will use the rest:
|
|
|
163
169
|
include Elasticsearch::Transport::Transport::Connections::Selector::Base
|
|
164
170
|
|
|
165
171
|
def select(options={})
|
|
166
|
-
connections.
|
|
172
|
+
connections.select do |c|
|
|
167
173
|
# Try selecting the nodes with a `rack_id:x1` attribute first
|
|
168
174
|
c.host[:attributes] && c.host[:attributes][:rack_id] == 'x1'
|
|
169
175
|
end.sample || connections.to_a.sample
|
|
@@ -201,7 +207,9 @@ You can also use a [_Curb_](https://rubygems.org/gems/curb) based transport impl
|
|
|
201
207
|
|
|
202
208
|
It's possible to customize the _Curb_ instance by passing a block to the constructor as well:
|
|
203
209
|
|
|
204
|
-
configuration = lambda
|
|
210
|
+
configuration = lambda do |c|
|
|
211
|
+
c.verbose = true
|
|
212
|
+
end
|
|
205
213
|
|
|
206
214
|
transport = Elasticsearch::Transport::Transport::HTTP::Curb.new \
|
|
207
215
|
hosts: [ { host: 'localhost', port: '9200' } ],
|
|
@@ -209,6 +217,17 @@ It's possible to customize the _Curb_ instance by passing a block to the constru
|
|
|
209
217
|
|
|
210
218
|
client = Elasticsearch::Client.new transport: transport
|
|
211
219
|
|
|
220
|
+
Instead of passing the transport to the constructor, you can inject it at run time:
|
|
221
|
+
|
|
222
|
+
faraday_client = Elasticsearch::Transport::Transport::HTTP::Faraday.new \
|
|
223
|
+
hosts: [ { host: '33.33.33.10', port: '443', user: 'USERNAME', password: 'PASSWORD', scheme: 'https' } ],
|
|
224
|
+
& lambda { |f| f.instance_variable_set :@ssl, { verify: false }
|
|
225
|
+
f.options[:ssl] = { verify: false }
|
|
226
|
+
f.adapter :excon }
|
|
227
|
+
|
|
228
|
+
client = Elasticsearch::Client.new
|
|
229
|
+
client.transport = faraday_client
|
|
230
|
+
|
|
212
231
|
You can write your own transport implementation easily, by including the
|
|
213
232
|
{Elasticsearch::Transport::Transport::Base} module, implementing the required contract,
|
|
214
233
|
and passing it to the client as the `transport_class` parameter. All the arguments
|
|
@@ -228,9 +247,9 @@ and passing it to the client as the `serializer_class` or `serializer` parameter
|
|
|
228
247
|
For local development, clone the repository and run `bundle install`. See `rake -T` for a list of
|
|
229
248
|
available Rake tasks for running tests, generating documentation, starting a testing cluster, etc.
|
|
230
249
|
|
|
231
|
-
Bug fixes and features must be
|
|
250
|
+
Bug fixes and features must be covered by unit tests. Integration tests are written in Ruby 1.9 syntax.
|
|
232
251
|
|
|
233
|
-
Github's pull requests and issues are used to send
|
|
252
|
+
Github's pull requests and issues are used to communicate, send bug reports and code contributions.
|
|
234
253
|
|
|
235
254
|
## The Architecture
|
|
236
255
|
|
data/Rakefile
CHANGED
|
@@ -8,7 +8,19 @@ task :test => 'test:unit'
|
|
|
8
8
|
|
|
9
9
|
require 'rake/testtask'
|
|
10
10
|
namespace :test do
|
|
11
|
+
task :ci_reporter do
|
|
12
|
+
ENV['CI_REPORTS'] ||= 'tmp/reports'
|
|
13
|
+
if defined?(RUBY_VERSION) && RUBY_VERSION < '1.9'
|
|
14
|
+
require 'ci/reporter/rake/test_unit'
|
|
15
|
+
Rake::Task['ci:setup:testunit'].invoke
|
|
16
|
+
else
|
|
17
|
+
require 'ci/reporter/rake/minitest'
|
|
18
|
+
Rake::Task['ci:setup:minitest'].invoke
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
11
22
|
Rake::TestTask.new(:unit) do |test|
|
|
23
|
+
Rake::Task['test:ci_reporter'].invoke if ENV['CI']
|
|
12
24
|
test.libs << 'lib' << 'test'
|
|
13
25
|
test.test_files = FileList["test/unit/**/*_test.rb"]
|
|
14
26
|
# test.verbose = true
|
|
@@ -16,16 +28,19 @@ namespace :test do
|
|
|
16
28
|
end
|
|
17
29
|
|
|
18
30
|
Rake::TestTask.new(:integration) do |test|
|
|
31
|
+
Rake::Task['test:ci_reporter'].invoke if ENV['CI']
|
|
19
32
|
test.libs << 'lib' << 'test'
|
|
20
33
|
test.test_files = FileList["test/integration/**/*_test.rb"]
|
|
21
34
|
end
|
|
22
35
|
|
|
23
36
|
Rake::TestTask.new(:all) do |test|
|
|
37
|
+
Rake::Task['test:ci_reporter'].invoke if ENV['CI']
|
|
24
38
|
test.libs << 'lib' << 'test'
|
|
25
39
|
test.test_files = FileList["test/unit/**/*_test.rb", "test/integration/**/*_test.rb"]
|
|
26
40
|
end
|
|
27
41
|
|
|
28
42
|
Rake::TestTask.new(:profile) do |test|
|
|
43
|
+
Rake::Task['test:ci_reporter'].invoke if ENV['CI']
|
|
29
44
|
test.libs << 'lib' << 'test'
|
|
30
45
|
test.test_files = FileList["test/profile/**/*_test.rb"]
|
|
31
46
|
end
|
|
@@ -34,17 +49,15 @@ namespace :test do
|
|
|
34
49
|
desc "Start Elasticsearch nodes for tests"
|
|
35
50
|
task :start do
|
|
36
51
|
$LOAD_PATH << File.expand_path('../lib', __FILE__) << File.expand_path('../test', __FILE__)
|
|
37
|
-
require 'elasticsearch/
|
|
38
|
-
|
|
39
|
-
Elasticsearch::TestCluster.start
|
|
52
|
+
require 'elasticsearch/extensions/test/cluster'
|
|
53
|
+
Elasticsearch::Extensions::Test::Cluster.start
|
|
40
54
|
end
|
|
41
55
|
|
|
42
56
|
desc "Stop Elasticsearch nodes for tests"
|
|
43
57
|
task :stop do
|
|
44
58
|
$LOAD_PATH << File.expand_path('../lib', __FILE__) << File.expand_path('../test', __FILE__)
|
|
45
|
-
require 'elasticsearch/
|
|
46
|
-
|
|
47
|
-
Elasticsearch::TestCluster.stop
|
|
59
|
+
require 'elasticsearch/extensions/test/cluster'
|
|
60
|
+
Elasticsearch::Extensions::Test::Cluster.stop
|
|
48
61
|
end
|
|
49
62
|
end
|
|
50
63
|
end
|
|
@@ -29,21 +29,31 @@ Gem::Specification.new do |s|
|
|
|
29
29
|
s.add_development_dependency "bundler", "> 1"
|
|
30
30
|
s.add_development_dependency "rake"
|
|
31
31
|
|
|
32
|
+
s.add_development_dependency "elasticsearch-extensions"
|
|
33
|
+
|
|
32
34
|
s.add_development_dependency "ansi"
|
|
33
35
|
s.add_development_dependency "shoulda-context"
|
|
34
36
|
s.add_development_dependency "mocha"
|
|
35
37
|
s.add_development_dependency "turn"
|
|
36
38
|
s.add_development_dependency "yard"
|
|
37
39
|
s.add_development_dependency "ruby-prof"
|
|
40
|
+
s.add_development_dependency "pry"
|
|
41
|
+
s.add_development_dependency "ci_reporter"
|
|
38
42
|
|
|
39
43
|
# Gems for testing integrations
|
|
40
44
|
s.add_development_dependency "curb"
|
|
41
|
-
s.add_development_dependency "typhoeus"
|
|
45
|
+
s.add_development_dependency "typhoeus", '~> 0.6'
|
|
46
|
+
|
|
47
|
+
# Prevent unit test failures on Ruby 1.8
|
|
48
|
+
if defined?(RUBY_VERSION) && RUBY_VERSION < '1.9'
|
|
49
|
+
s.add_development_dependency "test-unit", '~> 2'
|
|
50
|
+
end
|
|
42
51
|
|
|
43
52
|
if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
|
|
44
53
|
s.add_development_dependency "simplecov"
|
|
45
54
|
s.add_development_dependency "cane"
|
|
46
55
|
s.add_development_dependency "require-prof"
|
|
56
|
+
s.add_development_dependency "coveralls"
|
|
47
57
|
end
|
|
48
58
|
|
|
49
59
|
s.description = <<-DESC.gsub(/^ /, '')
|
|
@@ -105,13 +105,19 @@ module Elasticsearch
|
|
|
105
105
|
hosts = hosts_config.map do |host|
|
|
106
106
|
case host
|
|
107
107
|
when String
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
if host =~ /^[a-z]+\:\/\//
|
|
109
|
+
uri = URI.parse(host)
|
|
110
|
+
{ :scheme => uri.scheme, :user => uri.user, :password => uri.password, :host => uri.host, :path => uri.path, :port => uri.port.to_s }
|
|
111
|
+
else
|
|
112
|
+
host, port = host.split(':')
|
|
113
|
+
{ :host => host, :port => port }
|
|
114
|
+
end
|
|
115
|
+
when URI
|
|
116
|
+
{ :scheme => host.scheme, :user => host.user, :password => host.password, :host => host.host, :path => host.path, :port => host.port.to_s }
|
|
111
117
|
when Hash
|
|
112
118
|
host
|
|
113
119
|
else
|
|
114
|
-
raise ArgumentError, "Please pass host as a String or Hash
|
|
120
|
+
raise ArgumentError, "Please pass host as a String, URI or Hash -- #{host.class} given."
|
|
115
121
|
end
|
|
116
122
|
end
|
|
117
123
|
|
|
@@ -139,6 +139,19 @@ module Elasticsearch
|
|
|
139
139
|
o = o.is_a?(String) ? o : serializer.dump(o, options)
|
|
140
140
|
end
|
|
141
141
|
|
|
142
|
+
# Returns a full URL based on information from host
|
|
143
|
+
#
|
|
144
|
+
# @param host [Hash] Host configuration passed in from {Client}
|
|
145
|
+
#
|
|
146
|
+
# @api private
|
|
147
|
+
def __full_url(host)
|
|
148
|
+
url = "#{host[:protocol]}://"
|
|
149
|
+
url += "#{host[:user]}:#{host[:password]}@" if host[:user]
|
|
150
|
+
url += "#{host[:host]}:#{host[:port]}"
|
|
151
|
+
url += "#{host[:path]}" if host[:path]
|
|
152
|
+
url
|
|
153
|
+
end
|
|
154
|
+
|
|
142
155
|
# Performs a request to Elasticsearch, while handling logging, tracing, marking dead connections,
|
|
143
156
|
# retrying the request and reloading the connections.
|
|
144
157
|
#
|
|
@@ -36,7 +36,11 @@ module Elasticsearch
|
|
|
36
36
|
# @return [String]
|
|
37
37
|
#
|
|
38
38
|
def full_url(path, params={})
|
|
39
|
-
"#{host[:protocol]}
|
|
39
|
+
url = "#{host[:protocol]}://"
|
|
40
|
+
url += "#{host[:user]}:#{host[:password]}@" if host[:user]
|
|
41
|
+
url += "#{host[:host]}:#{host[:port]}"
|
|
42
|
+
url += "#{host[:path]}" if host[:path]
|
|
43
|
+
url += "/#{full_path(path, params)}"
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
# Returns the complete endpoint path with serialized parameters.
|
|
@@ -20,15 +20,14 @@ module Elasticsearch
|
|
|
20
20
|
connection.connection.url = url
|
|
21
21
|
|
|
22
22
|
case method
|
|
23
|
-
when 'HEAD'
|
|
24
|
-
when 'PUT'
|
|
25
|
-
|
|
26
|
-
when 'POST'
|
|
27
|
-
connection.connection.post_body = __convert_to_json(body) if body
|
|
28
|
-
connection.connection.http_post
|
|
23
|
+
when 'HEAD'
|
|
24
|
+
when 'GET', 'POST', 'PUT', 'DELETE'
|
|
25
|
+
connection.connection.put_data = __convert_to_json(body) if body
|
|
29
26
|
else raise ArgumentError, "Unsupported HTTP method: #{method}"
|
|
30
27
|
end
|
|
31
28
|
|
|
29
|
+
connection.connection.http(method.to_sym)
|
|
30
|
+
|
|
32
31
|
Response.new connection.connection.response_code, connection.connection.body_str
|
|
33
32
|
end
|
|
34
33
|
end
|
|
@@ -40,13 +39,19 @@ module Elasticsearch
|
|
|
40
39
|
def __build_connections
|
|
41
40
|
Connections::Collection.new \
|
|
42
41
|
:connections => hosts.map { |host|
|
|
43
|
-
host[:protocol]
|
|
42
|
+
host[:protocol] = host[:scheme] || DEFAULT_PROTOCOL
|
|
44
43
|
host[:port] ||= DEFAULT_PORT
|
|
45
44
|
|
|
46
45
|
client = ::Curl::Easy.new
|
|
47
46
|
client.resolve_mode = :ipv4
|
|
48
|
-
client.headers = {'Content-Type' => 'application/json'}
|
|
49
|
-
client.url =
|
|
47
|
+
client.headers = {'User-Agent' => "Curb #{Curl::CURB_VERSION}", 'Content-Type' => 'application/json' }
|
|
48
|
+
client.url = __full_url(host)
|
|
49
|
+
|
|
50
|
+
if host[:user]
|
|
51
|
+
client.http_auth_types = host[:auth_type] || :basic
|
|
52
|
+
client.username = host[:user]
|
|
53
|
+
client.password = host[:password]
|
|
54
|
+
end
|
|
50
55
|
|
|
51
56
|
client.instance_eval &@block if @block
|
|
52
57
|
|
|
@@ -33,9 +33,9 @@ module Elasticsearch
|
|
|
33
33
|
def __build_connections
|
|
34
34
|
Connections::Collection.new \
|
|
35
35
|
:connections => hosts.map { |host|
|
|
36
|
-
host[:protocol]
|
|
36
|
+
host[:protocol] = host[:scheme] || DEFAULT_PROTOCOL
|
|
37
37
|
host[:port] ||= DEFAULT_PORT
|
|
38
|
-
url =
|
|
38
|
+
url = __full_url(host)
|
|
39
39
|
|
|
40
40
|
Connections::Connection.new \
|
|
41
41
|
:host => host,
|
|
@@ -2,12 +2,13 @@ require 'test_helper'
|
|
|
2
2
|
|
|
3
3
|
class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::IntegrationTestCase
|
|
4
4
|
startup do
|
|
5
|
-
Elasticsearch::
|
|
5
|
+
Elasticsearch::Extensions::Test::Cluster.start if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
context "Elasticsearch client" do
|
|
9
9
|
setup do
|
|
10
|
-
|
|
10
|
+
@port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
|
|
11
|
+
system "curl -X DELETE http://localhost:#{@port}/_all > /dev/null 2>&1"
|
|
11
12
|
|
|
12
13
|
@logger = Logger.new(STDERR)
|
|
13
14
|
@logger.formatter = proc do |severity, datetime, progname, msg|
|
|
@@ -20,7 +21,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
|
20
21
|
ANSI.ansi(severity[0] + ' ', color, :faint) + ANSI.ansi(msg, :white, :faint) + "\n"
|
|
21
22
|
end
|
|
22
23
|
|
|
23
|
-
@client = Elasticsearch::Client.new host:
|
|
24
|
+
@client = Elasticsearch::Client.new host: "localhost:#{@port}"
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
should "connect to the cluster" do
|
|
@@ -32,6 +33,8 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
|
32
33
|
|
|
33
34
|
should "handle paths and URL parameters" do
|
|
34
35
|
@client.perform_request 'PUT', 'myindex/mydoc/1', {routing: 'XYZ'}, {foo: 'bar'}
|
|
36
|
+
@client.perform_request 'GET', '_cluster/health?wait_for_status=green', {}
|
|
37
|
+
|
|
35
38
|
response = @client.perform_request 'GET', 'myindex/mydoc/1?routing=XYZ'
|
|
36
39
|
assert_equal true, response.body['exists']
|
|
37
40
|
assert_equal 'bar', response.body['_source']['foo']
|
|
@@ -45,7 +48,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
|
45
48
|
context "with round robin selector" do
|
|
46
49
|
setup do
|
|
47
50
|
@client = Elasticsearch::Client.new \
|
|
48
|
-
hosts:
|
|
51
|
+
hosts: ["localhost:#{@port}", "localhost:#{@port+1}" ],
|
|
49
52
|
logger: @logger
|
|
50
53
|
end
|
|
51
54
|
|
|
@@ -66,8 +69,9 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
|
66
69
|
|
|
67
70
|
context "with a sick node and retry on failure" do
|
|
68
71
|
setup do
|
|
72
|
+
@port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
|
|
69
73
|
@client = Elasticsearch::Client.new \
|
|
70
|
-
hosts:
|
|
74
|
+
hosts: ["localhost:#{@port}", "foobar1"],
|
|
71
75
|
logger: @logger,
|
|
72
76
|
retry_on_failure: true
|
|
73
77
|
end
|
|
@@ -80,7 +84,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
|
80
84
|
|
|
81
85
|
should "raise exception when it cannot get any healthy server" do
|
|
82
86
|
@client = Elasticsearch::Client.new \
|
|
83
|
-
hosts:
|
|
87
|
+
hosts: ["localhost:#{@port}", "foobar1", "foobar2", "foobar3"],
|
|
84
88
|
logger: @logger,
|
|
85
89
|
retry_on_failure: 1
|
|
86
90
|
|
|
@@ -99,7 +103,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
|
99
103
|
context "with a sick node and reloading on failure" do
|
|
100
104
|
setup do
|
|
101
105
|
@client = Elasticsearch::Client.new \
|
|
102
|
-
hosts:
|
|
106
|
+
hosts: ["localhost:#{@port}", "foobar1", "foobar2"],
|
|
103
107
|
logger: @logger,
|
|
104
108
|
reload_on_failure: true
|
|
105
109
|
end
|
|
@@ -2,16 +2,20 @@ require 'test_helper'
|
|
|
2
2
|
|
|
3
3
|
class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::IntegrationTestCase
|
|
4
4
|
startup do
|
|
5
|
-
Elasticsearch::
|
|
5
|
+
Elasticsearch::Extensions::Test::Cluster.start if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
context "Transport" do
|
|
9
|
+
setup do
|
|
10
|
+
@port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
|
|
11
|
+
end
|
|
12
|
+
|
|
9
13
|
should "allow to customize the Faraday adapter" do
|
|
10
14
|
require 'typhoeus'
|
|
11
15
|
require 'typhoeus/adapters/faraday'
|
|
12
16
|
|
|
13
17
|
transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new \
|
|
14
|
-
:hosts => [ { :host => 'localhost', :port =>
|
|
18
|
+
:hosts => [ { :host => 'localhost', :port => @port } ] do |f|
|
|
15
19
|
f.response :logger
|
|
16
20
|
f.adapter :typhoeus
|
|
17
21
|
end
|
|
@@ -25,7 +29,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
|
25
29
|
require 'elasticsearch/transport/transport/http/curb'
|
|
26
30
|
|
|
27
31
|
transport = Elasticsearch::Transport::Transport::HTTP::Curb.new \
|
|
28
|
-
:hosts => [ { :host => 'localhost', :port =>
|
|
32
|
+
:hosts => [ { :host => 'localhost', :port => @port } ] do |curl|
|
|
29
33
|
curl.verbose = true
|
|
30
34
|
end
|
|
31
35
|
|
|
@@ -2,26 +2,27 @@ require 'test_helper'
|
|
|
2
2
|
|
|
3
3
|
class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::ProfilingTest
|
|
4
4
|
startup do
|
|
5
|
-
Elasticsearch::
|
|
5
|
+
Elasticsearch::Extensions::Test::Cluster.start if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
context "Elasticsearch client benchmark" do
|
|
9
9
|
setup do
|
|
10
|
-
|
|
10
|
+
@port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
|
|
11
|
+
client = Elasticsearch::Client.new host: "localhost:#{@port}"
|
|
11
12
|
client.perform_request 'DELETE', '/ruby_test_benchmark/' rescue nil
|
|
12
13
|
client.perform_request 'POST', '/ruby_test_benchmark/', {index: {number_of_shards: 1, number_of_replicas: 0}}
|
|
13
14
|
100.times do client.perform_request 'POST', '/ruby_test_benchmark_search/test/', {}, {foo: 'bar'}; end
|
|
14
15
|
client.perform_request 'POST', '/ruby_test_benchmark_search/_refresh'
|
|
15
16
|
end
|
|
16
17
|
teardown do
|
|
17
|
-
client = Elasticsearch::Client.new host:
|
|
18
|
+
client = Elasticsearch::Client.new host: "localhost:#{@port}"
|
|
18
19
|
client.perform_request 'DELETE', '/ruby_test_benchmark/'
|
|
19
20
|
client.perform_request 'DELETE', '/ruby_test_benchmark_search/'
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
context "with a single-node cluster" do
|
|
23
24
|
setup do
|
|
24
|
-
@client = Elasticsearch::Client.new hosts:
|
|
25
|
+
@client = Elasticsearch::Client.new hosts: "localhost:#{@port}"
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
measure "get the cluster info", count: 1_000 do
|
|
@@ -39,7 +40,7 @@ class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::Profi
|
|
|
39
40
|
|
|
40
41
|
context "with a two-node cluster" do
|
|
41
42
|
setup do
|
|
42
|
-
@client = Elasticsearch::Client.new hosts: [
|
|
43
|
+
@client = Elasticsearch::Client.new hosts: ["localhost:#{@port}", "localhost:#{@port+1}"]
|
|
43
44
|
end
|
|
44
45
|
|
|
45
46
|
measure "get the cluster info", count: 1_000 do
|
|
@@ -59,7 +60,7 @@ class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::Profi
|
|
|
59
60
|
setup do
|
|
60
61
|
require 'curb'
|
|
61
62
|
require 'elasticsearch/transport/transport/http/curb'
|
|
62
|
-
@client = Elasticsearch::Client.new host:
|
|
63
|
+
@client = Elasticsearch::Client.new host: "localhost:#{@port}",
|
|
63
64
|
transport_class: Elasticsearch::Transport::Transport::HTTP::Curb
|
|
64
65
|
end
|
|
65
66
|
|
|
@@ -82,7 +83,7 @@ class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::Profi
|
|
|
82
83
|
require 'typhoeus/adapters/faraday'
|
|
83
84
|
|
|
84
85
|
transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new \
|
|
85
|
-
:hosts => [ { :host => 'localhost', :port =>
|
|
86
|
+
:hosts => [ { :host => 'localhost', :port => @port } ] do |f|
|
|
86
87
|
f.adapter :typhoeus
|
|
87
88
|
end
|
|
88
89
|
|
data/test/test_helper.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
RUBY_1_8 = defined?(RUBY_VERSION) && RUBY_VERSION < '1.9'
|
|
2
2
|
|
|
3
|
-
if RUBY_1_8
|
|
3
|
+
if RUBY_1_8 and not ENV['BUNDLE_GEMFILE']
|
|
4
4
|
require 'rubygems'
|
|
5
5
|
gem 'test-unit'
|
|
6
6
|
end
|
|
@@ -19,15 +19,16 @@ require 'mocha/setup'
|
|
|
19
19
|
require 'ansi/code'
|
|
20
20
|
require 'turn' unless ENV["TM_FILEPATH"] || ENV["NOTURN"] || RUBY_1_8
|
|
21
21
|
|
|
22
|
-
require 'test_extensions'
|
|
23
|
-
|
|
24
22
|
require 'require-prof' if ENV["REQUIRE_PROF"]
|
|
25
23
|
require 'elasticsearch-transport'
|
|
26
|
-
require 'elasticsearch/transport/extensions/test_cluster'
|
|
27
24
|
require 'logger'
|
|
28
25
|
|
|
29
26
|
RequireProf.print_timing_infos if ENV["REQUIRE_PROF"]
|
|
30
27
|
|
|
28
|
+
require 'elasticsearch/extensions/test/cluster'
|
|
29
|
+
require 'elasticsearch/extensions/test/startup_shutdown'
|
|
30
|
+
require 'elasticsearch/extensions/test/profiling'
|
|
31
|
+
|
|
31
32
|
class Test::Unit::TestCase
|
|
32
33
|
def setup
|
|
33
34
|
end
|
|
@@ -39,19 +40,19 @@ end
|
|
|
39
40
|
module Elasticsearch
|
|
40
41
|
module Test
|
|
41
42
|
class IntegrationTestCase < ::Test::Unit::TestCase
|
|
42
|
-
extend
|
|
43
|
+
extend Elasticsearch::Extensions::Test::StartupShutdown
|
|
43
44
|
|
|
44
|
-
shutdown { Elasticsearch::
|
|
45
|
+
shutdown { Elasticsearch::Extensions::Test::Cluster.stop if ENV['SERVER'] && started? }
|
|
45
46
|
context "IntegrationTest" do; should "noop on Ruby 1.8" do; end; end if RUBY_1_8
|
|
46
47
|
end
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
module Test
|
|
50
51
|
class ProfilingTest < ::Test::Unit::TestCase
|
|
51
|
-
extend
|
|
52
|
-
extend
|
|
52
|
+
extend Elasticsearch::Extensions::Test::StartupShutdown
|
|
53
|
+
extend Elasticsearch::Extensions::Test::Profiling
|
|
53
54
|
|
|
54
|
-
shutdown { Elasticsearch::
|
|
55
|
+
shutdown { Elasticsearch::Extensions::Test::Cluster.stop if ENV['SERVER'] && started? }
|
|
55
56
|
context "IntegrationTest" do; should "noop on Ruby 1.8" do; end; end if RUBY_1_8
|
|
56
57
|
end
|
|
57
58
|
end
|
data/test/unit/client_test.rb
CHANGED
|
@@ -66,30 +66,83 @@ class Elasticsearch::Transport::ClientTest < Test::Unit::TestCase
|
|
|
66
66
|
|
|
67
67
|
context "extracting hosts" do
|
|
68
68
|
should "handle defaults" do
|
|
69
|
-
|
|
69
|
+
hosts = @client.__extract_hosts
|
|
70
|
+
|
|
71
|
+
assert_equal 'localhost', hosts[0][:host]
|
|
72
|
+
assert_nil hosts[0][:port]
|
|
70
73
|
end
|
|
71
74
|
|
|
72
75
|
should "extract from string" do
|
|
73
|
-
|
|
76
|
+
hosts = @client.__extract_hosts 'myhost'
|
|
77
|
+
|
|
78
|
+
assert_equal 'myhost', hosts[0][:host]
|
|
79
|
+
assert_nil hosts[0][:port]
|
|
74
80
|
end
|
|
75
81
|
|
|
76
82
|
should "extract from array" do
|
|
77
|
-
|
|
83
|
+
hosts = @client.__extract_hosts ['myhost']
|
|
84
|
+
|
|
85
|
+
assert_equal 'myhost', hosts[0][:host]
|
|
78
86
|
end
|
|
79
87
|
|
|
80
88
|
should "extract from array with multiple hosts" do
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
hosts = @client.__extract_hosts ['host1', 'host2']
|
|
90
|
+
|
|
91
|
+
assert_equal 'host1', hosts[0][:host]
|
|
92
|
+
assert_equal 'host2', hosts[1][:host]
|
|
83
93
|
end
|
|
84
94
|
|
|
85
95
|
should "extract from array with ports" do
|
|
86
|
-
|
|
87
|
-
|
|
96
|
+
hosts = @client.__extract_hosts ['host1:1000', 'host2:2000']
|
|
97
|
+
|
|
98
|
+
assert_equal 'host1', hosts[0][:host]
|
|
99
|
+
assert_equal '1000', hosts[0][:port]
|
|
100
|
+
|
|
101
|
+
assert_equal 'host2', hosts[1][:host]
|
|
102
|
+
assert_equal '2000', hosts[1][:port]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
should "extract path" do
|
|
106
|
+
hosts = @client.__extract_hosts 'https://myhost:8080/api'
|
|
107
|
+
|
|
108
|
+
assert_equal '/api', hosts[0][:path]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
should "extract scheme (protocol)" do
|
|
112
|
+
hosts = @client.__extract_hosts 'https://myhost:8080'
|
|
113
|
+
|
|
114
|
+
assert_equal 'https', hosts[0][:scheme]
|
|
115
|
+
assert_equal 'myhost', hosts[0][:host]
|
|
116
|
+
assert_equal '8080', hosts[0][:port]
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
should "extract credentials" do
|
|
120
|
+
hosts = @client.__extract_hosts 'http://USERNAME:PASSWORD@myhost:8080'
|
|
121
|
+
|
|
122
|
+
assert_equal 'http', hosts[0][:scheme]
|
|
123
|
+
assert_equal 'USERNAME', hosts[0][:user]
|
|
124
|
+
assert_equal 'PASSWORD', hosts[0][:password]
|
|
125
|
+
assert_equal 'myhost', hosts[0][:host]
|
|
126
|
+
assert_equal '8080', hosts[0][:port]
|
|
88
127
|
end
|
|
89
128
|
|
|
90
129
|
should "pass Hashes over" do
|
|
91
|
-
|
|
92
|
-
|
|
130
|
+
hosts = @client.__extract_hosts [{:host => 'myhost', :port => '1000', :foo => 'bar'}]
|
|
131
|
+
|
|
132
|
+
assert_equal 'myhost', hosts[0][:host]
|
|
133
|
+
assert_equal '1000', hosts[0][:port]
|
|
134
|
+
assert_equal 'bar', hosts[0][:foo]
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
should "use URL instance" do
|
|
138
|
+
require 'uri'
|
|
139
|
+
hosts = @client.__extract_hosts URI.parse('https://USERNAME:PASSWORD@myhost:4430')
|
|
140
|
+
|
|
141
|
+
assert_equal 'https', hosts[0][:scheme]
|
|
142
|
+
assert_equal 'USERNAME', hosts[0][:user]
|
|
143
|
+
assert_equal 'PASSWORD', hosts[0][:password]
|
|
144
|
+
assert_equal 'myhost', hosts[0][:host]
|
|
145
|
+
assert_equal '4430', hosts[0][:port]
|
|
93
146
|
end
|
|
94
147
|
|
|
95
148
|
should "raise error for incompatible argument" do
|
|
@@ -100,7 +153,10 @@ class Elasticsearch::Transport::ClientTest < Test::Unit::TestCase
|
|
|
100
153
|
|
|
101
154
|
should "randomize hosts" do
|
|
102
155
|
hosts = [ {:host => 'host1'}, {:host => 'host2'}, {:host => 'host3'}, {:host => 'host4'}, {:host => 'host5'}]
|
|
103
|
-
|
|
156
|
+
|
|
157
|
+
Array.any_instance.expects(:shuffle!).twice
|
|
158
|
+
|
|
159
|
+
@client.__extract_hosts(hosts, :randomize_hosts => true)
|
|
104
160
|
assert_same_elements hosts, @client.__extract_hosts(hosts, :randomize_hosts => true)
|
|
105
161
|
end
|
|
106
162
|
end
|
|
@@ -25,6 +25,16 @@ class Elasticsearch::Transport::Transport::Connections::ConnectionTest < Test::U
|
|
|
25
25
|
assert_equal 'http://localhost:9200/_search?foo=bar', c.full_url('_search', {:foo => 'bar'})
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
should "return full url with credentials" do
|
|
29
|
+
c = Connection.new :host => { :protocol => 'http', :user => 'U', :password => 'P', :host => 'localhost', :port => '9200' }
|
|
30
|
+
assert_equal 'http://U:P@localhost:9200/_search?foo=bar', c.full_url('_search', {:foo => 'bar'})
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
should "return full url with path" do
|
|
34
|
+
c = Connection.new :host => { :protocol => 'http', :host => 'localhost', :port => '9200', :path => '/foo' }
|
|
35
|
+
assert_equal 'http://localhost:9200/foo/_search?foo=bar', c.full_url('_search', {:foo => 'bar'})
|
|
36
|
+
end
|
|
37
|
+
|
|
28
38
|
should "have a string representation" do
|
|
29
39
|
c = Connection.new :host => 'x'
|
|
30
40
|
assert_match /host: x/, c.to_s
|
data/test/unit/sniffer_test.rb
CHANGED
|
@@ -135,10 +135,9 @@ class Elasticsearch::Transport::Transport::SnifferTest < Test::Unit::TestCase
|
|
|
135
135
|
}
|
|
136
136
|
JSON
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
Array.any_instance.expects(:shuffle!)
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
assert_same_elements ['Node 1', 'Node 2', 'Node 3', 'Node 4', 'Node 5'], hosts.map { |h| h['name'] }
|
|
140
|
+
hosts = @sniffer.hosts
|
|
142
141
|
end
|
|
143
142
|
|
|
144
143
|
end
|
|
@@ -57,6 +57,25 @@ class Elasticsearch::Transport::Transport::BaseTest < Test::Unit::TestCase
|
|
|
57
57
|
transport = DummyTransport.new :options => { :sniffer_class => DummySniffer }
|
|
58
58
|
assert_instance_of DummySniffer, transport.sniffer
|
|
59
59
|
end
|
|
60
|
+
|
|
61
|
+
context "when combining the URL" do
|
|
62
|
+
setup do
|
|
63
|
+
@transport = DummyTransport.new
|
|
64
|
+
@basic_parts = { :protocol => 'http', :host => 'myhost', :port => 8080 }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
should "combine basic parts" do
|
|
68
|
+
assert_equal 'http://myhost:8080', @transport.__full_url(@basic_parts)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
should "combine path" do
|
|
72
|
+
assert_equal 'http://myhost:8080/api', @transport.__full_url(@basic_parts.merge :path => '/api')
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
should "combine authentication credentials" do
|
|
76
|
+
assert_equal 'http://U:P@myhost:8080', @transport.__full_url(@basic_parts.merge :user => 'U', :password => 'P')
|
|
77
|
+
end
|
|
78
|
+
end
|
|
60
79
|
end
|
|
61
80
|
|
|
62
81
|
context "getting a connection" do
|
|
@@ -260,7 +279,9 @@ class Elasticsearch::Transport::Transport::BaseTest < Test::Unit::TestCase
|
|
|
260
279
|
end
|
|
261
280
|
|
|
262
281
|
should "log the request and response" do
|
|
263
|
-
@transport.logger.expects(:info). with
|
|
282
|
+
@transport.logger.expects(:info). with do |line|
|
|
283
|
+
line =~ %r|POST localhost\:9200/_search\?size=1 \[status\:200, request:.*s, query:n/a\]|
|
|
284
|
+
end
|
|
264
285
|
@transport.logger.expects(:debug). with '> {"foo":"bar"}'
|
|
265
286
|
@transport.logger.expects(:debug). with '< {"foo":"bar"}'
|
|
266
287
|
|
|
@@ -14,7 +14,7 @@ class Elasticsearch::Transport::Transport::HTTP::FaradayTest < Test::Unit::TestC
|
|
|
14
14
|
assert_equal 1, @transport.hosts.size
|
|
15
15
|
assert_equal 1, @transport.connections.size
|
|
16
16
|
|
|
17
|
-
assert_instance_of ::Curl::Easy,
|
|
17
|
+
assert_instance_of ::Curl::Easy, @transport.connections.first.connection
|
|
18
18
|
assert_equal 'http://foobar:1234', @transport.connections.first.connection.url
|
|
19
19
|
end
|
|
20
20
|
|
|
@@ -23,23 +23,36 @@ class Elasticsearch::Transport::Transport::HTTP::FaradayTest < Test::Unit::TestC
|
|
|
23
23
|
@transport.perform_request 'GET', '/'
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
should "set body for GET request" do
|
|
27
|
+
@transport.connections.first.connection.expects(:put_data=).with('{"foo":"bar"}')
|
|
28
|
+
@transport.connections.first.connection.expects(:http).with(:GET).returns(stub_everything)
|
|
29
|
+
@transport.perform_request 'GET', '/', {}, '{"foo":"bar"}'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
should "set body for PUT request" do
|
|
33
|
+
@transport.connections.first.connection.expects(:put_data=)
|
|
34
|
+
@transport.connections.first.connection.expects(:http).with(:PUT).returns(stub_everything)
|
|
35
|
+
@transport.perform_request 'PUT', '/', {}, {:foo => 'bar'}
|
|
36
|
+
end
|
|
37
|
+
|
|
26
38
|
should "serialize the request body" do
|
|
27
|
-
@transport.connections.first.connection.expects(:
|
|
39
|
+
@transport.connections.first.connection.expects(:http).with(:POST).returns(stub_everything)
|
|
28
40
|
@transport.serializer.expects(:dump)
|
|
29
41
|
@transport.perform_request 'POST', '/', {}, {:foo => 'bar'}
|
|
30
42
|
end
|
|
31
43
|
|
|
32
44
|
should "not serialize a String request body" do
|
|
33
|
-
@transport.connections.first.connection.expects(:
|
|
45
|
+
@transport.connections.first.connection.expects(:http).with(:POST).returns(stub_everything)
|
|
34
46
|
@transport.serializer.expects(:dump).never
|
|
35
47
|
@transport.perform_request 'POST', '/', {}, '{"foo":"bar"}'
|
|
36
48
|
end
|
|
37
49
|
|
|
38
50
|
should "handle HTTP methods" do
|
|
39
|
-
@transport.connections.first.connection.expects(:http).
|
|
40
|
-
@transport.connections.first.connection.expects(:
|
|
41
|
-
@transport.connections.first.connection.expects(:
|
|
42
|
-
@transport.connections.first.connection.expects(:
|
|
51
|
+
@transport.connections.first.connection.expects(:http).with(:HEAD).returns(stub_everything)
|
|
52
|
+
@transport.connections.first.connection.expects(:http).with(:GET).returns(stub_everything)
|
|
53
|
+
@transport.connections.first.connection.expects(:http).with(:PUT).returns(stub_everything)
|
|
54
|
+
@transport.connections.first.connection.expects(:http).with(:POST).returns(stub_everything)
|
|
55
|
+
@transport.connections.first.connection.expects(:http).with(:DELETE).returns(stub_everything)
|
|
43
56
|
|
|
44
57
|
%w| HEAD GET PUT POST DELETE |.each { |method| @transport.perform_request method, '/' }
|
|
45
58
|
|
|
@@ -54,6 +67,12 @@ class Elasticsearch::Transport::Transport::HTTP::FaradayTest < Test::Unit::TestC
|
|
|
54
67
|
assert_equal( {"Content-Type"=>"application/json", "User-Agent"=>"myapp-0.0"},
|
|
55
68
|
transport.connections.first.connection.headers )
|
|
56
69
|
end
|
|
70
|
+
|
|
71
|
+
should "set the credentials if passed" do
|
|
72
|
+
transport = Curb.new :hosts => [ { :host => 'foobar', :port => 1234, :user => 'foo', :password => 'bar' } ]
|
|
73
|
+
assert_equal 'foo', transport.connections.first.connection.username
|
|
74
|
+
assert_equal 'bar', transport.connections.first.connection.password
|
|
75
|
+
end
|
|
57
76
|
end
|
|
58
77
|
|
|
59
78
|
end
|
|
@@ -17,7 +17,7 @@ class Elasticsearch::Transport::Transport::HTTP::FaradayTest < Test::Unit::TestC
|
|
|
17
17
|
assert_equal 1, @transport.connections.size
|
|
18
18
|
|
|
19
19
|
assert_instance_of ::Faraday::Connection, @transport.connections.first.connection
|
|
20
|
-
assert_equal 'http://foobar:1234/',
|
|
20
|
+
assert_equal 'http://foobar:1234/', @transport.connections.first.connection.url_prefix.to_s
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
should "perform the request" do
|
|
@@ -68,6 +68,11 @@ class Elasticsearch::Transport::Transport::HTTP::FaradayTest < Test::Unit::TestC
|
|
|
68
68
|
handlers = transport.connections.first.connection.instance_variable_get(:@builder).instance_variable_get(:@handlers)
|
|
69
69
|
assert handlers.include?(::Faraday::Response::Logger), "#{handlers.inspect} does not include <::Faraday::Adapter::Typhoeus>"
|
|
70
70
|
end
|
|
71
|
+
|
|
72
|
+
should "set the credentials if passed" do
|
|
73
|
+
transport = Faraday.new :hosts => [ { :host => 'foobar', :port => 1234, :user => 'foo', :password => 'bar' } ]
|
|
74
|
+
assert_equal 'Basic Zm9vOmJhcg==', transport.connections.first.connection.headers['Authorization']
|
|
75
|
+
end
|
|
71
76
|
end
|
|
72
77
|
|
|
73
78
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: elasticsearch-transport
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.2
|
|
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-09
|
|
12
|
+
date: 2013-12-09 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: multi_json
|
|
@@ -75,6 +75,22 @@ dependencies:
|
|
|
75
75
|
- - ! '>='
|
|
76
76
|
- !ruby/object:Gem::Version
|
|
77
77
|
version: '0'
|
|
78
|
+
- !ruby/object:Gem::Dependency
|
|
79
|
+
name: elasticsearch-extensions
|
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
|
81
|
+
none: false
|
|
82
|
+
requirements:
|
|
83
|
+
- - ! '>='
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: '0'
|
|
86
|
+
type: :development
|
|
87
|
+
prerelease: false
|
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
90
|
+
requirements:
|
|
91
|
+
- - ! '>='
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '0'
|
|
78
94
|
- !ruby/object:Gem::Dependency
|
|
79
95
|
name: ansi
|
|
80
96
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -172,7 +188,7 @@ dependencies:
|
|
|
172
188
|
- !ruby/object:Gem::Version
|
|
173
189
|
version: '0'
|
|
174
190
|
- !ruby/object:Gem::Dependency
|
|
175
|
-
name:
|
|
191
|
+
name: pry
|
|
176
192
|
requirement: !ruby/object:Gem::Requirement
|
|
177
193
|
none: false
|
|
178
194
|
requirements:
|
|
@@ -188,7 +204,23 @@ dependencies:
|
|
|
188
204
|
- !ruby/object:Gem::Version
|
|
189
205
|
version: '0'
|
|
190
206
|
- !ruby/object:Gem::Dependency
|
|
191
|
-
name:
|
|
207
|
+
name: ci_reporter
|
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
|
209
|
+
none: false
|
|
210
|
+
requirements:
|
|
211
|
+
- - ! '>='
|
|
212
|
+
- !ruby/object:Gem::Version
|
|
213
|
+
version: '0'
|
|
214
|
+
type: :development
|
|
215
|
+
prerelease: false
|
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
217
|
+
none: false
|
|
218
|
+
requirements:
|
|
219
|
+
- - ! '>='
|
|
220
|
+
- !ruby/object:Gem::Version
|
|
221
|
+
version: '0'
|
|
222
|
+
- !ruby/object:Gem::Dependency
|
|
223
|
+
name: curb
|
|
192
224
|
requirement: !ruby/object:Gem::Requirement
|
|
193
225
|
none: false
|
|
194
226
|
requirements:
|
|
@@ -203,6 +235,22 @@ dependencies:
|
|
|
203
235
|
- - ! '>='
|
|
204
236
|
- !ruby/object:Gem::Version
|
|
205
237
|
version: '0'
|
|
238
|
+
- !ruby/object:Gem::Dependency
|
|
239
|
+
name: typhoeus
|
|
240
|
+
requirement: !ruby/object:Gem::Requirement
|
|
241
|
+
none: false
|
|
242
|
+
requirements:
|
|
243
|
+
- - ~>
|
|
244
|
+
- !ruby/object:Gem::Version
|
|
245
|
+
version: '0.6'
|
|
246
|
+
type: :development
|
|
247
|
+
prerelease: false
|
|
248
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
249
|
+
none: false
|
|
250
|
+
requirements:
|
|
251
|
+
- - ~>
|
|
252
|
+
- !ruby/object:Gem::Version
|
|
253
|
+
version: '0.6'
|
|
206
254
|
- !ruby/object:Gem::Dependency
|
|
207
255
|
name: simplecov
|
|
208
256
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -251,6 +299,22 @@ dependencies:
|
|
|
251
299
|
- - ! '>='
|
|
252
300
|
- !ruby/object:Gem::Version
|
|
253
301
|
version: '0'
|
|
302
|
+
- !ruby/object:Gem::Dependency
|
|
303
|
+
name: coveralls
|
|
304
|
+
requirement: !ruby/object:Gem::Requirement
|
|
305
|
+
none: false
|
|
306
|
+
requirements:
|
|
307
|
+
- - ! '>='
|
|
308
|
+
- !ruby/object:Gem::Version
|
|
309
|
+
version: '0'
|
|
310
|
+
type: :development
|
|
311
|
+
prerelease: false
|
|
312
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
313
|
+
none: false
|
|
314
|
+
requirements:
|
|
315
|
+
- - ! '>='
|
|
316
|
+
- !ruby/object:Gem::Version
|
|
317
|
+
version: '0'
|
|
254
318
|
description: ! 'Ruby client for Elasticsearch. See the `elasticsearch` gem for full
|
|
255
319
|
integration.
|
|
256
320
|
|
|
@@ -272,7 +336,6 @@ files:
|
|
|
272
336
|
- lib/elasticsearch-transport.rb
|
|
273
337
|
- lib/elasticsearch/transport.rb
|
|
274
338
|
- lib/elasticsearch/transport/client.rb
|
|
275
|
-
- lib/elasticsearch/transport/extensions/test_cluster.rb
|
|
276
339
|
- lib/elasticsearch/transport/transport/base.rb
|
|
277
340
|
- lib/elasticsearch/transport/transport/connections/collection.rb
|
|
278
341
|
- lib/elasticsearch/transport/transport/connections/connection.rb
|
|
@@ -287,7 +350,6 @@ files:
|
|
|
287
350
|
- test/integration/client_test.rb
|
|
288
351
|
- test/integration/transport_test.rb
|
|
289
352
|
- test/profile/client_benchmark_test.rb
|
|
290
|
-
- test/test_extensions.rb
|
|
291
353
|
- test/test_helper.rb
|
|
292
354
|
- test/unit/client_test.rb
|
|
293
355
|
- test/unit/connection_collection_test.rb
|
|
@@ -328,7 +390,6 @@ test_files:
|
|
|
328
390
|
- test/integration/client_test.rb
|
|
329
391
|
- test/integration/transport_test.rb
|
|
330
392
|
- test/profile/client_benchmark_test.rb
|
|
331
|
-
- test/test_extensions.rb
|
|
332
393
|
- test/test_helper.rb
|
|
333
394
|
- test/unit/client_test.rb
|
|
334
395
|
- test/unit/connection_collection_test.rb
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
require 'ansi/code'
|
|
2
|
-
|
|
3
|
-
module Elasticsearch
|
|
4
|
-
|
|
5
|
-
# A convenience Ruby class for starting and stopping a separate testing cluster,
|
|
6
|
-
# to not depend on -- and not mess up -- <localhost:9200>.
|
|
7
|
-
#
|
|
8
|
-
module TestCluster
|
|
9
|
-
require 'timeout'
|
|
10
|
-
require 'net/http'
|
|
11
|
-
require 'uri'
|
|
12
|
-
|
|
13
|
-
@@number_of_nodes = 2
|
|
14
|
-
@@pids = []
|
|
15
|
-
|
|
16
|
-
# Start a cluster
|
|
17
|
-
#
|
|
18
|
-
# Starts the desired number of nodes in test-suitable configuration (memory store, no persistence, etc).
|
|
19
|
-
#
|
|
20
|
-
# @option arguments [String] :command Elasticsearch command (default: `elasticsearch`).
|
|
21
|
-
# @option arguments [Integer] :count Number of desired nodes (default: 2).
|
|
22
|
-
# @option arguments [String] :cluster_name Cluster name (default: `elasticsearch-ruby-test`).
|
|
23
|
-
# @option arguments [String] :port Starting port number; will be auto-incremented (default: 9250).
|
|
24
|
-
#
|
|
25
|
-
# You can also use environment variables to set these options.
|
|
26
|
-
#
|
|
27
|
-
def start(arguments={})
|
|
28
|
-
arguments[:command] = ENV['TEST_CLUSTER_COMMAND'] || 'elasticsearch'
|
|
29
|
-
|
|
30
|
-
unless system "which #{arguments[:command]} > /dev/null 2>&1"
|
|
31
|
-
STDERR.puts ANSI.red("[ERROR] Elasticsearch can't be started, is it installed? Run: $ which elasticsearch"), ''
|
|
32
|
-
abort
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
@@number_of_nodes = arguments[:count] if arguments[:count]
|
|
36
|
-
|
|
37
|
-
arguments[:port] = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
|
|
38
|
-
arguments[:cluster_name] = ENV['TEST_CLUSTER_NAME'] || 'elasticsearch-ruby-test'
|
|
39
|
-
arguments[:node_name] = 'node'
|
|
40
|
-
|
|
41
|
-
if running? :on => arguments[:port], :as => arguments[:cluster_name]
|
|
42
|
-
print ANSI.red("Elasticsearch cluster already running")
|
|
43
|
-
__wait_for_green(arguments[:port])
|
|
44
|
-
exit(0)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
print ANSI.faint("Starting ") + ANSI.ansi(@@number_of_nodes.to_s, :bold, :faint) + ANSI.faint(" Elasticsearch nodes")
|
|
48
|
-
|
|
49
|
-
@@number_of_nodes.times do |n|
|
|
50
|
-
n += 1
|
|
51
|
-
pidfile = File.expand_path("tmp/elasticsearch-#{n}.pid", Dir.pwd)
|
|
52
|
-
pid = Process.spawn <<-COMMAND
|
|
53
|
-
#{arguments[:command]} \
|
|
54
|
-
-D es.foreground=yes \
|
|
55
|
-
-D es.cluster.name=#{arguments[:cluster_name]} \
|
|
56
|
-
-D es.node.name=#{arguments[:node_name]}-#{n} \
|
|
57
|
-
-D es.http.port=#{arguments[:port].to_i + (n-1)} \
|
|
58
|
-
-D es.gateway.type=none \
|
|
59
|
-
-D es.index.store.type=memory \
|
|
60
|
-
-D es.network.host=0.0.0.0 \
|
|
61
|
-
-D es.discovery.zen.ping.multicast.enabled=true \
|
|
62
|
-
-D es.pidfile=#{pidfile} \
|
|
63
|
-
> /dev/null 2>&1
|
|
64
|
-
COMMAND
|
|
65
|
-
Process.detach pid
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
__wait_for_green(arguments[:port])
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# Stop the cluster.
|
|
72
|
-
#
|
|
73
|
-
# Gets the PID numbers from pidfiles in `$CWD/tmp` and stops any matching nodes.
|
|
74
|
-
#
|
|
75
|
-
def stop
|
|
76
|
-
pids = __get_pids
|
|
77
|
-
pidfiles = __get_pidfiles
|
|
78
|
-
|
|
79
|
-
unless pids.empty?
|
|
80
|
-
print "Stopping Elasticsearch nodes... "
|
|
81
|
-
pids.each_with_index do |pid, i|
|
|
82
|
-
begin
|
|
83
|
-
print ANSI.green("stopped PID #{pid}. ") if Process.kill 'KILL', pid
|
|
84
|
-
rescue Exception => e
|
|
85
|
-
print ANSI.red("[#{e.class}] PID #{pid} not found. ")
|
|
86
|
-
end
|
|
87
|
-
File.delete pidfiles[i] if pidfiles[i] && File.exists?(pidfiles[i])
|
|
88
|
-
end
|
|
89
|
-
puts
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Returns true when a specific test node is running.
|
|
94
|
-
#
|
|
95
|
-
# @option arguments [Integer] :on The port on which the node is running.
|
|
96
|
-
# @option arguments [String] :as The cluster name.
|
|
97
|
-
#
|
|
98
|
-
def running?(arguments={})
|
|
99
|
-
port = arguments[:on] || 9250
|
|
100
|
-
cluster_name = arguments[:as] || 'elasticsearch-ruby-test'
|
|
101
|
-
|
|
102
|
-
if cluster_health = Timeout::timeout(0.25) { __get_cluster_health(port) } rescue nil
|
|
103
|
-
return cluster_health['cluster_name'] == cluster_name && \
|
|
104
|
-
cluster_health['number_of_nodes'] == @@number_of_nodes
|
|
105
|
-
end
|
|
106
|
-
return false
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# Blocks the process and waits for the cluster to be in a "green" state.
|
|
110
|
-
# Prints information about the cluster on STDOUT.
|
|
111
|
-
#
|
|
112
|
-
def __wait_for_green(port=9250)
|
|
113
|
-
uri = URI("http://localhost:#{port}/_cluster/health")
|
|
114
|
-
|
|
115
|
-
Timeout::timeout(30) do
|
|
116
|
-
loop do
|
|
117
|
-
response = Net::HTTP.get(uri) rescue nil
|
|
118
|
-
if response
|
|
119
|
-
pids = __get_pids
|
|
120
|
-
|
|
121
|
-
json = MultiJson.load(response)
|
|
122
|
-
if json['status'] == 'green' && json['number_of_nodes'].to_i == @@number_of_nodes
|
|
123
|
-
puts '',
|
|
124
|
-
ANSI.faint('-'*80),
|
|
125
|
-
ANSI.faint(
|
|
126
|
-
'Cluster: '.ljust(20) + json['cluster_name'].to_s + "\n" +
|
|
127
|
-
'Status: '.ljust(20) + json['status'].to_s + "\n" +
|
|
128
|
-
'Number of nodes: '.ljust(20) + json['number_of_nodes'].to_s + "\n" +
|
|
129
|
-
'PIDs'.ljust(20) + pids.inspect
|
|
130
|
-
),
|
|
131
|
-
ANSI.faint('-'*80)
|
|
132
|
-
break
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
print ANSI.faint('.')
|
|
136
|
-
sleep 1
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
# Tries to load cluster health information
|
|
142
|
-
#
|
|
143
|
-
def __get_cluster_health(port=9250)
|
|
144
|
-
uri = URI("http://localhost:#{port}/_cluster/health")
|
|
145
|
-
if response = Net::HTTP.get(uri) rescue nil
|
|
146
|
-
return MultiJson.load(response)
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
# Returns a collection of PID numbers from pidfiles.
|
|
151
|
-
def __get_pids
|
|
152
|
-
__get_pidfiles.map { |pidfile| File.read(pidfile).to_i }.uniq
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
# Returns a collection of files with PID information.
|
|
156
|
-
#
|
|
157
|
-
def __get_pidfiles
|
|
158
|
-
Dir[File.expand_path('tmp/elasticsearch-*.pid', Dir.pwd)]
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
extend self
|
|
162
|
-
end
|
|
163
|
-
end
|
data/test/test_extensions.rb
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
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
|