mongo 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/README.md +9 -6
  2. data/Rakefile +3 -4
  3. data/docs/HISTORY.md +20 -2
  4. data/docs/READ_PREFERENCE.md +39 -0
  5. data/docs/RELEASES.md +1 -1
  6. data/docs/REPLICA_SETS.md +23 -2
  7. data/docs/TAILABLE_CURSORS.md +51 -0
  8. data/docs/TUTORIAL.md +4 -4
  9. data/docs/WRITE_CONCERN.md +5 -2
  10. data/lib/mongo.rb +7 -22
  11. data/lib/mongo/collection.rb +96 -29
  12. data/lib/mongo/connection.rb +107 -62
  13. data/lib/mongo/cursor.rb +136 -57
  14. data/lib/mongo/db.rb +26 -5
  15. data/lib/mongo/exceptions.rb +17 -1
  16. data/lib/mongo/gridfs/grid.rb +1 -1
  17. data/lib/mongo/repl_set_connection.rb +273 -156
  18. data/lib/mongo/util/logging.rb +42 -0
  19. data/lib/mongo/util/node.rb +183 -0
  20. data/lib/mongo/util/pool.rb +76 -13
  21. data/lib/mongo/util/pool_manager.rb +208 -0
  22. data/lib/mongo/util/ssl_socket.rb +38 -0
  23. data/lib/mongo/util/support.rb +9 -1
  24. data/lib/mongo/util/timeout.rb +42 -0
  25. data/lib/mongo/version.rb +3 -0
  26. data/mongo.gemspec +2 -2
  27. data/test/bson/binary_test.rb +1 -1
  28. data/test/bson/bson_string_test.rb +30 -0
  29. data/test/bson/bson_test.rb +6 -3
  30. data/test/bson/byte_buffer_test.rb +1 -1
  31. data/test/bson/hash_with_indifferent_access_test.rb +1 -1
  32. data/test/bson/json_test.rb +1 -1
  33. data/test/bson/object_id_test.rb +2 -18
  34. data/test/bson/ordered_hash_test.rb +38 -3
  35. data/test/bson/test_helper.rb +46 -0
  36. data/test/bson/timestamp_test.rb +32 -10
  37. data/test/collection_test.rb +89 -3
  38. data/test/connection_test.rb +35 -20
  39. data/test/cursor_test.rb +63 -2
  40. data/test/db_test.rb +12 -2
  41. data/test/pool_test.rb +21 -0
  42. data/test/replica_sets/connect_test.rb +26 -13
  43. data/test/replica_sets/connection_string_test.rb +1 -4
  44. data/test/replica_sets/count_test.rb +1 -0
  45. data/test/replica_sets/insert_test.rb +1 -0
  46. data/test/replica_sets/pooled_insert_test.rb +4 -1
  47. data/test/replica_sets/query_secondaries.rb +2 -1
  48. data/test/replica_sets/query_test.rb +2 -1
  49. data/test/replica_sets/read_preference_test.rb +43 -0
  50. data/test/replica_sets/refresh_test.rb +123 -0
  51. data/test/replica_sets/replication_ack_test.rb +9 -4
  52. data/test/replica_sets/rs_test_helper.rb +2 -2
  53. data/test/timeout_test.rb +14 -0
  54. data/test/tools/repl_set_manager.rb +134 -23
  55. data/test/unit/collection_test.rb +6 -8
  56. data/test/unit/connection_test.rb +4 -4
  57. data/test/unit/cursor_test.rb +23 -5
  58. data/test/unit/db_test.rb +2 -0
  59. data/test/unit/grid_test.rb +2 -0
  60. data/test/unit/node_test.rb +73 -0
  61. data/test/unit/pool_manager_test.rb +47 -0
  62. data/test/unit/read_test.rb +101 -0
  63. metadata +214 -138
  64. data/lib/mongo/test.rb +0 -20
  65. data/test/async/collection_test.rb +0 -224
  66. data/test/async/connection_test.rb +0 -24
  67. data/test/async/cursor_test.rb +0 -162
  68. data/test/async/worker_pool_test.rb +0 -99
  69. data/test/load/resque/load.rb +0 -21
  70. data/test/load/resque/processor.rb +0 -26
  71. data/test/load/unicorn/unicorn.rb +0 -29
  72. data/test/tools/load.rb +0 -58
  73. data/test/tools/sharding_manager.rb +0 -202
  74. data/test/tools/test.rb +0 -4
  75. data/test/unit/repl_set_connection_test.rb +0 -59
@@ -1,20 +0,0 @@
1
-
2
- class Foo
3
-
4
- def zed
5
- puts "Foo"
6
- end
7
-
8
- end
9
-
10
- class Bar < Foo
11
-
12
- def zed(n=nil)
13
- if n.nil?
14
- puts "Bar"
15
- else
16
- super()
17
- end
18
- end
19
-
20
- end
@@ -1,224 +0,0 @@
1
- require 'test/test_helper'
2
-
3
- class TestCollection < Test::Unit::TestCase
4
- @@connection ||= Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost', ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT)
5
- @@db = @@connection.db(MONGO_TEST_DB)
6
- @@test = @@db.collection("test")
7
- @@version = @@connection.server_version
8
-
9
- def setup
10
- @@test.remove
11
- end
12
-
13
- def wait_for_async
14
- sleep 0.2
15
- end
16
-
17
- def test_async_update
18
- id1 = @@test.save("x" => 5)
19
- failsafe = mock('failsafe will get called in block', :call => true)
20
-
21
- @@test.update({}, {"$inc" => {"x" => 1}}, :async => true) do |error, result|
22
- assert_nil error
23
- assert result
24
- failsafe.call
25
- end
26
- wait_for_async
27
-
28
- assert_equal 1, @@test.count()
29
- assert_equal 6, @@test.find_one(:_id => id1)["x"]
30
- end
31
-
32
- if @@version >= "1.1.3"
33
- def test_async_multi_update
34
- failsafe = mock('failsafe will get called in block', :call => true)
35
-
36
- @@test.save("num" => 10)
37
- @@test.save("num" => 10)
38
- @@test.save("num" => 10)
39
- assert_equal 3, @@test.count
40
-
41
- @@test.update({"num" => 10}, {"$set" => {"num" => 100}}, :multi => true, :async => true) do |error, result|
42
- assert_nil error
43
- assert result
44
- failsafe.call
45
- end
46
- wait_for_async
47
- end
48
- end
49
-
50
- def test_async_upsert
51
- failsafe = mock('failsafe will get called in block')
52
- failsafe.expects(:call).times(2)
53
-
54
- @@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true, :async => true) do |error, result|
55
- assert_nil error
56
- assert result
57
- failsafe.call
58
- end
59
-
60
- @@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true, :async => true) do |error, result|
61
- assert_nil error
62
- assert result
63
- failsafe.call
64
- end
65
- wait_for_async
66
-
67
- assert_equal 1, @@test.count()
68
- assert_equal 2, @@test.find_one()["count"]
69
- end
70
-
71
- def test_async_save
72
- failsafe = mock('failsafe will get called in block', :call => true)
73
-
74
- # note that the first parameter has explicit curly brackets around
75
- # the hash; without those brackets as a delimiter, the :async key is
76
- # viewed as part of the required +document+ parameter
77
- @@test.save({"hello" => "world"}, :async => true) do |error, result|
78
- assert_nil error
79
- assert result
80
- failsafe.call
81
- end
82
- wait_for_async
83
-
84
- assert_equal "world", @@test.find_one()["hello"]
85
- end
86
-
87
- def test_async_save_with_exception
88
- failsafe = mock('failsafe will get called in block', :call => true)
89
-
90
- @@test.create_index("hello", :unique => true)
91
- @@test.save("hello" => "world")
92
-
93
- # all async calls on collections occur in :safe mode
94
- @@test.save({"hello" => "world"}, :async => true) do |error, result|
95
- assert error
96
- assert error.instance_of?(OperationFailure)
97
- assert_nil result
98
- failsafe.call
99
- end
100
- wait_for_async
101
-
102
- assert_equal 1, @@test.count()
103
- @@test.drop
104
- end
105
-
106
- def test_async_remove
107
- failsafe = mock('failsafe will get called in block', :call => true)
108
-
109
- @conn = Connection.new
110
- @db = @conn[MONGO_TEST_DB]
111
- @test = @db['test-async-remove']
112
- @test.save({:a => 50})
113
- @test.remove({}, :async => true) do |error, result|
114
- assert_nil error
115
- assert result
116
- failsafe.call
117
- end
118
- wait_for_async
119
-
120
- @test.drop
121
- end
122
-
123
- def test_async_count
124
- failsafe = mock('failsafe will get called in block', :call => true)
125
-
126
- @@test.drop
127
-
128
- @@test.save("x" => 1)
129
- @@test.save("x" => 2)
130
-
131
- @@test.count(:async => true) do |error, result|
132
- assert_nil error
133
- assert_equal 2, result
134
- failsafe.call
135
- end
136
- wait_for_async
137
- end
138
-
139
- # Note: #size is just an alias for #count.
140
- def test_async_size
141
- failsafe = mock('failsafe will get called in block', :call => true)
142
-
143
- @@test.drop
144
-
145
- @@test.save("x" => 1)
146
- @@test.save("x" => 2)
147
-
148
- @@test.size(:async => true) do |error, result|
149
- assert_nil error
150
- assert_equal 2, result
151
- failsafe.call
152
- end
153
- wait_for_async
154
- end
155
-
156
- def test_async_find_one
157
- failsafe = mock('failsafe will get called in block', :call => true)
158
-
159
- id = @@test.save("hello" => "world", "foo" => "bar")
160
-
161
- @@test.find_one({}, :async => true) do |error, result|
162
- assert_nil error
163
- assert_equal @@test.find_one(id), result
164
- failsafe.call
165
- end
166
- wait_for_async
167
- end
168
-
169
- def test_async_insert
170
- failsafe = mock('failsafe will get called in block', :call => true)
171
-
172
- doc = {"hello" => "world"}
173
- @@test.insert(doc, :async => true) do |error, result|
174
- assert_nil error
175
- assert result
176
- failsafe.call
177
- end
178
- wait_for_async
179
-
180
- assert_equal 1, @@test.count
181
- end
182
-
183
- def test_async_find
184
- assert_raise RuntimeError do
185
- @@test.find({}, :async => true)
186
- end
187
- end
188
-
189
- if @@version > "1.3.0"
190
- def test_async_find_and_modify
191
- failsafe = mock('failsafe will get called in block', :call => true)
192
-
193
- @@test << { :a => 1, :processed => false }
194
- @@test << { :a => 2, :processed => false }
195
- @@test << { :a => 3, :processed => false }
196
-
197
- @@test.find_and_modify(:query => {}, :sort => [['a', -1]], :update => {"$set" => {:processed => true}}, :async => true) do |error, result|
198
- assert_nil error
199
- assert result
200
- failsafe.call
201
- end
202
- wait_for_async
203
-
204
- assert @@test.find_one({:a => 3})['processed']
205
- end
206
-
207
- def test_async_find_and_modify_with_invalid_options
208
- failsafe = mock('failsafe will get called in block', :call => true)
209
-
210
- @@test << { :a => 1, :processed => false }
211
- @@test << { :a => 2, :processed => false }
212
- @@test << { :a => 3, :processed => false }
213
-
214
- @@test.find_and_modify(:blimey => {}, :async => true) do |error, result|
215
- assert error
216
- assert error.instance_of?(OperationFailure)
217
- assert_nil result
218
- failsafe.call
219
- end
220
- wait_for_async
221
- end
222
- end
223
-
224
- end
@@ -1,24 +0,0 @@
1
- require 'test/test_helper'
2
- include Mongo
3
-
4
- class ConnectionTest < Test::Unit::TestCase
5
- context "Initialization: " do
6
-
7
- context "given async connection options" do
8
-
9
- should "default the workers pool to 1" do
10
- Async::WorkerPool.expects(:new).with(1)
11
-
12
- Connection.new('localhost', 27017)
13
- end
14
-
15
- should "override the workers pool size with the :worker_pool_size key" do
16
- size = 6
17
- Async::WorkerPool.expects(:new).with(size)
18
-
19
- Connection.new('localhost', 27017, :worker_pool_size => size)
20
- end
21
- end # context 'given async connection options'
22
-
23
- end # context 'Initialization'
24
- end
@@ -1,162 +0,0 @@
1
- require 'test/test_helper'
2
- require 'logger'
3
-
4
- class CursorTest < Test::Unit::TestCase
5
-
6
- include Mongo
7
-
8
- @@connection = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
9
- ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT)
10
- @@db = @@connection.db(MONGO_TEST_DB)
11
- @@coll = @@db.collection('test')
12
- @@version = @@connection.server_version
13
-
14
- def wait_for_async
15
- sleep 0.2
16
- end
17
-
18
- def setup
19
- @@coll.remove
20
- @@coll.insert('a' => 1) # collection not created until it's used
21
- @@coll_full_name = "#{MONGO_TEST_DB}.test"
22
- end
23
-
24
- def test_async_explain
25
- failsafe = mock('failsafe will get called in block', :call => true)
26
-
27
- cursor = @@coll.find('a' => 1)
28
-
29
- cursor.explain(:async => true) do |error, result|
30
- assert_not_nil result['cursor']
31
- assert_kind_of Numeric, result['n']
32
- assert_kind_of Numeric, result['millis']
33
- assert_kind_of Numeric, result['nscanned']
34
- failsafe.call
35
- end
36
- wait_for_async
37
- end
38
-
39
- def test_async_count
40
- failsafe = mock('failsafe will get called in block')
41
- failsafe.expects(:call).times(3)
42
-
43
- @@coll.remove
44
-
45
- @@coll.find.count(:async => true) do |error, count|
46
- assert_equal 0, count
47
- failsafe.call
48
- end
49
- wait_for_async
50
-
51
- 10.times do |i|
52
- @@coll.save("x" => i)
53
- end
54
-
55
- @@coll.find.count(:async => true) do |error, count|
56
- assert_equal 10, count
57
- failsafe.call
58
- end
59
- wait_for_async
60
-
61
- @@coll.find({"x" => 1}).count(:async => true) do |error, count|
62
- assert_equal 1, count
63
- failsafe.call
64
- end
65
- wait_for_async
66
- end
67
-
68
- def test_async_close
69
- failsafe = mock('failsafe will get called in block', :call => true)
70
-
71
- @@coll.remove
72
- cursor = @@coll.find
73
-
74
- cursor.close(:async => true) do |error, result|
75
- assert_nil error
76
- assert result
77
- assert cursor.closed?
78
- failsafe.call
79
- end
80
- wait_for_async
81
- end
82
-
83
- def test_async_has_next
84
- failsafe = mock('failsafe will get called in block', :call => true)
85
-
86
- @@coll.remove
87
- 200.times do |n|
88
- @@coll.save("x" => n)
89
- end
90
-
91
- cursor = @@coll.find
92
- cursor.has_next?(:async => true) do |error, result|
93
- assert_nil error
94
- assert result
95
- failsafe.call
96
- end
97
- wait_for_async
98
- end
99
-
100
- def test_async_next_document
101
- failsafe = mock('failsafe will get called in block')
102
- failsafe.expects(:call).times(2)
103
-
104
- @@coll.remove
105
- 200.times do |n|
106
- @@coll.save("x" => n)
107
- end
108
-
109
- cursor = @@coll.find
110
- cursor.next_document(:async => true) do |error, result|
111
- assert_nil error
112
- assert result
113
- failsafe.call
114
- end
115
- wait_for_async
116
-
117
- callback = Proc.new do |error, result|
118
- assert_nil error
119
- assert result
120
- failsafe.call
121
- end
122
-
123
- cursor.next_document(:async => true, :callback => callback)
124
- wait_for_async
125
- end
126
-
127
- def test_async_to_a
128
- failsafe = mock('failsafe will get called in block')
129
- failsafe.expects(:call)
130
-
131
- @@coll.remove
132
- total = 200
133
- total.times do |n|
134
- @@coll.save("x" => n)
135
- end
136
-
137
- cursor = @@coll.find
138
- cursor.to_a(:async => true) do |error, result|
139
- assert_nil error
140
- assert_equal total, result.size
141
- failsafe.call
142
- end
143
- wait_for_async
144
- end
145
-
146
- def test_async_each
147
- @@coll.remove
148
- total = 200
149
- total.times do |n|
150
- @@coll.save("x" => n)
151
- end
152
-
153
- cursor = @@coll.find
154
- count = 0
155
- cursor.each(:async => true) do |error, result|
156
- count += 1
157
- end
158
- wait_for_async
159
-
160
- assert_equal total, count
161
- end
162
- end
@@ -1,99 +0,0 @@
1
- require 'test/test_helper'
2
- include Mongo
3
-
4
- class WorkerPoolTest < Test::Unit::TestCase
5
- context "Initialization: " do
6
-
7
- def wait_for_async
8
- sleep 0.2
9
- end
10
-
11
- setup do
12
- def new_mock_queue
13
- stub_everything('queue')
14
- end
15
-
16
- def new_mock_thread
17
- stub_everything('thread')
18
- end
19
- end
20
-
21
- context "given a size" do
22
- setup do
23
- @size = 5
24
- end
25
-
26
- should "allocate a Thread 'size' times" do
27
- Queue.stubs(:new).returns(new_mock_queue)
28
- Thread.expects(:new).times(@size).returns(new_mock_thread)
29
- Async::WorkerPool.new @size
30
- end
31
-
32
- should "set 'abort_on_exception' for each current thread" do
33
- Queue.stubs(:new).returns(new_mock_queue)
34
- thread = new_mock_thread
35
- Thread.stubs(:new).returns(thread)
36
-
37
- thread.expects(:abort_on_exception=).with(true).times(@size)
38
-
39
- Async::WorkerPool.new @size
40
- end
41
-
42
- should "save each thread into the workers queue" do
43
- assert_equal @size, Async::WorkerPool.new(@size).workers.size
44
- end
45
-
46
- end # context 'given a size'
47
-
48
-
49
- context "given a job" do
50
- setup do
51
- @pool = Async::WorkerPool.new 1
52
- @command = stub_everything('command')
53
- @cmd_args = stub_everything('command args')
54
- @callback = stub_everything('callback')
55
- end
56
-
57
- should "remove nils from the command args array and pass the results to the callback" do
58
- args = [nil, @cmd_args]
59
- @command.expects(:call).with(@cmd_args).returns(2)
60
- @callback.expects(:call).with(nil, 2)
61
-
62
- @pool.enqueue @command, args, @callback
63
- wait_for_async
64
- end
65
-
66
- should "execute the original command with args and pass the results to the callback" do
67
- @cmd_args.expects(:compact).returns(@cmd_args)
68
- @command.expects(:call).with(@cmd_args).returns(2)
69
- @callback.expects(:call).with(nil, 2)
70
-
71
- @pool.enqueue @command, @cmd_args, @callback
72
- wait_for_async
73
- end
74
-
75
- should "capture any exceptions and pass them to the callback" do
76
- args = [@cmd_args]
77
- error = StandardError.new
78
- @command.expects(:call).with(@cmd_args).raises(error)
79
- @callback.expects(:call).with(error, nil)
80
-
81
- @pool.enqueue @command, args, @callback
82
- wait_for_async
83
- end
84
-
85
- should "abort the thread when the callback raises an exception" do
86
- args = [@cmd_args]
87
- error = StandardError.new
88
- @callback.expects(:call).raises(error)
89
-
90
- assert_raises(StandardError) do
91
- @pool.enqueue @command, args, @callback
92
- wait_for_async
93
- end
94
- end
95
- end # context 'given a job'
96
-
97
-
98
- end
99
- end