mongo 2.9.2 → 2.10.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
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