elasticsearch-transport 7.1.0 → 7.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +12 -8
  3. data/{LICENSE.txt → LICENSE} +0 -0
  4. data/README.md +160 -72
  5. data/Rakefile +1 -1
  6. data/elasticsearch-transport.gemspec +42 -60
  7. data/lib/elasticsearch/transport/client.rb +70 -19
  8. data/lib/elasticsearch/transport/redacted.rb +1 -1
  9. data/lib/elasticsearch/transport/transport/base.rb +86 -12
  10. data/lib/elasticsearch/transport/transport/connections/collection.rb +1 -1
  11. data/lib/elasticsearch/transport/transport/connections/connection.rb +1 -1
  12. data/lib/elasticsearch/transport/transport/connections/selector.rb +18 -6
  13. data/lib/elasticsearch/transport/transport/errors.rb +1 -1
  14. data/lib/elasticsearch/transport/transport/http/curb.rb +26 -9
  15. data/lib/elasticsearch/transport/transport/http/faraday.rb +18 -4
  16. data/lib/elasticsearch/transport/transport/http/manticore.rb +25 -10
  17. data/lib/elasticsearch/transport/transport/loggable.rb +1 -1
  18. data/lib/elasticsearch/transport/transport/response.rb +1 -2
  19. data/lib/elasticsearch/transport/transport/serializer/multi_json.rb +1 -1
  20. data/lib/elasticsearch/transport/transport/sniffer.rb +3 -2
  21. data/lib/elasticsearch/transport/version.rb +2 -2
  22. data/lib/elasticsearch/transport.rb +1 -1
  23. data/lib/elasticsearch-transport.rb +1 -1
  24. data/spec/elasticsearch/connections/collection_spec.rb +254 -0
  25. data/spec/elasticsearch/connections/selector_spec.rb +174 -0
  26. data/spec/elasticsearch/transport/base_spec.rb +177 -9
  27. data/spec/elasticsearch/transport/client_spec.rb +525 -29
  28. data/spec/elasticsearch/transport/sniffer_spec.rb +1 -1
  29. data/spec/spec_helper.rb +25 -1
  30. data/test/integration/transport_test.rb +1 -1
  31. data/test/profile/client_benchmark_test.rb +1 -1
  32. data/test/test_helper.rb +1 -1
  33. data/test/unit/connection_test.rb +1 -1
  34. data/test/unit/response_test.rb +2 -2
  35. data/test/unit/serializer_test.rb +1 -1
  36. data/test/unit/transport_base_test.rb +1 -1
  37. data/test/unit/transport_curb_test.rb +2 -2
  38. data/test/unit/transport_faraday_test.rb +1 -1
  39. data/test/unit/transport_manticore_test.rb +28 -12
  40. metadata +85 -61
  41. data/test/unit/connection_collection_test.rb +0 -147
  42. data/test/unit/connection_selector_test.rb +0 -81
@@ -6,7 +6,7 @@
6
6
  # not use this file except in compliance with the License.
7
7
  # You may obtain a copy of the License at
8
8
  #
9
- # http://www.apache.org/licenses/LICENSE-2.0
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
10
  #
11
11
  # Unless required by applicable law or agreed to in writing,
12
12
  # software distributed under the License is distributed on an
@@ -18,7 +18,6 @@
18
18
  require 'spec_helper'
19
19
 
20
20
  describe Elasticsearch::Transport::Client do
21
-
22
21
  let(:client) do
23
22
  described_class.new.tap do |_client|
24
23
  allow(_client).to receive(:__build_connections)
@@ -33,35 +32,231 @@ describe Elasticsearch::Transport::Client do
33
32
  expect(client.transport).to be_a(Elasticsearch::Transport::Client::DEFAULT_TRANSPORT_CLASS)
34
33
  end
35
34
 
36
- it 'uses Faraday as the default transport' do
35
+ it 'preserves the Faraday default user agent header' do
37
36
  expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/Faraday/)
38
37
  end
39
38
 
39
+ it 'identifies the Ruby client in the User-Agent header' do
40
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/elasticsearch-ruby\/#{Elasticsearch::Transport::VERSION}/)
41
+ end
42
+
43
+ it 'identifies the Ruby version in the User-Agent header' do
44
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RUBY_VERSION}/)
45
+ end
46
+
47
+ it 'identifies the host_os in the User-Agent header' do
48
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase}/)
49
+ end
50
+
51
+ it 'identifies the target_cpu in the User-Agent header' do
52
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RbConfig::CONFIG['target_cpu']}/)
53
+ end
54
+
40
55
  it 'sets the \'Content-Type\' header to \'application/json\' by default' do
41
- expect(client.transport.options[:transport_options][:headers]['Content-Type']).to eq('application/json')
56
+ expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('application/json')
42
57
  end
43
58
 
44
59
  it 'uses localhost by default' do
45
60
  expect(client.transport.hosts[0][:host]).to eq('localhost')
46
61
  end
47
62
 
48
- describe 'adapter' do
63
+ context 'when a User-Agent header is specified as client option' do
64
+ let(:client) do
65
+ described_class.new(transport_options: { headers: { 'User-Agent' => 'testing' } })
66
+ end
49
67
 
50
- context 'when no adapter is specified' do
68
+ it 'sets the specified User-Agent header' do
69
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to eq('testing')
70
+ end
71
+ end
72
+
73
+ context 'when an encoded api_key is provided' do
74
+ let(:client) do
75
+ described_class.new(api_key: 'an_api_key')
76
+ end
77
+ let(:authorization_header) do
78
+ client.transport.connections.first.connection.headers['Authorization']
79
+ end
80
+
81
+ it 'Adds the ApiKey header to the connection' do
82
+ expect(authorization_header).to eq('ApiKey an_api_key')
83
+ end
84
+ end
85
+
86
+ context 'when an un-encoded api_key is provided' do
87
+ let(:client) do
88
+ described_class.new(api_key: { id: 'my_id', api_key: 'my_api_key' })
89
+ end
90
+ let(:authorization_header) do
91
+ client.transport.connections.first.connection.headers['Authorization']
92
+ end
93
+
94
+ it 'Adds the ApiKey header to the connection' do
95
+ expect(authorization_header).to eq("ApiKey #{Base64.strict_encode64('my_id:my_api_key')}")
96
+ end
97
+ end
98
+
99
+ context 'when basic auth and api_key are provided' do
100
+ let(:client) do
101
+ described_class.new(
102
+ api_key: { id: 'my_id', api_key: 'my_api_key' },
103
+ host: 'http://elastic:password@localhost:9200'
104
+ )
105
+ end
106
+ let(:authorization_header) do
107
+ client.transport.connections.first.connection.headers['Authorization']
108
+ end
109
+
110
+ it 'removes basic auth credentials' do
111
+ expect(authorization_header).not_to match(/^Basic/)
112
+ expect(authorization_header).to match(/^ApiKey/)
113
+ end
114
+ end
115
+
116
+ context 'when a user-agent header is specified as client option in lower-case' do
117
+
118
+ let(:client) do
119
+ described_class.new(transport_options: { headers: { 'user-agent' => 'testing' } })
120
+ end
121
+
122
+ it 'sets the specified User-Agent header' do
123
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to eq('testing')
124
+ end
125
+ end
126
+
127
+ context 'when a Content-Type header is specified as client option' do
128
+
129
+ let(:client) do
130
+ described_class.new(transport_options: { headers: { 'Content-Type' => 'testing' } })
131
+ end
132
+
133
+ it 'sets the specified Content-Type header' do
134
+ expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('testing')
135
+ end
136
+ end
137
+
138
+ context 'when a content-type header is specified as client option in lower-case' do
139
+
140
+ let(:client) do
141
+ described_class.new(transport_options: { headers: { 'content-type' => 'testing' } })
142
+ end
143
+
144
+ it 'sets the specified Content-Type header' do
145
+ expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('testing')
146
+ end
147
+ end
148
+
149
+ context 'when the Curb transport class is used', unless: jruby? do
150
+
151
+ let(:client) do
152
+ described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb)
153
+ end
154
+
155
+ it 'preserves the Curb default user agent header' do
156
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/Curb/)
157
+ end
158
+
159
+ it 'identifies the Ruby client in the User-Agent header' do
160
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/elasticsearch-ruby\/#{Elasticsearch::Transport::VERSION}/)
161
+ end
162
+
163
+ it 'identifies the Ruby version in the User-Agent header' do
164
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RUBY_VERSION}/)
165
+ end
166
+
167
+ it 'identifies the host_os in the User-Agent header' do
168
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase}/)
169
+ end
170
+
171
+ it 'identifies the target_cpu in the User-Agent header' do
172
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to match(/#{RbConfig::CONFIG['target_cpu']}/)
173
+ end
51
174
 
175
+ it 'sets the \'Content-Type\' header to \'application/json\' by default' do
176
+ expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('application/json')
177
+ end
178
+
179
+ it 'uses localhost by default' do
180
+ expect(client.transport.hosts[0][:host]).to eq('localhost')
181
+ end
182
+
183
+ context 'when a User-Agent header is specified as a client option' do
184
+
185
+ let(:client) do
186
+ described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb,
187
+ transport_options: { headers: { 'User-Agent' => 'testing' } })
188
+ end
189
+
190
+ it 'sets the specified User-Agent header' do
191
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to eq('testing')
192
+ end
193
+ end
194
+
195
+ context 'when a user-agent header is specified as a client option as lower-case' do
196
+
197
+ let(:client) do
198
+ described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb,
199
+ transport_options: { headers: { 'user-agent' => 'testing' } })
200
+ end
201
+
202
+ it 'sets the specified User-Agent header' do
203
+ expect(client.transport.connections.first.connection.headers['User-Agent']).to eq('testing')
204
+ end
205
+ end
206
+
207
+ context 'when a Content-Type header is specified as client option' do
208
+
209
+ let(:client) do
210
+ described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb,
211
+ transport_options: { headers: { 'Content-Type' => 'testing' } })
212
+ end
213
+
214
+ it 'sets the specified Content-Type header' do
215
+ expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('testing')
216
+ end
217
+ end
218
+
219
+ context 'when a content-type header is specified as client option in lower-case' do
220
+
221
+ let(:client) do
222
+ described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb,
223
+ transport_options: { headers: { 'content-type' => 'testing' } })
224
+ end
225
+
226
+ it 'sets the specified Content-Type header' do
227
+ expect(client.transport.connections.first.connection.headers['Content-Type']).to eq('testing')
228
+ end
229
+ end
230
+ end
231
+
232
+ describe 'adapter' do
233
+ context 'when no adapter is specified' do
52
234
  let(:adapter) do
53
- client.transport.connections.all.first.connection.builder.handlers
235
+ client.transport.connections.all.first.connection.builder.adapter
54
236
  end
55
237
 
56
238
  it 'uses Faraday NetHttp' do
57
- expect(adapter).to include(Faraday::Adapter::NetHttp)
239
+ expect(adapter).to eq Faraday::Adapter::NetHttp
58
240
  end
59
241
  end
60
242
 
61
- context 'when the adapter is specified' do
243
+ context 'when the adapter is patron' do
244
+ let(:adapter) do
245
+ client.transport.connections.all.first.connection.builder.adapter
246
+ end
247
+
248
+ let(:client) do
249
+ described_class.new(adapter: :patron)
250
+ end
251
+
252
+ it 'uses Faraday with the adapter' do
253
+ expect(adapter).to eq Faraday::Adapter::Patron
254
+ end
255
+ end
62
256
 
257
+ context 'when the adapter is typhoeus' do
63
258
  let(:adapter) do
64
- client.transport.connections.all.first.connection.builder.handlers
259
+ client.transport.connections.all.first.connection.builder.adapter
65
260
  end
66
261
 
67
262
  let(:client) do
@@ -69,22 +264,21 @@ describe Elasticsearch::Transport::Client do
69
264
  end
70
265
 
71
266
  it 'uses Faraday with the adapter' do
72
- expect(adapter).to include(Faraday::Adapter::Typhoeus)
267
+ expect(adapter).to eq Faraday::Adapter::Typhoeus
73
268
  end
74
269
  end
75
270
 
76
271
  context 'when the adapter is specified as a string key' do
77
-
78
272
  let(:adapter) do
79
- client.transport.connections.all.first.connection.builder.handlers
273
+ client.transport.connections.all.first.connection.builder.adapter
80
274
  end
81
275
 
82
276
  let(:client) do
83
- described_class.new('adapter' => :typhoeus)
277
+ described_class.new('adapter' => :patron)
84
278
  end
85
279
 
86
280
  it 'uses Faraday with the adapter' do
87
- expect(adapter).to include(Faraday::Adapter::Typhoeus)
281
+ expect(adapter).to eq Faraday::Adapter::Patron
88
282
  end
89
283
  end
90
284
 
@@ -96,11 +290,11 @@ describe Elasticsearch::Transport::Client do
96
290
  end
97
291
 
98
292
  let(:adapter) do
99
- client.transport.connections.all.first.connection.builder.handlers
293
+ client.transport.connections.all.first.connection.builder.adapter
100
294
  end
101
295
 
102
296
  it 'uses the detected adapter' do
103
- expect(adapter).to include(Faraday::Adapter::Patron)
297
+ expect(adapter).to eq Faraday::Adapter::Patron
104
298
  end
105
299
  end
106
300
 
@@ -108,17 +302,21 @@ describe Elasticsearch::Transport::Client do
108
302
 
109
303
  let(:client) do
110
304
  described_class.new do |faraday|
111
- faraday.adapter :typhoeus
305
+ faraday.adapter :patron
112
306
  faraday.response :logger
113
307
  end
114
308
  end
115
309
 
310
+ let(:adapter) do
311
+ client.transport.connections.all.first.connection.builder.adapter
312
+ end
313
+
116
314
  let(:handlers) do
117
315
  client.transport.connections.all.first.connection.builder.handlers
118
316
  end
119
317
 
120
318
  it 'sets the adapter' do
121
- expect(handlers).to include(Faraday::Adapter::Typhoeus)
319
+ expect(adapter).to eq Faraday::Adapter::Patron
122
320
  end
123
321
 
124
322
  it 'sets the logger' do
@@ -127,6 +325,72 @@ describe Elasticsearch::Transport::Client do
127
325
  end
128
326
  end
129
327
 
328
+ context 'when cloud credentials are provided' do
329
+
330
+ let(:client) do
331
+ described_class.new(cloud_id: 'name:bG9jYWxob3N0JGFiY2QkZWZnaA==', user: 'elastic', password: 'changeme')
332
+ end
333
+
334
+ let(:hosts) do
335
+ client.transport.hosts
336
+ end
337
+
338
+ it 'extracts the cloud credentials' do
339
+ expect(hosts[0][:host]).to eq('abcd.localhost')
340
+ expect(hosts[0][:protocol]).to eq('https')
341
+ expect(hosts[0][:user]).to eq('elastic')
342
+ expect(hosts[0][:password]).to eq('changeme')
343
+ expect(hosts[0][:port]).to eq(9243)
344
+ end
345
+
346
+ it 'creates the correct full url' do
347
+ expect(client.transport.__full_url(client.transport.hosts[0])).to eq('https://elastic:changeme@abcd.localhost:9243')
348
+ end
349
+
350
+ context 'when a port is specified' do
351
+
352
+ let(:client) do
353
+ described_class.new(cloud_id: 'name:bG9jYWxob3N0JGFiY2QkZWZnaA==', user: 'elastic', password: 'changeme', port: 9200 )
354
+ end
355
+
356
+ it 'sets the specified port along with the cloud credentials' do
357
+ expect(hosts[0][:host]).to eq('abcd.localhost')
358
+ expect(hosts[0][:protocol]).to eq('https')
359
+ expect(hosts[0][:user]).to eq('elastic')
360
+ expect(hosts[0][:password]).to eq('changeme')
361
+ expect(hosts[0][:port]).to eq(9200)
362
+ end
363
+
364
+ it 'creates the correct full url' do
365
+ expect(client.transport.__full_url(client.transport.hosts[0])).to eq('https://elastic:changeme@abcd.localhost:9200')
366
+ end
367
+ end
368
+
369
+ context 'when the cluster has alternate names' do
370
+
371
+ let(:client) do
372
+ described_class.new(cloud_id: 'myCluster:bG9jYWxob3N0JGFiY2QkZWZnaA==', user: 'elasticfantastic', password: 'tobechanged')
373
+ end
374
+
375
+ let(:hosts) do
376
+ client.transport.hosts
377
+ end
378
+
379
+ it 'extracts the cloud credentials' do
380
+ expect(hosts[0][:host]).to eq('abcd.localhost')
381
+ expect(hosts[0][:protocol]).to eq('https')
382
+ expect(hosts[0][:user]).to eq('elasticfantastic')
383
+ expect(hosts[0][:password]).to eq('tobechanged')
384
+ expect(hosts[0][:port]).to eq(9243)
385
+ end
386
+
387
+ it 'creates the correct full url' do
388
+ expect(client.transport.__full_url(client.transport.hosts[0])).to eq('https://elasticfantastic:tobechanged@abcd.localhost:9243')
389
+ end
390
+
391
+ end
392
+ end
393
+
130
394
  shared_examples_for 'a client that extracts hosts' do
131
395
 
132
396
  context 'when the hosts are a String' do
@@ -859,10 +1123,81 @@ describe Elasticsearch::Transport::Client do
859
1123
  expect(request).to be(true)
860
1124
  end
861
1125
  end
1126
+
1127
+ context 'when x-opaque-id is set' do
1128
+ let(:client) { described_class.new(host: hosts) }
1129
+
1130
+ it 'uses x-opaque-id on a request' do
1131
+ expect(client.perform_request('GET', '/', { opaque_id: '12345' }).headers['x-opaque-id']).to eq('12345')
1132
+ end
1133
+ end
1134
+
1135
+ context 'when an x-opaque-id prefix is set on initialization' do
1136
+ let(:prefix) { 'elastic_cloud' }
1137
+ let(:client) do
1138
+ described_class.new(host: hosts, opaque_id_prefix: prefix)
1139
+ end
1140
+
1141
+ it 'uses x-opaque-id on a request' do
1142
+ expect(client.perform_request('GET', '/', { opaque_id: '12345' }).headers['x-opaque-id']).to eq("#{prefix}12345")
1143
+ end
1144
+
1145
+ context 'when using an API call' do
1146
+ let(:client) { described_class.new(host: hosts) }
1147
+
1148
+ it 'doesnae raise an ArgumentError' do
1149
+ expect { client.search(opaque_id: 'no_error') }.not_to raise_error
1150
+ end
1151
+
1152
+ it 'uses X-Opaque-Id in the header' do
1153
+ allow(client).to receive(:perform_request) { OpenStruct.new(body: '') }
1154
+ expect { client.search(opaque_id: 'opaque_id') }.not_to raise_error
1155
+ expect(client).to have_received(:perform_request)
1156
+ .with('GET', '_search', { opaque_id: 'opaque_id' }, nil, {})
1157
+ end
1158
+ end
1159
+ end
1160
+
1161
+ context 'when Elasticsearch response includes a warning header' do
1162
+ let(:client) do
1163
+ Elasticsearch::Transport::Client.new(hosts: hosts)
1164
+ end
1165
+
1166
+ let(:warning) { 'Elasticsearch warning: "deprecation warning"' }
1167
+
1168
+ it 'prints a warning' do
1169
+ allow_any_instance_of(Elasticsearch::Transport::Transport::Response).to receive(:headers) do
1170
+ { 'warning' => warning }
1171
+ end
1172
+
1173
+ begin
1174
+ stderr = $stderr
1175
+ fake_stderr = StringIO.new
1176
+ $stderr = fake_stderr
1177
+
1178
+ client.perform_request('GET', '/')
1179
+ fake_stderr.rewind
1180
+ expect(fake_stderr.string).to eq("warning: #{warning}\n")
1181
+ ensure
1182
+ $stderr = stderr
1183
+ end
1184
+ end
1185
+ end
1186
+
1187
+ context 'when a header is set on an endpoint request' do
1188
+ let(:client) { described_class.new(host: hosts) }
1189
+ let(:headers) { { 'user-agent' => 'my ruby app' } }
1190
+
1191
+ it 'performs the request with the header' do
1192
+ allow(client).to receive(:perform_request) { OpenStruct.new(body: '') }
1193
+ expect { client.search(headers: headers) }.not_to raise_error
1194
+ expect(client).to have_received(:perform_request)
1195
+ .with('GET', '_search', {}, nil, headers)
1196
+ end
1197
+ end
862
1198
  end
863
1199
 
864
1200
  context 'when the client connects to Elasticsearch' do
865
-
866
1201
  let(:logger) do
867
1202
  Logger.new(STDERR).tap do |logger|
868
1203
  logger.formatter = proc do |severity, datetime, progname, msg|
@@ -940,15 +1275,14 @@ describe Elasticsearch::Transport::Client do
940
1275
  end
941
1276
 
942
1277
  context 'when the Faraday adapter is set in the block' do
943
-
944
1278
  let(:client) do
945
1279
  Elasticsearch::Client.new(host: ELASTICSEARCH_HOSTS.first, logger: logger) do |client|
946
1280
  client.adapter(:net_http_persistent)
947
1281
  end
948
1282
  end
949
1283
 
950
- let(:connection_handler) do
951
- client.transport.connections.first.connection.builder.handlers.first
1284
+ let(:handler_name) do
1285
+ client.transport.connections.first.connection.builder.adapter.name
952
1286
  end
953
1287
 
954
1288
  let(:response) do
@@ -956,7 +1290,7 @@ describe Elasticsearch::Transport::Client do
956
1290
  end
957
1291
 
958
1292
  it 'sets the adapter' do
959
- expect(connection_handler.name).to eq('Faraday::Adapter::NetHttpPersistent')
1293
+ expect(handler_name).to eq('Faraday::Adapter::NetHttpPersistent')
960
1294
  end
961
1295
 
962
1296
  it 'uses the adapter to connect' do
@@ -1006,7 +1340,7 @@ describe Elasticsearch::Transport::Client do
1006
1340
  expect(client.perform_request('GET', '_nodes/_local'))
1007
1341
  expect {
1008
1342
  client.perform_request('GET', '_nodes/_local')
1009
- }.to raise_exception(Faraday::Error::ConnectionFailed)
1343
+ }.to raise_exception(Faraday::ConnectionFailed)
1010
1344
  end
1011
1345
  end
1012
1346
 
@@ -1053,6 +1387,141 @@ describe Elasticsearch::Transport::Client do
1053
1387
  }.to raise_exception(Elasticsearch::Transport::Transport::Errors::BadRequest)
1054
1388
  end
1055
1389
  end
1390
+
1391
+ context 'when the \'compression\' option is set to true' do
1392
+
1393
+ context 'when using Faraday as the transport' do
1394
+
1395
+ context 'when using the Net::HTTP adapter' do
1396
+
1397
+ let(:client) do
1398
+ described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :net_http)
1399
+ end
1400
+
1401
+ it 'compresses the request and decompresses the response' do
1402
+ expect(client.perform_request('GET', '/').body).to be_a(Hash)
1403
+ end
1404
+
1405
+ it 'sets the Accept-Encoding header' do
1406
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1407
+ end
1408
+
1409
+ it 'preserves the other headers' do
1410
+ expect(client.transport.connections[0].connection.headers['User-Agent'])
1411
+ end
1412
+ end
1413
+
1414
+ context 'when using the HTTPClient adapter' do
1415
+
1416
+ let(:client) do
1417
+ described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :httpclient)
1418
+ end
1419
+
1420
+ it 'compresses the request and decompresses the response' do
1421
+ expect(client.perform_request('GET', '/').body).to be_a(Hash)
1422
+ end
1423
+
1424
+ it 'sets the Accept-Encoding header' do
1425
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1426
+ end
1427
+
1428
+ it 'preserves the other headers' do
1429
+ expect(client.transport.connections[0].connection.headers['User-Agent'])
1430
+ end
1431
+ end
1432
+
1433
+ context 'when using the Patron adapter', unless: jruby? do
1434
+
1435
+ let(:client) do
1436
+ described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :patron)
1437
+ end
1438
+
1439
+ it 'compresses the request and decompresses the response' do
1440
+ expect(client.perform_request('GET', '/').body).to be_a(Hash)
1441
+ end
1442
+
1443
+ it 'sets the Accept-Encoding header' do
1444
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1445
+ end
1446
+
1447
+ it 'preserves the other headers' do
1448
+ expect(client.transport.connections[0].connection.headers['User-Agent'])
1449
+ end
1450
+ end
1451
+
1452
+ context 'when using the Net::HTTP::Persistent adapter' do
1453
+
1454
+ let(:client) do
1455
+ described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :net_http_persistent)
1456
+ end
1457
+
1458
+ it 'compresses the request and decompresses the response' do
1459
+ expect(client.perform_request('GET', '/').body).to be_a(Hash)
1460
+ end
1461
+
1462
+ it 'sets the Accept-Encoding header' do
1463
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1464
+ end
1465
+
1466
+ it 'preserves the other headers' do
1467
+ expect(client.transport.connections[0].connection.headers['User-Agent'])
1468
+ end
1469
+ end
1470
+
1471
+ context 'when using the Typhoeus adapter' do
1472
+
1473
+ let(:client) do
1474
+ described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :typhoeus)
1475
+ end
1476
+
1477
+ it 'compresses the request and decompresses the response' do
1478
+ expect(client.perform_request('GET', '/').body).to be_a(Hash)
1479
+ end
1480
+
1481
+ it 'sets the Accept-Encoding header' do
1482
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1483
+ end
1484
+
1485
+ it 'preserves the other headers' do
1486
+ expect(client.transport.connections[0].connection.headers['User-Agent'])
1487
+ end
1488
+ end
1489
+ end
1490
+ end
1491
+
1492
+ context 'when using Curb as the transport', unless: jruby? do
1493
+
1494
+ let(:client) do
1495
+ described_class.new(hosts: ELASTICSEARCH_HOSTS,
1496
+ compression: true,
1497
+ transport_class: Elasticsearch::Transport::Transport::HTTP::Curb)
1498
+ end
1499
+
1500
+ it 'compresses the request and decompresses the response' do
1501
+ expect(client.perform_request('GET', '/').body).to be_a(Hash)
1502
+ end
1503
+
1504
+ it 'sets the Accept-Encoding header' do
1505
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1506
+ end
1507
+
1508
+ it 'preserves the other headers' do
1509
+ expect(client.transport.connections[0].connection.headers['User-Agent'])
1510
+ end
1511
+ end
1512
+
1513
+ context 'when using Manticore as the transport', if: jruby? do
1514
+
1515
+ let(:client) do
1516
+ described_class.new(hosts: ELASTICSEARCH_HOSTS,
1517
+ compression: true,
1518
+ transport_class: Elasticsearch::Transport::Transport::HTTP::Manticore)
1519
+ end
1520
+
1521
+ it 'compresses the request and decompresses the response' do
1522
+ expect(client.perform_request('GET', '/').body).to be_a(Hash)
1523
+ end
1524
+ end
1056
1525
  end
1057
1526
 
1058
1527
  describe '#perform_request' do
@@ -1064,7 +1533,7 @@ describe Elasticsearch::Transport::Client do
1064
1533
  client.perform_request('DELETE', 'myindex') rescue
1065
1534
  client.perform_request('PUT', 'myindex', {}, { settings: { number_of_shards: 2, number_of_replicas: 0 } })
1066
1535
  client.perform_request('PUT', 'myindex/mydoc/1', { routing: 'XYZ', timeout: '1s' }, { foo: 'bar' })
1067
- client.perform_request('GET', '_cluster/health?wait_for_status=green', {})
1536
+ client.perform_request('GET', '_cluster/health?wait_for_status=green&timeout=2s', {})
1068
1537
  end
1069
1538
 
1070
1539
  let(:response) do
@@ -1155,12 +1624,39 @@ describe Elasticsearch::Transport::Client do
1155
1624
  { adapter: :patron }
1156
1625
  end
1157
1626
 
1158
- let(:connection_handler) do
1159
- client.transport.connections.first.connection.builder.handlers.first
1627
+ let(:adapter) do
1628
+ client.transport.connections.first.connection.builder.adapter
1629
+ end
1630
+
1631
+ it 'uses the patron connection handler' do
1632
+ expect(adapter).to eq('Faraday::Adapter::Patron')
1633
+ end
1634
+
1635
+ it 'keeps connections open' do
1636
+ response = client.perform_request('GET', '_nodes/stats/http')
1637
+ connections_before = response.body['nodes'].values.find { |n| n['name'] == node_names.first }['http']['total_opened']
1638
+ client.transport.reload_connections!
1639
+ response = client.perform_request('GET', '_nodes/stats/http')
1640
+ connections_after = response.body['nodes'].values.find { |n| n['name'] == node_names.first }['http']['total_opened']
1641
+ expect(connections_after).to be >= (connections_before)
1642
+ end
1643
+ end
1644
+
1645
+ context 'when typhoeus is used as an adapter', unless: jruby? do
1646
+ before do
1647
+ require 'typhoeus'
1648
+ end
1649
+
1650
+ let(:options) do
1651
+ { adapter: :typhoeus }
1652
+ end
1653
+
1654
+ let(:adapter) do
1655
+ client.transport.connections.first.connection.builder.adapter
1160
1656
  end
1161
1657
 
1162
1658
  it 'uses the patron connection handler' do
1163
- expect(connection_handler).to eq('Faraday::Adapter::Patron')
1659
+ expect(adapter).to eq('Faraday::Adapter::Typhoeus')
1164
1660
  end
1165
1661
 
1166
1662
  it 'keeps connections open' do