elasticsearch-transport 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +13 -0
- data/README.md +276 -0
- data/Rakefile +67 -0
- data/elasticsearch-transport.gemspec +52 -0
- data/lib/elasticsearch-transport.rb +1 -0
- data/lib/elasticsearch/transport.rb +29 -0
- data/lib/elasticsearch/transport/client.rb +123 -0
- data/lib/elasticsearch/transport/extensions/test_cluster.rb +163 -0
- data/lib/elasticsearch/transport/transport/base.rb +236 -0
- data/lib/elasticsearch/transport/transport/connections/collection.rb +93 -0
- data/lib/elasticsearch/transport/transport/connections/connection.rb +117 -0
- data/lib/elasticsearch/transport/transport/connections/selector.rb +63 -0
- data/lib/elasticsearch/transport/transport/errors.rb +73 -0
- data/lib/elasticsearch/transport/transport/http/curb.rb +70 -0
- data/lib/elasticsearch/transport/transport/http/faraday.rb +59 -0
- data/lib/elasticsearch/transport/transport/response.rb +20 -0
- data/lib/elasticsearch/transport/transport/serializer/multi_json.rb +36 -0
- data/lib/elasticsearch/transport/transport/sniffer.rb +46 -0
- data/lib/elasticsearch/transport/version.rb +5 -0
- data/test/integration/client_test.rb +117 -0
- data/test/integration/transport_test.rb +37 -0
- data/test/profile/client_benchmark_test.rb +107 -0
- data/test/test_extensions.rb +139 -0
- data/test/test_helper.rb +58 -0
- data/test/unit/client_test.rb +109 -0
- data/test/unit/connection_collection_test.rb +83 -0
- data/test/unit/connection_selector_test.rb +64 -0
- data/test/unit/connection_test.rb +90 -0
- data/test/unit/serializer_test.rb +16 -0
- data/test/unit/sniffer_test.rb +146 -0
- data/test/unit/transport_base_test.rb +402 -0
- data/test/unit/transport_curb_test.rb +59 -0
- data/test/unit/transport_faraday_test.rb +73 -0
- metadata +342 -0
@@ -0,0 +1,402 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Elasticsearch::Transport::Transport::BaseTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class EmptyTransport
|
6
|
+
include Elasticsearch::Transport::Transport::Base
|
7
|
+
end
|
8
|
+
|
9
|
+
class DummyTransport
|
10
|
+
include Elasticsearch::Transport::Transport::Base
|
11
|
+
def __build_connections; hosts; end
|
12
|
+
end
|
13
|
+
|
14
|
+
class DummyTransportPerformer < DummyTransport
|
15
|
+
def perform_request(method, path, params={}, body=nil, &block); super; end
|
16
|
+
end
|
17
|
+
|
18
|
+
class DummySerializer
|
19
|
+
def initialize(*); end
|
20
|
+
end
|
21
|
+
|
22
|
+
class DummySniffer
|
23
|
+
def initialize(*); end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "Transport::Base" do
|
27
|
+
should "raise exception when it doesn't implement __build_connections" do
|
28
|
+
assert_raise NoMethodError do
|
29
|
+
EmptyTransport.new.__build_connections
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
should "build connections on initialization" do
|
34
|
+
DummyTransport.any_instance.expects(:__build_connections)
|
35
|
+
transport = DummyTransport.new
|
36
|
+
end
|
37
|
+
|
38
|
+
should "have default serializer" do
|
39
|
+
transport = DummyTransport.new
|
40
|
+
assert_instance_of Elasticsearch::Transport::Transport::Base::DEFAULT_SERIALIZER_CLASS, transport.serializer
|
41
|
+
end
|
42
|
+
|
43
|
+
should "have custom serializer" do
|
44
|
+
transport = DummyTransport.new :options => { :serializer_class => DummySerializer }
|
45
|
+
assert_instance_of DummySerializer, transport.serializer
|
46
|
+
|
47
|
+
transport = DummyTransport.new :options => { :serializer => DummySerializer.new }
|
48
|
+
assert_instance_of DummySerializer, transport.serializer
|
49
|
+
end
|
50
|
+
|
51
|
+
should "have default sniffer" do
|
52
|
+
transport = DummyTransport.new
|
53
|
+
assert_instance_of Elasticsearch::Transport::Transport::Sniffer, transport.sniffer
|
54
|
+
end
|
55
|
+
|
56
|
+
should "have custom sniffer" do
|
57
|
+
transport = DummyTransport.new :options => { :sniffer_class => DummySniffer }
|
58
|
+
assert_instance_of DummySniffer, transport.sniffer
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "getting a connection" do
|
63
|
+
setup do
|
64
|
+
@transport = DummyTransportPerformer.new :options => { :reload_connections => 5 }
|
65
|
+
@transport.stubs(:connections).returns(stub :get_connection => Object.new)
|
66
|
+
@transport.stubs(:sniffer).returns(stub :hosts => [])
|
67
|
+
end
|
68
|
+
|
69
|
+
should "get a connection" do
|
70
|
+
assert_not_nil @transport.get_connection
|
71
|
+
end
|
72
|
+
|
73
|
+
should "increment the counter" do
|
74
|
+
assert_equal 0, @transport.counter
|
75
|
+
3.times { @transport.get_connection }
|
76
|
+
assert_equal 3, @transport.counter
|
77
|
+
end
|
78
|
+
|
79
|
+
should "reload connections when it hits the threshold" do
|
80
|
+
@transport.expects(:reload_connections!).twice
|
81
|
+
12.times { @transport.get_connection }
|
82
|
+
assert_equal 12, @transport.counter
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "performing a request" do
|
87
|
+
setup do
|
88
|
+
@transport = DummyTransportPerformer.new
|
89
|
+
end
|
90
|
+
|
91
|
+
should "raise an error when no block is passed" do
|
92
|
+
assert_raise NoMethodError do
|
93
|
+
@transport.peform_request 'GET', '/'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
should "get the connection" do
|
98
|
+
@transport.expects(:get_connection).returns(stub_everything :failures => 1)
|
99
|
+
@transport.perform_request 'GET', '/' do; Elasticsearch::Transport::Transport::Response.new 200, 'OK'; end
|
100
|
+
end
|
101
|
+
|
102
|
+
should "raise an error when no connection is available" do
|
103
|
+
@transport.expects(:get_connection).returns(nil)
|
104
|
+
assert_raise Elasticsearch::Transport::Transport::Error do
|
105
|
+
@transport.perform_request 'GET', '/' do; Elasticsearch::Transport::Transport::Response.new 200, 'OK'; end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
should "call the passed block" do
|
110
|
+
x = 0
|
111
|
+
@transport.expects(:get_connection).returns(stub_everything :failures => 1)
|
112
|
+
|
113
|
+
@transport.perform_request 'GET', '/' do |connection, url|
|
114
|
+
x += 1
|
115
|
+
Elasticsearch::Transport::Transport::Response.new 200, 'OK'
|
116
|
+
end
|
117
|
+
|
118
|
+
assert_equal 1, x
|
119
|
+
end
|
120
|
+
|
121
|
+
should "deserialize a response JSON body" do
|
122
|
+
@transport.expects(:get_connection).returns(stub_everything :failures => 1)
|
123
|
+
@transport.serializer.expects(:load).returns({'foo' => 'bar'})
|
124
|
+
|
125
|
+
response = @transport.perform_request 'GET', '/' do
|
126
|
+
Elasticsearch::Transport::Transport::Response.new 200, '{"foo":"bar"}'
|
127
|
+
end
|
128
|
+
|
129
|
+
assert_instance_of Elasticsearch::Transport::Transport::Response, response
|
130
|
+
assert_equal 'bar', response.body['foo']
|
131
|
+
end
|
132
|
+
|
133
|
+
should "not deserialize a response string body" do
|
134
|
+
@transport.expects(:get_connection).returns(stub_everything :failures => 1)
|
135
|
+
@transport.serializer.expects(:load).never
|
136
|
+
response = @transport.perform_request 'GET', '/' do
|
137
|
+
Elasticsearch::Transport::Transport::Response.new 200, 'FOOBAR'
|
138
|
+
end
|
139
|
+
|
140
|
+
assert_instance_of Elasticsearch::Transport::Transport::Response, response
|
141
|
+
assert_equal 'FOOBAR', response.body
|
142
|
+
end
|
143
|
+
|
144
|
+
should "serialize non-String objects" do
|
145
|
+
@transport.serializer.expects(:dump).times(3)
|
146
|
+
@transport.__convert_to_json({:foo => 'bar'})
|
147
|
+
@transport.__convert_to_json([1, 2, 3])
|
148
|
+
@transport.__convert_to_json(nil)
|
149
|
+
end
|
150
|
+
|
151
|
+
should "not serialize a String object" do
|
152
|
+
@transport.serializer.expects(:dump).never
|
153
|
+
@transport.__convert_to_json('{"foo":"bar"}')
|
154
|
+
end
|
155
|
+
|
156
|
+
should "raise an error for HTTP status 404" do
|
157
|
+
@transport.expects(:get_connection).returns(stub_everything :failures => 1)
|
158
|
+
assert_raise Elasticsearch::Transport::Transport::Errors::NotFound do
|
159
|
+
@transport.perform_request 'GET', '/' do
|
160
|
+
Elasticsearch::Transport::Transport::Response.new 404, 'NOT FOUND'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
should "raise an error on server failure" do
|
166
|
+
@transport.expects(:get_connection).returns(stub_everything :failures => 1)
|
167
|
+
assert_raise Elasticsearch::Transport::Transport::Errors::InternalServerError do
|
168
|
+
@transport.perform_request 'GET', '/' do
|
169
|
+
Elasticsearch::Transport::Transport::Response.new 500, 'ERROR'
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
should "raise an error on connection failure" do
|
175
|
+
@transport.expects(:get_connection).returns(stub_everything :failures => 1)
|
176
|
+
|
177
|
+
# `block.expects(:call).raises(::Errno::ECONNREFUSED)` fails on Ruby 1.8
|
178
|
+
block = lambda { |a, b| raise ::Errno::ECONNREFUSED }
|
179
|
+
|
180
|
+
assert_raise ::Errno::ECONNREFUSED do
|
181
|
+
@transport.perform_request 'GET', '/', &block
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
should "mark the connection as dead on failure" do
|
186
|
+
c = stub_everything :failures => 1
|
187
|
+
@transport.expects(:get_connection).returns(c)
|
188
|
+
|
189
|
+
block = lambda { |a,b| raise ::Errno::ECONNREFUSED }
|
190
|
+
|
191
|
+
c.expects(:dead!)
|
192
|
+
|
193
|
+
assert_raise( ::Errno::ECONNREFUSED ) { @transport.perform_request 'GET', '/', &block }
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context "performing a request with reload connections on connection failures" do
|
198
|
+
setup do
|
199
|
+
fake_collection = stub_everything :get_connection => stub_everything(:failures => 1),
|
200
|
+
:all => stub_everything(:size => 2)
|
201
|
+
@transport = DummyTransportPerformer.new :options => { :reload_on_failure => 2 }
|
202
|
+
@transport.stubs(:connections).
|
203
|
+
returns(fake_collection)
|
204
|
+
@block = lambda { |c, u| puts "UNREACHABLE" }
|
205
|
+
end
|
206
|
+
|
207
|
+
should "reload connections when host is unreachable" do
|
208
|
+
@block.expects(:call).times(2).
|
209
|
+
raises(Errno::ECONNREFUSED).
|
210
|
+
then.returns(stub_everything :failures => 1)
|
211
|
+
|
212
|
+
@transport.expects(:reload_connections!).returns([])
|
213
|
+
|
214
|
+
@transport.perform_request('GET', '/', &@block)
|
215
|
+
assert_equal 2, @transport.counter
|
216
|
+
end
|
217
|
+
end unless RUBY_1_8
|
218
|
+
|
219
|
+
context "performing a request with retry on connection failures" do
|
220
|
+
setup do
|
221
|
+
@transport = DummyTransportPerformer.new :options => { :retry_on_failure => true }
|
222
|
+
@transport.stubs(:connections).returns(stub :get_connection => stub_everything(:failures => 1))
|
223
|
+
@block = Proc.new { |c, u| puts "UNREACHABLE" }
|
224
|
+
end
|
225
|
+
|
226
|
+
should "retry DEFAULT_MAX_TRIES when host is unreachable" do
|
227
|
+
@block.expects(:call).times(3).
|
228
|
+
raises(Errno::ECONNREFUSED).
|
229
|
+
then.raises(Errno::ECONNREFUSED).
|
230
|
+
then.returns(stub_everything :failures => 1)
|
231
|
+
|
232
|
+
assert_nothing_raised do
|
233
|
+
@transport.perform_request('GET', '/', &@block)
|
234
|
+
assert_equal 3, @transport.counter
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
should "raise an error after max tries" do
|
239
|
+
@block.expects(:call).times(3).
|
240
|
+
raises(Errno::ECONNREFUSED).
|
241
|
+
then.raises(Errno::ECONNREFUSED).
|
242
|
+
then.raises(Errno::ECONNREFUSED).
|
243
|
+
then.raises(Errno::ECONNREFUSED)
|
244
|
+
|
245
|
+
assert_raise Errno::ECONNREFUSED do
|
246
|
+
@transport.perform_request('GET', '/', &@block)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end unless RUBY_1_8
|
250
|
+
|
251
|
+
context "logging" do
|
252
|
+
setup do
|
253
|
+
@transport = DummyTransportPerformer.new :options => { :logger => Logger.new('/dev/null') }
|
254
|
+
@transport.stubs(:get_connection).returns stub :full_url => 'localhost:9200/_search?size=1',
|
255
|
+
:host => 'localhost',
|
256
|
+
:failures => 0,
|
257
|
+
:healthy! => true
|
258
|
+
@transport.serializer.stubs(:load).returns 'foo' => 'bar'
|
259
|
+
@transport.serializer.stubs(:dump).returns '{"foo":"bar"}'
|
260
|
+
end
|
261
|
+
|
262
|
+
should "log the request and response" do
|
263
|
+
@transport.logger.expects(:info). with "POST localhost:9200/_search?size=1 [status:200, request:0.000s, query:n/a]"
|
264
|
+
@transport.logger.expects(:debug). with '> {"foo":"bar"}'
|
265
|
+
@transport.logger.expects(:debug). with '< {"foo":"bar"}'
|
266
|
+
|
267
|
+
@transport.perform_request 'POST', '_search', {:size => 1}, {:foo => 'bar'} do
|
268
|
+
Elasticsearch::Transport::Transport::Response.new 200, '{"foo":"bar"}'
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
should "log failed request" do
|
273
|
+
@block = Proc.new { |c, u| puts "ERROR" }
|
274
|
+
@block.expects(:call).returns(Elasticsearch::Transport::Transport::Response.new 500, 'ERROR')
|
275
|
+
|
276
|
+
@transport.logger.expects(:fatal)
|
277
|
+
|
278
|
+
assert_raise Elasticsearch::Transport::Transport::Errors::InternalServerError do
|
279
|
+
@transport.perform_request('POST', '_search', &@block)
|
280
|
+
end
|
281
|
+
end unless RUBY_1_8
|
282
|
+
|
283
|
+
should "log and re-raise exception" do
|
284
|
+
@block = Proc.new { |c, u| puts "ERROR" }
|
285
|
+
@block.expects(:call).raises(Exception)
|
286
|
+
|
287
|
+
@transport.logger.expects(:fatal)
|
288
|
+
|
289
|
+
assert_raise(Exception) { @transport.perform_request('POST', '_search', &@block) }
|
290
|
+
end unless RUBY_1_8
|
291
|
+
end
|
292
|
+
|
293
|
+
context "tracing" do
|
294
|
+
setup do
|
295
|
+
@transport = DummyTransportPerformer.new :options => { :tracer => Logger.new('/dev/null') }
|
296
|
+
@transport.stubs(:get_connection).returns stub :full_url => 'localhost:9200/_search?size=1',
|
297
|
+
:host => 'localhost',
|
298
|
+
:failures => 0,
|
299
|
+
:healthy! => true
|
300
|
+
@transport.serializer.stubs(:load).returns 'foo' => 'bar'
|
301
|
+
@transport.serializer.stubs(:dump).returns <<-JSON.gsub(/^ /, '')
|
302
|
+
{
|
303
|
+
"foo" : {
|
304
|
+
"bar" : {
|
305
|
+
"bam" : true
|
306
|
+
}
|
307
|
+
}
|
308
|
+
}
|
309
|
+
JSON
|
310
|
+
end
|
311
|
+
|
312
|
+
should "trace the request" do
|
313
|
+
@transport.tracer.expects(:info). with do |message|
|
314
|
+
message == <<-CURL.gsub(/^ /, '')
|
315
|
+
curl -X POST 'http://localhost:9200/_search?pretty&size=1' -d '{
|
316
|
+
"foo" : {
|
317
|
+
"bar" : {
|
318
|
+
"bam" : true
|
319
|
+
}
|
320
|
+
}
|
321
|
+
}
|
322
|
+
'
|
323
|
+
CURL
|
324
|
+
end.once
|
325
|
+
|
326
|
+
@transport.perform_request 'POST', '_search', {:size => 1}, {:q => 'foo'} do
|
327
|
+
Elasticsearch::Transport::Transport::Response.new 200, '{"foo":"bar"}'
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
332
|
+
|
333
|
+
context "reloading connections" do
|
334
|
+
setup do
|
335
|
+
@transport = DummyTransport.new :options => { :logger => Logger.new('/dev/null') }
|
336
|
+
end
|
337
|
+
|
338
|
+
should "rebuild connections" do
|
339
|
+
@transport.sniffer.expects(:hosts).returns([])
|
340
|
+
@transport.expects(:__rebuild_connections)
|
341
|
+
@transport.reload_connections!
|
342
|
+
end
|
343
|
+
|
344
|
+
should "log error and continue when timing out while sniffing hosts" do
|
345
|
+
@transport.sniffer.expects(:hosts).raises(Elasticsearch::Transport::Transport::SnifferTimeoutError)
|
346
|
+
@transport.logger.expects(:error)
|
347
|
+
assert_nothing_raised do
|
348
|
+
@transport.reload_connections!
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
context "rebuilding connections" do
|
354
|
+
setup do
|
355
|
+
@transport = DummyTransport.new
|
356
|
+
end
|
357
|
+
|
358
|
+
should "should replace the connections" do
|
359
|
+
assert_equal [], @transport.connections
|
360
|
+
@transport.__rebuild_connections :hosts => ['foo', 'bar']
|
361
|
+
assert_equal ['foo', 'bar'], @transport.connections
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
context "resurrecting connections" do
|
366
|
+
setup do
|
367
|
+
@transport = DummyTransportPerformer.new
|
368
|
+
end
|
369
|
+
|
370
|
+
should "delegate to dead connections" do
|
371
|
+
@transport.connections.expects(:dead).returns([])
|
372
|
+
@transport.resurrect_dead_connections!
|
373
|
+
end
|
374
|
+
|
375
|
+
should "not resurrect connections until timeout" do
|
376
|
+
@transport.connections.expects(:get_connection).returns(stub_everything :failures => 1).times(5)
|
377
|
+
@transport.expects(:resurrect_dead_connections!).never
|
378
|
+
5.times { @transport.get_connection }
|
379
|
+
end
|
380
|
+
|
381
|
+
should "resurrect connections after timeout" do
|
382
|
+
@transport.connections.expects(:get_connection).returns(stub_everything :failures => 1).times(5)
|
383
|
+
@transport.expects(:resurrect_dead_connections!)
|
384
|
+
|
385
|
+
4.times { @transport.get_connection }
|
386
|
+
|
387
|
+
now = Time.now + 60*2
|
388
|
+
Time.stubs(:now).returns(now)
|
389
|
+
|
390
|
+
@transport.get_connection
|
391
|
+
end
|
392
|
+
|
393
|
+
should "mark connection healthy if it succeeds" do
|
394
|
+
c = stub_everything(:failures => 1)
|
395
|
+
@transport.expects(:get_connection).returns(c)
|
396
|
+
c.expects(:healthy!)
|
397
|
+
|
398
|
+
@transport.perform_request('GET', '/') { |connection, url| Elasticsearch::Transport::Transport::Response.new 200, 'OK' }
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'elasticsearch/transport/transport/http/curb'
|
3
|
+
require 'curb'
|
4
|
+
|
5
|
+
class Elasticsearch::Transport::Transport::HTTP::FaradayTest < Test::Unit::TestCase
|
6
|
+
include Elasticsearch::Transport::Transport::HTTP
|
7
|
+
|
8
|
+
context "Curb transport" do
|
9
|
+
setup do
|
10
|
+
@transport = Curb.new :hosts => [ { :host => 'foobar', :port => 1234 } ]
|
11
|
+
end
|
12
|
+
|
13
|
+
should "implement __build_connections" do
|
14
|
+
assert_equal 1, @transport.hosts.size
|
15
|
+
assert_equal 1, @transport.connections.size
|
16
|
+
|
17
|
+
assert_instance_of ::Curl::Easy, @transport.connections.first.connection
|
18
|
+
assert_equal 'http://foobar:1234', @transport.connections.first.connection.url
|
19
|
+
end
|
20
|
+
|
21
|
+
should "perform the request" do
|
22
|
+
@transport.connections.first.connection.expects(:http).returns(stub_everything)
|
23
|
+
@transport.perform_request 'GET', '/'
|
24
|
+
end
|
25
|
+
|
26
|
+
should "serialize the request body" do
|
27
|
+
@transport.connections.first.connection.expects(:http_post).returns(stub_everything)
|
28
|
+
@transport.serializer.expects(:dump)
|
29
|
+
@transport.perform_request 'POST', '/', {}, {:foo => 'bar'}
|
30
|
+
end
|
31
|
+
|
32
|
+
should "not serialize a String request body" do
|
33
|
+
@transport.connections.first.connection.expects(:http_post).returns(stub_everything)
|
34
|
+
@transport.serializer.expects(:dump).never
|
35
|
+
@transport.perform_request 'POST', '/', {}, '{"foo":"bar"}'
|
36
|
+
end
|
37
|
+
|
38
|
+
should "handle HTTP methods" do
|
39
|
+
@transport.connections.first.connection.expects(:http).twice.returns(stub_everything)
|
40
|
+
@transport.connections.first.connection.expects(:http_put).returns(stub_everything)
|
41
|
+
@transport.connections.first.connection.expects(:http_post).returns(stub_everything)
|
42
|
+
@transport.connections.first.connection.expects(:http_delete).returns(stub_everything)
|
43
|
+
|
44
|
+
%w| HEAD GET PUT POST DELETE |.each { |method| @transport.perform_request method, '/' }
|
45
|
+
|
46
|
+
assert_raise(ArgumentError) { @transport.perform_request 'FOOBAR', '/' }
|
47
|
+
end
|
48
|
+
|
49
|
+
should "allow to set options for Curb" do
|
50
|
+
transport = Curb.new :hosts => [ { :host => 'foobar', :port => 1234 } ] do |curl|
|
51
|
+
curl.headers["User-Agent"] = "myapp-0.0"
|
52
|
+
end
|
53
|
+
|
54
|
+
assert_equal( {"Content-Type"=>"application/json", "User-Agent"=>"myapp-0.0"},
|
55
|
+
transport.connections.first.connection.headers )
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|