mongo 1.10.0-java

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 (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