mongo 2.5.0.beta → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo/address.rb +1 -1
  5. data/lib/mongo/address/unix.rb +1 -1
  6. data/lib/mongo/auth/user.rb +0 -5
  7. data/lib/mongo/auth/user/view.rb +4 -4
  8. data/lib/mongo/bulk_write.rb +60 -32
  9. data/lib/mongo/client.rb +44 -8
  10. data/lib/mongo/cluster.rb +14 -12
  11. data/lib/mongo/cluster/periodic_executor.rb +106 -0
  12. data/lib/mongo/cluster/{cursor_reaper.rb → reapers/cursor_reaper.rb} +5 -37
  13. data/lib/mongo/cluster/reapers/socket_reaper.rb +59 -0
  14. data/lib/mongo/collection.rb +9 -6
  15. data/lib/mongo/collection/view.rb +2 -2
  16. data/lib/mongo/collection/view/builder/aggregation.rb +2 -1
  17. data/lib/mongo/collection/view/builder/find_command.rb +1 -1
  18. data/lib/mongo/collection/view/change_stream.rb +14 -1
  19. data/lib/mongo/collection/view/map_reduce.rb +30 -13
  20. data/lib/mongo/collection/view/readable.rb +5 -5
  21. data/lib/mongo/collection/view/writable.rb +98 -51
  22. data/lib/mongo/error.rb +3 -0
  23. data/lib/mongo/error/invalid_txt_record.rb +27 -0
  24. data/lib/mongo/error/invalid_uri.rb +7 -6
  25. data/lib/mongo/error/mismatched_domain.rb +27 -0
  26. data/lib/mongo/error/no_srv_records.rb +26 -0
  27. data/lib/mongo/error/unsupported_features.rb +0 -18
  28. data/lib/mongo/index/view.rb +2 -2
  29. data/lib/mongo/operation.rb +1 -0
  30. data/lib/mongo/operation/causally_consistent.rb +33 -0
  31. data/lib/mongo/operation/commands.rb +2 -1
  32. data/lib/mongo/operation/commands/aggregate.rb +2 -7
  33. data/lib/mongo/operation/commands/count.rb +27 -0
  34. data/lib/mongo/operation/commands/distinct.rb +27 -0
  35. data/lib/mongo/operation/commands/find.rb +3 -1
  36. data/lib/mongo/operation/commands/map_reduce.rb +1 -0
  37. data/lib/mongo/operation/commands/parallel_scan.rb +1 -0
  38. data/lib/mongo/operation/specifiable.rb +12 -0
  39. data/lib/mongo/operation/uses_command_op_msg.rb +36 -5
  40. data/lib/mongo/operation/write.rb +0 -5
  41. data/lib/mongo/operation/write/bulk/bulkable.rb +4 -8
  42. data/lib/mongo/operation/write/bulk/mergable.rb +2 -0
  43. data/lib/mongo/operation/write/command/create_index.rb +19 -0
  44. data/lib/mongo/operation/write/command/create_user.rb +19 -0
  45. data/lib/mongo/operation/write/command/delete.rb +1 -2
  46. data/lib/mongo/operation/write/command/drop_index.rb +19 -0
  47. data/lib/mongo/operation/write/command/insert.rb +1 -2
  48. data/lib/mongo/operation/write/command/remove_user.rb +19 -0
  49. data/lib/mongo/operation/write/command/update.rb +1 -2
  50. data/lib/mongo/operation/write/command/update_user.rb +19 -0
  51. data/lib/mongo/operation/write/write_command_enabled.rb +1 -3
  52. data/lib/mongo/protocol/compressed.rb +2 -1
  53. data/lib/mongo/protocol/serializers.rb +6 -6
  54. data/lib/mongo/retryable.rb +48 -5
  55. data/lib/mongo/server.rb +15 -0
  56. data/lib/mongo/server/connection.rb +21 -1
  57. data/lib/mongo/server/connection_pool.rb +3 -0
  58. data/lib/mongo/server/connection_pool/queue.rb +50 -5
  59. data/lib/mongo/server/description.rb +11 -3
  60. data/lib/mongo/server/description/features.rb +26 -7
  61. data/lib/mongo/session.rb +133 -6
  62. data/lib/mongo/session/server_session.rb +30 -0
  63. data/lib/mongo/session/session_pool.rb +20 -20
  64. data/lib/mongo/uri.rb +88 -44
  65. data/lib/mongo/uri/srv_protocol.rb +158 -0
  66. data/lib/mongo/version.rb +1 -1
  67. data/lib/mongo/write_concern/normalizable.rb +12 -0
  68. data/mongo.gemspec +1 -2
  69. data/spec/mongo/address_spec.rb +12 -0
  70. data/spec/mongo/auth/user/view_spec.rb +1 -5
  71. data/spec/mongo/bulk_write_spec.rb +232 -401
  72. data/spec/mongo/change_stream_examples_spec.rb +150 -0
  73. data/spec/mongo/client_spec.rb +142 -2
  74. data/spec/mongo/cluster/cursor_reaper_spec.rb +0 -70
  75. data/spec/mongo/cluster/socket_reaper_spec.rb +32 -0
  76. data/spec/mongo/cluster_spec.rb +11 -7
  77. data/spec/mongo/collection/view/aggregation_spec.rb +46 -1
  78. data/spec/mongo/collection/view/builder/find_command_spec.rb +15 -0
  79. data/spec/mongo/collection/view/change_stream_spec.rb +79 -12
  80. data/spec/mongo/collection/view/map_reduce_spec.rb +120 -4
  81. data/spec/mongo/collection/view/readable_spec.rb +23 -5
  82. data/spec/mongo/collection_spec.rb +292 -102
  83. data/spec/mongo/command_monitoring_spec.rb +26 -32
  84. data/spec/mongo/crud_spec.rb +1 -1
  85. data/spec/mongo/cursor_spec.rb +2 -3
  86. data/spec/mongo/database_spec.rb +30 -14
  87. data/spec/mongo/dns_seedlist_discovery_spec.rb +94 -0
  88. data/spec/mongo/grid/fs_bucket_spec.rb +1 -1
  89. data/spec/mongo/grid/stream/write_spec.rb +1 -1
  90. data/spec/mongo/index/view_spec.rb +8 -46
  91. data/spec/mongo/operation/write/bulk/delete_spec.rb +2 -2
  92. data/spec/mongo/operation/write/bulk/insert_spec.rb +2 -10
  93. data/spec/mongo/operation/write/{create_index_spec.rb → command/create_index_spec.rb} +2 -6
  94. data/spec/mongo/operation/write/command/delete_spec.rb +35 -7
  95. data/spec/mongo/operation/write/{drop_index_spec.rb → command/drop_index_spec.rb} +1 -1
  96. data/spec/mongo/operation/write/command/insert_spec.rb +37 -6
  97. data/spec/mongo/operation/write/{remove_user_spec.rb → command/remove_user_spec.rb} +2 -6
  98. data/spec/mongo/operation/write/command/update_spec.rb +34 -7
  99. data/spec/mongo/operation/write/{update_user_spec.rb → command/update_user_spec.rb} +1 -1
  100. data/spec/mongo/operation/write/create_user_spec.rb +1 -1
  101. data/spec/mongo/operation/write/delete_spec.rb +1 -1
  102. data/spec/mongo/operation/write/insert_spec.rb +2 -10
  103. data/spec/mongo/operation/write/update_spec.rb +3 -15
  104. data/spec/mongo/retryable_spec.rb +1 -1
  105. data/spec/mongo/retryable_writes_spec.rb +815 -0
  106. data/spec/mongo/server/connection_pool/queue_spec.rb +35 -2
  107. data/spec/mongo/server/connection_pool_spec.rb +234 -1
  108. data/spec/mongo/server/connection_spec.rb +10 -6
  109. data/spec/mongo/server/description/features_spec.rb +51 -37
  110. data/spec/mongo/server/description_spec.rb +6 -3
  111. data/spec/mongo/server_spec.rb +87 -0
  112. data/spec/mongo/session/server_session_spec.rb +43 -0
  113. data/spec/mongo/session/session_pool_spec.rb +63 -27
  114. data/spec/mongo/session_spec.rb +247 -0
  115. data/spec/mongo/shell_examples_spec.rb +2 -2
  116. data/spec/mongo/uri/srv_protocol_spec.rb +933 -0
  117. data/spec/mongo/uri_spec.rb +42 -3
  118. data/spec/mongo/write_concern/acknowledged_spec.rb +11 -0
  119. data/spec/mongo/write_concern/unacknowledged_spec.rb +11 -0
  120. data/spec/spec_helper.rb +11 -25
  121. data/spec/support/authorization.rb +2 -1
  122. data/spec/support/connection_string.rb +8 -4
  123. data/spec/support/crud.rb +38 -24
  124. data/spec/support/crud/write.rb +30 -3
  125. data/spec/support/crud_tests/read/aggregate-out.yml +21 -0
  126. data/spec/support/crud_tests/write/bulkWrite-arrayFilters.yml +44 -0
  127. data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +1 -1
  128. data/spec/support/crud_tests/write/insertMany.yml +1 -3
  129. data/spec/support/crud_tests/write/replaceOne.yml +1 -1
  130. data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +1 -1
  131. data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +1 -1
  132. data/spec/support/dns_seedlist_discovery_tests/longer-parent-in-return.yml +11 -0
  133. data/spec/support/dns_seedlist_discovery_tests/misformatted-option.yml +5 -0
  134. data/spec/support/dns_seedlist_discovery_tests/no-results.yml +5 -0
  135. data/spec/support/dns_seedlist_discovery_tests/not-enough-parts.yml +5 -0
  136. data/spec/support/dns_seedlist_discovery_tests/one-result-default-port.yml +10 -0
  137. data/spec/support/dns_seedlist_discovery_tests/one-txt-record-multiple-strings.yml +10 -0
  138. data/spec/support/dns_seedlist_discovery_tests/one-txt-record.yml +11 -0
  139. data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch1.yml +5 -0
  140. data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch2.yml +5 -0
  141. data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch3.yml +5 -0
  142. data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch4.yml +5 -0
  143. data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch5.yml +5 -0
  144. data/spec/support/dns_seedlist_discovery_tests/returned-parent-too-short.yml +5 -0
  145. data/spec/support/dns_seedlist_discovery_tests/returned-parent-wrong.yml +5 -0
  146. data/spec/support/dns_seedlist_discovery_tests/two-results-default-port.yml +11 -0
  147. data/spec/support/dns_seedlist_discovery_tests/two-results-nonstandard-port.yml +11 -0
  148. data/spec/support/dns_seedlist_discovery_tests/two-txt-records.yml +5 -0
  149. data/spec/support/dns_seedlist_discovery_tests/txt-record-not-allowed-option.yml +5 -0
  150. data/spec/support/dns_seedlist_discovery_tests/txt-record-with-overridden-ssl-option.yml +11 -0
  151. data/spec/support/dns_seedlist_discovery_tests/txt-record-with-overridden-uri-option.yml +11 -0
  152. data/spec/support/dns_seedlist_discovery_tests/txt-record-with-unallowed-option.yml +5 -0
  153. data/spec/support/dns_seedlist_discovery_tests/uri-with-port.yml +5 -0
  154. data/spec/support/dns_seedlist_discovery_tests/uri-with-two-hosts.yml +5 -0
  155. data/spec/support/retryable_writes_tests/bulkWrite.yml +305 -0
  156. data/spec/support/retryable_writes_tests/deleteOne.yml +51 -0
  157. data/spec/support/retryable_writes_tests/findOneAndDelete.yml +52 -0
  158. data/spec/support/retryable_writes_tests/findOneAndReplace.yml +57 -0
  159. data/spec/support/retryable_writes_tests/findOneAndUpdate.yml +56 -0
  160. data/spec/support/retryable_writes_tests/insertMany.yml +72 -0
  161. data/spec/support/retryable_writes_tests/insertOne.yml +55 -0
  162. data/spec/support/retryable_writes_tests/replaceOne.yml +60 -0
  163. data/spec/support/retryable_writes_tests/updateOne.yml +120 -0
  164. data/spec/support/shared/session.rb +525 -24
  165. metadata +437 -350
  166. metadata.gz.sig +0 -0
  167. data/lib/mongo/operation/commands/user_query.rb +0 -72
  168. data/lib/mongo/operation/write/create_index.rb +0 -67
  169. data/lib/mongo/operation/write/create_user.rb +0 -50
  170. data/lib/mongo/operation/write/drop_index.rb +0 -63
  171. data/lib/mongo/operation/write/remove_user.rb +0 -48
  172. data/lib/mongo/operation/write/update_user.rb +0 -50
@@ -0,0 +1,158 @@
1
+ # Copyright (C) 2017 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 'resolv'
16
+
17
+ module Mongo
18
+
19
+ class URI
20
+
21
+ # Parser for a URI using the mongodb+srv protocol, which specifies a DNS to query for SRV records.
22
+ # The driver will query the DNS server for SRV records on {hostname}.{domainname},
23
+ # prefixed with _mongodb._tcp
24
+ # The SRV records can then be used as the seedlist for a Mongo::Client.
25
+ # The driver also queries for a TXT record providing default connection string options.
26
+ # Only one TXT record is allowed, and only a subset of Mongo::Client options is allowed.
27
+ #
28
+ # Please refer to the Initial DNS Seedlist Discovery spec for details.
29
+ #
30
+ # https://github.com/mongodb/specifications/blob/master/source/initial-dns-seedlist-discovery
31
+ #
32
+ # @example Use the uri string to make a client connection.
33
+ # client = Mongo::Client.new('mongodb+srv://test6.test.build.10gen.cc/')
34
+ #
35
+ # @since 2.5.0
36
+ class SRVProtocol < URI
37
+
38
+ # Gets the options hash that needs to be passed to a Mongo::Client on instantiation, so we
39
+ # don't have to merge the txt record options, credentials, and database in at that point -
40
+ # we only have a single point here.
41
+ #
42
+ # @example Get the client options.
43
+ # uri.client_options
44
+ #
45
+ # @return [ Hash ] The options passed to the Mongo::Client
46
+ #
47
+ # @since 2.5.0
48
+ def client_options
49
+ opts = @txt_options.merge(ssl: true)
50
+ opts = opts.merge(uri_options).merge(:database => database)
51
+ @user ? opts.merge(credentials) : opts
52
+ end
53
+
54
+ private
55
+
56
+ RECORD_PREFIX = '_mongodb._tcp.'.freeze
57
+
58
+ DOT_PARTITION = '.'.freeze
59
+
60
+ VALID_TXT_OPTIONS = ['replicaset', 'authsource'].freeze
61
+
62
+ INVALID_HOST = "One and only one host is required in a connection string with the " +
63
+ "'#{MONGODB_SRV_SCHEME}' protocol.".freeze
64
+
65
+ INVALID_PORT = "It is not allowed to specify a port in a connection string with the " +
66
+ "'#{MONGODB_SRV_SCHEME}' protocol.".freeze
67
+
68
+ INVALID_DOMAIN = "The domain name must consist of at least two parts: the domain name, " +
69
+ "and a TLD.".freeze
70
+
71
+ NO_SRV_RECORDS = "The DNS query returned no SRV records at hostname (%s)".freeze
72
+
73
+ MORE_THAN_ONE_TXT_RECORD_FOUND = "Only one TXT record is allowed. Querying hostname (%s) " +
74
+ "returned more than one result.".freeze
75
+
76
+ INVALID_TXT_RECORD_OPTION = "TXT records can only specify the options " +
77
+ "[#{VALID_TXT_OPTIONS.join(', ')}].".freeze
78
+
79
+ MISMATCHED_DOMAINNAME = "Parent domain name in SRV record result (%s) does not match " +
80
+ "that of the hostname (%s)".freeze
81
+
82
+ FORMAT = 'mongodb+srv://[username:password@]host[/[database][?options]]'.freeze
83
+
84
+ def scheme
85
+ MONGODB_SRV_SCHEME
86
+ end
87
+
88
+ def raise_invalid_error!(details)
89
+ raise Error::InvalidURI.new(@string, details, FORMAT)
90
+ end
91
+
92
+ def resolver
93
+ @resolver ||= Resolv::DNS.new
94
+ end
95
+
96
+ def parse_creds_hosts!(string)
97
+ hostname, creds = split_creds_hosts(string)
98
+ validate_hostname!(hostname)
99
+ records = get_records(hostname)
100
+ @txt_options = get_txt_opts(hostname) || {}
101
+ @servers = parse_servers!(records.join(','))
102
+ @user = parse_user!(creds)
103
+ @password = parse_password!(creds)
104
+ end
105
+
106
+ def validate_hostname!(hostname)
107
+ raise_invalid_error!(INVALID_HOST) if hostname.empty?
108
+ raise_invalid_error!(INVALID_HOST) if hostname.include?(HOST_DELIM)
109
+ raise_invalid_error!(INVALID_PORT) if hostname.include?(HOST_PORT_DELIM)
110
+ _, _, domain = hostname.partition(DOT_PARTITION)
111
+ raise_invalid_error!(INVALID_DOMAIN) unless domain.include?(DOT_PARTITION)
112
+ end
113
+
114
+ def get_records(hostname)
115
+ query_name = RECORD_PREFIX + hostname
116
+ records = resolver.getresources(query_name, Resolv::DNS::Resource::IN::SRV).collect do |record|
117
+ record_host = record.target.to_s
118
+ port = record.port
119
+ validate_record!(record_host, hostname)
120
+ "#{record_host}#{HOST_PORT_DELIM}#{port}"
121
+ end
122
+ raise Error::NoSRVRecords.new(NO_SRV_RECORDS % hostname) if records.empty?
123
+ records
124
+ end
125
+
126
+ def validate_record!(record_host, hostname)
127
+ domainname = hostname.split(DOT_PARTITION)[1..-1]
128
+ host_parts = record_host.split(DOT_PARTITION)
129
+ unless (host_parts.size > domainname.size) && (domainname == host_parts[-domainname.length..-1])
130
+ raise Error::MismatchedDomain.new(MISMATCHED_DOMAINNAME % [record_host, domainname])
131
+ end
132
+ end
133
+
134
+ def get_txt_opts(host)
135
+ records = resolver.getresources(host, Resolv::DNS::Resource::IN::TXT)
136
+ unless records.empty?
137
+ if records.size > 1
138
+ raise Error::InvalidTXTRecord.new(MORE_THAN_ONE_TXT_RECORD_FOUND % host)
139
+ end
140
+ options_string = records[0].strings.join
141
+ parse_txt_options!(options_string)
142
+ end
143
+ end
144
+
145
+ def parse_txt_options!(string)
146
+ return {} unless string
147
+ string.split(INDIV_URI_OPTS_DELIM).reduce({}) do |txt_options, opt|
148
+ raise Error::InvalidTXTRecord.new(INVALID_OPTS_VALUE_DELIM) unless opt.index(URI_OPTS_VALUE_DELIM)
149
+ key, value = opt.split(URI_OPTS_VALUE_DELIM)
150
+ raise Error::InvalidTXTRecord.new(INVALID_TXT_RECORD_OPTION) unless VALID_TXT_OPTIONS.include?(key.downcase)
151
+ strategy = URI_OPTION_MAP[key.downcase]
152
+ add_uri_option(strategy, value, txt_options)
153
+ txt_options
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
data/lib/mongo/version.rb CHANGED
@@ -17,5 +17,5 @@ module Mongo
17
17
  # The current version of the driver.
18
18
  #
19
19
  # @since 2.0.0
20
- VERSION = '2.5.0.beta'.freeze
20
+ VERSION = '2.5.0'.freeze
21
21
  end
@@ -47,6 +47,18 @@ module Mongo
47
47
  opts = Options::Mapper.transform_keys_to_symbols(options)
48
48
  @options = Options::Mapper.transform_values_to_strings(opts).freeze
49
49
  end
50
+
51
+ # Is this write concern acknowledged.
52
+ #
53
+ # @example Whether this write concern object is acknowledged.
54
+ # write_concern.acknowledged?
55
+ #
56
+ # @return [ true, false ] Whether this write concern is acknowledged.
57
+ #
58
+ # @since 2.5.0
59
+ def acknowledged?
60
+ !!get_last_error
61
+ end
50
62
  end
51
63
  end
52
64
  end
data/mongo.gemspec CHANGED
@@ -29,6 +29,5 @@ Gem::Specification.new do |s|
29
29
  s.require_paths = ['lib']
30
30
  s.bindir = 'bin'
31
31
 
32
- #s.add_dependency 'bson', '>=4.3.0', '<5.0.0'
33
- s.add_dependency 'bson', '4.3.0.beta'
32
+ s.add_dependency 'bson', '>=4.3.0', '<5.0.0'
34
33
  end
@@ -228,5 +228,17 @@ describe Mongo::Address do
228
228
  expect(address.socket(0.0)).not_to be_nil
229
229
  end
230
230
  end
231
+
232
+ context 'when creating a socket using the resolver' do
233
+
234
+ before do
235
+ address.instance_variable_set(:@resolver, nil)
236
+ address.send(:initialize_resolver!, (SSL ? SSL_OPTIONS : {}))
237
+ end
238
+
239
+ it 'uses the host, not the IP address' do
240
+ expect(address.socket(0.0).host).to eq(host)
241
+ end
242
+ end
231
243
  end
232
244
  end
@@ -200,15 +200,11 @@ describe Mongo::Auth::User::View do
200
200
 
201
201
  context 'when removal was not successful' do
202
202
 
203
- it 'raises an exception', if: write_command_enabled? do
203
+ it 'raises an exception' do
204
204
  expect {
205
205
  view.remove('notauser')
206
206
  }.to raise_error(Mongo::Error::OperationFailure)
207
207
  end
208
-
209
- it 'does not raise an exception', unless: write_command_enabled? do
210
- expect(view.remove('notauser').written_count).to eq(0)
211
- end
212
208
  end
213
209
  end
214
210
 
@@ -31,6 +31,14 @@ describe Mongo::BulkWrite do
31
31
  [{ 'i.y' => 3}]
32
32
  end
33
33
 
34
+ let(:collection) do
35
+ authorized_collection
36
+ end
37
+
38
+ let(:client) do
39
+ authorized_client
40
+ end
41
+
34
42
  describe '#execute' do
35
43
  shared_examples_for 'an executable bulk write' do
36
44
 
@@ -135,39 +143,27 @@ describe Mongo::BulkWrite do
135
143
 
136
144
  context 'when there is a write concern error' do
137
145
 
138
- context 'when the server version is < 2.6' do
139
-
140
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
141
- expect {
142
- bulk_write_invalid_write_concern.execute
143
- }.to raise_error(Mongo::Error::BulkWriteError)
144
- end
146
+ it 'raises an OperationFailure', if: standalone? do
147
+ expect {
148
+ bulk_write_invalid_write_concern.execute
149
+ }.to raise_error(Mongo::Error::OperationFailure)
145
150
  end
146
151
 
147
- context 'when the server version has write commands enabled' do
152
+ context 'when a session is provided' do
148
153
 
149
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
150
- expect {
151
- bulk_write_invalid_write_concern.execute
152
- }.to raise_error(Mongo::Error::OperationFailure)
154
+ let(:extra_options) do
155
+ {session: session}
153
156
  end
154
157
 
155
- context 'when a session is provided' do
156
-
157
- let(:extra_options) do
158
- { session: session }
159
- end
160
-
161
- let(:client) do
162
- collection_invalid_write_concern.client
163
- end
164
-
165
- let(:failed_operation) do
166
- bulk_write_invalid_write_concern.execute
167
- end
158
+ let(:client) do
159
+ collection_invalid_write_concern.client
160
+ end
168
161
 
169
- it_behaves_like 'a failed operation using a session'
162
+ let(:failed_operation) do
163
+ bulk_write_invalid_write_concern.execute
170
164
  end
165
+
166
+ it_behaves_like 'a failed operation using a session'
171
167
  end
172
168
  end
173
169
  end
@@ -206,39 +202,27 @@ describe Mongo::BulkWrite do
206
202
 
207
203
  context 'when there is a write concern error' do
208
204
 
209
- context 'when the server version is < 2.6' do
210
-
211
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
212
- expect {
213
- bulk_write_invalid_write_concern.execute
214
- }.to raise_error(Mongo::Error::BulkWriteError)
215
- end
205
+ it 'raises an OperationFailure', if: standalone? do
206
+ expect {
207
+ bulk_write_invalid_write_concern.execute
208
+ }.to raise_error(Mongo::Error::OperationFailure)
216
209
  end
217
210
 
218
- context 'when the server version has write commands enabled' do
211
+ context 'when a session is provided' do
219
212
 
220
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
221
- expect {
222
- bulk_write_invalid_write_concern.execute
223
- }.to raise_error(Mongo::Error::OperationFailure)
213
+ let(:extra_options) do
214
+ {session: session}
224
215
  end
225
216
 
226
- context 'when a session is provided' do
227
-
228
- let(:extra_options) do
229
- { session: session }
230
- end
231
-
232
- let(:client) do
233
- collection_invalid_write_concern.client
234
- end
235
-
236
- let(:failed_operation) do
237
- bulk_write_invalid_write_concern.execute
238
- end
217
+ let(:client) do
218
+ collection_invalid_write_concern.client
219
+ end
239
220
 
240
- it_behaves_like 'a failed operation using a session'
221
+ let(:failed_operation) do
222
+ bulk_write_invalid_write_concern.execute
241
223
  end
224
+
225
+ it_behaves_like 'a failed operation using a session'
242
226
  end
243
227
  end
244
228
  end
@@ -281,39 +265,27 @@ describe Mongo::BulkWrite do
281
265
 
282
266
  context 'when there is a write concern error' do
283
267
 
284
- context 'when the server version is < 2.6' do
285
-
286
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
287
- expect {
288
- bulk_write_invalid_write_concern.execute
289
- }.to raise_error(Mongo::Error::BulkWriteError)
290
- end
268
+ it 'raises an OperationFailure', if: standalone? do
269
+ expect {
270
+ bulk_write_invalid_write_concern.execute
271
+ }.to raise_error(Mongo::Error::OperationFailure)
291
272
  end
292
273
 
293
- context 'when the server version has write commands enabled' do
274
+ context 'when a session is provided' do
294
275
 
295
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
296
- expect {
297
- bulk_write_invalid_write_concern.execute
298
- }.to raise_error(Mongo::Error::OperationFailure)
276
+ let(:extra_options) do
277
+ {session: session}
299
278
  end
300
279
 
301
- context 'when a session is provided' do
302
-
303
- let(:extra_options) do
304
- { session: session }
305
- end
306
-
307
- let(:client) do
308
- collection_invalid_write_concern.client
309
- end
310
-
311
- let(:failed_operation) do
312
- bulk_write_invalid_write_concern.execute
313
- end
280
+ let(:client) do
281
+ collection_invalid_write_concern.client
282
+ end
314
283
 
315
- it_behaves_like 'a failed operation using a session'
284
+ let(:failed_operation) do
285
+ bulk_write_invalid_write_concern.execute
316
286
  end
287
+
288
+ it_behaves_like 'a failed operation using a session'
317
289
  end
318
290
 
319
291
  context 'when the write has a collation specified' do
@@ -558,39 +530,28 @@ describe Mongo::BulkWrite do
558
530
 
559
531
  context 'when there is a write concern error' do
560
532
 
561
- context 'when the server version is < 2.6' do
562
533
 
563
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
564
- expect {
565
- bulk_write_invalid_write_concern.execute
566
- }.to raise_error(Mongo::Error::BulkWriteError)
567
- end
534
+ it 'raises an OperationFailure', if: standalone? do
535
+ expect {
536
+ bulk_write_invalid_write_concern.execute
537
+ }.to raise_error(Mongo::Error::OperationFailure)
568
538
  end
569
539
 
570
- context 'when the server version has write commands enabled' do
540
+ context 'when a session is provided' do
571
541
 
572
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
573
- expect {
574
- bulk_write_invalid_write_concern.execute
575
- }.to raise_error(Mongo::Error::OperationFailure)
542
+ let(:extra_options) do
543
+ {session: session}
576
544
  end
577
545
 
578
- context 'when a session is provided' do
579
-
580
- let(:extra_options) do
581
- { session: session }
582
- end
583
-
584
- let(:client) do
585
- collection_invalid_write_concern.client
586
- end
587
-
588
- let(:failed_operation) do
589
- bulk_write_invalid_write_concern.execute
590
- end
546
+ let(:client) do
547
+ collection_invalid_write_concern.client
548
+ end
591
549
 
592
- it_behaves_like 'a failed operation using a session'
550
+ let(:failed_operation) do
551
+ bulk_write_invalid_write_concern.execute
593
552
  end
553
+
554
+ it_behaves_like 'a failed operation using a session'
594
555
  end
595
556
  end
596
557
 
@@ -709,39 +670,27 @@ describe Mongo::BulkWrite do
709
670
 
710
671
  context 'when there is a write concern error' do
711
672
 
712
- context 'when the server version is < 2.6' do
713
-
714
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
715
- expect {
716
- bulk_write_invalid_write_concern.execute
717
- }.to raise_error(Mongo::Error::BulkWriteError)
718
- end
673
+ it 'raises an OperationFailure', if: standalone? do
674
+ expect {
675
+ bulk_write_invalid_write_concern.execute
676
+ }.to raise_error(Mongo::Error::OperationFailure)
719
677
  end
720
678
 
721
- context 'when the server version has write commands enabled' do
679
+ context 'when a session is provided' do
722
680
 
723
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
724
- expect {
725
- bulk_write_invalid_write_concern.execute
726
- }.to raise_error(Mongo::Error::OperationFailure)
681
+ let(:extra_options) do
682
+ {session: session}
727
683
  end
728
684
 
729
- context 'when a session is provided' do
730
-
731
- let(:extra_options) do
732
- { session: session }
733
- end
734
-
735
- let(:client) do
736
- collection_invalid_write_concern.client
737
- end
738
-
739
- let(:failed_operation) do
740
- bulk_write_invalid_write_concern.execute
741
- end
685
+ let(:client) do
686
+ collection_invalid_write_concern.client
687
+ end
742
688
 
743
- it_behaves_like 'a failed operation using a session'
689
+ let(:failed_operation) do
690
+ bulk_write_invalid_write_concern.execute
744
691
  end
692
+
693
+ it_behaves_like 'a failed operation using a session'
745
694
  end
746
695
  end
747
696
 
@@ -863,39 +812,27 @@ describe Mongo::BulkWrite do
863
812
 
864
813
  context 'when there is a write concern error' do
865
814
 
866
- context 'when the server version is < 2.6' do
867
-
868
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
869
- expect {
870
- bulk_write_invalid_write_concern.execute
871
- }.to raise_error(Mongo::Error::BulkWriteError)
872
- end
815
+ it 'raises an OperationFailure', if: standalone? do
816
+ expect {
817
+ bulk_write_invalid_write_concern.execute
818
+ }.to raise_error(Mongo::Error::OperationFailure)
873
819
  end
874
820
 
875
- context 'when the server version has write commands enabled' do
821
+ context 'when a session is provided' do
876
822
 
877
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
878
- expect {
879
- bulk_write_invalid_write_concern.execute
880
- }.to raise_error(Mongo::Error::OperationFailure)
823
+ let(:operation) do
824
+ result
881
825
  end
882
826
 
883
- context 'when a session is provided' do
884
-
885
- let(:operation) do
886
- result
887
- end
888
-
889
- let(:client) do
890
- authorized_client
891
- end
892
-
893
- let(:extra_options) do
894
- { session: session }
895
- end
827
+ let(:client) do
828
+ authorized_client
829
+ end
896
830
 
897
- it_behaves_like 'an operation using a session'
831
+ let(:extra_options) do
832
+ {session: session}
898
833
  end
834
+
835
+ it_behaves_like 'an operation using a session'
899
836
  end
900
837
  end
901
838
 
@@ -992,16 +929,11 @@ describe Mongo::BulkWrite do
992
929
  authorized_collection.insert_one({ _id: 0 })
993
930
  end
994
931
 
995
- it 'replaces the document', if: write_command_enabled? do
932
+ it 'replaces the document' do
996
933
  expect(result.modified_count).to eq(1)
997
934
  expect(authorized_collection.find(_id: 0).first[:name]).to eq('test')
998
935
  end
999
936
 
1000
- it 'replaces the document', unless: write_command_enabled? do
1001
- expect(result.modified_count).to be_nil
1002
- expect(authorized_collection.find(_id: 0).first[:name]).to eq('test')
1003
- end
1004
-
1005
937
  context 'when a session is provided' do
1006
938
 
1007
939
  let(:operation) do
@@ -1021,39 +953,27 @@ describe Mongo::BulkWrite do
1021
953
 
1022
954
  context 'when there is a write concern error' do
1023
955
 
1024
- context 'when the server version is < 2.6' do
1025
-
1026
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
1027
- expect {
1028
- bulk_write_invalid_write_concern.execute
1029
- }.to raise_error(Mongo::Error::BulkWriteError)
1030
- end
956
+ it 'raises an OperationFailure', if: standalone? do
957
+ expect {
958
+ bulk_write_invalid_write_concern.execute
959
+ }.to raise_error(Mongo::Error::OperationFailure)
1031
960
  end
1032
961
 
1033
- context 'when the server version has write commands enabled' do
962
+ context 'when a session is provided' do
1034
963
 
1035
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
1036
- expect {
1037
- bulk_write_invalid_write_concern.execute
1038
- }.to raise_error(Mongo::Error::OperationFailure)
964
+ let(:extra_options) do
965
+ {session: session}
1039
966
  end
1040
967
 
1041
- context 'when a session is provided' do
1042
-
1043
- let(:extra_options) do
1044
- { session: session }
1045
- end
1046
-
1047
- let(:client) do
1048
- collection_invalid_write_concern.client
1049
- end
1050
-
1051
- let(:failed_operation) do
1052
- bulk_write_invalid_write_concern.execute
1053
- end
968
+ let(:client) do
969
+ collection_invalid_write_concern.client
970
+ end
1054
971
 
1055
- it_behaves_like 'a failed operation using a session'
972
+ let(:failed_operation) do
973
+ bulk_write_invalid_write_concern.execute
1056
974
  end
975
+
976
+ it_behaves_like 'a failed operation using a session'
1057
977
  end
1058
978
  end
1059
979
 
@@ -1087,14 +1007,10 @@ describe Mongo::BulkWrite do
1087
1007
  expect(result.upserted_count).to eq(0)
1088
1008
  end
1089
1009
 
1090
- it 'reports the modified count', if: collation_enabled? && write_command_enabled? do
1010
+ it 'reports the modified count', if: collation_enabled? do
1091
1011
  expect(result.modified_count).to eq(1)
1092
1012
  end
1093
1013
 
1094
- it 'returns nil for the modified count', if: collation_enabled? && !write_command_enabled? do
1095
- expect(result.modified_count).to be_nil
1096
- end
1097
-
1098
1014
  it 'reports the matched count', if: collation_enabled? do
1099
1015
  expect(result.matched_count).to eq(1)
1100
1016
  end
@@ -1151,14 +1067,10 @@ describe Mongo::BulkWrite do
1151
1067
  expect(result.upserted_count).to eq(0)
1152
1068
  end
1153
1069
 
1154
- it 'reports the modified count', if: write_command_enabled? do
1070
+ it 'reports the modified count' do
1155
1071
  expect(result.modified_count).to eq(0)
1156
1072
  end
1157
1073
 
1158
- it 'returns nil as the modified count', unless: write_command_enabled? do
1159
- expect(result.modified_count).to be_nil
1160
- end
1161
-
1162
1074
  it 'reports the matched count' do
1163
1075
  expect(result.matched_count).to eq(0)
1164
1076
  end
@@ -1194,14 +1106,10 @@ describe Mongo::BulkWrite do
1194
1106
  expect(result.upserted_count).to eq(0)
1195
1107
  end
1196
1108
 
1197
- it 'reports the modified count', if: write_command_enabled? do
1109
+ it 'reports the modified count' do
1198
1110
  expect(result.modified_count).to eq(1)
1199
1111
  end
1200
1112
 
1201
- it 'returns nil for the modified count', unless: write_command_enabled? do
1202
- expect(result.modified_count).to be_nil
1203
- end
1204
-
1205
1113
  it 'reports the matched count' do
1206
1114
  expect(result.matched_count).to eq(1)
1207
1115
  end
@@ -1241,68 +1149,60 @@ describe Mongo::BulkWrite do
1241
1149
  expect(result.upserted_count).to eq(0)
1242
1150
  end
1243
1151
 
1244
- it 'reports the modified count', if: write_command_enabled? do
1152
+ it 'reports the modified count' do
1245
1153
  expect(result.modified_count).to eq(0)
1246
1154
  end
1247
1155
 
1248
- it 'returns nil for the modified count', unless: write_command_enabled? do
1249
- expect(result.modified_count).to be_nil
1250
- end
1251
-
1252
1156
  it 'reports the matched count' do
1253
1157
  expect(result.matched_count).to eq(1)
1254
1158
  end
1255
1159
  end
1256
1160
 
1257
- context 'when the number of updates exceeds the max batch size', if: write_command_enabled? do
1161
+ context 'when the number of updates exceeds the max batch size' do
1162
+
1163
+ let(:batch_size) do
1164
+ 11
1165
+ end
1166
+
1167
+ before do
1168
+ allow(client.cluster.next_primary).to receive(:max_write_batch_size).and_return(batch_size - 1)
1169
+ end
1258
1170
 
1259
1171
  let(:requests) do
1260
- 1001.times.collect do |i|
1172
+ batch_size.times.collect do |i|
1261
1173
  { update_one: { filter: { a: i }, update: { "$set" => { a: i, b: 3 }}, upsert: true }}
1262
1174
  end
1263
1175
  end
1264
1176
 
1265
1177
  it 'updates the documents and reports the correct number of upserted ids' do
1266
- expect(result.upserted_ids.size).to eq(1001)
1267
- expect(authorized_collection.find(b: 3).count).to eq(1001)
1178
+ expect(result.upserted_ids.size).to eq(batch_size)
1179
+ expect(authorized_collection.find(b: 3).count).to eq(batch_size)
1268
1180
  end
1269
1181
  end
1270
1182
 
1271
1183
  context 'when there is a write concern error' do
1272
1184
 
1273
- context 'when the server version is < 2.6' do
1274
-
1275
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
1276
- expect {
1277
- bulk_write_invalid_write_concern.execute
1278
- }.to raise_error(Mongo::Error::BulkWriteError)
1279
- end
1185
+ it 'raises an OperationFailure', if: standalone? do
1186
+ expect {
1187
+ bulk_write_invalid_write_concern.execute
1188
+ }.to raise_error(Mongo::Error::OperationFailure)
1280
1189
  end
1281
1190
 
1282
- context 'when the server version has write commands enabled' do
1191
+ context 'when a session is provided' do
1283
1192
 
1284
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
1285
- expect {
1286
- bulk_write_invalid_write_concern.execute
1287
- }.to raise_error(Mongo::Error::OperationFailure)
1193
+ let(:extra_options) do
1194
+ {session: session}
1288
1195
  end
1289
1196
 
1290
- context 'when a session is provided' do
1291
-
1292
- let(:extra_options) do
1293
- { session: session }
1294
- end
1295
-
1296
- let(:client) do
1297
- collection_invalid_write_concern.client
1298
- end
1299
-
1300
- let(:failed_operation) do
1301
- bulk_write_invalid_write_concern.execute
1302
- end
1197
+ let(:client) do
1198
+ collection_invalid_write_concern.client
1199
+ end
1303
1200
 
1304
- it_behaves_like 'a failed operation using a session'
1201
+ let(:failed_operation) do
1202
+ bulk_write_invalid_write_concern.execute
1305
1203
  end
1204
+
1205
+ it_behaves_like 'a failed operation using a session'
1306
1206
  end
1307
1207
  end
1308
1208
  end
@@ -1326,40 +1226,24 @@ describe Mongo::BulkWrite do
1326
1226
  expect(result.upserted_count).to eq(1)
1327
1227
  end
1328
1228
 
1329
- it 'reports the modified_count count', if: write_command_enabled? do
1229
+ it 'reports the modified_count count' do
1330
1230
  expect(result.modified_count).to eq(0)
1331
1231
  end
1332
1232
 
1333
- it 'returns nil for the modified_count count', unless: write_command_enabled? do
1334
- expect(result.modified_count).to be_nil
1335
- end
1336
-
1337
1233
  it 'reports the matched count' do
1338
1234
  expect(result.matched_count).to eq(0)
1339
1235
  end
1340
1236
 
1341
- it 'reports the upserted id', if: write_command_enabled? do
1237
+ it 'reports the upserted id' do
1342
1238
  expect(result.upserted_ids).to eq([0])
1343
1239
  end
1344
1240
 
1345
1241
  context 'when there is a write concern error' do
1346
1242
 
1347
- context 'when the server version is < 2.6' do
1348
-
1349
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
1350
- expect {
1351
- bulk_write_invalid_write_concern.execute
1352
- }.to raise_error(Mongo::Error::BulkWriteError)
1353
- end
1354
- end
1355
-
1356
- context 'when the server version has write commands enabled' do
1357
-
1358
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
1359
- expect {
1360
- bulk_write_invalid_write_concern.execute
1361
- }.to raise_error(Mongo::Error::OperationFailure)
1362
- end
1243
+ it 'raises an OperationFailure', if: standalone? do
1244
+ expect {
1245
+ bulk_write_invalid_write_concern.execute
1246
+ }.to raise_error(Mongo::Error::OperationFailure)
1363
1247
  end
1364
1248
  end
1365
1249
  end
@@ -1394,14 +1278,10 @@ describe Mongo::BulkWrite do
1394
1278
  expect(result.upserted_count).to eq(0)
1395
1279
  end
1396
1280
 
1397
- it 'reports the modified count', if: collation_enabled? && write_command_enabled? do
1281
+ it 'reports the modified count', if: collation_enabled? do
1398
1282
  expect(result.modified_count).to eq(1)
1399
1283
  end
1400
1284
 
1401
- it 'returns nil for the modified count', if: collation_enabled? && !write_command_enabled? do
1402
- expect(result.modified_count).to be_nil
1403
- end
1404
-
1405
1285
  it 'reports the matched count', if: collation_enabled? do
1406
1286
  expect(result.matched_count).to eq(1)
1407
1287
  end
@@ -1458,14 +1338,10 @@ describe Mongo::BulkWrite do
1458
1338
  expect(result.upserted_count).to eq(0)
1459
1339
  end
1460
1340
 
1461
- it 'reports the modified count', if: write_command_enabled? do
1341
+ it 'reports the modified count' do
1462
1342
  expect(result.modified_count).to eq(0)
1463
1343
  end
1464
1344
 
1465
- it 'returns nil for the modified count', unless: write_command_enabled? do
1466
- expect(result.modified_count).to be_nil
1467
- end
1468
-
1469
1345
  it 'reports the matched count' do
1470
1346
  expect(result.matched_count).to eq(0)
1471
1347
  end
@@ -1508,14 +1384,10 @@ describe Mongo::BulkWrite do
1508
1384
  expect(result.upserted_count).to eq(0)
1509
1385
  end
1510
1386
 
1511
- it 'reports the modified count', if: collation_enabled? && write_command_enabled? do
1387
+ it 'reports the modified count', if: collation_enabled? do
1512
1388
  expect(result.modified_count).to eq(2)
1513
1389
  end
1514
1390
 
1515
- it 'returns nil for the modified count', if: collation_enabled? && !write_command_enabled? do
1516
- expect(result.modified_count).to be_nil
1517
- end
1518
-
1519
1391
  it 'reports the matched count', if: collation_enabled? do
1520
1392
  expect(result.matched_count).to eq(2)
1521
1393
  end
@@ -1577,14 +1449,10 @@ describe Mongo::BulkWrite do
1577
1449
  expect(result.upserted_count).to eq(0)
1578
1450
  end
1579
1451
 
1580
- it 'reports the modified count', if: write_command_enabled? do
1452
+ it 'reports the modified count' do
1581
1453
  expect(result.modified_count).to eq(0)
1582
1454
  end
1583
1455
 
1584
- it 'returns nil for the modified count', unless: write_command_enabled? do
1585
- expect(result.modified_count).to be_nil
1586
- end
1587
-
1588
1456
  it 'reports the matched count' do
1589
1457
  expect(result.matched_count).to eq(0)
1590
1458
  end
@@ -1618,19 +1486,14 @@ describe Mongo::BulkWrite do
1618
1486
  expect(result.upserted_count).to eq(0)
1619
1487
  end
1620
1488
 
1621
- it 'reports the modified count', if: write_command_enabled? do
1489
+ it 'reports the modified count' do
1622
1490
  expect(result.modified_count).to eq(2)
1623
1491
  end
1624
1492
 
1625
- it 'returns nil for the modified count', unless: write_command_enabled? do
1626
- expect(result.modified_count).to be_nil
1627
- end
1628
-
1629
1493
  it 'reports the matched count' do
1630
1494
  expect(result.matched_count).to eq(2)
1631
1495
  end
1632
1496
 
1633
-
1634
1497
  context 'when there is a mix of updates and matched without an update' do
1635
1498
 
1636
1499
  let(:requests) do
@@ -1659,14 +1522,10 @@ describe Mongo::BulkWrite do
1659
1522
  expect(result.upserted_count).to eq(0)
1660
1523
  end
1661
1524
 
1662
- it 'reports the modified count', if: write_command_enabled? do
1525
+ it 'reports the modified count' do
1663
1526
  expect(result.modified_count).to eq(1)
1664
1527
  end
1665
1528
 
1666
- it 'returns nil for the modified count', unless: write_command_enabled? do
1667
- expect(result.modified_count).to be_nil
1668
- end
1669
-
1670
1529
  it 'reports the matched count' do
1671
1530
  expect(result.matched_count).to eq(2)
1672
1531
  end
@@ -1674,22 +1533,10 @@ describe Mongo::BulkWrite do
1674
1533
 
1675
1534
  context 'when there is a write concern error' do
1676
1535
 
1677
- context 'when the server version is < 2.6' do
1678
-
1679
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
1680
- expect {
1681
- bulk_write_invalid_write_concern.execute
1682
- }.to raise_error(Mongo::Error::BulkWriteError)
1683
- end
1684
- end
1685
-
1686
- context 'when the server version has write commands enabled' do
1687
-
1688
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
1689
- expect {
1690
- bulk_write_invalid_write_concern.execute
1691
- }.to raise_error(Mongo::Error::OperationFailure)
1692
- end
1536
+ it 'raises an OperationFailure', if: standalone? do
1537
+ expect {
1538
+ bulk_write_invalid_write_concern.execute
1539
+ }.to raise_error(Mongo::Error::OperationFailure)
1693
1540
  end
1694
1541
  end
1695
1542
  end
@@ -1705,33 +1552,24 @@ describe Mongo::BulkWrite do
1705
1552
  bulk_write.execute
1706
1553
  end
1707
1554
 
1708
- it 'updates the document', if: write_command_enabled? do
1555
+ it 'updates the document' do
1709
1556
  expect(result.modified_count).to eq(0)
1710
1557
  expect(authorized_collection.find(name: { '$in' => ['test', 'test1'] }).count).to eq(2)
1711
1558
  end
1712
1559
 
1713
- it 'updates the document', unless: write_command_enabled? do
1714
- expect(result.modified_count).to be_nil
1715
- expect(authorized_collection.find(name: { '$in' => ['test', 'test1'] }).count).to eq(2)
1716
- end
1717
-
1718
1560
  it 'reports the upserted count' do
1719
1561
  expect(result.upserted_count).to eq(2)
1720
1562
  end
1721
1563
 
1722
- it 'reports the modified count', if: write_command_enabled? do
1564
+ it 'reports the modified count' do
1723
1565
  expect(result.modified_count).to eq(0)
1724
1566
  end
1725
1567
 
1726
- it 'returns nil for the modified count', unless: write_command_enabled? do
1727
- expect(result.modified_count).to be_nil
1728
- end
1729
-
1730
1568
  it 'reports the matched count' do
1731
1569
  expect(result.matched_count).to eq(0)
1732
1570
  end
1733
1571
 
1734
- it 'reports the upserted id', if: write_command_enabled? do
1572
+ it 'reports the upserted id' do
1735
1573
  expect(result.upserted_ids).to eq([0, 1])
1736
1574
  end
1737
1575
 
@@ -1757,7 +1595,7 @@ describe Mongo::BulkWrite do
1757
1595
  expect(authorized_collection.find(a: 4).count).to eq(1)
1758
1596
  end
1759
1597
 
1760
- it 'reports the upserted id', if: write_command_enabled? do
1598
+ it 'reports the upserted id' do
1761
1599
  expect(result.upserted_ids).to eq([3])
1762
1600
  end
1763
1601
 
@@ -1765,14 +1603,10 @@ describe Mongo::BulkWrite do
1765
1603
  expect(result.upserted_count).to eq(1)
1766
1604
  end
1767
1605
 
1768
- it 'reports the modified count', if: write_command_enabled? do
1606
+ it 'reports the modified count' do
1769
1607
  expect(result.modified_count).to eq(1)
1770
1608
  end
1771
1609
 
1772
- it 'returns nil for the modified count', unless: write_command_enabled? do
1773
- expect(result.modified_count).to be_nil
1774
- end
1775
-
1776
1610
  it 'reports the matched count' do
1777
1611
  expect(result.matched_count).to eq(2)
1778
1612
  end
@@ -1780,22 +1614,10 @@ describe Mongo::BulkWrite do
1780
1614
 
1781
1615
  context 'when there is a write concern error' do
1782
1616
 
1783
- context 'when the server version is < 2.6' do
1784
-
1785
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
1786
- expect {
1787
- bulk_write_invalid_write_concern.execute
1788
- }.to raise_error(Mongo::Error::BulkWriteError)
1789
- end
1790
- end
1791
-
1792
- context 'when the server version has write commands enabled' do
1793
-
1794
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
1795
- expect {
1796
- bulk_write_invalid_write_concern.execute
1797
- }.to raise_error(Mongo::Error::OperationFailure)
1798
- end
1617
+ it 'raises an OperationFailure', if: standalone? do
1618
+ expect {
1619
+ bulk_write_invalid_write_concern.execute
1620
+ }.to raise_error(Mongo::Error::OperationFailure)
1799
1621
  end
1800
1622
  end
1801
1623
  end
@@ -1834,14 +1656,10 @@ describe Mongo::BulkWrite do
1834
1656
  expect(result.upserted_count).to eq(0)
1835
1657
  end
1836
1658
 
1837
- it 'reports the modified count', if: collation_enabled? && write_command_enabled? do
1659
+ it 'reports the modified count', if: collation_enabled? do
1838
1660
  expect(result.modified_count).to eq(2)
1839
1661
  end
1840
1662
 
1841
- it 'returns nil for the modified count', if: collation_enabled? && !write_command_enabled? do
1842
- expect(result.modified_count).to be_nil
1843
- end
1844
-
1845
1663
  it 'reports the matched count', if: collation_enabled? do
1846
1664
  expect(result.matched_count).to eq(2)
1847
1665
  end
@@ -1899,14 +1717,10 @@ describe Mongo::BulkWrite do
1899
1717
  expect(result.upserted_count).to eq(0)
1900
1718
  end
1901
1719
 
1902
- it 'reports the modified count', if: write_command_enabled? do
1720
+ it 'reports the modified count' do
1903
1721
  expect(result.modified_count).to eq(0)
1904
1722
  end
1905
1723
 
1906
- it 'returns nil for the modified count', unless: write_command_enabled? do
1907
- expect(result.modified_count).to be_nil
1908
- end
1909
-
1910
1724
  it 'reports the matched count' do
1911
1725
  expect(result.matched_count).to be(0)
1912
1726
  end
@@ -1938,36 +1752,20 @@ describe Mongo::BulkWrite do
1938
1752
  expect(result.upserted_count).to eq(0)
1939
1753
  end
1940
1754
 
1941
- it 'reports the modified count', if: write_command_enabled? do
1755
+ it 'reports the modified count' do
1942
1756
  expect(result.modified_count).to eq(2)
1943
1757
  end
1944
1758
 
1945
- it 'returns nil for the modified count', unless: write_command_enabled? do
1946
- expect(result.modified_count).to be_nil
1947
- end
1948
-
1949
1759
  it 'reports the matched count' do
1950
1760
  expect(result.matched_count).to eq(2)
1951
1761
  end
1952
1762
 
1953
1763
  context 'when there is a write concern error' do
1954
1764
 
1955
- context 'when the server version is < 2.6' do
1956
-
1957
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
1958
- expect {
1959
- bulk_write_invalid_write_concern.execute
1960
- }.to raise_error(Mongo::Error::BulkWriteError)
1961
- end
1962
- end
1963
-
1964
- context 'when the server version has write commands enabled' do
1965
-
1966
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
1967
- expect {
1968
- bulk_write_invalid_write_concern.execute
1969
- }.to raise_error(Mongo::Error::OperationFailure)
1970
- end
1765
+ it 'raises an OperationFailure', if: standalone? do
1766
+ expect {
1767
+ bulk_write_invalid_write_concern.execute
1768
+ }.to raise_error(Mongo::Error::OperationFailure)
1971
1769
  end
1972
1770
  end
1973
1771
  end
@@ -1995,36 +1793,20 @@ describe Mongo::BulkWrite do
1995
1793
  expect(result.matched_count).to eq(0)
1996
1794
  end
1997
1795
 
1998
- it 'reports the modified count', if: write_command_enabled? do
1796
+ it 'reports the modified count' do
1999
1797
  expect(result.modified_count).to eq(0)
2000
1798
  end
2001
1799
 
2002
- it 'returns nil for the modified count', unless: write_command_enabled? do
2003
- expect(result.modified_count).to be_nil
2004
- end
2005
-
2006
- it 'reports the upserted id', if: write_command_enabled? do
1800
+ it 'reports the upserted id' do
2007
1801
  expect(result.upserted_ids).to eq([0])
2008
1802
  end
2009
1803
 
2010
1804
  context 'when there is a write concern error' do
2011
1805
 
2012
- context 'when the server version is < 2.6' do
2013
-
2014
- it 'raises a BulkWriteError', if: !write_command_enabled? && standalone? do
2015
- expect {
2016
- bulk_write_invalid_write_concern.execute
2017
- }.to raise_error(Mongo::Error::BulkWriteError)
2018
- end
2019
- end
2020
-
2021
- context 'when the server version has write commands enabled' do
2022
-
2023
- it 'raises an OperationFailure', if: write_command_enabled? && standalone? do
2024
- expect {
2025
- bulk_write_invalid_write_concern.execute
2026
- }.to raise_error(Mongo::Error::OperationFailure)
2027
- end
1806
+ it 'raises an OperationFailure', if: standalone? do
1807
+ expect {
1808
+ bulk_write_invalid_write_concern.execute
1809
+ }.to raise_error(Mongo::Error::OperationFailure)
2028
1810
  end
2029
1811
  end
2030
1812
  end
@@ -2033,10 +1815,18 @@ describe Mongo::BulkWrite do
2033
1815
 
2034
1816
  context 'when the operations need to be split' do
2035
1817
 
1818
+ let(:batch_size) do
1819
+ 11
1820
+ end
1821
+
1822
+ before do
1823
+ allow(client.cluster.next_primary).to receive(:max_write_batch_size).and_return(batch_size - 1)
1824
+ end
1825
+
2036
1826
  context 'when a write error occurs' do
2037
1827
 
2038
1828
  let(:requests) do
2039
- 1001.times.map do |i|
1829
+ batch_size.times.map do |i|
2040
1830
  { insert_one: { _id: i }}
2041
1831
  end
2042
1832
  end
@@ -2058,14 +1848,14 @@ describe Mongo::BulkWrite do
2058
1848
 
2059
1849
  it 'sets the document index on the error' do
2060
1850
  requests.push({ insert_one: { _id: 5 }})
2061
- expect(error.result[Mongo::Error::WRITE_ERRORS].first['index']).to eq(1001)
1851
+ expect(error.result[Mongo::Error::WRITE_ERRORS].first['index']).to eq(batch_size)
2062
1852
  end
2063
1853
  end
2064
1854
 
2065
1855
  context 'when no write errors occur' do
2066
1856
 
2067
1857
  let(:requests) do
2068
- 1001.times.map do |i|
1858
+ batch_size.times.map do |i|
2069
1859
  { insert_one: { _id: i }}
2070
1860
  end
2071
1861
  end
@@ -2075,11 +1865,11 @@ describe Mongo::BulkWrite do
2075
1865
  end
2076
1866
 
2077
1867
  it 'inserts the documents' do
2078
- expect(result.inserted_count).to eq(1001)
1868
+ expect(result.inserted_count).to eq(batch_size)
2079
1869
  end
2080
1870
 
2081
1871
  it 'combines the inserted ids' do
2082
- expect(result.inserted_ids.size).to eq(1001)
1872
+ expect(result.inserted_ids.size).to eq(batch_size)
2083
1873
  end
2084
1874
 
2085
1875
  context 'when a session is provided' do
@@ -2098,6 +1888,47 @@ describe Mongo::BulkWrite do
2098
1888
 
2099
1889
  it_behaves_like 'an operation using a session'
2100
1890
  end
1891
+
1892
+ context 'when retryable writes are supported', if: (sessions_enabled? && (replica_set? || sharded?)) do
1893
+
1894
+ let(:client) do
1895
+ authorized_client.with(heartbeat_frequency: 100, retry_writes: true).tap do |cl|
1896
+ cl.subscribe(Mongo::Monitoring::COMMAND, subscriber)
1897
+ end
1898
+ end
1899
+
1900
+ let(:collection) do
1901
+ client[authorized_collection.name]
1902
+ end
1903
+
1904
+ let(:subscriber) do
1905
+ EventSubscriber.new
1906
+ end
1907
+
1908
+ let!(:result) do
1909
+ bulk_write.execute
1910
+ end
1911
+
1912
+ let(:first_txn_number) do
1913
+ subscriber.started_events[-2].command['txnNumber'].instance_variable_get(:@integer)
1914
+ end
1915
+
1916
+ let(:second_txn_number) do
1917
+ subscriber.started_events[-1].command['txnNumber'].instance_variable_get(:@integer)
1918
+ end
1919
+
1920
+ it 'inserts the documents' do
1921
+ expect(result.inserted_count).to eq(batch_size)
1922
+ end
1923
+
1924
+ it 'combines the inserted ids' do
1925
+ expect(result.inserted_ids.size).to eq(batch_size)
1926
+ end
1927
+
1928
+ it 'increments the transaction number' do
1929
+ expect(first_txn_number + 1). to eq(second_txn_number)
1930
+ end
1931
+ end
2101
1932
  end
2102
1933
  end
2103
1934
 
@@ -2139,7 +1970,7 @@ describe Mongo::BulkWrite do
2139
1970
  context 'when the bulk write is unordered' do
2140
1971
 
2141
1972
  let(:bulk_write) do
2142
- described_class.new(authorized_collection, requests, options)
1973
+ described_class.new(collection, requests, options)
2143
1974
  end
2144
1975
 
2145
1976
  let(:options) do
@@ -2160,7 +1991,7 @@ describe Mongo::BulkWrite do
2160
1991
  context 'when the bulk write is ordered' do
2161
1992
 
2162
1993
  let(:bulk_write) do
2163
- described_class.new(authorized_collection, requests, options)
1994
+ described_class.new(collection, requests, options)
2164
1995
  end
2165
1996
 
2166
1997
  let(:options) do
@@ -2313,7 +2144,7 @@ describe Mongo::BulkWrite do
2313
2144
  ops, :bypass_document_validation => true)
2314
2145
  end
2315
2146
 
2316
- it 'executes successfully', if: write_command_enabled? do
2147
+ it 'executes successfully' do
2317
2148
  expect(result2.modified_count).to eq(2)
2318
2149
  expect(result2.inserted_count).to eq(1)
2319
2150
  end