mongo 0.17.1 → 0.18
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/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
|
+
|