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.
Files changed (185) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/{LICENSE.txt → LICENSE} +1 -1
  4. data/README.md +122 -271
  5. data/Rakefile +25 -209
  6. data/VERSION +1 -0
  7. data/bin/mongo_console +31 -9
  8. data/lib/mongo/bulk_write_collection_view.rb +387 -0
  9. data/lib/mongo/collection.rb +576 -269
  10. data/lib/mongo/collection_writer.rb +364 -0
  11. data/lib/mongo/connection/node.rb +249 -0
  12. data/lib/mongo/connection/pool.rb +340 -0
  13. data/lib/mongo/connection/pool_manager.rb +320 -0
  14. data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
  15. data/lib/mongo/connection/socket/socket_util.rb +37 -0
  16. data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
  17. data/lib/mongo/connection/socket/tcp_socket.rb +87 -0
  18. data/lib/mongo/connection/socket/unix_socket.rb +39 -0
  19. data/lib/mongo/connection/socket.rb +18 -0
  20. data/lib/mongo/connection.rb +7 -875
  21. data/lib/mongo/cursor.rb +403 -117
  22. data/lib/mongo/db.rb +444 -243
  23. data/lib/mongo/exception.rb +145 -0
  24. data/lib/mongo/functional/authentication.rb +455 -0
  25. data/lib/mongo/functional/logging.rb +85 -0
  26. data/lib/mongo/functional/read_preference.rb +183 -0
  27. data/lib/mongo/functional/scram.rb +556 -0
  28. data/lib/mongo/functional/uri_parser.rb +409 -0
  29. data/lib/mongo/functional/write_concern.rb +66 -0
  30. data/lib/mongo/functional.rb +20 -0
  31. data/lib/mongo/gridfs/grid.rb +30 -24
  32. data/lib/mongo/gridfs/grid_ext.rb +6 -10
  33. data/lib/mongo/gridfs/grid_file_system.rb +38 -20
  34. data/lib/mongo/gridfs/grid_io.rb +84 -75
  35. data/lib/mongo/gridfs.rb +18 -0
  36. data/lib/mongo/legacy.rb +140 -0
  37. data/lib/mongo/mongo_client.rb +697 -0
  38. data/lib/mongo/mongo_replica_set_client.rb +535 -0
  39. data/lib/mongo/mongo_sharded_client.rb +159 -0
  40. data/lib/mongo/networking.rb +372 -0
  41. data/lib/mongo/{util → utils}/conversions.rb +29 -8
  42. data/lib/mongo/{util → utils}/core_ext.rb +28 -18
  43. data/lib/mongo/{util → utils}/server_version.rb +4 -6
  44. data/lib/mongo/{util → utils}/support.rb +29 -31
  45. data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
  46. data/lib/mongo/utils.rb +19 -0
  47. data/lib/mongo.rb +51 -50
  48. data/mongo.gemspec +29 -32
  49. data/test/functional/authentication_test.rb +39 -0
  50. data/test/functional/bulk_api_stress_test.rb +133 -0
  51. data/test/functional/bulk_write_collection_view_test.rb +1198 -0
  52. data/test/functional/client_test.rb +627 -0
  53. data/test/functional/collection_test.rb +2175 -0
  54. data/test/functional/collection_writer_test.rb +83 -0
  55. data/test/{conversions_test.rb → functional/conversions_test.rb} +47 -3
  56. data/test/functional/cursor_fail_test.rb +57 -0
  57. data/test/functional/cursor_message_test.rb +56 -0
  58. data/test/functional/cursor_test.rb +683 -0
  59. data/test/functional/db_api_test.rb +835 -0
  60. data/test/functional/db_connection_test.rb +25 -0
  61. data/test/functional/db_test.rb +348 -0
  62. data/test/functional/grid_file_system_test.rb +285 -0
  63. data/test/{grid_io_test.rb → functional/grid_io_test.rb} +72 -11
  64. data/test/{grid_test.rb → functional/grid_test.rb} +88 -15
  65. data/test/functional/pool_test.rb +136 -0
  66. data/test/functional/safe_test.rb +98 -0
  67. data/test/functional/ssl_test.rb +29 -0
  68. data/test/functional/support_test.rb +62 -0
  69. data/test/functional/timeout_test.rb +60 -0
  70. data/test/functional/uri_test.rb +446 -0
  71. data/test/functional/write_concern_test.rb +118 -0
  72. data/test/helpers/general.rb +50 -0
  73. data/test/helpers/test_unit.rb +476 -0
  74. data/test/replica_set/authentication_test.rb +37 -0
  75. data/test/replica_set/basic_test.rb +189 -0
  76. data/test/replica_set/client_test.rb +393 -0
  77. data/test/replica_set/connection_test.rb +138 -0
  78. data/test/replica_set/count_test.rb +66 -0
  79. data/test/replica_set/cursor_test.rb +220 -0
  80. data/test/replica_set/insert_test.rb +157 -0
  81. data/test/replica_set/max_values_test.rb +151 -0
  82. data/test/replica_set/pinning_test.rb +105 -0
  83. data/test/replica_set/query_test.rb +73 -0
  84. data/test/replica_set/read_preference_test.rb +219 -0
  85. data/test/replica_set/refresh_test.rb +211 -0
  86. data/test/replica_set/replication_ack_test.rb +95 -0
  87. data/test/replica_set/ssl_test.rb +32 -0
  88. data/test/sharded_cluster/basic_test.rb +203 -0
  89. data/test/shared/authentication/basic_auth_shared.rb +260 -0
  90. data/test/shared/authentication/bulk_api_auth_shared.rb +249 -0
  91. data/test/shared/authentication/gssapi_shared.rb +176 -0
  92. data/test/shared/authentication/sasl_plain_shared.rb +96 -0
  93. data/test/shared/authentication/scram_shared.rb +92 -0
  94. data/test/shared/ssl_shared.rb +235 -0
  95. data/test/test_helper.rb +53 -94
  96. data/test/threading/basic_test.rb +120 -0
  97. data/test/tools/mongo_config.rb +708 -0
  98. data/test/tools/mongo_config_test.rb +160 -0
  99. data/test/unit/client_test.rb +381 -0
  100. data/test/unit/collection_test.rb +89 -53
  101. data/test/unit/connection_test.rb +282 -32
  102. data/test/unit/cursor_test.rb +206 -8
  103. data/test/unit/db_test.rb +55 -13
  104. data/test/unit/grid_test.rb +43 -16
  105. data/test/unit/mongo_sharded_client_test.rb +48 -0
  106. data/test/unit/node_test.rb +93 -0
  107. data/test/unit/pool_manager_test.rb +111 -0
  108. data/test/unit/read_pref_test.rb +406 -0
  109. data/test/unit/read_test.rb +159 -0
  110. data/test/unit/safe_test.rb +69 -36
  111. data/test/unit/sharding_pool_manager_test.rb +84 -0
  112. data/test/unit/write_concern_test.rb +175 -0
  113. data.tar.gz.sig +3 -0
  114. metadata +227 -216
  115. metadata.gz.sig +0 -0
  116. data/docs/CREDITS.md +0 -123
  117. data/docs/FAQ.md +0 -116
  118. data/docs/GridFS.md +0 -158
  119. data/docs/HISTORY.md +0 -244
  120. data/docs/RELEASES.md +0 -33
  121. data/docs/REPLICA_SETS.md +0 -72
  122. data/docs/TUTORIAL.md +0 -247
  123. data/docs/WRITE_CONCERN.md +0 -28
  124. data/lib/mongo/exceptions.rb +0 -71
  125. data/lib/mongo/gridfs/grid_io_fix.rb +0 -38
  126. data/lib/mongo/repl_set_connection.rb +0 -342
  127. data/lib/mongo/test.rb +0 -20
  128. data/lib/mongo/util/pool.rb +0 -177
  129. data/lib/mongo/util/uri_parser.rb +0 -185
  130. data/test/async/collection_test.rb +0 -224
  131. data/test/async/connection_test.rb +0 -24
  132. data/test/async/cursor_test.rb +0 -162
  133. data/test/async/worker_pool_test.rb +0 -99
  134. data/test/auxillary/1.4_features.rb +0 -166
  135. data/test/auxillary/authentication_test.rb +0 -68
  136. data/test/auxillary/autoreconnect_test.rb +0 -41
  137. data/test/auxillary/fork_test.rb +0 -30
  138. data/test/auxillary/repl_set_auth_test.rb +0 -58
  139. data/test/auxillary/slave_connection_test.rb +0 -36
  140. data/test/auxillary/threaded_authentication_test.rb +0 -101
  141. data/test/bson/binary_test.rb +0 -15
  142. data/test/bson/bson_test.rb +0 -649
  143. data/test/bson/byte_buffer_test.rb +0 -208
  144. data/test/bson/hash_with_indifferent_access_test.rb +0 -38
  145. data/test/bson/json_test.rb +0 -17
  146. data/test/bson/object_id_test.rb +0 -154
  147. data/test/bson/ordered_hash_test.rb +0 -204
  148. data/test/bson/timestamp_test.rb +0 -24
  149. data/test/collection_test.rb +0 -910
  150. data/test/connection_test.rb +0 -309
  151. data/test/cursor_fail_test.rb +0 -75
  152. data/test/cursor_message_test.rb +0 -43
  153. data/test/cursor_test.rb +0 -483
  154. data/test/db_api_test.rb +0 -726
  155. data/test/db_connection_test.rb +0 -15
  156. data/test/db_test.rb +0 -287
  157. data/test/grid_file_system_test.rb +0 -243
  158. data/test/load/resque/load.rb +0 -21
  159. data/test/load/resque/processor.rb +0 -26
  160. data/test/load/thin/load.rb +0 -24
  161. data/test/load/unicorn/load.rb +0 -23
  162. data/test/load/unicorn/unicorn.rb +0 -29
  163. data/test/replica_sets/connect_test.rb +0 -94
  164. data/test/replica_sets/connection_string_test.rb +0 -32
  165. data/test/replica_sets/count_test.rb +0 -35
  166. data/test/replica_sets/insert_test.rb +0 -53
  167. data/test/replica_sets/pooled_insert_test.rb +0 -55
  168. data/test/replica_sets/query_secondaries.rb +0 -96
  169. data/test/replica_sets/query_test.rb +0 -51
  170. data/test/replica_sets/replication_ack_test.rb +0 -66
  171. data/test/replica_sets/rs_test_helper.rb +0 -27
  172. data/test/safe_test.rb +0 -68
  173. data/test/support/hash_with_indifferent_access.rb +0 -186
  174. data/test/support/keys.rb +0 -45
  175. data/test/support_test.rb +0 -18
  176. data/test/threading/threading_with_large_pool_test.rb +0 -90
  177. data/test/threading_test.rb +0 -87
  178. data/test/tools/auth_repl_set_manager.rb +0 -14
  179. data/test/tools/load.rb +0 -58
  180. data/test/tools/repl_set_manager.rb +0 -266
  181. data/test/tools/sharding_manager.rb +0 -202
  182. data/test/tools/test.rb +0 -4
  183. data/test/unit/pool_test.rb +0 -9
  184. data/test/unit/repl_set_connection_test.rb +0 -59
  185. 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