em-synchrony-moped 1.0.0.beta.1 → 1.0.0.beta.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.
- checksums.yaml +8 -8
- data/.travis.yml +5 -0
- data/Gemfile +1 -1
- data/Guardfile +1 -1
- data/README.md +9 -3
- data/em-synchrony-moped.gemspec +5 -4
- data/lib/em-synchrony/moped/cluster.rb +1 -5
- data/lib/em-synchrony/moped/connection.rb +40 -52
- data/lib/em-synchrony/moped/node.rb +8 -11
- data/spec/lib/em-synchrony/moped/connection_spec.rb +196 -71
- data/spec/lib/em-synchrony/moped/node_spec.rb +5 -3
- data/spec/spec_helper.rb +8 -0
- data/spec/support/contexts.rb +6 -4
- data/spec/support/simulated_mongod.rb +1 -1
- metadata +27 -12
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzlmYzgxNjFkMDA3MjZmY2RkYjQwMjU5NjBkMTQ4Nzc1Yzk0ZjY2NQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZjM4ZmMxNTJlZTU1MWQ1YTJhNDU3YjY3OTE3MzVhMGM2YjMzYTA5Mg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MTgyMzg5YTI5NmE0ZTI0MWU5NTA0Y2UzYjc0ZTc0M2ZlZDA1OGE1NzQ1MTlj
|
10
|
+
YTEyY2IwM2UxMjIxYmFmYzRjNzQ0NDQzYmYwN2ZlYjUzYTJmODNmZTZkM2Ex
|
11
|
+
ZmIyOTAzY2IyODMxZjlmZjljMmVhOTUxZDNhZTRhYjE5ZDc4NTU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YmVkZTRhOTYwNjBmMjc1MjdlZDM4MTIxNzAxNzhmMThjZDdmYjJkYjdjNTFj
|
14
|
+
NGFmMGUxNWMwNGQ0YjcwNmM5YjhmMjZiMjJhMGZjZjdhMzc4ZGFjNmJjZmU0
|
15
|
+
MGRmZGQ0ZDRmYzhhNGJiNWVkOTdlNWExODk4NWJkOGExZWFkOWI=
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
-
|
1
|
+
EM-Synchrony-Moped
|
2
|
+
=====
|
3
|
+
[](http://badge.fury.io/rb/em-synchrony-moped) [](https://gemnasium.com/alebsack/em-synchrony-moped) [](https://travis-ci.org/alebsack/em-synchrony-moped) [](https://coveralls.io/r/alebsack/em-synchrony-moped?branch=master) [](https://codeclimate.com/github/alebsack/em-synchrony-moped)
|
2
4
|
|
3
|
-
EM-Synchrony-Moped is a [Moped](https://github.com/mongoid/
|
5
|
+
EM-Synchrony-Moped is a [Moped](https://github.com/mongoid/moped) driver patch for [EM-Synchrony](http://github.com/igrigorik/em-synchrony). Moped is the MongoDB driver for the [Mongoid](http://github.com/mongoid/mongoid) ORM.
|
4
6
|
|
5
|
-
|
7
|
+
## Features
|
8
|
+
* Supports SSL connections and server certificate checking
|
9
|
+
* Uses an EventMachine-aware DNS lookup
|
10
|
+
* Can be included in threaded applications
|
11
|
+
* Unit tested against the threaded (original driver) behavior
|
6
12
|
|
7
13
|
## Usage
|
8
14
|
|
data/em-synchrony-moped.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'em-synchrony-moped'
|
5
|
-
s.version = "1.0.0.beta.
|
5
|
+
s.version = "1.0.0.beta.2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Adam Lebsack"]
|
@@ -19,11 +19,12 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
21
|
s.add_runtime_dependency 'eventmachine', '~> 1.0'
|
22
|
-
s.add_runtime_dependency 'em-synchrony', '~> 1.0'
|
22
|
+
s.add_runtime_dependency 'em-synchrony', '~> 1.0.3'
|
23
23
|
s.add_runtime_dependency 'moped', '~> 1.5.1'
|
24
|
-
s.add_runtime_dependency 'em-resolv-replace'
|
24
|
+
s.add_runtime_dependency 'em-resolv-replace'
|
25
25
|
|
26
|
-
s.add_development_dependency '
|
26
|
+
s.add_development_dependency 'rake'
|
27
|
+
s.add_development_dependency 'rspec'
|
27
28
|
s.add_development_dependency 'guard'
|
28
29
|
s.add_development_dependency 'guard-rspec'
|
29
30
|
s.add_development_dependency 'guard-bundler'
|
@@ -4,7 +4,7 @@ require 'moped/cluster'
|
|
4
4
|
|
5
5
|
module Moped
|
6
6
|
# Our patches to Moped::Cluster
|
7
|
-
|
7
|
+
class Cluster
|
8
8
|
def sleep(seconds)
|
9
9
|
if EventMachine.reactor_thread?
|
10
10
|
EM::Synchrony.sleep(seconds)
|
@@ -13,8 +13,4 @@ module Moped
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
17
|
-
class Cluster
|
18
|
-
include EventedCluster
|
19
|
-
end
|
20
16
|
end
|
@@ -1,26 +1,24 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require 'moped/connection'
|
4
|
+
|
3
5
|
module Moped
|
6
|
+
# Em-Synchrony overrides for Moped::Connection
|
4
7
|
class Connection
|
8
|
+
alias_method :super_connect, :connect
|
5
9
|
def connect
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
else # use old driver
|
13
|
-
if !!options[:ssl]
|
14
|
-
@sock = Sockets::SSL.connect(host, port, timeout)
|
15
|
-
else
|
16
|
-
@sock = Sockets::TCP.connect(host, port, timeout)
|
17
|
-
end
|
10
|
+
return super_connect unless EventMachine.reactor_thread?
|
11
|
+
if !!options[:ssl]
|
12
|
+
@sock = Sockets::EmSSL.em_connect(host, port, timeout, options)
|
13
|
+
else
|
14
|
+
@sock = Sockets::EmTCP.em_connect(host, port, timeout, options)
|
18
15
|
end
|
19
16
|
end
|
20
|
-
end
|
17
|
+
end
|
21
18
|
|
22
19
|
module Sockets
|
23
20
|
module Connectable
|
21
|
+
# Class methods to extend the Connectable Class
|
24
22
|
module ClassMethods
|
25
23
|
def em_connect(host, port, timeout, options)
|
26
24
|
socket = EventMachine.connect(host, port, self) do |c|
|
@@ -36,10 +34,9 @@ module Moped
|
|
36
34
|
fail SocketError, socket.unbind_reason
|
37
35
|
end
|
38
36
|
socket
|
39
|
-
|
40
37
|
rescue Errno::ETIMEDOUT
|
41
|
-
|
42
|
-
|
38
|
+
raise Errors::ConnectionFailure,
|
39
|
+
"Timed out connection to Mongo on #{host}:#{port}"
|
43
40
|
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::EPIPE,
|
44
41
|
Errno::ECONNRESET, IOError => error
|
45
42
|
fail Errors::ConnectionFailure,
|
@@ -48,10 +45,6 @@ module Moped
|
|
48
45
|
rescue SocketError => error
|
49
46
|
fail Errors::ConnectionFailure,
|
50
47
|
"#{host}:#{port}: #{error.class.name}: #{error.message}"
|
51
|
-
rescue OpenSSL::SSL::SSLError => error
|
52
|
-
fail Errors::ConnectionFailure,
|
53
|
-
"#{host}:#{port}: #{error.class.name} (#{error.errno}): " +
|
54
|
-
"#{error.message}"
|
55
48
|
end
|
56
49
|
end
|
57
50
|
end
|
@@ -59,11 +52,7 @@ module Moped
|
|
59
52
|
# The EM-Synchrony flavor of Moped::Sockets::TCP
|
60
53
|
class EmTCP < EventMachine::Synchrony::TCPSocket
|
61
54
|
include Connectable
|
62
|
-
|
63
|
-
# TODO: re-evaluate the options call. Can't we pass the caller
|
64
|
-
# up to the connection or something?
|
65
55
|
attr_accessor :options
|
66
|
-
|
67
56
|
def alive?
|
68
57
|
!closed?
|
69
58
|
end
|
@@ -73,50 +62,49 @@ module Moped
|
|
73
62
|
class EmSSL < EmTCP
|
74
63
|
def connection_completed
|
75
64
|
@verified = false
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
65
|
+
@cert_store = ssl_options.delete(:cert_store)
|
66
|
+
@cert_store ||= OpenSSL::X509::Store.new
|
67
|
+
if (cert_file = ssl_options.delete(:verify_cert))
|
68
|
+
@cert_store.add_file(cert_file)
|
80
69
|
end
|
70
|
+
start_tls(ssl_options)
|
81
71
|
end
|
82
72
|
|
83
73
|
def ssl_verify_peer(pem)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
if (cert = OpenSSL::X509::Certificate.new(pem) rescue nil)
|
90
|
-
if cert_store.verify(cert)
|
91
|
-
|
92
|
-
cert.extensions.each do |e|
|
93
|
-
if e.oid == 'basicConstraints' && e.value == 'CA:TRUE'
|
94
|
-
return true
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
host = @options[:ssl][:verify_host]
|
99
|
-
if OpenSSL::SSL.verify_certificate_identity(cert, host)
|
100
|
-
@verified = true
|
101
|
-
return true
|
102
|
-
end
|
74
|
+
return true unless ssl_options[:verify_peer]
|
75
|
+
if (cert = certificate(pem)) && @cert_store.verify(cert)
|
76
|
+
# bypass hostname checking for this cert if it's a CA
|
77
|
+
return true if cert.extensions.find do |e|
|
78
|
+
e.oid == 'basicConstraints' && e.value == 'CA:TRUE'
|
103
79
|
end
|
80
|
+
|
81
|
+
@verified = true if (host = ssl_options[:verify_host]) &&
|
82
|
+
OpenSSL::SSL.verify_certificate_identity(cert, host)
|
104
83
|
end
|
105
84
|
|
85
|
+
# Always return true. We will evaluate the certificate chain in
|
86
|
+
# ssl_handshake_completed.
|
106
87
|
true
|
107
|
-
rescue
|
108
|
-
unbind 'Failed to verify SSL certificate of peer'
|
109
|
-
false
|
110
88
|
end
|
111
89
|
|
112
90
|
def ssl_handshake_completed
|
113
|
-
if
|
91
|
+
if ssl_options[:verify_peer] && !@verified
|
114
92
|
unbind 'Failed to verify SSL certificate of peer'
|
115
93
|
else
|
116
94
|
@opening = false
|
117
95
|
@in_req.succeed self
|
118
96
|
end
|
119
97
|
end
|
120
|
-
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def ssl_options
|
102
|
+
@ssl_options ||= @options[:ssl] == true ? {} : @options[:ssl] || {}
|
103
|
+
end
|
104
|
+
|
105
|
+
def certificate(pem)
|
106
|
+
OpenSSL::X509::Certificate.new(pem)
|
107
|
+
end
|
108
|
+
end # EmSSL
|
121
109
|
end
|
122
110
|
end
|
@@ -5,15 +5,16 @@ require 'em-dns-resolver'
|
|
5
5
|
require 'fiber'
|
6
6
|
|
7
7
|
module Moped
|
8
|
-
# Our monkey patches to Moped::Node
|
9
|
-
|
8
|
+
# # Our monkey patches to Moped::Node
|
9
|
+
class Node
|
10
|
+
alias_method :super_parse_address, :parse_address
|
10
11
|
# Override to support non-blocking DNS requests
|
11
12
|
def parse_address
|
12
|
-
return
|
13
|
+
return super_parse_address unless EventMachine.reactor_thread?
|
13
14
|
host, port = address.split(':')
|
14
15
|
@port = (port || 27_017).to_i
|
15
16
|
|
16
|
-
@ip_address = em_lookup_address(host)
|
17
|
+
@ip_address = em_lookup_address(host).grep(/(::){0}/).first
|
17
18
|
fail SocketError unless @ip_address
|
18
19
|
@resolved_address = "#{@ip_address}:#{@port}"
|
19
20
|
rescue Resolv::ResolvError
|
@@ -24,7 +25,7 @@ module Moped
|
|
24
25
|
# Lookup in /etc/hosts
|
25
26
|
result = []
|
26
27
|
@hosts ||= Resolv::Hosts.new
|
27
|
-
@hosts.send(:each_address, value) { |x| result << x.to_s }
|
28
|
+
@hosts.send(:each_address, value) { |x| result << x.to_s if x !~ /::/ }
|
28
29
|
return result unless result.empty?
|
29
30
|
|
30
31
|
# Nothing, hit DNS
|
@@ -34,15 +35,11 @@ module Moped
|
|
34
35
|
fiber.resume(a)
|
35
36
|
end
|
36
37
|
df.errback do |*a|
|
37
|
-
fiber.resume(ResolvError.new(a.inspect))
|
38
|
+
fiber.resume(Resolv::ResolvError.new(a.inspect))
|
38
39
|
end
|
39
40
|
result = Fiber.yield
|
40
|
-
|
41
|
+
fail result if result.is_a?(StandardError)
|
41
42
|
result
|
42
43
|
end
|
43
44
|
end
|
44
|
-
|
45
|
-
class Node
|
46
|
-
include EventedNode
|
47
|
-
end
|
48
45
|
end
|
@@ -4,12 +4,9 @@ require 'spec_helper'
|
|
4
4
|
require 'moped'
|
5
5
|
require 'em-synchrony/moped'
|
6
6
|
|
7
|
-
# TODO: clean up a bit. we're basically testing Connection through Node.
|
8
|
-
# we should be able to test Connection by itself.
|
9
|
-
|
10
7
|
describe Moped::Connection do
|
11
8
|
it 'should have patches included' do
|
12
|
-
expect { Moped::Sockets::EmTCP }.not_to raise_error
|
9
|
+
expect { Moped::Sockets::EmTCP }.not_to raise_error
|
13
10
|
end
|
14
11
|
|
15
12
|
let(:mongod_options) { {} }
|
@@ -17,56 +14,48 @@ describe Moped::Connection do
|
|
17
14
|
let(:server_port) { server.port }
|
18
15
|
after { server.stop }
|
19
16
|
|
20
|
-
let(:
|
21
|
-
let(:
|
22
|
-
|
23
|
-
host = options.delete(:host) || '
|
24
|
-
|
17
|
+
let(:options) { {} }
|
18
|
+
let(:conn) do
|
19
|
+
timeout = 1
|
20
|
+
host = options.delete(:host) || '127.0.0.1'
|
21
|
+
port = options.delete(:port) || server_port
|
22
|
+
Moped::Connection.new(host, port, timeout, options)
|
25
23
|
end
|
26
24
|
|
27
25
|
shared_context 'common connection' do
|
28
26
|
context 'with a running server' do
|
29
27
|
it 'should connect' do
|
30
|
-
|
31
|
-
node.should be_primary
|
32
|
-
node.should be_connected
|
28
|
+
expect(conn.connect).to be_a(connection_class)
|
33
29
|
end
|
30
|
+
end
|
34
31
|
|
35
|
-
|
36
|
-
node.refresh
|
37
|
-
node.should be_primary
|
38
|
-
node.should be_connected
|
39
|
-
server.stop
|
40
|
-
expect do
|
41
|
-
node.command('admin', ismaster: 1)
|
42
|
-
end.to raise_error(
|
43
|
-
Moped::Errors::ConnectionFailure # TODO: check the message
|
44
|
-
)
|
45
|
-
node.should_not be_connected
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'with an unpresponsive host' do
|
32
|
+
context 'with an unresponsive host' do
|
50
33
|
# 127.0.0.2 seems to timeout for my tests...
|
51
|
-
let(:
|
34
|
+
let(:options) { { host: ENV['TIMEOUT_HOST'] } }
|
52
35
|
it 'should raise a timeout error' do
|
53
|
-
expect {
|
36
|
+
expect { conn.connect }.to raise_error(
|
54
37
|
Moped::Errors::ConnectionFailure,
|
55
38
|
/^Timed out connection to Mongo on/)
|
56
39
|
end
|
57
40
|
end
|
58
41
|
|
59
42
|
context 'without a server' do
|
43
|
+
let(:options) { { port: 2 } }
|
60
44
|
it 'should raise a connection error on connection refused' do
|
61
45
|
server.stop
|
62
|
-
expect {
|
46
|
+
expect { conn.connect }.to raise_error(
|
63
47
|
Moped::Errors::ConnectionFailure, /ECONNREFUSED/)
|
64
48
|
end
|
65
49
|
end
|
66
50
|
end
|
67
51
|
|
68
|
-
|
69
|
-
|
52
|
+
context 'evented' do
|
53
|
+
include_context 'with em-synchrony'
|
54
|
+
let(:connection_class) { Moped::Sockets::EmTCP }
|
55
|
+
include_context 'common connection'
|
56
|
+
context 'with ssl' do
|
57
|
+
let(:ssl_options) { nil }
|
58
|
+
let(:options) { { ssl: ssl_options } }
|
70
59
|
let(:mongod_options) do
|
71
60
|
{
|
72
61
|
ssl: {
|
@@ -77,60 +66,196 @@ describe Moped::Connection do
|
|
77
66
|
}
|
78
67
|
end
|
79
68
|
|
80
|
-
context 'without
|
81
|
-
let(:
|
82
|
-
|
83
|
-
|
84
|
-
|
69
|
+
context 'without specifying ssl' do
|
70
|
+
let(:ssl_options) { nil }
|
71
|
+
let(:options) { {} }
|
72
|
+
it 'should connect (though comms will fail later)' do
|
73
|
+
expect(conn.connect).to be_a(Moped::Sockets::EmTCP)
|
85
74
|
end
|
86
75
|
end
|
87
76
|
|
88
|
-
context '
|
89
|
-
|
90
|
-
{
|
91
|
-
|
92
|
-
|
93
|
-
|
77
|
+
context 'and a server with a trusted certificate' do
|
78
|
+
context 'when specifying ssl: true' do
|
79
|
+
let(:ssl_options) { true }
|
80
|
+
it 'should connect' do
|
81
|
+
expect(conn.connect).to be_a(Moped::Sockets::EmSSL)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'when specifying ssl: {}' do
|
86
|
+
let(:ssl_options) { {} }
|
87
|
+
it 'should connect' do
|
88
|
+
expect(conn.connect).to be_a(Moped::Sockets::EmSSL)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'when not verifying peer' do
|
93
|
+
let(:ssl_options) { { verify_peer: false } }
|
94
|
+
it 'should connect' do
|
95
|
+
expect(conn.connect).to be_a(Moped::Sockets::EmSSL)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'when verifying peer' do
|
100
|
+
context 'and no certificate provided' do
|
101
|
+
let(:ssl_options) { { verify_peer: true } }
|
102
|
+
it 'should raise an error' do
|
103
|
+
expect { conn.connect }
|
104
|
+
.to raise_error(
|
105
|
+
Moped::Errors::ConnectionFailure,
|
106
|
+
/Failed to verify SSL certificate of peer/
|
107
|
+
)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'and a certificate is provided' do
|
112
|
+
context 'and verify_host is not provided' do
|
113
|
+
let(:ssl_options) do
|
114
|
+
{
|
115
|
+
verify_peer: true,
|
116
|
+
verify_cert: "#{SSL_DIR}/ca_cert.pem"
|
117
|
+
}
|
118
|
+
end
|
119
|
+
it 'should raise an error' do
|
120
|
+
expect { conn.connect }
|
121
|
+
.to raise_error(
|
122
|
+
Moped::Errors::ConnectionFailure,
|
123
|
+
/Failed to verify SSL certificate of peer/
|
124
|
+
)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
context 'and verify_host does not match the server cert' do
|
128
|
+
let(:ssl_options) do
|
129
|
+
{
|
130
|
+
verify_peer: true,
|
131
|
+
verify_cert: "#{SSL_DIR}/ca_cert.pem",
|
132
|
+
verify_host: 'remotehost'
|
133
|
+
}
|
134
|
+
end
|
135
|
+
it 'should raise an error' do
|
136
|
+
expect { conn.connect }
|
137
|
+
.to raise_error(
|
138
|
+
Moped::Errors::ConnectionFailure,
|
139
|
+
/Failed to verify SSL certificate of peer/
|
140
|
+
)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
context 'and verify_host matches the server cert' do
|
144
|
+
let(:ssl_options) do
|
145
|
+
{
|
146
|
+
verify_peer: true,
|
147
|
+
verify_cert: "#{SSL_DIR}/ca_cert.pem",
|
148
|
+
verify_host: 'localhost'
|
149
|
+
}
|
150
|
+
end
|
151
|
+
it 'should connect' do
|
152
|
+
expect(conn.connect).to be_a(Moped::Sockets::EmSSL)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end # 'and a certificate is provided'
|
156
|
+
end # 'when verifying peer'
|
157
|
+
end # server with a trusted certificate
|
158
|
+
context 'and a server with an untrusted certificate' do
|
159
|
+
let(:mongod_options) do
|
160
|
+
{
|
161
|
+
ssl: {
|
162
|
+
private_key_file: "#{SSL_DIR}/untrusted.key",
|
163
|
+
cert_chain_file: "#{SSL_DIR}/untrusted.crt",
|
164
|
+
verify_peer: false
|
94
165
|
}
|
95
166
|
}
|
96
167
|
end
|
97
|
-
|
98
|
-
|
99
|
-
|
168
|
+
|
169
|
+
context 'when specifying ssl: true' do
|
170
|
+
let(:ssl_options) { true }
|
171
|
+
it 'should connect' do
|
172
|
+
expect(conn.connect).to be_a(Moped::Sockets::EmSSL)
|
173
|
+
end
|
100
174
|
end
|
101
175
|
|
102
|
-
context '
|
103
|
-
let(:
|
104
|
-
|
105
|
-
|
106
|
-
private_key_file: "#{SSL_DIR}/untrusted.key",
|
107
|
-
cert_chain_file: "#{SSL_DIR}/untrusted.crt",
|
108
|
-
verify_peer: false
|
109
|
-
}
|
110
|
-
}
|
176
|
+
context 'when specifying ssl: {}' do
|
177
|
+
let(:ssl_options) { {} }
|
178
|
+
it 'should connect' do
|
179
|
+
expect(conn.connect).to be_a(Moped::Sockets::EmSSL)
|
111
180
|
end
|
181
|
+
end
|
112
182
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
end.to raise_error(
|
118
|
-
Moped::Errors::ConnectionFailure,
|
119
|
-
/Failed to verify SSL certificate of peer/
|
120
|
-
)
|
183
|
+
context 'when not verifying peer' do
|
184
|
+
let(:ssl_options) { { verify_peer: false } }
|
185
|
+
it 'should connect' do
|
186
|
+
expect(conn.connect).to be_a(Moped::Sockets::EmSSL)
|
121
187
|
end
|
122
188
|
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
189
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
190
|
+
context 'when verifying peer' do
|
191
|
+
context 'and no certificate provided' do
|
192
|
+
let(:ssl_options) { { verify_peer: true } }
|
193
|
+
it 'should raise an error' do
|
194
|
+
expect { conn.connect }
|
195
|
+
.to raise_error(
|
196
|
+
Moped::Errors::ConnectionFailure,
|
197
|
+
/Failed to verify SSL certificate of peer/
|
198
|
+
)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'and a certificate is provided' do
|
203
|
+
context 'and verify_host is not provided' do
|
204
|
+
let(:ssl_options) do
|
205
|
+
{
|
206
|
+
verify_peer: true,
|
207
|
+
verify_cert: "#{SSL_DIR}/ca_cert.pem"
|
208
|
+
}
|
209
|
+
end
|
210
|
+
it 'should raise an error' do
|
211
|
+
expect { conn.connect }
|
212
|
+
.to raise_error(
|
213
|
+
Moped::Errors::ConnectionFailure,
|
214
|
+
/Failed to verify SSL certificate of peer/
|
215
|
+
)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
context 'and verify_host does not match the server cert' do
|
219
|
+
let(:ssl_options) do
|
220
|
+
{
|
221
|
+
verify_peer: true,
|
222
|
+
verify_cert: "#{SSL_DIR}/ca_cert.pem",
|
223
|
+
verify_host: 'remotehost'
|
224
|
+
}
|
225
|
+
end
|
226
|
+
it 'should raise an error' do
|
227
|
+
expect { conn.connect }
|
228
|
+
.to raise_error(
|
229
|
+
Moped::Errors::ConnectionFailure,
|
230
|
+
/Failed to verify SSL certificate of peer/
|
231
|
+
)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
context 'and verify_host matches the server cert' do
|
235
|
+
let(:ssl_options) do
|
236
|
+
{
|
237
|
+
verify_peer: true,
|
238
|
+
verify_cert: "#{SSL_DIR}/ca_cert.pem",
|
239
|
+
verify_host: 'localhost'
|
240
|
+
}
|
241
|
+
end
|
242
|
+
it 'should raise an error' do
|
243
|
+
expect { conn.connect }
|
244
|
+
.to raise_error(
|
245
|
+
Moped::Errors::ConnectionFailure,
|
246
|
+
/Failed to verify SSL certificate of peer/
|
247
|
+
)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end # 'and a certificate is provided'
|
251
|
+
end # 'when verifying peer'
|
252
|
+
end # 'and a server with an untrusted certificate'
|
253
|
+
end # 'with ssl'
|
254
|
+
end # 'evented'
|
255
|
+
|
132
256
|
context 'threaded' do
|
133
257
|
include_context 'without em-synchrony'
|
258
|
+
let(:connection_class) { Moped::Sockets::TCP }
|
134
259
|
include_context 'common connection'
|
135
260
|
end
|
136
261
|
|
@@ -14,7 +14,8 @@ describe Moped::Node do
|
|
14
14
|
let(:node) do
|
15
15
|
options = node_options.merge(timeout: 1)
|
16
16
|
host = options.delete(:host) || 'localhost'
|
17
|
-
|
17
|
+
port = options.delete(:port) || server_port
|
18
|
+
Moped::Node.new("#{host}:#{port}", options)
|
18
19
|
end
|
19
20
|
|
20
21
|
shared_context 'common node' do
|
@@ -39,9 +40,9 @@ describe Moped::Node do
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
42
|
-
context 'with an
|
43
|
+
context 'with an unresponsive host' do
|
43
44
|
# 127.0.0.2 seems to timeout for my tests...
|
44
|
-
let(:node_options) { { host: '
|
45
|
+
let(:node_options) { { host: ENV['TIMEOUT_HOST'] } }
|
45
46
|
it 'should raise a timeout error' do
|
46
47
|
expect { node.refresh }.to raise_error(
|
47
48
|
Moped::Errors::ConnectionFailure,
|
@@ -58,6 +59,7 @@ describe Moped::Node do
|
|
58
59
|
end
|
59
60
|
|
60
61
|
context 'without a server' do
|
62
|
+
let(:node_options) { { port: 2 } }
|
61
63
|
it 'should raise a connection error on connection refused' do
|
62
64
|
server.stop
|
63
65
|
expect { node.refresh }.to raise_error(
|
data/spec/spec_helper.rb
CHANGED
@@ -10,8 +10,16 @@ Spork.prefork do
|
|
10
10
|
# if you change any configuration or code from libraries loaded here, you'll
|
11
11
|
# need to restart spork for it take effect.
|
12
12
|
|
13
|
+
ENV['TIMEOUT_HOST'] ||= 'www.google.com'
|
14
|
+
|
13
15
|
require 'rspec'
|
14
16
|
require 'simplecov'
|
17
|
+
require 'coveralls'
|
18
|
+
|
19
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
20
|
+
SimpleCov::Formatter::HTMLFormatter,
|
21
|
+
Coveralls::SimpleCov::Formatter
|
22
|
+
]
|
15
23
|
SimpleCov.start do
|
16
24
|
add_group 'Lib', 'lib'
|
17
25
|
add_filter '/spec/'
|
data/spec/support/contexts.rb
CHANGED
@@ -5,11 +5,12 @@ shared_context 'with em-synchrony' do
|
|
5
5
|
require 'em-synchrony'
|
6
6
|
EventMachine.error_handler do |e|
|
7
7
|
puts "Error in Eventmachine: #{e.inspect}"
|
8
|
-
|
8
|
+
puts e.backtrace.join("\n")
|
9
|
+
EventMachine.stop
|
9
10
|
end
|
10
11
|
EventMachine.synchrony do
|
11
12
|
example.run
|
12
|
-
|
13
|
+
EventMachine.stop if EventMachine.reactor_running?
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
@@ -18,7 +19,8 @@ shared_context 'without em-synchrony' do
|
|
18
19
|
before(:each) do
|
19
20
|
EventMachine.error_handler do |e|
|
20
21
|
puts "Error in Eventmachine: #{e.inspect}"
|
21
|
-
|
22
|
+
puts e.backtrace.join("\n")
|
23
|
+
EventMachine.stop
|
22
24
|
end
|
23
25
|
queue = Queue.new
|
24
26
|
@em_thread = Thread.new { EventMachine.run { queue << true } }
|
@@ -26,7 +28,7 @@ shared_context 'without em-synchrony' do
|
|
26
28
|
end
|
27
29
|
|
28
30
|
after(:each) do
|
29
|
-
|
31
|
+
EventMachine.stop
|
30
32
|
@em_thread.join
|
31
33
|
end
|
32
34
|
end
|
@@ -134,7 +134,7 @@ class FakeMongodServer
|
|
134
134
|
ensure_reactor do
|
135
135
|
@server = EventMachine.start_server(
|
136
136
|
@host, 0, FakeMongod, @options, self)
|
137
|
-
@port = Socket.unpack_sockaddr_in(
|
137
|
+
@port = Socket.unpack_sockaddr_in(EventMachine.get_sockname(@server))[0]
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-synchrony-moped
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.beta.
|
4
|
+
version: 1.0.0.beta.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Lebsack
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.0.3
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 1.0.3
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: moped
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,30 +56,44 @@ dependencies:
|
|
56
56
|
name: em-resolv-replace
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: '0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ! '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rspec
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- -
|
87
|
+
- - ! '>='
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
89
|
+
version: '0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- -
|
94
|
+
- - ! '>='
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: guard
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -187,6 +201,7 @@ extensions: []
|
|
187
201
|
extra_rdoc_files: []
|
188
202
|
files:
|
189
203
|
- .gitignore
|
204
|
+
- .travis.yml
|
190
205
|
- Gemfile
|
191
206
|
- Guardfile
|
192
207
|
- README.md
|