mongo 2.9.2 → 2.10.0.rc0

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 (227) 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.rb +1 -0
  5. data/lib/mongo/auth/user/view.rb +4 -4
  6. data/lib/mongo/bulk_write.rb +14 -8
  7. data/lib/mongo/bulk_write/result.rb +1 -1
  8. data/lib/mongo/bulk_write/result_combiner.rb +2 -2
  9. data/lib/mongo/bulk_write/transformable.rb +17 -9
  10. data/lib/mongo/client.rb +107 -16
  11. data/lib/mongo/cluster.rb +47 -25
  12. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +1 -1
  13. data/lib/mongo/cluster_time.rb +139 -0
  14. data/lib/mongo/collection.rb +84 -25
  15. data/lib/mongo/collection/view.rb +7 -3
  16. data/lib/mongo/collection/view/aggregation.rb +4 -4
  17. data/lib/mongo/collection/view/builder/aggregation.rb +31 -6
  18. data/lib/mongo/collection/view/builder/find_command.rb +4 -1
  19. data/lib/mongo/collection/view/builder/map_reduce.rb +4 -1
  20. data/lib/mongo/collection/view/change_stream.rb +54 -66
  21. data/lib/mongo/collection/view/iterable.rb +2 -2
  22. data/lib/mongo/collection/view/map_reduce.rb +6 -4
  23. data/lib/mongo/collection/view/readable.rb +36 -16
  24. data/lib/mongo/collection/view/writable.rb +68 -22
  25. data/lib/mongo/cursor.rb +87 -20
  26. data/lib/mongo/database.rb +47 -43
  27. data/lib/mongo/database/view.rb +54 -11
  28. data/lib/mongo/error.rb +13 -4
  29. data/lib/mongo/error/invalid_write_concern.rb +2 -2
  30. data/lib/mongo/error/operation_failure.rb +65 -11
  31. data/lib/mongo/error/parser.rb +41 -8
  32. data/lib/mongo/grid/fs_bucket.rb +26 -6
  33. data/lib/mongo/grid/stream/read.rb +9 -2
  34. data/lib/mongo/grid/stream/write.rb +21 -5
  35. data/lib/mongo/index/view.rb +3 -3
  36. data/lib/mongo/lint.rb +10 -3
  37. data/lib/mongo/operation.rb +2 -0
  38. data/lib/mongo/operation/aggregate/result.rb +19 -6
  39. data/lib/mongo/operation/collections_info.rb +1 -1
  40. data/lib/mongo/operation/get_more/result.rb +9 -0
  41. data/lib/mongo/operation/list_collections/command.rb +1 -3
  42. data/lib/mongo/operation/list_collections/op_msg.rb +1 -2
  43. data/lib/mongo/operation/parallel_scan/command.rb +4 -1
  44. data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -1
  45. data/lib/mongo/operation/result.rb +27 -4
  46. data/lib/mongo/operation/shared/executable.rb +19 -5
  47. data/lib/mongo/operation/shared/executable_no_validate.rb +1 -2
  48. data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -9
  49. data/lib/mongo/operation/shared/polymorphic_result.rb +9 -1
  50. data/lib/mongo/operation/shared/result/aggregatable.rb +2 -2
  51. data/lib/mongo/operation/shared/sessions_supported.rb +42 -32
  52. data/lib/mongo/operation/shared/specifiable.rb +40 -0
  53. data/lib/mongo/operation/shared/unpinnable.rb +39 -0
  54. data/lib/mongo/operation/shared/write.rb +1 -1
  55. data/lib/mongo/protocol/update.rb +6 -2
  56. data/lib/mongo/retryable.rb +79 -39
  57. data/lib/mongo/server/connection.rb +10 -3
  58. data/lib/mongo/server/description.rb +25 -1
  59. data/lib/mongo/server/monitor/connection.rb +1 -1
  60. data/lib/mongo/server_selector.rb +10 -0
  61. data/lib/mongo/server_selector/selectable.rb +172 -32
  62. data/lib/mongo/session.rb +654 -581
  63. data/lib/mongo/session/session_pool.rb +1 -1
  64. data/lib/mongo/socket.rb +7 -28
  65. data/lib/mongo/socket/ssl.rb +26 -1
  66. data/lib/mongo/socket/tcp.rb +3 -0
  67. data/lib/mongo/socket/unix.rb +3 -0
  68. data/lib/mongo/uri.rb +112 -265
  69. data/lib/mongo/uri/srv_protocol.rb +4 -1
  70. data/lib/mongo/version.rb +1 -1
  71. data/lib/mongo/write_concern.rb +10 -29
  72. data/lib/mongo/write_concern/acknowledged.rb +12 -0
  73. data/lib/mongo/write_concern/base.rb +17 -13
  74. data/lib/mongo/write_concern/unacknowledged.rb +12 -0
  75. data/spec/atlas/atlas_connectivity_spec.rb +7 -37
  76. data/spec/atlas/operations_spec.rb +25 -0
  77. data/spec/integration/change_stream_examples_spec.rb +45 -31
  78. data/spec/integration/change_stream_spec.rb +305 -5
  79. data/spec/integration/client_spec.rb +44 -0
  80. data/spec/integration/command_monitoring_spec.rb +1 -0
  81. data/spec/integration/command_spec.rb +7 -1
  82. data/spec/integration/mmapv1_spec.rb +28 -0
  83. data/spec/integration/mongos_pinning_spec.rb +34 -0
  84. data/spec/integration/operation_failure_code_spec.rb +2 -2
  85. data/spec/integration/{read_concern.rb → read_concern_spec.rb} +7 -1
  86. data/spec/integration/read_preference_spec.rb +485 -0
  87. data/spec/integration/retryable_writes_spec.rb +8 -19
  88. data/spec/integration/sdam_error_handling_spec.rb +1 -1
  89. data/spec/integration/sdam_events_spec.rb +2 -2
  90. data/spec/integration/server_description_spec.rb +14 -17
  91. data/spec/integration/server_selector_spec.rb +7 -3
  92. data/spec/integration/server_spec.rb +48 -0
  93. data/spec/integration/ssl_uri_options_spec.rb +1 -1
  94. data/spec/integration/step_down_spec.rb +10 -4
  95. data/spec/integration/transactions_examples_spec.rb +11 -10
  96. data/spec/lite_spec_helper.rb +19 -16
  97. data/spec/mongo/auth/scram/negotiation_spec.rb +11 -8
  98. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +6 -6
  99. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +4 -4
  100. data/spec/mongo/bulk_write_spec.rb +12 -2
  101. data/spec/mongo/client_construction_spec.rb +160 -8
  102. data/spec/mongo/client_spec.rb +5 -4
  103. data/spec/mongo/cluster_spec.rb +6 -6
  104. data/spec/mongo/cluster_time_spec.rb +148 -0
  105. data/spec/mongo/collection/view/aggregation_spec.rb +34 -15
  106. data/spec/mongo/collection/view/change_stream_spec.rb +62 -3
  107. data/spec/mongo/collection/view/map_reduce_spec.rb +7 -5
  108. data/spec/mongo/collection/view/readable_spec.rb +4 -4
  109. data/spec/mongo/collection_spec.rb +331 -14
  110. data/spec/mongo/cursor_spec.rb +117 -5
  111. data/spec/mongo/database_spec.rb +240 -8
  112. data/spec/mongo/error/operation_failure_spec.rb +47 -1
  113. data/spec/mongo/error/parser_spec.rb +160 -23
  114. data/spec/mongo/operation/insert/bulk_spec.rb +2 -1
  115. data/spec/mongo/operation/result_spec.rb +27 -0
  116. data/spec/mongo/operation/update/bulk_spec.rb +1 -0
  117. data/spec/mongo/retryable_spec.rb +2 -0
  118. data/spec/mongo/server/app_metadata_spec.rb +2 -2
  119. data/spec/mongo/server/connection_spec.rb +13 -17
  120. data/spec/mongo/server/monitor/connection_spec.rb +13 -10
  121. data/spec/mongo/server_selector_spec.rb +34 -2
  122. data/spec/mongo/session/session_pool_spec.rb +14 -3
  123. data/spec/mongo/session_spec.rb +3 -3
  124. data/spec/mongo/session_transaction_spec.rb +4 -3
  125. data/spec/mongo/socket/ssl_spec.rb +19 -5
  126. data/spec/mongo/socket_spec.rb +1 -62
  127. data/spec/mongo/uri/srv_protocol_spec.rb +14 -20
  128. data/spec/mongo/uri_option_parsing_spec.rb +94 -8
  129. data/spec/mongo/uri_spec.rb +23 -10
  130. data/spec/mongo/write_concern_spec.rb +56 -3
  131. data/spec/spec_tests/change_streams_spec.rb +2 -1
  132. data/spec/spec_tests/cmap_spec.rb +1 -1
  133. data/spec/spec_tests/crud_spec.rb +12 -2
  134. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +24 -1
  135. data/spec/spec_tests/data/change_streams/change-streams.yml +172 -3
  136. data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +1 -1
  137. data/spec/spec_tests/data/command_monitoring/updateMany.yml +0 -2
  138. data/spec/spec_tests/data/command_monitoring/updateOne.yml +0 -5
  139. data/spec/spec_tests/data/crud/read/aggregate-out.yml +0 -6
  140. data/spec/spec_tests/data/crud/read/count-empty.yml +29 -0
  141. data/spec/spec_tests/data/crud/write/bulkWrite-arrayFilters.yml +1 -0
  142. data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +101 -0
  143. data/spec/spec_tests/data/crud/write/bulkWrite.yml +401 -0
  144. data/spec/spec_tests/data/crud/write/insertMany.yml +58 -2
  145. data/spec/spec_tests/data/crud/write/updateMany-arrayFilters.yml +3 -0
  146. data/spec/spec_tests/data/crud/write/updateOne-arrayFilters.yml +6 -1
  147. data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +103 -0
  148. data/spec/spec_tests/data/crud_v2/aggregate-out-readConcern.yml +110 -0
  149. data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +81 -0
  150. data/spec/spec_tests/data/crud_v2/db-aggregate.yml +38 -0
  151. data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +92 -0
  152. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +2 -2
  153. data/spec/spec_tests/data/transactions/abort.yml +3 -0
  154. data/spec/spec_tests/data/transactions/bulk.yml +3 -8
  155. data/spec/spec_tests/data/transactions/causal-consistency.yml +3 -8
  156. data/spec/spec_tests/data/transactions/commit.yml +3 -1
  157. data/spec/spec_tests/data/transactions/count.yml +3 -0
  158. data/spec/spec_tests/data/transactions/delete.yml +3 -0
  159. data/spec/spec_tests/data/transactions/error-labels.yml +4 -1
  160. data/spec/spec_tests/data/transactions/errors-client.yml +56 -0
  161. data/spec/spec_tests/data/transactions/errors.yml +3 -0
  162. data/spec/spec_tests/data/transactions/findOneAndDelete.yml +3 -0
  163. data/spec/spec_tests/data/transactions/findOneAndReplace.yml +3 -0
  164. data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +3 -0
  165. data/spec/spec_tests/data/transactions/insert.yml +3 -0
  166. data/spec/spec_tests/data/transactions/isolation.yml +3 -0
  167. data/spec/spec_tests/data/transactions/mongos-pin-auto.yml +1671 -0
  168. data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +347 -0
  169. data/spec/spec_tests/data/transactions/pin-mongos.yml +557 -0
  170. data/spec/spec_tests/data/transactions/read-concern.yml +3 -0
  171. data/spec/spec_tests/data/transactions/read-pref.yml +3 -0
  172. data/spec/spec_tests/data/transactions/reads.yml +3 -0
  173. data/spec/spec_tests/data/transactions/retryable-abort.yml +5 -2
  174. data/spec/spec_tests/data/transactions/retryable-commit.yml +4 -1
  175. data/spec/spec_tests/data/transactions/retryable-writes.yml +3 -0
  176. data/spec/spec_tests/data/transactions/run-command.yml +3 -0
  177. data/spec/spec_tests/data/transactions/transaction-options.yml +6 -0
  178. data/spec/spec_tests/data/transactions/update.yml +3 -8
  179. data/spec/spec_tests/data/transactions/write-concern.yml +348 -38
  180. data/spec/spec_tests/data/transactions_api/callback-aborts.yml +6 -0
  181. data/spec/spec_tests/data/transactions_api/callback-commits.yml +5 -0
  182. data/spec/spec_tests/data/transactions_api/callback-retry.yml +7 -2
  183. data/spec/spec_tests/data/transactions_api/commit-retry.yml +70 -15
  184. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +3 -0
  185. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +3 -0
  186. data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +59 -109
  187. data/spec/spec_tests/data/transactions_api/commit.yml +5 -0
  188. data/spec/spec_tests/data/transactions_api/transaction-options.yml +10 -0
  189. data/spec/spec_tests/retryable_reads_spec.rb +5 -2
  190. data/spec/spec_tests/retryable_writes_spec.rb +5 -2
  191. data/spec/spec_tests/sdam_monitoring_spec.rb +3 -3
  192. data/spec/spec_tests/sdam_spec.rb +2 -2
  193. data/spec/spec_tests/transactions_api_spec.rb +1 -67
  194. data/spec/spec_tests/transactions_spec.rb +2 -66
  195. data/spec/support/authorization.rb +4 -0
  196. data/spec/support/change_streams.rb +30 -10
  197. data/spec/support/change_streams/operation.rb +27 -0
  198. data/spec/support/client_registry.rb +44 -25
  199. data/spec/support/cluster_config.rb +25 -14
  200. data/spec/support/cluster_tools.rb +32 -10
  201. data/spec/support/command_monitoring.rb +1 -1
  202. data/spec/support/common_shortcuts.rb +30 -0
  203. data/spec/support/connection_string.rb +8 -3
  204. data/spec/support/constraints.rb +34 -0
  205. data/spec/support/crud.rb +31 -16
  206. data/spec/support/crud/context.rb +23 -0
  207. data/spec/support/crud/operation.rb +311 -14
  208. data/spec/support/crud/spec.rb +2 -1
  209. data/spec/support/crud/test.rb +24 -27
  210. data/spec/support/crud/test_base.rb +22 -0
  211. data/spec/support/crud/verifier.rb +15 -1
  212. data/spec/support/event_subscriber.rb +12 -0
  213. data/spec/support/sdam_formatter_integration.rb +12 -6
  214. data/spec/support/shared/server_selector.rb +10 -0
  215. data/spec/support/shared/session.rb +13 -12
  216. data/spec/support/spec_config.rb +32 -22
  217. data/spec/support/spec_setup.rb +2 -2
  218. data/spec/support/transactions.rb +87 -0
  219. data/spec/support/transactions/context.rb +33 -0
  220. data/spec/support/transactions/operation.rb +99 -349
  221. data/spec/support/transactions/spec.rb +1 -3
  222. data/spec/support/transactions/test.rb +110 -49
  223. data/spec/support/utils.rb +74 -1
  224. metadata +52 -10
  225. metadata.gz.sig +0 -0
  226. data/spec/support/crud/read.rb +0 -265
  227. data/spec/support/crud/write.rb +0 -284
@@ -219,8 +219,6 @@ describe Mongo::Collection::View::Aggregation do
219
219
  end
220
220
 
221
221
  describe '#explain' do
222
- # Broken on 4.2 - https://jira.mongodb.org/browse/RUBY-1788
223
- max_server_version '4.0'
224
222
 
225
223
  it 'executes an explain' do
226
224
  expect(aggregation.explain).to_not be_empty
@@ -273,26 +271,47 @@ describe Mongo::Collection::View::Aggregation do
273
271
  context 'when the server selected supports collations' do
274
272
  min_server_fcv '3.4'
275
273
 
276
- context 'when the collation key is a String' do
274
+ shared_examples_for 'applies the collation' do
277
275
 
278
- let(:options) do
279
- { 'collation' => { locale: 'en_US', strength: 2 } }
276
+ context 'when the collation key is a String' do
277
+
278
+ let(:options) do
279
+ { 'collation' => { locale: 'en_US', strength: 2 } }
280
+ end
281
+
282
+ it 'applies the collation' do
283
+ expect(result).to eq('en_US')
284
+ end
280
285
  end
281
286
 
282
- it 'applies the collation' do
283
- expect(result).to eq('en_US')
287
+ context 'when the collation key is a Symbol' do
288
+
289
+ let(:options) do
290
+ { collation: { locale: 'en_US', strength: 2 } }
291
+ end
292
+
293
+ it 'applies the collation' do
294
+ expect(result).to eq('en_US')
295
+ end
284
296
  end
285
297
  end
286
298
 
287
- context 'when the collation key is a Symbol' do
299
+ context '4.0-' do
300
+ max_server_version '4.0'
288
301
 
289
- let(:options) do
290
- { collation: { locale: 'en_US', strength: 2 } }
291
- end
302
+ it_behaves_like 'applies the collation'
303
+ end
292
304
 
293
- it 'applies the collation' do
294
- expect(result).to eq('en_US')
305
+ context '4.2+' do
306
+ min_server_fcv '4.2'
307
+
308
+ let(:result) do
309
+ skip 'RUBY-1827 / upgrading evergreen 4.1 server binary'
310
+
311
+ aggregation.explain['queryPlanner']['collation']['locale']
295
312
  end
313
+
314
+ it_behaves_like 'applies the collation'
296
315
  end
297
316
  end
298
317
 
@@ -596,7 +615,7 @@ describe Mongo::Collection::View::Aggregation do
596
615
 
597
616
  it 'reroutes the operation to a primary' do
598
617
  allow(aggregation).to receive(:valid_server?).and_return(false)
599
- expect(Mongo::Logger.logger).to receive(:warn?).and_call_original
618
+ expect(Mongo::Logger.logger).to receive(:warn).and_call_original
600
619
  aggregation.to_a
601
620
  end
602
621
  end
@@ -604,7 +623,7 @@ describe Mongo::Collection::View::Aggregation do
604
623
  context 'when the server is a valid for writing' do
605
624
 
606
625
  it 'does not reroute the operation to a primary' do
607
- expect(Mongo::Logger.logger).not_to receive(:warn?)
626
+ expect(Mongo::Logger.logger).not_to receive(:warn)
608
627
  aggregation.to_a
609
628
  end
610
629
 
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Mongo::Collection::View::ChangeStream do
4
+ require_wired_tiger
4
5
  min_server_fcv '3.6'
5
6
  require_topology :replica_set
6
7
  max_example_run_time 7
@@ -275,11 +276,11 @@ describe Mongo::Collection::View::ChangeStream do
275
276
 
276
277
  it 'does not close the cursor' do
277
278
  expect(cursor).to be_a(Mongo::Cursor)
279
+ expect(cursor.closed?).to be false
278
280
  end
279
281
  end
280
282
 
281
283
  context 'when provided a session' do
282
- min_server_fcv '3.6'
283
284
 
284
285
  let(:options) do
285
286
  { session: session }
@@ -443,7 +444,7 @@ describe Mongo::Collection::View::ChangeStream do
443
444
  collection.insert_one(a: 1)
444
445
  end
445
446
 
446
- context 'pre-4.1 server' do
447
+ context 'pre-4.2 server' do
447
448
  max_server_version '4.0'
448
449
 
449
450
  it 'driver raises an exception and closes the cursor' do
@@ -454,7 +455,7 @@ describe Mongo::Collection::View::ChangeStream do
454
455
  end
455
456
  end
456
457
 
457
- context '4.1+ server' do
458
+ context '4.2+ server' do
458
459
  min_server_fcv '4.2'
459
460
 
460
461
  it 'server errors, driver closes the cursor' do
@@ -592,6 +593,63 @@ describe Mongo::Collection::View::ChangeStream do
592
593
  end
593
594
  end
594
595
 
596
+ context 'when a killCursors command is issued for the cursor' do
597
+ context 'using Enumerable' do
598
+ only_mri
599
+
600
+ before do
601
+ change_stream
602
+ collection.insert_one(a:1)
603
+ enum.next
604
+ collection.insert_one(a:2)
605
+ end
606
+
607
+ let(:enum) do
608
+ change_stream.to_enum
609
+ end
610
+
611
+ it 'should create a new cursor and resume' do
612
+ original_cursor_id = cursor.id
613
+
614
+ client.use(:admin).command({
615
+ killCursors: collection.name,
616
+ cursors: [cursor.id]
617
+ })
618
+
619
+ document = enum.next
620
+ expect(document[:fullDocument][:a]).to eq(2)
621
+
622
+ new_cursor_id = change_stream.instance_variable_get(:@cursor).id
623
+ expect(new_cursor_id).not_to eq(original_cursor_id)
624
+ end
625
+ end
626
+
627
+ context 'using try_next' do
628
+ before do
629
+ change_stream
630
+ collection.insert_one(a:1)
631
+ expect(change_stream.try_next).to be_a(BSON::Document)
632
+ collection.insert_one(a:2)
633
+ end
634
+
635
+ it 'should create a new cursor and resume' do
636
+ original_cursor_id = cursor.id
637
+
638
+ client.use(:admin).command({
639
+ killCursors: collection.name,
640
+ cursors: [cursor.id]
641
+ })
642
+
643
+ document = change_stream.try_next
644
+ expect(document).to be_a(BSON::Document)
645
+ expect(document[:fullDocument][:a]).to eq(2)
646
+
647
+ new_cursor_id = change_stream.instance_variable_get(:@cursor).id
648
+ expect(new_cursor_id).not_to eq(original_cursor_id)
649
+ end
650
+ end
651
+ end
652
+
595
653
  context 'when a server error is encountered during a getMore' do
596
654
  fails_on_jruby
597
655
 
@@ -606,6 +664,7 @@ describe Mongo::Collection::View::ChangeStream do
606
664
  collection.insert_one(a: 2)
607
665
  expect(cursor).to receive(:get_more).once.and_raise(error)
608
666
  expect(cursor).to receive(:kill_cursors).and_call_original
667
+ expect(view.send(:server_selector)).to receive(:select_server).once.and_call_original
609
668
  expect(Mongo::Operation::Aggregate).to receive(:new).and_call_original
610
669
  end
611
670
 
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Mongo::Collection::View::MapReduce do
4
+ clean_slate_on_evergreen
4
5
 
5
6
  let(:map) do
6
7
  %Q{
@@ -578,7 +579,9 @@ describe Mongo::Collection::View::MapReduce do
578
579
 
579
580
  it 'reroutes the operation to a primary' do
580
581
  allow(map_reduce).to receive(:valid_server?).and_return(false)
581
- expect(Mongo::Logger.logger).to receive(:warn?).and_call_original
582
+ expect(Mongo::Logger.logger).to receive(:warn).once do |msg|
583
+ expect(msg).to include('Rerouting the MapReduce operation to the primary server')
584
+ end
582
585
  map_reduce.to_a
583
586
  end
584
587
 
@@ -650,13 +653,12 @@ describe Mongo::Collection::View::MapReduce do
650
653
  # We are inspecting server state - kill monitor threads so that
651
654
  # server state is not changed in background due to intermittent
652
655
  # connectivity issues in Evergreen
653
- authorized_collection.client.cluster.servers_list.map do |server|
654
- server.monitor.stop!
655
- end
656
+ ClientRegistry.instance.close_all_clients
657
+ authorized_collection.client.cluster.disconnect!
656
658
  end
657
659
 
658
660
  it 'does not reroute the operation to a primary' do
659
- expect(Mongo::Logger.logger).not_to receive(:warn?)
661
+ expect(Mongo::Logger.logger).not_to receive(:warn)
660
662
  map_reduce.to_a
661
663
  end
662
664
  end
@@ -369,7 +369,7 @@ describe Mongo::Collection::View::Readable do
369
369
  context 'when the collection has a read preference set' do
370
370
 
371
371
  after do
372
- client.close
372
+ client.close(true)
373
373
  end
374
374
 
375
375
  let(:client) do
@@ -438,7 +438,7 @@ describe Mongo::Collection::View::Readable do
438
438
  require_topology :single, :replica_set
439
439
 
440
440
  after do
441
- client.close
441
+ client.close(true)
442
442
  end
443
443
 
444
444
  let(:client) do
@@ -756,7 +756,7 @@ describe Mongo::Collection::View::Readable do
756
756
  end
757
757
 
758
758
  after do
759
- client.close
759
+ client.close(true)
760
760
  end
761
761
 
762
762
  let(:client) do
@@ -819,7 +819,7 @@ describe Mongo::Collection::View::Readable do
819
819
  end
820
820
 
821
821
  after do
822
- client.close
822
+ client.close(true)
823
823
  end
824
824
 
825
825
  let(:client) do
@@ -98,10 +98,108 @@ describe Mongo::Collection do
98
98
  end
99
99
  end
100
100
 
101
+ describe '#initialize' do
102
+
103
+ let(:client) do
104
+ new_local_client(SpecConfig.instance.addresses,
105
+ SpecConfig.instance.test_options.merge(monitoring_io: false))
106
+ end
107
+
108
+ let(:database) { client.database }
109
+
110
+ context 'write concern given in :write option' do
111
+ let(:collection) do
112
+ Mongo::Collection.new(database, 'foo', write: {w: 1})
113
+ end
114
+
115
+ it 'stores write concern' do
116
+ expect(collection.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
117
+ expect(collection.write_concern.options).to eq(w: 1)
118
+ end
119
+
120
+ it 'stores write concern under :write' do
121
+ expect(collection.options[:write]).to eq(w: 1)
122
+ expect(collection.options[:write_concern]).to be nil
123
+ end
124
+ end
125
+
126
+ context 'write concern given in :write_concern option' do
127
+ let(:collection) do
128
+ Mongo::Collection.new(database, 'foo', write_concern: {w: 1})
129
+ end
130
+
131
+ it 'stores write concern' do
132
+ expect(collection.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
133
+ expect(collection.write_concern.options).to eq(w: 1)
134
+ end
135
+
136
+ it 'stores write concern under :write_concern' do
137
+ expect(collection.options[:write_concern]).to eq(w: 1)
138
+ expect(collection.options[:write]).to be nil
139
+ end
140
+ end
141
+
142
+ context 'write concern given in both :write and :write_concern options' do
143
+ context 'identical values' do
144
+
145
+ let(:collection) do
146
+ Mongo::Collection.new(database, 'foo',
147
+ write: {w: 1}, write_concern: {w: 1})
148
+ end
149
+
150
+ it 'stores write concern' do
151
+ expect(collection.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
152
+ expect(collection.write_concern.options).to eq(w: 1)
153
+ end
154
+
155
+ it 'stores write concern under both options' do
156
+ expect(collection.options[:write]).to eq(w: 1)
157
+ expect(collection.options[:write_concern]).to eq(w: 1)
158
+ end
159
+ end
160
+
161
+ context 'different values' do
162
+
163
+ let(:collection) do
164
+ Mongo::Collection.new(database, 'foo',
165
+ write: {w: 1}, write_concern: {w: 2})
166
+ end
167
+
168
+ it 'raises an exception' do
169
+ expect do
170
+ collection
171
+ end.to raise_error(ArgumentError, /If :write and :write_concern are both given, they must be identical/)
172
+ end
173
+ end
174
+ end
175
+
176
+ =begin WriteConcern object support
177
+ context 'when write concern is provided via a WriteConcern object' do
178
+
179
+ let(:collection) do
180
+ Mongo::Collection.new(database, 'foo', write_concern: wc)
181
+ end
182
+
183
+ let(:wc) { Mongo::WriteConcern.get(w: 2) }
184
+
185
+ it 'stores write concern options in collection options' do
186
+ expect(collection.options[:write_concern]).to eq(w: 2)
187
+ end
188
+
189
+ it 'caches write concern object' do
190
+ expect(collection.write_concern).to be wc
191
+ end
192
+ end
193
+ =end
194
+ end
195
+
101
196
  describe '#with' do
102
197
 
103
198
  let(:client) do
104
- new_local_client(SpecConfig.instance.addresses, SpecConfig.instance.test_options)
199
+ new_local_client_nmio(SpecConfig.instance.addresses,
200
+ SpecConfig.instance.test_options.merge(
201
+ SpecConfig.instance.auth_options
202
+ ))
105
203
  end
106
204
 
107
205
  let(:database) do
@@ -133,7 +231,8 @@ describe Mongo::Collection do
133
231
  context 'when the client has a server selection timeout setting' do
134
232
 
135
233
  let(:client) do
136
- new_local_client(SpecConfig.instance.addresses, SpecConfig.instance.test_options.merge(server_selection_timeout: 2))
234
+ new_local_client(SpecConfig.instance.addresses,
235
+ SpecConfig.instance.test_options.merge(server_selection_timeout: 2, monitoring_io: false))
137
236
  end
138
237
 
139
238
  it 'passes the the server_selection_timeout to the cluster' do
@@ -142,21 +241,113 @@ describe Mongo::Collection do
142
241
  end
143
242
 
144
243
  context 'when the client has a read preference set' do
244
+ clean_slate_on_evergreen
145
245
 
146
246
  let(:client) do
147
- new_local_client(SpecConfig.instance.addresses, SpecConfig.instance.test_options.merge(read: { mode: :primary_preferred }))
247
+ authorized_client.with(SpecConfig.instance.auth_options.merge(
248
+ client_options
249
+ )).tap do |client|
250
+ expect(client.options[:read]).to eq(Mongo::Options::Redacted.new(
251
+ mode: :primary_preferred))
252
+ end
253
+ end
254
+
255
+ let(:client_options) do
256
+ {
257
+ read: { mode: :primary_preferred },
258
+ monitoring_io: false,
259
+ }
260
+ end
261
+
262
+ let(:new_options) do
263
+ { read: { mode: :secondary } }
148
264
  end
149
265
 
150
266
  it 'sets the new read options on the new collection' do
151
- expect(new_collection.read_preference).to eq(new_options[:read])
152
- expect(new_collection.read_preference).not_to eq(client.read_preference)
267
+ # This is strictly a Hash, not a BSON::Document like the client's
268
+ # read preference.
269
+ expect(new_collection.read_preference).to eq(mode: :secondary)
270
+ end
271
+
272
+ it 'duplicates the read option' do
273
+ expect(new_collection.read_preference).not_to eql(client.read_preference)
274
+ end
275
+
276
+ context 'when reading from collection' do
277
+ # Since we are requesting a secondary read, we need a replica set.
278
+ require_topology :replica_set
279
+
280
+ let(:client_options) do
281
+ {
282
+ read: { mode: :primary_preferred },
283
+ }
284
+ end
285
+
286
+ let(:subscriber) { EventSubscriber.new }
287
+
288
+ before do
289
+ client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
290
+ end
291
+
292
+ shared_examples_for "uses collection's read preference when reading" do
293
+ it "uses collection's read preference when reading" do
294
+ expect do
295
+ new_collection.find.to_a.count
296
+ end.not_to raise_error
297
+
298
+ event = subscriber.started_events.detect do |event|
299
+ event.command['find']
300
+ end
301
+ actual_rp = event.command['$readPreference']
302
+ expect(actual_rp).to eq(expected_read_preference)
303
+ end
304
+ end
305
+
306
+ context 'post-OP_MSG server' do
307
+ min_server_fcv '3.6'
308
+
309
+ context 'standalone' do
310
+ require_topology :single
311
+
312
+ let(:expected_read_preference) do
313
+ nil
314
+ end
315
+
316
+ it_behaves_like "uses collection's read preference when reading"
317
+ end
318
+
319
+ context 'RS, sharded' do
320
+ require_topology :replica_set, :sharded
321
+
322
+ let(:expected_read_preference) do
323
+ {'mode' => 'secondary'}
324
+ end
325
+
326
+ it_behaves_like "uses collection's read preference when reading"
327
+ end
328
+ end
329
+
330
+ context 'pre-OP-MSG server' do
331
+ max_server_version '3.4'
332
+
333
+ let(:expected_read_preference) do
334
+ nil
335
+ end
336
+
337
+ it_behaves_like "uses collection's read preference when reading"
338
+ end
153
339
  end
154
340
  end
155
341
 
156
342
  context 'when the client has a read preference and server selection timeout set' do
157
343
 
158
344
  let(:client) do
159
- new_local_client(SpecConfig.instance.addresses, SpecConfig.instance.test_options.merge(read: { mode: :primary_preferred }, server_selection_timeout: 2))
345
+ new_local_client(SpecConfig.instance.addresses,
346
+ SpecConfig.instance.test_options.merge(
347
+ read: { mode: :primary_preferred },
348
+ server_selection_timeout: 2,
349
+ monitoring_io: false
350
+ ))
160
351
  end
161
352
 
162
353
  it 'sets the new read options on the new collection' do
@@ -186,12 +377,116 @@ describe Mongo::Collection do
186
377
  context 'when the client has a write concern set' do
187
378
 
188
379
  let(:client) do
189
- new_local_client(SpecConfig.instance.addresses, SpecConfig.instance.test_options.merge(write: INVALID_WRITE_CONCERN))
380
+ new_local_client(SpecConfig.instance.addresses,
381
+ SpecConfig.instance.test_options.merge(
382
+ write: INVALID_WRITE_CONCERN,
383
+ monitoring_io: false,
384
+ ))
190
385
  end
191
386
 
192
387
  it 'sets the new write options on the new collection' do
193
388
  expect(new_collection.write_concern.options).to eq(Mongo::WriteConcern.get(new_options[:write]).options)
194
389
  end
390
+
391
+ context 'when client uses :write_concern and collection uses :write' do
392
+
393
+ let(:client) do
394
+ new_local_client(SpecConfig.instance.addresses,
395
+ SpecConfig.instance.test_options.merge(
396
+ write_concern: {w: 1},
397
+ monitoring_io: false,
398
+ ))
399
+ end
400
+
401
+ it 'uses :write from collection options only' do
402
+ expect(new_collection.options[:write]).to eq(w: 5)
403
+ expect(new_collection.options[:write_concern]).to be nil
404
+ end
405
+ end
406
+
407
+ context 'when client uses :write and collection uses :write_concern' do
408
+
409
+ let(:client) do
410
+ new_local_client(SpecConfig.instance.addresses,
411
+ SpecConfig.instance.test_options.merge(
412
+ write: {w: 1},
413
+ monitoring_io: false,
414
+ ))
415
+ end
416
+
417
+ let(:new_options) do
418
+ { write_concern: { w: 5 } }
419
+ end
420
+
421
+ it 'uses :write_concern from collection options only' do
422
+ expect(new_collection.options[:write_concern]).to eq(w: 5)
423
+ expect(new_collection.options[:write]).to be nil
424
+ end
425
+ end
426
+
427
+ context 'when collection previously had :wrte_concern and :write is used with a different value' do
428
+
429
+ let(:collection) do
430
+ database.collection(:users, write_concern: {w: 2})
431
+ end
432
+
433
+ let(:new_options) do
434
+ { write: { w: 5 } }
435
+ end
436
+
437
+ it 'uses the new option' do
438
+ expect(new_collection.options[:write]).to eq(w: 5)
439
+ expect(new_collection.options[:write_concern]).to be nil
440
+ end
441
+ end
442
+
443
+ context 'when collection previously had :wrte and :write_concern is used with a different value' do
444
+
445
+ let(:collection) do
446
+ database.collection(:users, write: {w: 2})
447
+ end
448
+
449
+ let(:new_options) do
450
+ { write_concern: { w: 5 } }
451
+ end
452
+
453
+ it 'uses the new option' do
454
+ expect(new_collection.options[:write_concern]).to eq(w: 5)
455
+ expect(new_collection.options[:write]).to be nil
456
+ end
457
+ end
458
+
459
+ context 'when collection previously had :wrte_concern and :write is used with the same value' do
460
+
461
+ let(:collection) do
462
+ database.collection(:users, write_concern: {w: 2})
463
+ end
464
+
465
+ let(:new_options) do
466
+ { write: { w: 2 } }
467
+ end
468
+
469
+ it 'uses the new option' do
470
+ expect(new_collection.options[:write]).to eq(w: 2)
471
+ expect(new_collection.options[:write_concern]).to be nil
472
+ end
473
+ end
474
+
475
+ context 'when collection previously had :wrte and :write_concern is used with the same value' do
476
+
477
+ let(:collection) do
478
+ database.collection(:users, write: {w: 2})
479
+ end
480
+
481
+ let(:new_options) do
482
+ { write_concern: { w: 2 } }
483
+ end
484
+
485
+ it 'uses the new option' do
486
+ expect(new_collection.options[:write]).to be nil
487
+ expect(new_collection.options[:write_concern]).to eq(w: 2)
488
+ end
489
+ end
195
490
  end
196
491
  end
197
492
 
@@ -219,7 +514,11 @@ describe Mongo::Collection do
219
514
  context 'when the client has a server selection timeout setting' do
220
515
 
221
516
  let(:client) do
222
- new_local_client(SpecConfig.instance.addresses, SpecConfig.instance.test_options.merge(server_selection_timeout: 2))
517
+ new_local_client(SpecConfig.instance.addresses,
518
+ SpecConfig.instance.test_options.merge(
519
+ server_selection_timeout: 2,
520
+ monitoring_io: false,
521
+ ))
223
522
  end
224
523
 
225
524
  it 'passes the server_selection_timeout setting to the cluster' do
@@ -230,7 +529,11 @@ describe Mongo::Collection do
230
529
  context 'when the client has a read preference set' do
231
530
 
232
531
  let(:client) do
233
- new_local_client(SpecConfig.instance.addresses, SpecConfig.instance.test_options.merge(read: { mode: :primary_preferred }))
532
+ new_local_client(SpecConfig.instance.addresses,
533
+ SpecConfig.instance.test_options.merge(
534
+ read: { mode: :primary_preferred },
535
+ monitoring_io: false,
536
+ ))
234
537
  end
235
538
 
236
539
  it 'sets the new read options on the new collection' do
@@ -877,6 +1180,7 @@ describe Mongo::Collection do
877
1180
  context 'when provided options' do
878
1181
 
879
1182
  context 'when a session is provided' do
1183
+ require_wired_tiger
880
1184
 
881
1185
  let(:operation) do
882
1186
  authorized_collection.find({}, session: session).to_a
@@ -901,6 +1205,7 @@ describe Mongo::Collection do
901
1205
  context 'session id' do
902
1206
  min_server_fcv '3.6'
903
1207
  require_topology :replica_set, :sharded
1208
+ require_wired_tiger
904
1209
 
905
1210
  let(:options) do
906
1211
  { session: session }
@@ -929,6 +1234,7 @@ describe Mongo::Collection do
929
1234
  end
930
1235
 
931
1236
  context 'when a session supporting causal consistency is used' do
1237
+ require_wired_tiger
932
1238
 
933
1239
  let(:operation) do
934
1240
  collection.find({}, session: session).to_a
@@ -1184,7 +1490,7 @@ describe Mongo::Collection do
1184
1490
  end
1185
1491
 
1186
1492
  after do
1187
- custom_client.close
1493
+ custom_client.close(true)
1188
1494
  end
1189
1495
 
1190
1496
  it 'inserts with the custom id' do
@@ -1235,7 +1541,7 @@ describe Mongo::Collection do
1235
1541
  end
1236
1542
 
1237
1543
  after do
1238
- client.close
1544
+ client.close(true)
1239
1545
  end
1240
1546
 
1241
1547
  let(:insert_events) do
@@ -1448,7 +1754,7 @@ describe Mongo::Collection do
1448
1754
  end
1449
1755
 
1450
1756
  after do
1451
- custom_client.close
1757
+ custom_client.close(true)
1452
1758
  end
1453
1759
 
1454
1760
  it 'inserts with the custom id' do
@@ -1541,6 +1847,7 @@ describe Mongo::Collection do
1541
1847
  end
1542
1848
 
1543
1849
  context 'when a session is provided' do
1850
+ require_wired_tiger
1544
1851
 
1545
1852
  let(:session) do
1546
1853
  authorized_client.start_session
@@ -1592,6 +1899,7 @@ describe Mongo::Collection do
1592
1899
  end
1593
1900
 
1594
1901
  context 'when a session supporting causal consistency is used' do
1902
+ require_wired_tiger
1595
1903
 
1596
1904
  let(:operation) do
1597
1905
  collection.aggregate([], session: session).first
@@ -1717,6 +2025,7 @@ describe Mongo::Collection do
1717
2025
 
1718
2026
  describe '#count_documents' do
1719
2027
  context 'when transactions are enabled' do
2028
+ require_wired_tiger
1720
2029
  require_transaction_support
1721
2030
 
1722
2031
  before do
@@ -1772,6 +2081,7 @@ describe Mongo::Collection do
1772
2081
  end
1773
2082
 
1774
2083
  context 'when a session is provided' do
2084
+ require_wired_tiger
1775
2085
 
1776
2086
  let(:session) do
1777
2087
  authorized_client.start_session
@@ -1794,6 +2104,7 @@ describe Mongo::Collection do
1794
2104
  end
1795
2105
 
1796
2106
  context 'when a session supporting causal consistency is used' do
2107
+ require_wired_tiger
1797
2108
 
1798
2109
  let(:operation) do
1799
2110
  collection.count({}, session: session)
@@ -1887,6 +2198,7 @@ describe Mongo::Collection do
1887
2198
  end
1888
2199
 
1889
2200
  context 'when a session is provided' do
2201
+ require_wired_tiger
1890
2202
 
1891
2203
  let(:session) do
1892
2204
  authorized_client.start_session
@@ -1910,6 +2222,7 @@ describe Mongo::Collection do
1910
2222
  end
1911
2223
 
1912
2224
  context 'when a session supporting causal consistency is used' do
2225
+ require_wired_tiger
1913
2226
 
1914
2227
  let(:operation) do
1915
2228
  collection.distinct(:field, {}, session: session)
@@ -2412,6 +2725,7 @@ describe Mongo::Collection do
2412
2725
  end
2413
2726
 
2414
2727
  context 'when a session is provided' do
2728
+ require_wired_tiger
2415
2729
 
2416
2730
  let(:cursors) do
2417
2731
  authorized_collection.parallel_scan(2, session: session)
@@ -2461,6 +2775,7 @@ describe Mongo::Collection do
2461
2775
  end
2462
2776
 
2463
2777
  context 'when a session supporting causal consistency is used' do
2778
+ require_wired_tiger
2464
2779
 
2465
2780
  let(:cursors) do
2466
2781
  collection.parallel_scan(2, session: session)
@@ -2481,6 +2796,7 @@ describe Mongo::Collection do
2481
2796
  end
2482
2797
 
2483
2798
  context 'when a read concern is provided' do
2799
+ require_wired_tiger
2484
2800
  min_server_fcv '3.2'
2485
2801
 
2486
2802
  let(:result) do
@@ -2520,7 +2836,7 @@ describe Mongo::Collection do
2520
2836
  end
2521
2837
 
2522
2838
  after do
2523
- client.close
2839
+ client.close(true)
2524
2840
  end
2525
2841
 
2526
2842
  let(:client) do
@@ -3672,7 +3988,7 @@ describe Mongo::Collection do
3672
3988
  end
3673
3989
 
3674
3990
  after do
3675
- client.close
3991
+ client.close(true)
3676
3992
  end
3677
3993
 
3678
3994
  let(:update_events) do
@@ -4691,6 +5007,7 @@ describe Mongo::Collection do
4691
5007
  describe '#watch' do
4692
5008
 
4693
5009
  context 'when change streams can be tested' do
5010
+ require_wired_tiger
4694
5011
  min_server_fcv '3.6'
4695
5012
  require_topology :replica_set
4696
5013