mongo 1.3.0 → 1.12.5
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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data/{LICENSE.txt → LICENSE} +1 -1
- data/README.md +122 -271
- data/Rakefile +25 -209
- data/VERSION +1 -0
- data/bin/mongo_console +31 -9
- data/lib/mongo/bulk_write_collection_view.rb +387 -0
- data/lib/mongo/collection.rb +576 -269
- data/lib/mongo/collection_writer.rb +364 -0
- data/lib/mongo/connection/node.rb +249 -0
- data/lib/mongo/connection/pool.rb +340 -0
- data/lib/mongo/connection/pool_manager.rb +320 -0
- data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
- data/lib/mongo/connection/socket/socket_util.rb +37 -0
- data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
- data/lib/mongo/connection/socket/tcp_socket.rb +87 -0
- data/lib/mongo/connection/socket/unix_socket.rb +39 -0
- data/lib/mongo/connection/socket.rb +18 -0
- data/lib/mongo/connection.rb +7 -875
- data/lib/mongo/cursor.rb +403 -117
- data/lib/mongo/db.rb +444 -243
- data/lib/mongo/exception.rb +145 -0
- data/lib/mongo/functional/authentication.rb +455 -0
- data/lib/mongo/functional/logging.rb +85 -0
- data/lib/mongo/functional/read_preference.rb +183 -0
- data/lib/mongo/functional/scram.rb +556 -0
- data/lib/mongo/functional/uri_parser.rb +409 -0
- data/lib/mongo/functional/write_concern.rb +66 -0
- data/lib/mongo/functional.rb +20 -0
- data/lib/mongo/gridfs/grid.rb +30 -24
- data/lib/mongo/gridfs/grid_ext.rb +6 -10
- data/lib/mongo/gridfs/grid_file_system.rb +38 -20
- data/lib/mongo/gridfs/grid_io.rb +84 -75
- data/lib/mongo/gridfs.rb +18 -0
- data/lib/mongo/legacy.rb +140 -0
- data/lib/mongo/mongo_client.rb +697 -0
- data/lib/mongo/mongo_replica_set_client.rb +535 -0
- data/lib/mongo/mongo_sharded_client.rb +159 -0
- data/lib/mongo/networking.rb +372 -0
- data/lib/mongo/{util → utils}/conversions.rb +29 -8
- data/lib/mongo/{util → utils}/core_ext.rb +28 -18
- data/lib/mongo/{util → utils}/server_version.rb +4 -6
- data/lib/mongo/{util → utils}/support.rb +29 -31
- data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
- data/lib/mongo/utils.rb +19 -0
- data/lib/mongo.rb +51 -50
- data/mongo.gemspec +29 -32
- data/test/functional/authentication_test.rb +39 -0
- data/test/functional/bulk_api_stress_test.rb +133 -0
- data/test/functional/bulk_write_collection_view_test.rb +1198 -0
- data/test/functional/client_test.rb +627 -0
- data/test/functional/collection_test.rb +2175 -0
- data/test/functional/collection_writer_test.rb +83 -0
- data/test/{conversions_test.rb → functional/conversions_test.rb} +47 -3
- data/test/functional/cursor_fail_test.rb +57 -0
- data/test/functional/cursor_message_test.rb +56 -0
- data/test/functional/cursor_test.rb +683 -0
- data/test/functional/db_api_test.rb +835 -0
- data/test/functional/db_connection_test.rb +25 -0
- data/test/functional/db_test.rb +348 -0
- data/test/functional/grid_file_system_test.rb +285 -0
- data/test/{grid_io_test.rb → functional/grid_io_test.rb} +72 -11
- data/test/{grid_test.rb → functional/grid_test.rb} +88 -15
- data/test/functional/pool_test.rb +136 -0
- data/test/functional/safe_test.rb +98 -0
- data/test/functional/ssl_test.rb +29 -0
- data/test/functional/support_test.rb +62 -0
- data/test/functional/timeout_test.rb +60 -0
- data/test/functional/uri_test.rb +446 -0
- data/test/functional/write_concern_test.rb +118 -0
- data/test/helpers/general.rb +50 -0
- data/test/helpers/test_unit.rb +476 -0
- data/test/replica_set/authentication_test.rb +37 -0
- data/test/replica_set/basic_test.rb +189 -0
- data/test/replica_set/client_test.rb +393 -0
- data/test/replica_set/connection_test.rb +138 -0
- data/test/replica_set/count_test.rb +66 -0
- data/test/replica_set/cursor_test.rb +220 -0
- data/test/replica_set/insert_test.rb +157 -0
- data/test/replica_set/max_values_test.rb +151 -0
- data/test/replica_set/pinning_test.rb +105 -0
- data/test/replica_set/query_test.rb +73 -0
- data/test/replica_set/read_preference_test.rb +219 -0
- data/test/replica_set/refresh_test.rb +211 -0
- data/test/replica_set/replication_ack_test.rb +95 -0
- data/test/replica_set/ssl_test.rb +32 -0
- data/test/sharded_cluster/basic_test.rb +203 -0
- data/test/shared/authentication/basic_auth_shared.rb +260 -0
- data/test/shared/authentication/bulk_api_auth_shared.rb +249 -0
- data/test/shared/authentication/gssapi_shared.rb +176 -0
- data/test/shared/authentication/sasl_plain_shared.rb +96 -0
- data/test/shared/authentication/scram_shared.rb +92 -0
- data/test/shared/ssl_shared.rb +235 -0
- data/test/test_helper.rb +53 -94
- data/test/threading/basic_test.rb +120 -0
- data/test/tools/mongo_config.rb +708 -0
- data/test/tools/mongo_config_test.rb +160 -0
- data/test/unit/client_test.rb +381 -0
- data/test/unit/collection_test.rb +89 -53
- data/test/unit/connection_test.rb +282 -32
- data/test/unit/cursor_test.rb +206 -8
- data/test/unit/db_test.rb +55 -13
- data/test/unit/grid_test.rb +43 -16
- data/test/unit/mongo_sharded_client_test.rb +48 -0
- data/test/unit/node_test.rb +93 -0
- data/test/unit/pool_manager_test.rb +111 -0
- data/test/unit/read_pref_test.rb +406 -0
- data/test/unit/read_test.rb +159 -0
- data/test/unit/safe_test.rb +69 -36
- data/test/unit/sharding_pool_manager_test.rb +84 -0
- data/test/unit/write_concern_test.rb +175 -0
- data.tar.gz.sig +3 -0
- metadata +227 -216
- metadata.gz.sig +0 -0
- data/docs/CREDITS.md +0 -123
- data/docs/FAQ.md +0 -116
- data/docs/GridFS.md +0 -158
- data/docs/HISTORY.md +0 -244
- data/docs/RELEASES.md +0 -33
- data/docs/REPLICA_SETS.md +0 -72
- data/docs/TUTORIAL.md +0 -247
- data/docs/WRITE_CONCERN.md +0 -28
- data/lib/mongo/exceptions.rb +0 -71
- data/lib/mongo/gridfs/grid_io_fix.rb +0 -38
- data/lib/mongo/repl_set_connection.rb +0 -342
- data/lib/mongo/test.rb +0 -20
- data/lib/mongo/util/pool.rb +0 -177
- data/lib/mongo/util/uri_parser.rb +0 -185
- data/test/async/collection_test.rb +0 -224
- data/test/async/connection_test.rb +0 -24
- data/test/async/cursor_test.rb +0 -162
- data/test/async/worker_pool_test.rb +0 -99
- data/test/auxillary/1.4_features.rb +0 -166
- data/test/auxillary/authentication_test.rb +0 -68
- data/test/auxillary/autoreconnect_test.rb +0 -41
- data/test/auxillary/fork_test.rb +0 -30
- data/test/auxillary/repl_set_auth_test.rb +0 -58
- data/test/auxillary/slave_connection_test.rb +0 -36
- data/test/auxillary/threaded_authentication_test.rb +0 -101
- data/test/bson/binary_test.rb +0 -15
- data/test/bson/bson_test.rb +0 -649
- data/test/bson/byte_buffer_test.rb +0 -208
- data/test/bson/hash_with_indifferent_access_test.rb +0 -38
- data/test/bson/json_test.rb +0 -17
- data/test/bson/object_id_test.rb +0 -154
- data/test/bson/ordered_hash_test.rb +0 -204
- data/test/bson/timestamp_test.rb +0 -24
- data/test/collection_test.rb +0 -910
- data/test/connection_test.rb +0 -309
- data/test/cursor_fail_test.rb +0 -75
- data/test/cursor_message_test.rb +0 -43
- data/test/cursor_test.rb +0 -483
- data/test/db_api_test.rb +0 -726
- data/test/db_connection_test.rb +0 -15
- data/test/db_test.rb +0 -287
- data/test/grid_file_system_test.rb +0 -243
- data/test/load/resque/load.rb +0 -21
- data/test/load/resque/processor.rb +0 -26
- data/test/load/thin/load.rb +0 -24
- data/test/load/unicorn/load.rb +0 -23
- data/test/load/unicorn/unicorn.rb +0 -29
- data/test/replica_sets/connect_test.rb +0 -94
- data/test/replica_sets/connection_string_test.rb +0 -32
- data/test/replica_sets/count_test.rb +0 -35
- data/test/replica_sets/insert_test.rb +0 -53
- data/test/replica_sets/pooled_insert_test.rb +0 -55
- data/test/replica_sets/query_secondaries.rb +0 -96
- data/test/replica_sets/query_test.rb +0 -51
- data/test/replica_sets/replication_ack_test.rb +0 -66
- data/test/replica_sets/rs_test_helper.rb +0 -27
- data/test/safe_test.rb +0 -68
- data/test/support/hash_with_indifferent_access.rb +0 -186
- data/test/support/keys.rb +0 -45
- data/test/support_test.rb +0 -18
- data/test/threading/threading_with_large_pool_test.rb +0 -90
- data/test/threading_test.rb +0 -87
- data/test/tools/auth_repl_set_manager.rb +0 -14
- data/test/tools/load.rb +0 -58
- data/test/tools/repl_set_manager.rb +0 -266
- data/test/tools/sharding_manager.rb +0 -202
- data/test/tools/test.rb +0 -4
- data/test/unit/pool_test.rb +0 -9
- data/test/unit/repl_set_connection_test.rb +0 -59
- data/test/uri_test.rb +0 -91
@@ -0,0 +1,73 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
|
17
|
+
class ReplicaSetQueryTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
def setup
|
20
|
+
ensure_cluster(:rs)
|
21
|
+
@client = MongoReplicaSetClient.from_uri(@uri, :op_timeout => TEST_OP_TIMEOUT)
|
22
|
+
@db = @client.db(TEST_DB)
|
23
|
+
@db.drop_collection("test-sets")
|
24
|
+
@coll = @db.collection("test-sets")
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
@client.close if @client
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_query
|
32
|
+
@coll.save({:a => 20}, :w => 3)
|
33
|
+
@coll.save({:a => 30}, :w => 3)
|
34
|
+
@coll.save({:a => 40}, :w => 3)
|
35
|
+
results = []
|
36
|
+
@coll.find.each {|r| results << r}
|
37
|
+
[20, 30, 40].each do |a|
|
38
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
39
|
+
end
|
40
|
+
|
41
|
+
@rs.primary.stop
|
42
|
+
|
43
|
+
results = []
|
44
|
+
rescue_connection_failure do
|
45
|
+
@coll.find.each {|r| results << r}
|
46
|
+
[20, 30, 40].each do |a|
|
47
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create a large collection and do a secondary query that returns
|
53
|
+
# enough records to require sending a GETMORE. In between opening
|
54
|
+
# the cursor and sending the GETMORE, do a :primary query. Confirm
|
55
|
+
# that the cursor reading from the secondary continues to talk to
|
56
|
+
# the secondary, rather than trying to read the cursor from the
|
57
|
+
# primary, where it does not exist.
|
58
|
+
# def test_secondary_getmore
|
59
|
+
# 200.times do |i|
|
60
|
+
# @coll.save({:a => i}, :w => 3)
|
61
|
+
# end
|
62
|
+
# as = []
|
63
|
+
# # Set an explicit batch size, in case the default ever changes.
|
64
|
+
# @coll.find({}, { :batch_size => 100, :read => :secondary }) do |c|
|
65
|
+
# c.each do |result|
|
66
|
+
# as << result['a']
|
67
|
+
# @coll.find({:a => result['a']}, :read => :primary).map
|
68
|
+
# end
|
69
|
+
# end
|
70
|
+
# assert_equal(as.sort, 0.upto(199).to_a)
|
71
|
+
# end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
|
17
|
+
class ReadPreferenceTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
def setup
|
20
|
+
ensure_cluster(:rs)
|
21
|
+
client = make_connection
|
22
|
+
db = client.db(TEST_DB)
|
23
|
+
coll = db.collection('test-sets')
|
24
|
+
coll.save({:a => 20}, {:w => 2})
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_read_primary
|
28
|
+
client = make_connection
|
29
|
+
rescue_connection_failure do
|
30
|
+
assert client.read_primary?
|
31
|
+
assert client.primary?
|
32
|
+
end
|
33
|
+
|
34
|
+
client = make_connection(:primary_preferred)
|
35
|
+
rescue_connection_failure do
|
36
|
+
assert client.read_primary?
|
37
|
+
assert client.primary?
|
38
|
+
end
|
39
|
+
|
40
|
+
client = make_connection(:secondary)
|
41
|
+
rescue_connection_failure do
|
42
|
+
assert !client.read_primary?
|
43
|
+
assert !client.primary?
|
44
|
+
end
|
45
|
+
|
46
|
+
client = make_connection(:secondary_preferred)
|
47
|
+
rescue_connection_failure do
|
48
|
+
assert !client.read_primary?
|
49
|
+
assert !client.primary?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_connection_pools
|
54
|
+
client = make_connection
|
55
|
+
assert client.primary_pool, "No primary pool!"
|
56
|
+
assert client.read_pool, "No read pool!"
|
57
|
+
assert client.primary_pool.port == client.read_pool.port,
|
58
|
+
"Primary port and read port are not the same!"
|
59
|
+
|
60
|
+
|
61
|
+
client = make_connection(:primary_preferred)
|
62
|
+
assert client.primary_pool, "No primary pool!"
|
63
|
+
assert client.read_pool, "No read pool!"
|
64
|
+
assert client.primary_pool.port == client.read_pool.port,
|
65
|
+
"Primary port and read port are not the same!"
|
66
|
+
|
67
|
+
client = make_connection(:secondary)
|
68
|
+
assert client.primary_pool, "No primary pool!"
|
69
|
+
assert client.read_pool, "No read pool!"
|
70
|
+
assert client.primary_pool.port != client.read_pool.port,
|
71
|
+
"Primary port and read port are the same!"
|
72
|
+
|
73
|
+
client = make_connection(:secondary_preferred)
|
74
|
+
assert client.primary_pool, "No primary pool!"
|
75
|
+
assert client.read_pool, "No read pool!"
|
76
|
+
assert client.primary_pool.port != client.read_pool.port,
|
77
|
+
"Primary port and read port are the same!"
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_read_routing
|
81
|
+
prepare_routing_test
|
82
|
+
|
83
|
+
# Test that reads are going to the right members
|
84
|
+
assert_query_route(@primary, :primary)
|
85
|
+
assert_query_route(@primary_preferred, :primary)
|
86
|
+
assert_query_route(@secondary, :secondary)
|
87
|
+
assert_query_route(@secondary_preferred, :secondary)
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_read_routing_with_primary_down
|
91
|
+
prepare_routing_test
|
92
|
+
|
93
|
+
# Test that reads are going to the right members
|
94
|
+
assert_query_route(@primary, :primary)
|
95
|
+
assert_query_route(@primary_preferred, :primary)
|
96
|
+
assert_query_route(@secondary, :secondary)
|
97
|
+
assert_query_route(@secondary_preferred, :secondary)
|
98
|
+
|
99
|
+
# Kill the primary so the remaining two members are secondaries
|
100
|
+
@rs.primary.kill
|
101
|
+
sleep(2)
|
102
|
+
# Test that reads are going to the right members
|
103
|
+
assert_raise_error ConnectionFailure do
|
104
|
+
@primary[TEST_DB]['test-sets'].find_one
|
105
|
+
end
|
106
|
+
assert_query_route(@primary_preferred, :secondary)
|
107
|
+
assert_query_route(@secondary, :secondary)
|
108
|
+
assert_query_route(@secondary_preferred, :secondary)
|
109
|
+
|
110
|
+
# Restore set
|
111
|
+
@rs.restart
|
112
|
+
sleep(1)
|
113
|
+
@repl_cons.each { |con| con.refresh }
|
114
|
+
sleep(1)
|
115
|
+
|
116
|
+
# Test that reads are going to the right members
|
117
|
+
assert_query_route(@primary, :primary)
|
118
|
+
assert_query_route(@primary_preferred, :primary)
|
119
|
+
assert_query_route(@secondary, :secondary)
|
120
|
+
assert_query_route(@secondary_preferred, :secondary)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_read_routing_with_secondary_down
|
124
|
+
prepare_routing_test
|
125
|
+
|
126
|
+
# Test that reads are going to the right members
|
127
|
+
assert_query_route(@primary, :primary)
|
128
|
+
assert_query_route(@primary_preferred, :primary)
|
129
|
+
assert_query_route(@secondary, :secondary)
|
130
|
+
assert_query_route(@secondary_preferred, :secondary)
|
131
|
+
|
132
|
+
secondaries = @rs.secondaries
|
133
|
+
secondaries[0].kill
|
134
|
+
assert_query_route(@secondary_preferred, :secondary)
|
135
|
+
|
136
|
+
secondaries[1].kill
|
137
|
+
sleep(2)
|
138
|
+
|
139
|
+
recovered = false
|
140
|
+
until recovered
|
141
|
+
begin
|
142
|
+
@secondary[TEST_DB]['test-sets'].find_one
|
143
|
+
recovered = true
|
144
|
+
rescue ConnectionFailure
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
assert_query_route(@secondary_preferred, :secondary)
|
149
|
+
assert_query_route(@secondary, :secondary)
|
150
|
+
assert_query_route(@primary_preferred, :secondary)
|
151
|
+
|
152
|
+
# Restore set
|
153
|
+
@rs.restart
|
154
|
+
sleep(1)
|
155
|
+
@repl_cons.each { |con| con.refresh }
|
156
|
+
sleep(1)
|
157
|
+
|
158
|
+
# Test that reads are going to the right members
|
159
|
+
assert_query_route(@primary, :primary)
|
160
|
+
assert_query_route(@primary_preferred, :primary)
|
161
|
+
assert_query_route(@secondary, :secondary)
|
162
|
+
assert_query_route(@secondary_preferred, :secondary)
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_write_lots_of_data
|
166
|
+
client = make_connection(:secondary_preferred)
|
167
|
+
db = client[TEST_DB]
|
168
|
+
coll = db.collection("test-sets", {:w => 2})
|
169
|
+
|
170
|
+
6000.times do |n|
|
171
|
+
coll.save({:a => n})
|
172
|
+
end
|
173
|
+
|
174
|
+
cursor = coll.find()
|
175
|
+
cursor.next
|
176
|
+
cursor.close
|
177
|
+
end
|
178
|
+
|
179
|
+
private
|
180
|
+
|
181
|
+
def prepare_routing_test
|
182
|
+
# Setup replica set connections
|
183
|
+
@primary = make_connection(:primary)
|
184
|
+
@primary_preferred = make_connection(:primary_preferred)
|
185
|
+
@secondary = make_connection(:secondary)
|
186
|
+
@secondary_preferred = make_connection(:secondary_preferred)
|
187
|
+
@repl_cons = [@primary, @primary_preferred, @secondary, @secondary_preferred]
|
188
|
+
|
189
|
+
@repl_cons.each do |client|
|
190
|
+
client.stubs(:pinned_pool).returns(nil)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def make_connection(mode = :primary, opts = {})
|
195
|
+
opts.merge!(:read => mode)
|
196
|
+
opts.merge!(:op_timeout => nil)
|
197
|
+
client = MongoReplicaSetClient.new(@rs.repl_set_seeds, opts)
|
198
|
+
authenticate_client(client)
|
199
|
+
end
|
200
|
+
|
201
|
+
def query_count(connection)
|
202
|
+
connection['admin'].command({:serverStatus => 1})['opcounters']['query']
|
203
|
+
end
|
204
|
+
|
205
|
+
def assert_query_route(test_connection, type)
|
206
|
+
secondary = type == :secondary
|
207
|
+
authenticate_client(test_connection)
|
208
|
+
cursor = test_connection[TEST_DB]['test-sets'].find
|
209
|
+
assert_nothing_raised do
|
210
|
+
cursor.next
|
211
|
+
end
|
212
|
+
pool = cursor.instance_variable_get("@pool")
|
213
|
+
assert_equal secondary, secondary?(MongoClient.new(pool.host, pool.port))
|
214
|
+
end
|
215
|
+
|
216
|
+
def secondary?(client)
|
217
|
+
client['admin'].command(:isMaster => 1)['secondary']
|
218
|
+
end
|
219
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
|
17
|
+
class ReplicaSetRefreshTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
def setup
|
20
|
+
ensure_cluster(:rs)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_connect_and_manual_refresh_with_secondary_down
|
24
|
+
num_secondaries = @rs.secondaries.size
|
25
|
+
client = MongoReplicaSetClient.new(@rs.repl_set_seeds, :refresh_mode => false,
|
26
|
+
:op_timeout => TEST_OP_TIMEOUT)
|
27
|
+
authenticate_client(client)
|
28
|
+
|
29
|
+
assert_equal num_secondaries, client.secondaries.size
|
30
|
+
assert client.connected?
|
31
|
+
assert_equal client.read_pool, client.primary_pool
|
32
|
+
old_refresh_version = client.refresh_version
|
33
|
+
|
34
|
+
@rs.stop_secondary
|
35
|
+
|
36
|
+
client.refresh
|
37
|
+
assert_equal num_secondaries - 1, client.secondaries.size
|
38
|
+
assert client.connected?
|
39
|
+
assert_equal client.read_pool, client.primary_pool
|
40
|
+
assert client.refresh_version > old_refresh_version
|
41
|
+
old_refresh_version = client.refresh_version
|
42
|
+
|
43
|
+
# Test no changes after restart until manual refresh
|
44
|
+
@rs.restart
|
45
|
+
assert_equal num_secondaries - 1, client.secondaries.size
|
46
|
+
assert client.connected?
|
47
|
+
assert_equal client.read_pool, client.primary_pool
|
48
|
+
assert_equal client.refresh_version, old_refresh_version
|
49
|
+
|
50
|
+
# Refresh and ensure state
|
51
|
+
client.refresh
|
52
|
+
assert_equal num_secondaries, client.secondaries.size
|
53
|
+
assert client.connected?
|
54
|
+
assert_equal client.read_pool, client.primary_pool
|
55
|
+
assert client.refresh_version > old_refresh_version
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_automated_refresh_with_secondary_down
|
59
|
+
num_secondaries = @rs.secondaries.size
|
60
|
+
client = MongoReplicaSetClient.new(@rs.repl_set_seeds,
|
61
|
+
:refresh_interval => 1, :refresh_mode => :sync, :read => :secondary_preferred,
|
62
|
+
:op_timeout => TEST_OP_TIMEOUT)
|
63
|
+
authenticate_client(client)
|
64
|
+
|
65
|
+
# Ensure secondaries are all recognized by client and client is connected
|
66
|
+
assert_equal num_secondaries, client.secondaries.size
|
67
|
+
assert client.connected?
|
68
|
+
assert client.secondary_pools.include?(client.read_pool)
|
69
|
+
pool = client.read_pool
|
70
|
+
|
71
|
+
@rs.member_by_name(pool.host_string).stop
|
72
|
+
sleep(2)
|
73
|
+
|
74
|
+
old_refresh_version = client.refresh_version
|
75
|
+
# Trigger synchronous refresh
|
76
|
+
client[TEST_DB]['rs-refresh-test'].find_one
|
77
|
+
|
78
|
+
assert client.connected?
|
79
|
+
assert client.refresh_version > old_refresh_version
|
80
|
+
assert_equal num_secondaries - 1, client.secondaries.size
|
81
|
+
assert client.secondary_pools.include?(client.read_pool)
|
82
|
+
assert_not_equal pool, client.read_pool
|
83
|
+
|
84
|
+
# Restart nodes and ensure refresh interval has passed
|
85
|
+
@rs.restart
|
86
|
+
sleep(2)
|
87
|
+
|
88
|
+
old_refresh_version = client.refresh_version
|
89
|
+
# Trigger synchronous refresh
|
90
|
+
client[TEST_DB]['rs-refresh-test'].find_one
|
91
|
+
|
92
|
+
assert client.connected?
|
93
|
+
assert client.refresh_version > old_refresh_version,
|
94
|
+
"Refresh version hasn't changed."
|
95
|
+
assert_equal num_secondaries, client.secondaries.size
|
96
|
+
"No secondaries have been added."
|
97
|
+
assert_equal num_secondaries, client.secondary_pools.size
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_concurrent_refreshes
|
101
|
+
factor = 5
|
102
|
+
nthreads = factor * 10
|
103
|
+
threads = []
|
104
|
+
client = MongoReplicaSetClient.new(@rs.repl_set_seeds, :refresh_mode => :sync,
|
105
|
+
:refresh_interval => 1, :op_timeout => TEST_OP_TIMEOUT)
|
106
|
+
authenticate_client(client)
|
107
|
+
|
108
|
+
nthreads.times do |i|
|
109
|
+
threads << Thread.new do
|
110
|
+
# force a connection failure every couple of threads that causes a refresh
|
111
|
+
if i % factor == 0
|
112
|
+
cursor = client[TEST_DB]['rs-refresh-test'].find
|
113
|
+
cursor.stubs(:checkout_socket_from_connection).raises(ConnectionFailure)
|
114
|
+
begin
|
115
|
+
cursor.next
|
116
|
+
rescue => ex
|
117
|
+
raise ex unless ex.class == ConnectionFailure
|
118
|
+
next
|
119
|
+
end
|
120
|
+
else
|
121
|
+
# synchronous refreshes will happen every couple of find_ones
|
122
|
+
cursor = client[TEST_DB]['rs-refresh-test'].find_one
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
threads.each do |t|
|
128
|
+
t.join
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_manager_recursive_locking
|
133
|
+
# See RUBY-775
|
134
|
+
# This tests that there isn't recursive locking when a pool manager reconnects
|
135
|
+
# to all replica set members. The bug in RUBY-775 occurred because the same lock
|
136
|
+
# acquired in order to connect the pool manager was used to read the pool manager's
|
137
|
+
# state.
|
138
|
+
client = MongoReplicaSetClient.from_uri(@uri)
|
139
|
+
|
140
|
+
cursor = client[TEST_DB]['rs-refresh-test'].find
|
141
|
+
client.stubs(:receive_message).raises(ConnectionFailure)
|
142
|
+
client.manager.stubs(:refresh_required?).returns(true)
|
143
|
+
client.manager.stubs(:check_connection_health).returns(true)
|
144
|
+
assert_raise ConnectionFailure do
|
145
|
+
cursor.next
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_ping_with_op_timeout
|
150
|
+
[nil, 10].each do |op_timeout|
|
151
|
+
client = MongoReplicaSetClient.new(@rs.repl_set_seeds, :op_timeout => op_timeout)
|
152
|
+
pool = client.primary_pool
|
153
|
+
admin_db = pool.client['admin']
|
154
|
+
admin_db.expects(:command).with({:ping => 1}, :socket => pool.node.socket,
|
155
|
+
:timeout => op_timeout || MongoClient::DEFAULT_OP_TIMEOUT).returns({'ok' => 1})
|
156
|
+
client.expects(:[]).with('admin').returns(admin_db)
|
157
|
+
assert pool.ping
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
=begin
|
162
|
+
def test_automated_refresh_with_removed_node
|
163
|
+
client = MongoReplicaSetClient.new(@rs.repl_set_seeds,
|
164
|
+
:refresh_interval => 1, :refresh_mode => :sync)
|
165
|
+
authenticate_client(client)
|
166
|
+
|
167
|
+
num_secondaries = client.secondary_pools.length
|
168
|
+
old_refresh_version = client.refresh_version
|
169
|
+
|
170
|
+
n = @rs.repl_set_remove_node(2)
|
171
|
+
sleep(2)
|
172
|
+
|
173
|
+
rescue_connection_failure do
|
174
|
+
client[TEST_DB]['rs-refresh-test'].find_one
|
175
|
+
end
|
176
|
+
|
177
|
+
assert client.refresh_version > old_refresh_version,
|
178
|
+
"Refresh version hasn't changed."
|
179
|
+
assert_equal num_secondaries - 1, client.secondaries.length
|
180
|
+
assert_equal num_secondaries - 1, client.secondary_pools.length
|
181
|
+
|
182
|
+
#@rs.add_node(n)
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_adding_and_removing_nodes
|
186
|
+
client = MongoReplicaSetClient.new(build_seeds(3),
|
187
|
+
:refresh_interval => 2, :refresh_mode => :sync)
|
188
|
+
|
189
|
+
@rs.add_node
|
190
|
+
sleep(4)
|
191
|
+
client[TEST_DB]['rs-refresh-test'].find_one
|
192
|
+
|
193
|
+
@conn2 = MongoReplicaSetClient.new(build_seeds(3),
|
194
|
+
:refresh_interval => 2, :refresh_mode => :sync)
|
195
|
+
|
196
|
+
assert @conn2.secondaries.sort == client.secondaries.sort,
|
197
|
+
"Second connection secondaries not equal to first."
|
198
|
+
assert_equal 3, client.secondary_pools.length
|
199
|
+
assert_equal 3, client.secondaries.length
|
200
|
+
|
201
|
+
config = client['admin'].command({:ismaster => 1})
|
202
|
+
|
203
|
+
@rs.remove_secondary_node
|
204
|
+
sleep(4)
|
205
|
+
config = client['admin'].command({:ismaster => 1})
|
206
|
+
|
207
|
+
assert_equal 2, client.secondary_pools.length
|
208
|
+
assert_equal 2, client.secondaries.length
|
209
|
+
end
|
210
|
+
=end
|
211
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
|
17
|
+
class ReplicaSetAckTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
def setup
|
20
|
+
ensure_cluster(:rs)
|
21
|
+
@client = MongoReplicaSetClient.from_uri(@uri, :op_timeout => TEST_OP_TIMEOUT)
|
22
|
+
|
23
|
+
@slave1 = MongoClient.new(
|
24
|
+
@client.secondary_pools.first.host,
|
25
|
+
@client.secondary_pools.first.port, :slave_ok => true)
|
26
|
+
authenticate_client(@slave1)
|
27
|
+
|
28
|
+
assert !@slave1.read_primary?
|
29
|
+
|
30
|
+
@db = @client.db(TEST_DB)
|
31
|
+
@db.drop_collection("test-sets")
|
32
|
+
@col = @db.collection("test-sets")
|
33
|
+
end
|
34
|
+
|
35
|
+
def teardown
|
36
|
+
@client.close if @client
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_safe_mode_with_w_failure
|
40
|
+
assert_raise_error WriteConcernError do
|
41
|
+
@col.insert({:foo => 1}, :w => 4, :wtimeout => 1, :fsync => true)
|
42
|
+
end
|
43
|
+
assert_raise_error WriteConcernError do
|
44
|
+
@col.update({:foo => 1}, {:foo => 2}, :w => 4, :wtimeout => 1, :fsync => true)
|
45
|
+
end
|
46
|
+
assert_raise_error WriteConcernError do
|
47
|
+
@col.remove({:foo => 2}, :w => 4, :wtimeout => 1, :fsync => true)
|
48
|
+
end
|
49
|
+
if @client.server_version >= '2.5.4'
|
50
|
+
assert_raise_error WriteConcernError do
|
51
|
+
@col.insert({:foo => 3}, :w => "test-tag")
|
52
|
+
end
|
53
|
+
else # indistinguishable "errmsg"=>"exception: unrecognized getLastError mode: test-tag"
|
54
|
+
assert_raise_error OperationFailure do
|
55
|
+
@col.insert({:foo => 3}, :w => "test-tag")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_safe_mode_replication_ack
|
61
|
+
@col.insert({:baz => "bar"}, :w => 3, :wtimeout => 5000)
|
62
|
+
|
63
|
+
assert @col.insert({:foo => "0" * 5000}, :w => 3, :wtimeout => 5000)
|
64
|
+
assert_equal 2, @slave1[TEST_DB]["test-sets"].count
|
65
|
+
|
66
|
+
assert @col.update({:baz => "bar"}, {:baz => "foo"}, :w => 3, :wtimeout => 5000)
|
67
|
+
assert @slave1[TEST_DB]["test-sets"].find_one({:baz => "foo"})
|
68
|
+
|
69
|
+
assert @col.insert({:foo => "bar"}, :w => "majority")
|
70
|
+
|
71
|
+
assert @col.insert({:bar => "baz"}, :w => :majority)
|
72
|
+
|
73
|
+
assert @col.remove({}, :w => 3, :wtimeout => 5000)
|
74
|
+
assert_equal 0, @slave1[TEST_DB]["test-sets"].count
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_last_error_responses
|
78
|
+
20.times { @col.insert({:baz => "bar"}) }
|
79
|
+
response = @db.get_last_error(:w => 3, :wtimeout => 5000)
|
80
|
+
assert response['ok'] == 1
|
81
|
+
assert response['lastOp']
|
82
|
+
|
83
|
+
@col.update({}, {:baz => "foo"})
|
84
|
+
response = @db.get_last_error(:w => 3, :wtimeout => 5000)
|
85
|
+
assert response['ok'] == 1
|
86
|
+
assert response['lastOp']
|
87
|
+
|
88
|
+
@col.remove({})
|
89
|
+
response = @db.get_last_error(:w => 3, :wtimeout => 5000)
|
90
|
+
assert response['ok'] == 1
|
91
|
+
assert response['n'] == 20
|
92
|
+
assert response['lastOp']
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
require 'shared/ssl_shared'
|
17
|
+
|
18
|
+
class ReplicaSetSSLTest < Test::Unit::TestCase
|
19
|
+
include Mongo
|
20
|
+
include SSLTests
|
21
|
+
|
22
|
+
SEEDS = ['server:3000','server:3001','server:3002']
|
23
|
+
BAD_SEEDS = ['localhost:3000','localhost:3001','localhost:3002']
|
24
|
+
|
25
|
+
def setup
|
26
|
+
@client_class = MongoReplicaSetClient
|
27
|
+
@uri_info = SEEDS.join(',')
|
28
|
+
@connect_info = SEEDS
|
29
|
+
@bad_connect_info = BAD_SEEDS
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|