mongo 1.10.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +190 -0
  5. data/README.md +149 -0
  6. data/Rakefile +31 -0
  7. data/VERSION +1 -0
  8. data/bin/mongo_console +43 -0
  9. data/ext/jsasl/target/jsasl.jar +0 -0
  10. data/lib/mongo.rb +90 -0
  11. data/lib/mongo/bulk_write_collection_view.rb +380 -0
  12. data/lib/mongo/collection.rb +1164 -0
  13. data/lib/mongo/collection_writer.rb +364 -0
  14. data/lib/mongo/connection.rb +19 -0
  15. data/lib/mongo/connection/node.rb +239 -0
  16. data/lib/mongo/connection/pool.rb +347 -0
  17. data/lib/mongo/connection/pool_manager.rb +325 -0
  18. data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
  19. data/lib/mongo/connection/socket.rb +18 -0
  20. data/lib/mongo/connection/socket/socket_util.rb +37 -0
  21. data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
  22. data/lib/mongo/connection/socket/tcp_socket.rb +86 -0
  23. data/lib/mongo/connection/socket/unix_socket.rb +39 -0
  24. data/lib/mongo/cursor.rb +719 -0
  25. data/lib/mongo/db.rb +735 -0
  26. data/lib/mongo/exception.rb +88 -0
  27. data/lib/mongo/functional.rb +21 -0
  28. data/lib/mongo/functional/authentication.rb +318 -0
  29. data/lib/mongo/functional/logging.rb +85 -0
  30. data/lib/mongo/functional/read_preference.rb +174 -0
  31. data/lib/mongo/functional/sasl_java.rb +48 -0
  32. data/lib/mongo/functional/uri_parser.rb +374 -0
  33. data/lib/mongo/functional/write_concern.rb +66 -0
  34. data/lib/mongo/gridfs.rb +18 -0
  35. data/lib/mongo/gridfs/grid.rb +112 -0
  36. data/lib/mongo/gridfs/grid_ext.rb +53 -0
  37. data/lib/mongo/gridfs/grid_file_system.rb +163 -0
  38. data/lib/mongo/gridfs/grid_io.rb +484 -0
  39. data/lib/mongo/legacy.rb +140 -0
  40. data/lib/mongo/mongo_client.rb +702 -0
  41. data/lib/mongo/mongo_replica_set_client.rb +523 -0
  42. data/lib/mongo/mongo_sharded_client.rb +159 -0
  43. data/lib/mongo/networking.rb +370 -0
  44. data/lib/mongo/utils.rb +19 -0
  45. data/lib/mongo/utils/conversions.rb +110 -0
  46. data/lib/mongo/utils/core_ext.rb +70 -0
  47. data/lib/mongo/utils/server_version.rb +69 -0
  48. data/lib/mongo/utils/support.rb +80 -0
  49. data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
  50. data/mongo.gemspec +36 -0
  51. data/test/functional/authentication_test.rb +35 -0
  52. data/test/functional/bulk_api_stress_test.rb +133 -0
  53. data/test/functional/bulk_write_collection_view_test.rb +1129 -0
  54. data/test/functional/client_test.rb +565 -0
  55. data/test/functional/collection_test.rb +2073 -0
  56. data/test/functional/collection_writer_test.rb +83 -0
  57. data/test/functional/conversions_test.rb +163 -0
  58. data/test/functional/cursor_fail_test.rb +63 -0
  59. data/test/functional/cursor_message_test.rb +57 -0
  60. data/test/functional/cursor_test.rb +625 -0
  61. data/test/functional/db_api_test.rb +819 -0
  62. data/test/functional/db_connection_test.rb +27 -0
  63. data/test/functional/db_test.rb +344 -0
  64. data/test/functional/grid_file_system_test.rb +285 -0
  65. data/test/functional/grid_io_test.rb +252 -0
  66. data/test/functional/grid_test.rb +273 -0
  67. data/test/functional/pool_test.rb +62 -0
  68. data/test/functional/safe_test.rb +98 -0
  69. data/test/functional/ssl_test.rb +29 -0
  70. data/test/functional/support_test.rb +62 -0
  71. data/test/functional/timeout_test.rb +58 -0
  72. data/test/functional/uri_test.rb +330 -0
  73. data/test/functional/write_concern_test.rb +118 -0
  74. data/test/helpers/general.rb +50 -0
  75. data/test/helpers/test_unit.rb +317 -0
  76. data/test/replica_set/authentication_test.rb +35 -0
  77. data/test/replica_set/basic_test.rb +174 -0
  78. data/test/replica_set/client_test.rb +341 -0
  79. data/test/replica_set/complex_connect_test.rb +77 -0
  80. data/test/replica_set/connection_test.rb +138 -0
  81. data/test/replica_set/count_test.rb +64 -0
  82. data/test/replica_set/cursor_test.rb +212 -0
  83. data/test/replica_set/insert_test.rb +140 -0
  84. data/test/replica_set/max_values_test.rb +145 -0
  85. data/test/replica_set/pinning_test.rb +55 -0
  86. data/test/replica_set/query_test.rb +73 -0
  87. data/test/replica_set/read_preference_test.rb +214 -0
  88. data/test/replica_set/refresh_test.rb +175 -0
  89. data/test/replica_set/replication_ack_test.rb +94 -0
  90. data/test/replica_set/ssl_test.rb +32 -0
  91. data/test/sharded_cluster/basic_test.rb +197 -0
  92. data/test/shared/authentication/basic_auth_shared.rb +286 -0
  93. data/test/shared/authentication/bulk_api_auth_shared.rb +259 -0
  94. data/test/shared/authentication/gssapi_shared.rb +164 -0
  95. data/test/shared/authentication/sasl_plain_shared.rb +96 -0
  96. data/test/shared/ssl_shared.rb +235 -0
  97. data/test/test_helper.rb +56 -0
  98. data/test/threading/basic_test.rb +120 -0
  99. data/test/tools/mongo_config.rb +608 -0
  100. data/test/tools/mongo_config_test.rb +160 -0
  101. data/test/unit/client_test.rb +347 -0
  102. data/test/unit/collection_test.rb +166 -0
  103. data/test/unit/connection_test.rb +325 -0
  104. data/test/unit/cursor_test.rb +299 -0
  105. data/test/unit/db_test.rb +136 -0
  106. data/test/unit/grid_test.rb +76 -0
  107. data/test/unit/mongo_sharded_client_test.rb +48 -0
  108. data/test/unit/node_test.rb +93 -0
  109. data/test/unit/pool_manager_test.rb +142 -0
  110. data/test/unit/read_pref_test.rb +115 -0
  111. data/test/unit/read_test.rb +159 -0
  112. data/test/unit/safe_test.rb +158 -0
  113. data/test/unit/sharding_pool_manager_test.rb +84 -0
  114. data/test/unit/write_concern_test.rb +175 -0
  115. metadata +260 -0
  116. metadata.gz.sig +0 -0
@@ -0,0 +1,286 @@
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
+ module BasicAuthTests
16
+
17
+ def init_auth_basic
18
+ # enable authentication by creating and logging in as admin user
19
+ @admin = @client['admin']
20
+ @admin.add_user('admin', 'password', nil, :roles => ['readAnyDatabase',
21
+ 'readWriteAnyDatabase',
22
+ 'userAdminAnyDatabase',
23
+ 'dbAdminAnyDatabase',
24
+ 'clusterAdmin'])
25
+ @admin.authenticate('admin', 'password')
26
+
27
+ # db user for cleanup (for pre-2.4)
28
+ @db.add_user('admin', 'cleanup', nil, :roles => [])
29
+ end
30
+
31
+ def teardown_basic
32
+ remove_all_users(@db, 'admin', 'cleanup')
33
+ remove_all_users(@admin, 'admin', 'password') if has_auth?(@admin.name)
34
+ end
35
+
36
+ def remove_all_users(database, username, password)
37
+ database.authenticate(username, password) unless has_auth?(database.name)
38
+ if @client.server_version < '2.5'
39
+ database['system.users'].remove
40
+ else
41
+ database.command(:dropAllUsersFromDatabase => 1)
42
+ end
43
+ database.logout
44
+ end
45
+
46
+ def has_auth?(db_name)
47
+ @client.auths.any? { |a| a[:source] == db_name }
48
+ end
49
+
50
+ def test_add_remove_user
51
+ init_auth_basic
52
+
53
+ # add user
54
+ silently { @db.add_user('bob','user') }
55
+ assert @db.authenticate('bob', 'user')
56
+
57
+ # remove user
58
+ assert @db.remove_user('bob')
59
+
60
+ teardown_basic
61
+ end
62
+
63
+ def test_update_user
64
+ init_auth_basic
65
+
66
+ # add user
67
+ silently { @db.add_user('bob', 'user') }
68
+ assert @db.authenticate('bob', 'user')
69
+ @db.logout
70
+
71
+ # update user
72
+ silently { @db.add_user('bob', 'updated') }
73
+ assert_raise Mongo::AuthenticationError do
74
+ @db.authenticate('bob', 'user')
75
+ end
76
+ assert @db.authenticate('bob', 'updated')
77
+
78
+ teardown_basic
79
+ end
80
+
81
+ def test_remove_non_existent_user
82
+ init_auth_basic
83
+
84
+ if @client.server_version < '2.5'
85
+ assert_equal false, @db.remove_user('joe')
86
+ else
87
+ assert_raise Mongo::OperationFailure do
88
+ assert @db.remove_user('joe')
89
+ end
90
+ end
91
+ teardown_basic
92
+ end
93
+
94
+ def test_authenticate
95
+ init_auth_basic
96
+ silently { @db.add_user('peggy', 'user') }
97
+ assert @db.authenticate('peggy', 'user')
98
+ @db.remove_user('peggy')
99
+ teardown_basic
100
+ end
101
+
102
+ def test_authenticate_non_existent_user
103
+ init_auth_basic
104
+ assert_raise Mongo::AuthenticationError do
105
+ @db.authenticate('frank', 'thetank')
106
+ end
107
+ teardown_basic
108
+ end
109
+
110
+ def test_logout
111
+ init_auth_basic
112
+ silently { @db.add_user('peggy', 'user') }
113
+ assert @db.authenticate('peggy', 'user')
114
+ assert @db.logout
115
+ teardown_basic
116
+ end
117
+
118
+ def test_authenticate_with_special_characters
119
+ init_auth_basic
120
+ silently { assert @db.add_user('foo:bar','@foo') }
121
+ assert @db.authenticate('foo:bar','@foo')
122
+ teardown_basic
123
+ end
124
+
125
+ def test_authenticate_read_only
126
+ init_auth_basic
127
+ silently { @db.add_user('randy', 'readonly', true) }
128
+ assert @db.authenticate('randy', 'readonly')
129
+ teardown_basic
130
+ end
131
+
132
+ def test_authenticate_with_connection_uri
133
+ init_auth_basic
134
+ silently { @db.add_user('eunice', 'uritest') }
135
+
136
+ uri = "mongodb://eunice:uritest@#{@host_info}/#{@db.name}"
137
+ client = Mongo::URIParser.new(uri).connection
138
+
139
+ assert client
140
+ assert_equal client.auths.size, 1
141
+ assert client[TEST_DB]['auth_test'].count
142
+
143
+ auth = client.auths.first
144
+ assert_equal @db.name, auth[:db_name]
145
+ assert_equal 'eunice', auth[:username]
146
+ assert_equal 'uritest', auth[:password]
147
+ teardown_basic
148
+ end
149
+
150
+ def test_socket_auths
151
+ init_auth_basic
152
+ # setup
153
+ db_a = @client[TEST_DB + '_a']
154
+ silently { db_a.add_user('user_a', 'password') }
155
+ assert db_a.authenticate('user_a', 'password')
156
+
157
+ db_b = @client[TEST_DB + '_b']
158
+ silently { db_b.add_user('user_b', 'password') }
159
+ assert db_b.authenticate('user_b', 'password')
160
+
161
+ db_c = @client[TEST_DB + '_c']
162
+ silently { db_c.add_user('user_c', 'password') }
163
+ assert db_c.authenticate('user_c', 'password')
164
+
165
+ # client auths should be applied to socket on checkout
166
+ socket = @client.checkout_reader(:mode => :primary)
167
+ assert_equal 4, socket.auths.size
168
+ assert_equal @client.auths, socket.auths
169
+ @client.checkin(socket)
170
+
171
+ # logout should remove saved auth on socket and client
172
+ assert db_b.logout
173
+ socket = @client.checkout_reader(:mode => :primary)
174
+ assert_equal 3, socket.auths.size
175
+ assert_equal @client.auths, socket.auths
176
+ @client.checkin(socket)
177
+
178
+ # clean-up
179
+ db_b.authenticate('user_b', 'password')
180
+ remove_all_users(db_a, 'user_a', 'password')
181
+ remove_all_users(db_b, 'user_b', 'password')
182
+ remove_all_users(db_c, 'user_c', 'password')
183
+ teardown_basic
184
+ end
185
+
186
+ def test_default_roles_non_admin
187
+ return unless @client.server_version >= '2.5.3'
188
+ init_auth_basic
189
+ silently { @db.add_user('user', 'pass') }
190
+ silently { @db.authenticate('user', 'pass') }
191
+ info = @db.command(:usersInfo => 'user')['users'].first
192
+ assert_equal 'dbOwner', info['roles'].first['role']
193
+
194
+ # read-only
195
+ silently { @db.add_user('ro-user', 'pass', true) }
196
+ @db.logout
197
+ @db.authenticate('ro-user', 'pass')
198
+ info = @db.command(:usersInfo => 'ro-user')['users'].first
199
+ assert_equal 'read', info['roles'].first['role']
200
+ @db.logout
201
+ teardown_basic
202
+ end
203
+
204
+ def test_delegated_authentication
205
+ return unless @client.server_version >= '2.4' && @client.server_version < '2.5'
206
+ with_auth(@client) do
207
+ init_auth_basic
208
+ # create user in test databases
209
+ accounts = @client[TEST_DB + '_accounts']
210
+ silently do
211
+ accounts.add_user('debbie', 'delegate')
212
+ @db.add_user('debbie', nil, nil, :roles => ['read'], :userSource => accounts.name)
213
+ end
214
+ @admin.logout
215
+
216
+ # validate that direct authentication is not allowed
217
+ assert_raise Mongo::AuthenticationError do
218
+ @db.authenticate('debbie', 'delegate')
219
+ end
220
+
221
+ # validate delegated authentication
222
+ assert accounts.authenticate('debbie', 'delegate')
223
+ assert @db.collection_names
224
+ accounts.logout
225
+ assert_raise Mongo::OperationFailure do
226
+ @db.collection_names
227
+ end
228
+
229
+ # validate auth using source database
230
+ @db.authenticate('debbie', 'delegate', nil, accounts.name)
231
+ assert @db.collection_names
232
+ accounts.logout
233
+ assert_raise Mongo::OperationFailure do
234
+ @db.collection_names
235
+ end
236
+
237
+ # clean-up
238
+ @admin.authenticate('admin', 'password')
239
+ remove_all_users(accounts, 'debbie', 'delegate')
240
+ teardown_basic
241
+ end
242
+ end
243
+
244
+ def test_non_admin_default_roles
245
+ return if @client.server_version < '2.5'
246
+ init_auth_basic
247
+
248
+ # add read-only user and verify that role is 'read'
249
+ @db.add_user('randy', 'password', nil, :roles => ['read'])
250
+ @db.authenticate('randy', 'password')
251
+ users = @db.command(:usersInfo => 'randy')['users']
252
+ assert_equal 'read', users.first['roles'].first['role']
253
+ @db.logout
254
+
255
+ # add dbOwner (default) user and verify role
256
+ silently { @db.add_user('emily', 'password') }
257
+ @db.authenticate('emily', 'password')
258
+ users = @db.command(:usersInfo => 'emily')['users']
259
+ assert_equal 'dbOwner', users.first['roles'].first['role']
260
+ teardown_basic
261
+ end
262
+
263
+ def test_update_user_to_read_only
264
+ with_auth(@client) do
265
+ init_auth_basic
266
+ silently { @db.add_user('emily', 'password') }
267
+ @admin.logout
268
+ @db.authenticate('emily', 'password')
269
+ @db['test'].insert({})
270
+ @db.logout
271
+
272
+ @admin.authenticate('admin', 'password')
273
+ silently { @db.add_user('emily', 'password', true) }
274
+ @admin.logout
275
+
276
+ silently { @db.authenticate('emily', 'password') }
277
+ assert_raise Mongo::OperationFailure do
278
+ @db['test'].insert({})
279
+ end
280
+ @db.logout
281
+ @admin.authenticate('admin', 'password')
282
+ teardown_basic
283
+ end
284
+ end
285
+
286
+ end
@@ -0,0 +1,259 @@
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.0x
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
+ module BulkAPIAuthTests
16
+
17
+ include Mongo
18
+
19
+ def init_auth_bulk
20
+ # enable authentication
21
+ @admin = @client["admin"]
22
+ @admin.add_user('admin', 'password', nil, :roles => ['readWriteAnyDatabase',
23
+ 'userAdminAnyDatabase',
24
+ 'dbAdminAnyDatabase'])
25
+ @admin.authenticate('admin', 'password')
26
+
27
+ # Set up the test db
28
+ @collection = @db["bulk-api-auth-tests"]
29
+
30
+ # db user can insert but not remove
31
+ res = BSON::OrderedHash.new
32
+ res[:db] = TEST_DB
33
+ res[:collection] = ""
34
+
35
+ cmd = BSON::OrderedHash.new
36
+ cmd[:createRole] = "insertOnly"
37
+ cmd[:privileges] = [{:resource => res, :actions => [ "insert", "find" ]}]
38
+ cmd[:roles] = []
39
+ @db.command(cmd)
40
+ @db.add_user('insertOnly', 'password', nil, :roles => ['insertOnly'])
41
+
42
+ # db user can insert and remove
43
+ cmd = BSON::OrderedHash.new
44
+ cmd[:createRole] = "insertAndRemove"
45
+ cmd[:privileges] = [{:resource => res, :actions => [ "insert", "remove", "find" ]}]
46
+ cmd[:roles] = []
47
+ @db.command(cmd)
48
+ @db.add_user('insertAndRemove', 'password', nil, :roles => ['insertAndRemove'])
49
+
50
+ # for 2.4 cleanup etc.
51
+ @db.add_user('admin', 'password', nil, :roles => ['readWrite',
52
+ 'userAdmin',
53
+ 'dbAdmin'])
54
+ @admin.logout
55
+ end
56
+
57
+ def teardown_bulk
58
+ remove_all_users_and_roles(@db, 'admin', 'password')
59
+ remove_all_users_and_roles(@admin, 'admin', 'password')
60
+ end
61
+
62
+ def clear_collection(collection)
63
+ @admin.authenticate('admin', 'password')
64
+ collection.remove
65
+ @admin.logout
66
+ end
67
+
68
+ def remove_all_users_and_roles(database, username, password)
69
+ @admin.authenticate('admin', 'password')
70
+ if @version < '2.5.3'
71
+ database['system.users'].remove
72
+ else
73
+ database.command({:dropAllRolesFromDatabase => 1})
74
+ database.command({:dropAllUsersFromDatabase => 1})
75
+ end
76
+ @admin.logout
77
+ end
78
+
79
+ def test_auth_no_error
80
+ return unless @version >= '2.5.3'
81
+ init_auth_bulk
82
+ with_write_commands_and_operations(@db.connection) do |wire_version|
83
+ clear_collection(@collection)
84
+ @db.authenticate('insertAndRemove', 'password')
85
+ bulk = @collection.initialize_ordered_bulk_op
86
+ bulk.insert({:a => 1})
87
+ bulk.find({:a => 1}).remove_one
88
+
89
+ result = bulk.execute
90
+ assert_match_document(
91
+ {
92
+ "ok" => 1,
93
+ "nInserted" => 1,
94
+ "nRemoved" => 1
95
+ }, result, "wire_version:#{wire_version}")
96
+ assert_equal 0, @collection.count
97
+ @db.logout
98
+ end
99
+ teardown_bulk
100
+ end
101
+
102
+ def test_auth_error
103
+ return unless @version >= '2.5.3'
104
+ init_auth_bulk
105
+ with_write_commands_and_operations(@db.connection) do |wire_version|
106
+ clear_collection(@collection)
107
+ @db.authenticate('insertOnly', 'password')
108
+ bulk = @collection.initialize_ordered_bulk_op
109
+ bulk.insert({:a => 1})
110
+ bulk.find({:a => 1}).remove
111
+ bulk.insert({:a => 2})
112
+
113
+ ex = assert_raise Mongo::BulkWriteError do
114
+ bulk.execute
115
+ end
116
+ result = ex.result
117
+ assert_match_document(
118
+ {
119
+ "ok" => 1,
120
+ "n" => 1,
121
+ "writeErrors" =>
122
+ [{
123
+ "index" => 1,
124
+ "code" => 13,
125
+ "errmsg" => /not authorized/
126
+ }],
127
+ "code" => 65,
128
+ "errmsg" => "batch item errors occurred",
129
+ "nInserted" => 1
130
+ }, result, "wire_version:#{wire_version}")
131
+ assert_equal 1, @collection.count
132
+ @db.logout
133
+ end
134
+ teardown_bulk
135
+ end
136
+
137
+ def test_auth_error_unordered
138
+ return unless @version >= '2.5.3'
139
+ init_auth_bulk
140
+ with_write_commands_and_operations(@db.connection) do |wire_version|
141
+ clear_collection(@collection)
142
+ @db.authenticate('insertOnly', 'password')
143
+ bulk = @collection.initialize_unordered_bulk_op
144
+ bulk.insert({:a => 1})
145
+ bulk.find({:a => 1}).remove_one
146
+ bulk.insert({:a => 2})
147
+
148
+ ex = assert_raise Mongo::BulkWriteError do
149
+ bulk.execute
150
+ end
151
+ result = ex.result
152
+ assert_equal 1, result["writeErrors"].length
153
+ assert_equal 2, result["n"]
154
+ assert_equal 2, result["nInserted"]
155
+ assert_equal 2, @collection.count
156
+ @db.logout
157
+ end
158
+ teardown_bulk
159
+ end
160
+
161
+ def test_duplicate_key_with_auth_error
162
+ return unless @version >= '2.5.3'
163
+ init_auth_bulk
164
+ with_write_commands_and_operations(@db.connection) do |wire_version|
165
+ clear_collection(@collection)
166
+ @db.authenticate('insertOnly', 'password')
167
+ bulk = @collection.initialize_ordered_bulk_op
168
+ bulk.insert({:_id => 1, :a => 1})
169
+ bulk.insert({:_id => 1, :a => 2})
170
+ bulk.find({:a => 1}).remove_one
171
+
172
+ ex = assert_raise Mongo::BulkWriteError do
173
+ bulk.execute
174
+ end
175
+ result = ex.result
176
+ assert_match_document(
177
+ {
178
+ "ok" => 1,
179
+ "n" => 1,
180
+ "writeErrors" =>
181
+ [{
182
+ "index" => 1,
183
+ "code" => 11000,
184
+ "errmsg" => /duplicate key error/
185
+ }],
186
+ "code" => 65,
187
+ "errmsg" => "batch item errors occurred",
188
+ "nInserted" => 1
189
+ }, result, "wire_version:#{wire_version}")
190
+ assert_equal 1, @collection.count
191
+ @db.logout
192
+ end
193
+ teardown_bulk
194
+ end
195
+
196
+ def test_duplicate_key_with_auth_error_unordered
197
+ return unless @version >= '2.5.3'
198
+ init_auth_bulk
199
+ with_write_commands_and_operations(@db.connection) do |wire_version|
200
+ clear_collection(@collection)
201
+ @db.authenticate('insertOnly', 'password')
202
+ bulk = @collection.initialize_unordered_bulk_op
203
+ bulk.insert({:_id => 1, :a => 1})
204
+ bulk.insert({:_id => 1, :a => 1})
205
+ bulk.find({:a => 1}).remove_one
206
+
207
+ ex = assert_raise Mongo::BulkWriteError do
208
+ bulk.execute
209
+ end
210
+ result = ex.result
211
+ assert_equal 2, result["writeErrors"].length
212
+ assert_equal 1, result["n"]
213
+ assert_equal 1, result["nInserted"]
214
+ assert_equal 1, @collection.count
215
+ @db.logout
216
+ end
217
+ teardown_bulk
218
+ end
219
+
220
+ def test_write_concern_error_with_auth_error
221
+ with_no_replication(@db.connection) do
222
+ return unless @version >= '2.5.3'
223
+ init_auth_bulk
224
+ with_write_commands_and_operations(@db.connection) do |wire_version|
225
+ clear_collection(@collection)
226
+ @db.authenticate('insertOnly', 'password')
227
+ bulk = @collection.initialize_ordered_bulk_op
228
+ bulk.insert({:_id => 1, :a => 1})
229
+ bulk.insert({:_id => 2, :a => 1})
230
+ bulk.find({:a => 1}).remove_one
231
+
232
+ ex = assert_raise Mongo::BulkWriteError do
233
+ bulk.execute({:w => 2})
234
+ end
235
+ result = ex.result
236
+
237
+ assert_match_document(
238
+ {
239
+ "ok" => 0,
240
+ "n" => 0,
241
+ "nInserted" => 0,
242
+ "writeErrors" =>
243
+ [{
244
+ "index" => 0,
245
+ "code" => 2,
246
+ "errmsg" => /'w' > 1/
247
+ }],
248
+ "code" => 65,
249
+ "errmsg" => "batch item errors occurred"
250
+ }, result, "wire_version#{wire_version}")
251
+ # Re-visit this when RUBY-731 is resolved:
252
+ assert (@collection.count == batch_commands?(wire_version) ? 0 : 1)
253
+ @db.logout
254
+ end
255
+ teardown_bulk
256
+ end
257
+ end
258
+
259
+ end