elasticsearch-transport 7.13.3 → 7.17.11

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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +9 -9
  3. data/Gemfile-faraday1.gemfile +47 -0
  4. data/README.md +3 -8
  5. data/Rakefile +47 -10
  6. data/elasticsearch-transport.gemspec +17 -18
  7. data/lib/elasticsearch/transport/client.rb +34 -3
  8. data/lib/elasticsearch/transport/transport/base.rb +41 -22
  9. data/lib/elasticsearch/transport/transport/connections/connection.rb +2 -1
  10. data/lib/elasticsearch/transport/transport/errors.rb +1 -0
  11. data/lib/elasticsearch/transport/transport/http/curb.rb +44 -32
  12. data/lib/elasticsearch/transport/transport/http/faraday.rb +5 -3
  13. data/lib/elasticsearch/transport/transport/http/manticore.rb +41 -29
  14. data/lib/elasticsearch/transport/transport/response.rb +1 -1
  15. data/lib/elasticsearch/transport/version.rb +1 -1
  16. data/lib/elasticsearch/transport.rb +19 -30
  17. data/spec/elasticsearch/transport/base_spec.rb +50 -9
  18. data/spec/elasticsearch/transport/client_spec.rb +138 -64
  19. data/spec/elasticsearch/transport/http/curb_spec.rb +126 -0
  20. data/spec/elasticsearch/transport/http/faraday_spec.rb +141 -0
  21. data/spec/elasticsearch/transport/http/manticore_spec.rb +161 -0
  22. data/spec/elasticsearch/transport/meta_header_spec.rb +66 -30
  23. data/spec/spec_helper.rb +13 -5
  24. data/test/integration/jruby_test.rb +43 -0
  25. data/test/integration/transport_test.rb +89 -52
  26. data/test/test_helper.rb +10 -22
  27. data/test/unit/adapters_test.rb +88 -0
  28. data/test/unit/response_test.rb +1 -1
  29. data/test/unit/transport_base_test.rb +16 -7
  30. data/test/unit/transport_curb_test.rb +0 -1
  31. data/test/unit/transport_manticore_test.rb +242 -155
  32. metadata +68 -79
@@ -24,10 +24,6 @@ describe Elasticsearch::Transport::Client do
24
24
  end
25
25
  end
26
26
 
27
- it 'is aliased as Elasticsearch::Client' do
28
- expect(Elasticsearch::Client.new).to be_a(described_class)
29
- end
30
-
31
27
  it 'has a default transport' do
32
28
  expect(client.transport).to be_a(Elasticsearch::Transport::Client::DEFAULT_TRANSPORT_CLASS)
33
29
  end
@@ -231,14 +227,15 @@ describe Elasticsearch::Transport::Client do
231
227
 
232
228
  describe 'adapter' do
233
229
  context 'when no adapter is specified' do
234
- let(:adapter) do
235
- client.transport.connections.all.first.connection.builder.adapter
236
- end
230
+ fork do
231
+ let(:client) { described_class.new }
232
+ let(:adapter) { client.transport.connections.all.first.connection.builder.adapter }
237
233
 
238
- it 'uses Faraday NetHttp' do
239
- expect(adapter).to eq Faraday::Adapter::NetHttp
234
+ it 'uses Faraday NetHttp' do
235
+ expect(adapter).to eq Faraday::Adapter::NetHttp
236
+ end
240
237
  end
241
- end
238
+ end unless jruby?
242
239
 
243
240
  context 'when the adapter is patron' do
244
241
  let(:adapter) do
@@ -250,9 +247,10 @@ describe Elasticsearch::Transport::Client do
250
247
  end
251
248
 
252
249
  it 'uses Faraday with the adapter' do
250
+ require 'faraday/patron'
253
251
  expect(adapter).to eq Faraday::Adapter::Patron
254
252
  end
255
- end
253
+ end unless jruby?
256
254
 
257
255
  context 'when the adapter is typhoeus' do
258
256
  let(:adapter) do
@@ -260,6 +258,8 @@ describe Elasticsearch::Transport::Client do
260
258
  end
261
259
 
262
260
  let(:client) do
261
+ require 'faraday/typhoeus' if is_faraday_v2?
262
+
263
263
  described_class.new(adapter: :typhoeus, enable_meta_header: false)
264
264
  end
265
265
 
@@ -280,7 +280,7 @@ describe Elasticsearch::Transport::Client do
280
280
  it 'uses Faraday with the adapter' do
281
281
  expect(adapter).to eq Faraday::Adapter::Patron
282
282
  end
283
- end
283
+ end unless jruby?
284
284
 
285
285
  context 'when the adapter can be detected', unless: jruby? do
286
286
 
@@ -322,7 +322,7 @@ describe Elasticsearch::Transport::Client do
322
322
  it 'sets the logger' do
323
323
  expect(handlers).to include(Faraday::Response::Logger)
324
324
  end
325
- end
325
+ end unless jruby?
326
326
  end
327
327
 
328
328
  context 'when cloud credentials are provided' do
@@ -1416,14 +1416,14 @@ describe Elasticsearch::Transport::Client do
1416
1416
  let(:client) { described_class.new(host: hosts) }
1417
1417
 
1418
1418
  it 'doesnae raise an ArgumentError' do
1419
- expect { client.search(opaque_id: 'no_error') }.not_to raise_error
1419
+ expect { client.perform_request('GET', '_search', opaque_id: 'no_error') }.not_to raise_error
1420
1420
  end
1421
1421
 
1422
1422
  it 'uses X-Opaque-Id in the header' do
1423
1423
  allow(client).to receive(:perform_request) { OpenStruct.new(body: '') }
1424
- expect { client.search(opaque_id: 'opaque_id') }.not_to raise_error
1424
+ expect { client.perform_request('GET', '_search', {}, nil, opaque_id: 'opaque_id') }.not_to raise_error
1425
1425
  expect(client).to have_received(:perform_request)
1426
- .with('GET', '_search', { opaque_id: 'opaque_id' }, nil, {})
1426
+ .with('GET', '_search', {}, nil, { opaque_id: 'opaque_id' })
1427
1427
  end
1428
1428
  end
1429
1429
  end
@@ -1435,10 +1435,7 @@ describe Elasticsearch::Transport::Client do
1435
1435
  headers = client.transport.connections.first.connection.headers
1436
1436
 
1437
1437
  expect(headers['Content-Type']).to eq('application/vnd.elasticsearch+json; compatible-with=7')
1438
- expect(headers['Accept']).to eq('application/vnd.elasticsearch+json;compatible-with=7')
1439
-
1440
- response = client.perform_request('GET', '/')
1441
- expect(response.headers['content-type']).to eq('application/json; charset=UTF-8')
1438
+ expect(headers['Accept']).to eq('application/vnd.elasticsearch+json; compatible-with=7')
1442
1439
 
1443
1440
  ENV.delete('ELASTIC_CLIENT_APIVERSIONING')
1444
1441
  end
@@ -1469,28 +1466,19 @@ describe Elasticsearch::Transport::Client do
1469
1466
  end
1470
1467
 
1471
1468
  context 'when Elasticsearch response includes a warning header' do
1469
+ let(:logger) { double('logger', warn: '', warn?: '', info?: '', info: '', debug?: '', debug: '') }
1472
1470
  let(:client) do
1473
- Elasticsearch::Transport::Client.new(hosts: hosts)
1471
+ Elasticsearch::Transport::Client.new(hosts: hosts, logger: logger)
1474
1472
  end
1475
1473
 
1476
1474
  let(:warning) { 'Elasticsearch warning: "deprecation warning"' }
1477
1475
 
1478
1476
  it 'prints a warning' do
1479
- allow_any_instance_of(Elasticsearch::Transport::Transport::Response).to receive(:headers) do
1480
- { 'warning' => warning }
1481
- end
1482
-
1483
- begin
1484
- stderr = $stderr
1485
- fake_stderr = StringIO.new
1486
- $stderr = fake_stderr
1487
-
1488
- client.perform_request('GET', '/')
1489
- fake_stderr.rewind
1490
- expect(fake_stderr.string).to eq("warning: #{warning}\n")
1491
- ensure
1492
- $stderr = stderr
1477
+ expect_any_instance_of(Faraday::Connection).to receive(:run_request) do
1478
+ Elasticsearch::Transport::Transport::Response.new(200, {}, { 'warning' => warning })
1493
1479
  end
1480
+ client.perform_request('GET', '/')
1481
+ expect(logger).to have_received(:warn).with(warning)
1494
1482
  end
1495
1483
  end
1496
1484
 
@@ -1500,7 +1488,7 @@ describe Elasticsearch::Transport::Client do
1500
1488
 
1501
1489
  it 'performs the request with the header' do
1502
1490
  allow(client).to receive(:perform_request) { OpenStruct.new(body: '') }
1503
- expect { client.search(headers: headers) }.not_to raise_error
1491
+ expect { client.perform_request('GET', '_search', {}, nil, headers) }.not_to raise_error
1504
1492
  expect(client).to have_received(:perform_request)
1505
1493
  .with('GET', '_search', {}, nil, headers)
1506
1494
  end
@@ -1514,7 +1502,7 @@ describe Elasticsearch::Transport::Client do
1514
1502
  )
1515
1503
  end
1516
1504
  let(:instance_headers) { { set_in_instantiation: 'header value' } }
1517
- let(:param_headers) {{'user-agent' => 'My Ruby Tests', 'set-on-method-call' => 'header value'}}
1505
+ let(:param_headers) { {'user-agent' => 'My Ruby Tests', 'set-on-method-call' => 'header value'} }
1518
1506
 
1519
1507
  it 'performs the request with the header' do
1520
1508
  expected_headers = client.transport.connections.connections.first.connection.headers.merge(param_headers)
@@ -1523,7 +1511,7 @@ describe Elasticsearch::Transport::Client do
1523
1511
  .to receive(:run_request)
1524
1512
  .with(:get, "http://#{hosts[0]}/_search", nil, expected_headers) { OpenStruct.new(body: '')}
1525
1513
 
1526
- client.search(headers: param_headers)
1514
+ client.perform_request('GET', '_search', {}, nil, param_headers)
1527
1515
  end
1528
1516
  end
1529
1517
  end
@@ -1560,7 +1548,6 @@ describe Elasticsearch::Transport::Client do
1560
1548
  end
1561
1549
 
1562
1550
  context 'when a request is made' do
1563
-
1564
1551
  let!(:response) do
1565
1552
  client.perform_request('GET', '_cluster/health')
1566
1553
  end
@@ -1571,9 +1558,7 @@ describe Elasticsearch::Transport::Client do
1571
1558
  end
1572
1559
 
1573
1560
  describe '#initialize' do
1574
-
1575
1561
  context 'when options are specified' do
1576
-
1577
1562
  let(:transport_options) do
1578
1563
  { headers: { accept: 'application/yaml', content_type: 'application/yaml' } }
1579
1564
  end
@@ -1589,9 +1574,8 @@ describe Elasticsearch::Transport::Client do
1589
1574
  end
1590
1575
 
1591
1576
  context 'when a block is provided' do
1592
-
1593
1577
  let(:client) do
1594
- Elasticsearch::Client.new(host: ELASTICSEARCH_HOSTS.first, logger: logger) do |client|
1578
+ described_class.new(host: ELASTICSEARCH_HOSTS.first, logger: logger) do |client|
1595
1579
  client.headers['Accept'] = 'application/yaml'
1596
1580
  end
1597
1581
  end
@@ -1606,8 +1590,10 @@ describe Elasticsearch::Transport::Client do
1606
1590
  end
1607
1591
 
1608
1592
  context 'when the Faraday adapter is set in the block' do
1593
+ require 'faraday/net_http_persistent' if is_faraday_v2?
1594
+
1609
1595
  let(:client) do
1610
- Elasticsearch::Client.new(host: ELASTICSEARCH_HOSTS.first, logger: logger) do |client|
1596
+ described_class.new(host: ELASTICSEARCH_HOSTS.first, logger: logger) do |client|
1611
1597
  client.adapter(:net_http_persistent)
1612
1598
  end
1613
1599
  end
@@ -1675,6 +1661,29 @@ describe Elasticsearch::Transport::Client do
1675
1661
  end
1676
1662
  end
1677
1663
 
1664
+ context 'when retry_on_failure is true and delay_on_retry is specified' do
1665
+ context 'when a node is unreachable' do
1666
+ let(:hosts) do
1667
+ [ELASTICSEARCH_HOSTS.first, "foobar1", "foobar2"]
1668
+ end
1669
+
1670
+ let(:options) do
1671
+ { retry_on_failure: true, delay_on_retry: 3000 }
1672
+ end
1673
+
1674
+ let(:responses) do
1675
+ 5.times.collect do
1676
+ client.perform_request('GET', '_nodes/_local')
1677
+ end
1678
+ end
1679
+
1680
+ it 'retries on failure' do
1681
+ allow_any_instance_of(Object).to receive(:sleep).with(3000 / 1000)
1682
+ expect(responses.all? { true }).to be(true)
1683
+ end
1684
+ end
1685
+ end
1686
+
1678
1687
  context 'when reload_on_failure is true' do
1679
1688
 
1680
1689
  let(:hosts) do
@@ -1734,7 +1743,7 @@ describe Elasticsearch::Transport::Client do
1734
1743
  end
1735
1744
 
1736
1745
  it 'sets the Accept-Encoding header' do
1737
- expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1746
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip'
1738
1747
  end
1739
1748
 
1740
1749
  it 'preserves the other headers' do
@@ -1743,6 +1752,7 @@ describe Elasticsearch::Transport::Client do
1743
1752
  end
1744
1753
 
1745
1754
  context 'when using the HTTPClient adapter' do
1755
+ require 'faraday/httpclient'
1746
1756
 
1747
1757
  let(:client) do
1748
1758
  described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :httpclient, enable_meta_header: false)
@@ -1753,7 +1763,7 @@ describe Elasticsearch::Transport::Client do
1753
1763
  end
1754
1764
 
1755
1765
  it 'sets the Accept-Encoding header' do
1756
- expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1766
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip'
1757
1767
  end
1758
1768
 
1759
1769
  it 'preserves the other headers' do
@@ -1772,7 +1782,7 @@ describe Elasticsearch::Transport::Client do
1772
1782
  end
1773
1783
 
1774
1784
  it 'sets the Accept-Encoding header' do
1775
- expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1785
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip'
1776
1786
  end
1777
1787
 
1778
1788
  it 'preserves the other headers' do
@@ -1791,7 +1801,7 @@ describe Elasticsearch::Transport::Client do
1791
1801
  end
1792
1802
 
1793
1803
  it 'sets the Accept-Encoding header' do
1794
- expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1804
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip'
1795
1805
  end
1796
1806
 
1797
1807
  it 'preserves the other headers' do
@@ -1810,7 +1820,7 @@ describe Elasticsearch::Transport::Client do
1810
1820
  end
1811
1821
 
1812
1822
  it 'sets the Accept-Encoding header' do
1813
- expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1823
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip'
1814
1824
  end
1815
1825
 
1816
1826
  it 'preserves the other headers' do
@@ -1821,11 +1831,12 @@ describe Elasticsearch::Transport::Client do
1821
1831
  end
1822
1832
 
1823
1833
  context 'when using Curb as the transport', unless: jruby? do
1824
-
1825
1834
  let(:client) do
1826
- described_class.new(hosts: ELASTICSEARCH_HOSTS,
1827
- compression: true,
1828
- transport_class: Elasticsearch::Transport::Transport::HTTP::Curb)
1835
+ described_class.new(
1836
+ hosts: ELASTICSEARCH_HOSTS,
1837
+ compression: true,
1838
+ transport_class: Elasticsearch::Transport::Transport::HTTP::Curb
1839
+ )
1829
1840
  end
1830
1841
 
1831
1842
  it 'compresses the request and decompresses the response' do
@@ -1833,7 +1844,7 @@ describe Elasticsearch::Transport::Client do
1833
1844
  end
1834
1845
 
1835
1846
  it 'sets the Accept-Encoding header' do
1836
- expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1847
+ expect(client.transport.connections[0].connection.headers['Accept-Encoding']).to eq 'gzip'
1837
1848
  end
1838
1849
 
1839
1850
  it 'preserves the other headers' do
@@ -1842,7 +1853,6 @@ describe Elasticsearch::Transport::Client do
1842
1853
  end
1843
1854
 
1844
1855
  context 'when using Manticore as the transport', if: jruby? do
1845
-
1846
1856
  let(:client) do
1847
1857
  described_class.new(hosts: ELASTICSEARCH_HOSTS,
1848
1858
  compression: true,
@@ -1856,9 +1866,7 @@ describe Elasticsearch::Transport::Client do
1856
1866
  end
1857
1867
 
1858
1868
  describe '#perform_request' do
1859
-
1860
1869
  context 'when a request is made' do
1861
-
1862
1870
  before do
1863
1871
  client.perform_request('DELETE', '_all')
1864
1872
  client.perform_request('DELETE', 'myindex') rescue
@@ -1881,7 +1889,6 @@ describe Elasticsearch::Transport::Client do
1881
1889
  end
1882
1890
 
1883
1891
  context 'when an invalid url is specified' do
1884
-
1885
1892
  it 'raises an exception' do
1886
1893
  expect {
1887
1894
  client.perform_request('GET', 'myindex/mydoc/1?routing=FOOBARBAZ')
@@ -1890,7 +1897,6 @@ describe Elasticsearch::Transport::Client do
1890
1897
  end
1891
1898
 
1892
1899
  context 'when the \'ignore\' parameter is specified' do
1893
-
1894
1900
  let(:response) do
1895
1901
  client.perform_request('PUT', '_foobar', ignore: 400)
1896
1902
  end
@@ -1906,7 +1912,6 @@ describe Elasticsearch::Transport::Client do
1906
1912
  end
1907
1913
 
1908
1914
  context 'when request headers are specified' do
1909
-
1910
1915
  let(:response) do
1911
1916
  client.perform_request('GET', '/', {}, nil, { 'Content-Type' => 'application/yaml' })
1912
1917
  end
@@ -1917,9 +1922,7 @@ describe Elasticsearch::Transport::Client do
1917
1922
  end
1918
1923
 
1919
1924
  describe 'selector' do
1920
-
1921
1925
  context 'when the round-robin selector is used' do
1922
-
1923
1926
  let(:nodes) do
1924
1927
  3.times.collect do
1925
1928
  client.perform_request('GET', '_nodes/_local').body['nodes'].to_a[0][1]['name']
@@ -1927,7 +1930,7 @@ describe Elasticsearch::Transport::Client do
1927
1930
  end
1928
1931
 
1929
1932
  let(:node_names) do
1930
- client.nodes.stats['nodes'].collect do |name, stats|
1933
+ client.perform_request('GET', '_nodes/stats').body('nodes').collect do |name, stats|
1931
1934
  stats['name']
1932
1935
  end
1933
1936
  end
@@ -1946,7 +1949,6 @@ describe Elasticsearch::Transport::Client do
1946
1949
  end
1947
1950
 
1948
1951
  context 'when patron is used as an adapter', unless: jruby? do
1949
-
1950
1952
  before do
1951
1953
  require 'patron'
1952
1954
  end
@@ -2001,4 +2003,76 @@ describe Elasticsearch::Transport::Client do
2001
2003
  end
2002
2004
  end
2003
2005
  end
2006
+
2007
+ context 'CA Fingerprinting' do
2008
+ context 'when setting a ca_fingerprint' do
2009
+ after do
2010
+ File.delete('./certificate.crt')
2011
+ File.delete('./certificate.key')
2012
+ end
2013
+
2014
+ let(:certificate) do
2015
+ system(
2016
+ 'openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 -subj "/C=BE/O=Test/CN=Test"' \
2017
+ ' -keyout certificate.key -out certificate.crt',
2018
+ err: File::NULL
2019
+ )
2020
+ OpenSSL::X509::Certificate.new File.read('./certificate.crt')
2021
+ end
2022
+
2023
+ let(:client) do
2024
+ Elasticsearch::Transport::Client.new(
2025
+ host: 'https://elastic:changeme@localhost:9200',
2026
+ ca_fingerprint: OpenSSL::Digest::SHA256.hexdigest(certificate.to_der)
2027
+ )
2028
+ end
2029
+
2030
+ it 'validates CA fingerprints on perform request' do
2031
+ expect(client.transport.connections.connections.map(&:verified).uniq).to eq [false]
2032
+ allow(client.transport).to receive(:perform_request) { 'Hello' }
2033
+
2034
+ server = double('server').as_null_object
2035
+ allow(TCPSocket).to receive(:new) { server }
2036
+ socket = double('socket')
2037
+ allow(OpenSSL::SSL::SSLSocket).to receive(:new) { socket }
2038
+ allow(socket).to receive(:connect) { nil }
2039
+ allow(socket).to receive(:peer_cert_chain) { [certificate] }
2040
+
2041
+ response = client.perform_request('GET', '/')
2042
+ expect(client.transport.connections.connections.map(&:verified).uniq).to eq [true]
2043
+ expect(response).to eq 'Hello'
2044
+ end
2045
+ end
2046
+
2047
+ context 'when using an http host' do
2048
+ let(:client) do
2049
+ Elasticsearch::Transport::Client.new(
2050
+ host: 'http://elastic:changeme@localhost:9200',
2051
+ ca_fingerprint: 'test'
2052
+ )
2053
+ end
2054
+
2055
+ it 'raises an error' do
2056
+ expect do
2057
+ client.perform_request('GET', '/')
2058
+ end.to raise_exception(Elasticsearch::Transport::Transport::Error)
2059
+ end
2060
+ end
2061
+
2062
+ context 'when not setting a ca_fingerprint' do
2063
+ let(:client) do
2064
+ Elasticsearch::Transport::Client.new(
2065
+ host: 'http://elastic:changeme@localhost:9200'
2066
+ )
2067
+ end
2068
+
2069
+ it 'has unvalidated connections' do
2070
+ allow(client).to receive(:validate_ca_fingerprints) { nil }
2071
+ allow(client.transport).to receive(:perform_request) { nil }
2072
+
2073
+ client.perform_request('GET', '/')
2074
+ expect(client).to_not have_received(:validate_ca_fingerprints)
2075
+ end
2076
+ end
2077
+ end
2004
2078
  end
@@ -0,0 +1,126 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ unless defined?(JRUBY_VERSION)
19
+ require_relative '../../../spec_helper'
20
+
21
+ describe Elasticsearch::Transport::Transport::HTTP::Curb do
22
+ let(:client) do
23
+ Elasticsearch::Transport::Client.new(transport_class: described_class)
24
+ end
25
+
26
+ describe '#perform_request' do
27
+ subject(:perform_request) { client.perform_request(*args) }
28
+ let(:args) do
29
+ ['POST', '/', {}, body, headers]
30
+ end
31
+ let(:body) { '{"foo":"bar"}' }
32
+ let(:headers) { { 'Content-Type' => 'application/x-ndjson' } }
33
+
34
+ before do
35
+ allow_any_instance_of(Curl::Easy).to receive(:http).and_return(true)
36
+ end
37
+
38
+ it 'convert body to json' do
39
+ expect(client.transport).to receive(:__convert_to_json).with(body)
40
+ perform_request
41
+ end
42
+
43
+ it 'call compress_request' do
44
+ expect(client.transport).to receive(:compress_request).with(body, headers)
45
+ perform_request
46
+ end
47
+
48
+ it 'return response' do
49
+ expect(perform_request).to be_kind_of(Elasticsearch::Transport::Transport::Response)
50
+ end
51
+
52
+ it 'put body' do
53
+ expect(client.transport.connections.first.connection).to receive('put_data=').with(body)
54
+ perform_request
55
+ end
56
+
57
+ context 'when body nil' do
58
+ let(:body) { nil }
59
+
60
+ it 'convert body to json' do
61
+ expect(client.transport).not_to receive(:__convert_to_json)
62
+ perform_request
63
+ end
64
+
65
+ it 'call compress_request' do
66
+ expect(client.transport).to receive(:compress_request).with(body, headers)
67
+ perform_request
68
+ end
69
+
70
+ it 'put body' do
71
+ expect(client.transport.connections.first.connection).not_to receive('put_data=')
72
+ perform_request
73
+ end
74
+ end
75
+
76
+ context 'when body is hash' do
77
+ let(:body) { { foo: 'bar' } }
78
+ let(:body_string) { '{"foo":"bar"}' }
79
+
80
+ it 'convert body to json' do
81
+ expect(client.transport).to receive(:__convert_to_json).with(body)
82
+ perform_request
83
+ end
84
+
85
+ it 'call compress_request' do
86
+ expect(client.transport).to receive(:compress_request).with(body_string, headers)
87
+ perform_request
88
+ end
89
+
90
+ it 'put body' do
91
+ expect(client.transport.connections.first.connection).to receive('put_data=').with(body_string)
92
+ perform_request
93
+ end
94
+ end
95
+
96
+ context 'when compression enabled' do
97
+ let(:client) do
98
+ Elasticsearch::Transport::Client.new(transport_class: described_class, compression: true)
99
+ end
100
+ let(:body_string) { '{"foo":"bar"}' }
101
+ let(:compressed_body) do
102
+ gzip = Zlib::GzipWriter.new(StringIO.new)
103
+ gzip << body_string
104
+ gzip.close.string
105
+ end
106
+
107
+ before { allow(client.transport).to receive(:decompress_response).and_return('') }
108
+
109
+ it 'put compressed body' do
110
+ expect(client.transport.connections.first.connection).to receive('put_data=').with(compressed_body)
111
+ perform_request
112
+ end
113
+
114
+ it 'set Content-Encoding header' do
115
+ perform_request
116
+ expect(client.transport.connections.first.connection.headers).to include('Content-Encoding')
117
+ end
118
+
119
+ it 'set Content-Encoding to gzip' do
120
+ perform_request
121
+ expect(client.transport.connections.first.connection.headers['Content-Encoding']).to eql('gzip')
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end