mongo 2.20.1 → 2.21.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.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/Rakefile +2 -2
- data/lib/mongo/address.rb +22 -3
- data/lib/mongo/auth/aws/credentials_retriever.rb +70 -17
- data/lib/mongo/auth/base.rb +1 -1
- data/lib/mongo/bulk_write.rb +35 -2
- data/lib/mongo/client.rb +38 -6
- data/lib/mongo/client_encryption.rb +6 -3
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -1
- data/lib/mongo/cluster/sdam_flow.rb +20 -7
- data/lib/mongo/cluster.rb +14 -4
- data/lib/mongo/collection/helpers.rb +1 -1
- data/lib/mongo/collection/view/aggregation/behavior.rb +131 -0
- data/lib/mongo/collection/view/aggregation.rb +33 -99
- data/lib/mongo/collection/view/builder/aggregation.rb +1 -7
- data/lib/mongo/collection/view/change_stream.rb +80 -27
- data/lib/mongo/collection/view/iterable.rb +76 -60
- data/lib/mongo/collection/view/map_reduce.rb +25 -8
- data/lib/mongo/collection/view/readable.rb +79 -30
- data/lib/mongo/collection/view/writable.rb +109 -48
- data/lib/mongo/collection/view.rb +43 -3
- data/lib/mongo/collection.rb +158 -23
- data/lib/mongo/crypt/auto_encrypter.rb +4 -6
- data/lib/mongo/crypt/binding.rb +4 -4
- data/lib/mongo/crypt/context.rb +20 -14
- data/lib/mongo/crypt/encryption_io.rb +56 -26
- data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
- data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
- data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
- data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
- data/lib/mongo/csot_timeout_holder.rb +119 -0
- data/lib/mongo/cursor/kill_spec.rb +5 -2
- data/lib/mongo/cursor/nontailable.rb +27 -0
- data/lib/mongo/cursor.rb +86 -24
- data/lib/mongo/cursor_host.rb +82 -0
- data/lib/mongo/database/view.rb +81 -14
- data/lib/mongo/database.rb +88 -18
- data/lib/mongo/error/operation_failure.rb +209 -204
- data/lib/mongo/error/server_timeout_error.rb +12 -0
- data/lib/mongo/error/socket_timeout_error.rb +3 -1
- data/lib/mongo/error/timeout_error.rb +23 -0
- data/lib/mongo/error.rb +2 -0
- data/lib/mongo/grid/fs_bucket.rb +45 -12
- data/lib/mongo/grid/stream/read.rb +15 -1
- data/lib/mongo/grid/stream/write.rb +21 -4
- data/lib/mongo/index/view.rb +77 -16
- data/lib/mongo/operation/context.rb +40 -2
- data/lib/mongo/operation/create_search_indexes/op_msg.rb +2 -2
- data/lib/mongo/operation/delete/op_msg.rb +2 -1
- data/lib/mongo/operation/drop_search_index/op_msg.rb +2 -2
- data/lib/mongo/operation/find/op_msg.rb +45 -0
- data/lib/mongo/operation/get_more/op_msg.rb +33 -0
- data/lib/mongo/operation/insert/op_msg.rb +3 -2
- data/lib/mongo/operation/insert/result.rb +4 -2
- data/lib/mongo/operation/list_collections/result.rb +1 -1
- data/lib/mongo/operation/map_reduce/result.rb +1 -1
- data/lib/mongo/operation/op_msg_base.rb +3 -1
- data/lib/mongo/operation/result.rb +26 -5
- data/lib/mongo/operation/shared/executable.rb +12 -1
- data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
- data/lib/mongo/operation/shared/response_handling.rb +3 -3
- data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
- data/lib/mongo/operation/shared/timed.rb +52 -0
- data/lib/mongo/operation/shared/write.rb +4 -1
- data/lib/mongo/operation/update/op_msg.rb +2 -1
- data/lib/mongo/operation/update_search_index/op_msg.rb +2 -2
- data/lib/mongo/operation.rb +1 -0
- data/lib/mongo/protocol/message.rb +1 -4
- data/lib/mongo/protocol/msg.rb +2 -2
- data/lib/mongo/retryable/read_worker.rb +69 -29
- data/lib/mongo/retryable/write_worker.rb +49 -18
- data/lib/mongo/retryable.rb +8 -2
- data/lib/mongo/server/connection.rb +11 -5
- data/lib/mongo/server/connection_base.rb +22 -2
- data/lib/mongo/server/connection_pool.rb +32 -14
- data/lib/mongo/server/description/features.rb +1 -1
- data/lib/mongo/server/description.rb +18 -5
- data/lib/mongo/server/monitor.rb +7 -4
- data/lib/mongo/server/pending_connection.rb +7 -3
- data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
- data/lib/mongo/server.rb +11 -6
- data/lib/mongo/server_selector/base.rb +25 -9
- data/lib/mongo/session.rb +78 -9
- data/lib/mongo/socket/ssl.rb +109 -17
- data/lib/mongo/socket/tcp.rb +40 -6
- data/lib/mongo/socket.rb +154 -25
- data/lib/mongo/uri/options_mapper.rb +1 -0
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo.rb +1 -0
- data/spec/atlas/atlas_connectivity_spec.rb +4 -0
- data/spec/atlas/operations_spec.rb +4 -0
- data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
- data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
- data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
- data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +66 -22
- data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
- data/spec/integration/connection_pool_populator_spec.rb +2 -0
- data/spec/integration/cursor_pinning_spec.rb +15 -60
- data/spec/integration/cursor_reaping_spec.rb +1 -1
- data/spec/integration/docs_examples_spec.rb +1 -1
- data/spec/integration/operation_failure_code_spec.rb +1 -1
- data/spec/integration/operation_failure_message_spec.rb +3 -3
- data/spec/integration/retryable_errors_spec.rb +2 -2
- data/spec/integration/sdam_error_handling_spec.rb +2 -1
- data/spec/integration/search_indexes_prose_spec.rb +4 -0
- data/spec/integration/server_spec.rb +4 -3
- data/spec/integration/transactions_api_examples_spec.rb +2 -0
- data/spec/kerberos/kerberos_spec.rb +4 -0
- data/spec/lite_spec_helper.rb +3 -1
- data/spec/mongo/auth/user/view_spec.rb +1 -1
- data/spec/mongo/caching_cursor_spec.rb +1 -1
- data/spec/mongo/client_encryption_spec.rb +1 -0
- data/spec/mongo/client_spec.rb +158 -4
- data/spec/mongo/collection/view/aggregation_spec.rb +14 -39
- data/spec/mongo/collection/view/change_stream_spec.rb +3 -3
- data/spec/mongo/collection_spec.rb +5 -6
- data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
- data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
- data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
- data/spec/mongo/crypt/handle_spec.rb +1 -1
- data/spec/mongo/cursor_spec.rb +26 -9
- data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
- data/spec/mongo/operation/context_spec.rb +79 -0
- data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
- data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
- data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
- data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
- data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
- data/spec/mongo/operation/shared/csot/examples.rb +113 -0
- data/spec/mongo/query_cache_spec.rb +243 -225
- data/spec/mongo/retryable_spec.rb +1 -0
- data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
- data/spec/mongo/socket/ssl_spec.rb +0 -10
- data/spec/runners/change_streams/test.rb +2 -2
- data/spec/runners/crud/operation.rb +1 -1
- data/spec/runners/crud/verifier.rb +3 -1
- data/spec/runners/transactions/operation.rb +4 -6
- data/spec/runners/unified/ambiguous_operations.rb +13 -0
- data/spec/runners/unified/assertions.rb +4 -0
- data/spec/runners/unified/change_stream_operations.rb +14 -24
- data/spec/runners/unified/crud_operations.rb +82 -59
- data/spec/runners/unified/ddl_operations.rb +38 -7
- data/spec/runners/unified/grid_fs_operations.rb +37 -2
- data/spec/runners/unified/support_operations.rb +43 -4
- data/spec/runners/unified/test.rb +22 -10
- data/spec/runners/unified.rb +1 -1
- data/spec/solo/clean_exit_spec.rb +2 -0
- data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
- data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
- data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
- data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
- data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
- data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
- data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
- data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
- data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
- data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
- data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
- data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
- data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
- data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
- data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
- data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
- data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
- data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
- data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
- data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
- data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
- data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +4 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +4 -0
- data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +29 -0
- data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
- data/spec/support/certificates/atlas-ocsp-ca.crt +81 -83
- data/spec/support/certificates/atlas-ocsp.crt +107 -107
- data/spec/support/cluster_tools.rb +3 -3
- data/spec/support/common_shortcuts.rb +2 -2
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
- data/spec/support/shared/session.rb +2 -2
- data/spec/support/spec_setup.rb +2 -2
- data/spec/support/utils.rb +3 -1
- metadata +78 -91
- data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -242
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -423
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -183
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -240
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -236
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -253
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1688
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -294
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -906
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1685
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1681
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1698
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -330
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -425
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -227
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -328
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -320
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -337
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -914
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -293
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -519
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -912
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -908
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -925
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -326
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -425
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -225
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -324
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -320
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -339
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -242
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -424
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -183
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -240
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -236
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -255
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -242
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -423
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -183
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -240
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -236
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -255
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -44
@@ -138,12 +138,19 @@ describe Mongo::QueryCache do
|
|
138
138
|
end
|
139
139
|
|
140
140
|
describe '#get' do
|
141
|
-
let(:view)
|
141
|
+
let(:view) do
|
142
|
+
double("Mongo::Collection::View").tap do |view|
|
143
|
+
allow(view).to receive(:client).and_return(client)
|
144
|
+
allow(view).to receive(:operation_timeouts).and_return({})
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
142
148
|
let(:result) do
|
143
149
|
double("Mongo::Operation::Result").tap do |result|
|
144
150
|
allow(result).to receive(:is_a?).with(Mongo::Operation::Result).and_return(true)
|
145
151
|
end
|
146
152
|
end
|
153
|
+
|
147
154
|
let(:server) { double("Mongo::Server") }
|
148
155
|
let(:caching_cursor) { Mongo::CachingCursor.new(view, result, server) }
|
149
156
|
|
@@ -161,257 +168,268 @@ describe Mongo::QueryCache do
|
|
161
168
|
allow(view).to receive(:limit) { nil }
|
162
169
|
end
|
163
170
|
|
164
|
-
|
165
|
-
|
166
|
-
expect(Mongo::QueryCache.get(**options)).to be_nil
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
context 'when there is an entry in the cache' do
|
171
|
-
before do
|
172
|
-
Mongo::QueryCache.set(caching_cursor, **caching_cursor_options)
|
173
|
-
end
|
174
|
-
|
175
|
-
context 'when that entry has no limit' do
|
176
|
-
let(:caching_cursor_options) do
|
177
|
-
{
|
178
|
-
namespace: 'db.coll',
|
179
|
-
selector: { field: 'value' },
|
180
|
-
}
|
181
|
-
end
|
182
|
-
|
183
|
-
let(:query_options) do
|
184
|
-
caching_cursor_options.merge(limit: limit)
|
185
|
-
end
|
186
|
-
|
187
|
-
context 'when the query has a limit' do
|
188
|
-
let(:limit) { 5 }
|
189
|
-
|
190
|
-
it 'returns the caching cursor' do
|
191
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
context 'when the query has a limit but negative' do
|
196
|
-
let(:limit) { -5 }
|
197
|
-
|
198
|
-
it 'returns the caching cursor' do
|
199
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
context 'when the query has no limit' do
|
204
|
-
let(:limit) { nil }
|
205
|
-
|
206
|
-
it 'returns the caching cursor' do
|
207
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
context 'when the query has a 0 limit' do
|
212
|
-
let(:limit) { 0 }
|
213
|
-
|
214
|
-
it 'returns the caching cursor' do
|
215
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
context 'when that entry has a 0 limit' do
|
221
|
-
let(:caching_cursor_options) do
|
222
|
-
{
|
223
|
-
namespace: 'db.coll',
|
224
|
-
selector: { field: 'value' },
|
225
|
-
limit: 0,
|
226
|
-
}
|
227
|
-
end
|
228
|
-
|
229
|
-
let(:query_options) do
|
230
|
-
caching_cursor_options.merge(limit: limit)
|
231
|
-
end
|
232
|
-
|
233
|
-
before do
|
234
|
-
allow(view).to receive(:limit) { 0 }
|
235
|
-
end
|
236
|
-
|
237
|
-
context 'when the query has a limit' do
|
238
|
-
let(:limit) { 5 }
|
239
|
-
|
240
|
-
it 'returns the caching cursor' do
|
241
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
context 'when the query has a limit but negative' do
|
246
|
-
let(:limit) { -5 }
|
247
|
-
|
248
|
-
it 'returns the caching cursor' do
|
249
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
|
254
|
-
context 'when the query has no limit' do
|
255
|
-
let(:limit) { nil }
|
256
|
-
|
257
|
-
it 'returns the caching cursor' do
|
258
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
context 'when the query has a 0 limit' do
|
263
|
-
let(:limit) { 0 }
|
264
|
-
|
265
|
-
it 'returns the caching cursor' do
|
266
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
context 'when that entry has a limit' do
|
272
|
-
let(:caching_cursor_options) do
|
273
|
-
{
|
274
|
-
namespace: 'db.coll',
|
275
|
-
selector: { field: 'value' },
|
276
|
-
limit: 5,
|
277
|
-
}
|
278
|
-
end
|
279
|
-
|
280
|
-
let(:query_options) do
|
281
|
-
caching_cursor_options.merge(limit: limit)
|
282
|
-
end
|
283
|
-
|
171
|
+
[true, false].each do |load_balancer|
|
172
|
+
context "when load_balancer is #{load_balancer}" do
|
284
173
|
before do
|
285
|
-
allow(
|
286
|
-
|
287
|
-
|
288
|
-
context 'and the new query has a smaller limit' do
|
289
|
-
let(:limit) { 4 }
|
290
|
-
|
291
|
-
it 'returns the caching cursor' do
|
292
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
293
|
-
end
|
294
|
-
end
|
295
|
-
|
296
|
-
context 'and the new query has a smaller limit but negative' do
|
297
|
-
let(:limit) { -4 }
|
298
|
-
|
299
|
-
it 'returns the caching cursor' do
|
300
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
174
|
+
allow(server).to receive(:load_balancer?) { load_balancer }
|
175
|
+
if load_balancer
|
176
|
+
allow(result).to receive(:connection) { nil }
|
301
177
|
end
|
302
178
|
end
|
303
179
|
|
304
|
-
context '
|
305
|
-
let(:limit) { 6 }
|
306
|
-
|
180
|
+
context 'when there is no entry in the cache' do
|
307
181
|
it 'returns nil' do
|
308
|
-
expect(Mongo::QueryCache.get(**
|
182
|
+
expect(Mongo::QueryCache.get(**options)).to be_nil
|
309
183
|
end
|
310
184
|
end
|
311
185
|
|
312
|
-
context '
|
313
|
-
|
314
|
-
|
315
|
-
it 'returns nil' do
|
316
|
-
expect(Mongo::QueryCache.get(**query_options)).to be_nil
|
317
|
-
end
|
318
|
-
end
|
319
|
-
|
320
|
-
context 'and the new query has the same limit' do
|
321
|
-
let(:limit) { 5 }
|
322
|
-
|
323
|
-
it 'returns the caching cursor' do
|
324
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
context 'and the new query has the same limit but negative' do
|
329
|
-
let(:limit) { -5 }
|
330
|
-
|
331
|
-
it 'returns the caching cursor' do
|
332
|
-
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
186
|
+
context 'when there is an entry in the cache' do
|
187
|
+
before do
|
188
|
+
Mongo::QueryCache.set(caching_cursor, **caching_cursor_options)
|
333
189
|
end
|
334
|
-
end
|
335
|
-
|
336
|
-
context 'and the new query has no limit' do
|
337
|
-
let(:limit) { nil }
|
338
190
|
|
339
|
-
|
340
|
-
|
191
|
+
context 'when that entry has no limit' do
|
192
|
+
let(:caching_cursor_options) do
|
193
|
+
{
|
194
|
+
namespace: 'db.coll',
|
195
|
+
selector: { field: 'value' },
|
196
|
+
}
|
197
|
+
end
|
198
|
+
|
199
|
+
let(:query_options) do
|
200
|
+
caching_cursor_options.merge(limit: limit)
|
201
|
+
end
|
202
|
+
|
203
|
+
context 'when the query has a limit' do
|
204
|
+
let(:limit) { 5 }
|
205
|
+
|
206
|
+
it 'returns the caching cursor' do
|
207
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context 'when the query has a limit but negative' do
|
212
|
+
let(:limit) { -5 }
|
213
|
+
|
214
|
+
it 'returns the caching cursor' do
|
215
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context 'when the query has no limit' do
|
220
|
+
let(:limit) { nil }
|
221
|
+
|
222
|
+
it 'returns the caching cursor' do
|
223
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
context 'when the query has a 0 limit' do
|
228
|
+
let(:limit) { 0 }
|
229
|
+
|
230
|
+
it 'returns the caching cursor' do
|
231
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
232
|
+
end
|
233
|
+
end
|
341
234
|
end
|
342
|
-
end
|
343
235
|
|
344
|
-
|
345
|
-
|
236
|
+
context 'when that entry has a 0 limit' do
|
237
|
+
let(:caching_cursor_options) do
|
238
|
+
{
|
239
|
+
namespace: 'db.coll',
|
240
|
+
selector: { field: 'value' },
|
241
|
+
limit: 0,
|
242
|
+
}
|
243
|
+
end
|
346
244
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
context 'when that entry has a negative limit' do
|
354
|
-
let(:caching_cursor_options) do
|
355
|
-
{
|
356
|
-
namespace: 'db.coll',
|
357
|
-
selector: { field: 'value' },
|
358
|
-
limit: -5,
|
359
|
-
}
|
360
|
-
end
|
245
|
+
let(:query_options) do
|
246
|
+
caching_cursor_options.merge(limit: limit)
|
247
|
+
end
|
361
248
|
|
362
|
-
|
363
|
-
|
364
|
-
|
249
|
+
before do
|
250
|
+
allow(view).to receive(:limit) { 0 }
|
251
|
+
end
|
365
252
|
|
366
|
-
|
367
|
-
|
368
|
-
end
|
253
|
+
context 'when the query has a limit' do
|
254
|
+
let(:limit) { 5 }
|
369
255
|
|
370
|
-
|
371
|
-
|
256
|
+
it 'returns the caching cursor' do
|
257
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
258
|
+
end
|
259
|
+
end
|
372
260
|
|
373
|
-
|
374
|
-
|
375
|
-
end
|
376
|
-
end
|
261
|
+
context 'when the query has a limit but negative' do
|
262
|
+
let(:limit) { -5 }
|
377
263
|
|
378
|
-
|
379
|
-
|
264
|
+
it 'returns the caching cursor' do
|
265
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
266
|
+
end
|
267
|
+
end
|
380
268
|
|
381
|
-
it 'returns nil' do
|
382
|
-
expect(Mongo::QueryCache.get(**query_options)).to be_nil
|
383
|
-
end
|
384
|
-
end
|
385
269
|
|
386
|
-
|
387
|
-
|
270
|
+
context 'when the query has no limit' do
|
271
|
+
let(:limit) { nil }
|
388
272
|
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
273
|
+
it 'returns the caching cursor' do
|
274
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
275
|
+
end
|
276
|
+
end
|
393
277
|
|
394
|
-
|
395
|
-
|
278
|
+
context 'when the query has a 0 limit' do
|
279
|
+
let(:limit) { 0 }
|
396
280
|
|
397
|
-
|
398
|
-
|
281
|
+
it 'returns the caching cursor' do
|
282
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
283
|
+
end
|
284
|
+
end
|
399
285
|
end
|
400
|
-
end
|
401
|
-
|
402
|
-
context 'and the new query has no limit' do
|
403
|
-
let(:limit) { nil }
|
404
286
|
|
405
|
-
|
406
|
-
|
287
|
+
context 'when that entry has a limit' do
|
288
|
+
let(:caching_cursor_options) do
|
289
|
+
{
|
290
|
+
namespace: 'db.coll',
|
291
|
+
selector: { field: 'value' },
|
292
|
+
limit: 5,
|
293
|
+
}
|
294
|
+
end
|
295
|
+
|
296
|
+
let(:query_options) do
|
297
|
+
caching_cursor_options.merge(limit: limit)
|
298
|
+
end
|
299
|
+
|
300
|
+
before do
|
301
|
+
allow(view).to receive(:limit) { 5 }
|
302
|
+
end
|
303
|
+
|
304
|
+
context 'and the new query has a smaller limit' do
|
305
|
+
let(:limit) { 4 }
|
306
|
+
|
307
|
+
it 'returns the caching cursor' do
|
308
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
context 'and the new query has a smaller limit but negative' do
|
313
|
+
let(:limit) { -4 }
|
314
|
+
|
315
|
+
it 'returns the caching cursor' do
|
316
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
context 'and the new query has a larger limit' do
|
321
|
+
let(:limit) { 6 }
|
322
|
+
|
323
|
+
it 'returns nil' do
|
324
|
+
expect(Mongo::QueryCache.get(**query_options)).to be_nil
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
context 'and the new query has a larger limit but negative' do
|
329
|
+
let(:limit) { -6 }
|
330
|
+
|
331
|
+
it 'returns nil' do
|
332
|
+
expect(Mongo::QueryCache.get(**query_options)).to be_nil
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
context 'and the new query has the same limit' do
|
337
|
+
let(:limit) { 5 }
|
338
|
+
|
339
|
+
it 'returns the caching cursor' do
|
340
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
context 'and the new query has the same limit but negative' do
|
345
|
+
let(:limit) { -5 }
|
346
|
+
|
347
|
+
it 'returns the caching cursor' do
|
348
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
context 'and the new query has no limit' do
|
353
|
+
let(:limit) { nil }
|
354
|
+
|
355
|
+
it 'returns nil' do
|
356
|
+
expect(Mongo::QueryCache.get(**query_options)).to be_nil
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
context 'and the new query has a 0 limit' do
|
361
|
+
let(:limit) { 0 }
|
362
|
+
|
363
|
+
it 'returns nil' do
|
364
|
+
expect(Mongo::QueryCache.get(**query_options)).to be_nil
|
365
|
+
end
|
366
|
+
end
|
407
367
|
end
|
408
|
-
end
|
409
|
-
|
410
|
-
context 'and the new query has a 0 limit' do
|
411
|
-
let(:limit) { 0 }
|
412
368
|
|
413
|
-
|
414
|
-
|
369
|
+
context 'when that entry has a negative limit' do
|
370
|
+
let(:caching_cursor_options) do
|
371
|
+
{
|
372
|
+
namespace: 'db.coll',
|
373
|
+
selector: { field: 'value' },
|
374
|
+
limit: -5,
|
375
|
+
}
|
376
|
+
end
|
377
|
+
|
378
|
+
let(:query_options) do
|
379
|
+
caching_cursor_options.merge(limit: limit)
|
380
|
+
end
|
381
|
+
|
382
|
+
before do
|
383
|
+
allow(view).to receive(:limit) { -5 }
|
384
|
+
end
|
385
|
+
|
386
|
+
context 'and the new query has a smaller limit' do
|
387
|
+
let(:limit) { 4 }
|
388
|
+
|
389
|
+
it 'returns the caching cursor' do
|
390
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
context 'and the new query has a larger limit' do
|
395
|
+
let(:limit) { 6 }
|
396
|
+
|
397
|
+
it 'returns nil' do
|
398
|
+
expect(Mongo::QueryCache.get(**query_options)).to be_nil
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
context 'and the new query has the same negative limit' do
|
403
|
+
let(:limit) { -5 }
|
404
|
+
|
405
|
+
it 'returns the caching cursor' do
|
406
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
context 'and the new query has the same positive limit' do
|
411
|
+
let(:limit) { 5 }
|
412
|
+
|
413
|
+
it 'returns the caching cursor' do
|
414
|
+
expect(Mongo::QueryCache.get(**query_options)).to eq(caching_cursor)
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
context 'and the new query has no limit' do
|
419
|
+
let(:limit) { nil }
|
420
|
+
|
421
|
+
it 'returns nil' do
|
422
|
+
expect(Mongo::QueryCache.get(**query_options)).to be_nil
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
context 'and the new query has a 0 limit' do
|
427
|
+
let(:limit) { 0 }
|
428
|
+
|
429
|
+
it 'returns nil' do
|
430
|
+
expect(Mongo::QueryCache.get(**query_options)).to be_nil
|
431
|
+
end
|
432
|
+
end
|
415
433
|
end
|
416
434
|
end
|
417
435
|
end
|
@@ -76,6 +76,7 @@ class ModernRetryableTestConsumer < LegacyRetryableTestConsumer
|
|
76
76
|
allow(session).to receive(:pinned_connection_global_id)
|
77
77
|
allow(session).to receive(:starting_transaction?).and_return(false)
|
78
78
|
allow(session).to receive(:materialize)
|
79
|
+
allow(session).to receive(:with_transaction_deadline).and_return(nil)
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# rubocop:todo all
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
describe Mongo::Server::RoundTripTimeCalculator do
|
7
|
+
let(:calculator) { Mongo::Server::RoundTripTimeCalculator.new }
|
8
|
+
|
9
|
+
describe '#update_average_round_trip_time' do
|
10
|
+
context 'no existing average rtt' do
|
11
|
+
it 'updates average rtt' do
|
12
|
+
calculator.instance_variable_set('@last_round_trip_time', 5)
|
13
|
+
calculator.update_average_round_trip_time
|
14
|
+
expect(calculator.average_round_trip_time).to eq(5)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with existing average rtt' do
|
19
|
+
it 'averages with existing average rtt' do
|
20
|
+
calculator.instance_variable_set('@last_round_trip_time', 5)
|
21
|
+
calculator.instance_variable_set('@average_round_trip_time', 10)
|
22
|
+
calculator.update_average_round_trip_time
|
23
|
+
expect(calculator.average_round_trip_time).to eq(9)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#update_minimum_round_trip_time' do
|
29
|
+
context 'with no samples' do
|
30
|
+
it 'sets minimum_round_trip_time to zero' do
|
31
|
+
calculator.update_minimum_round_trip_time
|
32
|
+
expect(calculator.minimum_round_trip_time).to eq(0)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'with one sample' do
|
37
|
+
before do
|
38
|
+
calculator.instance_variable_set('@last_round_trip_time', 5)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'sets minimum_round_trip_time to zero' do
|
42
|
+
calculator.update_minimum_round_trip_time
|
43
|
+
expect(calculator.minimum_round_trip_time).to eq(0)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'with two samples' do
|
48
|
+
before do
|
49
|
+
calculator.instance_variable_set('@last_round_trip_time', 10)
|
50
|
+
calculator.instance_variable_set('@rtts', [5])
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'sets minimum_round_trip_time to zero' do
|
54
|
+
calculator.update_minimum_round_trip_time
|
55
|
+
expect(calculator.minimum_round_trip_time).to eq(0)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with samples less than maximum' do
|
60
|
+
before do
|
61
|
+
calculator.instance_variable_set('@last_round_trip_time', 10)
|
62
|
+
calculator.instance_variable_set('@rtts', [5, 4, 120])
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'properly sets minimum_round_trip_time' do
|
66
|
+
calculator.update_minimum_round_trip_time
|
67
|
+
expect(calculator.minimum_round_trip_time).to eq(4)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with more than maximum samples' do
|
72
|
+
before do
|
73
|
+
calculator.instance_variable_set('@last_round_trip_time', 2)
|
74
|
+
calculator.instance_variable_set('@rtts', [1, 20, 15, 4, 5, 6, 7, 39, 8, 4])
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'properly sets minimum_round_trip_time' do
|
78
|
+
calculator.update_minimum_round_trip_time
|
79
|
+
expect(calculator.minimum_round_trip_time).to eq(2)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#measure' do
|
86
|
+
context 'block does not raise' do
|
87
|
+
it 'updates average rtt' do
|
88
|
+
expect(calculator).to receive(:update_average_round_trip_time)
|
89
|
+
calculator.measure do
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'updates minimum rtt' do
|
94
|
+
expect(calculator).to receive(:update_minimum_round_trip_time)
|
95
|
+
calculator.measure do
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'block raises' do
|
101
|
+
it 'does not update average rtt' do
|
102
|
+
expect(calculator).not_to receive(:update_average_round_trip_time)
|
103
|
+
expect do
|
104
|
+
calculator.measure do
|
105
|
+
raise "Problem"
|
106
|
+
end
|
107
|
+
end.to raise_error(/Problem/)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'does not update minimum rtt' do
|
111
|
+
expect(calculator).not_to receive(:update_minimum_round_trip_time)
|
112
|
+
expect do
|
113
|
+
calculator.measure do
|
114
|
+
raise "Problem"
|
115
|
+
end
|
116
|
+
end.to raise_error(/Problem/)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -103,16 +103,6 @@ describe Mongo::Socket::SSL do
|
|
103
103
|
expect(socket).to be_alive
|
104
104
|
end
|
105
105
|
end
|
106
|
-
|
107
|
-
context 'when connecting the tcp socket raises an exception' do
|
108
|
-
|
109
|
-
it 'raises an exception' do
|
110
|
-
expect_any_instance_of(::Socket).to receive(:connect).and_raise(Mongo::Error::SocketTimeoutError)
|
111
|
-
expect do
|
112
|
-
socket
|
113
|
-
end.to raise_error(Mongo::Error::SocketTimeoutError)
|
114
|
-
end
|
115
|
-
end
|
116
106
|
end
|
117
107
|
|
118
108
|
context 'when a certificate and key are provided as strings' do
|
@@ -111,7 +111,7 @@ module Mongo
|
|
111
111
|
def run
|
112
112
|
change_stream = begin
|
113
113
|
@target.watch(@pipeline, ::Utils.snakeize_hash(@options))
|
114
|
-
rescue Mongo::Error::OperationFailure => e
|
114
|
+
rescue Mongo::Error::OperationFailure::Family => e
|
115
115
|
return {
|
116
116
|
result: {
|
117
117
|
error: {
|
@@ -146,7 +146,7 @@ module Mongo
|
|
146
146
|
begin
|
147
147
|
change = enum.next
|
148
148
|
changes << change
|
149
|
-
rescue Mongo::Error::OperationFailure => e
|
149
|
+
rescue Mongo::Error::OperationFailure::Family => e
|
150
150
|
return {
|
151
151
|
result: {
|
152
152
|
error: {
|
@@ -355,7 +355,7 @@ module Mongo
|
|
355
355
|
if coll.indexes.map { |doc| doc['name'] }.include?(ixn = arguments.fetch('index'))
|
356
356
|
raise "Index #{ixn} exists in collection #{cn} in database #{dn}, but must not"
|
357
357
|
end
|
358
|
-
rescue Mongo::Error::OperationFailure => e
|
358
|
+
rescue Mongo::Error::OperationFailure::Family => e
|
359
359
|
if e.to_s =~ /ns does not exist/
|
360
360
|
# Success.
|
361
361
|
else
|