elastic-transport 8.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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