mongo 2.16.4 → 2.17.0

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 (123) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/lib/mongo/auth/aws/request.rb +0 -1
  5. data/lib/mongo/client.rb +4 -0
  6. data/lib/mongo/collection/view/aggregation.rb +62 -17
  7. data/lib/mongo/collection/view/builder/aggregation.rb +11 -13
  8. data/lib/mongo/collection/view/builder/map_reduce.rb +5 -8
  9. data/lib/mongo/collection/view/change_stream.rb +7 -3
  10. data/lib/mongo/collection/view/iterable.rb +3 -20
  11. data/lib/mongo/collection/view/map_reduce.rb +3 -14
  12. data/lib/mongo/collection/view/readable.rb +24 -1
  13. data/lib/mongo/collection/view/writable.rb +23 -0
  14. data/lib/mongo/collection/view.rb +0 -1
  15. data/lib/mongo/collection.rb +21 -1
  16. data/lib/mongo/database/view.rb +4 -2
  17. data/lib/mongo/database.rb +6 -6
  18. data/lib/mongo/error/snapshot_session_invalid_server_version.rb +31 -0
  19. data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +30 -0
  20. data/lib/mongo/error.rb +2 -0
  21. data/lib/mongo/operation/delete/op_msg.rb +2 -1
  22. data/lib/mongo/operation/find/builder/command.rb +1 -0
  23. data/lib/mongo/operation/result.rb +6 -0
  24. data/lib/mongo/operation/shared/executable.rb +4 -0
  25. data/lib/mongo/operation/shared/sessions_supported.rb +18 -2
  26. data/lib/mongo/operation/update/op_msg.rb +2 -1
  27. data/lib/mongo/query_cache.rb +2 -12
  28. data/lib/mongo/server/description/features.rb +3 -1
  29. data/lib/mongo/server/monitor/connection.rb +4 -10
  30. data/lib/mongo/server_selector/base.rb +26 -4
  31. data/lib/mongo/session.rb +19 -0
  32. data/lib/mongo/socket/ocsp_cache.rb +2 -3
  33. data/lib/mongo/socket.rb +1 -5
  34. data/lib/mongo/utils.rb +0 -6
  35. data/lib/mongo/version.rb +1 -1
  36. data/mongo.gemspec +1 -1
  37. data/spec/integration/query_cache_spec.rb +0 -159
  38. data/spec/integration/read_preference_spec.rb +16 -12
  39. data/spec/integration/sdam_events_spec.rb +0 -40
  40. data/spec/lite_spec_helper.rb +0 -7
  41. data/spec/mongo/collection/view/aggregation_spec.rb +71 -95
  42. data/spec/mongo/collection/view/change_stream_spec.rb +1 -1
  43. data/spec/mongo/collection/view/map_reduce_spec.rb +14 -17
  44. data/spec/mongo/collection/view/readable_spec.rb +0 -56
  45. data/spec/mongo/operation/read_preference_op_msg_spec.rb +24 -1
  46. data/spec/mongo/query_cache_spec.rb +0 -165
  47. data/spec/mongo/server_selector_spec.rb +136 -15
  48. data/spec/mongo/socket/ssl_spec.rb +26 -58
  49. data/spec/mongo/utils_spec.rb +0 -14
  50. data/spec/runners/auth.rb +1 -1
  51. data/spec/runners/change_streams/spec.rb +1 -1
  52. data/spec/runners/cmap.rb +1 -1
  53. data/spec/runners/command_monitoring.rb +1 -1
  54. data/spec/runners/connection_string.rb +1 -1
  55. data/spec/runners/crud/spec.rb +3 -1
  56. data/spec/runners/crud/verifier.rb +1 -2
  57. data/spec/runners/gridfs.rb +1 -1
  58. data/spec/runners/read_write_concern_document.rb +1 -1
  59. data/spec/runners/sdam.rb +1 -1
  60. data/spec/runners/server_selection.rb +1 -1
  61. data/spec/runners/server_selection_rtt.rb +1 -1
  62. data/spec/runners/unified/assertions.rb +3 -1
  63. data/spec/runners/unified/crud_operations.rb +77 -23
  64. data/spec/runners/unified/ddl_operations.rb +29 -1
  65. data/spec/runners/unified/entity_map.rb +3 -3
  66. data/spec/runners/unified/support_operations.rb +6 -1
  67. data/spec/runners/unified/test.rb +15 -3
  68. data/spec/runners/unified/test_group.rb +1 -1
  69. data/spec/shared/share/Dockerfile.erb +3 -3
  70. data/spec/shared/shlib/server.sh +1 -1
  71. data/spec/spec_tests/data/crud_unified/aggregate-let.yml +138 -0
  72. data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +155 -0
  73. data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +151 -0
  74. data/spec/spec_tests/data/crud_unified/deleteMany-let.yml +91 -0
  75. data/spec/spec_tests/data/crud_unified/deleteOne-let.yml +89 -0
  76. data/spec/spec_tests/data/crud_unified/find-let.yml +71 -0
  77. data/spec/spec_tests/data/crud_unified/findOneAndDelete-let.yml +88 -0
  78. data/spec/spec_tests/data/crud_unified/findOneAndReplace-let.yml +94 -0
  79. data/spec/spec_tests/data/crud_unified/findOneAndUpdate-let.yml +96 -0
  80. data/spec/spec_tests/data/crud_unified/updateMany-let.yml +103 -0
  81. data/spec/spec_tests/data/crud_unified/updateOne-let.yml +98 -0
  82. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +2 -2
  83. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +3 -3
  84. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest.yml +3 -3
  85. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +3 -3
  86. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +2 -2
  87. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +2 -2
  88. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Secondary.yml +4 -4
  89. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +2 -2
  90. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +4 -4
  91. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.yml +2 -2
  92. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +2 -2
  93. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +3 -3
  94. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.yml +2 -2
  95. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.yml +2 -2
  96. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +2 -2
  97. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +2 -2
  98. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest.yml +3 -3
  99. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +3 -3
  100. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +2 -2
  101. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +2 -2
  102. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +2 -2
  103. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +5 -5
  104. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +3 -3
  105. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +5 -5
  106. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +3 -3
  107. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +2 -2
  108. data/spec/spec_tests/data/max_staleness/Sharded/SmallMaxStaleness.yml +2 -2
  109. data/spec/spec_tests/data/max_staleness/Single/SmallMaxStaleness.yml +1 -1
  110. data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -1
  111. data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-client-error.yml +69 -0
  112. data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-server-error.yml +102 -0
  113. data/spec/spec_tests/data/sessions_unified/snapshot-sessions-unsupported-ops.yml +258 -0
  114. data/spec/spec_tests/data/sessions_unified/snapshot-sessions.yml +482 -0
  115. data/spec/spec_tests/seed_list_discovery_spec.rb +1 -1
  116. data/spec/spec_tests/sessions_unified_spec.rb +13 -0
  117. data/spec/support/certificates/atlas-ocsp-ca.crt +47 -40
  118. data/spec/support/certificates/atlas-ocsp.crt +106 -101
  119. data/spec/support/utils.rb +0 -31
  120. data.tar.gz.sig +0 -0
  121. metadata +1084 -1058
  122. metadata.gz.sig +0 -0
  123. data/spec/integration/find_options_spec.rb +0 -227
@@ -45,16 +45,6 @@ describe 'Read preference' do
45
45
  {}
46
46
  end
47
47
 
48
- shared_examples_for 'sends expected read preference when reading' do
49
- it 'sends expected read preference when reading' do
50
- read_operation
51
-
52
- event = subscriber.single_command_started_event('find')
53
- actual_preference = event.command['$readPreference']
54
- expect(actual_preference).to eq(expected_read_preference)
55
- end
56
- end
57
-
58
48
  shared_examples_for 'does not send read preference when reading' do
59
49
  it 'does not send read preference when reading' do
60
50
  read_operation
@@ -95,7 +85,17 @@ describe 'Read preference' do
95
85
  context 'server supporting OP_MSG' do
96
86
  min_server_fcv '3.6'
97
87
 
98
- it_behaves_like 'sends expected read preference when reading'
88
+ it 'sends expected read preference when reading' do
89
+ read_operation
90
+
91
+ event = subscriber.single_command_started_event('find')
92
+ actual_preference = event.command['$readPreference']
93
+ if expected_read_preference&.[]("mode") == "primary"
94
+ expect(actual_preference).to be_nil
95
+ else
96
+ expect(actual_preference).to eq(expected_read_preference)
97
+ end
98
+ end
99
99
  end
100
100
  end
101
101
 
@@ -307,7 +307,11 @@ describe 'Read preference' do
307
307
 
308
308
  event = subscriber.single_command_started_event('find')
309
309
  actual_preference = event.command['$readPreference']
310
- expect(actual_preference).to eq(expected_read_preference)
310
+ if expected_read_preference&.[]("mode") == "primary"
311
+ expect(actual_preference).to be_nil
312
+ else
313
+ expect(actual_preference).to eq(expected_read_preference)
314
+ end
311
315
  end
312
316
  end
313
317
  end
@@ -135,44 +135,4 @@ describe 'SDAM events' do
135
135
  end
136
136
  end
137
137
  end
138
-
139
- describe 'server description changed' do
140
- require_topology :single
141
-
142
- let(:sdam_proc) do
143
- Proc.new do |client|
144
- client.subscribe(Mongo::Monitoring::SERVER_DESCRIPTION_CHANGED, subscriber)
145
- end
146
- end
147
-
148
- let(:client) do
149
- new_local_client(SpecConfig.instance.addresses,
150
- # Heartbeat interval is bound by 500 ms
151
- SpecConfig.instance.test_options.merge(client_options).merge(
152
- heartbeat_frequency: 0.5,
153
- sdam_proc: sdam_proc,
154
- ),
155
- )
156
- end
157
-
158
- let(:client_options) do
159
- {}
160
- end
161
-
162
- it 'is not published when there are no changes in server state' do
163
- client
164
- sleep 6
165
- client.close
166
-
167
- events = subscriber.select_succeeded_events(Mongo::Monitoring::Event::ServerDescriptionChanged)
168
-
169
- # In 6 seconds we should have about 10 or 12 heartbeats.
170
- # We expect 1 or 2 description changes:
171
- # The first one from unknown to known,
172
- # The second one because server changes the fields it returns based on
173
- # driver server check payload (e.g. ismaster/isWritablePrimary).
174
- events.length.should >= 1
175
- events.length.should <= 2
176
- end
177
- end
178
138
  end
@@ -157,13 +157,6 @@ RSpec.configure do |config|
157
157
  end
158
158
 
159
159
  if SpecConfig.instance.active_support?
160
- require "active_support/version"
161
- if ActiveSupport.version >= Gem::Version.new(7)
162
- # ActiveSupport wants us to require ALL of it all of the time.
163
- # See: https://github.com/rails/rails/issues/43851,
164
- # https://github.com/rails/rails/issues/43889, etc.
165
- require 'active_support'
166
- end
167
160
  require "active_support/time"
168
161
  require 'mongo/active_support'
169
162
  end
@@ -29,8 +29,16 @@ describe Mongo::Collection::View::Aggregation do
29
29
  described_class.new(view, pipeline, options)
30
30
  end
31
31
 
32
+ let(:server) do
33
+ double('server')
34
+ end
35
+
36
+ let(:session) do
37
+ double('session')
38
+ end
39
+
32
40
  let(:aggregation_spec) do
33
- aggregation.send(:aggregate_spec, double('session'))
41
+ aggregation.send(:aggregate_spec, server, session, nil)
34
42
  end
35
43
 
36
44
  before do
@@ -351,15 +359,15 @@ describe Mongo::Collection::View::Aggregation do
351
359
 
352
360
  describe '#aggregate_spec' do
353
361
 
354
- context 'when the collection has a read preference' do
362
+ context 'when a read preference is given' do
355
363
 
356
364
  let(:read_preference) do
357
- {mode: :secondary}
365
+ BSON::Document.new({mode: :secondary})
358
366
  end
359
367
 
360
368
  it 'includes the read preference in the spec' do
361
- allow(authorized_collection).to receive(:read_preference).and_return(read_preference)
362
- expect(aggregation_spec[:read]).to eq(read_preference)
369
+ spec = aggregation.send(:aggregate_spec, server, session, read_preference)
370
+ expect(spec[:read]).to eq(read_preference)
363
371
  end
364
372
  end
365
373
 
@@ -570,109 +578,77 @@ describe Mongo::Collection::View::Aggregation do
570
578
  end
571
579
 
572
580
  context 'when $out is in the pipeline' do
573
-
574
- let(:pipeline) do
575
- [{
576
- "$group" => {
577
- "_id" => "$city",
578
- "totalpop" => { "$sum" => "$pop" }
581
+ [['$out', 'string'], [:$out, 'symbol']].each do |op, type|
582
+ context "when #{op} is a #{type}" do
583
+ let(:pipeline) do
584
+ [{
585
+ "$group" => {
586
+ "_id" => "$city",
587
+ "totalpop" => { "$sum" => "$pop" }
588
+ }
589
+ },
590
+ {
591
+ op => 'output_collection'
579
592
  }
580
- },
581
- {
582
- '$out' => 'output_collection'
583
- }
584
- ]
585
- end
586
-
587
- before do
588
- authorized_client['output_collection'].delete_many
589
- end
590
-
591
- context 'when $out is a string' do
592
-
593
- it 'does not allow the operation on a secondary' do
594
- expect(aggregation.send(:secondary_ok?)).to be(false)
595
- end
596
- end
597
-
598
- context 'when $out is a symbol' do
599
-
600
- let(:pipeline) do
601
- [{
602
- "$group" => {
603
- "_id" => "$city",
604
- "totalpop" => { "$sum" => "$pop" }
605
- }
606
- },
607
- {
608
- :$out => 'output_collection'
609
- }
610
- ]
611
- end
612
-
613
- it 'does not allow the operation on a secondary' do
614
- expect(aggregation.send(:secondary_ok?)).to be(false)
615
- end
616
- end
593
+ ]
594
+ end
617
595
 
596
+ before do
597
+ authorized_client['output_collection'].delete_many
598
+ end
618
599
 
619
- context 'when the server is not a valid for writing' do
600
+ let(:features) do
601
+ double()
602
+ end
620
603
 
621
- it 'reroutes the operation to a primary' do
622
- allow(aggregation).to receive(:valid_server?).and_return(false)
623
- expect(Mongo::Logger.logger).to receive(:warn).and_call_original
624
- aggregation.to_a
625
- end
626
- end
604
+ let(:server) do
605
+ double().tap do |server|
606
+ allow(server).to receive(:features).and_return(features)
607
+ end
608
+ end
627
609
 
628
- context 'when the server is a valid for writing' do
610
+ context 'when the view has a write concern' do
629
611
 
630
- it 'does not reroute the operation to a primary' do
631
- expect(Mongo::Logger.logger).not_to receive(:warn)
632
- aggregation.to_a
633
- end
612
+ let(:collection) do
613
+ authorized_collection.with(write: INVALID_WRITE_CONCERN)
614
+ end
634
615
 
635
- context 'when the view has a write concern' do
616
+ let(:view) do
617
+ Mongo::Collection::View.new(collection, selector, view_options)
618
+ end
636
619
 
637
- let(:collection) do
638
- authorized_collection.with(write: INVALID_WRITE_CONCERN)
639
- end
620
+ context 'when the server supports write concern on the aggregate command' do
621
+ min_server_fcv '3.4'
640
622
 
641
- let(:view) do
642
- Mongo::Collection::View.new(collection, selector, view_options)
643
- end
623
+ it 'uses the write concern' do
624
+ expect {
625
+ aggregation.to_a
626
+ }.to raise_exception(Mongo::Error::OperationFailure)
627
+ end
628
+ end
644
629
 
645
- context 'when the server supports write concern on the aggregate command' do
646
- min_server_fcv '3.4'
630
+ context 'when the server does not support write concern on the aggregation command' do
631
+ max_server_version '3.2'
647
632
 
648
- it 'uses the write concern' do
649
- expect {
650
- aggregation.to_a
651
- }.to raise_exception(Mongo::Error::OperationFailure)
652
- end
653
- end
633
+ let(:documents) do
634
+ [
635
+ { city: "Berlin", pop: 18913, neighborhood: "Kreuzberg" },
636
+ { city: "Berlin", pop: 84143, neighborhood: "Mitte" },
637
+ { city: "New York", pop: 40270, neighborhood: "Brooklyn" }
638
+ ]
639
+ end
654
640
 
655
- context 'when the server does not support write concern on the aggregation command' do
656
- max_server_version '3.2'
641
+ before do
642
+ authorized_collection.insert_many(documents)
643
+ aggregation.to_a
644
+ end
657
645
 
658
- let(:documents) do
659
- [
660
- { city: "Berlin", pop: 18913, neighborhood: "Kreuzberg" },
661
- { city: "Berlin", pop: 84143, neighborhood: "Mitte" },
662
- { city: "New York", pop: 40270, neighborhood: "Brooklyn" }
663
- ]
664
- end
665
-
666
- before do
667
- authorized_collection.insert_many(documents)
668
- aggregation.to_a
669
- end
670
-
671
- it 'does not apply the write concern' do
672
- expect(authorized_client['output_collection'].find.count).to eq(2)
673
- end
674
- end
675
- end
646
+ it 'does not apply the write concern' do
647
+ expect(authorized_client['output_collection'].find.count).to eq(2)
648
+ end
649
+ end
650
+ end
651
+ end
676
652
  end
677
653
  end
678
654
  end
@@ -56,7 +56,7 @@ describe Mongo::Collection::View::ChangeStream do
56
56
 
57
57
  let(:command_spec) do
58
58
  change_stream.send(:instance_variable_set, '@resuming', false)
59
- change_stream.send(:aggregate_spec, double('session'))
59
+ change_stream.send(:aggregate_spec, double('server'), double('session'), nil)
60
60
  end
61
61
 
62
62
  let(:cursor) do
@@ -60,6 +60,14 @@ describe Mongo::Collection::View::MapReduce do
60
60
  described_class.new(view, map, reduce, options)
61
61
  end
62
62
 
63
+ describe '#initialize' do
64
+ it 'warns of deprecation' do
65
+ Mongo::Logger.logger.should receive(:warn).with('MONGODB | The map_reduce operation is deprecated, please use the aggregation pipeline instead')
66
+
67
+ map_reduce
68
+ end
69
+ end
70
+
63
71
  describe '#map_function' do
64
72
 
65
73
  it 'returns the map function' do
@@ -672,7 +680,12 @@ describe Mongo::Collection::View::MapReduce do
672
680
  end
673
681
 
674
682
  it 'does not reroute the operation to a primary' do
675
- expect(Mongo::Logger.logger).not_to receive(:warn)
683
+ # We produce a deprecation warning, but there shouldn't be
684
+ # the reroute warning.
685
+ expect(Mongo::Logger.logger).to receive(:warn).once do |msg|
686
+ expect(msg).not_to include('Rerouting the MapReduce operation to the primary server')
687
+ end
688
+
676
689
  map_reduce.to_a
677
690
  end
678
691
  end
@@ -865,20 +878,4 @@ describe Mongo::Collection::View::MapReduce do
865
878
  end
866
879
  end
867
880
  end
868
-
869
- describe '#map_reduce_spec' do
870
- context 'when read preference is given' do
871
- let(:view_options) do
872
- { read: {mode: :secondary} }
873
- end
874
-
875
- context 'selector' do
876
- # For compatibility with released versions of Mongoid, this method
877
- # must return read preference under the :read key.
878
- it 'contains read preference' do
879
- map_reduce_spec[:selector][:read].should == {'mode' => :secondary}
880
- end
881
- end
882
- end
883
- end
884
881
  end
@@ -1186,62 +1186,6 @@ describe Mongo::Collection::View::Readable do
1186
1186
  it 'returns a new View' do
1187
1187
  expect(new_view).not_to be(view)
1188
1188
  end
1189
-
1190
- context 'when sending to server' do
1191
- let(:subscriber) { Mrss::EventSubscriber.new }
1192
-
1193
- before do
1194
- authorized_collection.client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
1195
- end
1196
-
1197
- let(:event) do
1198
- subscriber.single_command_started_event('find')
1199
- end
1200
-
1201
- it 'is sent to server' do
1202
- new_view.to_a
1203
- event.command.slice('noCursorTimeout').should == {'noCursorTimeout' => true}
1204
- end
1205
- end
1206
-
1207
- context 'integration test' do
1208
- require_topology :single
1209
-
1210
- # The number of open cursors with the option set to prevent timeout.
1211
- def current_no_timeout_count
1212
- root_authorized_client
1213
- .command(serverStatus: 1)
1214
- .documents
1215
- .first
1216
- .fetch('metrics')
1217
- .fetch('cursor')
1218
- .fetch('open')
1219
- .fetch('noTimeout')
1220
- end
1221
-
1222
- it 'is applied on the server' do
1223
- # Initialize collection with two documents.
1224
- new_view.collection.insert_many([{}, {}])
1225
-
1226
- expect(new_view.count).to be == 2
1227
-
1228
- # Initial "noTimeout" count should be zero.
1229
- states = [current_no_timeout_count]
1230
-
1231
- # The "noTimeout" count should be one while iterating.
1232
- new_view.batch_size(1).each { states << current_no_timeout_count }
1233
-
1234
- # Final "noTimeout" count should be back to zero.
1235
- states << current_no_timeout_count
1236
-
1237
- # This succeeds on:
1238
- # commit aab776ebdfb15ddb9765039f7300e15796de0c5c
1239
- #
1240
- # This starts failing with [0, 0, 0, 0] from:
1241
- # commit 2d9f0217ec904a1952a1ada2136502eefbca562e
1242
- expect(states).to be == [0, 1, 1, 0]
1243
- end
1244
- end
1245
1189
  end
1246
1190
 
1247
1191
  describe '#projection' do
@@ -99,6 +99,29 @@ describe Mongo::Operation::SessionsSupported do
99
99
  end
100
100
  end
101
101
 
102
+ shared_examples_for 'sends read preference correctly for replica set' do
103
+ context "when read preference mode is primary" do
104
+ let(:mode) { :primary}
105
+
106
+ it_behaves_like 'does not modify selector'
107
+ end
108
+ %i(primary_preferred secondary secondary_preferred nearest).each do |_mode|
109
+ active_mode = _mode
110
+
111
+ context "when read preference mode is #{active_mode}" do
112
+ let(:mode) { active_mode }
113
+
114
+ let(:expected) do
115
+ selector.merge(:$readPreference => expected_read_preference)
116
+ end
117
+
118
+ it 'adds read preference' do
119
+ expect(actual).to eq(expected)
120
+ end
121
+ end
122
+ end
123
+ end
124
+
102
125
  shared_examples_for 'sends user-specified read preference' do
103
126
  %i(primary primary_preferred secondary secondary_preferred nearest).each do |_mode|
104
127
  active_mode = _mode
@@ -302,7 +325,7 @@ describe Mongo::Operation::SessionsSupported do
302
325
  let(:standalone?) { false }
303
326
  let(:mongos?) { false }
304
327
 
305
- it_behaves_like 'sends user-specified read preference'
328
+ it_behaves_like 'sends read preference correctly for replica set'
306
329
  end
307
330
  end
308
331
  end
@@ -191,14 +191,6 @@ describe Mongo::QueryCache do
191
191
  end
192
192
  end
193
193
 
194
- context 'when the query has a limit but negative' do
195
- let(:limit) { -5 }
196
-
197
- it 'returns the caching cursor' do
198
- expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
199
- end
200
- end
201
-
202
194
  context 'when the query has no limit' do
203
195
  let(:limit) { nil }
204
196
 
@@ -206,65 +198,6 @@ describe Mongo::QueryCache do
206
198
  expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
207
199
  end
208
200
  end
209
-
210
- context 'when the query has a 0 limit' do
211
- let(:limit) { 0 }
212
-
213
- it 'returns the caching cursor' do
214
- expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
215
- end
216
- end
217
- end
218
-
219
- context 'when that entry has a 0 limit' do
220
- let(:caching_cursor_options) do
221
- {
222
- namespace: 'db.coll',
223
- selector: { field: 'value' },
224
- limit: 0,
225
- }
226
- end
227
-
228
- let(:query_options) do
229
- caching_cursor_options.merge(limit: limit)
230
- end
231
-
232
- before do
233
- allow(view).to receive(:limit) { 0 }
234
- end
235
-
236
- context 'when the query has a limit' do
237
- let(:limit) { 5 }
238
-
239
- it 'returns the caching cursor' do
240
- expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
241
- end
242
- end
243
-
244
- context 'when the query has a limit but negative' do
245
- let(:limit) { -5 }
246
-
247
- it 'returns the caching cursor' do
248
- expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
249
- end
250
- end
251
-
252
-
253
- context 'when the query has no limit' do
254
- let(:limit) { nil }
255
-
256
- it 'returns the caching cursor' do
257
- expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
258
- end
259
- end
260
-
261
- context 'when the query has a 0 limit' do
262
- let(:limit) { 0 }
263
-
264
- it 'returns the caching cursor' do
265
- expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
266
- end
267
- end
268
201
  end
269
202
 
270
203
  context 'when that entry has a limit' do
@@ -292,14 +225,6 @@ describe Mongo::QueryCache do
292
225
  end
293
226
  end
294
227
 
295
- context 'and the new query has a smaller limit but negative' do
296
- let(:limit) { -4 }
297
-
298
- it 'returns the caching cursor' do
299
- expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
300
- end
301
- end
302
-
303
228
  context 'and the new query has a larger limit' do
304
229
  let(:limit) { 6 }
305
230
 
@@ -308,14 +233,6 @@ describe Mongo::QueryCache do
308
233
  end
309
234
  end
310
235
 
311
- context 'and the new query has a larger limit but negative' do
312
- let(:limit) { -6 }
313
-
314
- it 'returns nil' do
315
- expect(Mongo::QueryCache.get(**query_options)).to be_nil
316
- end
317
- end
318
-
319
236
  context 'and the new query has the same limit' do
320
237
  let(:limit) { 5 }
321
238
 
@@ -324,80 +241,6 @@ describe Mongo::QueryCache do
324
241
  end
325
242
  end
326
243
 
327
- context 'and the new query has the same limit but negative' do
328
- let(:limit) { -5 }
329
-
330
- it 'returns the caching cursor' do
331
- expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
332
- end
333
- end
334
-
335
- context 'and the new query has no limit' do
336
- let(:limit) { nil }
337
-
338
- it 'returns nil' do
339
- expect(Mongo::QueryCache.get(**query_options)).to be_nil
340
- end
341
- end
342
-
343
- context 'and the new query has a 0 limit' do
344
- let(:limit) { 0 }
345
-
346
- it 'returns nil' do
347
- expect(Mongo::QueryCache.get(**query_options)).to be_nil
348
- end
349
- end
350
- end
351
-
352
- context 'when that entry has a negative limit' do
353
- let(:caching_cursor_options) do
354
- {
355
- namespace: 'db.coll',
356
- selector: { field: 'value' },
357
- limit: -5,
358
- }
359
- end
360
-
361
- let(:query_options) do
362
- caching_cursor_options.merge(limit: limit)
363
- end
364
-
365
- before do
366
- allow(view).to receive(:limit) { -5 }
367
- end
368
-
369
- context 'and the new query has a smaller limit' do
370
- let(:limit) { 4 }
371
-
372
- it 'returns the caching cursor' do
373
- expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
374
- end
375
- end
376
-
377
- context 'and the new query has a larger limit' do
378
- let(:limit) { 6 }
379
-
380
- it 'returns nil' do
381
- expect(Mongo::QueryCache.get(**query_options)).to be_nil
382
- end
383
- end
384
-
385
- context 'and the new query has the same negative limit' do
386
- let(:limit) { -5 }
387
-
388
- it 'returns the caching cursor' do
389
- expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
390
- end
391
- end
392
-
393
- context 'and the new query has the same positive limit' do
394
- let(:limit) { 5 }
395
-
396
- it 'returns the caching cursor' do
397
- expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
398
- end
399
- end
400
-
401
244
  context 'and the new query has no limit' do
402
245
  let(:limit) { nil }
403
246
 
@@ -405,14 +248,6 @@ describe Mongo::QueryCache do
405
248
  expect(Mongo::QueryCache.get(**query_options)).to be_nil
406
249
  end
407
250
  end
408
-
409
- context 'and the new query has a 0 limit' do
410
- let(:limit) { 0 }
411
-
412
- it 'returns nil' do
413
- expect(Mongo::QueryCache.get(**query_options)).to be_nil
414
- end
415
- end
416
251
  end
417
252
  end
418
253
  end