elastic-transport 8.0.0.pre1

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 (48) hide show
  1. checksums.yaml +7 -0
  2. data/.github/check_license_headers.rb +33 -0
  3. data/.github/license-header.txt +16 -0
  4. data/.github/workflows/license.yml +13 -0
  5. data/.github/workflows/tests.yml +45 -0
  6. data/.gitignore +19 -0
  7. data/CHANGELOG.md +224 -0
  8. data/Gemfile +38 -0
  9. data/LICENSE +202 -0
  10. data/README.md +552 -0
  11. data/Rakefile +87 -0
  12. data/elastic-transport.gemspec +74 -0
  13. data/lib/elastic/transport/client.rb +276 -0
  14. data/lib/elastic/transport/meta_header.rb +135 -0
  15. data/lib/elastic/transport/redacted.rb +73 -0
  16. data/lib/elastic/transport/transport/base.rb +450 -0
  17. data/lib/elastic/transport/transport/connections/collection.rb +126 -0
  18. data/lib/elastic/transport/transport/connections/connection.rb +160 -0
  19. data/lib/elastic/transport/transport/connections/selector.rb +91 -0
  20. data/lib/elastic/transport/transport/errors.rb +91 -0
  21. data/lib/elastic/transport/transport/http/curb.rb +120 -0
  22. data/lib/elastic/transport/transport/http/faraday.rb +95 -0
  23. data/lib/elastic/transport/transport/http/manticore.rb +179 -0
  24. data/lib/elastic/transport/transport/loggable.rb +83 -0
  25. data/lib/elastic/transport/transport/response.rb +36 -0
  26. data/lib/elastic/transport/transport/serializer/multi_json.rb +52 -0
  27. data/lib/elastic/transport/transport/sniffer.rb +101 -0
  28. data/lib/elastic/transport/version.rb +22 -0
  29. data/lib/elastic/transport.rb +37 -0
  30. data/lib/elastic-transport.rb +18 -0
  31. data/spec/elasticsearch/connections/collection_spec.rb +266 -0
  32. data/spec/elasticsearch/connections/selector_spec.rb +166 -0
  33. data/spec/elasticsearch/transport/base_spec.rb +264 -0
  34. data/spec/elasticsearch/transport/client_spec.rb +1651 -0
  35. data/spec/elasticsearch/transport/meta_header_spec.rb +274 -0
  36. data/spec/elasticsearch/transport/sniffer_spec.rb +275 -0
  37. data/spec/spec_helper.rb +90 -0
  38. data/test/integration/transport_test.rb +98 -0
  39. data/test/profile/client_benchmark_test.rb +132 -0
  40. data/test/test_helper.rb +83 -0
  41. data/test/unit/connection_test.rb +135 -0
  42. data/test/unit/response_test.rb +30 -0
  43. data/test/unit/serializer_test.rb +33 -0
  44. data/test/unit/transport_base_test.rb +664 -0
  45. data/test/unit/transport_curb_test.rb +135 -0
  46. data/test/unit/transport_faraday_test.rb +228 -0
  47. data/test/unit/transport_manticore_test.rb +251 -0
  48. metadata +412 -0
@@ -0,0 +1,90 @@
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
+ if ENV['COVERAGE'] && ENV['CI'].nil?
18
+ require 'simplecov'
19
+ SimpleCov.start { add_filter %r{^/test|spec/} }
20
+ end
21
+
22
+ require 'elastic-transport'
23
+ require 'logger'
24
+ require 'ansi/code'
25
+ require 'hashie/mash'
26
+ if defined?(JRUBY_VERSION)
27
+ require 'elastic/transport/transport/http/manticore'
28
+ require 'pry-nav'
29
+ else
30
+ require 'pry-byebug'
31
+ require 'elastic/transport/transport/http/curb'
32
+ require 'curb'
33
+ end
34
+
35
+ # The hosts to use for creating a elasticsearch client.
36
+ #
37
+ # @since 7.0.0
38
+ ELASTICSEARCH_HOSTS = if (hosts = ENV['TEST_ES_SERVER'] || ENV['ELASTICSEARCH_HOSTS'])
39
+ hosts.split(',').map do |host|
40
+ /(http\:\/\/)?(\S+)/.match(host)[2]
41
+ end
42
+ else
43
+ ['localhost:9200']
44
+ end.freeze
45
+
46
+ TEST_HOST, TEST_PORT = ELASTICSEARCH_HOSTS.first.split(':') if ELASTICSEARCH_HOSTS
47
+
48
+ # Are we testing on JRuby?
49
+ #
50
+ # @return [ true, false ] Whether JRuby is being used.
51
+ #
52
+ # @since 7.0.0
53
+ def jruby?
54
+ RUBY_PLATFORM =~ /\bjava\b/
55
+ end
56
+
57
+ # The names of the connected nodes.
58
+ #
59
+ # @return [ Array<String> ] The node names.
60
+ #
61
+ # @since 7.0.0
62
+ def node_names
63
+ $node_names ||= default_client.perform_request('GET', '_nodes/stats').body['nodes'].collect do |name, stats|
64
+ stats['name']
65
+ end
66
+ end
67
+
68
+ # The default client.
69
+ #
70
+ # @return [ Elastic::Transport::Client ] The default client.
71
+ #
72
+ # @since 7.0.0
73
+ def default_client
74
+ $client ||= Elastic::Transport::Client.new(hosts: ELASTICSEARCH_HOSTS)
75
+ end
76
+
77
+ module Config
78
+ def self.included(context)
79
+ # Get the hosts to use to connect an elasticsearch client.
80
+ #
81
+ # @since 7.0.0
82
+ context.let(:hosts) { ELASTICSEARCH_HOSTS }
83
+ end
84
+ end
85
+
86
+ RSpec.configure do |config|
87
+ config.include(Config)
88
+ config.formatter = 'documentation'
89
+ config.color = true
90
+ end
@@ -0,0 +1,98 @@
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
+ require 'test_helper'
19
+
20
+ class Elastic::Transport::ClientIntegrationTest < Minitest::Test
21
+ context "Transport" do
22
+ setup do
23
+ begin; Object.send(:remove_const, :Patron); rescue NameError; end
24
+ uri = URI(HOST)
25
+ @host = {
26
+ host: uri.host,
27
+ port: uri.port,
28
+ user: uri.user,
29
+ password: uri.password
30
+ }
31
+ end
32
+
33
+ should "allow to customize the Faraday adapter to Typhoeus" do
34
+ require 'typhoeus'
35
+ require 'typhoeus/adapters/faraday'
36
+
37
+ transport = Elastic::Transport::Transport::HTTP::Faraday.new(hosts: [@host]) do |f|
38
+ f.response :logger
39
+ f.adapter :typhoeus
40
+ end
41
+
42
+ client = Elastic::Transport::Client.new(transport: transport)
43
+ client.perform_request 'GET', ''
44
+ end unless jruby?
45
+
46
+ should "allow to customize the Faraday adapter to NetHttpPersistent" do
47
+ require 'net/http/persistent'
48
+
49
+ transport = Elastic::Transport::Transport::HTTP::Faraday.new(hosts: [@host]) do |f|
50
+ f.response :logger
51
+ f.adapter :net_http_persistent
52
+ end
53
+
54
+ client = Elastic::Transport::Client.new(transport: transport)
55
+ client.perform_request 'GET', ''
56
+ end
57
+
58
+ should "allow to define connection parameters and pass them" do
59
+ transport = Elastic::Transport::Transport::HTTP::Faraday.new(
60
+ hosts: [@host],
61
+ options: { transport_options: { params: { format: 'yaml' } } }
62
+ )
63
+
64
+ client = Elastic::Transport::Client.new transport: transport
65
+ response = client.perform_request 'GET', ''
66
+
67
+ assert response.body.start_with?("---\n"), "Response body should be YAML: #{response.body.inspect}"
68
+ end
69
+
70
+ should "use the Curb client" do
71
+ require 'curb'
72
+ require 'elastic/transport/transport/http/curb'
73
+
74
+ transport = Elastic::Transport::Transport::HTTP::Curb.new(hosts: [@host]) do |curl|
75
+ curl.verbose = true
76
+ end
77
+
78
+ client = Elastic::Transport::Client.new(transport: transport)
79
+ client.perform_request 'GET', ''
80
+ end unless JRUBY
81
+
82
+ should "deserialize JSON responses in the Curb client" do
83
+ require 'curb'
84
+ require 'elastic/transport/transport/http/curb'
85
+
86
+ transport = Elastic::Transport::Transport::HTTP::Curb.new(hosts: [@host]) do |curl|
87
+ curl.verbose = true
88
+ end
89
+
90
+ client = Elastic::Transport::Client.new(transport: transport)
91
+ response = client.perform_request 'GET', ''
92
+
93
+ assert_respond_to(response.body, :to_hash)
94
+ assert_not_nil response.body['name']
95
+ assert_equal 'application/json', response.headers['content-type']
96
+ end unless JRUBY
97
+ end
98
+ end
@@ -0,0 +1,132 @@
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
+ require 'test_helper'
19
+
20
+ class Elasticsearch::Transport::ClientProfilingTest < Minitest::Test
21
+ context "Elasticsearch client benchmark" do
22
+ setup do
23
+ @port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
24
+ client = Elasticsearch::Client.new host: "localhost:#{@port}", adapter: ::Faraday.default_adapter
25
+ client.perform_request 'DELETE', 'ruby_test_benchmark' rescue nil
26
+ client.perform_request 'PUT', 'ruby_test_benchmark', {}, {settings: {index: {number_of_shards: 1, number_of_replicas: 0}}}
27
+ 100.times do client.perform_request 'POST', 'ruby_test_benchmark_search/test', {}, {foo: 'bar'}; end
28
+ client.perform_request 'POST', 'ruby_test_benchmark_search/_refresh'
29
+ end
30
+ teardown do
31
+ client = Elasticsearch::Client.new host: "localhost:#{@port}"
32
+ client.perform_request 'DELETE', 'ruby_test_benchmark' rescue nil
33
+ client.perform_request 'DELETE', 'ruby_test_benchmark_search' rescue nil
34
+ end
35
+
36
+ context "with a single-node cluster and the default adapter" do
37
+ setup do
38
+ @client = Elasticsearch::Client.new hosts: "localhost:#{@port}", adapter: ::Faraday.default_adapter
39
+ end
40
+
41
+ measure "get the cluster info", count: 1_000 do
42
+ @client.perform_request 'GET', ''
43
+ end
44
+
45
+ measure "index a document" do
46
+ @client.perform_request 'POST', 'ruby_test_benchmark/test', {}, {foo: 'bar'}
47
+ end
48
+
49
+ measure "search" do
50
+ @client.perform_request 'GET', 'ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}}
51
+ end
52
+ end
53
+
54
+ context "with a two-node cluster and the default adapter" do
55
+ setup do
56
+ @client = Elasticsearch::Client.new hosts: ["localhost:#{@port}", "localhost:#{@port+1}"], adapter: ::Faraday.default_adapter
57
+ end
58
+
59
+ measure "get the cluster info", count: 1_000 do
60
+ @client.perform_request 'GET', ''
61
+ end
62
+
63
+ measure "index a document"do
64
+ @client.perform_request 'POST', 'ruby_test_benchmark/test', {}, {foo: 'bar'}
65
+ end
66
+
67
+ measure "search" do
68
+ @client.perform_request 'GET', 'ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}}
69
+ end
70
+ end
71
+
72
+ context "with a single-node cluster and the Curb client" do
73
+ setup do
74
+ require 'curb'
75
+ require 'elasticsearch/transport/transport/http/curb'
76
+ @client = Elasticsearch::Client.new host: "localhost:#{@port}",
77
+ transport_class: Elasticsearch::Transport::Transport::HTTP::Curb
78
+ end
79
+
80
+ measure "get the cluster info", count: 1_000 do
81
+ @client.perform_request 'GET', ''
82
+ end
83
+
84
+ measure "index a document" do
85
+ @client.perform_request 'POST', 'ruby_test_benchmark/test', {}, {foo: 'bar'}
86
+ end
87
+
88
+ measure "search" do
89
+ @client.perform_request 'GET', 'ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}}
90
+ end
91
+ end
92
+
93
+ context "with a single-node cluster and the Typhoeus client" do
94
+ setup do
95
+ require 'typhoeus'
96
+ require 'typhoeus/adapters/faraday'
97
+ @client = Elasticsearch::Client.new host: "localhost:#{@port}", adapter: :typhoeus
98
+ end
99
+
100
+ measure "get the cluster info", count: 1_000 do
101
+ @client.perform_request 'GET', ''
102
+ end
103
+
104
+ measure "index a document" do
105
+ @client.perform_request 'POST', 'ruby_test_benchmark/test', {}, {foo: 'bar'}
106
+ end
107
+
108
+ measure "search" do
109
+ @client.perform_request 'GET', 'ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}}
110
+ end
111
+ end
112
+
113
+ context "with a single-node cluster and the Patron adapter" do
114
+ setup do
115
+ require 'patron'
116
+ @client = Elasticsearch::Client.new host: "localhost:#{@port}", adapter: :patron
117
+ end
118
+
119
+ measure "get the cluster info", count: 1_000 do
120
+ @client.perform_request 'GET', ''
121
+ end
122
+
123
+ measure "index a document" do
124
+ @client.perform_request 'POST', 'ruby_test_benchmark/test', {}, {foo: 'bar'}
125
+ end
126
+
127
+ measure "search" do
128
+ @client.perform_request 'GET', 'ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}}
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,83 @@
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
+ password = ENV['ELASTIC_PASSWORD'] || 'changeme'
19
+ host = ENV['TEST_ES_SERVER'] || 'http://localhost:9200'
20
+ raise URI::InvalidURIError unless host =~ /\A#{URI::DEFAULT_PARSER.make_regexp}\z/
21
+
22
+ uri = URI.parse(host)
23
+ HOST = "http://elastic:#{password}@#{uri.host}:#{uri.port}".freeze
24
+
25
+ JRUBY = defined?(JRUBY_VERSION)
26
+
27
+ if ENV['COVERAGE']
28
+ require 'simplecov'
29
+ SimpleCov.start { add_filter %r{^/test/} }
30
+ end
31
+
32
+ require 'minitest/autorun'
33
+ require 'minitest/reporters'
34
+ require 'shoulda/context'
35
+ require 'mocha/minitest'
36
+ require 'ansi/code'
37
+
38
+ require 'require-prof' if ENV["REQUIRE_PROF"]
39
+ require 'elastic-transport'
40
+ require 'logger'
41
+
42
+ require 'hashie'
43
+
44
+ RequireProf.print_timing_infos if ENV["REQUIRE_PROF"]
45
+
46
+ class FixedMinitestSpecReporter < Minitest::Reporters::SpecReporter
47
+ def before_test(test)
48
+ last_test = tests.last
49
+
50
+ before_suite(test.class) unless last_test
51
+
52
+ if last_test && last_test.klass.to_s != test.class.to_s
53
+ after_suite(last_test.class) if last_test
54
+ before_suite(test.class)
55
+ end
56
+ end
57
+ end
58
+
59
+ module Minitest
60
+ class Test
61
+ def assert_nothing_raised(*args)
62
+ begin
63
+ yield
64
+ rescue RuntimeError => e
65
+ raise MiniTest::Assertion, "Exception raised:\n<#{e.class}>", e.backtrace
66
+ end
67
+ true
68
+ end
69
+
70
+ def assert_not_nil(object, msg=nil)
71
+ msg = message(msg) { "<#{object.inspect}> expected to not be nil" }
72
+ assert !object.nil?, msg
73
+ end
74
+
75
+ def assert_block(*msgs)
76
+ assert yield, *msgs
77
+ end
78
+
79
+ alias :assert_raise :assert_raises
80
+ end
81
+ end
82
+
83
+ Minitest::Reporters.use! FixedMinitestSpecReporter.new
@@ -0,0 +1,135 @@
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
+ require 'test_helper'
19
+
20
+ class Elastic::Transport::Transport::Connections::ConnectionTest < Minitest::Test
21
+ include Elastic::Transport::Transport::Connections
22
+
23
+ context "Connection" do
24
+ should "be initialized with :host, :connection, and :options" do
25
+ c = Connection.new :host => 'x', :connection => 'y', :options => {}
26
+ assert_equal 'x', c.host
27
+ assert_equal 'y', c.connection
28
+ assert_instance_of Hash, c.options
29
+ end
30
+
31
+ should "return full path" do
32
+ c = Connection.new
33
+ assert_equal '_search', c.full_path('_search')
34
+ assert_equal '_search', c.full_path('_search', {})
35
+ assert_equal '_search?foo=bar', c.full_path('_search', {:foo => 'bar'})
36
+ assert_equal '_search?foo=bar+bam', c.full_path('_search', {:foo => 'bar bam'})
37
+ end
38
+
39
+ should "return full url" do
40
+ c = Connection.new :host => { :protocol => 'http', :host => 'localhost', :port => '9200' }
41
+ assert_equal 'http://localhost:9200/_search?foo=bar', c.full_url('_search', {:foo => 'bar'})
42
+ end
43
+
44
+ should "return full url with credentials" do
45
+ c = Connection.new :host => { :protocol => 'http', :user => 'U', :password => 'P', :host => 'localhost', :port => '9200' }
46
+ assert_equal 'http://U:P@localhost:9200/_search?foo=bar', c.full_url('_search', {:foo => 'bar'})
47
+ end
48
+
49
+ should "return full url with escaped credentials" do
50
+ c = Connection.new :host => { :protocol => 'http', :user => 'U$$$', :password => 'P^^^', :host => 'localhost', :port => '9200' }
51
+ assert_equal 'http://U%24%24%24:P%5E%5E%5E@localhost:9200/_search?foo=bar', c.full_url('_search', {:foo => 'bar'})
52
+ end
53
+
54
+ should "return full url with path" do
55
+ c = Connection.new :host => { :protocol => 'http', :host => 'localhost', :port => '9200', :path => '/foo' }
56
+ assert_equal 'http://localhost:9200/foo/_search?foo=bar', c.full_url('_search', {:foo => 'bar'})
57
+ end
58
+
59
+ should "return right full url with path when path starts with /" do
60
+ c = Connection.new :host => { :protocol => 'http', :host => 'localhost', :port => '9200', :path => '/foo' }
61
+ assert_equal 'http://localhost:9200/foo/_search?foo=bar', c.full_url('/_search', {:foo => 'bar'})
62
+ end
63
+
64
+ should "have a string representation" do
65
+ c = Connection.new :host => 'x'
66
+ assert_match(/host: x/, c.to_s)
67
+ assert_match(/alive/, c.to_s)
68
+ end
69
+
70
+ should "not be dead by default" do
71
+ c = Connection.new
72
+ assert ! c.dead?
73
+ end
74
+
75
+ should "be dead when marked" do
76
+ c = Connection.new.dead!
77
+ assert c.dead?
78
+ assert_equal 1, c.failures
79
+ assert_in_delta c.dead_since, Time.now, 1
80
+ end
81
+
82
+ should "be alive when marked" do
83
+ c = Connection.new.dead!
84
+ assert c.dead?
85
+ assert_equal 1, c.failures
86
+ assert_in_delta c.dead_since, Time.now, 1
87
+
88
+ c.alive!
89
+ assert ! c.dead?
90
+ assert_equal 1, c.failures
91
+ end
92
+
93
+ should "be healthy when marked" do
94
+ c = Connection.new.dead!
95
+ assert c.dead?
96
+ assert_equal 1, c.failures
97
+ assert_in_delta c.dead_since, Time.now, 1
98
+
99
+ c.healthy!
100
+ assert ! c.dead?
101
+ assert_equal 0, c.failures
102
+ end
103
+
104
+ should "be resurrected if timeout passed" do
105
+ c = Connection.new.dead!
106
+
107
+ now = Time.now + 60
108
+ Time.stubs(:now).returns(now)
109
+
110
+ assert c.resurrect!, c.inspect
111
+ assert ! c.dead?, c.inspect
112
+ end
113
+
114
+ should "be resurrected if timeout passed for multiple failures" do
115
+ c = Connection.new.dead!.dead!
116
+
117
+ now = Time.now + 60*2
118
+ Time.stubs(:now).returns(now)
119
+
120
+ assert c.resurrect!, c.inspect
121
+ assert ! c.dead?, c.inspect
122
+ end
123
+
124
+ should "implement the equality operator" do
125
+ c1 = Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 123 })
126
+ c2 = Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 123 })
127
+ c3 = Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 456 })
128
+
129
+ assert c1 == c2, "Connection #{c1} should be equal to #{c2}"
130
+ assert c2 != c3, "Connection #{c2} should NOT be equal to #{c3}"
131
+ end
132
+
133
+ end
134
+
135
+ end