mongo 0.17.1 → 0.18
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +69 -47
- data/Rakefile +26 -0
- data/lib/mongo.rb +2 -2
- data/lib/mongo/admin.rb +3 -3
- data/lib/mongo/collection.rb +51 -29
- data/lib/mongo/connection.rb +476 -94
- data/lib/mongo/cursor.rb +19 -17
- data/lib/mongo/db.rb +52 -324
- data/lib/mongo/errors.rb +9 -0
- data/lib/mongo/gridfs/grid_store.rb +1 -1
- data/lib/mongo/util/conversions.rb +4 -36
- data/test/replica/count_test.rb +34 -0
- data/test/replica/insert_test.rb +50 -0
- data/test/replica/pooled_insert_test.rb +54 -0
- data/test/replica/query_test.rb +39 -0
- data/test/test_collection.rb +23 -10
- data/test/test_connection.rb +19 -20
- data/test/test_conversions.rb +2 -2
- data/test/test_cursor.rb +18 -18
- data/test/test_db.rb +26 -35
- data/test/test_db_api.rb +9 -30
- data/test/test_helper.rb +15 -0
- data/test/test_slave_connection.rb +5 -4
- data/test/test_threading.rb +2 -2
- data/test/threading/test_threading_large_pool.rb +90 -0
- data/test/unit/collection_test.rb +13 -15
- data/test/unit/connection_test.rb +122 -0
- data/test/unit/cursor_test.rb +4 -32
- data/test/unit/db_test.rb +4 -32
- metadata +8 -2
data/test/test_db.rb
CHANGED
@@ -17,9 +17,10 @@ class DBTest < Test::Unit::TestCase
|
|
17
17
|
|
18
18
|
include Mongo
|
19
19
|
|
20
|
-
@@host
|
21
|
-
@@port
|
22
|
-
@@
|
20
|
+
@@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
21
|
+
@@port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
|
22
|
+
@@conn = Connection.new(@@host, @@port)
|
23
|
+
@@db = @@conn.db('ruby-mongo-test')
|
23
24
|
@@users = @@db.collection('system.users')
|
24
25
|
|
25
26
|
def setup
|
@@ -35,8 +36,8 @@ class DBTest < Test::Unit::TestCase
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def test_close
|
38
|
-
@@
|
39
|
-
assert !@@
|
39
|
+
@@conn.close
|
40
|
+
assert !@@conn.connected?
|
40
41
|
begin
|
41
42
|
@@db.collection('test').insert('a' => 1)
|
42
43
|
fail "expected 'NilClass' exception"
|
@@ -52,10 +53,10 @@ class DBTest < Test::Unit::TestCase
|
|
52
53
|
output = StringIO.new
|
53
54
|
logger = Logger.new(output)
|
54
55
|
logger.level = Logger::DEBUG
|
55
|
-
|
56
|
-
assert_equal logger,
|
56
|
+
conn = Connection.new(@host, @port, :logger => logger)
|
57
|
+
assert_equal logger, conn.logger
|
57
58
|
|
58
|
-
|
59
|
+
conn.logger.debug 'testing'
|
59
60
|
assert output.string.include?('testing')
|
60
61
|
end
|
61
62
|
|
@@ -89,12 +90,16 @@ class DBTest < Test::Unit::TestCase
|
|
89
90
|
end
|
90
91
|
|
91
92
|
def test_pair
|
92
|
-
@@
|
93
|
+
@@conn.close
|
93
94
|
@@users = nil
|
94
|
-
@@
|
95
|
-
|
95
|
+
@@conn = Connection.new({:left => "this-should-fail", :right => [@@host, @@port]})
|
96
|
+
@@db = @@conn['ruby-mongo-test']
|
97
|
+
assert @@conn.connected?
|
96
98
|
ensure
|
97
|
-
|
99
|
+
unless @@conn.connected?
|
100
|
+
@@conn = Connection.new(@@host, @@port)
|
101
|
+
@@db = @@conn.db('ruby-mongo-test')
|
102
|
+
end
|
98
103
|
@@users = @@db.collection('system.users')
|
99
104
|
end
|
100
105
|
|
@@ -122,7 +127,8 @@ class DBTest < Test::Unit::TestCase
|
|
122
127
|
end
|
123
128
|
|
124
129
|
def test_pk_factory_reset
|
125
|
-
|
130
|
+
conn = Connection.new(@@host, @@port)
|
131
|
+
db = conn.db('ruby-mongo-test')
|
126
132
|
db.pk_factory = Object.new # first time
|
127
133
|
begin
|
128
134
|
db.pk_factory = Object.new
|
@@ -130,7 +136,7 @@ class DBTest < Test::Unit::TestCase
|
|
130
136
|
rescue => ex
|
131
137
|
assert_match /can not change PK factory/, ex.to_s
|
132
138
|
ensure
|
133
|
-
|
139
|
+
conn.close
|
134
140
|
end
|
135
141
|
end
|
136
142
|
|
@@ -144,33 +150,18 @@ class DBTest < Test::Unit::TestCase
|
|
144
150
|
@@db.logout # only testing that we don't throw exception
|
145
151
|
end
|
146
152
|
|
147
|
-
def test_auto_connect
|
148
|
-
@@db.close
|
149
|
-
db = Connection.new(@@host, @@port, :auto_reconnect => true).db('ruby-mongo-test')
|
150
|
-
assert db.connected?
|
151
|
-
assert db.auto_reconnect?
|
152
|
-
db.close
|
153
|
-
assert !db.connected?
|
154
|
-
assert db.auto_reconnect?
|
155
|
-
db.collection('test').insert('a' => 1)
|
156
|
-
assert db.connected?
|
157
|
-
ensure
|
158
|
-
@@db = Connection.new(@@host, @@port).db('ruby-mongo-test')
|
159
|
-
@@users = @@db.collection('system.users')
|
160
|
-
end
|
161
|
-
|
162
153
|
def test_error
|
163
154
|
@@db.reset_error_history
|
164
155
|
assert_nil @@db.error
|
165
156
|
assert !@@db.error?
|
166
157
|
assert_nil @@db.previous_error
|
167
158
|
|
168
|
-
@@db.send(:
|
159
|
+
@@db.send(:command, :forceerror => 1)
|
169
160
|
assert @@db.error?
|
170
161
|
assert_not_nil @@db.error
|
171
162
|
assert_not_nil @@db.previous_error
|
172
163
|
|
173
|
-
@@db.send(:
|
164
|
+
@@db.send(:command, :forceerror => 1)
|
174
165
|
assert @@db.error?
|
175
166
|
assert @@db.error
|
176
167
|
prev_error = @@db.previous_error
|
@@ -207,10 +198,10 @@ class DBTest < Test::Unit::TestCase
|
|
207
198
|
assert !@@db.last_status()["updatedExisting"]
|
208
199
|
end
|
209
200
|
|
210
|
-
def
|
211
|
-
|
212
|
-
|
213
|
-
db.collection('users').remove
|
201
|
+
def test_text_port_number_raises_no_errors
|
202
|
+
conn = Connection.new(@@host, @@port.to_s)
|
203
|
+
db = conn['ruby-mongo-test']
|
204
|
+
assert db.collection('users').remove
|
214
205
|
end
|
215
206
|
|
216
207
|
end
|
data/test/test_db_api.rb
CHANGED
@@ -6,11 +6,11 @@ require 'test/unit'
|
|
6
6
|
class DBAPITest < Test::Unit::TestCase
|
7
7
|
include Mongo
|
8
8
|
|
9
|
-
@@
|
9
|
+
@@conn = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
|
10
10
|
ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT)
|
11
|
-
@@db = @@
|
11
|
+
@@db = @@conn.db("ruby-mongo-test")
|
12
12
|
@@coll = @@db.collection('test')
|
13
|
-
@@version = @@
|
13
|
+
@@version = @@conn.server_version
|
14
14
|
|
15
15
|
def setup
|
16
16
|
@@coll.remove
|
@@ -95,7 +95,7 @@ class DBAPITest < Test::Unit::TestCase
|
|
95
95
|
# Can't compare _id values because at insert, an _id was added to @r1 by
|
96
96
|
# the database but we don't know what it is without re-reading the record
|
97
97
|
# (which is what we are doing right now).
|
98
|
-
#
|
98
|
+
# assert_equal doc['_id'], @r1['_id']
|
99
99
|
assert_equal doc['a'], @r1['a']
|
100
100
|
end
|
101
101
|
|
@@ -167,7 +167,7 @@ class DBAPITest < Test::Unit::TestCase
|
|
167
167
|
assert_equal 1, docs[3]['a']
|
168
168
|
|
169
169
|
# Sorting using array of names; assumes ascending order.
|
170
|
-
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort =>
|
170
|
+
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => 'a').to_a
|
171
171
|
assert_equal 4, docs.size
|
172
172
|
assert_equal 1, docs[0]['a']
|
173
173
|
assert_equal 2, docs[1]['a']
|
@@ -197,22 +197,9 @@ class DBAPITest < Test::Unit::TestCase
|
|
197
197
|
# order of the keys won't be guaranteed thus your sort won't make sense.
|
198
198
|
oh = OrderedHash.new
|
199
199
|
oh['a'] = -1
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
assert_equal 3, docs[1]['a']
|
204
|
-
assert_equal 2, docs[2]['a']
|
205
|
-
assert_equal 1, docs[3]['a']
|
206
|
-
|
207
|
-
oh = OrderedHash.new
|
208
|
-
oh['b'] = -1
|
209
|
-
oh['a'] = 1
|
210
|
-
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a
|
211
|
-
assert_equal 4, docs.size
|
212
|
-
assert_equal 1, docs[0]['a']
|
213
|
-
assert_equal 3, docs[1]['a']
|
214
|
-
assert_equal 2, docs[2]['a']
|
215
|
-
assert_equal 4, docs[3]['a']
|
200
|
+
assert_raise InvalidSortValueError do
|
201
|
+
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a
|
202
|
+
end
|
216
203
|
end
|
217
204
|
|
218
205
|
def test_find_limits
|
@@ -488,14 +475,6 @@ class DBAPITest < Test::Unit::TestCase
|
|
488
475
|
end
|
489
476
|
end
|
490
477
|
|
491
|
-
def test_ismaster
|
492
|
-
assert @@db.master?
|
493
|
-
end
|
494
|
-
|
495
|
-
def test_master
|
496
|
-
assert_equal "#{@@db.host}:#{@@db.port}", @@db.master
|
497
|
-
end
|
498
|
-
|
499
478
|
def test_where
|
500
479
|
@@coll.insert('a' => 2)
|
501
480
|
@@coll.insert('a' => 3)
|
@@ -776,7 +755,7 @@ class DBAPITest < Test::Unit::TestCase
|
|
776
755
|
# doesn't really test functionality, just that the option is set correctly
|
777
756
|
def test_snapshot
|
778
757
|
@@db.collection("test").find({}, :snapshot => true).to_a
|
779
|
-
assert_raise
|
758
|
+
assert_raise OperationFailure do
|
780
759
|
@@db.collection("test").find({}, :snapshot => true, :sort => 'a').to_a
|
781
760
|
end
|
782
761
|
end
|
data/test/test_helper.rb
CHANGED
@@ -22,4 +22,19 @@ require 'mongo'
|
|
22
22
|
# NOTE: most tests assume that MongoDB is running.
|
23
23
|
class Test::Unit::TestCase
|
24
24
|
include Mongo
|
25
|
+
|
26
|
+
# Generic code for rescuing connection failures and retrying operations.
|
27
|
+
# This could be combined with some timeout functionality.
|
28
|
+
def rescue_connection_failure
|
29
|
+
success = false
|
30
|
+
while !success
|
31
|
+
begin
|
32
|
+
yield
|
33
|
+
success = true
|
34
|
+
rescue Mongo::ConnectionFailure
|
35
|
+
puts "Rescuing"
|
36
|
+
sleep(1)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
25
40
|
end
|
@@ -9,8 +9,9 @@ class SlaveConnectionTest < Test::Unit::TestCase
|
|
9
9
|
def self.connect_to_slave
|
10
10
|
@@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
11
11
|
@@port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
|
12
|
-
|
13
|
-
|
12
|
+
conn = Connection.new(@@host, @@port, :slave_ok => true)
|
13
|
+
cmd = conn['admin'].command(:ismaster => 1)
|
14
|
+
cmd['ok'] == 1 && cmd['ismaster'] != 1
|
14
15
|
end
|
15
16
|
|
16
17
|
if self.connect_to_slave
|
@@ -30,8 +31,8 @@ class SlaveConnectionTest < Test::Unit::TestCase
|
|
30
31
|
puts "Not connected to slave; skipping slave connection tests."
|
31
32
|
|
32
33
|
def test_slave_ok_false_on_queries
|
33
|
-
@
|
34
|
-
assert !@
|
34
|
+
@conn = Connection.new(@@host, @@port)
|
35
|
+
assert !@conn.slave_ok?
|
35
36
|
end
|
36
37
|
end
|
37
38
|
end
|
data/test/test_threading.rb
CHANGED
@@ -4,14 +4,14 @@ class TestThreading < Test::Unit::TestCase
|
|
4
4
|
|
5
5
|
include Mongo
|
6
6
|
|
7
|
-
@@db = Connection.new.db('ruby-mongo-test')
|
7
|
+
@@db = Connection.new('localhost', 27017, :pool_size => 1, :timeout => 3).db('ruby-mongo-test')
|
8
8
|
@@coll = @@db.collection('thread-test-collection')
|
9
9
|
|
10
10
|
def set_up_safe_data
|
11
11
|
@@db.drop_collection('duplicate')
|
12
12
|
@@db.drop_collection('unique')
|
13
13
|
@duplicate = @@db.collection('duplicate')
|
14
|
-
@unique = @@db.collection('unique')
|
14
|
+
@unique = @@db.collection('unique')
|
15
15
|
|
16
16
|
@duplicate.insert("test" => "insert")
|
17
17
|
@duplicate.insert("test" => "update")
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
# Essentialy the same as test_threading.rb but with an expanded pool for
|
4
|
+
# testing multiple connections.
|
5
|
+
class TestThreadingLargePool < Test::Unit::TestCase
|
6
|
+
|
7
|
+
include Mongo
|
8
|
+
|
9
|
+
@@db = Connection.new('localhost', 27017, :pool_size => 50, :timeout => 15).db('ruby-mongo-test')
|
10
|
+
@@coll = @@db.collection('thread-test-collection')
|
11
|
+
|
12
|
+
def set_up_safe_data
|
13
|
+
@@db.drop_collection('duplicate')
|
14
|
+
@@db.drop_collection('unique')
|
15
|
+
@duplicate = @@db.collection('duplicate')
|
16
|
+
@unique = @@db.collection('unique')
|
17
|
+
|
18
|
+
@duplicate.insert("test" => "insert")
|
19
|
+
@duplicate.insert("test" => "update")
|
20
|
+
@unique.insert("test" => "insert")
|
21
|
+
@unique.insert("test" => "update")
|
22
|
+
@unique.create_index("test", true)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_safe_update
|
26
|
+
set_up_safe_data
|
27
|
+
threads = []
|
28
|
+
100.times do |i|
|
29
|
+
threads[i] = Thread.new do
|
30
|
+
if i % 2 == 0
|
31
|
+
assert_raise Mongo::OperationFailure do
|
32
|
+
@unique.update({"test" => "insert"}, {"$set" => {"test" => "update"}}, :safe => true)
|
33
|
+
end
|
34
|
+
else
|
35
|
+
@duplicate.update({"test" => "insert"}, {"$set" => {"test" => "update"}}, :safe => true)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
100.times do |i|
|
41
|
+
threads[i].join
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_safe_insert
|
46
|
+
set_up_safe_data
|
47
|
+
threads = []
|
48
|
+
100.times do |i|
|
49
|
+
threads[i] = Thread.new do
|
50
|
+
if i % 2 == 0
|
51
|
+
assert_raise Mongo::OperationFailure do
|
52
|
+
@unique.insert({"test" => "insert"}, :safe => true)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
@duplicate.insert({"test" => "insert"}, :safe => true)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
100.times do |i|
|
61
|
+
threads[i].join
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_threading
|
66
|
+
@@coll.drop
|
67
|
+
@@coll = @@db.collection('thread-test-collection')
|
68
|
+
|
69
|
+
1000.times do |i|
|
70
|
+
@@coll.insert("x" => i)
|
71
|
+
end
|
72
|
+
|
73
|
+
threads = []
|
74
|
+
|
75
|
+
10.times do |i|
|
76
|
+
threads[i] = Thread.new do
|
77
|
+
sum = 0
|
78
|
+
@@coll.find().each do |document|
|
79
|
+
sum += document["x"]
|
80
|
+
end
|
81
|
+
assert_equal 499500, sum
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
10.times do |i|
|
86
|
+
threads[i].join
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -1,12 +1,6 @@
|
|
1
1
|
require 'test/test_helper'
|
2
2
|
|
3
|
-
class
|
4
|
-
|
5
|
-
class MockDB < DB
|
6
|
-
def connect_to_master
|
7
|
-
true
|
8
|
-
end
|
9
|
-
end
|
3
|
+
class ConnectionTest < Test::Unit::TestCase
|
10
4
|
|
11
5
|
context "Basic operations: " do
|
12
6
|
setup do
|
@@ -14,36 +8,40 @@ class CollectionTest < Test::Unit::TestCase
|
|
14
8
|
end
|
15
9
|
|
16
10
|
should "send update message" do
|
17
|
-
@
|
11
|
+
@conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
|
12
|
+
@db = @conn['testing']
|
18
13
|
@coll = @db.collection('books')
|
19
|
-
@
|
14
|
+
@conn.expects(:send_message).with do |op, msg, log|
|
20
15
|
op == 2001 && log.include?("db.books.update")
|
21
16
|
end
|
22
17
|
@coll.update({}, {:title => 'Moby Dick'})
|
23
18
|
end
|
24
19
|
|
25
20
|
should "send insert message" do
|
26
|
-
@
|
21
|
+
@conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
|
22
|
+
@db = @conn['testing']
|
27
23
|
@coll = @db.collection('books')
|
28
|
-
@
|
24
|
+
@conn.expects(:send_message).with do |op, msg, log|
|
29
25
|
op == 2002 && log.include?("db.books.insert")
|
30
26
|
end
|
31
27
|
@coll.insert({:title => 'Moby Dick'})
|
32
28
|
end
|
33
29
|
|
34
30
|
should "send safe update message" do
|
35
|
-
@
|
31
|
+
@conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
|
32
|
+
@db = @conn['testing']
|
36
33
|
@coll = @db.collection('books')
|
37
|
-
@
|
34
|
+
@conn.expects(:send_message_with_safe_check).with do |op, msg, db_name, log|
|
38
35
|
op == 2001 && log.include?("db.books.update")
|
39
36
|
end
|
40
37
|
@coll.update({}, {:title => 'Moby Dick'}, :safe => true)
|
41
38
|
end
|
42
39
|
|
43
40
|
should "send safe insert message" do
|
44
|
-
@
|
41
|
+
@conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
|
42
|
+
@db = @conn['testing']
|
45
43
|
@coll = @db.collection('books')
|
46
|
-
@
|
44
|
+
@conn.expects(:send_message_with_safe_check).with do |op, msg, db_name, log|
|
47
45
|
op == 2001 && log.include?("db.books.update")
|
48
46
|
end
|
49
47
|
@coll.update({}, {:title => 'Moby Dick'}, :safe => true)
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class ConnectionTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def new_mock_socket
|
6
|
+
socket = Object.new
|
7
|
+
socket.stubs(:setsockopt).with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
8
|
+
socket
|
9
|
+
end
|
10
|
+
|
11
|
+
def new_mock_db
|
12
|
+
db = Object.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# Make a few methods public for these tests.
|
16
|
+
class Mongo::Connection
|
17
|
+
public :checkin, :checkout, :clear_stale_cached_connections!
|
18
|
+
end
|
19
|
+
|
20
|
+
context "Initialization: " do
|
21
|
+
|
22
|
+
context "given a single node" do
|
23
|
+
setup do
|
24
|
+
TCPSocket.stubs(:new).returns(new_mock_socket)
|
25
|
+
@conn = Connection.new('localhost', 27107, :connect => false)
|
26
|
+
|
27
|
+
admin_db = new_mock_db
|
28
|
+
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
|
29
|
+
@conn.expects(:[]).with('admin').returns(admin_db)
|
30
|
+
@conn.connect_to_master
|
31
|
+
end
|
32
|
+
|
33
|
+
should "set localhost and port to master" do
|
34
|
+
assert_equal 'localhost', @conn.host
|
35
|
+
assert_equal 27017, @conn.port
|
36
|
+
end
|
37
|
+
|
38
|
+
should "set connection pool to 1" do
|
39
|
+
assert_equal 1, @conn.size
|
40
|
+
end
|
41
|
+
|
42
|
+
should "default slave_ok to false" do
|
43
|
+
assert !@conn.slave_ok?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "Connection pooling: " do
|
49
|
+
setup do
|
50
|
+
TCPSocket.stubs(:new).returns(new_mock_socket)
|
51
|
+
@conn = Connection.new('localhost', 27107, :connect => false,
|
52
|
+
:pool_size => 3)
|
53
|
+
|
54
|
+
admin_db = new_mock_db
|
55
|
+
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
|
56
|
+
@conn.expects(:[]).with('admin').returns(admin_db)
|
57
|
+
@conn.connect_to_master
|
58
|
+
end
|
59
|
+
|
60
|
+
should "check out a new connection" do
|
61
|
+
socket = @conn.checkout
|
62
|
+
assert @conn.reserved_connections.keys.include?(Thread.current.object_id)
|
63
|
+
end
|
64
|
+
|
65
|
+
context "with multiple threads" do
|
66
|
+
setup do
|
67
|
+
@thread1 = Object.new
|
68
|
+
@thread2 = Object.new
|
69
|
+
@thread3 = Object.new
|
70
|
+
@thread4 = Object.new
|
71
|
+
|
72
|
+
Thread.stubs(:current).returns(@thread1)
|
73
|
+
@socket1 = @conn.checkout
|
74
|
+
Thread.stubs(:current).returns(@thread2)
|
75
|
+
@socket2 = @conn.checkout
|
76
|
+
Thread.stubs(:current).returns(@thread3)
|
77
|
+
@socket3 = @conn.checkout
|
78
|
+
end
|
79
|
+
|
80
|
+
should "add each thread to the reserved pool" do
|
81
|
+
assert @conn.reserved_connections.keys.include?(@thread1.object_id)
|
82
|
+
assert @conn.reserved_connections.keys.include?(@thread2.object_id)
|
83
|
+
assert @conn.reserved_connections.keys.include?(@thread3.object_id)
|
84
|
+
end
|
85
|
+
|
86
|
+
should "only add one socket per thread" do
|
87
|
+
@conn.reserved_connections.values do |socket|
|
88
|
+
assert [@socket1, @socket2, @socket3].include?(socket)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
should "check out all sockets" do
|
93
|
+
assert_equal @conn.sockets.size, @conn.checked_out.size
|
94
|
+
@conn.sockets.each do |sock|
|
95
|
+
assert @conn.checked_out.include?(sock)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
should "raise an error if no more sockets can be checked out" do
|
100
|
+
# This can't be tested with mock threads.
|
101
|
+
# Will test in integration tests.
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when releasing dead threads" do
|
105
|
+
setup do
|
106
|
+
@thread1.expects(:alive?).returns(false)
|
107
|
+
@thread2.expects(:alive?).returns(true)
|
108
|
+
@thread3.expects(:alive?).returns(true)
|
109
|
+
Thread.expects(:list).returns([@thread1, @thread2, @thread3])
|
110
|
+
@conn.clear_stale_cached_connections!
|
111
|
+
end
|
112
|
+
|
113
|
+
should "return connections for dead threads" do
|
114
|
+
assert !@conn.checked_out.include?(@socket1)
|
115
|
+
assert_nil @conn.reserved_connections[@thread1.object_id]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|